ALSA: hda - Improve input control names for IDT/STAC codecs

Changing the way the input controls are named using port connection
type and jack location info.

Signed-off-by: Vitaliy Kulikov <Vitaliy.Kulikov@idt.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
Vitaliy Kulikov 2010-09-08 08:56:03 +02:00 коммит произвёл Takashi Iwai
Родитель ab5a6ebee3
Коммит 263d0328c4
1 изменённых файлов: 88 добавлений и 19 удалений

Просмотреть файл

@ -191,6 +191,11 @@ struct sigmatel_mic_route {
signed char dmux_idx; signed char dmux_idx;
}; };
struct unique_input_names {
int num;
char uname[HDA_MAX_NUM_INPUTS][32];
};
struct sigmatel_spec { struct sigmatel_spec {
struct snd_kcontrol_new *mixers[4]; struct snd_kcontrol_new *mixers[4];
unsigned int num_mixers; unsigned int num_mixers;
@ -307,6 +312,7 @@ struct sigmatel_spec {
struct hda_input_mux private_imux; struct hda_input_mux private_imux;
struct hda_input_mux private_smux; struct hda_input_mux private_smux;
struct hda_input_mux private_mono_mux; struct hda_input_mux private_mono_mux;
struct unique_input_names private_u_inp_names;
}; };
static hda_nid_t stac9200_adc_nids[1] = { static hda_nid_t stac9200_adc_nids[1] = {
@ -3452,6 +3458,76 @@ static int create_elem_capture_vol(struct hda_codec *codec, hda_nid_t nid,
return 1; return 1;
} }
static const char *get_input_src_label(struct hda_codec *codec, hda_nid_t nid)
{
unsigned int def_conf;
def_conf = snd_hda_codec_get_pincfg(codec, nid);
switch (get_defcfg_device(def_conf)) {
case AC_JACK_MIC_IN:
if (get_defcfg_connect(def_conf) == AC_JACK_PORT_FIXED ||
((get_defcfg_location(def_conf) & 0xf0)
== AC_JACK_LOC_INTERNAL))
return "Internal Mic";
if ((get_defcfg_location(def_conf) & 0xf0)
== AC_JACK_LOC_SEPARATE)
return "Dock Mic";
if (get_defcfg_location(def_conf) == AC_JACK_LOC_REAR)
return "Rear Mic";
return "Mic";
case AC_JACK_LINE_IN:
if ((get_defcfg_location(def_conf) & 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";
}
snd_printd("invalid inp pin %02x device config %08x", nid, def_conf);
return NULL;
}
static const char *get_unique_inp_src_label(struct hda_codec *codec,
hda_nid_t nid)
{
int i, n;
const char *label;
struct sigmatel_spec *spec = codec->spec;
struct hda_input_mux *imux = &spec->private_imux;
struct hda_input_mux *dimux = &spec->private_dimux;
struct unique_input_names *unames = &spec->private_u_inp_names;
label = get_input_src_label(codec, nid);
n = 0;
for (i = 0; i < imux->num_items; i++) {
if (!strncmp(label, imux->items[i].label, strlen(label)))
n++;
}
if (snd_hda_get_bool_hint(codec, "separate_dmux") == 1) {
for (i = 0; i < dimux->num_items; i++) {
if (!strncmp(label, dimux->items[i].label,
strlen(label)))
n++;
}
}
if (n > 0 && unames->num < HDA_MAX_NUM_INPUTS) {
sprintf(&unames->uname[unames->num][0], "%.28s %d", label, n);
label = &unames->uname[unames->num][0];
unames->num++;
}
return label;
}
/* create playback/capture controls for input pins on dmic capable codecs */ /* create playback/capture controls for input pins on dmic capable codecs */
static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec, static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec,
const struct auto_pin_cfg *cfg) const struct auto_pin_cfg *cfg)
@ -3459,24 +3535,13 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec,
struct sigmatel_spec *spec = codec->spec; struct sigmatel_spec *spec = codec->spec;
struct hda_input_mux *imux = &spec->private_imux; struct hda_input_mux *imux = &spec->private_imux;
struct hda_input_mux *dimux = &spec->private_dimux; struct hda_input_mux *dimux = &spec->private_dimux;
int err, i, active_mics; int err, i;
unsigned int def_conf; unsigned int def_conf;
dimux->items[dimux->num_items].label = stac92xx_dmic_labels[0]; dimux->items[dimux->num_items].label = stac92xx_dmic_labels[0];
dimux->items[dimux->num_items].index = 0; dimux->items[dimux->num_items].index = 0;
dimux->num_items++; dimux->num_items++;
active_mics = 0;
for (i = 0; i < spec->num_dmics; i++) {
/* check the validity: sometimes it's a dead vendor-spec node */
if (get_wcaps_type(get_wcaps(codec, spec->dmic_nids[i]))
!= AC_WID_PIN)
continue;
def_conf = snd_hda_codec_get_pincfg(codec, spec->dmic_nids[i]);
if (get_defcfg_connect(def_conf) != AC_JACK_PORT_NONE)
active_mics++;
}
for (i = 0; i < spec->num_dmics; i++) { for (i = 0; i < spec->num_dmics; i++) {
hda_nid_t nid; hda_nid_t nid;
int index; int index;
@ -3493,10 +3558,9 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec,
if (index < 0) if (index < 0)
continue; continue;
if (active_mics == 1) label = get_unique_inp_src_label(codec, nid);
label = "Digital Mic"; if (label == NULL)
else return -EINVAL;
label = stac92xx_dmic_labels[dimux->num_items];
err = create_elem_capture_vol(codec, nid, label, 0, HDA_INPUT); err = create_elem_capture_vol(codec, nid, label, 0, HDA_INPUT);
if (err < 0) if (err < 0)
@ -3618,6 +3682,7 @@ static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const
struct sigmatel_spec *spec = codec->spec; struct sigmatel_spec *spec = codec->spec;
struct hda_input_mux *imux = &spec->private_imux; struct hda_input_mux *imux = &spec->private_imux;
int i, j, type_idx = 0; int i, j, type_idx = 0;
const char *label;
for (i = 0; i < cfg->num_inputs; i++) { for (i = 0; i < cfg->num_inputs; i++) {
hda_nid_t nid = cfg->inputs[i].pin; hda_nid_t nid = cfg->inputs[i].pin;
@ -3637,14 +3702,18 @@ static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const
type_idx++; type_idx++;
else else
type_idx = 0; type_idx = 0;
label = get_unique_inp_src_label(codec, nid);
if (label == NULL)
return -EINVAL;
err = create_elem_capture_vol(codec, nid, err = create_elem_capture_vol(codec, nid,
auto_pin_cfg_labels[i], type_idx, label, type_idx,
HDA_INPUT); HDA_INPUT);
if (err < 0) if (err < 0)
return err; return err;
imux->items[imux->num_items].label = imux->items[imux->num_items].label = label;
snd_hda_get_input_pin_label(cfg, i);
imux->items[imux->num_items].index = index; imux->items[imux->num_items].index = index;
imux->num_items++; imux->num_items++;
} }