ALSA: hda - Check pincap while parsing the configuration
authorTakashi Iwai <tiwai@suse.de>
Tue, 15 Jan 2013 07:45:33 +0000 (08:45 +0100)
committerTakashi Iwai <tiwai@suse.de>
Tue, 15 Jan 2013 07:49:09 +0000 (08:49 +0100)
Sometimes (or rather often) BIOS sets the pin default configurations
obviously wrongly.  Looking through these failures, one common pattern
is to enable some dead pins that are usually marked as speaker pins.
In such a case, we can skip them if the pins don't have the output
capability.

In this patch, add a check for the valid pin cap bit for each parsed
pin, and filter out when it's invalid.

The fix was originally suggested by Raymond Yau.

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

index 33b3ece224c6917e39a24ab033eb76782e8e3c18..a4810c7437bd4d09917db84374f2b2692adbc5b9 100644 (file)
@@ -97,6 +97,28 @@ static void reorder_outputs(unsigned int nums, hda_nid_t *pins)
        }
 }
 
+/* check whether the given pin has a proper pin I/O capability bit */
+static bool check_pincap_validity(struct hda_codec *codec, hda_nid_t pin,
+                                 unsigned int dev)
+{
+       unsigned int pincap = snd_hda_query_pin_caps(codec, pin);
+
+       /* some old hardware don't return the proper pincaps */
+       if (!pincap)
+               return true;
+
+       switch (dev) {
+       case AC_JACK_LINE_OUT:
+       case AC_JACK_SPEAKER:
+       case AC_JACK_HP_OUT:
+       case AC_JACK_SPDIF_OUT:
+       case AC_JACK_DIG_OTHER_OUT:
+               return !!(pincap & AC_PINCAP_OUT);
+       default:
+               return !!(pincap & AC_PINCAP_IN);
+       }
+}
+
 /*
  * Parse all pin widgets and store the useful pin nids to cfg
  *
@@ -164,6 +186,9 @@ int snd_hda_parse_pin_defcfg(struct hda_codec *codec,
                                dev = AC_JACK_SPEAKER;
                }
 
+               if (!check_pincap_validity(codec, nid, dev))
+                       continue;
+
                switch (dev) {
                case AC_JACK_LINE_OUT:
                        seq = get_defcfg_sequence(def_conf);
This page took 0.026646 seconds and 5 git commands to generate.