ALSA: hda - Fix detection of dual headphones
authorTakashi Iwai <tiwai@suse.de>
Wed, 18 Nov 2009 13:23:37 +0000 (14:23 +0100)
committerTakashi Iwai <tiwai@suse.de>
Wed, 18 Nov 2009 13:23:37 +0000 (14:23 +0100)
The dual-headphone mode with STAC/IDT codecs is useful only for machines
that have two (or more) built-in headphones.

But, some HP laptops give multiple headphone pin configs, one for the
built-in and another for the separate (likely a docking station) one.
This results in a missing speaker volume control.

This patch adds more check for the dual-headphone mode to avoid this
problem.

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

index d83649c25fb25619ba9a88414052cc8adeb7f522..39001c47e6270251eb1c0a851e4adcb445478aa3 100644 (file)
@@ -3635,6 +3635,26 @@ static void stac92xx_auto_init_hp_out(struct hda_codec *codec)
        }
 }
 
+static int is_dual_headphones(struct hda_codec *codec)
+{
+       struct sigmatel_spec *spec = codec->spec;
+       int i, valid_hps;
+
+       if (spec->autocfg.line_out_type != AUTO_PIN_SPEAKER_OUT ||
+           spec->autocfg.hp_outs <= 1)
+               return 0;
+       valid_hps = 0;
+       for (i = 0; i < spec->autocfg.hp_outs; i++) {
+               hda_nid_t nid = spec->autocfg.hp_pins[i];
+               unsigned int cfg = snd_hda_codec_get_pincfg(codec, nid);
+               if (get_defcfg_location(cfg) & AC_JACK_LOC_SEPARATE)
+                       continue;
+               valid_hps++;
+       }
+       return (valid_hps > 1);
+}
+
+
 static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out, hda_nid_t dig_in)
 {
        struct sigmatel_spec *spec = codec->spec;
@@ -3651,8 +3671,7 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
        /* If we have no real line-out pin and multiple hp-outs, HPs should
         * be set up as multi-channel outputs.
         */
-       if (spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT &&
-           spec->autocfg.hp_outs > 1) {
+       if (is_dual_headphones(codec)) {
                /* Copy hp_outs to line_outs, backup line_outs in
                 * speaker_outs so that the following routines can handle
                 * HP pins as primary outputs.