Commit e32dfbed8cc06aac72528e2bb53067ce02262413
Committed by
Takashi Iwai
1 parent
474a596107
Exists in
master
and in
13 other branches
ALSA: hda - add headset mic detect quirk for a Dell laptop
When we plug a 3-ring headset on the Dell machine (VID: 0x10ec0255, SID: 0x10280674), the headset mic can't be detected, after apply this patch, the headset mic can work well. BugLink: https://bugs.launchpad.net/bugs/1297581 Cc: David Henningsson <david.henningsson@canonical.com> Cc: stable@vger.kernel.org Signed-off-by: Hui Wang <hui.wang@canonical.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Showing 1 changed file with 1 additions and 0 deletions Inline Diff
sound/pci/hda/patch_realtek.c
1 | /* | 1 | /* |
2 | * Universal Interface for Intel High Definition Audio Codec | 2 | * Universal Interface for Intel High Definition Audio Codec |
3 | * | 3 | * |
4 | * HD audio interface patch for Realtek ALC codecs | 4 | * HD audio interface patch for Realtek ALC codecs |
5 | * | 5 | * |
6 | * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw> | 6 | * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw> |
7 | * PeiSen Hou <pshou@realtek.com.tw> | 7 | * PeiSen Hou <pshou@realtek.com.tw> |
8 | * Takashi Iwai <tiwai@suse.de> | 8 | * Takashi Iwai <tiwai@suse.de> |
9 | * Jonathan Woithe <jwoithe@just42.net> | 9 | * Jonathan Woithe <jwoithe@just42.net> |
10 | * | 10 | * |
11 | * This driver is free software; you can redistribute it and/or modify | 11 | * This driver is free software; you can redistribute it and/or modify |
12 | * it under the terms of the GNU General Public License as published by | 12 | * it under the terms of the GNU General Public License as published by |
13 | * the Free Software Foundation; either version 2 of the License, or | 13 | * the Free Software Foundation; either version 2 of the License, or |
14 | * (at your option) any later version. | 14 | * (at your option) any later version. |
15 | * | 15 | * |
16 | * This driver is distributed in the hope that it will be useful, | 16 | * This driver is distributed in the hope that it will be useful, |
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
19 | * GNU General Public License for more details. | 19 | * GNU General Public License for more details. |
20 | * | 20 | * |
21 | * You should have received a copy of the GNU General Public License | 21 | * You should have received a copy of the GNU General Public License |
22 | * along with this program; if not, write to the Free Software | 22 | * along with this program; if not, write to the Free Software |
23 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 23 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
24 | */ | 24 | */ |
25 | 25 | ||
26 | #include <linux/init.h> | 26 | #include <linux/init.h> |
27 | #include <linux/delay.h> | 27 | #include <linux/delay.h> |
28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
29 | #include <linux/pci.h> | 29 | #include <linux/pci.h> |
30 | #include <linux/dmi.h> | 30 | #include <linux/dmi.h> |
31 | #include <linux/module.h> | 31 | #include <linux/module.h> |
32 | #include <sound/core.h> | 32 | #include <sound/core.h> |
33 | #include <sound/jack.h> | 33 | #include <sound/jack.h> |
34 | #include "hda_codec.h" | 34 | #include "hda_codec.h" |
35 | #include "hda_local.h" | 35 | #include "hda_local.h" |
36 | #include "hda_auto_parser.h" | 36 | #include "hda_auto_parser.h" |
37 | #include "hda_jack.h" | 37 | #include "hda_jack.h" |
38 | #include "hda_generic.h" | 38 | #include "hda_generic.h" |
39 | 39 | ||
40 | /* keep halting ALC5505 DSP, for power saving */ | 40 | /* keep halting ALC5505 DSP, for power saving */ |
41 | #define HALT_REALTEK_ALC5505 | 41 | #define HALT_REALTEK_ALC5505 |
42 | 42 | ||
43 | /* unsol event tags */ | 43 | /* unsol event tags */ |
44 | #define ALC_DCVOL_EVENT 0x08 | 44 | #define ALC_DCVOL_EVENT 0x08 |
45 | 45 | ||
46 | /* for GPIO Poll */ | 46 | /* for GPIO Poll */ |
47 | #define GPIO_MASK 0x03 | 47 | #define GPIO_MASK 0x03 |
48 | 48 | ||
49 | /* extra amp-initialization sequence types */ | 49 | /* extra amp-initialization sequence types */ |
50 | enum { | 50 | enum { |
51 | ALC_INIT_NONE, | 51 | ALC_INIT_NONE, |
52 | ALC_INIT_DEFAULT, | 52 | ALC_INIT_DEFAULT, |
53 | ALC_INIT_GPIO1, | 53 | ALC_INIT_GPIO1, |
54 | ALC_INIT_GPIO2, | 54 | ALC_INIT_GPIO2, |
55 | ALC_INIT_GPIO3, | 55 | ALC_INIT_GPIO3, |
56 | }; | 56 | }; |
57 | 57 | ||
58 | enum { | 58 | enum { |
59 | ALC_HEADSET_MODE_UNKNOWN, | 59 | ALC_HEADSET_MODE_UNKNOWN, |
60 | ALC_HEADSET_MODE_UNPLUGGED, | 60 | ALC_HEADSET_MODE_UNPLUGGED, |
61 | ALC_HEADSET_MODE_HEADSET, | 61 | ALC_HEADSET_MODE_HEADSET, |
62 | ALC_HEADSET_MODE_MIC, | 62 | ALC_HEADSET_MODE_MIC, |
63 | ALC_HEADSET_MODE_HEADPHONE, | 63 | ALC_HEADSET_MODE_HEADPHONE, |
64 | }; | 64 | }; |
65 | 65 | ||
66 | enum { | 66 | enum { |
67 | ALC_HEADSET_TYPE_UNKNOWN, | 67 | ALC_HEADSET_TYPE_UNKNOWN, |
68 | ALC_HEADSET_TYPE_CTIA, | 68 | ALC_HEADSET_TYPE_CTIA, |
69 | ALC_HEADSET_TYPE_OMTP, | 69 | ALC_HEADSET_TYPE_OMTP, |
70 | }; | 70 | }; |
71 | 71 | ||
72 | struct alc_customize_define { | 72 | struct alc_customize_define { |
73 | unsigned int sku_cfg; | 73 | unsigned int sku_cfg; |
74 | unsigned char port_connectivity; | 74 | unsigned char port_connectivity; |
75 | unsigned char check_sum; | 75 | unsigned char check_sum; |
76 | unsigned char customization; | 76 | unsigned char customization; |
77 | unsigned char external_amp; | 77 | unsigned char external_amp; |
78 | unsigned int enable_pcbeep:1; | 78 | unsigned int enable_pcbeep:1; |
79 | unsigned int platform_type:1; | 79 | unsigned int platform_type:1; |
80 | unsigned int swap:1; | 80 | unsigned int swap:1; |
81 | unsigned int override:1; | 81 | unsigned int override:1; |
82 | unsigned int fixup:1; /* Means that this sku is set by driver, not read from hw */ | 82 | unsigned int fixup:1; /* Means that this sku is set by driver, not read from hw */ |
83 | }; | 83 | }; |
84 | 84 | ||
85 | struct alc_spec { | 85 | struct alc_spec { |
86 | struct hda_gen_spec gen; /* must be at head */ | 86 | struct hda_gen_spec gen; /* must be at head */ |
87 | 87 | ||
88 | /* codec parameterization */ | 88 | /* codec parameterization */ |
89 | const struct snd_kcontrol_new *mixers[5]; /* mixer arrays */ | 89 | const struct snd_kcontrol_new *mixers[5]; /* mixer arrays */ |
90 | unsigned int num_mixers; | 90 | unsigned int num_mixers; |
91 | unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */ | 91 | unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */ |
92 | 92 | ||
93 | struct alc_customize_define cdefine; | 93 | struct alc_customize_define cdefine; |
94 | unsigned int parse_flags; /* flag for snd_hda_parse_pin_defcfg() */ | 94 | unsigned int parse_flags; /* flag for snd_hda_parse_pin_defcfg() */ |
95 | 95 | ||
96 | /* inverted dmic fix */ | 96 | /* inverted dmic fix */ |
97 | unsigned int inv_dmic_fixup:1; /* has inverted digital-mic workaround */ | 97 | unsigned int inv_dmic_fixup:1; /* has inverted digital-mic workaround */ |
98 | unsigned int inv_dmic_muted:1; /* R-ch of inv d-mic is muted? */ | 98 | unsigned int inv_dmic_muted:1; /* R-ch of inv d-mic is muted? */ |
99 | hda_nid_t inv_dmic_pin; | 99 | hda_nid_t inv_dmic_pin; |
100 | 100 | ||
101 | /* mute LED for HP laptops, see alc269_fixup_mic_mute_hook() */ | 101 | /* mute LED for HP laptops, see alc269_fixup_mic_mute_hook() */ |
102 | int mute_led_polarity; | 102 | int mute_led_polarity; |
103 | hda_nid_t mute_led_nid; | 103 | hda_nid_t mute_led_nid; |
104 | 104 | ||
105 | unsigned int gpio_led; /* used for alc269_fixup_hp_gpio_led() */ | 105 | unsigned int gpio_led; /* used for alc269_fixup_hp_gpio_led() */ |
106 | 106 | ||
107 | hda_nid_t headset_mic_pin; | 107 | hda_nid_t headset_mic_pin; |
108 | hda_nid_t headphone_mic_pin; | 108 | hda_nid_t headphone_mic_pin; |
109 | int current_headset_mode; | 109 | int current_headset_mode; |
110 | int current_headset_type; | 110 | int current_headset_type; |
111 | 111 | ||
112 | /* hooks */ | 112 | /* hooks */ |
113 | void (*init_hook)(struct hda_codec *codec); | 113 | void (*init_hook)(struct hda_codec *codec); |
114 | #ifdef CONFIG_PM | 114 | #ifdef CONFIG_PM |
115 | void (*power_hook)(struct hda_codec *codec); | 115 | void (*power_hook)(struct hda_codec *codec); |
116 | #endif | 116 | #endif |
117 | void (*shutup)(struct hda_codec *codec); | 117 | void (*shutup)(struct hda_codec *codec); |
118 | 118 | ||
119 | int init_amp; | 119 | int init_amp; |
120 | int codec_variant; /* flag for other variants */ | 120 | int codec_variant; /* flag for other variants */ |
121 | unsigned int has_alc5505_dsp:1; | 121 | unsigned int has_alc5505_dsp:1; |
122 | unsigned int no_depop_delay:1; | 122 | unsigned int no_depop_delay:1; |
123 | 123 | ||
124 | /* for PLL fix */ | 124 | /* for PLL fix */ |
125 | hda_nid_t pll_nid; | 125 | hda_nid_t pll_nid; |
126 | unsigned int pll_coef_idx, pll_coef_bit; | 126 | unsigned int pll_coef_idx, pll_coef_bit; |
127 | unsigned int coef0; | 127 | unsigned int coef0; |
128 | }; | 128 | }; |
129 | 129 | ||
130 | /* | 130 | /* |
131 | * Append the given mixer and verb elements for the later use | 131 | * Append the given mixer and verb elements for the later use |
132 | * The mixer array is referred in build_controls(), and init_verbs are | 132 | * The mixer array is referred in build_controls(), and init_verbs are |
133 | * called in init(). | 133 | * called in init(). |
134 | */ | 134 | */ |
135 | static void add_mixer(struct alc_spec *spec, const struct snd_kcontrol_new *mix) | 135 | static void add_mixer(struct alc_spec *spec, const struct snd_kcontrol_new *mix) |
136 | { | 136 | { |
137 | if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers))) | 137 | if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers))) |
138 | return; | 138 | return; |
139 | spec->mixers[spec->num_mixers++] = mix; | 139 | spec->mixers[spec->num_mixers++] = mix; |
140 | } | 140 | } |
141 | 141 | ||
142 | /* | 142 | /* |
143 | * GPIO setup tables, used in initialization | 143 | * GPIO setup tables, used in initialization |
144 | */ | 144 | */ |
145 | /* Enable GPIO mask and set output */ | 145 | /* Enable GPIO mask and set output */ |
146 | static const struct hda_verb alc_gpio1_init_verbs[] = { | 146 | static const struct hda_verb alc_gpio1_init_verbs[] = { |
147 | {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, | 147 | {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, |
148 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, | 148 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, |
149 | {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, | 149 | {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, |
150 | { } | 150 | { } |
151 | }; | 151 | }; |
152 | 152 | ||
153 | static const struct hda_verb alc_gpio2_init_verbs[] = { | 153 | static const struct hda_verb alc_gpio2_init_verbs[] = { |
154 | {0x01, AC_VERB_SET_GPIO_MASK, 0x02}, | 154 | {0x01, AC_VERB_SET_GPIO_MASK, 0x02}, |
155 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02}, | 155 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02}, |
156 | {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, | 156 | {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, |
157 | { } | 157 | { } |
158 | }; | 158 | }; |
159 | 159 | ||
160 | static const struct hda_verb alc_gpio3_init_verbs[] = { | 160 | static const struct hda_verb alc_gpio3_init_verbs[] = { |
161 | {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, | 161 | {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, |
162 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03}, | 162 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03}, |
163 | {0x01, AC_VERB_SET_GPIO_DATA, 0x03}, | 163 | {0x01, AC_VERB_SET_GPIO_DATA, 0x03}, |
164 | { } | 164 | { } |
165 | }; | 165 | }; |
166 | 166 | ||
167 | /* | 167 | /* |
168 | * Fix hardware PLL issue | 168 | * Fix hardware PLL issue |
169 | * On some codecs, the analog PLL gating control must be off while | 169 | * On some codecs, the analog PLL gating control must be off while |
170 | * the default value is 1. | 170 | * the default value is 1. |
171 | */ | 171 | */ |
172 | static void alc_fix_pll(struct hda_codec *codec) | 172 | static void alc_fix_pll(struct hda_codec *codec) |
173 | { | 173 | { |
174 | struct alc_spec *spec = codec->spec; | 174 | struct alc_spec *spec = codec->spec; |
175 | unsigned int val; | 175 | unsigned int val; |
176 | 176 | ||
177 | if (!spec->pll_nid) | 177 | if (!spec->pll_nid) |
178 | return; | 178 | return; |
179 | snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX, | 179 | snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX, |
180 | spec->pll_coef_idx); | 180 | spec->pll_coef_idx); |
181 | val = snd_hda_codec_read(codec, spec->pll_nid, 0, | 181 | val = snd_hda_codec_read(codec, spec->pll_nid, 0, |
182 | AC_VERB_GET_PROC_COEF, 0); | 182 | AC_VERB_GET_PROC_COEF, 0); |
183 | snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX, | 183 | snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX, |
184 | spec->pll_coef_idx); | 184 | spec->pll_coef_idx); |
185 | snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF, | 185 | snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF, |
186 | val & ~(1 << spec->pll_coef_bit)); | 186 | val & ~(1 << spec->pll_coef_bit)); |
187 | } | 187 | } |
188 | 188 | ||
189 | static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid, | 189 | static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid, |
190 | unsigned int coef_idx, unsigned int coef_bit) | 190 | unsigned int coef_idx, unsigned int coef_bit) |
191 | { | 191 | { |
192 | struct alc_spec *spec = codec->spec; | 192 | struct alc_spec *spec = codec->spec; |
193 | spec->pll_nid = nid; | 193 | spec->pll_nid = nid; |
194 | spec->pll_coef_idx = coef_idx; | 194 | spec->pll_coef_idx = coef_idx; |
195 | spec->pll_coef_bit = coef_bit; | 195 | spec->pll_coef_bit = coef_bit; |
196 | alc_fix_pll(codec); | 196 | alc_fix_pll(codec); |
197 | } | 197 | } |
198 | 198 | ||
199 | /* update the master volume per volume-knob's unsol event */ | 199 | /* update the master volume per volume-knob's unsol event */ |
200 | static void alc_update_knob_master(struct hda_codec *codec, struct hda_jack_tbl *jack) | 200 | static void alc_update_knob_master(struct hda_codec *codec, struct hda_jack_tbl *jack) |
201 | { | 201 | { |
202 | unsigned int val; | 202 | unsigned int val; |
203 | struct snd_kcontrol *kctl; | 203 | struct snd_kcontrol *kctl; |
204 | struct snd_ctl_elem_value *uctl; | 204 | struct snd_ctl_elem_value *uctl; |
205 | 205 | ||
206 | kctl = snd_hda_find_mixer_ctl(codec, "Master Playback Volume"); | 206 | kctl = snd_hda_find_mixer_ctl(codec, "Master Playback Volume"); |
207 | if (!kctl) | 207 | if (!kctl) |
208 | return; | 208 | return; |
209 | uctl = kzalloc(sizeof(*uctl), GFP_KERNEL); | 209 | uctl = kzalloc(sizeof(*uctl), GFP_KERNEL); |
210 | if (!uctl) | 210 | if (!uctl) |
211 | return; | 211 | return; |
212 | val = snd_hda_codec_read(codec, jack->nid, 0, | 212 | val = snd_hda_codec_read(codec, jack->nid, 0, |
213 | AC_VERB_GET_VOLUME_KNOB_CONTROL, 0); | 213 | AC_VERB_GET_VOLUME_KNOB_CONTROL, 0); |
214 | val &= HDA_AMP_VOLMASK; | 214 | val &= HDA_AMP_VOLMASK; |
215 | uctl->value.integer.value[0] = val; | 215 | uctl->value.integer.value[0] = val; |
216 | uctl->value.integer.value[1] = val; | 216 | uctl->value.integer.value[1] = val; |
217 | kctl->put(kctl, uctl); | 217 | kctl->put(kctl, uctl); |
218 | kfree(uctl); | 218 | kfree(uctl); |
219 | } | 219 | } |
220 | 220 | ||
221 | static void alc880_unsol_event(struct hda_codec *codec, unsigned int res) | 221 | static void alc880_unsol_event(struct hda_codec *codec, unsigned int res) |
222 | { | 222 | { |
223 | /* For some reason, the res given from ALC880 is broken. | 223 | /* For some reason, the res given from ALC880 is broken. |
224 | Here we adjust it properly. */ | 224 | Here we adjust it properly. */ |
225 | snd_hda_jack_unsol_event(codec, res >> 2); | 225 | snd_hda_jack_unsol_event(codec, res >> 2); |
226 | } | 226 | } |
227 | 227 | ||
228 | /* additional initialization for ALC888 variants */ | 228 | /* additional initialization for ALC888 variants */ |
229 | static void alc888_coef_init(struct hda_codec *codec) | 229 | static void alc888_coef_init(struct hda_codec *codec) |
230 | { | 230 | { |
231 | unsigned int tmp; | 231 | unsigned int tmp; |
232 | 232 | ||
233 | snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0); | 233 | snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0); |
234 | tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); | 234 | tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); |
235 | snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7); | 235 | snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7); |
236 | if ((tmp & 0xf0) == 0x20) | 236 | if ((tmp & 0xf0) == 0x20) |
237 | /* alc888S-VC */ | 237 | /* alc888S-VC */ |
238 | snd_hda_codec_read(codec, 0x20, 0, | 238 | snd_hda_codec_read(codec, 0x20, 0, |
239 | AC_VERB_SET_PROC_COEF, 0x830); | 239 | AC_VERB_SET_PROC_COEF, 0x830); |
240 | else | 240 | else |
241 | /* alc888-VB */ | 241 | /* alc888-VB */ |
242 | snd_hda_codec_read(codec, 0x20, 0, | 242 | snd_hda_codec_read(codec, 0x20, 0, |
243 | AC_VERB_SET_PROC_COEF, 0x3030); | 243 | AC_VERB_SET_PROC_COEF, 0x3030); |
244 | } | 244 | } |
245 | 245 | ||
246 | /* additional initialization for ALC889 variants */ | 246 | /* additional initialization for ALC889 variants */ |
247 | static void alc889_coef_init(struct hda_codec *codec) | 247 | static void alc889_coef_init(struct hda_codec *codec) |
248 | { | 248 | { |
249 | unsigned int tmp; | 249 | unsigned int tmp; |
250 | 250 | ||
251 | snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7); | 251 | snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7); |
252 | tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); | 252 | tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); |
253 | snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7); | 253 | snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7); |
254 | snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010); | 254 | snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010); |
255 | } | 255 | } |
256 | 256 | ||
257 | /* turn on/off EAPD control (only if available) */ | 257 | /* turn on/off EAPD control (only if available) */ |
258 | static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on) | 258 | static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on) |
259 | { | 259 | { |
260 | if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN) | 260 | if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN) |
261 | return; | 261 | return; |
262 | if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD) | 262 | if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD) |
263 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE, | 263 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE, |
264 | on ? 2 : 0); | 264 | on ? 2 : 0); |
265 | } | 265 | } |
266 | 266 | ||
267 | /* turn on/off EAPD controls of the codec */ | 267 | /* turn on/off EAPD controls of the codec */ |
268 | static void alc_auto_setup_eapd(struct hda_codec *codec, bool on) | 268 | static void alc_auto_setup_eapd(struct hda_codec *codec, bool on) |
269 | { | 269 | { |
270 | /* We currently only handle front, HP */ | 270 | /* We currently only handle front, HP */ |
271 | static hda_nid_t pins[] = { | 271 | static hda_nid_t pins[] = { |
272 | 0x0f, 0x10, 0x14, 0x15, 0 | 272 | 0x0f, 0x10, 0x14, 0x15, 0 |
273 | }; | 273 | }; |
274 | hda_nid_t *p; | 274 | hda_nid_t *p; |
275 | for (p = pins; *p; p++) | 275 | for (p = pins; *p; p++) |
276 | set_eapd(codec, *p, on); | 276 | set_eapd(codec, *p, on); |
277 | } | 277 | } |
278 | 278 | ||
279 | /* generic shutup callback; | 279 | /* generic shutup callback; |
280 | * just turning off EPAD and a little pause for avoiding pop-noise | 280 | * just turning off EPAD and a little pause for avoiding pop-noise |
281 | */ | 281 | */ |
282 | static void alc_eapd_shutup(struct hda_codec *codec) | 282 | static void alc_eapd_shutup(struct hda_codec *codec) |
283 | { | 283 | { |
284 | struct alc_spec *spec = codec->spec; | 284 | struct alc_spec *spec = codec->spec; |
285 | 285 | ||
286 | alc_auto_setup_eapd(codec, false); | 286 | alc_auto_setup_eapd(codec, false); |
287 | if (!spec->no_depop_delay) | 287 | if (!spec->no_depop_delay) |
288 | msleep(200); | 288 | msleep(200); |
289 | snd_hda_shutup_pins(codec); | 289 | snd_hda_shutup_pins(codec); |
290 | } | 290 | } |
291 | 291 | ||
292 | /* generic EAPD initialization */ | 292 | /* generic EAPD initialization */ |
293 | static void alc_auto_init_amp(struct hda_codec *codec, int type) | 293 | static void alc_auto_init_amp(struct hda_codec *codec, int type) |
294 | { | 294 | { |
295 | unsigned int tmp; | 295 | unsigned int tmp; |
296 | 296 | ||
297 | alc_auto_setup_eapd(codec, true); | 297 | alc_auto_setup_eapd(codec, true); |
298 | switch (type) { | 298 | switch (type) { |
299 | case ALC_INIT_GPIO1: | 299 | case ALC_INIT_GPIO1: |
300 | snd_hda_sequence_write(codec, alc_gpio1_init_verbs); | 300 | snd_hda_sequence_write(codec, alc_gpio1_init_verbs); |
301 | break; | 301 | break; |
302 | case ALC_INIT_GPIO2: | 302 | case ALC_INIT_GPIO2: |
303 | snd_hda_sequence_write(codec, alc_gpio2_init_verbs); | 303 | snd_hda_sequence_write(codec, alc_gpio2_init_verbs); |
304 | break; | 304 | break; |
305 | case ALC_INIT_GPIO3: | 305 | case ALC_INIT_GPIO3: |
306 | snd_hda_sequence_write(codec, alc_gpio3_init_verbs); | 306 | snd_hda_sequence_write(codec, alc_gpio3_init_verbs); |
307 | break; | 307 | break; |
308 | case ALC_INIT_DEFAULT: | 308 | case ALC_INIT_DEFAULT: |
309 | switch (codec->vendor_id) { | 309 | switch (codec->vendor_id) { |
310 | case 0x10ec0260: | 310 | case 0x10ec0260: |
311 | snd_hda_codec_write(codec, 0x1a, 0, | 311 | snd_hda_codec_write(codec, 0x1a, 0, |
312 | AC_VERB_SET_COEF_INDEX, 7); | 312 | AC_VERB_SET_COEF_INDEX, 7); |
313 | tmp = snd_hda_codec_read(codec, 0x1a, 0, | 313 | tmp = snd_hda_codec_read(codec, 0x1a, 0, |
314 | AC_VERB_GET_PROC_COEF, 0); | 314 | AC_VERB_GET_PROC_COEF, 0); |
315 | snd_hda_codec_write(codec, 0x1a, 0, | 315 | snd_hda_codec_write(codec, 0x1a, 0, |
316 | AC_VERB_SET_COEF_INDEX, 7); | 316 | AC_VERB_SET_COEF_INDEX, 7); |
317 | snd_hda_codec_write(codec, 0x1a, 0, | 317 | snd_hda_codec_write(codec, 0x1a, 0, |
318 | AC_VERB_SET_PROC_COEF, | 318 | AC_VERB_SET_PROC_COEF, |
319 | tmp | 0x2010); | 319 | tmp | 0x2010); |
320 | break; | 320 | break; |
321 | case 0x10ec0262: | 321 | case 0x10ec0262: |
322 | case 0x10ec0880: | 322 | case 0x10ec0880: |
323 | case 0x10ec0882: | 323 | case 0x10ec0882: |
324 | case 0x10ec0883: | 324 | case 0x10ec0883: |
325 | case 0x10ec0885: | 325 | case 0x10ec0885: |
326 | case 0x10ec0887: | 326 | case 0x10ec0887: |
327 | /*case 0x10ec0889:*/ /* this causes an SPDIF problem */ | 327 | /*case 0x10ec0889:*/ /* this causes an SPDIF problem */ |
328 | alc889_coef_init(codec); | 328 | alc889_coef_init(codec); |
329 | break; | 329 | break; |
330 | case 0x10ec0888: | 330 | case 0x10ec0888: |
331 | alc888_coef_init(codec); | 331 | alc888_coef_init(codec); |
332 | break; | 332 | break; |
333 | #if 0 /* XXX: This may cause the silent output on speaker on some machines */ | 333 | #if 0 /* XXX: This may cause the silent output on speaker on some machines */ |
334 | case 0x10ec0267: | 334 | case 0x10ec0267: |
335 | case 0x10ec0268: | 335 | case 0x10ec0268: |
336 | snd_hda_codec_write(codec, 0x20, 0, | 336 | snd_hda_codec_write(codec, 0x20, 0, |
337 | AC_VERB_SET_COEF_INDEX, 7); | 337 | AC_VERB_SET_COEF_INDEX, 7); |
338 | tmp = snd_hda_codec_read(codec, 0x20, 0, | 338 | tmp = snd_hda_codec_read(codec, 0x20, 0, |
339 | AC_VERB_GET_PROC_COEF, 0); | 339 | AC_VERB_GET_PROC_COEF, 0); |
340 | snd_hda_codec_write(codec, 0x20, 0, | 340 | snd_hda_codec_write(codec, 0x20, 0, |
341 | AC_VERB_SET_COEF_INDEX, 7); | 341 | AC_VERB_SET_COEF_INDEX, 7); |
342 | snd_hda_codec_write(codec, 0x20, 0, | 342 | snd_hda_codec_write(codec, 0x20, 0, |
343 | AC_VERB_SET_PROC_COEF, | 343 | AC_VERB_SET_PROC_COEF, |
344 | tmp | 0x3000); | 344 | tmp | 0x3000); |
345 | break; | 345 | break; |
346 | #endif /* XXX */ | 346 | #endif /* XXX */ |
347 | } | 347 | } |
348 | break; | 348 | break; |
349 | } | 349 | } |
350 | } | 350 | } |
351 | 351 | ||
352 | 352 | ||
353 | /* | 353 | /* |
354 | * Realtek SSID verification | 354 | * Realtek SSID verification |
355 | */ | 355 | */ |
356 | 356 | ||
357 | /* Could be any non-zero and even value. When used as fixup, tells | 357 | /* Could be any non-zero and even value. When used as fixup, tells |
358 | * the driver to ignore any present sku defines. | 358 | * the driver to ignore any present sku defines. |
359 | */ | 359 | */ |
360 | #define ALC_FIXUP_SKU_IGNORE (2) | 360 | #define ALC_FIXUP_SKU_IGNORE (2) |
361 | 361 | ||
362 | static void alc_fixup_sku_ignore(struct hda_codec *codec, | 362 | static void alc_fixup_sku_ignore(struct hda_codec *codec, |
363 | const struct hda_fixup *fix, int action) | 363 | const struct hda_fixup *fix, int action) |
364 | { | 364 | { |
365 | struct alc_spec *spec = codec->spec; | 365 | struct alc_spec *spec = codec->spec; |
366 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | 366 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
367 | spec->cdefine.fixup = 1; | 367 | spec->cdefine.fixup = 1; |
368 | spec->cdefine.sku_cfg = ALC_FIXUP_SKU_IGNORE; | 368 | spec->cdefine.sku_cfg = ALC_FIXUP_SKU_IGNORE; |
369 | } | 369 | } |
370 | } | 370 | } |
371 | 371 | ||
372 | static void alc_fixup_no_depop_delay(struct hda_codec *codec, | 372 | static void alc_fixup_no_depop_delay(struct hda_codec *codec, |
373 | const struct hda_fixup *fix, int action) | 373 | const struct hda_fixup *fix, int action) |
374 | { | 374 | { |
375 | struct alc_spec *spec = codec->spec; | 375 | struct alc_spec *spec = codec->spec; |
376 | 376 | ||
377 | if (action == HDA_FIXUP_ACT_PROBE) { | 377 | if (action == HDA_FIXUP_ACT_PROBE) { |
378 | spec->no_depop_delay = 1; | 378 | spec->no_depop_delay = 1; |
379 | codec->depop_delay = 0; | 379 | codec->depop_delay = 0; |
380 | } | 380 | } |
381 | } | 381 | } |
382 | 382 | ||
383 | static int alc_auto_parse_customize_define(struct hda_codec *codec) | 383 | static int alc_auto_parse_customize_define(struct hda_codec *codec) |
384 | { | 384 | { |
385 | unsigned int ass, tmp, i; | 385 | unsigned int ass, tmp, i; |
386 | unsigned nid = 0; | 386 | unsigned nid = 0; |
387 | struct alc_spec *spec = codec->spec; | 387 | struct alc_spec *spec = codec->spec; |
388 | 388 | ||
389 | spec->cdefine.enable_pcbeep = 1; /* assume always enabled */ | 389 | spec->cdefine.enable_pcbeep = 1; /* assume always enabled */ |
390 | 390 | ||
391 | if (spec->cdefine.fixup) { | 391 | if (spec->cdefine.fixup) { |
392 | ass = spec->cdefine.sku_cfg; | 392 | ass = spec->cdefine.sku_cfg; |
393 | if (ass == ALC_FIXUP_SKU_IGNORE) | 393 | if (ass == ALC_FIXUP_SKU_IGNORE) |
394 | return -1; | 394 | return -1; |
395 | goto do_sku; | 395 | goto do_sku; |
396 | } | 396 | } |
397 | 397 | ||
398 | if (!codec->bus->pci) | 398 | if (!codec->bus->pci) |
399 | return -1; | 399 | return -1; |
400 | ass = codec->subsystem_id & 0xffff; | 400 | ass = codec->subsystem_id & 0xffff; |
401 | if (ass != codec->bus->pci->subsystem_device && (ass & 1)) | 401 | if (ass != codec->bus->pci->subsystem_device && (ass & 1)) |
402 | goto do_sku; | 402 | goto do_sku; |
403 | 403 | ||
404 | nid = 0x1d; | 404 | nid = 0x1d; |
405 | if (codec->vendor_id == 0x10ec0260) | 405 | if (codec->vendor_id == 0x10ec0260) |
406 | nid = 0x17; | 406 | nid = 0x17; |
407 | ass = snd_hda_codec_get_pincfg(codec, nid); | 407 | ass = snd_hda_codec_get_pincfg(codec, nid); |
408 | 408 | ||
409 | if (!(ass & 1)) { | 409 | if (!(ass & 1)) { |
410 | codec_info(codec, "%s: SKU not ready 0x%08x\n", | 410 | codec_info(codec, "%s: SKU not ready 0x%08x\n", |
411 | codec->chip_name, ass); | 411 | codec->chip_name, ass); |
412 | return -1; | 412 | return -1; |
413 | } | 413 | } |
414 | 414 | ||
415 | /* check sum */ | 415 | /* check sum */ |
416 | tmp = 0; | 416 | tmp = 0; |
417 | for (i = 1; i < 16; i++) { | 417 | for (i = 1; i < 16; i++) { |
418 | if ((ass >> i) & 1) | 418 | if ((ass >> i) & 1) |
419 | tmp++; | 419 | tmp++; |
420 | } | 420 | } |
421 | if (((ass >> 16) & 0xf) != tmp) | 421 | if (((ass >> 16) & 0xf) != tmp) |
422 | return -1; | 422 | return -1; |
423 | 423 | ||
424 | spec->cdefine.port_connectivity = ass >> 30; | 424 | spec->cdefine.port_connectivity = ass >> 30; |
425 | spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20; | 425 | spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20; |
426 | spec->cdefine.check_sum = (ass >> 16) & 0xf; | 426 | spec->cdefine.check_sum = (ass >> 16) & 0xf; |
427 | spec->cdefine.customization = ass >> 8; | 427 | spec->cdefine.customization = ass >> 8; |
428 | do_sku: | 428 | do_sku: |
429 | spec->cdefine.sku_cfg = ass; | 429 | spec->cdefine.sku_cfg = ass; |
430 | spec->cdefine.external_amp = (ass & 0x38) >> 3; | 430 | spec->cdefine.external_amp = (ass & 0x38) >> 3; |
431 | spec->cdefine.platform_type = (ass & 0x4) >> 2; | 431 | spec->cdefine.platform_type = (ass & 0x4) >> 2; |
432 | spec->cdefine.swap = (ass & 0x2) >> 1; | 432 | spec->cdefine.swap = (ass & 0x2) >> 1; |
433 | spec->cdefine.override = ass & 0x1; | 433 | spec->cdefine.override = ass & 0x1; |
434 | 434 | ||
435 | codec_dbg(codec, "SKU: Nid=0x%x sku_cfg=0x%08x\n", | 435 | codec_dbg(codec, "SKU: Nid=0x%x sku_cfg=0x%08x\n", |
436 | nid, spec->cdefine.sku_cfg); | 436 | nid, spec->cdefine.sku_cfg); |
437 | codec_dbg(codec, "SKU: port_connectivity=0x%x\n", | 437 | codec_dbg(codec, "SKU: port_connectivity=0x%x\n", |
438 | spec->cdefine.port_connectivity); | 438 | spec->cdefine.port_connectivity); |
439 | codec_dbg(codec, "SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep); | 439 | codec_dbg(codec, "SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep); |
440 | codec_dbg(codec, "SKU: check_sum=0x%08x\n", spec->cdefine.check_sum); | 440 | codec_dbg(codec, "SKU: check_sum=0x%08x\n", spec->cdefine.check_sum); |
441 | codec_dbg(codec, "SKU: customization=0x%08x\n", spec->cdefine.customization); | 441 | codec_dbg(codec, "SKU: customization=0x%08x\n", spec->cdefine.customization); |
442 | codec_dbg(codec, "SKU: external_amp=0x%x\n", spec->cdefine.external_amp); | 442 | codec_dbg(codec, "SKU: external_amp=0x%x\n", spec->cdefine.external_amp); |
443 | codec_dbg(codec, "SKU: platform_type=0x%x\n", spec->cdefine.platform_type); | 443 | codec_dbg(codec, "SKU: platform_type=0x%x\n", spec->cdefine.platform_type); |
444 | codec_dbg(codec, "SKU: swap=0x%x\n", spec->cdefine.swap); | 444 | codec_dbg(codec, "SKU: swap=0x%x\n", spec->cdefine.swap); |
445 | codec_dbg(codec, "SKU: override=0x%x\n", spec->cdefine.override); | 445 | codec_dbg(codec, "SKU: override=0x%x\n", spec->cdefine.override); |
446 | 446 | ||
447 | return 0; | 447 | return 0; |
448 | } | 448 | } |
449 | 449 | ||
450 | /* return the position of NID in the list, or -1 if not found */ | 450 | /* return the position of NID in the list, or -1 if not found */ |
451 | static int find_idx_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums) | 451 | static int find_idx_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums) |
452 | { | 452 | { |
453 | int i; | 453 | int i; |
454 | for (i = 0; i < nums; i++) | 454 | for (i = 0; i < nums; i++) |
455 | if (list[i] == nid) | 455 | if (list[i] == nid) |
456 | return i; | 456 | return i; |
457 | return -1; | 457 | return -1; |
458 | } | 458 | } |
459 | /* return true if the given NID is found in the list */ | 459 | /* return true if the given NID is found in the list */ |
460 | static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums) | 460 | static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums) |
461 | { | 461 | { |
462 | return find_idx_in_nid_list(nid, list, nums) >= 0; | 462 | return find_idx_in_nid_list(nid, list, nums) >= 0; |
463 | } | 463 | } |
464 | 464 | ||
465 | /* check subsystem ID and set up device-specific initialization; | 465 | /* check subsystem ID and set up device-specific initialization; |
466 | * return 1 if initialized, 0 if invalid SSID | 466 | * return 1 if initialized, 0 if invalid SSID |
467 | */ | 467 | */ |
468 | /* 32-bit subsystem ID for BIOS loading in HD Audio codec. | 468 | /* 32-bit subsystem ID for BIOS loading in HD Audio codec. |
469 | * 31 ~ 16 : Manufacture ID | 469 | * 31 ~ 16 : Manufacture ID |
470 | * 15 ~ 8 : SKU ID | 470 | * 15 ~ 8 : SKU ID |
471 | * 7 ~ 0 : Assembly ID | 471 | * 7 ~ 0 : Assembly ID |
472 | * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36 | 472 | * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36 |
473 | */ | 473 | */ |
474 | static int alc_subsystem_id(struct hda_codec *codec, const hda_nid_t *ports) | 474 | static int alc_subsystem_id(struct hda_codec *codec, const hda_nid_t *ports) |
475 | { | 475 | { |
476 | unsigned int ass, tmp, i; | 476 | unsigned int ass, tmp, i; |
477 | unsigned nid; | 477 | unsigned nid; |
478 | struct alc_spec *spec = codec->spec; | 478 | struct alc_spec *spec = codec->spec; |
479 | 479 | ||
480 | if (spec->cdefine.fixup) { | 480 | if (spec->cdefine.fixup) { |
481 | ass = spec->cdefine.sku_cfg; | 481 | ass = spec->cdefine.sku_cfg; |
482 | if (ass == ALC_FIXUP_SKU_IGNORE) | 482 | if (ass == ALC_FIXUP_SKU_IGNORE) |
483 | return 0; | 483 | return 0; |
484 | goto do_sku; | 484 | goto do_sku; |
485 | } | 485 | } |
486 | 486 | ||
487 | ass = codec->subsystem_id & 0xffff; | 487 | ass = codec->subsystem_id & 0xffff; |
488 | if (codec->bus->pci && | 488 | if (codec->bus->pci && |
489 | ass != codec->bus->pci->subsystem_device && (ass & 1)) | 489 | ass != codec->bus->pci->subsystem_device && (ass & 1)) |
490 | goto do_sku; | 490 | goto do_sku; |
491 | 491 | ||
492 | /* invalid SSID, check the special NID pin defcfg instead */ | 492 | /* invalid SSID, check the special NID pin defcfg instead */ |
493 | /* | 493 | /* |
494 | * 31~30 : port connectivity | 494 | * 31~30 : port connectivity |
495 | * 29~21 : reserve | 495 | * 29~21 : reserve |
496 | * 20 : PCBEEP input | 496 | * 20 : PCBEEP input |
497 | * 19~16 : Check sum (15:1) | 497 | * 19~16 : Check sum (15:1) |
498 | * 15~1 : Custom | 498 | * 15~1 : Custom |
499 | * 0 : override | 499 | * 0 : override |
500 | */ | 500 | */ |
501 | nid = 0x1d; | 501 | nid = 0x1d; |
502 | if (codec->vendor_id == 0x10ec0260) | 502 | if (codec->vendor_id == 0x10ec0260) |
503 | nid = 0x17; | 503 | nid = 0x17; |
504 | ass = snd_hda_codec_get_pincfg(codec, nid); | 504 | ass = snd_hda_codec_get_pincfg(codec, nid); |
505 | codec_dbg(codec, | 505 | codec_dbg(codec, |
506 | "realtek: No valid SSID, checking pincfg 0x%08x for NID 0x%x\n", | 506 | "realtek: No valid SSID, checking pincfg 0x%08x for NID 0x%x\n", |
507 | ass, nid); | 507 | ass, nid); |
508 | if (!(ass & 1)) | 508 | if (!(ass & 1)) |
509 | return 0; | 509 | return 0; |
510 | if ((ass >> 30) != 1) /* no physical connection */ | 510 | if ((ass >> 30) != 1) /* no physical connection */ |
511 | return 0; | 511 | return 0; |
512 | 512 | ||
513 | /* check sum */ | 513 | /* check sum */ |
514 | tmp = 0; | 514 | tmp = 0; |
515 | for (i = 1; i < 16; i++) { | 515 | for (i = 1; i < 16; i++) { |
516 | if ((ass >> i) & 1) | 516 | if ((ass >> i) & 1) |
517 | tmp++; | 517 | tmp++; |
518 | } | 518 | } |
519 | if (((ass >> 16) & 0xf) != tmp) | 519 | if (((ass >> 16) & 0xf) != tmp) |
520 | return 0; | 520 | return 0; |
521 | do_sku: | 521 | do_sku: |
522 | codec_dbg(codec, "realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n", | 522 | codec_dbg(codec, "realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n", |
523 | ass & 0xffff, codec->vendor_id); | 523 | ass & 0xffff, codec->vendor_id); |
524 | /* | 524 | /* |
525 | * 0 : override | 525 | * 0 : override |
526 | * 1 : Swap Jack | 526 | * 1 : Swap Jack |
527 | * 2 : 0 --> Desktop, 1 --> Laptop | 527 | * 2 : 0 --> Desktop, 1 --> Laptop |
528 | * 3~5 : External Amplifier control | 528 | * 3~5 : External Amplifier control |
529 | * 7~6 : Reserved | 529 | * 7~6 : Reserved |
530 | */ | 530 | */ |
531 | tmp = (ass & 0x38) >> 3; /* external Amp control */ | 531 | tmp = (ass & 0x38) >> 3; /* external Amp control */ |
532 | switch (tmp) { | 532 | switch (tmp) { |
533 | case 1: | 533 | case 1: |
534 | spec->init_amp = ALC_INIT_GPIO1; | 534 | spec->init_amp = ALC_INIT_GPIO1; |
535 | break; | 535 | break; |
536 | case 3: | 536 | case 3: |
537 | spec->init_amp = ALC_INIT_GPIO2; | 537 | spec->init_amp = ALC_INIT_GPIO2; |
538 | break; | 538 | break; |
539 | case 7: | 539 | case 7: |
540 | spec->init_amp = ALC_INIT_GPIO3; | 540 | spec->init_amp = ALC_INIT_GPIO3; |
541 | break; | 541 | break; |
542 | case 5: | 542 | case 5: |
543 | default: | 543 | default: |
544 | spec->init_amp = ALC_INIT_DEFAULT; | 544 | spec->init_amp = ALC_INIT_DEFAULT; |
545 | break; | 545 | break; |
546 | } | 546 | } |
547 | 547 | ||
548 | /* is laptop or Desktop and enable the function "Mute internal speaker | 548 | /* is laptop or Desktop and enable the function "Mute internal speaker |
549 | * when the external headphone out jack is plugged" | 549 | * when the external headphone out jack is plugged" |
550 | */ | 550 | */ |
551 | if (!(ass & 0x8000)) | 551 | if (!(ass & 0x8000)) |
552 | return 1; | 552 | return 1; |
553 | /* | 553 | /* |
554 | * 10~8 : Jack location | 554 | * 10~8 : Jack location |
555 | * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered | 555 | * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered |
556 | * 14~13: Resvered | 556 | * 14~13: Resvered |
557 | * 15 : 1 --> enable the function "Mute internal speaker | 557 | * 15 : 1 --> enable the function "Mute internal speaker |
558 | * when the external headphone out jack is plugged" | 558 | * when the external headphone out jack is plugged" |
559 | */ | 559 | */ |
560 | if (!spec->gen.autocfg.hp_pins[0] && | 560 | if (!spec->gen.autocfg.hp_pins[0] && |
561 | !(spec->gen.autocfg.line_out_pins[0] && | 561 | !(spec->gen.autocfg.line_out_pins[0] && |
562 | spec->gen.autocfg.line_out_type == AUTO_PIN_HP_OUT)) { | 562 | spec->gen.autocfg.line_out_type == AUTO_PIN_HP_OUT)) { |
563 | hda_nid_t nid; | 563 | hda_nid_t nid; |
564 | tmp = (ass >> 11) & 0x3; /* HP to chassis */ | 564 | tmp = (ass >> 11) & 0x3; /* HP to chassis */ |
565 | nid = ports[tmp]; | 565 | nid = ports[tmp]; |
566 | if (found_in_nid_list(nid, spec->gen.autocfg.line_out_pins, | 566 | if (found_in_nid_list(nid, spec->gen.autocfg.line_out_pins, |
567 | spec->gen.autocfg.line_outs)) | 567 | spec->gen.autocfg.line_outs)) |
568 | return 1; | 568 | return 1; |
569 | spec->gen.autocfg.hp_pins[0] = nid; | 569 | spec->gen.autocfg.hp_pins[0] = nid; |
570 | } | 570 | } |
571 | return 1; | 571 | return 1; |
572 | } | 572 | } |
573 | 573 | ||
574 | /* Check the validity of ALC subsystem-id | 574 | /* Check the validity of ALC subsystem-id |
575 | * ports contains an array of 4 pin NIDs for port-A, E, D and I */ | 575 | * ports contains an array of 4 pin NIDs for port-A, E, D and I */ |
576 | static void alc_ssid_check(struct hda_codec *codec, const hda_nid_t *ports) | 576 | static void alc_ssid_check(struct hda_codec *codec, const hda_nid_t *ports) |
577 | { | 577 | { |
578 | if (!alc_subsystem_id(codec, ports)) { | 578 | if (!alc_subsystem_id(codec, ports)) { |
579 | struct alc_spec *spec = codec->spec; | 579 | struct alc_spec *spec = codec->spec; |
580 | codec_dbg(codec, | 580 | codec_dbg(codec, |
581 | "realtek: Enable default setup for auto mode as fallback\n"); | 581 | "realtek: Enable default setup for auto mode as fallback\n"); |
582 | spec->init_amp = ALC_INIT_DEFAULT; | 582 | spec->init_amp = ALC_INIT_DEFAULT; |
583 | } | 583 | } |
584 | } | 584 | } |
585 | 585 | ||
586 | /* | 586 | /* |
587 | * COEF access helper functions | 587 | * COEF access helper functions |
588 | */ | 588 | */ |
589 | 589 | ||
590 | static int alc_read_coefex_idx(struct hda_codec *codec, | 590 | static int alc_read_coefex_idx(struct hda_codec *codec, |
591 | hda_nid_t nid, | 591 | hda_nid_t nid, |
592 | unsigned int coef_idx) | 592 | unsigned int coef_idx) |
593 | { | 593 | { |
594 | unsigned int val; | 594 | unsigned int val; |
595 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, | 595 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, |
596 | coef_idx); | 596 | coef_idx); |
597 | val = snd_hda_codec_read(codec, nid, 0, | 597 | val = snd_hda_codec_read(codec, nid, 0, |
598 | AC_VERB_GET_PROC_COEF, 0); | 598 | AC_VERB_GET_PROC_COEF, 0); |
599 | return val; | 599 | return val; |
600 | } | 600 | } |
601 | 601 | ||
602 | #define alc_read_coef_idx(codec, coef_idx) \ | 602 | #define alc_read_coef_idx(codec, coef_idx) \ |
603 | alc_read_coefex_idx(codec, 0x20, coef_idx) | 603 | alc_read_coefex_idx(codec, 0x20, coef_idx) |
604 | 604 | ||
605 | static void alc_write_coefex_idx(struct hda_codec *codec, hda_nid_t nid, | 605 | static void alc_write_coefex_idx(struct hda_codec *codec, hda_nid_t nid, |
606 | unsigned int coef_idx, | 606 | unsigned int coef_idx, |
607 | unsigned int coef_val) | 607 | unsigned int coef_val) |
608 | { | 608 | { |
609 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, | 609 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, |
610 | coef_idx); | 610 | coef_idx); |
611 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PROC_COEF, | 611 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PROC_COEF, |
612 | coef_val); | 612 | coef_val); |
613 | } | 613 | } |
614 | 614 | ||
615 | #define alc_write_coef_idx(codec, coef_idx, coef_val) \ | 615 | #define alc_write_coef_idx(codec, coef_idx, coef_val) \ |
616 | alc_write_coefex_idx(codec, 0x20, coef_idx, coef_val) | 616 | alc_write_coefex_idx(codec, 0x20, coef_idx, coef_val) |
617 | 617 | ||
618 | /* a special bypass for COEF 0; read the cached value at the second time */ | 618 | /* a special bypass for COEF 0; read the cached value at the second time */ |
619 | static unsigned int alc_get_coef0(struct hda_codec *codec) | 619 | static unsigned int alc_get_coef0(struct hda_codec *codec) |
620 | { | 620 | { |
621 | struct alc_spec *spec = codec->spec; | 621 | struct alc_spec *spec = codec->spec; |
622 | if (!spec->coef0) | 622 | if (!spec->coef0) |
623 | spec->coef0 = alc_read_coef_idx(codec, 0); | 623 | spec->coef0 = alc_read_coef_idx(codec, 0); |
624 | return spec->coef0; | 624 | return spec->coef0; |
625 | } | 625 | } |
626 | 626 | ||
627 | /* | 627 | /* |
628 | */ | 628 | */ |
629 | 629 | ||
630 | static hda_nid_t get_adc_nid(struct hda_codec *codec, int adc_idx, int imux_idx) | 630 | static hda_nid_t get_adc_nid(struct hda_codec *codec, int adc_idx, int imux_idx) |
631 | { | 631 | { |
632 | struct hda_gen_spec *spec = codec->spec; | 632 | struct hda_gen_spec *spec = codec->spec; |
633 | if (spec->dyn_adc_switch) | 633 | if (spec->dyn_adc_switch) |
634 | adc_idx = spec->dyn_adc_idx[imux_idx]; | 634 | adc_idx = spec->dyn_adc_idx[imux_idx]; |
635 | return spec->adc_nids[adc_idx]; | 635 | return spec->adc_nids[adc_idx]; |
636 | } | 636 | } |
637 | 637 | ||
638 | static void alc_inv_dmic_sync_adc(struct hda_codec *codec, int adc_idx) | 638 | static void alc_inv_dmic_sync_adc(struct hda_codec *codec, int adc_idx) |
639 | { | 639 | { |
640 | struct alc_spec *spec = codec->spec; | 640 | struct alc_spec *spec = codec->spec; |
641 | struct hda_input_mux *imux = &spec->gen.input_mux; | 641 | struct hda_input_mux *imux = &spec->gen.input_mux; |
642 | struct nid_path *path; | 642 | struct nid_path *path; |
643 | hda_nid_t nid; | 643 | hda_nid_t nid; |
644 | int i, dir, parm; | 644 | int i, dir, parm; |
645 | unsigned int val; | 645 | unsigned int val; |
646 | 646 | ||
647 | for (i = 0; i < imux->num_items; i++) { | 647 | for (i = 0; i < imux->num_items; i++) { |
648 | if (spec->gen.imux_pins[i] == spec->inv_dmic_pin) | 648 | if (spec->gen.imux_pins[i] == spec->inv_dmic_pin) |
649 | break; | 649 | break; |
650 | } | 650 | } |
651 | if (i >= imux->num_items) | 651 | if (i >= imux->num_items) |
652 | return; | 652 | return; |
653 | 653 | ||
654 | path = snd_hda_get_nid_path(codec, spec->inv_dmic_pin, | 654 | path = snd_hda_get_nid_path(codec, spec->inv_dmic_pin, |
655 | get_adc_nid(codec, adc_idx, i)); | 655 | get_adc_nid(codec, adc_idx, i)); |
656 | val = path->ctls[NID_PATH_MUTE_CTL]; | 656 | val = path->ctls[NID_PATH_MUTE_CTL]; |
657 | if (!val) | 657 | if (!val) |
658 | return; | 658 | return; |
659 | nid = get_amp_nid_(val); | 659 | nid = get_amp_nid_(val); |
660 | dir = get_amp_direction_(val); | 660 | dir = get_amp_direction_(val); |
661 | parm = AC_AMP_SET_RIGHT | | 661 | parm = AC_AMP_SET_RIGHT | |
662 | (dir == HDA_OUTPUT ? AC_AMP_SET_OUTPUT : AC_AMP_SET_INPUT); | 662 | (dir == HDA_OUTPUT ? AC_AMP_SET_OUTPUT : AC_AMP_SET_INPUT); |
663 | 663 | ||
664 | /* flush all cached amps at first */ | 664 | /* flush all cached amps at first */ |
665 | snd_hda_codec_flush_cache(codec); | 665 | snd_hda_codec_flush_cache(codec); |
666 | 666 | ||
667 | /* we care only right channel */ | 667 | /* we care only right channel */ |
668 | val = snd_hda_codec_amp_read(codec, nid, 1, dir, 0); | 668 | val = snd_hda_codec_amp_read(codec, nid, 1, dir, 0); |
669 | if (val & 0x80) /* if already muted, we don't need to touch */ | 669 | if (val & 0x80) /* if already muted, we don't need to touch */ |
670 | return; | 670 | return; |
671 | val |= 0x80; | 671 | val |= 0x80; |
672 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, | 672 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, |
673 | parm | val); | 673 | parm | val); |
674 | } | 674 | } |
675 | 675 | ||
676 | /* | 676 | /* |
677 | * Inverted digital-mic handling | 677 | * Inverted digital-mic handling |
678 | * | 678 | * |
679 | * First off, it's a bit tricky. The "Inverted Internal Mic Capture Switch" | 679 | * First off, it's a bit tricky. The "Inverted Internal Mic Capture Switch" |
680 | * gives the additional mute only to the right channel of the digital mic | 680 | * gives the additional mute only to the right channel of the digital mic |
681 | * capture stream. This is a workaround for avoiding the almost silence | 681 | * capture stream. This is a workaround for avoiding the almost silence |
682 | * by summing the stereo stream from some (known to be ForteMedia) | 682 | * by summing the stereo stream from some (known to be ForteMedia) |
683 | * digital mic unit. | 683 | * digital mic unit. |
684 | * | 684 | * |
685 | * The logic is to call alc_inv_dmic_sync() after each action (possibly) | 685 | * The logic is to call alc_inv_dmic_sync() after each action (possibly) |
686 | * modifying ADC amp. When the mute flag is set, it mutes the R-channel | 686 | * modifying ADC amp. When the mute flag is set, it mutes the R-channel |
687 | * without caching so that the cache can still keep the original value. | 687 | * without caching so that the cache can still keep the original value. |
688 | * The cached value is then restored when the flag is set off or any other | 688 | * The cached value is then restored when the flag is set off or any other |
689 | * than d-mic is used as the current input source. | 689 | * than d-mic is used as the current input source. |
690 | */ | 690 | */ |
691 | static void alc_inv_dmic_sync(struct hda_codec *codec, bool force) | 691 | static void alc_inv_dmic_sync(struct hda_codec *codec, bool force) |
692 | { | 692 | { |
693 | struct alc_spec *spec = codec->spec; | 693 | struct alc_spec *spec = codec->spec; |
694 | int src, nums; | 694 | int src, nums; |
695 | 695 | ||
696 | if (!spec->inv_dmic_fixup) | 696 | if (!spec->inv_dmic_fixup) |
697 | return; | 697 | return; |
698 | if (!spec->inv_dmic_muted && !force) | 698 | if (!spec->inv_dmic_muted && !force) |
699 | return; | 699 | return; |
700 | nums = spec->gen.dyn_adc_switch ? 1 : spec->gen.num_adc_nids; | 700 | nums = spec->gen.dyn_adc_switch ? 1 : spec->gen.num_adc_nids; |
701 | for (src = 0; src < nums; src++) { | 701 | for (src = 0; src < nums; src++) { |
702 | bool dmic_fixup = false; | 702 | bool dmic_fixup = false; |
703 | 703 | ||
704 | if (spec->inv_dmic_muted && | 704 | if (spec->inv_dmic_muted && |
705 | spec->gen.imux_pins[spec->gen.cur_mux[src]] == spec->inv_dmic_pin) | 705 | spec->gen.imux_pins[spec->gen.cur_mux[src]] == spec->inv_dmic_pin) |
706 | dmic_fixup = true; | 706 | dmic_fixup = true; |
707 | if (!dmic_fixup && !force) | 707 | if (!dmic_fixup && !force) |
708 | continue; | 708 | continue; |
709 | alc_inv_dmic_sync_adc(codec, src); | 709 | alc_inv_dmic_sync_adc(codec, src); |
710 | } | 710 | } |
711 | } | 711 | } |
712 | 712 | ||
713 | static void alc_inv_dmic_hook(struct hda_codec *codec, | 713 | static void alc_inv_dmic_hook(struct hda_codec *codec, |
714 | struct snd_kcontrol *kcontrol, | 714 | struct snd_kcontrol *kcontrol, |
715 | struct snd_ctl_elem_value *ucontrol) | 715 | struct snd_ctl_elem_value *ucontrol) |
716 | { | 716 | { |
717 | alc_inv_dmic_sync(codec, false); | 717 | alc_inv_dmic_sync(codec, false); |
718 | } | 718 | } |
719 | 719 | ||
720 | static int alc_inv_dmic_sw_get(struct snd_kcontrol *kcontrol, | 720 | static int alc_inv_dmic_sw_get(struct snd_kcontrol *kcontrol, |
721 | struct snd_ctl_elem_value *ucontrol) | 721 | struct snd_ctl_elem_value *ucontrol) |
722 | { | 722 | { |
723 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 723 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
724 | struct alc_spec *spec = codec->spec; | 724 | struct alc_spec *spec = codec->spec; |
725 | 725 | ||
726 | ucontrol->value.integer.value[0] = !spec->inv_dmic_muted; | 726 | ucontrol->value.integer.value[0] = !spec->inv_dmic_muted; |
727 | return 0; | 727 | return 0; |
728 | } | 728 | } |
729 | 729 | ||
730 | static int alc_inv_dmic_sw_put(struct snd_kcontrol *kcontrol, | 730 | static int alc_inv_dmic_sw_put(struct snd_kcontrol *kcontrol, |
731 | struct snd_ctl_elem_value *ucontrol) | 731 | struct snd_ctl_elem_value *ucontrol) |
732 | { | 732 | { |
733 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 733 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
734 | struct alc_spec *spec = codec->spec; | 734 | struct alc_spec *spec = codec->spec; |
735 | unsigned int val = !ucontrol->value.integer.value[0]; | 735 | unsigned int val = !ucontrol->value.integer.value[0]; |
736 | 736 | ||
737 | if (val == spec->inv_dmic_muted) | 737 | if (val == spec->inv_dmic_muted) |
738 | return 0; | 738 | return 0; |
739 | spec->inv_dmic_muted = val; | 739 | spec->inv_dmic_muted = val; |
740 | alc_inv_dmic_sync(codec, true); | 740 | alc_inv_dmic_sync(codec, true); |
741 | return 0; | 741 | return 0; |
742 | } | 742 | } |
743 | 743 | ||
744 | static const struct snd_kcontrol_new alc_inv_dmic_sw = { | 744 | static const struct snd_kcontrol_new alc_inv_dmic_sw = { |
745 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 745 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
746 | .name = "Inverted Internal Mic Capture Switch", | 746 | .name = "Inverted Internal Mic Capture Switch", |
747 | .info = snd_ctl_boolean_mono_info, | 747 | .info = snd_ctl_boolean_mono_info, |
748 | .get = alc_inv_dmic_sw_get, | 748 | .get = alc_inv_dmic_sw_get, |
749 | .put = alc_inv_dmic_sw_put, | 749 | .put = alc_inv_dmic_sw_put, |
750 | }; | 750 | }; |
751 | 751 | ||
752 | static int alc_add_inv_dmic_mixer(struct hda_codec *codec, hda_nid_t nid) | 752 | static int alc_add_inv_dmic_mixer(struct hda_codec *codec, hda_nid_t nid) |
753 | { | 753 | { |
754 | struct alc_spec *spec = codec->spec; | 754 | struct alc_spec *spec = codec->spec; |
755 | 755 | ||
756 | if (!snd_hda_gen_add_kctl(&spec->gen, NULL, &alc_inv_dmic_sw)) | 756 | if (!snd_hda_gen_add_kctl(&spec->gen, NULL, &alc_inv_dmic_sw)) |
757 | return -ENOMEM; | 757 | return -ENOMEM; |
758 | spec->inv_dmic_fixup = 1; | 758 | spec->inv_dmic_fixup = 1; |
759 | spec->inv_dmic_muted = 0; | 759 | spec->inv_dmic_muted = 0; |
760 | spec->inv_dmic_pin = nid; | 760 | spec->inv_dmic_pin = nid; |
761 | spec->gen.cap_sync_hook = alc_inv_dmic_hook; | 761 | spec->gen.cap_sync_hook = alc_inv_dmic_hook; |
762 | return 0; | 762 | return 0; |
763 | } | 763 | } |
764 | 764 | ||
765 | /* typically the digital mic is put at node 0x12 */ | 765 | /* typically the digital mic is put at node 0x12 */ |
766 | static void alc_fixup_inv_dmic_0x12(struct hda_codec *codec, | 766 | static void alc_fixup_inv_dmic_0x12(struct hda_codec *codec, |
767 | const struct hda_fixup *fix, int action) | 767 | const struct hda_fixup *fix, int action) |
768 | { | 768 | { |
769 | if (action == HDA_FIXUP_ACT_PROBE) | 769 | if (action == HDA_FIXUP_ACT_PROBE) |
770 | alc_add_inv_dmic_mixer(codec, 0x12); | 770 | alc_add_inv_dmic_mixer(codec, 0x12); |
771 | } | 771 | } |
772 | 772 | ||
773 | 773 | ||
774 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | 774 | #ifdef CONFIG_SND_HDA_INPUT_BEEP |
775 | /* additional beep mixers; the actual parameters are overwritten at build */ | 775 | /* additional beep mixers; the actual parameters are overwritten at build */ |
776 | static const struct snd_kcontrol_new alc_beep_mixer[] = { | 776 | static const struct snd_kcontrol_new alc_beep_mixer[] = { |
777 | HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT), | 777 | HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT), |
778 | HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT), | 778 | HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT), |
779 | { } /* end */ | 779 | { } /* end */ |
780 | }; | 780 | }; |
781 | #endif | 781 | #endif |
782 | 782 | ||
783 | static int alc_build_controls(struct hda_codec *codec) | 783 | static int alc_build_controls(struct hda_codec *codec) |
784 | { | 784 | { |
785 | struct alc_spec *spec = codec->spec; | 785 | struct alc_spec *spec = codec->spec; |
786 | int i, err; | 786 | int i, err; |
787 | 787 | ||
788 | err = snd_hda_gen_build_controls(codec); | 788 | err = snd_hda_gen_build_controls(codec); |
789 | if (err < 0) | 789 | if (err < 0) |
790 | return err; | 790 | return err; |
791 | 791 | ||
792 | for (i = 0; i < spec->num_mixers; i++) { | 792 | for (i = 0; i < spec->num_mixers; i++) { |
793 | err = snd_hda_add_new_ctls(codec, spec->mixers[i]); | 793 | err = snd_hda_add_new_ctls(codec, spec->mixers[i]); |
794 | if (err < 0) | 794 | if (err < 0) |
795 | return err; | 795 | return err; |
796 | } | 796 | } |
797 | 797 | ||
798 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | 798 | #ifdef CONFIG_SND_HDA_INPUT_BEEP |
799 | /* create beep controls if needed */ | 799 | /* create beep controls if needed */ |
800 | if (spec->beep_amp) { | 800 | if (spec->beep_amp) { |
801 | const struct snd_kcontrol_new *knew; | 801 | const struct snd_kcontrol_new *knew; |
802 | for (knew = alc_beep_mixer; knew->name; knew++) { | 802 | for (knew = alc_beep_mixer; knew->name; knew++) { |
803 | struct snd_kcontrol *kctl; | 803 | struct snd_kcontrol *kctl; |
804 | kctl = snd_ctl_new1(knew, codec); | 804 | kctl = snd_ctl_new1(knew, codec); |
805 | if (!kctl) | 805 | if (!kctl) |
806 | return -ENOMEM; | 806 | return -ENOMEM; |
807 | kctl->private_value = spec->beep_amp; | 807 | kctl->private_value = spec->beep_amp; |
808 | err = snd_hda_ctl_add(codec, 0, kctl); | 808 | err = snd_hda_ctl_add(codec, 0, kctl); |
809 | if (err < 0) | 809 | if (err < 0) |
810 | return err; | 810 | return err; |
811 | } | 811 | } |
812 | } | 812 | } |
813 | #endif | 813 | #endif |
814 | 814 | ||
815 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_BUILD); | 815 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_BUILD); |
816 | return 0; | 816 | return 0; |
817 | } | 817 | } |
818 | 818 | ||
819 | 819 | ||
820 | /* | 820 | /* |
821 | * Common callbacks | 821 | * Common callbacks |
822 | */ | 822 | */ |
823 | 823 | ||
824 | static int alc_init(struct hda_codec *codec) | 824 | static int alc_init(struct hda_codec *codec) |
825 | { | 825 | { |
826 | struct alc_spec *spec = codec->spec; | 826 | struct alc_spec *spec = codec->spec; |
827 | 827 | ||
828 | if (spec->init_hook) | 828 | if (spec->init_hook) |
829 | spec->init_hook(codec); | 829 | spec->init_hook(codec); |
830 | 830 | ||
831 | alc_fix_pll(codec); | 831 | alc_fix_pll(codec); |
832 | alc_auto_init_amp(codec, spec->init_amp); | 832 | alc_auto_init_amp(codec, spec->init_amp); |
833 | 833 | ||
834 | snd_hda_gen_init(codec); | 834 | snd_hda_gen_init(codec); |
835 | 835 | ||
836 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_INIT); | 836 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_INIT); |
837 | 837 | ||
838 | return 0; | 838 | return 0; |
839 | } | 839 | } |
840 | 840 | ||
841 | static inline void alc_shutup(struct hda_codec *codec) | 841 | static inline void alc_shutup(struct hda_codec *codec) |
842 | { | 842 | { |
843 | struct alc_spec *spec = codec->spec; | 843 | struct alc_spec *spec = codec->spec; |
844 | 844 | ||
845 | if (spec && spec->shutup) | 845 | if (spec && spec->shutup) |
846 | spec->shutup(codec); | 846 | spec->shutup(codec); |
847 | else | 847 | else |
848 | snd_hda_shutup_pins(codec); | 848 | snd_hda_shutup_pins(codec); |
849 | } | 849 | } |
850 | 850 | ||
851 | #define alc_free snd_hda_gen_free | 851 | #define alc_free snd_hda_gen_free |
852 | 852 | ||
853 | #ifdef CONFIG_PM | 853 | #ifdef CONFIG_PM |
854 | static void alc_power_eapd(struct hda_codec *codec) | 854 | static void alc_power_eapd(struct hda_codec *codec) |
855 | { | 855 | { |
856 | alc_auto_setup_eapd(codec, false); | 856 | alc_auto_setup_eapd(codec, false); |
857 | } | 857 | } |
858 | 858 | ||
859 | static int alc_suspend(struct hda_codec *codec) | 859 | static int alc_suspend(struct hda_codec *codec) |
860 | { | 860 | { |
861 | struct alc_spec *spec = codec->spec; | 861 | struct alc_spec *spec = codec->spec; |
862 | alc_shutup(codec); | 862 | alc_shutup(codec); |
863 | if (spec && spec->power_hook) | 863 | if (spec && spec->power_hook) |
864 | spec->power_hook(codec); | 864 | spec->power_hook(codec); |
865 | return 0; | 865 | return 0; |
866 | } | 866 | } |
867 | #endif | 867 | #endif |
868 | 868 | ||
869 | #ifdef CONFIG_PM | 869 | #ifdef CONFIG_PM |
870 | static int alc_resume(struct hda_codec *codec) | 870 | static int alc_resume(struct hda_codec *codec) |
871 | { | 871 | { |
872 | struct alc_spec *spec = codec->spec; | 872 | struct alc_spec *spec = codec->spec; |
873 | 873 | ||
874 | if (!spec->no_depop_delay) | 874 | if (!spec->no_depop_delay) |
875 | msleep(150); /* to avoid pop noise */ | 875 | msleep(150); /* to avoid pop noise */ |
876 | codec->patch_ops.init(codec); | 876 | codec->patch_ops.init(codec); |
877 | snd_hda_codec_resume_amp(codec); | 877 | snd_hda_codec_resume_amp(codec); |
878 | snd_hda_codec_resume_cache(codec); | 878 | snd_hda_codec_resume_cache(codec); |
879 | alc_inv_dmic_sync(codec, true); | 879 | alc_inv_dmic_sync(codec, true); |
880 | hda_call_check_power_status(codec, 0x01); | 880 | hda_call_check_power_status(codec, 0x01); |
881 | return 0; | 881 | return 0; |
882 | } | 882 | } |
883 | #endif | 883 | #endif |
884 | 884 | ||
885 | /* | 885 | /* |
886 | */ | 886 | */ |
887 | static const struct hda_codec_ops alc_patch_ops = { | 887 | static const struct hda_codec_ops alc_patch_ops = { |
888 | .build_controls = alc_build_controls, | 888 | .build_controls = alc_build_controls, |
889 | .build_pcms = snd_hda_gen_build_pcms, | 889 | .build_pcms = snd_hda_gen_build_pcms, |
890 | .init = alc_init, | 890 | .init = alc_init, |
891 | .free = alc_free, | 891 | .free = alc_free, |
892 | .unsol_event = snd_hda_jack_unsol_event, | 892 | .unsol_event = snd_hda_jack_unsol_event, |
893 | #ifdef CONFIG_PM | 893 | #ifdef CONFIG_PM |
894 | .resume = alc_resume, | 894 | .resume = alc_resume, |
895 | .suspend = alc_suspend, | 895 | .suspend = alc_suspend, |
896 | .check_power_status = snd_hda_gen_check_power_status, | 896 | .check_power_status = snd_hda_gen_check_power_status, |
897 | #endif | 897 | #endif |
898 | .reboot_notify = alc_shutup, | 898 | .reboot_notify = alc_shutup, |
899 | }; | 899 | }; |
900 | 900 | ||
901 | 901 | ||
902 | /* replace the codec chip_name with the given string */ | 902 | /* replace the codec chip_name with the given string */ |
903 | static int alc_codec_rename(struct hda_codec *codec, const char *name) | 903 | static int alc_codec_rename(struct hda_codec *codec, const char *name) |
904 | { | 904 | { |
905 | kfree(codec->chip_name); | 905 | kfree(codec->chip_name); |
906 | codec->chip_name = kstrdup(name, GFP_KERNEL); | 906 | codec->chip_name = kstrdup(name, GFP_KERNEL); |
907 | if (!codec->chip_name) { | 907 | if (!codec->chip_name) { |
908 | alc_free(codec); | 908 | alc_free(codec); |
909 | return -ENOMEM; | 909 | return -ENOMEM; |
910 | } | 910 | } |
911 | return 0; | 911 | return 0; |
912 | } | 912 | } |
913 | 913 | ||
914 | /* | 914 | /* |
915 | * Rename codecs appropriately from COEF value or subvendor id | 915 | * Rename codecs appropriately from COEF value or subvendor id |
916 | */ | 916 | */ |
917 | struct alc_codec_rename_table { | 917 | struct alc_codec_rename_table { |
918 | unsigned int vendor_id; | 918 | unsigned int vendor_id; |
919 | unsigned short coef_mask; | 919 | unsigned short coef_mask; |
920 | unsigned short coef_bits; | 920 | unsigned short coef_bits; |
921 | const char *name; | 921 | const char *name; |
922 | }; | 922 | }; |
923 | 923 | ||
924 | struct alc_codec_rename_pci_table { | 924 | struct alc_codec_rename_pci_table { |
925 | unsigned int codec_vendor_id; | 925 | unsigned int codec_vendor_id; |
926 | unsigned short pci_subvendor; | 926 | unsigned short pci_subvendor; |
927 | unsigned short pci_subdevice; | 927 | unsigned short pci_subdevice; |
928 | const char *name; | 928 | const char *name; |
929 | }; | 929 | }; |
930 | 930 | ||
931 | static struct alc_codec_rename_table rename_tbl[] = { | 931 | static struct alc_codec_rename_table rename_tbl[] = { |
932 | { 0x10ec0269, 0xfff0, 0x3010, "ALC277" }, | 932 | { 0x10ec0269, 0xfff0, 0x3010, "ALC277" }, |
933 | { 0x10ec0269, 0xf0f0, 0x2010, "ALC259" }, | 933 | { 0x10ec0269, 0xf0f0, 0x2010, "ALC259" }, |
934 | { 0x10ec0269, 0xf0f0, 0x3010, "ALC258" }, | 934 | { 0x10ec0269, 0xf0f0, 0x3010, "ALC258" }, |
935 | { 0x10ec0269, 0x00f0, 0x0010, "ALC269VB" }, | 935 | { 0x10ec0269, 0x00f0, 0x0010, "ALC269VB" }, |
936 | { 0x10ec0269, 0xffff, 0xa023, "ALC259" }, | 936 | { 0x10ec0269, 0xffff, 0xa023, "ALC259" }, |
937 | { 0x10ec0269, 0xffff, 0x6023, "ALC281X" }, | 937 | { 0x10ec0269, 0xffff, 0x6023, "ALC281X" }, |
938 | { 0x10ec0269, 0x00f0, 0x0020, "ALC269VC" }, | 938 | { 0x10ec0269, 0x00f0, 0x0020, "ALC269VC" }, |
939 | { 0x10ec0269, 0x00f0, 0x0030, "ALC269VD" }, | 939 | { 0x10ec0269, 0x00f0, 0x0030, "ALC269VD" }, |
940 | { 0x10ec0887, 0x00f0, 0x0030, "ALC887-VD" }, | 940 | { 0x10ec0887, 0x00f0, 0x0030, "ALC887-VD" }, |
941 | { 0x10ec0888, 0x00f0, 0x0030, "ALC888-VD" }, | 941 | { 0x10ec0888, 0x00f0, 0x0030, "ALC888-VD" }, |
942 | { 0x10ec0888, 0xf0f0, 0x3020, "ALC886" }, | 942 | { 0x10ec0888, 0xf0f0, 0x3020, "ALC886" }, |
943 | { 0x10ec0899, 0x2000, 0x2000, "ALC899" }, | 943 | { 0x10ec0899, 0x2000, 0x2000, "ALC899" }, |
944 | { 0x10ec0892, 0xffff, 0x8020, "ALC661" }, | 944 | { 0x10ec0892, 0xffff, 0x8020, "ALC661" }, |
945 | { 0x10ec0892, 0xffff, 0x8011, "ALC661" }, | 945 | { 0x10ec0892, 0xffff, 0x8011, "ALC661" }, |
946 | { 0x10ec0892, 0xffff, 0x4011, "ALC656" }, | 946 | { 0x10ec0892, 0xffff, 0x4011, "ALC656" }, |
947 | { } /* terminator */ | 947 | { } /* terminator */ |
948 | }; | 948 | }; |
949 | 949 | ||
950 | static struct alc_codec_rename_pci_table rename_pci_tbl[] = { | 950 | static struct alc_codec_rename_pci_table rename_pci_tbl[] = { |
951 | { 0x10ec0280, 0x1028, 0, "ALC3220" }, | 951 | { 0x10ec0280, 0x1028, 0, "ALC3220" }, |
952 | { 0x10ec0282, 0x1028, 0, "ALC3221" }, | 952 | { 0x10ec0282, 0x1028, 0, "ALC3221" }, |
953 | { 0x10ec0283, 0x1028, 0, "ALC3223" }, | 953 | { 0x10ec0283, 0x1028, 0, "ALC3223" }, |
954 | { 0x10ec0292, 0x1028, 0, "ALC3226" }, | 954 | { 0x10ec0292, 0x1028, 0, "ALC3226" }, |
955 | { 0x10ec0255, 0x1028, 0, "ALC3234" }, | 955 | { 0x10ec0255, 0x1028, 0, "ALC3234" }, |
956 | { 0x10ec0668, 0x1028, 0, "ALC3661" }, | 956 | { 0x10ec0668, 0x1028, 0, "ALC3661" }, |
957 | { } /* terminator */ | 957 | { } /* terminator */ |
958 | }; | 958 | }; |
959 | 959 | ||
960 | static int alc_codec_rename_from_preset(struct hda_codec *codec) | 960 | static int alc_codec_rename_from_preset(struct hda_codec *codec) |
961 | { | 961 | { |
962 | const struct alc_codec_rename_table *p; | 962 | const struct alc_codec_rename_table *p; |
963 | const struct alc_codec_rename_pci_table *q; | 963 | const struct alc_codec_rename_pci_table *q; |
964 | 964 | ||
965 | for (p = rename_tbl; p->vendor_id; p++) { | 965 | for (p = rename_tbl; p->vendor_id; p++) { |
966 | if (p->vendor_id != codec->vendor_id) | 966 | if (p->vendor_id != codec->vendor_id) |
967 | continue; | 967 | continue; |
968 | if ((alc_get_coef0(codec) & p->coef_mask) == p->coef_bits) | 968 | if ((alc_get_coef0(codec) & p->coef_mask) == p->coef_bits) |
969 | return alc_codec_rename(codec, p->name); | 969 | return alc_codec_rename(codec, p->name); |
970 | } | 970 | } |
971 | 971 | ||
972 | if (!codec->bus->pci) | 972 | if (!codec->bus->pci) |
973 | return 0; | 973 | return 0; |
974 | for (q = rename_pci_tbl; q->codec_vendor_id; q++) { | 974 | for (q = rename_pci_tbl; q->codec_vendor_id; q++) { |
975 | if (q->codec_vendor_id != codec->vendor_id) | 975 | if (q->codec_vendor_id != codec->vendor_id) |
976 | continue; | 976 | continue; |
977 | if (q->pci_subvendor != codec->bus->pci->subsystem_vendor) | 977 | if (q->pci_subvendor != codec->bus->pci->subsystem_vendor) |
978 | continue; | 978 | continue; |
979 | if (!q->pci_subdevice || | 979 | if (!q->pci_subdevice || |
980 | q->pci_subdevice == codec->bus->pci->subsystem_device) | 980 | q->pci_subdevice == codec->bus->pci->subsystem_device) |
981 | return alc_codec_rename(codec, q->name); | 981 | return alc_codec_rename(codec, q->name); |
982 | } | 982 | } |
983 | 983 | ||
984 | return 0; | 984 | return 0; |
985 | } | 985 | } |
986 | 986 | ||
987 | 987 | ||
988 | /* | 988 | /* |
989 | * Digital-beep handlers | 989 | * Digital-beep handlers |
990 | */ | 990 | */ |
991 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | 991 | #ifdef CONFIG_SND_HDA_INPUT_BEEP |
992 | #define set_beep_amp(spec, nid, idx, dir) \ | 992 | #define set_beep_amp(spec, nid, idx, dir) \ |
993 | ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir)) | 993 | ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir)) |
994 | 994 | ||
995 | static const struct snd_pci_quirk beep_white_list[] = { | 995 | static const struct snd_pci_quirk beep_white_list[] = { |
996 | SND_PCI_QUIRK(0x1043, 0x103c, "ASUS", 1), | 996 | SND_PCI_QUIRK(0x1043, 0x103c, "ASUS", 1), |
997 | SND_PCI_QUIRK(0x1043, 0x115d, "ASUS", 1), | 997 | SND_PCI_QUIRK(0x1043, 0x115d, "ASUS", 1), |
998 | SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1), | 998 | SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1), |
999 | SND_PCI_QUIRK(0x1043, 0x8376, "EeePC", 1), | 999 | SND_PCI_QUIRK(0x1043, 0x8376, "EeePC", 1), |
1000 | SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1), | 1000 | SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1), |
1001 | SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1), | 1001 | SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1), |
1002 | SND_PCI_QUIRK(0x1043, 0x834a, "EeePC", 1), | 1002 | SND_PCI_QUIRK(0x1043, 0x834a, "EeePC", 1), |
1003 | SND_PCI_QUIRK(0x1458, 0xa002, "GA-MA790X", 1), | 1003 | SND_PCI_QUIRK(0x1458, 0xa002, "GA-MA790X", 1), |
1004 | SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1), | 1004 | SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1), |
1005 | {} | 1005 | {} |
1006 | }; | 1006 | }; |
1007 | 1007 | ||
1008 | static inline int has_cdefine_beep(struct hda_codec *codec) | 1008 | static inline int has_cdefine_beep(struct hda_codec *codec) |
1009 | { | 1009 | { |
1010 | struct alc_spec *spec = codec->spec; | 1010 | struct alc_spec *spec = codec->spec; |
1011 | const struct snd_pci_quirk *q; | 1011 | const struct snd_pci_quirk *q; |
1012 | q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list); | 1012 | q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list); |
1013 | if (q) | 1013 | if (q) |
1014 | return q->value; | 1014 | return q->value; |
1015 | return spec->cdefine.enable_pcbeep; | 1015 | return spec->cdefine.enable_pcbeep; |
1016 | } | 1016 | } |
1017 | #else | 1017 | #else |
1018 | #define set_beep_amp(spec, nid, idx, dir) /* NOP */ | 1018 | #define set_beep_amp(spec, nid, idx, dir) /* NOP */ |
1019 | #define has_cdefine_beep(codec) 0 | 1019 | #define has_cdefine_beep(codec) 0 |
1020 | #endif | 1020 | #endif |
1021 | 1021 | ||
1022 | /* parse the BIOS configuration and set up the alc_spec */ | 1022 | /* parse the BIOS configuration and set up the alc_spec */ |
1023 | /* return 1 if successful, 0 if the proper config is not found, | 1023 | /* return 1 if successful, 0 if the proper config is not found, |
1024 | * or a negative error code | 1024 | * or a negative error code |
1025 | */ | 1025 | */ |
1026 | static int alc_parse_auto_config(struct hda_codec *codec, | 1026 | static int alc_parse_auto_config(struct hda_codec *codec, |
1027 | const hda_nid_t *ignore_nids, | 1027 | const hda_nid_t *ignore_nids, |
1028 | const hda_nid_t *ssid_nids) | 1028 | const hda_nid_t *ssid_nids) |
1029 | { | 1029 | { |
1030 | struct alc_spec *spec = codec->spec; | 1030 | struct alc_spec *spec = codec->spec; |
1031 | struct auto_pin_cfg *cfg = &spec->gen.autocfg; | 1031 | struct auto_pin_cfg *cfg = &spec->gen.autocfg; |
1032 | int err; | 1032 | int err; |
1033 | 1033 | ||
1034 | err = snd_hda_parse_pin_defcfg(codec, cfg, ignore_nids, | 1034 | err = snd_hda_parse_pin_defcfg(codec, cfg, ignore_nids, |
1035 | spec->parse_flags); | 1035 | spec->parse_flags); |
1036 | if (err < 0) | 1036 | if (err < 0) |
1037 | return err; | 1037 | return err; |
1038 | 1038 | ||
1039 | if (ssid_nids) | 1039 | if (ssid_nids) |
1040 | alc_ssid_check(codec, ssid_nids); | 1040 | alc_ssid_check(codec, ssid_nids); |
1041 | 1041 | ||
1042 | err = snd_hda_gen_parse_auto_config(codec, cfg); | 1042 | err = snd_hda_gen_parse_auto_config(codec, cfg); |
1043 | if (err < 0) | 1043 | if (err < 0) |
1044 | return err; | 1044 | return err; |
1045 | 1045 | ||
1046 | return 1; | 1046 | return 1; |
1047 | } | 1047 | } |
1048 | 1048 | ||
1049 | /* common preparation job for alc_spec */ | 1049 | /* common preparation job for alc_spec */ |
1050 | static int alc_alloc_spec(struct hda_codec *codec, hda_nid_t mixer_nid) | 1050 | static int alc_alloc_spec(struct hda_codec *codec, hda_nid_t mixer_nid) |
1051 | { | 1051 | { |
1052 | struct alc_spec *spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 1052 | struct alc_spec *spec = kzalloc(sizeof(*spec), GFP_KERNEL); |
1053 | int err; | 1053 | int err; |
1054 | 1054 | ||
1055 | if (!spec) | 1055 | if (!spec) |
1056 | return -ENOMEM; | 1056 | return -ENOMEM; |
1057 | codec->spec = spec; | 1057 | codec->spec = spec; |
1058 | snd_hda_gen_spec_init(&spec->gen); | 1058 | snd_hda_gen_spec_init(&spec->gen); |
1059 | spec->gen.mixer_nid = mixer_nid; | 1059 | spec->gen.mixer_nid = mixer_nid; |
1060 | spec->gen.own_eapd_ctl = 1; | 1060 | spec->gen.own_eapd_ctl = 1; |
1061 | codec->single_adc_amp = 1; | 1061 | codec->single_adc_amp = 1; |
1062 | /* FIXME: do we need this for all Realtek codec models? */ | 1062 | /* FIXME: do we need this for all Realtek codec models? */ |
1063 | codec->spdif_status_reset = 1; | 1063 | codec->spdif_status_reset = 1; |
1064 | 1064 | ||
1065 | err = alc_codec_rename_from_preset(codec); | 1065 | err = alc_codec_rename_from_preset(codec); |
1066 | if (err < 0) { | 1066 | if (err < 0) { |
1067 | kfree(spec); | 1067 | kfree(spec); |
1068 | return err; | 1068 | return err; |
1069 | } | 1069 | } |
1070 | return 0; | 1070 | return 0; |
1071 | } | 1071 | } |
1072 | 1072 | ||
1073 | static int alc880_parse_auto_config(struct hda_codec *codec) | 1073 | static int alc880_parse_auto_config(struct hda_codec *codec) |
1074 | { | 1074 | { |
1075 | static const hda_nid_t alc880_ignore[] = { 0x1d, 0 }; | 1075 | static const hda_nid_t alc880_ignore[] = { 0x1d, 0 }; |
1076 | static const hda_nid_t alc880_ssids[] = { 0x15, 0x1b, 0x14, 0 }; | 1076 | static const hda_nid_t alc880_ssids[] = { 0x15, 0x1b, 0x14, 0 }; |
1077 | return alc_parse_auto_config(codec, alc880_ignore, alc880_ssids); | 1077 | return alc_parse_auto_config(codec, alc880_ignore, alc880_ssids); |
1078 | } | 1078 | } |
1079 | 1079 | ||
1080 | /* | 1080 | /* |
1081 | * ALC880 fix-ups | 1081 | * ALC880 fix-ups |
1082 | */ | 1082 | */ |
1083 | enum { | 1083 | enum { |
1084 | ALC880_FIXUP_GPIO1, | 1084 | ALC880_FIXUP_GPIO1, |
1085 | ALC880_FIXUP_GPIO2, | 1085 | ALC880_FIXUP_GPIO2, |
1086 | ALC880_FIXUP_MEDION_RIM, | 1086 | ALC880_FIXUP_MEDION_RIM, |
1087 | ALC880_FIXUP_LG, | 1087 | ALC880_FIXUP_LG, |
1088 | ALC880_FIXUP_LG_LW25, | 1088 | ALC880_FIXUP_LG_LW25, |
1089 | ALC880_FIXUP_W810, | 1089 | ALC880_FIXUP_W810, |
1090 | ALC880_FIXUP_EAPD_COEF, | 1090 | ALC880_FIXUP_EAPD_COEF, |
1091 | ALC880_FIXUP_TCL_S700, | 1091 | ALC880_FIXUP_TCL_S700, |
1092 | ALC880_FIXUP_VOL_KNOB, | 1092 | ALC880_FIXUP_VOL_KNOB, |
1093 | ALC880_FIXUP_FUJITSU, | 1093 | ALC880_FIXUP_FUJITSU, |
1094 | ALC880_FIXUP_F1734, | 1094 | ALC880_FIXUP_F1734, |
1095 | ALC880_FIXUP_UNIWILL, | 1095 | ALC880_FIXUP_UNIWILL, |
1096 | ALC880_FIXUP_UNIWILL_DIG, | 1096 | ALC880_FIXUP_UNIWILL_DIG, |
1097 | ALC880_FIXUP_Z71V, | 1097 | ALC880_FIXUP_Z71V, |
1098 | ALC880_FIXUP_ASUS_W5A, | 1098 | ALC880_FIXUP_ASUS_W5A, |
1099 | ALC880_FIXUP_3ST_BASE, | 1099 | ALC880_FIXUP_3ST_BASE, |
1100 | ALC880_FIXUP_3ST, | 1100 | ALC880_FIXUP_3ST, |
1101 | ALC880_FIXUP_3ST_DIG, | 1101 | ALC880_FIXUP_3ST_DIG, |
1102 | ALC880_FIXUP_5ST_BASE, | 1102 | ALC880_FIXUP_5ST_BASE, |
1103 | ALC880_FIXUP_5ST, | 1103 | ALC880_FIXUP_5ST, |
1104 | ALC880_FIXUP_5ST_DIG, | 1104 | ALC880_FIXUP_5ST_DIG, |
1105 | ALC880_FIXUP_6ST_BASE, | 1105 | ALC880_FIXUP_6ST_BASE, |
1106 | ALC880_FIXUP_6ST, | 1106 | ALC880_FIXUP_6ST, |
1107 | ALC880_FIXUP_6ST_DIG, | 1107 | ALC880_FIXUP_6ST_DIG, |
1108 | ALC880_FIXUP_6ST_AUTOMUTE, | 1108 | ALC880_FIXUP_6ST_AUTOMUTE, |
1109 | }; | 1109 | }; |
1110 | 1110 | ||
1111 | /* enable the volume-knob widget support on NID 0x21 */ | 1111 | /* enable the volume-knob widget support on NID 0x21 */ |
1112 | static void alc880_fixup_vol_knob(struct hda_codec *codec, | 1112 | static void alc880_fixup_vol_knob(struct hda_codec *codec, |
1113 | const struct hda_fixup *fix, int action) | 1113 | const struct hda_fixup *fix, int action) |
1114 | { | 1114 | { |
1115 | if (action == HDA_FIXUP_ACT_PROBE) | 1115 | if (action == HDA_FIXUP_ACT_PROBE) |
1116 | snd_hda_jack_detect_enable_callback(codec, 0x21, ALC_DCVOL_EVENT, alc_update_knob_master); | 1116 | snd_hda_jack_detect_enable_callback(codec, 0x21, ALC_DCVOL_EVENT, alc_update_knob_master); |
1117 | } | 1117 | } |
1118 | 1118 | ||
1119 | static const struct hda_fixup alc880_fixups[] = { | 1119 | static const struct hda_fixup alc880_fixups[] = { |
1120 | [ALC880_FIXUP_GPIO1] = { | 1120 | [ALC880_FIXUP_GPIO1] = { |
1121 | .type = HDA_FIXUP_VERBS, | 1121 | .type = HDA_FIXUP_VERBS, |
1122 | .v.verbs = alc_gpio1_init_verbs, | 1122 | .v.verbs = alc_gpio1_init_verbs, |
1123 | }, | 1123 | }, |
1124 | [ALC880_FIXUP_GPIO2] = { | 1124 | [ALC880_FIXUP_GPIO2] = { |
1125 | .type = HDA_FIXUP_VERBS, | 1125 | .type = HDA_FIXUP_VERBS, |
1126 | .v.verbs = alc_gpio2_init_verbs, | 1126 | .v.verbs = alc_gpio2_init_verbs, |
1127 | }, | 1127 | }, |
1128 | [ALC880_FIXUP_MEDION_RIM] = { | 1128 | [ALC880_FIXUP_MEDION_RIM] = { |
1129 | .type = HDA_FIXUP_VERBS, | 1129 | .type = HDA_FIXUP_VERBS, |
1130 | .v.verbs = (const struct hda_verb[]) { | 1130 | .v.verbs = (const struct hda_verb[]) { |
1131 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, | 1131 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, |
1132 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 }, | 1132 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 }, |
1133 | { } | 1133 | { } |
1134 | }, | 1134 | }, |
1135 | .chained = true, | 1135 | .chained = true, |
1136 | .chain_id = ALC880_FIXUP_GPIO2, | 1136 | .chain_id = ALC880_FIXUP_GPIO2, |
1137 | }, | 1137 | }, |
1138 | [ALC880_FIXUP_LG] = { | 1138 | [ALC880_FIXUP_LG] = { |
1139 | .type = HDA_FIXUP_PINS, | 1139 | .type = HDA_FIXUP_PINS, |
1140 | .v.pins = (const struct hda_pintbl[]) { | 1140 | .v.pins = (const struct hda_pintbl[]) { |
1141 | /* disable bogus unused pins */ | 1141 | /* disable bogus unused pins */ |
1142 | { 0x16, 0x411111f0 }, | 1142 | { 0x16, 0x411111f0 }, |
1143 | { 0x18, 0x411111f0 }, | 1143 | { 0x18, 0x411111f0 }, |
1144 | { 0x1a, 0x411111f0 }, | 1144 | { 0x1a, 0x411111f0 }, |
1145 | { } | 1145 | { } |
1146 | } | 1146 | } |
1147 | }, | 1147 | }, |
1148 | [ALC880_FIXUP_LG_LW25] = { | 1148 | [ALC880_FIXUP_LG_LW25] = { |
1149 | .type = HDA_FIXUP_PINS, | 1149 | .type = HDA_FIXUP_PINS, |
1150 | .v.pins = (const struct hda_pintbl[]) { | 1150 | .v.pins = (const struct hda_pintbl[]) { |
1151 | { 0x1a, 0x0181344f }, /* line-in */ | 1151 | { 0x1a, 0x0181344f }, /* line-in */ |
1152 | { 0x1b, 0x0321403f }, /* headphone */ | 1152 | { 0x1b, 0x0321403f }, /* headphone */ |
1153 | { } | 1153 | { } |
1154 | } | 1154 | } |
1155 | }, | 1155 | }, |
1156 | [ALC880_FIXUP_W810] = { | 1156 | [ALC880_FIXUP_W810] = { |
1157 | .type = HDA_FIXUP_PINS, | 1157 | .type = HDA_FIXUP_PINS, |
1158 | .v.pins = (const struct hda_pintbl[]) { | 1158 | .v.pins = (const struct hda_pintbl[]) { |
1159 | /* disable bogus unused pins */ | 1159 | /* disable bogus unused pins */ |
1160 | { 0x17, 0x411111f0 }, | 1160 | { 0x17, 0x411111f0 }, |
1161 | { } | 1161 | { } |
1162 | }, | 1162 | }, |
1163 | .chained = true, | 1163 | .chained = true, |
1164 | .chain_id = ALC880_FIXUP_GPIO2, | 1164 | .chain_id = ALC880_FIXUP_GPIO2, |
1165 | }, | 1165 | }, |
1166 | [ALC880_FIXUP_EAPD_COEF] = { | 1166 | [ALC880_FIXUP_EAPD_COEF] = { |
1167 | .type = HDA_FIXUP_VERBS, | 1167 | .type = HDA_FIXUP_VERBS, |
1168 | .v.verbs = (const struct hda_verb[]) { | 1168 | .v.verbs = (const struct hda_verb[]) { |
1169 | /* change to EAPD mode */ | 1169 | /* change to EAPD mode */ |
1170 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, | 1170 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, |
1171 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 }, | 1171 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 }, |
1172 | {} | 1172 | {} |
1173 | }, | 1173 | }, |
1174 | }, | 1174 | }, |
1175 | [ALC880_FIXUP_TCL_S700] = { | 1175 | [ALC880_FIXUP_TCL_S700] = { |
1176 | .type = HDA_FIXUP_VERBS, | 1176 | .type = HDA_FIXUP_VERBS, |
1177 | .v.verbs = (const struct hda_verb[]) { | 1177 | .v.verbs = (const struct hda_verb[]) { |
1178 | /* change to EAPD mode */ | 1178 | /* change to EAPD mode */ |
1179 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, | 1179 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, |
1180 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 }, | 1180 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 }, |
1181 | {} | 1181 | {} |
1182 | }, | 1182 | }, |
1183 | .chained = true, | 1183 | .chained = true, |
1184 | .chain_id = ALC880_FIXUP_GPIO2, | 1184 | .chain_id = ALC880_FIXUP_GPIO2, |
1185 | }, | 1185 | }, |
1186 | [ALC880_FIXUP_VOL_KNOB] = { | 1186 | [ALC880_FIXUP_VOL_KNOB] = { |
1187 | .type = HDA_FIXUP_FUNC, | 1187 | .type = HDA_FIXUP_FUNC, |
1188 | .v.func = alc880_fixup_vol_knob, | 1188 | .v.func = alc880_fixup_vol_knob, |
1189 | }, | 1189 | }, |
1190 | [ALC880_FIXUP_FUJITSU] = { | 1190 | [ALC880_FIXUP_FUJITSU] = { |
1191 | /* override all pins as BIOS on old Amilo is broken */ | 1191 | /* override all pins as BIOS on old Amilo is broken */ |
1192 | .type = HDA_FIXUP_PINS, | 1192 | .type = HDA_FIXUP_PINS, |
1193 | .v.pins = (const struct hda_pintbl[]) { | 1193 | .v.pins = (const struct hda_pintbl[]) { |
1194 | { 0x14, 0x0121411f }, /* HP */ | 1194 | { 0x14, 0x0121411f }, /* HP */ |
1195 | { 0x15, 0x99030120 }, /* speaker */ | 1195 | { 0x15, 0x99030120 }, /* speaker */ |
1196 | { 0x16, 0x99030130 }, /* bass speaker */ | 1196 | { 0x16, 0x99030130 }, /* bass speaker */ |
1197 | { 0x17, 0x411111f0 }, /* N/A */ | 1197 | { 0x17, 0x411111f0 }, /* N/A */ |
1198 | { 0x18, 0x411111f0 }, /* N/A */ | 1198 | { 0x18, 0x411111f0 }, /* N/A */ |
1199 | { 0x19, 0x01a19950 }, /* mic-in */ | 1199 | { 0x19, 0x01a19950 }, /* mic-in */ |
1200 | { 0x1a, 0x411111f0 }, /* N/A */ | 1200 | { 0x1a, 0x411111f0 }, /* N/A */ |
1201 | { 0x1b, 0x411111f0 }, /* N/A */ | 1201 | { 0x1b, 0x411111f0 }, /* N/A */ |
1202 | { 0x1c, 0x411111f0 }, /* N/A */ | 1202 | { 0x1c, 0x411111f0 }, /* N/A */ |
1203 | { 0x1d, 0x411111f0 }, /* N/A */ | 1203 | { 0x1d, 0x411111f0 }, /* N/A */ |
1204 | { 0x1e, 0x01454140 }, /* SPDIF out */ | 1204 | { 0x1e, 0x01454140 }, /* SPDIF out */ |
1205 | { } | 1205 | { } |
1206 | }, | 1206 | }, |
1207 | .chained = true, | 1207 | .chained = true, |
1208 | .chain_id = ALC880_FIXUP_VOL_KNOB, | 1208 | .chain_id = ALC880_FIXUP_VOL_KNOB, |
1209 | }, | 1209 | }, |
1210 | [ALC880_FIXUP_F1734] = { | 1210 | [ALC880_FIXUP_F1734] = { |
1211 | /* almost compatible with FUJITSU, but no bass and SPDIF */ | 1211 | /* almost compatible with FUJITSU, but no bass and SPDIF */ |
1212 | .type = HDA_FIXUP_PINS, | 1212 | .type = HDA_FIXUP_PINS, |
1213 | .v.pins = (const struct hda_pintbl[]) { | 1213 | .v.pins = (const struct hda_pintbl[]) { |
1214 | { 0x14, 0x0121411f }, /* HP */ | 1214 | { 0x14, 0x0121411f }, /* HP */ |
1215 | { 0x15, 0x99030120 }, /* speaker */ | 1215 | { 0x15, 0x99030120 }, /* speaker */ |
1216 | { 0x16, 0x411111f0 }, /* N/A */ | 1216 | { 0x16, 0x411111f0 }, /* N/A */ |
1217 | { 0x17, 0x411111f0 }, /* N/A */ | 1217 | { 0x17, 0x411111f0 }, /* N/A */ |
1218 | { 0x18, 0x411111f0 }, /* N/A */ | 1218 | { 0x18, 0x411111f0 }, /* N/A */ |
1219 | { 0x19, 0x01a19950 }, /* mic-in */ | 1219 | { 0x19, 0x01a19950 }, /* mic-in */ |
1220 | { 0x1a, 0x411111f0 }, /* N/A */ | 1220 | { 0x1a, 0x411111f0 }, /* N/A */ |
1221 | { 0x1b, 0x411111f0 }, /* N/A */ | 1221 | { 0x1b, 0x411111f0 }, /* N/A */ |
1222 | { 0x1c, 0x411111f0 }, /* N/A */ | 1222 | { 0x1c, 0x411111f0 }, /* N/A */ |
1223 | { 0x1d, 0x411111f0 }, /* N/A */ | 1223 | { 0x1d, 0x411111f0 }, /* N/A */ |
1224 | { 0x1e, 0x411111f0 }, /* N/A */ | 1224 | { 0x1e, 0x411111f0 }, /* N/A */ |
1225 | { } | 1225 | { } |
1226 | }, | 1226 | }, |
1227 | .chained = true, | 1227 | .chained = true, |
1228 | .chain_id = ALC880_FIXUP_VOL_KNOB, | 1228 | .chain_id = ALC880_FIXUP_VOL_KNOB, |
1229 | }, | 1229 | }, |
1230 | [ALC880_FIXUP_UNIWILL] = { | 1230 | [ALC880_FIXUP_UNIWILL] = { |
1231 | /* need to fix HP and speaker pins to be parsed correctly */ | 1231 | /* need to fix HP and speaker pins to be parsed correctly */ |
1232 | .type = HDA_FIXUP_PINS, | 1232 | .type = HDA_FIXUP_PINS, |
1233 | .v.pins = (const struct hda_pintbl[]) { | 1233 | .v.pins = (const struct hda_pintbl[]) { |
1234 | { 0x14, 0x0121411f }, /* HP */ | 1234 | { 0x14, 0x0121411f }, /* HP */ |
1235 | { 0x15, 0x99030120 }, /* speaker */ | 1235 | { 0x15, 0x99030120 }, /* speaker */ |
1236 | { 0x16, 0x99030130 }, /* bass speaker */ | 1236 | { 0x16, 0x99030130 }, /* bass speaker */ |
1237 | { } | 1237 | { } |
1238 | }, | 1238 | }, |
1239 | }, | 1239 | }, |
1240 | [ALC880_FIXUP_UNIWILL_DIG] = { | 1240 | [ALC880_FIXUP_UNIWILL_DIG] = { |
1241 | .type = HDA_FIXUP_PINS, | 1241 | .type = HDA_FIXUP_PINS, |
1242 | .v.pins = (const struct hda_pintbl[]) { | 1242 | .v.pins = (const struct hda_pintbl[]) { |
1243 | /* disable bogus unused pins */ | 1243 | /* disable bogus unused pins */ |
1244 | { 0x17, 0x411111f0 }, | 1244 | { 0x17, 0x411111f0 }, |
1245 | { 0x19, 0x411111f0 }, | 1245 | { 0x19, 0x411111f0 }, |
1246 | { 0x1b, 0x411111f0 }, | 1246 | { 0x1b, 0x411111f0 }, |
1247 | { 0x1f, 0x411111f0 }, | 1247 | { 0x1f, 0x411111f0 }, |
1248 | { } | 1248 | { } |
1249 | } | 1249 | } |
1250 | }, | 1250 | }, |
1251 | [ALC880_FIXUP_Z71V] = { | 1251 | [ALC880_FIXUP_Z71V] = { |
1252 | .type = HDA_FIXUP_PINS, | 1252 | .type = HDA_FIXUP_PINS, |
1253 | .v.pins = (const struct hda_pintbl[]) { | 1253 | .v.pins = (const struct hda_pintbl[]) { |
1254 | /* set up the whole pins as BIOS is utterly broken */ | 1254 | /* set up the whole pins as BIOS is utterly broken */ |
1255 | { 0x14, 0x99030120 }, /* speaker */ | 1255 | { 0x14, 0x99030120 }, /* speaker */ |
1256 | { 0x15, 0x0121411f }, /* HP */ | 1256 | { 0x15, 0x0121411f }, /* HP */ |
1257 | { 0x16, 0x411111f0 }, /* N/A */ | 1257 | { 0x16, 0x411111f0 }, /* N/A */ |
1258 | { 0x17, 0x411111f0 }, /* N/A */ | 1258 | { 0x17, 0x411111f0 }, /* N/A */ |
1259 | { 0x18, 0x01a19950 }, /* mic-in */ | 1259 | { 0x18, 0x01a19950 }, /* mic-in */ |
1260 | { 0x19, 0x411111f0 }, /* N/A */ | 1260 | { 0x19, 0x411111f0 }, /* N/A */ |
1261 | { 0x1a, 0x01813031 }, /* line-in */ | 1261 | { 0x1a, 0x01813031 }, /* line-in */ |
1262 | { 0x1b, 0x411111f0 }, /* N/A */ | 1262 | { 0x1b, 0x411111f0 }, /* N/A */ |
1263 | { 0x1c, 0x411111f0 }, /* N/A */ | 1263 | { 0x1c, 0x411111f0 }, /* N/A */ |
1264 | { 0x1d, 0x411111f0 }, /* N/A */ | 1264 | { 0x1d, 0x411111f0 }, /* N/A */ |
1265 | { 0x1e, 0x0144111e }, /* SPDIF */ | 1265 | { 0x1e, 0x0144111e }, /* SPDIF */ |
1266 | { } | 1266 | { } |
1267 | } | 1267 | } |
1268 | }, | 1268 | }, |
1269 | [ALC880_FIXUP_ASUS_W5A] = { | 1269 | [ALC880_FIXUP_ASUS_W5A] = { |
1270 | .type = HDA_FIXUP_PINS, | 1270 | .type = HDA_FIXUP_PINS, |
1271 | .v.pins = (const struct hda_pintbl[]) { | 1271 | .v.pins = (const struct hda_pintbl[]) { |
1272 | /* set up the whole pins as BIOS is utterly broken */ | 1272 | /* set up the whole pins as BIOS is utterly broken */ |
1273 | { 0x14, 0x0121411f }, /* HP */ | 1273 | { 0x14, 0x0121411f }, /* HP */ |
1274 | { 0x15, 0x411111f0 }, /* N/A */ | 1274 | { 0x15, 0x411111f0 }, /* N/A */ |
1275 | { 0x16, 0x411111f0 }, /* N/A */ | 1275 | { 0x16, 0x411111f0 }, /* N/A */ |
1276 | { 0x17, 0x411111f0 }, /* N/A */ | 1276 | { 0x17, 0x411111f0 }, /* N/A */ |
1277 | { 0x18, 0x90a60160 }, /* mic */ | 1277 | { 0x18, 0x90a60160 }, /* mic */ |
1278 | { 0x19, 0x411111f0 }, /* N/A */ | 1278 | { 0x19, 0x411111f0 }, /* N/A */ |
1279 | { 0x1a, 0x411111f0 }, /* N/A */ | 1279 | { 0x1a, 0x411111f0 }, /* N/A */ |
1280 | { 0x1b, 0x411111f0 }, /* N/A */ | 1280 | { 0x1b, 0x411111f0 }, /* N/A */ |
1281 | { 0x1c, 0x411111f0 }, /* N/A */ | 1281 | { 0x1c, 0x411111f0 }, /* N/A */ |
1282 | { 0x1d, 0x411111f0 }, /* N/A */ | 1282 | { 0x1d, 0x411111f0 }, /* N/A */ |
1283 | { 0x1e, 0xb743111e }, /* SPDIF out */ | 1283 | { 0x1e, 0xb743111e }, /* SPDIF out */ |
1284 | { } | 1284 | { } |
1285 | }, | 1285 | }, |
1286 | .chained = true, | 1286 | .chained = true, |
1287 | .chain_id = ALC880_FIXUP_GPIO1, | 1287 | .chain_id = ALC880_FIXUP_GPIO1, |
1288 | }, | 1288 | }, |
1289 | [ALC880_FIXUP_3ST_BASE] = { | 1289 | [ALC880_FIXUP_3ST_BASE] = { |
1290 | .type = HDA_FIXUP_PINS, | 1290 | .type = HDA_FIXUP_PINS, |
1291 | .v.pins = (const struct hda_pintbl[]) { | 1291 | .v.pins = (const struct hda_pintbl[]) { |
1292 | { 0x14, 0x01014010 }, /* line-out */ | 1292 | { 0x14, 0x01014010 }, /* line-out */ |
1293 | { 0x15, 0x411111f0 }, /* N/A */ | 1293 | { 0x15, 0x411111f0 }, /* N/A */ |
1294 | { 0x16, 0x411111f0 }, /* N/A */ | 1294 | { 0x16, 0x411111f0 }, /* N/A */ |
1295 | { 0x17, 0x411111f0 }, /* N/A */ | 1295 | { 0x17, 0x411111f0 }, /* N/A */ |
1296 | { 0x18, 0x01a19c30 }, /* mic-in */ | 1296 | { 0x18, 0x01a19c30 }, /* mic-in */ |
1297 | { 0x19, 0x0121411f }, /* HP */ | 1297 | { 0x19, 0x0121411f }, /* HP */ |
1298 | { 0x1a, 0x01813031 }, /* line-in */ | 1298 | { 0x1a, 0x01813031 }, /* line-in */ |
1299 | { 0x1b, 0x02a19c40 }, /* front-mic */ | 1299 | { 0x1b, 0x02a19c40 }, /* front-mic */ |
1300 | { 0x1c, 0x411111f0 }, /* N/A */ | 1300 | { 0x1c, 0x411111f0 }, /* N/A */ |
1301 | { 0x1d, 0x411111f0 }, /* N/A */ | 1301 | { 0x1d, 0x411111f0 }, /* N/A */ |
1302 | /* 0x1e is filled in below */ | 1302 | /* 0x1e is filled in below */ |
1303 | { 0x1f, 0x411111f0 }, /* N/A */ | 1303 | { 0x1f, 0x411111f0 }, /* N/A */ |
1304 | { } | 1304 | { } |
1305 | } | 1305 | } |
1306 | }, | 1306 | }, |
1307 | [ALC880_FIXUP_3ST] = { | 1307 | [ALC880_FIXUP_3ST] = { |
1308 | .type = HDA_FIXUP_PINS, | 1308 | .type = HDA_FIXUP_PINS, |
1309 | .v.pins = (const struct hda_pintbl[]) { | 1309 | .v.pins = (const struct hda_pintbl[]) { |
1310 | { 0x1e, 0x411111f0 }, /* N/A */ | 1310 | { 0x1e, 0x411111f0 }, /* N/A */ |
1311 | { } | 1311 | { } |
1312 | }, | 1312 | }, |
1313 | .chained = true, | 1313 | .chained = true, |
1314 | .chain_id = ALC880_FIXUP_3ST_BASE, | 1314 | .chain_id = ALC880_FIXUP_3ST_BASE, |
1315 | }, | 1315 | }, |
1316 | [ALC880_FIXUP_3ST_DIG] = { | 1316 | [ALC880_FIXUP_3ST_DIG] = { |
1317 | .type = HDA_FIXUP_PINS, | 1317 | .type = HDA_FIXUP_PINS, |
1318 | .v.pins = (const struct hda_pintbl[]) { | 1318 | .v.pins = (const struct hda_pintbl[]) { |
1319 | { 0x1e, 0x0144111e }, /* SPDIF */ | 1319 | { 0x1e, 0x0144111e }, /* SPDIF */ |
1320 | { } | 1320 | { } |
1321 | }, | 1321 | }, |
1322 | .chained = true, | 1322 | .chained = true, |
1323 | .chain_id = ALC880_FIXUP_3ST_BASE, | 1323 | .chain_id = ALC880_FIXUP_3ST_BASE, |
1324 | }, | 1324 | }, |
1325 | [ALC880_FIXUP_5ST_BASE] = { | 1325 | [ALC880_FIXUP_5ST_BASE] = { |
1326 | .type = HDA_FIXUP_PINS, | 1326 | .type = HDA_FIXUP_PINS, |
1327 | .v.pins = (const struct hda_pintbl[]) { | 1327 | .v.pins = (const struct hda_pintbl[]) { |
1328 | { 0x14, 0x01014010 }, /* front */ | 1328 | { 0x14, 0x01014010 }, /* front */ |
1329 | { 0x15, 0x411111f0 }, /* N/A */ | 1329 | { 0x15, 0x411111f0 }, /* N/A */ |
1330 | { 0x16, 0x01011411 }, /* CLFE */ | 1330 | { 0x16, 0x01011411 }, /* CLFE */ |
1331 | { 0x17, 0x01016412 }, /* surr */ | 1331 | { 0x17, 0x01016412 }, /* surr */ |
1332 | { 0x18, 0x01a19c30 }, /* mic-in */ | 1332 | { 0x18, 0x01a19c30 }, /* mic-in */ |
1333 | { 0x19, 0x0121411f }, /* HP */ | 1333 | { 0x19, 0x0121411f }, /* HP */ |
1334 | { 0x1a, 0x01813031 }, /* line-in */ | 1334 | { 0x1a, 0x01813031 }, /* line-in */ |
1335 | { 0x1b, 0x02a19c40 }, /* front-mic */ | 1335 | { 0x1b, 0x02a19c40 }, /* front-mic */ |
1336 | { 0x1c, 0x411111f0 }, /* N/A */ | 1336 | { 0x1c, 0x411111f0 }, /* N/A */ |
1337 | { 0x1d, 0x411111f0 }, /* N/A */ | 1337 | { 0x1d, 0x411111f0 }, /* N/A */ |
1338 | /* 0x1e is filled in below */ | 1338 | /* 0x1e is filled in below */ |
1339 | { 0x1f, 0x411111f0 }, /* N/A */ | 1339 | { 0x1f, 0x411111f0 }, /* N/A */ |
1340 | { } | 1340 | { } |
1341 | } | 1341 | } |
1342 | }, | 1342 | }, |
1343 | [ALC880_FIXUP_5ST] = { | 1343 | [ALC880_FIXUP_5ST] = { |
1344 | .type = HDA_FIXUP_PINS, | 1344 | .type = HDA_FIXUP_PINS, |
1345 | .v.pins = (const struct hda_pintbl[]) { | 1345 | .v.pins = (const struct hda_pintbl[]) { |
1346 | { 0x1e, 0x411111f0 }, /* N/A */ | 1346 | { 0x1e, 0x411111f0 }, /* N/A */ |
1347 | { } | 1347 | { } |
1348 | }, | 1348 | }, |
1349 | .chained = true, | 1349 | .chained = true, |
1350 | .chain_id = ALC880_FIXUP_5ST_BASE, | 1350 | .chain_id = ALC880_FIXUP_5ST_BASE, |
1351 | }, | 1351 | }, |
1352 | [ALC880_FIXUP_5ST_DIG] = { | 1352 | [ALC880_FIXUP_5ST_DIG] = { |
1353 | .type = HDA_FIXUP_PINS, | 1353 | .type = HDA_FIXUP_PINS, |
1354 | .v.pins = (const struct hda_pintbl[]) { | 1354 | .v.pins = (const struct hda_pintbl[]) { |
1355 | { 0x1e, 0x0144111e }, /* SPDIF */ | 1355 | { 0x1e, 0x0144111e }, /* SPDIF */ |
1356 | { } | 1356 | { } |
1357 | }, | 1357 | }, |
1358 | .chained = true, | 1358 | .chained = true, |
1359 | .chain_id = ALC880_FIXUP_5ST_BASE, | 1359 | .chain_id = ALC880_FIXUP_5ST_BASE, |
1360 | }, | 1360 | }, |
1361 | [ALC880_FIXUP_6ST_BASE] = { | 1361 | [ALC880_FIXUP_6ST_BASE] = { |
1362 | .type = HDA_FIXUP_PINS, | 1362 | .type = HDA_FIXUP_PINS, |
1363 | .v.pins = (const struct hda_pintbl[]) { | 1363 | .v.pins = (const struct hda_pintbl[]) { |
1364 | { 0x14, 0x01014010 }, /* front */ | 1364 | { 0x14, 0x01014010 }, /* front */ |
1365 | { 0x15, 0x01016412 }, /* surr */ | 1365 | { 0x15, 0x01016412 }, /* surr */ |
1366 | { 0x16, 0x01011411 }, /* CLFE */ | 1366 | { 0x16, 0x01011411 }, /* CLFE */ |
1367 | { 0x17, 0x01012414 }, /* side */ | 1367 | { 0x17, 0x01012414 }, /* side */ |
1368 | { 0x18, 0x01a19c30 }, /* mic-in */ | 1368 | { 0x18, 0x01a19c30 }, /* mic-in */ |
1369 | { 0x19, 0x02a19c40 }, /* front-mic */ | 1369 | { 0x19, 0x02a19c40 }, /* front-mic */ |
1370 | { 0x1a, 0x01813031 }, /* line-in */ | 1370 | { 0x1a, 0x01813031 }, /* line-in */ |
1371 | { 0x1b, 0x0121411f }, /* HP */ | 1371 | { 0x1b, 0x0121411f }, /* HP */ |
1372 | { 0x1c, 0x411111f0 }, /* N/A */ | 1372 | { 0x1c, 0x411111f0 }, /* N/A */ |
1373 | { 0x1d, 0x411111f0 }, /* N/A */ | 1373 | { 0x1d, 0x411111f0 }, /* N/A */ |
1374 | /* 0x1e is filled in below */ | 1374 | /* 0x1e is filled in below */ |
1375 | { 0x1f, 0x411111f0 }, /* N/A */ | 1375 | { 0x1f, 0x411111f0 }, /* N/A */ |
1376 | { } | 1376 | { } |
1377 | } | 1377 | } |
1378 | }, | 1378 | }, |
1379 | [ALC880_FIXUP_6ST] = { | 1379 | [ALC880_FIXUP_6ST] = { |
1380 | .type = HDA_FIXUP_PINS, | 1380 | .type = HDA_FIXUP_PINS, |
1381 | .v.pins = (const struct hda_pintbl[]) { | 1381 | .v.pins = (const struct hda_pintbl[]) { |
1382 | { 0x1e, 0x411111f0 }, /* N/A */ | 1382 | { 0x1e, 0x411111f0 }, /* N/A */ |
1383 | { } | 1383 | { } |
1384 | }, | 1384 | }, |
1385 | .chained = true, | 1385 | .chained = true, |
1386 | .chain_id = ALC880_FIXUP_6ST_BASE, | 1386 | .chain_id = ALC880_FIXUP_6ST_BASE, |
1387 | }, | 1387 | }, |
1388 | [ALC880_FIXUP_6ST_DIG] = { | 1388 | [ALC880_FIXUP_6ST_DIG] = { |
1389 | .type = HDA_FIXUP_PINS, | 1389 | .type = HDA_FIXUP_PINS, |
1390 | .v.pins = (const struct hda_pintbl[]) { | 1390 | .v.pins = (const struct hda_pintbl[]) { |
1391 | { 0x1e, 0x0144111e }, /* SPDIF */ | 1391 | { 0x1e, 0x0144111e }, /* SPDIF */ |
1392 | { } | 1392 | { } |
1393 | }, | 1393 | }, |
1394 | .chained = true, | 1394 | .chained = true, |
1395 | .chain_id = ALC880_FIXUP_6ST_BASE, | 1395 | .chain_id = ALC880_FIXUP_6ST_BASE, |
1396 | }, | 1396 | }, |
1397 | [ALC880_FIXUP_6ST_AUTOMUTE] = { | 1397 | [ALC880_FIXUP_6ST_AUTOMUTE] = { |
1398 | .type = HDA_FIXUP_PINS, | 1398 | .type = HDA_FIXUP_PINS, |
1399 | .v.pins = (const struct hda_pintbl[]) { | 1399 | .v.pins = (const struct hda_pintbl[]) { |
1400 | { 0x1b, 0x0121401f }, /* HP with jack detect */ | 1400 | { 0x1b, 0x0121401f }, /* HP with jack detect */ |
1401 | { } | 1401 | { } |
1402 | }, | 1402 | }, |
1403 | .chained_before = true, | 1403 | .chained_before = true, |
1404 | .chain_id = ALC880_FIXUP_6ST_BASE, | 1404 | .chain_id = ALC880_FIXUP_6ST_BASE, |
1405 | }, | 1405 | }, |
1406 | }; | 1406 | }; |
1407 | 1407 | ||
1408 | static const struct snd_pci_quirk alc880_fixup_tbl[] = { | 1408 | static const struct snd_pci_quirk alc880_fixup_tbl[] = { |
1409 | SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_FIXUP_W810), | 1409 | SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_FIXUP_W810), |
1410 | SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS W5A", ALC880_FIXUP_ASUS_W5A), | 1410 | SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS W5A", ALC880_FIXUP_ASUS_W5A), |
1411 | SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_FIXUP_Z71V), | 1411 | SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_FIXUP_Z71V), |
1412 | SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_FIXUP_GPIO1), | 1412 | SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_FIXUP_GPIO1), |
1413 | SND_PCI_QUIRK(0x1558, 0x5401, "Clevo GPIO2", ALC880_FIXUP_GPIO2), | 1413 | SND_PCI_QUIRK(0x1558, 0x5401, "Clevo GPIO2", ALC880_FIXUP_GPIO2), |
1414 | SND_PCI_QUIRK_VENDOR(0x1558, "Clevo", ALC880_FIXUP_EAPD_COEF), | 1414 | SND_PCI_QUIRK_VENDOR(0x1558, "Clevo", ALC880_FIXUP_EAPD_COEF), |
1415 | SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_FIXUP_UNIWILL_DIG), | 1415 | SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_FIXUP_UNIWILL_DIG), |
1416 | SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_FIXUP_F1734), | 1416 | SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_FIXUP_F1734), |
1417 | SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_FIXUP_UNIWILL), | 1417 | SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_FIXUP_UNIWILL), |
1418 | SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_FIXUP_VOL_KNOB), | 1418 | SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_FIXUP_VOL_KNOB), |
1419 | SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_FIXUP_W810), | 1419 | SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_FIXUP_W810), |
1420 | SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_FIXUP_MEDION_RIM), | 1420 | SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_FIXUP_MEDION_RIM), |
1421 | SND_PCI_QUIRK(0x1631, 0xe011, "PB 13201056", ALC880_FIXUP_6ST_AUTOMUTE), | 1421 | SND_PCI_QUIRK(0x1631, 0xe011, "PB 13201056", ALC880_FIXUP_6ST_AUTOMUTE), |
1422 | SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_FIXUP_F1734), | 1422 | SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_FIXUP_F1734), |
1423 | SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FIXUP_FUJITSU), | 1423 | SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FIXUP_FUJITSU), |
1424 | SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_FIXUP_F1734), | 1424 | SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_FIXUP_F1734), |
1425 | SND_PCI_QUIRK(0x1734, 0x10b0, "FSC Amilo Pi1556", ALC880_FIXUP_FUJITSU), | 1425 | SND_PCI_QUIRK(0x1734, 0x10b0, "FSC Amilo Pi1556", ALC880_FIXUP_FUJITSU), |
1426 | SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_FIXUP_LG), | 1426 | SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_FIXUP_LG), |
1427 | SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_FIXUP_LG), | 1427 | SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_FIXUP_LG), |
1428 | SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_FIXUP_LG), | 1428 | SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_FIXUP_LG), |
1429 | SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_FIXUP_LG_LW25), | 1429 | SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_FIXUP_LG_LW25), |
1430 | SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_FIXUP_TCL_S700), | 1430 | SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_FIXUP_TCL_S700), |
1431 | 1431 | ||
1432 | /* Below is the copied entries from alc880_quirks.c. | 1432 | /* Below is the copied entries from alc880_quirks.c. |
1433 | * It's not quite sure whether BIOS sets the correct pin-config table | 1433 | * It's not quite sure whether BIOS sets the correct pin-config table |
1434 | * on these machines, thus they are kept to be compatible with | 1434 | * on these machines, thus they are kept to be compatible with |
1435 | * the old static quirks. Once when it's confirmed to work without | 1435 | * the old static quirks. Once when it's confirmed to work without |
1436 | * these overrides, it'd be better to remove. | 1436 | * these overrides, it'd be better to remove. |
1437 | */ | 1437 | */ |
1438 | SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_FIXUP_5ST_DIG), | 1438 | SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_FIXUP_5ST_DIG), |
1439 | SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_FIXUP_6ST), | 1439 | SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_FIXUP_6ST), |
1440 | SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_FIXUP_3ST_DIG), | 1440 | SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_FIXUP_3ST_DIG), |
1441 | SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_FIXUP_6ST_DIG), | 1441 | SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_FIXUP_6ST_DIG), |
1442 | SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_FIXUP_6ST_DIG), | 1442 | SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_FIXUP_6ST_DIG), |
1443 | SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_FIXUP_6ST_DIG), | 1443 | SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_FIXUP_6ST_DIG), |
1444 | SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_FIXUP_3ST_DIG), | 1444 | SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_FIXUP_3ST_DIG), |
1445 | SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_FIXUP_3ST), | 1445 | SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_FIXUP_3ST), |
1446 | SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_FIXUP_6ST_DIG), | 1446 | SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_FIXUP_6ST_DIG), |
1447 | SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_FIXUP_3ST), | 1447 | SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_FIXUP_3ST), |
1448 | SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_FIXUP_3ST), | 1448 | SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_FIXUP_3ST), |
1449 | SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_FIXUP_5ST), | 1449 | SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_FIXUP_5ST), |
1450 | SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_FIXUP_5ST), | 1450 | SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_FIXUP_5ST), |
1451 | SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_FIXUP_5ST), | 1451 | SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_FIXUP_5ST), |
1452 | SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_FIXUP_6ST_DIG), | 1452 | SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_FIXUP_6ST_DIG), |
1453 | SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_FIXUP_6ST_DIG), | 1453 | SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_FIXUP_6ST_DIG), |
1454 | SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_FIXUP_6ST_DIG), | 1454 | SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_FIXUP_6ST_DIG), |
1455 | SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_FIXUP_6ST_DIG), | 1455 | SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_FIXUP_6ST_DIG), |
1456 | SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_FIXUP_5ST_DIG), | 1456 | SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_FIXUP_5ST_DIG), |
1457 | SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_FIXUP_5ST_DIG), | 1457 | SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_FIXUP_5ST_DIG), |
1458 | SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_FIXUP_5ST_DIG), | 1458 | SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_FIXUP_5ST_DIG), |
1459 | SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_FIXUP_6ST_DIG), /* broken BIOS */ | 1459 | SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_FIXUP_6ST_DIG), /* broken BIOS */ |
1460 | SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_FIXUP_6ST_DIG), | 1460 | SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_FIXUP_6ST_DIG), |
1461 | SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_FIXUP_5ST_DIG), | 1461 | SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_FIXUP_5ST_DIG), |
1462 | SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_FIXUP_5ST_DIG), | 1462 | SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_FIXUP_5ST_DIG), |
1463 | SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_FIXUP_5ST_DIG), | 1463 | SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_FIXUP_5ST_DIG), |
1464 | SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_FIXUP_3ST_DIG), | 1464 | SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_FIXUP_3ST_DIG), |
1465 | SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_FIXUP_5ST_DIG), | 1465 | SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_FIXUP_5ST_DIG), |
1466 | SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_FIXUP_3ST_DIG), | 1466 | SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_FIXUP_3ST_DIG), |
1467 | SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_FIXUP_3ST_DIG), | 1467 | SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_FIXUP_3ST_DIG), |
1468 | SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_FIXUP_5ST_DIG), | 1468 | SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_FIXUP_5ST_DIG), |
1469 | SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_FIXUP_5ST_DIG), | 1469 | SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_FIXUP_5ST_DIG), |
1470 | SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_FIXUP_5ST_DIG), | 1470 | SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_FIXUP_5ST_DIG), |
1471 | /* default Intel */ | 1471 | /* default Intel */ |
1472 | SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_FIXUP_3ST), | 1472 | SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_FIXUP_3ST), |
1473 | SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_FIXUP_5ST_DIG), | 1473 | SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_FIXUP_5ST_DIG), |
1474 | SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_FIXUP_6ST_DIG), | 1474 | SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_FIXUP_6ST_DIG), |
1475 | {} | 1475 | {} |
1476 | }; | 1476 | }; |
1477 | 1477 | ||
1478 | static const struct hda_model_fixup alc880_fixup_models[] = { | 1478 | static const struct hda_model_fixup alc880_fixup_models[] = { |
1479 | {.id = ALC880_FIXUP_3ST, .name = "3stack"}, | 1479 | {.id = ALC880_FIXUP_3ST, .name = "3stack"}, |
1480 | {.id = ALC880_FIXUP_3ST_DIG, .name = "3stack-digout"}, | 1480 | {.id = ALC880_FIXUP_3ST_DIG, .name = "3stack-digout"}, |
1481 | {.id = ALC880_FIXUP_5ST, .name = "5stack"}, | 1481 | {.id = ALC880_FIXUP_5ST, .name = "5stack"}, |
1482 | {.id = ALC880_FIXUP_5ST_DIG, .name = "5stack-digout"}, | 1482 | {.id = ALC880_FIXUP_5ST_DIG, .name = "5stack-digout"}, |
1483 | {.id = ALC880_FIXUP_6ST, .name = "6stack"}, | 1483 | {.id = ALC880_FIXUP_6ST, .name = "6stack"}, |
1484 | {.id = ALC880_FIXUP_6ST_DIG, .name = "6stack-digout"}, | 1484 | {.id = ALC880_FIXUP_6ST_DIG, .name = "6stack-digout"}, |
1485 | {.id = ALC880_FIXUP_6ST_AUTOMUTE, .name = "6stack-automute"}, | 1485 | {.id = ALC880_FIXUP_6ST_AUTOMUTE, .name = "6stack-automute"}, |
1486 | {} | 1486 | {} |
1487 | }; | 1487 | }; |
1488 | 1488 | ||
1489 | 1489 | ||
1490 | /* | 1490 | /* |
1491 | * OK, here we have finally the patch for ALC880 | 1491 | * OK, here we have finally the patch for ALC880 |
1492 | */ | 1492 | */ |
1493 | static int patch_alc880(struct hda_codec *codec) | 1493 | static int patch_alc880(struct hda_codec *codec) |
1494 | { | 1494 | { |
1495 | struct alc_spec *spec; | 1495 | struct alc_spec *spec; |
1496 | int err; | 1496 | int err; |
1497 | 1497 | ||
1498 | err = alc_alloc_spec(codec, 0x0b); | 1498 | err = alc_alloc_spec(codec, 0x0b); |
1499 | if (err < 0) | 1499 | if (err < 0) |
1500 | return err; | 1500 | return err; |
1501 | 1501 | ||
1502 | spec = codec->spec; | 1502 | spec = codec->spec; |
1503 | spec->gen.need_dac_fix = 1; | 1503 | spec->gen.need_dac_fix = 1; |
1504 | spec->gen.beep_nid = 0x01; | 1504 | spec->gen.beep_nid = 0x01; |
1505 | 1505 | ||
1506 | snd_hda_pick_fixup(codec, alc880_fixup_models, alc880_fixup_tbl, | 1506 | snd_hda_pick_fixup(codec, alc880_fixup_models, alc880_fixup_tbl, |
1507 | alc880_fixups); | 1507 | alc880_fixups); |
1508 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); | 1508 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); |
1509 | 1509 | ||
1510 | /* automatic parse from the BIOS config */ | 1510 | /* automatic parse from the BIOS config */ |
1511 | err = alc880_parse_auto_config(codec); | 1511 | err = alc880_parse_auto_config(codec); |
1512 | if (err < 0) | 1512 | if (err < 0) |
1513 | goto error; | 1513 | goto error; |
1514 | 1514 | ||
1515 | if (!spec->gen.no_analog) | 1515 | if (!spec->gen.no_analog) |
1516 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); | 1516 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); |
1517 | 1517 | ||
1518 | codec->patch_ops = alc_patch_ops; | 1518 | codec->patch_ops = alc_patch_ops; |
1519 | codec->patch_ops.unsol_event = alc880_unsol_event; | 1519 | codec->patch_ops.unsol_event = alc880_unsol_event; |
1520 | 1520 | ||
1521 | 1521 | ||
1522 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); | 1522 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); |
1523 | 1523 | ||
1524 | return 0; | 1524 | return 0; |
1525 | 1525 | ||
1526 | error: | 1526 | error: |
1527 | alc_free(codec); | 1527 | alc_free(codec); |
1528 | return err; | 1528 | return err; |
1529 | } | 1529 | } |
1530 | 1530 | ||
1531 | 1531 | ||
1532 | /* | 1532 | /* |
1533 | * ALC260 support | 1533 | * ALC260 support |
1534 | */ | 1534 | */ |
1535 | static int alc260_parse_auto_config(struct hda_codec *codec) | 1535 | static int alc260_parse_auto_config(struct hda_codec *codec) |
1536 | { | 1536 | { |
1537 | static const hda_nid_t alc260_ignore[] = { 0x17, 0 }; | 1537 | static const hda_nid_t alc260_ignore[] = { 0x17, 0 }; |
1538 | static const hda_nid_t alc260_ssids[] = { 0x10, 0x15, 0x0f, 0 }; | 1538 | static const hda_nid_t alc260_ssids[] = { 0x10, 0x15, 0x0f, 0 }; |
1539 | return alc_parse_auto_config(codec, alc260_ignore, alc260_ssids); | 1539 | return alc_parse_auto_config(codec, alc260_ignore, alc260_ssids); |
1540 | } | 1540 | } |
1541 | 1541 | ||
1542 | /* | 1542 | /* |
1543 | * Pin config fixes | 1543 | * Pin config fixes |
1544 | */ | 1544 | */ |
1545 | enum { | 1545 | enum { |
1546 | ALC260_FIXUP_HP_DC5750, | 1546 | ALC260_FIXUP_HP_DC5750, |
1547 | ALC260_FIXUP_HP_PIN_0F, | 1547 | ALC260_FIXUP_HP_PIN_0F, |
1548 | ALC260_FIXUP_COEF, | 1548 | ALC260_FIXUP_COEF, |
1549 | ALC260_FIXUP_GPIO1, | 1549 | ALC260_FIXUP_GPIO1, |
1550 | ALC260_FIXUP_GPIO1_TOGGLE, | 1550 | ALC260_FIXUP_GPIO1_TOGGLE, |
1551 | ALC260_FIXUP_REPLACER, | 1551 | ALC260_FIXUP_REPLACER, |
1552 | ALC260_FIXUP_HP_B1900, | 1552 | ALC260_FIXUP_HP_B1900, |
1553 | ALC260_FIXUP_KN1, | 1553 | ALC260_FIXUP_KN1, |
1554 | ALC260_FIXUP_FSC_S7020, | 1554 | ALC260_FIXUP_FSC_S7020, |
1555 | ALC260_FIXUP_FSC_S7020_JWSE, | 1555 | ALC260_FIXUP_FSC_S7020_JWSE, |
1556 | ALC260_FIXUP_VAIO_PINS, | 1556 | ALC260_FIXUP_VAIO_PINS, |
1557 | }; | 1557 | }; |
1558 | 1558 | ||
1559 | static void alc260_gpio1_automute(struct hda_codec *codec) | 1559 | static void alc260_gpio1_automute(struct hda_codec *codec) |
1560 | { | 1560 | { |
1561 | struct alc_spec *spec = codec->spec; | 1561 | struct alc_spec *spec = codec->spec; |
1562 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, | 1562 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, |
1563 | spec->gen.hp_jack_present); | 1563 | spec->gen.hp_jack_present); |
1564 | } | 1564 | } |
1565 | 1565 | ||
1566 | static void alc260_fixup_gpio1_toggle(struct hda_codec *codec, | 1566 | static void alc260_fixup_gpio1_toggle(struct hda_codec *codec, |
1567 | const struct hda_fixup *fix, int action) | 1567 | const struct hda_fixup *fix, int action) |
1568 | { | 1568 | { |
1569 | struct alc_spec *spec = codec->spec; | 1569 | struct alc_spec *spec = codec->spec; |
1570 | if (action == HDA_FIXUP_ACT_PROBE) { | 1570 | if (action == HDA_FIXUP_ACT_PROBE) { |
1571 | /* although the machine has only one output pin, we need to | 1571 | /* although the machine has only one output pin, we need to |
1572 | * toggle GPIO1 according to the jack state | 1572 | * toggle GPIO1 according to the jack state |
1573 | */ | 1573 | */ |
1574 | spec->gen.automute_hook = alc260_gpio1_automute; | 1574 | spec->gen.automute_hook = alc260_gpio1_automute; |
1575 | spec->gen.detect_hp = 1; | 1575 | spec->gen.detect_hp = 1; |
1576 | spec->gen.automute_speaker = 1; | 1576 | spec->gen.automute_speaker = 1; |
1577 | spec->gen.autocfg.hp_pins[0] = 0x0f; /* copy it for automute */ | 1577 | spec->gen.autocfg.hp_pins[0] = 0x0f; /* copy it for automute */ |
1578 | snd_hda_jack_detect_enable_callback(codec, 0x0f, HDA_GEN_HP_EVENT, | 1578 | snd_hda_jack_detect_enable_callback(codec, 0x0f, HDA_GEN_HP_EVENT, |
1579 | snd_hda_gen_hp_automute); | 1579 | snd_hda_gen_hp_automute); |
1580 | snd_hda_add_verbs(codec, alc_gpio1_init_verbs); | 1580 | snd_hda_add_verbs(codec, alc_gpio1_init_verbs); |
1581 | } | 1581 | } |
1582 | } | 1582 | } |
1583 | 1583 | ||
1584 | static void alc260_fixup_kn1(struct hda_codec *codec, | 1584 | static void alc260_fixup_kn1(struct hda_codec *codec, |
1585 | const struct hda_fixup *fix, int action) | 1585 | const struct hda_fixup *fix, int action) |
1586 | { | 1586 | { |
1587 | struct alc_spec *spec = codec->spec; | 1587 | struct alc_spec *spec = codec->spec; |
1588 | static const struct hda_pintbl pincfgs[] = { | 1588 | static const struct hda_pintbl pincfgs[] = { |
1589 | { 0x0f, 0x02214000 }, /* HP/speaker */ | 1589 | { 0x0f, 0x02214000 }, /* HP/speaker */ |
1590 | { 0x12, 0x90a60160 }, /* int mic */ | 1590 | { 0x12, 0x90a60160 }, /* int mic */ |
1591 | { 0x13, 0x02a19000 }, /* ext mic */ | 1591 | { 0x13, 0x02a19000 }, /* ext mic */ |
1592 | { 0x18, 0x01446000 }, /* SPDIF out */ | 1592 | { 0x18, 0x01446000 }, /* SPDIF out */ |
1593 | /* disable bogus I/O pins */ | 1593 | /* disable bogus I/O pins */ |
1594 | { 0x10, 0x411111f0 }, | 1594 | { 0x10, 0x411111f0 }, |
1595 | { 0x11, 0x411111f0 }, | 1595 | { 0x11, 0x411111f0 }, |
1596 | { 0x14, 0x411111f0 }, | 1596 | { 0x14, 0x411111f0 }, |
1597 | { 0x15, 0x411111f0 }, | 1597 | { 0x15, 0x411111f0 }, |
1598 | { 0x16, 0x411111f0 }, | 1598 | { 0x16, 0x411111f0 }, |
1599 | { 0x17, 0x411111f0 }, | 1599 | { 0x17, 0x411111f0 }, |
1600 | { 0x19, 0x411111f0 }, | 1600 | { 0x19, 0x411111f0 }, |
1601 | { } | 1601 | { } |
1602 | }; | 1602 | }; |
1603 | 1603 | ||
1604 | switch (action) { | 1604 | switch (action) { |
1605 | case HDA_FIXUP_ACT_PRE_PROBE: | 1605 | case HDA_FIXUP_ACT_PRE_PROBE: |
1606 | snd_hda_apply_pincfgs(codec, pincfgs); | 1606 | snd_hda_apply_pincfgs(codec, pincfgs); |
1607 | break; | 1607 | break; |
1608 | case HDA_FIXUP_ACT_PROBE: | 1608 | case HDA_FIXUP_ACT_PROBE: |
1609 | spec->init_amp = ALC_INIT_NONE; | 1609 | spec->init_amp = ALC_INIT_NONE; |
1610 | break; | 1610 | break; |
1611 | } | 1611 | } |
1612 | } | 1612 | } |
1613 | 1613 | ||
1614 | static void alc260_fixup_fsc_s7020(struct hda_codec *codec, | 1614 | static void alc260_fixup_fsc_s7020(struct hda_codec *codec, |
1615 | const struct hda_fixup *fix, int action) | 1615 | const struct hda_fixup *fix, int action) |
1616 | { | 1616 | { |
1617 | struct alc_spec *spec = codec->spec; | 1617 | struct alc_spec *spec = codec->spec; |
1618 | if (action == HDA_FIXUP_ACT_PROBE) | 1618 | if (action == HDA_FIXUP_ACT_PROBE) |
1619 | spec->init_amp = ALC_INIT_NONE; | 1619 | spec->init_amp = ALC_INIT_NONE; |
1620 | } | 1620 | } |
1621 | 1621 | ||
1622 | static void alc260_fixup_fsc_s7020_jwse(struct hda_codec *codec, | 1622 | static void alc260_fixup_fsc_s7020_jwse(struct hda_codec *codec, |
1623 | const struct hda_fixup *fix, int action) | 1623 | const struct hda_fixup *fix, int action) |
1624 | { | 1624 | { |
1625 | struct alc_spec *spec = codec->spec; | 1625 | struct alc_spec *spec = codec->spec; |
1626 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | 1626 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
1627 | spec->gen.add_jack_modes = 1; | 1627 | spec->gen.add_jack_modes = 1; |
1628 | spec->gen.hp_mic = 1; | 1628 | spec->gen.hp_mic = 1; |
1629 | } | 1629 | } |
1630 | } | 1630 | } |
1631 | 1631 | ||
1632 | static const struct hda_fixup alc260_fixups[] = { | 1632 | static const struct hda_fixup alc260_fixups[] = { |
1633 | [ALC260_FIXUP_HP_DC5750] = { | 1633 | [ALC260_FIXUP_HP_DC5750] = { |
1634 | .type = HDA_FIXUP_PINS, | 1634 | .type = HDA_FIXUP_PINS, |
1635 | .v.pins = (const struct hda_pintbl[]) { | 1635 | .v.pins = (const struct hda_pintbl[]) { |
1636 | { 0x11, 0x90130110 }, /* speaker */ | 1636 | { 0x11, 0x90130110 }, /* speaker */ |
1637 | { } | 1637 | { } |
1638 | } | 1638 | } |
1639 | }, | 1639 | }, |
1640 | [ALC260_FIXUP_HP_PIN_0F] = { | 1640 | [ALC260_FIXUP_HP_PIN_0F] = { |
1641 | .type = HDA_FIXUP_PINS, | 1641 | .type = HDA_FIXUP_PINS, |
1642 | .v.pins = (const struct hda_pintbl[]) { | 1642 | .v.pins = (const struct hda_pintbl[]) { |
1643 | { 0x0f, 0x01214000 }, /* HP */ | 1643 | { 0x0f, 0x01214000 }, /* HP */ |
1644 | { } | 1644 | { } |
1645 | } | 1645 | } |
1646 | }, | 1646 | }, |
1647 | [ALC260_FIXUP_COEF] = { | 1647 | [ALC260_FIXUP_COEF] = { |
1648 | .type = HDA_FIXUP_VERBS, | 1648 | .type = HDA_FIXUP_VERBS, |
1649 | .v.verbs = (const struct hda_verb[]) { | 1649 | .v.verbs = (const struct hda_verb[]) { |
1650 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, | 1650 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, |
1651 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3040 }, | 1651 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3040 }, |
1652 | { } | 1652 | { } |
1653 | }, | 1653 | }, |
1654 | .chained = true, | 1654 | .chained = true, |
1655 | .chain_id = ALC260_FIXUP_HP_PIN_0F, | 1655 | .chain_id = ALC260_FIXUP_HP_PIN_0F, |
1656 | }, | 1656 | }, |
1657 | [ALC260_FIXUP_GPIO1] = { | 1657 | [ALC260_FIXUP_GPIO1] = { |
1658 | .type = HDA_FIXUP_VERBS, | 1658 | .type = HDA_FIXUP_VERBS, |
1659 | .v.verbs = alc_gpio1_init_verbs, | 1659 | .v.verbs = alc_gpio1_init_verbs, |
1660 | }, | 1660 | }, |
1661 | [ALC260_FIXUP_GPIO1_TOGGLE] = { | 1661 | [ALC260_FIXUP_GPIO1_TOGGLE] = { |
1662 | .type = HDA_FIXUP_FUNC, | 1662 | .type = HDA_FIXUP_FUNC, |
1663 | .v.func = alc260_fixup_gpio1_toggle, | 1663 | .v.func = alc260_fixup_gpio1_toggle, |
1664 | .chained = true, | 1664 | .chained = true, |
1665 | .chain_id = ALC260_FIXUP_HP_PIN_0F, | 1665 | .chain_id = ALC260_FIXUP_HP_PIN_0F, |
1666 | }, | 1666 | }, |
1667 | [ALC260_FIXUP_REPLACER] = { | 1667 | [ALC260_FIXUP_REPLACER] = { |
1668 | .type = HDA_FIXUP_VERBS, | 1668 | .type = HDA_FIXUP_VERBS, |
1669 | .v.verbs = (const struct hda_verb[]) { | 1669 | .v.verbs = (const struct hda_verb[]) { |
1670 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, | 1670 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, |
1671 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 }, | 1671 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 }, |
1672 | { } | 1672 | { } |
1673 | }, | 1673 | }, |
1674 | .chained = true, | 1674 | .chained = true, |
1675 | .chain_id = ALC260_FIXUP_GPIO1_TOGGLE, | 1675 | .chain_id = ALC260_FIXUP_GPIO1_TOGGLE, |
1676 | }, | 1676 | }, |
1677 | [ALC260_FIXUP_HP_B1900] = { | 1677 | [ALC260_FIXUP_HP_B1900] = { |
1678 | .type = HDA_FIXUP_FUNC, | 1678 | .type = HDA_FIXUP_FUNC, |
1679 | .v.func = alc260_fixup_gpio1_toggle, | 1679 | .v.func = alc260_fixup_gpio1_toggle, |
1680 | .chained = true, | 1680 | .chained = true, |
1681 | .chain_id = ALC260_FIXUP_COEF, | 1681 | .chain_id = ALC260_FIXUP_COEF, |
1682 | }, | 1682 | }, |
1683 | [ALC260_FIXUP_KN1] = { | 1683 | [ALC260_FIXUP_KN1] = { |
1684 | .type = HDA_FIXUP_FUNC, | 1684 | .type = HDA_FIXUP_FUNC, |
1685 | .v.func = alc260_fixup_kn1, | 1685 | .v.func = alc260_fixup_kn1, |
1686 | }, | 1686 | }, |
1687 | [ALC260_FIXUP_FSC_S7020] = { | 1687 | [ALC260_FIXUP_FSC_S7020] = { |
1688 | .type = HDA_FIXUP_FUNC, | 1688 | .type = HDA_FIXUP_FUNC, |
1689 | .v.func = alc260_fixup_fsc_s7020, | 1689 | .v.func = alc260_fixup_fsc_s7020, |
1690 | }, | 1690 | }, |
1691 | [ALC260_FIXUP_FSC_S7020_JWSE] = { | 1691 | [ALC260_FIXUP_FSC_S7020_JWSE] = { |
1692 | .type = HDA_FIXUP_FUNC, | 1692 | .type = HDA_FIXUP_FUNC, |
1693 | .v.func = alc260_fixup_fsc_s7020_jwse, | 1693 | .v.func = alc260_fixup_fsc_s7020_jwse, |
1694 | .chained = true, | 1694 | .chained = true, |
1695 | .chain_id = ALC260_FIXUP_FSC_S7020, | 1695 | .chain_id = ALC260_FIXUP_FSC_S7020, |
1696 | }, | 1696 | }, |
1697 | [ALC260_FIXUP_VAIO_PINS] = { | 1697 | [ALC260_FIXUP_VAIO_PINS] = { |
1698 | .type = HDA_FIXUP_PINS, | 1698 | .type = HDA_FIXUP_PINS, |
1699 | .v.pins = (const struct hda_pintbl[]) { | 1699 | .v.pins = (const struct hda_pintbl[]) { |
1700 | /* Pin configs are missing completely on some VAIOs */ | 1700 | /* Pin configs are missing completely on some VAIOs */ |
1701 | { 0x0f, 0x01211020 }, | 1701 | { 0x0f, 0x01211020 }, |
1702 | { 0x10, 0x0001003f }, | 1702 | { 0x10, 0x0001003f }, |
1703 | { 0x11, 0x411111f0 }, | 1703 | { 0x11, 0x411111f0 }, |
1704 | { 0x12, 0x01a15930 }, | 1704 | { 0x12, 0x01a15930 }, |
1705 | { 0x13, 0x411111f0 }, | 1705 | { 0x13, 0x411111f0 }, |
1706 | { 0x14, 0x411111f0 }, | 1706 | { 0x14, 0x411111f0 }, |
1707 | { 0x15, 0x411111f0 }, | 1707 | { 0x15, 0x411111f0 }, |
1708 | { 0x16, 0x411111f0 }, | 1708 | { 0x16, 0x411111f0 }, |
1709 | { 0x17, 0x411111f0 }, | 1709 | { 0x17, 0x411111f0 }, |
1710 | { 0x18, 0x411111f0 }, | 1710 | { 0x18, 0x411111f0 }, |
1711 | { 0x19, 0x411111f0 }, | 1711 | { 0x19, 0x411111f0 }, |
1712 | { } | 1712 | { } |
1713 | } | 1713 | } |
1714 | }, | 1714 | }, |
1715 | }; | 1715 | }; |
1716 | 1716 | ||
1717 | static const struct snd_pci_quirk alc260_fixup_tbl[] = { | 1717 | static const struct snd_pci_quirk alc260_fixup_tbl[] = { |
1718 | SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_FIXUP_GPIO1), | 1718 | SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_FIXUP_GPIO1), |
1719 | SND_PCI_QUIRK(0x1025, 0x007f, "Acer Aspire 9500", ALC260_FIXUP_COEF), | 1719 | SND_PCI_QUIRK(0x1025, 0x007f, "Acer Aspire 9500", ALC260_FIXUP_COEF), |
1720 | SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_FIXUP_GPIO1), | 1720 | SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_FIXUP_GPIO1), |
1721 | SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", ALC260_FIXUP_HP_DC5750), | 1721 | SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", ALC260_FIXUP_HP_DC5750), |
1722 | SND_PCI_QUIRK(0x103c, 0x30ba, "HP Presario B1900", ALC260_FIXUP_HP_B1900), | 1722 | SND_PCI_QUIRK(0x103c, 0x30ba, "HP Presario B1900", ALC260_FIXUP_HP_B1900), |
1723 | SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_FIXUP_VAIO_PINS), | 1723 | SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_FIXUP_VAIO_PINS), |
1724 | SND_PCI_QUIRK(0x104d, 0x81e2, "Sony VAIO TX", ALC260_FIXUP_HP_PIN_0F), | 1724 | SND_PCI_QUIRK(0x104d, 0x81e2, "Sony VAIO TX", ALC260_FIXUP_HP_PIN_0F), |
1725 | SND_PCI_QUIRK(0x10cf, 0x1326, "FSC LifeBook S7020", ALC260_FIXUP_FSC_S7020), | 1725 | SND_PCI_QUIRK(0x10cf, 0x1326, "FSC LifeBook S7020", ALC260_FIXUP_FSC_S7020), |
1726 | SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FIXUP_GPIO1), | 1726 | SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FIXUP_GPIO1), |
1727 | SND_PCI_QUIRK(0x152d, 0x0729, "Quanta KN1", ALC260_FIXUP_KN1), | 1727 | SND_PCI_QUIRK(0x152d, 0x0729, "Quanta KN1", ALC260_FIXUP_KN1), |
1728 | SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_FIXUP_REPLACER), | 1728 | SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_FIXUP_REPLACER), |
1729 | SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_FIXUP_COEF), | 1729 | SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_FIXUP_COEF), |
1730 | {} | 1730 | {} |
1731 | }; | 1731 | }; |
1732 | 1732 | ||
1733 | static const struct hda_model_fixup alc260_fixup_models[] = { | 1733 | static const struct hda_model_fixup alc260_fixup_models[] = { |
1734 | {.id = ALC260_FIXUP_GPIO1, .name = "gpio1"}, | 1734 | {.id = ALC260_FIXUP_GPIO1, .name = "gpio1"}, |
1735 | {.id = ALC260_FIXUP_COEF, .name = "coef"}, | 1735 | {.id = ALC260_FIXUP_COEF, .name = "coef"}, |
1736 | {.id = ALC260_FIXUP_FSC_S7020, .name = "fujitsu"}, | 1736 | {.id = ALC260_FIXUP_FSC_S7020, .name = "fujitsu"}, |
1737 | {.id = ALC260_FIXUP_FSC_S7020_JWSE, .name = "fujitsu-jwse"}, | 1737 | {.id = ALC260_FIXUP_FSC_S7020_JWSE, .name = "fujitsu-jwse"}, |
1738 | {} | 1738 | {} |
1739 | }; | 1739 | }; |
1740 | 1740 | ||
1741 | /* | 1741 | /* |
1742 | */ | 1742 | */ |
1743 | static int patch_alc260(struct hda_codec *codec) | 1743 | static int patch_alc260(struct hda_codec *codec) |
1744 | { | 1744 | { |
1745 | struct alc_spec *spec; | 1745 | struct alc_spec *spec; |
1746 | int err; | 1746 | int err; |
1747 | 1747 | ||
1748 | err = alc_alloc_spec(codec, 0x07); | 1748 | err = alc_alloc_spec(codec, 0x07); |
1749 | if (err < 0) | 1749 | if (err < 0) |
1750 | return err; | 1750 | return err; |
1751 | 1751 | ||
1752 | spec = codec->spec; | 1752 | spec = codec->spec; |
1753 | /* as quite a few machines require HP amp for speaker outputs, | 1753 | /* as quite a few machines require HP amp for speaker outputs, |
1754 | * it's easier to enable it unconditionally; even if it's unneeded, | 1754 | * it's easier to enable it unconditionally; even if it's unneeded, |
1755 | * it's almost harmless. | 1755 | * it's almost harmless. |
1756 | */ | 1756 | */ |
1757 | spec->gen.prefer_hp_amp = 1; | 1757 | spec->gen.prefer_hp_amp = 1; |
1758 | spec->gen.beep_nid = 0x01; | 1758 | spec->gen.beep_nid = 0x01; |
1759 | 1759 | ||
1760 | snd_hda_pick_fixup(codec, alc260_fixup_models, alc260_fixup_tbl, | 1760 | snd_hda_pick_fixup(codec, alc260_fixup_models, alc260_fixup_tbl, |
1761 | alc260_fixups); | 1761 | alc260_fixups); |
1762 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); | 1762 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); |
1763 | 1763 | ||
1764 | /* automatic parse from the BIOS config */ | 1764 | /* automatic parse from the BIOS config */ |
1765 | err = alc260_parse_auto_config(codec); | 1765 | err = alc260_parse_auto_config(codec); |
1766 | if (err < 0) | 1766 | if (err < 0) |
1767 | goto error; | 1767 | goto error; |
1768 | 1768 | ||
1769 | if (!spec->gen.no_analog) | 1769 | if (!spec->gen.no_analog) |
1770 | set_beep_amp(spec, 0x07, 0x05, HDA_INPUT); | 1770 | set_beep_amp(spec, 0x07, 0x05, HDA_INPUT); |
1771 | 1771 | ||
1772 | codec->patch_ops = alc_patch_ops; | 1772 | codec->patch_ops = alc_patch_ops; |
1773 | spec->shutup = alc_eapd_shutup; | 1773 | spec->shutup = alc_eapd_shutup; |
1774 | 1774 | ||
1775 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); | 1775 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); |
1776 | 1776 | ||
1777 | return 0; | 1777 | return 0; |
1778 | 1778 | ||
1779 | error: | 1779 | error: |
1780 | alc_free(codec); | 1780 | alc_free(codec); |
1781 | return err; | 1781 | return err; |
1782 | } | 1782 | } |
1783 | 1783 | ||
1784 | 1784 | ||
1785 | /* | 1785 | /* |
1786 | * ALC882/883/885/888/889 support | 1786 | * ALC882/883/885/888/889 support |
1787 | * | 1787 | * |
1788 | * ALC882 is almost identical with ALC880 but has cleaner and more flexible | 1788 | * ALC882 is almost identical with ALC880 but has cleaner and more flexible |
1789 | * configuration. Each pin widget can choose any input DACs and a mixer. | 1789 | * configuration. Each pin widget can choose any input DACs and a mixer. |
1790 | * Each ADC is connected from a mixer of all inputs. This makes possible | 1790 | * Each ADC is connected from a mixer of all inputs. This makes possible |
1791 | * 6-channel independent captures. | 1791 | * 6-channel independent captures. |
1792 | * | 1792 | * |
1793 | * In addition, an independent DAC for the multi-playback (not used in this | 1793 | * In addition, an independent DAC for the multi-playback (not used in this |
1794 | * driver yet). | 1794 | * driver yet). |
1795 | */ | 1795 | */ |
1796 | 1796 | ||
1797 | /* | 1797 | /* |
1798 | * Pin config fixes | 1798 | * Pin config fixes |
1799 | */ | 1799 | */ |
1800 | enum { | 1800 | enum { |
1801 | ALC882_FIXUP_ABIT_AW9D_MAX, | 1801 | ALC882_FIXUP_ABIT_AW9D_MAX, |
1802 | ALC882_FIXUP_LENOVO_Y530, | 1802 | ALC882_FIXUP_LENOVO_Y530, |
1803 | ALC882_FIXUP_PB_M5210, | 1803 | ALC882_FIXUP_PB_M5210, |
1804 | ALC882_FIXUP_ACER_ASPIRE_7736, | 1804 | ALC882_FIXUP_ACER_ASPIRE_7736, |
1805 | ALC882_FIXUP_ASUS_W90V, | 1805 | ALC882_FIXUP_ASUS_W90V, |
1806 | ALC889_FIXUP_CD, | 1806 | ALC889_FIXUP_CD, |
1807 | ALC889_FIXUP_FRONT_HP_NO_PRESENCE, | 1807 | ALC889_FIXUP_FRONT_HP_NO_PRESENCE, |
1808 | ALC889_FIXUP_VAIO_TT, | 1808 | ALC889_FIXUP_VAIO_TT, |
1809 | ALC888_FIXUP_EEE1601, | 1809 | ALC888_FIXUP_EEE1601, |
1810 | ALC882_FIXUP_EAPD, | 1810 | ALC882_FIXUP_EAPD, |
1811 | ALC883_FIXUP_EAPD, | 1811 | ALC883_FIXUP_EAPD, |
1812 | ALC883_FIXUP_ACER_EAPD, | 1812 | ALC883_FIXUP_ACER_EAPD, |
1813 | ALC882_FIXUP_GPIO1, | 1813 | ALC882_FIXUP_GPIO1, |
1814 | ALC882_FIXUP_GPIO2, | 1814 | ALC882_FIXUP_GPIO2, |
1815 | ALC882_FIXUP_GPIO3, | 1815 | ALC882_FIXUP_GPIO3, |
1816 | ALC889_FIXUP_COEF, | 1816 | ALC889_FIXUP_COEF, |
1817 | ALC882_FIXUP_ASUS_W2JC, | 1817 | ALC882_FIXUP_ASUS_W2JC, |
1818 | ALC882_FIXUP_ACER_ASPIRE_4930G, | 1818 | ALC882_FIXUP_ACER_ASPIRE_4930G, |
1819 | ALC882_FIXUP_ACER_ASPIRE_8930G, | 1819 | ALC882_FIXUP_ACER_ASPIRE_8930G, |
1820 | ALC882_FIXUP_ASPIRE_8930G_VERBS, | 1820 | ALC882_FIXUP_ASPIRE_8930G_VERBS, |
1821 | ALC885_FIXUP_MACPRO_GPIO, | 1821 | ALC885_FIXUP_MACPRO_GPIO, |
1822 | ALC889_FIXUP_DAC_ROUTE, | 1822 | ALC889_FIXUP_DAC_ROUTE, |
1823 | ALC889_FIXUP_MBP_VREF, | 1823 | ALC889_FIXUP_MBP_VREF, |
1824 | ALC889_FIXUP_IMAC91_VREF, | 1824 | ALC889_FIXUP_IMAC91_VREF, |
1825 | ALC889_FIXUP_MBA11_VREF, | 1825 | ALC889_FIXUP_MBA11_VREF, |
1826 | ALC889_FIXUP_MBA21_VREF, | 1826 | ALC889_FIXUP_MBA21_VREF, |
1827 | ALC889_FIXUP_MP11_VREF, | 1827 | ALC889_FIXUP_MP11_VREF, |
1828 | ALC882_FIXUP_INV_DMIC, | 1828 | ALC882_FIXUP_INV_DMIC, |
1829 | ALC882_FIXUP_NO_PRIMARY_HP, | 1829 | ALC882_FIXUP_NO_PRIMARY_HP, |
1830 | ALC887_FIXUP_ASUS_BASS, | 1830 | ALC887_FIXUP_ASUS_BASS, |
1831 | ALC887_FIXUP_BASS_CHMAP, | 1831 | ALC887_FIXUP_BASS_CHMAP, |
1832 | }; | 1832 | }; |
1833 | 1833 | ||
1834 | static void alc889_fixup_coef(struct hda_codec *codec, | 1834 | static void alc889_fixup_coef(struct hda_codec *codec, |
1835 | const struct hda_fixup *fix, int action) | 1835 | const struct hda_fixup *fix, int action) |
1836 | { | 1836 | { |
1837 | if (action != HDA_FIXUP_ACT_INIT) | 1837 | if (action != HDA_FIXUP_ACT_INIT) |
1838 | return; | 1838 | return; |
1839 | alc889_coef_init(codec); | 1839 | alc889_coef_init(codec); |
1840 | } | 1840 | } |
1841 | 1841 | ||
1842 | /* toggle speaker-output according to the hp-jack state */ | 1842 | /* toggle speaker-output according to the hp-jack state */ |
1843 | static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted) | 1843 | static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted) |
1844 | { | 1844 | { |
1845 | unsigned int gpiostate, gpiomask, gpiodir; | 1845 | unsigned int gpiostate, gpiomask, gpiodir; |
1846 | 1846 | ||
1847 | gpiostate = snd_hda_codec_read(codec, codec->afg, 0, | 1847 | gpiostate = snd_hda_codec_read(codec, codec->afg, 0, |
1848 | AC_VERB_GET_GPIO_DATA, 0); | 1848 | AC_VERB_GET_GPIO_DATA, 0); |
1849 | 1849 | ||
1850 | if (!muted) | 1850 | if (!muted) |
1851 | gpiostate |= (1 << pin); | 1851 | gpiostate |= (1 << pin); |
1852 | else | 1852 | else |
1853 | gpiostate &= ~(1 << pin); | 1853 | gpiostate &= ~(1 << pin); |
1854 | 1854 | ||
1855 | gpiomask = snd_hda_codec_read(codec, codec->afg, 0, | 1855 | gpiomask = snd_hda_codec_read(codec, codec->afg, 0, |
1856 | AC_VERB_GET_GPIO_MASK, 0); | 1856 | AC_VERB_GET_GPIO_MASK, 0); |
1857 | gpiomask |= (1 << pin); | 1857 | gpiomask |= (1 << pin); |
1858 | 1858 | ||
1859 | gpiodir = snd_hda_codec_read(codec, codec->afg, 0, | 1859 | gpiodir = snd_hda_codec_read(codec, codec->afg, 0, |
1860 | AC_VERB_GET_GPIO_DIRECTION, 0); | 1860 | AC_VERB_GET_GPIO_DIRECTION, 0); |
1861 | gpiodir |= (1 << pin); | 1861 | gpiodir |= (1 << pin); |
1862 | 1862 | ||
1863 | 1863 | ||
1864 | snd_hda_codec_write(codec, codec->afg, 0, | 1864 | snd_hda_codec_write(codec, codec->afg, 0, |
1865 | AC_VERB_SET_GPIO_MASK, gpiomask); | 1865 | AC_VERB_SET_GPIO_MASK, gpiomask); |
1866 | snd_hda_codec_write(codec, codec->afg, 0, | 1866 | snd_hda_codec_write(codec, codec->afg, 0, |
1867 | AC_VERB_SET_GPIO_DIRECTION, gpiodir); | 1867 | AC_VERB_SET_GPIO_DIRECTION, gpiodir); |
1868 | 1868 | ||
1869 | msleep(1); | 1869 | msleep(1); |
1870 | 1870 | ||
1871 | snd_hda_codec_write(codec, codec->afg, 0, | 1871 | snd_hda_codec_write(codec, codec->afg, 0, |
1872 | AC_VERB_SET_GPIO_DATA, gpiostate); | 1872 | AC_VERB_SET_GPIO_DATA, gpiostate); |
1873 | } | 1873 | } |
1874 | 1874 | ||
1875 | /* set up GPIO at initialization */ | 1875 | /* set up GPIO at initialization */ |
1876 | static void alc885_fixup_macpro_gpio(struct hda_codec *codec, | 1876 | static void alc885_fixup_macpro_gpio(struct hda_codec *codec, |
1877 | const struct hda_fixup *fix, int action) | 1877 | const struct hda_fixup *fix, int action) |
1878 | { | 1878 | { |
1879 | if (action != HDA_FIXUP_ACT_INIT) | 1879 | if (action != HDA_FIXUP_ACT_INIT) |
1880 | return; | 1880 | return; |
1881 | alc882_gpio_mute(codec, 0, 0); | 1881 | alc882_gpio_mute(codec, 0, 0); |
1882 | alc882_gpio_mute(codec, 1, 0); | 1882 | alc882_gpio_mute(codec, 1, 0); |
1883 | } | 1883 | } |
1884 | 1884 | ||
1885 | /* Fix the connection of some pins for ALC889: | 1885 | /* Fix the connection of some pins for ALC889: |
1886 | * At least, Acer Aspire 5935 shows the connections to DAC3/4 don't | 1886 | * At least, Acer Aspire 5935 shows the connections to DAC3/4 don't |
1887 | * work correctly (bko#42740) | 1887 | * work correctly (bko#42740) |
1888 | */ | 1888 | */ |
1889 | static void alc889_fixup_dac_route(struct hda_codec *codec, | 1889 | static void alc889_fixup_dac_route(struct hda_codec *codec, |
1890 | const struct hda_fixup *fix, int action) | 1890 | const struct hda_fixup *fix, int action) |
1891 | { | 1891 | { |
1892 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | 1892 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
1893 | /* fake the connections during parsing the tree */ | 1893 | /* fake the connections during parsing the tree */ |
1894 | hda_nid_t conn1[2] = { 0x0c, 0x0d }; | 1894 | hda_nid_t conn1[2] = { 0x0c, 0x0d }; |
1895 | hda_nid_t conn2[2] = { 0x0e, 0x0f }; | 1895 | hda_nid_t conn2[2] = { 0x0e, 0x0f }; |
1896 | snd_hda_override_conn_list(codec, 0x14, 2, conn1); | 1896 | snd_hda_override_conn_list(codec, 0x14, 2, conn1); |
1897 | snd_hda_override_conn_list(codec, 0x15, 2, conn1); | 1897 | snd_hda_override_conn_list(codec, 0x15, 2, conn1); |
1898 | snd_hda_override_conn_list(codec, 0x18, 2, conn2); | 1898 | snd_hda_override_conn_list(codec, 0x18, 2, conn2); |
1899 | snd_hda_override_conn_list(codec, 0x1a, 2, conn2); | 1899 | snd_hda_override_conn_list(codec, 0x1a, 2, conn2); |
1900 | } else if (action == HDA_FIXUP_ACT_PROBE) { | 1900 | } else if (action == HDA_FIXUP_ACT_PROBE) { |
1901 | /* restore the connections */ | 1901 | /* restore the connections */ |
1902 | hda_nid_t conn[5] = { 0x0c, 0x0d, 0x0e, 0x0f, 0x26 }; | 1902 | hda_nid_t conn[5] = { 0x0c, 0x0d, 0x0e, 0x0f, 0x26 }; |
1903 | snd_hda_override_conn_list(codec, 0x14, 5, conn); | 1903 | snd_hda_override_conn_list(codec, 0x14, 5, conn); |
1904 | snd_hda_override_conn_list(codec, 0x15, 5, conn); | 1904 | snd_hda_override_conn_list(codec, 0x15, 5, conn); |
1905 | snd_hda_override_conn_list(codec, 0x18, 5, conn); | 1905 | snd_hda_override_conn_list(codec, 0x18, 5, conn); |
1906 | snd_hda_override_conn_list(codec, 0x1a, 5, conn); | 1906 | snd_hda_override_conn_list(codec, 0x1a, 5, conn); |
1907 | } | 1907 | } |
1908 | } | 1908 | } |
1909 | 1909 | ||
1910 | /* Set VREF on HP pin */ | 1910 | /* Set VREF on HP pin */ |
1911 | static void alc889_fixup_mbp_vref(struct hda_codec *codec, | 1911 | static void alc889_fixup_mbp_vref(struct hda_codec *codec, |
1912 | const struct hda_fixup *fix, int action) | 1912 | const struct hda_fixup *fix, int action) |
1913 | { | 1913 | { |
1914 | struct alc_spec *spec = codec->spec; | 1914 | struct alc_spec *spec = codec->spec; |
1915 | static hda_nid_t nids[2] = { 0x14, 0x15 }; | 1915 | static hda_nid_t nids[2] = { 0x14, 0x15 }; |
1916 | int i; | 1916 | int i; |
1917 | 1917 | ||
1918 | if (action != HDA_FIXUP_ACT_INIT) | 1918 | if (action != HDA_FIXUP_ACT_INIT) |
1919 | return; | 1919 | return; |
1920 | for (i = 0; i < ARRAY_SIZE(nids); i++) { | 1920 | for (i = 0; i < ARRAY_SIZE(nids); i++) { |
1921 | unsigned int val = snd_hda_codec_get_pincfg(codec, nids[i]); | 1921 | unsigned int val = snd_hda_codec_get_pincfg(codec, nids[i]); |
1922 | if (get_defcfg_device(val) != AC_JACK_HP_OUT) | 1922 | if (get_defcfg_device(val) != AC_JACK_HP_OUT) |
1923 | continue; | 1923 | continue; |
1924 | val = snd_hda_codec_get_pin_target(codec, nids[i]); | 1924 | val = snd_hda_codec_get_pin_target(codec, nids[i]); |
1925 | val |= AC_PINCTL_VREF_80; | 1925 | val |= AC_PINCTL_VREF_80; |
1926 | snd_hda_set_pin_ctl(codec, nids[i], val); | 1926 | snd_hda_set_pin_ctl(codec, nids[i], val); |
1927 | spec->gen.keep_vref_in_automute = 1; | 1927 | spec->gen.keep_vref_in_automute = 1; |
1928 | break; | 1928 | break; |
1929 | } | 1929 | } |
1930 | } | 1930 | } |
1931 | 1931 | ||
1932 | static void alc889_fixup_mac_pins(struct hda_codec *codec, | 1932 | static void alc889_fixup_mac_pins(struct hda_codec *codec, |
1933 | const hda_nid_t *nids, int num_nids) | 1933 | const hda_nid_t *nids, int num_nids) |
1934 | { | 1934 | { |
1935 | struct alc_spec *spec = codec->spec; | 1935 | struct alc_spec *spec = codec->spec; |
1936 | int i; | 1936 | int i; |
1937 | 1937 | ||
1938 | for (i = 0; i < num_nids; i++) { | 1938 | for (i = 0; i < num_nids; i++) { |
1939 | unsigned int val; | 1939 | unsigned int val; |
1940 | val = snd_hda_codec_get_pin_target(codec, nids[i]); | 1940 | val = snd_hda_codec_get_pin_target(codec, nids[i]); |
1941 | val |= AC_PINCTL_VREF_50; | 1941 | val |= AC_PINCTL_VREF_50; |
1942 | snd_hda_set_pin_ctl(codec, nids[i], val); | 1942 | snd_hda_set_pin_ctl(codec, nids[i], val); |
1943 | } | 1943 | } |
1944 | spec->gen.keep_vref_in_automute = 1; | 1944 | spec->gen.keep_vref_in_automute = 1; |
1945 | } | 1945 | } |
1946 | 1946 | ||
1947 | /* Set VREF on speaker pins on imac91 */ | 1947 | /* Set VREF on speaker pins on imac91 */ |
1948 | static void alc889_fixup_imac91_vref(struct hda_codec *codec, | 1948 | static void alc889_fixup_imac91_vref(struct hda_codec *codec, |
1949 | const struct hda_fixup *fix, int action) | 1949 | const struct hda_fixup *fix, int action) |
1950 | { | 1950 | { |
1951 | static hda_nid_t nids[2] = { 0x18, 0x1a }; | 1951 | static hda_nid_t nids[2] = { 0x18, 0x1a }; |
1952 | 1952 | ||
1953 | if (action == HDA_FIXUP_ACT_INIT) | 1953 | if (action == HDA_FIXUP_ACT_INIT) |
1954 | alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids)); | 1954 | alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids)); |
1955 | } | 1955 | } |
1956 | 1956 | ||
1957 | /* Set VREF on speaker pins on mba11 */ | 1957 | /* Set VREF on speaker pins on mba11 */ |
1958 | static void alc889_fixup_mba11_vref(struct hda_codec *codec, | 1958 | static void alc889_fixup_mba11_vref(struct hda_codec *codec, |
1959 | const struct hda_fixup *fix, int action) | 1959 | const struct hda_fixup *fix, int action) |
1960 | { | 1960 | { |
1961 | static hda_nid_t nids[1] = { 0x18 }; | 1961 | static hda_nid_t nids[1] = { 0x18 }; |
1962 | 1962 | ||
1963 | if (action == HDA_FIXUP_ACT_INIT) | 1963 | if (action == HDA_FIXUP_ACT_INIT) |
1964 | alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids)); | 1964 | alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids)); |
1965 | } | 1965 | } |
1966 | 1966 | ||
1967 | /* Set VREF on speaker pins on mba21 */ | 1967 | /* Set VREF on speaker pins on mba21 */ |
1968 | static void alc889_fixup_mba21_vref(struct hda_codec *codec, | 1968 | static void alc889_fixup_mba21_vref(struct hda_codec *codec, |
1969 | const struct hda_fixup *fix, int action) | 1969 | const struct hda_fixup *fix, int action) |
1970 | { | 1970 | { |
1971 | static hda_nid_t nids[2] = { 0x18, 0x19 }; | 1971 | static hda_nid_t nids[2] = { 0x18, 0x19 }; |
1972 | 1972 | ||
1973 | if (action == HDA_FIXUP_ACT_INIT) | 1973 | if (action == HDA_FIXUP_ACT_INIT) |
1974 | alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids)); | 1974 | alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids)); |
1975 | } | 1975 | } |
1976 | 1976 | ||
1977 | /* Don't take HP output as primary | 1977 | /* Don't take HP output as primary |
1978 | * Strangely, the speaker output doesn't work on Vaio Z and some Vaio | 1978 | * Strangely, the speaker output doesn't work on Vaio Z and some Vaio |
1979 | * all-in-one desktop PCs (for example VGC-LN51JGB) through DAC 0x05 | 1979 | * all-in-one desktop PCs (for example VGC-LN51JGB) through DAC 0x05 |
1980 | */ | 1980 | */ |
1981 | static void alc882_fixup_no_primary_hp(struct hda_codec *codec, | 1981 | static void alc882_fixup_no_primary_hp(struct hda_codec *codec, |
1982 | const struct hda_fixup *fix, int action) | 1982 | const struct hda_fixup *fix, int action) |
1983 | { | 1983 | { |
1984 | struct alc_spec *spec = codec->spec; | 1984 | struct alc_spec *spec = codec->spec; |
1985 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | 1985 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
1986 | spec->gen.no_primary_hp = 1; | 1986 | spec->gen.no_primary_hp = 1; |
1987 | spec->gen.no_multi_io = 1; | 1987 | spec->gen.no_multi_io = 1; |
1988 | } | 1988 | } |
1989 | } | 1989 | } |
1990 | 1990 | ||
1991 | static void alc_fixup_bass_chmap(struct hda_codec *codec, | 1991 | static void alc_fixup_bass_chmap(struct hda_codec *codec, |
1992 | const struct hda_fixup *fix, int action); | 1992 | const struct hda_fixup *fix, int action); |
1993 | 1993 | ||
1994 | static const struct hda_fixup alc882_fixups[] = { | 1994 | static const struct hda_fixup alc882_fixups[] = { |
1995 | [ALC882_FIXUP_ABIT_AW9D_MAX] = { | 1995 | [ALC882_FIXUP_ABIT_AW9D_MAX] = { |
1996 | .type = HDA_FIXUP_PINS, | 1996 | .type = HDA_FIXUP_PINS, |
1997 | .v.pins = (const struct hda_pintbl[]) { | 1997 | .v.pins = (const struct hda_pintbl[]) { |
1998 | { 0x15, 0x01080104 }, /* side */ | 1998 | { 0x15, 0x01080104 }, /* side */ |
1999 | { 0x16, 0x01011012 }, /* rear */ | 1999 | { 0x16, 0x01011012 }, /* rear */ |
2000 | { 0x17, 0x01016011 }, /* clfe */ | 2000 | { 0x17, 0x01016011 }, /* clfe */ |
2001 | { } | 2001 | { } |
2002 | } | 2002 | } |
2003 | }, | 2003 | }, |
2004 | [ALC882_FIXUP_LENOVO_Y530] = { | 2004 | [ALC882_FIXUP_LENOVO_Y530] = { |
2005 | .type = HDA_FIXUP_PINS, | 2005 | .type = HDA_FIXUP_PINS, |
2006 | .v.pins = (const struct hda_pintbl[]) { | 2006 | .v.pins = (const struct hda_pintbl[]) { |
2007 | { 0x15, 0x99130112 }, /* rear int speakers */ | 2007 | { 0x15, 0x99130112 }, /* rear int speakers */ |
2008 | { 0x16, 0x99130111 }, /* subwoofer */ | 2008 | { 0x16, 0x99130111 }, /* subwoofer */ |
2009 | { } | 2009 | { } |
2010 | } | 2010 | } |
2011 | }, | 2011 | }, |
2012 | [ALC882_FIXUP_PB_M5210] = { | 2012 | [ALC882_FIXUP_PB_M5210] = { |
2013 | .type = HDA_FIXUP_PINCTLS, | 2013 | .type = HDA_FIXUP_PINCTLS, |
2014 | .v.pins = (const struct hda_pintbl[]) { | 2014 | .v.pins = (const struct hda_pintbl[]) { |
2015 | { 0x19, PIN_VREF50 }, | 2015 | { 0x19, PIN_VREF50 }, |
2016 | {} | 2016 | {} |
2017 | } | 2017 | } |
2018 | }, | 2018 | }, |
2019 | [ALC882_FIXUP_ACER_ASPIRE_7736] = { | 2019 | [ALC882_FIXUP_ACER_ASPIRE_7736] = { |
2020 | .type = HDA_FIXUP_FUNC, | 2020 | .type = HDA_FIXUP_FUNC, |
2021 | .v.func = alc_fixup_sku_ignore, | 2021 | .v.func = alc_fixup_sku_ignore, |
2022 | }, | 2022 | }, |
2023 | [ALC882_FIXUP_ASUS_W90V] = { | 2023 | [ALC882_FIXUP_ASUS_W90V] = { |
2024 | .type = HDA_FIXUP_PINS, | 2024 | .type = HDA_FIXUP_PINS, |
2025 | .v.pins = (const struct hda_pintbl[]) { | 2025 | .v.pins = (const struct hda_pintbl[]) { |
2026 | { 0x16, 0x99130110 }, /* fix sequence for CLFE */ | 2026 | { 0x16, 0x99130110 }, /* fix sequence for CLFE */ |
2027 | { } | 2027 | { } |
2028 | } | 2028 | } |
2029 | }, | 2029 | }, |
2030 | [ALC889_FIXUP_CD] = { | 2030 | [ALC889_FIXUP_CD] = { |
2031 | .type = HDA_FIXUP_PINS, | 2031 | .type = HDA_FIXUP_PINS, |
2032 | .v.pins = (const struct hda_pintbl[]) { | 2032 | .v.pins = (const struct hda_pintbl[]) { |
2033 | { 0x1c, 0x993301f0 }, /* CD */ | 2033 | { 0x1c, 0x993301f0 }, /* CD */ |
2034 | { } | 2034 | { } |
2035 | } | 2035 | } |
2036 | }, | 2036 | }, |
2037 | [ALC889_FIXUP_FRONT_HP_NO_PRESENCE] = { | 2037 | [ALC889_FIXUP_FRONT_HP_NO_PRESENCE] = { |
2038 | .type = HDA_FIXUP_PINS, | 2038 | .type = HDA_FIXUP_PINS, |
2039 | .v.pins = (const struct hda_pintbl[]) { | 2039 | .v.pins = (const struct hda_pintbl[]) { |
2040 | { 0x1b, 0x02214120 }, /* Front HP jack is flaky, disable jack detect */ | 2040 | { 0x1b, 0x02214120 }, /* Front HP jack is flaky, disable jack detect */ |
2041 | { } | 2041 | { } |
2042 | }, | 2042 | }, |
2043 | .chained = true, | 2043 | .chained = true, |
2044 | .chain_id = ALC889_FIXUP_CD, | 2044 | .chain_id = ALC889_FIXUP_CD, |
2045 | }, | 2045 | }, |
2046 | [ALC889_FIXUP_VAIO_TT] = { | 2046 | [ALC889_FIXUP_VAIO_TT] = { |
2047 | .type = HDA_FIXUP_PINS, | 2047 | .type = HDA_FIXUP_PINS, |
2048 | .v.pins = (const struct hda_pintbl[]) { | 2048 | .v.pins = (const struct hda_pintbl[]) { |
2049 | { 0x17, 0x90170111 }, /* hidden surround speaker */ | 2049 | { 0x17, 0x90170111 }, /* hidden surround speaker */ |
2050 | { } | 2050 | { } |
2051 | } | 2051 | } |
2052 | }, | 2052 | }, |
2053 | [ALC888_FIXUP_EEE1601] = { | 2053 | [ALC888_FIXUP_EEE1601] = { |
2054 | .type = HDA_FIXUP_VERBS, | 2054 | .type = HDA_FIXUP_VERBS, |
2055 | .v.verbs = (const struct hda_verb[]) { | 2055 | .v.verbs = (const struct hda_verb[]) { |
2056 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b }, | 2056 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b }, |
2057 | { 0x20, AC_VERB_SET_PROC_COEF, 0x0838 }, | 2057 | { 0x20, AC_VERB_SET_PROC_COEF, 0x0838 }, |
2058 | { } | 2058 | { } |
2059 | } | 2059 | } |
2060 | }, | 2060 | }, |
2061 | [ALC882_FIXUP_EAPD] = { | 2061 | [ALC882_FIXUP_EAPD] = { |
2062 | .type = HDA_FIXUP_VERBS, | 2062 | .type = HDA_FIXUP_VERBS, |
2063 | .v.verbs = (const struct hda_verb[]) { | 2063 | .v.verbs = (const struct hda_verb[]) { |
2064 | /* change to EAPD mode */ | 2064 | /* change to EAPD mode */ |
2065 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, | 2065 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, |
2066 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 }, | 2066 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 }, |
2067 | { } | 2067 | { } |
2068 | } | 2068 | } |
2069 | }, | 2069 | }, |
2070 | [ALC883_FIXUP_EAPD] = { | 2070 | [ALC883_FIXUP_EAPD] = { |
2071 | .type = HDA_FIXUP_VERBS, | 2071 | .type = HDA_FIXUP_VERBS, |
2072 | .v.verbs = (const struct hda_verb[]) { | 2072 | .v.verbs = (const struct hda_verb[]) { |
2073 | /* change to EAPD mode */ | 2073 | /* change to EAPD mode */ |
2074 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, | 2074 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, |
2075 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 }, | 2075 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 }, |
2076 | { } | 2076 | { } |
2077 | } | 2077 | } |
2078 | }, | 2078 | }, |
2079 | [ALC883_FIXUP_ACER_EAPD] = { | 2079 | [ALC883_FIXUP_ACER_EAPD] = { |
2080 | .type = HDA_FIXUP_VERBS, | 2080 | .type = HDA_FIXUP_VERBS, |
2081 | .v.verbs = (const struct hda_verb[]) { | 2081 | .v.verbs = (const struct hda_verb[]) { |
2082 | /* eanable EAPD on Acer laptops */ | 2082 | /* eanable EAPD on Acer laptops */ |
2083 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, | 2083 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, |
2084 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 }, | 2084 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 }, |
2085 | { } | 2085 | { } |
2086 | } | 2086 | } |
2087 | }, | 2087 | }, |
2088 | [ALC882_FIXUP_GPIO1] = { | 2088 | [ALC882_FIXUP_GPIO1] = { |
2089 | .type = HDA_FIXUP_VERBS, | 2089 | .type = HDA_FIXUP_VERBS, |
2090 | .v.verbs = alc_gpio1_init_verbs, | 2090 | .v.verbs = alc_gpio1_init_verbs, |
2091 | }, | 2091 | }, |
2092 | [ALC882_FIXUP_GPIO2] = { | 2092 | [ALC882_FIXUP_GPIO2] = { |
2093 | .type = HDA_FIXUP_VERBS, | 2093 | .type = HDA_FIXUP_VERBS, |
2094 | .v.verbs = alc_gpio2_init_verbs, | 2094 | .v.verbs = alc_gpio2_init_verbs, |
2095 | }, | 2095 | }, |
2096 | [ALC882_FIXUP_GPIO3] = { | 2096 | [ALC882_FIXUP_GPIO3] = { |
2097 | .type = HDA_FIXUP_VERBS, | 2097 | .type = HDA_FIXUP_VERBS, |
2098 | .v.verbs = alc_gpio3_init_verbs, | 2098 | .v.verbs = alc_gpio3_init_verbs, |
2099 | }, | 2099 | }, |
2100 | [ALC882_FIXUP_ASUS_W2JC] = { | 2100 | [ALC882_FIXUP_ASUS_W2JC] = { |
2101 | .type = HDA_FIXUP_VERBS, | 2101 | .type = HDA_FIXUP_VERBS, |
2102 | .v.verbs = alc_gpio1_init_verbs, | 2102 | .v.verbs = alc_gpio1_init_verbs, |
2103 | .chained = true, | 2103 | .chained = true, |
2104 | .chain_id = ALC882_FIXUP_EAPD, | 2104 | .chain_id = ALC882_FIXUP_EAPD, |
2105 | }, | 2105 | }, |
2106 | [ALC889_FIXUP_COEF] = { | 2106 | [ALC889_FIXUP_COEF] = { |
2107 | .type = HDA_FIXUP_FUNC, | 2107 | .type = HDA_FIXUP_FUNC, |
2108 | .v.func = alc889_fixup_coef, | 2108 | .v.func = alc889_fixup_coef, |
2109 | }, | 2109 | }, |
2110 | [ALC882_FIXUP_ACER_ASPIRE_4930G] = { | 2110 | [ALC882_FIXUP_ACER_ASPIRE_4930G] = { |
2111 | .type = HDA_FIXUP_PINS, | 2111 | .type = HDA_FIXUP_PINS, |
2112 | .v.pins = (const struct hda_pintbl[]) { | 2112 | .v.pins = (const struct hda_pintbl[]) { |
2113 | { 0x16, 0x99130111 }, /* CLFE speaker */ | 2113 | { 0x16, 0x99130111 }, /* CLFE speaker */ |
2114 | { 0x17, 0x99130112 }, /* surround speaker */ | 2114 | { 0x17, 0x99130112 }, /* surround speaker */ |
2115 | { } | 2115 | { } |
2116 | }, | 2116 | }, |
2117 | .chained = true, | 2117 | .chained = true, |
2118 | .chain_id = ALC882_FIXUP_GPIO1, | 2118 | .chain_id = ALC882_FIXUP_GPIO1, |
2119 | }, | 2119 | }, |
2120 | [ALC882_FIXUP_ACER_ASPIRE_8930G] = { | 2120 | [ALC882_FIXUP_ACER_ASPIRE_8930G] = { |
2121 | .type = HDA_FIXUP_PINS, | 2121 | .type = HDA_FIXUP_PINS, |
2122 | .v.pins = (const struct hda_pintbl[]) { | 2122 | .v.pins = (const struct hda_pintbl[]) { |
2123 | { 0x16, 0x99130111 }, /* CLFE speaker */ | 2123 | { 0x16, 0x99130111 }, /* CLFE speaker */ |
2124 | { 0x1b, 0x99130112 }, /* surround speaker */ | 2124 | { 0x1b, 0x99130112 }, /* surround speaker */ |
2125 | { } | 2125 | { } |
2126 | }, | 2126 | }, |
2127 | .chained = true, | 2127 | .chained = true, |
2128 | .chain_id = ALC882_FIXUP_ASPIRE_8930G_VERBS, | 2128 | .chain_id = ALC882_FIXUP_ASPIRE_8930G_VERBS, |
2129 | }, | 2129 | }, |
2130 | [ALC882_FIXUP_ASPIRE_8930G_VERBS] = { | 2130 | [ALC882_FIXUP_ASPIRE_8930G_VERBS] = { |
2131 | /* additional init verbs for Acer Aspire 8930G */ | 2131 | /* additional init verbs for Acer Aspire 8930G */ |
2132 | .type = HDA_FIXUP_VERBS, | 2132 | .type = HDA_FIXUP_VERBS, |
2133 | .v.verbs = (const struct hda_verb[]) { | 2133 | .v.verbs = (const struct hda_verb[]) { |
2134 | /* Enable all DACs */ | 2134 | /* Enable all DACs */ |
2135 | /* DAC DISABLE/MUTE 1? */ | 2135 | /* DAC DISABLE/MUTE 1? */ |
2136 | /* setting bits 1-5 disables DAC nids 0x02-0x06 | 2136 | /* setting bits 1-5 disables DAC nids 0x02-0x06 |
2137 | * apparently. Init=0x38 */ | 2137 | * apparently. Init=0x38 */ |
2138 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x03 }, | 2138 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x03 }, |
2139 | { 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, | 2139 | { 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, |
2140 | /* DAC DISABLE/MUTE 2? */ | 2140 | /* DAC DISABLE/MUTE 2? */ |
2141 | /* some bit here disables the other DACs. | 2141 | /* some bit here disables the other DACs. |
2142 | * Init=0x4900 */ | 2142 | * Init=0x4900 */ |
2143 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x08 }, | 2143 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x08 }, |
2144 | { 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, | 2144 | { 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, |
2145 | /* DMIC fix | 2145 | /* DMIC fix |
2146 | * This laptop has a stereo digital microphone. | 2146 | * This laptop has a stereo digital microphone. |
2147 | * The mics are only 1cm apart which makes the stereo | 2147 | * The mics are only 1cm apart which makes the stereo |
2148 | * useless. However, either the mic or the ALC889 | 2148 | * useless. However, either the mic or the ALC889 |
2149 | * makes the signal become a difference/sum signal | 2149 | * makes the signal become a difference/sum signal |
2150 | * instead of standard stereo, which is annoying. | 2150 | * instead of standard stereo, which is annoying. |
2151 | * So instead we flip this bit which makes the | 2151 | * So instead we flip this bit which makes the |
2152 | * codec replicate the sum signal to both channels, | 2152 | * codec replicate the sum signal to both channels, |
2153 | * turning it into a normal mono mic. | 2153 | * turning it into a normal mono mic. |
2154 | */ | 2154 | */ |
2155 | /* DMIC_CONTROL? Init value = 0x0001 */ | 2155 | /* DMIC_CONTROL? Init value = 0x0001 */ |
2156 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b }, | 2156 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b }, |
2157 | { 0x20, AC_VERB_SET_PROC_COEF, 0x0003 }, | 2157 | { 0x20, AC_VERB_SET_PROC_COEF, 0x0003 }, |
2158 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, | 2158 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, |
2159 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 }, | 2159 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 }, |
2160 | { } | 2160 | { } |
2161 | }, | 2161 | }, |
2162 | .chained = true, | 2162 | .chained = true, |
2163 | .chain_id = ALC882_FIXUP_GPIO1, | 2163 | .chain_id = ALC882_FIXUP_GPIO1, |
2164 | }, | 2164 | }, |
2165 | [ALC885_FIXUP_MACPRO_GPIO] = { | 2165 | [ALC885_FIXUP_MACPRO_GPIO] = { |
2166 | .type = HDA_FIXUP_FUNC, | 2166 | .type = HDA_FIXUP_FUNC, |
2167 | .v.func = alc885_fixup_macpro_gpio, | 2167 | .v.func = alc885_fixup_macpro_gpio, |
2168 | }, | 2168 | }, |
2169 | [ALC889_FIXUP_DAC_ROUTE] = { | 2169 | [ALC889_FIXUP_DAC_ROUTE] = { |
2170 | .type = HDA_FIXUP_FUNC, | 2170 | .type = HDA_FIXUP_FUNC, |
2171 | .v.func = alc889_fixup_dac_route, | 2171 | .v.func = alc889_fixup_dac_route, |
2172 | }, | 2172 | }, |
2173 | [ALC889_FIXUP_MBP_VREF] = { | 2173 | [ALC889_FIXUP_MBP_VREF] = { |
2174 | .type = HDA_FIXUP_FUNC, | 2174 | .type = HDA_FIXUP_FUNC, |
2175 | .v.func = alc889_fixup_mbp_vref, | 2175 | .v.func = alc889_fixup_mbp_vref, |
2176 | .chained = true, | 2176 | .chained = true, |
2177 | .chain_id = ALC882_FIXUP_GPIO1, | 2177 | .chain_id = ALC882_FIXUP_GPIO1, |
2178 | }, | 2178 | }, |
2179 | [ALC889_FIXUP_IMAC91_VREF] = { | 2179 | [ALC889_FIXUP_IMAC91_VREF] = { |
2180 | .type = HDA_FIXUP_FUNC, | 2180 | .type = HDA_FIXUP_FUNC, |
2181 | .v.func = alc889_fixup_imac91_vref, | 2181 | .v.func = alc889_fixup_imac91_vref, |
2182 | .chained = true, | 2182 | .chained = true, |
2183 | .chain_id = ALC882_FIXUP_GPIO1, | 2183 | .chain_id = ALC882_FIXUP_GPIO1, |
2184 | }, | 2184 | }, |
2185 | [ALC889_FIXUP_MBA11_VREF] = { | 2185 | [ALC889_FIXUP_MBA11_VREF] = { |
2186 | .type = HDA_FIXUP_FUNC, | 2186 | .type = HDA_FIXUP_FUNC, |
2187 | .v.func = alc889_fixup_mba11_vref, | 2187 | .v.func = alc889_fixup_mba11_vref, |
2188 | .chained = true, | 2188 | .chained = true, |
2189 | .chain_id = ALC889_FIXUP_MBP_VREF, | 2189 | .chain_id = ALC889_FIXUP_MBP_VREF, |
2190 | }, | 2190 | }, |
2191 | [ALC889_FIXUP_MBA21_VREF] = { | 2191 | [ALC889_FIXUP_MBA21_VREF] = { |
2192 | .type = HDA_FIXUP_FUNC, | 2192 | .type = HDA_FIXUP_FUNC, |
2193 | .v.func = alc889_fixup_mba21_vref, | 2193 | .v.func = alc889_fixup_mba21_vref, |
2194 | .chained = true, | 2194 | .chained = true, |
2195 | .chain_id = ALC889_FIXUP_MBP_VREF, | 2195 | .chain_id = ALC889_FIXUP_MBP_VREF, |
2196 | }, | 2196 | }, |
2197 | [ALC889_FIXUP_MP11_VREF] = { | 2197 | [ALC889_FIXUP_MP11_VREF] = { |
2198 | .type = HDA_FIXUP_FUNC, | 2198 | .type = HDA_FIXUP_FUNC, |
2199 | .v.func = alc889_fixup_mba11_vref, | 2199 | .v.func = alc889_fixup_mba11_vref, |
2200 | .chained = true, | 2200 | .chained = true, |
2201 | .chain_id = ALC885_FIXUP_MACPRO_GPIO, | 2201 | .chain_id = ALC885_FIXUP_MACPRO_GPIO, |
2202 | }, | 2202 | }, |
2203 | [ALC882_FIXUP_INV_DMIC] = { | 2203 | [ALC882_FIXUP_INV_DMIC] = { |
2204 | .type = HDA_FIXUP_FUNC, | 2204 | .type = HDA_FIXUP_FUNC, |
2205 | .v.func = alc_fixup_inv_dmic_0x12, | 2205 | .v.func = alc_fixup_inv_dmic_0x12, |
2206 | }, | 2206 | }, |
2207 | [ALC882_FIXUP_NO_PRIMARY_HP] = { | 2207 | [ALC882_FIXUP_NO_PRIMARY_HP] = { |
2208 | .type = HDA_FIXUP_FUNC, | 2208 | .type = HDA_FIXUP_FUNC, |
2209 | .v.func = alc882_fixup_no_primary_hp, | 2209 | .v.func = alc882_fixup_no_primary_hp, |
2210 | }, | 2210 | }, |
2211 | [ALC887_FIXUP_ASUS_BASS] = { | 2211 | [ALC887_FIXUP_ASUS_BASS] = { |
2212 | .type = HDA_FIXUP_PINS, | 2212 | .type = HDA_FIXUP_PINS, |
2213 | .v.pins = (const struct hda_pintbl[]) { | 2213 | .v.pins = (const struct hda_pintbl[]) { |
2214 | {0x16, 0x99130130}, /* bass speaker */ | 2214 | {0x16, 0x99130130}, /* bass speaker */ |
2215 | {} | 2215 | {} |
2216 | }, | 2216 | }, |
2217 | .chained = true, | 2217 | .chained = true, |
2218 | .chain_id = ALC887_FIXUP_BASS_CHMAP, | 2218 | .chain_id = ALC887_FIXUP_BASS_CHMAP, |
2219 | }, | 2219 | }, |
2220 | [ALC887_FIXUP_BASS_CHMAP] = { | 2220 | [ALC887_FIXUP_BASS_CHMAP] = { |
2221 | .type = HDA_FIXUP_FUNC, | 2221 | .type = HDA_FIXUP_FUNC, |
2222 | .v.func = alc_fixup_bass_chmap, | 2222 | .v.func = alc_fixup_bass_chmap, |
2223 | }, | 2223 | }, |
2224 | }; | 2224 | }; |
2225 | 2225 | ||
2226 | static const struct snd_pci_quirk alc882_fixup_tbl[] = { | 2226 | static const struct snd_pci_quirk alc882_fixup_tbl[] = { |
2227 | SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_FIXUP_ACER_EAPD), | 2227 | SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_FIXUP_ACER_EAPD), |
2228 | SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_FIXUP_ACER_EAPD), | 2228 | SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_FIXUP_ACER_EAPD), |
2229 | SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_FIXUP_ACER_EAPD), | 2229 | SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_FIXUP_ACER_EAPD), |
2230 | SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_FIXUP_ACER_EAPD), | 2230 | SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_FIXUP_ACER_EAPD), |
2231 | SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_FIXUP_ACER_EAPD), | 2231 | SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_FIXUP_ACER_EAPD), |
2232 | SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_FIXUP_ACER_EAPD), | 2232 | SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_FIXUP_ACER_EAPD), |
2233 | SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G", | 2233 | SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G", |
2234 | ALC882_FIXUP_ACER_ASPIRE_4930G), | 2234 | ALC882_FIXUP_ACER_ASPIRE_4930G), |
2235 | SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G", | 2235 | SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G", |
2236 | ALC882_FIXUP_ACER_ASPIRE_4930G), | 2236 | ALC882_FIXUP_ACER_ASPIRE_4930G), |
2237 | SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G", | 2237 | SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G", |
2238 | ALC882_FIXUP_ACER_ASPIRE_8930G), | 2238 | ALC882_FIXUP_ACER_ASPIRE_8930G), |
2239 | SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G", | 2239 | SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G", |
2240 | ALC882_FIXUP_ACER_ASPIRE_8930G), | 2240 | ALC882_FIXUP_ACER_ASPIRE_8930G), |
2241 | SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G", | 2241 | SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G", |
2242 | ALC882_FIXUP_ACER_ASPIRE_4930G), | 2242 | ALC882_FIXUP_ACER_ASPIRE_4930G), |
2243 | SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G", | 2243 | SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G", |
2244 | ALC882_FIXUP_ACER_ASPIRE_4930G), | 2244 | ALC882_FIXUP_ACER_ASPIRE_4930G), |
2245 | SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G", | 2245 | SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G", |
2246 | ALC882_FIXUP_ACER_ASPIRE_4930G), | 2246 | ALC882_FIXUP_ACER_ASPIRE_4930G), |
2247 | SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", ALC882_FIXUP_PB_M5210), | 2247 | SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", ALC882_FIXUP_PB_M5210), |
2248 | SND_PCI_QUIRK(0x1025, 0x021e, "Acer Aspire 5739G", | 2248 | SND_PCI_QUIRK(0x1025, 0x021e, "Acer Aspire 5739G", |
2249 | ALC882_FIXUP_ACER_ASPIRE_4930G), | 2249 | ALC882_FIXUP_ACER_ASPIRE_4930G), |
2250 | SND_PCI_QUIRK(0x1025, 0x0259, "Acer Aspire 5935", ALC889_FIXUP_DAC_ROUTE), | 2250 | SND_PCI_QUIRK(0x1025, 0x0259, "Acer Aspire 5935", ALC889_FIXUP_DAC_ROUTE), |
2251 | SND_PCI_QUIRK(0x1025, 0x026b, "Acer Aspire 8940G", ALC882_FIXUP_ACER_ASPIRE_8930G), | 2251 | SND_PCI_QUIRK(0x1025, 0x026b, "Acer Aspire 8940G", ALC882_FIXUP_ACER_ASPIRE_8930G), |
2252 | SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", ALC882_FIXUP_ACER_ASPIRE_7736), | 2252 | SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", ALC882_FIXUP_ACER_ASPIRE_7736), |
2253 | SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_FIXUP_EAPD), | 2253 | SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_FIXUP_EAPD), |
2254 | SND_PCI_QUIRK(0x1043, 0x1873, "ASUS W90V", ALC882_FIXUP_ASUS_W90V), | 2254 | SND_PCI_QUIRK(0x1043, 0x1873, "ASUS W90V", ALC882_FIXUP_ASUS_W90V), |
2255 | SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_FIXUP_ASUS_W2JC), | 2255 | SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_FIXUP_ASUS_W2JC), |
2256 | SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_FIXUP_EEE1601), | 2256 | SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_FIXUP_EEE1601), |
2257 | SND_PCI_QUIRK(0x1043, 0x84bc, "ASUS ET2700", ALC887_FIXUP_ASUS_BASS), | 2257 | SND_PCI_QUIRK(0x1043, 0x84bc, "ASUS ET2700", ALC887_FIXUP_ASUS_BASS), |
2258 | SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT), | 2258 | SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT), |
2259 | SND_PCI_QUIRK(0x104d, 0x905a, "Sony Vaio Z", ALC882_FIXUP_NO_PRIMARY_HP), | 2259 | SND_PCI_QUIRK(0x104d, 0x905a, "Sony Vaio Z", ALC882_FIXUP_NO_PRIMARY_HP), |
2260 | SND_PCI_QUIRK(0x104d, 0x9043, "Sony Vaio VGC-LN51JGB", ALC882_FIXUP_NO_PRIMARY_HP), | 2260 | SND_PCI_QUIRK(0x104d, 0x9043, "Sony Vaio VGC-LN51JGB", ALC882_FIXUP_NO_PRIMARY_HP), |
2261 | 2261 | ||
2262 | /* All Apple entries are in codec SSIDs */ | 2262 | /* All Apple entries are in codec SSIDs */ |
2263 | SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC889_FIXUP_MBP_VREF), | 2263 | SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC889_FIXUP_MBP_VREF), |
2264 | SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC889_FIXUP_MBP_VREF), | 2264 | SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC889_FIXUP_MBP_VREF), |
2265 | SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF), | 2265 | SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF), |
2266 | SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC889_FIXUP_MP11_VREF), | 2266 | SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC889_FIXUP_MP11_VREF), |
2267 | SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_FIXUP_MACPRO_GPIO), | 2267 | SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_FIXUP_MACPRO_GPIO), |
2268 | SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_FIXUP_MACPRO_GPIO), | 2268 | SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_FIXUP_MACPRO_GPIO), |
2269 | SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC889_FIXUP_MBP_VREF), | 2269 | SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC889_FIXUP_MBP_VREF), |
2270 | SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889_FIXUP_MBP_VREF), | 2270 | SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889_FIXUP_MBP_VREF), |
2271 | SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_FIXUP_EAPD), | 2271 | SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_FIXUP_EAPD), |
2272 | SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC889_FIXUP_MBA11_VREF), | 2272 | SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC889_FIXUP_MBA11_VREF), |
2273 | SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC889_FIXUP_MBA21_VREF), | 2273 | SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC889_FIXUP_MBA21_VREF), |
2274 | SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889_FIXUP_MBP_VREF), | 2274 | SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889_FIXUP_MBP_VREF), |
2275 | SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF), | 2275 | SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF), |
2276 | SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_FIXUP_MACPRO_GPIO), | 2276 | SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_FIXUP_MACPRO_GPIO), |
2277 | SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC889_FIXUP_IMAC91_VREF), | 2277 | SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC889_FIXUP_IMAC91_VREF), |
2278 | SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC889_FIXUP_IMAC91_VREF), | 2278 | SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC889_FIXUP_IMAC91_VREF), |
2279 | SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC889_FIXUP_IMAC91_VREF), | 2279 | SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC889_FIXUP_IMAC91_VREF), |
2280 | SND_PCI_QUIRK(0x106b, 0x4200, "Mac Pro 5,1", ALC885_FIXUP_MACPRO_GPIO), | 2280 | SND_PCI_QUIRK(0x106b, 0x4200, "Mac Pro 5,1", ALC885_FIXUP_MACPRO_GPIO), |
2281 | SND_PCI_QUIRK(0x106b, 0x4300, "iMac 9,1", ALC889_FIXUP_IMAC91_VREF), | 2281 | SND_PCI_QUIRK(0x106b, 0x4300, "iMac 9,1", ALC889_FIXUP_IMAC91_VREF), |
2282 | SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC889_FIXUP_IMAC91_VREF), | 2282 | SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC889_FIXUP_IMAC91_VREF), |
2283 | SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC889_FIXUP_IMAC91_VREF), | 2283 | SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC889_FIXUP_IMAC91_VREF), |
2284 | SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC889_FIXUP_IMAC91_VREF), | 2284 | SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC889_FIXUP_IMAC91_VREF), |
2285 | 2285 | ||
2286 | SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC882_FIXUP_EAPD), | 2286 | SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC882_FIXUP_EAPD), |
2287 | SND_PCI_QUIRK(0x1462, 0x7350, "MSI-7350", ALC889_FIXUP_CD), | 2287 | SND_PCI_QUIRK(0x1462, 0x7350, "MSI-7350", ALC889_FIXUP_CD), |
2288 | SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3), | 2288 | SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3), |
2289 | SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3/Z87X-UD3H", ALC889_FIXUP_FRONT_HP_NO_PRESENCE), | 2289 | SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3/Z87X-UD3H", ALC889_FIXUP_FRONT_HP_NO_PRESENCE), |
2290 | SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX), | 2290 | SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX), |
2291 | SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD), | 2291 | SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD), |
2292 | SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD), | 2292 | SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD), |
2293 | SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", ALC882_FIXUP_LENOVO_Y530), | 2293 | SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", ALC882_FIXUP_LENOVO_Y530), |
2294 | SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_FIXUP_COEF), | 2294 | SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_FIXUP_COEF), |
2295 | {} | 2295 | {} |
2296 | }; | 2296 | }; |
2297 | 2297 | ||
2298 | static const struct hda_model_fixup alc882_fixup_models[] = { | 2298 | static const struct hda_model_fixup alc882_fixup_models[] = { |
2299 | {.id = ALC882_FIXUP_ACER_ASPIRE_4930G, .name = "acer-aspire-4930g"}, | 2299 | {.id = ALC882_FIXUP_ACER_ASPIRE_4930G, .name = "acer-aspire-4930g"}, |
2300 | {.id = ALC882_FIXUP_ACER_ASPIRE_8930G, .name = "acer-aspire-8930g"}, | 2300 | {.id = ALC882_FIXUP_ACER_ASPIRE_8930G, .name = "acer-aspire-8930g"}, |
2301 | {.id = ALC883_FIXUP_ACER_EAPD, .name = "acer-aspire"}, | 2301 | {.id = ALC883_FIXUP_ACER_EAPD, .name = "acer-aspire"}, |
2302 | {.id = ALC882_FIXUP_INV_DMIC, .name = "inv-dmic"}, | 2302 | {.id = ALC882_FIXUP_INV_DMIC, .name = "inv-dmic"}, |
2303 | {.id = ALC882_FIXUP_NO_PRIMARY_HP, .name = "no-primary-hp"}, | 2303 | {.id = ALC882_FIXUP_NO_PRIMARY_HP, .name = "no-primary-hp"}, |
2304 | {} | 2304 | {} |
2305 | }; | 2305 | }; |
2306 | 2306 | ||
2307 | /* | 2307 | /* |
2308 | * BIOS auto configuration | 2308 | * BIOS auto configuration |
2309 | */ | 2309 | */ |
2310 | /* almost identical with ALC880 parser... */ | 2310 | /* almost identical with ALC880 parser... */ |
2311 | static int alc882_parse_auto_config(struct hda_codec *codec) | 2311 | static int alc882_parse_auto_config(struct hda_codec *codec) |
2312 | { | 2312 | { |
2313 | static const hda_nid_t alc882_ignore[] = { 0x1d, 0 }; | 2313 | static const hda_nid_t alc882_ignore[] = { 0x1d, 0 }; |
2314 | static const hda_nid_t alc882_ssids[] = { 0x15, 0x1b, 0x14, 0 }; | 2314 | static const hda_nid_t alc882_ssids[] = { 0x15, 0x1b, 0x14, 0 }; |
2315 | return alc_parse_auto_config(codec, alc882_ignore, alc882_ssids); | 2315 | return alc_parse_auto_config(codec, alc882_ignore, alc882_ssids); |
2316 | } | 2316 | } |
2317 | 2317 | ||
2318 | /* | 2318 | /* |
2319 | */ | 2319 | */ |
2320 | static int patch_alc882(struct hda_codec *codec) | 2320 | static int patch_alc882(struct hda_codec *codec) |
2321 | { | 2321 | { |
2322 | struct alc_spec *spec; | 2322 | struct alc_spec *spec; |
2323 | int err; | 2323 | int err; |
2324 | 2324 | ||
2325 | err = alc_alloc_spec(codec, 0x0b); | 2325 | err = alc_alloc_spec(codec, 0x0b); |
2326 | if (err < 0) | 2326 | if (err < 0) |
2327 | return err; | 2327 | return err; |
2328 | 2328 | ||
2329 | spec = codec->spec; | 2329 | spec = codec->spec; |
2330 | 2330 | ||
2331 | switch (codec->vendor_id) { | 2331 | switch (codec->vendor_id) { |
2332 | case 0x10ec0882: | 2332 | case 0x10ec0882: |
2333 | case 0x10ec0885: | 2333 | case 0x10ec0885: |
2334 | break; | 2334 | break; |
2335 | default: | 2335 | default: |
2336 | /* ALC883 and variants */ | 2336 | /* ALC883 and variants */ |
2337 | alc_fix_pll_init(codec, 0x20, 0x0a, 10); | 2337 | alc_fix_pll_init(codec, 0x20, 0x0a, 10); |
2338 | break; | 2338 | break; |
2339 | } | 2339 | } |
2340 | 2340 | ||
2341 | snd_hda_pick_fixup(codec, alc882_fixup_models, alc882_fixup_tbl, | 2341 | snd_hda_pick_fixup(codec, alc882_fixup_models, alc882_fixup_tbl, |
2342 | alc882_fixups); | 2342 | alc882_fixups); |
2343 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); | 2343 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); |
2344 | 2344 | ||
2345 | alc_auto_parse_customize_define(codec); | 2345 | alc_auto_parse_customize_define(codec); |
2346 | 2346 | ||
2347 | if (has_cdefine_beep(codec)) | 2347 | if (has_cdefine_beep(codec)) |
2348 | spec->gen.beep_nid = 0x01; | 2348 | spec->gen.beep_nid = 0x01; |
2349 | 2349 | ||
2350 | /* automatic parse from the BIOS config */ | 2350 | /* automatic parse from the BIOS config */ |
2351 | err = alc882_parse_auto_config(codec); | 2351 | err = alc882_parse_auto_config(codec); |
2352 | if (err < 0) | 2352 | if (err < 0) |
2353 | goto error; | 2353 | goto error; |
2354 | 2354 | ||
2355 | if (!spec->gen.no_analog && spec->gen.beep_nid) | 2355 | if (!spec->gen.no_analog && spec->gen.beep_nid) |
2356 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); | 2356 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); |
2357 | 2357 | ||
2358 | codec->patch_ops = alc_patch_ops; | 2358 | codec->patch_ops = alc_patch_ops; |
2359 | 2359 | ||
2360 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); | 2360 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); |
2361 | 2361 | ||
2362 | return 0; | 2362 | return 0; |
2363 | 2363 | ||
2364 | error: | 2364 | error: |
2365 | alc_free(codec); | 2365 | alc_free(codec); |
2366 | return err; | 2366 | return err; |
2367 | } | 2367 | } |
2368 | 2368 | ||
2369 | 2369 | ||
2370 | /* | 2370 | /* |
2371 | * ALC262 support | 2371 | * ALC262 support |
2372 | */ | 2372 | */ |
2373 | static int alc262_parse_auto_config(struct hda_codec *codec) | 2373 | static int alc262_parse_auto_config(struct hda_codec *codec) |
2374 | { | 2374 | { |
2375 | static const hda_nid_t alc262_ignore[] = { 0x1d, 0 }; | 2375 | static const hda_nid_t alc262_ignore[] = { 0x1d, 0 }; |
2376 | static const hda_nid_t alc262_ssids[] = { 0x15, 0x1b, 0x14, 0 }; | 2376 | static const hda_nid_t alc262_ssids[] = { 0x15, 0x1b, 0x14, 0 }; |
2377 | return alc_parse_auto_config(codec, alc262_ignore, alc262_ssids); | 2377 | return alc_parse_auto_config(codec, alc262_ignore, alc262_ssids); |
2378 | } | 2378 | } |
2379 | 2379 | ||
2380 | /* | 2380 | /* |
2381 | * Pin config fixes | 2381 | * Pin config fixes |
2382 | */ | 2382 | */ |
2383 | enum { | 2383 | enum { |
2384 | ALC262_FIXUP_FSC_H270, | 2384 | ALC262_FIXUP_FSC_H270, |
2385 | ALC262_FIXUP_FSC_S7110, | 2385 | ALC262_FIXUP_FSC_S7110, |
2386 | ALC262_FIXUP_HP_Z200, | 2386 | ALC262_FIXUP_HP_Z200, |
2387 | ALC262_FIXUP_TYAN, | 2387 | ALC262_FIXUP_TYAN, |
2388 | ALC262_FIXUP_LENOVO_3000, | 2388 | ALC262_FIXUP_LENOVO_3000, |
2389 | ALC262_FIXUP_BENQ, | 2389 | ALC262_FIXUP_BENQ, |
2390 | ALC262_FIXUP_BENQ_T31, | 2390 | ALC262_FIXUP_BENQ_T31, |
2391 | ALC262_FIXUP_INV_DMIC, | 2391 | ALC262_FIXUP_INV_DMIC, |
2392 | ALC262_FIXUP_INTEL_BAYLEYBAY, | 2392 | ALC262_FIXUP_INTEL_BAYLEYBAY, |
2393 | }; | 2393 | }; |
2394 | 2394 | ||
2395 | static const struct hda_fixup alc262_fixups[] = { | 2395 | static const struct hda_fixup alc262_fixups[] = { |
2396 | [ALC262_FIXUP_FSC_H270] = { | 2396 | [ALC262_FIXUP_FSC_H270] = { |
2397 | .type = HDA_FIXUP_PINS, | 2397 | .type = HDA_FIXUP_PINS, |
2398 | .v.pins = (const struct hda_pintbl[]) { | 2398 | .v.pins = (const struct hda_pintbl[]) { |
2399 | { 0x14, 0x99130110 }, /* speaker */ | 2399 | { 0x14, 0x99130110 }, /* speaker */ |
2400 | { 0x15, 0x0221142f }, /* front HP */ | 2400 | { 0x15, 0x0221142f }, /* front HP */ |
2401 | { 0x1b, 0x0121141f }, /* rear HP */ | 2401 | { 0x1b, 0x0121141f }, /* rear HP */ |
2402 | { } | 2402 | { } |
2403 | } | 2403 | } |
2404 | }, | 2404 | }, |
2405 | [ALC262_FIXUP_FSC_S7110] = { | 2405 | [ALC262_FIXUP_FSC_S7110] = { |
2406 | .type = HDA_FIXUP_PINS, | 2406 | .type = HDA_FIXUP_PINS, |
2407 | .v.pins = (const struct hda_pintbl[]) { | 2407 | .v.pins = (const struct hda_pintbl[]) { |
2408 | { 0x15, 0x90170110 }, /* speaker */ | 2408 | { 0x15, 0x90170110 }, /* speaker */ |
2409 | { } | 2409 | { } |
2410 | }, | 2410 | }, |
2411 | .chained = true, | 2411 | .chained = true, |
2412 | .chain_id = ALC262_FIXUP_BENQ, | 2412 | .chain_id = ALC262_FIXUP_BENQ, |
2413 | }, | 2413 | }, |
2414 | [ALC262_FIXUP_HP_Z200] = { | 2414 | [ALC262_FIXUP_HP_Z200] = { |
2415 | .type = HDA_FIXUP_PINS, | 2415 | .type = HDA_FIXUP_PINS, |
2416 | .v.pins = (const struct hda_pintbl[]) { | 2416 | .v.pins = (const struct hda_pintbl[]) { |
2417 | { 0x16, 0x99130120 }, /* internal speaker */ | 2417 | { 0x16, 0x99130120 }, /* internal speaker */ |
2418 | { } | 2418 | { } |
2419 | } | 2419 | } |
2420 | }, | 2420 | }, |
2421 | [ALC262_FIXUP_TYAN] = { | 2421 | [ALC262_FIXUP_TYAN] = { |
2422 | .type = HDA_FIXUP_PINS, | 2422 | .type = HDA_FIXUP_PINS, |
2423 | .v.pins = (const struct hda_pintbl[]) { | 2423 | .v.pins = (const struct hda_pintbl[]) { |
2424 | { 0x14, 0x1993e1f0 }, /* int AUX */ | 2424 | { 0x14, 0x1993e1f0 }, /* int AUX */ |
2425 | { } | 2425 | { } |
2426 | } | 2426 | } |
2427 | }, | 2427 | }, |
2428 | [ALC262_FIXUP_LENOVO_3000] = { | 2428 | [ALC262_FIXUP_LENOVO_3000] = { |
2429 | .type = HDA_FIXUP_PINCTLS, | 2429 | .type = HDA_FIXUP_PINCTLS, |
2430 | .v.pins = (const struct hda_pintbl[]) { | 2430 | .v.pins = (const struct hda_pintbl[]) { |
2431 | { 0x19, PIN_VREF50 }, | 2431 | { 0x19, PIN_VREF50 }, |
2432 | {} | 2432 | {} |
2433 | }, | 2433 | }, |
2434 | .chained = true, | 2434 | .chained = true, |
2435 | .chain_id = ALC262_FIXUP_BENQ, | 2435 | .chain_id = ALC262_FIXUP_BENQ, |
2436 | }, | 2436 | }, |
2437 | [ALC262_FIXUP_BENQ] = { | 2437 | [ALC262_FIXUP_BENQ] = { |
2438 | .type = HDA_FIXUP_VERBS, | 2438 | .type = HDA_FIXUP_VERBS, |
2439 | .v.verbs = (const struct hda_verb[]) { | 2439 | .v.verbs = (const struct hda_verb[]) { |
2440 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, | 2440 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, |
2441 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 }, | 2441 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 }, |
2442 | {} | 2442 | {} |
2443 | } | 2443 | } |
2444 | }, | 2444 | }, |
2445 | [ALC262_FIXUP_BENQ_T31] = { | 2445 | [ALC262_FIXUP_BENQ_T31] = { |
2446 | .type = HDA_FIXUP_VERBS, | 2446 | .type = HDA_FIXUP_VERBS, |
2447 | .v.verbs = (const struct hda_verb[]) { | 2447 | .v.verbs = (const struct hda_verb[]) { |
2448 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, | 2448 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, |
2449 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 }, | 2449 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 }, |
2450 | {} | 2450 | {} |
2451 | } | 2451 | } |
2452 | }, | 2452 | }, |
2453 | [ALC262_FIXUP_INV_DMIC] = { | 2453 | [ALC262_FIXUP_INV_DMIC] = { |
2454 | .type = HDA_FIXUP_FUNC, | 2454 | .type = HDA_FIXUP_FUNC, |
2455 | .v.func = alc_fixup_inv_dmic_0x12, | 2455 | .v.func = alc_fixup_inv_dmic_0x12, |
2456 | }, | 2456 | }, |
2457 | [ALC262_FIXUP_INTEL_BAYLEYBAY] = { | 2457 | [ALC262_FIXUP_INTEL_BAYLEYBAY] = { |
2458 | .type = HDA_FIXUP_FUNC, | 2458 | .type = HDA_FIXUP_FUNC, |
2459 | .v.func = alc_fixup_no_depop_delay, | 2459 | .v.func = alc_fixup_no_depop_delay, |
2460 | }, | 2460 | }, |
2461 | }; | 2461 | }; |
2462 | 2462 | ||
2463 | static const struct snd_pci_quirk alc262_fixup_tbl[] = { | 2463 | static const struct snd_pci_quirk alc262_fixup_tbl[] = { |
2464 | SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", ALC262_FIXUP_HP_Z200), | 2464 | SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", ALC262_FIXUP_HP_Z200), |
2465 | SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu Lifebook S7110", ALC262_FIXUP_FSC_S7110), | 2465 | SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu Lifebook S7110", ALC262_FIXUP_FSC_S7110), |
2466 | SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FIXUP_BENQ), | 2466 | SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FIXUP_BENQ), |
2467 | SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_FIXUP_TYAN), | 2467 | SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_FIXUP_TYAN), |
2468 | SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", ALC262_FIXUP_FSC_H270), | 2468 | SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", ALC262_FIXUP_FSC_H270), |
2469 | SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000", ALC262_FIXUP_LENOVO_3000), | 2469 | SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000", ALC262_FIXUP_LENOVO_3000), |
2470 | SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_FIXUP_BENQ), | 2470 | SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_FIXUP_BENQ), |
2471 | SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_FIXUP_BENQ_T31), | 2471 | SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_FIXUP_BENQ_T31), |
2472 | SND_PCI_QUIRK(0x8086, 0x7270, "BayleyBay", ALC262_FIXUP_INTEL_BAYLEYBAY), | 2472 | SND_PCI_QUIRK(0x8086, 0x7270, "BayleyBay", ALC262_FIXUP_INTEL_BAYLEYBAY), |
2473 | {} | 2473 | {} |
2474 | }; | 2474 | }; |
2475 | 2475 | ||
2476 | static const struct hda_model_fixup alc262_fixup_models[] = { | 2476 | static const struct hda_model_fixup alc262_fixup_models[] = { |
2477 | {.id = ALC262_FIXUP_INV_DMIC, .name = "inv-dmic"}, | 2477 | {.id = ALC262_FIXUP_INV_DMIC, .name = "inv-dmic"}, |
2478 | {} | 2478 | {} |
2479 | }; | 2479 | }; |
2480 | 2480 | ||
2481 | /* | 2481 | /* |
2482 | */ | 2482 | */ |
2483 | static int patch_alc262(struct hda_codec *codec) | 2483 | static int patch_alc262(struct hda_codec *codec) |
2484 | { | 2484 | { |
2485 | struct alc_spec *spec; | 2485 | struct alc_spec *spec; |
2486 | int err; | 2486 | int err; |
2487 | 2487 | ||
2488 | err = alc_alloc_spec(codec, 0x0b); | 2488 | err = alc_alloc_spec(codec, 0x0b); |
2489 | if (err < 0) | 2489 | if (err < 0) |
2490 | return err; | 2490 | return err; |
2491 | 2491 | ||
2492 | spec = codec->spec; | 2492 | spec = codec->spec; |
2493 | spec->gen.shared_mic_vref_pin = 0x18; | 2493 | spec->gen.shared_mic_vref_pin = 0x18; |
2494 | 2494 | ||
2495 | #if 0 | 2495 | #if 0 |
2496 | /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is | 2496 | /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is |
2497 | * under-run | 2497 | * under-run |
2498 | */ | 2498 | */ |
2499 | { | 2499 | { |
2500 | int tmp; | 2500 | int tmp; |
2501 | snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7); | 2501 | snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7); |
2502 | tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); | 2502 | tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); |
2503 | snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7); | 2503 | snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7); |
2504 | snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80); | 2504 | snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80); |
2505 | } | 2505 | } |
2506 | #endif | 2506 | #endif |
2507 | alc_fix_pll_init(codec, 0x20, 0x0a, 10); | 2507 | alc_fix_pll_init(codec, 0x20, 0x0a, 10); |
2508 | 2508 | ||
2509 | snd_hda_pick_fixup(codec, alc262_fixup_models, alc262_fixup_tbl, | 2509 | snd_hda_pick_fixup(codec, alc262_fixup_models, alc262_fixup_tbl, |
2510 | alc262_fixups); | 2510 | alc262_fixups); |
2511 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); | 2511 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); |
2512 | 2512 | ||
2513 | alc_auto_parse_customize_define(codec); | 2513 | alc_auto_parse_customize_define(codec); |
2514 | 2514 | ||
2515 | if (has_cdefine_beep(codec)) | 2515 | if (has_cdefine_beep(codec)) |
2516 | spec->gen.beep_nid = 0x01; | 2516 | spec->gen.beep_nid = 0x01; |
2517 | 2517 | ||
2518 | /* automatic parse from the BIOS config */ | 2518 | /* automatic parse from the BIOS config */ |
2519 | err = alc262_parse_auto_config(codec); | 2519 | err = alc262_parse_auto_config(codec); |
2520 | if (err < 0) | 2520 | if (err < 0) |
2521 | goto error; | 2521 | goto error; |
2522 | 2522 | ||
2523 | if (!spec->gen.no_analog && spec->gen.beep_nid) | 2523 | if (!spec->gen.no_analog && spec->gen.beep_nid) |
2524 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); | 2524 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); |
2525 | 2525 | ||
2526 | codec->patch_ops = alc_patch_ops; | 2526 | codec->patch_ops = alc_patch_ops; |
2527 | spec->shutup = alc_eapd_shutup; | 2527 | spec->shutup = alc_eapd_shutup; |
2528 | 2528 | ||
2529 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); | 2529 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); |
2530 | 2530 | ||
2531 | return 0; | 2531 | return 0; |
2532 | 2532 | ||
2533 | error: | 2533 | error: |
2534 | alc_free(codec); | 2534 | alc_free(codec); |
2535 | return err; | 2535 | return err; |
2536 | } | 2536 | } |
2537 | 2537 | ||
2538 | /* | 2538 | /* |
2539 | * ALC268 | 2539 | * ALC268 |
2540 | */ | 2540 | */ |
2541 | /* bind Beep switches of both NID 0x0f and 0x10 */ | 2541 | /* bind Beep switches of both NID 0x0f and 0x10 */ |
2542 | static const struct hda_bind_ctls alc268_bind_beep_sw = { | 2542 | static const struct hda_bind_ctls alc268_bind_beep_sw = { |
2543 | .ops = &snd_hda_bind_sw, | 2543 | .ops = &snd_hda_bind_sw, |
2544 | .values = { | 2544 | .values = { |
2545 | HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT), | 2545 | HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT), |
2546 | HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT), | 2546 | HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT), |
2547 | 0 | 2547 | 0 |
2548 | }, | 2548 | }, |
2549 | }; | 2549 | }; |
2550 | 2550 | ||
2551 | static const struct snd_kcontrol_new alc268_beep_mixer[] = { | 2551 | static const struct snd_kcontrol_new alc268_beep_mixer[] = { |
2552 | HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT), | 2552 | HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT), |
2553 | HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw), | 2553 | HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw), |
2554 | { } | 2554 | { } |
2555 | }; | 2555 | }; |
2556 | 2556 | ||
2557 | /* set PCBEEP vol = 0, mute connections */ | 2557 | /* set PCBEEP vol = 0, mute connections */ |
2558 | static const struct hda_verb alc268_beep_init_verbs[] = { | 2558 | static const struct hda_verb alc268_beep_init_verbs[] = { |
2559 | {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 2559 | {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
2560 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | 2560 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, |
2561 | {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | 2561 | {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, |
2562 | { } | 2562 | { } |
2563 | }; | 2563 | }; |
2564 | 2564 | ||
2565 | enum { | 2565 | enum { |
2566 | ALC268_FIXUP_INV_DMIC, | 2566 | ALC268_FIXUP_INV_DMIC, |
2567 | ALC268_FIXUP_HP_EAPD, | 2567 | ALC268_FIXUP_HP_EAPD, |
2568 | ALC268_FIXUP_SPDIF, | 2568 | ALC268_FIXUP_SPDIF, |
2569 | }; | 2569 | }; |
2570 | 2570 | ||
2571 | static const struct hda_fixup alc268_fixups[] = { | 2571 | static const struct hda_fixup alc268_fixups[] = { |
2572 | [ALC268_FIXUP_INV_DMIC] = { | 2572 | [ALC268_FIXUP_INV_DMIC] = { |
2573 | .type = HDA_FIXUP_FUNC, | 2573 | .type = HDA_FIXUP_FUNC, |
2574 | .v.func = alc_fixup_inv_dmic_0x12, | 2574 | .v.func = alc_fixup_inv_dmic_0x12, |
2575 | }, | 2575 | }, |
2576 | [ALC268_FIXUP_HP_EAPD] = { | 2576 | [ALC268_FIXUP_HP_EAPD] = { |
2577 | .type = HDA_FIXUP_VERBS, | 2577 | .type = HDA_FIXUP_VERBS, |
2578 | .v.verbs = (const struct hda_verb[]) { | 2578 | .v.verbs = (const struct hda_verb[]) { |
2579 | {0x15, AC_VERB_SET_EAPD_BTLENABLE, 0}, | 2579 | {0x15, AC_VERB_SET_EAPD_BTLENABLE, 0}, |
2580 | {} | 2580 | {} |
2581 | } | 2581 | } |
2582 | }, | 2582 | }, |
2583 | [ALC268_FIXUP_SPDIF] = { | 2583 | [ALC268_FIXUP_SPDIF] = { |
2584 | .type = HDA_FIXUP_PINS, | 2584 | .type = HDA_FIXUP_PINS, |
2585 | .v.pins = (const struct hda_pintbl[]) { | 2585 | .v.pins = (const struct hda_pintbl[]) { |
2586 | { 0x1e, 0x014b1180 }, /* enable SPDIF out */ | 2586 | { 0x1e, 0x014b1180 }, /* enable SPDIF out */ |
2587 | {} | 2587 | {} |
2588 | } | 2588 | } |
2589 | }, | 2589 | }, |
2590 | }; | 2590 | }; |
2591 | 2591 | ||
2592 | static const struct hda_model_fixup alc268_fixup_models[] = { | 2592 | static const struct hda_model_fixup alc268_fixup_models[] = { |
2593 | {.id = ALC268_FIXUP_INV_DMIC, .name = "inv-dmic"}, | 2593 | {.id = ALC268_FIXUP_INV_DMIC, .name = "inv-dmic"}, |
2594 | {.id = ALC268_FIXUP_HP_EAPD, .name = "hp-eapd"}, | 2594 | {.id = ALC268_FIXUP_HP_EAPD, .name = "hp-eapd"}, |
2595 | {} | 2595 | {} |
2596 | }; | 2596 | }; |
2597 | 2597 | ||
2598 | static const struct snd_pci_quirk alc268_fixup_tbl[] = { | 2598 | static const struct snd_pci_quirk alc268_fixup_tbl[] = { |
2599 | SND_PCI_QUIRK(0x1025, 0x0139, "Acer TravelMate 6293", ALC268_FIXUP_SPDIF), | 2599 | SND_PCI_QUIRK(0x1025, 0x0139, "Acer TravelMate 6293", ALC268_FIXUP_SPDIF), |
2600 | SND_PCI_QUIRK(0x1025, 0x015b, "Acer AOA 150 (ZG5)", ALC268_FIXUP_INV_DMIC), | 2600 | SND_PCI_QUIRK(0x1025, 0x015b, "Acer AOA 150 (ZG5)", ALC268_FIXUP_INV_DMIC), |
2601 | /* below is codec SSID since multiple Toshiba laptops have the | 2601 | /* below is codec SSID since multiple Toshiba laptops have the |
2602 | * same PCI SSID 1179:ff00 | 2602 | * same PCI SSID 1179:ff00 |
2603 | */ | 2603 | */ |
2604 | SND_PCI_QUIRK(0x1179, 0xff06, "Toshiba P200", ALC268_FIXUP_HP_EAPD), | 2604 | SND_PCI_QUIRK(0x1179, 0xff06, "Toshiba P200", ALC268_FIXUP_HP_EAPD), |
2605 | {} | 2605 | {} |
2606 | }; | 2606 | }; |
2607 | 2607 | ||
2608 | /* | 2608 | /* |
2609 | * BIOS auto configuration | 2609 | * BIOS auto configuration |
2610 | */ | 2610 | */ |
2611 | static int alc268_parse_auto_config(struct hda_codec *codec) | 2611 | static int alc268_parse_auto_config(struct hda_codec *codec) |
2612 | { | 2612 | { |
2613 | static const hda_nid_t alc268_ssids[] = { 0x15, 0x1b, 0x14, 0 }; | 2613 | static const hda_nid_t alc268_ssids[] = { 0x15, 0x1b, 0x14, 0 }; |
2614 | return alc_parse_auto_config(codec, NULL, alc268_ssids); | 2614 | return alc_parse_auto_config(codec, NULL, alc268_ssids); |
2615 | } | 2615 | } |
2616 | 2616 | ||
2617 | /* | 2617 | /* |
2618 | */ | 2618 | */ |
2619 | static int patch_alc268(struct hda_codec *codec) | 2619 | static int patch_alc268(struct hda_codec *codec) |
2620 | { | 2620 | { |
2621 | struct alc_spec *spec; | 2621 | struct alc_spec *spec; |
2622 | int err; | 2622 | int err; |
2623 | 2623 | ||
2624 | /* ALC268 has no aa-loopback mixer */ | 2624 | /* ALC268 has no aa-loopback mixer */ |
2625 | err = alc_alloc_spec(codec, 0); | 2625 | err = alc_alloc_spec(codec, 0); |
2626 | if (err < 0) | 2626 | if (err < 0) |
2627 | return err; | 2627 | return err; |
2628 | 2628 | ||
2629 | spec = codec->spec; | 2629 | spec = codec->spec; |
2630 | spec->gen.beep_nid = 0x01; | 2630 | spec->gen.beep_nid = 0x01; |
2631 | 2631 | ||
2632 | snd_hda_pick_fixup(codec, alc268_fixup_models, alc268_fixup_tbl, alc268_fixups); | 2632 | snd_hda_pick_fixup(codec, alc268_fixup_models, alc268_fixup_tbl, alc268_fixups); |
2633 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); | 2633 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); |
2634 | 2634 | ||
2635 | /* automatic parse from the BIOS config */ | 2635 | /* automatic parse from the BIOS config */ |
2636 | err = alc268_parse_auto_config(codec); | 2636 | err = alc268_parse_auto_config(codec); |
2637 | if (err < 0) | 2637 | if (err < 0) |
2638 | goto error; | 2638 | goto error; |
2639 | 2639 | ||
2640 | if (err > 0 && !spec->gen.no_analog && | 2640 | if (err > 0 && !spec->gen.no_analog && |
2641 | spec->gen.autocfg.speaker_pins[0] != 0x1d) { | 2641 | spec->gen.autocfg.speaker_pins[0] != 0x1d) { |
2642 | add_mixer(spec, alc268_beep_mixer); | 2642 | add_mixer(spec, alc268_beep_mixer); |
2643 | snd_hda_add_verbs(codec, alc268_beep_init_verbs); | 2643 | snd_hda_add_verbs(codec, alc268_beep_init_verbs); |
2644 | if (!query_amp_caps(codec, 0x1d, HDA_INPUT)) | 2644 | if (!query_amp_caps(codec, 0x1d, HDA_INPUT)) |
2645 | /* override the amp caps for beep generator */ | 2645 | /* override the amp caps for beep generator */ |
2646 | snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT, | 2646 | snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT, |
2647 | (0x0c << AC_AMPCAP_OFFSET_SHIFT) | | 2647 | (0x0c << AC_AMPCAP_OFFSET_SHIFT) | |
2648 | (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) | | 2648 | (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) | |
2649 | (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) | | 2649 | (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) | |
2650 | (0 << AC_AMPCAP_MUTE_SHIFT)); | 2650 | (0 << AC_AMPCAP_MUTE_SHIFT)); |
2651 | } | 2651 | } |
2652 | 2652 | ||
2653 | codec->patch_ops = alc_patch_ops; | 2653 | codec->patch_ops = alc_patch_ops; |
2654 | spec->shutup = alc_eapd_shutup; | 2654 | spec->shutup = alc_eapd_shutup; |
2655 | 2655 | ||
2656 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); | 2656 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); |
2657 | 2657 | ||
2658 | return 0; | 2658 | return 0; |
2659 | 2659 | ||
2660 | error: | 2660 | error: |
2661 | alc_free(codec); | 2661 | alc_free(codec); |
2662 | return err; | 2662 | return err; |
2663 | } | 2663 | } |
2664 | 2664 | ||
2665 | /* | 2665 | /* |
2666 | * ALC269 | 2666 | * ALC269 |
2667 | */ | 2667 | */ |
2668 | 2668 | ||
2669 | static int playback_pcm_open(struct hda_pcm_stream *hinfo, | 2669 | static int playback_pcm_open(struct hda_pcm_stream *hinfo, |
2670 | struct hda_codec *codec, | 2670 | struct hda_codec *codec, |
2671 | struct snd_pcm_substream *substream) | 2671 | struct snd_pcm_substream *substream) |
2672 | { | 2672 | { |
2673 | struct hda_gen_spec *spec = codec->spec; | 2673 | struct hda_gen_spec *spec = codec->spec; |
2674 | return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream, | 2674 | return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream, |
2675 | hinfo); | 2675 | hinfo); |
2676 | } | 2676 | } |
2677 | 2677 | ||
2678 | static int playback_pcm_prepare(struct hda_pcm_stream *hinfo, | 2678 | static int playback_pcm_prepare(struct hda_pcm_stream *hinfo, |
2679 | struct hda_codec *codec, | 2679 | struct hda_codec *codec, |
2680 | unsigned int stream_tag, | 2680 | unsigned int stream_tag, |
2681 | unsigned int format, | 2681 | unsigned int format, |
2682 | struct snd_pcm_substream *substream) | 2682 | struct snd_pcm_substream *substream) |
2683 | { | 2683 | { |
2684 | struct hda_gen_spec *spec = codec->spec; | 2684 | struct hda_gen_spec *spec = codec->spec; |
2685 | return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, | 2685 | return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, |
2686 | stream_tag, format, substream); | 2686 | stream_tag, format, substream); |
2687 | } | 2687 | } |
2688 | 2688 | ||
2689 | static int playback_pcm_cleanup(struct hda_pcm_stream *hinfo, | 2689 | static int playback_pcm_cleanup(struct hda_pcm_stream *hinfo, |
2690 | struct hda_codec *codec, | 2690 | struct hda_codec *codec, |
2691 | struct snd_pcm_substream *substream) | 2691 | struct snd_pcm_substream *substream) |
2692 | { | 2692 | { |
2693 | struct hda_gen_spec *spec = codec->spec; | 2693 | struct hda_gen_spec *spec = codec->spec; |
2694 | return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); | 2694 | return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); |
2695 | } | 2695 | } |
2696 | 2696 | ||
2697 | static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = { | 2697 | static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = { |
2698 | .substreams = 1, | 2698 | .substreams = 1, |
2699 | .channels_min = 2, | 2699 | .channels_min = 2, |
2700 | .channels_max = 8, | 2700 | .channels_max = 8, |
2701 | .rates = SNDRV_PCM_RATE_44100, /* fixed rate */ | 2701 | .rates = SNDRV_PCM_RATE_44100, /* fixed rate */ |
2702 | /* NID is set in alc_build_pcms */ | 2702 | /* NID is set in alc_build_pcms */ |
2703 | .ops = { | 2703 | .ops = { |
2704 | .open = playback_pcm_open, | 2704 | .open = playback_pcm_open, |
2705 | .prepare = playback_pcm_prepare, | 2705 | .prepare = playback_pcm_prepare, |
2706 | .cleanup = playback_pcm_cleanup | 2706 | .cleanup = playback_pcm_cleanup |
2707 | }, | 2707 | }, |
2708 | }; | 2708 | }; |
2709 | 2709 | ||
2710 | static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = { | 2710 | static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = { |
2711 | .substreams = 1, | 2711 | .substreams = 1, |
2712 | .channels_min = 2, | 2712 | .channels_min = 2, |
2713 | .channels_max = 2, | 2713 | .channels_max = 2, |
2714 | .rates = SNDRV_PCM_RATE_44100, /* fixed rate */ | 2714 | .rates = SNDRV_PCM_RATE_44100, /* fixed rate */ |
2715 | /* NID is set in alc_build_pcms */ | 2715 | /* NID is set in alc_build_pcms */ |
2716 | }; | 2716 | }; |
2717 | 2717 | ||
2718 | /* different alc269-variants */ | 2718 | /* different alc269-variants */ |
2719 | enum { | 2719 | enum { |
2720 | ALC269_TYPE_ALC269VA, | 2720 | ALC269_TYPE_ALC269VA, |
2721 | ALC269_TYPE_ALC269VB, | 2721 | ALC269_TYPE_ALC269VB, |
2722 | ALC269_TYPE_ALC269VC, | 2722 | ALC269_TYPE_ALC269VC, |
2723 | ALC269_TYPE_ALC269VD, | 2723 | ALC269_TYPE_ALC269VD, |
2724 | ALC269_TYPE_ALC280, | 2724 | ALC269_TYPE_ALC280, |
2725 | ALC269_TYPE_ALC282, | 2725 | ALC269_TYPE_ALC282, |
2726 | ALC269_TYPE_ALC283, | 2726 | ALC269_TYPE_ALC283, |
2727 | ALC269_TYPE_ALC284, | 2727 | ALC269_TYPE_ALC284, |
2728 | ALC269_TYPE_ALC285, | 2728 | ALC269_TYPE_ALC285, |
2729 | ALC269_TYPE_ALC286, | 2729 | ALC269_TYPE_ALC286, |
2730 | ALC269_TYPE_ALC255, | 2730 | ALC269_TYPE_ALC255, |
2731 | }; | 2731 | }; |
2732 | 2732 | ||
2733 | /* | 2733 | /* |
2734 | * BIOS auto configuration | 2734 | * BIOS auto configuration |
2735 | */ | 2735 | */ |
2736 | static int alc269_parse_auto_config(struct hda_codec *codec) | 2736 | static int alc269_parse_auto_config(struct hda_codec *codec) |
2737 | { | 2737 | { |
2738 | static const hda_nid_t alc269_ignore[] = { 0x1d, 0 }; | 2738 | static const hda_nid_t alc269_ignore[] = { 0x1d, 0 }; |
2739 | static const hda_nid_t alc269_ssids[] = { 0, 0x1b, 0x14, 0x21 }; | 2739 | static const hda_nid_t alc269_ssids[] = { 0, 0x1b, 0x14, 0x21 }; |
2740 | static const hda_nid_t alc269va_ssids[] = { 0x15, 0x1b, 0x14, 0 }; | 2740 | static const hda_nid_t alc269va_ssids[] = { 0x15, 0x1b, 0x14, 0 }; |
2741 | struct alc_spec *spec = codec->spec; | 2741 | struct alc_spec *spec = codec->spec; |
2742 | const hda_nid_t *ssids; | 2742 | const hda_nid_t *ssids; |
2743 | 2743 | ||
2744 | switch (spec->codec_variant) { | 2744 | switch (spec->codec_variant) { |
2745 | case ALC269_TYPE_ALC269VA: | 2745 | case ALC269_TYPE_ALC269VA: |
2746 | case ALC269_TYPE_ALC269VC: | 2746 | case ALC269_TYPE_ALC269VC: |
2747 | case ALC269_TYPE_ALC280: | 2747 | case ALC269_TYPE_ALC280: |
2748 | case ALC269_TYPE_ALC284: | 2748 | case ALC269_TYPE_ALC284: |
2749 | case ALC269_TYPE_ALC285: | 2749 | case ALC269_TYPE_ALC285: |
2750 | ssids = alc269va_ssids; | 2750 | ssids = alc269va_ssids; |
2751 | break; | 2751 | break; |
2752 | case ALC269_TYPE_ALC269VB: | 2752 | case ALC269_TYPE_ALC269VB: |
2753 | case ALC269_TYPE_ALC269VD: | 2753 | case ALC269_TYPE_ALC269VD: |
2754 | case ALC269_TYPE_ALC282: | 2754 | case ALC269_TYPE_ALC282: |
2755 | case ALC269_TYPE_ALC283: | 2755 | case ALC269_TYPE_ALC283: |
2756 | case ALC269_TYPE_ALC286: | 2756 | case ALC269_TYPE_ALC286: |
2757 | case ALC269_TYPE_ALC255: | 2757 | case ALC269_TYPE_ALC255: |
2758 | ssids = alc269_ssids; | 2758 | ssids = alc269_ssids; |
2759 | break; | 2759 | break; |
2760 | default: | 2760 | default: |
2761 | ssids = alc269_ssids; | 2761 | ssids = alc269_ssids; |
2762 | break; | 2762 | break; |
2763 | } | 2763 | } |
2764 | 2764 | ||
2765 | return alc_parse_auto_config(codec, alc269_ignore, ssids); | 2765 | return alc_parse_auto_config(codec, alc269_ignore, ssids); |
2766 | } | 2766 | } |
2767 | 2767 | ||
2768 | static void alc269vb_toggle_power_output(struct hda_codec *codec, int power_up) | 2768 | static void alc269vb_toggle_power_output(struct hda_codec *codec, int power_up) |
2769 | { | 2769 | { |
2770 | int val = alc_read_coef_idx(codec, 0x04); | 2770 | int val = alc_read_coef_idx(codec, 0x04); |
2771 | if (power_up) | 2771 | if (power_up) |
2772 | val |= 1 << 11; | 2772 | val |= 1 << 11; |
2773 | else | 2773 | else |
2774 | val &= ~(1 << 11); | 2774 | val &= ~(1 << 11); |
2775 | alc_write_coef_idx(codec, 0x04, val); | 2775 | alc_write_coef_idx(codec, 0x04, val); |
2776 | } | 2776 | } |
2777 | 2777 | ||
2778 | static void alc269_shutup(struct hda_codec *codec) | 2778 | static void alc269_shutup(struct hda_codec *codec) |
2779 | { | 2779 | { |
2780 | struct alc_spec *spec = codec->spec; | 2780 | struct alc_spec *spec = codec->spec; |
2781 | 2781 | ||
2782 | if (spec->codec_variant == ALC269_TYPE_ALC269VB) | 2782 | if (spec->codec_variant == ALC269_TYPE_ALC269VB) |
2783 | alc269vb_toggle_power_output(codec, 0); | 2783 | alc269vb_toggle_power_output(codec, 0); |
2784 | if (spec->codec_variant == ALC269_TYPE_ALC269VB && | 2784 | if (spec->codec_variant == ALC269_TYPE_ALC269VB && |
2785 | (alc_get_coef0(codec) & 0x00ff) == 0x018) { | 2785 | (alc_get_coef0(codec) & 0x00ff) == 0x018) { |
2786 | msleep(150); | 2786 | msleep(150); |
2787 | } | 2787 | } |
2788 | snd_hda_shutup_pins(codec); | 2788 | snd_hda_shutup_pins(codec); |
2789 | } | 2789 | } |
2790 | 2790 | ||
2791 | static void alc282_restore_default_value(struct hda_codec *codec) | 2791 | static void alc282_restore_default_value(struct hda_codec *codec) |
2792 | { | 2792 | { |
2793 | int val; | 2793 | int val; |
2794 | 2794 | ||
2795 | /* Power Down Control */ | 2795 | /* Power Down Control */ |
2796 | alc_write_coef_idx(codec, 0x03, 0x0002); | 2796 | alc_write_coef_idx(codec, 0x03, 0x0002); |
2797 | /* FIFO and filter clock */ | 2797 | /* FIFO and filter clock */ |
2798 | alc_write_coef_idx(codec, 0x05, 0x0700); | 2798 | alc_write_coef_idx(codec, 0x05, 0x0700); |
2799 | /* DMIC control */ | 2799 | /* DMIC control */ |
2800 | alc_write_coef_idx(codec, 0x07, 0x0200); | 2800 | alc_write_coef_idx(codec, 0x07, 0x0200); |
2801 | /* Analog clock */ | 2801 | /* Analog clock */ |
2802 | val = alc_read_coef_idx(codec, 0x06); | 2802 | val = alc_read_coef_idx(codec, 0x06); |
2803 | alc_write_coef_idx(codec, 0x06, (val & ~0x00f0) | 0x0); | 2803 | alc_write_coef_idx(codec, 0x06, (val & ~0x00f0) | 0x0); |
2804 | /* JD */ | 2804 | /* JD */ |
2805 | val = alc_read_coef_idx(codec, 0x08); | 2805 | val = alc_read_coef_idx(codec, 0x08); |
2806 | alc_write_coef_idx(codec, 0x08, (val & ~0xfffc) | 0x0c2c); | 2806 | alc_write_coef_idx(codec, 0x08, (val & ~0xfffc) | 0x0c2c); |
2807 | /* JD offset1 */ | 2807 | /* JD offset1 */ |
2808 | alc_write_coef_idx(codec, 0x0a, 0xcccc); | 2808 | alc_write_coef_idx(codec, 0x0a, 0xcccc); |
2809 | /* JD offset2 */ | 2809 | /* JD offset2 */ |
2810 | alc_write_coef_idx(codec, 0x0b, 0xcccc); | 2810 | alc_write_coef_idx(codec, 0x0b, 0xcccc); |
2811 | /* LDO1/2/3, DAC/ADC */ | 2811 | /* LDO1/2/3, DAC/ADC */ |
2812 | alc_write_coef_idx(codec, 0x0e, 0x6e00); | 2812 | alc_write_coef_idx(codec, 0x0e, 0x6e00); |
2813 | /* JD */ | 2813 | /* JD */ |
2814 | val = alc_read_coef_idx(codec, 0x0f); | 2814 | val = alc_read_coef_idx(codec, 0x0f); |
2815 | alc_write_coef_idx(codec, 0x0f, (val & ~0xf800) | 0x1000); | 2815 | alc_write_coef_idx(codec, 0x0f, (val & ~0xf800) | 0x1000); |
2816 | /* Capless */ | 2816 | /* Capless */ |
2817 | val = alc_read_coef_idx(codec, 0x10); | 2817 | val = alc_read_coef_idx(codec, 0x10); |
2818 | alc_write_coef_idx(codec, 0x10, (val & ~0xfc00) | 0x0c00); | 2818 | alc_write_coef_idx(codec, 0x10, (val & ~0xfc00) | 0x0c00); |
2819 | /* Class D test 4 */ | 2819 | /* Class D test 4 */ |
2820 | alc_write_coef_idx(codec, 0x6f, 0x0); | 2820 | alc_write_coef_idx(codec, 0x6f, 0x0); |
2821 | /* IO power down directly */ | 2821 | /* IO power down directly */ |
2822 | val = alc_read_coef_idx(codec, 0x0c); | 2822 | val = alc_read_coef_idx(codec, 0x0c); |
2823 | alc_write_coef_idx(codec, 0x0c, (val & ~0xfe00) | 0x0); | 2823 | alc_write_coef_idx(codec, 0x0c, (val & ~0xfe00) | 0x0); |
2824 | /* ANC */ | 2824 | /* ANC */ |
2825 | alc_write_coef_idx(codec, 0x34, 0xa0c0); | 2825 | alc_write_coef_idx(codec, 0x34, 0xa0c0); |
2826 | /* AGC MUX */ | 2826 | /* AGC MUX */ |
2827 | val = alc_read_coef_idx(codec, 0x16); | 2827 | val = alc_read_coef_idx(codec, 0x16); |
2828 | alc_write_coef_idx(codec, 0x16, (val & ~0x0008) | 0x0); | 2828 | alc_write_coef_idx(codec, 0x16, (val & ~0x0008) | 0x0); |
2829 | /* DAC simple content protection */ | 2829 | /* DAC simple content protection */ |
2830 | val = alc_read_coef_idx(codec, 0x1d); | 2830 | val = alc_read_coef_idx(codec, 0x1d); |
2831 | alc_write_coef_idx(codec, 0x1d, (val & ~0x00e0) | 0x0); | 2831 | alc_write_coef_idx(codec, 0x1d, (val & ~0x00e0) | 0x0); |
2832 | /* ADC simple content protection */ | 2832 | /* ADC simple content protection */ |
2833 | val = alc_read_coef_idx(codec, 0x1f); | 2833 | val = alc_read_coef_idx(codec, 0x1f); |
2834 | alc_write_coef_idx(codec, 0x1f, (val & ~0x00e0) | 0x0); | 2834 | alc_write_coef_idx(codec, 0x1f, (val & ~0x00e0) | 0x0); |
2835 | /* DAC ADC Zero Detection */ | 2835 | /* DAC ADC Zero Detection */ |
2836 | alc_write_coef_idx(codec, 0x21, 0x8804); | 2836 | alc_write_coef_idx(codec, 0x21, 0x8804); |
2837 | /* PLL */ | 2837 | /* PLL */ |
2838 | alc_write_coef_idx(codec, 0x63, 0x2902); | 2838 | alc_write_coef_idx(codec, 0x63, 0x2902); |
2839 | /* capless control 2 */ | 2839 | /* capless control 2 */ |
2840 | alc_write_coef_idx(codec, 0x68, 0xa080); | 2840 | alc_write_coef_idx(codec, 0x68, 0xa080); |
2841 | /* capless control 3 */ | 2841 | /* capless control 3 */ |
2842 | alc_write_coef_idx(codec, 0x69, 0x3400); | 2842 | alc_write_coef_idx(codec, 0x69, 0x3400); |
2843 | /* capless control 4 */ | 2843 | /* capless control 4 */ |
2844 | alc_write_coef_idx(codec, 0x6a, 0x2f3e); | 2844 | alc_write_coef_idx(codec, 0x6a, 0x2f3e); |
2845 | /* capless control 5 */ | 2845 | /* capless control 5 */ |
2846 | alc_write_coef_idx(codec, 0x6b, 0x0); | 2846 | alc_write_coef_idx(codec, 0x6b, 0x0); |
2847 | /* class D test 2 */ | 2847 | /* class D test 2 */ |
2848 | val = alc_read_coef_idx(codec, 0x6d); | 2848 | val = alc_read_coef_idx(codec, 0x6d); |
2849 | alc_write_coef_idx(codec, 0x6d, (val & ~0x0fff) | 0x0900); | 2849 | alc_write_coef_idx(codec, 0x6d, (val & ~0x0fff) | 0x0900); |
2850 | /* class D test 3 */ | 2850 | /* class D test 3 */ |
2851 | alc_write_coef_idx(codec, 0x6e, 0x110a); | 2851 | alc_write_coef_idx(codec, 0x6e, 0x110a); |
2852 | /* class D test 5 */ | 2852 | /* class D test 5 */ |
2853 | val = alc_read_coef_idx(codec, 0x70); | 2853 | val = alc_read_coef_idx(codec, 0x70); |
2854 | alc_write_coef_idx(codec, 0x70, (val & ~0x00f8) | 0x00d8); | 2854 | alc_write_coef_idx(codec, 0x70, (val & ~0x00f8) | 0x00d8); |
2855 | /* class D test 6 */ | 2855 | /* class D test 6 */ |
2856 | alc_write_coef_idx(codec, 0x71, 0x0014); | 2856 | alc_write_coef_idx(codec, 0x71, 0x0014); |
2857 | /* classD OCP */ | 2857 | /* classD OCP */ |
2858 | alc_write_coef_idx(codec, 0x72, 0xc2ba); | 2858 | alc_write_coef_idx(codec, 0x72, 0xc2ba); |
2859 | /* classD pure DC test */ | 2859 | /* classD pure DC test */ |
2860 | val = alc_read_coef_idx(codec, 0x77); | 2860 | val = alc_read_coef_idx(codec, 0x77); |
2861 | alc_write_coef_idx(codec, 0x77, (val & ~0x0f80) | 0x0); | 2861 | alc_write_coef_idx(codec, 0x77, (val & ~0x0f80) | 0x0); |
2862 | /* Class D amp control */ | 2862 | /* Class D amp control */ |
2863 | alc_write_coef_idx(codec, 0x6c, 0xfc06); | 2863 | alc_write_coef_idx(codec, 0x6c, 0xfc06); |
2864 | } | 2864 | } |
2865 | 2865 | ||
2866 | static void alc282_init(struct hda_codec *codec) | 2866 | static void alc282_init(struct hda_codec *codec) |
2867 | { | 2867 | { |
2868 | struct alc_spec *spec = codec->spec; | 2868 | struct alc_spec *spec = codec->spec; |
2869 | hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; | 2869 | hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; |
2870 | bool hp_pin_sense; | 2870 | bool hp_pin_sense; |
2871 | int coef78; | 2871 | int coef78; |
2872 | 2872 | ||
2873 | alc282_restore_default_value(codec); | 2873 | alc282_restore_default_value(codec); |
2874 | 2874 | ||
2875 | if (!hp_pin) | 2875 | if (!hp_pin) |
2876 | return; | 2876 | return; |
2877 | hp_pin_sense = snd_hda_jack_detect(codec, hp_pin); | 2877 | hp_pin_sense = snd_hda_jack_detect(codec, hp_pin); |
2878 | coef78 = alc_read_coef_idx(codec, 0x78); | 2878 | coef78 = alc_read_coef_idx(codec, 0x78); |
2879 | 2879 | ||
2880 | /* Index 0x78 Direct Drive HP AMP LPM Control 1 */ | 2880 | /* Index 0x78 Direct Drive HP AMP LPM Control 1 */ |
2881 | /* Headphone capless set to high power mode */ | 2881 | /* Headphone capless set to high power mode */ |
2882 | alc_write_coef_idx(codec, 0x78, 0x9004); | 2882 | alc_write_coef_idx(codec, 0x78, 0x9004); |
2883 | 2883 | ||
2884 | if (hp_pin_sense) | 2884 | if (hp_pin_sense) |
2885 | msleep(2); | 2885 | msleep(2); |
2886 | 2886 | ||
2887 | snd_hda_codec_write(codec, hp_pin, 0, | 2887 | snd_hda_codec_write(codec, hp_pin, 0, |
2888 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); | 2888 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); |
2889 | 2889 | ||
2890 | if (hp_pin_sense) | 2890 | if (hp_pin_sense) |
2891 | msleep(85); | 2891 | msleep(85); |
2892 | 2892 | ||
2893 | snd_hda_codec_write(codec, hp_pin, 0, | 2893 | snd_hda_codec_write(codec, hp_pin, 0, |
2894 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); | 2894 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); |
2895 | 2895 | ||
2896 | if (hp_pin_sense) | 2896 | if (hp_pin_sense) |
2897 | msleep(100); | 2897 | msleep(100); |
2898 | 2898 | ||
2899 | /* Headphone capless set to normal mode */ | 2899 | /* Headphone capless set to normal mode */ |
2900 | alc_write_coef_idx(codec, 0x78, coef78); | 2900 | alc_write_coef_idx(codec, 0x78, coef78); |
2901 | } | 2901 | } |
2902 | 2902 | ||
2903 | static void alc282_shutup(struct hda_codec *codec) | 2903 | static void alc282_shutup(struct hda_codec *codec) |
2904 | { | 2904 | { |
2905 | struct alc_spec *spec = codec->spec; | 2905 | struct alc_spec *spec = codec->spec; |
2906 | hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; | 2906 | hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; |
2907 | bool hp_pin_sense; | 2907 | bool hp_pin_sense; |
2908 | int coef78; | 2908 | int coef78; |
2909 | 2909 | ||
2910 | if (!hp_pin) { | 2910 | if (!hp_pin) { |
2911 | alc269_shutup(codec); | 2911 | alc269_shutup(codec); |
2912 | return; | 2912 | return; |
2913 | } | 2913 | } |
2914 | 2914 | ||
2915 | hp_pin_sense = snd_hda_jack_detect(codec, hp_pin); | 2915 | hp_pin_sense = snd_hda_jack_detect(codec, hp_pin); |
2916 | coef78 = alc_read_coef_idx(codec, 0x78); | 2916 | coef78 = alc_read_coef_idx(codec, 0x78); |
2917 | alc_write_coef_idx(codec, 0x78, 0x9004); | 2917 | alc_write_coef_idx(codec, 0x78, 0x9004); |
2918 | 2918 | ||
2919 | if (hp_pin_sense) | 2919 | if (hp_pin_sense) |
2920 | msleep(2); | 2920 | msleep(2); |
2921 | 2921 | ||
2922 | snd_hda_codec_write(codec, hp_pin, 0, | 2922 | snd_hda_codec_write(codec, hp_pin, 0, |
2923 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); | 2923 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); |
2924 | 2924 | ||
2925 | if (hp_pin_sense) | 2925 | if (hp_pin_sense) |
2926 | msleep(85); | 2926 | msleep(85); |
2927 | 2927 | ||
2928 | snd_hda_codec_write(codec, hp_pin, 0, | 2928 | snd_hda_codec_write(codec, hp_pin, 0, |
2929 | AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0); | 2929 | AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0); |
2930 | 2930 | ||
2931 | if (hp_pin_sense) | 2931 | if (hp_pin_sense) |
2932 | msleep(100); | 2932 | msleep(100); |
2933 | 2933 | ||
2934 | alc_auto_setup_eapd(codec, false); | 2934 | alc_auto_setup_eapd(codec, false); |
2935 | snd_hda_shutup_pins(codec); | 2935 | snd_hda_shutup_pins(codec); |
2936 | alc_write_coef_idx(codec, 0x78, coef78); | 2936 | alc_write_coef_idx(codec, 0x78, coef78); |
2937 | } | 2937 | } |
2938 | 2938 | ||
2939 | static void alc283_restore_default_value(struct hda_codec *codec) | 2939 | static void alc283_restore_default_value(struct hda_codec *codec) |
2940 | { | 2940 | { |
2941 | int val; | 2941 | int val; |
2942 | 2942 | ||
2943 | /* Power Down Control */ | 2943 | /* Power Down Control */ |
2944 | alc_write_coef_idx(codec, 0x03, 0x0002); | 2944 | alc_write_coef_idx(codec, 0x03, 0x0002); |
2945 | /* FIFO and filter clock */ | 2945 | /* FIFO and filter clock */ |
2946 | alc_write_coef_idx(codec, 0x05, 0x0700); | 2946 | alc_write_coef_idx(codec, 0x05, 0x0700); |
2947 | /* DMIC control */ | 2947 | /* DMIC control */ |
2948 | alc_write_coef_idx(codec, 0x07, 0x0200); | 2948 | alc_write_coef_idx(codec, 0x07, 0x0200); |
2949 | /* Analog clock */ | 2949 | /* Analog clock */ |
2950 | val = alc_read_coef_idx(codec, 0x06); | 2950 | val = alc_read_coef_idx(codec, 0x06); |
2951 | alc_write_coef_idx(codec, 0x06, (val & ~0x00f0) | 0x0); | 2951 | alc_write_coef_idx(codec, 0x06, (val & ~0x00f0) | 0x0); |
2952 | /* JD */ | 2952 | /* JD */ |
2953 | val = alc_read_coef_idx(codec, 0x08); | 2953 | val = alc_read_coef_idx(codec, 0x08); |
2954 | alc_write_coef_idx(codec, 0x08, (val & ~0xfffc) | 0x0c2c); | 2954 | alc_write_coef_idx(codec, 0x08, (val & ~0xfffc) | 0x0c2c); |
2955 | /* JD offset1 */ | 2955 | /* JD offset1 */ |
2956 | alc_write_coef_idx(codec, 0x0a, 0xcccc); | 2956 | alc_write_coef_idx(codec, 0x0a, 0xcccc); |
2957 | /* JD offset2 */ | 2957 | /* JD offset2 */ |
2958 | alc_write_coef_idx(codec, 0x0b, 0xcccc); | 2958 | alc_write_coef_idx(codec, 0x0b, 0xcccc); |
2959 | /* LDO1/2/3, DAC/ADC */ | 2959 | /* LDO1/2/3, DAC/ADC */ |
2960 | alc_write_coef_idx(codec, 0x0e, 0x6fc0); | 2960 | alc_write_coef_idx(codec, 0x0e, 0x6fc0); |
2961 | /* JD */ | 2961 | /* JD */ |
2962 | val = alc_read_coef_idx(codec, 0x0f); | 2962 | val = alc_read_coef_idx(codec, 0x0f); |
2963 | alc_write_coef_idx(codec, 0x0f, (val & ~0xf800) | 0x1000); | 2963 | alc_write_coef_idx(codec, 0x0f, (val & ~0xf800) | 0x1000); |
2964 | /* Capless */ | 2964 | /* Capless */ |
2965 | val = alc_read_coef_idx(codec, 0x10); | 2965 | val = alc_read_coef_idx(codec, 0x10); |
2966 | alc_write_coef_idx(codec, 0x10, (val & ~0xfc00) | 0x0c00); | 2966 | alc_write_coef_idx(codec, 0x10, (val & ~0xfc00) | 0x0c00); |
2967 | /* Class D test 4 */ | 2967 | /* Class D test 4 */ |
2968 | alc_write_coef_idx(codec, 0x3a, 0x0); | 2968 | alc_write_coef_idx(codec, 0x3a, 0x0); |
2969 | /* IO power down directly */ | 2969 | /* IO power down directly */ |
2970 | val = alc_read_coef_idx(codec, 0x0c); | 2970 | val = alc_read_coef_idx(codec, 0x0c); |
2971 | alc_write_coef_idx(codec, 0x0c, (val & ~0xfe00) | 0x0); | 2971 | alc_write_coef_idx(codec, 0x0c, (val & ~0xfe00) | 0x0); |
2972 | /* ANC */ | 2972 | /* ANC */ |
2973 | alc_write_coef_idx(codec, 0x22, 0xa0c0); | 2973 | alc_write_coef_idx(codec, 0x22, 0xa0c0); |
2974 | /* AGC MUX */ | 2974 | /* AGC MUX */ |
2975 | val = alc_read_coefex_idx(codec, 0x53, 0x01); | 2975 | val = alc_read_coefex_idx(codec, 0x53, 0x01); |
2976 | alc_write_coefex_idx(codec, 0x53, 0x01, (val & ~0x000f) | 0x0008); | 2976 | alc_write_coefex_idx(codec, 0x53, 0x01, (val & ~0x000f) | 0x0008); |
2977 | /* DAC simple content protection */ | 2977 | /* DAC simple content protection */ |
2978 | val = alc_read_coef_idx(codec, 0x1d); | 2978 | val = alc_read_coef_idx(codec, 0x1d); |
2979 | alc_write_coef_idx(codec, 0x1d, (val & ~0x00e0) | 0x0); | 2979 | alc_write_coef_idx(codec, 0x1d, (val & ~0x00e0) | 0x0); |
2980 | /* ADC simple content protection */ | 2980 | /* ADC simple content protection */ |
2981 | val = alc_read_coef_idx(codec, 0x1f); | 2981 | val = alc_read_coef_idx(codec, 0x1f); |
2982 | alc_write_coef_idx(codec, 0x1f, (val & ~0x00e0) | 0x0); | 2982 | alc_write_coef_idx(codec, 0x1f, (val & ~0x00e0) | 0x0); |
2983 | /* DAC ADC Zero Detection */ | 2983 | /* DAC ADC Zero Detection */ |
2984 | alc_write_coef_idx(codec, 0x21, 0x8804); | 2984 | alc_write_coef_idx(codec, 0x21, 0x8804); |
2985 | /* PLL */ | 2985 | /* PLL */ |
2986 | alc_write_coef_idx(codec, 0x2e, 0x2902); | 2986 | alc_write_coef_idx(codec, 0x2e, 0x2902); |
2987 | /* capless control 2 */ | 2987 | /* capless control 2 */ |
2988 | alc_write_coef_idx(codec, 0x33, 0xa080); | 2988 | alc_write_coef_idx(codec, 0x33, 0xa080); |
2989 | /* capless control 3 */ | 2989 | /* capless control 3 */ |
2990 | alc_write_coef_idx(codec, 0x34, 0x3400); | 2990 | alc_write_coef_idx(codec, 0x34, 0x3400); |
2991 | /* capless control 4 */ | 2991 | /* capless control 4 */ |
2992 | alc_write_coef_idx(codec, 0x35, 0x2f3e); | 2992 | alc_write_coef_idx(codec, 0x35, 0x2f3e); |
2993 | /* capless control 5 */ | 2993 | /* capless control 5 */ |
2994 | alc_write_coef_idx(codec, 0x36, 0x0); | 2994 | alc_write_coef_idx(codec, 0x36, 0x0); |
2995 | /* class D test 2 */ | 2995 | /* class D test 2 */ |
2996 | val = alc_read_coef_idx(codec, 0x38); | 2996 | val = alc_read_coef_idx(codec, 0x38); |
2997 | alc_write_coef_idx(codec, 0x38, (val & ~0x0fff) | 0x0900); | 2997 | alc_write_coef_idx(codec, 0x38, (val & ~0x0fff) | 0x0900); |
2998 | /* class D test 3 */ | 2998 | /* class D test 3 */ |
2999 | alc_write_coef_idx(codec, 0x39, 0x110a); | 2999 | alc_write_coef_idx(codec, 0x39, 0x110a); |
3000 | /* class D test 5 */ | 3000 | /* class D test 5 */ |
3001 | val = alc_read_coef_idx(codec, 0x3b); | 3001 | val = alc_read_coef_idx(codec, 0x3b); |
3002 | alc_write_coef_idx(codec, 0x3b, (val & ~0x00f8) | 0x00d8); | 3002 | alc_write_coef_idx(codec, 0x3b, (val & ~0x00f8) | 0x00d8); |
3003 | /* class D test 6 */ | 3003 | /* class D test 6 */ |
3004 | alc_write_coef_idx(codec, 0x3c, 0x0014); | 3004 | alc_write_coef_idx(codec, 0x3c, 0x0014); |
3005 | /* classD OCP */ | 3005 | /* classD OCP */ |
3006 | alc_write_coef_idx(codec, 0x3d, 0xc2ba); | 3006 | alc_write_coef_idx(codec, 0x3d, 0xc2ba); |
3007 | /* classD pure DC test */ | 3007 | /* classD pure DC test */ |
3008 | val = alc_read_coef_idx(codec, 0x42); | 3008 | val = alc_read_coef_idx(codec, 0x42); |
3009 | alc_write_coef_idx(codec, 0x42, (val & ~0x0f80) | 0x0); | 3009 | alc_write_coef_idx(codec, 0x42, (val & ~0x0f80) | 0x0); |
3010 | /* test mode */ | 3010 | /* test mode */ |
3011 | alc_write_coef_idx(codec, 0x49, 0x0); | 3011 | alc_write_coef_idx(codec, 0x49, 0x0); |
3012 | /* Class D DC enable */ | 3012 | /* Class D DC enable */ |
3013 | val = alc_read_coef_idx(codec, 0x40); | 3013 | val = alc_read_coef_idx(codec, 0x40); |
3014 | alc_write_coef_idx(codec, 0x40, (val & ~0xf800) | 0x9800); | 3014 | alc_write_coef_idx(codec, 0x40, (val & ~0xf800) | 0x9800); |
3015 | /* DC offset */ | 3015 | /* DC offset */ |
3016 | val = alc_read_coef_idx(codec, 0x42); | 3016 | val = alc_read_coef_idx(codec, 0x42); |
3017 | alc_write_coef_idx(codec, 0x42, (val & ~0xf000) | 0x2000); | 3017 | alc_write_coef_idx(codec, 0x42, (val & ~0xf000) | 0x2000); |
3018 | /* Class D amp control */ | 3018 | /* Class D amp control */ |
3019 | alc_write_coef_idx(codec, 0x37, 0xfc06); | 3019 | alc_write_coef_idx(codec, 0x37, 0xfc06); |
3020 | } | 3020 | } |
3021 | 3021 | ||
3022 | static void alc283_init(struct hda_codec *codec) | 3022 | static void alc283_init(struct hda_codec *codec) |
3023 | { | 3023 | { |
3024 | struct alc_spec *spec = codec->spec; | 3024 | struct alc_spec *spec = codec->spec; |
3025 | hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; | 3025 | hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; |
3026 | bool hp_pin_sense; | 3026 | bool hp_pin_sense; |
3027 | int val; | 3027 | int val; |
3028 | 3028 | ||
3029 | if (!spec->gen.autocfg.hp_outs) { | 3029 | if (!spec->gen.autocfg.hp_outs) { |
3030 | if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT) | 3030 | if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT) |
3031 | hp_pin = spec->gen.autocfg.line_out_pins[0]; | 3031 | hp_pin = spec->gen.autocfg.line_out_pins[0]; |
3032 | } | 3032 | } |
3033 | 3033 | ||
3034 | alc283_restore_default_value(codec); | 3034 | alc283_restore_default_value(codec); |
3035 | 3035 | ||
3036 | if (!hp_pin) | 3036 | if (!hp_pin) |
3037 | return; | 3037 | return; |
3038 | hp_pin_sense = snd_hda_jack_detect(codec, hp_pin); | 3038 | hp_pin_sense = snd_hda_jack_detect(codec, hp_pin); |
3039 | 3039 | ||
3040 | /* Index 0x43 Direct Drive HP AMP LPM Control 1 */ | 3040 | /* Index 0x43 Direct Drive HP AMP LPM Control 1 */ |
3041 | /* Headphone capless set to high power mode */ | 3041 | /* Headphone capless set to high power mode */ |
3042 | alc_write_coef_idx(codec, 0x43, 0x9004); | 3042 | alc_write_coef_idx(codec, 0x43, 0x9004); |
3043 | 3043 | ||
3044 | snd_hda_codec_write(codec, hp_pin, 0, | 3044 | snd_hda_codec_write(codec, hp_pin, 0, |
3045 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); | 3045 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); |
3046 | 3046 | ||
3047 | if (hp_pin_sense) | 3047 | if (hp_pin_sense) |
3048 | msleep(85); | 3048 | msleep(85); |
3049 | 3049 | ||
3050 | snd_hda_codec_write(codec, hp_pin, 0, | 3050 | snd_hda_codec_write(codec, hp_pin, 0, |
3051 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); | 3051 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); |
3052 | 3052 | ||
3053 | if (hp_pin_sense) | 3053 | if (hp_pin_sense) |
3054 | msleep(85); | 3054 | msleep(85); |
3055 | /* Index 0x46 Combo jack auto switch control 2 */ | 3055 | /* Index 0x46 Combo jack auto switch control 2 */ |
3056 | /* 3k pull low control for Headset jack. */ | 3056 | /* 3k pull low control for Headset jack. */ |
3057 | val = alc_read_coef_idx(codec, 0x46); | 3057 | val = alc_read_coef_idx(codec, 0x46); |
3058 | alc_write_coef_idx(codec, 0x46, val & ~(3 << 12)); | 3058 | alc_write_coef_idx(codec, 0x46, val & ~(3 << 12)); |
3059 | /* Headphone capless set to normal mode */ | 3059 | /* Headphone capless set to normal mode */ |
3060 | alc_write_coef_idx(codec, 0x43, 0x9614); | 3060 | alc_write_coef_idx(codec, 0x43, 0x9614); |
3061 | } | 3061 | } |
3062 | 3062 | ||
3063 | static void alc283_shutup(struct hda_codec *codec) | 3063 | static void alc283_shutup(struct hda_codec *codec) |
3064 | { | 3064 | { |
3065 | struct alc_spec *spec = codec->spec; | 3065 | struct alc_spec *spec = codec->spec; |
3066 | hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; | 3066 | hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; |
3067 | bool hp_pin_sense; | 3067 | bool hp_pin_sense; |
3068 | int val; | 3068 | int val; |
3069 | 3069 | ||
3070 | if (!spec->gen.autocfg.hp_outs) { | 3070 | if (!spec->gen.autocfg.hp_outs) { |
3071 | if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT) | 3071 | if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT) |
3072 | hp_pin = spec->gen.autocfg.line_out_pins[0]; | 3072 | hp_pin = spec->gen.autocfg.line_out_pins[0]; |
3073 | } | 3073 | } |
3074 | 3074 | ||
3075 | if (!hp_pin) { | 3075 | if (!hp_pin) { |
3076 | alc269_shutup(codec); | 3076 | alc269_shutup(codec); |
3077 | return; | 3077 | return; |
3078 | } | 3078 | } |
3079 | 3079 | ||
3080 | hp_pin_sense = snd_hda_jack_detect(codec, hp_pin); | 3080 | hp_pin_sense = snd_hda_jack_detect(codec, hp_pin); |
3081 | 3081 | ||
3082 | alc_write_coef_idx(codec, 0x43, 0x9004); | 3082 | alc_write_coef_idx(codec, 0x43, 0x9004); |
3083 | 3083 | ||
3084 | snd_hda_codec_write(codec, hp_pin, 0, | 3084 | snd_hda_codec_write(codec, hp_pin, 0, |
3085 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); | 3085 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); |
3086 | 3086 | ||
3087 | if (hp_pin_sense) | 3087 | if (hp_pin_sense) |
3088 | msleep(100); | 3088 | msleep(100); |
3089 | 3089 | ||
3090 | snd_hda_codec_write(codec, hp_pin, 0, | 3090 | snd_hda_codec_write(codec, hp_pin, 0, |
3091 | AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0); | 3091 | AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0); |
3092 | 3092 | ||
3093 | val = alc_read_coef_idx(codec, 0x46); | 3093 | val = alc_read_coef_idx(codec, 0x46); |
3094 | alc_write_coef_idx(codec, 0x46, val | (3 << 12)); | 3094 | alc_write_coef_idx(codec, 0x46, val | (3 << 12)); |
3095 | 3095 | ||
3096 | if (hp_pin_sense) | 3096 | if (hp_pin_sense) |
3097 | msleep(100); | 3097 | msleep(100); |
3098 | alc_auto_setup_eapd(codec, false); | 3098 | alc_auto_setup_eapd(codec, false); |
3099 | snd_hda_shutup_pins(codec); | 3099 | snd_hda_shutup_pins(codec); |
3100 | alc_write_coef_idx(codec, 0x43, 0x9614); | 3100 | alc_write_coef_idx(codec, 0x43, 0x9614); |
3101 | } | 3101 | } |
3102 | 3102 | ||
3103 | static void alc5505_coef_set(struct hda_codec *codec, unsigned int index_reg, | 3103 | static void alc5505_coef_set(struct hda_codec *codec, unsigned int index_reg, |
3104 | unsigned int val) | 3104 | unsigned int val) |
3105 | { | 3105 | { |
3106 | snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_COEF_INDEX, index_reg >> 1); | 3106 | snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_COEF_INDEX, index_reg >> 1); |
3107 | snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_PROC_COEF, val & 0xffff); /* LSB */ | 3107 | snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_PROC_COEF, val & 0xffff); /* LSB */ |
3108 | snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_PROC_COEF, val >> 16); /* MSB */ | 3108 | snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_PROC_COEF, val >> 16); /* MSB */ |
3109 | } | 3109 | } |
3110 | 3110 | ||
3111 | static int alc5505_coef_get(struct hda_codec *codec, unsigned int index_reg) | 3111 | static int alc5505_coef_get(struct hda_codec *codec, unsigned int index_reg) |
3112 | { | 3112 | { |
3113 | unsigned int val; | 3113 | unsigned int val; |
3114 | 3114 | ||
3115 | snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_COEF_INDEX, index_reg >> 1); | 3115 | snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_COEF_INDEX, index_reg >> 1); |
3116 | val = snd_hda_codec_read(codec, 0x51, 0, AC_VERB_GET_PROC_COEF, 0) | 3116 | val = snd_hda_codec_read(codec, 0x51, 0, AC_VERB_GET_PROC_COEF, 0) |
3117 | & 0xffff; | 3117 | & 0xffff; |
3118 | val |= snd_hda_codec_read(codec, 0x51, 0, AC_VERB_GET_PROC_COEF, 0) | 3118 | val |= snd_hda_codec_read(codec, 0x51, 0, AC_VERB_GET_PROC_COEF, 0) |
3119 | << 16; | 3119 | << 16; |
3120 | return val; | 3120 | return val; |
3121 | } | 3121 | } |
3122 | 3122 | ||
3123 | static void alc5505_dsp_halt(struct hda_codec *codec) | 3123 | static void alc5505_dsp_halt(struct hda_codec *codec) |
3124 | { | 3124 | { |
3125 | unsigned int val; | 3125 | unsigned int val; |
3126 | 3126 | ||
3127 | alc5505_coef_set(codec, 0x3000, 0x000c); /* DSP CPU stop */ | 3127 | alc5505_coef_set(codec, 0x3000, 0x000c); /* DSP CPU stop */ |
3128 | alc5505_coef_set(codec, 0x880c, 0x0008); /* DDR enter self refresh */ | 3128 | alc5505_coef_set(codec, 0x880c, 0x0008); /* DDR enter self refresh */ |
3129 | alc5505_coef_set(codec, 0x61c0, 0x11110080); /* Clock control for PLL and CPU */ | 3129 | alc5505_coef_set(codec, 0x61c0, 0x11110080); /* Clock control for PLL and CPU */ |
3130 | alc5505_coef_set(codec, 0x6230, 0xfc0d4011); /* Disable Input OP */ | 3130 | alc5505_coef_set(codec, 0x6230, 0xfc0d4011); /* Disable Input OP */ |
3131 | alc5505_coef_set(codec, 0x61b4, 0x040a2b03); /* Stop PLL2 */ | 3131 | alc5505_coef_set(codec, 0x61b4, 0x040a2b03); /* Stop PLL2 */ |
3132 | alc5505_coef_set(codec, 0x61b0, 0x00005b17); /* Stop PLL1 */ | 3132 | alc5505_coef_set(codec, 0x61b0, 0x00005b17); /* Stop PLL1 */ |
3133 | alc5505_coef_set(codec, 0x61b8, 0x04133303); /* Stop PLL3 */ | 3133 | alc5505_coef_set(codec, 0x61b8, 0x04133303); /* Stop PLL3 */ |
3134 | val = alc5505_coef_get(codec, 0x6220); | 3134 | val = alc5505_coef_get(codec, 0x6220); |
3135 | alc5505_coef_set(codec, 0x6220, (val | 0x3000)); /* switch Ringbuffer clock to DBUS clock */ | 3135 | alc5505_coef_set(codec, 0x6220, (val | 0x3000)); /* switch Ringbuffer clock to DBUS clock */ |
3136 | } | 3136 | } |
3137 | 3137 | ||
3138 | static void alc5505_dsp_back_from_halt(struct hda_codec *codec) | 3138 | static void alc5505_dsp_back_from_halt(struct hda_codec *codec) |
3139 | { | 3139 | { |
3140 | alc5505_coef_set(codec, 0x61b8, 0x04133302); | 3140 | alc5505_coef_set(codec, 0x61b8, 0x04133302); |
3141 | alc5505_coef_set(codec, 0x61b0, 0x00005b16); | 3141 | alc5505_coef_set(codec, 0x61b0, 0x00005b16); |
3142 | alc5505_coef_set(codec, 0x61b4, 0x040a2b02); | 3142 | alc5505_coef_set(codec, 0x61b4, 0x040a2b02); |
3143 | alc5505_coef_set(codec, 0x6230, 0xf80d4011); | 3143 | alc5505_coef_set(codec, 0x6230, 0xf80d4011); |
3144 | alc5505_coef_set(codec, 0x6220, 0x2002010f); | 3144 | alc5505_coef_set(codec, 0x6220, 0x2002010f); |
3145 | alc5505_coef_set(codec, 0x880c, 0x00000004); | 3145 | alc5505_coef_set(codec, 0x880c, 0x00000004); |
3146 | } | 3146 | } |
3147 | 3147 | ||
3148 | static void alc5505_dsp_init(struct hda_codec *codec) | 3148 | static void alc5505_dsp_init(struct hda_codec *codec) |
3149 | { | 3149 | { |
3150 | unsigned int val; | 3150 | unsigned int val; |
3151 | 3151 | ||
3152 | alc5505_dsp_halt(codec); | 3152 | alc5505_dsp_halt(codec); |
3153 | alc5505_dsp_back_from_halt(codec); | 3153 | alc5505_dsp_back_from_halt(codec); |
3154 | alc5505_coef_set(codec, 0x61b0, 0x5b14); /* PLL1 control */ | 3154 | alc5505_coef_set(codec, 0x61b0, 0x5b14); /* PLL1 control */ |
3155 | alc5505_coef_set(codec, 0x61b0, 0x5b16); | 3155 | alc5505_coef_set(codec, 0x61b0, 0x5b16); |
3156 | alc5505_coef_set(codec, 0x61b4, 0x04132b00); /* PLL2 control */ | 3156 | alc5505_coef_set(codec, 0x61b4, 0x04132b00); /* PLL2 control */ |
3157 | alc5505_coef_set(codec, 0x61b4, 0x04132b02); | 3157 | alc5505_coef_set(codec, 0x61b4, 0x04132b02); |
3158 | alc5505_coef_set(codec, 0x61b8, 0x041f3300); /* PLL3 control*/ | 3158 | alc5505_coef_set(codec, 0x61b8, 0x041f3300); /* PLL3 control*/ |
3159 | alc5505_coef_set(codec, 0x61b8, 0x041f3302); | 3159 | alc5505_coef_set(codec, 0x61b8, 0x041f3302); |
3160 | snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_CODEC_RESET, 0); /* Function reset */ | 3160 | snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_CODEC_RESET, 0); /* Function reset */ |
3161 | alc5505_coef_set(codec, 0x61b8, 0x041b3302); | 3161 | alc5505_coef_set(codec, 0x61b8, 0x041b3302); |
3162 | alc5505_coef_set(codec, 0x61b8, 0x04173302); | 3162 | alc5505_coef_set(codec, 0x61b8, 0x04173302); |
3163 | alc5505_coef_set(codec, 0x61b8, 0x04163302); | 3163 | alc5505_coef_set(codec, 0x61b8, 0x04163302); |
3164 | alc5505_coef_set(codec, 0x8800, 0x348b328b); /* DRAM control */ | 3164 | alc5505_coef_set(codec, 0x8800, 0x348b328b); /* DRAM control */ |
3165 | alc5505_coef_set(codec, 0x8808, 0x00020022); /* DRAM control */ | 3165 | alc5505_coef_set(codec, 0x8808, 0x00020022); /* DRAM control */ |
3166 | alc5505_coef_set(codec, 0x8818, 0x00000400); /* DRAM control */ | 3166 | alc5505_coef_set(codec, 0x8818, 0x00000400); /* DRAM control */ |
3167 | 3167 | ||
3168 | val = alc5505_coef_get(codec, 0x6200) >> 16; /* Read revision ID */ | 3168 | val = alc5505_coef_get(codec, 0x6200) >> 16; /* Read revision ID */ |
3169 | if (val <= 3) | 3169 | if (val <= 3) |
3170 | alc5505_coef_set(codec, 0x6220, 0x2002010f); /* I/O PAD Configuration */ | 3170 | alc5505_coef_set(codec, 0x6220, 0x2002010f); /* I/O PAD Configuration */ |
3171 | else | 3171 | else |
3172 | alc5505_coef_set(codec, 0x6220, 0x6002018f); | 3172 | alc5505_coef_set(codec, 0x6220, 0x6002018f); |
3173 | 3173 | ||
3174 | alc5505_coef_set(codec, 0x61ac, 0x055525f0); /**/ | 3174 | alc5505_coef_set(codec, 0x61ac, 0x055525f0); /**/ |
3175 | alc5505_coef_set(codec, 0x61c0, 0x12230080); /* Clock control */ | 3175 | alc5505_coef_set(codec, 0x61c0, 0x12230080); /* Clock control */ |
3176 | alc5505_coef_set(codec, 0x61b4, 0x040e2b02); /* PLL2 control */ | 3176 | alc5505_coef_set(codec, 0x61b4, 0x040e2b02); /* PLL2 control */ |
3177 | alc5505_coef_set(codec, 0x61bc, 0x010234f8); /* OSC Control */ | 3177 | alc5505_coef_set(codec, 0x61bc, 0x010234f8); /* OSC Control */ |
3178 | alc5505_coef_set(codec, 0x880c, 0x00000004); /* DRAM Function control */ | 3178 | alc5505_coef_set(codec, 0x880c, 0x00000004); /* DRAM Function control */ |
3179 | alc5505_coef_set(codec, 0x880c, 0x00000003); | 3179 | alc5505_coef_set(codec, 0x880c, 0x00000003); |
3180 | alc5505_coef_set(codec, 0x880c, 0x00000010); | 3180 | alc5505_coef_set(codec, 0x880c, 0x00000010); |
3181 | 3181 | ||
3182 | #ifdef HALT_REALTEK_ALC5505 | 3182 | #ifdef HALT_REALTEK_ALC5505 |
3183 | alc5505_dsp_halt(codec); | 3183 | alc5505_dsp_halt(codec); |
3184 | #endif | 3184 | #endif |
3185 | } | 3185 | } |
3186 | 3186 | ||
3187 | #ifdef HALT_REALTEK_ALC5505 | 3187 | #ifdef HALT_REALTEK_ALC5505 |
3188 | #define alc5505_dsp_suspend(codec) /* NOP */ | 3188 | #define alc5505_dsp_suspend(codec) /* NOP */ |
3189 | #define alc5505_dsp_resume(codec) /* NOP */ | 3189 | #define alc5505_dsp_resume(codec) /* NOP */ |
3190 | #else | 3190 | #else |
3191 | #define alc5505_dsp_suspend(codec) alc5505_dsp_halt(codec) | 3191 | #define alc5505_dsp_suspend(codec) alc5505_dsp_halt(codec) |
3192 | #define alc5505_dsp_resume(codec) alc5505_dsp_back_from_halt(codec) | 3192 | #define alc5505_dsp_resume(codec) alc5505_dsp_back_from_halt(codec) |
3193 | #endif | 3193 | #endif |
3194 | 3194 | ||
3195 | #ifdef CONFIG_PM | 3195 | #ifdef CONFIG_PM |
3196 | static int alc269_suspend(struct hda_codec *codec) | 3196 | static int alc269_suspend(struct hda_codec *codec) |
3197 | { | 3197 | { |
3198 | struct alc_spec *spec = codec->spec; | 3198 | struct alc_spec *spec = codec->spec; |
3199 | 3199 | ||
3200 | if (spec->has_alc5505_dsp) | 3200 | if (spec->has_alc5505_dsp) |
3201 | alc5505_dsp_suspend(codec); | 3201 | alc5505_dsp_suspend(codec); |
3202 | return alc_suspend(codec); | 3202 | return alc_suspend(codec); |
3203 | } | 3203 | } |
3204 | 3204 | ||
3205 | static int alc269_resume(struct hda_codec *codec) | 3205 | static int alc269_resume(struct hda_codec *codec) |
3206 | { | 3206 | { |
3207 | struct alc_spec *spec = codec->spec; | 3207 | struct alc_spec *spec = codec->spec; |
3208 | 3208 | ||
3209 | if (spec->codec_variant == ALC269_TYPE_ALC269VB) | 3209 | if (spec->codec_variant == ALC269_TYPE_ALC269VB) |
3210 | alc269vb_toggle_power_output(codec, 0); | 3210 | alc269vb_toggle_power_output(codec, 0); |
3211 | if (spec->codec_variant == ALC269_TYPE_ALC269VB && | 3211 | if (spec->codec_variant == ALC269_TYPE_ALC269VB && |
3212 | (alc_get_coef0(codec) & 0x00ff) == 0x018) { | 3212 | (alc_get_coef0(codec) & 0x00ff) == 0x018) { |
3213 | msleep(150); | 3213 | msleep(150); |
3214 | } | 3214 | } |
3215 | 3215 | ||
3216 | codec->patch_ops.init(codec); | 3216 | codec->patch_ops.init(codec); |
3217 | 3217 | ||
3218 | if (spec->codec_variant == ALC269_TYPE_ALC269VB) | 3218 | if (spec->codec_variant == ALC269_TYPE_ALC269VB) |
3219 | alc269vb_toggle_power_output(codec, 1); | 3219 | alc269vb_toggle_power_output(codec, 1); |
3220 | if (spec->codec_variant == ALC269_TYPE_ALC269VB && | 3220 | if (spec->codec_variant == ALC269_TYPE_ALC269VB && |
3221 | (alc_get_coef0(codec) & 0x00ff) == 0x017) { | 3221 | (alc_get_coef0(codec) & 0x00ff) == 0x017) { |
3222 | msleep(200); | 3222 | msleep(200); |
3223 | } | 3223 | } |
3224 | 3224 | ||
3225 | snd_hda_codec_resume_amp(codec); | 3225 | snd_hda_codec_resume_amp(codec); |
3226 | snd_hda_codec_resume_cache(codec); | 3226 | snd_hda_codec_resume_cache(codec); |
3227 | alc_inv_dmic_sync(codec, true); | 3227 | alc_inv_dmic_sync(codec, true); |
3228 | hda_call_check_power_status(codec, 0x01); | 3228 | hda_call_check_power_status(codec, 0x01); |
3229 | if (spec->has_alc5505_dsp) | 3229 | if (spec->has_alc5505_dsp) |
3230 | alc5505_dsp_resume(codec); | 3230 | alc5505_dsp_resume(codec); |
3231 | 3231 | ||
3232 | return 0; | 3232 | return 0; |
3233 | } | 3233 | } |
3234 | #endif /* CONFIG_PM */ | 3234 | #endif /* CONFIG_PM */ |
3235 | 3235 | ||
3236 | static void alc269_fixup_pincfg_no_hp_to_lineout(struct hda_codec *codec, | 3236 | static void alc269_fixup_pincfg_no_hp_to_lineout(struct hda_codec *codec, |
3237 | const struct hda_fixup *fix, int action) | 3237 | const struct hda_fixup *fix, int action) |
3238 | { | 3238 | { |
3239 | struct alc_spec *spec = codec->spec; | 3239 | struct alc_spec *spec = codec->spec; |
3240 | 3240 | ||
3241 | if (action == HDA_FIXUP_ACT_PRE_PROBE) | 3241 | if (action == HDA_FIXUP_ACT_PRE_PROBE) |
3242 | spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP; | 3242 | spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP; |
3243 | } | 3243 | } |
3244 | 3244 | ||
3245 | static void alc269_fixup_hweq(struct hda_codec *codec, | 3245 | static void alc269_fixup_hweq(struct hda_codec *codec, |
3246 | const struct hda_fixup *fix, int action) | 3246 | const struct hda_fixup *fix, int action) |
3247 | { | 3247 | { |
3248 | int coef; | 3248 | int coef; |
3249 | 3249 | ||
3250 | if (action != HDA_FIXUP_ACT_INIT) | 3250 | if (action != HDA_FIXUP_ACT_INIT) |
3251 | return; | 3251 | return; |
3252 | coef = alc_read_coef_idx(codec, 0x1e); | 3252 | coef = alc_read_coef_idx(codec, 0x1e); |
3253 | alc_write_coef_idx(codec, 0x1e, coef | 0x80); | 3253 | alc_write_coef_idx(codec, 0x1e, coef | 0x80); |
3254 | } | 3254 | } |
3255 | 3255 | ||
3256 | static void alc269_fixup_headset_mic(struct hda_codec *codec, | 3256 | static void alc269_fixup_headset_mic(struct hda_codec *codec, |
3257 | const struct hda_fixup *fix, int action) | 3257 | const struct hda_fixup *fix, int action) |
3258 | { | 3258 | { |
3259 | struct alc_spec *spec = codec->spec; | 3259 | struct alc_spec *spec = codec->spec; |
3260 | 3260 | ||
3261 | if (action == HDA_FIXUP_ACT_PRE_PROBE) | 3261 | if (action == HDA_FIXUP_ACT_PRE_PROBE) |
3262 | spec->parse_flags |= HDA_PINCFG_HEADSET_MIC; | 3262 | spec->parse_flags |= HDA_PINCFG_HEADSET_MIC; |
3263 | } | 3263 | } |
3264 | 3264 | ||
3265 | static void alc271_fixup_dmic(struct hda_codec *codec, | 3265 | static void alc271_fixup_dmic(struct hda_codec *codec, |
3266 | const struct hda_fixup *fix, int action) | 3266 | const struct hda_fixup *fix, int action) |
3267 | { | 3267 | { |
3268 | static const struct hda_verb verbs[] = { | 3268 | static const struct hda_verb verbs[] = { |
3269 | {0x20, AC_VERB_SET_COEF_INDEX, 0x0d}, | 3269 | {0x20, AC_VERB_SET_COEF_INDEX, 0x0d}, |
3270 | {0x20, AC_VERB_SET_PROC_COEF, 0x4000}, | 3270 | {0x20, AC_VERB_SET_PROC_COEF, 0x4000}, |
3271 | {} | 3271 | {} |
3272 | }; | 3272 | }; |
3273 | unsigned int cfg; | 3273 | unsigned int cfg; |
3274 | 3274 | ||
3275 | if (strcmp(codec->chip_name, "ALC271X") && | 3275 | if (strcmp(codec->chip_name, "ALC271X") && |
3276 | strcmp(codec->chip_name, "ALC269VB")) | 3276 | strcmp(codec->chip_name, "ALC269VB")) |
3277 | return; | 3277 | return; |
3278 | cfg = snd_hda_codec_get_pincfg(codec, 0x12); | 3278 | cfg = snd_hda_codec_get_pincfg(codec, 0x12); |
3279 | if (get_defcfg_connect(cfg) == AC_JACK_PORT_FIXED) | 3279 | if (get_defcfg_connect(cfg) == AC_JACK_PORT_FIXED) |
3280 | snd_hda_sequence_write(codec, verbs); | 3280 | snd_hda_sequence_write(codec, verbs); |
3281 | } | 3281 | } |
3282 | 3282 | ||
3283 | static void alc269_fixup_pcm_44k(struct hda_codec *codec, | 3283 | static void alc269_fixup_pcm_44k(struct hda_codec *codec, |
3284 | const struct hda_fixup *fix, int action) | 3284 | const struct hda_fixup *fix, int action) |
3285 | { | 3285 | { |
3286 | struct alc_spec *spec = codec->spec; | 3286 | struct alc_spec *spec = codec->spec; |
3287 | 3287 | ||
3288 | if (action != HDA_FIXUP_ACT_PROBE) | 3288 | if (action != HDA_FIXUP_ACT_PROBE) |
3289 | return; | 3289 | return; |
3290 | 3290 | ||
3291 | /* Due to a hardware problem on Lenovo Ideadpad, we need to | 3291 | /* Due to a hardware problem on Lenovo Ideadpad, we need to |
3292 | * fix the sample rate of analog I/O to 44.1kHz | 3292 | * fix the sample rate of analog I/O to 44.1kHz |
3293 | */ | 3293 | */ |
3294 | spec->gen.stream_analog_playback = &alc269_44k_pcm_analog_playback; | 3294 | spec->gen.stream_analog_playback = &alc269_44k_pcm_analog_playback; |
3295 | spec->gen.stream_analog_capture = &alc269_44k_pcm_analog_capture; | 3295 | spec->gen.stream_analog_capture = &alc269_44k_pcm_analog_capture; |
3296 | } | 3296 | } |
3297 | 3297 | ||
3298 | static void alc269_fixup_stereo_dmic(struct hda_codec *codec, | 3298 | static void alc269_fixup_stereo_dmic(struct hda_codec *codec, |
3299 | const struct hda_fixup *fix, int action) | 3299 | const struct hda_fixup *fix, int action) |
3300 | { | 3300 | { |
3301 | int coef; | 3301 | int coef; |
3302 | 3302 | ||
3303 | if (action != HDA_FIXUP_ACT_INIT) | 3303 | if (action != HDA_FIXUP_ACT_INIT) |
3304 | return; | 3304 | return; |
3305 | /* The digital-mic unit sends PDM (differential signal) instead of | 3305 | /* The digital-mic unit sends PDM (differential signal) instead of |
3306 | * the standard PCM, thus you can't record a valid mono stream as is. | 3306 | * the standard PCM, thus you can't record a valid mono stream as is. |
3307 | * Below is a workaround specific to ALC269 to control the dmic | 3307 | * Below is a workaround specific to ALC269 to control the dmic |
3308 | * signal source as mono. | 3308 | * signal source as mono. |
3309 | */ | 3309 | */ |
3310 | coef = alc_read_coef_idx(codec, 0x07); | 3310 | coef = alc_read_coef_idx(codec, 0x07); |
3311 | alc_write_coef_idx(codec, 0x07, coef | 0x80); | 3311 | alc_write_coef_idx(codec, 0x07, coef | 0x80); |
3312 | } | 3312 | } |
3313 | 3313 | ||
3314 | static void alc269_quanta_automute(struct hda_codec *codec) | 3314 | static void alc269_quanta_automute(struct hda_codec *codec) |
3315 | { | 3315 | { |
3316 | snd_hda_gen_update_outputs(codec); | 3316 | snd_hda_gen_update_outputs(codec); |
3317 | 3317 | ||
3318 | snd_hda_codec_write(codec, 0x20, 0, | 3318 | snd_hda_codec_write(codec, 0x20, 0, |
3319 | AC_VERB_SET_COEF_INDEX, 0x0c); | 3319 | AC_VERB_SET_COEF_INDEX, 0x0c); |
3320 | snd_hda_codec_write(codec, 0x20, 0, | 3320 | snd_hda_codec_write(codec, 0x20, 0, |
3321 | AC_VERB_SET_PROC_COEF, 0x680); | 3321 | AC_VERB_SET_PROC_COEF, 0x680); |
3322 | 3322 | ||
3323 | snd_hda_codec_write(codec, 0x20, 0, | 3323 | snd_hda_codec_write(codec, 0x20, 0, |
3324 | AC_VERB_SET_COEF_INDEX, 0x0c); | 3324 | AC_VERB_SET_COEF_INDEX, 0x0c); |
3325 | snd_hda_codec_write(codec, 0x20, 0, | 3325 | snd_hda_codec_write(codec, 0x20, 0, |
3326 | AC_VERB_SET_PROC_COEF, 0x480); | 3326 | AC_VERB_SET_PROC_COEF, 0x480); |
3327 | } | 3327 | } |
3328 | 3328 | ||
3329 | static void alc269_fixup_quanta_mute(struct hda_codec *codec, | 3329 | static void alc269_fixup_quanta_mute(struct hda_codec *codec, |
3330 | const struct hda_fixup *fix, int action) | 3330 | const struct hda_fixup *fix, int action) |
3331 | { | 3331 | { |
3332 | struct alc_spec *spec = codec->spec; | 3332 | struct alc_spec *spec = codec->spec; |
3333 | if (action != HDA_FIXUP_ACT_PROBE) | 3333 | if (action != HDA_FIXUP_ACT_PROBE) |
3334 | return; | 3334 | return; |
3335 | spec->gen.automute_hook = alc269_quanta_automute; | 3335 | spec->gen.automute_hook = alc269_quanta_automute; |
3336 | } | 3336 | } |
3337 | 3337 | ||
3338 | static void alc269_x101_hp_automute_hook(struct hda_codec *codec, | 3338 | static void alc269_x101_hp_automute_hook(struct hda_codec *codec, |
3339 | struct hda_jack_tbl *jack) | 3339 | struct hda_jack_tbl *jack) |
3340 | { | 3340 | { |
3341 | struct alc_spec *spec = codec->spec; | 3341 | struct alc_spec *spec = codec->spec; |
3342 | int vref; | 3342 | int vref; |
3343 | msleep(200); | 3343 | msleep(200); |
3344 | snd_hda_gen_hp_automute(codec, jack); | 3344 | snd_hda_gen_hp_automute(codec, jack); |
3345 | 3345 | ||
3346 | vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0; | 3346 | vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0; |
3347 | msleep(100); | 3347 | msleep(100); |
3348 | snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | 3348 | snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, |
3349 | vref); | 3349 | vref); |
3350 | msleep(500); | 3350 | msleep(500); |
3351 | snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | 3351 | snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, |
3352 | vref); | 3352 | vref); |
3353 | } | 3353 | } |
3354 | 3354 | ||
3355 | static void alc269_fixup_x101_headset_mic(struct hda_codec *codec, | 3355 | static void alc269_fixup_x101_headset_mic(struct hda_codec *codec, |
3356 | const struct hda_fixup *fix, int action) | 3356 | const struct hda_fixup *fix, int action) |
3357 | { | 3357 | { |
3358 | struct alc_spec *spec = codec->spec; | 3358 | struct alc_spec *spec = codec->spec; |
3359 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | 3359 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
3360 | spec->parse_flags |= HDA_PINCFG_HEADSET_MIC; | 3360 | spec->parse_flags |= HDA_PINCFG_HEADSET_MIC; |
3361 | spec->gen.hp_automute_hook = alc269_x101_hp_automute_hook; | 3361 | spec->gen.hp_automute_hook = alc269_x101_hp_automute_hook; |
3362 | } | 3362 | } |
3363 | } | 3363 | } |
3364 | 3364 | ||
3365 | 3365 | ||
3366 | /* update mute-LED according to the speaker mute state via mic VREF pin */ | 3366 | /* update mute-LED according to the speaker mute state via mic VREF pin */ |
3367 | static void alc269_fixup_mic_mute_hook(void *private_data, int enabled) | 3367 | static void alc269_fixup_mic_mute_hook(void *private_data, int enabled) |
3368 | { | 3368 | { |
3369 | struct hda_codec *codec = private_data; | 3369 | struct hda_codec *codec = private_data; |
3370 | struct alc_spec *spec = codec->spec; | 3370 | struct alc_spec *spec = codec->spec; |
3371 | unsigned int pinval; | 3371 | unsigned int pinval; |
3372 | 3372 | ||
3373 | if (spec->mute_led_polarity) | 3373 | if (spec->mute_led_polarity) |
3374 | enabled = !enabled; | 3374 | enabled = !enabled; |
3375 | pinval = snd_hda_codec_get_pin_target(codec, spec->mute_led_nid); | 3375 | pinval = snd_hda_codec_get_pin_target(codec, spec->mute_led_nid); |
3376 | pinval &= ~AC_PINCTL_VREFEN; | 3376 | pinval &= ~AC_PINCTL_VREFEN; |
3377 | pinval |= enabled ? AC_PINCTL_VREF_HIZ : AC_PINCTL_VREF_80; | 3377 | pinval |= enabled ? AC_PINCTL_VREF_HIZ : AC_PINCTL_VREF_80; |
3378 | if (spec->mute_led_nid) | 3378 | if (spec->mute_led_nid) |
3379 | snd_hda_set_pin_ctl_cache(codec, spec->mute_led_nid, pinval); | 3379 | snd_hda_set_pin_ctl_cache(codec, spec->mute_led_nid, pinval); |
3380 | } | 3380 | } |
3381 | 3381 | ||
3382 | /* Make sure the led works even in runtime suspend */ | 3382 | /* Make sure the led works even in runtime suspend */ |
3383 | static unsigned int led_power_filter(struct hda_codec *codec, | 3383 | static unsigned int led_power_filter(struct hda_codec *codec, |
3384 | hda_nid_t nid, | 3384 | hda_nid_t nid, |
3385 | unsigned int power_state) | 3385 | unsigned int power_state) |
3386 | { | 3386 | { |
3387 | struct alc_spec *spec = codec->spec; | 3387 | struct alc_spec *spec = codec->spec; |
3388 | 3388 | ||
3389 | if (power_state != AC_PWRST_D3 || nid != spec->mute_led_nid) | 3389 | if (power_state != AC_PWRST_D3 || nid != spec->mute_led_nid) |
3390 | return power_state; | 3390 | return power_state; |
3391 | 3391 | ||
3392 | /* Set pin ctl again, it might have just been set to 0 */ | 3392 | /* Set pin ctl again, it might have just been set to 0 */ |
3393 | snd_hda_set_pin_ctl(codec, nid, | 3393 | snd_hda_set_pin_ctl(codec, nid, |
3394 | snd_hda_codec_get_pin_target(codec, nid)); | 3394 | snd_hda_codec_get_pin_target(codec, nid)); |
3395 | 3395 | ||
3396 | return AC_PWRST_D0; | 3396 | return AC_PWRST_D0; |
3397 | } | 3397 | } |
3398 | 3398 | ||
3399 | static void alc269_fixup_hp_mute_led(struct hda_codec *codec, | 3399 | static void alc269_fixup_hp_mute_led(struct hda_codec *codec, |
3400 | const struct hda_fixup *fix, int action) | 3400 | const struct hda_fixup *fix, int action) |
3401 | { | 3401 | { |
3402 | struct alc_spec *spec = codec->spec; | 3402 | struct alc_spec *spec = codec->spec; |
3403 | const struct dmi_device *dev = NULL; | 3403 | const struct dmi_device *dev = NULL; |
3404 | 3404 | ||
3405 | if (action != HDA_FIXUP_ACT_PRE_PROBE) | 3405 | if (action != HDA_FIXUP_ACT_PRE_PROBE) |
3406 | return; | 3406 | return; |
3407 | 3407 | ||
3408 | while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) { | 3408 | while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) { |
3409 | int pol, pin; | 3409 | int pol, pin; |
3410 | if (sscanf(dev->name, "HP_Mute_LED_%d_%x", &pol, &pin) != 2) | 3410 | if (sscanf(dev->name, "HP_Mute_LED_%d_%x", &pol, &pin) != 2) |
3411 | continue; | 3411 | continue; |
3412 | if (pin < 0x0a || pin >= 0x10) | 3412 | if (pin < 0x0a || pin >= 0x10) |
3413 | break; | 3413 | break; |
3414 | spec->mute_led_polarity = pol; | 3414 | spec->mute_led_polarity = pol; |
3415 | spec->mute_led_nid = pin - 0x0a + 0x18; | 3415 | spec->mute_led_nid = pin - 0x0a + 0x18; |
3416 | spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook; | 3416 | spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook; |
3417 | spec->gen.vmaster_mute_enum = 1; | 3417 | spec->gen.vmaster_mute_enum = 1; |
3418 | codec->power_filter = led_power_filter; | 3418 | codec->power_filter = led_power_filter; |
3419 | codec_dbg(codec, | 3419 | codec_dbg(codec, |
3420 | "Detected mute LED for %x:%d\n", spec->mute_led_nid, | 3420 | "Detected mute LED for %x:%d\n", spec->mute_led_nid, |
3421 | spec->mute_led_polarity); | 3421 | spec->mute_led_polarity); |
3422 | break; | 3422 | break; |
3423 | } | 3423 | } |
3424 | } | 3424 | } |
3425 | 3425 | ||
3426 | static void alc269_fixup_hp_mute_led_mic1(struct hda_codec *codec, | 3426 | static void alc269_fixup_hp_mute_led_mic1(struct hda_codec *codec, |
3427 | const struct hda_fixup *fix, int action) | 3427 | const struct hda_fixup *fix, int action) |
3428 | { | 3428 | { |
3429 | struct alc_spec *spec = codec->spec; | 3429 | struct alc_spec *spec = codec->spec; |
3430 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | 3430 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
3431 | spec->mute_led_polarity = 0; | 3431 | spec->mute_led_polarity = 0; |
3432 | spec->mute_led_nid = 0x18; | 3432 | spec->mute_led_nid = 0x18; |
3433 | spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook; | 3433 | spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook; |
3434 | spec->gen.vmaster_mute_enum = 1; | 3434 | spec->gen.vmaster_mute_enum = 1; |
3435 | codec->power_filter = led_power_filter; | 3435 | codec->power_filter = led_power_filter; |
3436 | } | 3436 | } |
3437 | } | 3437 | } |
3438 | 3438 | ||
3439 | static void alc269_fixup_hp_mute_led_mic2(struct hda_codec *codec, | 3439 | static void alc269_fixup_hp_mute_led_mic2(struct hda_codec *codec, |
3440 | const struct hda_fixup *fix, int action) | 3440 | const struct hda_fixup *fix, int action) |
3441 | { | 3441 | { |
3442 | struct alc_spec *spec = codec->spec; | 3442 | struct alc_spec *spec = codec->spec; |
3443 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | 3443 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
3444 | spec->mute_led_polarity = 0; | 3444 | spec->mute_led_polarity = 0; |
3445 | spec->mute_led_nid = 0x19; | 3445 | spec->mute_led_nid = 0x19; |
3446 | spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook; | 3446 | spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook; |
3447 | spec->gen.vmaster_mute_enum = 1; | 3447 | spec->gen.vmaster_mute_enum = 1; |
3448 | codec->power_filter = led_power_filter; | 3448 | codec->power_filter = led_power_filter; |
3449 | } | 3449 | } |
3450 | } | 3450 | } |
3451 | 3451 | ||
3452 | /* turn on/off mute LED per vmaster hook */ | 3452 | /* turn on/off mute LED per vmaster hook */ |
3453 | static void alc269_fixup_hp_gpio_mute_hook(void *private_data, int enabled) | 3453 | static void alc269_fixup_hp_gpio_mute_hook(void *private_data, int enabled) |
3454 | { | 3454 | { |
3455 | struct hda_codec *codec = private_data; | 3455 | struct hda_codec *codec = private_data; |
3456 | struct alc_spec *spec = codec->spec; | 3456 | struct alc_spec *spec = codec->spec; |
3457 | unsigned int oldval = spec->gpio_led; | 3457 | unsigned int oldval = spec->gpio_led; |
3458 | 3458 | ||
3459 | if (enabled) | 3459 | if (enabled) |
3460 | spec->gpio_led &= ~0x08; | 3460 | spec->gpio_led &= ~0x08; |
3461 | else | 3461 | else |
3462 | spec->gpio_led |= 0x08; | 3462 | spec->gpio_led |= 0x08; |
3463 | if (spec->gpio_led != oldval) | 3463 | if (spec->gpio_led != oldval) |
3464 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, | 3464 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, |
3465 | spec->gpio_led); | 3465 | spec->gpio_led); |
3466 | } | 3466 | } |
3467 | 3467 | ||
3468 | /* turn on/off mic-mute LED per capture hook */ | 3468 | /* turn on/off mic-mute LED per capture hook */ |
3469 | static void alc269_fixup_hp_gpio_mic_mute_hook(struct hda_codec *codec, | 3469 | static void alc269_fixup_hp_gpio_mic_mute_hook(struct hda_codec *codec, |
3470 | struct snd_kcontrol *kcontrol, | 3470 | struct snd_kcontrol *kcontrol, |
3471 | struct snd_ctl_elem_value *ucontrol) | 3471 | struct snd_ctl_elem_value *ucontrol) |
3472 | { | 3472 | { |
3473 | struct alc_spec *spec = codec->spec; | 3473 | struct alc_spec *spec = codec->spec; |
3474 | unsigned int oldval = spec->gpio_led; | 3474 | unsigned int oldval = spec->gpio_led; |
3475 | 3475 | ||
3476 | if (!ucontrol) | 3476 | if (!ucontrol) |
3477 | return; | 3477 | return; |
3478 | 3478 | ||
3479 | if (ucontrol->value.integer.value[0] || | 3479 | if (ucontrol->value.integer.value[0] || |
3480 | ucontrol->value.integer.value[1]) | 3480 | ucontrol->value.integer.value[1]) |
3481 | spec->gpio_led &= ~0x10; | 3481 | spec->gpio_led &= ~0x10; |
3482 | else | 3482 | else |
3483 | spec->gpio_led |= 0x10; | 3483 | spec->gpio_led |= 0x10; |
3484 | if (spec->gpio_led != oldval) | 3484 | if (spec->gpio_led != oldval) |
3485 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, | 3485 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, |
3486 | spec->gpio_led); | 3486 | spec->gpio_led); |
3487 | } | 3487 | } |
3488 | 3488 | ||
3489 | static void alc269_fixup_hp_gpio_led(struct hda_codec *codec, | 3489 | static void alc269_fixup_hp_gpio_led(struct hda_codec *codec, |
3490 | const struct hda_fixup *fix, int action) | 3490 | const struct hda_fixup *fix, int action) |
3491 | { | 3491 | { |
3492 | struct alc_spec *spec = codec->spec; | 3492 | struct alc_spec *spec = codec->spec; |
3493 | static const struct hda_verb gpio_init[] = { | 3493 | static const struct hda_verb gpio_init[] = { |
3494 | { 0x01, AC_VERB_SET_GPIO_MASK, 0x18 }, | 3494 | { 0x01, AC_VERB_SET_GPIO_MASK, 0x18 }, |
3495 | { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x18 }, | 3495 | { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x18 }, |
3496 | {} | 3496 | {} |
3497 | }; | 3497 | }; |
3498 | 3498 | ||
3499 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | 3499 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
3500 | spec->gen.vmaster_mute.hook = alc269_fixup_hp_gpio_mute_hook; | 3500 | spec->gen.vmaster_mute.hook = alc269_fixup_hp_gpio_mute_hook; |
3501 | spec->gen.cap_sync_hook = alc269_fixup_hp_gpio_mic_mute_hook; | 3501 | spec->gen.cap_sync_hook = alc269_fixup_hp_gpio_mic_mute_hook; |
3502 | spec->gpio_led = 0; | 3502 | spec->gpio_led = 0; |
3503 | snd_hda_add_verbs(codec, gpio_init); | 3503 | snd_hda_add_verbs(codec, gpio_init); |
3504 | } | 3504 | } |
3505 | } | 3505 | } |
3506 | 3506 | ||
3507 | static void alc_headset_mode_unplugged(struct hda_codec *codec) | 3507 | static void alc_headset_mode_unplugged(struct hda_codec *codec) |
3508 | { | 3508 | { |
3509 | int val; | 3509 | int val; |
3510 | 3510 | ||
3511 | switch (codec->vendor_id) { | 3511 | switch (codec->vendor_id) { |
3512 | case 0x10ec0255: | 3512 | case 0x10ec0255: |
3513 | /* LDO and MISC control */ | 3513 | /* LDO and MISC control */ |
3514 | alc_write_coef_idx(codec, 0x1b, 0x0c0b); | 3514 | alc_write_coef_idx(codec, 0x1b, 0x0c0b); |
3515 | /* UAJ function set to menual mode */ | 3515 | /* UAJ function set to menual mode */ |
3516 | alc_write_coef_idx(codec, 0x45, 0xd089); | 3516 | alc_write_coef_idx(codec, 0x45, 0xd089); |
3517 | /* Direct Drive HP Amp control(Set to verb control)*/ | 3517 | /* Direct Drive HP Amp control(Set to verb control)*/ |
3518 | val = alc_read_coefex_idx(codec, 0x57, 0x05); | 3518 | val = alc_read_coefex_idx(codec, 0x57, 0x05); |
3519 | alc_write_coefex_idx(codec, 0x57, 0x05, val & ~(1<<14)); | 3519 | alc_write_coefex_idx(codec, 0x57, 0x05, val & ~(1<<14)); |
3520 | /* Set MIC2 Vref gate with HP */ | 3520 | /* Set MIC2 Vref gate with HP */ |
3521 | alc_write_coef_idx(codec, 0x06, 0x6104); | 3521 | alc_write_coef_idx(codec, 0x06, 0x6104); |
3522 | /* Direct Drive HP Amp control */ | 3522 | /* Direct Drive HP Amp control */ |
3523 | alc_write_coefex_idx(codec, 0x57, 0x03, 0x8aa6); | 3523 | alc_write_coefex_idx(codec, 0x57, 0x03, 0x8aa6); |
3524 | break; | 3524 | break; |
3525 | case 0x10ec0283: | 3525 | case 0x10ec0283: |
3526 | alc_write_coef_idx(codec, 0x1b, 0x0c0b); | 3526 | alc_write_coef_idx(codec, 0x1b, 0x0c0b); |
3527 | alc_write_coef_idx(codec, 0x45, 0xc429); | 3527 | alc_write_coef_idx(codec, 0x45, 0xc429); |
3528 | val = alc_read_coef_idx(codec, 0x35); | 3528 | val = alc_read_coef_idx(codec, 0x35); |
3529 | alc_write_coef_idx(codec, 0x35, val & 0xbfff); | 3529 | alc_write_coef_idx(codec, 0x35, val & 0xbfff); |
3530 | alc_write_coef_idx(codec, 0x06, 0x2104); | 3530 | alc_write_coef_idx(codec, 0x06, 0x2104); |
3531 | alc_write_coef_idx(codec, 0x1a, 0x0001); | 3531 | alc_write_coef_idx(codec, 0x1a, 0x0001); |
3532 | alc_write_coef_idx(codec, 0x26, 0x0004); | 3532 | alc_write_coef_idx(codec, 0x26, 0x0004); |
3533 | alc_write_coef_idx(codec, 0x32, 0x42a3); | 3533 | alc_write_coef_idx(codec, 0x32, 0x42a3); |
3534 | break; | 3534 | break; |
3535 | case 0x10ec0292: | 3535 | case 0x10ec0292: |
3536 | alc_write_coef_idx(codec, 0x76, 0x000e); | 3536 | alc_write_coef_idx(codec, 0x76, 0x000e); |
3537 | alc_write_coef_idx(codec, 0x6c, 0x2400); | 3537 | alc_write_coef_idx(codec, 0x6c, 0x2400); |
3538 | alc_write_coef_idx(codec, 0x18, 0x7308); | 3538 | alc_write_coef_idx(codec, 0x18, 0x7308); |
3539 | alc_write_coef_idx(codec, 0x6b, 0xc429); | 3539 | alc_write_coef_idx(codec, 0x6b, 0xc429); |
3540 | break; | 3540 | break; |
3541 | case 0x10ec0668: | 3541 | case 0x10ec0668: |
3542 | alc_write_coef_idx(codec, 0x15, 0x0d40); | 3542 | alc_write_coef_idx(codec, 0x15, 0x0d40); |
3543 | alc_write_coef_idx(codec, 0xb7, 0x802b); | 3543 | alc_write_coef_idx(codec, 0xb7, 0x802b); |
3544 | break; | 3544 | break; |
3545 | } | 3545 | } |
3546 | codec_dbg(codec, "Headset jack set to unplugged mode.\n"); | 3546 | codec_dbg(codec, "Headset jack set to unplugged mode.\n"); |
3547 | } | 3547 | } |
3548 | 3548 | ||
3549 | 3549 | ||
3550 | static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin, | 3550 | static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin, |
3551 | hda_nid_t mic_pin) | 3551 | hda_nid_t mic_pin) |
3552 | { | 3552 | { |
3553 | int val; | 3553 | int val; |
3554 | 3554 | ||
3555 | switch (codec->vendor_id) { | 3555 | switch (codec->vendor_id) { |
3556 | case 0x10ec0255: | 3556 | case 0x10ec0255: |
3557 | alc_write_coef_idx(codec, 0x45, 0xc489); | 3557 | alc_write_coef_idx(codec, 0x45, 0xc489); |
3558 | snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); | 3558 | snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); |
3559 | alc_write_coefex_idx(codec, 0x57, 0x03, 0x8aa6); | 3559 | alc_write_coefex_idx(codec, 0x57, 0x03, 0x8aa6); |
3560 | /* Set MIC2 Vref gate to normal */ | 3560 | /* Set MIC2 Vref gate to normal */ |
3561 | alc_write_coef_idx(codec, 0x06, 0x6100); | 3561 | alc_write_coef_idx(codec, 0x06, 0x6100); |
3562 | snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); | 3562 | snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); |
3563 | break; | 3563 | break; |
3564 | case 0x10ec0283: | 3564 | case 0x10ec0283: |
3565 | alc_write_coef_idx(codec, 0x45, 0xc429); | 3565 | alc_write_coef_idx(codec, 0x45, 0xc429); |
3566 | snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); | 3566 | snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); |
3567 | val = alc_read_coef_idx(codec, 0x35); | 3567 | val = alc_read_coef_idx(codec, 0x35); |
3568 | alc_write_coef_idx(codec, 0x35, val | 1<<14); | 3568 | alc_write_coef_idx(codec, 0x35, val | 1<<14); |
3569 | alc_write_coef_idx(codec, 0x06, 0x2100); | 3569 | alc_write_coef_idx(codec, 0x06, 0x2100); |
3570 | alc_write_coef_idx(codec, 0x1a, 0x0021); | 3570 | alc_write_coef_idx(codec, 0x1a, 0x0021); |
3571 | alc_write_coef_idx(codec, 0x26, 0x008c); | 3571 | alc_write_coef_idx(codec, 0x26, 0x008c); |
3572 | snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); | 3572 | snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); |
3573 | break; | 3573 | break; |
3574 | case 0x10ec0292: | 3574 | case 0x10ec0292: |
3575 | snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); | 3575 | snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); |
3576 | alc_write_coef_idx(codec, 0x19, 0xa208); | 3576 | alc_write_coef_idx(codec, 0x19, 0xa208); |
3577 | alc_write_coef_idx(codec, 0x2e, 0xacf0); | 3577 | alc_write_coef_idx(codec, 0x2e, 0xacf0); |
3578 | break; | 3578 | break; |
3579 | case 0x10ec0668: | 3579 | case 0x10ec0668: |
3580 | alc_write_coef_idx(codec, 0x11, 0x0001); | 3580 | alc_write_coef_idx(codec, 0x11, 0x0001); |
3581 | snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); | 3581 | snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); |
3582 | alc_write_coef_idx(codec, 0xb7, 0x802b); | 3582 | alc_write_coef_idx(codec, 0xb7, 0x802b); |
3583 | alc_write_coef_idx(codec, 0xb5, 0x1040); | 3583 | alc_write_coef_idx(codec, 0xb5, 0x1040); |
3584 | val = alc_read_coef_idx(codec, 0xc3); | 3584 | val = alc_read_coef_idx(codec, 0xc3); |
3585 | alc_write_coef_idx(codec, 0xc3, val | 1<<12); | 3585 | alc_write_coef_idx(codec, 0xc3, val | 1<<12); |
3586 | snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); | 3586 | snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); |
3587 | break; | 3587 | break; |
3588 | } | 3588 | } |
3589 | codec_dbg(codec, "Headset jack set to mic-in mode.\n"); | 3589 | codec_dbg(codec, "Headset jack set to mic-in mode.\n"); |
3590 | } | 3590 | } |
3591 | 3591 | ||
3592 | static void alc_headset_mode_default(struct hda_codec *codec) | 3592 | static void alc_headset_mode_default(struct hda_codec *codec) |
3593 | { | 3593 | { |
3594 | switch (codec->vendor_id) { | 3594 | switch (codec->vendor_id) { |
3595 | case 0x10ec0255: | 3595 | case 0x10ec0255: |
3596 | alc_write_coef_idx(codec, 0x45, 0xc089); | 3596 | alc_write_coef_idx(codec, 0x45, 0xc089); |
3597 | alc_write_coef_idx(codec, 0x45, 0xc489); | 3597 | alc_write_coef_idx(codec, 0x45, 0xc489); |
3598 | alc_write_coefex_idx(codec, 0x57, 0x03, 0x8ea6); | 3598 | alc_write_coefex_idx(codec, 0x57, 0x03, 0x8ea6); |
3599 | alc_write_coef_idx(codec, 0x49, 0x0049); | 3599 | alc_write_coef_idx(codec, 0x49, 0x0049); |
3600 | break; | 3600 | break; |
3601 | case 0x10ec0283: | 3601 | case 0x10ec0283: |
3602 | alc_write_coef_idx(codec, 0x06, 0x2100); | 3602 | alc_write_coef_idx(codec, 0x06, 0x2100); |
3603 | alc_write_coef_idx(codec, 0x32, 0x4ea3); | 3603 | alc_write_coef_idx(codec, 0x32, 0x4ea3); |
3604 | break; | 3604 | break; |
3605 | case 0x10ec0292: | 3605 | case 0x10ec0292: |
3606 | alc_write_coef_idx(codec, 0x76, 0x000e); | 3606 | alc_write_coef_idx(codec, 0x76, 0x000e); |
3607 | alc_write_coef_idx(codec, 0x6c, 0x2400); | 3607 | alc_write_coef_idx(codec, 0x6c, 0x2400); |
3608 | alc_write_coef_idx(codec, 0x6b, 0xc429); | 3608 | alc_write_coef_idx(codec, 0x6b, 0xc429); |
3609 | alc_write_coef_idx(codec, 0x18, 0x7308); | 3609 | alc_write_coef_idx(codec, 0x18, 0x7308); |
3610 | break; | 3610 | break; |
3611 | case 0x10ec0668: | 3611 | case 0x10ec0668: |
3612 | alc_write_coef_idx(codec, 0x11, 0x0041); | 3612 | alc_write_coef_idx(codec, 0x11, 0x0041); |
3613 | alc_write_coef_idx(codec, 0x15, 0x0d40); | 3613 | alc_write_coef_idx(codec, 0x15, 0x0d40); |
3614 | alc_write_coef_idx(codec, 0xb7, 0x802b); | 3614 | alc_write_coef_idx(codec, 0xb7, 0x802b); |
3615 | break; | 3615 | break; |
3616 | } | 3616 | } |
3617 | codec_dbg(codec, "Headset jack set to headphone (default) mode.\n"); | 3617 | codec_dbg(codec, "Headset jack set to headphone (default) mode.\n"); |
3618 | } | 3618 | } |
3619 | 3619 | ||
3620 | /* Iphone type */ | 3620 | /* Iphone type */ |
3621 | static void alc_headset_mode_ctia(struct hda_codec *codec) | 3621 | static void alc_headset_mode_ctia(struct hda_codec *codec) |
3622 | { | 3622 | { |
3623 | switch (codec->vendor_id) { | 3623 | switch (codec->vendor_id) { |
3624 | case 0x10ec0255: | 3624 | case 0x10ec0255: |
3625 | /* Set to CTIA type */ | 3625 | /* Set to CTIA type */ |
3626 | alc_write_coef_idx(codec, 0x45, 0xd489); | 3626 | alc_write_coef_idx(codec, 0x45, 0xd489); |
3627 | alc_write_coef_idx(codec, 0x1b, 0x0c2b); | 3627 | alc_write_coef_idx(codec, 0x1b, 0x0c2b); |
3628 | alc_write_coefex_idx(codec, 0x57, 0x03, 0x8ea6); | 3628 | alc_write_coefex_idx(codec, 0x57, 0x03, 0x8ea6); |
3629 | break; | 3629 | break; |
3630 | case 0x10ec0283: | 3630 | case 0x10ec0283: |
3631 | alc_write_coef_idx(codec, 0x45, 0xd429); | 3631 | alc_write_coef_idx(codec, 0x45, 0xd429); |
3632 | alc_write_coef_idx(codec, 0x1b, 0x0c2b); | 3632 | alc_write_coef_idx(codec, 0x1b, 0x0c2b); |
3633 | alc_write_coef_idx(codec, 0x32, 0x4ea3); | 3633 | alc_write_coef_idx(codec, 0x32, 0x4ea3); |
3634 | break; | 3634 | break; |
3635 | case 0x10ec0292: | 3635 | case 0x10ec0292: |
3636 | alc_write_coef_idx(codec, 0x6b, 0xd429); | 3636 | alc_write_coef_idx(codec, 0x6b, 0xd429); |
3637 | alc_write_coef_idx(codec, 0x76, 0x0008); | 3637 | alc_write_coef_idx(codec, 0x76, 0x0008); |
3638 | alc_write_coef_idx(codec, 0x18, 0x7388); | 3638 | alc_write_coef_idx(codec, 0x18, 0x7388); |
3639 | break; | 3639 | break; |
3640 | case 0x10ec0668: | 3640 | case 0x10ec0668: |
3641 | alc_write_coef_idx(codec, 0x11, 0x0001); | 3641 | alc_write_coef_idx(codec, 0x11, 0x0001); |
3642 | alc_write_coef_idx(codec, 0x15, 0x0d60); | 3642 | alc_write_coef_idx(codec, 0x15, 0x0d60); |
3643 | alc_write_coef_idx(codec, 0xc3, 0x0000); | 3643 | alc_write_coef_idx(codec, 0xc3, 0x0000); |
3644 | break; | 3644 | break; |
3645 | } | 3645 | } |
3646 | codec_dbg(codec, "Headset jack set to iPhone-style headset mode.\n"); | 3646 | codec_dbg(codec, "Headset jack set to iPhone-style headset mode.\n"); |
3647 | } | 3647 | } |
3648 | 3648 | ||
3649 | /* Nokia type */ | 3649 | /* Nokia type */ |
3650 | static void alc_headset_mode_omtp(struct hda_codec *codec) | 3650 | static void alc_headset_mode_omtp(struct hda_codec *codec) |
3651 | { | 3651 | { |
3652 | switch (codec->vendor_id) { | 3652 | switch (codec->vendor_id) { |
3653 | case 0x10ec0255: | 3653 | case 0x10ec0255: |
3654 | /* Set to OMTP Type */ | 3654 | /* Set to OMTP Type */ |
3655 | alc_write_coef_idx(codec, 0x45, 0xe489); | 3655 | alc_write_coef_idx(codec, 0x45, 0xe489); |
3656 | alc_write_coef_idx(codec, 0x1b, 0x0c2b); | 3656 | alc_write_coef_idx(codec, 0x1b, 0x0c2b); |
3657 | alc_write_coefex_idx(codec, 0x57, 0x03, 0x8ea6); | 3657 | alc_write_coefex_idx(codec, 0x57, 0x03, 0x8ea6); |
3658 | break; | 3658 | break; |
3659 | case 0x10ec0283: | 3659 | case 0x10ec0283: |
3660 | alc_write_coef_idx(codec, 0x45, 0xe429); | 3660 | alc_write_coef_idx(codec, 0x45, 0xe429); |
3661 | alc_write_coef_idx(codec, 0x1b, 0x0c2b); | 3661 | alc_write_coef_idx(codec, 0x1b, 0x0c2b); |
3662 | alc_write_coef_idx(codec, 0x32, 0x4ea3); | 3662 | alc_write_coef_idx(codec, 0x32, 0x4ea3); |
3663 | break; | 3663 | break; |
3664 | case 0x10ec0292: | 3664 | case 0x10ec0292: |
3665 | alc_write_coef_idx(codec, 0x6b, 0xe429); | 3665 | alc_write_coef_idx(codec, 0x6b, 0xe429); |
3666 | alc_write_coef_idx(codec, 0x76, 0x0008); | 3666 | alc_write_coef_idx(codec, 0x76, 0x0008); |
3667 | alc_write_coef_idx(codec, 0x18, 0x7388); | 3667 | alc_write_coef_idx(codec, 0x18, 0x7388); |
3668 | break; | 3668 | break; |
3669 | case 0x10ec0668: | 3669 | case 0x10ec0668: |
3670 | alc_write_coef_idx(codec, 0x11, 0x0001); | 3670 | alc_write_coef_idx(codec, 0x11, 0x0001); |
3671 | alc_write_coef_idx(codec, 0x15, 0x0d50); | 3671 | alc_write_coef_idx(codec, 0x15, 0x0d50); |
3672 | alc_write_coef_idx(codec, 0xc3, 0x0000); | 3672 | alc_write_coef_idx(codec, 0xc3, 0x0000); |
3673 | break; | 3673 | break; |
3674 | } | 3674 | } |
3675 | codec_dbg(codec, "Headset jack set to Nokia-style headset mode.\n"); | 3675 | codec_dbg(codec, "Headset jack set to Nokia-style headset mode.\n"); |
3676 | } | 3676 | } |
3677 | 3677 | ||
3678 | static void alc_determine_headset_type(struct hda_codec *codec) | 3678 | static void alc_determine_headset_type(struct hda_codec *codec) |
3679 | { | 3679 | { |
3680 | int val; | 3680 | int val; |
3681 | bool is_ctia = false; | 3681 | bool is_ctia = false; |
3682 | struct alc_spec *spec = codec->spec; | 3682 | struct alc_spec *spec = codec->spec; |
3683 | 3683 | ||
3684 | switch (codec->vendor_id) { | 3684 | switch (codec->vendor_id) { |
3685 | case 0x10ec0255: | 3685 | case 0x10ec0255: |
3686 | /* combo jack auto switch control(Check type)*/ | 3686 | /* combo jack auto switch control(Check type)*/ |
3687 | alc_write_coef_idx(codec, 0x45, 0xd089); | 3687 | alc_write_coef_idx(codec, 0x45, 0xd089); |
3688 | /* combo jack auto switch control(Vref conteol) */ | 3688 | /* combo jack auto switch control(Vref conteol) */ |
3689 | alc_write_coef_idx(codec, 0x49, 0x0149); | 3689 | alc_write_coef_idx(codec, 0x49, 0x0149); |
3690 | msleep(300); | 3690 | msleep(300); |
3691 | val = alc_read_coef_idx(codec, 0x46); | 3691 | val = alc_read_coef_idx(codec, 0x46); |
3692 | is_ctia = (val & 0x0070) == 0x0070; | 3692 | is_ctia = (val & 0x0070) == 0x0070; |
3693 | break; | 3693 | break; |
3694 | case 0x10ec0283: | 3694 | case 0x10ec0283: |
3695 | alc_write_coef_idx(codec, 0x45, 0xd029); | 3695 | alc_write_coef_idx(codec, 0x45, 0xd029); |
3696 | msleep(300); | 3696 | msleep(300); |
3697 | val = alc_read_coef_idx(codec, 0x46); | 3697 | val = alc_read_coef_idx(codec, 0x46); |
3698 | is_ctia = (val & 0x0070) == 0x0070; | 3698 | is_ctia = (val & 0x0070) == 0x0070; |
3699 | break; | 3699 | break; |
3700 | case 0x10ec0292: | 3700 | case 0x10ec0292: |
3701 | alc_write_coef_idx(codec, 0x6b, 0xd429); | 3701 | alc_write_coef_idx(codec, 0x6b, 0xd429); |
3702 | msleep(300); | 3702 | msleep(300); |
3703 | val = alc_read_coef_idx(codec, 0x6c); | 3703 | val = alc_read_coef_idx(codec, 0x6c); |
3704 | is_ctia = (val & 0x001c) == 0x001c; | 3704 | is_ctia = (val & 0x001c) == 0x001c; |
3705 | break; | 3705 | break; |
3706 | case 0x10ec0668: | 3706 | case 0x10ec0668: |
3707 | alc_write_coef_idx(codec, 0x11, 0x0001); | 3707 | alc_write_coef_idx(codec, 0x11, 0x0001); |
3708 | alc_write_coef_idx(codec, 0xb7, 0x802b); | 3708 | alc_write_coef_idx(codec, 0xb7, 0x802b); |
3709 | alc_write_coef_idx(codec, 0x15, 0x0d60); | 3709 | alc_write_coef_idx(codec, 0x15, 0x0d60); |
3710 | alc_write_coef_idx(codec, 0xc3, 0x0c00); | 3710 | alc_write_coef_idx(codec, 0xc3, 0x0c00); |
3711 | msleep(300); | 3711 | msleep(300); |
3712 | val = alc_read_coef_idx(codec, 0xbe); | 3712 | val = alc_read_coef_idx(codec, 0xbe); |
3713 | is_ctia = (val & 0x1c02) == 0x1c02; | 3713 | is_ctia = (val & 0x1c02) == 0x1c02; |
3714 | break; | 3714 | break; |
3715 | } | 3715 | } |
3716 | 3716 | ||
3717 | codec_dbg(codec, "Headset jack detected iPhone-style headset: %s\n", | 3717 | codec_dbg(codec, "Headset jack detected iPhone-style headset: %s\n", |
3718 | is_ctia ? "yes" : "no"); | 3718 | is_ctia ? "yes" : "no"); |
3719 | spec->current_headset_type = is_ctia ? ALC_HEADSET_TYPE_CTIA : ALC_HEADSET_TYPE_OMTP; | 3719 | spec->current_headset_type = is_ctia ? ALC_HEADSET_TYPE_CTIA : ALC_HEADSET_TYPE_OMTP; |
3720 | } | 3720 | } |
3721 | 3721 | ||
3722 | static void alc_update_headset_mode(struct hda_codec *codec) | 3722 | static void alc_update_headset_mode(struct hda_codec *codec) |
3723 | { | 3723 | { |
3724 | struct alc_spec *spec = codec->spec; | 3724 | struct alc_spec *spec = codec->spec; |
3725 | 3725 | ||
3726 | hda_nid_t mux_pin = spec->gen.imux_pins[spec->gen.cur_mux[0]]; | 3726 | hda_nid_t mux_pin = spec->gen.imux_pins[spec->gen.cur_mux[0]]; |
3727 | hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; | 3727 | hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; |
3728 | 3728 | ||
3729 | int new_headset_mode; | 3729 | int new_headset_mode; |
3730 | 3730 | ||
3731 | if (!snd_hda_jack_detect(codec, hp_pin)) | 3731 | if (!snd_hda_jack_detect(codec, hp_pin)) |
3732 | new_headset_mode = ALC_HEADSET_MODE_UNPLUGGED; | 3732 | new_headset_mode = ALC_HEADSET_MODE_UNPLUGGED; |
3733 | else if (mux_pin == spec->headset_mic_pin) | 3733 | else if (mux_pin == spec->headset_mic_pin) |
3734 | new_headset_mode = ALC_HEADSET_MODE_HEADSET; | 3734 | new_headset_mode = ALC_HEADSET_MODE_HEADSET; |
3735 | else if (mux_pin == spec->headphone_mic_pin) | 3735 | else if (mux_pin == spec->headphone_mic_pin) |
3736 | new_headset_mode = ALC_HEADSET_MODE_MIC; | 3736 | new_headset_mode = ALC_HEADSET_MODE_MIC; |
3737 | else | 3737 | else |
3738 | new_headset_mode = ALC_HEADSET_MODE_HEADPHONE; | 3738 | new_headset_mode = ALC_HEADSET_MODE_HEADPHONE; |
3739 | 3739 | ||
3740 | if (new_headset_mode == spec->current_headset_mode) { | 3740 | if (new_headset_mode == spec->current_headset_mode) { |
3741 | snd_hda_gen_update_outputs(codec); | 3741 | snd_hda_gen_update_outputs(codec); |
3742 | return; | 3742 | return; |
3743 | } | 3743 | } |
3744 | 3744 | ||
3745 | switch (new_headset_mode) { | 3745 | switch (new_headset_mode) { |
3746 | case ALC_HEADSET_MODE_UNPLUGGED: | 3746 | case ALC_HEADSET_MODE_UNPLUGGED: |
3747 | alc_headset_mode_unplugged(codec); | 3747 | alc_headset_mode_unplugged(codec); |
3748 | spec->gen.hp_jack_present = false; | 3748 | spec->gen.hp_jack_present = false; |
3749 | break; | 3749 | break; |
3750 | case ALC_HEADSET_MODE_HEADSET: | 3750 | case ALC_HEADSET_MODE_HEADSET: |
3751 | if (spec->current_headset_type == ALC_HEADSET_TYPE_UNKNOWN) | 3751 | if (spec->current_headset_type == ALC_HEADSET_TYPE_UNKNOWN) |
3752 | alc_determine_headset_type(codec); | 3752 | alc_determine_headset_type(codec); |
3753 | if (spec->current_headset_type == ALC_HEADSET_TYPE_CTIA) | 3753 | if (spec->current_headset_type == ALC_HEADSET_TYPE_CTIA) |
3754 | alc_headset_mode_ctia(codec); | 3754 | alc_headset_mode_ctia(codec); |
3755 | else if (spec->current_headset_type == ALC_HEADSET_TYPE_OMTP) | 3755 | else if (spec->current_headset_type == ALC_HEADSET_TYPE_OMTP) |
3756 | alc_headset_mode_omtp(codec); | 3756 | alc_headset_mode_omtp(codec); |
3757 | spec->gen.hp_jack_present = true; | 3757 | spec->gen.hp_jack_present = true; |
3758 | break; | 3758 | break; |
3759 | case ALC_HEADSET_MODE_MIC: | 3759 | case ALC_HEADSET_MODE_MIC: |
3760 | alc_headset_mode_mic_in(codec, hp_pin, spec->headphone_mic_pin); | 3760 | alc_headset_mode_mic_in(codec, hp_pin, spec->headphone_mic_pin); |
3761 | spec->gen.hp_jack_present = false; | 3761 | spec->gen.hp_jack_present = false; |
3762 | break; | 3762 | break; |
3763 | case ALC_HEADSET_MODE_HEADPHONE: | 3763 | case ALC_HEADSET_MODE_HEADPHONE: |
3764 | alc_headset_mode_default(codec); | 3764 | alc_headset_mode_default(codec); |
3765 | spec->gen.hp_jack_present = true; | 3765 | spec->gen.hp_jack_present = true; |
3766 | break; | 3766 | break; |
3767 | } | 3767 | } |
3768 | if (new_headset_mode != ALC_HEADSET_MODE_MIC) { | 3768 | if (new_headset_mode != ALC_HEADSET_MODE_MIC) { |
3769 | snd_hda_set_pin_ctl_cache(codec, hp_pin, | 3769 | snd_hda_set_pin_ctl_cache(codec, hp_pin, |
3770 | AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN); | 3770 | AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN); |
3771 | if (spec->headphone_mic_pin) | 3771 | if (spec->headphone_mic_pin) |
3772 | snd_hda_set_pin_ctl_cache(codec, spec->headphone_mic_pin, | 3772 | snd_hda_set_pin_ctl_cache(codec, spec->headphone_mic_pin, |
3773 | PIN_VREFHIZ); | 3773 | PIN_VREFHIZ); |
3774 | } | 3774 | } |
3775 | spec->current_headset_mode = new_headset_mode; | 3775 | spec->current_headset_mode = new_headset_mode; |
3776 | 3776 | ||
3777 | snd_hda_gen_update_outputs(codec); | 3777 | snd_hda_gen_update_outputs(codec); |
3778 | } | 3778 | } |
3779 | 3779 | ||
3780 | static void alc_update_headset_mode_hook(struct hda_codec *codec, | 3780 | static void alc_update_headset_mode_hook(struct hda_codec *codec, |
3781 | struct snd_kcontrol *kcontrol, | 3781 | struct snd_kcontrol *kcontrol, |
3782 | struct snd_ctl_elem_value *ucontrol) | 3782 | struct snd_ctl_elem_value *ucontrol) |
3783 | { | 3783 | { |
3784 | alc_update_headset_mode(codec); | 3784 | alc_update_headset_mode(codec); |
3785 | } | 3785 | } |
3786 | 3786 | ||
3787 | static void alc_update_headset_jack_cb(struct hda_codec *codec, struct hda_jack_tbl *jack) | 3787 | static void alc_update_headset_jack_cb(struct hda_codec *codec, struct hda_jack_tbl *jack) |
3788 | { | 3788 | { |
3789 | struct alc_spec *spec = codec->spec; | 3789 | struct alc_spec *spec = codec->spec; |
3790 | spec->current_headset_type = ALC_HEADSET_TYPE_UNKNOWN; | 3790 | spec->current_headset_type = ALC_HEADSET_TYPE_UNKNOWN; |
3791 | snd_hda_gen_hp_automute(codec, jack); | 3791 | snd_hda_gen_hp_automute(codec, jack); |
3792 | } | 3792 | } |
3793 | 3793 | ||
3794 | static void alc_probe_headset_mode(struct hda_codec *codec) | 3794 | static void alc_probe_headset_mode(struct hda_codec *codec) |
3795 | { | 3795 | { |
3796 | int i; | 3796 | int i; |
3797 | struct alc_spec *spec = codec->spec; | 3797 | struct alc_spec *spec = codec->spec; |
3798 | struct auto_pin_cfg *cfg = &spec->gen.autocfg; | 3798 | struct auto_pin_cfg *cfg = &spec->gen.autocfg; |
3799 | 3799 | ||
3800 | /* Find mic pins */ | 3800 | /* Find mic pins */ |
3801 | for (i = 0; i < cfg->num_inputs; i++) { | 3801 | for (i = 0; i < cfg->num_inputs; i++) { |
3802 | if (cfg->inputs[i].is_headset_mic && !spec->headset_mic_pin) | 3802 | if (cfg->inputs[i].is_headset_mic && !spec->headset_mic_pin) |
3803 | spec->headset_mic_pin = cfg->inputs[i].pin; | 3803 | spec->headset_mic_pin = cfg->inputs[i].pin; |
3804 | if (cfg->inputs[i].is_headphone_mic && !spec->headphone_mic_pin) | 3804 | if (cfg->inputs[i].is_headphone_mic && !spec->headphone_mic_pin) |
3805 | spec->headphone_mic_pin = cfg->inputs[i].pin; | 3805 | spec->headphone_mic_pin = cfg->inputs[i].pin; |
3806 | } | 3806 | } |
3807 | 3807 | ||
3808 | spec->gen.cap_sync_hook = alc_update_headset_mode_hook; | 3808 | spec->gen.cap_sync_hook = alc_update_headset_mode_hook; |
3809 | spec->gen.automute_hook = alc_update_headset_mode; | 3809 | spec->gen.automute_hook = alc_update_headset_mode; |
3810 | spec->gen.hp_automute_hook = alc_update_headset_jack_cb; | 3810 | spec->gen.hp_automute_hook = alc_update_headset_jack_cb; |
3811 | } | 3811 | } |
3812 | 3812 | ||
3813 | static void alc_fixup_headset_mode(struct hda_codec *codec, | 3813 | static void alc_fixup_headset_mode(struct hda_codec *codec, |
3814 | const struct hda_fixup *fix, int action) | 3814 | const struct hda_fixup *fix, int action) |
3815 | { | 3815 | { |
3816 | struct alc_spec *spec = codec->spec; | 3816 | struct alc_spec *spec = codec->spec; |
3817 | 3817 | ||
3818 | switch (action) { | 3818 | switch (action) { |
3819 | case HDA_FIXUP_ACT_PRE_PROBE: | 3819 | case HDA_FIXUP_ACT_PRE_PROBE: |
3820 | spec->parse_flags |= HDA_PINCFG_HEADSET_MIC | HDA_PINCFG_HEADPHONE_MIC; | 3820 | spec->parse_flags |= HDA_PINCFG_HEADSET_MIC | HDA_PINCFG_HEADPHONE_MIC; |
3821 | break; | 3821 | break; |
3822 | case HDA_FIXUP_ACT_PROBE: | 3822 | case HDA_FIXUP_ACT_PROBE: |
3823 | alc_probe_headset_mode(codec); | 3823 | alc_probe_headset_mode(codec); |
3824 | break; | 3824 | break; |
3825 | case HDA_FIXUP_ACT_INIT: | 3825 | case HDA_FIXUP_ACT_INIT: |
3826 | spec->current_headset_mode = 0; | 3826 | spec->current_headset_mode = 0; |
3827 | alc_update_headset_mode(codec); | 3827 | alc_update_headset_mode(codec); |
3828 | break; | 3828 | break; |
3829 | } | 3829 | } |
3830 | } | 3830 | } |
3831 | 3831 | ||
3832 | static void alc_fixup_headset_mode_no_hp_mic(struct hda_codec *codec, | 3832 | static void alc_fixup_headset_mode_no_hp_mic(struct hda_codec *codec, |
3833 | const struct hda_fixup *fix, int action) | 3833 | const struct hda_fixup *fix, int action) |
3834 | { | 3834 | { |
3835 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | 3835 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
3836 | struct alc_spec *spec = codec->spec; | 3836 | struct alc_spec *spec = codec->spec; |
3837 | spec->parse_flags |= HDA_PINCFG_HEADSET_MIC; | 3837 | spec->parse_flags |= HDA_PINCFG_HEADSET_MIC; |
3838 | } | 3838 | } |
3839 | else | 3839 | else |
3840 | alc_fixup_headset_mode(codec, fix, action); | 3840 | alc_fixup_headset_mode(codec, fix, action); |
3841 | } | 3841 | } |
3842 | 3842 | ||
3843 | static void alc255_set_default_jack_type(struct hda_codec *codec) | 3843 | static void alc255_set_default_jack_type(struct hda_codec *codec) |
3844 | { | 3844 | { |
3845 | /* Set to iphone type */ | 3845 | /* Set to iphone type */ |
3846 | alc_write_coef_idx(codec, 0x1b, 0x880b); | 3846 | alc_write_coef_idx(codec, 0x1b, 0x880b); |
3847 | alc_write_coef_idx(codec, 0x45, 0xd089); | 3847 | alc_write_coef_idx(codec, 0x45, 0xd089); |
3848 | alc_write_coef_idx(codec, 0x1b, 0x080b); | 3848 | alc_write_coef_idx(codec, 0x1b, 0x080b); |
3849 | alc_write_coef_idx(codec, 0x46, 0x0004); | 3849 | alc_write_coef_idx(codec, 0x46, 0x0004); |
3850 | alc_write_coef_idx(codec, 0x1b, 0x0c0b); | 3850 | alc_write_coef_idx(codec, 0x1b, 0x0c0b); |
3851 | msleep(30); | 3851 | msleep(30); |
3852 | } | 3852 | } |
3853 | 3853 | ||
3854 | static void alc_fixup_headset_mode_alc255(struct hda_codec *codec, | 3854 | static void alc_fixup_headset_mode_alc255(struct hda_codec *codec, |
3855 | const struct hda_fixup *fix, int action) | 3855 | const struct hda_fixup *fix, int action) |
3856 | { | 3856 | { |
3857 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | 3857 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
3858 | alc255_set_default_jack_type(codec); | 3858 | alc255_set_default_jack_type(codec); |
3859 | } | 3859 | } |
3860 | alc_fixup_headset_mode(codec, fix, action); | 3860 | alc_fixup_headset_mode(codec, fix, action); |
3861 | } | 3861 | } |
3862 | 3862 | ||
3863 | static void alc_fixup_headset_mode_alc255_no_hp_mic(struct hda_codec *codec, | 3863 | static void alc_fixup_headset_mode_alc255_no_hp_mic(struct hda_codec *codec, |
3864 | const struct hda_fixup *fix, int action) | 3864 | const struct hda_fixup *fix, int action) |
3865 | { | 3865 | { |
3866 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | 3866 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
3867 | struct alc_spec *spec = codec->spec; | 3867 | struct alc_spec *spec = codec->spec; |
3868 | spec->parse_flags |= HDA_PINCFG_HEADSET_MIC; | 3868 | spec->parse_flags |= HDA_PINCFG_HEADSET_MIC; |
3869 | alc255_set_default_jack_type(codec); | 3869 | alc255_set_default_jack_type(codec); |
3870 | } | 3870 | } |
3871 | else | 3871 | else |
3872 | alc_fixup_headset_mode(codec, fix, action); | 3872 | alc_fixup_headset_mode(codec, fix, action); |
3873 | } | 3873 | } |
3874 | 3874 | ||
3875 | static void alc_fixup_auto_mute_via_amp(struct hda_codec *codec, | 3875 | static void alc_fixup_auto_mute_via_amp(struct hda_codec *codec, |
3876 | const struct hda_fixup *fix, int action) | 3876 | const struct hda_fixup *fix, int action) |
3877 | { | 3877 | { |
3878 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | 3878 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
3879 | struct alc_spec *spec = codec->spec; | 3879 | struct alc_spec *spec = codec->spec; |
3880 | spec->gen.auto_mute_via_amp = 1; | 3880 | spec->gen.auto_mute_via_amp = 1; |
3881 | } | 3881 | } |
3882 | } | 3882 | } |
3883 | 3883 | ||
3884 | static void alc_no_shutup(struct hda_codec *codec) | 3884 | static void alc_no_shutup(struct hda_codec *codec) |
3885 | { | 3885 | { |
3886 | } | 3886 | } |
3887 | 3887 | ||
3888 | static void alc_fixup_no_shutup(struct hda_codec *codec, | 3888 | static void alc_fixup_no_shutup(struct hda_codec *codec, |
3889 | const struct hda_fixup *fix, int action) | 3889 | const struct hda_fixup *fix, int action) |
3890 | { | 3890 | { |
3891 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | 3891 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
3892 | struct alc_spec *spec = codec->spec; | 3892 | struct alc_spec *spec = codec->spec; |
3893 | spec->shutup = alc_no_shutup; | 3893 | spec->shutup = alc_no_shutup; |
3894 | } | 3894 | } |
3895 | } | 3895 | } |
3896 | 3896 | ||
3897 | static void alc_fixup_headset_mode_alc668(struct hda_codec *codec, | 3897 | static void alc_fixup_headset_mode_alc668(struct hda_codec *codec, |
3898 | const struct hda_fixup *fix, int action) | 3898 | const struct hda_fixup *fix, int action) |
3899 | { | 3899 | { |
3900 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | 3900 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
3901 | int val; | 3901 | int val; |
3902 | alc_write_coef_idx(codec, 0xc4, 0x8000); | 3902 | alc_write_coef_idx(codec, 0xc4, 0x8000); |
3903 | val = alc_read_coef_idx(codec, 0xc2); | 3903 | val = alc_read_coef_idx(codec, 0xc2); |
3904 | alc_write_coef_idx(codec, 0xc2, val & 0xfe); | 3904 | alc_write_coef_idx(codec, 0xc2, val & 0xfe); |
3905 | snd_hda_set_pin_ctl_cache(codec, 0x18, 0); | 3905 | snd_hda_set_pin_ctl_cache(codec, 0x18, 0); |
3906 | } | 3906 | } |
3907 | alc_fixup_headset_mode(codec, fix, action); | 3907 | alc_fixup_headset_mode(codec, fix, action); |
3908 | } | 3908 | } |
3909 | 3909 | ||
3910 | /* Returns the nid of the external mic input pin, or 0 if it cannot be found. */ | 3910 | /* Returns the nid of the external mic input pin, or 0 if it cannot be found. */ |
3911 | static int find_ext_mic_pin(struct hda_codec *codec) | 3911 | static int find_ext_mic_pin(struct hda_codec *codec) |
3912 | { | 3912 | { |
3913 | struct alc_spec *spec = codec->spec; | 3913 | struct alc_spec *spec = codec->spec; |
3914 | struct auto_pin_cfg *cfg = &spec->gen.autocfg; | 3914 | struct auto_pin_cfg *cfg = &spec->gen.autocfg; |
3915 | hda_nid_t nid; | 3915 | hda_nid_t nid; |
3916 | unsigned int defcfg; | 3916 | unsigned int defcfg; |
3917 | int i; | 3917 | int i; |
3918 | 3918 | ||
3919 | for (i = 0; i < cfg->num_inputs; i++) { | 3919 | for (i = 0; i < cfg->num_inputs; i++) { |
3920 | if (cfg->inputs[i].type != AUTO_PIN_MIC) | 3920 | if (cfg->inputs[i].type != AUTO_PIN_MIC) |
3921 | continue; | 3921 | continue; |
3922 | nid = cfg->inputs[i].pin; | 3922 | nid = cfg->inputs[i].pin; |
3923 | defcfg = snd_hda_codec_get_pincfg(codec, nid); | 3923 | defcfg = snd_hda_codec_get_pincfg(codec, nid); |
3924 | if (snd_hda_get_input_pin_attr(defcfg) == INPUT_PIN_ATTR_INT) | 3924 | if (snd_hda_get_input_pin_attr(defcfg) == INPUT_PIN_ATTR_INT) |
3925 | continue; | 3925 | continue; |
3926 | return nid; | 3926 | return nid; |
3927 | } | 3927 | } |
3928 | 3928 | ||
3929 | return 0; | 3929 | return 0; |
3930 | } | 3930 | } |
3931 | 3931 | ||
3932 | static void alc271_hp_gate_mic_jack(struct hda_codec *codec, | 3932 | static void alc271_hp_gate_mic_jack(struct hda_codec *codec, |
3933 | const struct hda_fixup *fix, | 3933 | const struct hda_fixup *fix, |
3934 | int action) | 3934 | int action) |
3935 | { | 3935 | { |
3936 | struct alc_spec *spec = codec->spec; | 3936 | struct alc_spec *spec = codec->spec; |
3937 | 3937 | ||
3938 | if (action == HDA_FIXUP_ACT_PROBE) { | 3938 | if (action == HDA_FIXUP_ACT_PROBE) { |
3939 | int mic_pin = find_ext_mic_pin(codec); | 3939 | int mic_pin = find_ext_mic_pin(codec); |
3940 | int hp_pin = spec->gen.autocfg.hp_pins[0]; | 3940 | int hp_pin = spec->gen.autocfg.hp_pins[0]; |
3941 | 3941 | ||
3942 | if (snd_BUG_ON(!mic_pin || !hp_pin)) | 3942 | if (snd_BUG_ON(!mic_pin || !hp_pin)) |
3943 | return; | 3943 | return; |
3944 | snd_hda_jack_set_gating_jack(codec, mic_pin, hp_pin); | 3944 | snd_hda_jack_set_gating_jack(codec, mic_pin, hp_pin); |
3945 | } | 3945 | } |
3946 | } | 3946 | } |
3947 | 3947 | ||
3948 | static void alc269_fixup_limit_int_mic_boost(struct hda_codec *codec, | 3948 | static void alc269_fixup_limit_int_mic_boost(struct hda_codec *codec, |
3949 | const struct hda_fixup *fix, | 3949 | const struct hda_fixup *fix, |
3950 | int action) | 3950 | int action) |
3951 | { | 3951 | { |
3952 | struct alc_spec *spec = codec->spec; | 3952 | struct alc_spec *spec = codec->spec; |
3953 | struct auto_pin_cfg *cfg = &spec->gen.autocfg; | 3953 | struct auto_pin_cfg *cfg = &spec->gen.autocfg; |
3954 | int i; | 3954 | int i; |
3955 | 3955 | ||
3956 | /* The mic boosts on level 2 and 3 are too noisy | 3956 | /* The mic boosts on level 2 and 3 are too noisy |
3957 | on the internal mic input. | 3957 | on the internal mic input. |
3958 | Therefore limit the boost to 0 or 1. */ | 3958 | Therefore limit the boost to 0 or 1. */ |
3959 | 3959 | ||
3960 | if (action != HDA_FIXUP_ACT_PROBE) | 3960 | if (action != HDA_FIXUP_ACT_PROBE) |
3961 | return; | 3961 | return; |
3962 | 3962 | ||
3963 | for (i = 0; i < cfg->num_inputs; i++) { | 3963 | for (i = 0; i < cfg->num_inputs; i++) { |
3964 | hda_nid_t nid = cfg->inputs[i].pin; | 3964 | hda_nid_t nid = cfg->inputs[i].pin; |
3965 | unsigned int defcfg; | 3965 | unsigned int defcfg; |
3966 | if (cfg->inputs[i].type != AUTO_PIN_MIC) | 3966 | if (cfg->inputs[i].type != AUTO_PIN_MIC) |
3967 | continue; | 3967 | continue; |
3968 | defcfg = snd_hda_codec_get_pincfg(codec, nid); | 3968 | defcfg = snd_hda_codec_get_pincfg(codec, nid); |
3969 | if (snd_hda_get_input_pin_attr(defcfg) != INPUT_PIN_ATTR_INT) | 3969 | if (snd_hda_get_input_pin_attr(defcfg) != INPUT_PIN_ATTR_INT) |
3970 | continue; | 3970 | continue; |
3971 | 3971 | ||
3972 | snd_hda_override_amp_caps(codec, nid, HDA_INPUT, | 3972 | snd_hda_override_amp_caps(codec, nid, HDA_INPUT, |
3973 | (0x00 << AC_AMPCAP_OFFSET_SHIFT) | | 3973 | (0x00 << AC_AMPCAP_OFFSET_SHIFT) | |
3974 | (0x01 << AC_AMPCAP_NUM_STEPS_SHIFT) | | 3974 | (0x01 << AC_AMPCAP_NUM_STEPS_SHIFT) | |
3975 | (0x2f << AC_AMPCAP_STEP_SIZE_SHIFT) | | 3975 | (0x2f << AC_AMPCAP_STEP_SIZE_SHIFT) | |
3976 | (0 << AC_AMPCAP_MUTE_SHIFT)); | 3976 | (0 << AC_AMPCAP_MUTE_SHIFT)); |
3977 | } | 3977 | } |
3978 | } | 3978 | } |
3979 | 3979 | ||
3980 | static void alc283_hp_automute_hook(struct hda_codec *codec, | 3980 | static void alc283_hp_automute_hook(struct hda_codec *codec, |
3981 | struct hda_jack_tbl *jack) | 3981 | struct hda_jack_tbl *jack) |
3982 | { | 3982 | { |
3983 | struct alc_spec *spec = codec->spec; | 3983 | struct alc_spec *spec = codec->spec; |
3984 | int vref; | 3984 | int vref; |
3985 | 3985 | ||
3986 | msleep(200); | 3986 | msleep(200); |
3987 | snd_hda_gen_hp_automute(codec, jack); | 3987 | snd_hda_gen_hp_automute(codec, jack); |
3988 | 3988 | ||
3989 | vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0; | 3989 | vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0; |
3990 | 3990 | ||
3991 | msleep(600); | 3991 | msleep(600); |
3992 | snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | 3992 | snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, |
3993 | vref); | 3993 | vref); |
3994 | } | 3994 | } |
3995 | 3995 | ||
3996 | static void alc283_fixup_chromebook(struct hda_codec *codec, | 3996 | static void alc283_fixup_chromebook(struct hda_codec *codec, |
3997 | const struct hda_fixup *fix, int action) | 3997 | const struct hda_fixup *fix, int action) |
3998 | { | 3998 | { |
3999 | struct alc_spec *spec = codec->spec; | 3999 | struct alc_spec *spec = codec->spec; |
4000 | int val; | 4000 | int val; |
4001 | 4001 | ||
4002 | switch (action) { | 4002 | switch (action) { |
4003 | case HDA_FIXUP_ACT_PRE_PROBE: | 4003 | case HDA_FIXUP_ACT_PRE_PROBE: |
4004 | snd_hda_override_wcaps(codec, 0x03, 0); | 4004 | snd_hda_override_wcaps(codec, 0x03, 0); |
4005 | /* Disable AA-loopback as it causes white noise */ | 4005 | /* Disable AA-loopback as it causes white noise */ |
4006 | spec->gen.mixer_nid = 0; | 4006 | spec->gen.mixer_nid = 0; |
4007 | break; | 4007 | break; |
4008 | case HDA_FIXUP_ACT_INIT: | 4008 | case HDA_FIXUP_ACT_INIT: |
4009 | /* MIC2-VREF control */ | 4009 | /* MIC2-VREF control */ |
4010 | /* Set to manual mode */ | 4010 | /* Set to manual mode */ |
4011 | val = alc_read_coef_idx(codec, 0x06); | 4011 | val = alc_read_coef_idx(codec, 0x06); |
4012 | alc_write_coef_idx(codec, 0x06, val & ~0x000c); | 4012 | alc_write_coef_idx(codec, 0x06, val & ~0x000c); |
4013 | /* Enable Line1 input control by verb */ | 4013 | /* Enable Line1 input control by verb */ |
4014 | val = alc_read_coef_idx(codec, 0x1a); | 4014 | val = alc_read_coef_idx(codec, 0x1a); |
4015 | alc_write_coef_idx(codec, 0x1a, val | (1 << 4)); | 4015 | alc_write_coef_idx(codec, 0x1a, val | (1 << 4)); |
4016 | break; | 4016 | break; |
4017 | } | 4017 | } |
4018 | } | 4018 | } |
4019 | 4019 | ||
4020 | static void alc283_fixup_sense_combo_jack(struct hda_codec *codec, | 4020 | static void alc283_fixup_sense_combo_jack(struct hda_codec *codec, |
4021 | const struct hda_fixup *fix, int action) | 4021 | const struct hda_fixup *fix, int action) |
4022 | { | 4022 | { |
4023 | struct alc_spec *spec = codec->spec; | 4023 | struct alc_spec *spec = codec->spec; |
4024 | int val; | 4024 | int val; |
4025 | 4025 | ||
4026 | switch (action) { | 4026 | switch (action) { |
4027 | case HDA_FIXUP_ACT_PRE_PROBE: | 4027 | case HDA_FIXUP_ACT_PRE_PROBE: |
4028 | spec->gen.hp_automute_hook = alc283_hp_automute_hook; | 4028 | spec->gen.hp_automute_hook = alc283_hp_automute_hook; |
4029 | break; | 4029 | break; |
4030 | case HDA_FIXUP_ACT_INIT: | 4030 | case HDA_FIXUP_ACT_INIT: |
4031 | /* MIC2-VREF control */ | 4031 | /* MIC2-VREF control */ |
4032 | /* Set to manual mode */ | 4032 | /* Set to manual mode */ |
4033 | val = alc_read_coef_idx(codec, 0x06); | 4033 | val = alc_read_coef_idx(codec, 0x06); |
4034 | alc_write_coef_idx(codec, 0x06, val & ~0x000c); | 4034 | alc_write_coef_idx(codec, 0x06, val & ~0x000c); |
4035 | break; | 4035 | break; |
4036 | } | 4036 | } |
4037 | } | 4037 | } |
4038 | 4038 | ||
4039 | /* mute tablet speaker pin (0x14) via dock plugging in addition */ | 4039 | /* mute tablet speaker pin (0x14) via dock plugging in addition */ |
4040 | static void asus_tx300_automute(struct hda_codec *codec) | 4040 | static void asus_tx300_automute(struct hda_codec *codec) |
4041 | { | 4041 | { |
4042 | struct alc_spec *spec = codec->spec; | 4042 | struct alc_spec *spec = codec->spec; |
4043 | snd_hda_gen_update_outputs(codec); | 4043 | snd_hda_gen_update_outputs(codec); |
4044 | if (snd_hda_jack_detect(codec, 0x1b)) | 4044 | if (snd_hda_jack_detect(codec, 0x1b)) |
4045 | spec->gen.mute_bits |= (1ULL << 0x14); | 4045 | spec->gen.mute_bits |= (1ULL << 0x14); |
4046 | } | 4046 | } |
4047 | 4047 | ||
4048 | static void alc282_fixup_asus_tx300(struct hda_codec *codec, | 4048 | static void alc282_fixup_asus_tx300(struct hda_codec *codec, |
4049 | const struct hda_fixup *fix, int action) | 4049 | const struct hda_fixup *fix, int action) |
4050 | { | 4050 | { |
4051 | struct alc_spec *spec = codec->spec; | 4051 | struct alc_spec *spec = codec->spec; |
4052 | /* TX300 needs to set up GPIO2 for the speaker amp */ | 4052 | /* TX300 needs to set up GPIO2 for the speaker amp */ |
4053 | static const struct hda_verb gpio2_verbs[] = { | 4053 | static const struct hda_verb gpio2_verbs[] = { |
4054 | { 0x01, AC_VERB_SET_GPIO_MASK, 0x04 }, | 4054 | { 0x01, AC_VERB_SET_GPIO_MASK, 0x04 }, |
4055 | { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04 }, | 4055 | { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04 }, |
4056 | { 0x01, AC_VERB_SET_GPIO_DATA, 0x04 }, | 4056 | { 0x01, AC_VERB_SET_GPIO_DATA, 0x04 }, |
4057 | {} | 4057 | {} |
4058 | }; | 4058 | }; |
4059 | static const struct hda_pintbl dock_pins[] = { | 4059 | static const struct hda_pintbl dock_pins[] = { |
4060 | { 0x1b, 0x21114000 }, /* dock speaker pin */ | 4060 | { 0x1b, 0x21114000 }, /* dock speaker pin */ |
4061 | {} | 4061 | {} |
4062 | }; | 4062 | }; |
4063 | struct snd_kcontrol *kctl; | 4063 | struct snd_kcontrol *kctl; |
4064 | 4064 | ||
4065 | switch (action) { | 4065 | switch (action) { |
4066 | case HDA_FIXUP_ACT_PRE_PROBE: | 4066 | case HDA_FIXUP_ACT_PRE_PROBE: |
4067 | snd_hda_add_verbs(codec, gpio2_verbs); | 4067 | snd_hda_add_verbs(codec, gpio2_verbs); |
4068 | snd_hda_apply_pincfgs(codec, dock_pins); | 4068 | snd_hda_apply_pincfgs(codec, dock_pins); |
4069 | spec->gen.auto_mute_via_amp = 1; | 4069 | spec->gen.auto_mute_via_amp = 1; |
4070 | spec->gen.automute_hook = asus_tx300_automute; | 4070 | spec->gen.automute_hook = asus_tx300_automute; |
4071 | snd_hda_jack_detect_enable_callback(codec, 0x1b, | 4071 | snd_hda_jack_detect_enable_callback(codec, 0x1b, |
4072 | HDA_GEN_HP_EVENT, | 4072 | HDA_GEN_HP_EVENT, |
4073 | snd_hda_gen_hp_automute); | 4073 | snd_hda_gen_hp_automute); |
4074 | break; | 4074 | break; |
4075 | case HDA_FIXUP_ACT_BUILD: | 4075 | case HDA_FIXUP_ACT_BUILD: |
4076 | /* this is a bit tricky; give more sane names for the main | 4076 | /* this is a bit tricky; give more sane names for the main |
4077 | * (tablet) speaker and the dock speaker, respectively | 4077 | * (tablet) speaker and the dock speaker, respectively |
4078 | */ | 4078 | */ |
4079 | kctl = snd_hda_find_mixer_ctl(codec, "Speaker Playback Switch"); | 4079 | kctl = snd_hda_find_mixer_ctl(codec, "Speaker Playback Switch"); |
4080 | if (kctl) | 4080 | if (kctl) |
4081 | strcpy(kctl->id.name, "Dock Speaker Playback Switch"); | 4081 | strcpy(kctl->id.name, "Dock Speaker Playback Switch"); |
4082 | kctl = snd_hda_find_mixer_ctl(codec, "Bass Speaker Playback Switch"); | 4082 | kctl = snd_hda_find_mixer_ctl(codec, "Bass Speaker Playback Switch"); |
4083 | if (kctl) | 4083 | if (kctl) |
4084 | strcpy(kctl->id.name, "Speaker Playback Switch"); | 4084 | strcpy(kctl->id.name, "Speaker Playback Switch"); |
4085 | break; | 4085 | break; |
4086 | } | 4086 | } |
4087 | } | 4087 | } |
4088 | 4088 | ||
4089 | static void alc290_fixup_mono_speakers(struct hda_codec *codec, | 4089 | static void alc290_fixup_mono_speakers(struct hda_codec *codec, |
4090 | const struct hda_fixup *fix, int action) | 4090 | const struct hda_fixup *fix, int action) |
4091 | { | 4091 | { |
4092 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | 4092 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
4093 | /* DAC node 0x03 is giving mono output. We therefore want to | 4093 | /* DAC node 0x03 is giving mono output. We therefore want to |
4094 | make sure 0x14 (front speaker) and 0x15 (headphones) use the | 4094 | make sure 0x14 (front speaker) and 0x15 (headphones) use the |
4095 | stereo DAC, while leaving 0x17 (bass speaker) for node 0x03. */ | 4095 | stereo DAC, while leaving 0x17 (bass speaker) for node 0x03. */ |
4096 | hda_nid_t conn1[2] = { 0x0c }; | 4096 | hda_nid_t conn1[2] = { 0x0c }; |
4097 | snd_hda_override_conn_list(codec, 0x14, 1, conn1); | 4097 | snd_hda_override_conn_list(codec, 0x14, 1, conn1); |
4098 | snd_hda_override_conn_list(codec, 0x15, 1, conn1); | 4098 | snd_hda_override_conn_list(codec, 0x15, 1, conn1); |
4099 | } | 4099 | } |
4100 | } | 4100 | } |
4101 | 4101 | ||
4102 | /* for hda_fixup_thinkpad_acpi() */ | 4102 | /* for hda_fixup_thinkpad_acpi() */ |
4103 | #include "thinkpad_helper.c" | 4103 | #include "thinkpad_helper.c" |
4104 | 4104 | ||
4105 | enum { | 4105 | enum { |
4106 | ALC269_FIXUP_SONY_VAIO, | 4106 | ALC269_FIXUP_SONY_VAIO, |
4107 | ALC275_FIXUP_SONY_VAIO_GPIO2, | 4107 | ALC275_FIXUP_SONY_VAIO_GPIO2, |
4108 | ALC269_FIXUP_DELL_M101Z, | 4108 | ALC269_FIXUP_DELL_M101Z, |
4109 | ALC269_FIXUP_SKU_IGNORE, | 4109 | ALC269_FIXUP_SKU_IGNORE, |
4110 | ALC269_FIXUP_ASUS_G73JW, | 4110 | ALC269_FIXUP_ASUS_G73JW, |
4111 | ALC269_FIXUP_LENOVO_EAPD, | 4111 | ALC269_FIXUP_LENOVO_EAPD, |
4112 | ALC275_FIXUP_SONY_HWEQ, | 4112 | ALC275_FIXUP_SONY_HWEQ, |
4113 | ALC271_FIXUP_DMIC, | 4113 | ALC271_FIXUP_DMIC, |
4114 | ALC269_FIXUP_PCM_44K, | 4114 | ALC269_FIXUP_PCM_44K, |
4115 | ALC269_FIXUP_STEREO_DMIC, | 4115 | ALC269_FIXUP_STEREO_DMIC, |
4116 | ALC269_FIXUP_HEADSET_MIC, | 4116 | ALC269_FIXUP_HEADSET_MIC, |
4117 | ALC269_FIXUP_QUANTA_MUTE, | 4117 | ALC269_FIXUP_QUANTA_MUTE, |
4118 | ALC269_FIXUP_LIFEBOOK, | 4118 | ALC269_FIXUP_LIFEBOOK, |
4119 | ALC269_FIXUP_AMIC, | 4119 | ALC269_FIXUP_AMIC, |
4120 | ALC269_FIXUP_DMIC, | 4120 | ALC269_FIXUP_DMIC, |
4121 | ALC269VB_FIXUP_AMIC, | 4121 | ALC269VB_FIXUP_AMIC, |
4122 | ALC269VB_FIXUP_DMIC, | 4122 | ALC269VB_FIXUP_DMIC, |
4123 | ALC269_FIXUP_HP_MUTE_LED, | 4123 | ALC269_FIXUP_HP_MUTE_LED, |
4124 | ALC269_FIXUP_HP_MUTE_LED_MIC1, | 4124 | ALC269_FIXUP_HP_MUTE_LED_MIC1, |
4125 | ALC269_FIXUP_HP_MUTE_LED_MIC2, | 4125 | ALC269_FIXUP_HP_MUTE_LED_MIC2, |
4126 | ALC269_FIXUP_HP_GPIO_LED, | 4126 | ALC269_FIXUP_HP_GPIO_LED, |
4127 | ALC269_FIXUP_INV_DMIC, | 4127 | ALC269_FIXUP_INV_DMIC, |
4128 | ALC269_FIXUP_LENOVO_DOCK, | 4128 | ALC269_FIXUP_LENOVO_DOCK, |
4129 | ALC269_FIXUP_NO_SHUTUP, | 4129 | ALC269_FIXUP_NO_SHUTUP, |
4130 | ALC286_FIXUP_SONY_MIC_NO_PRESENCE, | 4130 | ALC286_FIXUP_SONY_MIC_NO_PRESENCE, |
4131 | ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT, | 4131 | ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT, |
4132 | ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, | 4132 | ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, |
4133 | ALC269_FIXUP_DELL2_MIC_NO_PRESENCE, | 4133 | ALC269_FIXUP_DELL2_MIC_NO_PRESENCE, |
4134 | ALC269_FIXUP_DELL3_MIC_NO_PRESENCE, | 4134 | ALC269_FIXUP_DELL3_MIC_NO_PRESENCE, |
4135 | ALC269_FIXUP_HEADSET_MODE, | 4135 | ALC269_FIXUP_HEADSET_MODE, |
4136 | ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC, | 4136 | ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC, |
4137 | ALC269_FIXUP_ASUS_X101_FUNC, | 4137 | ALC269_FIXUP_ASUS_X101_FUNC, |
4138 | ALC269_FIXUP_ASUS_X101_VERB, | 4138 | ALC269_FIXUP_ASUS_X101_VERB, |
4139 | ALC269_FIXUP_ASUS_X101, | 4139 | ALC269_FIXUP_ASUS_X101, |
4140 | ALC271_FIXUP_AMIC_MIC2, | 4140 | ALC271_FIXUP_AMIC_MIC2, |
4141 | ALC271_FIXUP_HP_GATE_MIC_JACK, | 4141 | ALC271_FIXUP_HP_GATE_MIC_JACK, |
4142 | ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572, | 4142 | ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572, |
4143 | ALC269_FIXUP_ACER_AC700, | 4143 | ALC269_FIXUP_ACER_AC700, |
4144 | ALC269_FIXUP_LIMIT_INT_MIC_BOOST, | 4144 | ALC269_FIXUP_LIMIT_INT_MIC_BOOST, |
4145 | ALC269VB_FIXUP_ASUS_ZENBOOK, | 4145 | ALC269VB_FIXUP_ASUS_ZENBOOK, |
4146 | ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A, | 4146 | ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A, |
4147 | ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED, | 4147 | ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED, |
4148 | ALC269VB_FIXUP_ORDISSIMO_EVE2, | 4148 | ALC269VB_FIXUP_ORDISSIMO_EVE2, |
4149 | ALC283_FIXUP_CHROME_BOOK, | 4149 | ALC283_FIXUP_CHROME_BOOK, |
4150 | ALC283_FIXUP_SENSE_COMBO_JACK, | 4150 | ALC283_FIXUP_SENSE_COMBO_JACK, |
4151 | ALC282_FIXUP_ASUS_TX300, | 4151 | ALC282_FIXUP_ASUS_TX300, |
4152 | ALC283_FIXUP_INT_MIC, | 4152 | ALC283_FIXUP_INT_MIC, |
4153 | ALC290_FIXUP_MONO_SPEAKERS, | 4153 | ALC290_FIXUP_MONO_SPEAKERS, |
4154 | ALC290_FIXUP_MONO_SPEAKERS_HSJACK, | 4154 | ALC290_FIXUP_MONO_SPEAKERS_HSJACK, |
4155 | ALC290_FIXUP_SUBWOOFER, | 4155 | ALC290_FIXUP_SUBWOOFER, |
4156 | ALC290_FIXUP_SUBWOOFER_HSJACK, | 4156 | ALC290_FIXUP_SUBWOOFER_HSJACK, |
4157 | ALC269_FIXUP_THINKPAD_ACPI, | 4157 | ALC269_FIXUP_THINKPAD_ACPI, |
4158 | ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, | 4158 | ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, |
4159 | ALC255_FIXUP_DELL2_MIC_NO_PRESENCE, | 4159 | ALC255_FIXUP_DELL2_MIC_NO_PRESENCE, |
4160 | ALC255_FIXUP_HEADSET_MODE, | 4160 | ALC255_FIXUP_HEADSET_MODE, |
4161 | ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC, | 4161 | ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC, |
4162 | }; | 4162 | }; |
4163 | 4163 | ||
4164 | static const struct hda_fixup alc269_fixups[] = { | 4164 | static const struct hda_fixup alc269_fixups[] = { |
4165 | [ALC269_FIXUP_SONY_VAIO] = { | 4165 | [ALC269_FIXUP_SONY_VAIO] = { |
4166 | .type = HDA_FIXUP_PINCTLS, | 4166 | .type = HDA_FIXUP_PINCTLS, |
4167 | .v.pins = (const struct hda_pintbl[]) { | 4167 | .v.pins = (const struct hda_pintbl[]) { |
4168 | {0x19, PIN_VREFGRD}, | 4168 | {0x19, PIN_VREFGRD}, |
4169 | {} | 4169 | {} |
4170 | } | 4170 | } |
4171 | }, | 4171 | }, |
4172 | [ALC275_FIXUP_SONY_VAIO_GPIO2] = { | 4172 | [ALC275_FIXUP_SONY_VAIO_GPIO2] = { |
4173 | .type = HDA_FIXUP_VERBS, | 4173 | .type = HDA_FIXUP_VERBS, |
4174 | .v.verbs = (const struct hda_verb[]) { | 4174 | .v.verbs = (const struct hda_verb[]) { |
4175 | {0x01, AC_VERB_SET_GPIO_MASK, 0x04}, | 4175 | {0x01, AC_VERB_SET_GPIO_MASK, 0x04}, |
4176 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04}, | 4176 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04}, |
4177 | {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, | 4177 | {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, |
4178 | { } | 4178 | { } |
4179 | }, | 4179 | }, |
4180 | .chained = true, | 4180 | .chained = true, |
4181 | .chain_id = ALC269_FIXUP_SONY_VAIO | 4181 | .chain_id = ALC269_FIXUP_SONY_VAIO |
4182 | }, | 4182 | }, |
4183 | [ALC269_FIXUP_DELL_M101Z] = { | 4183 | [ALC269_FIXUP_DELL_M101Z] = { |
4184 | .type = HDA_FIXUP_VERBS, | 4184 | .type = HDA_FIXUP_VERBS, |
4185 | .v.verbs = (const struct hda_verb[]) { | 4185 | .v.verbs = (const struct hda_verb[]) { |
4186 | /* Enables internal speaker */ | 4186 | /* Enables internal speaker */ |
4187 | {0x20, AC_VERB_SET_COEF_INDEX, 13}, | 4187 | {0x20, AC_VERB_SET_COEF_INDEX, 13}, |
4188 | {0x20, AC_VERB_SET_PROC_COEF, 0x4040}, | 4188 | {0x20, AC_VERB_SET_PROC_COEF, 0x4040}, |
4189 | {} | 4189 | {} |
4190 | } | 4190 | } |
4191 | }, | 4191 | }, |
4192 | [ALC269_FIXUP_SKU_IGNORE] = { | 4192 | [ALC269_FIXUP_SKU_IGNORE] = { |
4193 | .type = HDA_FIXUP_FUNC, | 4193 | .type = HDA_FIXUP_FUNC, |
4194 | .v.func = alc_fixup_sku_ignore, | 4194 | .v.func = alc_fixup_sku_ignore, |
4195 | }, | 4195 | }, |
4196 | [ALC269_FIXUP_ASUS_G73JW] = { | 4196 | [ALC269_FIXUP_ASUS_G73JW] = { |
4197 | .type = HDA_FIXUP_PINS, | 4197 | .type = HDA_FIXUP_PINS, |
4198 | .v.pins = (const struct hda_pintbl[]) { | 4198 | .v.pins = (const struct hda_pintbl[]) { |
4199 | { 0x17, 0x99130111 }, /* subwoofer */ | 4199 | { 0x17, 0x99130111 }, /* subwoofer */ |
4200 | { } | 4200 | { } |
4201 | } | 4201 | } |
4202 | }, | 4202 | }, |
4203 | [ALC269_FIXUP_LENOVO_EAPD] = { | 4203 | [ALC269_FIXUP_LENOVO_EAPD] = { |
4204 | .type = HDA_FIXUP_VERBS, | 4204 | .type = HDA_FIXUP_VERBS, |
4205 | .v.verbs = (const struct hda_verb[]) { | 4205 | .v.verbs = (const struct hda_verb[]) { |
4206 | {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0}, | 4206 | {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0}, |
4207 | {} | 4207 | {} |
4208 | } | 4208 | } |
4209 | }, | 4209 | }, |
4210 | [ALC275_FIXUP_SONY_HWEQ] = { | 4210 | [ALC275_FIXUP_SONY_HWEQ] = { |
4211 | .type = HDA_FIXUP_FUNC, | 4211 | .type = HDA_FIXUP_FUNC, |
4212 | .v.func = alc269_fixup_hweq, | 4212 | .v.func = alc269_fixup_hweq, |
4213 | .chained = true, | 4213 | .chained = true, |
4214 | .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2 | 4214 | .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2 |
4215 | }, | 4215 | }, |
4216 | [ALC271_FIXUP_DMIC] = { | 4216 | [ALC271_FIXUP_DMIC] = { |
4217 | .type = HDA_FIXUP_FUNC, | 4217 | .type = HDA_FIXUP_FUNC, |
4218 | .v.func = alc271_fixup_dmic, | 4218 | .v.func = alc271_fixup_dmic, |
4219 | }, | 4219 | }, |
4220 | [ALC269_FIXUP_PCM_44K] = { | 4220 | [ALC269_FIXUP_PCM_44K] = { |
4221 | .type = HDA_FIXUP_FUNC, | 4221 | .type = HDA_FIXUP_FUNC, |
4222 | .v.func = alc269_fixup_pcm_44k, | 4222 | .v.func = alc269_fixup_pcm_44k, |
4223 | .chained = true, | 4223 | .chained = true, |
4224 | .chain_id = ALC269_FIXUP_QUANTA_MUTE | 4224 | .chain_id = ALC269_FIXUP_QUANTA_MUTE |
4225 | }, | 4225 | }, |
4226 | [ALC269_FIXUP_STEREO_DMIC] = { | 4226 | [ALC269_FIXUP_STEREO_DMIC] = { |
4227 | .type = HDA_FIXUP_FUNC, | 4227 | .type = HDA_FIXUP_FUNC, |
4228 | .v.func = alc269_fixup_stereo_dmic, | 4228 | .v.func = alc269_fixup_stereo_dmic, |
4229 | }, | 4229 | }, |
4230 | [ALC269_FIXUP_HEADSET_MIC] = { | 4230 | [ALC269_FIXUP_HEADSET_MIC] = { |
4231 | .type = HDA_FIXUP_FUNC, | 4231 | .type = HDA_FIXUP_FUNC, |
4232 | .v.func = alc269_fixup_headset_mic, | 4232 | .v.func = alc269_fixup_headset_mic, |
4233 | }, | 4233 | }, |
4234 | [ALC269_FIXUP_QUANTA_MUTE] = { | 4234 | [ALC269_FIXUP_QUANTA_MUTE] = { |
4235 | .type = HDA_FIXUP_FUNC, | 4235 | .type = HDA_FIXUP_FUNC, |
4236 | .v.func = alc269_fixup_quanta_mute, | 4236 | .v.func = alc269_fixup_quanta_mute, |
4237 | }, | 4237 | }, |
4238 | [ALC269_FIXUP_LIFEBOOK] = { | 4238 | [ALC269_FIXUP_LIFEBOOK] = { |
4239 | .type = HDA_FIXUP_PINS, | 4239 | .type = HDA_FIXUP_PINS, |
4240 | .v.pins = (const struct hda_pintbl[]) { | 4240 | .v.pins = (const struct hda_pintbl[]) { |
4241 | { 0x1a, 0x2101103f }, /* dock line-out */ | 4241 | { 0x1a, 0x2101103f }, /* dock line-out */ |
4242 | { 0x1b, 0x23a11040 }, /* dock mic-in */ | 4242 | { 0x1b, 0x23a11040 }, /* dock mic-in */ |
4243 | { } | 4243 | { } |
4244 | }, | 4244 | }, |
4245 | .chained = true, | 4245 | .chained = true, |
4246 | .chain_id = ALC269_FIXUP_QUANTA_MUTE | 4246 | .chain_id = ALC269_FIXUP_QUANTA_MUTE |
4247 | }, | 4247 | }, |
4248 | [ALC269_FIXUP_AMIC] = { | 4248 | [ALC269_FIXUP_AMIC] = { |
4249 | .type = HDA_FIXUP_PINS, | 4249 | .type = HDA_FIXUP_PINS, |
4250 | .v.pins = (const struct hda_pintbl[]) { | 4250 | .v.pins = (const struct hda_pintbl[]) { |
4251 | { 0x14, 0x99130110 }, /* speaker */ | 4251 | { 0x14, 0x99130110 }, /* speaker */ |
4252 | { 0x15, 0x0121401f }, /* HP out */ | 4252 | { 0x15, 0x0121401f }, /* HP out */ |
4253 | { 0x18, 0x01a19c20 }, /* mic */ | 4253 | { 0x18, 0x01a19c20 }, /* mic */ |
4254 | { 0x19, 0x99a3092f }, /* int-mic */ | 4254 | { 0x19, 0x99a3092f }, /* int-mic */ |
4255 | { } | 4255 | { } |
4256 | }, | 4256 | }, |
4257 | }, | 4257 | }, |
4258 | [ALC269_FIXUP_DMIC] = { | 4258 | [ALC269_FIXUP_DMIC] = { |
4259 | .type = HDA_FIXUP_PINS, | 4259 | .type = HDA_FIXUP_PINS, |
4260 | .v.pins = (const struct hda_pintbl[]) { | 4260 | .v.pins = (const struct hda_pintbl[]) { |
4261 | { 0x12, 0x99a3092f }, /* int-mic */ | 4261 | { 0x12, 0x99a3092f }, /* int-mic */ |
4262 | { 0x14, 0x99130110 }, /* speaker */ | 4262 | { 0x14, 0x99130110 }, /* speaker */ |
4263 | { 0x15, 0x0121401f }, /* HP out */ | 4263 | { 0x15, 0x0121401f }, /* HP out */ |
4264 | { 0x18, 0x01a19c20 }, /* mic */ | 4264 | { 0x18, 0x01a19c20 }, /* mic */ |
4265 | { } | 4265 | { } |
4266 | }, | 4266 | }, |
4267 | }, | 4267 | }, |
4268 | [ALC269VB_FIXUP_AMIC] = { | 4268 | [ALC269VB_FIXUP_AMIC] = { |
4269 | .type = HDA_FIXUP_PINS, | 4269 | .type = HDA_FIXUP_PINS, |
4270 | .v.pins = (const struct hda_pintbl[]) { | 4270 | .v.pins = (const struct hda_pintbl[]) { |
4271 | { 0x14, 0x99130110 }, /* speaker */ | 4271 | { 0x14, 0x99130110 }, /* speaker */ |
4272 | { 0x18, 0x01a19c20 }, /* mic */ | 4272 | { 0x18, 0x01a19c20 }, /* mic */ |
4273 | { 0x19, 0x99a3092f }, /* int-mic */ | 4273 | { 0x19, 0x99a3092f }, /* int-mic */ |
4274 | { 0x21, 0x0121401f }, /* HP out */ | 4274 | { 0x21, 0x0121401f }, /* HP out */ |
4275 | { } | 4275 | { } |
4276 | }, | 4276 | }, |
4277 | }, | 4277 | }, |
4278 | [ALC269VB_FIXUP_DMIC] = { | 4278 | [ALC269VB_FIXUP_DMIC] = { |
4279 | .type = HDA_FIXUP_PINS, | 4279 | .type = HDA_FIXUP_PINS, |
4280 | .v.pins = (const struct hda_pintbl[]) { | 4280 | .v.pins = (const struct hda_pintbl[]) { |
4281 | { 0x12, 0x99a3092f }, /* int-mic */ | 4281 | { 0x12, 0x99a3092f }, /* int-mic */ |
4282 | { 0x14, 0x99130110 }, /* speaker */ | 4282 | { 0x14, 0x99130110 }, /* speaker */ |
4283 | { 0x18, 0x01a19c20 }, /* mic */ | 4283 | { 0x18, 0x01a19c20 }, /* mic */ |
4284 | { 0x21, 0x0121401f }, /* HP out */ | 4284 | { 0x21, 0x0121401f }, /* HP out */ |
4285 | { } | 4285 | { } |
4286 | }, | 4286 | }, |
4287 | }, | 4287 | }, |
4288 | [ALC269_FIXUP_HP_MUTE_LED] = { | 4288 | [ALC269_FIXUP_HP_MUTE_LED] = { |
4289 | .type = HDA_FIXUP_FUNC, | 4289 | .type = HDA_FIXUP_FUNC, |
4290 | .v.func = alc269_fixup_hp_mute_led, | 4290 | .v.func = alc269_fixup_hp_mute_led, |
4291 | }, | 4291 | }, |
4292 | [ALC269_FIXUP_HP_MUTE_LED_MIC1] = { | 4292 | [ALC269_FIXUP_HP_MUTE_LED_MIC1] = { |
4293 | .type = HDA_FIXUP_FUNC, | 4293 | .type = HDA_FIXUP_FUNC, |
4294 | .v.func = alc269_fixup_hp_mute_led_mic1, | 4294 | .v.func = alc269_fixup_hp_mute_led_mic1, |
4295 | }, | 4295 | }, |
4296 | [ALC269_FIXUP_HP_MUTE_LED_MIC2] = { | 4296 | [ALC269_FIXUP_HP_MUTE_LED_MIC2] = { |
4297 | .type = HDA_FIXUP_FUNC, | 4297 | .type = HDA_FIXUP_FUNC, |
4298 | .v.func = alc269_fixup_hp_mute_led_mic2, | 4298 | .v.func = alc269_fixup_hp_mute_led_mic2, |
4299 | }, | 4299 | }, |
4300 | [ALC269_FIXUP_HP_GPIO_LED] = { | 4300 | [ALC269_FIXUP_HP_GPIO_LED] = { |
4301 | .type = HDA_FIXUP_FUNC, | 4301 | .type = HDA_FIXUP_FUNC, |
4302 | .v.func = alc269_fixup_hp_gpio_led, | 4302 | .v.func = alc269_fixup_hp_gpio_led, |
4303 | }, | 4303 | }, |
4304 | [ALC269_FIXUP_INV_DMIC] = { | 4304 | [ALC269_FIXUP_INV_DMIC] = { |
4305 | .type = HDA_FIXUP_FUNC, | 4305 | .type = HDA_FIXUP_FUNC, |
4306 | .v.func = alc_fixup_inv_dmic_0x12, | 4306 | .v.func = alc_fixup_inv_dmic_0x12, |
4307 | }, | 4307 | }, |
4308 | [ALC269_FIXUP_NO_SHUTUP] = { | 4308 | [ALC269_FIXUP_NO_SHUTUP] = { |
4309 | .type = HDA_FIXUP_FUNC, | 4309 | .type = HDA_FIXUP_FUNC, |
4310 | .v.func = alc_fixup_no_shutup, | 4310 | .v.func = alc_fixup_no_shutup, |
4311 | }, | 4311 | }, |
4312 | [ALC269_FIXUP_LENOVO_DOCK] = { | 4312 | [ALC269_FIXUP_LENOVO_DOCK] = { |
4313 | .type = HDA_FIXUP_PINS, | 4313 | .type = HDA_FIXUP_PINS, |
4314 | .v.pins = (const struct hda_pintbl[]) { | 4314 | .v.pins = (const struct hda_pintbl[]) { |
4315 | { 0x19, 0x23a11040 }, /* dock mic */ | 4315 | { 0x19, 0x23a11040 }, /* dock mic */ |
4316 | { 0x1b, 0x2121103f }, /* dock headphone */ | 4316 | { 0x1b, 0x2121103f }, /* dock headphone */ |
4317 | { } | 4317 | { } |
4318 | }, | 4318 | }, |
4319 | .chained = true, | 4319 | .chained = true, |
4320 | .chain_id = ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT | 4320 | .chain_id = ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT |
4321 | }, | 4321 | }, |
4322 | [ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT] = { | 4322 | [ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT] = { |
4323 | .type = HDA_FIXUP_FUNC, | 4323 | .type = HDA_FIXUP_FUNC, |
4324 | .v.func = alc269_fixup_pincfg_no_hp_to_lineout, | 4324 | .v.func = alc269_fixup_pincfg_no_hp_to_lineout, |
4325 | .chained = true, | 4325 | .chained = true, |
4326 | .chain_id = ALC269_FIXUP_THINKPAD_ACPI, | 4326 | .chain_id = ALC269_FIXUP_THINKPAD_ACPI, |
4327 | }, | 4327 | }, |
4328 | [ALC269_FIXUP_DELL1_MIC_NO_PRESENCE] = { | 4328 | [ALC269_FIXUP_DELL1_MIC_NO_PRESENCE] = { |
4329 | .type = HDA_FIXUP_PINS, | 4329 | .type = HDA_FIXUP_PINS, |
4330 | .v.pins = (const struct hda_pintbl[]) { | 4330 | .v.pins = (const struct hda_pintbl[]) { |
4331 | { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */ | 4331 | { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */ |
4332 | { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */ | 4332 | { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */ |
4333 | { } | 4333 | { } |
4334 | }, | 4334 | }, |
4335 | .chained = true, | 4335 | .chained = true, |
4336 | .chain_id = ALC269_FIXUP_HEADSET_MODE | 4336 | .chain_id = ALC269_FIXUP_HEADSET_MODE |
4337 | }, | 4337 | }, |
4338 | [ALC269_FIXUP_DELL2_MIC_NO_PRESENCE] = { | 4338 | [ALC269_FIXUP_DELL2_MIC_NO_PRESENCE] = { |
4339 | .type = HDA_FIXUP_PINS, | 4339 | .type = HDA_FIXUP_PINS, |
4340 | .v.pins = (const struct hda_pintbl[]) { | 4340 | .v.pins = (const struct hda_pintbl[]) { |
4341 | { 0x16, 0x21014020 }, /* dock line out */ | 4341 | { 0x16, 0x21014020 }, /* dock line out */ |
4342 | { 0x19, 0x21a19030 }, /* dock mic */ | 4342 | { 0x19, 0x21a19030 }, /* dock mic */ |
4343 | { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */ | 4343 | { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */ |
4344 | { } | 4344 | { } |
4345 | }, | 4345 | }, |
4346 | .chained = true, | 4346 | .chained = true, |
4347 | .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC | 4347 | .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC |
4348 | }, | 4348 | }, |
4349 | [ALC269_FIXUP_DELL3_MIC_NO_PRESENCE] = { | 4349 | [ALC269_FIXUP_DELL3_MIC_NO_PRESENCE] = { |
4350 | .type = HDA_FIXUP_PINS, | 4350 | .type = HDA_FIXUP_PINS, |
4351 | .v.pins = (const struct hda_pintbl[]) { | 4351 | .v.pins = (const struct hda_pintbl[]) { |
4352 | { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */ | 4352 | { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */ |
4353 | { } | 4353 | { } |
4354 | }, | 4354 | }, |
4355 | .chained = true, | 4355 | .chained = true, |
4356 | .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC | 4356 | .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC |
4357 | }, | 4357 | }, |
4358 | [ALC269_FIXUP_HEADSET_MODE] = { | 4358 | [ALC269_FIXUP_HEADSET_MODE] = { |
4359 | .type = HDA_FIXUP_FUNC, | 4359 | .type = HDA_FIXUP_FUNC, |
4360 | .v.func = alc_fixup_headset_mode, | 4360 | .v.func = alc_fixup_headset_mode, |
4361 | }, | 4361 | }, |
4362 | [ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC] = { | 4362 | [ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC] = { |
4363 | .type = HDA_FIXUP_FUNC, | 4363 | .type = HDA_FIXUP_FUNC, |
4364 | .v.func = alc_fixup_headset_mode_no_hp_mic, | 4364 | .v.func = alc_fixup_headset_mode_no_hp_mic, |
4365 | }, | 4365 | }, |
4366 | [ALC286_FIXUP_SONY_MIC_NO_PRESENCE] = { | 4366 | [ALC286_FIXUP_SONY_MIC_NO_PRESENCE] = { |
4367 | .type = HDA_FIXUP_PINS, | 4367 | .type = HDA_FIXUP_PINS, |
4368 | .v.pins = (const struct hda_pintbl[]) { | 4368 | .v.pins = (const struct hda_pintbl[]) { |
4369 | { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */ | 4369 | { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */ |
4370 | { } | 4370 | { } |
4371 | }, | 4371 | }, |
4372 | .chained = true, | 4372 | .chained = true, |
4373 | .chain_id = ALC269_FIXUP_HEADSET_MIC | 4373 | .chain_id = ALC269_FIXUP_HEADSET_MIC |
4374 | }, | 4374 | }, |
4375 | [ALC269_FIXUP_ASUS_X101_FUNC] = { | 4375 | [ALC269_FIXUP_ASUS_X101_FUNC] = { |
4376 | .type = HDA_FIXUP_FUNC, | 4376 | .type = HDA_FIXUP_FUNC, |
4377 | .v.func = alc269_fixup_x101_headset_mic, | 4377 | .v.func = alc269_fixup_x101_headset_mic, |
4378 | }, | 4378 | }, |
4379 | [ALC269_FIXUP_ASUS_X101_VERB] = { | 4379 | [ALC269_FIXUP_ASUS_X101_VERB] = { |
4380 | .type = HDA_FIXUP_VERBS, | 4380 | .type = HDA_FIXUP_VERBS, |
4381 | .v.verbs = (const struct hda_verb[]) { | 4381 | .v.verbs = (const struct hda_verb[]) { |
4382 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | 4382 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, |
4383 | {0x20, AC_VERB_SET_COEF_INDEX, 0x08}, | 4383 | {0x20, AC_VERB_SET_COEF_INDEX, 0x08}, |
4384 | {0x20, AC_VERB_SET_PROC_COEF, 0x0310}, | 4384 | {0x20, AC_VERB_SET_PROC_COEF, 0x0310}, |
4385 | { } | 4385 | { } |
4386 | }, | 4386 | }, |
4387 | .chained = true, | 4387 | .chained = true, |
4388 | .chain_id = ALC269_FIXUP_ASUS_X101_FUNC | 4388 | .chain_id = ALC269_FIXUP_ASUS_X101_FUNC |
4389 | }, | 4389 | }, |
4390 | [ALC269_FIXUP_ASUS_X101] = { | 4390 | [ALC269_FIXUP_ASUS_X101] = { |
4391 | .type = HDA_FIXUP_PINS, | 4391 | .type = HDA_FIXUP_PINS, |
4392 | .v.pins = (const struct hda_pintbl[]) { | 4392 | .v.pins = (const struct hda_pintbl[]) { |
4393 | { 0x18, 0x04a1182c }, /* Headset mic */ | 4393 | { 0x18, 0x04a1182c }, /* Headset mic */ |
4394 | { } | 4394 | { } |
4395 | }, | 4395 | }, |
4396 | .chained = true, | 4396 | .chained = true, |
4397 | .chain_id = ALC269_FIXUP_ASUS_X101_VERB | 4397 | .chain_id = ALC269_FIXUP_ASUS_X101_VERB |
4398 | }, | 4398 | }, |
4399 | [ALC271_FIXUP_AMIC_MIC2] = { | 4399 | [ALC271_FIXUP_AMIC_MIC2] = { |
4400 | .type = HDA_FIXUP_PINS, | 4400 | .type = HDA_FIXUP_PINS, |
4401 | .v.pins = (const struct hda_pintbl[]) { | 4401 | .v.pins = (const struct hda_pintbl[]) { |
4402 | { 0x14, 0x99130110 }, /* speaker */ | 4402 | { 0x14, 0x99130110 }, /* speaker */ |
4403 | { 0x19, 0x01a19c20 }, /* mic */ | 4403 | { 0x19, 0x01a19c20 }, /* mic */ |
4404 | { 0x1b, 0x99a7012f }, /* int-mic */ | 4404 | { 0x1b, 0x99a7012f }, /* int-mic */ |
4405 | { 0x21, 0x0121401f }, /* HP out */ | 4405 | { 0x21, 0x0121401f }, /* HP out */ |
4406 | { } | 4406 | { } |
4407 | }, | 4407 | }, |
4408 | }, | 4408 | }, |
4409 | [ALC271_FIXUP_HP_GATE_MIC_JACK] = { | 4409 | [ALC271_FIXUP_HP_GATE_MIC_JACK] = { |
4410 | .type = HDA_FIXUP_FUNC, | 4410 | .type = HDA_FIXUP_FUNC, |
4411 | .v.func = alc271_hp_gate_mic_jack, | 4411 | .v.func = alc271_hp_gate_mic_jack, |
4412 | .chained = true, | 4412 | .chained = true, |
4413 | .chain_id = ALC271_FIXUP_AMIC_MIC2, | 4413 | .chain_id = ALC271_FIXUP_AMIC_MIC2, |
4414 | }, | 4414 | }, |
4415 | [ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572] = { | 4415 | [ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572] = { |
4416 | .type = HDA_FIXUP_FUNC, | 4416 | .type = HDA_FIXUP_FUNC, |
4417 | .v.func = alc269_fixup_limit_int_mic_boost, | 4417 | .v.func = alc269_fixup_limit_int_mic_boost, |
4418 | .chained = true, | 4418 | .chained = true, |
4419 | .chain_id = ALC271_FIXUP_HP_GATE_MIC_JACK, | 4419 | .chain_id = ALC271_FIXUP_HP_GATE_MIC_JACK, |
4420 | }, | 4420 | }, |
4421 | [ALC269_FIXUP_ACER_AC700] = { | 4421 | [ALC269_FIXUP_ACER_AC700] = { |
4422 | .type = HDA_FIXUP_PINS, | 4422 | .type = HDA_FIXUP_PINS, |
4423 | .v.pins = (const struct hda_pintbl[]) { | 4423 | .v.pins = (const struct hda_pintbl[]) { |
4424 | { 0x12, 0x99a3092f }, /* int-mic */ | 4424 | { 0x12, 0x99a3092f }, /* int-mic */ |
4425 | { 0x14, 0x99130110 }, /* speaker */ | 4425 | { 0x14, 0x99130110 }, /* speaker */ |
4426 | { 0x18, 0x03a11c20 }, /* mic */ | 4426 | { 0x18, 0x03a11c20 }, /* mic */ |
4427 | { 0x1e, 0x0346101e }, /* SPDIF1 */ | 4427 | { 0x1e, 0x0346101e }, /* SPDIF1 */ |
4428 | { 0x21, 0x0321101f }, /* HP out */ | 4428 | { 0x21, 0x0321101f }, /* HP out */ |
4429 | { } | 4429 | { } |
4430 | }, | 4430 | }, |
4431 | .chained = true, | 4431 | .chained = true, |
4432 | .chain_id = ALC271_FIXUP_DMIC, | 4432 | .chain_id = ALC271_FIXUP_DMIC, |
4433 | }, | 4433 | }, |
4434 | [ALC269_FIXUP_LIMIT_INT_MIC_BOOST] = { | 4434 | [ALC269_FIXUP_LIMIT_INT_MIC_BOOST] = { |
4435 | .type = HDA_FIXUP_FUNC, | 4435 | .type = HDA_FIXUP_FUNC, |
4436 | .v.func = alc269_fixup_limit_int_mic_boost, | 4436 | .v.func = alc269_fixup_limit_int_mic_boost, |
4437 | .chained = true, | 4437 | .chained = true, |
4438 | .chain_id = ALC269_FIXUP_THINKPAD_ACPI, | 4438 | .chain_id = ALC269_FIXUP_THINKPAD_ACPI, |
4439 | }, | 4439 | }, |
4440 | [ALC269VB_FIXUP_ASUS_ZENBOOK] = { | 4440 | [ALC269VB_FIXUP_ASUS_ZENBOOK] = { |
4441 | .type = HDA_FIXUP_FUNC, | 4441 | .type = HDA_FIXUP_FUNC, |
4442 | .v.func = alc269_fixup_limit_int_mic_boost, | 4442 | .v.func = alc269_fixup_limit_int_mic_boost, |
4443 | .chained = true, | 4443 | .chained = true, |
4444 | .chain_id = ALC269VB_FIXUP_DMIC, | 4444 | .chain_id = ALC269VB_FIXUP_DMIC, |
4445 | }, | 4445 | }, |
4446 | [ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A] = { | 4446 | [ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A] = { |
4447 | .type = HDA_FIXUP_VERBS, | 4447 | .type = HDA_FIXUP_VERBS, |
4448 | .v.verbs = (const struct hda_verb[]) { | 4448 | .v.verbs = (const struct hda_verb[]) { |
4449 | /* class-D output amp +5dB */ | 4449 | /* class-D output amp +5dB */ |
4450 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x12 }, | 4450 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x12 }, |
4451 | { 0x20, AC_VERB_SET_PROC_COEF, 0x2800 }, | 4451 | { 0x20, AC_VERB_SET_PROC_COEF, 0x2800 }, |
4452 | {} | 4452 | {} |
4453 | }, | 4453 | }, |
4454 | .chained = true, | 4454 | .chained = true, |
4455 | .chain_id = ALC269VB_FIXUP_ASUS_ZENBOOK, | 4455 | .chain_id = ALC269VB_FIXUP_ASUS_ZENBOOK, |
4456 | }, | 4456 | }, |
4457 | [ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED] = { | 4457 | [ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED] = { |
4458 | .type = HDA_FIXUP_FUNC, | 4458 | .type = HDA_FIXUP_FUNC, |
4459 | .v.func = alc269_fixup_limit_int_mic_boost, | 4459 | .v.func = alc269_fixup_limit_int_mic_boost, |
4460 | .chained = true, | 4460 | .chained = true, |
4461 | .chain_id = ALC269_FIXUP_HP_MUTE_LED_MIC1, | 4461 | .chain_id = ALC269_FIXUP_HP_MUTE_LED_MIC1, |
4462 | }, | 4462 | }, |
4463 | [ALC269VB_FIXUP_ORDISSIMO_EVE2] = { | 4463 | [ALC269VB_FIXUP_ORDISSIMO_EVE2] = { |
4464 | .type = HDA_FIXUP_PINS, | 4464 | .type = HDA_FIXUP_PINS, |
4465 | .v.pins = (const struct hda_pintbl[]) { | 4465 | .v.pins = (const struct hda_pintbl[]) { |
4466 | { 0x12, 0x99a3092f }, /* int-mic */ | 4466 | { 0x12, 0x99a3092f }, /* int-mic */ |
4467 | { 0x18, 0x03a11d20 }, /* mic */ | 4467 | { 0x18, 0x03a11d20 }, /* mic */ |
4468 | { 0x19, 0x411111f0 }, /* Unused bogus pin */ | 4468 | { 0x19, 0x411111f0 }, /* Unused bogus pin */ |
4469 | { } | 4469 | { } |
4470 | }, | 4470 | }, |
4471 | }, | 4471 | }, |
4472 | [ALC283_FIXUP_CHROME_BOOK] = { | 4472 | [ALC283_FIXUP_CHROME_BOOK] = { |
4473 | .type = HDA_FIXUP_FUNC, | 4473 | .type = HDA_FIXUP_FUNC, |
4474 | .v.func = alc283_fixup_chromebook, | 4474 | .v.func = alc283_fixup_chromebook, |
4475 | }, | 4475 | }, |
4476 | [ALC283_FIXUP_SENSE_COMBO_JACK] = { | 4476 | [ALC283_FIXUP_SENSE_COMBO_JACK] = { |
4477 | .type = HDA_FIXUP_FUNC, | 4477 | .type = HDA_FIXUP_FUNC, |
4478 | .v.func = alc283_fixup_sense_combo_jack, | 4478 | .v.func = alc283_fixup_sense_combo_jack, |
4479 | .chained = true, | 4479 | .chained = true, |
4480 | .chain_id = ALC283_FIXUP_CHROME_BOOK, | 4480 | .chain_id = ALC283_FIXUP_CHROME_BOOK, |
4481 | }, | 4481 | }, |
4482 | [ALC282_FIXUP_ASUS_TX300] = { | 4482 | [ALC282_FIXUP_ASUS_TX300] = { |
4483 | .type = HDA_FIXUP_FUNC, | 4483 | .type = HDA_FIXUP_FUNC, |
4484 | .v.func = alc282_fixup_asus_tx300, | 4484 | .v.func = alc282_fixup_asus_tx300, |
4485 | }, | 4485 | }, |
4486 | [ALC283_FIXUP_INT_MIC] = { | 4486 | [ALC283_FIXUP_INT_MIC] = { |
4487 | .type = HDA_FIXUP_VERBS, | 4487 | .type = HDA_FIXUP_VERBS, |
4488 | .v.verbs = (const struct hda_verb[]) { | 4488 | .v.verbs = (const struct hda_verb[]) { |
4489 | {0x20, AC_VERB_SET_COEF_INDEX, 0x1a}, | 4489 | {0x20, AC_VERB_SET_COEF_INDEX, 0x1a}, |
4490 | {0x20, AC_VERB_SET_PROC_COEF, 0x0011}, | 4490 | {0x20, AC_VERB_SET_PROC_COEF, 0x0011}, |
4491 | { } | 4491 | { } |
4492 | }, | 4492 | }, |
4493 | .chained = true, | 4493 | .chained = true, |
4494 | .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST | 4494 | .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST |
4495 | }, | 4495 | }, |
4496 | [ALC290_FIXUP_SUBWOOFER_HSJACK] = { | 4496 | [ALC290_FIXUP_SUBWOOFER_HSJACK] = { |
4497 | .type = HDA_FIXUP_PINS, | 4497 | .type = HDA_FIXUP_PINS, |
4498 | .v.pins = (const struct hda_pintbl[]) { | 4498 | .v.pins = (const struct hda_pintbl[]) { |
4499 | { 0x17, 0x90170112 }, /* subwoofer */ | 4499 | { 0x17, 0x90170112 }, /* subwoofer */ |
4500 | { } | 4500 | { } |
4501 | }, | 4501 | }, |
4502 | .chained = true, | 4502 | .chained = true, |
4503 | .chain_id = ALC290_FIXUP_MONO_SPEAKERS_HSJACK, | 4503 | .chain_id = ALC290_FIXUP_MONO_SPEAKERS_HSJACK, |
4504 | }, | 4504 | }, |
4505 | [ALC290_FIXUP_SUBWOOFER] = { | 4505 | [ALC290_FIXUP_SUBWOOFER] = { |
4506 | .type = HDA_FIXUP_PINS, | 4506 | .type = HDA_FIXUP_PINS, |
4507 | .v.pins = (const struct hda_pintbl[]) { | 4507 | .v.pins = (const struct hda_pintbl[]) { |
4508 | { 0x17, 0x90170112 }, /* subwoofer */ | 4508 | { 0x17, 0x90170112 }, /* subwoofer */ |
4509 | { } | 4509 | { } |
4510 | }, | 4510 | }, |
4511 | .chained = true, | 4511 | .chained = true, |
4512 | .chain_id = ALC290_FIXUP_MONO_SPEAKERS, | 4512 | .chain_id = ALC290_FIXUP_MONO_SPEAKERS, |
4513 | }, | 4513 | }, |
4514 | [ALC290_FIXUP_MONO_SPEAKERS] = { | 4514 | [ALC290_FIXUP_MONO_SPEAKERS] = { |
4515 | .type = HDA_FIXUP_FUNC, | 4515 | .type = HDA_FIXUP_FUNC, |
4516 | .v.func = alc290_fixup_mono_speakers, | 4516 | .v.func = alc290_fixup_mono_speakers, |
4517 | }, | 4517 | }, |
4518 | [ALC290_FIXUP_MONO_SPEAKERS_HSJACK] = { | 4518 | [ALC290_FIXUP_MONO_SPEAKERS_HSJACK] = { |
4519 | .type = HDA_FIXUP_FUNC, | 4519 | .type = HDA_FIXUP_FUNC, |
4520 | .v.func = alc290_fixup_mono_speakers, | 4520 | .v.func = alc290_fixup_mono_speakers, |
4521 | .chained = true, | 4521 | .chained = true, |
4522 | .chain_id = ALC269_FIXUP_DELL3_MIC_NO_PRESENCE, | 4522 | .chain_id = ALC269_FIXUP_DELL3_MIC_NO_PRESENCE, |
4523 | }, | 4523 | }, |
4524 | [ALC269_FIXUP_THINKPAD_ACPI] = { | 4524 | [ALC269_FIXUP_THINKPAD_ACPI] = { |
4525 | .type = HDA_FIXUP_FUNC, | 4525 | .type = HDA_FIXUP_FUNC, |
4526 | .v.func = hda_fixup_thinkpad_acpi, | 4526 | .v.func = hda_fixup_thinkpad_acpi, |
4527 | }, | 4527 | }, |
4528 | [ALC255_FIXUP_DELL1_MIC_NO_PRESENCE] = { | 4528 | [ALC255_FIXUP_DELL1_MIC_NO_PRESENCE] = { |
4529 | .type = HDA_FIXUP_PINS, | 4529 | .type = HDA_FIXUP_PINS, |
4530 | .v.pins = (const struct hda_pintbl[]) { | 4530 | .v.pins = (const struct hda_pintbl[]) { |
4531 | { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */ | 4531 | { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */ |
4532 | { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */ | 4532 | { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */ |
4533 | { } | 4533 | { } |
4534 | }, | 4534 | }, |
4535 | .chained = true, | 4535 | .chained = true, |
4536 | .chain_id = ALC255_FIXUP_HEADSET_MODE | 4536 | .chain_id = ALC255_FIXUP_HEADSET_MODE |
4537 | }, | 4537 | }, |
4538 | [ALC255_FIXUP_DELL2_MIC_NO_PRESENCE] = { | 4538 | [ALC255_FIXUP_DELL2_MIC_NO_PRESENCE] = { |
4539 | .type = HDA_FIXUP_PINS, | 4539 | .type = HDA_FIXUP_PINS, |
4540 | .v.pins = (const struct hda_pintbl[]) { | 4540 | .v.pins = (const struct hda_pintbl[]) { |
4541 | { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */ | 4541 | { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */ |
4542 | { } | 4542 | { } |
4543 | }, | 4543 | }, |
4544 | .chained = true, | 4544 | .chained = true, |
4545 | .chain_id = ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC | 4545 | .chain_id = ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC |
4546 | }, | 4546 | }, |
4547 | [ALC255_FIXUP_HEADSET_MODE] = { | 4547 | [ALC255_FIXUP_HEADSET_MODE] = { |
4548 | .type = HDA_FIXUP_FUNC, | 4548 | .type = HDA_FIXUP_FUNC, |
4549 | .v.func = alc_fixup_headset_mode_alc255, | 4549 | .v.func = alc_fixup_headset_mode_alc255, |
4550 | }, | 4550 | }, |
4551 | [ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC] = { | 4551 | [ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC] = { |
4552 | .type = HDA_FIXUP_FUNC, | 4552 | .type = HDA_FIXUP_FUNC, |
4553 | .v.func = alc_fixup_headset_mode_alc255_no_hp_mic, | 4553 | .v.func = alc_fixup_headset_mode_alc255_no_hp_mic, |
4554 | }, | 4554 | }, |
4555 | }; | 4555 | }; |
4556 | 4556 | ||
4557 | static const struct snd_pci_quirk alc269_fixup_tbl[] = { | 4557 | static const struct snd_pci_quirk alc269_fixup_tbl[] = { |
4558 | SND_PCI_QUIRK(0x1025, 0x0283, "Acer TravelMate 8371", ALC269_FIXUP_INV_DMIC), | 4558 | SND_PCI_QUIRK(0x1025, 0x0283, "Acer TravelMate 8371", ALC269_FIXUP_INV_DMIC), |
4559 | SND_PCI_QUIRK(0x1025, 0x029b, "Acer 1810TZ", ALC269_FIXUP_INV_DMIC), | 4559 | SND_PCI_QUIRK(0x1025, 0x029b, "Acer 1810TZ", ALC269_FIXUP_INV_DMIC), |
4560 | SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC), | 4560 | SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC), |
4561 | SND_PCI_QUIRK(0x1025, 0x047c, "Acer AC700", ALC269_FIXUP_ACER_AC700), | 4561 | SND_PCI_QUIRK(0x1025, 0x047c, "Acer AC700", ALC269_FIXUP_ACER_AC700), |
4562 | SND_PCI_QUIRK(0x1025, 0x0740, "Acer AO725", ALC271_FIXUP_HP_GATE_MIC_JACK), | 4562 | SND_PCI_QUIRK(0x1025, 0x0740, "Acer AO725", ALC271_FIXUP_HP_GATE_MIC_JACK), |
4563 | SND_PCI_QUIRK(0x1025, 0x0742, "Acer AO756", ALC271_FIXUP_HP_GATE_MIC_JACK), | 4563 | SND_PCI_QUIRK(0x1025, 0x0742, "Acer AO756", ALC271_FIXUP_HP_GATE_MIC_JACK), |
4564 | SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC), | 4564 | SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC), |
4565 | SND_PCI_QUIRK(0x1025, 0x0775, "Acer Aspire E1-572", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572), | 4565 | SND_PCI_QUIRK(0x1025, 0x0775, "Acer Aspire E1-572", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572), |
4566 | SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), | 4566 | SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), |
4567 | SND_PCI_QUIRK(0x1028, 0x05bd, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), | 4567 | SND_PCI_QUIRK(0x1028, 0x05bd, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), |
4568 | SND_PCI_QUIRK(0x1028, 0x05be, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), | 4568 | SND_PCI_QUIRK(0x1028, 0x05be, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), |
4569 | SND_PCI_QUIRK(0x1028, 0x05c4, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4569 | SND_PCI_QUIRK(0x1028, 0x05c4, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4570 | SND_PCI_QUIRK(0x1028, 0x05c5, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4570 | SND_PCI_QUIRK(0x1028, 0x05c5, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4571 | SND_PCI_QUIRK(0x1028, 0x05c6, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4571 | SND_PCI_QUIRK(0x1028, 0x05c6, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4572 | SND_PCI_QUIRK(0x1028, 0x05c7, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4572 | SND_PCI_QUIRK(0x1028, 0x05c7, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4573 | SND_PCI_QUIRK(0x1028, 0x05c8, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4573 | SND_PCI_QUIRK(0x1028, 0x05c8, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4574 | SND_PCI_QUIRK(0x1028, 0x05c9, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4574 | SND_PCI_QUIRK(0x1028, 0x05c9, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4575 | SND_PCI_QUIRK(0x1028, 0x05ca, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), | 4575 | SND_PCI_QUIRK(0x1028, 0x05ca, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), |
4576 | SND_PCI_QUIRK(0x1028, 0x05cb, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), | 4576 | SND_PCI_QUIRK(0x1028, 0x05cb, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), |
4577 | SND_PCI_QUIRK(0x1028, 0x05cc, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), | 4577 | SND_PCI_QUIRK(0x1028, 0x05cc, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), |
4578 | SND_PCI_QUIRK(0x1028, 0x05cd, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), | 4578 | SND_PCI_QUIRK(0x1028, 0x05cd, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), |
4579 | SND_PCI_QUIRK(0x1028, 0x05da, "Dell Vostro 5460", ALC290_FIXUP_SUBWOOFER), | 4579 | SND_PCI_QUIRK(0x1028, 0x05da, "Dell Vostro 5460", ALC290_FIXUP_SUBWOOFER), |
4580 | SND_PCI_QUIRK(0x1028, 0x05de, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), | 4580 | SND_PCI_QUIRK(0x1028, 0x05de, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), |
4581 | SND_PCI_QUIRK(0x1028, 0x05e0, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), | 4581 | SND_PCI_QUIRK(0x1028, 0x05e0, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), |
4582 | SND_PCI_QUIRK(0x1028, 0x05e9, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4582 | SND_PCI_QUIRK(0x1028, 0x05e9, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4583 | SND_PCI_QUIRK(0x1028, 0x05ea, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4583 | SND_PCI_QUIRK(0x1028, 0x05ea, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4584 | SND_PCI_QUIRK(0x1028, 0x05eb, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4584 | SND_PCI_QUIRK(0x1028, 0x05eb, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4585 | SND_PCI_QUIRK(0x1028, 0x05ec, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4585 | SND_PCI_QUIRK(0x1028, 0x05ec, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4586 | SND_PCI_QUIRK(0x1028, 0x05ed, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4586 | SND_PCI_QUIRK(0x1028, 0x05ed, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4587 | SND_PCI_QUIRK(0x1028, 0x05ee, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4587 | SND_PCI_QUIRK(0x1028, 0x05ee, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4588 | SND_PCI_QUIRK(0x1028, 0x05f3, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4588 | SND_PCI_QUIRK(0x1028, 0x05f3, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4589 | SND_PCI_QUIRK(0x1028, 0x05f4, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4589 | SND_PCI_QUIRK(0x1028, 0x05f4, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4590 | SND_PCI_QUIRK(0x1028, 0x05f5, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4590 | SND_PCI_QUIRK(0x1028, 0x05f5, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4591 | SND_PCI_QUIRK(0x1028, 0x05f6, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4591 | SND_PCI_QUIRK(0x1028, 0x05f6, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4592 | SND_PCI_QUIRK(0x1028, 0x05f8, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4592 | SND_PCI_QUIRK(0x1028, 0x05f8, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4593 | SND_PCI_QUIRK(0x1028, 0x05f9, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4593 | SND_PCI_QUIRK(0x1028, 0x05f9, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4594 | SND_PCI_QUIRK(0x1028, 0x05fb, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4594 | SND_PCI_QUIRK(0x1028, 0x05fb, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4595 | SND_PCI_QUIRK(0x1028, 0x0606, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4595 | SND_PCI_QUIRK(0x1028, 0x0606, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4596 | SND_PCI_QUIRK(0x1028, 0x0608, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4596 | SND_PCI_QUIRK(0x1028, 0x0608, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4597 | SND_PCI_QUIRK(0x1028, 0x0609, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4597 | SND_PCI_QUIRK(0x1028, 0x0609, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4598 | SND_PCI_QUIRK(0x1028, 0x060f, "Dell", ALC269_FIXUP_DELL3_MIC_NO_PRESENCE), | 4598 | SND_PCI_QUIRK(0x1028, 0x060f, "Dell", ALC269_FIXUP_DELL3_MIC_NO_PRESENCE), |
4599 | SND_PCI_QUIRK(0x1028, 0x0610, "Dell", ALC269_FIXUP_DELL3_MIC_NO_PRESENCE), | 4599 | SND_PCI_QUIRK(0x1028, 0x0610, "Dell", ALC269_FIXUP_DELL3_MIC_NO_PRESENCE), |
4600 | SND_PCI_QUIRK(0x1028, 0x0613, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4600 | SND_PCI_QUIRK(0x1028, 0x0613, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4601 | SND_PCI_QUIRK(0x1028, 0x0614, "Dell Inspiron 3135", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4601 | SND_PCI_QUIRK(0x1028, 0x0614, "Dell Inspiron 3135", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4602 | SND_PCI_QUIRK(0x1028, 0x0615, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK), | 4602 | SND_PCI_QUIRK(0x1028, 0x0615, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK), |
4603 | SND_PCI_QUIRK(0x1028, 0x0616, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK), | 4603 | SND_PCI_QUIRK(0x1028, 0x0616, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK), |
4604 | SND_PCI_QUIRK(0x1028, 0x061f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4604 | SND_PCI_QUIRK(0x1028, 0x061f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4605 | SND_PCI_QUIRK(0x1028, 0x0629, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4605 | SND_PCI_QUIRK(0x1028, 0x0629, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4606 | SND_PCI_QUIRK(0x1028, 0x062c, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4606 | SND_PCI_QUIRK(0x1028, 0x062c, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4607 | SND_PCI_QUIRK(0x1028, 0x062e, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4607 | SND_PCI_QUIRK(0x1028, 0x062e, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4608 | SND_PCI_QUIRK(0x1028, 0x0632, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4608 | SND_PCI_QUIRK(0x1028, 0x0632, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4609 | SND_PCI_QUIRK(0x1028, 0x0638, "Dell Inspiron 5439", ALC290_FIXUP_MONO_SPEAKERS_HSJACK), | 4609 | SND_PCI_QUIRK(0x1028, 0x0638, "Dell Inspiron 5439", ALC290_FIXUP_MONO_SPEAKERS_HSJACK), |
4610 | SND_PCI_QUIRK(0x1028, 0x063e, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4610 | SND_PCI_QUIRK(0x1028, 0x063e, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4611 | SND_PCI_QUIRK(0x1028, 0x063f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4611 | SND_PCI_QUIRK(0x1028, 0x063f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4612 | SND_PCI_QUIRK(0x1028, 0x0640, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4612 | SND_PCI_QUIRK(0x1028, 0x0640, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4613 | SND_PCI_QUIRK(0x1028, 0x064d, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4613 | SND_PCI_QUIRK(0x1028, 0x064d, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4614 | SND_PCI_QUIRK(0x1028, 0x0651, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4614 | SND_PCI_QUIRK(0x1028, 0x0651, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4615 | SND_PCI_QUIRK(0x1028, 0x0652, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4615 | SND_PCI_QUIRK(0x1028, 0x0652, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4616 | SND_PCI_QUIRK(0x1028, 0x0653, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4616 | SND_PCI_QUIRK(0x1028, 0x0653, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4617 | SND_PCI_QUIRK(0x1028, 0x0657, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4617 | SND_PCI_QUIRK(0x1028, 0x0657, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4618 | SND_PCI_QUIRK(0x1028, 0x0658, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4618 | SND_PCI_QUIRK(0x1028, 0x0658, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4619 | SND_PCI_QUIRK(0x1028, 0x065f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4619 | SND_PCI_QUIRK(0x1028, 0x065f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4620 | SND_PCI_QUIRK(0x1028, 0x0662, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4620 | SND_PCI_QUIRK(0x1028, 0x0662, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4621 | SND_PCI_QUIRK(0x1028, 0x0667, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4621 | SND_PCI_QUIRK(0x1028, 0x0667, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4622 | SND_PCI_QUIRK(0x1028, 0x0668, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE), | 4622 | SND_PCI_QUIRK(0x1028, 0x0668, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE), |
4623 | SND_PCI_QUIRK(0x1028, 0x0669, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE), | 4623 | SND_PCI_QUIRK(0x1028, 0x0669, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE), |
4624 | SND_PCI_QUIRK(0x1028, 0x0674, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | ||
4624 | SND_PCI_QUIRK(0x1028, 0x067f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4625 | SND_PCI_QUIRK(0x1028, 0x067f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4625 | SND_PCI_QUIRK(0x1028, 0x15cc, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), | 4626 | SND_PCI_QUIRK(0x1028, 0x15cc, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), |
4626 | SND_PCI_QUIRK(0x1028, 0x15cd, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), | 4627 | SND_PCI_QUIRK(0x1028, 0x15cd, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), |
4627 | SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2), | 4628 | SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2), |
4628 | SND_PCI_QUIRK(0x103c, 0x18e6, "HP", ALC269_FIXUP_HP_GPIO_LED), | 4629 | SND_PCI_QUIRK(0x103c, 0x18e6, "HP", ALC269_FIXUP_HP_GPIO_LED), |
4629 | SND_PCI_QUIRK(0x103c, 0x1973, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4630 | SND_PCI_QUIRK(0x103c, 0x1973, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4630 | SND_PCI_QUIRK(0x103c, 0x1983, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4631 | SND_PCI_QUIRK(0x103c, 0x1983, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4631 | SND_PCI_QUIRK(0x103c, 0x218b, "HP", ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED), | 4632 | SND_PCI_QUIRK(0x103c, 0x218b, "HP", ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED), |
4632 | /* ALC282 */ | 4633 | /* ALC282 */ |
4633 | SND_PCI_QUIRK(0x103c, 0x220f, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4634 | SND_PCI_QUIRK(0x103c, 0x220f, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4634 | SND_PCI_QUIRK(0x103c, 0x2213, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4635 | SND_PCI_QUIRK(0x103c, 0x2213, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4635 | SND_PCI_QUIRK(0x103c, 0x2266, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4636 | SND_PCI_QUIRK(0x103c, 0x2266, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4636 | SND_PCI_QUIRK(0x103c, 0x2267, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4637 | SND_PCI_QUIRK(0x103c, 0x2267, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4637 | SND_PCI_QUIRK(0x103c, 0x2268, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4638 | SND_PCI_QUIRK(0x103c, 0x2268, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4638 | SND_PCI_QUIRK(0x103c, 0x2269, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4639 | SND_PCI_QUIRK(0x103c, 0x2269, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4639 | SND_PCI_QUIRK(0x103c, 0x226a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4640 | SND_PCI_QUIRK(0x103c, 0x226a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4640 | SND_PCI_QUIRK(0x103c, 0x226b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4641 | SND_PCI_QUIRK(0x103c, 0x226b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4641 | SND_PCI_QUIRK(0x103c, 0x227a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4642 | SND_PCI_QUIRK(0x103c, 0x227a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4642 | SND_PCI_QUIRK(0x103c, 0x227b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4643 | SND_PCI_QUIRK(0x103c, 0x227b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4643 | SND_PCI_QUIRK(0x103c, 0x229e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4644 | SND_PCI_QUIRK(0x103c, 0x229e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4644 | SND_PCI_QUIRK(0x103c, 0x22a0, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4645 | SND_PCI_QUIRK(0x103c, 0x22a0, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4645 | SND_PCI_QUIRK(0x103c, 0x22b2, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4646 | SND_PCI_QUIRK(0x103c, 0x22b2, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4646 | SND_PCI_QUIRK(0x103c, 0x22b7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4647 | SND_PCI_QUIRK(0x103c, 0x22b7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4647 | SND_PCI_QUIRK(0x103c, 0x22bf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4648 | SND_PCI_QUIRK(0x103c, 0x22bf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4648 | SND_PCI_QUIRK(0x103c, 0x22c0, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4649 | SND_PCI_QUIRK(0x103c, 0x22c0, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4649 | SND_PCI_QUIRK(0x103c, 0x22c1, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4650 | SND_PCI_QUIRK(0x103c, 0x22c1, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4650 | SND_PCI_QUIRK(0x103c, 0x22c2, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4651 | SND_PCI_QUIRK(0x103c, 0x22c2, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4651 | SND_PCI_QUIRK(0x103c, 0x22cd, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4652 | SND_PCI_QUIRK(0x103c, 0x22cd, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4652 | SND_PCI_QUIRK(0x103c, 0x22ce, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4653 | SND_PCI_QUIRK(0x103c, 0x22ce, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4653 | SND_PCI_QUIRK(0x103c, 0x22cf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4654 | SND_PCI_QUIRK(0x103c, 0x22cf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4654 | SND_PCI_QUIRK(0x103c, 0x22d0, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4655 | SND_PCI_QUIRK(0x103c, 0x22d0, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4655 | /* ALC290 */ | 4656 | /* ALC290 */ |
4656 | SND_PCI_QUIRK(0x103c, 0x2260, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4657 | SND_PCI_QUIRK(0x103c, 0x2260, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4657 | SND_PCI_QUIRK(0x103c, 0x2261, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4658 | SND_PCI_QUIRK(0x103c, 0x2261, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4658 | SND_PCI_QUIRK(0x103c, 0x2262, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4659 | SND_PCI_QUIRK(0x103c, 0x2262, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4659 | SND_PCI_QUIRK(0x103c, 0x2263, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4660 | SND_PCI_QUIRK(0x103c, 0x2263, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4660 | SND_PCI_QUIRK(0x103c, 0x2264, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4661 | SND_PCI_QUIRK(0x103c, 0x2264, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4661 | SND_PCI_QUIRK(0x103c, 0x2265, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4662 | SND_PCI_QUIRK(0x103c, 0x2265, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4662 | SND_PCI_QUIRK(0x103c, 0x227d, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4663 | SND_PCI_QUIRK(0x103c, 0x227d, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4663 | SND_PCI_QUIRK(0x103c, 0x227e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4664 | SND_PCI_QUIRK(0x103c, 0x227e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4664 | SND_PCI_QUIRK(0x103c, 0x227f, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4665 | SND_PCI_QUIRK(0x103c, 0x227f, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4665 | SND_PCI_QUIRK(0x103c, 0x2280, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4666 | SND_PCI_QUIRK(0x103c, 0x2280, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4666 | SND_PCI_QUIRK(0x103c, 0x2281, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4667 | SND_PCI_QUIRK(0x103c, 0x2281, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4667 | SND_PCI_QUIRK(0x103c, 0x2282, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4668 | SND_PCI_QUIRK(0x103c, 0x2282, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4668 | SND_PCI_QUIRK(0x103c, 0x2289, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4669 | SND_PCI_QUIRK(0x103c, 0x2289, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4669 | SND_PCI_QUIRK(0x103c, 0x228a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4670 | SND_PCI_QUIRK(0x103c, 0x228a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4670 | SND_PCI_QUIRK(0x103c, 0x228b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4671 | SND_PCI_QUIRK(0x103c, 0x228b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4671 | SND_PCI_QUIRK(0x103c, 0x228c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4672 | SND_PCI_QUIRK(0x103c, 0x228c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4672 | SND_PCI_QUIRK(0x103c, 0x228d, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4673 | SND_PCI_QUIRK(0x103c, 0x228d, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4673 | SND_PCI_QUIRK(0x103c, 0x228e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4674 | SND_PCI_QUIRK(0x103c, 0x228e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4674 | SND_PCI_QUIRK(0x103c, 0x22c5, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4675 | SND_PCI_QUIRK(0x103c, 0x22c5, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4675 | SND_PCI_QUIRK(0x103c, 0x22c6, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4676 | SND_PCI_QUIRK(0x103c, 0x22c6, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4676 | SND_PCI_QUIRK(0x103c, 0x22c7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4677 | SND_PCI_QUIRK(0x103c, 0x22c7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4677 | SND_PCI_QUIRK(0x103c, 0x22c8, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4678 | SND_PCI_QUIRK(0x103c, 0x22c8, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4678 | SND_PCI_QUIRK(0x103c, 0x22c3, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4679 | SND_PCI_QUIRK(0x103c, 0x22c3, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4679 | SND_PCI_QUIRK(0x103c, 0x22c4, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4680 | SND_PCI_QUIRK(0x103c, 0x22c4, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4680 | SND_PCI_QUIRK_VENDOR(0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED), | 4681 | SND_PCI_QUIRK_VENDOR(0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED), |
4681 | SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300), | 4682 | SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300), |
4682 | SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), | 4683 | SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
4683 | SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), | 4684 | SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
4684 | SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK), | 4685 | SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK), |
4685 | SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A), | 4686 | SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A), |
4686 | SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC), | 4687 | SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC), |
4687 | SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), | 4688 | SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), |
4688 | SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC), | 4689 | SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC), |
4689 | SND_PCI_QUIRK(0x1043, 0x1c23, "Asus X55U", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), | 4690 | SND_PCI_QUIRK(0x1043, 0x1c23, "Asus X55U", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
4690 | SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC), | 4691 | SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC), |
4691 | SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC), | 4692 | SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC), |
4692 | SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC), | 4693 | SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC), |
4693 | SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC), | 4694 | SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC), |
4694 | SND_PCI_QUIRK(0x1043, 0x8516, "ASUS X101CH", ALC269_FIXUP_ASUS_X101), | 4695 | SND_PCI_QUIRK(0x1043, 0x8516, "ASUS X101CH", ALC269_FIXUP_ASUS_X101), |
4695 | SND_PCI_QUIRK(0x104d, 0x90b5, "Sony VAIO Pro 11", ALC286_FIXUP_SONY_MIC_NO_PRESENCE), | 4696 | SND_PCI_QUIRK(0x104d, 0x90b5, "Sony VAIO Pro 11", ALC286_FIXUP_SONY_MIC_NO_PRESENCE), |
4696 | SND_PCI_QUIRK(0x104d, 0x90b6, "Sony VAIO Pro 13", ALC286_FIXUP_SONY_MIC_NO_PRESENCE), | 4697 | SND_PCI_QUIRK(0x104d, 0x90b6, "Sony VAIO Pro 13", ALC286_FIXUP_SONY_MIC_NO_PRESENCE), |
4697 | SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2), | 4698 | SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2), |
4698 | SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), | 4699 | SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), |
4699 | SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), | 4700 | SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), |
4700 | SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), | 4701 | SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), |
4701 | SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook", ALC269_FIXUP_LIFEBOOK), | 4702 | SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook", ALC269_FIXUP_LIFEBOOK), |
4702 | SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE), | 4703 | SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE), |
4703 | SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE), | 4704 | SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE), |
4704 | SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE), | 4705 | SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE), |
4705 | SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE), | 4706 | SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE), |
4706 | SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE), | 4707 | SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE), |
4707 | SND_PCI_QUIRK(0x17aa, 0x21f6, "Thinkpad T530", ALC269_FIXUP_LENOVO_DOCK), | 4708 | SND_PCI_QUIRK(0x17aa, 0x21f6, "Thinkpad T530", ALC269_FIXUP_LENOVO_DOCK), |
4708 | SND_PCI_QUIRK(0x17aa, 0x21fa, "Thinkpad X230", ALC269_FIXUP_LENOVO_DOCK), | 4709 | SND_PCI_QUIRK(0x17aa, 0x21fa, "Thinkpad X230", ALC269_FIXUP_LENOVO_DOCK), |
4709 | SND_PCI_QUIRK(0x17aa, 0x21f3, "Thinkpad T430", ALC269_FIXUP_LENOVO_DOCK), | 4710 | SND_PCI_QUIRK(0x17aa, 0x21f3, "Thinkpad T430", ALC269_FIXUP_LENOVO_DOCK), |
4710 | SND_PCI_QUIRK(0x17aa, 0x21fb, "Thinkpad T430s", ALC269_FIXUP_LENOVO_DOCK), | 4711 | SND_PCI_QUIRK(0x17aa, 0x21fb, "Thinkpad T430s", ALC269_FIXUP_LENOVO_DOCK), |
4711 | SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK), | 4712 | SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK), |
4712 | SND_PCI_QUIRK(0x17aa, 0x2208, "Thinkpad T431s", ALC269_FIXUP_LENOVO_DOCK), | 4713 | SND_PCI_QUIRK(0x17aa, 0x2208, "Thinkpad T431s", ALC269_FIXUP_LENOVO_DOCK), |
4713 | SND_PCI_QUIRK(0x17aa, 0x220c, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), | 4714 | SND_PCI_QUIRK(0x17aa, 0x220c, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
4714 | SND_PCI_QUIRK(0x17aa, 0x2212, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), | 4715 | SND_PCI_QUIRK(0x17aa, 0x2212, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
4715 | SND_PCI_QUIRK(0x17aa, 0x2214, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), | 4716 | SND_PCI_QUIRK(0x17aa, 0x2214, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
4716 | SND_PCI_QUIRK(0x17aa, 0x2215, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), | 4717 | SND_PCI_QUIRK(0x17aa, 0x2215, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
4717 | SND_PCI_QUIRK(0x17aa, 0x3978, "IdeaPad Y410P", ALC269_FIXUP_NO_SHUTUP), | 4718 | SND_PCI_QUIRK(0x17aa, 0x3978, "IdeaPad Y410P", ALC269_FIXUP_NO_SHUTUP), |
4718 | SND_PCI_QUIRK(0x17aa, 0x5013, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), | 4719 | SND_PCI_QUIRK(0x17aa, 0x5013, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
4719 | SND_PCI_QUIRK(0x17aa, 0x501a, "Thinkpad", ALC283_FIXUP_INT_MIC), | 4720 | SND_PCI_QUIRK(0x17aa, 0x501a, "Thinkpad", ALC283_FIXUP_INT_MIC), |
4720 | SND_PCI_QUIRK(0x17aa, 0x5026, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), | 4721 | SND_PCI_QUIRK(0x17aa, 0x5026, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
4721 | SND_PCI_QUIRK(0x17aa, 0x5109, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), | 4722 | SND_PCI_QUIRK(0x17aa, 0x5109, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
4722 | SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K), | 4723 | SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K), |
4723 | SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD), | 4724 | SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD), |
4724 | SND_PCI_QUIRK_VENDOR(0x17aa, "Thinkpad", ALC269_FIXUP_THINKPAD_ACPI), | 4725 | SND_PCI_QUIRK_VENDOR(0x17aa, "Thinkpad", ALC269_FIXUP_THINKPAD_ACPI), |
4725 | SND_PCI_QUIRK(0x1b7d, 0xa831, "Ordissimo EVE2 ", ALC269VB_FIXUP_ORDISSIMO_EVE2), /* Also known as Malata PC-B1303 */ | 4726 | SND_PCI_QUIRK(0x1b7d, 0xa831, "Ordissimo EVE2 ", ALC269VB_FIXUP_ORDISSIMO_EVE2), /* Also known as Malata PC-B1303 */ |
4726 | 4727 | ||
4727 | #if 0 | 4728 | #if 0 |
4728 | /* Below is a quirk table taken from the old code. | 4729 | /* Below is a quirk table taken from the old code. |
4729 | * Basically the device should work as is without the fixup table. | 4730 | * Basically the device should work as is without the fixup table. |
4730 | * If BIOS doesn't give a proper info, enable the corresponding | 4731 | * If BIOS doesn't give a proper info, enable the corresponding |
4731 | * fixup entry. | 4732 | * fixup entry. |
4732 | */ | 4733 | */ |
4733 | SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A", | 4734 | SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A", |
4734 | ALC269_FIXUP_AMIC), | 4735 | ALC269_FIXUP_AMIC), |
4735 | SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269_FIXUP_AMIC), | 4736 | SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269_FIXUP_AMIC), |
4736 | SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269_FIXUP_AMIC), | 4737 | SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269_FIXUP_AMIC), |
4737 | SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_FIXUP_AMIC), | 4738 | SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_FIXUP_AMIC), |
4738 | SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269_FIXUP_AMIC), | 4739 | SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269_FIXUP_AMIC), |
4739 | SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269_FIXUP_AMIC), | 4740 | SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269_FIXUP_AMIC), |
4740 | SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269_FIXUP_AMIC), | 4741 | SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269_FIXUP_AMIC), |
4741 | SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269_FIXUP_AMIC), | 4742 | SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269_FIXUP_AMIC), |
4742 | SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_FIXUP_AMIC), | 4743 | SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_FIXUP_AMIC), |
4743 | SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269_FIXUP_AMIC), | 4744 | SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269_FIXUP_AMIC), |
4744 | SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_FIXUP_AMIC), | 4745 | SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_FIXUP_AMIC), |
4745 | SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_FIXUP_AMIC), | 4746 | SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_FIXUP_AMIC), |
4746 | SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_FIXUP_AMIC), | 4747 | SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_FIXUP_AMIC), |
4747 | SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_FIXUP_AMIC), | 4748 | SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_FIXUP_AMIC), |
4748 | SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_FIXUP_AMIC), | 4749 | SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_FIXUP_AMIC), |
4749 | SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_FIXUP_AMIC), | 4750 | SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_FIXUP_AMIC), |
4750 | SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_FIXUP_AMIC), | 4751 | SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_FIXUP_AMIC), |
4751 | SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_FIXUP_AMIC), | 4752 | SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_FIXUP_AMIC), |
4752 | SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_FIXUP_AMIC), | 4753 | SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_FIXUP_AMIC), |
4753 | SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_FIXUP_AMIC), | 4754 | SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_FIXUP_AMIC), |
4754 | SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_FIXUP_AMIC), | 4755 | SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_FIXUP_AMIC), |
4755 | SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_FIXUP_AMIC), | 4756 | SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_FIXUP_AMIC), |
4756 | SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_FIXUP_AMIC), | 4757 | SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_FIXUP_AMIC), |
4757 | SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_FIXUP_AMIC), | 4758 | SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_FIXUP_AMIC), |
4758 | SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_FIXUP_AMIC), | 4759 | SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_FIXUP_AMIC), |
4759 | SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_FIXUP_AMIC), | 4760 | SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_FIXUP_AMIC), |
4760 | SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_FIXUP_AMIC), | 4761 | SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_FIXUP_AMIC), |
4761 | SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_FIXUP_AMIC), | 4762 | SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_FIXUP_AMIC), |
4762 | SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_FIXUP_AMIC), | 4763 | SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_FIXUP_AMIC), |
4763 | SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_FIXUP_AMIC), | 4764 | SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_FIXUP_AMIC), |
4764 | SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_FIXUP_AMIC), | 4765 | SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_FIXUP_AMIC), |
4765 | SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_FIXUP_AMIC), | 4766 | SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_FIXUP_AMIC), |
4766 | SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_FIXUP_AMIC), | 4767 | SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_FIXUP_AMIC), |
4767 | SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_FIXUP_AMIC), | 4768 | SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_FIXUP_AMIC), |
4768 | SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_FIXUP_AMIC), | 4769 | SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_FIXUP_AMIC), |
4769 | SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_FIXUP_DMIC), | 4770 | SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_FIXUP_DMIC), |
4770 | SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_FIXUP_AMIC), | 4771 | SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_FIXUP_AMIC), |
4771 | SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_AMIC), | 4772 | SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_AMIC), |
4772 | SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_FIXUP_DMIC), | 4773 | SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_FIXUP_DMIC), |
4773 | SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_FIXUP_DMIC), | 4774 | SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_FIXUP_DMIC), |
4774 | #endif | 4775 | #endif |
4775 | {} | 4776 | {} |
4776 | }; | 4777 | }; |
4777 | 4778 | ||
4778 | static const struct hda_model_fixup alc269_fixup_models[] = { | 4779 | static const struct hda_model_fixup alc269_fixup_models[] = { |
4779 | {.id = ALC269_FIXUP_AMIC, .name = "laptop-amic"}, | 4780 | {.id = ALC269_FIXUP_AMIC, .name = "laptop-amic"}, |
4780 | {.id = ALC269_FIXUP_DMIC, .name = "laptop-dmic"}, | 4781 | {.id = ALC269_FIXUP_DMIC, .name = "laptop-dmic"}, |
4781 | {.id = ALC269_FIXUP_STEREO_DMIC, .name = "alc269-dmic"}, | 4782 | {.id = ALC269_FIXUP_STEREO_DMIC, .name = "alc269-dmic"}, |
4782 | {.id = ALC271_FIXUP_DMIC, .name = "alc271-dmic"}, | 4783 | {.id = ALC271_FIXUP_DMIC, .name = "alc271-dmic"}, |
4783 | {.id = ALC269_FIXUP_INV_DMIC, .name = "inv-dmic"}, | 4784 | {.id = ALC269_FIXUP_INV_DMIC, .name = "inv-dmic"}, |
4784 | {.id = ALC269_FIXUP_HEADSET_MIC, .name = "headset-mic"}, | 4785 | {.id = ALC269_FIXUP_HEADSET_MIC, .name = "headset-mic"}, |
4785 | {.id = ALC269_FIXUP_LENOVO_DOCK, .name = "lenovo-dock"}, | 4786 | {.id = ALC269_FIXUP_LENOVO_DOCK, .name = "lenovo-dock"}, |
4786 | {.id = ALC269_FIXUP_HP_GPIO_LED, .name = "hp-gpio-led"}, | 4787 | {.id = ALC269_FIXUP_HP_GPIO_LED, .name = "hp-gpio-led"}, |
4787 | {.id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "dell-headset-multi"}, | 4788 | {.id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "dell-headset-multi"}, |
4788 | {.id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE, .name = "dell-headset-dock"}, | 4789 | {.id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE, .name = "dell-headset-dock"}, |
4789 | {.id = ALC283_FIXUP_CHROME_BOOK, .name = "alc283-dac-wcaps"}, | 4790 | {.id = ALC283_FIXUP_CHROME_BOOK, .name = "alc283-dac-wcaps"}, |
4790 | {.id = ALC283_FIXUP_SENSE_COMBO_JACK, .name = "alc283-sense-combo"}, | 4791 | {.id = ALC283_FIXUP_SENSE_COMBO_JACK, .name = "alc283-sense-combo"}, |
4791 | {} | 4792 | {} |
4792 | }; | 4793 | }; |
4793 | 4794 | ||
4794 | 4795 | ||
4795 | static void alc269_fill_coef(struct hda_codec *codec) | 4796 | static void alc269_fill_coef(struct hda_codec *codec) |
4796 | { | 4797 | { |
4797 | struct alc_spec *spec = codec->spec; | 4798 | struct alc_spec *spec = codec->spec; |
4798 | int val; | 4799 | int val; |
4799 | 4800 | ||
4800 | if (spec->codec_variant != ALC269_TYPE_ALC269VB) | 4801 | if (spec->codec_variant != ALC269_TYPE_ALC269VB) |
4801 | return; | 4802 | return; |
4802 | 4803 | ||
4803 | if ((alc_get_coef0(codec) & 0x00ff) < 0x015) { | 4804 | if ((alc_get_coef0(codec) & 0x00ff) < 0x015) { |
4804 | alc_write_coef_idx(codec, 0xf, 0x960b); | 4805 | alc_write_coef_idx(codec, 0xf, 0x960b); |
4805 | alc_write_coef_idx(codec, 0xe, 0x8817); | 4806 | alc_write_coef_idx(codec, 0xe, 0x8817); |
4806 | } | 4807 | } |
4807 | 4808 | ||
4808 | if ((alc_get_coef0(codec) & 0x00ff) == 0x016) { | 4809 | if ((alc_get_coef0(codec) & 0x00ff) == 0x016) { |
4809 | alc_write_coef_idx(codec, 0xf, 0x960b); | 4810 | alc_write_coef_idx(codec, 0xf, 0x960b); |
4810 | alc_write_coef_idx(codec, 0xe, 0x8814); | 4811 | alc_write_coef_idx(codec, 0xe, 0x8814); |
4811 | } | 4812 | } |
4812 | 4813 | ||
4813 | if ((alc_get_coef0(codec) & 0x00ff) == 0x017) { | 4814 | if ((alc_get_coef0(codec) & 0x00ff) == 0x017) { |
4814 | val = alc_read_coef_idx(codec, 0x04); | 4815 | val = alc_read_coef_idx(codec, 0x04); |
4815 | /* Power up output pin */ | 4816 | /* Power up output pin */ |
4816 | alc_write_coef_idx(codec, 0x04, val | (1<<11)); | 4817 | alc_write_coef_idx(codec, 0x04, val | (1<<11)); |
4817 | } | 4818 | } |
4818 | 4819 | ||
4819 | if ((alc_get_coef0(codec) & 0x00ff) == 0x018) { | 4820 | if ((alc_get_coef0(codec) & 0x00ff) == 0x018) { |
4820 | val = alc_read_coef_idx(codec, 0xd); | 4821 | val = alc_read_coef_idx(codec, 0xd); |
4821 | if ((val & 0x0c00) >> 10 != 0x1) { | 4822 | if ((val & 0x0c00) >> 10 != 0x1) { |
4822 | /* Capless ramp up clock control */ | 4823 | /* Capless ramp up clock control */ |
4823 | alc_write_coef_idx(codec, 0xd, val | (1<<10)); | 4824 | alc_write_coef_idx(codec, 0xd, val | (1<<10)); |
4824 | } | 4825 | } |
4825 | val = alc_read_coef_idx(codec, 0x17); | 4826 | val = alc_read_coef_idx(codec, 0x17); |
4826 | if ((val & 0x01c0) >> 6 != 0x4) { | 4827 | if ((val & 0x01c0) >> 6 != 0x4) { |
4827 | /* Class D power on reset */ | 4828 | /* Class D power on reset */ |
4828 | alc_write_coef_idx(codec, 0x17, val | (1<<7)); | 4829 | alc_write_coef_idx(codec, 0x17, val | (1<<7)); |
4829 | } | 4830 | } |
4830 | } | 4831 | } |
4831 | 4832 | ||
4832 | val = alc_read_coef_idx(codec, 0xd); /* Class D */ | 4833 | val = alc_read_coef_idx(codec, 0xd); /* Class D */ |
4833 | alc_write_coef_idx(codec, 0xd, val | (1<<14)); | 4834 | alc_write_coef_idx(codec, 0xd, val | (1<<14)); |
4834 | 4835 | ||
4835 | val = alc_read_coef_idx(codec, 0x4); /* HP */ | 4836 | val = alc_read_coef_idx(codec, 0x4); /* HP */ |
4836 | alc_write_coef_idx(codec, 0x4, val | (1<<11)); | 4837 | alc_write_coef_idx(codec, 0x4, val | (1<<11)); |
4837 | } | 4838 | } |
4838 | 4839 | ||
4839 | /* | 4840 | /* |
4840 | */ | 4841 | */ |
4841 | static int patch_alc269(struct hda_codec *codec) | 4842 | static int patch_alc269(struct hda_codec *codec) |
4842 | { | 4843 | { |
4843 | struct alc_spec *spec; | 4844 | struct alc_spec *spec; |
4844 | int err; | 4845 | int err; |
4845 | 4846 | ||
4846 | err = alc_alloc_spec(codec, 0x0b); | 4847 | err = alc_alloc_spec(codec, 0x0b); |
4847 | if (err < 0) | 4848 | if (err < 0) |
4848 | return err; | 4849 | return err; |
4849 | 4850 | ||
4850 | spec = codec->spec; | 4851 | spec = codec->spec; |
4851 | spec->gen.shared_mic_vref_pin = 0x18; | 4852 | spec->gen.shared_mic_vref_pin = 0x18; |
4852 | 4853 | ||
4853 | snd_hda_pick_fixup(codec, alc269_fixup_models, | 4854 | snd_hda_pick_fixup(codec, alc269_fixup_models, |
4854 | alc269_fixup_tbl, alc269_fixups); | 4855 | alc269_fixup_tbl, alc269_fixups); |
4855 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); | 4856 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); |
4856 | 4857 | ||
4857 | alc_auto_parse_customize_define(codec); | 4858 | alc_auto_parse_customize_define(codec); |
4858 | 4859 | ||
4859 | if (has_cdefine_beep(codec)) | 4860 | if (has_cdefine_beep(codec)) |
4860 | spec->gen.beep_nid = 0x01; | 4861 | spec->gen.beep_nid = 0x01; |
4861 | 4862 | ||
4862 | switch (codec->vendor_id) { | 4863 | switch (codec->vendor_id) { |
4863 | case 0x10ec0269: | 4864 | case 0x10ec0269: |
4864 | spec->codec_variant = ALC269_TYPE_ALC269VA; | 4865 | spec->codec_variant = ALC269_TYPE_ALC269VA; |
4865 | switch (alc_get_coef0(codec) & 0x00f0) { | 4866 | switch (alc_get_coef0(codec) & 0x00f0) { |
4866 | case 0x0010: | 4867 | case 0x0010: |
4867 | if (codec->bus->pci && | 4868 | if (codec->bus->pci && |
4868 | codec->bus->pci->subsystem_vendor == 0x1025 && | 4869 | codec->bus->pci->subsystem_vendor == 0x1025 && |
4869 | spec->cdefine.platform_type == 1) | 4870 | spec->cdefine.platform_type == 1) |
4870 | err = alc_codec_rename(codec, "ALC271X"); | 4871 | err = alc_codec_rename(codec, "ALC271X"); |
4871 | spec->codec_variant = ALC269_TYPE_ALC269VB; | 4872 | spec->codec_variant = ALC269_TYPE_ALC269VB; |
4872 | break; | 4873 | break; |
4873 | case 0x0020: | 4874 | case 0x0020: |
4874 | if (codec->bus->pci && | 4875 | if (codec->bus->pci && |
4875 | codec->bus->pci->subsystem_vendor == 0x17aa && | 4876 | codec->bus->pci->subsystem_vendor == 0x17aa && |
4876 | codec->bus->pci->subsystem_device == 0x21f3) | 4877 | codec->bus->pci->subsystem_device == 0x21f3) |
4877 | err = alc_codec_rename(codec, "ALC3202"); | 4878 | err = alc_codec_rename(codec, "ALC3202"); |
4878 | spec->codec_variant = ALC269_TYPE_ALC269VC; | 4879 | spec->codec_variant = ALC269_TYPE_ALC269VC; |
4879 | break; | 4880 | break; |
4880 | case 0x0030: | 4881 | case 0x0030: |
4881 | spec->codec_variant = ALC269_TYPE_ALC269VD; | 4882 | spec->codec_variant = ALC269_TYPE_ALC269VD; |
4882 | break; | 4883 | break; |
4883 | default: | 4884 | default: |
4884 | alc_fix_pll_init(codec, 0x20, 0x04, 15); | 4885 | alc_fix_pll_init(codec, 0x20, 0x04, 15); |
4885 | } | 4886 | } |
4886 | if (err < 0) | 4887 | if (err < 0) |
4887 | goto error; | 4888 | goto error; |
4888 | spec->init_hook = alc269_fill_coef; | 4889 | spec->init_hook = alc269_fill_coef; |
4889 | alc269_fill_coef(codec); | 4890 | alc269_fill_coef(codec); |
4890 | break; | 4891 | break; |
4891 | 4892 | ||
4892 | case 0x10ec0280: | 4893 | case 0x10ec0280: |
4893 | case 0x10ec0290: | 4894 | case 0x10ec0290: |
4894 | spec->codec_variant = ALC269_TYPE_ALC280; | 4895 | spec->codec_variant = ALC269_TYPE_ALC280; |
4895 | break; | 4896 | break; |
4896 | case 0x10ec0282: | 4897 | case 0x10ec0282: |
4897 | spec->codec_variant = ALC269_TYPE_ALC282; | 4898 | spec->codec_variant = ALC269_TYPE_ALC282; |
4898 | spec->shutup = alc282_shutup; | 4899 | spec->shutup = alc282_shutup; |
4899 | spec->init_hook = alc282_init; | 4900 | spec->init_hook = alc282_init; |
4900 | break; | 4901 | break; |
4901 | case 0x10ec0233: | 4902 | case 0x10ec0233: |
4902 | case 0x10ec0283: | 4903 | case 0x10ec0283: |
4903 | spec->codec_variant = ALC269_TYPE_ALC283; | 4904 | spec->codec_variant = ALC269_TYPE_ALC283; |
4904 | spec->shutup = alc283_shutup; | 4905 | spec->shutup = alc283_shutup; |
4905 | spec->init_hook = alc283_init; | 4906 | spec->init_hook = alc283_init; |
4906 | break; | 4907 | break; |
4907 | case 0x10ec0284: | 4908 | case 0x10ec0284: |
4908 | case 0x10ec0292: | 4909 | case 0x10ec0292: |
4909 | spec->codec_variant = ALC269_TYPE_ALC284; | 4910 | spec->codec_variant = ALC269_TYPE_ALC284; |
4910 | break; | 4911 | break; |
4911 | case 0x10ec0285: | 4912 | case 0x10ec0285: |
4912 | case 0x10ec0293: | 4913 | case 0x10ec0293: |
4913 | spec->codec_variant = ALC269_TYPE_ALC285; | 4914 | spec->codec_variant = ALC269_TYPE_ALC285; |
4914 | break; | 4915 | break; |
4915 | case 0x10ec0286: | 4916 | case 0x10ec0286: |
4916 | case 0x10ec0288: | 4917 | case 0x10ec0288: |
4917 | spec->codec_variant = ALC269_TYPE_ALC286; | 4918 | spec->codec_variant = ALC269_TYPE_ALC286; |
4918 | break; | 4919 | break; |
4919 | case 0x10ec0255: | 4920 | case 0x10ec0255: |
4920 | spec->codec_variant = ALC269_TYPE_ALC255; | 4921 | spec->codec_variant = ALC269_TYPE_ALC255; |
4921 | break; | 4922 | break; |
4922 | } | 4923 | } |
4923 | 4924 | ||
4924 | if (snd_hda_codec_read(codec, 0x51, 0, AC_VERB_PARAMETERS, 0) == 0x10ec5505) { | 4925 | if (snd_hda_codec_read(codec, 0x51, 0, AC_VERB_PARAMETERS, 0) == 0x10ec5505) { |
4925 | spec->has_alc5505_dsp = 1; | 4926 | spec->has_alc5505_dsp = 1; |
4926 | spec->init_hook = alc5505_dsp_init; | 4927 | spec->init_hook = alc5505_dsp_init; |
4927 | } | 4928 | } |
4928 | 4929 | ||
4929 | /* automatic parse from the BIOS config */ | 4930 | /* automatic parse from the BIOS config */ |
4930 | err = alc269_parse_auto_config(codec); | 4931 | err = alc269_parse_auto_config(codec); |
4931 | if (err < 0) | 4932 | if (err < 0) |
4932 | goto error; | 4933 | goto error; |
4933 | 4934 | ||
4934 | if (!spec->gen.no_analog && spec->gen.beep_nid) | 4935 | if (!spec->gen.no_analog && spec->gen.beep_nid) |
4935 | set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); | 4936 | set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); |
4936 | 4937 | ||
4937 | codec->patch_ops = alc_patch_ops; | 4938 | codec->patch_ops = alc_patch_ops; |
4938 | #ifdef CONFIG_PM | 4939 | #ifdef CONFIG_PM |
4939 | codec->patch_ops.suspend = alc269_suspend; | 4940 | codec->patch_ops.suspend = alc269_suspend; |
4940 | codec->patch_ops.resume = alc269_resume; | 4941 | codec->patch_ops.resume = alc269_resume; |
4941 | #endif | 4942 | #endif |
4942 | if (!spec->shutup) | 4943 | if (!spec->shutup) |
4943 | spec->shutup = alc269_shutup; | 4944 | spec->shutup = alc269_shutup; |
4944 | 4945 | ||
4945 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); | 4946 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); |
4946 | 4947 | ||
4947 | return 0; | 4948 | return 0; |
4948 | 4949 | ||
4949 | error: | 4950 | error: |
4950 | alc_free(codec); | 4951 | alc_free(codec); |
4951 | return err; | 4952 | return err; |
4952 | } | 4953 | } |
4953 | 4954 | ||
4954 | /* | 4955 | /* |
4955 | * ALC861 | 4956 | * ALC861 |
4956 | */ | 4957 | */ |
4957 | 4958 | ||
4958 | static int alc861_parse_auto_config(struct hda_codec *codec) | 4959 | static int alc861_parse_auto_config(struct hda_codec *codec) |
4959 | { | 4960 | { |
4960 | static const hda_nid_t alc861_ignore[] = { 0x1d, 0 }; | 4961 | static const hda_nid_t alc861_ignore[] = { 0x1d, 0 }; |
4961 | static const hda_nid_t alc861_ssids[] = { 0x0e, 0x0f, 0x0b, 0 }; | 4962 | static const hda_nid_t alc861_ssids[] = { 0x0e, 0x0f, 0x0b, 0 }; |
4962 | return alc_parse_auto_config(codec, alc861_ignore, alc861_ssids); | 4963 | return alc_parse_auto_config(codec, alc861_ignore, alc861_ssids); |
4963 | } | 4964 | } |
4964 | 4965 | ||
4965 | /* Pin config fixes */ | 4966 | /* Pin config fixes */ |
4966 | enum { | 4967 | enum { |
4967 | ALC861_FIXUP_FSC_AMILO_PI1505, | 4968 | ALC861_FIXUP_FSC_AMILO_PI1505, |
4968 | ALC861_FIXUP_AMP_VREF_0F, | 4969 | ALC861_FIXUP_AMP_VREF_0F, |
4969 | ALC861_FIXUP_NO_JACK_DETECT, | 4970 | ALC861_FIXUP_NO_JACK_DETECT, |
4970 | ALC861_FIXUP_ASUS_A6RP, | 4971 | ALC861_FIXUP_ASUS_A6RP, |
4971 | ALC660_FIXUP_ASUS_W7J, | 4972 | ALC660_FIXUP_ASUS_W7J, |
4972 | }; | 4973 | }; |
4973 | 4974 | ||
4974 | /* On some laptops, VREF of pin 0x0f is abused for controlling the main amp */ | 4975 | /* On some laptops, VREF of pin 0x0f is abused for controlling the main amp */ |
4975 | static void alc861_fixup_asus_amp_vref_0f(struct hda_codec *codec, | 4976 | static void alc861_fixup_asus_amp_vref_0f(struct hda_codec *codec, |
4976 | const struct hda_fixup *fix, int action) | 4977 | const struct hda_fixup *fix, int action) |
4977 | { | 4978 | { |
4978 | struct alc_spec *spec = codec->spec; | 4979 | struct alc_spec *spec = codec->spec; |
4979 | unsigned int val; | 4980 | unsigned int val; |
4980 | 4981 | ||
4981 | if (action != HDA_FIXUP_ACT_INIT) | 4982 | if (action != HDA_FIXUP_ACT_INIT) |
4982 | return; | 4983 | return; |
4983 | val = snd_hda_codec_get_pin_target(codec, 0x0f); | 4984 | val = snd_hda_codec_get_pin_target(codec, 0x0f); |
4984 | if (!(val & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN))) | 4985 | if (!(val & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN))) |
4985 | val |= AC_PINCTL_IN_EN; | 4986 | val |= AC_PINCTL_IN_EN; |
4986 | val |= AC_PINCTL_VREF_50; | 4987 | val |= AC_PINCTL_VREF_50; |
4987 | snd_hda_set_pin_ctl(codec, 0x0f, val); | 4988 | snd_hda_set_pin_ctl(codec, 0x0f, val); |
4988 | spec->gen.keep_vref_in_automute = 1; | 4989 | spec->gen.keep_vref_in_automute = 1; |
4989 | } | 4990 | } |
4990 | 4991 | ||
4991 | /* suppress the jack-detection */ | 4992 | /* suppress the jack-detection */ |
4992 | static void alc_fixup_no_jack_detect(struct hda_codec *codec, | 4993 | static void alc_fixup_no_jack_detect(struct hda_codec *codec, |
4993 | const struct hda_fixup *fix, int action) | 4994 | const struct hda_fixup *fix, int action) |
4994 | { | 4995 | { |
4995 | if (action == HDA_FIXUP_ACT_PRE_PROBE) | 4996 | if (action == HDA_FIXUP_ACT_PRE_PROBE) |
4996 | codec->no_jack_detect = 1; | 4997 | codec->no_jack_detect = 1; |
4997 | } | 4998 | } |
4998 | 4999 | ||
4999 | static const struct hda_fixup alc861_fixups[] = { | 5000 | static const struct hda_fixup alc861_fixups[] = { |
5000 | [ALC861_FIXUP_FSC_AMILO_PI1505] = { | 5001 | [ALC861_FIXUP_FSC_AMILO_PI1505] = { |
5001 | .type = HDA_FIXUP_PINS, | 5002 | .type = HDA_FIXUP_PINS, |
5002 | .v.pins = (const struct hda_pintbl[]) { | 5003 | .v.pins = (const struct hda_pintbl[]) { |
5003 | { 0x0b, 0x0221101f }, /* HP */ | 5004 | { 0x0b, 0x0221101f }, /* HP */ |
5004 | { 0x0f, 0x90170310 }, /* speaker */ | 5005 | { 0x0f, 0x90170310 }, /* speaker */ |
5005 | { } | 5006 | { } |
5006 | } | 5007 | } |
5007 | }, | 5008 | }, |
5008 | [ALC861_FIXUP_AMP_VREF_0F] = { | 5009 | [ALC861_FIXUP_AMP_VREF_0F] = { |
5009 | .type = HDA_FIXUP_FUNC, | 5010 | .type = HDA_FIXUP_FUNC, |
5010 | .v.func = alc861_fixup_asus_amp_vref_0f, | 5011 | .v.func = alc861_fixup_asus_amp_vref_0f, |
5011 | }, | 5012 | }, |
5012 | [ALC861_FIXUP_NO_JACK_DETECT] = { | 5013 | [ALC861_FIXUP_NO_JACK_DETECT] = { |
5013 | .type = HDA_FIXUP_FUNC, | 5014 | .type = HDA_FIXUP_FUNC, |
5014 | .v.func = alc_fixup_no_jack_detect, | 5015 | .v.func = alc_fixup_no_jack_detect, |
5015 | }, | 5016 | }, |
5016 | [ALC861_FIXUP_ASUS_A6RP] = { | 5017 | [ALC861_FIXUP_ASUS_A6RP] = { |
5017 | .type = HDA_FIXUP_FUNC, | 5018 | .type = HDA_FIXUP_FUNC, |
5018 | .v.func = alc861_fixup_asus_amp_vref_0f, | 5019 | .v.func = alc861_fixup_asus_amp_vref_0f, |
5019 | .chained = true, | 5020 | .chained = true, |
5020 | .chain_id = ALC861_FIXUP_NO_JACK_DETECT, | 5021 | .chain_id = ALC861_FIXUP_NO_JACK_DETECT, |
5021 | }, | 5022 | }, |
5022 | [ALC660_FIXUP_ASUS_W7J] = { | 5023 | [ALC660_FIXUP_ASUS_W7J] = { |
5023 | .type = HDA_FIXUP_VERBS, | 5024 | .type = HDA_FIXUP_VERBS, |
5024 | .v.verbs = (const struct hda_verb[]) { | 5025 | .v.verbs = (const struct hda_verb[]) { |
5025 | /* ASUS W7J needs a magic pin setup on unused NID 0x10 | 5026 | /* ASUS W7J needs a magic pin setup on unused NID 0x10 |
5026 | * for enabling outputs | 5027 | * for enabling outputs |
5027 | */ | 5028 | */ |
5028 | {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, | 5029 | {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, |
5029 | { } | 5030 | { } |
5030 | }, | 5031 | }, |
5031 | } | 5032 | } |
5032 | }; | 5033 | }; |
5033 | 5034 | ||
5034 | static const struct snd_pci_quirk alc861_fixup_tbl[] = { | 5035 | static const struct snd_pci_quirk alc861_fixup_tbl[] = { |
5035 | SND_PCI_QUIRK(0x1043, 0x1253, "ASUS W7J", ALC660_FIXUP_ASUS_W7J), | 5036 | SND_PCI_QUIRK(0x1043, 0x1253, "ASUS W7J", ALC660_FIXUP_ASUS_W7J), |
5036 | SND_PCI_QUIRK(0x1043, 0x1263, "ASUS Z35HL", ALC660_FIXUP_ASUS_W7J), | 5037 | SND_PCI_QUIRK(0x1043, 0x1263, "ASUS Z35HL", ALC660_FIXUP_ASUS_W7J), |
5037 | SND_PCI_QUIRK(0x1043, 0x1393, "ASUS A6Rp", ALC861_FIXUP_ASUS_A6RP), | 5038 | SND_PCI_QUIRK(0x1043, 0x1393, "ASUS A6Rp", ALC861_FIXUP_ASUS_A6RP), |
5038 | SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", ALC861_FIXUP_AMP_VREF_0F), | 5039 | SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", ALC861_FIXUP_AMP_VREF_0F), |
5039 | SND_PCI_QUIRK(0x1462, 0x7254, "HP DX2200", ALC861_FIXUP_NO_JACK_DETECT), | 5040 | SND_PCI_QUIRK(0x1462, 0x7254, "HP DX2200", ALC861_FIXUP_NO_JACK_DETECT), |
5040 | SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", ALC861_FIXUP_AMP_VREF_0F), | 5041 | SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", ALC861_FIXUP_AMP_VREF_0F), |
5041 | SND_PCI_QUIRK(0x1584, 0x0000, "Uniwill ECS M31EI", ALC861_FIXUP_AMP_VREF_0F), | 5042 | SND_PCI_QUIRK(0x1584, 0x0000, "Uniwill ECS M31EI", ALC861_FIXUP_AMP_VREF_0F), |
5042 | SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", ALC861_FIXUP_FSC_AMILO_PI1505), | 5043 | SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", ALC861_FIXUP_FSC_AMILO_PI1505), |
5043 | {} | 5044 | {} |
5044 | }; | 5045 | }; |
5045 | 5046 | ||
5046 | /* | 5047 | /* |
5047 | */ | 5048 | */ |
5048 | static int patch_alc861(struct hda_codec *codec) | 5049 | static int patch_alc861(struct hda_codec *codec) |
5049 | { | 5050 | { |
5050 | struct alc_spec *spec; | 5051 | struct alc_spec *spec; |
5051 | int err; | 5052 | int err; |
5052 | 5053 | ||
5053 | err = alc_alloc_spec(codec, 0x15); | 5054 | err = alc_alloc_spec(codec, 0x15); |
5054 | if (err < 0) | 5055 | if (err < 0) |
5055 | return err; | 5056 | return err; |
5056 | 5057 | ||
5057 | spec = codec->spec; | 5058 | spec = codec->spec; |
5058 | spec->gen.beep_nid = 0x23; | 5059 | spec->gen.beep_nid = 0x23; |
5059 | 5060 | ||
5060 | snd_hda_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups); | 5061 | snd_hda_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups); |
5061 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); | 5062 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); |
5062 | 5063 | ||
5063 | /* automatic parse from the BIOS config */ | 5064 | /* automatic parse from the BIOS config */ |
5064 | err = alc861_parse_auto_config(codec); | 5065 | err = alc861_parse_auto_config(codec); |
5065 | if (err < 0) | 5066 | if (err < 0) |
5066 | goto error; | 5067 | goto error; |
5067 | 5068 | ||
5068 | if (!spec->gen.no_analog) | 5069 | if (!spec->gen.no_analog) |
5069 | set_beep_amp(spec, 0x23, 0, HDA_OUTPUT); | 5070 | set_beep_amp(spec, 0x23, 0, HDA_OUTPUT); |
5070 | 5071 | ||
5071 | codec->patch_ops = alc_patch_ops; | 5072 | codec->patch_ops = alc_patch_ops; |
5072 | #ifdef CONFIG_PM | 5073 | #ifdef CONFIG_PM |
5073 | spec->power_hook = alc_power_eapd; | 5074 | spec->power_hook = alc_power_eapd; |
5074 | #endif | 5075 | #endif |
5075 | 5076 | ||
5076 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); | 5077 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); |
5077 | 5078 | ||
5078 | return 0; | 5079 | return 0; |
5079 | 5080 | ||
5080 | error: | 5081 | error: |
5081 | alc_free(codec); | 5082 | alc_free(codec); |
5082 | return err; | 5083 | return err; |
5083 | } | 5084 | } |
5084 | 5085 | ||
5085 | /* | 5086 | /* |
5086 | * ALC861-VD support | 5087 | * ALC861-VD support |
5087 | * | 5088 | * |
5088 | * Based on ALC882 | 5089 | * Based on ALC882 |
5089 | * | 5090 | * |
5090 | * In addition, an independent DAC | 5091 | * In addition, an independent DAC |
5091 | */ | 5092 | */ |
5092 | static int alc861vd_parse_auto_config(struct hda_codec *codec) | 5093 | static int alc861vd_parse_auto_config(struct hda_codec *codec) |
5093 | { | 5094 | { |
5094 | static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 }; | 5095 | static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 }; |
5095 | static const hda_nid_t alc861vd_ssids[] = { 0x15, 0x1b, 0x14, 0 }; | 5096 | static const hda_nid_t alc861vd_ssids[] = { 0x15, 0x1b, 0x14, 0 }; |
5096 | return alc_parse_auto_config(codec, alc861vd_ignore, alc861vd_ssids); | 5097 | return alc_parse_auto_config(codec, alc861vd_ignore, alc861vd_ssids); |
5097 | } | 5098 | } |
5098 | 5099 | ||
5099 | enum { | 5100 | enum { |
5100 | ALC660VD_FIX_ASUS_GPIO1, | 5101 | ALC660VD_FIX_ASUS_GPIO1, |
5101 | ALC861VD_FIX_DALLAS, | 5102 | ALC861VD_FIX_DALLAS, |
5102 | }; | 5103 | }; |
5103 | 5104 | ||
5104 | /* exclude VREF80 */ | 5105 | /* exclude VREF80 */ |
5105 | static void alc861vd_fixup_dallas(struct hda_codec *codec, | 5106 | static void alc861vd_fixup_dallas(struct hda_codec *codec, |
5106 | const struct hda_fixup *fix, int action) | 5107 | const struct hda_fixup *fix, int action) |
5107 | { | 5108 | { |
5108 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | 5109 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
5109 | snd_hda_override_pin_caps(codec, 0x18, 0x00000734); | 5110 | snd_hda_override_pin_caps(codec, 0x18, 0x00000734); |
5110 | snd_hda_override_pin_caps(codec, 0x19, 0x0000073c); | 5111 | snd_hda_override_pin_caps(codec, 0x19, 0x0000073c); |
5111 | } | 5112 | } |
5112 | } | 5113 | } |
5113 | 5114 | ||
5114 | static const struct hda_fixup alc861vd_fixups[] = { | 5115 | static const struct hda_fixup alc861vd_fixups[] = { |
5115 | [ALC660VD_FIX_ASUS_GPIO1] = { | 5116 | [ALC660VD_FIX_ASUS_GPIO1] = { |
5116 | .type = HDA_FIXUP_VERBS, | 5117 | .type = HDA_FIXUP_VERBS, |
5117 | .v.verbs = (const struct hda_verb[]) { | 5118 | .v.verbs = (const struct hda_verb[]) { |
5118 | /* reset GPIO1 */ | 5119 | /* reset GPIO1 */ |
5119 | {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, | 5120 | {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, |
5120 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, | 5121 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, |
5121 | {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, | 5122 | {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, |
5122 | { } | 5123 | { } |
5123 | } | 5124 | } |
5124 | }, | 5125 | }, |
5125 | [ALC861VD_FIX_DALLAS] = { | 5126 | [ALC861VD_FIX_DALLAS] = { |
5126 | .type = HDA_FIXUP_FUNC, | 5127 | .type = HDA_FIXUP_FUNC, |
5127 | .v.func = alc861vd_fixup_dallas, | 5128 | .v.func = alc861vd_fixup_dallas, |
5128 | }, | 5129 | }, |
5129 | }; | 5130 | }; |
5130 | 5131 | ||
5131 | static const struct snd_pci_quirk alc861vd_fixup_tbl[] = { | 5132 | static const struct snd_pci_quirk alc861vd_fixup_tbl[] = { |
5132 | SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_FIX_DALLAS), | 5133 | SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_FIX_DALLAS), |
5133 | SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1), | 5134 | SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1), |
5134 | SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_FIX_DALLAS), | 5135 | SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_FIX_DALLAS), |
5135 | {} | 5136 | {} |
5136 | }; | 5137 | }; |
5137 | 5138 | ||
5138 | /* | 5139 | /* |
5139 | */ | 5140 | */ |
5140 | static int patch_alc861vd(struct hda_codec *codec) | 5141 | static int patch_alc861vd(struct hda_codec *codec) |
5141 | { | 5142 | { |
5142 | struct alc_spec *spec; | 5143 | struct alc_spec *spec; |
5143 | int err; | 5144 | int err; |
5144 | 5145 | ||
5145 | err = alc_alloc_spec(codec, 0x0b); | 5146 | err = alc_alloc_spec(codec, 0x0b); |
5146 | if (err < 0) | 5147 | if (err < 0) |
5147 | return err; | 5148 | return err; |
5148 | 5149 | ||
5149 | spec = codec->spec; | 5150 | spec = codec->spec; |
5150 | spec->gen.beep_nid = 0x23; | 5151 | spec->gen.beep_nid = 0x23; |
5151 | 5152 | ||
5152 | snd_hda_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups); | 5153 | snd_hda_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups); |
5153 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); | 5154 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); |
5154 | 5155 | ||
5155 | /* automatic parse from the BIOS config */ | 5156 | /* automatic parse from the BIOS config */ |
5156 | err = alc861vd_parse_auto_config(codec); | 5157 | err = alc861vd_parse_auto_config(codec); |
5157 | if (err < 0) | 5158 | if (err < 0) |
5158 | goto error; | 5159 | goto error; |
5159 | 5160 | ||
5160 | if (!spec->gen.no_analog) | 5161 | if (!spec->gen.no_analog) |
5161 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); | 5162 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); |
5162 | 5163 | ||
5163 | codec->patch_ops = alc_patch_ops; | 5164 | codec->patch_ops = alc_patch_ops; |
5164 | 5165 | ||
5165 | spec->shutup = alc_eapd_shutup; | 5166 | spec->shutup = alc_eapd_shutup; |
5166 | 5167 | ||
5167 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); | 5168 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); |
5168 | 5169 | ||
5169 | return 0; | 5170 | return 0; |
5170 | 5171 | ||
5171 | error: | 5172 | error: |
5172 | alc_free(codec); | 5173 | alc_free(codec); |
5173 | return err; | 5174 | return err; |
5174 | } | 5175 | } |
5175 | 5176 | ||
5176 | /* | 5177 | /* |
5177 | * ALC662 support | 5178 | * ALC662 support |
5178 | * | 5179 | * |
5179 | * ALC662 is almost identical with ALC880 but has cleaner and more flexible | 5180 | * ALC662 is almost identical with ALC880 but has cleaner and more flexible |
5180 | * configuration. Each pin widget can choose any input DACs and a mixer. | 5181 | * configuration. Each pin widget can choose any input DACs and a mixer. |
5181 | * Each ADC is connected from a mixer of all inputs. This makes possible | 5182 | * Each ADC is connected from a mixer of all inputs. This makes possible |
5182 | * 6-channel independent captures. | 5183 | * 6-channel independent captures. |
5183 | * | 5184 | * |
5184 | * In addition, an independent DAC for the multi-playback (not used in this | 5185 | * In addition, an independent DAC for the multi-playback (not used in this |
5185 | * driver yet). | 5186 | * driver yet). |
5186 | */ | 5187 | */ |
5187 | 5188 | ||
5188 | /* | 5189 | /* |
5189 | * BIOS auto configuration | 5190 | * BIOS auto configuration |
5190 | */ | 5191 | */ |
5191 | 5192 | ||
5192 | static int alc662_parse_auto_config(struct hda_codec *codec) | 5193 | static int alc662_parse_auto_config(struct hda_codec *codec) |
5193 | { | 5194 | { |
5194 | static const hda_nid_t alc662_ignore[] = { 0x1d, 0 }; | 5195 | static const hda_nid_t alc662_ignore[] = { 0x1d, 0 }; |
5195 | static const hda_nid_t alc663_ssids[] = { 0x15, 0x1b, 0x14, 0x21 }; | 5196 | static const hda_nid_t alc663_ssids[] = { 0x15, 0x1b, 0x14, 0x21 }; |
5196 | static const hda_nid_t alc662_ssids[] = { 0x15, 0x1b, 0x14, 0 }; | 5197 | static const hda_nid_t alc662_ssids[] = { 0x15, 0x1b, 0x14, 0 }; |
5197 | const hda_nid_t *ssids; | 5198 | const hda_nid_t *ssids; |
5198 | 5199 | ||
5199 | if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 || | 5200 | if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 || |
5200 | codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670 || | 5201 | codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670 || |
5201 | codec->vendor_id == 0x10ec0671) | 5202 | codec->vendor_id == 0x10ec0671) |
5202 | ssids = alc663_ssids; | 5203 | ssids = alc663_ssids; |
5203 | else | 5204 | else |
5204 | ssids = alc662_ssids; | 5205 | ssids = alc662_ssids; |
5205 | return alc_parse_auto_config(codec, alc662_ignore, ssids); | 5206 | return alc_parse_auto_config(codec, alc662_ignore, ssids); |
5206 | } | 5207 | } |
5207 | 5208 | ||
5208 | static void alc272_fixup_mario(struct hda_codec *codec, | 5209 | static void alc272_fixup_mario(struct hda_codec *codec, |
5209 | const struct hda_fixup *fix, int action) | 5210 | const struct hda_fixup *fix, int action) |
5210 | { | 5211 | { |
5211 | if (action != HDA_FIXUP_ACT_PRE_PROBE) | 5212 | if (action != HDA_FIXUP_ACT_PRE_PROBE) |
5212 | return; | 5213 | return; |
5213 | if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT, | 5214 | if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT, |
5214 | (0x3b << AC_AMPCAP_OFFSET_SHIFT) | | 5215 | (0x3b << AC_AMPCAP_OFFSET_SHIFT) | |
5215 | (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) | | 5216 | (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) | |
5216 | (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) | | 5217 | (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) | |
5217 | (0 << AC_AMPCAP_MUTE_SHIFT))) | 5218 | (0 << AC_AMPCAP_MUTE_SHIFT))) |
5218 | codec_warn(codec, "failed to override amp caps for NID 0x2\n"); | 5219 | codec_warn(codec, "failed to override amp caps for NID 0x2\n"); |
5219 | } | 5220 | } |
5220 | 5221 | ||
5221 | static const struct snd_pcm_chmap_elem asus_pcm_2_1_chmaps[] = { | 5222 | static const struct snd_pcm_chmap_elem asus_pcm_2_1_chmaps[] = { |
5222 | { .channels = 2, | 5223 | { .channels = 2, |
5223 | .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } }, | 5224 | .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } }, |
5224 | { .channels = 4, | 5225 | { .channels = 4, |
5225 | .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, | 5226 | .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, |
5226 | SNDRV_CHMAP_NA, SNDRV_CHMAP_LFE } }, /* LFE only on right */ | 5227 | SNDRV_CHMAP_NA, SNDRV_CHMAP_LFE } }, /* LFE only on right */ |
5227 | { } | 5228 | { } |
5228 | }; | 5229 | }; |
5229 | 5230 | ||
5230 | /* override the 2.1 chmap */ | 5231 | /* override the 2.1 chmap */ |
5231 | static void alc_fixup_bass_chmap(struct hda_codec *codec, | 5232 | static void alc_fixup_bass_chmap(struct hda_codec *codec, |
5232 | const struct hda_fixup *fix, int action) | 5233 | const struct hda_fixup *fix, int action) |
5233 | { | 5234 | { |
5234 | if (action == HDA_FIXUP_ACT_BUILD) { | 5235 | if (action == HDA_FIXUP_ACT_BUILD) { |
5235 | struct alc_spec *spec = codec->spec; | 5236 | struct alc_spec *spec = codec->spec; |
5236 | spec->gen.pcm_rec[0].stream[0].chmap = asus_pcm_2_1_chmaps; | 5237 | spec->gen.pcm_rec[0].stream[0].chmap = asus_pcm_2_1_chmaps; |
5237 | } | 5238 | } |
5238 | } | 5239 | } |
5239 | 5240 | ||
5240 | /* turn on/off mute LED per vmaster hook */ | 5241 | /* turn on/off mute LED per vmaster hook */ |
5241 | static void alc662_led_gpio1_mute_hook(void *private_data, int enabled) | 5242 | static void alc662_led_gpio1_mute_hook(void *private_data, int enabled) |
5242 | { | 5243 | { |
5243 | struct hda_codec *codec = private_data; | 5244 | struct hda_codec *codec = private_data; |
5244 | struct alc_spec *spec = codec->spec; | 5245 | struct alc_spec *spec = codec->spec; |
5245 | unsigned int oldval = spec->gpio_led; | 5246 | unsigned int oldval = spec->gpio_led; |
5246 | 5247 | ||
5247 | if (enabled) | 5248 | if (enabled) |
5248 | spec->gpio_led &= ~0x01; | 5249 | spec->gpio_led &= ~0x01; |
5249 | else | 5250 | else |
5250 | spec->gpio_led |= 0x01; | 5251 | spec->gpio_led |= 0x01; |
5251 | if (spec->gpio_led != oldval) | 5252 | if (spec->gpio_led != oldval) |
5252 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, | 5253 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, |
5253 | spec->gpio_led); | 5254 | spec->gpio_led); |
5254 | } | 5255 | } |
5255 | 5256 | ||
5256 | /* avoid D3 for keeping GPIO up */ | 5257 | /* avoid D3 for keeping GPIO up */ |
5257 | static unsigned int gpio_led_power_filter(struct hda_codec *codec, | 5258 | static unsigned int gpio_led_power_filter(struct hda_codec *codec, |
5258 | hda_nid_t nid, | 5259 | hda_nid_t nid, |
5259 | unsigned int power_state) | 5260 | unsigned int power_state) |
5260 | { | 5261 | { |
5261 | struct alc_spec *spec = codec->spec; | 5262 | struct alc_spec *spec = codec->spec; |
5262 | if (nid == codec->afg && power_state == AC_PWRST_D3 && spec->gpio_led) | 5263 | if (nid == codec->afg && power_state == AC_PWRST_D3 && spec->gpio_led) |
5263 | return AC_PWRST_D0; | 5264 | return AC_PWRST_D0; |
5264 | return power_state; | 5265 | return power_state; |
5265 | } | 5266 | } |
5266 | 5267 | ||
5267 | static void alc662_fixup_led_gpio1(struct hda_codec *codec, | 5268 | static void alc662_fixup_led_gpio1(struct hda_codec *codec, |
5268 | const struct hda_fixup *fix, int action) | 5269 | const struct hda_fixup *fix, int action) |
5269 | { | 5270 | { |
5270 | struct alc_spec *spec = codec->spec; | 5271 | struct alc_spec *spec = codec->spec; |
5271 | static const struct hda_verb gpio_init[] = { | 5272 | static const struct hda_verb gpio_init[] = { |
5272 | { 0x01, AC_VERB_SET_GPIO_MASK, 0x01 }, | 5273 | { 0x01, AC_VERB_SET_GPIO_MASK, 0x01 }, |
5273 | { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01 }, | 5274 | { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01 }, |
5274 | {} | 5275 | {} |
5275 | }; | 5276 | }; |
5276 | 5277 | ||
5277 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | 5278 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
5278 | spec->gen.vmaster_mute.hook = alc662_led_gpio1_mute_hook; | 5279 | spec->gen.vmaster_mute.hook = alc662_led_gpio1_mute_hook; |
5279 | spec->gpio_led = 0; | 5280 | spec->gpio_led = 0; |
5280 | snd_hda_add_verbs(codec, gpio_init); | 5281 | snd_hda_add_verbs(codec, gpio_init); |
5281 | codec->power_filter = gpio_led_power_filter; | 5282 | codec->power_filter = gpio_led_power_filter; |
5282 | } | 5283 | } |
5283 | } | 5284 | } |
5284 | 5285 | ||
5285 | enum { | 5286 | enum { |
5286 | ALC662_FIXUP_ASPIRE, | 5287 | ALC662_FIXUP_ASPIRE, |
5287 | ALC662_FIXUP_LED_GPIO1, | 5288 | ALC662_FIXUP_LED_GPIO1, |
5288 | ALC662_FIXUP_IDEAPAD, | 5289 | ALC662_FIXUP_IDEAPAD, |
5289 | ALC272_FIXUP_MARIO, | 5290 | ALC272_FIXUP_MARIO, |
5290 | ALC662_FIXUP_CZC_P10T, | 5291 | ALC662_FIXUP_CZC_P10T, |
5291 | ALC662_FIXUP_SKU_IGNORE, | 5292 | ALC662_FIXUP_SKU_IGNORE, |
5292 | ALC662_FIXUP_HP_RP5800, | 5293 | ALC662_FIXUP_HP_RP5800, |
5293 | ALC662_FIXUP_ASUS_MODE1, | 5294 | ALC662_FIXUP_ASUS_MODE1, |
5294 | ALC662_FIXUP_ASUS_MODE2, | 5295 | ALC662_FIXUP_ASUS_MODE2, |
5295 | ALC662_FIXUP_ASUS_MODE3, | 5296 | ALC662_FIXUP_ASUS_MODE3, |
5296 | ALC662_FIXUP_ASUS_MODE4, | 5297 | ALC662_FIXUP_ASUS_MODE4, |
5297 | ALC662_FIXUP_ASUS_MODE5, | 5298 | ALC662_FIXUP_ASUS_MODE5, |
5298 | ALC662_FIXUP_ASUS_MODE6, | 5299 | ALC662_FIXUP_ASUS_MODE6, |
5299 | ALC662_FIXUP_ASUS_MODE7, | 5300 | ALC662_FIXUP_ASUS_MODE7, |
5300 | ALC662_FIXUP_ASUS_MODE8, | 5301 | ALC662_FIXUP_ASUS_MODE8, |
5301 | ALC662_FIXUP_NO_JACK_DETECT, | 5302 | ALC662_FIXUP_NO_JACK_DETECT, |
5302 | ALC662_FIXUP_ZOTAC_Z68, | 5303 | ALC662_FIXUP_ZOTAC_Z68, |
5303 | ALC662_FIXUP_INV_DMIC, | 5304 | ALC662_FIXUP_INV_DMIC, |
5304 | ALC668_FIXUP_DELL_MIC_NO_PRESENCE, | 5305 | ALC668_FIXUP_DELL_MIC_NO_PRESENCE, |
5305 | ALC668_FIXUP_HEADSET_MODE, | 5306 | ALC668_FIXUP_HEADSET_MODE, |
5306 | ALC662_FIXUP_BASS_MODE4_CHMAP, | 5307 | ALC662_FIXUP_BASS_MODE4_CHMAP, |
5307 | ALC662_FIXUP_BASS_16, | 5308 | ALC662_FIXUP_BASS_16, |
5308 | ALC662_FIXUP_BASS_1A, | 5309 | ALC662_FIXUP_BASS_1A, |
5309 | ALC662_FIXUP_BASS_CHMAP, | 5310 | ALC662_FIXUP_BASS_CHMAP, |
5310 | ALC668_FIXUP_AUTO_MUTE, | 5311 | ALC668_FIXUP_AUTO_MUTE, |
5311 | }; | 5312 | }; |
5312 | 5313 | ||
5313 | static const struct hda_fixup alc662_fixups[] = { | 5314 | static const struct hda_fixup alc662_fixups[] = { |
5314 | [ALC662_FIXUP_ASPIRE] = { | 5315 | [ALC662_FIXUP_ASPIRE] = { |
5315 | .type = HDA_FIXUP_PINS, | 5316 | .type = HDA_FIXUP_PINS, |
5316 | .v.pins = (const struct hda_pintbl[]) { | 5317 | .v.pins = (const struct hda_pintbl[]) { |
5317 | { 0x15, 0x99130112 }, /* subwoofer */ | 5318 | { 0x15, 0x99130112 }, /* subwoofer */ |
5318 | { } | 5319 | { } |
5319 | } | 5320 | } |
5320 | }, | 5321 | }, |
5321 | [ALC662_FIXUP_LED_GPIO1] = { | 5322 | [ALC662_FIXUP_LED_GPIO1] = { |
5322 | .type = HDA_FIXUP_FUNC, | 5323 | .type = HDA_FIXUP_FUNC, |
5323 | .v.func = alc662_fixup_led_gpio1, | 5324 | .v.func = alc662_fixup_led_gpio1, |
5324 | }, | 5325 | }, |
5325 | [ALC662_FIXUP_IDEAPAD] = { | 5326 | [ALC662_FIXUP_IDEAPAD] = { |
5326 | .type = HDA_FIXUP_PINS, | 5327 | .type = HDA_FIXUP_PINS, |
5327 | .v.pins = (const struct hda_pintbl[]) { | 5328 | .v.pins = (const struct hda_pintbl[]) { |
5328 | { 0x17, 0x99130112 }, /* subwoofer */ | 5329 | { 0x17, 0x99130112 }, /* subwoofer */ |
5329 | { } | 5330 | { } |
5330 | }, | 5331 | }, |
5331 | .chained = true, | 5332 | .chained = true, |
5332 | .chain_id = ALC662_FIXUP_LED_GPIO1, | 5333 | .chain_id = ALC662_FIXUP_LED_GPIO1, |
5333 | }, | 5334 | }, |
5334 | [ALC272_FIXUP_MARIO] = { | 5335 | [ALC272_FIXUP_MARIO] = { |
5335 | .type = HDA_FIXUP_FUNC, | 5336 | .type = HDA_FIXUP_FUNC, |
5336 | .v.func = alc272_fixup_mario, | 5337 | .v.func = alc272_fixup_mario, |
5337 | }, | 5338 | }, |
5338 | [ALC662_FIXUP_CZC_P10T] = { | 5339 | [ALC662_FIXUP_CZC_P10T] = { |
5339 | .type = HDA_FIXUP_VERBS, | 5340 | .type = HDA_FIXUP_VERBS, |
5340 | .v.verbs = (const struct hda_verb[]) { | 5341 | .v.verbs = (const struct hda_verb[]) { |
5341 | {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0}, | 5342 | {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0}, |
5342 | {} | 5343 | {} |
5343 | } | 5344 | } |
5344 | }, | 5345 | }, |
5345 | [ALC662_FIXUP_SKU_IGNORE] = { | 5346 | [ALC662_FIXUP_SKU_IGNORE] = { |
5346 | .type = HDA_FIXUP_FUNC, | 5347 | .type = HDA_FIXUP_FUNC, |
5347 | .v.func = alc_fixup_sku_ignore, | 5348 | .v.func = alc_fixup_sku_ignore, |
5348 | }, | 5349 | }, |
5349 | [ALC662_FIXUP_HP_RP5800] = { | 5350 | [ALC662_FIXUP_HP_RP5800] = { |
5350 | .type = HDA_FIXUP_PINS, | 5351 | .type = HDA_FIXUP_PINS, |
5351 | .v.pins = (const struct hda_pintbl[]) { | 5352 | .v.pins = (const struct hda_pintbl[]) { |
5352 | { 0x14, 0x0221201f }, /* HP out */ | 5353 | { 0x14, 0x0221201f }, /* HP out */ |
5353 | { } | 5354 | { } |
5354 | }, | 5355 | }, |
5355 | .chained = true, | 5356 | .chained = true, |
5356 | .chain_id = ALC662_FIXUP_SKU_IGNORE | 5357 | .chain_id = ALC662_FIXUP_SKU_IGNORE |
5357 | }, | 5358 | }, |
5358 | [ALC662_FIXUP_ASUS_MODE1] = { | 5359 | [ALC662_FIXUP_ASUS_MODE1] = { |
5359 | .type = HDA_FIXUP_PINS, | 5360 | .type = HDA_FIXUP_PINS, |
5360 | .v.pins = (const struct hda_pintbl[]) { | 5361 | .v.pins = (const struct hda_pintbl[]) { |
5361 | { 0x14, 0x99130110 }, /* speaker */ | 5362 | { 0x14, 0x99130110 }, /* speaker */ |
5362 | { 0x18, 0x01a19c20 }, /* mic */ | 5363 | { 0x18, 0x01a19c20 }, /* mic */ |
5363 | { 0x19, 0x99a3092f }, /* int-mic */ | 5364 | { 0x19, 0x99a3092f }, /* int-mic */ |
5364 | { 0x21, 0x0121401f }, /* HP out */ | 5365 | { 0x21, 0x0121401f }, /* HP out */ |
5365 | { } | 5366 | { } |
5366 | }, | 5367 | }, |
5367 | .chained = true, | 5368 | .chained = true, |
5368 | .chain_id = ALC662_FIXUP_SKU_IGNORE | 5369 | .chain_id = ALC662_FIXUP_SKU_IGNORE |
5369 | }, | 5370 | }, |
5370 | [ALC662_FIXUP_ASUS_MODE2] = { | 5371 | [ALC662_FIXUP_ASUS_MODE2] = { |
5371 | .type = HDA_FIXUP_PINS, | 5372 | .type = HDA_FIXUP_PINS, |
5372 | .v.pins = (const struct hda_pintbl[]) { | 5373 | .v.pins = (const struct hda_pintbl[]) { |
5373 | { 0x14, 0x99130110 }, /* speaker */ | 5374 | { 0x14, 0x99130110 }, /* speaker */ |
5374 | { 0x18, 0x01a19820 }, /* mic */ | 5375 | { 0x18, 0x01a19820 }, /* mic */ |
5375 | { 0x19, 0x99a3092f }, /* int-mic */ | 5376 | { 0x19, 0x99a3092f }, /* int-mic */ |
5376 | { 0x1b, 0x0121401f }, /* HP out */ | 5377 | { 0x1b, 0x0121401f }, /* HP out */ |
5377 | { } | 5378 | { } |
5378 | }, | 5379 | }, |
5379 | .chained = true, | 5380 | .chained = true, |
5380 | .chain_id = ALC662_FIXUP_SKU_IGNORE | 5381 | .chain_id = ALC662_FIXUP_SKU_IGNORE |
5381 | }, | 5382 | }, |
5382 | [ALC662_FIXUP_ASUS_MODE3] = { | 5383 | [ALC662_FIXUP_ASUS_MODE3] = { |
5383 | .type = HDA_FIXUP_PINS, | 5384 | .type = HDA_FIXUP_PINS, |
5384 | .v.pins = (const struct hda_pintbl[]) { | 5385 | .v.pins = (const struct hda_pintbl[]) { |
5385 | { 0x14, 0x99130110 }, /* speaker */ | 5386 | { 0x14, 0x99130110 }, /* speaker */ |
5386 | { 0x15, 0x0121441f }, /* HP */ | 5387 | { 0x15, 0x0121441f }, /* HP */ |
5387 | { 0x18, 0x01a19840 }, /* mic */ | 5388 | { 0x18, 0x01a19840 }, /* mic */ |
5388 | { 0x19, 0x99a3094f }, /* int-mic */ | 5389 | { 0x19, 0x99a3094f }, /* int-mic */ |
5389 | { 0x21, 0x01211420 }, /* HP2 */ | 5390 | { 0x21, 0x01211420 }, /* HP2 */ |
5390 | { } | 5391 | { } |
5391 | }, | 5392 | }, |
5392 | .chained = true, | 5393 | .chained = true, |
5393 | .chain_id = ALC662_FIXUP_SKU_IGNORE | 5394 | .chain_id = ALC662_FIXUP_SKU_IGNORE |
5394 | }, | 5395 | }, |
5395 | [ALC662_FIXUP_ASUS_MODE4] = { | 5396 | [ALC662_FIXUP_ASUS_MODE4] = { |
5396 | .type = HDA_FIXUP_PINS, | 5397 | .type = HDA_FIXUP_PINS, |
5397 | .v.pins = (const struct hda_pintbl[]) { | 5398 | .v.pins = (const struct hda_pintbl[]) { |
5398 | { 0x14, 0x99130110 }, /* speaker */ | 5399 | { 0x14, 0x99130110 }, /* speaker */ |
5399 | { 0x16, 0x99130111 }, /* speaker */ | 5400 | { 0x16, 0x99130111 }, /* speaker */ |
5400 | { 0x18, 0x01a19840 }, /* mic */ | 5401 | { 0x18, 0x01a19840 }, /* mic */ |
5401 | { 0x19, 0x99a3094f }, /* int-mic */ | 5402 | { 0x19, 0x99a3094f }, /* int-mic */ |
5402 | { 0x21, 0x0121441f }, /* HP */ | 5403 | { 0x21, 0x0121441f }, /* HP */ |
5403 | { } | 5404 | { } |
5404 | }, | 5405 | }, |
5405 | .chained = true, | 5406 | .chained = true, |
5406 | .chain_id = ALC662_FIXUP_SKU_IGNORE | 5407 | .chain_id = ALC662_FIXUP_SKU_IGNORE |
5407 | }, | 5408 | }, |
5408 | [ALC662_FIXUP_ASUS_MODE5] = { | 5409 | [ALC662_FIXUP_ASUS_MODE5] = { |
5409 | .type = HDA_FIXUP_PINS, | 5410 | .type = HDA_FIXUP_PINS, |
5410 | .v.pins = (const struct hda_pintbl[]) { | 5411 | .v.pins = (const struct hda_pintbl[]) { |
5411 | { 0x14, 0x99130110 }, /* speaker */ | 5412 | { 0x14, 0x99130110 }, /* speaker */ |
5412 | { 0x15, 0x0121441f }, /* HP */ | 5413 | { 0x15, 0x0121441f }, /* HP */ |
5413 | { 0x16, 0x99130111 }, /* speaker */ | 5414 | { 0x16, 0x99130111 }, /* speaker */ |
5414 | { 0x18, 0x01a19840 }, /* mic */ | 5415 | { 0x18, 0x01a19840 }, /* mic */ |
5415 | { 0x19, 0x99a3094f }, /* int-mic */ | 5416 | { 0x19, 0x99a3094f }, /* int-mic */ |
5416 | { } | 5417 | { } |
5417 | }, | 5418 | }, |
5418 | .chained = true, | 5419 | .chained = true, |
5419 | .chain_id = ALC662_FIXUP_SKU_IGNORE | 5420 | .chain_id = ALC662_FIXUP_SKU_IGNORE |
5420 | }, | 5421 | }, |
5421 | [ALC662_FIXUP_ASUS_MODE6] = { | 5422 | [ALC662_FIXUP_ASUS_MODE6] = { |
5422 | .type = HDA_FIXUP_PINS, | 5423 | .type = HDA_FIXUP_PINS, |
5423 | .v.pins = (const struct hda_pintbl[]) { | 5424 | .v.pins = (const struct hda_pintbl[]) { |
5424 | { 0x14, 0x99130110 }, /* speaker */ | 5425 | { 0x14, 0x99130110 }, /* speaker */ |
5425 | { 0x15, 0x01211420 }, /* HP2 */ | 5426 | { 0x15, 0x01211420 }, /* HP2 */ |
5426 | { 0x18, 0x01a19840 }, /* mic */ | 5427 | { 0x18, 0x01a19840 }, /* mic */ |
5427 | { 0x19, 0x99a3094f }, /* int-mic */ | 5428 | { 0x19, 0x99a3094f }, /* int-mic */ |
5428 | { 0x1b, 0x0121441f }, /* HP */ | 5429 | { 0x1b, 0x0121441f }, /* HP */ |
5429 | { } | 5430 | { } |
5430 | }, | 5431 | }, |
5431 | .chained = true, | 5432 | .chained = true, |
5432 | .chain_id = ALC662_FIXUP_SKU_IGNORE | 5433 | .chain_id = ALC662_FIXUP_SKU_IGNORE |
5433 | }, | 5434 | }, |
5434 | [ALC662_FIXUP_ASUS_MODE7] = { | 5435 | [ALC662_FIXUP_ASUS_MODE7] = { |
5435 | .type = HDA_FIXUP_PINS, | 5436 | .type = HDA_FIXUP_PINS, |
5436 | .v.pins = (const struct hda_pintbl[]) { | 5437 | .v.pins = (const struct hda_pintbl[]) { |
5437 | { 0x14, 0x99130110 }, /* speaker */ | 5438 | { 0x14, 0x99130110 }, /* speaker */ |
5438 | { 0x17, 0x99130111 }, /* speaker */ | 5439 | { 0x17, 0x99130111 }, /* speaker */ |
5439 | { 0x18, 0x01a19840 }, /* mic */ | 5440 | { 0x18, 0x01a19840 }, /* mic */ |
5440 | { 0x19, 0x99a3094f }, /* int-mic */ | 5441 | { 0x19, 0x99a3094f }, /* int-mic */ |
5441 | { 0x1b, 0x01214020 }, /* HP */ | 5442 | { 0x1b, 0x01214020 }, /* HP */ |
5442 | { 0x21, 0x0121401f }, /* HP */ | 5443 | { 0x21, 0x0121401f }, /* HP */ |
5443 | { } | 5444 | { } |
5444 | }, | 5445 | }, |
5445 | .chained = true, | 5446 | .chained = true, |
5446 | .chain_id = ALC662_FIXUP_SKU_IGNORE | 5447 | .chain_id = ALC662_FIXUP_SKU_IGNORE |
5447 | }, | 5448 | }, |
5448 | [ALC662_FIXUP_ASUS_MODE8] = { | 5449 | [ALC662_FIXUP_ASUS_MODE8] = { |
5449 | .type = HDA_FIXUP_PINS, | 5450 | .type = HDA_FIXUP_PINS, |
5450 | .v.pins = (const struct hda_pintbl[]) { | 5451 | .v.pins = (const struct hda_pintbl[]) { |
5451 | { 0x14, 0x99130110 }, /* speaker */ | 5452 | { 0x14, 0x99130110 }, /* speaker */ |
5452 | { 0x12, 0x99a30970 }, /* int-mic */ | 5453 | { 0x12, 0x99a30970 }, /* int-mic */ |
5453 | { 0x15, 0x01214020 }, /* HP */ | 5454 | { 0x15, 0x01214020 }, /* HP */ |
5454 | { 0x17, 0x99130111 }, /* speaker */ | 5455 | { 0x17, 0x99130111 }, /* speaker */ |
5455 | { 0x18, 0x01a19840 }, /* mic */ | 5456 | { 0x18, 0x01a19840 }, /* mic */ |
5456 | { 0x21, 0x0121401f }, /* HP */ | 5457 | { 0x21, 0x0121401f }, /* HP */ |
5457 | { } | 5458 | { } |
5458 | }, | 5459 | }, |
5459 | .chained = true, | 5460 | .chained = true, |
5460 | .chain_id = ALC662_FIXUP_SKU_IGNORE | 5461 | .chain_id = ALC662_FIXUP_SKU_IGNORE |
5461 | }, | 5462 | }, |
5462 | [ALC662_FIXUP_NO_JACK_DETECT] = { | 5463 | [ALC662_FIXUP_NO_JACK_DETECT] = { |
5463 | .type = HDA_FIXUP_FUNC, | 5464 | .type = HDA_FIXUP_FUNC, |
5464 | .v.func = alc_fixup_no_jack_detect, | 5465 | .v.func = alc_fixup_no_jack_detect, |
5465 | }, | 5466 | }, |
5466 | [ALC662_FIXUP_ZOTAC_Z68] = { | 5467 | [ALC662_FIXUP_ZOTAC_Z68] = { |
5467 | .type = HDA_FIXUP_PINS, | 5468 | .type = HDA_FIXUP_PINS, |
5468 | .v.pins = (const struct hda_pintbl[]) { | 5469 | .v.pins = (const struct hda_pintbl[]) { |
5469 | { 0x1b, 0x02214020 }, /* Front HP */ | 5470 | { 0x1b, 0x02214020 }, /* Front HP */ |
5470 | { } | 5471 | { } |
5471 | } | 5472 | } |
5472 | }, | 5473 | }, |
5473 | [ALC662_FIXUP_INV_DMIC] = { | 5474 | [ALC662_FIXUP_INV_DMIC] = { |
5474 | .type = HDA_FIXUP_FUNC, | 5475 | .type = HDA_FIXUP_FUNC, |
5475 | .v.func = alc_fixup_inv_dmic_0x12, | 5476 | .v.func = alc_fixup_inv_dmic_0x12, |
5476 | }, | 5477 | }, |
5477 | [ALC668_FIXUP_AUTO_MUTE] = { | 5478 | [ALC668_FIXUP_AUTO_MUTE] = { |
5478 | .type = HDA_FIXUP_FUNC, | 5479 | .type = HDA_FIXUP_FUNC, |
5479 | .v.func = alc_fixup_auto_mute_via_amp, | 5480 | .v.func = alc_fixup_auto_mute_via_amp, |
5480 | .chained = true, | 5481 | .chained = true, |
5481 | .chain_id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE | 5482 | .chain_id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE |
5482 | }, | 5483 | }, |
5483 | [ALC668_FIXUP_DELL_MIC_NO_PRESENCE] = { | 5484 | [ALC668_FIXUP_DELL_MIC_NO_PRESENCE] = { |
5484 | .type = HDA_FIXUP_PINS, | 5485 | .type = HDA_FIXUP_PINS, |
5485 | .v.pins = (const struct hda_pintbl[]) { | 5486 | .v.pins = (const struct hda_pintbl[]) { |
5486 | { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */ | 5487 | { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */ |
5487 | { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */ | 5488 | { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */ |
5488 | { } | 5489 | { } |
5489 | }, | 5490 | }, |
5490 | .chained = true, | 5491 | .chained = true, |
5491 | .chain_id = ALC668_FIXUP_HEADSET_MODE | 5492 | .chain_id = ALC668_FIXUP_HEADSET_MODE |
5492 | }, | 5493 | }, |
5493 | [ALC668_FIXUP_HEADSET_MODE] = { | 5494 | [ALC668_FIXUP_HEADSET_MODE] = { |
5494 | .type = HDA_FIXUP_FUNC, | 5495 | .type = HDA_FIXUP_FUNC, |
5495 | .v.func = alc_fixup_headset_mode_alc668, | 5496 | .v.func = alc_fixup_headset_mode_alc668, |
5496 | }, | 5497 | }, |
5497 | [ALC662_FIXUP_BASS_MODE4_CHMAP] = { | 5498 | [ALC662_FIXUP_BASS_MODE4_CHMAP] = { |
5498 | .type = HDA_FIXUP_FUNC, | 5499 | .type = HDA_FIXUP_FUNC, |
5499 | .v.func = alc_fixup_bass_chmap, | 5500 | .v.func = alc_fixup_bass_chmap, |
5500 | .chained = true, | 5501 | .chained = true, |
5501 | .chain_id = ALC662_FIXUP_ASUS_MODE4 | 5502 | .chain_id = ALC662_FIXUP_ASUS_MODE4 |
5502 | }, | 5503 | }, |
5503 | [ALC662_FIXUP_BASS_16] = { | 5504 | [ALC662_FIXUP_BASS_16] = { |
5504 | .type = HDA_FIXUP_PINS, | 5505 | .type = HDA_FIXUP_PINS, |
5505 | .v.pins = (const struct hda_pintbl[]) { | 5506 | .v.pins = (const struct hda_pintbl[]) { |
5506 | {0x16, 0x80106111}, /* bass speaker */ | 5507 | {0x16, 0x80106111}, /* bass speaker */ |
5507 | {} | 5508 | {} |
5508 | }, | 5509 | }, |
5509 | .chained = true, | 5510 | .chained = true, |
5510 | .chain_id = ALC662_FIXUP_BASS_CHMAP, | 5511 | .chain_id = ALC662_FIXUP_BASS_CHMAP, |
5511 | }, | 5512 | }, |
5512 | [ALC662_FIXUP_BASS_1A] = { | 5513 | [ALC662_FIXUP_BASS_1A] = { |
5513 | .type = HDA_FIXUP_PINS, | 5514 | .type = HDA_FIXUP_PINS, |
5514 | .v.pins = (const struct hda_pintbl[]) { | 5515 | .v.pins = (const struct hda_pintbl[]) { |
5515 | {0x1a, 0x80106111}, /* bass speaker */ | 5516 | {0x1a, 0x80106111}, /* bass speaker */ |
5516 | {} | 5517 | {} |
5517 | }, | 5518 | }, |
5518 | .chained = true, | 5519 | .chained = true, |
5519 | .chain_id = ALC662_FIXUP_BASS_CHMAP, | 5520 | .chain_id = ALC662_FIXUP_BASS_CHMAP, |
5520 | }, | 5521 | }, |
5521 | [ALC662_FIXUP_BASS_CHMAP] = { | 5522 | [ALC662_FIXUP_BASS_CHMAP] = { |
5522 | .type = HDA_FIXUP_FUNC, | 5523 | .type = HDA_FIXUP_FUNC, |
5523 | .v.func = alc_fixup_bass_chmap, | 5524 | .v.func = alc_fixup_bass_chmap, |
5524 | }, | 5525 | }, |
5525 | }; | 5526 | }; |
5526 | 5527 | ||
5527 | static const struct snd_pci_quirk alc662_fixup_tbl[] = { | 5528 | static const struct snd_pci_quirk alc662_fixup_tbl[] = { |
5528 | SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_FIXUP_ASUS_MODE2), | 5529 | SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_FIXUP_ASUS_MODE2), |
5529 | SND_PCI_QUIRK(0x1025, 0x022f, "Acer Aspire One", ALC662_FIXUP_INV_DMIC), | 5530 | SND_PCI_QUIRK(0x1025, 0x022f, "Acer Aspire One", ALC662_FIXUP_INV_DMIC), |
5530 | SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE), | 5531 | SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE), |
5531 | SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE), | 5532 | SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE), |
5532 | SND_PCI_QUIRK(0x1025, 0x0349, "eMachines eM250", ALC662_FIXUP_INV_DMIC), | 5533 | SND_PCI_QUIRK(0x1025, 0x0349, "eMachines eM250", ALC662_FIXUP_INV_DMIC), |
5533 | SND_PCI_QUIRK(0x1025, 0x034a, "Gateway LT27", ALC662_FIXUP_INV_DMIC), | 5534 | SND_PCI_QUIRK(0x1025, 0x034a, "Gateway LT27", ALC662_FIXUP_INV_DMIC), |
5534 | SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), | 5535 | SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), |
5535 | SND_PCI_QUIRK(0x1028, 0x05d8, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), | 5536 | SND_PCI_QUIRK(0x1028, 0x05d8, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), |
5536 | SND_PCI_QUIRK(0x1028, 0x05db, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), | 5537 | SND_PCI_QUIRK(0x1028, 0x05db, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), |
5537 | SND_PCI_QUIRK(0x1028, 0x060a, "Dell XPS 13", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), | 5538 | SND_PCI_QUIRK(0x1028, 0x060a, "Dell XPS 13", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), |
5538 | SND_PCI_QUIRK(0x1028, 0x0623, "Dell", ALC668_FIXUP_AUTO_MUTE), | 5539 | SND_PCI_QUIRK(0x1028, 0x0623, "Dell", ALC668_FIXUP_AUTO_MUTE), |
5539 | SND_PCI_QUIRK(0x1028, 0x0624, "Dell", ALC668_FIXUP_AUTO_MUTE), | 5540 | SND_PCI_QUIRK(0x1028, 0x0624, "Dell", ALC668_FIXUP_AUTO_MUTE), |
5540 | SND_PCI_QUIRK(0x1028, 0x0625, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), | 5541 | SND_PCI_QUIRK(0x1028, 0x0625, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), |
5541 | SND_PCI_QUIRK(0x1028, 0x0626, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), | 5542 | SND_PCI_QUIRK(0x1028, 0x0626, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), |
5542 | SND_PCI_QUIRK(0x1028, 0x0628, "Dell", ALC668_FIXUP_AUTO_MUTE), | 5543 | SND_PCI_QUIRK(0x1028, 0x0628, "Dell", ALC668_FIXUP_AUTO_MUTE), |
5543 | SND_PCI_QUIRK(0x1028, 0x064e, "Dell", ALC668_FIXUP_AUTO_MUTE), | 5544 | SND_PCI_QUIRK(0x1028, 0x064e, "Dell", ALC668_FIXUP_AUTO_MUTE), |
5544 | SND_PCI_QUIRK(0x1028, 0x0696, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), | 5545 | SND_PCI_QUIRK(0x1028, 0x0696, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), |
5545 | SND_PCI_QUIRK(0x1028, 0x0698, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), | 5546 | SND_PCI_QUIRK(0x1028, 0x0698, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), |
5546 | SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800), | 5547 | SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800), |
5547 | SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_BASS_1A), | 5548 | SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_BASS_1A), |
5548 | SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_BASS_MODE4_CHMAP), | 5549 | SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_BASS_MODE4_CHMAP), |
5549 | SND_PCI_QUIRK(0x1043, 0x15a7, "ASUS UX51VZH", ALC662_FIXUP_BASS_16), | 5550 | SND_PCI_QUIRK(0x1043, 0x15a7, "ASUS UX51VZH", ALC662_FIXUP_BASS_16), |
5550 | SND_PCI_QUIRK(0x1043, 0x1b73, "ASUS N55SF", ALC662_FIXUP_BASS_16), | 5551 | SND_PCI_QUIRK(0x1043, 0x1b73, "ASUS N55SF", ALC662_FIXUP_BASS_16), |
5551 | SND_PCI_QUIRK(0x1043, 0x1bf3, "ASUS N76VZ", ALC662_FIXUP_BASS_MODE4_CHMAP), | 5552 | SND_PCI_QUIRK(0x1043, 0x1bf3, "ASUS N76VZ", ALC662_FIXUP_BASS_MODE4_CHMAP), |
5552 | SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT), | 5553 | SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT), |
5553 | SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2), | 5554 | SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2), |
5554 | SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD), | 5555 | SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD), |
5555 | SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD), | 5556 | SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD), |
5556 | SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD), | 5557 | SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD), |
5557 | SND_PCI_QUIRK(0x19da, 0xa130, "Zotac Z68", ALC662_FIXUP_ZOTAC_Z68), | 5558 | SND_PCI_QUIRK(0x19da, 0xa130, "Zotac Z68", ALC662_FIXUP_ZOTAC_Z68), |
5558 | SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T), | 5559 | SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T), |
5559 | 5560 | ||
5560 | #if 0 | 5561 | #if 0 |
5561 | /* Below is a quirk table taken from the old code. | 5562 | /* Below is a quirk table taken from the old code. |
5562 | * Basically the device should work as is without the fixup table. | 5563 | * Basically the device should work as is without the fixup table. |
5563 | * If BIOS doesn't give a proper info, enable the corresponding | 5564 | * If BIOS doesn't give a proper info, enable the corresponding |
5564 | * fixup entry. | 5565 | * fixup entry. |
5565 | */ | 5566 | */ |
5566 | SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC662_FIXUP_ASUS_MODE1), | 5567 | SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC662_FIXUP_ASUS_MODE1), |
5567 | SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC662_FIXUP_ASUS_MODE3), | 5568 | SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC662_FIXUP_ASUS_MODE3), |
5568 | SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC662_FIXUP_ASUS_MODE1), | 5569 | SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC662_FIXUP_ASUS_MODE1), |
5569 | SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC662_FIXUP_ASUS_MODE3), | 5570 | SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC662_FIXUP_ASUS_MODE3), |
5570 | SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1), | 5571 | SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1), |
5571 | SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), | 5572 | SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), |
5572 | SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC662_FIXUP_ASUS_MODE1), | 5573 | SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC662_FIXUP_ASUS_MODE1), |
5573 | SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC662_FIXUP_ASUS_MODE1), | 5574 | SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC662_FIXUP_ASUS_MODE1), |
5574 | SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC662_FIXUP_ASUS_MODE1), | 5575 | SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC662_FIXUP_ASUS_MODE1), |
5575 | SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), | 5576 | SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), |
5576 | SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC662_FIXUP_ASUS_MODE7), | 5577 | SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC662_FIXUP_ASUS_MODE7), |
5577 | SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC662_FIXUP_ASUS_MODE7), | 5578 | SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC662_FIXUP_ASUS_MODE7), |
5578 | SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC662_FIXUP_ASUS_MODE8), | 5579 | SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC662_FIXUP_ASUS_MODE8), |
5579 | SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC662_FIXUP_ASUS_MODE3), | 5580 | SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC662_FIXUP_ASUS_MODE3), |
5580 | SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC662_FIXUP_ASUS_MODE1), | 5581 | SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC662_FIXUP_ASUS_MODE1), |
5581 | SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), | 5582 | SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), |
5582 | SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_FIXUP_ASUS_MODE2), | 5583 | SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_FIXUP_ASUS_MODE2), |
5583 | SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC662_FIXUP_ASUS_MODE1), | 5584 | SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC662_FIXUP_ASUS_MODE1), |
5584 | SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), | 5585 | SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), |
5585 | SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC662_FIXUP_ASUS_MODE6), | 5586 | SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC662_FIXUP_ASUS_MODE6), |
5586 | SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC662_FIXUP_ASUS_MODE6), | 5587 | SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC662_FIXUP_ASUS_MODE6), |
5587 | SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), | 5588 | SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), |
5588 | SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC662_FIXUP_ASUS_MODE1), | 5589 | SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC662_FIXUP_ASUS_MODE1), |
5589 | SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC662_FIXUP_ASUS_MODE3), | 5590 | SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC662_FIXUP_ASUS_MODE3), |
5590 | SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_FIXUP_ASUS_MODE2), | 5591 | SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_FIXUP_ASUS_MODE2), |
5591 | SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), | 5592 | SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), |
5592 | SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC662_FIXUP_ASUS_MODE5), | 5593 | SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC662_FIXUP_ASUS_MODE5), |
5593 | SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC662_FIXUP_ASUS_MODE6), | 5594 | SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC662_FIXUP_ASUS_MODE6), |
5594 | SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), | 5595 | SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), |
5595 | SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC662_FIXUP_ASUS_MODE1), | 5596 | SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC662_FIXUP_ASUS_MODE1), |
5596 | SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), | 5597 | SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), |
5597 | SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), | 5598 | SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), |
5598 | SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC662_FIXUP_ASUS_MODE3), | 5599 | SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC662_FIXUP_ASUS_MODE3), |
5599 | SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC662_FIXUP_ASUS_MODE3), | 5600 | SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC662_FIXUP_ASUS_MODE3), |
5600 | SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC662_FIXUP_ASUS_MODE1), | 5601 | SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC662_FIXUP_ASUS_MODE1), |
5601 | SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC662_FIXUP_ASUS_MODE1), | 5602 | SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC662_FIXUP_ASUS_MODE1), |
5602 | SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC662_FIXUP_ASUS_MODE1), | 5603 | SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC662_FIXUP_ASUS_MODE1), |
5603 | SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC662_FIXUP_ASUS_MODE1), | 5604 | SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC662_FIXUP_ASUS_MODE1), |
5604 | SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC662_FIXUP_ASUS_MODE1), | 5605 | SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC662_FIXUP_ASUS_MODE1), |
5605 | SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), | 5606 | SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), |
5606 | SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_FIXUP_ASUS_MODE2), | 5607 | SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_FIXUP_ASUS_MODE2), |
5607 | SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC662_FIXUP_ASUS_MODE1), | 5608 | SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC662_FIXUP_ASUS_MODE1), |
5608 | SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC662_FIXUP_ASUS_MODE1), | 5609 | SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC662_FIXUP_ASUS_MODE1), |
5609 | SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC662_FIXUP_ASUS_MODE3), | 5610 | SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC662_FIXUP_ASUS_MODE3), |
5610 | SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC662_FIXUP_ASUS_MODE1), | 5611 | SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC662_FIXUP_ASUS_MODE1), |
5611 | SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC662_FIXUP_ASUS_MODE1), | 5612 | SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC662_FIXUP_ASUS_MODE1), |
5612 | SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC662_FIXUP_ASUS_MODE1), | 5613 | SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC662_FIXUP_ASUS_MODE1), |
5613 | SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_FIXUP_ASUS_MODE2), | 5614 | SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_FIXUP_ASUS_MODE2), |
5614 | SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1), | 5615 | SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1), |
5615 | SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE4), | 5616 | SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE4), |
5616 | #endif | 5617 | #endif |
5617 | {} | 5618 | {} |
5618 | }; | 5619 | }; |
5619 | 5620 | ||
5620 | static const struct hda_model_fixup alc662_fixup_models[] = { | 5621 | static const struct hda_model_fixup alc662_fixup_models[] = { |
5621 | {.id = ALC272_FIXUP_MARIO, .name = "mario"}, | 5622 | {.id = ALC272_FIXUP_MARIO, .name = "mario"}, |
5622 | {.id = ALC662_FIXUP_ASUS_MODE1, .name = "asus-mode1"}, | 5623 | {.id = ALC662_FIXUP_ASUS_MODE1, .name = "asus-mode1"}, |
5623 | {.id = ALC662_FIXUP_ASUS_MODE2, .name = "asus-mode2"}, | 5624 | {.id = ALC662_FIXUP_ASUS_MODE2, .name = "asus-mode2"}, |
5624 | {.id = ALC662_FIXUP_ASUS_MODE3, .name = "asus-mode3"}, | 5625 | {.id = ALC662_FIXUP_ASUS_MODE3, .name = "asus-mode3"}, |
5625 | {.id = ALC662_FIXUP_ASUS_MODE4, .name = "asus-mode4"}, | 5626 | {.id = ALC662_FIXUP_ASUS_MODE4, .name = "asus-mode4"}, |
5626 | {.id = ALC662_FIXUP_ASUS_MODE5, .name = "asus-mode5"}, | 5627 | {.id = ALC662_FIXUP_ASUS_MODE5, .name = "asus-mode5"}, |
5627 | {.id = ALC662_FIXUP_ASUS_MODE6, .name = "asus-mode6"}, | 5628 | {.id = ALC662_FIXUP_ASUS_MODE6, .name = "asus-mode6"}, |
5628 | {.id = ALC662_FIXUP_ASUS_MODE7, .name = "asus-mode7"}, | 5629 | {.id = ALC662_FIXUP_ASUS_MODE7, .name = "asus-mode7"}, |
5629 | {.id = ALC662_FIXUP_ASUS_MODE8, .name = "asus-mode8"}, | 5630 | {.id = ALC662_FIXUP_ASUS_MODE8, .name = "asus-mode8"}, |
5630 | {.id = ALC662_FIXUP_INV_DMIC, .name = "inv-dmic"}, | 5631 | {.id = ALC662_FIXUP_INV_DMIC, .name = "inv-dmic"}, |
5631 | {.id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE, .name = "dell-headset-multi"}, | 5632 | {.id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE, .name = "dell-headset-multi"}, |
5632 | {} | 5633 | {} |
5633 | }; | 5634 | }; |
5634 | 5635 | ||
5635 | static void alc662_fill_coef(struct hda_codec *codec) | 5636 | static void alc662_fill_coef(struct hda_codec *codec) |
5636 | { | 5637 | { |
5637 | int val, coef; | 5638 | int val, coef; |
5638 | 5639 | ||
5639 | coef = alc_get_coef0(codec); | 5640 | coef = alc_get_coef0(codec); |
5640 | 5641 | ||
5641 | switch (codec->vendor_id) { | 5642 | switch (codec->vendor_id) { |
5642 | case 0x10ec0662: | 5643 | case 0x10ec0662: |
5643 | if ((coef & 0x00f0) == 0x0030) { | 5644 | if ((coef & 0x00f0) == 0x0030) { |
5644 | val = alc_read_coef_idx(codec, 0x4); /* EAPD Ctrl */ | 5645 | val = alc_read_coef_idx(codec, 0x4); /* EAPD Ctrl */ |
5645 | alc_write_coef_idx(codec, 0x4, val & ~(1<<10)); | 5646 | alc_write_coef_idx(codec, 0x4, val & ~(1<<10)); |
5646 | } | 5647 | } |
5647 | break; | 5648 | break; |
5648 | case 0x10ec0272: | 5649 | case 0x10ec0272: |
5649 | case 0x10ec0273: | 5650 | case 0x10ec0273: |
5650 | case 0x10ec0663: | 5651 | case 0x10ec0663: |
5651 | case 0x10ec0665: | 5652 | case 0x10ec0665: |
5652 | case 0x10ec0670: | 5653 | case 0x10ec0670: |
5653 | case 0x10ec0671: | 5654 | case 0x10ec0671: |
5654 | case 0x10ec0672: | 5655 | case 0x10ec0672: |
5655 | val = alc_read_coef_idx(codec, 0xd); /* EAPD Ctrl */ | 5656 | val = alc_read_coef_idx(codec, 0xd); /* EAPD Ctrl */ |
5656 | alc_write_coef_idx(codec, 0xd, val | (1<<14)); | 5657 | alc_write_coef_idx(codec, 0xd, val | (1<<14)); |
5657 | break; | 5658 | break; |
5658 | } | 5659 | } |
5659 | } | 5660 | } |
5660 | 5661 | ||
5661 | /* | 5662 | /* |
5662 | */ | 5663 | */ |
5663 | static int patch_alc662(struct hda_codec *codec) | 5664 | static int patch_alc662(struct hda_codec *codec) |
5664 | { | 5665 | { |
5665 | struct alc_spec *spec; | 5666 | struct alc_spec *spec; |
5666 | int err; | 5667 | int err; |
5667 | 5668 | ||
5668 | err = alc_alloc_spec(codec, 0x0b); | 5669 | err = alc_alloc_spec(codec, 0x0b); |
5669 | if (err < 0) | 5670 | if (err < 0) |
5670 | return err; | 5671 | return err; |
5671 | 5672 | ||
5672 | spec = codec->spec; | 5673 | spec = codec->spec; |
5673 | 5674 | ||
5674 | /* handle multiple HPs as is */ | 5675 | /* handle multiple HPs as is */ |
5675 | spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP; | 5676 | spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP; |
5676 | 5677 | ||
5677 | alc_fix_pll_init(codec, 0x20, 0x04, 15); | 5678 | alc_fix_pll_init(codec, 0x20, 0x04, 15); |
5678 | 5679 | ||
5679 | spec->init_hook = alc662_fill_coef; | 5680 | spec->init_hook = alc662_fill_coef; |
5680 | alc662_fill_coef(codec); | 5681 | alc662_fill_coef(codec); |
5681 | 5682 | ||
5682 | snd_hda_pick_fixup(codec, alc662_fixup_models, | 5683 | snd_hda_pick_fixup(codec, alc662_fixup_models, |
5683 | alc662_fixup_tbl, alc662_fixups); | 5684 | alc662_fixup_tbl, alc662_fixups); |
5684 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); | 5685 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); |
5685 | 5686 | ||
5686 | alc_auto_parse_customize_define(codec); | 5687 | alc_auto_parse_customize_define(codec); |
5687 | 5688 | ||
5688 | if (has_cdefine_beep(codec)) | 5689 | if (has_cdefine_beep(codec)) |
5689 | spec->gen.beep_nid = 0x01; | 5690 | spec->gen.beep_nid = 0x01; |
5690 | 5691 | ||
5691 | if ((alc_get_coef0(codec) & (1 << 14)) && | 5692 | if ((alc_get_coef0(codec) & (1 << 14)) && |
5692 | codec->bus->pci && codec->bus->pci->subsystem_vendor == 0x1025 && | 5693 | codec->bus->pci && codec->bus->pci->subsystem_vendor == 0x1025 && |
5693 | spec->cdefine.platform_type == 1) { | 5694 | spec->cdefine.platform_type == 1) { |
5694 | err = alc_codec_rename(codec, "ALC272X"); | 5695 | err = alc_codec_rename(codec, "ALC272X"); |
5695 | if (err < 0) | 5696 | if (err < 0) |
5696 | goto error; | 5697 | goto error; |
5697 | } | 5698 | } |
5698 | 5699 | ||
5699 | /* automatic parse from the BIOS config */ | 5700 | /* automatic parse from the BIOS config */ |
5700 | err = alc662_parse_auto_config(codec); | 5701 | err = alc662_parse_auto_config(codec); |
5701 | if (err < 0) | 5702 | if (err < 0) |
5702 | goto error; | 5703 | goto error; |
5703 | 5704 | ||
5704 | if (!spec->gen.no_analog && spec->gen.beep_nid) { | 5705 | if (!spec->gen.no_analog && spec->gen.beep_nid) { |
5705 | switch (codec->vendor_id) { | 5706 | switch (codec->vendor_id) { |
5706 | case 0x10ec0662: | 5707 | case 0x10ec0662: |
5707 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); | 5708 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); |
5708 | break; | 5709 | break; |
5709 | case 0x10ec0272: | 5710 | case 0x10ec0272: |
5710 | case 0x10ec0663: | 5711 | case 0x10ec0663: |
5711 | case 0x10ec0665: | 5712 | case 0x10ec0665: |
5712 | case 0x10ec0668: | 5713 | case 0x10ec0668: |
5713 | set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); | 5714 | set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); |
5714 | break; | 5715 | break; |
5715 | case 0x10ec0273: | 5716 | case 0x10ec0273: |
5716 | set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT); | 5717 | set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT); |
5717 | break; | 5718 | break; |
5718 | } | 5719 | } |
5719 | } | 5720 | } |
5720 | 5721 | ||
5721 | codec->patch_ops = alc_patch_ops; | 5722 | codec->patch_ops = alc_patch_ops; |
5722 | spec->shutup = alc_eapd_shutup; | 5723 | spec->shutup = alc_eapd_shutup; |
5723 | 5724 | ||
5724 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); | 5725 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); |
5725 | 5726 | ||
5726 | return 0; | 5727 | return 0; |
5727 | 5728 | ||
5728 | error: | 5729 | error: |
5729 | alc_free(codec); | 5730 | alc_free(codec); |
5730 | return err; | 5731 | return err; |
5731 | } | 5732 | } |
5732 | 5733 | ||
5733 | /* | 5734 | /* |
5734 | * ALC680 support | 5735 | * ALC680 support |
5735 | */ | 5736 | */ |
5736 | 5737 | ||
5737 | static int alc680_parse_auto_config(struct hda_codec *codec) | 5738 | static int alc680_parse_auto_config(struct hda_codec *codec) |
5738 | { | 5739 | { |
5739 | return alc_parse_auto_config(codec, NULL, NULL); | 5740 | return alc_parse_auto_config(codec, NULL, NULL); |
5740 | } | 5741 | } |
5741 | 5742 | ||
5742 | /* | 5743 | /* |
5743 | */ | 5744 | */ |
5744 | static int patch_alc680(struct hda_codec *codec) | 5745 | static int patch_alc680(struct hda_codec *codec) |
5745 | { | 5746 | { |
5746 | int err; | 5747 | int err; |
5747 | 5748 | ||
5748 | /* ALC680 has no aa-loopback mixer */ | 5749 | /* ALC680 has no aa-loopback mixer */ |
5749 | err = alc_alloc_spec(codec, 0); | 5750 | err = alc_alloc_spec(codec, 0); |
5750 | if (err < 0) | 5751 | if (err < 0) |
5751 | return err; | 5752 | return err; |
5752 | 5753 | ||
5753 | /* automatic parse from the BIOS config */ | 5754 | /* automatic parse from the BIOS config */ |
5754 | err = alc680_parse_auto_config(codec); | 5755 | err = alc680_parse_auto_config(codec); |
5755 | if (err < 0) { | 5756 | if (err < 0) { |
5756 | alc_free(codec); | 5757 | alc_free(codec); |
5757 | return err; | 5758 | return err; |
5758 | } | 5759 | } |
5759 | 5760 | ||
5760 | codec->patch_ops = alc_patch_ops; | 5761 | codec->patch_ops = alc_patch_ops; |
5761 | 5762 | ||
5762 | return 0; | 5763 | return 0; |
5763 | } | 5764 | } |
5764 | 5765 | ||
5765 | /* | 5766 | /* |
5766 | * patch entries | 5767 | * patch entries |
5767 | */ | 5768 | */ |
5768 | static const struct hda_codec_preset snd_hda_preset_realtek[] = { | 5769 | static const struct hda_codec_preset snd_hda_preset_realtek[] = { |
5769 | { .id = 0x10ec0221, .name = "ALC221", .patch = patch_alc269 }, | 5770 | { .id = 0x10ec0221, .name = "ALC221", .patch = patch_alc269 }, |
5770 | { .id = 0x10ec0231, .name = "ALC231", .patch = patch_alc269 }, | 5771 | { .id = 0x10ec0231, .name = "ALC231", .patch = patch_alc269 }, |
5771 | { .id = 0x10ec0233, .name = "ALC233", .patch = patch_alc269 }, | 5772 | { .id = 0x10ec0233, .name = "ALC233", .patch = patch_alc269 }, |
5772 | { .id = 0x10ec0255, .name = "ALC255", .patch = patch_alc269 }, | 5773 | { .id = 0x10ec0255, .name = "ALC255", .patch = patch_alc269 }, |
5773 | { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 }, | 5774 | { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 }, |
5774 | { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 }, | 5775 | { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 }, |
5775 | { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 }, | 5776 | { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 }, |
5776 | { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 }, | 5777 | { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 }, |
5777 | { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 }, | 5778 | { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 }, |
5778 | { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 }, | 5779 | { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 }, |
5779 | { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 }, | 5780 | { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 }, |
5780 | { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 }, | 5781 | { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 }, |
5781 | { .id = 0x10ec0276, .name = "ALC276", .patch = patch_alc269 }, | 5782 | { .id = 0x10ec0276, .name = "ALC276", .patch = patch_alc269 }, |
5782 | { .id = 0x10ec0280, .name = "ALC280", .patch = patch_alc269 }, | 5783 | { .id = 0x10ec0280, .name = "ALC280", .patch = patch_alc269 }, |
5783 | { .id = 0x10ec0282, .name = "ALC282", .patch = patch_alc269 }, | 5784 | { .id = 0x10ec0282, .name = "ALC282", .patch = patch_alc269 }, |
5784 | { .id = 0x10ec0283, .name = "ALC283", .patch = patch_alc269 }, | 5785 | { .id = 0x10ec0283, .name = "ALC283", .patch = patch_alc269 }, |
5785 | { .id = 0x10ec0284, .name = "ALC284", .patch = patch_alc269 }, | 5786 | { .id = 0x10ec0284, .name = "ALC284", .patch = patch_alc269 }, |
5786 | { .id = 0x10ec0285, .name = "ALC285", .patch = patch_alc269 }, | 5787 | { .id = 0x10ec0285, .name = "ALC285", .patch = patch_alc269 }, |
5787 | { .id = 0x10ec0286, .name = "ALC286", .patch = patch_alc269 }, | 5788 | { .id = 0x10ec0286, .name = "ALC286", .patch = patch_alc269 }, |
5788 | { .id = 0x10ec0288, .name = "ALC288", .patch = patch_alc269 }, | 5789 | { .id = 0x10ec0288, .name = "ALC288", .patch = patch_alc269 }, |
5789 | { .id = 0x10ec0290, .name = "ALC290", .patch = patch_alc269 }, | 5790 | { .id = 0x10ec0290, .name = "ALC290", .patch = patch_alc269 }, |
5790 | { .id = 0x10ec0292, .name = "ALC292", .patch = patch_alc269 }, | 5791 | { .id = 0x10ec0292, .name = "ALC292", .patch = patch_alc269 }, |
5791 | { .id = 0x10ec0293, .name = "ALC293", .patch = patch_alc269 }, | 5792 | { .id = 0x10ec0293, .name = "ALC293", .patch = patch_alc269 }, |
5792 | { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", | 5793 | { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", |
5793 | .patch = patch_alc861 }, | 5794 | .patch = patch_alc861 }, |
5794 | { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd }, | 5795 | { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd }, |
5795 | { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 }, | 5796 | { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 }, |
5796 | { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd }, | 5797 | { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd }, |
5797 | { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2", | 5798 | { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2", |
5798 | .patch = patch_alc882 }, | 5799 | .patch = patch_alc882 }, |
5799 | { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1", | 5800 | { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1", |
5800 | .patch = patch_alc662 }, | 5801 | .patch = patch_alc662 }, |
5801 | { .id = 0x10ec0662, .rev = 0x100300, .name = "ALC662 rev3", | 5802 | { .id = 0x10ec0662, .rev = 0x100300, .name = "ALC662 rev3", |
5802 | .patch = patch_alc662 }, | 5803 | .patch = patch_alc662 }, |
5803 | { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 }, | 5804 | { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 }, |
5804 | { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 }, | 5805 | { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 }, |
5805 | { .id = 0x10ec0668, .name = "ALC668", .patch = patch_alc662 }, | 5806 | { .id = 0x10ec0668, .name = "ALC668", .patch = patch_alc662 }, |
5806 | { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 }, | 5807 | { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 }, |
5807 | { .id = 0x10ec0671, .name = "ALC671", .patch = patch_alc662 }, | 5808 | { .id = 0x10ec0671, .name = "ALC671", .patch = patch_alc662 }, |
5808 | { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 }, | 5809 | { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 }, |
5809 | { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, | 5810 | { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, |
5810 | { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, | 5811 | { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, |
5811 | { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 }, | 5812 | { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 }, |
5812 | { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A", | 5813 | { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A", |
5813 | .patch = patch_alc882 }, | 5814 | .patch = patch_alc882 }, |
5814 | { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A", | 5815 | { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A", |
5815 | .patch = patch_alc882 }, | 5816 | .patch = patch_alc882 }, |
5816 | { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 }, | 5817 | { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 }, |
5817 | { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 }, | 5818 | { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 }, |
5818 | { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200", | 5819 | { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200", |
5819 | .patch = patch_alc882 }, | 5820 | .patch = patch_alc882 }, |
5820 | { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc882 }, | 5821 | { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc882 }, |
5821 | { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 }, | 5822 | { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 }, |
5822 | { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 }, | 5823 | { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 }, |
5823 | { .id = 0x10ec0899, .name = "ALC898", .patch = patch_alc882 }, | 5824 | { .id = 0x10ec0899, .name = "ALC898", .patch = patch_alc882 }, |
5824 | { .id = 0x10ec0900, .name = "ALC1150", .patch = patch_alc882 }, | 5825 | { .id = 0x10ec0900, .name = "ALC1150", .patch = patch_alc882 }, |
5825 | {} /* terminator */ | 5826 | {} /* terminator */ |
5826 | }; | 5827 | }; |
5827 | 5828 | ||
5828 | MODULE_ALIAS("snd-hda-codec-id:10ec*"); | 5829 | MODULE_ALIAS("snd-hda-codec-id:10ec*"); |
5829 | 5830 | ||
5830 | MODULE_LICENSE("GPL"); | 5831 | MODULE_LICENSE("GPL"); |
5831 | MODULE_DESCRIPTION("Realtek HD-audio codec"); | 5832 | MODULE_DESCRIPTION("Realtek HD-audio codec"); |
5832 | 5833 | ||
5833 | static struct hda_codec_preset_list realtek_list = { | 5834 | static struct hda_codec_preset_list realtek_list = { |
5834 | .preset = snd_hda_preset_realtek, | 5835 | .preset = snd_hda_preset_realtek, |
5835 | .owner = THIS_MODULE, | 5836 | .owner = THIS_MODULE, |
5836 | }; | 5837 | }; |
5837 | 5838 | ||
5838 | static int __init patch_realtek_init(void) | 5839 | static int __init patch_realtek_init(void) |
5839 | { | 5840 | { |
5840 | return snd_hda_add_codec_preset(&realtek_list); | 5841 | return snd_hda_add_codec_preset(&realtek_list); |
5841 | } | 5842 | } |
5842 | 5843 | ||
5843 | static void __exit patch_realtek_exit(void) | 5844 | static void __exit patch_realtek_exit(void) |
5844 | { | 5845 | { |
5845 | snd_hda_delete_codec_preset(&realtek_list); | 5846 | snd_hda_delete_codec_preset(&realtek_list); |
5846 | } | 5847 | } |
5847 | 5848 | ||
5848 | module_init(patch_realtek_init) | 5849 | module_init(patch_realtek_init) |
5849 | module_exit(patch_realtek_exit) | 5850 | module_exit(patch_realtek_exit) |
5850 | 5851 |