aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc
diff options
context:
space:
mode:
authorTimur Tabi <timur@freescale.com>2009-03-25 19:20:37 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2009-04-02 11:34:14 -0400
commita4d11fe50c238a7da5225d1399314c3505cbd792 (patch)
tree100766010c57f0ee04eed149a0b3e9fd323ca398 /sound/soc
parent7377226c344a7295a7573dce400ce9ddd42f0ca4 (diff)
ASoC: remove trigger delay in Freescale MPC8610 sound driver
Remove the delay from the trigger function in the Freescale MPC8610 sound driver when capture is started. This delay was used to ensure that the DMA controller was active when ALSA call the .pointer function to request a DMA transfer status. A better approach is for the .pointer function to detect that DMA has not started, and return zero instead. This change eliminates the need for the delay. Also add some related code to check for a DMA programming error, and report XRUN if it occurs. 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.c17
-rw-r--r--sound/soc/fsl/fsl_ssi.c20
2 files changed, 19 insertions, 18 deletions
diff --git a/sound/soc/fsl/fsl_dma.c b/sound/soc/fsl/fsl_dma.c
index b3eb8570cd7b..2c4892c853cf 100644
--- a/sound/soc/fsl/fsl_dma.c
+++ b/sound/soc/fsl/fsl_dma.c
@@ -697,6 +697,23 @@ static snd_pcm_uframes_t fsl_dma_pointer(struct snd_pcm_substream *substream)
697 else 697 else
698 position = in_be32(&dma_channel->dar); 698 position = in_be32(&dma_channel->dar);
699 699
700 /*
701 * When capture is started, the SSI immediately starts to fill its FIFO.
702 * This means that the DMA controller is not started until the FIFO is
703 * full. However, ALSA calls this function before that happens, when
704 * MR.DAR is still zero. In this case, just return zero to indicate
705 * that nothing has been received yet.
706 */
707 if (!position)
708 return 0;
709
710 if ((position < dma_private->dma_buf_phys) ||
711 (position > dma_private->dma_buf_end)) {
712 dev_err(substream->pcm->card->dev,
713 "dma pointer is out of range, halting stream\n");
714 return SNDRV_PCM_POS_XRUN;
715 }
716
700 frames = bytes_to_frames(runtime, position - dma_private->dma_buf_phys); 717 frames = bytes_to_frames(runtime, position - dma_private->dma_buf_phys);
701 718
702 /* 719 /*
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 169bca295b78..72823a2b33d6 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -466,28 +466,12 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
466 case SNDRV_PCM_TRIGGER_START: 466 case SNDRV_PCM_TRIGGER_START:
467 clrbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN); 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 setbits32(&ssi->scr, 470 setbits32(&ssi->scr,
471 CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_TE); 471 CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_TE);
472 } else { 472 else
473 long timeout = jiffies + 10;
474
475 setbits32(&ssi->scr, 473 setbits32(&ssi->scr,
476 CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_RE); 474 CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_RE);
477
478 /* Wait until the SSI has filled its FIFO. Without this
479 * delay, ALSA complains about overruns. When the FIFO
480 * is full, the DMA controller initiates its first
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.
485 */
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;
490 }
491 break; 475 break;
492 476
493 case SNDRV_PCM_TRIGGER_STOP: 477 case SNDRV_PCM_TRIGGER_STOP: