summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorChen Liangjun <b36089@freescale.com>2012-09-26 16:00:55 +0800
committerChen Liangjun <b36089@freescale.com>2012-11-15 11:13:22 +0800
commit6b9084c36436a6de030bf9e074efd733b6139fa6 (patch)
treeb881e7ec3935503b3ea3a6cea00f00134fc1bbad /sound
parent649363219c76a2c91db7df3effeb61ba201c560c (diff)
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 <b36089@freescale.com>
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/imx/imx-hdmi-dma.c107
1 files 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();