diff options
author | Shengjiu Wang <shengjiu.wang@nxp.com> | 2018-07-16 18:29:23 +0800 |
---|---|---|
committer | Leonard Crestez <leonard.crestez@nxp.com> | 2018-08-24 12:41:33 +0300 |
commit | e1bbf60895c9ca124b371e0dcd174e02c7ef7724 (patch) | |
tree | 5f36147e8df3e39105cd8646bb3abd45703035ae /sound | |
parent | 2f37b9f4806a92cdc0f9c103f6b0ce79e4317ca4 (diff) |
MLK-18866: ASoC: imx-pcm-dma-v2: refine the callback function
The commit 7f3ff14b7eb1 ("dmaengine: imx-sdma: add 1ms delay
to ensure SDMA channel is stopped") add 1ms delay may cause
the audio underrun/overrun.
But ESAI has an hardware issue in older version which work abnormal
after underrun/overrun, especially there will be channel swap.
To workaround this issue, the ESAI need to be reset. in
imx-pcm-dma.c we include a new callback function for DMA interrupt
which will check the state of cpu dai and reset it in necessary.
So inport same function to imx-pcm-dma-v2.
Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
Reviewed-by: Viorel Suman <viorel.suman@nxp.com>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/soc/fsl/imx-pcm-dma-v2.c | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/sound/soc/fsl/imx-pcm-dma-v2.c b/sound/soc/fsl/imx-pcm-dma-v2.c index 814483790a97..4831141b9afd 100644 --- a/sound/soc/fsl/imx-pcm-dma-v2.c +++ b/sound/soc/fsl/imx-pcm-dma-v2.c @@ -45,6 +45,25 @@ static bool imx_dma_filter_fn(struct dma_chan *chan, void *param) return true; } +static void imx_pcm_dma_v2_complete(void *arg) +{ + struct snd_pcm_substream *substream = arg; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct dmaengine_pcm_runtime_data *prtd = + substream->runtime->private_data; + struct snd_dmaengine_dai_dma_data *dma_data; + + prtd->pos += snd_pcm_lib_period_bytes(substream); + if (prtd->pos >= snd_pcm_lib_buffer_bytes(substream)) + prtd->pos = 0; + + snd_pcm_period_elapsed(substream); + + dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); + if (dma_data->check_xrun && dma_data->check_xrun(substream)) + dma_data->device_reset(substream, 1); +} + /* this may get called several times by oss emulation */ static int imx_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) @@ -54,8 +73,12 @@ static int imx_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_dmaengine_dai_dma_data *dma_data; struct dma_slave_config config; struct dma_chan *chan; + struct dmaengine_pcm_runtime_data *prtd = + substream->runtime->private_data; int err = 0; + prtd->callback = imx_pcm_dma_v2_complete; + dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); /* return if this is a bufferless transfer e.g. |