diff options
author | Chen Liangjun <b36089@freescale.com> | 2012-09-13 21:28:11 +0800 |
---|---|---|
committer | Jason Liu <r64343@freescale.com> | 2012-09-14 00:56:25 +0800 |
commit | eaaf30efdc8dfeb03418bde1499a76c9903bd211 (patch) | |
tree | 87f261c7c15dd9ed1293e8532699789ea1ca54ba | |
parent | 9bba02d47489f2455bae09815b779bdc494efabb (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.c | 12 | ||||
-rw-r--r-- | include/linux/mfd/mxc-hdmi-core.h | 1 | ||||
-rw-r--r-- | sound/soc/imx/imx-hdmi-dma.c | 2 |
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, |