diff options
Diffstat (limited to 'sound/pci/hda/patch_realtek.c')
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 107 |
1 files changed, 105 insertions, 2 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index ef4955c73c88..a378c0145125 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -307,6 +307,13 @@ struct alc_spec { | |||
307 | /* for PLL fix */ | 307 | /* for PLL fix */ |
308 | hda_nid_t pll_nid; | 308 | hda_nid_t pll_nid; |
309 | unsigned int pll_coef_idx, pll_coef_bit; | 309 | unsigned int pll_coef_idx, pll_coef_bit; |
310 | |||
311 | #ifdef SND_HDA_NEEDS_RESUME | ||
312 | #define ALC_MAX_PINS 16 | ||
313 | unsigned int num_pins; | ||
314 | hda_nid_t pin_nids[ALC_MAX_PINS]; | ||
315 | unsigned int pin_cfgs[ALC_MAX_PINS]; | ||
316 | #endif | ||
310 | }; | 317 | }; |
311 | 318 | ||
312 | /* | 319 | /* |
@@ -822,6 +829,7 @@ static void alc_sku_automute(struct hda_codec *codec) | |||
822 | spec->jack_present ? 0 : PIN_OUT); | 829 | spec->jack_present ? 0 : PIN_OUT); |
823 | } | 830 | } |
824 | 831 | ||
832 | #if 0 /* it's broken in some acses -- temporarily disabled */ | ||
825 | static void alc_mic_automute(struct hda_codec *codec) | 833 | static void alc_mic_automute(struct hda_codec *codec) |
826 | { | 834 | { |
827 | struct alc_spec *spec = codec->spec; | 835 | struct alc_spec *spec = codec->spec; |
@@ -842,6 +850,9 @@ static void alc_mic_automute(struct hda_codec *codec) | |||
842 | snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, capsrc_idx_fmic, | 850 | snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, capsrc_idx_fmic, |
843 | HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); | 851 | HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); |
844 | } | 852 | } |
853 | #else | ||
854 | #define alc_mic_automute(codec) /* NOP */ | ||
855 | #endif /* disabled */ | ||
845 | 856 | ||
846 | /* unsolicited event for HP jack sensing */ | 857 | /* unsolicited event for HP jack sensing */ |
847 | static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) | 858 | static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) |
@@ -1051,12 +1062,14 @@ do_sku: | |||
1051 | AC_VERB_SET_UNSOLICITED_ENABLE, | 1062 | AC_VERB_SET_UNSOLICITED_ENABLE, |
1052 | AC_USRSP_EN | ALC880_HP_EVENT); | 1063 | AC_USRSP_EN | ALC880_HP_EVENT); |
1053 | 1064 | ||
1065 | #if 0 /* it's broken in some acses -- temporarily disabled */ | ||
1054 | if (spec->autocfg.input_pins[AUTO_PIN_MIC] && | 1066 | if (spec->autocfg.input_pins[AUTO_PIN_MIC] && |
1055 | spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC]) | 1067 | spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC]) |
1056 | snd_hda_codec_write(codec, | 1068 | snd_hda_codec_write(codec, |
1057 | spec->autocfg.input_pins[AUTO_PIN_MIC], 0, | 1069 | spec->autocfg.input_pins[AUTO_PIN_MIC], 0, |
1058 | AC_VERB_SET_UNSOLICITED_ENABLE, | 1070 | AC_VERB_SET_UNSOLICITED_ENABLE, |
1059 | AC_USRSP_EN | ALC880_MIC_EVENT); | 1071 | AC_USRSP_EN | ALC880_MIC_EVENT); |
1072 | #endif /* disabled */ | ||
1060 | 1073 | ||
1061 | spec->unsol_event = alc_sku_unsol_event; | 1074 | spec->unsol_event = alc_sku_unsol_event; |
1062 | } | 1075 | } |
@@ -2778,6 +2791,64 @@ static void alc_free(struct hda_codec *codec) | |||
2778 | codec->spec = NULL; /* to be sure */ | 2791 | codec->spec = NULL; /* to be sure */ |
2779 | } | 2792 | } |
2780 | 2793 | ||
2794 | #ifdef SND_HDA_NEEDS_RESUME | ||
2795 | static void store_pin_configs(struct hda_codec *codec) | ||
2796 | { | ||
2797 | struct alc_spec *spec = codec->spec; | ||
2798 | hda_nid_t nid, end_nid; | ||
2799 | |||
2800 | end_nid = codec->start_nid + codec->num_nodes; | ||
2801 | for (nid = codec->start_nid; nid < end_nid; nid++) { | ||
2802 | unsigned int wid_caps = get_wcaps(codec, nid); | ||
2803 | unsigned int wid_type = | ||
2804 | (wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; | ||
2805 | if (wid_type != AC_WID_PIN) | ||
2806 | continue; | ||
2807 | if (spec->num_pins >= ARRAY_SIZE(spec->pin_nids)) | ||
2808 | break; | ||
2809 | spec->pin_nids[spec->num_pins] = nid; | ||
2810 | spec->pin_cfgs[spec->num_pins] = | ||
2811 | snd_hda_codec_read(codec, nid, 0, | ||
2812 | AC_VERB_GET_CONFIG_DEFAULT, 0); | ||
2813 | spec->num_pins++; | ||
2814 | } | ||
2815 | } | ||
2816 | |||
2817 | static void resume_pin_configs(struct hda_codec *codec) | ||
2818 | { | ||
2819 | struct alc_spec *spec = codec->spec; | ||
2820 | int i; | ||
2821 | |||
2822 | for (i = 0; i < spec->num_pins; i++) { | ||
2823 | hda_nid_t pin_nid = spec->pin_nids[i]; | ||
2824 | unsigned int pin_config = spec->pin_cfgs[i]; | ||
2825 | snd_hda_codec_write(codec, pin_nid, 0, | ||
2826 | AC_VERB_SET_CONFIG_DEFAULT_BYTES_0, | ||
2827 | pin_config & 0x000000ff); | ||
2828 | snd_hda_codec_write(codec, pin_nid, 0, | ||
2829 | AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, | ||
2830 | (pin_config & 0x0000ff00) >> 8); | ||
2831 | snd_hda_codec_write(codec, pin_nid, 0, | ||
2832 | AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, | ||
2833 | (pin_config & 0x00ff0000) >> 16); | ||
2834 | snd_hda_codec_write(codec, pin_nid, 0, | ||
2835 | AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, | ||
2836 | pin_config >> 24); | ||
2837 | } | ||
2838 | } | ||
2839 | |||
2840 | static int alc_resume(struct hda_codec *codec) | ||
2841 | { | ||
2842 | resume_pin_configs(codec); | ||
2843 | codec->patch_ops.init(codec); | ||
2844 | snd_hda_codec_resume_amp(codec); | ||
2845 | snd_hda_codec_resume_cache(codec); | ||
2846 | return 0; | ||
2847 | } | ||
2848 | #else | ||
2849 | #define store_pin_configs(codec) | ||
2850 | #endif | ||
2851 | |||
2781 | /* | 2852 | /* |
2782 | */ | 2853 | */ |
2783 | static struct hda_codec_ops alc_patch_ops = { | 2854 | static struct hda_codec_ops alc_patch_ops = { |
@@ -2786,6 +2857,9 @@ static struct hda_codec_ops alc_patch_ops = { | |||
2786 | .init = alc_init, | 2857 | .init = alc_init, |
2787 | .free = alc_free, | 2858 | .free = alc_free, |
2788 | .unsol_event = alc_unsol_event, | 2859 | .unsol_event = alc_unsol_event, |
2860 | #ifdef SND_HDA_NEEDS_RESUME | ||
2861 | .resume = alc_resume, | ||
2862 | #endif | ||
2789 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 2863 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
2790 | .check_power_status = alc_check_power_status, | 2864 | .check_power_status = alc_check_power_status, |
2791 | #endif | 2865 | #endif |
@@ -3832,6 +3906,7 @@ static int alc880_parse_auto_config(struct hda_codec *codec) | |||
3832 | spec->num_mux_defs = 1; | 3906 | spec->num_mux_defs = 1; |
3833 | spec->input_mux = &spec->private_imux; | 3907 | spec->input_mux = &spec->private_imux; |
3834 | 3908 | ||
3909 | store_pin_configs(codec); | ||
3835 | return 1; | 3910 | return 1; |
3836 | } | 3911 | } |
3837 | 3912 | ||
@@ -5250,6 +5325,7 @@ static int alc260_parse_auto_config(struct hda_codec *codec) | |||
5250 | } | 5325 | } |
5251 | spec->num_mixers++; | 5326 | spec->num_mixers++; |
5252 | 5327 | ||
5328 | store_pin_configs(codec); | ||
5253 | return 1; | 5329 | return 1; |
5254 | } | 5330 | } |
5255 | 5331 | ||
@@ -8338,6 +8414,7 @@ static const char *alc883_models[ALC883_MODEL_LAST] = { | |||
8338 | static struct snd_pci_quirk alc883_cfg_tbl[] = { | 8414 | static struct snd_pci_quirk alc883_cfg_tbl[] = { |
8339 | SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG), | 8415 | SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG), |
8340 | SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE), | 8416 | SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE), |
8417 | SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE), | ||
8341 | SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE), | 8418 | SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE), |
8342 | SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE), | 8419 | SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE), |
8343 | SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE), | 8420 | SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE), |
@@ -8392,6 +8469,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { | |||
8392 | SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763), | 8469 | SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763), |
8393 | SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY), | 8470 | SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY), |
8394 | SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2), | 8471 | SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2), |
8472 | SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG), | ||
8395 | SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG), | 8473 | SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG), |
8396 | SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66), | 8474 | SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66), |
8397 | SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL), | 8475 | SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL), |
@@ -10313,6 +10391,7 @@ static int alc262_parse_auto_config(struct hda_codec *codec) | |||
10313 | if (err < 0) | 10391 | if (err < 0) |
10314 | return err; | 10392 | return err; |
10315 | 10393 | ||
10394 | store_pin_configs(codec); | ||
10316 | return 1; | 10395 | return 1; |
10317 | } | 10396 | } |
10318 | 10397 | ||
@@ -11447,6 +11526,7 @@ static int alc268_parse_auto_config(struct hda_codec *codec) | |||
11447 | if (err < 0) | 11526 | if (err < 0) |
11448 | return err; | 11527 | return err; |
11449 | 11528 | ||
11529 | store_pin_configs(codec); | ||
11450 | return 1; | 11530 | return 1; |
11451 | } | 11531 | } |
11452 | 11532 | ||
@@ -12166,8 +12246,26 @@ static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec, | |||
12166 | return 0; | 12246 | return 0; |
12167 | } | 12247 | } |
12168 | 12248 | ||
12169 | #define alc269_auto_create_analog_input_ctls \ | 12249 | static int alc269_auto_create_analog_input_ctls(struct alc_spec *spec, |
12170 | alc880_auto_create_analog_input_ctls | 12250 | const struct auto_pin_cfg *cfg) |
12251 | { | ||
12252 | int err; | ||
12253 | |||
12254 | err = alc880_auto_create_analog_input_ctls(spec, cfg); | ||
12255 | if (err < 0) | ||
12256 | return err; | ||
12257 | /* digital-mic input pin is excluded in alc880_auto_create..() | ||
12258 | * because it's under 0x18 | ||
12259 | */ | ||
12260 | if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 || | ||
12261 | cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) { | ||
12262 | struct hda_input_mux *imux = &spec->private_imux; | ||
12263 | imux->items[imux->num_items].label = "Int Mic"; | ||
12264 | imux->items[imux->num_items].index = 0x05; | ||
12265 | imux->num_items++; | ||
12266 | } | ||
12267 | return 0; | ||
12268 | } | ||
12171 | 12269 | ||
12172 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 12270 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
12173 | #define alc269_loopbacks alc880_loopbacks | 12271 | #define alc269_loopbacks alc880_loopbacks |
@@ -12230,6 +12328,7 @@ static int alc269_parse_auto_config(struct hda_codec *codec) | |||
12230 | spec->mixers[spec->num_mixers] = alc269_capture_mixer; | 12328 | spec->mixers[spec->num_mixers] = alc269_capture_mixer; |
12231 | spec->num_mixers++; | 12329 | spec->num_mixers++; |
12232 | 12330 | ||
12331 | store_pin_configs(codec); | ||
12233 | return 1; | 12332 | return 1; |
12234 | } | 12333 | } |
12235 | 12334 | ||
@@ -13316,6 +13415,7 @@ static int alc861_parse_auto_config(struct hda_codec *codec) | |||
13316 | spec->mixers[spec->num_mixers] = alc861_capture_mixer; | 13415 | spec->mixers[spec->num_mixers] = alc861_capture_mixer; |
13317 | spec->num_mixers++; | 13416 | spec->num_mixers++; |
13318 | 13417 | ||
13418 | store_pin_configs(codec); | ||
13319 | return 1; | 13419 | return 1; |
13320 | } | 13420 | } |
13321 | 13421 | ||
@@ -14427,6 +14527,7 @@ static int alc861vd_parse_auto_config(struct hda_codec *codec) | |||
14427 | if (err < 0) | 14527 | if (err < 0) |
14428 | return err; | 14528 | return err; |
14429 | 14529 | ||
14530 | store_pin_configs(codec); | ||
14430 | return 1; | 14531 | return 1; |
14431 | } | 14532 | } |
14432 | 14533 | ||
@@ -16258,6 +16359,8 @@ static int alc662_parse_auto_config(struct hda_codec *codec) | |||
16258 | 16359 | ||
16259 | spec->mixers[spec->num_mixers] = alc662_capture_mixer; | 16360 | spec->mixers[spec->num_mixers] = alc662_capture_mixer; |
16260 | spec->num_mixers++; | 16361 | spec->num_mixers++; |
16362 | |||
16363 | store_pin_configs(codec); | ||
16261 | return 1; | 16364 | return 1; |
16262 | } | 16365 | } |
16263 | 16366 | ||