]> git.hungrycats.org Git - linux/commitdiff
ALSA: hda - Fix the lost power-setup of seconary pins after PM resume
authorTakashi Iwai <tiwai@suse.de>
Wed, 11 Jan 2012 11:34:11 +0000 (12:34 +0100)
committerGreg Kroah-Hartman <gregkh@suse.de>
Wed, 18 Jan 2012 15:31:53 +0000 (07:31 -0800)
commit f2cbba7602383cd9cdd21f0a5d0b8bd1aad47b33 upstream.

When multiple headphone or other detectable output pins are present,
the power-map has to be updated after resume appropriately, but the
current driver doesn't check all pins but only the first pin (since
it's enough to check it for the mute-behavior).  This resulted in the
silent output from the secondary outputs after PM resume.

This patch fixes the problem by checking all pins at (re-)init time.

Bugzilla: https://bugzilla.novell.com/show_bug.cgi?id=740347

Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
sound/pci/hda/patch_sigmatel.c

index 5261fd85d8648654943dd3560a7a5dd2515eb3e7..fc3c9034f713d0d217edf737957a59783f4ff2ad 100644 (file)
@@ -4306,6 +4306,27 @@ static void stac_store_hints(struct hda_codec *codec)
        }
 }
 
+static void stac_issue_unsol_events(struct hda_codec *codec, int num_pins,
+                                   const hda_nid_t *pins)
+{
+       while (num_pins--)
+               stac_issue_unsol_event(codec, *pins++);
+}
+
+/* fake event to set up pins */
+static void stac_fake_hp_events(struct hda_codec *codec)
+{
+       struct sigmatel_spec *spec = codec->spec;
+
+       if (spec->autocfg.hp_outs)
+               stac_issue_unsol_events(codec, spec->autocfg.hp_outs,
+                                       spec->autocfg.hp_pins);
+       if (spec->autocfg.line_outs &&
+           spec->autocfg.line_out_pins[0] != spec->autocfg.hp_pins[0])
+               stac_issue_unsol_events(codec, spec->autocfg.line_outs,
+                                       spec->autocfg.line_out_pins);
+}
+
 static int stac92xx_init(struct hda_codec *codec)
 {
        struct sigmatel_spec *spec = codec->spec;
@@ -4356,10 +4377,7 @@ static int stac92xx_init(struct hda_codec *codec)
                stac92xx_auto_set_pinctl(codec, spec->autocfg.line_out_pins[0],
                                AC_PINCTL_OUT_EN);
                /* fake event to set up pins */
-               if (cfg->hp_pins[0])
-                       stac_issue_unsol_event(codec, cfg->hp_pins[0]);
-               else if (cfg->line_out_pins[0])
-                       stac_issue_unsol_event(codec, cfg->line_out_pins[0]);
+               stac_fake_hp_events(codec);
        } else {
                stac92xx_auto_init_multi_out(codec);
                stac92xx_auto_init_hp_out(codec);
@@ -5000,19 +5018,11 @@ static void stac927x_proc_hook(struct snd_info_buffer *buffer,
 #ifdef CONFIG_PM
 static int stac92xx_resume(struct hda_codec *codec)
 {
-       struct sigmatel_spec *spec = codec->spec;
-
        stac92xx_init(codec);
        snd_hda_codec_resume_amp(codec);
        snd_hda_codec_resume_cache(codec);
        /* fake event to set up pins again to override cached values */
-       if (spec->hp_detect) {
-               if (spec->autocfg.hp_pins[0])
-                       stac_issue_unsol_event(codec, spec->autocfg.hp_pins[0]);
-               else if (spec->autocfg.line_out_pins[0])
-                       stac_issue_unsol_event(codec,
-                                              spec->autocfg.line_out_pins[0]);
-       }
+       stac_fake_hp_events(codec);
        return 0;
 }