aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/fsl/fsl_ssi.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/fsl/fsl_ssi.c')
-rw-r--r--sound/soc/fsl/fsl_ssi.c23
1 files changed, 14 insertions, 9 deletions
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 8cb6bcf2c00f..b7733e6be192 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -464,28 +464,33 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
464 464
465 switch (cmd) { 465 switch (cmd) {
466 case SNDRV_PCM_TRIGGER_START: 466 case SNDRV_PCM_TRIGGER_START:
467 case SNDRV_PCM_TRIGGER_RESUME: 467 clrbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN);
468 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 468 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
469 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 469 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
470 clrbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN);
471 setbits32(&ssi->scr, 470 setbits32(&ssi->scr,
472 CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_TE); 471 CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_TE);
473 } else { 472 } else {
474 clrbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN); 473 long timeout = jiffies + 10;
474
475 setbits32(&ssi->scr, 475 setbits32(&ssi->scr,
476 CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_RE); 476 CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_RE);
477 477
478 /* 478 /* Wait until the SSI has filled its FIFO. Without this
479 * I think we need this delay to allow time for the SSI 479 * delay, ALSA complains about overruns. When the FIFO
480 * to put data into its FIFO. Without it, ALSA starts 480 * is full, the DMA controller initiates its first
481 * to complain about overruns. 481 * transfer. Until then, however, the DMA's DAR
482 * register is zero, which translates to an
483 * out-of-bounds pointer. This makes ALSA think an
484 * overrun has occurred.
482 */ 485 */
483 mdelay(1); 486 while (!(in_be32(&ssi->sisr) & CCSR_SSI_SISR_RFF0) &&
487 (jiffies < timeout));
488 if (!(in_be32(&ssi->sisr) & CCSR_SSI_SISR_RFF0))
489 return -EIO;
484 } 490 }
485 break; 491 break;
486 492
487 case SNDRV_PCM_TRIGGER_STOP: 493 case SNDRV_PCM_TRIGGER_STOP:
488 case SNDRV_PCM_TRIGGER_SUSPEND:
489 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 494 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
490 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 495 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
491 clrbits32(&ssi->scr, CCSR_SSI_SCR_TE); 496 clrbits32(&ssi->scr, CCSR_SSI_SCR_TE);