summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChen Liangjun <b36089@freescale.com>2012-09-13 21:28:11 +0800
committerJason Liu <r64343@freescale.com>2012-09-14 00:56:25 +0800
commiteaaf30efdc8dfeb03418bde1499a76c9903bd211 (patch)
tree87f261c7c15dd9ed1293e8532699789ea1ca54ba
parent9bba02d47489f2455bae09815b779bdc494efabb (diff)
ENGR00224245 HDMI AUDIO: stop/start PCM while unplug,blank/plug, unblankrel_imx_3.0.35_12.09.013.0-imx6-12.09.01-201209132128
When unplug, blank happens, HDMI audio can't play properly. So in driver, audio pcm would be disconnected when event above happens. However, pulse audio can't process disconnect event properly and if an blank or unplug event happens, HDMI sink would lost and can't be back again. In this patch, instead of disconnecting audio PCM stream, triggering stop audio pcm while unplug and blank, triggering start again while plug and unblank if the audio pcm is triggerd stop in the unplug/blank event. Signed-off-by: Chen Liangjun <b36089@freescale.com>
-rw-r--r--drivers/mfd/mxc-hdmi-core.c12
-rw-r--r--include/linux/mfd/mxc-hdmi-core.h1
-rw-r--r--sound/soc/imx/imx-hdmi-dma.c2
3 files changed, 13 insertions, 2 deletions
diff --git a/drivers/mfd/mxc-hdmi-core.c b/drivers/mfd/mxc-hdmi-core.c
index e9322477ff6d..a07db1b0c070 100644
--- a/drivers/mfd/mxc-hdmi-core.c
+++ b/drivers/mfd/mxc-hdmi-core.c
@@ -41,6 +41,7 @@
#include <linux/mfd/mxc-hdmi-core.h>
#include <linux/fsl_devices.h>
#include <mach/hardware.h>
+#include <linux/mfd/mxc-hdmi-core.h>
struct mxc_hdmi_data {
struct platform_device *pdev;
@@ -72,22 +73,29 @@ static spinlock_t hdmi_audio_lock, hdmi_blank_state_lock, hdmi_cable_state_lock;
unsigned int hdmi_set_cable_state(unsigned int state)
{
unsigned long flags;
+ struct snd_pcm_substream *substream = hdmi_audio_stream_playback;
spin_lock_irqsave(&hdmi_cable_state_lock, flags);
hdmi_cable_state = state;
spin_unlock_irqrestore(&hdmi_cable_state_lock, flags);
+ if (check_hdmi_state() && substream)
+ substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_START);
return 0;
}
unsigned int hdmi_set_blank_state(unsigned int state)
{
unsigned long flags;
+ struct snd_pcm_substream *substream = hdmi_audio_stream_playback;
spin_lock_irqsave(&hdmi_blank_state_lock, flags);
hdmi_blank_state = state;
spin_unlock_irqrestore(&hdmi_blank_state_lock, flags);
+ if (check_hdmi_state() && substream)
+ substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_START);
+
return 0;
}
@@ -98,7 +106,7 @@ static void hdmi_audio_abort_stream(struct snd_pcm_substream *substream)
snd_pcm_stream_lock_irqsave(substream, flags);
if (snd_pcm_running(substream))
- snd_pcm_stop(substream, SNDRV_PCM_STATE_DISCONNECTED);
+ substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_STOP);
snd_pcm_stream_unlock_irqrestore(substream, flags);
}
@@ -114,7 +122,7 @@ int mxc_hdmi_abort_stream(void)
return 0;
}
-static int check_hdmi_state(void)
+int check_hdmi_state(void)
{
unsigned long flags1, flags2;
unsigned int ret;
diff --git a/include/linux/mfd/mxc-hdmi-core.h b/include/linux/mfd/mxc-hdmi-core.h
index f16b11cb5cf4..26fa47d09abf 100644
--- a/include/linux/mfd/mxc-hdmi-core.h
+++ b/include/linux/mfd/mxc-hdmi-core.h
@@ -60,5 +60,6 @@ int mxc_hdmi_register_audio(struct snd_pcm_substream *substream);
void mxc_hdmi_unregister_audio(struct snd_pcm_substream *substream);
unsigned int hdmi_set_cable_state(unsigned int state);
unsigned int hdmi_set_blank_state(unsigned int state);
+int check_hdmi_state(void);
#endif
diff --git a/sound/soc/imx/imx-hdmi-dma.c b/sound/soc/imx/imx-hdmi-dma.c
index ab0207a428d0..74d45558c97d 100644
--- a/sound/soc/imx/imx-hdmi-dma.c
+++ b/sound/soc/imx/imx-hdmi-dma.c
@@ -1115,6 +1115,8 @@ static int hdmi_dma_trigger(struct snd_pcm_substream *substream, int cmd)
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ if (!check_hdmi_state())
+ return 0;
rtd->frame_idx = 0;
if (runtime->access == SNDRV_PCM_ACCESS_MMAP_INTERLEAVED) {
appl_bytes = frames_to_bytes(runtime,