78
78
* @second_stream: pointer to second stream
79
79
* @playback: the number of playback streams opened
80
80
* @capture: the number of capture streams opened
81
- * @asynchronous: 0=synchronous mode, 1=asynchronous mode
82
81
* @cpu_dai: the CPU DAI for this device
83
82
* @dev_attr: the sysfs device attribute structure
84
83
* @stats: SSI statistics
@@ -90,9 +89,6 @@ struct fsl_ssi_private {
90
89
unsigned int irq ;
91
90
struct snd_pcm_substream * first_stream ;
92
91
struct snd_pcm_substream * second_stream ;
93
- unsigned int playback ;
94
- unsigned int capture ;
95
- int asynchronous ;
96
92
unsigned int fifo_depth ;
97
93
struct snd_soc_dai_driver cpu_dai_drv ;
98
94
struct device_attribute dev_attr ;
@@ -281,15 +277,19 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
281
277
struct snd_soc_dai * dai )
282
278
{
283
279
struct snd_soc_pcm_runtime * rtd = substream -> private_data ;
284
- struct fsl_ssi_private * ssi_private = snd_soc_dai_get_drvdata (rtd -> cpu_dai );
280
+ struct fsl_ssi_private * ssi_private =
281
+ snd_soc_dai_get_drvdata (rtd -> cpu_dai );
282
+ int synchronous = ssi_private -> cpu_dai_drv .symmetric_rates ;
285
283
286
284
/*
287
285
* If this is the first stream opened, then request the IRQ
288
286
* and initialize the SSI registers.
289
287
*/
290
- if (!ssi_private -> playback && ! ssi_private -> capture ) {
288
+ if (!ssi_private -> first_stream ) {
291
289
struct ccsr_ssi __iomem * ssi = ssi_private -> ssi ;
292
290
291
+ ssi_private -> first_stream = substream ;
292
+
293
293
/*
294
294
* Section 16.5 of the MPC8610 reference manual says that the
295
295
* SSI needs to be disabled before updating the registers we set
@@ -306,7 +306,7 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
306
306
clrsetbits_be32 (& ssi -> scr ,
307
307
CCSR_SSI_SCR_I2S_MODE_MASK | CCSR_SSI_SCR_SYN ,
308
308
CCSR_SSI_SCR_TFR_CLK_DIS | CCSR_SSI_SCR_I2S_MODE_SLAVE
309
- | (ssi_private -> asynchronous ? 0 : CCSR_SSI_SCR_SYN ));
309
+ | (synchronous ? CCSR_SSI_SCR_SYN : 0 ));
310
310
311
311
out_be32 (& ssi -> stcr ,
312
312
CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFEN0 |
@@ -323,7 +323,7 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
323
323
* master.
324
324
*/
325
325
326
- /* 4. Enable the interrupts and DMA requests */
326
+ /* Enable the interrupts and DMA requests */
327
327
out_be32 (& ssi -> sier , SIER_FLAGS );
328
328
329
329
/*
@@ -352,58 +352,47 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
352
352
* this is bad is because at this point, the PCM driver has not
353
353
* finished initializing the DMA controller.
354
354
*/
355
- }
356
-
357
- if (!ssi_private -> first_stream )
358
- ssi_private -> first_stream = substream ;
359
- else {
360
- /* This is the second stream open, so we need to impose sample
361
- * rate and maybe sample size constraints. Note that this can
362
- * cause a race condition if the second stream is opened before
363
- * the first stream is fully initialized.
364
- *
365
- * We provide some protection by checking to make sure the first
366
- * stream is initialized, but it's not perfect. ALSA sometimes
367
- * re-initializes the driver with a different sample rate or
368
- * size. If the second stream is opened before the first stream
369
- * has received its final parameters, then the second stream may
370
- * be constrained to the wrong sample rate or size.
371
- *
372
- * FIXME: This code does not handle opening and closing streams
373
- * repeatedly. If you open two streams and then close the first
374
- * one, you may not be able to open another stream until you
375
- * close the second one as well.
376
- */
377
- struct snd_pcm_runtime * first_runtime =
378
- ssi_private -> first_stream -> runtime ;
379
-
380
- if (!first_runtime -> sample_bits ) {
381
- dev_err (substream -> pcm -> card -> dev ,
382
- "set sample size in %s stream first\n" ,
383
- substream -> stream == SNDRV_PCM_STREAM_PLAYBACK
384
- ? "capture" : "playback" );
385
- return - EAGAIN ;
386
- }
355
+ } else {
356
+ if (synchronous ) {
357
+ struct snd_pcm_runtime * first_runtime =
358
+ ssi_private -> first_stream -> runtime ;
359
+ /*
360
+ * This is the second stream open, and we're in
361
+ * synchronous mode, so we need to impose sample
362
+ * sample size constraints. This is because STCCR is
363
+ * used for playback and capture in synchronous mode,
364
+ * so there's no way to specify different word
365
+ * lengths.
366
+ *
367
+ * Note that this can cause a race condition if the
368
+ * second stream is opened before the first stream is
369
+ * fully initialized. We provide some protection by
370
+ * checking to make sure the first stream is
371
+ * initialized, but it's not perfect. ALSA sometimes
372
+ * re-initializes the driver with a different sample
373
+ * rate or size. If the second stream is opened
374
+ * before the first stream has received its final
375
+ * parameters, then the second stream may be
376
+ * constrained to the wrong sample rate or size.
377
+ */
378
+ if (!first_runtime -> sample_bits ) {
379
+ dev_err (substream -> pcm -> card -> dev ,
380
+ "set sample size in %s stream first\n" ,
381
+ substream -> stream ==
382
+ SNDRV_PCM_STREAM_PLAYBACK
383
+ ? "capture" : "playback" );
384
+ return - EAGAIN ;
385
+ }
387
386
388
- /* If we're in synchronous mode, then we need to constrain
389
- * the sample size as well. We don't support independent sample
390
- * rates in asynchronous mode.
391
- */
392
- if (!ssi_private -> asynchronous )
393
387
snd_pcm_hw_constraint_minmax (substream -> runtime ,
394
388
SNDRV_PCM_HW_PARAM_SAMPLE_BITS ,
395
389
first_runtime -> sample_bits ,
396
390
first_runtime -> sample_bits );
391
+ }
397
392
398
393
ssi_private -> second_stream = substream ;
399
394
}
400
395
401
- if (substream -> stream == SNDRV_PCM_STREAM_PLAYBACK )
402
- ssi_private -> playback ++ ;
403
-
404
- if (substream -> stream == SNDRV_PCM_STREAM_CAPTURE )
405
- ssi_private -> capture ++ ;
406
-
407
396
return 0 ;
408
397
}
409
398
@@ -424,24 +413,35 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream,
424
413
struct snd_pcm_hw_params * hw_params , struct snd_soc_dai * cpu_dai )
425
414
{
426
415
struct fsl_ssi_private * ssi_private = snd_soc_dai_get_drvdata (cpu_dai );
416
+ struct ccsr_ssi __iomem * ssi = ssi_private -> ssi ;
417
+ unsigned int sample_size =
418
+ snd_pcm_format_width (params_format (hw_params ));
419
+ u32 wl = CCSR_SSI_SxCCR_WL (sample_size );
420
+ int enabled = in_be32 (& ssi -> scr ) & CCSR_SSI_SCR_SSIEN ;
427
421
428
- if (substream == ssi_private -> first_stream ) {
429
- struct ccsr_ssi __iomem * ssi = ssi_private -> ssi ;
430
- unsigned int sample_size =
431
- snd_pcm_format_width (params_format (hw_params ));
432
- u32 wl = CCSR_SSI_SxCCR_WL (sample_size );
422
+ /*
423
+ * If we're in synchronous mode, and the SSI is already enabled,
424
+ * then STCCR is already set properly.
425
+ */
426
+ if (enabled && ssi_private -> cpu_dai_drv .symmetric_rates )
427
+ return 0 ;
433
428
434
- /* The SSI should always be disabled at this points (SSIEN=0) */
429
+ /*
430
+ * FIXME: The documentation says that SxCCR[WL] should not be
431
+ * modified while the SSI is enabled. The only time this can
432
+ * happen is if we're trying to do simultaneous playback and
433
+ * capture in asynchronous mode. Unfortunately, I have been enable
434
+ * to get that to work at all on the P1022DS. Therefore, we don't
435
+ * bother to disable/enable the SSI when setting SxCCR[WL], because
436
+ * the SSI will stop anyway. Maybe one day, this will get fixed.
437
+ */
435
438
436
- /* In synchronous mode, the SSI uses STCCR for capture */
437
- if ((substream -> stream == SNDRV_PCM_STREAM_PLAYBACK ) ||
438
- !ssi_private -> asynchronous )
439
- clrsetbits_be32 (& ssi -> stccr ,
440
- CCSR_SSI_SxCCR_WL_MASK , wl );
441
- else
442
- clrsetbits_be32 (& ssi -> srccr ,
443
- CCSR_SSI_SxCCR_WL_MASK , wl );
444
- }
439
+ /* In synchronous mode, the SSI uses STCCR for capture */
440
+ if ((substream -> stream == SNDRV_PCM_STREAM_PLAYBACK ) ||
441
+ ssi_private -> cpu_dai_drv .symmetric_rates )
442
+ clrsetbits_be32 (& ssi -> stccr , CCSR_SSI_SxCCR_WL_MASK , wl );
443
+ else
444
+ clrsetbits_be32 (& ssi -> srccr , CCSR_SSI_SxCCR_WL_MASK , wl );
445
445
446
446
return 0 ;
447
447
}
@@ -464,7 +464,6 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
464
464
465
465
switch (cmd ) {
466
466
case SNDRV_PCM_TRIGGER_START :
467
- clrbits32 (& ssi -> scr , CCSR_SSI_SCR_SSIEN );
468
467
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE :
469
468
if (substream -> stream == SNDRV_PCM_STREAM_PLAYBACK )
470
469
setbits32 (& ssi -> scr ,
@@ -500,12 +499,6 @@ static void fsl_ssi_shutdown(struct snd_pcm_substream *substream,
500
499
struct snd_soc_pcm_runtime * rtd = substream -> private_data ;
501
500
struct fsl_ssi_private * ssi_private = snd_soc_dai_get_drvdata (rtd -> cpu_dai );
502
501
503
- if (substream -> stream == SNDRV_PCM_STREAM_PLAYBACK )
504
- ssi_private -> playback -- ;
505
-
506
- if (substream -> stream == SNDRV_PCM_STREAM_CAPTURE )
507
- ssi_private -> capture -- ;
508
-
509
502
if (ssi_private -> first_stream == substream )
510
503
ssi_private -> first_stream = ssi_private -> second_stream ;
511
504
@@ -514,7 +507,7 @@ static void fsl_ssi_shutdown(struct snd_pcm_substream *substream,
514
507
/*
515
508
* If this is the last active substream, disable the SSI.
516
509
*/
517
- if (!ssi_private -> playback && ! ssi_private -> capture ) {
510
+ if (!ssi_private -> first_stream ) {
518
511
struct ccsr_ssi __iomem * ssi = ssi_private -> ssi ;
519
512
520
513
clrbits32 (& ssi -> scr , CCSR_SSI_SCR_SSIEN );
@@ -688,9 +681,7 @@ static int __devinit fsl_ssi_probe(struct platform_device *pdev)
688
681
}
689
682
690
683
/* Are the RX and the TX clocks locked? */
691
- if (of_find_property (np , "fsl,ssi-asynchronous" , NULL ))
692
- ssi_private -> asynchronous = 1 ;
693
- else
684
+ if (!of_find_property (np , "fsl,ssi-asynchronous" , NULL ))
694
685
ssi_private -> cpu_dai_drv .symmetric_rates = 1 ;
695
686
696
687
/* Determine the FIFO depth. */
0 commit comments