static void parse_input(struct hda_codec *codec) { struct ca0110_spec *spec = codec->spec; struct auto_pin_cfg *cfg = &spec->autocfg; hda_nid_t nid, pin; int n, i, j; n = 0; nid = codec->start_nid; for (i = 0; i < codec->num_nodes; i++, nid++) { unsigned int wcaps = get_wcaps(codec, nid); unsigned int type = get_wcaps_type(wcaps); if (type != AC_WID_AUD_IN) continue; if (snd_hda_get_connections(codec, nid, &pin, 1) != 1) continue; if (pin == cfg->dig_in_pin) { spec->dig_in = nid; continue; } for (j = 0; j < cfg->num_inputs; j++) if (cfg->inputs[j].pin == pin) break; if (j >= cfg->num_inputs) continue; spec->input_pins[n] = pin; spec->input_labels[n] = hda_get_input_pin_label(codec, pin, 1); spec->adcs[n] = nid; n++; } spec->num_inputs = n; }
/** * snd_hda_get_pin_label - Get a label for the given I/O pin * * Get a label for the given pin. This function works for both input and * output pins. When @cfg is given as non-NULL, the function tries to get * an optimized label using hda_get_autocfg_input_label(). * * This function tries to give a unique label string for the pin as much as * possible. For example, when the multiple line-outs are present, it adds * the channel suffix like "Front", "Surround", etc (only when @cfg is given). * If no unique name with a suffix is available and @indexp is non-NULL, the * index number is stored in the pointer. */ int snd_hda_get_pin_label(struct hda_codec *codec, hda_nid_t nid, const struct auto_pin_cfg *cfg, char *label, int maxlen, int *indexp) { unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid); const char *name = NULL; int i; bool hdmi; if (indexp) *indexp = 0; if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE) return 0; switch (get_defcfg_device(def_conf)) { case AC_JACK_LINE_OUT: return fill_audio_out_name(codec, nid, cfg, "Line Out", label, maxlen, indexp); case AC_JACK_SPEAKER: return fill_audio_out_name(codec, nid, cfg, "Speaker", label, maxlen, indexp); case AC_JACK_HP_OUT: return fill_audio_out_name(codec, nid, cfg, "Headphone", label, maxlen, indexp); case AC_JACK_SPDIF_OUT: case AC_JACK_DIG_OTHER_OUT: hdmi = is_hdmi_cfg(def_conf); name = hdmi ? "HDMI" : "SPDIF"; if (cfg && indexp) for (i = 0; i < cfg->dig_outs; i++) { hda_nid_t pin = cfg->dig_out_pins[i]; unsigned int c; if (pin == nid) break; c = snd_hda_codec_get_pincfg(codec, pin); if (hdmi == is_hdmi_cfg(c)) (*indexp)++; } break; default: if (cfg) { for (i = 0; i < cfg->num_inputs; i++) { if (cfg->inputs[i].pin != nid) continue; name = hda_get_autocfg_input_label(codec, cfg, i); if (name) break; } } if (!name) name = hda_get_input_pin_label(codec, NULL, nid, true); break; } if (!name) return 0; strlcpy(label, name, maxlen); return 1; }
/** * snd_hda_get_pin_label - Get a label for the given I/O pin * * Get a label for the given pin. This function works for both input and * output pins. When @cfg is given as non-NULL, the function tries to get * an optimized label using hda_get_autocfg_input_label(). * * This function tries to give a unique label string for the pin as much as * possible. For example, when the multiple line-outs are present, it adds * the channel suffix like "Front", "Surround", etc (only when @cfg is given). * If no unique name with a suffix is available and @indexp is non-NULL, the * index number is stored in the pointer. */ int snd_hda_get_pin_label(struct hda_codec *codec, hda_nid_t nid, const struct auto_pin_cfg *cfg, char *label, int maxlen, int *indexp) { unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid); const char *name = NULL; int i; if (indexp) *indexp = 0; if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE) return 0; switch (get_defcfg_device(def_conf)) { case AC_JACK_LINE_OUT: return fill_audio_out_name(codec, nid, cfg, "Line Out", label, maxlen, indexp); case AC_JACK_SPEAKER: return fill_audio_out_name(codec, nid, cfg, "Speaker", label, maxlen, indexp); case AC_JACK_HP_OUT: return fill_audio_out_name(codec, nid, cfg, "Headphone", label, maxlen, indexp); case AC_JACK_SPDIF_OUT: case AC_JACK_DIG_OTHER_OUT: if (get_defcfg_location(def_conf) == AC_JACK_LOC_HDMI) name = "HDMI"; else name = "SPDIF"; if (cfg && indexp) { i = find_idx_in_nid_list(nid, cfg->dig_out_pins, cfg->dig_outs); if (i >= 0) *indexp = i; } break; default: if (cfg) { for (i = 0; i < cfg->num_inputs; i++) { if (cfg->inputs[i].pin != nid) continue; name = hda_get_autocfg_input_label(codec, cfg, i); if (name) break; } } if (!name) name = hda_get_input_pin_label(codec, nid, true); break; } if (!name) return 0; strlcpy(label, name, maxlen); return 1; }
/** * hda_get_autocfg_input_label - Get a label for the given input * * Get a label for the given input pin defined by the autocfg item. * Unlike hda_get_input_pin_label(), this function checks all inputs * defined in autocfg and avoids the redundant mic/line prefix as much as * possible. */ 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 has_multiple_pins = 0; if ((input > 0 && cfg->inputs[input - 1].type == type) || (input < cfg->num_inputs - 1 && cfg->inputs[input + 1].type == type)) has_multiple_pins = 1; if (has_multiple_pins && type == AUTO_PIN_MIC) has_multiple_pins &= check_mic_location_need(codec, cfg, input); return hda_get_input_pin_label(codec, cfg->inputs[input].pin, has_multiple_pins); }
static int cs_capture_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); struct cs_spec *spec = codec->spec; struct auto_pin_cfg *cfg = &spec->autocfg; unsigned int idx; uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; uinfo->count = 1; uinfo->value.enumerated.items = spec->num_inputs; if (uinfo->value.enumerated.item >= spec->num_inputs) uinfo->value.enumerated.item = spec->num_inputs - 1; idx = spec->input_idx[uinfo->value.enumerated.item]; strcpy(uinfo->value.enumerated.name, hda_get_input_pin_label(codec, cfg->inputs[idx].pin, 1)); return 0; }