diff options
author | Xinyu Chen <xinyu.chen@freescale.com> | 2012-09-07 09:57:12 +0800 |
---|---|---|
committer | Xinyu Chen <xinyu.chen@freescale.com> | 2012-09-07 09:57:12 +0800 |
commit | cbc0db0202a9d92e726de41c9884baee5190e4c1 (patch) | |
tree | 943b80849424b5f2be814c8a31c455371c4fbfac /sound | |
parent | a45bfa0fcb4f54a4ff8e4c6785f8faa6bdf1cd8c (diff) | |
parent | b387e1ccdaaf6f15a0c40e9738ef6eef0df83253 (diff) |
Merge remote branch 'fsl-linux-sdk/imx_3.0.35_12.09.01' into imx_3.0.35_android
Conflicts:
arch/arm/mach-mx6/pm.c
Diffstat (limited to 'sound')
-rw-r--r-- | sound/soc/codecs/mxc_spdif.c | 5 | ||||
-rw-r--r-- | sound/soc/imx/imx-hdmi-dma.c | 42 |
2 files changed, 44 insertions, 3 deletions
diff --git a/sound/soc/codecs/mxc_spdif.c b/sound/soc/codecs/mxc_spdif.c index 883aa4d26687..c80eed6d80d3 100644 --- a/sound/soc/codecs/mxc_spdif.c +++ b/sound/soc/codecs/mxc_spdif.c @@ -571,6 +571,7 @@ static int mxc_spdif_playback_start(struct snd_pcm_substream *substream, if (!plat_data->spdif_tx) return -EINVAL; + spdif_priv->tx_active = true; regval = __raw_readl(spdif_base_addr + SPDIF_REG_SCR); regval &= 0xfc33e3; regval &= ~SCR_LOW_POWER; @@ -715,9 +716,11 @@ static int mxc_spdif_capture_start(struct snd_pcm_substream *substream, struct mxc_spdif_platform_data *plat_data = spdif_priv->plat_data; unsigned long regval; - if (!plat_data->spdif_rx || !spdif_priv->rx_active) + if (!plat_data->spdif_rx) return -EINVAL; + spdif_priv->rx_active = true; + regval = __raw_readl(spdif_base_addr + SPDIF_REG_SCR); /* * initial and reset SPDIF configuration: diff --git a/sound/soc/imx/imx-hdmi-dma.c b/sound/soc/imx/imx-hdmi-dma.c index 70c8cb13d3de..45811429985f 100644 --- a/sound/soc/imx/imx-hdmi-dma.c +++ b/sound/soc/imx/imx-hdmi-dma.c @@ -597,9 +597,15 @@ static void hdmi_sdma_isr(void *data) if (runtime->access == SNDRV_PCM_ACCESS_MMAP_INTERLEAVED) { appl_bytes = frames_to_bytes(runtime, runtime->control->appl_ptr); + if (rtd->appl_bytes > appl_bytes) + rtd->appl_bytes = 0; 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) { + pr_info("HDMI is slow,ring buffer size[%ld], count[%ld]!\n", + rtd->buffer_bytes, count); + } rtd->appl_bytes = appl_bytes; if (count <= space_to_end) { @@ -645,9 +651,15 @@ static irqreturn_t hdmi_dma_isr(int irq, void *dev_id) if (runtime->access == SNDRV_PCM_ACCESS_MMAP_INTERLEAVED) { appl_bytes = frames_to_bytes(runtime, runtime->control->appl_ptr); + if (rtd->appl_bytes > appl_bytes) + rtd->appl_bytes = 0; 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) { + pr_info("HDMI is slow,ring buffer size[%ld],count[%ld]!\n", + rtd->buffer_bytes, count); + } rtd->appl_bytes = appl_bytes; if (count <= space_to_end) { @@ -1066,6 +1078,8 @@ static int hdmi_dma_hw_params(struct snd_pcm_substream *substream, /* Init par for mmap optimizate */ init_table(rtd->channels); + rtd->appl_bytes = 0; + return 0; } @@ -1073,6 +1087,7 @@ static int hdmi_dma_trigger(struct snd_pcm_substream *substream, int cmd) { struct snd_pcm_runtime *runtime = substream->runtime; struct imx_hdmi_dma_runtime_data *rtd = runtime->private_data; + unsigned long offset, count, space_to_end, appl_bytes; switch (cmd) { case SNDRV_PCM_TRIGGER_START: @@ -1080,11 +1095,34 @@ static int hdmi_dma_trigger(struct snd_pcm_substream *substream, int cmd) case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: rtd->frame_idx = 0; if (runtime->access == SNDRV_PCM_ACCESS_MMAP_INTERLEAVED) { - rtd->appl_bytes = frames_to_bytes(runtime, + 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) + rtd->appl_bytes = 0; + offset = rtd->appl_bytes % rtd->buffer_bytes; + space_to_end = rtd->buffer_bytes - offset; + count = appl_bytes - rtd->appl_bytes; - hdmi_dma_mmap_copy(substream, 0, 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); + } else { + hdmi_dma_mmap_copy(substream, + offset, space_to_end); + hdmi_dma_mmap_copy(substream, + 0, count - space_to_end); + } } dumpregs(); |