ALSA: hda - Improve the input source name labels
This patch improves the input-source label strings to be generated from
the pin information instead of fixed strings per AUTO_PIN_* type.
This gives more suitable labels, especially for mic and line-in pins.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 0ee4439..e328434 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -4607,7 +4607,7 @@
snd_printd(" inputs:");
for (i = 0; i < cfg->num_inputs; i++) {
snd_printdd(" %s=0x%x",
- auto_pin_cfg_labels[cfg->inputs[i].type],
+ hda_get_autocfg_input_label(codec, cfg, i),
cfg->inputs[i].pin);
}
snd_printd("\n");
@@ -4618,28 +4618,87 @@
}
EXPORT_SYMBOL_HDA(snd_hda_parse_pin_def_config);
-/* labels for input pins - for obsoleted config stuff */
-const char *auto_pin_cfg_labels[AUTO_PIN_LAST] = {
- "Mic", "Line", "CD", "Aux"
-};
-EXPORT_SYMBOL_HDA(auto_pin_cfg_labels);
+const char *hda_get_input_pin_label(struct hda_codec *codec, hda_nid_t pin,
+ int check_location)
+{
+ unsigned int def_conf, loc;
-void snd_hda_get_input_pin_label(const struct auto_pin_cfg *cfg,
- int input, char *str)
+ def_conf = snd_hda_codec_get_pincfg(codec, pin);
+ loc = get_defcfg_location(def_conf);
+
+ switch (get_defcfg_device(def_conf)) {
+ case AC_JACK_MIC_IN:
+ if (!check_location)
+ return "Mic";
+ if (get_defcfg_connect(def_conf) == AC_JACK_PORT_FIXED ||
+ (loc & 0x30) == AC_JACK_LOC_INTERNAL)
+ return "Internal Mic";
+ if ((loc & 0x30) == AC_JACK_LOC_SEPARATE)
+ return "Dock Mic";
+ if (loc == AC_JACK_LOC_REAR)
+ return "Rear Mic";
+ return "Mic";
+ case AC_JACK_LINE_IN:
+ if (!check_location)
+ return "Line";
+ if ((loc & 0xf0) == AC_JACK_LOC_SEPARATE)
+ return "Dock Line";
+ return "Line";
+ case AC_JACK_AUX:
+ return "Aux";
+ case AC_JACK_CD:
+ return "CD";
+ case AC_JACK_SPDIF_IN:
+ return "SPDIF In";
+ case AC_JACK_DIG_OTHER_IN:
+ return "Digital In";
+ default:
+ return "Misc";
+ }
+}
+EXPORT_SYMBOL_HDA(hda_get_input_pin_label);
+
+const char *hda_get_autocfg_input_label(struct hda_codec *codec,
+ const struct auto_pin_cfg *cfg,
+ int input)
{
int type = cfg->inputs[input].type;
- int idx;
+ int has_multiple_pins = 0;
- for (idx = 0; idx < 3 && --input >= 0; idx++) {
- if (type != cfg->inputs[input].type)
- break;
- }
- if (idx > 0)
- sprintf(str, "%s %d", auto_pin_cfg_labels[type], idx);
- else
- strcpy(str, auto_pin_cfg_labels[type]);
+ if ((input > 0 && cfg->inputs[input - 1].type == type) ||
+ (input < cfg->num_inputs - 1 && cfg->inputs[input + 1].type == type))
+ has_multiple_pins = 1;
+ return hda_get_input_pin_label(codec, cfg->inputs[input].pin,
+ has_multiple_pins);
}
-EXPORT_SYMBOL_HDA(snd_hda_get_input_pin_label);
+EXPORT_SYMBOL_HDA(hda_get_autocfg_input_label);
+
+int snd_hda_add_imux_item(struct hda_input_mux *imux, const char *label,
+ int index, int *type_idx)
+{
+ int i, label_idx = 0;
+ if (imux->num_items >= HDA_MAX_NUM_INPUTS) {
+ snd_printd(KERN_ERR "hda_codec: Too many imux items!\n");
+ return -EINVAL;
+ }
+ for (i = 0; i < imux->num_items; i++) {
+ if (!strncmp(label, imux->items[i].label, strlen(label)))
+ label_idx++;
+ }
+ if (type_idx)
+ *type_idx = label_idx;
+ if (label_idx > 0)
+ snprintf(imux->items[imux->num_items].label,
+ sizeof(imux->items[imux->num_items].label),
+ "%s %d", label, label_idx);
+ else
+ strlcpy(imux->items[imux->num_items].label, label,
+ sizeof(imux->items[imux->num_items].label));
+ imux->items[imux->num_items].index = index;
+ imux->num_items++;
+ return 0;
+}
+EXPORT_SYMBOL_HDA(snd_hda_add_imux_item);
#ifdef CONFIG_PM