* 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)
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);
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;
{
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)
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;
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;