From: Yuly Novikov Date: Tue, 14 May 2013 20:59:01 +0000 (-0400) Subject: CHROMIUM: ALSA: ASoC: exynos hdmi - fix audio transfer on unplug X-Git-Url: http://git.cascardo.eti.br/?p=cascardo%2Flinux.git;a=commitdiff_plain;h=c17dd45a794c63db0b66faa2e3eddff3104cd6d0 CHROMIUM: ALSA: ASoC: exynos hdmi - fix audio transfer on unplug Because hotplug handling timeout was increased, it is no longer safe to read HDMI_MODE_SEL in hdmi_audio_hotplug_func, since HDMI might be off at that time. This broke transferring audio to internal speakers on HDMI unplug, since bogus value was read. So, move the code that handles DVI plugging inside "if (plugged)", where reading HDMI registers is safe, since it is powered on. BUG=chromium:222145,chromium:239641 TEST=Various HDMI/DVI plug/unplug scenarios, the most complex being: play music, plug HDMI, suspend, unplug HDMI, plug DVI, resume, listen to sound on internal speakers. Signed-off-by: Yuly Novikov Change-Id: I9d27d0e388f444756576e643e20811901c6afe85 Reviewed-on: https://gerrit.chromium.org/gerrit/51178 Reviewed-by: Dylan Reid --- diff --git a/sound/soc/samsung/hdmi_audio.c b/sound/soc/samsung/hdmi_audio.c index 5ded4ad1b8f1..a003d37993bf 100644 --- a/sound/soc/samsung/hdmi_audio.c +++ b/sound/soc/samsung/hdmi_audio.c @@ -439,21 +439,20 @@ static void hdmi_audio_hotplug_func(struct work_struct *work) plugged = atomic_read(&ctx->plugged); - if (hdmi_reg_read(ctx, HDMI_MODE_SEL) & HDMI_DVI_MODE_EN) { - /* If HDMI operates in DVI mode, - * for audio purposes it is the same as nothing plugged. - * Unfortunately, hotplug interrupt is received multiple times, - * and HDMI_DVI_MODE_EN is set only in the last one. - * So, we have already reported that HDMI audio was plugged. - * So, update ctx, report now that it was unplugged and return. - */ - atomic_set(&ctx->plugged, 0); - if (plugged && ctx->plugin.jack_cb) - ctx->plugin.jack_cb(false); - return; - } - if (plugged) { + if (hdmi_reg_read(ctx, HDMI_MODE_SEL) & HDMI_DVI_MODE_EN) { + /* If HDMI operates in DVI mode, + * for audio purposes it is the same as nothing plugged. + * So, change the "ctx->plugged" state to unplugged. + * Also, simulate unplugging for jack_cb, as this + * takes care of swapping HDMI with DVI when suspended. + */ + atomic_set(&ctx->plugged, 0); + if (ctx->plugin.jack_cb) + ctx->plugin.jack_cb(false); + return; + } + hdmi_audio_control(ctx, false); hdmi_conf_init(ctx); hdmi_audio_init(ctx);