diff options
author | Takashi Iwai <tiwai@suse.de> | 2010-08-30 07:06:15 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2010-08-30 07:06:15 -0400 |
commit | eea7dc932bfa802ad0377755ea821f416f4f8623 (patch) | |
tree | a40ea1564ade7398de29a26ea076b489aac5785a /sound | |
parent | 66ceeb6bc2809bef0cfa18b1e22ddad5fc9b58b0 (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.c | 183 |
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 | ||
2836 | static 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 */ |
2835 | static hda_nid_t check_mic_out_switch(struct hda_codec *codec) | 2839 | static 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 */ |
3417 | static int create_elem_capture_vol(struct hda_codec *codec, hda_nid_t nid, | 3425 | static 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], |