Commit 6b9084c3 authored by Chen Liangjun's avatar Chen Liangjun

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: default avatarChen Liangjun <b36089@freescale.com>
parent 64936321
......@@ -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();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment