]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
ENGR00233663 HDMI: add support for ALSA DMIX
authorChen Liangjun <b36089@freescale.com>
Wed, 26 Sep 2012 08:00:55 +0000 (16:00 +0800)
committerLothar Waßmann <LW@KARO-electronics.de>
Fri, 24 May 2013 06:35:42 +0000 (08:35 +0200)
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 <b36089@freescale.com>
sound/soc/imx/imx-hdmi-dma.c

index dc71d52b79ca4157057d26d7182a5b08923a77e6..84b350386328512b67a33dd54d4005055c2335bd 100644 (file)
@@ -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();