diff options
author | Takashi Iwai <tiwai@suse.de> | 2009-08-11 03:47:30 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2009-08-11 03:47:30 -0400 |
commit | b59bdf3b0ca11bfc6a539012431d751deaa65b32 (patch) | |
tree | dfaa6317d64d5f0acfa5ae3afed1614d27ec1bb3 /sound/pci/hda/patch_realtek.c | |
parent | 52b5deefbbd7493092b1cbc35da09e0e2ad46cca (diff) |
ALSA: hda - Check connectivity for auto-mic of Realtek codecs
Some Realtek codecs don't provide the full connections for certain pins
from each ADC; e.g. ACL662/ALC272 gives only one of two digital-mic pins
for each ADC. Thus, depending on the digital mic pin, the ADC/MUX to be
used has to be chosen properly.
This patch adds the check of the connectivity of pins at auto-mic mode.
If no proper connectivity is found, auto_mic flag is turned off to be
sure.
Also the mux_idx is determined during this check so it won't be checked
in the unsol event any more.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda/patch_realtek.c')
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 83 |
1 files changed, 51 insertions, 32 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 2c348e1339d8..5156c4f14f80 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -987,16 +987,6 @@ static int get_connection_index(struct hda_codec *codec, hda_nid_t mux, | |||
987 | return -1; | 987 | return -1; |
988 | } | 988 | } |
989 | 989 | ||
990 | static int set_mic_mux_idx(struct hda_codec *codec, hda_nid_t cap, | ||
991 | struct alc_mic_route *mic) | ||
992 | { | ||
993 | int idx = get_connection_index(codec, cap, mic->pin); | ||
994 | if (idx < 0) | ||
995 | return 1; /* invalid */ | ||
996 | mic->mux_idx = idx; | ||
997 | return 0; | ||
998 | } | ||
999 | |||
1000 | static void alc_mic_automute(struct hda_codec *codec) | 990 | static void alc_mic_automute(struct hda_codec *codec) |
1001 | { | 991 | { |
1002 | struct alc_spec *spec = codec->spec; | 992 | struct alc_spec *spec = codec->spec; |
@@ -1004,6 +994,8 @@ static void alc_mic_automute(struct hda_codec *codec) | |||
1004 | unsigned int present, type; | 994 | unsigned int present, type; |
1005 | hda_nid_t cap_nid; | 995 | hda_nid_t cap_nid; |
1006 | 996 | ||
997 | if (!spec->auto_mic) | ||
998 | return; | ||
1007 | if (!spec->int_mic.pin || !spec->ext_mic.pin) | 999 | if (!spec->int_mic.pin || !spec->ext_mic.pin) |
1008 | return; | 1000 | return; |
1009 | if (snd_BUG_ON(!spec->adc_nids)) | 1001 | if (snd_BUG_ON(!spec->adc_nids)) |
@@ -1022,13 +1014,6 @@ static void alc_mic_automute(struct hda_codec *codec) | |||
1022 | dead = &spec->ext_mic; | 1014 | dead = &spec->ext_mic; |
1023 | } | 1015 | } |
1024 | 1016 | ||
1025 | if (alive->mux_idx == MUX_IDX_UNDEF && | ||
1026 | set_mic_mux_idx(codec, cap_nid, alive)) | ||
1027 | return; | ||
1028 | if (dead->mux_idx == MUX_IDX_UNDEF && | ||
1029 | set_mic_mux_idx(codec, cap_nid, dead)) | ||
1030 | return; | ||
1031 | |||
1032 | type = get_wcaps_type(get_wcaps(codec, cap_nid)); | 1017 | type = get_wcaps_type(get_wcaps(codec, cap_nid)); |
1033 | if (type == AC_WID_AUD_MIX) { | 1018 | if (type == AC_WID_AUD_MIX) { |
1034 | /* Matrix-mixer style (e.g. ALC882) */ | 1019 | /* Matrix-mixer style (e.g. ALC882) */ |
@@ -4671,8 +4656,42 @@ static void alc880_auto_init(struct hda_codec *codec) | |||
4671 | alc_inithook(codec); | 4656 | alc_inithook(codec); |
4672 | } | 4657 | } |
4673 | 4658 | ||
4674 | static void set_capture_mixer(struct alc_spec *spec) | 4659 | /* check the ADC/MUX contains all input pins; some ADC/MUX contains only |
4660 | * one of two digital mic pins, e.g. on ALC272 | ||
4661 | */ | ||
4662 | static void fixup_automic_adc(struct hda_codec *codec) | ||
4663 | { | ||
4664 | struct alc_spec *spec = codec->spec; | ||
4665 | int i; | ||
4666 | |||
4667 | for (i = 0; i < spec->num_adc_nids; i++) { | ||
4668 | hda_nid_t cap = spec->capsrc_nids ? | ||
4669 | spec->capsrc_nids[i] : spec->adc_nids[i]; | ||
4670 | int iidx, eidx; | ||
4671 | |||
4672 | iidx = get_connection_index(codec, cap, spec->int_mic.pin); | ||
4673 | if (iidx < 0) | ||
4674 | continue; | ||
4675 | eidx = get_connection_index(codec, cap, spec->ext_mic.pin); | ||
4676 | if (eidx < 0) | ||
4677 | continue; | ||
4678 | spec->int_mic.mux_idx = iidx; | ||
4679 | spec->ext_mic.mux_idx = eidx; | ||
4680 | if (spec->capsrc_nids) | ||
4681 | spec->capsrc_nids += i; | ||
4682 | spec->adc_nids += i; | ||
4683 | spec->num_adc_nids = 1; | ||
4684 | return; | ||
4685 | } | ||
4686 | snd_printd(KERN_INFO "hda_codec: %s: " | ||
4687 | "No ADC/MUX containing both 0x%x and 0x%x pins\n", | ||
4688 | codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin); | ||
4689 | spec->auto_mic = 0; /* disable auto-mic to be sure */ | ||
4690 | } | ||
4691 | |||
4692 | static void set_capture_mixer(struct hda_codec *codec) | ||
4675 | { | 4693 | { |
4694 | struct alc_spec *spec = codec->spec; | ||
4676 | static struct snd_kcontrol_new *caps[2][3] = { | 4695 | static struct snd_kcontrol_new *caps[2][3] = { |
4677 | { alc_capture_mixer_nosrc1, | 4696 | { alc_capture_mixer_nosrc1, |
4678 | alc_capture_mixer_nosrc2, | 4697 | alc_capture_mixer_nosrc2, |
@@ -4685,7 +4704,7 @@ static void set_capture_mixer(struct alc_spec *spec) | |||
4685 | int mux; | 4704 | int mux; |
4686 | if (spec->auto_mic) { | 4705 | if (spec->auto_mic) { |
4687 | mux = 0; | 4706 | mux = 0; |
4688 | spec->num_adc_nids = 1; /* support only one ADC */ | 4707 | fixup_automic_adc(codec); |
4689 | } else if (spec->input_mux && spec->input_mux->num_items > 1) | 4708 | } else if (spec->input_mux && spec->input_mux->num_items > 1) |
4690 | mux = 1; | 4709 | mux = 1; |
4691 | else | 4710 | else |
@@ -4765,7 +4784,7 @@ static int patch_alc880(struct hda_codec *codec) | |||
4765 | spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids); | 4784 | spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids); |
4766 | } | 4785 | } |
4767 | } | 4786 | } |
4768 | set_capture_mixer(spec); | 4787 | set_capture_mixer(codec); |
4769 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); | 4788 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); |
4770 | 4789 | ||
4771 | spec->vmaster_nid = 0x0c; | 4790 | spec->vmaster_nid = 0x0c; |
@@ -6408,7 +6427,7 @@ static int patch_alc260(struct hda_codec *codec) | |||
6408 | spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids); | 6427 | spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids); |
6409 | } | 6428 | } |
6410 | } | 6429 | } |
6411 | set_capture_mixer(spec); | 6430 | set_capture_mixer(codec); |
6412 | set_beep_amp(spec, 0x07, 0x05, HDA_INPUT); | 6431 | set_beep_amp(spec, 0x07, 0x05, HDA_INPUT); |
6413 | 6432 | ||
6414 | spec->vmaster_nid = 0x08; | 6433 | spec->vmaster_nid = 0x08; |
@@ -9737,7 +9756,7 @@ static int patch_alc882(struct hda_codec *codec) | |||
9737 | spec->capsrc_nids = spec->private_capsrc_nids; | 9756 | spec->capsrc_nids = spec->private_capsrc_nids; |
9738 | } | 9757 | } |
9739 | 9758 | ||
9740 | set_capture_mixer(spec); | 9759 | set_capture_mixer(codec); |
9741 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); | 9760 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); |
9742 | 9761 | ||
9743 | spec->vmaster_nid = 0x0c; | 9762 | spec->vmaster_nid = 0x0c; |
@@ -11616,7 +11635,7 @@ static int patch_alc262(struct hda_codec *codec) | |||
11616 | } | 11635 | } |
11617 | } | 11636 | } |
11618 | if (!spec->cap_mixer && !spec->no_analog) | 11637 | if (!spec->cap_mixer && !spec->no_analog) |
11619 | set_capture_mixer(spec); | 11638 | set_capture_mixer(codec); |
11620 | if (!spec->no_analog) | 11639 | if (!spec->no_analog) |
11621 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); | 11640 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); |
11622 | 11641 | ||
@@ -13285,7 +13304,7 @@ static int alc269_parse_auto_config(struct hda_codec *codec) | |||
13285 | return err; | 13304 | return err; |
13286 | 13305 | ||
13287 | if (!spec->cap_mixer && !spec->no_analog) | 13306 | if (!spec->cap_mixer && !spec->no_analog) |
13288 | set_capture_mixer(spec); | 13307 | set_capture_mixer(codec); |
13289 | 13308 | ||
13290 | alc_ssid_check(codec, 0x15, 0x1b, 0x14); | 13309 | alc_ssid_check(codec, 0x15, 0x1b, 0x14); |
13291 | 13310 | ||
@@ -13483,7 +13502,7 @@ static int patch_alc269(struct hda_codec *codec) | |||
13483 | spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids); | 13502 | spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids); |
13484 | spec->capsrc_nids = alc269_capsrc_nids; | 13503 | spec->capsrc_nids = alc269_capsrc_nids; |
13485 | if (!spec->cap_mixer) | 13504 | if (!spec->cap_mixer) |
13486 | set_capture_mixer(spec); | 13505 | set_capture_mixer(codec); |
13487 | set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); | 13506 | set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); |
13488 | 13507 | ||
13489 | spec->vmaster_nid = 0x02; | 13508 | spec->vmaster_nid = 0x02; |
@@ -14398,7 +14417,7 @@ static int alc861_parse_auto_config(struct hda_codec *codec) | |||
14398 | 14417 | ||
14399 | spec->adc_nids = alc861_adc_nids; | 14418 | spec->adc_nids = alc861_adc_nids; |
14400 | spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids); | 14419 | spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids); |
14401 | set_capture_mixer(spec); | 14420 | set_capture_mixer(codec); |
14402 | 14421 | ||
14403 | alc_ssid_check(codec, 0x0e, 0x0f, 0x0b); | 14422 | alc_ssid_check(codec, 0x0e, 0x0f, 0x0b); |
14404 | 14423 | ||
@@ -15561,7 +15580,7 @@ static int patch_alc861vd(struct hda_codec *codec) | |||
15561 | if (!spec->capsrc_nids) | 15580 | if (!spec->capsrc_nids) |
15562 | spec->capsrc_nids = alc861vd_capsrc_nids; | 15581 | spec->capsrc_nids = alc861vd_capsrc_nids; |
15563 | 15582 | ||
15564 | set_capture_mixer(spec); | 15583 | set_capture_mixer(codec); |
15565 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); | 15584 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); |
15566 | 15585 | ||
15567 | spec->vmaster_nid = 0x02; | 15586 | spec->vmaster_nid = 0x02; |
@@ -15602,9 +15621,9 @@ static hda_nid_t alc272_dac_nids[2] = { | |||
15602 | 0x02, 0x03 | 15621 | 0x02, 0x03 |
15603 | }; | 15622 | }; |
15604 | 15623 | ||
15605 | static hda_nid_t alc662_adc_nids[1] = { | 15624 | static hda_nid_t alc662_adc_nids[2] = { |
15606 | /* ADC1-2 */ | 15625 | /* ADC1-2 */ |
15607 | 0x09, | 15626 | 0x09, 0x08 |
15608 | }; | 15627 | }; |
15609 | 15628 | ||
15610 | static hda_nid_t alc272_adc_nids[1] = { | 15629 | static hda_nid_t alc272_adc_nids[1] = { |
@@ -15612,7 +15631,7 @@ static hda_nid_t alc272_adc_nids[1] = { | |||
15612 | 0x08, | 15631 | 0x08, |
15613 | }; | 15632 | }; |
15614 | 15633 | ||
15615 | static hda_nid_t alc662_capsrc_nids[1] = { 0x22 }; | 15634 | static hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 }; |
15616 | static hda_nid_t alc272_capsrc_nids[1] = { 0x23 }; | 15635 | static hda_nid_t alc272_capsrc_nids[1] = { 0x23 }; |
15617 | 15636 | ||
15618 | 15637 | ||
@@ -17099,7 +17118,7 @@ static struct alc_config_preset alc662_presets[] = { | |||
17099 | .dac_nids = alc662_dac_nids, | 17118 | .dac_nids = alc662_dac_nids, |
17100 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | 17119 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), |
17101 | .adc_nids = alc662_adc_nids, | 17120 | .adc_nids = alc662_adc_nids, |
17102 | .num_adc_nids = ARRAY_SIZE(alc662_adc_nids), | 17121 | .num_adc_nids = 1, |
17103 | .capsrc_nids = alc662_capsrc_nids, | 17122 | .capsrc_nids = alc662_capsrc_nids, |
17104 | .channel_mode = alc662_3ST_2ch_modes, | 17123 | .channel_mode = alc662_3ST_2ch_modes, |
17105 | .input_mux = &alc663_m51va_capture_source, | 17124 | .input_mux = &alc663_m51va_capture_source, |
@@ -17465,7 +17484,7 @@ static int patch_alc662(struct hda_codec *codec) | |||
17465 | spec->capsrc_nids = alc662_capsrc_nids; | 17484 | spec->capsrc_nids = alc662_capsrc_nids; |
17466 | 17485 | ||
17467 | if (!spec->cap_mixer) | 17486 | if (!spec->cap_mixer) |
17468 | set_capture_mixer(spec); | 17487 | set_capture_mixer(codec); |
17469 | if (codec->vendor_id == 0x10ec0662) | 17488 | if (codec->vendor_id == 0x10ec0662) |
17470 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); | 17489 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); |
17471 | else | 17490 | else |