diff options
author | Shine Liu <shinel@foxmail.com> | 2009-08-25 14:05:50 +0200 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2009-08-25 14:09:05 +0200 |
commit | faf907c7ba3d7df6266366556817f2ef7314640a (patch) | |
tree | 5b89e22322e9fce532e4c78e80b52e791366bd0d /sound/soc/s3c24xx/s3c-i2s-v2.c | |
parent | ARM: OMAP: McBSP: Merge two functions into omap_mcbsp_start/_stop (diff) | |
download | linux-faf907c7ba3d7df6266366556817f2ef7314640a.tar.xz linux-faf907c7ba3d7df6266366556817f2ef7314640a.zip |
ASoC: S3C platform: Fix s3c2410_dma_started() called at improper time
s3c24xx dma has the auto reload feature, when the the trnasfer is done,
CURR_TC(DSTAT[19:0], current value of transfer count) reaches 0, and DMA
ACK becomes 1, and then, TC(DCON[19:0]) will be loaded into CURR_TC. So
the transmission is repeated.
IRQ is issued while auto reload occurs. We change the DISRC and
DCON[19:0] in the ISR, but at this time, the auto reload has been
performed already. The first block is being re-transmitted by the DMA.
So we need rewrite the DISRC and DCON[19:0] for the next block
immediatly after the this block has been started to be transported.
The function s3c2410_dma_started() is for this perpose, which is called
in the form of "s3c2410_dma_ctrl(prtd->params->channel,
S3C2410_DMAOP_STARTED);" in s3c24xx_pcm_trigger().
But it is not correct. DMA transmission won't start until DMA REQ signal
arrived, it is the time s3c24xx_snd_txctrl(1) or s3c24xx_snd_rxctrl(1)
is called in s3c24xx_i2s_trigger().
In the current framework, s3c24xx_pcm_trigger() is always called before
s3c24xx_pcm_trigger(). So the s3c2410_dma_started() should be called in
s3c24xx_pcm_trigger() after s3c24xx_snd_txctrl(1) or
s3c24xx_snd_rxctrl(1) is called in this function.
However, s3c2410_dma_started() is dma related, to call this function we
should provide the channel number, which is given by
substream->runtime->private_data->params->channel. The private_data
points to a struct s3c24xx_runtime_data object, which is define in
s3c24xx_pcm.c, so s3c2410_dma_started() can't be called in s3c24xx_i2s.c
Fix this by moving the call to signal the DMA started to the DAI
drivers.
Signed-off-by: Shine Liu <liuxian@redflag-linux.com>
Signed-off-by: Shine Liu <shinel@foxmail.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/s3c24xx/s3c-i2s-v2.c')
-rw-r--r-- | sound/soc/s3c24xx/s3c-i2s-v2.c | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/sound/soc/s3c24xx/s3c-i2s-v2.c b/sound/soc/s3c24xx/s3c-i2s-v2.c index ebfb2f631054..11d8717c9ea0 100644 --- a/sound/soc/s3c24xx/s3c-i2s-v2.c +++ b/sound/soc/s3c24xx/s3c-i2s-v2.c @@ -387,6 +387,8 @@ static int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd, int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE); unsigned long irqs; int ret = 0; + int channel = ((struct s3c24xx_pcm_dma_params *) + rtd->dai->cpu_dai->dma_data)->channel; pr_debug("Entered %s\n", __func__); @@ -416,6 +418,14 @@ static int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd, s3c2412_snd_txctrl(i2s, 1); local_irq_restore(irqs); + + /* + * Load the next buffer to DMA to meet the reqirement + * of the auto reload mechanism of S3C24XX. + * This call won't bother S3C64XX. + */ + s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STARTED); + break; case SNDRV_PCM_TRIGGER_STOP: |