summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorXinyu Chen <xinyu.chen@freescale.com>2012-09-07 09:57:12 +0800
committerXinyu Chen <xinyu.chen@freescale.com>2012-09-07 09:57:12 +0800
commitcbc0db0202a9d92e726de41c9884baee5190e4c1 (patch)
tree943b80849424b5f2be814c8a31c455371c4fbfac /sound
parenta45bfa0fcb4f54a4ff8e4c6785f8faa6bdf1cd8c (diff)
parentb387e1ccdaaf6f15a0c40e9738ef6eef0df83253 (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.c5
-rw-r--r--sound/soc/imx/imx-hdmi-dma.c42
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();