diff options
Diffstat (limited to 'sound/pci/hda/hda_auto_parser.c')
-rw-r--r-- | sound/pci/hda/hda_auto_parser.c | 61 |
1 files changed, 41 insertions, 20 deletions
diff --git a/sound/pci/hda/hda_auto_parser.c b/sound/pci/hda/hda_auto_parser.c index 647218d69f68..4ec6dc88b7f8 100644 --- a/sound/pci/hda/hda_auto_parser.c +++ b/sound/pci/hda/hda_auto_parser.c @@ -141,7 +141,6 @@ int snd_hda_parse_pin_defcfg(struct hda_codec *codec, memset(sequences_hp, 0, sizeof(sequences_hp)); assoc_line_out = 0; - codec->ignore_misc_bit = true; end_nid = codec->start_nid + codec->num_nodes; for (nid = codec->start_nid; nid < end_nid; nid++) { unsigned int wid_caps = get_wcaps(codec, nid); @@ -157,9 +156,6 @@ int snd_hda_parse_pin_defcfg(struct hda_codec *codec, continue; def_conf = snd_hda_codec_get_pincfg(codec, nid); - if (!(get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)) & - AC_DEFCFG_MISC_NO_PRESENCE)) - codec->ignore_misc_bit = false; conn = get_defcfg_connect(def_conf); if (conn == AC_JACK_PORT_NONE) continue; @@ -332,13 +328,12 @@ int snd_hda_parse_pin_defcfg(struct hda_codec *codec, if (cfg->dig_outs) snd_printd(" dig-out=0x%x/0x%x\n", cfg->dig_out_pins[0], cfg->dig_out_pins[1]); - snd_printd(" inputs:"); + snd_printd(" inputs:\n"); for (i = 0; i < cfg->num_inputs; i++) { - snd_printd(" %s=0x%x", + snd_printd(" %s=0x%x\n", hda_get_autocfg_input_label(codec, cfg, i), cfg->inputs[i].pin); } - snd_printd("\n"); if (cfg->dig_in_pin) snd_printd(" dig-in=0x%x\n", cfg->dig_in_pin); @@ -503,6 +498,38 @@ static const char *check_output_sfx(hda_nid_t nid, const hda_nid_t *pins, return channel_sfx[i]; } +static const char *check_output_pfx(struct hda_codec *codec, hda_nid_t nid) +{ + unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid); + int attr = snd_hda_get_input_pin_attr(def_conf); + + /* check the location */ + switch (attr) { + case INPUT_PIN_ATTR_DOCK: + return "Dock "; + case INPUT_PIN_ATTR_FRONT: + return "Front "; + } + return ""; +} + +static int get_hp_label_index(struct hda_codec *codec, hda_nid_t nid, + const hda_nid_t *pins, int num_pins) +{ + int i, j, idx = 0; + + const char *pfx = check_output_pfx(codec, nid); + + i = find_idx_in_nid_list(nid, pins, num_pins); + if (i < 0) + return -1; + for (j = 0; j < i; j++) + if (pfx == check_output_pfx(codec, pins[j])) + idx++; + + return idx; +} + static int fill_audio_out_name(struct hda_codec *codec, hda_nid_t nid, const struct auto_pin_cfg *cfg, const char *name, char *label, int maxlen, @@ -510,20 +537,13 @@ static int fill_audio_out_name(struct hda_codec *codec, hda_nid_t nid, { unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid); int attr = snd_hda_get_input_pin_attr(def_conf); - const char *pfx = "", *sfx = ""; + const char *pfx, *sfx = ""; /* handle as a speaker if it's a fixed line-out */ if (!strcmp(name, "Line Out") && attr == INPUT_PIN_ATTR_INT) name = "Speaker"; - /* check the location */ - switch (attr) { - case INPUT_PIN_ATTR_DOCK: - pfx = "Dock "; - break; - case INPUT_PIN_ATTR_FRONT: - pfx = "Front "; - break; - } + pfx = check_output_pfx(codec, nid); + if (cfg) { /* try to give a unique suffix if needed */ sfx = check_output_sfx(nid, cfg->line_out_pins, cfg->line_outs, @@ -533,8 +553,8 @@ static int fill_audio_out_name(struct hda_codec *codec, hda_nid_t nid, indexp); if (!sfx) { /* don't add channel suffix for Headphone controls */ - int idx = find_idx_in_nid_list(nid, cfg->hp_pins, - cfg->hp_outs); + int idx = get_hp_label_index(codec, nid, cfg->hp_pins, + cfg->hp_outs); if (idx >= 0) *indexp = idx; sfx = ""; @@ -740,7 +760,8 @@ void snd_hda_pick_fixup(struct hda_codec *codec, for (q = quirk; q->subvendor; q++) { unsigned int vendorid = q->subdevice | (q->subvendor << 16); - if (vendorid == codec->subsystem_id) { + unsigned int mask = 0xffff0000 | q->subdevice_mask; + if ((codec->subsystem_id & mask) == (vendorid & mask)) { id = q->value; #ifdef CONFIG_SND_DEBUG_VERBOSE name = q->name; |