diff options
Diffstat (limited to 'sound/pci/hda/patch_realtek.c')
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 133 |
1 files changed, 106 insertions, 27 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index c7465053d6bb..da34095c707f 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -1093,6 +1093,16 @@ static void alc889_coef_init(struct hda_codec *codec) | |||
1093 | snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010); | 1093 | snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010); |
1094 | } | 1094 | } |
1095 | 1095 | ||
1096 | /* turn on/off EAPD control (only if available) */ | ||
1097 | static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on) | ||
1098 | { | ||
1099 | if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN) | ||
1100 | return; | ||
1101 | if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD) | ||
1102 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE, | ||
1103 | on ? 2 : 0); | ||
1104 | } | ||
1105 | |||
1096 | static void alc_auto_init_amp(struct hda_codec *codec, int type) | 1106 | static void alc_auto_init_amp(struct hda_codec *codec, int type) |
1097 | { | 1107 | { |
1098 | unsigned int tmp; | 1108 | unsigned int tmp; |
@@ -1110,25 +1120,22 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type) | |||
1110 | case ALC_INIT_DEFAULT: | 1120 | case ALC_INIT_DEFAULT: |
1111 | switch (codec->vendor_id) { | 1121 | switch (codec->vendor_id) { |
1112 | case 0x10ec0260: | 1122 | case 0x10ec0260: |
1113 | snd_hda_codec_write(codec, 0x0f, 0, | 1123 | set_eapd(codec, 0x0f, 1); |
1114 | AC_VERB_SET_EAPD_BTLENABLE, 2); | 1124 | set_eapd(codec, 0x10, 1); |
1115 | snd_hda_codec_write(codec, 0x10, 0, | ||
1116 | AC_VERB_SET_EAPD_BTLENABLE, 2); | ||
1117 | break; | 1125 | break; |
1118 | case 0x10ec0262: | 1126 | case 0x10ec0262: |
1119 | case 0x10ec0267: | 1127 | case 0x10ec0267: |
1120 | case 0x10ec0268: | 1128 | case 0x10ec0268: |
1121 | case 0x10ec0269: | 1129 | case 0x10ec0269: |
1130 | case 0x10ec0270: | ||
1122 | case 0x10ec0272: | 1131 | case 0x10ec0272: |
1123 | case 0x10ec0660: | 1132 | case 0x10ec0660: |
1124 | case 0x10ec0662: | 1133 | case 0x10ec0662: |
1125 | case 0x10ec0663: | 1134 | case 0x10ec0663: |
1126 | case 0x10ec0862: | 1135 | case 0x10ec0862: |
1127 | case 0x10ec0889: | 1136 | case 0x10ec0889: |
1128 | snd_hda_codec_write(codec, 0x14, 0, | 1137 | set_eapd(codec, 0x14, 1); |
1129 | AC_VERB_SET_EAPD_BTLENABLE, 2); | 1138 | set_eapd(codec, 0x15, 1); |
1130 | snd_hda_codec_write(codec, 0x15, 0, | ||
1131 | AC_VERB_SET_EAPD_BTLENABLE, 2); | ||
1132 | break; | 1139 | break; |
1133 | } | 1140 | } |
1134 | switch (codec->vendor_id) { | 1141 | switch (codec->vendor_id) { |
@@ -1230,6 +1237,8 @@ static void alc_init_auto_mic(struct hda_codec *codec) | |||
1230 | return; /* invalid entry */ | 1237 | return; /* invalid entry */ |
1231 | } | 1238 | } |
1232 | } | 1239 | } |
1240 | if (!ext || !fixed) | ||
1241 | return; | ||
1233 | if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP)) | 1242 | if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP)) |
1234 | return; /* no unsol support */ | 1243 | return; /* no unsol support */ |
1235 | snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x\n", | 1244 | snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x\n", |
@@ -1834,10 +1843,8 @@ static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec) | |||
1834 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 1843 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
1835 | static void alc889_power_eapd(struct hda_codec *codec, int power) | 1844 | static void alc889_power_eapd(struct hda_codec *codec, int power) |
1836 | { | 1845 | { |
1837 | snd_hda_codec_write(codec, 0x14, 0, | 1846 | set_eapd(codec, 0x14, power); |
1838 | AC_VERB_SET_EAPD_BTLENABLE, power ? 2 : 0); | 1847 | set_eapd(codec, 0x15, power); |
1839 | snd_hda_codec_write(codec, 0x15, 0, | ||
1840 | AC_VERB_SET_EAPD_BTLENABLE, power ? 2 : 0); | ||
1841 | } | 1848 | } |
1842 | #endif | 1849 | #endif |
1843 | 1850 | ||
@@ -4812,6 +4819,49 @@ static void fixup_automic_adc(struct hda_codec *codec) | |||
4812 | spec->auto_mic = 0; /* disable auto-mic to be sure */ | 4819 | spec->auto_mic = 0; /* disable auto-mic to be sure */ |
4813 | } | 4820 | } |
4814 | 4821 | ||
4822 | /* choose the ADC/MUX containing the input pin and initialize the setup */ | ||
4823 | static void fixup_single_adc(struct hda_codec *codec) | ||
4824 | { | ||
4825 | struct alc_spec *spec = codec->spec; | ||
4826 | hda_nid_t pin; | ||
4827 | int i; | ||
4828 | |||
4829 | /* search for the input pin; there must be only one */ | ||
4830 | for (i = 0; i < AUTO_PIN_LAST; i++) { | ||
4831 | if (spec->autocfg.input_pins[i]) { | ||
4832 | pin = spec->autocfg.input_pins[i]; | ||
4833 | break; | ||
4834 | } | ||
4835 | } | ||
4836 | if (!pin) | ||
4837 | return; | ||
4838 | |||
4839 | /* set the default connection to that pin */ | ||
4840 | for (i = 0; i < spec->num_adc_nids; i++) { | ||
4841 | hda_nid_t cap = spec->capsrc_nids ? | ||
4842 | spec->capsrc_nids[i] : spec->adc_nids[i]; | ||
4843 | int idx; | ||
4844 | |||
4845 | idx = get_connection_index(codec, cap, pin); | ||
4846 | if (idx < 0) | ||
4847 | continue; | ||
4848 | /* use only this ADC */ | ||
4849 | if (spec->capsrc_nids) | ||
4850 | spec->capsrc_nids += i; | ||
4851 | spec->adc_nids += i; | ||
4852 | spec->num_adc_nids = 1; | ||
4853 | /* select or unmute this route */ | ||
4854 | if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) { | ||
4855 | snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx, | ||
4856 | HDA_AMP_MUTE, 0); | ||
4857 | } else { | ||
4858 | snd_hda_codec_write_cache(codec, cap, 0, | ||
4859 | AC_VERB_SET_CONNECT_SEL, idx); | ||
4860 | } | ||
4861 | return; | ||
4862 | } | ||
4863 | } | ||
4864 | |||
4815 | static void set_capture_mixer(struct hda_codec *codec) | 4865 | static void set_capture_mixer(struct hda_codec *codec) |
4816 | { | 4866 | { |
4817 | struct alc_spec *spec = codec->spec; | 4867 | struct alc_spec *spec = codec->spec; |
@@ -4824,14 +4874,15 @@ static void set_capture_mixer(struct hda_codec *codec) | |||
4824 | alc_capture_mixer3 }, | 4874 | alc_capture_mixer3 }, |
4825 | }; | 4875 | }; |
4826 | if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) { | 4876 | if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) { |
4827 | int mux; | 4877 | int mux = 0; |
4828 | if (spec->auto_mic) { | 4878 | if (spec->auto_mic) |
4829 | mux = 0; | ||
4830 | fixup_automic_adc(codec); | 4879 | fixup_automic_adc(codec); |
4831 | } else if (spec->input_mux && spec->input_mux->num_items > 1) | 4880 | else if (spec->input_mux) { |
4832 | mux = 1; | 4881 | if (spec->input_mux->num_items > 1) |
4833 | else | 4882 | mux = 1; |
4834 | mux = 0; | 4883 | else if (spec->input_mux->num_items == 1) |
4884 | fixup_single_adc(codec); | ||
4885 | } | ||
4835 | spec->cap_mixer = caps[mux][spec->num_adc_nids - 1]; | 4886 | spec->cap_mixer = caps[mux][spec->num_adc_nids - 1]; |
4836 | } | 4887 | } |
4837 | } | 4888 | } |
@@ -7094,8 +7145,8 @@ static struct snd_kcontrol_new alc885_mb5_mixer[] = { | |||
7094 | HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT), | 7145 | HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT), |
7095 | HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT), | 7146 | HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT), |
7096 | HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT), | 7147 | HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT), |
7097 | HDA_CODEC_VOLUME("HP Playback Volume", 0x0f, 0x00, HDA_OUTPUT), | 7148 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT), |
7098 | HDA_BIND_MUTE ("HP Playback Switch", 0x0f, 0x02, HDA_INPUT), | 7149 | HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT), |
7099 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | 7150 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), |
7100 | HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | 7151 | HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), |
7101 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), | 7152 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), |
@@ -7496,6 +7547,7 @@ static struct hda_verb alc885_mb5_init_verbs[] = { | |||
7496 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | 7547 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, |
7497 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 7548 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
7498 | {0x14, AC_VERB_SET_CONNECT_SEL, 0x03}, | 7549 | {0x14, AC_VERB_SET_CONNECT_SEL, 0x03}, |
7550 | {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, | ||
7499 | /* Front Mic pin: input vref at 80% */ | 7551 | /* Front Mic pin: input vref at 80% */ |
7500 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | 7552 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, |
7501 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | 7553 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, |
@@ -7680,6 +7732,27 @@ static void alc885_mbp3_setup(struct hda_codec *codec) | |||
7680 | spec->autocfg.speaker_pins[0] = 0x14; | 7732 | spec->autocfg.speaker_pins[0] = 0x14; |
7681 | } | 7733 | } |
7682 | 7734 | ||
7735 | static void alc885_mb5_automute(struct hda_codec *codec) | ||
7736 | { | ||
7737 | unsigned int present; | ||
7738 | |||
7739 | present = snd_hda_codec_read(codec, 0x14, 0, | ||
7740 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
7741 | snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0, | ||
7742 | HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); | ||
7743 | snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0, | ||
7744 | HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); | ||
7745 | |||
7746 | } | ||
7747 | |||
7748 | static void alc885_mb5_unsol_event(struct hda_codec *codec, | ||
7749 | unsigned int res) | ||
7750 | { | ||
7751 | /* Headphone insertion or removal. */ | ||
7752 | if ((res >> 26) == ALC880_HP_EVENT) | ||
7753 | alc885_mb5_automute(codec); | ||
7754 | } | ||
7755 | |||
7683 | static void alc885_imac91_automute(struct hda_codec *codec) | 7756 | static void alc885_imac91_automute(struct hda_codec *codec) |
7684 | { | 7757 | { |
7685 | unsigned int present; | 7758 | unsigned int present; |
@@ -9126,6 +9199,8 @@ static struct alc_config_preset alc882_presets[] = { | |||
9126 | .input_mux = &mb5_capture_source, | 9199 | .input_mux = &mb5_capture_source, |
9127 | .dig_out_nid = ALC882_DIGOUT_NID, | 9200 | .dig_out_nid = ALC882_DIGOUT_NID, |
9128 | .dig_in_nid = ALC882_DIGIN_NID, | 9201 | .dig_in_nid = ALC882_DIGIN_NID, |
9202 | .unsol_event = alc885_mb5_unsol_event, | ||
9203 | .init_hook = alc885_mb5_automute, | ||
9129 | }, | 9204 | }, |
9130 | [ALC885_MACPRO] = { | 9205 | [ALC885_MACPRO] = { |
9131 | .mixers = { alc882_macpro_mixer }, | 9206 | .mixers = { alc882_macpro_mixer }, |
@@ -9403,6 +9478,7 @@ static struct alc_config_preset alc882_presets[] = { | |||
9403 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), | 9478 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), |
9404 | .channel_mode = alc883_3ST_6ch_modes, | 9479 | .channel_mode = alc883_3ST_6ch_modes, |
9405 | .need_dac_fix = 1, | 9480 | .need_dac_fix = 1, |
9481 | .const_channel_count = 6, | ||
9406 | .num_mux_defs = | 9482 | .num_mux_defs = |
9407 | ARRAY_SIZE(alc888_2_capture_sources), | 9483 | ARRAY_SIZE(alc888_2_capture_sources), |
9408 | .input_mux = alc888_2_capture_sources, | 9484 | .input_mux = alc888_2_capture_sources, |
@@ -10307,7 +10383,7 @@ static void alc262_hp_t5735_setup(struct hda_codec *codec) | |||
10307 | struct alc_spec *spec = codec->spec; | 10383 | struct alc_spec *spec = codec->spec; |
10308 | 10384 | ||
10309 | spec->autocfg.hp_pins[0] = 0x15; | 10385 | spec->autocfg.hp_pins[0] = 0x15; |
10310 | spec->autocfg.speaker_pins[0] = 0x0c; /* HACK: not actually a pin */ | 10386 | spec->autocfg.speaker_pins[0] = 0x14; |
10311 | } | 10387 | } |
10312 | 10388 | ||
10313 | static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = { | 10389 | static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = { |
@@ -11179,7 +11255,7 @@ static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, | |||
11179 | } | 11255 | } |
11180 | 11256 | ||
11181 | #define alc262_auto_create_input_ctls \ | 11257 | #define alc262_auto_create_input_ctls \ |
11182 | alc880_auto_create_input_ctls | 11258 | alc882_auto_create_input_ctls |
11183 | 11259 | ||
11184 | /* | 11260 | /* |
11185 | * generic initialization of ADC, input mixers and output mixers | 11261 | * generic initialization of ADC, input mixers and output mixers |
@@ -11718,9 +11794,9 @@ static struct alc_config_preset alc262_presets[] = { | |||
11718 | .num_channel_mode = ARRAY_SIZE(alc262_modes), | 11794 | .num_channel_mode = ARRAY_SIZE(alc262_modes), |
11719 | .channel_mode = alc262_modes, | 11795 | .channel_mode = alc262_modes, |
11720 | .input_mux = &alc262_capture_source, | 11796 | .input_mux = &alc262_capture_source, |
11721 | .unsol_event = alc_automute_amp_unsol_event, | 11797 | .unsol_event = alc_sku_unsol_event, |
11722 | .setup = alc262_hp_t5735_setup, | 11798 | .setup = alc262_hp_t5735_setup, |
11723 | .init_hook = alc_automute_amp, | 11799 | .init_hook = alc_inithook, |
11724 | }, | 11800 | }, |
11725 | [ALC262_HP_RP5700] = { | 11801 | [ALC262_HP_RP5700] = { |
11726 | .mixers = { alc262_hp_rp5700_mixer }, | 11802 | .mixers = { alc262_hp_rp5700_mixer }, |
@@ -12471,6 +12547,7 @@ static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid, | |||
12471 | dac = 0x02; | 12547 | dac = 0x02; |
12472 | break; | 12548 | break; |
12473 | case 0x15: | 12549 | case 0x15: |
12550 | case 0x21: | ||
12474 | dac = 0x03; | 12551 | dac = 0x03; |
12475 | break; | 12552 | break; |
12476 | default: | 12553 | default: |
@@ -14855,6 +14932,8 @@ static int patch_alc861(struct hda_codec *codec) | |||
14855 | spec->stream_digital_playback = &alc861_pcm_digital_playback; | 14932 | spec->stream_digital_playback = &alc861_pcm_digital_playback; |
14856 | spec->stream_digital_capture = &alc861_pcm_digital_capture; | 14933 | spec->stream_digital_capture = &alc861_pcm_digital_capture; |
14857 | 14934 | ||
14935 | if (!spec->cap_mixer) | ||
14936 | set_capture_mixer(codec); | ||
14858 | set_beep_amp(spec, 0x23, 0, HDA_OUTPUT); | 14937 | set_beep_amp(spec, 0x23, 0, HDA_OUTPUT); |
14859 | 14938 | ||
14860 | spec->vmaster_nid = 0x03; | 14939 | spec->vmaster_nid = 0x03; |
@@ -15493,7 +15572,7 @@ static struct alc_config_preset alc861vd_presets[] = { | |||
15493 | static int alc861vd_auto_create_input_ctls(struct hda_codec *codec, | 15572 | static int alc861vd_auto_create_input_ctls(struct hda_codec *codec, |
15494 | const struct auto_pin_cfg *cfg) | 15573 | const struct auto_pin_cfg *cfg) |
15495 | { | 15574 | { |
15496 | return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x09, 0); | 15575 | return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x22, 0); |
15497 | } | 15576 | } |
15498 | 15577 | ||
15499 | 15578 | ||
@@ -17251,7 +17330,7 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = { | |||
17251 | SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS), | 17330 | SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS), |
17252 | SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K", | 17331 | SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K", |
17253 | ALC662_3ST_6ch_DIG), | 17332 | ALC662_3ST_6ch_DIG), |
17254 | SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB200", ALC663_ASUS_MODE4), | 17333 | SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO), |
17255 | SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10), | 17334 | SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10), |
17256 | SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L", | 17335 | SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L", |
17257 | ALC662_3ST_6ch_DIG), | 17336 | ALC662_3ST_6ch_DIG), |