diff options
author | Takashi Iwai <tiwai@suse.de> | 2014-03-18 04:51:06 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2014-03-18 04:51:06 -0400 |
commit | 376f94c33989a1ea5be4b9e03666582e7052a331 (patch) | |
tree | 0064b2fef3502772156f3540aaac8f113e38be61 /sound/pci | |
parent | 5418bd2f57ec6830e53b3aa8f837b00420688522 (diff) | |
parent | 7b5c7a0240b11b382073361c4ba9257c42d057e9 (diff) |
Merge branch 'topic/alc28x' into for-next
Diffstat (limited to 'sound/pci')
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index b50114176736..9dffed37953c 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -2787,6 +2787,160 @@ static void alc269_shutup(struct hda_codec *codec) | |||
2787 | snd_hda_shutup_pins(codec); | 2787 | snd_hda_shutup_pins(codec); |
2788 | } | 2788 | } |
2789 | 2789 | ||
2790 | static void alc282_init(struct hda_codec *codec) | ||
2791 | { | ||
2792 | struct alc_spec *spec = codec->spec; | ||
2793 | hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; | ||
2794 | bool hp_pin_sense; | ||
2795 | int coef78; | ||
2796 | |||
2797 | if (!hp_pin) | ||
2798 | return; | ||
2799 | hp_pin_sense = snd_hda_jack_detect(codec, hp_pin); | ||
2800 | coef78 = alc_read_coef_idx(codec, 0x78); | ||
2801 | |||
2802 | /* Index 0x78 Direct Drive HP AMP LPM Control 1 */ | ||
2803 | /* Headphone capless set to high power mode */ | ||
2804 | alc_write_coef_idx(codec, 0x78, 0x9004); | ||
2805 | |||
2806 | if (hp_pin_sense) | ||
2807 | msleep(2); | ||
2808 | |||
2809 | snd_hda_codec_write(codec, hp_pin, 0, | ||
2810 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); | ||
2811 | |||
2812 | if (hp_pin_sense) | ||
2813 | msleep(85); | ||
2814 | |||
2815 | snd_hda_codec_write(codec, hp_pin, 0, | ||
2816 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); | ||
2817 | |||
2818 | if (hp_pin_sense) | ||
2819 | msleep(100); | ||
2820 | |||
2821 | /* Headphone capless set to normal mode */ | ||
2822 | alc_write_coef_idx(codec, 0x78, coef78); | ||
2823 | } | ||
2824 | |||
2825 | static void alc282_shutup(struct hda_codec *codec) | ||
2826 | { | ||
2827 | struct alc_spec *spec = codec->spec; | ||
2828 | hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; | ||
2829 | bool hp_pin_sense; | ||
2830 | int coef78; | ||
2831 | |||
2832 | if (!hp_pin) { | ||
2833 | alc269_shutup(codec); | ||
2834 | return; | ||
2835 | } | ||
2836 | |||
2837 | hp_pin_sense = snd_hda_jack_detect(codec, hp_pin); | ||
2838 | coef78 = alc_read_coef_idx(codec, 0x78); | ||
2839 | alc_write_coef_idx(codec, 0x78, 0x9004); | ||
2840 | |||
2841 | if (hp_pin_sense) | ||
2842 | msleep(2); | ||
2843 | |||
2844 | snd_hda_codec_write(codec, hp_pin, 0, | ||
2845 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); | ||
2846 | |||
2847 | if (hp_pin_sense) | ||
2848 | msleep(85); | ||
2849 | |||
2850 | snd_hda_codec_write(codec, hp_pin, 0, | ||
2851 | AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0); | ||
2852 | |||
2853 | if (hp_pin_sense) | ||
2854 | msleep(100); | ||
2855 | |||
2856 | alc_auto_setup_eapd(codec, false); | ||
2857 | snd_hda_shutup_pins(codec); | ||
2858 | alc_write_coef_idx(codec, 0x78, coef78); | ||
2859 | } | ||
2860 | |||
2861 | static void alc283_restore_default_value(struct hda_codec *codec) | ||
2862 | { | ||
2863 | int val; | ||
2864 | |||
2865 | /* Power Down Control */ | ||
2866 | alc_write_coef_idx(codec, 0x03, 0x0002); | ||
2867 | /* FIFO and filter clock */ | ||
2868 | alc_write_coef_idx(codec, 0x05, 0x0700); | ||
2869 | /* DMIC control */ | ||
2870 | alc_write_coef_idx(codec, 0x07, 0x0200); | ||
2871 | /* Analog clock */ | ||
2872 | val = alc_read_coef_idx(codec, 0x06); | ||
2873 | alc_write_coef_idx(codec, 0x06, (val & ~0x00f0) | 0x0); | ||
2874 | /* JD */ | ||
2875 | val = alc_read_coef_idx(codec, 0x08); | ||
2876 | alc_write_coef_idx(codec, 0x08, (val & ~0xfffc) | 0x0c2c); | ||
2877 | /* JD offset1 */ | ||
2878 | alc_write_coef_idx(codec, 0x0a, 0xcccc); | ||
2879 | /* JD offset2 */ | ||
2880 | alc_write_coef_idx(codec, 0x0b, 0xcccc); | ||
2881 | /* LDO1/2/3, DAC/ADC */ | ||
2882 | alc_write_coef_idx(codec, 0x0e, 0x6fc0); | ||
2883 | /* JD */ | ||
2884 | val = alc_read_coef_idx(codec, 0x0f); | ||
2885 | alc_write_coef_idx(codec, 0x0f, (val & ~0xf800) | 0x1000); | ||
2886 | /* Capless */ | ||
2887 | val = alc_read_coef_idx(codec, 0x10); | ||
2888 | alc_write_coef_idx(codec, 0x10, (val & ~0xfc00) | 0x0c00); | ||
2889 | /* Class D test 4 */ | ||
2890 | alc_write_coef_idx(codec, 0x3a, 0x0); | ||
2891 | /* IO power down directly */ | ||
2892 | val = alc_read_coef_idx(codec, 0x0c); | ||
2893 | alc_write_coef_idx(codec, 0x0c, (val & ~0xfe00) | 0x0); | ||
2894 | /* ANC */ | ||
2895 | alc_write_coef_idx(codec, 0x22, 0xa0c0); | ||
2896 | /* AGC MUX */ | ||
2897 | val = alc_read_coefex_idx(codec, 0x53, 0x01); | ||
2898 | alc_write_coefex_idx(codec, 0x53, 0x01, (val & ~0x000f) | 0x0008); | ||
2899 | /* DAC simple content protection */ | ||
2900 | val = alc_read_coef_idx(codec, 0x1d); | ||
2901 | alc_write_coef_idx(codec, 0x1d, (val & ~0x00e0) | 0x0); | ||
2902 | /* ADC simple content protection */ | ||
2903 | val = alc_read_coef_idx(codec, 0x1f); | ||
2904 | alc_write_coef_idx(codec, 0x1f, (val & ~0x00e0) | 0x0); | ||
2905 | /* DAC ADC Zero Detection */ | ||
2906 | alc_write_coef_idx(codec, 0x21, 0x8804); | ||
2907 | /* PLL */ | ||
2908 | alc_write_coef_idx(codec, 0x2e, 0x2902); | ||
2909 | /* capless control 2 */ | ||
2910 | alc_write_coef_idx(codec, 0x33, 0xa080); | ||
2911 | /* capless control 3 */ | ||
2912 | alc_write_coef_idx(codec, 0x34, 0x3400); | ||
2913 | /* capless control 4 */ | ||
2914 | alc_write_coef_idx(codec, 0x35, 0x2f3e); | ||
2915 | /* capless control 5 */ | ||
2916 | alc_write_coef_idx(codec, 0x36, 0x0); | ||
2917 | /* class D test 2 */ | ||
2918 | val = alc_read_coef_idx(codec, 0x38); | ||
2919 | alc_write_coef_idx(codec, 0x38, (val & ~0x0fff) | 0x0900); | ||
2920 | /* class D test 3 */ | ||
2921 | alc_write_coef_idx(codec, 0x39, 0x110a); | ||
2922 | /* class D test 5 */ | ||
2923 | val = alc_read_coef_idx(codec, 0x3b); | ||
2924 | alc_write_coef_idx(codec, 0x3b, (val & ~0x00f8) | 0x00d8); | ||
2925 | /* class D test 6 */ | ||
2926 | alc_write_coef_idx(codec, 0x3c, 0x0014); | ||
2927 | /* classD OCP */ | ||
2928 | alc_write_coef_idx(codec, 0x3d, 0xc2ba); | ||
2929 | /* classD pure DC test */ | ||
2930 | val = alc_read_coef_idx(codec, 0x42); | ||
2931 | alc_write_coef_idx(codec, 0x42, (val & ~0x0f80) | 0x0); | ||
2932 | /* test mode */ | ||
2933 | alc_write_coef_idx(codec, 0x49, 0x0); | ||
2934 | /* Class D DC enable */ | ||
2935 | val = alc_read_coef_idx(codec, 0x40); | ||
2936 | alc_write_coef_idx(codec, 0x40, (val & ~0xf800) | 0x9800); | ||
2937 | /* DC offset */ | ||
2938 | val = alc_read_coef_idx(codec, 0x42); | ||
2939 | alc_write_coef_idx(codec, 0x42, (val & ~0xf000) | 0x2000); | ||
2940 | /* Class D amp control */ | ||
2941 | alc_write_coef_idx(codec, 0x37, 0xfc06); | ||
2942 | } | ||
2943 | |||
2790 | static void alc283_init(struct hda_codec *codec) | 2944 | static void alc283_init(struct hda_codec *codec) |
2791 | { | 2945 | { |
2792 | struct alc_spec *spec = codec->spec; | 2946 | struct alc_spec *spec = codec->spec; |
@@ -2794,6 +2948,8 @@ static void alc283_init(struct hda_codec *codec) | |||
2794 | bool hp_pin_sense; | 2948 | bool hp_pin_sense; |
2795 | int val; | 2949 | int val; |
2796 | 2950 | ||
2951 | alc283_restore_default_value(codec); | ||
2952 | |||
2797 | if (!hp_pin) | 2953 | if (!hp_pin) |
2798 | return; | 2954 | return; |
2799 | hp_pin_sense = snd_hda_jack_detect(codec, hp_pin); | 2955 | hp_pin_sense = snd_hda_jack_detect(codec, hp_pin); |
@@ -3635,6 +3791,19 @@ static void alc_fixup_auto_mute_via_amp(struct hda_codec *codec, | |||
3635 | } | 3791 | } |
3636 | } | 3792 | } |
3637 | 3793 | ||
3794 | static void alc_no_shutup(struct hda_codec *codec) | ||
3795 | { | ||
3796 | } | ||
3797 | |||
3798 | static void alc_fixup_no_shutup(struct hda_codec *codec, | ||
3799 | const struct hda_fixup *fix, int action) | ||
3800 | { | ||
3801 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | ||
3802 | struct alc_spec *spec = codec->spec; | ||
3803 | spec->shutup = alc_no_shutup; | ||
3804 | } | ||
3805 | } | ||
3806 | |||
3638 | static void alc_fixup_headset_mode_alc668(struct hda_codec *codec, | 3807 | static void alc_fixup_headset_mode_alc668(struct hda_codec *codec, |
3639 | const struct hda_fixup *fix, int action) | 3808 | const struct hda_fixup *fix, int action) |
3640 | { | 3809 | { |
@@ -3863,6 +4032,7 @@ enum { | |||
3863 | ALC269_FIXUP_HP_GPIO_LED, | 4032 | ALC269_FIXUP_HP_GPIO_LED, |
3864 | ALC269_FIXUP_INV_DMIC, | 4033 | ALC269_FIXUP_INV_DMIC, |
3865 | ALC269_FIXUP_LENOVO_DOCK, | 4034 | ALC269_FIXUP_LENOVO_DOCK, |
4035 | ALC269_FIXUP_NO_SHUTUP, | ||
3866 | ALC286_FIXUP_SONY_MIC_NO_PRESENCE, | 4036 | ALC286_FIXUP_SONY_MIC_NO_PRESENCE, |
3867 | ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT, | 4037 | ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT, |
3868 | ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, | 4038 | ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, |
@@ -4041,6 +4211,10 @@ static const struct hda_fixup alc269_fixups[] = { | |||
4041 | .type = HDA_FIXUP_FUNC, | 4211 | .type = HDA_FIXUP_FUNC, |
4042 | .v.func = alc_fixup_inv_dmic_0x12, | 4212 | .v.func = alc_fixup_inv_dmic_0x12, |
4043 | }, | 4213 | }, |
4214 | [ALC269_FIXUP_NO_SHUTUP] = { | ||
4215 | .type = HDA_FIXUP_FUNC, | ||
4216 | .v.func = alc_fixup_no_shutup, | ||
4217 | }, | ||
4044 | [ALC269_FIXUP_LENOVO_DOCK] = { | 4218 | [ALC269_FIXUP_LENOVO_DOCK] = { |
4045 | .type = HDA_FIXUP_PINS, | 4219 | .type = HDA_FIXUP_PINS, |
4046 | .v.pins = (const struct hda_pintbl[]) { | 4220 | .v.pins = (const struct hda_pintbl[]) { |
@@ -4441,6 +4615,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { | |||
4441 | SND_PCI_QUIRK(0x17aa, 0x2212, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), | 4615 | SND_PCI_QUIRK(0x17aa, 0x2212, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
4442 | SND_PCI_QUIRK(0x17aa, 0x2214, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), | 4616 | SND_PCI_QUIRK(0x17aa, 0x2214, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
4443 | SND_PCI_QUIRK(0x17aa, 0x2215, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), | 4617 | SND_PCI_QUIRK(0x17aa, 0x2215, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
4618 | SND_PCI_QUIRK(0x17aa, 0x3978, "IdeaPad Y410P", ALC269_FIXUP_NO_SHUTUP), | ||
4444 | SND_PCI_QUIRK(0x17aa, 0x5013, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), | 4619 | SND_PCI_QUIRK(0x17aa, 0x5013, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
4445 | SND_PCI_QUIRK(0x17aa, 0x501a, "Thinkpad", ALC283_FIXUP_INT_MIC), | 4620 | SND_PCI_QUIRK(0x17aa, 0x501a, "Thinkpad", ALC283_FIXUP_INT_MIC), |
4446 | SND_PCI_QUIRK(0x17aa, 0x5026, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), | 4621 | SND_PCI_QUIRK(0x17aa, 0x5026, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
@@ -4621,6 +4796,8 @@ static int patch_alc269(struct hda_codec *codec) | |||
4621 | break; | 4796 | break; |
4622 | case 0x10ec0282: | 4797 | case 0x10ec0282: |
4623 | spec->codec_variant = ALC269_TYPE_ALC282; | 4798 | spec->codec_variant = ALC269_TYPE_ALC282; |
4799 | spec->shutup = alc282_shutup; | ||
4800 | spec->init_hook = alc282_init; | ||
4624 | break; | 4801 | break; |
4625 | case 0x10ec0233: | 4802 | case 0x10ec0233: |
4626 | case 0x10ec0283: | 4803 | case 0x10ec0283: |