diff options
Diffstat (limited to 'sound/soc')
-rw-r--r-- | sound/soc/fsl/fsl_dma.c | 3 | ||||
-rw-r--r-- | sound/soc/fsl/fsl_ssi.c | 23 |
2 files changed, 16 insertions, 10 deletions
diff --git a/sound/soc/fsl/fsl_dma.c b/sound/soc/fsl/fsl_dma.c index 58a3fa497503..b3eb8570cd7b 100644 --- a/sound/soc/fsl/fsl_dma.c +++ b/sound/soc/fsl/fsl_dma.c | |||
@@ -142,7 +142,8 @@ static const struct snd_pcm_hardware fsl_dma_hardware = { | |||
142 | .info = SNDRV_PCM_INFO_INTERLEAVED | | 142 | .info = SNDRV_PCM_INFO_INTERLEAVED | |
143 | SNDRV_PCM_INFO_MMAP | | 143 | SNDRV_PCM_INFO_MMAP | |
144 | SNDRV_PCM_INFO_MMAP_VALID | | 144 | SNDRV_PCM_INFO_MMAP_VALID | |
145 | SNDRV_PCM_INFO_JOINT_DUPLEX, | 145 | SNDRV_PCM_INFO_JOINT_DUPLEX | |
146 | SNDRV_PCM_INFO_PAUSE, | ||
146 | .formats = FSLDMA_PCM_FORMATS, | 147 | .formats = FSLDMA_PCM_FORMATS, |
147 | .rates = FSLDMA_PCM_RATES, | 148 | .rates = FSLDMA_PCM_RATES, |
148 | .rate_min = 5512, | 149 | .rate_min = 5512, |
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); |