diff options
author | Vitaliy Kulikov <Vitaliy.Kulikov@idt.com> | 2010-09-08 02:56:03 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2010-09-08 03:01:28 -0400 |
commit | 263d0328c46995d8e4fb478005177839104483d2 (patch) | |
tree | 0c362fdf9225b2fe2dd7be6975dd1411ebb7babb /sound | |
parent | ab5a6ebee38f3ed311f0565ecd3fba5cf111564a (diff) |
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>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 107 |
1 files changed, 88 insertions, 19 deletions
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 82d1e4378621..7f09e140953e 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -191,6 +191,11 @@ struct sigmatel_mic_route { | |||
191 | signed char dmux_idx; | 191 | signed char dmux_idx; |
192 | }; | 192 | }; |
193 | 193 | ||
194 | struct unique_input_names { | ||
195 | int num; | ||
196 | char uname[HDA_MAX_NUM_INPUTS][32]; | ||
197 | }; | ||
198 | |||
194 | struct sigmatel_spec { | 199 | struct sigmatel_spec { |
195 | struct snd_kcontrol_new *mixers[4]; | 200 | struct snd_kcontrol_new *mixers[4]; |
196 | unsigned int num_mixers; | 201 | unsigned int num_mixers; |
@@ -307,6 +312,7 @@ struct sigmatel_spec { | |||
307 | struct hda_input_mux private_imux; | 312 | struct hda_input_mux private_imux; |
308 | struct hda_input_mux private_smux; | 313 | struct hda_input_mux private_smux; |
309 | struct hda_input_mux private_mono_mux; | 314 | struct hda_input_mux private_mono_mux; |
315 | struct unique_input_names private_u_inp_names; | ||
310 | }; | 316 | }; |
311 | 317 | ||
312 | static hda_nid_t stac9200_adc_nids[1] = { | 318 | 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, | |||
3452 | return 1; | 3458 | return 1; |
3453 | } | 3459 | } |
3454 | 3460 | ||
3461 | static const char *get_input_src_label(struct hda_codec *codec, hda_nid_t nid) | ||
3462 | { | ||
3463 | unsigned int def_conf; | ||
3464 | |||
3465 | def_conf = snd_hda_codec_get_pincfg(codec, nid); | ||
3466 | |||
3467 | switch (get_defcfg_device(def_conf)) { | ||
3468 | case AC_JACK_MIC_IN: | ||
3469 | if (get_defcfg_connect(def_conf) == AC_JACK_PORT_FIXED || | ||
3470 | ((get_defcfg_location(def_conf) & 0xf0) | ||
3471 | == AC_JACK_LOC_INTERNAL)) | ||
3472 | return "Internal Mic"; | ||
3473 | if ((get_defcfg_location(def_conf) & 0xf0) | ||
3474 | == AC_JACK_LOC_SEPARATE) | ||
3475 | return "Dock Mic"; | ||
3476 | if (get_defcfg_location(def_conf) == AC_JACK_LOC_REAR) | ||
3477 | return "Rear Mic"; | ||
3478 | return "Mic"; | ||
3479 | case AC_JACK_LINE_IN: | ||
3480 | if ((get_defcfg_location(def_conf) & 0xf0) | ||
3481 | == AC_JACK_LOC_SEPARATE) | ||
3482 | return "Dock Line"; | ||
3483 | return "Line"; | ||
3484 | case AC_JACK_AUX: | ||
3485 | return "Aux"; | ||
3486 | case AC_JACK_CD: | ||
3487 | return "CD"; | ||
3488 | case AC_JACK_SPDIF_IN: | ||
3489 | return "SPDIF In"; | ||
3490 | case AC_JACK_DIG_OTHER_IN: | ||
3491 | return "Digital In"; | ||
3492 | } | ||
3493 | |||
3494 | snd_printd("invalid inp pin %02x device config %08x", nid, def_conf); | ||
3495 | return NULL; | ||
3496 | } | ||
3497 | |||
3498 | static const char *get_unique_inp_src_label(struct hda_codec *codec, | ||
3499 | hda_nid_t nid) | ||
3500 | { | ||
3501 | int i, n; | ||
3502 | const char *label; | ||
3503 | struct sigmatel_spec *spec = codec->spec; | ||
3504 | struct hda_input_mux *imux = &spec->private_imux; | ||
3505 | struct hda_input_mux *dimux = &spec->private_dimux; | ||
3506 | struct unique_input_names *unames = &spec->private_u_inp_names; | ||
3507 | |||
3508 | label = get_input_src_label(codec, nid); | ||
3509 | n = 0; | ||
3510 | |||
3511 | for (i = 0; i < imux->num_items; i++) { | ||
3512 | if (!strncmp(label, imux->items[i].label, strlen(label))) | ||
3513 | n++; | ||
3514 | } | ||
3515 | if (snd_hda_get_bool_hint(codec, "separate_dmux") == 1) { | ||
3516 | for (i = 0; i < dimux->num_items; i++) { | ||
3517 | if (!strncmp(label, dimux->items[i].label, | ||
3518 | strlen(label))) | ||
3519 | n++; | ||
3520 | } | ||
3521 | } | ||
3522 | if (n > 0 && unames->num < HDA_MAX_NUM_INPUTS) { | ||
3523 | sprintf(&unames->uname[unames->num][0], "%.28s %d", label, n); | ||
3524 | label = &unames->uname[unames->num][0]; | ||
3525 | unames->num++; | ||
3526 | } | ||
3527 | |||
3528 | return label; | ||
3529 | } | ||
3530 | |||
3455 | /* create playback/capture controls for input pins on dmic capable codecs */ | 3531 | /* create playback/capture controls for input pins on dmic capable codecs */ |
3456 | static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec, | 3532 | static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec, |
3457 | const struct auto_pin_cfg *cfg) | 3533 | const struct auto_pin_cfg *cfg) |
@@ -3459,24 +3535,13 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec, | |||
3459 | struct sigmatel_spec *spec = codec->spec; | 3535 | struct sigmatel_spec *spec = codec->spec; |
3460 | struct hda_input_mux *imux = &spec->private_imux; | 3536 | struct hda_input_mux *imux = &spec->private_imux; |
3461 | struct hda_input_mux *dimux = &spec->private_dimux; | 3537 | struct hda_input_mux *dimux = &spec->private_dimux; |
3462 | int err, i, active_mics; | 3538 | int err, i; |
3463 | unsigned int def_conf; | 3539 | unsigned int def_conf; |
3464 | 3540 | ||
3465 | dimux->items[dimux->num_items].label = stac92xx_dmic_labels[0]; | 3541 | dimux->items[dimux->num_items].label = stac92xx_dmic_labels[0]; |
3466 | dimux->items[dimux->num_items].index = 0; | 3542 | dimux->items[dimux->num_items].index = 0; |
3467 | dimux->num_items++; | 3543 | dimux->num_items++; |
3468 | 3544 | ||
3469 | active_mics = 0; | ||
3470 | for (i = 0; i < spec->num_dmics; i++) { | ||
3471 | /* check the validity: sometimes it's a dead vendor-spec node */ | ||
3472 | if (get_wcaps_type(get_wcaps(codec, spec->dmic_nids[i])) | ||
3473 | != AC_WID_PIN) | ||
3474 | continue; | ||
3475 | def_conf = snd_hda_codec_get_pincfg(codec, spec->dmic_nids[i]); | ||
3476 | if (get_defcfg_connect(def_conf) != AC_JACK_PORT_NONE) | ||
3477 | active_mics++; | ||
3478 | } | ||
3479 | |||
3480 | for (i = 0; i < spec->num_dmics; i++) { | 3545 | for (i = 0; i < spec->num_dmics; i++) { |
3481 | hda_nid_t nid; | 3546 | hda_nid_t nid; |
3482 | int index; | 3547 | int index; |
@@ -3493,10 +3558,9 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec, | |||
3493 | if (index < 0) | 3558 | if (index < 0) |
3494 | continue; | 3559 | continue; |
3495 | 3560 | ||
3496 | if (active_mics == 1) | 3561 | label = get_unique_inp_src_label(codec, nid); |
3497 | label = "Digital Mic"; | 3562 | if (label == NULL) |
3498 | else | 3563 | return -EINVAL; |
3499 | label = stac92xx_dmic_labels[dimux->num_items]; | ||
3500 | 3564 | ||
3501 | err = create_elem_capture_vol(codec, nid, label, 0, HDA_INPUT); | 3565 | err = create_elem_capture_vol(codec, nid, label, 0, HDA_INPUT); |
3502 | if (err < 0) | 3566 | if (err < 0) |
@@ -3618,6 +3682,7 @@ static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const | |||
3618 | struct sigmatel_spec *spec = codec->spec; | 3682 | struct sigmatel_spec *spec = codec->spec; |
3619 | struct hda_input_mux *imux = &spec->private_imux; | 3683 | struct hda_input_mux *imux = &spec->private_imux; |
3620 | int i, j, type_idx = 0; | 3684 | int i, j, type_idx = 0; |
3685 | const char *label; | ||
3621 | 3686 | ||
3622 | for (i = 0; i < cfg->num_inputs; i++) { | 3687 | for (i = 0; i < cfg->num_inputs; i++) { |
3623 | hda_nid_t nid = cfg->inputs[i].pin; | 3688 | 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 | |||
3637 | type_idx++; | 3702 | type_idx++; |
3638 | else | 3703 | else |
3639 | type_idx = 0; | 3704 | type_idx = 0; |
3705 | |||
3706 | label = get_unique_inp_src_label(codec, nid); | ||
3707 | if (label == NULL) | ||
3708 | return -EINVAL; | ||
3709 | |||
3640 | err = create_elem_capture_vol(codec, nid, | 3710 | err = create_elem_capture_vol(codec, nid, |
3641 | auto_pin_cfg_labels[i], type_idx, | 3711 | label, type_idx, |
3642 | HDA_INPUT); | 3712 | HDA_INPUT); |
3643 | if (err < 0) | 3713 | if (err < 0) |
3644 | return err; | 3714 | return err; |
3645 | 3715 | ||
3646 | imux->items[imux->num_items].label = | 3716 | imux->items[imux->num_items].label = label; |
3647 | snd_hda_get_input_pin_label(cfg, i); | ||
3648 | imux->items[imux->num_items].index = index; | 3717 | imux->items[imux->num_items].index = index; |
3649 | imux->num_items++; | 3718 | imux->num_items++; |
3650 | } | 3719 | } |