aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorVitaliy Kulikov <Vitaliy.Kulikov@idt.com>2010-09-08 02:56:03 -0400
committerTakashi Iwai <tiwai@suse.de>2010-09-08 03:01:28 -0400
commit263d0328c46995d8e4fb478005177839104483d2 (patch)
tree0c362fdf9225b2fe2dd7be6975dd1411ebb7babb /sound
parentab5a6ebee38f3ed311f0565ecd3fba5cf111564a (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.c107
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
194struct unique_input_names {
195 int num;
196 char uname[HDA_MAX_NUM_INPUTS][32];
197};
198
194struct sigmatel_spec { 199struct 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
312static hda_nid_t stac9200_adc_nids[1] = { 318static 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
3461static 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
3498static 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 */
3456static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec, 3532static 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 }