From 98976283211d22fec2e2f3accb884049cf67e209 Mon Sep 17 00:00:00 2001 From: Chen Liangjun Date: Wed, 26 Sep 2012 16:00:55 +0800 Subject: [PATCH] ENGR00233663 HDMI: add support for ALSA DMIX when using DMIX for ALSA playback, ALSA would not update write index into driver but maintain it in ALSA LIB level. However, HDMI driver need write index for HDMI header packing. In this case, HDMI driver would fail to do HDMI header pack and user hear no sound when using DMIX in HDMI audio playback. In this patch, use read index(hw_ptr) for HDMI header packing. Signed-off-by: Chen Liangjun --- sound/soc/imx/imx-hdmi-dma.c | 107 +++++------------------------------ 1 file changed, 15 insertions(+), 92 deletions(-) diff --git a/sound/soc/imx/imx-hdmi-dma.c b/sound/soc/imx/imx-hdmi-dma.c index dc71d52b79ca..84b350386328 100644 --- a/sound/soc/imx/imx-hdmi-dma.c +++ b/sound/soc/imx/imx-hdmi-dma.c @@ -583,7 +583,7 @@ static void hdmi_sdma_isr(void *data) struct imx_hdmi_dma_runtime_data *rtd = data; struct snd_pcm_substream *substream = rtd->tx_substream; struct snd_pcm_runtime *runtime = substream->runtime; - unsigned long offset, count, space_to_end, appl_bytes; + unsigned long offset, count, appl_bytes; unsigned long flags; spin_lock_irqsave(&rtd->irq_lock, flags); @@ -597,38 +597,11 @@ static void hdmi_sdma_isr(void *data) * to hw_buffer and add the frame info. */ if (runtime->access == SNDRV_PCM_ACCESS_MMAP_INTERLEAVED) { appl_bytes = frames_to_bytes(runtime, - runtime->control->appl_ptr); - - if (rtd->appl_bytes > appl_bytes) { - if (appl_bytes > rtd->buffer_bytes) - rtd->appl_bytes = - appl_bytes - rtd->buffer_bytes; - else - rtd->appl_bytes = 0; - } else { - if ((appl_bytes - rtd->appl_bytes) > - rtd->buffer_bytes) - rtd->appl_bytes = - appl_bytes - rtd->buffer_bytes; - - } - - offset = rtd->appl_bytes % rtd->buffer_bytes; - space_to_end = rtd->buffer_bytes - offset; - count = appl_bytes - rtd->appl_bytes; - if (count > rtd->buffer_bytes) - count = rtd->buffer_bytes; - - rtd->appl_bytes = appl_bytes; - - if (count <= space_to_end) { - hdmi_dma_mmap_copy(substream, offset, count); - } else { - hdmi_dma_mmap_copy(substream, - offset, space_to_end); - hdmi_dma_mmap_copy(substream, - 0, count - space_to_end); - } + runtime->status->hw_ptr); + appl_bytes += 2 * rtd->period_bytes; + offset = appl_bytes % rtd->buffer_bytes; + count = rtd->period_bytes; + hdmi_dma_mmap_copy(substream, offset, count); } snd_pcm_period_elapsed(substream); @@ -645,7 +618,7 @@ static irqreturn_t hdmi_dma_isr(int irq, void *dev_id) struct imx_hdmi_dma_runtime_data *rtd = dev_id; struct snd_pcm_substream *substream = rtd->tx_substream; struct snd_pcm_runtime *runtime = substream->runtime; - unsigned long offset, count, space_to_end, appl_bytes; + unsigned long offset, count, appl_bytes; unsigned long flags; unsigned int status; @@ -663,34 +636,11 @@ static irqreturn_t hdmi_dma_isr(int irq, void *dev_id) * to hw_buffer and add the frame info. */ if (runtime->access == SNDRV_PCM_ACCESS_MMAP_INTERLEAVED) { appl_bytes = frames_to_bytes(runtime, - runtime->control->appl_ptr); - if (rtd->appl_bytes > appl_bytes) { - if (appl_bytes > rtd->buffer_bytes) - rtd->appl_bytes = - appl_bytes - rtd->buffer_bytes; - else - rtd->appl_bytes = 0; - } else { - if ((appl_bytes - rtd->appl_bytes) > - rtd->buffer_bytes) - rtd->appl_bytes = - appl_bytes - rtd->buffer_bytes; - - } - - offset = rtd->appl_bytes % rtd->buffer_bytes; - space_to_end = rtd->buffer_bytes - offset; - count = appl_bytes - rtd->appl_bytes; - if (count > rtd->buffer_bytes) - count = rtd->buffer_bytes; - rtd->appl_bytes = appl_bytes; - - if (count <= space_to_end) { - hdmi_dma_mmap_copy(substream, offset, count); - } else { - hdmi_dma_mmap_copy(substream, offset, space_to_end); - hdmi_dma_mmap_copy(substream, 0, count - space_to_end); - } + runtime->status->hw_ptr); + appl_bytes += 2 * rtd->period_bytes; + offset = appl_bytes % rtd->buffer_bytes; + count = rtd->period_bytes; + hdmi_dma_mmap_copy(substream, offset, count); } snd_pcm_period_elapsed(substream); @@ -1122,36 +1072,10 @@ static int hdmi_dma_trigger(struct snd_pcm_substream *substream, int cmd) rtd->frame_idx = 0; if (runtime->access == SNDRV_PCM_ACCESS_MMAP_INTERLEAVED) { appl_bytes = frames_to_bytes(runtime, - runtime->control->appl_ptr); - /* If resume, the rtd->appl_bytes may stil - * keep the old value but the control-> - * appl_ptr is clear. Reset it if this - * misalignment happens*/ - if (rtd->appl_bytes > appl_bytes) { - if (appl_bytes > rtd->buffer_bytes) - rtd->appl_bytes = - appl_bytes - rtd->buffer_bytes; - else - rtd->appl_bytes = 0; - } else { - if ((appl_bytes - rtd->appl_bytes) > - rtd->buffer_bytes) - rtd->appl_bytes = - appl_bytes - rtd->buffer_bytes; - - } - - offset = rtd->appl_bytes % rtd->buffer_bytes; + runtime->status->hw_ptr); + offset = appl_bytes % rtd->buffer_bytes; + count = rtd->buffer_bytes; space_to_end = rtd->buffer_bytes - offset; - count = appl_bytes - rtd->appl_bytes; - - if (count > rtd->buffer_bytes) { - pr_err("Error Count,ring buffer size[%ld], count[%ld]!\n", - rtd->buffer_bytes, count); - return -EINVAL; - } - - rtd->appl_bytes = appl_bytes; if (count <= space_to_end) { hdmi_dma_mmap_copy(substream, offset, count); @@ -1161,7 +1085,6 @@ static int hdmi_dma_trigger(struct snd_pcm_substream *substream, int cmd) hdmi_dma_mmap_copy(substream, 0, count - space_to_end); } - } dumpregs(); -- 2.39.5