aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2010-08-30 07:06:15 -0400
committerTakashi Iwai <tiwai@suse.de>2010-08-30 07:06:15 -0400
commiteea7dc932bfa802ad0377755ea821f416f4f8623 (patch)
treea40ea1564ade7398de29a26ea076b489aac5785a /sound
parent66ceeb6bc2809bef0cfa18b1e22ddad5fc9b58b0 (diff)
ALSA: hda - Use new inputs[] field to parse input-pins for STAC/IDT codecs
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r--sound/pci/hda/patch_sigmatel.c183
1 files changed, 96 insertions, 87 deletions
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 95148e58026c..d226edd1e143 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -1180,14 +1180,11 @@ static int stac92xx_build_controls(struct hda_codec *codec)
1180 if (err < 0) 1180 if (err < 0)
1181 return err; 1181 return err;
1182 } 1182 }
1183 for (i = 0; i < AUTO_PIN_LAST; i++) { 1183 for (i = 0; i < cfg->num_inputs; i++) {
1184 nid = cfg->input_pins[i]; 1184 nid = cfg->inputs[i].pin;
1185 if (nid) { 1185 err = stac92xx_add_jack(codec, nid, SND_JACK_MICROPHONE);
1186 err = stac92xx_add_jack(codec, nid, 1186 if (err < 0)
1187 SND_JACK_MICROPHONE); 1187 return err;
1188 if (err < 0)
1189 return err;
1190 }
1191 } 1188 }
1192 1189
1193 return 0; 1190 return 0;
@@ -2821,41 +2818,55 @@ static hda_nid_t check_line_out_switch(struct hda_codec *codec)
2821 struct auto_pin_cfg *cfg = &spec->autocfg; 2818 struct auto_pin_cfg *cfg = &spec->autocfg;
2822 hda_nid_t nid; 2819 hda_nid_t nid;
2823 unsigned int pincap; 2820 unsigned int pincap;
2821 int i;
2824 2822
2825 if (cfg->line_out_type != AUTO_PIN_LINE_OUT) 2823 if (cfg->line_out_type != AUTO_PIN_LINE_OUT)
2826 return 0; 2824 return 0;
2827 nid = cfg->input_pins[AUTO_PIN_LINE]; 2825 for (i = 0; i < cfg->num_inputs; i++) {
2828 pincap = snd_hda_query_pin_caps(codec, nid); 2826 if (cfg->inputs[i].type == AUTO_PIN_LINE) {
2829 if (pincap & AC_PINCAP_OUT) 2827 nid = cfg->inputs[i].pin;
2830 return nid; 2828 pincap = snd_hda_query_pin_caps(codec, nid);
2829 if (pincap & AC_PINCAP_OUT)
2830 return nid;
2831 }
2832 }
2831 return 0; 2833 return 0;
2832} 2834}
2833 2835
2836static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t nid);
2837
2834/* check whether the mic-input can be used as line-out */ 2838/* check whether the mic-input can be used as line-out */
2835static hda_nid_t check_mic_out_switch(struct hda_codec *codec) 2839static hda_nid_t check_mic_out_switch(struct hda_codec *codec, hda_nid_t *dac)
2836{ 2840{
2837 struct sigmatel_spec *spec = codec->spec; 2841 struct sigmatel_spec *spec = codec->spec;
2838 struct auto_pin_cfg *cfg = &spec->autocfg; 2842 struct auto_pin_cfg *cfg = &spec->autocfg;
2839 unsigned int def_conf, pincap; 2843 unsigned int def_conf, pincap;
2840 unsigned int mic_pin; 2844 int i, mic_type;
2841 2845
2846 *dac = 0;
2842 if (cfg->line_out_type != AUTO_PIN_LINE_OUT) 2847 if (cfg->line_out_type != AUTO_PIN_LINE_OUT)
2843 return 0; 2848 return 0;
2844 mic_pin = AUTO_PIN_MIC; 2849 mic_type = AUTO_PIN_MIC;
2845 for (;;) { 2850 again:
2846 hda_nid_t nid = cfg->input_pins[mic_pin]; 2851 for (i = 0; i < cfg->num_inputs; i++) {
2852 hda_nid_t nid = cfg->inputs[i].pin;
2853 if (cfg->inputs[i].type != mic_type)
2854 continue;
2847 def_conf = snd_hda_codec_get_pincfg(codec, nid); 2855 def_conf = snd_hda_codec_get_pincfg(codec, nid);
2848 /* some laptops have an internal analog microphone 2856 /* some laptops have an internal analog microphone
2849 * which can't be used as a output */ 2857 * which can't be used as a output */
2850 if (get_defcfg_connect(def_conf) != AC_JACK_PORT_FIXED) { 2858 if (get_defcfg_connect(def_conf) != AC_JACK_PORT_FIXED) {
2851 pincap = snd_hda_query_pin_caps(codec, nid); 2859 pincap = snd_hda_query_pin_caps(codec, nid);
2852 if (pincap & AC_PINCAP_OUT) 2860 if (pincap & AC_PINCAP_OUT) {
2853 return nid; 2861 *dac = get_unassigned_dac(codec, nid);
2862 if (*dac)
2863 return nid;
2864 }
2854 } 2865 }
2855 if (mic_pin == AUTO_PIN_MIC) 2866 }
2856 mic_pin = AUTO_PIN_FRONT_MIC; 2867 if (mic_type == AUTO_PIN_MIC) {
2857 else 2868 mic_type = AUTO_PIN_FRONT_MIC;
2858 break; 2869 goto again;
2859 } 2870 }
2860 return 0; 2871 return 0;
2861} 2872}
@@ -3002,17 +3013,14 @@ static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec)
3002 } 3013 }
3003 } 3014 }
3004 /* add mic as output */ 3015 /* add mic as output */
3005 nid = check_mic_out_switch(codec); 3016 nid = check_mic_out_switch(codec, &dac);
3006 if (nid) { 3017 if (nid && dac) {
3007 dac = get_unassigned_dac(codec, nid); 3018 snd_printdd("STAC: Add mic-in 0x%x as output %d\n",
3008 if (dac) { 3019 nid, cfg->line_outs);
3009 snd_printdd("STAC: Add mic-in 0x%x as output %d\n", 3020 cfg->line_out_pins[cfg->line_outs] = nid;
3010 nid, cfg->line_outs); 3021 cfg->line_outs++;
3011 cfg->line_out_pins[cfg->line_outs] = nid; 3022 spec->mic_switch = nid;
3012 cfg->line_outs++; 3023 add_spec_dacs(spec, dac);
3013 spec->mic_switch = nid;
3014 add_spec_dacs(spec, dac);
3015 }
3016 } 3024 }
3017 3025
3018 snd_printd("stac92xx: dac_nids=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n", 3026 snd_printd("stac92xx: dac_nids=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n",
@@ -3202,13 +3210,13 @@ static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec,
3202 return err; 3210 return err;
3203 } 3211 }
3204 3212
3205 for (idx = AUTO_PIN_MIC; idx <= AUTO_PIN_FRONT_LINE; idx++) { 3213 for (idx = 0; idx < cfg->num_inputs; idx++) {
3206 nid = cfg->input_pins[idx]; 3214 if (cfg->inputs[idx].type > AUTO_PIN_FRONT_LINE)
3207 if (nid) { 3215 break;
3208 err = stac92xx_add_jack_mode_control(codec, nid, idx); 3216 nid = cfg->inputs[idx].pin;
3209 if (err < 0) 3217 err = stac92xx_add_jack_mode_control(codec, nid, idx);
3210 return err; 3218 if (err < 0)
3211 } 3219 return err;
3212 } 3220 }
3213 3221
3214 return 0; 3222 return 0;
@@ -3415,7 +3423,7 @@ static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
3415/* create a volume assigned to the given pin (only if supported) */ 3423/* create a volume assigned to the given pin (only if supported) */
3416/* return 1 if the volume control is created */ 3424/* return 1 if the volume control is created */
3417static int create_elem_capture_vol(struct hda_codec *codec, hda_nid_t nid, 3425static int create_elem_capture_vol(struct hda_codec *codec, hda_nid_t nid,
3418 const char *label, int direction) 3426 const char *label, int idx, int direction)
3419{ 3427{
3420 unsigned int caps, nums; 3428 unsigned int caps, nums;
3421 char name[32]; 3429 char name[32];
@@ -3432,8 +3440,8 @@ static int create_elem_capture_vol(struct hda_codec *codec, hda_nid_t nid,
3432 if (!nums) 3440 if (!nums)
3433 return 0; 3441 return 0;
3434 snprintf(name, sizeof(name), "%s Capture Volume", label); 3442 snprintf(name, sizeof(name), "%s Capture Volume", label);
3435 err = stac92xx_add_control(codec->spec, STAC_CTL_WIDGET_VOL, name, 3443 err = stac92xx_add_control_idx(codec->spec, STAC_CTL_WIDGET_VOL, idx, name,
3436 HDA_COMPOSE_AMP_VAL(nid, 3, 0, direction)); 3444 HDA_COMPOSE_AMP_VAL(nid, 3, 0, direction));
3437 if (err < 0) 3445 if (err < 0)
3438 return err; 3446 return err;
3439 return 1; 3447 return 1;
@@ -3485,11 +3493,11 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec,
3485 else 3493 else
3486 label = stac92xx_dmic_labels[dimux->num_items]; 3494 label = stac92xx_dmic_labels[dimux->num_items];
3487 3495
3488 err = create_elem_capture_vol(codec, nid, label, HDA_INPUT); 3496 err = create_elem_capture_vol(codec, nid, label, 0, HDA_INPUT);
3489 if (err < 0) 3497 if (err < 0)
3490 return err; 3498 return err;
3491 if (!err) { 3499 if (!err) {
3492 err = create_elem_capture_vol(codec, nid, label, 3500 err = create_elem_capture_vol(codec, nid, label, 0,
3493 HDA_OUTPUT); 3501 HDA_OUTPUT);
3494 if (err < 0) 3502 if (err < 0)
3495 return err; 3503 return err;
@@ -3540,10 +3548,11 @@ static int set_mic_route(struct hda_codec *codec,
3540 int i; 3548 int i;
3541 3549
3542 mic->pin = pin; 3550 mic->pin = pin;
3543 for (i = AUTO_PIN_MIC; i <= AUTO_PIN_FRONT_MIC; i++) 3551 for (i = 0; i < cfg->num_inputs; i++) {
3544 if (pin == cfg->input_pins[i]) 3552 if (pin == cfg->inputs[i].pin)
3545 break; 3553 break;
3546 if (i <= AUTO_PIN_FRONT_MIC) { 3554 }
3555 if (i < cfg->num_inputs && cfg->inputs[i].type <= AUTO_PIN_FRONT_MIC) {
3547 /* analog pin */ 3556 /* analog pin */
3548 i = get_connection_index(codec, spec->mux_nids[0], pin); 3557 i = get_connection_index(codec, spec->mux_nids[0], pin);
3549 if (i < 0) 3558 if (i < 0)
@@ -3577,13 +3586,13 @@ static int stac_check_auto_mic(struct hda_codec *codec)
3577 hda_nid_t fixed, ext; 3586 hda_nid_t fixed, ext;
3578 int i; 3587 int i;
3579 3588
3580 for (i = AUTO_PIN_LINE; i < AUTO_PIN_LAST; i++) { 3589 for (i = 0; i < cfg->num_inputs; i++) {
3581 if (cfg->input_pins[i]) 3590 if (cfg->inputs[i].type >= AUTO_PIN_LINE)
3582 return 0; /* must be exclusively mics */ 3591 return 0; /* must be exclusively mics */
3583 } 3592 }
3584 fixed = ext = 0; 3593 fixed = ext = 0;
3585 for (i = AUTO_PIN_MIC; i <= AUTO_PIN_FRONT_MIC; i++) 3594 for (i = 0; i < cfg->num_inputs; i++)
3586 if (check_mic_pin(codec, cfg->input_pins[i], &fixed, &ext)) 3595 if (check_mic_pin(codec, cfg->inputs[i].pin, &fixed, &ext))
3587 return 0; 3596 return 0;
3588 for (i = 0; i < spec->num_dmics; i++) 3597 for (i = 0; i < spec->num_dmics; i++)
3589 if (check_mic_pin(codec, spec->dmic_nids[i], &fixed, &ext)) 3598 if (check_mic_pin(codec, spec->dmic_nids[i], &fixed, &ext))
@@ -3603,14 +3612,12 @@ static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const
3603{ 3612{
3604 struct sigmatel_spec *spec = codec->spec; 3613 struct sigmatel_spec *spec = codec->spec;
3605 struct hda_input_mux *imux = &spec->private_imux; 3614 struct hda_input_mux *imux = &spec->private_imux;
3606 int i, j; 3615 int i, j, type_idx = 0;
3607 3616
3608 for (i = 0; i < AUTO_PIN_LAST; i++) { 3617 for (i = 0; i < cfg->num_inputs; i++) {
3609 hda_nid_t nid = cfg->input_pins[i]; 3618 hda_nid_t nid = cfg->inputs[i].pin;
3610 int index, err; 3619 int index, err;
3611 3620
3612 if (!nid)
3613 continue;
3614 index = -1; 3621 index = -1;
3615 for (j = 0; j < spec->num_muxes; j++) { 3622 for (j = 0; j < spec->num_muxes; j++) {
3616 index = get_connection_index(codec, spec->mux_nids[j], 3623 index = get_connection_index(codec, spec->mux_nids[j],
@@ -3621,13 +3628,18 @@ static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const
3621 if (index < 0) 3628 if (index < 0)
3622 continue; 3629 continue;
3623 3630
3631 if (i > 0 && cfg->inputs[i].type == cfg->inputs[i - 1].type)
3632 type_idx++;
3633 else
3634 type_idx = 0;
3624 err = create_elem_capture_vol(codec, nid, 3635 err = create_elem_capture_vol(codec, nid,
3625 auto_pin_cfg_labels[i], 3636 auto_pin_cfg_labels[i], type_idx,
3626 HDA_INPUT); 3637 HDA_INPUT);
3627 if (err < 0) 3638 if (err < 0)
3628 return err; 3639 return err;
3629 3640
3630 imux->items[imux->num_items].label = auto_pin_cfg_labels[i]; 3641 imux->items[imux->num_items].label =
3642 snd_hda_get_input_pin_label(cfg, i);
3631 imux->items[imux->num_items].index = index; 3643 imux->items[imux->num_items].index = index;
3632 imux->num_items++; 3644 imux->num_items++;
3633 } 3645 }
@@ -4304,37 +4316,34 @@ static int stac92xx_init(struct hda_codec *codec)
4304 if (enable_pin_detect(codec, spec->ext_mic.pin, STAC_MIC_EVENT)) 4316 if (enable_pin_detect(codec, spec->ext_mic.pin, STAC_MIC_EVENT))
4305 stac_issue_unsol_event(codec, spec->ext_mic.pin); 4317 stac_issue_unsol_event(codec, spec->ext_mic.pin);
4306 } 4318 }
4307 for (i = 0; i < AUTO_PIN_LAST; i++) { 4319 for (i = 0; i < cfg->num_inputs; i++) {
4308 hda_nid_t nid = cfg->input_pins[i]; 4320 hda_nid_t nid = cfg->inputs[i].pin;
4309 if (nid) { 4321 int type = cfg->inputs[i].type;
4310 unsigned int pinctl, conf; 4322 unsigned int pinctl, conf;
4311 if (i == AUTO_PIN_MIC || i == AUTO_PIN_FRONT_MIC) { 4323 if (type == AUTO_PIN_MIC || type == AUTO_PIN_FRONT_MIC) {
4312 /* for mic pins, force to initialize */ 4324 /* for mic pins, force to initialize */
4313 pinctl = stac92xx_get_default_vref(codec, nid); 4325 pinctl = stac92xx_get_default_vref(codec, nid);
4326 pinctl |= AC_PINCTL_IN_EN;
4327 stac92xx_auto_set_pinctl(codec, nid, pinctl);
4328 } else {
4329 pinctl = snd_hda_codec_read(codec, nid, 0,
4330 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4331 /* if PINCTL already set then skip */
4332 /* Also, if both INPUT and OUTPUT are set,
4333 * it must be a BIOS bug; need to override, too
4334 */
4335 if (!(pinctl & AC_PINCTL_IN_EN) ||
4336 (pinctl & AC_PINCTL_OUT_EN)) {
4337 pinctl &= ~AC_PINCTL_OUT_EN;
4314 pinctl |= AC_PINCTL_IN_EN; 4338 pinctl |= AC_PINCTL_IN_EN;
4315 stac92xx_auto_set_pinctl(codec, nid, pinctl); 4339 stac92xx_auto_set_pinctl(codec, nid, pinctl);
4316 } else {
4317 pinctl = snd_hda_codec_read(codec, nid, 0,
4318 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4319 /* if PINCTL already set then skip */
4320 /* Also, if both INPUT and OUTPUT are set,
4321 * it must be a BIOS bug; need to override, too
4322 */
4323 if (!(pinctl & AC_PINCTL_IN_EN) ||
4324 (pinctl & AC_PINCTL_OUT_EN)) {
4325 pinctl &= ~AC_PINCTL_OUT_EN;
4326 pinctl |= AC_PINCTL_IN_EN;
4327 stac92xx_auto_set_pinctl(codec, nid,
4328 pinctl);
4329 }
4330 }
4331 conf = snd_hda_codec_get_pincfg(codec, nid);
4332 if (get_defcfg_connect(conf) != AC_JACK_PORT_FIXED) {
4333 if (enable_pin_detect(codec, nid,
4334 STAC_INSERT_EVENT))
4335 stac_issue_unsol_event(codec, nid);
4336 } 4340 }
4337 } 4341 }
4342 conf = snd_hda_codec_get_pincfg(codec, nid);
4343 if (get_defcfg_connect(conf) != AC_JACK_PORT_FIXED) {
4344 if (enable_pin_detect(codec, nid, STAC_INSERT_EVENT))
4345 stac_issue_unsol_event(codec, nid);
4346 }
4338 } 4347 }
4339 for (i = 0; i < spec->num_dmics; i++) 4348 for (i = 0; i < spec->num_dmics; i++)
4340 stac92xx_auto_set_pinctl(codec, spec->dmic_nids[i], 4349 stac92xx_auto_set_pinctl(codec, spec->dmic_nids[i],