aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc
diff options
context:
space:
mode:
authorTimur Tabi <timur@freescale.com>2009-03-06 19:39:34 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2009-03-07 06:01:49 -0500
commit3a638ff272744247aad4a75b1fac174ac5746114 (patch)
tree60cf2c815f58380a4e72b8dca2792bd6d9eafcea /sound/soc
parent96deff6baf55da68b4b9b4dfe8ef572c6f1835fd (diff)
ASoC: Improve pause/unpause performance in Freescale 8610 drivers
Add support for true pause and unpause. Without this, mplayer will drop some audio (less than one second, but still noticeable) when pausing playback. Remove support for PM suspend and resume from the trigger function, since the driver doesn't support PM anyway. Optimize the delay after starting capture. Instead of delaying 1ms, the driver now polls the hardware. The new delay is shorter by over 90% yet still effective. Signed-off-by: Timur Tabi <timur@freescale.com> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc')
-rw-r--r--sound/soc/fsl/fsl_dma.c3
-rw-r--r--sound/soc/fsl/fsl_ssi.c23
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);