CHROMIUM: ALSA: ASoC: exynos hdmi - fix audio transfer on unplug
authorYuly Novikov <ynovikov@chromium.org>
Tue, 14 May 2013 20:59:01 +0000 (16:59 -0400)
committerChromeBot <chrome-bot@google.com>
Tue, 14 May 2013 23:38:20 +0000 (16:38 -0700)
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 <ynovikov@chromium.org>
Change-Id: I9d27d0e388f444756576e643e20811901c6afe85
Reviewed-on: https://gerrit.chromium.org/gerrit/51178
Reviewed-by: Dylan Reid <dgreid@chromium.org>
sound/soc/samsung/hdmi_audio.c

index 5ded4ad..a003d37 100644 (file)
@@ -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);