/* Check whether the location prefix needs to be added to the label. * If all mic-jacks are in the same location (e.g. rear panel), we don't * have to put "Front" prefix to each label. In such a case, returns false. */ static int check_mic_location_need(struct hda_codec *codec, const struct auto_pin_cfg *cfg, int input) { unsigned int defc; int i, attr, attr2; defc = snd_hda_codec_get_pincfg(codec, cfg->inputs[input].pin); attr = snd_hda_get_input_pin_attr(defc); /* for internal or docking mics, we need locations */ if (attr <= INPUT_PIN_ATTR_NORMAL) return 1; attr = 0; for (i = 0; i < cfg->num_inputs; i++) { defc = snd_hda_codec_get_pincfg(codec, cfg->inputs[i].pin); attr2 = snd_hda_get_input_pin_attr(defc); if (attr2 >= INPUT_PIN_ATTR_NORMAL) { if (attr && attr != attr2) return 1; /* different locations found */ attr = attr2; } } return 0; }
static bool can_be_headset_mic(struct hda_codec *codec, struct auto_pin_cfg_item *item, int seq_number) { int attr; unsigned int def_conf; if (item->type != AUTO_PIN_MIC) return false; if (item->is_headset_mic || item->is_headphone_mic) return false; /* Already assigned */ def_conf = snd_hda_codec_get_pincfg(codec, item->pin); attr = snd_hda_get_input_pin_attr(def_conf); if (attr <= INPUT_PIN_ATTR_DOCK) return false; if (seq_number >= 0) { int seq = get_defcfg_sequence(def_conf); if (seq != seq_number) return false; } return true; }
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, int *indexp) { 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 = ""; /* handle as a speaker if it's a fixed line-out */ if (!strcmp(name, "Line Out") && attr == INPUT_PIN_ATTR_INT) name = "Speaker"; 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, indexp); if (!sfx) sfx = check_output_sfx(nid, cfg->speaker_pins, cfg->speaker_outs, indexp); if (!sfx) { /* don't add channel suffix for Headphone controls */ int idx = get_hp_label_index(codec, nid, cfg->hp_pins, cfg->hp_outs); if (idx >= 0) *indexp = idx; sfx = ""; } } snprintf(label, maxlen, "%s%s%s", pfx, name, sfx); return 1; }
static const char *hda_get_input_pin_label(struct hda_codec *codec, const struct auto_pin_cfg_item *item, hda_nid_t pin, bool check_location) { unsigned int def_conf; static const char * const mic_names[] = { "Internal Mic", "Dock Mic", "Mic", "Rear Mic", "Front Mic" }; int attr; def_conf = snd_hda_codec_get_pincfg(codec, pin); switch (get_defcfg_device(def_conf)) { case AC_JACK_MIC_IN: if (item && item->is_headset_mic) return "Headset Mic"; if (item && item->is_headphone_mic) return "Headphone Mic"; if (!check_location) return "Mic"; attr = snd_hda_get_input_pin_attr(def_conf); if (!attr) return "None"; return mic_names[attr - 1]; case AC_JACK_LINE_IN: if (!check_location) return "Line"; attr = snd_hda_get_input_pin_attr(def_conf); if (!attr) return "None"; if (attr == INPUT_PIN_ATTR_DOCK) 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"; case AC_JACK_HP_OUT: return "Headphone Mic"; default: return "Misc"; } }
static int is_ext_mic(struct hda_codec *codec, unsigned int idx) { struct cs_spec *spec = codec->spec; struct auto_pin_cfg *cfg = &spec->autocfg; hda_nid_t pin = cfg->inputs[idx].pin; unsigned int val; if (!is_jack_detectable(codec, pin)) return 0; val = snd_hda_codec_get_pincfg(codec, pin); return (snd_hda_get_input_pin_attr(val) != INPUT_PIN_ATTR_INT); }
static int is_ext_mic(struct hda_codec *codec, unsigned int idx) { struct cs_spec *spec = codec->spec; struct auto_pin_cfg *cfg = &spec->autocfg; hda_nid_t pin = cfg->inputs[idx].pin; unsigned int val = snd_hda_query_pin_caps(codec, pin); if (!(val & AC_PINCAP_PRES_DETECT)) return 0; val = snd_hda_codec_get_pincfg(codec, pin); return (snd_hda_get_input_pin_attr(val) != INPUT_PIN_ATTR_INT); }
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 ""; }