diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index 7444d2e7a82a7426795a333a2edb5925e35a1a52..ebb558414314b7db06229185702f4dfad70e411f 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c @@ -2514,6 +2514,38 @@ static int parse_capture_source(struct hda_codec *codec, hda_nid_t pin, * create playback/capture controls for input pins */ +/* fill the label for each input at first */ +static int fill_input_pin_labels(struct hda_codec *codec) +{ + struct hda_gen_spec *spec = codec->spec; + const struct auto_pin_cfg *cfg = &spec->autocfg; + int i; + + for (i = 0; i < cfg->num_inputs; i++) { + hda_nid_t pin = cfg->inputs[i].pin; + const char *label; + int j, idx; + + if (!is_input_pin(codec, pin)) + continue; + + label = hda_get_autocfg_input_label(codec, cfg, i); + idx = 0; + for (j = i; j >= 0; j--) { + if (spec->input_labels[j] && + !strcmp(spec->input_labels[j], label)) { + idx = spec->input_label_idxs[j] + 1; + break; + } + } + + spec->input_labels[i] = label; + spec->input_label_idxs[i] = idx; + } + + return 0; +} + #define CFG_IDX_MIX 99 /* a dummy cfg->input idx for stereo mix */ static int create_input_ctls(struct hda_codec *codec) @@ -2522,29 +2554,24 @@ static int create_input_ctls(struct hda_codec *codec) const struct auto_pin_cfg *cfg = &spec->autocfg; hda_nid_t mixer = spec->mixer_nid; int num_adcs; - int i, err, type_idx = 0; - const char *prev_label = NULL; + int i, err; unsigned int val; num_adcs = fill_adc_nids(codec); if (num_adcs < 0) return 0; + err = fill_input_pin_labels(codec); + if (err < 0) + return err; + for (i = 0; i < cfg->num_inputs; i++) { hda_nid_t pin; - const char *label; pin = cfg->inputs[i].pin; if (!is_input_pin(codec, pin)) continue; - label = hda_get_autocfg_input_label(codec, cfg, i); - if (prev_label && !strcmp(label, prev_label)) - type_idx++; - else - type_idx = 0; - prev_label = label; - val = PIN_IN; if (cfg->inputs[i].type == AUTO_PIN_MIC) val |= snd_hda_get_default_vref(codec, pin); @@ -2553,14 +2580,16 @@ static int create_input_ctls(struct hda_codec *codec) if (mixer) { if (is_reachable_path(codec, pin, mixer)) { err = new_analog_input(codec, i, pin, - label, type_idx, mixer); + spec->input_labels[i], + spec->input_label_idxs[i], + mixer); if (err < 0) return err; } } - err = parse_capture_source(codec, pin, i, - num_adcs, label, -mixer); + err = parse_capture_source(codec, pin, i, num_adcs, + spec->input_labels[i], -mixer); if (err < 0) return err; @@ -2907,26 +2936,22 @@ static int create_multi_cap_vol_ctl(struct hda_codec *codec) { struct hda_gen_spec *spec = codec->spec; struct hda_input_mux *imux = &spec->input_mux; - int i, err, type, type_idx = 0; - const char *prev_label = NULL; + int i, err, type; for (i = 0; i < imux->num_items; i++) { - const char *label; bool inv_dmic; + int idx; - if (imux->items[i].index >= spec->autocfg.num_inputs) + idx = imux->items[i].index; + if (idx >= spec->autocfg.num_inputs) continue; - label = hda_get_autocfg_input_label(codec, &spec->autocfg, - imux->items[i].index); - if (prev_label && !strcmp(label, prev_label)) - type_idx++; - else - type_idx = 0; - prev_label = label; inv_dmic = is_inv_dmic_pin(codec, spec->imux_pins[i]); for (type = 0; type < 2; type++) { - err = add_single_cap_ctl(codec, label, type_idx, type, + err = add_single_cap_ctl(codec, + spec->input_labels[idx], + spec->input_label_idxs[idx], + type, get_first_cap_ctl(codec, i, type), inv_dmic); if (err < 0) @@ -3012,16 +3037,13 @@ static int parse_mic_boost(struct hda_codec *codec) struct hda_gen_spec *spec = codec->spec; struct auto_pin_cfg *cfg = &spec->autocfg; int i, err; - int type_idx = 0; hda_nid_t nid; - const char *prev_label = NULL; for (i = 0; i < cfg->num_inputs; i++) { if (cfg->inputs[i].type > AUTO_PIN_MIC) break; nid = cfg->inputs[i].pin; if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) { - const char *label; char boost_label[44]; struct nid_path *path; unsigned int val; @@ -3029,18 +3051,13 @@ static int parse_mic_boost(struct hda_codec *codec) if (!nid_has_volume(codec, nid, HDA_INPUT)) continue; - label = hda_get_autocfg_input_label(codec, cfg, i); - if (prev_label && !strcmp(label, prev_label)) - type_idx++; - else - type_idx = 0; - prev_label = label; - snprintf(boost_label, sizeof(boost_label), - "%s Boost Volume", label); + "%s Boost Volume", + spec->input_labels[i]); val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT); err = add_control(spec, HDA_CTL_WIDGET_VOL, - boost_label, type_idx, val); + boost_label, + spec->input_label_idxs[i], val); if (err < 0) return err; diff --git a/sound/pci/hda/hda_generic.h b/sound/pci/hda/hda_generic.h index 7b14e9ce748646ad7e5e6e67fed336976b6aac9e..f6b88cd4584f9fe4720b48d463347be4ff3fef0d 100644 --- a/sound/pci/hda/hda_generic.h +++ b/sound/pci/hda/hda_generic.h @@ -105,6 +105,8 @@ struct hda_gen_spec { hda_nid_t adc_nids[AUTO_CFG_MAX_OUTS]; hda_nid_t dig_in_nid; /* digital-in NID; optional */ hda_nid_t mixer_nid; /* analog-mixer NID */ + const char *input_labels[AUTO_CFG_MAX_OUTS]; + int input_label_idxs[AUTO_CFG_MAX_OUTS]; /* capture setup for dynamic dual-adc switch */ hda_nid_t cur_adc;