Commit 192a98e280e560510a62aca8cfa83b4ae7c095bb
1 parent
e30cf2d2be
Exists in
ti-lsk-linux-4.1.y
and in
12 other branches
ALSA: hda/realtek - Fix COEF widget NID for ALC260 replacer fixup
The conversion to a fixup table for Replacer model with ALC260 in commit 20f7d928 took the wrong widget NID for COEF setups. Namely, NID 0x1a should have been used instead of NID 0x20, which is the common node for all Realtek codecs but ALC260. Fixes: 20f7d928fa6e ('ALSA: hda/realtek - Replace ALC260 model=replacer with the auto-parser') Cc: <stable@vger.kernel.org> [v3.4+] Signed-off-by: Takashi Iwai <tiwai@suse.de>
Showing 1 changed file with 2 additions and 2 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 | { 0x1a, AC_VERB_SET_COEF_INDEX, 0x07 }, | 1650 | { 0x1a, AC_VERB_SET_COEF_INDEX, 0x07 }, |
1651 | { 0x1a, AC_VERB_SET_PROC_COEF, 0x3040 }, | 1651 | { 0x1a, AC_VERB_SET_PROC_COEF, 0x3040 }, |
1652 | { } | 1652 | { } |
1653 | }, | 1653 | }, |
1654 | }, | 1654 | }, |
1655 | [ALC260_FIXUP_GPIO1] = { | 1655 | [ALC260_FIXUP_GPIO1] = { |
1656 | .type = HDA_FIXUP_VERBS, | 1656 | .type = HDA_FIXUP_VERBS, |
1657 | .v.verbs = alc_gpio1_init_verbs, | 1657 | .v.verbs = alc_gpio1_init_verbs, |
1658 | }, | 1658 | }, |
1659 | [ALC260_FIXUP_GPIO1_TOGGLE] = { | 1659 | [ALC260_FIXUP_GPIO1_TOGGLE] = { |
1660 | .type = HDA_FIXUP_FUNC, | 1660 | .type = HDA_FIXUP_FUNC, |
1661 | .v.func = alc260_fixup_gpio1_toggle, | 1661 | .v.func = alc260_fixup_gpio1_toggle, |
1662 | .chained = true, | 1662 | .chained = true, |
1663 | .chain_id = ALC260_FIXUP_HP_PIN_0F, | 1663 | .chain_id = ALC260_FIXUP_HP_PIN_0F, |
1664 | }, | 1664 | }, |
1665 | [ALC260_FIXUP_REPLACER] = { | 1665 | [ALC260_FIXUP_REPLACER] = { |
1666 | .type = HDA_FIXUP_VERBS, | 1666 | .type = HDA_FIXUP_VERBS, |
1667 | .v.verbs = (const struct hda_verb[]) { | 1667 | .v.verbs = (const struct hda_verb[]) { |
1668 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, | 1668 | { 0x1a, AC_VERB_SET_COEF_INDEX, 0x07 }, |
1669 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 }, | 1669 | { 0x1a, AC_VERB_SET_PROC_COEF, 0x3050 }, |
1670 | { } | 1670 | { } |
1671 | }, | 1671 | }, |
1672 | .chained = true, | 1672 | .chained = true, |
1673 | .chain_id = ALC260_FIXUP_GPIO1_TOGGLE, | 1673 | .chain_id = ALC260_FIXUP_GPIO1_TOGGLE, |
1674 | }, | 1674 | }, |
1675 | [ALC260_FIXUP_HP_B1900] = { | 1675 | [ALC260_FIXUP_HP_B1900] = { |
1676 | .type = HDA_FIXUP_FUNC, | 1676 | .type = HDA_FIXUP_FUNC, |
1677 | .v.func = alc260_fixup_gpio1_toggle, | 1677 | .v.func = alc260_fixup_gpio1_toggle, |
1678 | .chained = true, | 1678 | .chained = true, |
1679 | .chain_id = ALC260_FIXUP_COEF, | 1679 | .chain_id = ALC260_FIXUP_COEF, |
1680 | }, | 1680 | }, |
1681 | [ALC260_FIXUP_KN1] = { | 1681 | [ALC260_FIXUP_KN1] = { |
1682 | .type = HDA_FIXUP_FUNC, | 1682 | .type = HDA_FIXUP_FUNC, |
1683 | .v.func = alc260_fixup_kn1, | 1683 | .v.func = alc260_fixup_kn1, |
1684 | }, | 1684 | }, |
1685 | [ALC260_FIXUP_FSC_S7020] = { | 1685 | [ALC260_FIXUP_FSC_S7020] = { |
1686 | .type = HDA_FIXUP_FUNC, | 1686 | .type = HDA_FIXUP_FUNC, |
1687 | .v.func = alc260_fixup_fsc_s7020, | 1687 | .v.func = alc260_fixup_fsc_s7020, |
1688 | }, | 1688 | }, |
1689 | [ALC260_FIXUP_FSC_S7020_JWSE] = { | 1689 | [ALC260_FIXUP_FSC_S7020_JWSE] = { |
1690 | .type = HDA_FIXUP_FUNC, | 1690 | .type = HDA_FIXUP_FUNC, |
1691 | .v.func = alc260_fixup_fsc_s7020_jwse, | 1691 | .v.func = alc260_fixup_fsc_s7020_jwse, |
1692 | .chained = true, | 1692 | .chained = true, |
1693 | .chain_id = ALC260_FIXUP_FSC_S7020, | 1693 | .chain_id = ALC260_FIXUP_FSC_S7020, |
1694 | }, | 1694 | }, |
1695 | [ALC260_FIXUP_VAIO_PINS] = { | 1695 | [ALC260_FIXUP_VAIO_PINS] = { |
1696 | .type = HDA_FIXUP_PINS, | 1696 | .type = HDA_FIXUP_PINS, |
1697 | .v.pins = (const struct hda_pintbl[]) { | 1697 | .v.pins = (const struct hda_pintbl[]) { |
1698 | /* Pin configs are missing completely on some VAIOs */ | 1698 | /* Pin configs are missing completely on some VAIOs */ |
1699 | { 0x0f, 0x01211020 }, | 1699 | { 0x0f, 0x01211020 }, |
1700 | { 0x10, 0x0001003f }, | 1700 | { 0x10, 0x0001003f }, |
1701 | { 0x11, 0x411111f0 }, | 1701 | { 0x11, 0x411111f0 }, |
1702 | { 0x12, 0x01a15930 }, | 1702 | { 0x12, 0x01a15930 }, |
1703 | { 0x13, 0x411111f0 }, | 1703 | { 0x13, 0x411111f0 }, |
1704 | { 0x14, 0x411111f0 }, | 1704 | { 0x14, 0x411111f0 }, |
1705 | { 0x15, 0x411111f0 }, | 1705 | { 0x15, 0x411111f0 }, |
1706 | { 0x16, 0x411111f0 }, | 1706 | { 0x16, 0x411111f0 }, |
1707 | { 0x17, 0x411111f0 }, | 1707 | { 0x17, 0x411111f0 }, |
1708 | { 0x18, 0x411111f0 }, | 1708 | { 0x18, 0x411111f0 }, |
1709 | { 0x19, 0x411111f0 }, | 1709 | { 0x19, 0x411111f0 }, |
1710 | { } | 1710 | { } |
1711 | } | 1711 | } |
1712 | }, | 1712 | }, |
1713 | }; | 1713 | }; |
1714 | 1714 | ||
1715 | static const struct snd_pci_quirk alc260_fixup_tbl[] = { | 1715 | static const struct snd_pci_quirk alc260_fixup_tbl[] = { |
1716 | SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_FIXUP_GPIO1), | 1716 | SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_FIXUP_GPIO1), |
1717 | SND_PCI_QUIRK(0x1025, 0x007f, "Acer Aspire 9500", ALC260_FIXUP_COEF), | 1717 | SND_PCI_QUIRK(0x1025, 0x007f, "Acer Aspire 9500", ALC260_FIXUP_COEF), |
1718 | SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_FIXUP_GPIO1), | 1718 | SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_FIXUP_GPIO1), |
1719 | SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", ALC260_FIXUP_HP_DC5750), | 1719 | SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", ALC260_FIXUP_HP_DC5750), |
1720 | SND_PCI_QUIRK(0x103c, 0x30ba, "HP Presario B1900", ALC260_FIXUP_HP_B1900), | 1720 | SND_PCI_QUIRK(0x103c, 0x30ba, "HP Presario B1900", ALC260_FIXUP_HP_B1900), |
1721 | SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_FIXUP_VAIO_PINS), | 1721 | SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_FIXUP_VAIO_PINS), |
1722 | SND_PCI_QUIRK(0x104d, 0x81e2, "Sony VAIO TX", ALC260_FIXUP_HP_PIN_0F), | 1722 | SND_PCI_QUIRK(0x104d, 0x81e2, "Sony VAIO TX", ALC260_FIXUP_HP_PIN_0F), |
1723 | SND_PCI_QUIRK(0x10cf, 0x1326, "FSC LifeBook S7020", ALC260_FIXUP_FSC_S7020), | 1723 | SND_PCI_QUIRK(0x10cf, 0x1326, "FSC LifeBook S7020", ALC260_FIXUP_FSC_S7020), |
1724 | SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FIXUP_GPIO1), | 1724 | SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FIXUP_GPIO1), |
1725 | SND_PCI_QUIRK(0x152d, 0x0729, "Quanta KN1", ALC260_FIXUP_KN1), | 1725 | SND_PCI_QUIRK(0x152d, 0x0729, "Quanta KN1", ALC260_FIXUP_KN1), |
1726 | SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_FIXUP_REPLACER), | 1726 | SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_FIXUP_REPLACER), |
1727 | SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_FIXUP_COEF), | 1727 | SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_FIXUP_COEF), |
1728 | {} | 1728 | {} |
1729 | }; | 1729 | }; |
1730 | 1730 | ||
1731 | static const struct hda_model_fixup alc260_fixup_models[] = { | 1731 | static const struct hda_model_fixup alc260_fixup_models[] = { |
1732 | {.id = ALC260_FIXUP_GPIO1, .name = "gpio1"}, | 1732 | {.id = ALC260_FIXUP_GPIO1, .name = "gpio1"}, |
1733 | {.id = ALC260_FIXUP_COEF, .name = "coef"}, | 1733 | {.id = ALC260_FIXUP_COEF, .name = "coef"}, |
1734 | {.id = ALC260_FIXUP_FSC_S7020, .name = "fujitsu"}, | 1734 | {.id = ALC260_FIXUP_FSC_S7020, .name = "fujitsu"}, |
1735 | {.id = ALC260_FIXUP_FSC_S7020_JWSE, .name = "fujitsu-jwse"}, | 1735 | {.id = ALC260_FIXUP_FSC_S7020_JWSE, .name = "fujitsu-jwse"}, |
1736 | {} | 1736 | {} |
1737 | }; | 1737 | }; |
1738 | 1738 | ||
1739 | /* | 1739 | /* |
1740 | */ | 1740 | */ |
1741 | static int patch_alc260(struct hda_codec *codec) | 1741 | static int patch_alc260(struct hda_codec *codec) |
1742 | { | 1742 | { |
1743 | struct alc_spec *spec; | 1743 | struct alc_spec *spec; |
1744 | int err; | 1744 | int err; |
1745 | 1745 | ||
1746 | err = alc_alloc_spec(codec, 0x07); | 1746 | err = alc_alloc_spec(codec, 0x07); |
1747 | if (err < 0) | 1747 | if (err < 0) |
1748 | return err; | 1748 | return err; |
1749 | 1749 | ||
1750 | spec = codec->spec; | 1750 | spec = codec->spec; |
1751 | /* as quite a few machines require HP amp for speaker outputs, | 1751 | /* as quite a few machines require HP amp for speaker outputs, |
1752 | * it's easier to enable it unconditionally; even if it's unneeded, | 1752 | * it's easier to enable it unconditionally; even if it's unneeded, |
1753 | * it's almost harmless. | 1753 | * it's almost harmless. |
1754 | */ | 1754 | */ |
1755 | spec->gen.prefer_hp_amp = 1; | 1755 | spec->gen.prefer_hp_amp = 1; |
1756 | spec->gen.beep_nid = 0x01; | 1756 | spec->gen.beep_nid = 0x01; |
1757 | 1757 | ||
1758 | snd_hda_pick_fixup(codec, alc260_fixup_models, alc260_fixup_tbl, | 1758 | snd_hda_pick_fixup(codec, alc260_fixup_models, alc260_fixup_tbl, |
1759 | alc260_fixups); | 1759 | alc260_fixups); |
1760 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); | 1760 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); |
1761 | 1761 | ||
1762 | /* automatic parse from the BIOS config */ | 1762 | /* automatic parse from the BIOS config */ |
1763 | err = alc260_parse_auto_config(codec); | 1763 | err = alc260_parse_auto_config(codec); |
1764 | if (err < 0) | 1764 | if (err < 0) |
1765 | goto error; | 1765 | goto error; |
1766 | 1766 | ||
1767 | if (!spec->gen.no_analog) | 1767 | if (!spec->gen.no_analog) |
1768 | set_beep_amp(spec, 0x07, 0x05, HDA_INPUT); | 1768 | set_beep_amp(spec, 0x07, 0x05, HDA_INPUT); |
1769 | 1769 | ||
1770 | codec->patch_ops = alc_patch_ops; | 1770 | codec->patch_ops = alc_patch_ops; |
1771 | spec->shutup = alc_eapd_shutup; | 1771 | spec->shutup = alc_eapd_shutup; |
1772 | 1772 | ||
1773 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); | 1773 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); |
1774 | 1774 | ||
1775 | return 0; | 1775 | return 0; |
1776 | 1776 | ||
1777 | error: | 1777 | error: |
1778 | alc_free(codec); | 1778 | alc_free(codec); |
1779 | return err; | 1779 | return err; |
1780 | } | 1780 | } |
1781 | 1781 | ||
1782 | 1782 | ||
1783 | /* | 1783 | /* |
1784 | * ALC882/883/885/888/889 support | 1784 | * ALC882/883/885/888/889 support |
1785 | * | 1785 | * |
1786 | * ALC882 is almost identical with ALC880 but has cleaner and more flexible | 1786 | * ALC882 is almost identical with ALC880 but has cleaner and more flexible |
1787 | * configuration. Each pin widget can choose any input DACs and a mixer. | 1787 | * configuration. Each pin widget can choose any input DACs and a mixer. |
1788 | * Each ADC is connected from a mixer of all inputs. This makes possible | 1788 | * Each ADC is connected from a mixer of all inputs. This makes possible |
1789 | * 6-channel independent captures. | 1789 | * 6-channel independent captures. |
1790 | * | 1790 | * |
1791 | * In addition, an independent DAC for the multi-playback (not used in this | 1791 | * In addition, an independent DAC for the multi-playback (not used in this |
1792 | * driver yet). | 1792 | * driver yet). |
1793 | */ | 1793 | */ |
1794 | 1794 | ||
1795 | /* | 1795 | /* |
1796 | * Pin config fixes | 1796 | * Pin config fixes |
1797 | */ | 1797 | */ |
1798 | enum { | 1798 | enum { |
1799 | ALC882_FIXUP_ABIT_AW9D_MAX, | 1799 | ALC882_FIXUP_ABIT_AW9D_MAX, |
1800 | ALC882_FIXUP_LENOVO_Y530, | 1800 | ALC882_FIXUP_LENOVO_Y530, |
1801 | ALC882_FIXUP_PB_M5210, | 1801 | ALC882_FIXUP_PB_M5210, |
1802 | ALC882_FIXUP_ACER_ASPIRE_7736, | 1802 | ALC882_FIXUP_ACER_ASPIRE_7736, |
1803 | ALC882_FIXUP_ASUS_W90V, | 1803 | ALC882_FIXUP_ASUS_W90V, |
1804 | ALC889_FIXUP_CD, | 1804 | ALC889_FIXUP_CD, |
1805 | ALC889_FIXUP_FRONT_HP_NO_PRESENCE, | 1805 | ALC889_FIXUP_FRONT_HP_NO_PRESENCE, |
1806 | ALC889_FIXUP_VAIO_TT, | 1806 | ALC889_FIXUP_VAIO_TT, |
1807 | ALC888_FIXUP_EEE1601, | 1807 | ALC888_FIXUP_EEE1601, |
1808 | ALC882_FIXUP_EAPD, | 1808 | ALC882_FIXUP_EAPD, |
1809 | ALC883_FIXUP_EAPD, | 1809 | ALC883_FIXUP_EAPD, |
1810 | ALC883_FIXUP_ACER_EAPD, | 1810 | ALC883_FIXUP_ACER_EAPD, |
1811 | ALC882_FIXUP_GPIO1, | 1811 | ALC882_FIXUP_GPIO1, |
1812 | ALC882_FIXUP_GPIO2, | 1812 | ALC882_FIXUP_GPIO2, |
1813 | ALC882_FIXUP_GPIO3, | 1813 | ALC882_FIXUP_GPIO3, |
1814 | ALC889_FIXUP_COEF, | 1814 | ALC889_FIXUP_COEF, |
1815 | ALC882_FIXUP_ASUS_W2JC, | 1815 | ALC882_FIXUP_ASUS_W2JC, |
1816 | ALC882_FIXUP_ACER_ASPIRE_4930G, | 1816 | ALC882_FIXUP_ACER_ASPIRE_4930G, |
1817 | ALC882_FIXUP_ACER_ASPIRE_8930G, | 1817 | ALC882_FIXUP_ACER_ASPIRE_8930G, |
1818 | ALC882_FIXUP_ASPIRE_8930G_VERBS, | 1818 | ALC882_FIXUP_ASPIRE_8930G_VERBS, |
1819 | ALC885_FIXUP_MACPRO_GPIO, | 1819 | ALC885_FIXUP_MACPRO_GPIO, |
1820 | ALC889_FIXUP_DAC_ROUTE, | 1820 | ALC889_FIXUP_DAC_ROUTE, |
1821 | ALC889_FIXUP_MBP_VREF, | 1821 | ALC889_FIXUP_MBP_VREF, |
1822 | ALC889_FIXUP_IMAC91_VREF, | 1822 | ALC889_FIXUP_IMAC91_VREF, |
1823 | ALC889_FIXUP_MBA11_VREF, | 1823 | ALC889_FIXUP_MBA11_VREF, |
1824 | ALC889_FIXUP_MBA21_VREF, | 1824 | ALC889_FIXUP_MBA21_VREF, |
1825 | ALC889_FIXUP_MP11_VREF, | 1825 | ALC889_FIXUP_MP11_VREF, |
1826 | ALC882_FIXUP_INV_DMIC, | 1826 | ALC882_FIXUP_INV_DMIC, |
1827 | ALC882_FIXUP_NO_PRIMARY_HP, | 1827 | ALC882_FIXUP_NO_PRIMARY_HP, |
1828 | ALC887_FIXUP_ASUS_BASS, | 1828 | ALC887_FIXUP_ASUS_BASS, |
1829 | ALC887_FIXUP_BASS_CHMAP, | 1829 | ALC887_FIXUP_BASS_CHMAP, |
1830 | }; | 1830 | }; |
1831 | 1831 | ||
1832 | static void alc889_fixup_coef(struct hda_codec *codec, | 1832 | static void alc889_fixup_coef(struct hda_codec *codec, |
1833 | const struct hda_fixup *fix, int action) | 1833 | const struct hda_fixup *fix, int action) |
1834 | { | 1834 | { |
1835 | if (action != HDA_FIXUP_ACT_INIT) | 1835 | if (action != HDA_FIXUP_ACT_INIT) |
1836 | return; | 1836 | return; |
1837 | alc889_coef_init(codec); | 1837 | alc889_coef_init(codec); |
1838 | } | 1838 | } |
1839 | 1839 | ||
1840 | /* toggle speaker-output according to the hp-jack state */ | 1840 | /* toggle speaker-output according to the hp-jack state */ |
1841 | static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted) | 1841 | static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted) |
1842 | { | 1842 | { |
1843 | unsigned int gpiostate, gpiomask, gpiodir; | 1843 | unsigned int gpiostate, gpiomask, gpiodir; |
1844 | 1844 | ||
1845 | gpiostate = snd_hda_codec_read(codec, codec->afg, 0, | 1845 | gpiostate = snd_hda_codec_read(codec, codec->afg, 0, |
1846 | AC_VERB_GET_GPIO_DATA, 0); | 1846 | AC_VERB_GET_GPIO_DATA, 0); |
1847 | 1847 | ||
1848 | if (!muted) | 1848 | if (!muted) |
1849 | gpiostate |= (1 << pin); | 1849 | gpiostate |= (1 << pin); |
1850 | else | 1850 | else |
1851 | gpiostate &= ~(1 << pin); | 1851 | gpiostate &= ~(1 << pin); |
1852 | 1852 | ||
1853 | gpiomask = snd_hda_codec_read(codec, codec->afg, 0, | 1853 | gpiomask = snd_hda_codec_read(codec, codec->afg, 0, |
1854 | AC_VERB_GET_GPIO_MASK, 0); | 1854 | AC_VERB_GET_GPIO_MASK, 0); |
1855 | gpiomask |= (1 << pin); | 1855 | gpiomask |= (1 << pin); |
1856 | 1856 | ||
1857 | gpiodir = snd_hda_codec_read(codec, codec->afg, 0, | 1857 | gpiodir = snd_hda_codec_read(codec, codec->afg, 0, |
1858 | AC_VERB_GET_GPIO_DIRECTION, 0); | 1858 | AC_VERB_GET_GPIO_DIRECTION, 0); |
1859 | gpiodir |= (1 << pin); | 1859 | gpiodir |= (1 << pin); |
1860 | 1860 | ||
1861 | 1861 | ||
1862 | snd_hda_codec_write(codec, codec->afg, 0, | 1862 | snd_hda_codec_write(codec, codec->afg, 0, |
1863 | AC_VERB_SET_GPIO_MASK, gpiomask); | 1863 | AC_VERB_SET_GPIO_MASK, gpiomask); |
1864 | snd_hda_codec_write(codec, codec->afg, 0, | 1864 | snd_hda_codec_write(codec, codec->afg, 0, |
1865 | AC_VERB_SET_GPIO_DIRECTION, gpiodir); | 1865 | AC_VERB_SET_GPIO_DIRECTION, gpiodir); |
1866 | 1866 | ||
1867 | msleep(1); | 1867 | msleep(1); |
1868 | 1868 | ||
1869 | snd_hda_codec_write(codec, codec->afg, 0, | 1869 | snd_hda_codec_write(codec, codec->afg, 0, |
1870 | AC_VERB_SET_GPIO_DATA, gpiostate); | 1870 | AC_VERB_SET_GPIO_DATA, gpiostate); |
1871 | } | 1871 | } |
1872 | 1872 | ||
1873 | /* set up GPIO at initialization */ | 1873 | /* set up GPIO at initialization */ |
1874 | static void alc885_fixup_macpro_gpio(struct hda_codec *codec, | 1874 | static void alc885_fixup_macpro_gpio(struct hda_codec *codec, |
1875 | const struct hda_fixup *fix, int action) | 1875 | const struct hda_fixup *fix, int action) |
1876 | { | 1876 | { |
1877 | if (action != HDA_FIXUP_ACT_INIT) | 1877 | if (action != HDA_FIXUP_ACT_INIT) |
1878 | return; | 1878 | return; |
1879 | alc882_gpio_mute(codec, 0, 0); | 1879 | alc882_gpio_mute(codec, 0, 0); |
1880 | alc882_gpio_mute(codec, 1, 0); | 1880 | alc882_gpio_mute(codec, 1, 0); |
1881 | } | 1881 | } |
1882 | 1882 | ||
1883 | /* Fix the connection of some pins for ALC889: | 1883 | /* Fix the connection of some pins for ALC889: |
1884 | * At least, Acer Aspire 5935 shows the connections to DAC3/4 don't | 1884 | * At least, Acer Aspire 5935 shows the connections to DAC3/4 don't |
1885 | * work correctly (bko#42740) | 1885 | * work correctly (bko#42740) |
1886 | */ | 1886 | */ |
1887 | static void alc889_fixup_dac_route(struct hda_codec *codec, | 1887 | static void alc889_fixup_dac_route(struct hda_codec *codec, |
1888 | const struct hda_fixup *fix, int action) | 1888 | const struct hda_fixup *fix, int action) |
1889 | { | 1889 | { |
1890 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | 1890 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
1891 | /* fake the connections during parsing the tree */ | 1891 | /* fake the connections during parsing the tree */ |
1892 | hda_nid_t conn1[2] = { 0x0c, 0x0d }; | 1892 | hda_nid_t conn1[2] = { 0x0c, 0x0d }; |
1893 | hda_nid_t conn2[2] = { 0x0e, 0x0f }; | 1893 | hda_nid_t conn2[2] = { 0x0e, 0x0f }; |
1894 | snd_hda_override_conn_list(codec, 0x14, 2, conn1); | 1894 | snd_hda_override_conn_list(codec, 0x14, 2, conn1); |
1895 | snd_hda_override_conn_list(codec, 0x15, 2, conn1); | 1895 | snd_hda_override_conn_list(codec, 0x15, 2, conn1); |
1896 | snd_hda_override_conn_list(codec, 0x18, 2, conn2); | 1896 | snd_hda_override_conn_list(codec, 0x18, 2, conn2); |
1897 | snd_hda_override_conn_list(codec, 0x1a, 2, conn2); | 1897 | snd_hda_override_conn_list(codec, 0x1a, 2, conn2); |
1898 | } else if (action == HDA_FIXUP_ACT_PROBE) { | 1898 | } else if (action == HDA_FIXUP_ACT_PROBE) { |
1899 | /* restore the connections */ | 1899 | /* restore the connections */ |
1900 | hda_nid_t conn[5] = { 0x0c, 0x0d, 0x0e, 0x0f, 0x26 }; | 1900 | hda_nid_t conn[5] = { 0x0c, 0x0d, 0x0e, 0x0f, 0x26 }; |
1901 | snd_hda_override_conn_list(codec, 0x14, 5, conn); | 1901 | snd_hda_override_conn_list(codec, 0x14, 5, conn); |
1902 | snd_hda_override_conn_list(codec, 0x15, 5, conn); | 1902 | snd_hda_override_conn_list(codec, 0x15, 5, conn); |
1903 | snd_hda_override_conn_list(codec, 0x18, 5, conn); | 1903 | snd_hda_override_conn_list(codec, 0x18, 5, conn); |
1904 | snd_hda_override_conn_list(codec, 0x1a, 5, conn); | 1904 | snd_hda_override_conn_list(codec, 0x1a, 5, conn); |
1905 | } | 1905 | } |
1906 | } | 1906 | } |
1907 | 1907 | ||
1908 | /* Set VREF on HP pin */ | 1908 | /* Set VREF on HP pin */ |
1909 | static void alc889_fixup_mbp_vref(struct hda_codec *codec, | 1909 | static void alc889_fixup_mbp_vref(struct hda_codec *codec, |
1910 | const struct hda_fixup *fix, int action) | 1910 | const struct hda_fixup *fix, int action) |
1911 | { | 1911 | { |
1912 | struct alc_spec *spec = codec->spec; | 1912 | struct alc_spec *spec = codec->spec; |
1913 | static hda_nid_t nids[2] = { 0x14, 0x15 }; | 1913 | static hda_nid_t nids[2] = { 0x14, 0x15 }; |
1914 | int i; | 1914 | int i; |
1915 | 1915 | ||
1916 | if (action != HDA_FIXUP_ACT_INIT) | 1916 | if (action != HDA_FIXUP_ACT_INIT) |
1917 | return; | 1917 | return; |
1918 | for (i = 0; i < ARRAY_SIZE(nids); i++) { | 1918 | for (i = 0; i < ARRAY_SIZE(nids); i++) { |
1919 | unsigned int val = snd_hda_codec_get_pincfg(codec, nids[i]); | 1919 | unsigned int val = snd_hda_codec_get_pincfg(codec, nids[i]); |
1920 | if (get_defcfg_device(val) != AC_JACK_HP_OUT) | 1920 | if (get_defcfg_device(val) != AC_JACK_HP_OUT) |
1921 | continue; | 1921 | continue; |
1922 | val = snd_hda_codec_get_pin_target(codec, nids[i]); | 1922 | val = snd_hda_codec_get_pin_target(codec, nids[i]); |
1923 | val |= AC_PINCTL_VREF_80; | 1923 | val |= AC_PINCTL_VREF_80; |
1924 | snd_hda_set_pin_ctl(codec, nids[i], val); | 1924 | snd_hda_set_pin_ctl(codec, nids[i], val); |
1925 | spec->gen.keep_vref_in_automute = 1; | 1925 | spec->gen.keep_vref_in_automute = 1; |
1926 | break; | 1926 | break; |
1927 | } | 1927 | } |
1928 | } | 1928 | } |
1929 | 1929 | ||
1930 | static void alc889_fixup_mac_pins(struct hda_codec *codec, | 1930 | static void alc889_fixup_mac_pins(struct hda_codec *codec, |
1931 | const hda_nid_t *nids, int num_nids) | 1931 | const hda_nid_t *nids, int num_nids) |
1932 | { | 1932 | { |
1933 | struct alc_spec *spec = codec->spec; | 1933 | struct alc_spec *spec = codec->spec; |
1934 | int i; | 1934 | int i; |
1935 | 1935 | ||
1936 | for (i = 0; i < num_nids; i++) { | 1936 | for (i = 0; i < num_nids; i++) { |
1937 | unsigned int val; | 1937 | unsigned int val; |
1938 | val = snd_hda_codec_get_pin_target(codec, nids[i]); | 1938 | val = snd_hda_codec_get_pin_target(codec, nids[i]); |
1939 | val |= AC_PINCTL_VREF_50; | 1939 | val |= AC_PINCTL_VREF_50; |
1940 | snd_hda_set_pin_ctl(codec, nids[i], val); | 1940 | snd_hda_set_pin_ctl(codec, nids[i], val); |
1941 | } | 1941 | } |
1942 | spec->gen.keep_vref_in_automute = 1; | 1942 | spec->gen.keep_vref_in_automute = 1; |
1943 | } | 1943 | } |
1944 | 1944 | ||
1945 | /* Set VREF on speaker pins on imac91 */ | 1945 | /* Set VREF on speaker pins on imac91 */ |
1946 | static void alc889_fixup_imac91_vref(struct hda_codec *codec, | 1946 | static void alc889_fixup_imac91_vref(struct hda_codec *codec, |
1947 | const struct hda_fixup *fix, int action) | 1947 | const struct hda_fixup *fix, int action) |
1948 | { | 1948 | { |
1949 | static hda_nid_t nids[2] = { 0x18, 0x1a }; | 1949 | static hda_nid_t nids[2] = { 0x18, 0x1a }; |
1950 | 1950 | ||
1951 | if (action == HDA_FIXUP_ACT_INIT) | 1951 | if (action == HDA_FIXUP_ACT_INIT) |
1952 | alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids)); | 1952 | alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids)); |
1953 | } | 1953 | } |
1954 | 1954 | ||
1955 | /* Set VREF on speaker pins on mba11 */ | 1955 | /* Set VREF on speaker pins on mba11 */ |
1956 | static void alc889_fixup_mba11_vref(struct hda_codec *codec, | 1956 | static void alc889_fixup_mba11_vref(struct hda_codec *codec, |
1957 | const struct hda_fixup *fix, int action) | 1957 | const struct hda_fixup *fix, int action) |
1958 | { | 1958 | { |
1959 | static hda_nid_t nids[1] = { 0x18 }; | 1959 | static hda_nid_t nids[1] = { 0x18 }; |
1960 | 1960 | ||
1961 | if (action == HDA_FIXUP_ACT_INIT) | 1961 | if (action == HDA_FIXUP_ACT_INIT) |
1962 | alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids)); | 1962 | alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids)); |
1963 | } | 1963 | } |
1964 | 1964 | ||
1965 | /* Set VREF on speaker pins on mba21 */ | 1965 | /* Set VREF on speaker pins on mba21 */ |
1966 | static void alc889_fixup_mba21_vref(struct hda_codec *codec, | 1966 | static void alc889_fixup_mba21_vref(struct hda_codec *codec, |
1967 | const struct hda_fixup *fix, int action) | 1967 | const struct hda_fixup *fix, int action) |
1968 | { | 1968 | { |
1969 | static hda_nid_t nids[2] = { 0x18, 0x19 }; | 1969 | static hda_nid_t nids[2] = { 0x18, 0x19 }; |
1970 | 1970 | ||
1971 | if (action == HDA_FIXUP_ACT_INIT) | 1971 | if (action == HDA_FIXUP_ACT_INIT) |
1972 | alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids)); | 1972 | alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids)); |
1973 | } | 1973 | } |
1974 | 1974 | ||
1975 | /* Don't take HP output as primary | 1975 | /* Don't take HP output as primary |
1976 | * Strangely, the speaker output doesn't work on Vaio Z and some Vaio | 1976 | * Strangely, the speaker output doesn't work on Vaio Z and some Vaio |
1977 | * all-in-one desktop PCs (for example VGC-LN51JGB) through DAC 0x05 | 1977 | * all-in-one desktop PCs (for example VGC-LN51JGB) through DAC 0x05 |
1978 | */ | 1978 | */ |
1979 | static void alc882_fixup_no_primary_hp(struct hda_codec *codec, | 1979 | static void alc882_fixup_no_primary_hp(struct hda_codec *codec, |
1980 | const struct hda_fixup *fix, int action) | 1980 | const struct hda_fixup *fix, int action) |
1981 | { | 1981 | { |
1982 | struct alc_spec *spec = codec->spec; | 1982 | struct alc_spec *spec = codec->spec; |
1983 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | 1983 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
1984 | spec->gen.no_primary_hp = 1; | 1984 | spec->gen.no_primary_hp = 1; |
1985 | spec->gen.no_multi_io = 1; | 1985 | spec->gen.no_multi_io = 1; |
1986 | } | 1986 | } |
1987 | } | 1987 | } |
1988 | 1988 | ||
1989 | static void alc_fixup_bass_chmap(struct hda_codec *codec, | 1989 | static void alc_fixup_bass_chmap(struct hda_codec *codec, |
1990 | const struct hda_fixup *fix, int action); | 1990 | const struct hda_fixup *fix, int action); |
1991 | 1991 | ||
1992 | static const struct hda_fixup alc882_fixups[] = { | 1992 | static const struct hda_fixup alc882_fixups[] = { |
1993 | [ALC882_FIXUP_ABIT_AW9D_MAX] = { | 1993 | [ALC882_FIXUP_ABIT_AW9D_MAX] = { |
1994 | .type = HDA_FIXUP_PINS, | 1994 | .type = HDA_FIXUP_PINS, |
1995 | .v.pins = (const struct hda_pintbl[]) { | 1995 | .v.pins = (const struct hda_pintbl[]) { |
1996 | { 0x15, 0x01080104 }, /* side */ | 1996 | { 0x15, 0x01080104 }, /* side */ |
1997 | { 0x16, 0x01011012 }, /* rear */ | 1997 | { 0x16, 0x01011012 }, /* rear */ |
1998 | { 0x17, 0x01016011 }, /* clfe */ | 1998 | { 0x17, 0x01016011 }, /* clfe */ |
1999 | { } | 1999 | { } |
2000 | } | 2000 | } |
2001 | }, | 2001 | }, |
2002 | [ALC882_FIXUP_LENOVO_Y530] = { | 2002 | [ALC882_FIXUP_LENOVO_Y530] = { |
2003 | .type = HDA_FIXUP_PINS, | 2003 | .type = HDA_FIXUP_PINS, |
2004 | .v.pins = (const struct hda_pintbl[]) { | 2004 | .v.pins = (const struct hda_pintbl[]) { |
2005 | { 0x15, 0x99130112 }, /* rear int speakers */ | 2005 | { 0x15, 0x99130112 }, /* rear int speakers */ |
2006 | { 0x16, 0x99130111 }, /* subwoofer */ | 2006 | { 0x16, 0x99130111 }, /* subwoofer */ |
2007 | { } | 2007 | { } |
2008 | } | 2008 | } |
2009 | }, | 2009 | }, |
2010 | [ALC882_FIXUP_PB_M5210] = { | 2010 | [ALC882_FIXUP_PB_M5210] = { |
2011 | .type = HDA_FIXUP_PINCTLS, | 2011 | .type = HDA_FIXUP_PINCTLS, |
2012 | .v.pins = (const struct hda_pintbl[]) { | 2012 | .v.pins = (const struct hda_pintbl[]) { |
2013 | { 0x19, PIN_VREF50 }, | 2013 | { 0x19, PIN_VREF50 }, |
2014 | {} | 2014 | {} |
2015 | } | 2015 | } |
2016 | }, | 2016 | }, |
2017 | [ALC882_FIXUP_ACER_ASPIRE_7736] = { | 2017 | [ALC882_FIXUP_ACER_ASPIRE_7736] = { |
2018 | .type = HDA_FIXUP_FUNC, | 2018 | .type = HDA_FIXUP_FUNC, |
2019 | .v.func = alc_fixup_sku_ignore, | 2019 | .v.func = alc_fixup_sku_ignore, |
2020 | }, | 2020 | }, |
2021 | [ALC882_FIXUP_ASUS_W90V] = { | 2021 | [ALC882_FIXUP_ASUS_W90V] = { |
2022 | .type = HDA_FIXUP_PINS, | 2022 | .type = HDA_FIXUP_PINS, |
2023 | .v.pins = (const struct hda_pintbl[]) { | 2023 | .v.pins = (const struct hda_pintbl[]) { |
2024 | { 0x16, 0x99130110 }, /* fix sequence for CLFE */ | 2024 | { 0x16, 0x99130110 }, /* fix sequence for CLFE */ |
2025 | { } | 2025 | { } |
2026 | } | 2026 | } |
2027 | }, | 2027 | }, |
2028 | [ALC889_FIXUP_CD] = { | 2028 | [ALC889_FIXUP_CD] = { |
2029 | .type = HDA_FIXUP_PINS, | 2029 | .type = HDA_FIXUP_PINS, |
2030 | .v.pins = (const struct hda_pintbl[]) { | 2030 | .v.pins = (const struct hda_pintbl[]) { |
2031 | { 0x1c, 0x993301f0 }, /* CD */ | 2031 | { 0x1c, 0x993301f0 }, /* CD */ |
2032 | { } | 2032 | { } |
2033 | } | 2033 | } |
2034 | }, | 2034 | }, |
2035 | [ALC889_FIXUP_FRONT_HP_NO_PRESENCE] = { | 2035 | [ALC889_FIXUP_FRONT_HP_NO_PRESENCE] = { |
2036 | .type = HDA_FIXUP_PINS, | 2036 | .type = HDA_FIXUP_PINS, |
2037 | .v.pins = (const struct hda_pintbl[]) { | 2037 | .v.pins = (const struct hda_pintbl[]) { |
2038 | { 0x1b, 0x02214120 }, /* Front HP jack is flaky, disable jack detect */ | 2038 | { 0x1b, 0x02214120 }, /* Front HP jack is flaky, disable jack detect */ |
2039 | { } | 2039 | { } |
2040 | }, | 2040 | }, |
2041 | .chained = true, | 2041 | .chained = true, |
2042 | .chain_id = ALC889_FIXUP_CD, | 2042 | .chain_id = ALC889_FIXUP_CD, |
2043 | }, | 2043 | }, |
2044 | [ALC889_FIXUP_VAIO_TT] = { | 2044 | [ALC889_FIXUP_VAIO_TT] = { |
2045 | .type = HDA_FIXUP_PINS, | 2045 | .type = HDA_FIXUP_PINS, |
2046 | .v.pins = (const struct hda_pintbl[]) { | 2046 | .v.pins = (const struct hda_pintbl[]) { |
2047 | { 0x17, 0x90170111 }, /* hidden surround speaker */ | 2047 | { 0x17, 0x90170111 }, /* hidden surround speaker */ |
2048 | { } | 2048 | { } |
2049 | } | 2049 | } |
2050 | }, | 2050 | }, |
2051 | [ALC888_FIXUP_EEE1601] = { | 2051 | [ALC888_FIXUP_EEE1601] = { |
2052 | .type = HDA_FIXUP_VERBS, | 2052 | .type = HDA_FIXUP_VERBS, |
2053 | .v.verbs = (const struct hda_verb[]) { | 2053 | .v.verbs = (const struct hda_verb[]) { |
2054 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b }, | 2054 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b }, |
2055 | { 0x20, AC_VERB_SET_PROC_COEF, 0x0838 }, | 2055 | { 0x20, AC_VERB_SET_PROC_COEF, 0x0838 }, |
2056 | { } | 2056 | { } |
2057 | } | 2057 | } |
2058 | }, | 2058 | }, |
2059 | [ALC882_FIXUP_EAPD] = { | 2059 | [ALC882_FIXUP_EAPD] = { |
2060 | .type = HDA_FIXUP_VERBS, | 2060 | .type = HDA_FIXUP_VERBS, |
2061 | .v.verbs = (const struct hda_verb[]) { | 2061 | .v.verbs = (const struct hda_verb[]) { |
2062 | /* change to EAPD mode */ | 2062 | /* change to EAPD mode */ |
2063 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, | 2063 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, |
2064 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 }, | 2064 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 }, |
2065 | { } | 2065 | { } |
2066 | } | 2066 | } |
2067 | }, | 2067 | }, |
2068 | [ALC883_FIXUP_EAPD] = { | 2068 | [ALC883_FIXUP_EAPD] = { |
2069 | .type = HDA_FIXUP_VERBS, | 2069 | .type = HDA_FIXUP_VERBS, |
2070 | .v.verbs = (const struct hda_verb[]) { | 2070 | .v.verbs = (const struct hda_verb[]) { |
2071 | /* change to EAPD mode */ | 2071 | /* change to EAPD mode */ |
2072 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, | 2072 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, |
2073 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 }, | 2073 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 }, |
2074 | { } | 2074 | { } |
2075 | } | 2075 | } |
2076 | }, | 2076 | }, |
2077 | [ALC883_FIXUP_ACER_EAPD] = { | 2077 | [ALC883_FIXUP_ACER_EAPD] = { |
2078 | .type = HDA_FIXUP_VERBS, | 2078 | .type = HDA_FIXUP_VERBS, |
2079 | .v.verbs = (const struct hda_verb[]) { | 2079 | .v.verbs = (const struct hda_verb[]) { |
2080 | /* eanable EAPD on Acer laptops */ | 2080 | /* eanable EAPD on Acer laptops */ |
2081 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, | 2081 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, |
2082 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 }, | 2082 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 }, |
2083 | { } | 2083 | { } |
2084 | } | 2084 | } |
2085 | }, | 2085 | }, |
2086 | [ALC882_FIXUP_GPIO1] = { | 2086 | [ALC882_FIXUP_GPIO1] = { |
2087 | .type = HDA_FIXUP_VERBS, | 2087 | .type = HDA_FIXUP_VERBS, |
2088 | .v.verbs = alc_gpio1_init_verbs, | 2088 | .v.verbs = alc_gpio1_init_verbs, |
2089 | }, | 2089 | }, |
2090 | [ALC882_FIXUP_GPIO2] = { | 2090 | [ALC882_FIXUP_GPIO2] = { |
2091 | .type = HDA_FIXUP_VERBS, | 2091 | .type = HDA_FIXUP_VERBS, |
2092 | .v.verbs = alc_gpio2_init_verbs, | 2092 | .v.verbs = alc_gpio2_init_verbs, |
2093 | }, | 2093 | }, |
2094 | [ALC882_FIXUP_GPIO3] = { | 2094 | [ALC882_FIXUP_GPIO3] = { |
2095 | .type = HDA_FIXUP_VERBS, | 2095 | .type = HDA_FIXUP_VERBS, |
2096 | .v.verbs = alc_gpio3_init_verbs, | 2096 | .v.verbs = alc_gpio3_init_verbs, |
2097 | }, | 2097 | }, |
2098 | [ALC882_FIXUP_ASUS_W2JC] = { | 2098 | [ALC882_FIXUP_ASUS_W2JC] = { |
2099 | .type = HDA_FIXUP_VERBS, | 2099 | .type = HDA_FIXUP_VERBS, |
2100 | .v.verbs = alc_gpio1_init_verbs, | 2100 | .v.verbs = alc_gpio1_init_verbs, |
2101 | .chained = true, | 2101 | .chained = true, |
2102 | .chain_id = ALC882_FIXUP_EAPD, | 2102 | .chain_id = ALC882_FIXUP_EAPD, |
2103 | }, | 2103 | }, |
2104 | [ALC889_FIXUP_COEF] = { | 2104 | [ALC889_FIXUP_COEF] = { |
2105 | .type = HDA_FIXUP_FUNC, | 2105 | .type = HDA_FIXUP_FUNC, |
2106 | .v.func = alc889_fixup_coef, | 2106 | .v.func = alc889_fixup_coef, |
2107 | }, | 2107 | }, |
2108 | [ALC882_FIXUP_ACER_ASPIRE_4930G] = { | 2108 | [ALC882_FIXUP_ACER_ASPIRE_4930G] = { |
2109 | .type = HDA_FIXUP_PINS, | 2109 | .type = HDA_FIXUP_PINS, |
2110 | .v.pins = (const struct hda_pintbl[]) { | 2110 | .v.pins = (const struct hda_pintbl[]) { |
2111 | { 0x16, 0x99130111 }, /* CLFE speaker */ | 2111 | { 0x16, 0x99130111 }, /* CLFE speaker */ |
2112 | { 0x17, 0x99130112 }, /* surround speaker */ | 2112 | { 0x17, 0x99130112 }, /* surround speaker */ |
2113 | { } | 2113 | { } |
2114 | }, | 2114 | }, |
2115 | .chained = true, | 2115 | .chained = true, |
2116 | .chain_id = ALC882_FIXUP_GPIO1, | 2116 | .chain_id = ALC882_FIXUP_GPIO1, |
2117 | }, | 2117 | }, |
2118 | [ALC882_FIXUP_ACER_ASPIRE_8930G] = { | 2118 | [ALC882_FIXUP_ACER_ASPIRE_8930G] = { |
2119 | .type = HDA_FIXUP_PINS, | 2119 | .type = HDA_FIXUP_PINS, |
2120 | .v.pins = (const struct hda_pintbl[]) { | 2120 | .v.pins = (const struct hda_pintbl[]) { |
2121 | { 0x16, 0x99130111 }, /* CLFE speaker */ | 2121 | { 0x16, 0x99130111 }, /* CLFE speaker */ |
2122 | { 0x1b, 0x99130112 }, /* surround speaker */ | 2122 | { 0x1b, 0x99130112 }, /* surround speaker */ |
2123 | { } | 2123 | { } |
2124 | }, | 2124 | }, |
2125 | .chained = true, | 2125 | .chained = true, |
2126 | .chain_id = ALC882_FIXUP_ASPIRE_8930G_VERBS, | 2126 | .chain_id = ALC882_FIXUP_ASPIRE_8930G_VERBS, |
2127 | }, | 2127 | }, |
2128 | [ALC882_FIXUP_ASPIRE_8930G_VERBS] = { | 2128 | [ALC882_FIXUP_ASPIRE_8930G_VERBS] = { |
2129 | /* additional init verbs for Acer Aspire 8930G */ | 2129 | /* additional init verbs for Acer Aspire 8930G */ |
2130 | .type = HDA_FIXUP_VERBS, | 2130 | .type = HDA_FIXUP_VERBS, |
2131 | .v.verbs = (const struct hda_verb[]) { | 2131 | .v.verbs = (const struct hda_verb[]) { |
2132 | /* Enable all DACs */ | 2132 | /* Enable all DACs */ |
2133 | /* DAC DISABLE/MUTE 1? */ | 2133 | /* DAC DISABLE/MUTE 1? */ |
2134 | /* setting bits 1-5 disables DAC nids 0x02-0x06 | 2134 | /* setting bits 1-5 disables DAC nids 0x02-0x06 |
2135 | * apparently. Init=0x38 */ | 2135 | * apparently. Init=0x38 */ |
2136 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x03 }, | 2136 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x03 }, |
2137 | { 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, | 2137 | { 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, |
2138 | /* DAC DISABLE/MUTE 2? */ | 2138 | /* DAC DISABLE/MUTE 2? */ |
2139 | /* some bit here disables the other DACs. | 2139 | /* some bit here disables the other DACs. |
2140 | * Init=0x4900 */ | 2140 | * Init=0x4900 */ |
2141 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x08 }, | 2141 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x08 }, |
2142 | { 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, | 2142 | { 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, |
2143 | /* DMIC fix | 2143 | /* DMIC fix |
2144 | * This laptop has a stereo digital microphone. | 2144 | * This laptop has a stereo digital microphone. |
2145 | * The mics are only 1cm apart which makes the stereo | 2145 | * The mics are only 1cm apart which makes the stereo |
2146 | * useless. However, either the mic or the ALC889 | 2146 | * useless. However, either the mic or the ALC889 |
2147 | * makes the signal become a difference/sum signal | 2147 | * makes the signal become a difference/sum signal |
2148 | * instead of standard stereo, which is annoying. | 2148 | * instead of standard stereo, which is annoying. |
2149 | * So instead we flip this bit which makes the | 2149 | * So instead we flip this bit which makes the |
2150 | * codec replicate the sum signal to both channels, | 2150 | * codec replicate the sum signal to both channels, |
2151 | * turning it into a normal mono mic. | 2151 | * turning it into a normal mono mic. |
2152 | */ | 2152 | */ |
2153 | /* DMIC_CONTROL? Init value = 0x0001 */ | 2153 | /* DMIC_CONTROL? Init value = 0x0001 */ |
2154 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b }, | 2154 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b }, |
2155 | { 0x20, AC_VERB_SET_PROC_COEF, 0x0003 }, | 2155 | { 0x20, AC_VERB_SET_PROC_COEF, 0x0003 }, |
2156 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, | 2156 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, |
2157 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 }, | 2157 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 }, |
2158 | { } | 2158 | { } |
2159 | }, | 2159 | }, |
2160 | .chained = true, | 2160 | .chained = true, |
2161 | .chain_id = ALC882_FIXUP_GPIO1, | 2161 | .chain_id = ALC882_FIXUP_GPIO1, |
2162 | }, | 2162 | }, |
2163 | [ALC885_FIXUP_MACPRO_GPIO] = { | 2163 | [ALC885_FIXUP_MACPRO_GPIO] = { |
2164 | .type = HDA_FIXUP_FUNC, | 2164 | .type = HDA_FIXUP_FUNC, |
2165 | .v.func = alc885_fixup_macpro_gpio, | 2165 | .v.func = alc885_fixup_macpro_gpio, |
2166 | }, | 2166 | }, |
2167 | [ALC889_FIXUP_DAC_ROUTE] = { | 2167 | [ALC889_FIXUP_DAC_ROUTE] = { |
2168 | .type = HDA_FIXUP_FUNC, | 2168 | .type = HDA_FIXUP_FUNC, |
2169 | .v.func = alc889_fixup_dac_route, | 2169 | .v.func = alc889_fixup_dac_route, |
2170 | }, | 2170 | }, |
2171 | [ALC889_FIXUP_MBP_VREF] = { | 2171 | [ALC889_FIXUP_MBP_VREF] = { |
2172 | .type = HDA_FIXUP_FUNC, | 2172 | .type = HDA_FIXUP_FUNC, |
2173 | .v.func = alc889_fixup_mbp_vref, | 2173 | .v.func = alc889_fixup_mbp_vref, |
2174 | .chained = true, | 2174 | .chained = true, |
2175 | .chain_id = ALC882_FIXUP_GPIO1, | 2175 | .chain_id = ALC882_FIXUP_GPIO1, |
2176 | }, | 2176 | }, |
2177 | [ALC889_FIXUP_IMAC91_VREF] = { | 2177 | [ALC889_FIXUP_IMAC91_VREF] = { |
2178 | .type = HDA_FIXUP_FUNC, | 2178 | .type = HDA_FIXUP_FUNC, |
2179 | .v.func = alc889_fixup_imac91_vref, | 2179 | .v.func = alc889_fixup_imac91_vref, |
2180 | .chained = true, | 2180 | .chained = true, |
2181 | .chain_id = ALC882_FIXUP_GPIO1, | 2181 | .chain_id = ALC882_FIXUP_GPIO1, |
2182 | }, | 2182 | }, |
2183 | [ALC889_FIXUP_MBA11_VREF] = { | 2183 | [ALC889_FIXUP_MBA11_VREF] = { |
2184 | .type = HDA_FIXUP_FUNC, | 2184 | .type = HDA_FIXUP_FUNC, |
2185 | .v.func = alc889_fixup_mba11_vref, | 2185 | .v.func = alc889_fixup_mba11_vref, |
2186 | .chained = true, | 2186 | .chained = true, |
2187 | .chain_id = ALC889_FIXUP_MBP_VREF, | 2187 | .chain_id = ALC889_FIXUP_MBP_VREF, |
2188 | }, | 2188 | }, |
2189 | [ALC889_FIXUP_MBA21_VREF] = { | 2189 | [ALC889_FIXUP_MBA21_VREF] = { |
2190 | .type = HDA_FIXUP_FUNC, | 2190 | .type = HDA_FIXUP_FUNC, |
2191 | .v.func = alc889_fixup_mba21_vref, | 2191 | .v.func = alc889_fixup_mba21_vref, |
2192 | .chained = true, | 2192 | .chained = true, |
2193 | .chain_id = ALC889_FIXUP_MBP_VREF, | 2193 | .chain_id = ALC889_FIXUP_MBP_VREF, |
2194 | }, | 2194 | }, |
2195 | [ALC889_FIXUP_MP11_VREF] = { | 2195 | [ALC889_FIXUP_MP11_VREF] = { |
2196 | .type = HDA_FIXUP_FUNC, | 2196 | .type = HDA_FIXUP_FUNC, |
2197 | .v.func = alc889_fixup_mba11_vref, | 2197 | .v.func = alc889_fixup_mba11_vref, |
2198 | .chained = true, | 2198 | .chained = true, |
2199 | .chain_id = ALC885_FIXUP_MACPRO_GPIO, | 2199 | .chain_id = ALC885_FIXUP_MACPRO_GPIO, |
2200 | }, | 2200 | }, |
2201 | [ALC882_FIXUP_INV_DMIC] = { | 2201 | [ALC882_FIXUP_INV_DMIC] = { |
2202 | .type = HDA_FIXUP_FUNC, | 2202 | .type = HDA_FIXUP_FUNC, |
2203 | .v.func = alc_fixup_inv_dmic_0x12, | 2203 | .v.func = alc_fixup_inv_dmic_0x12, |
2204 | }, | 2204 | }, |
2205 | [ALC882_FIXUP_NO_PRIMARY_HP] = { | 2205 | [ALC882_FIXUP_NO_PRIMARY_HP] = { |
2206 | .type = HDA_FIXUP_FUNC, | 2206 | .type = HDA_FIXUP_FUNC, |
2207 | .v.func = alc882_fixup_no_primary_hp, | 2207 | .v.func = alc882_fixup_no_primary_hp, |
2208 | }, | 2208 | }, |
2209 | [ALC887_FIXUP_ASUS_BASS] = { | 2209 | [ALC887_FIXUP_ASUS_BASS] = { |
2210 | .type = HDA_FIXUP_PINS, | 2210 | .type = HDA_FIXUP_PINS, |
2211 | .v.pins = (const struct hda_pintbl[]) { | 2211 | .v.pins = (const struct hda_pintbl[]) { |
2212 | {0x16, 0x99130130}, /* bass speaker */ | 2212 | {0x16, 0x99130130}, /* bass speaker */ |
2213 | {} | 2213 | {} |
2214 | }, | 2214 | }, |
2215 | .chained = true, | 2215 | .chained = true, |
2216 | .chain_id = ALC887_FIXUP_BASS_CHMAP, | 2216 | .chain_id = ALC887_FIXUP_BASS_CHMAP, |
2217 | }, | 2217 | }, |
2218 | [ALC887_FIXUP_BASS_CHMAP] = { | 2218 | [ALC887_FIXUP_BASS_CHMAP] = { |
2219 | .type = HDA_FIXUP_FUNC, | 2219 | .type = HDA_FIXUP_FUNC, |
2220 | .v.func = alc_fixup_bass_chmap, | 2220 | .v.func = alc_fixup_bass_chmap, |
2221 | }, | 2221 | }, |
2222 | }; | 2222 | }; |
2223 | 2223 | ||
2224 | static const struct snd_pci_quirk alc882_fixup_tbl[] = { | 2224 | static const struct snd_pci_quirk alc882_fixup_tbl[] = { |
2225 | SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_FIXUP_ACER_EAPD), | 2225 | SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_FIXUP_ACER_EAPD), |
2226 | SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_FIXUP_ACER_EAPD), | 2226 | SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_FIXUP_ACER_EAPD), |
2227 | SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_FIXUP_ACER_EAPD), | 2227 | SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_FIXUP_ACER_EAPD), |
2228 | SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_FIXUP_ACER_EAPD), | 2228 | SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_FIXUP_ACER_EAPD), |
2229 | SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_FIXUP_ACER_EAPD), | 2229 | SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_FIXUP_ACER_EAPD), |
2230 | SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_FIXUP_ACER_EAPD), | 2230 | SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_FIXUP_ACER_EAPD), |
2231 | SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G", | 2231 | SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G", |
2232 | ALC882_FIXUP_ACER_ASPIRE_4930G), | 2232 | ALC882_FIXUP_ACER_ASPIRE_4930G), |
2233 | SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G", | 2233 | SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G", |
2234 | ALC882_FIXUP_ACER_ASPIRE_4930G), | 2234 | ALC882_FIXUP_ACER_ASPIRE_4930G), |
2235 | SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G", | 2235 | SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G", |
2236 | ALC882_FIXUP_ACER_ASPIRE_8930G), | 2236 | ALC882_FIXUP_ACER_ASPIRE_8930G), |
2237 | SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G", | 2237 | SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G", |
2238 | ALC882_FIXUP_ACER_ASPIRE_8930G), | 2238 | ALC882_FIXUP_ACER_ASPIRE_8930G), |
2239 | SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G", | 2239 | SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G", |
2240 | ALC882_FIXUP_ACER_ASPIRE_4930G), | 2240 | ALC882_FIXUP_ACER_ASPIRE_4930G), |
2241 | SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G", | 2241 | SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G", |
2242 | ALC882_FIXUP_ACER_ASPIRE_4930G), | 2242 | ALC882_FIXUP_ACER_ASPIRE_4930G), |
2243 | SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G", | 2243 | SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G", |
2244 | ALC882_FIXUP_ACER_ASPIRE_4930G), | 2244 | ALC882_FIXUP_ACER_ASPIRE_4930G), |
2245 | SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", ALC882_FIXUP_PB_M5210), | 2245 | SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", ALC882_FIXUP_PB_M5210), |
2246 | SND_PCI_QUIRK(0x1025, 0x021e, "Acer Aspire 5739G", | 2246 | SND_PCI_QUIRK(0x1025, 0x021e, "Acer Aspire 5739G", |
2247 | ALC882_FIXUP_ACER_ASPIRE_4930G), | 2247 | ALC882_FIXUP_ACER_ASPIRE_4930G), |
2248 | SND_PCI_QUIRK(0x1025, 0x0259, "Acer Aspire 5935", ALC889_FIXUP_DAC_ROUTE), | 2248 | SND_PCI_QUIRK(0x1025, 0x0259, "Acer Aspire 5935", ALC889_FIXUP_DAC_ROUTE), |
2249 | SND_PCI_QUIRK(0x1025, 0x026b, "Acer Aspire 8940G", ALC882_FIXUP_ACER_ASPIRE_8930G), | 2249 | SND_PCI_QUIRK(0x1025, 0x026b, "Acer Aspire 8940G", ALC882_FIXUP_ACER_ASPIRE_8930G), |
2250 | SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", ALC882_FIXUP_ACER_ASPIRE_7736), | 2250 | SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", ALC882_FIXUP_ACER_ASPIRE_7736), |
2251 | SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_FIXUP_EAPD), | 2251 | SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_FIXUP_EAPD), |
2252 | SND_PCI_QUIRK(0x1043, 0x1873, "ASUS W90V", ALC882_FIXUP_ASUS_W90V), | 2252 | SND_PCI_QUIRK(0x1043, 0x1873, "ASUS W90V", ALC882_FIXUP_ASUS_W90V), |
2253 | SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_FIXUP_ASUS_W2JC), | 2253 | SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_FIXUP_ASUS_W2JC), |
2254 | SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_FIXUP_EEE1601), | 2254 | SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_FIXUP_EEE1601), |
2255 | SND_PCI_QUIRK(0x1043, 0x84bc, "ASUS ET2700", ALC887_FIXUP_ASUS_BASS), | 2255 | SND_PCI_QUIRK(0x1043, 0x84bc, "ASUS ET2700", ALC887_FIXUP_ASUS_BASS), |
2256 | SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT), | 2256 | SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT), |
2257 | SND_PCI_QUIRK(0x104d, 0x905a, "Sony Vaio Z", ALC882_FIXUP_NO_PRIMARY_HP), | 2257 | SND_PCI_QUIRK(0x104d, 0x905a, "Sony Vaio Z", ALC882_FIXUP_NO_PRIMARY_HP), |
2258 | SND_PCI_QUIRK(0x104d, 0x9043, "Sony Vaio VGC-LN51JGB", ALC882_FIXUP_NO_PRIMARY_HP), | 2258 | SND_PCI_QUIRK(0x104d, 0x9043, "Sony Vaio VGC-LN51JGB", ALC882_FIXUP_NO_PRIMARY_HP), |
2259 | 2259 | ||
2260 | /* All Apple entries are in codec SSIDs */ | 2260 | /* All Apple entries are in codec SSIDs */ |
2261 | SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC889_FIXUP_MBP_VREF), | 2261 | SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC889_FIXUP_MBP_VREF), |
2262 | SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC889_FIXUP_MBP_VREF), | 2262 | SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC889_FIXUP_MBP_VREF), |
2263 | SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF), | 2263 | SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF), |
2264 | SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC889_FIXUP_MP11_VREF), | 2264 | SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC889_FIXUP_MP11_VREF), |
2265 | SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_FIXUP_MACPRO_GPIO), | 2265 | SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_FIXUP_MACPRO_GPIO), |
2266 | SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_FIXUP_MACPRO_GPIO), | 2266 | SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_FIXUP_MACPRO_GPIO), |
2267 | SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC889_FIXUP_MBP_VREF), | 2267 | SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC889_FIXUP_MBP_VREF), |
2268 | SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889_FIXUP_MBP_VREF), | 2268 | SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889_FIXUP_MBP_VREF), |
2269 | SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_FIXUP_EAPD), | 2269 | SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_FIXUP_EAPD), |
2270 | SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC889_FIXUP_MBA11_VREF), | 2270 | SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC889_FIXUP_MBA11_VREF), |
2271 | SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC889_FIXUP_MBA21_VREF), | 2271 | SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC889_FIXUP_MBA21_VREF), |
2272 | SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889_FIXUP_MBP_VREF), | 2272 | SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889_FIXUP_MBP_VREF), |
2273 | SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF), | 2273 | SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF), |
2274 | SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_FIXUP_MACPRO_GPIO), | 2274 | SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_FIXUP_MACPRO_GPIO), |
2275 | SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC889_FIXUP_IMAC91_VREF), | 2275 | SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC889_FIXUP_IMAC91_VREF), |
2276 | SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC889_FIXUP_IMAC91_VREF), | 2276 | SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC889_FIXUP_IMAC91_VREF), |
2277 | SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC889_FIXUP_IMAC91_VREF), | 2277 | SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC889_FIXUP_IMAC91_VREF), |
2278 | SND_PCI_QUIRK(0x106b, 0x4200, "Mac Pro 5,1", ALC885_FIXUP_MACPRO_GPIO), | 2278 | SND_PCI_QUIRK(0x106b, 0x4200, "Mac Pro 5,1", ALC885_FIXUP_MACPRO_GPIO), |
2279 | SND_PCI_QUIRK(0x106b, 0x4300, "iMac 9,1", ALC889_FIXUP_IMAC91_VREF), | 2279 | SND_PCI_QUIRK(0x106b, 0x4300, "iMac 9,1", ALC889_FIXUP_IMAC91_VREF), |
2280 | SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC889_FIXUP_IMAC91_VREF), | 2280 | SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC889_FIXUP_IMAC91_VREF), |
2281 | SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC889_FIXUP_IMAC91_VREF), | 2281 | SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC889_FIXUP_IMAC91_VREF), |
2282 | SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC889_FIXUP_IMAC91_VREF), | 2282 | SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC889_FIXUP_IMAC91_VREF), |
2283 | 2283 | ||
2284 | SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC882_FIXUP_EAPD), | 2284 | SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC882_FIXUP_EAPD), |
2285 | SND_PCI_QUIRK(0x1462, 0x7350, "MSI-7350", ALC889_FIXUP_CD), | 2285 | SND_PCI_QUIRK(0x1462, 0x7350, "MSI-7350", ALC889_FIXUP_CD), |
2286 | SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3), | 2286 | SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3), |
2287 | SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3/Z87X-UD3H", ALC889_FIXUP_FRONT_HP_NO_PRESENCE), | 2287 | SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3/Z87X-UD3H", ALC889_FIXUP_FRONT_HP_NO_PRESENCE), |
2288 | SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX), | 2288 | SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX), |
2289 | SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD), | 2289 | SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD), |
2290 | SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD), | 2290 | SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD), |
2291 | SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", ALC882_FIXUP_LENOVO_Y530), | 2291 | SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", ALC882_FIXUP_LENOVO_Y530), |
2292 | SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_FIXUP_COEF), | 2292 | SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_FIXUP_COEF), |
2293 | {} | 2293 | {} |
2294 | }; | 2294 | }; |
2295 | 2295 | ||
2296 | static const struct hda_model_fixup alc882_fixup_models[] = { | 2296 | static const struct hda_model_fixup alc882_fixup_models[] = { |
2297 | {.id = ALC882_FIXUP_ACER_ASPIRE_4930G, .name = "acer-aspire-4930g"}, | 2297 | {.id = ALC882_FIXUP_ACER_ASPIRE_4930G, .name = "acer-aspire-4930g"}, |
2298 | {.id = ALC882_FIXUP_ACER_ASPIRE_8930G, .name = "acer-aspire-8930g"}, | 2298 | {.id = ALC882_FIXUP_ACER_ASPIRE_8930G, .name = "acer-aspire-8930g"}, |
2299 | {.id = ALC883_FIXUP_ACER_EAPD, .name = "acer-aspire"}, | 2299 | {.id = ALC883_FIXUP_ACER_EAPD, .name = "acer-aspire"}, |
2300 | {.id = ALC882_FIXUP_INV_DMIC, .name = "inv-dmic"}, | 2300 | {.id = ALC882_FIXUP_INV_DMIC, .name = "inv-dmic"}, |
2301 | {.id = ALC882_FIXUP_NO_PRIMARY_HP, .name = "no-primary-hp"}, | 2301 | {.id = ALC882_FIXUP_NO_PRIMARY_HP, .name = "no-primary-hp"}, |
2302 | {} | 2302 | {} |
2303 | }; | 2303 | }; |
2304 | 2304 | ||
2305 | /* | 2305 | /* |
2306 | * BIOS auto configuration | 2306 | * BIOS auto configuration |
2307 | */ | 2307 | */ |
2308 | /* almost identical with ALC880 parser... */ | 2308 | /* almost identical with ALC880 parser... */ |
2309 | static int alc882_parse_auto_config(struct hda_codec *codec) | 2309 | static int alc882_parse_auto_config(struct hda_codec *codec) |
2310 | { | 2310 | { |
2311 | static const hda_nid_t alc882_ignore[] = { 0x1d, 0 }; | 2311 | static const hda_nid_t alc882_ignore[] = { 0x1d, 0 }; |
2312 | static const hda_nid_t alc882_ssids[] = { 0x15, 0x1b, 0x14, 0 }; | 2312 | static const hda_nid_t alc882_ssids[] = { 0x15, 0x1b, 0x14, 0 }; |
2313 | return alc_parse_auto_config(codec, alc882_ignore, alc882_ssids); | 2313 | return alc_parse_auto_config(codec, alc882_ignore, alc882_ssids); |
2314 | } | 2314 | } |
2315 | 2315 | ||
2316 | /* | 2316 | /* |
2317 | */ | 2317 | */ |
2318 | static int patch_alc882(struct hda_codec *codec) | 2318 | static int patch_alc882(struct hda_codec *codec) |
2319 | { | 2319 | { |
2320 | struct alc_spec *spec; | 2320 | struct alc_spec *spec; |
2321 | int err; | 2321 | int err; |
2322 | 2322 | ||
2323 | err = alc_alloc_spec(codec, 0x0b); | 2323 | err = alc_alloc_spec(codec, 0x0b); |
2324 | if (err < 0) | 2324 | if (err < 0) |
2325 | return err; | 2325 | return err; |
2326 | 2326 | ||
2327 | spec = codec->spec; | 2327 | spec = codec->spec; |
2328 | 2328 | ||
2329 | switch (codec->vendor_id) { | 2329 | switch (codec->vendor_id) { |
2330 | case 0x10ec0882: | 2330 | case 0x10ec0882: |
2331 | case 0x10ec0885: | 2331 | case 0x10ec0885: |
2332 | break; | 2332 | break; |
2333 | default: | 2333 | default: |
2334 | /* ALC883 and variants */ | 2334 | /* ALC883 and variants */ |
2335 | alc_fix_pll_init(codec, 0x20, 0x0a, 10); | 2335 | alc_fix_pll_init(codec, 0x20, 0x0a, 10); |
2336 | break; | 2336 | break; |
2337 | } | 2337 | } |
2338 | 2338 | ||
2339 | snd_hda_pick_fixup(codec, alc882_fixup_models, alc882_fixup_tbl, | 2339 | snd_hda_pick_fixup(codec, alc882_fixup_models, alc882_fixup_tbl, |
2340 | alc882_fixups); | 2340 | alc882_fixups); |
2341 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); | 2341 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); |
2342 | 2342 | ||
2343 | alc_auto_parse_customize_define(codec); | 2343 | alc_auto_parse_customize_define(codec); |
2344 | 2344 | ||
2345 | if (has_cdefine_beep(codec)) | 2345 | if (has_cdefine_beep(codec)) |
2346 | spec->gen.beep_nid = 0x01; | 2346 | spec->gen.beep_nid = 0x01; |
2347 | 2347 | ||
2348 | /* automatic parse from the BIOS config */ | 2348 | /* automatic parse from the BIOS config */ |
2349 | err = alc882_parse_auto_config(codec); | 2349 | err = alc882_parse_auto_config(codec); |
2350 | if (err < 0) | 2350 | if (err < 0) |
2351 | goto error; | 2351 | goto error; |
2352 | 2352 | ||
2353 | if (!spec->gen.no_analog && spec->gen.beep_nid) | 2353 | if (!spec->gen.no_analog && spec->gen.beep_nid) |
2354 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); | 2354 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); |
2355 | 2355 | ||
2356 | codec->patch_ops = alc_patch_ops; | 2356 | codec->patch_ops = alc_patch_ops; |
2357 | 2357 | ||
2358 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); | 2358 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); |
2359 | 2359 | ||
2360 | return 0; | 2360 | return 0; |
2361 | 2361 | ||
2362 | error: | 2362 | error: |
2363 | alc_free(codec); | 2363 | alc_free(codec); |
2364 | return err; | 2364 | return err; |
2365 | } | 2365 | } |
2366 | 2366 | ||
2367 | 2367 | ||
2368 | /* | 2368 | /* |
2369 | * ALC262 support | 2369 | * ALC262 support |
2370 | */ | 2370 | */ |
2371 | static int alc262_parse_auto_config(struct hda_codec *codec) | 2371 | static int alc262_parse_auto_config(struct hda_codec *codec) |
2372 | { | 2372 | { |
2373 | static const hda_nid_t alc262_ignore[] = { 0x1d, 0 }; | 2373 | static const hda_nid_t alc262_ignore[] = { 0x1d, 0 }; |
2374 | static const hda_nid_t alc262_ssids[] = { 0x15, 0x1b, 0x14, 0 }; | 2374 | static const hda_nid_t alc262_ssids[] = { 0x15, 0x1b, 0x14, 0 }; |
2375 | return alc_parse_auto_config(codec, alc262_ignore, alc262_ssids); | 2375 | return alc_parse_auto_config(codec, alc262_ignore, alc262_ssids); |
2376 | } | 2376 | } |
2377 | 2377 | ||
2378 | /* | 2378 | /* |
2379 | * Pin config fixes | 2379 | * Pin config fixes |
2380 | */ | 2380 | */ |
2381 | enum { | 2381 | enum { |
2382 | ALC262_FIXUP_FSC_H270, | 2382 | ALC262_FIXUP_FSC_H270, |
2383 | ALC262_FIXUP_FSC_S7110, | 2383 | ALC262_FIXUP_FSC_S7110, |
2384 | ALC262_FIXUP_HP_Z200, | 2384 | ALC262_FIXUP_HP_Z200, |
2385 | ALC262_FIXUP_TYAN, | 2385 | ALC262_FIXUP_TYAN, |
2386 | ALC262_FIXUP_LENOVO_3000, | 2386 | ALC262_FIXUP_LENOVO_3000, |
2387 | ALC262_FIXUP_BENQ, | 2387 | ALC262_FIXUP_BENQ, |
2388 | ALC262_FIXUP_BENQ_T31, | 2388 | ALC262_FIXUP_BENQ_T31, |
2389 | ALC262_FIXUP_INV_DMIC, | 2389 | ALC262_FIXUP_INV_DMIC, |
2390 | ALC262_FIXUP_INTEL_BAYLEYBAY, | 2390 | ALC262_FIXUP_INTEL_BAYLEYBAY, |
2391 | }; | 2391 | }; |
2392 | 2392 | ||
2393 | static const struct hda_fixup alc262_fixups[] = { | 2393 | static const struct hda_fixup alc262_fixups[] = { |
2394 | [ALC262_FIXUP_FSC_H270] = { | 2394 | [ALC262_FIXUP_FSC_H270] = { |
2395 | .type = HDA_FIXUP_PINS, | 2395 | .type = HDA_FIXUP_PINS, |
2396 | .v.pins = (const struct hda_pintbl[]) { | 2396 | .v.pins = (const struct hda_pintbl[]) { |
2397 | { 0x14, 0x99130110 }, /* speaker */ | 2397 | { 0x14, 0x99130110 }, /* speaker */ |
2398 | { 0x15, 0x0221142f }, /* front HP */ | 2398 | { 0x15, 0x0221142f }, /* front HP */ |
2399 | { 0x1b, 0x0121141f }, /* rear HP */ | 2399 | { 0x1b, 0x0121141f }, /* rear HP */ |
2400 | { } | 2400 | { } |
2401 | } | 2401 | } |
2402 | }, | 2402 | }, |
2403 | [ALC262_FIXUP_FSC_S7110] = { | 2403 | [ALC262_FIXUP_FSC_S7110] = { |
2404 | .type = HDA_FIXUP_PINS, | 2404 | .type = HDA_FIXUP_PINS, |
2405 | .v.pins = (const struct hda_pintbl[]) { | 2405 | .v.pins = (const struct hda_pintbl[]) { |
2406 | { 0x15, 0x90170110 }, /* speaker */ | 2406 | { 0x15, 0x90170110 }, /* speaker */ |
2407 | { } | 2407 | { } |
2408 | }, | 2408 | }, |
2409 | .chained = true, | 2409 | .chained = true, |
2410 | .chain_id = ALC262_FIXUP_BENQ, | 2410 | .chain_id = ALC262_FIXUP_BENQ, |
2411 | }, | 2411 | }, |
2412 | [ALC262_FIXUP_HP_Z200] = { | 2412 | [ALC262_FIXUP_HP_Z200] = { |
2413 | .type = HDA_FIXUP_PINS, | 2413 | .type = HDA_FIXUP_PINS, |
2414 | .v.pins = (const struct hda_pintbl[]) { | 2414 | .v.pins = (const struct hda_pintbl[]) { |
2415 | { 0x16, 0x99130120 }, /* internal speaker */ | 2415 | { 0x16, 0x99130120 }, /* internal speaker */ |
2416 | { } | 2416 | { } |
2417 | } | 2417 | } |
2418 | }, | 2418 | }, |
2419 | [ALC262_FIXUP_TYAN] = { | 2419 | [ALC262_FIXUP_TYAN] = { |
2420 | .type = HDA_FIXUP_PINS, | 2420 | .type = HDA_FIXUP_PINS, |
2421 | .v.pins = (const struct hda_pintbl[]) { | 2421 | .v.pins = (const struct hda_pintbl[]) { |
2422 | { 0x14, 0x1993e1f0 }, /* int AUX */ | 2422 | { 0x14, 0x1993e1f0 }, /* int AUX */ |
2423 | { } | 2423 | { } |
2424 | } | 2424 | } |
2425 | }, | 2425 | }, |
2426 | [ALC262_FIXUP_LENOVO_3000] = { | 2426 | [ALC262_FIXUP_LENOVO_3000] = { |
2427 | .type = HDA_FIXUP_PINCTLS, | 2427 | .type = HDA_FIXUP_PINCTLS, |
2428 | .v.pins = (const struct hda_pintbl[]) { | 2428 | .v.pins = (const struct hda_pintbl[]) { |
2429 | { 0x19, PIN_VREF50 }, | 2429 | { 0x19, PIN_VREF50 }, |
2430 | {} | 2430 | {} |
2431 | }, | 2431 | }, |
2432 | .chained = true, | 2432 | .chained = true, |
2433 | .chain_id = ALC262_FIXUP_BENQ, | 2433 | .chain_id = ALC262_FIXUP_BENQ, |
2434 | }, | 2434 | }, |
2435 | [ALC262_FIXUP_BENQ] = { | 2435 | [ALC262_FIXUP_BENQ] = { |
2436 | .type = HDA_FIXUP_VERBS, | 2436 | .type = HDA_FIXUP_VERBS, |
2437 | .v.verbs = (const struct hda_verb[]) { | 2437 | .v.verbs = (const struct hda_verb[]) { |
2438 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, | 2438 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, |
2439 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 }, | 2439 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 }, |
2440 | {} | 2440 | {} |
2441 | } | 2441 | } |
2442 | }, | 2442 | }, |
2443 | [ALC262_FIXUP_BENQ_T31] = { | 2443 | [ALC262_FIXUP_BENQ_T31] = { |
2444 | .type = HDA_FIXUP_VERBS, | 2444 | .type = HDA_FIXUP_VERBS, |
2445 | .v.verbs = (const struct hda_verb[]) { | 2445 | .v.verbs = (const struct hda_verb[]) { |
2446 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, | 2446 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, |
2447 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 }, | 2447 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 }, |
2448 | {} | 2448 | {} |
2449 | } | 2449 | } |
2450 | }, | 2450 | }, |
2451 | [ALC262_FIXUP_INV_DMIC] = { | 2451 | [ALC262_FIXUP_INV_DMIC] = { |
2452 | .type = HDA_FIXUP_FUNC, | 2452 | .type = HDA_FIXUP_FUNC, |
2453 | .v.func = alc_fixup_inv_dmic_0x12, | 2453 | .v.func = alc_fixup_inv_dmic_0x12, |
2454 | }, | 2454 | }, |
2455 | [ALC262_FIXUP_INTEL_BAYLEYBAY] = { | 2455 | [ALC262_FIXUP_INTEL_BAYLEYBAY] = { |
2456 | .type = HDA_FIXUP_FUNC, | 2456 | .type = HDA_FIXUP_FUNC, |
2457 | .v.func = alc_fixup_no_depop_delay, | 2457 | .v.func = alc_fixup_no_depop_delay, |
2458 | }, | 2458 | }, |
2459 | }; | 2459 | }; |
2460 | 2460 | ||
2461 | static const struct snd_pci_quirk alc262_fixup_tbl[] = { | 2461 | static const struct snd_pci_quirk alc262_fixup_tbl[] = { |
2462 | SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", ALC262_FIXUP_HP_Z200), | 2462 | SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", ALC262_FIXUP_HP_Z200), |
2463 | SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu Lifebook S7110", ALC262_FIXUP_FSC_S7110), | 2463 | SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu Lifebook S7110", ALC262_FIXUP_FSC_S7110), |
2464 | SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FIXUP_BENQ), | 2464 | SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FIXUP_BENQ), |
2465 | SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_FIXUP_TYAN), | 2465 | SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_FIXUP_TYAN), |
2466 | SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", ALC262_FIXUP_FSC_H270), | 2466 | SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", ALC262_FIXUP_FSC_H270), |
2467 | SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000", ALC262_FIXUP_LENOVO_3000), | 2467 | SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000", ALC262_FIXUP_LENOVO_3000), |
2468 | SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_FIXUP_BENQ), | 2468 | SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_FIXUP_BENQ), |
2469 | SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_FIXUP_BENQ_T31), | 2469 | SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_FIXUP_BENQ_T31), |
2470 | SND_PCI_QUIRK(0x8086, 0x7270, "BayleyBay", ALC262_FIXUP_INTEL_BAYLEYBAY), | 2470 | SND_PCI_QUIRK(0x8086, 0x7270, "BayleyBay", ALC262_FIXUP_INTEL_BAYLEYBAY), |
2471 | {} | 2471 | {} |
2472 | }; | 2472 | }; |
2473 | 2473 | ||
2474 | static const struct hda_model_fixup alc262_fixup_models[] = { | 2474 | static const struct hda_model_fixup alc262_fixup_models[] = { |
2475 | {.id = ALC262_FIXUP_INV_DMIC, .name = "inv-dmic"}, | 2475 | {.id = ALC262_FIXUP_INV_DMIC, .name = "inv-dmic"}, |
2476 | {} | 2476 | {} |
2477 | }; | 2477 | }; |
2478 | 2478 | ||
2479 | /* | 2479 | /* |
2480 | */ | 2480 | */ |
2481 | static int patch_alc262(struct hda_codec *codec) | 2481 | static int patch_alc262(struct hda_codec *codec) |
2482 | { | 2482 | { |
2483 | struct alc_spec *spec; | 2483 | struct alc_spec *spec; |
2484 | int err; | 2484 | int err; |
2485 | 2485 | ||
2486 | err = alc_alloc_spec(codec, 0x0b); | 2486 | err = alc_alloc_spec(codec, 0x0b); |
2487 | if (err < 0) | 2487 | if (err < 0) |
2488 | return err; | 2488 | return err; |
2489 | 2489 | ||
2490 | spec = codec->spec; | 2490 | spec = codec->spec; |
2491 | spec->gen.shared_mic_vref_pin = 0x18; | 2491 | spec->gen.shared_mic_vref_pin = 0x18; |
2492 | 2492 | ||
2493 | #if 0 | 2493 | #if 0 |
2494 | /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is | 2494 | /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is |
2495 | * under-run | 2495 | * under-run |
2496 | */ | 2496 | */ |
2497 | { | 2497 | { |
2498 | int tmp; | 2498 | int tmp; |
2499 | snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7); | 2499 | snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7); |
2500 | tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); | 2500 | tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); |
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 | snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80); | 2502 | snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80); |
2503 | } | 2503 | } |
2504 | #endif | 2504 | #endif |
2505 | alc_fix_pll_init(codec, 0x20, 0x0a, 10); | 2505 | alc_fix_pll_init(codec, 0x20, 0x0a, 10); |
2506 | 2506 | ||
2507 | snd_hda_pick_fixup(codec, alc262_fixup_models, alc262_fixup_tbl, | 2507 | snd_hda_pick_fixup(codec, alc262_fixup_models, alc262_fixup_tbl, |
2508 | alc262_fixups); | 2508 | alc262_fixups); |
2509 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); | 2509 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); |
2510 | 2510 | ||
2511 | alc_auto_parse_customize_define(codec); | 2511 | alc_auto_parse_customize_define(codec); |
2512 | 2512 | ||
2513 | if (has_cdefine_beep(codec)) | 2513 | if (has_cdefine_beep(codec)) |
2514 | spec->gen.beep_nid = 0x01; | 2514 | spec->gen.beep_nid = 0x01; |
2515 | 2515 | ||
2516 | /* automatic parse from the BIOS config */ | 2516 | /* automatic parse from the BIOS config */ |
2517 | err = alc262_parse_auto_config(codec); | 2517 | err = alc262_parse_auto_config(codec); |
2518 | if (err < 0) | 2518 | if (err < 0) |
2519 | goto error; | 2519 | goto error; |
2520 | 2520 | ||
2521 | if (!spec->gen.no_analog && spec->gen.beep_nid) | 2521 | if (!spec->gen.no_analog && spec->gen.beep_nid) |
2522 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); | 2522 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); |
2523 | 2523 | ||
2524 | codec->patch_ops = alc_patch_ops; | 2524 | codec->patch_ops = alc_patch_ops; |
2525 | spec->shutup = alc_eapd_shutup; | 2525 | spec->shutup = alc_eapd_shutup; |
2526 | 2526 | ||
2527 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); | 2527 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); |
2528 | 2528 | ||
2529 | return 0; | 2529 | return 0; |
2530 | 2530 | ||
2531 | error: | 2531 | error: |
2532 | alc_free(codec); | 2532 | alc_free(codec); |
2533 | return err; | 2533 | return err; |
2534 | } | 2534 | } |
2535 | 2535 | ||
2536 | /* | 2536 | /* |
2537 | * ALC268 | 2537 | * ALC268 |
2538 | */ | 2538 | */ |
2539 | /* bind Beep switches of both NID 0x0f and 0x10 */ | 2539 | /* bind Beep switches of both NID 0x0f and 0x10 */ |
2540 | static const struct hda_bind_ctls alc268_bind_beep_sw = { | 2540 | static const struct hda_bind_ctls alc268_bind_beep_sw = { |
2541 | .ops = &snd_hda_bind_sw, | 2541 | .ops = &snd_hda_bind_sw, |
2542 | .values = { | 2542 | .values = { |
2543 | HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT), | 2543 | HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT), |
2544 | HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT), | 2544 | HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT), |
2545 | 0 | 2545 | 0 |
2546 | }, | 2546 | }, |
2547 | }; | 2547 | }; |
2548 | 2548 | ||
2549 | static const struct snd_kcontrol_new alc268_beep_mixer[] = { | 2549 | static const struct snd_kcontrol_new alc268_beep_mixer[] = { |
2550 | HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT), | 2550 | HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT), |
2551 | HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw), | 2551 | HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw), |
2552 | { } | 2552 | { } |
2553 | }; | 2553 | }; |
2554 | 2554 | ||
2555 | /* set PCBEEP vol = 0, mute connections */ | 2555 | /* set PCBEEP vol = 0, mute connections */ |
2556 | static const struct hda_verb alc268_beep_init_verbs[] = { | 2556 | static const struct hda_verb alc268_beep_init_verbs[] = { |
2557 | {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 2557 | {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
2558 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | 2558 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, |
2559 | {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | 2559 | {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, |
2560 | { } | 2560 | { } |
2561 | }; | 2561 | }; |
2562 | 2562 | ||
2563 | enum { | 2563 | enum { |
2564 | ALC268_FIXUP_INV_DMIC, | 2564 | ALC268_FIXUP_INV_DMIC, |
2565 | ALC268_FIXUP_HP_EAPD, | 2565 | ALC268_FIXUP_HP_EAPD, |
2566 | ALC268_FIXUP_SPDIF, | 2566 | ALC268_FIXUP_SPDIF, |
2567 | }; | 2567 | }; |
2568 | 2568 | ||
2569 | static const struct hda_fixup alc268_fixups[] = { | 2569 | static const struct hda_fixup alc268_fixups[] = { |
2570 | [ALC268_FIXUP_INV_DMIC] = { | 2570 | [ALC268_FIXUP_INV_DMIC] = { |
2571 | .type = HDA_FIXUP_FUNC, | 2571 | .type = HDA_FIXUP_FUNC, |
2572 | .v.func = alc_fixup_inv_dmic_0x12, | 2572 | .v.func = alc_fixup_inv_dmic_0x12, |
2573 | }, | 2573 | }, |
2574 | [ALC268_FIXUP_HP_EAPD] = { | 2574 | [ALC268_FIXUP_HP_EAPD] = { |
2575 | .type = HDA_FIXUP_VERBS, | 2575 | .type = HDA_FIXUP_VERBS, |
2576 | .v.verbs = (const struct hda_verb[]) { | 2576 | .v.verbs = (const struct hda_verb[]) { |
2577 | {0x15, AC_VERB_SET_EAPD_BTLENABLE, 0}, | 2577 | {0x15, AC_VERB_SET_EAPD_BTLENABLE, 0}, |
2578 | {} | 2578 | {} |
2579 | } | 2579 | } |
2580 | }, | 2580 | }, |
2581 | [ALC268_FIXUP_SPDIF] = { | 2581 | [ALC268_FIXUP_SPDIF] = { |
2582 | .type = HDA_FIXUP_PINS, | 2582 | .type = HDA_FIXUP_PINS, |
2583 | .v.pins = (const struct hda_pintbl[]) { | 2583 | .v.pins = (const struct hda_pintbl[]) { |
2584 | { 0x1e, 0x014b1180 }, /* enable SPDIF out */ | 2584 | { 0x1e, 0x014b1180 }, /* enable SPDIF out */ |
2585 | {} | 2585 | {} |
2586 | } | 2586 | } |
2587 | }, | 2587 | }, |
2588 | }; | 2588 | }; |
2589 | 2589 | ||
2590 | static const struct hda_model_fixup alc268_fixup_models[] = { | 2590 | static const struct hda_model_fixup alc268_fixup_models[] = { |
2591 | {.id = ALC268_FIXUP_INV_DMIC, .name = "inv-dmic"}, | 2591 | {.id = ALC268_FIXUP_INV_DMIC, .name = "inv-dmic"}, |
2592 | {.id = ALC268_FIXUP_HP_EAPD, .name = "hp-eapd"}, | 2592 | {.id = ALC268_FIXUP_HP_EAPD, .name = "hp-eapd"}, |
2593 | {} | 2593 | {} |
2594 | }; | 2594 | }; |
2595 | 2595 | ||
2596 | static const struct snd_pci_quirk alc268_fixup_tbl[] = { | 2596 | static const struct snd_pci_quirk alc268_fixup_tbl[] = { |
2597 | SND_PCI_QUIRK(0x1025, 0x0139, "Acer TravelMate 6293", ALC268_FIXUP_SPDIF), | 2597 | SND_PCI_QUIRK(0x1025, 0x0139, "Acer TravelMate 6293", ALC268_FIXUP_SPDIF), |
2598 | SND_PCI_QUIRK(0x1025, 0x015b, "Acer AOA 150 (ZG5)", ALC268_FIXUP_INV_DMIC), | 2598 | SND_PCI_QUIRK(0x1025, 0x015b, "Acer AOA 150 (ZG5)", ALC268_FIXUP_INV_DMIC), |
2599 | /* below is codec SSID since multiple Toshiba laptops have the | 2599 | /* below is codec SSID since multiple Toshiba laptops have the |
2600 | * same PCI SSID 1179:ff00 | 2600 | * same PCI SSID 1179:ff00 |
2601 | */ | 2601 | */ |
2602 | SND_PCI_QUIRK(0x1179, 0xff06, "Toshiba P200", ALC268_FIXUP_HP_EAPD), | 2602 | SND_PCI_QUIRK(0x1179, 0xff06, "Toshiba P200", ALC268_FIXUP_HP_EAPD), |
2603 | {} | 2603 | {} |
2604 | }; | 2604 | }; |
2605 | 2605 | ||
2606 | /* | 2606 | /* |
2607 | * BIOS auto configuration | 2607 | * BIOS auto configuration |
2608 | */ | 2608 | */ |
2609 | static int alc268_parse_auto_config(struct hda_codec *codec) | 2609 | static int alc268_parse_auto_config(struct hda_codec *codec) |
2610 | { | 2610 | { |
2611 | static const hda_nid_t alc268_ssids[] = { 0x15, 0x1b, 0x14, 0 }; | 2611 | static const hda_nid_t alc268_ssids[] = { 0x15, 0x1b, 0x14, 0 }; |
2612 | return alc_parse_auto_config(codec, NULL, alc268_ssids); | 2612 | return alc_parse_auto_config(codec, NULL, alc268_ssids); |
2613 | } | 2613 | } |
2614 | 2614 | ||
2615 | /* | 2615 | /* |
2616 | */ | 2616 | */ |
2617 | static int patch_alc268(struct hda_codec *codec) | 2617 | static int patch_alc268(struct hda_codec *codec) |
2618 | { | 2618 | { |
2619 | struct alc_spec *spec; | 2619 | struct alc_spec *spec; |
2620 | int err; | 2620 | int err; |
2621 | 2621 | ||
2622 | /* ALC268 has no aa-loopback mixer */ | 2622 | /* ALC268 has no aa-loopback mixer */ |
2623 | err = alc_alloc_spec(codec, 0); | 2623 | err = alc_alloc_spec(codec, 0); |
2624 | if (err < 0) | 2624 | if (err < 0) |
2625 | return err; | 2625 | return err; |
2626 | 2626 | ||
2627 | spec = codec->spec; | 2627 | spec = codec->spec; |
2628 | spec->gen.beep_nid = 0x01; | 2628 | spec->gen.beep_nid = 0x01; |
2629 | 2629 | ||
2630 | snd_hda_pick_fixup(codec, alc268_fixup_models, alc268_fixup_tbl, alc268_fixups); | 2630 | snd_hda_pick_fixup(codec, alc268_fixup_models, alc268_fixup_tbl, alc268_fixups); |
2631 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); | 2631 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); |
2632 | 2632 | ||
2633 | /* automatic parse from the BIOS config */ | 2633 | /* automatic parse from the BIOS config */ |
2634 | err = alc268_parse_auto_config(codec); | 2634 | err = alc268_parse_auto_config(codec); |
2635 | if (err < 0) | 2635 | if (err < 0) |
2636 | goto error; | 2636 | goto error; |
2637 | 2637 | ||
2638 | if (err > 0 && !spec->gen.no_analog && | 2638 | if (err > 0 && !spec->gen.no_analog && |
2639 | spec->gen.autocfg.speaker_pins[0] != 0x1d) { | 2639 | spec->gen.autocfg.speaker_pins[0] != 0x1d) { |
2640 | add_mixer(spec, alc268_beep_mixer); | 2640 | add_mixer(spec, alc268_beep_mixer); |
2641 | snd_hda_add_verbs(codec, alc268_beep_init_verbs); | 2641 | snd_hda_add_verbs(codec, alc268_beep_init_verbs); |
2642 | if (!query_amp_caps(codec, 0x1d, HDA_INPUT)) | 2642 | if (!query_amp_caps(codec, 0x1d, HDA_INPUT)) |
2643 | /* override the amp caps for beep generator */ | 2643 | /* override the amp caps for beep generator */ |
2644 | snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT, | 2644 | snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT, |
2645 | (0x0c << AC_AMPCAP_OFFSET_SHIFT) | | 2645 | (0x0c << AC_AMPCAP_OFFSET_SHIFT) | |
2646 | (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) | | 2646 | (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) | |
2647 | (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) | | 2647 | (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) | |
2648 | (0 << AC_AMPCAP_MUTE_SHIFT)); | 2648 | (0 << AC_AMPCAP_MUTE_SHIFT)); |
2649 | } | 2649 | } |
2650 | 2650 | ||
2651 | codec->patch_ops = alc_patch_ops; | 2651 | codec->patch_ops = alc_patch_ops; |
2652 | spec->shutup = alc_eapd_shutup; | 2652 | spec->shutup = alc_eapd_shutup; |
2653 | 2653 | ||
2654 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); | 2654 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); |
2655 | 2655 | ||
2656 | return 0; | 2656 | return 0; |
2657 | 2657 | ||
2658 | error: | 2658 | error: |
2659 | alc_free(codec); | 2659 | alc_free(codec); |
2660 | return err; | 2660 | return err; |
2661 | } | 2661 | } |
2662 | 2662 | ||
2663 | /* | 2663 | /* |
2664 | * ALC269 | 2664 | * ALC269 |
2665 | */ | 2665 | */ |
2666 | 2666 | ||
2667 | static int playback_pcm_open(struct hda_pcm_stream *hinfo, | 2667 | static int playback_pcm_open(struct hda_pcm_stream *hinfo, |
2668 | struct hda_codec *codec, | 2668 | struct hda_codec *codec, |
2669 | struct snd_pcm_substream *substream) | 2669 | struct snd_pcm_substream *substream) |
2670 | { | 2670 | { |
2671 | struct hda_gen_spec *spec = codec->spec; | 2671 | struct hda_gen_spec *spec = codec->spec; |
2672 | return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream, | 2672 | return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream, |
2673 | hinfo); | 2673 | hinfo); |
2674 | } | 2674 | } |
2675 | 2675 | ||
2676 | static int playback_pcm_prepare(struct hda_pcm_stream *hinfo, | 2676 | static int playback_pcm_prepare(struct hda_pcm_stream *hinfo, |
2677 | struct hda_codec *codec, | 2677 | struct hda_codec *codec, |
2678 | unsigned int stream_tag, | 2678 | unsigned int stream_tag, |
2679 | unsigned int format, | 2679 | unsigned int format, |
2680 | struct snd_pcm_substream *substream) | 2680 | struct snd_pcm_substream *substream) |
2681 | { | 2681 | { |
2682 | struct hda_gen_spec *spec = codec->spec; | 2682 | struct hda_gen_spec *spec = codec->spec; |
2683 | return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, | 2683 | return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, |
2684 | stream_tag, format, substream); | 2684 | stream_tag, format, substream); |
2685 | } | 2685 | } |
2686 | 2686 | ||
2687 | static int playback_pcm_cleanup(struct hda_pcm_stream *hinfo, | 2687 | static int playback_pcm_cleanup(struct hda_pcm_stream *hinfo, |
2688 | struct hda_codec *codec, | 2688 | struct hda_codec *codec, |
2689 | struct snd_pcm_substream *substream) | 2689 | struct snd_pcm_substream *substream) |
2690 | { | 2690 | { |
2691 | struct hda_gen_spec *spec = codec->spec; | 2691 | struct hda_gen_spec *spec = codec->spec; |
2692 | return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); | 2692 | return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); |
2693 | } | 2693 | } |
2694 | 2694 | ||
2695 | static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = { | 2695 | static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = { |
2696 | .substreams = 1, | 2696 | .substreams = 1, |
2697 | .channels_min = 2, | 2697 | .channels_min = 2, |
2698 | .channels_max = 8, | 2698 | .channels_max = 8, |
2699 | .rates = SNDRV_PCM_RATE_44100, /* fixed rate */ | 2699 | .rates = SNDRV_PCM_RATE_44100, /* fixed rate */ |
2700 | /* NID is set in alc_build_pcms */ | 2700 | /* NID is set in alc_build_pcms */ |
2701 | .ops = { | 2701 | .ops = { |
2702 | .open = playback_pcm_open, | 2702 | .open = playback_pcm_open, |
2703 | .prepare = playback_pcm_prepare, | 2703 | .prepare = playback_pcm_prepare, |
2704 | .cleanup = playback_pcm_cleanup | 2704 | .cleanup = playback_pcm_cleanup |
2705 | }, | 2705 | }, |
2706 | }; | 2706 | }; |
2707 | 2707 | ||
2708 | static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = { | 2708 | static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = { |
2709 | .substreams = 1, | 2709 | .substreams = 1, |
2710 | .channels_min = 2, | 2710 | .channels_min = 2, |
2711 | .channels_max = 2, | 2711 | .channels_max = 2, |
2712 | .rates = SNDRV_PCM_RATE_44100, /* fixed rate */ | 2712 | .rates = SNDRV_PCM_RATE_44100, /* fixed rate */ |
2713 | /* NID is set in alc_build_pcms */ | 2713 | /* NID is set in alc_build_pcms */ |
2714 | }; | 2714 | }; |
2715 | 2715 | ||
2716 | /* different alc269-variants */ | 2716 | /* different alc269-variants */ |
2717 | enum { | 2717 | enum { |
2718 | ALC269_TYPE_ALC269VA, | 2718 | ALC269_TYPE_ALC269VA, |
2719 | ALC269_TYPE_ALC269VB, | 2719 | ALC269_TYPE_ALC269VB, |
2720 | ALC269_TYPE_ALC269VC, | 2720 | ALC269_TYPE_ALC269VC, |
2721 | ALC269_TYPE_ALC269VD, | 2721 | ALC269_TYPE_ALC269VD, |
2722 | ALC269_TYPE_ALC280, | 2722 | ALC269_TYPE_ALC280, |
2723 | ALC269_TYPE_ALC282, | 2723 | ALC269_TYPE_ALC282, |
2724 | ALC269_TYPE_ALC283, | 2724 | ALC269_TYPE_ALC283, |
2725 | ALC269_TYPE_ALC284, | 2725 | ALC269_TYPE_ALC284, |
2726 | ALC269_TYPE_ALC285, | 2726 | ALC269_TYPE_ALC285, |
2727 | ALC269_TYPE_ALC286, | 2727 | ALC269_TYPE_ALC286, |
2728 | ALC269_TYPE_ALC255, | 2728 | ALC269_TYPE_ALC255, |
2729 | }; | 2729 | }; |
2730 | 2730 | ||
2731 | /* | 2731 | /* |
2732 | * BIOS auto configuration | 2732 | * BIOS auto configuration |
2733 | */ | 2733 | */ |
2734 | static int alc269_parse_auto_config(struct hda_codec *codec) | 2734 | static int alc269_parse_auto_config(struct hda_codec *codec) |
2735 | { | 2735 | { |
2736 | static const hda_nid_t alc269_ignore[] = { 0x1d, 0 }; | 2736 | static const hda_nid_t alc269_ignore[] = { 0x1d, 0 }; |
2737 | static const hda_nid_t alc269_ssids[] = { 0, 0x1b, 0x14, 0x21 }; | 2737 | static const hda_nid_t alc269_ssids[] = { 0, 0x1b, 0x14, 0x21 }; |
2738 | static const hda_nid_t alc269va_ssids[] = { 0x15, 0x1b, 0x14, 0 }; | 2738 | static const hda_nid_t alc269va_ssids[] = { 0x15, 0x1b, 0x14, 0 }; |
2739 | struct alc_spec *spec = codec->spec; | 2739 | struct alc_spec *spec = codec->spec; |
2740 | const hda_nid_t *ssids; | 2740 | const hda_nid_t *ssids; |
2741 | 2741 | ||
2742 | switch (spec->codec_variant) { | 2742 | switch (spec->codec_variant) { |
2743 | case ALC269_TYPE_ALC269VA: | 2743 | case ALC269_TYPE_ALC269VA: |
2744 | case ALC269_TYPE_ALC269VC: | 2744 | case ALC269_TYPE_ALC269VC: |
2745 | case ALC269_TYPE_ALC280: | 2745 | case ALC269_TYPE_ALC280: |
2746 | case ALC269_TYPE_ALC284: | 2746 | case ALC269_TYPE_ALC284: |
2747 | case ALC269_TYPE_ALC285: | 2747 | case ALC269_TYPE_ALC285: |
2748 | ssids = alc269va_ssids; | 2748 | ssids = alc269va_ssids; |
2749 | break; | 2749 | break; |
2750 | case ALC269_TYPE_ALC269VB: | 2750 | case ALC269_TYPE_ALC269VB: |
2751 | case ALC269_TYPE_ALC269VD: | 2751 | case ALC269_TYPE_ALC269VD: |
2752 | case ALC269_TYPE_ALC282: | 2752 | case ALC269_TYPE_ALC282: |
2753 | case ALC269_TYPE_ALC283: | 2753 | case ALC269_TYPE_ALC283: |
2754 | case ALC269_TYPE_ALC286: | 2754 | case ALC269_TYPE_ALC286: |
2755 | case ALC269_TYPE_ALC255: | 2755 | case ALC269_TYPE_ALC255: |
2756 | ssids = alc269_ssids; | 2756 | ssids = alc269_ssids; |
2757 | break; | 2757 | break; |
2758 | default: | 2758 | default: |
2759 | ssids = alc269_ssids; | 2759 | ssids = alc269_ssids; |
2760 | break; | 2760 | break; |
2761 | } | 2761 | } |
2762 | 2762 | ||
2763 | return alc_parse_auto_config(codec, alc269_ignore, ssids); | 2763 | return alc_parse_auto_config(codec, alc269_ignore, ssids); |
2764 | } | 2764 | } |
2765 | 2765 | ||
2766 | static void alc269vb_toggle_power_output(struct hda_codec *codec, int power_up) | 2766 | static void alc269vb_toggle_power_output(struct hda_codec *codec, int power_up) |
2767 | { | 2767 | { |
2768 | int val = alc_read_coef_idx(codec, 0x04); | 2768 | int val = alc_read_coef_idx(codec, 0x04); |
2769 | if (power_up) | 2769 | if (power_up) |
2770 | val |= 1 << 11; | 2770 | val |= 1 << 11; |
2771 | else | 2771 | else |
2772 | val &= ~(1 << 11); | 2772 | val &= ~(1 << 11); |
2773 | alc_write_coef_idx(codec, 0x04, val); | 2773 | alc_write_coef_idx(codec, 0x04, val); |
2774 | } | 2774 | } |
2775 | 2775 | ||
2776 | static void alc269_shutup(struct hda_codec *codec) | 2776 | static void alc269_shutup(struct hda_codec *codec) |
2777 | { | 2777 | { |
2778 | struct alc_spec *spec = codec->spec; | 2778 | struct alc_spec *spec = codec->spec; |
2779 | 2779 | ||
2780 | if (spec->codec_variant == ALC269_TYPE_ALC269VB) | 2780 | if (spec->codec_variant == ALC269_TYPE_ALC269VB) |
2781 | alc269vb_toggle_power_output(codec, 0); | 2781 | alc269vb_toggle_power_output(codec, 0); |
2782 | if (spec->codec_variant == ALC269_TYPE_ALC269VB && | 2782 | if (spec->codec_variant == ALC269_TYPE_ALC269VB && |
2783 | (alc_get_coef0(codec) & 0x00ff) == 0x018) { | 2783 | (alc_get_coef0(codec) & 0x00ff) == 0x018) { |
2784 | msleep(150); | 2784 | msleep(150); |
2785 | } | 2785 | } |
2786 | snd_hda_shutup_pins(codec); | 2786 | snd_hda_shutup_pins(codec); |
2787 | } | 2787 | } |
2788 | 2788 | ||
2789 | static void alc282_restore_default_value(struct hda_codec *codec) | 2789 | static void alc282_restore_default_value(struct hda_codec *codec) |
2790 | { | 2790 | { |
2791 | int val; | 2791 | int val; |
2792 | 2792 | ||
2793 | /* Power Down Control */ | 2793 | /* Power Down Control */ |
2794 | alc_write_coef_idx(codec, 0x03, 0x0002); | 2794 | alc_write_coef_idx(codec, 0x03, 0x0002); |
2795 | /* FIFO and filter clock */ | 2795 | /* FIFO and filter clock */ |
2796 | alc_write_coef_idx(codec, 0x05, 0x0700); | 2796 | alc_write_coef_idx(codec, 0x05, 0x0700); |
2797 | /* DMIC control */ | 2797 | /* DMIC control */ |
2798 | alc_write_coef_idx(codec, 0x07, 0x0200); | 2798 | alc_write_coef_idx(codec, 0x07, 0x0200); |
2799 | /* Analog clock */ | 2799 | /* Analog clock */ |
2800 | val = alc_read_coef_idx(codec, 0x06); | 2800 | val = alc_read_coef_idx(codec, 0x06); |
2801 | alc_write_coef_idx(codec, 0x06, (val & ~0x00f0) | 0x0); | 2801 | alc_write_coef_idx(codec, 0x06, (val & ~0x00f0) | 0x0); |
2802 | /* JD */ | 2802 | /* JD */ |
2803 | val = alc_read_coef_idx(codec, 0x08); | 2803 | val = alc_read_coef_idx(codec, 0x08); |
2804 | alc_write_coef_idx(codec, 0x08, (val & ~0xfffc) | 0x0c2c); | 2804 | alc_write_coef_idx(codec, 0x08, (val & ~0xfffc) | 0x0c2c); |
2805 | /* JD offset1 */ | 2805 | /* JD offset1 */ |
2806 | alc_write_coef_idx(codec, 0x0a, 0xcccc); | 2806 | alc_write_coef_idx(codec, 0x0a, 0xcccc); |
2807 | /* JD offset2 */ | 2807 | /* JD offset2 */ |
2808 | alc_write_coef_idx(codec, 0x0b, 0xcccc); | 2808 | alc_write_coef_idx(codec, 0x0b, 0xcccc); |
2809 | /* LDO1/2/3, DAC/ADC */ | 2809 | /* LDO1/2/3, DAC/ADC */ |
2810 | alc_write_coef_idx(codec, 0x0e, 0x6e00); | 2810 | alc_write_coef_idx(codec, 0x0e, 0x6e00); |
2811 | /* JD */ | 2811 | /* JD */ |
2812 | val = alc_read_coef_idx(codec, 0x0f); | 2812 | val = alc_read_coef_idx(codec, 0x0f); |
2813 | alc_write_coef_idx(codec, 0x0f, (val & ~0xf800) | 0x1000); | 2813 | alc_write_coef_idx(codec, 0x0f, (val & ~0xf800) | 0x1000); |
2814 | /* Capless */ | 2814 | /* Capless */ |
2815 | val = alc_read_coef_idx(codec, 0x10); | 2815 | val = alc_read_coef_idx(codec, 0x10); |
2816 | alc_write_coef_idx(codec, 0x10, (val & ~0xfc00) | 0x0c00); | 2816 | alc_write_coef_idx(codec, 0x10, (val & ~0xfc00) | 0x0c00); |
2817 | /* Class D test 4 */ | 2817 | /* Class D test 4 */ |
2818 | alc_write_coef_idx(codec, 0x6f, 0x0); | 2818 | alc_write_coef_idx(codec, 0x6f, 0x0); |
2819 | /* IO power down directly */ | 2819 | /* IO power down directly */ |
2820 | val = alc_read_coef_idx(codec, 0x0c); | 2820 | val = alc_read_coef_idx(codec, 0x0c); |
2821 | alc_write_coef_idx(codec, 0x0c, (val & ~0xfe00) | 0x0); | 2821 | alc_write_coef_idx(codec, 0x0c, (val & ~0xfe00) | 0x0); |
2822 | /* ANC */ | 2822 | /* ANC */ |
2823 | alc_write_coef_idx(codec, 0x34, 0xa0c0); | 2823 | alc_write_coef_idx(codec, 0x34, 0xa0c0); |
2824 | /* AGC MUX */ | 2824 | /* AGC MUX */ |
2825 | val = alc_read_coef_idx(codec, 0x16); | 2825 | val = alc_read_coef_idx(codec, 0x16); |
2826 | alc_write_coef_idx(codec, 0x16, (val & ~0x0008) | 0x0); | 2826 | alc_write_coef_idx(codec, 0x16, (val & ~0x0008) | 0x0); |
2827 | /* DAC simple content protection */ | 2827 | /* DAC simple content protection */ |
2828 | val = alc_read_coef_idx(codec, 0x1d); | 2828 | val = alc_read_coef_idx(codec, 0x1d); |
2829 | alc_write_coef_idx(codec, 0x1d, (val & ~0x00e0) | 0x0); | 2829 | alc_write_coef_idx(codec, 0x1d, (val & ~0x00e0) | 0x0); |
2830 | /* ADC simple content protection */ | 2830 | /* ADC simple content protection */ |
2831 | val = alc_read_coef_idx(codec, 0x1f); | 2831 | val = alc_read_coef_idx(codec, 0x1f); |
2832 | alc_write_coef_idx(codec, 0x1f, (val & ~0x00e0) | 0x0); | 2832 | alc_write_coef_idx(codec, 0x1f, (val & ~0x00e0) | 0x0); |
2833 | /* DAC ADC Zero Detection */ | 2833 | /* DAC ADC Zero Detection */ |
2834 | alc_write_coef_idx(codec, 0x21, 0x8804); | 2834 | alc_write_coef_idx(codec, 0x21, 0x8804); |
2835 | /* PLL */ | 2835 | /* PLL */ |
2836 | alc_write_coef_idx(codec, 0x63, 0x2902); | 2836 | alc_write_coef_idx(codec, 0x63, 0x2902); |
2837 | /* capless control 2 */ | 2837 | /* capless control 2 */ |
2838 | alc_write_coef_idx(codec, 0x68, 0xa080); | 2838 | alc_write_coef_idx(codec, 0x68, 0xa080); |
2839 | /* capless control 3 */ | 2839 | /* capless control 3 */ |
2840 | alc_write_coef_idx(codec, 0x69, 0x3400); | 2840 | alc_write_coef_idx(codec, 0x69, 0x3400); |
2841 | /* capless control 4 */ | 2841 | /* capless control 4 */ |
2842 | alc_write_coef_idx(codec, 0x6a, 0x2f3e); | 2842 | alc_write_coef_idx(codec, 0x6a, 0x2f3e); |
2843 | /* capless control 5 */ | 2843 | /* capless control 5 */ |
2844 | alc_write_coef_idx(codec, 0x6b, 0x0); | 2844 | alc_write_coef_idx(codec, 0x6b, 0x0); |
2845 | /* class D test 2 */ | 2845 | /* class D test 2 */ |
2846 | val = alc_read_coef_idx(codec, 0x6d); | 2846 | val = alc_read_coef_idx(codec, 0x6d); |
2847 | alc_write_coef_idx(codec, 0x6d, (val & ~0x0fff) | 0x0900); | 2847 | alc_write_coef_idx(codec, 0x6d, (val & ~0x0fff) | 0x0900); |
2848 | /* class D test 3 */ | 2848 | /* class D test 3 */ |
2849 | alc_write_coef_idx(codec, 0x6e, 0x110a); | 2849 | alc_write_coef_idx(codec, 0x6e, 0x110a); |
2850 | /* class D test 5 */ | 2850 | /* class D test 5 */ |
2851 | val = alc_read_coef_idx(codec, 0x70); | 2851 | val = alc_read_coef_idx(codec, 0x70); |
2852 | alc_write_coef_idx(codec, 0x70, (val & ~0x00f8) | 0x00d8); | 2852 | alc_write_coef_idx(codec, 0x70, (val & ~0x00f8) | 0x00d8); |
2853 | /* class D test 6 */ | 2853 | /* class D test 6 */ |
2854 | alc_write_coef_idx(codec, 0x71, 0x0014); | 2854 | alc_write_coef_idx(codec, 0x71, 0x0014); |
2855 | /* classD OCP */ | 2855 | /* classD OCP */ |
2856 | alc_write_coef_idx(codec, 0x72, 0xc2ba); | 2856 | alc_write_coef_idx(codec, 0x72, 0xc2ba); |
2857 | /* classD pure DC test */ | 2857 | /* classD pure DC test */ |
2858 | val = alc_read_coef_idx(codec, 0x77); | 2858 | val = alc_read_coef_idx(codec, 0x77); |
2859 | alc_write_coef_idx(codec, 0x77, (val & ~0x0f80) | 0x0); | 2859 | alc_write_coef_idx(codec, 0x77, (val & ~0x0f80) | 0x0); |
2860 | /* Class D amp control */ | 2860 | /* Class D amp control */ |
2861 | alc_write_coef_idx(codec, 0x6c, 0xfc06); | 2861 | alc_write_coef_idx(codec, 0x6c, 0xfc06); |
2862 | } | 2862 | } |
2863 | 2863 | ||
2864 | static void alc282_init(struct hda_codec *codec) | 2864 | static void alc282_init(struct hda_codec *codec) |
2865 | { | 2865 | { |
2866 | struct alc_spec *spec = codec->spec; | 2866 | struct alc_spec *spec = codec->spec; |
2867 | hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; | 2867 | hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; |
2868 | bool hp_pin_sense; | 2868 | bool hp_pin_sense; |
2869 | int coef78; | 2869 | int coef78; |
2870 | 2870 | ||
2871 | alc282_restore_default_value(codec); | 2871 | alc282_restore_default_value(codec); |
2872 | 2872 | ||
2873 | if (!hp_pin) | 2873 | if (!hp_pin) |
2874 | return; | 2874 | return; |
2875 | hp_pin_sense = snd_hda_jack_detect(codec, hp_pin); | 2875 | hp_pin_sense = snd_hda_jack_detect(codec, hp_pin); |
2876 | coef78 = alc_read_coef_idx(codec, 0x78); | 2876 | coef78 = alc_read_coef_idx(codec, 0x78); |
2877 | 2877 | ||
2878 | /* Index 0x78 Direct Drive HP AMP LPM Control 1 */ | 2878 | /* Index 0x78 Direct Drive HP AMP LPM Control 1 */ |
2879 | /* Headphone capless set to high power mode */ | 2879 | /* Headphone capless set to high power mode */ |
2880 | alc_write_coef_idx(codec, 0x78, 0x9004); | 2880 | alc_write_coef_idx(codec, 0x78, 0x9004); |
2881 | 2881 | ||
2882 | if (hp_pin_sense) | 2882 | if (hp_pin_sense) |
2883 | msleep(2); | 2883 | msleep(2); |
2884 | 2884 | ||
2885 | snd_hda_codec_write(codec, hp_pin, 0, | 2885 | snd_hda_codec_write(codec, hp_pin, 0, |
2886 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); | 2886 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); |
2887 | 2887 | ||
2888 | if (hp_pin_sense) | 2888 | if (hp_pin_sense) |
2889 | msleep(85); | 2889 | msleep(85); |
2890 | 2890 | ||
2891 | snd_hda_codec_write(codec, hp_pin, 0, | 2891 | snd_hda_codec_write(codec, hp_pin, 0, |
2892 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); | 2892 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); |
2893 | 2893 | ||
2894 | if (hp_pin_sense) | 2894 | if (hp_pin_sense) |
2895 | msleep(100); | 2895 | msleep(100); |
2896 | 2896 | ||
2897 | /* Headphone capless set to normal mode */ | 2897 | /* Headphone capless set to normal mode */ |
2898 | alc_write_coef_idx(codec, 0x78, coef78); | 2898 | alc_write_coef_idx(codec, 0x78, coef78); |
2899 | } | 2899 | } |
2900 | 2900 | ||
2901 | static void alc282_shutup(struct hda_codec *codec) | 2901 | static void alc282_shutup(struct hda_codec *codec) |
2902 | { | 2902 | { |
2903 | struct alc_spec *spec = codec->spec; | 2903 | struct alc_spec *spec = codec->spec; |
2904 | hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; | 2904 | hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; |
2905 | bool hp_pin_sense; | 2905 | bool hp_pin_sense; |
2906 | int coef78; | 2906 | int coef78; |
2907 | 2907 | ||
2908 | if (!hp_pin) { | 2908 | if (!hp_pin) { |
2909 | alc269_shutup(codec); | 2909 | alc269_shutup(codec); |
2910 | return; | 2910 | return; |
2911 | } | 2911 | } |
2912 | 2912 | ||
2913 | hp_pin_sense = snd_hda_jack_detect(codec, hp_pin); | 2913 | hp_pin_sense = snd_hda_jack_detect(codec, hp_pin); |
2914 | coef78 = alc_read_coef_idx(codec, 0x78); | 2914 | coef78 = alc_read_coef_idx(codec, 0x78); |
2915 | alc_write_coef_idx(codec, 0x78, 0x9004); | 2915 | alc_write_coef_idx(codec, 0x78, 0x9004); |
2916 | 2916 | ||
2917 | if (hp_pin_sense) | 2917 | if (hp_pin_sense) |
2918 | msleep(2); | 2918 | msleep(2); |
2919 | 2919 | ||
2920 | snd_hda_codec_write(codec, hp_pin, 0, | 2920 | snd_hda_codec_write(codec, hp_pin, 0, |
2921 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); | 2921 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); |
2922 | 2922 | ||
2923 | if (hp_pin_sense) | 2923 | if (hp_pin_sense) |
2924 | msleep(85); | 2924 | msleep(85); |
2925 | 2925 | ||
2926 | snd_hda_codec_write(codec, hp_pin, 0, | 2926 | snd_hda_codec_write(codec, hp_pin, 0, |
2927 | AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0); | 2927 | AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0); |
2928 | 2928 | ||
2929 | if (hp_pin_sense) | 2929 | if (hp_pin_sense) |
2930 | msleep(100); | 2930 | msleep(100); |
2931 | 2931 | ||
2932 | alc_auto_setup_eapd(codec, false); | 2932 | alc_auto_setup_eapd(codec, false); |
2933 | snd_hda_shutup_pins(codec); | 2933 | snd_hda_shutup_pins(codec); |
2934 | alc_write_coef_idx(codec, 0x78, coef78); | 2934 | alc_write_coef_idx(codec, 0x78, coef78); |
2935 | } | 2935 | } |
2936 | 2936 | ||
2937 | static void alc283_restore_default_value(struct hda_codec *codec) | 2937 | static void alc283_restore_default_value(struct hda_codec *codec) |
2938 | { | 2938 | { |
2939 | int val; | 2939 | int val; |
2940 | 2940 | ||
2941 | /* Power Down Control */ | 2941 | /* Power Down Control */ |
2942 | alc_write_coef_idx(codec, 0x03, 0x0002); | 2942 | alc_write_coef_idx(codec, 0x03, 0x0002); |
2943 | /* FIFO and filter clock */ | 2943 | /* FIFO and filter clock */ |
2944 | alc_write_coef_idx(codec, 0x05, 0x0700); | 2944 | alc_write_coef_idx(codec, 0x05, 0x0700); |
2945 | /* DMIC control */ | 2945 | /* DMIC control */ |
2946 | alc_write_coef_idx(codec, 0x07, 0x0200); | 2946 | alc_write_coef_idx(codec, 0x07, 0x0200); |
2947 | /* Analog clock */ | 2947 | /* Analog clock */ |
2948 | val = alc_read_coef_idx(codec, 0x06); | 2948 | val = alc_read_coef_idx(codec, 0x06); |
2949 | alc_write_coef_idx(codec, 0x06, (val & ~0x00f0) | 0x0); | 2949 | alc_write_coef_idx(codec, 0x06, (val & ~0x00f0) | 0x0); |
2950 | /* JD */ | 2950 | /* JD */ |
2951 | val = alc_read_coef_idx(codec, 0x08); | 2951 | val = alc_read_coef_idx(codec, 0x08); |
2952 | alc_write_coef_idx(codec, 0x08, (val & ~0xfffc) | 0x0c2c); | 2952 | alc_write_coef_idx(codec, 0x08, (val & ~0xfffc) | 0x0c2c); |
2953 | /* JD offset1 */ | 2953 | /* JD offset1 */ |
2954 | alc_write_coef_idx(codec, 0x0a, 0xcccc); | 2954 | alc_write_coef_idx(codec, 0x0a, 0xcccc); |
2955 | /* JD offset2 */ | 2955 | /* JD offset2 */ |
2956 | alc_write_coef_idx(codec, 0x0b, 0xcccc); | 2956 | alc_write_coef_idx(codec, 0x0b, 0xcccc); |
2957 | /* LDO1/2/3, DAC/ADC */ | 2957 | /* LDO1/2/3, DAC/ADC */ |
2958 | alc_write_coef_idx(codec, 0x0e, 0x6fc0); | 2958 | alc_write_coef_idx(codec, 0x0e, 0x6fc0); |
2959 | /* JD */ | 2959 | /* JD */ |
2960 | val = alc_read_coef_idx(codec, 0x0f); | 2960 | val = alc_read_coef_idx(codec, 0x0f); |
2961 | alc_write_coef_idx(codec, 0x0f, (val & ~0xf800) | 0x1000); | 2961 | alc_write_coef_idx(codec, 0x0f, (val & ~0xf800) | 0x1000); |
2962 | /* Capless */ | 2962 | /* Capless */ |
2963 | val = alc_read_coef_idx(codec, 0x10); | 2963 | val = alc_read_coef_idx(codec, 0x10); |
2964 | alc_write_coef_idx(codec, 0x10, (val & ~0xfc00) | 0x0c00); | 2964 | alc_write_coef_idx(codec, 0x10, (val & ~0xfc00) | 0x0c00); |
2965 | /* Class D test 4 */ | 2965 | /* Class D test 4 */ |
2966 | alc_write_coef_idx(codec, 0x3a, 0x0); | 2966 | alc_write_coef_idx(codec, 0x3a, 0x0); |
2967 | /* IO power down directly */ | 2967 | /* IO power down directly */ |
2968 | val = alc_read_coef_idx(codec, 0x0c); | 2968 | val = alc_read_coef_idx(codec, 0x0c); |
2969 | alc_write_coef_idx(codec, 0x0c, (val & ~0xfe00) | 0x0); | 2969 | alc_write_coef_idx(codec, 0x0c, (val & ~0xfe00) | 0x0); |
2970 | /* ANC */ | 2970 | /* ANC */ |
2971 | alc_write_coef_idx(codec, 0x22, 0xa0c0); | 2971 | alc_write_coef_idx(codec, 0x22, 0xa0c0); |
2972 | /* AGC MUX */ | 2972 | /* AGC MUX */ |
2973 | val = alc_read_coefex_idx(codec, 0x53, 0x01); | 2973 | val = alc_read_coefex_idx(codec, 0x53, 0x01); |
2974 | alc_write_coefex_idx(codec, 0x53, 0x01, (val & ~0x000f) | 0x0008); | 2974 | alc_write_coefex_idx(codec, 0x53, 0x01, (val & ~0x000f) | 0x0008); |
2975 | /* DAC simple content protection */ | 2975 | /* DAC simple content protection */ |
2976 | val = alc_read_coef_idx(codec, 0x1d); | 2976 | val = alc_read_coef_idx(codec, 0x1d); |
2977 | alc_write_coef_idx(codec, 0x1d, (val & ~0x00e0) | 0x0); | 2977 | alc_write_coef_idx(codec, 0x1d, (val & ~0x00e0) | 0x0); |
2978 | /* ADC simple content protection */ | 2978 | /* ADC simple content protection */ |
2979 | val = alc_read_coef_idx(codec, 0x1f); | 2979 | val = alc_read_coef_idx(codec, 0x1f); |
2980 | alc_write_coef_idx(codec, 0x1f, (val & ~0x00e0) | 0x0); | 2980 | alc_write_coef_idx(codec, 0x1f, (val & ~0x00e0) | 0x0); |
2981 | /* DAC ADC Zero Detection */ | 2981 | /* DAC ADC Zero Detection */ |
2982 | alc_write_coef_idx(codec, 0x21, 0x8804); | 2982 | alc_write_coef_idx(codec, 0x21, 0x8804); |
2983 | /* PLL */ | 2983 | /* PLL */ |
2984 | alc_write_coef_idx(codec, 0x2e, 0x2902); | 2984 | alc_write_coef_idx(codec, 0x2e, 0x2902); |
2985 | /* capless control 2 */ | 2985 | /* capless control 2 */ |
2986 | alc_write_coef_idx(codec, 0x33, 0xa080); | 2986 | alc_write_coef_idx(codec, 0x33, 0xa080); |
2987 | /* capless control 3 */ | 2987 | /* capless control 3 */ |
2988 | alc_write_coef_idx(codec, 0x34, 0x3400); | 2988 | alc_write_coef_idx(codec, 0x34, 0x3400); |
2989 | /* capless control 4 */ | 2989 | /* capless control 4 */ |
2990 | alc_write_coef_idx(codec, 0x35, 0x2f3e); | 2990 | alc_write_coef_idx(codec, 0x35, 0x2f3e); |
2991 | /* capless control 5 */ | 2991 | /* capless control 5 */ |
2992 | alc_write_coef_idx(codec, 0x36, 0x0); | 2992 | alc_write_coef_idx(codec, 0x36, 0x0); |
2993 | /* class D test 2 */ | 2993 | /* class D test 2 */ |
2994 | val = alc_read_coef_idx(codec, 0x38); | 2994 | val = alc_read_coef_idx(codec, 0x38); |
2995 | alc_write_coef_idx(codec, 0x38, (val & ~0x0fff) | 0x0900); | 2995 | alc_write_coef_idx(codec, 0x38, (val & ~0x0fff) | 0x0900); |
2996 | /* class D test 3 */ | 2996 | /* class D test 3 */ |
2997 | alc_write_coef_idx(codec, 0x39, 0x110a); | 2997 | alc_write_coef_idx(codec, 0x39, 0x110a); |
2998 | /* class D test 5 */ | 2998 | /* class D test 5 */ |
2999 | val = alc_read_coef_idx(codec, 0x3b); | 2999 | val = alc_read_coef_idx(codec, 0x3b); |
3000 | alc_write_coef_idx(codec, 0x3b, (val & ~0x00f8) | 0x00d8); | 3000 | alc_write_coef_idx(codec, 0x3b, (val & ~0x00f8) | 0x00d8); |
3001 | /* class D test 6 */ | 3001 | /* class D test 6 */ |
3002 | alc_write_coef_idx(codec, 0x3c, 0x0014); | 3002 | alc_write_coef_idx(codec, 0x3c, 0x0014); |
3003 | /* classD OCP */ | 3003 | /* classD OCP */ |
3004 | alc_write_coef_idx(codec, 0x3d, 0xc2ba); | 3004 | alc_write_coef_idx(codec, 0x3d, 0xc2ba); |
3005 | /* classD pure DC test */ | 3005 | /* classD pure DC test */ |
3006 | val = alc_read_coef_idx(codec, 0x42); | 3006 | val = alc_read_coef_idx(codec, 0x42); |
3007 | alc_write_coef_idx(codec, 0x42, (val & ~0x0f80) | 0x0); | 3007 | alc_write_coef_idx(codec, 0x42, (val & ~0x0f80) | 0x0); |
3008 | /* test mode */ | 3008 | /* test mode */ |
3009 | alc_write_coef_idx(codec, 0x49, 0x0); | 3009 | alc_write_coef_idx(codec, 0x49, 0x0); |
3010 | /* Class D DC enable */ | 3010 | /* Class D DC enable */ |
3011 | val = alc_read_coef_idx(codec, 0x40); | 3011 | val = alc_read_coef_idx(codec, 0x40); |
3012 | alc_write_coef_idx(codec, 0x40, (val & ~0xf800) | 0x9800); | 3012 | alc_write_coef_idx(codec, 0x40, (val & ~0xf800) | 0x9800); |
3013 | /* DC offset */ | 3013 | /* DC offset */ |
3014 | val = alc_read_coef_idx(codec, 0x42); | 3014 | val = alc_read_coef_idx(codec, 0x42); |
3015 | alc_write_coef_idx(codec, 0x42, (val & ~0xf000) | 0x2000); | 3015 | alc_write_coef_idx(codec, 0x42, (val & ~0xf000) | 0x2000); |
3016 | /* Class D amp control */ | 3016 | /* Class D amp control */ |
3017 | alc_write_coef_idx(codec, 0x37, 0xfc06); | 3017 | alc_write_coef_idx(codec, 0x37, 0xfc06); |
3018 | } | 3018 | } |
3019 | 3019 | ||
3020 | static void alc283_init(struct hda_codec *codec) | 3020 | static void alc283_init(struct hda_codec *codec) |
3021 | { | 3021 | { |
3022 | struct alc_spec *spec = codec->spec; | 3022 | struct alc_spec *spec = codec->spec; |
3023 | hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; | 3023 | hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; |
3024 | bool hp_pin_sense; | 3024 | bool hp_pin_sense; |
3025 | int val; | 3025 | int val; |
3026 | 3026 | ||
3027 | if (!spec->gen.autocfg.hp_outs) { | 3027 | if (!spec->gen.autocfg.hp_outs) { |
3028 | if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT) | 3028 | if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT) |
3029 | hp_pin = spec->gen.autocfg.line_out_pins[0]; | 3029 | hp_pin = spec->gen.autocfg.line_out_pins[0]; |
3030 | } | 3030 | } |
3031 | 3031 | ||
3032 | alc283_restore_default_value(codec); | 3032 | alc283_restore_default_value(codec); |
3033 | 3033 | ||
3034 | if (!hp_pin) | 3034 | if (!hp_pin) |
3035 | return; | 3035 | return; |
3036 | hp_pin_sense = snd_hda_jack_detect(codec, hp_pin); | 3036 | hp_pin_sense = snd_hda_jack_detect(codec, hp_pin); |
3037 | 3037 | ||
3038 | /* Index 0x43 Direct Drive HP AMP LPM Control 1 */ | 3038 | /* Index 0x43 Direct Drive HP AMP LPM Control 1 */ |
3039 | /* Headphone capless set to high power mode */ | 3039 | /* Headphone capless set to high power mode */ |
3040 | alc_write_coef_idx(codec, 0x43, 0x9004); | 3040 | alc_write_coef_idx(codec, 0x43, 0x9004); |
3041 | 3041 | ||
3042 | snd_hda_codec_write(codec, hp_pin, 0, | 3042 | snd_hda_codec_write(codec, hp_pin, 0, |
3043 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); | 3043 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); |
3044 | 3044 | ||
3045 | if (hp_pin_sense) | 3045 | if (hp_pin_sense) |
3046 | msleep(85); | 3046 | msleep(85); |
3047 | 3047 | ||
3048 | snd_hda_codec_write(codec, hp_pin, 0, | 3048 | snd_hda_codec_write(codec, hp_pin, 0, |
3049 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); | 3049 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); |
3050 | 3050 | ||
3051 | if (hp_pin_sense) | 3051 | if (hp_pin_sense) |
3052 | msleep(85); | 3052 | msleep(85); |
3053 | /* Index 0x46 Combo jack auto switch control 2 */ | 3053 | /* Index 0x46 Combo jack auto switch control 2 */ |
3054 | /* 3k pull low control for Headset jack. */ | 3054 | /* 3k pull low control for Headset jack. */ |
3055 | val = alc_read_coef_idx(codec, 0x46); | 3055 | val = alc_read_coef_idx(codec, 0x46); |
3056 | alc_write_coef_idx(codec, 0x46, val & ~(3 << 12)); | 3056 | alc_write_coef_idx(codec, 0x46, val & ~(3 << 12)); |
3057 | /* Headphone capless set to normal mode */ | 3057 | /* Headphone capless set to normal mode */ |
3058 | alc_write_coef_idx(codec, 0x43, 0x9614); | 3058 | alc_write_coef_idx(codec, 0x43, 0x9614); |
3059 | } | 3059 | } |
3060 | 3060 | ||
3061 | static void alc283_shutup(struct hda_codec *codec) | 3061 | static void alc283_shutup(struct hda_codec *codec) |
3062 | { | 3062 | { |
3063 | struct alc_spec *spec = codec->spec; | 3063 | struct alc_spec *spec = codec->spec; |
3064 | hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; | 3064 | hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; |
3065 | bool hp_pin_sense; | 3065 | bool hp_pin_sense; |
3066 | int val; | 3066 | int val; |
3067 | 3067 | ||
3068 | if (!spec->gen.autocfg.hp_outs) { | 3068 | if (!spec->gen.autocfg.hp_outs) { |
3069 | if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT) | 3069 | if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT) |
3070 | hp_pin = spec->gen.autocfg.line_out_pins[0]; | 3070 | hp_pin = spec->gen.autocfg.line_out_pins[0]; |
3071 | } | 3071 | } |
3072 | 3072 | ||
3073 | if (!hp_pin) { | 3073 | if (!hp_pin) { |
3074 | alc269_shutup(codec); | 3074 | alc269_shutup(codec); |
3075 | return; | 3075 | return; |
3076 | } | 3076 | } |
3077 | 3077 | ||
3078 | hp_pin_sense = snd_hda_jack_detect(codec, hp_pin); | 3078 | hp_pin_sense = snd_hda_jack_detect(codec, hp_pin); |
3079 | 3079 | ||
3080 | alc_write_coef_idx(codec, 0x43, 0x9004); | 3080 | alc_write_coef_idx(codec, 0x43, 0x9004); |
3081 | 3081 | ||
3082 | snd_hda_codec_write(codec, hp_pin, 0, | 3082 | snd_hda_codec_write(codec, hp_pin, 0, |
3083 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); | 3083 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); |
3084 | 3084 | ||
3085 | if (hp_pin_sense) | 3085 | if (hp_pin_sense) |
3086 | msleep(100); | 3086 | msleep(100); |
3087 | 3087 | ||
3088 | snd_hda_codec_write(codec, hp_pin, 0, | 3088 | snd_hda_codec_write(codec, hp_pin, 0, |
3089 | AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0); | 3089 | AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0); |
3090 | 3090 | ||
3091 | val = alc_read_coef_idx(codec, 0x46); | 3091 | val = alc_read_coef_idx(codec, 0x46); |
3092 | alc_write_coef_idx(codec, 0x46, val | (3 << 12)); | 3092 | alc_write_coef_idx(codec, 0x46, val | (3 << 12)); |
3093 | 3093 | ||
3094 | if (hp_pin_sense) | 3094 | if (hp_pin_sense) |
3095 | msleep(100); | 3095 | msleep(100); |
3096 | alc_auto_setup_eapd(codec, false); | 3096 | alc_auto_setup_eapd(codec, false); |
3097 | snd_hda_shutup_pins(codec); | 3097 | snd_hda_shutup_pins(codec); |
3098 | alc_write_coef_idx(codec, 0x43, 0x9614); | 3098 | alc_write_coef_idx(codec, 0x43, 0x9614); |
3099 | } | 3099 | } |
3100 | 3100 | ||
3101 | static void alc5505_coef_set(struct hda_codec *codec, unsigned int index_reg, | 3101 | static void alc5505_coef_set(struct hda_codec *codec, unsigned int index_reg, |
3102 | unsigned int val) | 3102 | unsigned int val) |
3103 | { | 3103 | { |
3104 | snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_COEF_INDEX, index_reg >> 1); | 3104 | snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_COEF_INDEX, index_reg >> 1); |
3105 | snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_PROC_COEF, val & 0xffff); /* LSB */ | 3105 | snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_PROC_COEF, val & 0xffff); /* LSB */ |
3106 | snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_PROC_COEF, val >> 16); /* MSB */ | 3106 | snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_PROC_COEF, val >> 16); /* MSB */ |
3107 | } | 3107 | } |
3108 | 3108 | ||
3109 | static int alc5505_coef_get(struct hda_codec *codec, unsigned int index_reg) | 3109 | static int alc5505_coef_get(struct hda_codec *codec, unsigned int index_reg) |
3110 | { | 3110 | { |
3111 | unsigned int val; | 3111 | unsigned int val; |
3112 | 3112 | ||
3113 | snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_COEF_INDEX, index_reg >> 1); | 3113 | snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_COEF_INDEX, index_reg >> 1); |
3114 | val = snd_hda_codec_read(codec, 0x51, 0, AC_VERB_GET_PROC_COEF, 0) | 3114 | val = snd_hda_codec_read(codec, 0x51, 0, AC_VERB_GET_PROC_COEF, 0) |
3115 | & 0xffff; | 3115 | & 0xffff; |
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 | << 16; | 3117 | << 16; |
3118 | return val; | 3118 | return val; |
3119 | } | 3119 | } |
3120 | 3120 | ||
3121 | static void alc5505_dsp_halt(struct hda_codec *codec) | 3121 | static void alc5505_dsp_halt(struct hda_codec *codec) |
3122 | { | 3122 | { |
3123 | unsigned int val; | 3123 | unsigned int val; |
3124 | 3124 | ||
3125 | alc5505_coef_set(codec, 0x3000, 0x000c); /* DSP CPU stop */ | 3125 | alc5505_coef_set(codec, 0x3000, 0x000c); /* DSP CPU stop */ |
3126 | alc5505_coef_set(codec, 0x880c, 0x0008); /* DDR enter self refresh */ | 3126 | alc5505_coef_set(codec, 0x880c, 0x0008); /* DDR enter self refresh */ |
3127 | alc5505_coef_set(codec, 0x61c0, 0x11110080); /* Clock control for PLL and CPU */ | 3127 | alc5505_coef_set(codec, 0x61c0, 0x11110080); /* Clock control for PLL and CPU */ |
3128 | alc5505_coef_set(codec, 0x6230, 0xfc0d4011); /* Disable Input OP */ | 3128 | alc5505_coef_set(codec, 0x6230, 0xfc0d4011); /* Disable Input OP */ |
3129 | alc5505_coef_set(codec, 0x61b4, 0x040a2b03); /* Stop PLL2 */ | 3129 | alc5505_coef_set(codec, 0x61b4, 0x040a2b03); /* Stop PLL2 */ |
3130 | alc5505_coef_set(codec, 0x61b0, 0x00005b17); /* Stop PLL1 */ | 3130 | alc5505_coef_set(codec, 0x61b0, 0x00005b17); /* Stop PLL1 */ |
3131 | alc5505_coef_set(codec, 0x61b8, 0x04133303); /* Stop PLL3 */ | 3131 | alc5505_coef_set(codec, 0x61b8, 0x04133303); /* Stop PLL3 */ |
3132 | val = alc5505_coef_get(codec, 0x6220); | 3132 | val = alc5505_coef_get(codec, 0x6220); |
3133 | alc5505_coef_set(codec, 0x6220, (val | 0x3000)); /* switch Ringbuffer clock to DBUS clock */ | 3133 | alc5505_coef_set(codec, 0x6220, (val | 0x3000)); /* switch Ringbuffer clock to DBUS clock */ |
3134 | } | 3134 | } |
3135 | 3135 | ||
3136 | static void alc5505_dsp_back_from_halt(struct hda_codec *codec) | 3136 | static void alc5505_dsp_back_from_halt(struct hda_codec *codec) |
3137 | { | 3137 | { |
3138 | alc5505_coef_set(codec, 0x61b8, 0x04133302); | 3138 | alc5505_coef_set(codec, 0x61b8, 0x04133302); |
3139 | alc5505_coef_set(codec, 0x61b0, 0x00005b16); | 3139 | alc5505_coef_set(codec, 0x61b0, 0x00005b16); |
3140 | alc5505_coef_set(codec, 0x61b4, 0x040a2b02); | 3140 | alc5505_coef_set(codec, 0x61b4, 0x040a2b02); |
3141 | alc5505_coef_set(codec, 0x6230, 0xf80d4011); | 3141 | alc5505_coef_set(codec, 0x6230, 0xf80d4011); |
3142 | alc5505_coef_set(codec, 0x6220, 0x2002010f); | 3142 | alc5505_coef_set(codec, 0x6220, 0x2002010f); |
3143 | alc5505_coef_set(codec, 0x880c, 0x00000004); | 3143 | alc5505_coef_set(codec, 0x880c, 0x00000004); |
3144 | } | 3144 | } |
3145 | 3145 | ||
3146 | static void alc5505_dsp_init(struct hda_codec *codec) | 3146 | static void alc5505_dsp_init(struct hda_codec *codec) |
3147 | { | 3147 | { |
3148 | unsigned int val; | 3148 | unsigned int val; |
3149 | 3149 | ||
3150 | alc5505_dsp_halt(codec); | 3150 | alc5505_dsp_halt(codec); |
3151 | alc5505_dsp_back_from_halt(codec); | 3151 | alc5505_dsp_back_from_halt(codec); |
3152 | alc5505_coef_set(codec, 0x61b0, 0x5b14); /* PLL1 control */ | 3152 | alc5505_coef_set(codec, 0x61b0, 0x5b14); /* PLL1 control */ |
3153 | alc5505_coef_set(codec, 0x61b0, 0x5b16); | 3153 | alc5505_coef_set(codec, 0x61b0, 0x5b16); |
3154 | alc5505_coef_set(codec, 0x61b4, 0x04132b00); /* PLL2 control */ | 3154 | alc5505_coef_set(codec, 0x61b4, 0x04132b00); /* PLL2 control */ |
3155 | alc5505_coef_set(codec, 0x61b4, 0x04132b02); | 3155 | alc5505_coef_set(codec, 0x61b4, 0x04132b02); |
3156 | alc5505_coef_set(codec, 0x61b8, 0x041f3300); /* PLL3 control*/ | 3156 | alc5505_coef_set(codec, 0x61b8, 0x041f3300); /* PLL3 control*/ |
3157 | alc5505_coef_set(codec, 0x61b8, 0x041f3302); | 3157 | alc5505_coef_set(codec, 0x61b8, 0x041f3302); |
3158 | snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_CODEC_RESET, 0); /* Function reset */ | 3158 | snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_CODEC_RESET, 0); /* Function reset */ |
3159 | alc5505_coef_set(codec, 0x61b8, 0x041b3302); | 3159 | alc5505_coef_set(codec, 0x61b8, 0x041b3302); |
3160 | alc5505_coef_set(codec, 0x61b8, 0x04173302); | 3160 | alc5505_coef_set(codec, 0x61b8, 0x04173302); |
3161 | alc5505_coef_set(codec, 0x61b8, 0x04163302); | 3161 | alc5505_coef_set(codec, 0x61b8, 0x04163302); |
3162 | alc5505_coef_set(codec, 0x8800, 0x348b328b); /* DRAM control */ | 3162 | alc5505_coef_set(codec, 0x8800, 0x348b328b); /* DRAM control */ |
3163 | alc5505_coef_set(codec, 0x8808, 0x00020022); /* DRAM control */ | 3163 | alc5505_coef_set(codec, 0x8808, 0x00020022); /* DRAM control */ |
3164 | alc5505_coef_set(codec, 0x8818, 0x00000400); /* DRAM control */ | 3164 | alc5505_coef_set(codec, 0x8818, 0x00000400); /* DRAM control */ |
3165 | 3165 | ||
3166 | val = alc5505_coef_get(codec, 0x6200) >> 16; /* Read revision ID */ | 3166 | val = alc5505_coef_get(codec, 0x6200) >> 16; /* Read revision ID */ |
3167 | if (val <= 3) | 3167 | if (val <= 3) |
3168 | alc5505_coef_set(codec, 0x6220, 0x2002010f); /* I/O PAD Configuration */ | 3168 | alc5505_coef_set(codec, 0x6220, 0x2002010f); /* I/O PAD Configuration */ |
3169 | else | 3169 | else |
3170 | alc5505_coef_set(codec, 0x6220, 0x6002018f); | 3170 | alc5505_coef_set(codec, 0x6220, 0x6002018f); |
3171 | 3171 | ||
3172 | alc5505_coef_set(codec, 0x61ac, 0x055525f0); /**/ | 3172 | alc5505_coef_set(codec, 0x61ac, 0x055525f0); /**/ |
3173 | alc5505_coef_set(codec, 0x61c0, 0x12230080); /* Clock control */ | 3173 | alc5505_coef_set(codec, 0x61c0, 0x12230080); /* Clock control */ |
3174 | alc5505_coef_set(codec, 0x61b4, 0x040e2b02); /* PLL2 control */ | 3174 | alc5505_coef_set(codec, 0x61b4, 0x040e2b02); /* PLL2 control */ |
3175 | alc5505_coef_set(codec, 0x61bc, 0x010234f8); /* OSC Control */ | 3175 | alc5505_coef_set(codec, 0x61bc, 0x010234f8); /* OSC Control */ |
3176 | alc5505_coef_set(codec, 0x880c, 0x00000004); /* DRAM Function control */ | 3176 | alc5505_coef_set(codec, 0x880c, 0x00000004); /* DRAM Function control */ |
3177 | alc5505_coef_set(codec, 0x880c, 0x00000003); | 3177 | alc5505_coef_set(codec, 0x880c, 0x00000003); |
3178 | alc5505_coef_set(codec, 0x880c, 0x00000010); | 3178 | alc5505_coef_set(codec, 0x880c, 0x00000010); |
3179 | 3179 | ||
3180 | #ifdef HALT_REALTEK_ALC5505 | 3180 | #ifdef HALT_REALTEK_ALC5505 |
3181 | alc5505_dsp_halt(codec); | 3181 | alc5505_dsp_halt(codec); |
3182 | #endif | 3182 | #endif |
3183 | } | 3183 | } |
3184 | 3184 | ||
3185 | #ifdef HALT_REALTEK_ALC5505 | 3185 | #ifdef HALT_REALTEK_ALC5505 |
3186 | #define alc5505_dsp_suspend(codec) /* NOP */ | 3186 | #define alc5505_dsp_suspend(codec) /* NOP */ |
3187 | #define alc5505_dsp_resume(codec) /* NOP */ | 3187 | #define alc5505_dsp_resume(codec) /* NOP */ |
3188 | #else | 3188 | #else |
3189 | #define alc5505_dsp_suspend(codec) alc5505_dsp_halt(codec) | 3189 | #define alc5505_dsp_suspend(codec) alc5505_dsp_halt(codec) |
3190 | #define alc5505_dsp_resume(codec) alc5505_dsp_back_from_halt(codec) | 3190 | #define alc5505_dsp_resume(codec) alc5505_dsp_back_from_halt(codec) |
3191 | #endif | 3191 | #endif |
3192 | 3192 | ||
3193 | #ifdef CONFIG_PM | 3193 | #ifdef CONFIG_PM |
3194 | static int alc269_suspend(struct hda_codec *codec) | 3194 | static int alc269_suspend(struct hda_codec *codec) |
3195 | { | 3195 | { |
3196 | struct alc_spec *spec = codec->spec; | 3196 | struct alc_spec *spec = codec->spec; |
3197 | 3197 | ||
3198 | if (spec->has_alc5505_dsp) | 3198 | if (spec->has_alc5505_dsp) |
3199 | alc5505_dsp_suspend(codec); | 3199 | alc5505_dsp_suspend(codec); |
3200 | return alc_suspend(codec); | 3200 | return alc_suspend(codec); |
3201 | } | 3201 | } |
3202 | 3202 | ||
3203 | static int alc269_resume(struct hda_codec *codec) | 3203 | static int alc269_resume(struct hda_codec *codec) |
3204 | { | 3204 | { |
3205 | struct alc_spec *spec = codec->spec; | 3205 | struct alc_spec *spec = codec->spec; |
3206 | 3206 | ||
3207 | if (spec->codec_variant == ALC269_TYPE_ALC269VB) | 3207 | if (spec->codec_variant == ALC269_TYPE_ALC269VB) |
3208 | alc269vb_toggle_power_output(codec, 0); | 3208 | alc269vb_toggle_power_output(codec, 0); |
3209 | if (spec->codec_variant == ALC269_TYPE_ALC269VB && | 3209 | if (spec->codec_variant == ALC269_TYPE_ALC269VB && |
3210 | (alc_get_coef0(codec) & 0x00ff) == 0x018) { | 3210 | (alc_get_coef0(codec) & 0x00ff) == 0x018) { |
3211 | msleep(150); | 3211 | msleep(150); |
3212 | } | 3212 | } |
3213 | 3213 | ||
3214 | codec->patch_ops.init(codec); | 3214 | codec->patch_ops.init(codec); |
3215 | 3215 | ||
3216 | if (spec->codec_variant == ALC269_TYPE_ALC269VB) | 3216 | if (spec->codec_variant == ALC269_TYPE_ALC269VB) |
3217 | alc269vb_toggle_power_output(codec, 1); | 3217 | alc269vb_toggle_power_output(codec, 1); |
3218 | if (spec->codec_variant == ALC269_TYPE_ALC269VB && | 3218 | if (spec->codec_variant == ALC269_TYPE_ALC269VB && |
3219 | (alc_get_coef0(codec) & 0x00ff) == 0x017) { | 3219 | (alc_get_coef0(codec) & 0x00ff) == 0x017) { |
3220 | msleep(200); | 3220 | msleep(200); |
3221 | } | 3221 | } |
3222 | 3222 | ||
3223 | snd_hda_codec_resume_amp(codec); | 3223 | snd_hda_codec_resume_amp(codec); |
3224 | snd_hda_codec_resume_cache(codec); | 3224 | snd_hda_codec_resume_cache(codec); |
3225 | alc_inv_dmic_sync(codec, true); | 3225 | alc_inv_dmic_sync(codec, true); |
3226 | hda_call_check_power_status(codec, 0x01); | 3226 | hda_call_check_power_status(codec, 0x01); |
3227 | if (spec->has_alc5505_dsp) | 3227 | if (spec->has_alc5505_dsp) |
3228 | alc5505_dsp_resume(codec); | 3228 | alc5505_dsp_resume(codec); |
3229 | 3229 | ||
3230 | return 0; | 3230 | return 0; |
3231 | } | 3231 | } |
3232 | #endif /* CONFIG_PM */ | 3232 | #endif /* CONFIG_PM */ |
3233 | 3233 | ||
3234 | static void alc269_fixup_pincfg_no_hp_to_lineout(struct hda_codec *codec, | 3234 | static void alc269_fixup_pincfg_no_hp_to_lineout(struct hda_codec *codec, |
3235 | const struct hda_fixup *fix, int action) | 3235 | const struct hda_fixup *fix, int action) |
3236 | { | 3236 | { |
3237 | struct alc_spec *spec = codec->spec; | 3237 | struct alc_spec *spec = codec->spec; |
3238 | 3238 | ||
3239 | if (action == HDA_FIXUP_ACT_PRE_PROBE) | 3239 | if (action == HDA_FIXUP_ACT_PRE_PROBE) |
3240 | spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP; | 3240 | spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP; |
3241 | } | 3241 | } |
3242 | 3242 | ||
3243 | static void alc269_fixup_hweq(struct hda_codec *codec, | 3243 | static void alc269_fixup_hweq(struct hda_codec *codec, |
3244 | const struct hda_fixup *fix, int action) | 3244 | const struct hda_fixup *fix, int action) |
3245 | { | 3245 | { |
3246 | int coef; | 3246 | int coef; |
3247 | 3247 | ||
3248 | if (action != HDA_FIXUP_ACT_INIT) | 3248 | if (action != HDA_FIXUP_ACT_INIT) |
3249 | return; | 3249 | return; |
3250 | coef = alc_read_coef_idx(codec, 0x1e); | 3250 | coef = alc_read_coef_idx(codec, 0x1e); |
3251 | alc_write_coef_idx(codec, 0x1e, coef | 0x80); | 3251 | alc_write_coef_idx(codec, 0x1e, coef | 0x80); |
3252 | } | 3252 | } |
3253 | 3253 | ||
3254 | static void alc269_fixup_headset_mic(struct hda_codec *codec, | 3254 | static void alc269_fixup_headset_mic(struct hda_codec *codec, |
3255 | const struct hda_fixup *fix, int action) | 3255 | const struct hda_fixup *fix, int action) |
3256 | { | 3256 | { |
3257 | struct alc_spec *spec = codec->spec; | 3257 | struct alc_spec *spec = codec->spec; |
3258 | 3258 | ||
3259 | if (action == HDA_FIXUP_ACT_PRE_PROBE) | 3259 | if (action == HDA_FIXUP_ACT_PRE_PROBE) |
3260 | spec->parse_flags |= HDA_PINCFG_HEADSET_MIC; | 3260 | spec->parse_flags |= HDA_PINCFG_HEADSET_MIC; |
3261 | } | 3261 | } |
3262 | 3262 | ||
3263 | static void alc271_fixup_dmic(struct hda_codec *codec, | 3263 | static void alc271_fixup_dmic(struct hda_codec *codec, |
3264 | const struct hda_fixup *fix, int action) | 3264 | const struct hda_fixup *fix, int action) |
3265 | { | 3265 | { |
3266 | static const struct hda_verb verbs[] = { | 3266 | static const struct hda_verb verbs[] = { |
3267 | {0x20, AC_VERB_SET_COEF_INDEX, 0x0d}, | 3267 | {0x20, AC_VERB_SET_COEF_INDEX, 0x0d}, |
3268 | {0x20, AC_VERB_SET_PROC_COEF, 0x4000}, | 3268 | {0x20, AC_VERB_SET_PROC_COEF, 0x4000}, |
3269 | {} | 3269 | {} |
3270 | }; | 3270 | }; |
3271 | unsigned int cfg; | 3271 | unsigned int cfg; |
3272 | 3272 | ||
3273 | if (strcmp(codec->chip_name, "ALC271X") && | 3273 | if (strcmp(codec->chip_name, "ALC271X") && |
3274 | strcmp(codec->chip_name, "ALC269VB")) | 3274 | strcmp(codec->chip_name, "ALC269VB")) |
3275 | return; | 3275 | return; |
3276 | cfg = snd_hda_codec_get_pincfg(codec, 0x12); | 3276 | cfg = snd_hda_codec_get_pincfg(codec, 0x12); |
3277 | if (get_defcfg_connect(cfg) == AC_JACK_PORT_FIXED) | 3277 | if (get_defcfg_connect(cfg) == AC_JACK_PORT_FIXED) |
3278 | snd_hda_sequence_write(codec, verbs); | 3278 | snd_hda_sequence_write(codec, verbs); |
3279 | } | 3279 | } |
3280 | 3280 | ||
3281 | static void alc269_fixup_pcm_44k(struct hda_codec *codec, | 3281 | static void alc269_fixup_pcm_44k(struct hda_codec *codec, |
3282 | const struct hda_fixup *fix, int action) | 3282 | const struct hda_fixup *fix, int action) |
3283 | { | 3283 | { |
3284 | struct alc_spec *spec = codec->spec; | 3284 | struct alc_spec *spec = codec->spec; |
3285 | 3285 | ||
3286 | if (action != HDA_FIXUP_ACT_PROBE) | 3286 | if (action != HDA_FIXUP_ACT_PROBE) |
3287 | return; | 3287 | return; |
3288 | 3288 | ||
3289 | /* Due to a hardware problem on Lenovo Ideadpad, we need to | 3289 | /* Due to a hardware problem on Lenovo Ideadpad, we need to |
3290 | * fix the sample rate of analog I/O to 44.1kHz | 3290 | * fix the sample rate of analog I/O to 44.1kHz |
3291 | */ | 3291 | */ |
3292 | spec->gen.stream_analog_playback = &alc269_44k_pcm_analog_playback; | 3292 | spec->gen.stream_analog_playback = &alc269_44k_pcm_analog_playback; |
3293 | spec->gen.stream_analog_capture = &alc269_44k_pcm_analog_capture; | 3293 | spec->gen.stream_analog_capture = &alc269_44k_pcm_analog_capture; |
3294 | } | 3294 | } |
3295 | 3295 | ||
3296 | static void alc269_fixup_stereo_dmic(struct hda_codec *codec, | 3296 | static void alc269_fixup_stereo_dmic(struct hda_codec *codec, |
3297 | const struct hda_fixup *fix, int action) | 3297 | const struct hda_fixup *fix, int action) |
3298 | { | 3298 | { |
3299 | int coef; | 3299 | int coef; |
3300 | 3300 | ||
3301 | if (action != HDA_FIXUP_ACT_INIT) | 3301 | if (action != HDA_FIXUP_ACT_INIT) |
3302 | return; | 3302 | return; |
3303 | /* The digital-mic unit sends PDM (differential signal) instead of | 3303 | /* The digital-mic unit sends PDM (differential signal) instead of |
3304 | * the standard PCM, thus you can't record a valid mono stream as is. | 3304 | * the standard PCM, thus you can't record a valid mono stream as is. |
3305 | * Below is a workaround specific to ALC269 to control the dmic | 3305 | * Below is a workaround specific to ALC269 to control the dmic |
3306 | * signal source as mono. | 3306 | * signal source as mono. |
3307 | */ | 3307 | */ |
3308 | coef = alc_read_coef_idx(codec, 0x07); | 3308 | coef = alc_read_coef_idx(codec, 0x07); |
3309 | alc_write_coef_idx(codec, 0x07, coef | 0x80); | 3309 | alc_write_coef_idx(codec, 0x07, coef | 0x80); |
3310 | } | 3310 | } |
3311 | 3311 | ||
3312 | static void alc269_quanta_automute(struct hda_codec *codec) | 3312 | static void alc269_quanta_automute(struct hda_codec *codec) |
3313 | { | 3313 | { |
3314 | snd_hda_gen_update_outputs(codec); | 3314 | snd_hda_gen_update_outputs(codec); |
3315 | 3315 | ||
3316 | snd_hda_codec_write(codec, 0x20, 0, | 3316 | snd_hda_codec_write(codec, 0x20, 0, |
3317 | AC_VERB_SET_COEF_INDEX, 0x0c); | 3317 | AC_VERB_SET_COEF_INDEX, 0x0c); |
3318 | snd_hda_codec_write(codec, 0x20, 0, | 3318 | snd_hda_codec_write(codec, 0x20, 0, |
3319 | AC_VERB_SET_PROC_COEF, 0x680); | 3319 | AC_VERB_SET_PROC_COEF, 0x680); |
3320 | 3320 | ||
3321 | snd_hda_codec_write(codec, 0x20, 0, | 3321 | snd_hda_codec_write(codec, 0x20, 0, |
3322 | AC_VERB_SET_COEF_INDEX, 0x0c); | 3322 | AC_VERB_SET_COEF_INDEX, 0x0c); |
3323 | snd_hda_codec_write(codec, 0x20, 0, | 3323 | snd_hda_codec_write(codec, 0x20, 0, |
3324 | AC_VERB_SET_PROC_COEF, 0x480); | 3324 | AC_VERB_SET_PROC_COEF, 0x480); |
3325 | } | 3325 | } |
3326 | 3326 | ||
3327 | static void alc269_fixup_quanta_mute(struct hda_codec *codec, | 3327 | static void alc269_fixup_quanta_mute(struct hda_codec *codec, |
3328 | const struct hda_fixup *fix, int action) | 3328 | const struct hda_fixup *fix, int action) |
3329 | { | 3329 | { |
3330 | struct alc_spec *spec = codec->spec; | 3330 | struct alc_spec *spec = codec->spec; |
3331 | if (action != HDA_FIXUP_ACT_PROBE) | 3331 | if (action != HDA_FIXUP_ACT_PROBE) |
3332 | return; | 3332 | return; |
3333 | spec->gen.automute_hook = alc269_quanta_automute; | 3333 | spec->gen.automute_hook = alc269_quanta_automute; |
3334 | } | 3334 | } |
3335 | 3335 | ||
3336 | static void alc269_x101_hp_automute_hook(struct hda_codec *codec, | 3336 | static void alc269_x101_hp_automute_hook(struct hda_codec *codec, |
3337 | struct hda_jack_tbl *jack) | 3337 | struct hda_jack_tbl *jack) |
3338 | { | 3338 | { |
3339 | struct alc_spec *spec = codec->spec; | 3339 | struct alc_spec *spec = codec->spec; |
3340 | int vref; | 3340 | int vref; |
3341 | msleep(200); | 3341 | msleep(200); |
3342 | snd_hda_gen_hp_automute(codec, jack); | 3342 | snd_hda_gen_hp_automute(codec, jack); |
3343 | 3343 | ||
3344 | vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0; | 3344 | vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0; |
3345 | msleep(100); | 3345 | msleep(100); |
3346 | snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | 3346 | snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, |
3347 | vref); | 3347 | vref); |
3348 | msleep(500); | 3348 | msleep(500); |
3349 | snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | 3349 | snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, |
3350 | vref); | 3350 | vref); |
3351 | } | 3351 | } |
3352 | 3352 | ||
3353 | static void alc269_fixup_x101_headset_mic(struct hda_codec *codec, | 3353 | static void alc269_fixup_x101_headset_mic(struct hda_codec *codec, |
3354 | const struct hda_fixup *fix, int action) | 3354 | const struct hda_fixup *fix, int action) |
3355 | { | 3355 | { |
3356 | struct alc_spec *spec = codec->spec; | 3356 | struct alc_spec *spec = codec->spec; |
3357 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | 3357 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
3358 | spec->parse_flags |= HDA_PINCFG_HEADSET_MIC; | 3358 | spec->parse_flags |= HDA_PINCFG_HEADSET_MIC; |
3359 | spec->gen.hp_automute_hook = alc269_x101_hp_automute_hook; | 3359 | spec->gen.hp_automute_hook = alc269_x101_hp_automute_hook; |
3360 | } | 3360 | } |
3361 | } | 3361 | } |
3362 | 3362 | ||
3363 | 3363 | ||
3364 | /* update mute-LED according to the speaker mute state via mic VREF pin */ | 3364 | /* update mute-LED according to the speaker mute state via mic VREF pin */ |
3365 | static void alc269_fixup_mic_mute_hook(void *private_data, int enabled) | 3365 | static void alc269_fixup_mic_mute_hook(void *private_data, int enabled) |
3366 | { | 3366 | { |
3367 | struct hda_codec *codec = private_data; | 3367 | struct hda_codec *codec = private_data; |
3368 | struct alc_spec *spec = codec->spec; | 3368 | struct alc_spec *spec = codec->spec; |
3369 | unsigned int pinval; | 3369 | unsigned int pinval; |
3370 | 3370 | ||
3371 | if (spec->mute_led_polarity) | 3371 | if (spec->mute_led_polarity) |
3372 | enabled = !enabled; | 3372 | enabled = !enabled; |
3373 | pinval = snd_hda_codec_get_pin_target(codec, spec->mute_led_nid); | 3373 | pinval = snd_hda_codec_get_pin_target(codec, spec->mute_led_nid); |
3374 | pinval &= ~AC_PINCTL_VREFEN; | 3374 | pinval &= ~AC_PINCTL_VREFEN; |
3375 | pinval |= enabled ? AC_PINCTL_VREF_HIZ : AC_PINCTL_VREF_80; | 3375 | pinval |= enabled ? AC_PINCTL_VREF_HIZ : AC_PINCTL_VREF_80; |
3376 | if (spec->mute_led_nid) | 3376 | if (spec->mute_led_nid) |
3377 | snd_hda_set_pin_ctl_cache(codec, spec->mute_led_nid, pinval); | 3377 | snd_hda_set_pin_ctl_cache(codec, spec->mute_led_nid, pinval); |
3378 | } | 3378 | } |
3379 | 3379 | ||
3380 | /* Make sure the led works even in runtime suspend */ | 3380 | /* Make sure the led works even in runtime suspend */ |
3381 | static unsigned int led_power_filter(struct hda_codec *codec, | 3381 | static unsigned int led_power_filter(struct hda_codec *codec, |
3382 | hda_nid_t nid, | 3382 | hda_nid_t nid, |
3383 | unsigned int power_state) | 3383 | unsigned int power_state) |
3384 | { | 3384 | { |
3385 | struct alc_spec *spec = codec->spec; | 3385 | struct alc_spec *spec = codec->spec; |
3386 | 3386 | ||
3387 | if (power_state != AC_PWRST_D3 || nid != spec->mute_led_nid) | 3387 | if (power_state != AC_PWRST_D3 || nid != spec->mute_led_nid) |
3388 | return power_state; | 3388 | return power_state; |
3389 | 3389 | ||
3390 | /* Set pin ctl again, it might have just been set to 0 */ | 3390 | /* Set pin ctl again, it might have just been set to 0 */ |
3391 | snd_hda_set_pin_ctl(codec, nid, | 3391 | snd_hda_set_pin_ctl(codec, nid, |
3392 | snd_hda_codec_get_pin_target(codec, nid)); | 3392 | snd_hda_codec_get_pin_target(codec, nid)); |
3393 | 3393 | ||
3394 | return AC_PWRST_D0; | 3394 | return AC_PWRST_D0; |
3395 | } | 3395 | } |
3396 | 3396 | ||
3397 | static void alc269_fixup_hp_mute_led(struct hda_codec *codec, | 3397 | static void alc269_fixup_hp_mute_led(struct hda_codec *codec, |
3398 | const struct hda_fixup *fix, int action) | 3398 | const struct hda_fixup *fix, int action) |
3399 | { | 3399 | { |
3400 | struct alc_spec *spec = codec->spec; | 3400 | struct alc_spec *spec = codec->spec; |
3401 | const struct dmi_device *dev = NULL; | 3401 | const struct dmi_device *dev = NULL; |
3402 | 3402 | ||
3403 | if (action != HDA_FIXUP_ACT_PRE_PROBE) | 3403 | if (action != HDA_FIXUP_ACT_PRE_PROBE) |
3404 | return; | 3404 | return; |
3405 | 3405 | ||
3406 | while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) { | 3406 | while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) { |
3407 | int pol, pin; | 3407 | int pol, pin; |
3408 | if (sscanf(dev->name, "HP_Mute_LED_%d_%x", &pol, &pin) != 2) | 3408 | if (sscanf(dev->name, "HP_Mute_LED_%d_%x", &pol, &pin) != 2) |
3409 | continue; | 3409 | continue; |
3410 | if (pin < 0x0a || pin >= 0x10) | 3410 | if (pin < 0x0a || pin >= 0x10) |
3411 | break; | 3411 | break; |
3412 | spec->mute_led_polarity = pol; | 3412 | spec->mute_led_polarity = pol; |
3413 | spec->mute_led_nid = pin - 0x0a + 0x18; | 3413 | spec->mute_led_nid = pin - 0x0a + 0x18; |
3414 | spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook; | 3414 | spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook; |
3415 | spec->gen.vmaster_mute_enum = 1; | 3415 | spec->gen.vmaster_mute_enum = 1; |
3416 | codec->power_filter = led_power_filter; | 3416 | codec->power_filter = led_power_filter; |
3417 | codec_dbg(codec, | 3417 | codec_dbg(codec, |
3418 | "Detected mute LED for %x:%d\n", spec->mute_led_nid, | 3418 | "Detected mute LED for %x:%d\n", spec->mute_led_nid, |
3419 | spec->mute_led_polarity); | 3419 | spec->mute_led_polarity); |
3420 | break; | 3420 | break; |
3421 | } | 3421 | } |
3422 | } | 3422 | } |
3423 | 3423 | ||
3424 | static void alc269_fixup_hp_mute_led_mic1(struct hda_codec *codec, | 3424 | static void alc269_fixup_hp_mute_led_mic1(struct hda_codec *codec, |
3425 | const struct hda_fixup *fix, int action) | 3425 | const struct hda_fixup *fix, int action) |
3426 | { | 3426 | { |
3427 | struct alc_spec *spec = codec->spec; | 3427 | struct alc_spec *spec = codec->spec; |
3428 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | 3428 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
3429 | spec->mute_led_polarity = 0; | 3429 | spec->mute_led_polarity = 0; |
3430 | spec->mute_led_nid = 0x18; | 3430 | spec->mute_led_nid = 0x18; |
3431 | spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook; | 3431 | spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook; |
3432 | spec->gen.vmaster_mute_enum = 1; | 3432 | spec->gen.vmaster_mute_enum = 1; |
3433 | codec->power_filter = led_power_filter; | 3433 | codec->power_filter = led_power_filter; |
3434 | } | 3434 | } |
3435 | } | 3435 | } |
3436 | 3436 | ||
3437 | static void alc269_fixup_hp_mute_led_mic2(struct hda_codec *codec, | 3437 | static void alc269_fixup_hp_mute_led_mic2(struct hda_codec *codec, |
3438 | const struct hda_fixup *fix, int action) | 3438 | const struct hda_fixup *fix, int action) |
3439 | { | 3439 | { |
3440 | struct alc_spec *spec = codec->spec; | 3440 | struct alc_spec *spec = codec->spec; |
3441 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | 3441 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
3442 | spec->mute_led_polarity = 0; | 3442 | spec->mute_led_polarity = 0; |
3443 | spec->mute_led_nid = 0x19; | 3443 | spec->mute_led_nid = 0x19; |
3444 | spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook; | 3444 | spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook; |
3445 | spec->gen.vmaster_mute_enum = 1; | 3445 | spec->gen.vmaster_mute_enum = 1; |
3446 | codec->power_filter = led_power_filter; | 3446 | codec->power_filter = led_power_filter; |
3447 | } | 3447 | } |
3448 | } | 3448 | } |
3449 | 3449 | ||
3450 | /* turn on/off mute LED per vmaster hook */ | 3450 | /* turn on/off mute LED per vmaster hook */ |
3451 | static void alc269_fixup_hp_gpio_mute_hook(void *private_data, int enabled) | 3451 | static void alc269_fixup_hp_gpio_mute_hook(void *private_data, int enabled) |
3452 | { | 3452 | { |
3453 | struct hda_codec *codec = private_data; | 3453 | struct hda_codec *codec = private_data; |
3454 | struct alc_spec *spec = codec->spec; | 3454 | struct alc_spec *spec = codec->spec; |
3455 | unsigned int oldval = spec->gpio_led; | 3455 | unsigned int oldval = spec->gpio_led; |
3456 | 3456 | ||
3457 | if (enabled) | 3457 | if (enabled) |
3458 | spec->gpio_led &= ~0x08; | 3458 | spec->gpio_led &= ~0x08; |
3459 | else | 3459 | else |
3460 | spec->gpio_led |= 0x08; | 3460 | spec->gpio_led |= 0x08; |
3461 | if (spec->gpio_led != oldval) | 3461 | if (spec->gpio_led != oldval) |
3462 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, | 3462 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, |
3463 | spec->gpio_led); | 3463 | spec->gpio_led); |
3464 | } | 3464 | } |
3465 | 3465 | ||
3466 | /* turn on/off mic-mute LED per capture hook */ | 3466 | /* turn on/off mic-mute LED per capture hook */ |
3467 | static void alc269_fixup_hp_gpio_mic_mute_hook(struct hda_codec *codec, | 3467 | static void alc269_fixup_hp_gpio_mic_mute_hook(struct hda_codec *codec, |
3468 | struct snd_kcontrol *kcontrol, | 3468 | struct snd_kcontrol *kcontrol, |
3469 | struct snd_ctl_elem_value *ucontrol) | 3469 | struct snd_ctl_elem_value *ucontrol) |
3470 | { | 3470 | { |
3471 | struct alc_spec *spec = codec->spec; | 3471 | struct alc_spec *spec = codec->spec; |
3472 | unsigned int oldval = spec->gpio_led; | 3472 | unsigned int oldval = spec->gpio_led; |
3473 | 3473 | ||
3474 | if (!ucontrol) | 3474 | if (!ucontrol) |
3475 | return; | 3475 | return; |
3476 | 3476 | ||
3477 | if (ucontrol->value.integer.value[0] || | 3477 | if (ucontrol->value.integer.value[0] || |
3478 | ucontrol->value.integer.value[1]) | 3478 | ucontrol->value.integer.value[1]) |
3479 | spec->gpio_led &= ~0x10; | 3479 | spec->gpio_led &= ~0x10; |
3480 | else | 3480 | else |
3481 | spec->gpio_led |= 0x10; | 3481 | spec->gpio_led |= 0x10; |
3482 | if (spec->gpio_led != oldval) | 3482 | if (spec->gpio_led != oldval) |
3483 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, | 3483 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, |
3484 | spec->gpio_led); | 3484 | spec->gpio_led); |
3485 | } | 3485 | } |
3486 | 3486 | ||
3487 | static void alc269_fixup_hp_gpio_led(struct hda_codec *codec, | 3487 | static void alc269_fixup_hp_gpio_led(struct hda_codec *codec, |
3488 | const struct hda_fixup *fix, int action) | 3488 | const struct hda_fixup *fix, int action) |
3489 | { | 3489 | { |
3490 | struct alc_spec *spec = codec->spec; | 3490 | struct alc_spec *spec = codec->spec; |
3491 | static const struct hda_verb gpio_init[] = { | 3491 | static const struct hda_verb gpio_init[] = { |
3492 | { 0x01, AC_VERB_SET_GPIO_MASK, 0x18 }, | 3492 | { 0x01, AC_VERB_SET_GPIO_MASK, 0x18 }, |
3493 | { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x18 }, | 3493 | { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x18 }, |
3494 | {} | 3494 | {} |
3495 | }; | 3495 | }; |
3496 | 3496 | ||
3497 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | 3497 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
3498 | spec->gen.vmaster_mute.hook = alc269_fixup_hp_gpio_mute_hook; | 3498 | spec->gen.vmaster_mute.hook = alc269_fixup_hp_gpio_mute_hook; |
3499 | spec->gen.cap_sync_hook = alc269_fixup_hp_gpio_mic_mute_hook; | 3499 | spec->gen.cap_sync_hook = alc269_fixup_hp_gpio_mic_mute_hook; |
3500 | spec->gpio_led = 0; | 3500 | spec->gpio_led = 0; |
3501 | snd_hda_add_verbs(codec, gpio_init); | 3501 | snd_hda_add_verbs(codec, gpio_init); |
3502 | } | 3502 | } |
3503 | } | 3503 | } |
3504 | 3504 | ||
3505 | static void alc_headset_mode_unplugged(struct hda_codec *codec) | 3505 | static void alc_headset_mode_unplugged(struct hda_codec *codec) |
3506 | { | 3506 | { |
3507 | int val; | 3507 | int val; |
3508 | 3508 | ||
3509 | switch (codec->vendor_id) { | 3509 | switch (codec->vendor_id) { |
3510 | case 0x10ec0255: | 3510 | case 0x10ec0255: |
3511 | /* LDO and MISC control */ | 3511 | /* LDO and MISC control */ |
3512 | alc_write_coef_idx(codec, 0x1b, 0x0c0b); | 3512 | alc_write_coef_idx(codec, 0x1b, 0x0c0b); |
3513 | /* UAJ function set to menual mode */ | 3513 | /* UAJ function set to menual mode */ |
3514 | alc_write_coef_idx(codec, 0x45, 0xd089); | 3514 | alc_write_coef_idx(codec, 0x45, 0xd089); |
3515 | /* Direct Drive HP Amp control(Set to verb control)*/ | 3515 | /* Direct Drive HP Amp control(Set to verb control)*/ |
3516 | val = alc_read_coefex_idx(codec, 0x57, 0x05); | 3516 | val = alc_read_coefex_idx(codec, 0x57, 0x05); |
3517 | alc_write_coefex_idx(codec, 0x57, 0x05, val & ~(1<<14)); | 3517 | alc_write_coefex_idx(codec, 0x57, 0x05, val & ~(1<<14)); |
3518 | /* Set MIC2 Vref gate with HP */ | 3518 | /* Set MIC2 Vref gate with HP */ |
3519 | alc_write_coef_idx(codec, 0x06, 0x6104); | 3519 | alc_write_coef_idx(codec, 0x06, 0x6104); |
3520 | /* Direct Drive HP Amp control */ | 3520 | /* Direct Drive HP Amp control */ |
3521 | alc_write_coefex_idx(codec, 0x57, 0x03, 0x8aa6); | 3521 | alc_write_coefex_idx(codec, 0x57, 0x03, 0x8aa6); |
3522 | break; | 3522 | break; |
3523 | case 0x10ec0283: | 3523 | case 0x10ec0283: |
3524 | alc_write_coef_idx(codec, 0x1b, 0x0c0b); | 3524 | alc_write_coef_idx(codec, 0x1b, 0x0c0b); |
3525 | alc_write_coef_idx(codec, 0x45, 0xc429); | 3525 | alc_write_coef_idx(codec, 0x45, 0xc429); |
3526 | val = alc_read_coef_idx(codec, 0x35); | 3526 | val = alc_read_coef_idx(codec, 0x35); |
3527 | alc_write_coef_idx(codec, 0x35, val & 0xbfff); | 3527 | alc_write_coef_idx(codec, 0x35, val & 0xbfff); |
3528 | alc_write_coef_idx(codec, 0x06, 0x2104); | 3528 | alc_write_coef_idx(codec, 0x06, 0x2104); |
3529 | alc_write_coef_idx(codec, 0x1a, 0x0001); | 3529 | alc_write_coef_idx(codec, 0x1a, 0x0001); |
3530 | alc_write_coef_idx(codec, 0x26, 0x0004); | 3530 | alc_write_coef_idx(codec, 0x26, 0x0004); |
3531 | alc_write_coef_idx(codec, 0x32, 0x42a3); | 3531 | alc_write_coef_idx(codec, 0x32, 0x42a3); |
3532 | break; | 3532 | break; |
3533 | case 0x10ec0292: | 3533 | case 0x10ec0292: |
3534 | alc_write_coef_idx(codec, 0x76, 0x000e); | 3534 | alc_write_coef_idx(codec, 0x76, 0x000e); |
3535 | alc_write_coef_idx(codec, 0x6c, 0x2400); | 3535 | alc_write_coef_idx(codec, 0x6c, 0x2400); |
3536 | alc_write_coef_idx(codec, 0x18, 0x7308); | 3536 | alc_write_coef_idx(codec, 0x18, 0x7308); |
3537 | alc_write_coef_idx(codec, 0x6b, 0xc429); | 3537 | alc_write_coef_idx(codec, 0x6b, 0xc429); |
3538 | break; | 3538 | break; |
3539 | case 0x10ec0668: | 3539 | case 0x10ec0668: |
3540 | alc_write_coef_idx(codec, 0x15, 0x0d40); | 3540 | alc_write_coef_idx(codec, 0x15, 0x0d40); |
3541 | alc_write_coef_idx(codec, 0xb7, 0x802b); | 3541 | alc_write_coef_idx(codec, 0xb7, 0x802b); |
3542 | break; | 3542 | break; |
3543 | } | 3543 | } |
3544 | codec_dbg(codec, "Headset jack set to unplugged mode.\n"); | 3544 | codec_dbg(codec, "Headset jack set to unplugged mode.\n"); |
3545 | } | 3545 | } |
3546 | 3546 | ||
3547 | 3547 | ||
3548 | static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin, | 3548 | static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin, |
3549 | hda_nid_t mic_pin) | 3549 | hda_nid_t mic_pin) |
3550 | { | 3550 | { |
3551 | int val; | 3551 | int val; |
3552 | 3552 | ||
3553 | switch (codec->vendor_id) { | 3553 | switch (codec->vendor_id) { |
3554 | case 0x10ec0255: | 3554 | case 0x10ec0255: |
3555 | alc_write_coef_idx(codec, 0x45, 0xc489); | 3555 | alc_write_coef_idx(codec, 0x45, 0xc489); |
3556 | snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); | 3556 | snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); |
3557 | alc_write_coefex_idx(codec, 0x57, 0x03, 0x8aa6); | 3557 | alc_write_coefex_idx(codec, 0x57, 0x03, 0x8aa6); |
3558 | /* Set MIC2 Vref gate to normal */ | 3558 | /* Set MIC2 Vref gate to normal */ |
3559 | alc_write_coef_idx(codec, 0x06, 0x6100); | 3559 | alc_write_coef_idx(codec, 0x06, 0x6100); |
3560 | snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); | 3560 | snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); |
3561 | break; | 3561 | break; |
3562 | case 0x10ec0283: | 3562 | case 0x10ec0283: |
3563 | alc_write_coef_idx(codec, 0x45, 0xc429); | 3563 | alc_write_coef_idx(codec, 0x45, 0xc429); |
3564 | snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); | 3564 | snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); |
3565 | val = alc_read_coef_idx(codec, 0x35); | 3565 | val = alc_read_coef_idx(codec, 0x35); |
3566 | alc_write_coef_idx(codec, 0x35, val | 1<<14); | 3566 | alc_write_coef_idx(codec, 0x35, val | 1<<14); |
3567 | alc_write_coef_idx(codec, 0x06, 0x2100); | 3567 | alc_write_coef_idx(codec, 0x06, 0x2100); |
3568 | alc_write_coef_idx(codec, 0x1a, 0x0021); | 3568 | alc_write_coef_idx(codec, 0x1a, 0x0021); |
3569 | alc_write_coef_idx(codec, 0x26, 0x008c); | 3569 | alc_write_coef_idx(codec, 0x26, 0x008c); |
3570 | snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); | 3570 | snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); |
3571 | break; | 3571 | break; |
3572 | case 0x10ec0292: | 3572 | case 0x10ec0292: |
3573 | snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); | 3573 | snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); |
3574 | alc_write_coef_idx(codec, 0x19, 0xa208); | 3574 | alc_write_coef_idx(codec, 0x19, 0xa208); |
3575 | alc_write_coef_idx(codec, 0x2e, 0xacf0); | 3575 | alc_write_coef_idx(codec, 0x2e, 0xacf0); |
3576 | break; | 3576 | break; |
3577 | case 0x10ec0668: | 3577 | case 0x10ec0668: |
3578 | alc_write_coef_idx(codec, 0x11, 0x0001); | 3578 | alc_write_coef_idx(codec, 0x11, 0x0001); |
3579 | snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); | 3579 | snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); |
3580 | alc_write_coef_idx(codec, 0xb7, 0x802b); | 3580 | alc_write_coef_idx(codec, 0xb7, 0x802b); |
3581 | alc_write_coef_idx(codec, 0xb5, 0x1040); | 3581 | alc_write_coef_idx(codec, 0xb5, 0x1040); |
3582 | val = alc_read_coef_idx(codec, 0xc3); | 3582 | val = alc_read_coef_idx(codec, 0xc3); |
3583 | alc_write_coef_idx(codec, 0xc3, val | 1<<12); | 3583 | alc_write_coef_idx(codec, 0xc3, val | 1<<12); |
3584 | snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); | 3584 | snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); |
3585 | break; | 3585 | break; |
3586 | } | 3586 | } |
3587 | codec_dbg(codec, "Headset jack set to mic-in mode.\n"); | 3587 | codec_dbg(codec, "Headset jack set to mic-in mode.\n"); |
3588 | } | 3588 | } |
3589 | 3589 | ||
3590 | static void alc_headset_mode_default(struct hda_codec *codec) | 3590 | static void alc_headset_mode_default(struct hda_codec *codec) |
3591 | { | 3591 | { |
3592 | switch (codec->vendor_id) { | 3592 | switch (codec->vendor_id) { |
3593 | case 0x10ec0255: | 3593 | case 0x10ec0255: |
3594 | alc_write_coef_idx(codec, 0x45, 0xc089); | 3594 | alc_write_coef_idx(codec, 0x45, 0xc089); |
3595 | alc_write_coef_idx(codec, 0x45, 0xc489); | 3595 | alc_write_coef_idx(codec, 0x45, 0xc489); |
3596 | alc_write_coefex_idx(codec, 0x57, 0x03, 0x8ea6); | 3596 | alc_write_coefex_idx(codec, 0x57, 0x03, 0x8ea6); |
3597 | alc_write_coef_idx(codec, 0x49, 0x0049); | 3597 | alc_write_coef_idx(codec, 0x49, 0x0049); |
3598 | break; | 3598 | break; |
3599 | case 0x10ec0283: | 3599 | case 0x10ec0283: |
3600 | alc_write_coef_idx(codec, 0x06, 0x2100); | 3600 | alc_write_coef_idx(codec, 0x06, 0x2100); |
3601 | alc_write_coef_idx(codec, 0x32, 0x4ea3); | 3601 | alc_write_coef_idx(codec, 0x32, 0x4ea3); |
3602 | break; | 3602 | break; |
3603 | case 0x10ec0292: | 3603 | case 0x10ec0292: |
3604 | alc_write_coef_idx(codec, 0x76, 0x000e); | 3604 | alc_write_coef_idx(codec, 0x76, 0x000e); |
3605 | alc_write_coef_idx(codec, 0x6c, 0x2400); | 3605 | alc_write_coef_idx(codec, 0x6c, 0x2400); |
3606 | alc_write_coef_idx(codec, 0x6b, 0xc429); | 3606 | alc_write_coef_idx(codec, 0x6b, 0xc429); |
3607 | alc_write_coef_idx(codec, 0x18, 0x7308); | 3607 | alc_write_coef_idx(codec, 0x18, 0x7308); |
3608 | break; | 3608 | break; |
3609 | case 0x10ec0668: | 3609 | case 0x10ec0668: |
3610 | alc_write_coef_idx(codec, 0x11, 0x0041); | 3610 | alc_write_coef_idx(codec, 0x11, 0x0041); |
3611 | alc_write_coef_idx(codec, 0x15, 0x0d40); | 3611 | alc_write_coef_idx(codec, 0x15, 0x0d40); |
3612 | alc_write_coef_idx(codec, 0xb7, 0x802b); | 3612 | alc_write_coef_idx(codec, 0xb7, 0x802b); |
3613 | break; | 3613 | break; |
3614 | } | 3614 | } |
3615 | codec_dbg(codec, "Headset jack set to headphone (default) mode.\n"); | 3615 | codec_dbg(codec, "Headset jack set to headphone (default) mode.\n"); |
3616 | } | 3616 | } |
3617 | 3617 | ||
3618 | /* Iphone type */ | 3618 | /* Iphone type */ |
3619 | static void alc_headset_mode_ctia(struct hda_codec *codec) | 3619 | static void alc_headset_mode_ctia(struct hda_codec *codec) |
3620 | { | 3620 | { |
3621 | switch (codec->vendor_id) { | 3621 | switch (codec->vendor_id) { |
3622 | case 0x10ec0255: | 3622 | case 0x10ec0255: |
3623 | /* Set to CTIA type */ | 3623 | /* Set to CTIA type */ |
3624 | alc_write_coef_idx(codec, 0x45, 0xd489); | 3624 | alc_write_coef_idx(codec, 0x45, 0xd489); |
3625 | alc_write_coef_idx(codec, 0x1b, 0x0c2b); | 3625 | alc_write_coef_idx(codec, 0x1b, 0x0c2b); |
3626 | alc_write_coefex_idx(codec, 0x57, 0x03, 0x8ea6); | 3626 | alc_write_coefex_idx(codec, 0x57, 0x03, 0x8ea6); |
3627 | break; | 3627 | break; |
3628 | case 0x10ec0283: | 3628 | case 0x10ec0283: |
3629 | alc_write_coef_idx(codec, 0x45, 0xd429); | 3629 | alc_write_coef_idx(codec, 0x45, 0xd429); |
3630 | alc_write_coef_idx(codec, 0x1b, 0x0c2b); | 3630 | alc_write_coef_idx(codec, 0x1b, 0x0c2b); |
3631 | alc_write_coef_idx(codec, 0x32, 0x4ea3); | 3631 | alc_write_coef_idx(codec, 0x32, 0x4ea3); |
3632 | break; | 3632 | break; |
3633 | case 0x10ec0292: | 3633 | case 0x10ec0292: |
3634 | alc_write_coef_idx(codec, 0x6b, 0xd429); | 3634 | alc_write_coef_idx(codec, 0x6b, 0xd429); |
3635 | alc_write_coef_idx(codec, 0x76, 0x0008); | 3635 | alc_write_coef_idx(codec, 0x76, 0x0008); |
3636 | alc_write_coef_idx(codec, 0x18, 0x7388); | 3636 | alc_write_coef_idx(codec, 0x18, 0x7388); |
3637 | break; | 3637 | break; |
3638 | case 0x10ec0668: | 3638 | case 0x10ec0668: |
3639 | alc_write_coef_idx(codec, 0x11, 0x0001); | 3639 | alc_write_coef_idx(codec, 0x11, 0x0001); |
3640 | alc_write_coef_idx(codec, 0x15, 0x0d60); | 3640 | alc_write_coef_idx(codec, 0x15, 0x0d60); |
3641 | alc_write_coef_idx(codec, 0xc3, 0x0000); | 3641 | alc_write_coef_idx(codec, 0xc3, 0x0000); |
3642 | break; | 3642 | break; |
3643 | } | 3643 | } |
3644 | codec_dbg(codec, "Headset jack set to iPhone-style headset mode.\n"); | 3644 | codec_dbg(codec, "Headset jack set to iPhone-style headset mode.\n"); |
3645 | } | 3645 | } |
3646 | 3646 | ||
3647 | /* Nokia type */ | 3647 | /* Nokia type */ |
3648 | static void alc_headset_mode_omtp(struct hda_codec *codec) | 3648 | static void alc_headset_mode_omtp(struct hda_codec *codec) |
3649 | { | 3649 | { |
3650 | switch (codec->vendor_id) { | 3650 | switch (codec->vendor_id) { |
3651 | case 0x10ec0255: | 3651 | case 0x10ec0255: |
3652 | /* Set to OMTP Type */ | 3652 | /* Set to OMTP Type */ |
3653 | alc_write_coef_idx(codec, 0x45, 0xe489); | 3653 | alc_write_coef_idx(codec, 0x45, 0xe489); |
3654 | alc_write_coef_idx(codec, 0x1b, 0x0c2b); | 3654 | alc_write_coef_idx(codec, 0x1b, 0x0c2b); |
3655 | alc_write_coefex_idx(codec, 0x57, 0x03, 0x8ea6); | 3655 | alc_write_coefex_idx(codec, 0x57, 0x03, 0x8ea6); |
3656 | break; | 3656 | break; |
3657 | case 0x10ec0283: | 3657 | case 0x10ec0283: |
3658 | alc_write_coef_idx(codec, 0x45, 0xe429); | 3658 | alc_write_coef_idx(codec, 0x45, 0xe429); |
3659 | alc_write_coef_idx(codec, 0x1b, 0x0c2b); | 3659 | alc_write_coef_idx(codec, 0x1b, 0x0c2b); |
3660 | alc_write_coef_idx(codec, 0x32, 0x4ea3); | 3660 | alc_write_coef_idx(codec, 0x32, 0x4ea3); |
3661 | break; | 3661 | break; |
3662 | case 0x10ec0292: | 3662 | case 0x10ec0292: |
3663 | alc_write_coef_idx(codec, 0x6b, 0xe429); | 3663 | alc_write_coef_idx(codec, 0x6b, 0xe429); |
3664 | alc_write_coef_idx(codec, 0x76, 0x0008); | 3664 | alc_write_coef_idx(codec, 0x76, 0x0008); |
3665 | alc_write_coef_idx(codec, 0x18, 0x7388); | 3665 | alc_write_coef_idx(codec, 0x18, 0x7388); |
3666 | break; | 3666 | break; |
3667 | case 0x10ec0668: | 3667 | case 0x10ec0668: |
3668 | alc_write_coef_idx(codec, 0x11, 0x0001); | 3668 | alc_write_coef_idx(codec, 0x11, 0x0001); |
3669 | alc_write_coef_idx(codec, 0x15, 0x0d50); | 3669 | alc_write_coef_idx(codec, 0x15, 0x0d50); |
3670 | alc_write_coef_idx(codec, 0xc3, 0x0000); | 3670 | alc_write_coef_idx(codec, 0xc3, 0x0000); |
3671 | break; | 3671 | break; |
3672 | } | 3672 | } |
3673 | codec_dbg(codec, "Headset jack set to Nokia-style headset mode.\n"); | 3673 | codec_dbg(codec, "Headset jack set to Nokia-style headset mode.\n"); |
3674 | } | 3674 | } |
3675 | 3675 | ||
3676 | static void alc_determine_headset_type(struct hda_codec *codec) | 3676 | static void alc_determine_headset_type(struct hda_codec *codec) |
3677 | { | 3677 | { |
3678 | int val; | 3678 | int val; |
3679 | bool is_ctia = false; | 3679 | bool is_ctia = false; |
3680 | struct alc_spec *spec = codec->spec; | 3680 | struct alc_spec *spec = codec->spec; |
3681 | 3681 | ||
3682 | switch (codec->vendor_id) { | 3682 | switch (codec->vendor_id) { |
3683 | case 0x10ec0255: | 3683 | case 0x10ec0255: |
3684 | /* combo jack auto switch control(Check type)*/ | 3684 | /* combo jack auto switch control(Check type)*/ |
3685 | alc_write_coef_idx(codec, 0x45, 0xd089); | 3685 | alc_write_coef_idx(codec, 0x45, 0xd089); |
3686 | /* combo jack auto switch control(Vref conteol) */ | 3686 | /* combo jack auto switch control(Vref conteol) */ |
3687 | alc_write_coef_idx(codec, 0x49, 0x0149); | 3687 | alc_write_coef_idx(codec, 0x49, 0x0149); |
3688 | msleep(300); | 3688 | msleep(300); |
3689 | val = alc_read_coef_idx(codec, 0x46); | 3689 | val = alc_read_coef_idx(codec, 0x46); |
3690 | is_ctia = (val & 0x0070) == 0x0070; | 3690 | is_ctia = (val & 0x0070) == 0x0070; |
3691 | break; | 3691 | break; |
3692 | case 0x10ec0283: | 3692 | case 0x10ec0283: |
3693 | alc_write_coef_idx(codec, 0x45, 0xd029); | 3693 | alc_write_coef_idx(codec, 0x45, 0xd029); |
3694 | msleep(300); | 3694 | msleep(300); |
3695 | val = alc_read_coef_idx(codec, 0x46); | 3695 | val = alc_read_coef_idx(codec, 0x46); |
3696 | is_ctia = (val & 0x0070) == 0x0070; | 3696 | is_ctia = (val & 0x0070) == 0x0070; |
3697 | break; | 3697 | break; |
3698 | case 0x10ec0292: | 3698 | case 0x10ec0292: |
3699 | alc_write_coef_idx(codec, 0x6b, 0xd429); | 3699 | alc_write_coef_idx(codec, 0x6b, 0xd429); |
3700 | msleep(300); | 3700 | msleep(300); |
3701 | val = alc_read_coef_idx(codec, 0x6c); | 3701 | val = alc_read_coef_idx(codec, 0x6c); |
3702 | is_ctia = (val & 0x001c) == 0x001c; | 3702 | is_ctia = (val & 0x001c) == 0x001c; |
3703 | break; | 3703 | break; |
3704 | case 0x10ec0668: | 3704 | case 0x10ec0668: |
3705 | alc_write_coef_idx(codec, 0x11, 0x0001); | 3705 | alc_write_coef_idx(codec, 0x11, 0x0001); |
3706 | alc_write_coef_idx(codec, 0xb7, 0x802b); | 3706 | alc_write_coef_idx(codec, 0xb7, 0x802b); |
3707 | alc_write_coef_idx(codec, 0x15, 0x0d60); | 3707 | alc_write_coef_idx(codec, 0x15, 0x0d60); |
3708 | alc_write_coef_idx(codec, 0xc3, 0x0c00); | 3708 | alc_write_coef_idx(codec, 0xc3, 0x0c00); |
3709 | msleep(300); | 3709 | msleep(300); |
3710 | val = alc_read_coef_idx(codec, 0xbe); | 3710 | val = alc_read_coef_idx(codec, 0xbe); |
3711 | is_ctia = (val & 0x1c02) == 0x1c02; | 3711 | is_ctia = (val & 0x1c02) == 0x1c02; |
3712 | break; | 3712 | break; |
3713 | } | 3713 | } |
3714 | 3714 | ||
3715 | codec_dbg(codec, "Headset jack detected iPhone-style headset: %s\n", | 3715 | codec_dbg(codec, "Headset jack detected iPhone-style headset: %s\n", |
3716 | is_ctia ? "yes" : "no"); | 3716 | is_ctia ? "yes" : "no"); |
3717 | spec->current_headset_type = is_ctia ? ALC_HEADSET_TYPE_CTIA : ALC_HEADSET_TYPE_OMTP; | 3717 | spec->current_headset_type = is_ctia ? ALC_HEADSET_TYPE_CTIA : ALC_HEADSET_TYPE_OMTP; |
3718 | } | 3718 | } |
3719 | 3719 | ||
3720 | static void alc_update_headset_mode(struct hda_codec *codec) | 3720 | static void alc_update_headset_mode(struct hda_codec *codec) |
3721 | { | 3721 | { |
3722 | struct alc_spec *spec = codec->spec; | 3722 | struct alc_spec *spec = codec->spec; |
3723 | 3723 | ||
3724 | hda_nid_t mux_pin = spec->gen.imux_pins[spec->gen.cur_mux[0]]; | 3724 | hda_nid_t mux_pin = spec->gen.imux_pins[spec->gen.cur_mux[0]]; |
3725 | hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; | 3725 | hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; |
3726 | 3726 | ||
3727 | int new_headset_mode; | 3727 | int new_headset_mode; |
3728 | 3728 | ||
3729 | if (!snd_hda_jack_detect(codec, hp_pin)) | 3729 | if (!snd_hda_jack_detect(codec, hp_pin)) |
3730 | new_headset_mode = ALC_HEADSET_MODE_UNPLUGGED; | 3730 | new_headset_mode = ALC_HEADSET_MODE_UNPLUGGED; |
3731 | else if (mux_pin == spec->headset_mic_pin) | 3731 | else if (mux_pin == spec->headset_mic_pin) |
3732 | new_headset_mode = ALC_HEADSET_MODE_HEADSET; | 3732 | new_headset_mode = ALC_HEADSET_MODE_HEADSET; |
3733 | else if (mux_pin == spec->headphone_mic_pin) | 3733 | else if (mux_pin == spec->headphone_mic_pin) |
3734 | new_headset_mode = ALC_HEADSET_MODE_MIC; | 3734 | new_headset_mode = ALC_HEADSET_MODE_MIC; |
3735 | else | 3735 | else |
3736 | new_headset_mode = ALC_HEADSET_MODE_HEADPHONE; | 3736 | new_headset_mode = ALC_HEADSET_MODE_HEADPHONE; |
3737 | 3737 | ||
3738 | if (new_headset_mode == spec->current_headset_mode) { | 3738 | if (new_headset_mode == spec->current_headset_mode) { |
3739 | snd_hda_gen_update_outputs(codec); | 3739 | snd_hda_gen_update_outputs(codec); |
3740 | return; | 3740 | return; |
3741 | } | 3741 | } |
3742 | 3742 | ||
3743 | switch (new_headset_mode) { | 3743 | switch (new_headset_mode) { |
3744 | case ALC_HEADSET_MODE_UNPLUGGED: | 3744 | case ALC_HEADSET_MODE_UNPLUGGED: |
3745 | alc_headset_mode_unplugged(codec); | 3745 | alc_headset_mode_unplugged(codec); |
3746 | spec->gen.hp_jack_present = false; | 3746 | spec->gen.hp_jack_present = false; |
3747 | break; | 3747 | break; |
3748 | case ALC_HEADSET_MODE_HEADSET: | 3748 | case ALC_HEADSET_MODE_HEADSET: |
3749 | if (spec->current_headset_type == ALC_HEADSET_TYPE_UNKNOWN) | 3749 | if (spec->current_headset_type == ALC_HEADSET_TYPE_UNKNOWN) |
3750 | alc_determine_headset_type(codec); | 3750 | alc_determine_headset_type(codec); |
3751 | if (spec->current_headset_type == ALC_HEADSET_TYPE_CTIA) | 3751 | if (spec->current_headset_type == ALC_HEADSET_TYPE_CTIA) |
3752 | alc_headset_mode_ctia(codec); | 3752 | alc_headset_mode_ctia(codec); |
3753 | else if (spec->current_headset_type == ALC_HEADSET_TYPE_OMTP) | 3753 | else if (spec->current_headset_type == ALC_HEADSET_TYPE_OMTP) |
3754 | alc_headset_mode_omtp(codec); | 3754 | alc_headset_mode_omtp(codec); |
3755 | spec->gen.hp_jack_present = true; | 3755 | spec->gen.hp_jack_present = true; |
3756 | break; | 3756 | break; |
3757 | case ALC_HEADSET_MODE_MIC: | 3757 | case ALC_HEADSET_MODE_MIC: |
3758 | alc_headset_mode_mic_in(codec, hp_pin, spec->headphone_mic_pin); | 3758 | alc_headset_mode_mic_in(codec, hp_pin, spec->headphone_mic_pin); |
3759 | spec->gen.hp_jack_present = false; | 3759 | spec->gen.hp_jack_present = false; |
3760 | break; | 3760 | break; |
3761 | case ALC_HEADSET_MODE_HEADPHONE: | 3761 | case ALC_HEADSET_MODE_HEADPHONE: |
3762 | alc_headset_mode_default(codec); | 3762 | alc_headset_mode_default(codec); |
3763 | spec->gen.hp_jack_present = true; | 3763 | spec->gen.hp_jack_present = true; |
3764 | break; | 3764 | break; |
3765 | } | 3765 | } |
3766 | if (new_headset_mode != ALC_HEADSET_MODE_MIC) { | 3766 | if (new_headset_mode != ALC_HEADSET_MODE_MIC) { |
3767 | snd_hda_set_pin_ctl_cache(codec, hp_pin, | 3767 | snd_hda_set_pin_ctl_cache(codec, hp_pin, |
3768 | AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN); | 3768 | AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN); |
3769 | if (spec->headphone_mic_pin) | 3769 | if (spec->headphone_mic_pin) |
3770 | snd_hda_set_pin_ctl_cache(codec, spec->headphone_mic_pin, | 3770 | snd_hda_set_pin_ctl_cache(codec, spec->headphone_mic_pin, |
3771 | PIN_VREFHIZ); | 3771 | PIN_VREFHIZ); |
3772 | } | 3772 | } |
3773 | spec->current_headset_mode = new_headset_mode; | 3773 | spec->current_headset_mode = new_headset_mode; |
3774 | 3774 | ||
3775 | snd_hda_gen_update_outputs(codec); | 3775 | snd_hda_gen_update_outputs(codec); |
3776 | } | 3776 | } |
3777 | 3777 | ||
3778 | static void alc_update_headset_mode_hook(struct hda_codec *codec, | 3778 | static void alc_update_headset_mode_hook(struct hda_codec *codec, |
3779 | struct snd_kcontrol *kcontrol, | 3779 | struct snd_kcontrol *kcontrol, |
3780 | struct snd_ctl_elem_value *ucontrol) | 3780 | struct snd_ctl_elem_value *ucontrol) |
3781 | { | 3781 | { |
3782 | alc_update_headset_mode(codec); | 3782 | alc_update_headset_mode(codec); |
3783 | } | 3783 | } |
3784 | 3784 | ||
3785 | static void alc_update_headset_jack_cb(struct hda_codec *codec, struct hda_jack_tbl *jack) | 3785 | static void alc_update_headset_jack_cb(struct hda_codec *codec, struct hda_jack_tbl *jack) |
3786 | { | 3786 | { |
3787 | struct alc_spec *spec = codec->spec; | 3787 | struct alc_spec *spec = codec->spec; |
3788 | spec->current_headset_type = ALC_HEADSET_TYPE_UNKNOWN; | 3788 | spec->current_headset_type = ALC_HEADSET_TYPE_UNKNOWN; |
3789 | snd_hda_gen_hp_automute(codec, jack); | 3789 | snd_hda_gen_hp_automute(codec, jack); |
3790 | } | 3790 | } |
3791 | 3791 | ||
3792 | static void alc_probe_headset_mode(struct hda_codec *codec) | 3792 | static void alc_probe_headset_mode(struct hda_codec *codec) |
3793 | { | 3793 | { |
3794 | int i; | 3794 | int i; |
3795 | struct alc_spec *spec = codec->spec; | 3795 | struct alc_spec *spec = codec->spec; |
3796 | struct auto_pin_cfg *cfg = &spec->gen.autocfg; | 3796 | struct auto_pin_cfg *cfg = &spec->gen.autocfg; |
3797 | 3797 | ||
3798 | /* Find mic pins */ | 3798 | /* Find mic pins */ |
3799 | for (i = 0; i < cfg->num_inputs; i++) { | 3799 | for (i = 0; i < cfg->num_inputs; i++) { |
3800 | if (cfg->inputs[i].is_headset_mic && !spec->headset_mic_pin) | 3800 | if (cfg->inputs[i].is_headset_mic && !spec->headset_mic_pin) |
3801 | spec->headset_mic_pin = cfg->inputs[i].pin; | 3801 | spec->headset_mic_pin = cfg->inputs[i].pin; |
3802 | if (cfg->inputs[i].is_headphone_mic && !spec->headphone_mic_pin) | 3802 | if (cfg->inputs[i].is_headphone_mic && !spec->headphone_mic_pin) |
3803 | spec->headphone_mic_pin = cfg->inputs[i].pin; | 3803 | spec->headphone_mic_pin = cfg->inputs[i].pin; |
3804 | } | 3804 | } |
3805 | 3805 | ||
3806 | spec->gen.cap_sync_hook = alc_update_headset_mode_hook; | 3806 | spec->gen.cap_sync_hook = alc_update_headset_mode_hook; |
3807 | spec->gen.automute_hook = alc_update_headset_mode; | 3807 | spec->gen.automute_hook = alc_update_headset_mode; |
3808 | spec->gen.hp_automute_hook = alc_update_headset_jack_cb; | 3808 | spec->gen.hp_automute_hook = alc_update_headset_jack_cb; |
3809 | } | 3809 | } |
3810 | 3810 | ||
3811 | static void alc_fixup_headset_mode(struct hda_codec *codec, | 3811 | static void alc_fixup_headset_mode(struct hda_codec *codec, |
3812 | const struct hda_fixup *fix, int action) | 3812 | const struct hda_fixup *fix, int action) |
3813 | { | 3813 | { |
3814 | struct alc_spec *spec = codec->spec; | 3814 | struct alc_spec *spec = codec->spec; |
3815 | 3815 | ||
3816 | switch (action) { | 3816 | switch (action) { |
3817 | case HDA_FIXUP_ACT_PRE_PROBE: | 3817 | case HDA_FIXUP_ACT_PRE_PROBE: |
3818 | spec->parse_flags |= HDA_PINCFG_HEADSET_MIC | HDA_PINCFG_HEADPHONE_MIC; | 3818 | spec->parse_flags |= HDA_PINCFG_HEADSET_MIC | HDA_PINCFG_HEADPHONE_MIC; |
3819 | break; | 3819 | break; |
3820 | case HDA_FIXUP_ACT_PROBE: | 3820 | case HDA_FIXUP_ACT_PROBE: |
3821 | alc_probe_headset_mode(codec); | 3821 | alc_probe_headset_mode(codec); |
3822 | break; | 3822 | break; |
3823 | case HDA_FIXUP_ACT_INIT: | 3823 | case HDA_FIXUP_ACT_INIT: |
3824 | spec->current_headset_mode = 0; | 3824 | spec->current_headset_mode = 0; |
3825 | alc_update_headset_mode(codec); | 3825 | alc_update_headset_mode(codec); |
3826 | break; | 3826 | break; |
3827 | } | 3827 | } |
3828 | } | 3828 | } |
3829 | 3829 | ||
3830 | static void alc_fixup_headset_mode_no_hp_mic(struct hda_codec *codec, | 3830 | static void alc_fixup_headset_mode_no_hp_mic(struct hda_codec *codec, |
3831 | const struct hda_fixup *fix, int action) | 3831 | const struct hda_fixup *fix, int action) |
3832 | { | 3832 | { |
3833 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | 3833 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
3834 | struct alc_spec *spec = codec->spec; | 3834 | struct alc_spec *spec = codec->spec; |
3835 | spec->parse_flags |= HDA_PINCFG_HEADSET_MIC; | 3835 | spec->parse_flags |= HDA_PINCFG_HEADSET_MIC; |
3836 | } | 3836 | } |
3837 | else | 3837 | else |
3838 | alc_fixup_headset_mode(codec, fix, action); | 3838 | alc_fixup_headset_mode(codec, fix, action); |
3839 | } | 3839 | } |
3840 | 3840 | ||
3841 | static void alc255_set_default_jack_type(struct hda_codec *codec) | 3841 | static void alc255_set_default_jack_type(struct hda_codec *codec) |
3842 | { | 3842 | { |
3843 | /* Set to iphone type */ | 3843 | /* Set to iphone type */ |
3844 | alc_write_coef_idx(codec, 0x1b, 0x880b); | 3844 | alc_write_coef_idx(codec, 0x1b, 0x880b); |
3845 | alc_write_coef_idx(codec, 0x45, 0xd089); | 3845 | alc_write_coef_idx(codec, 0x45, 0xd089); |
3846 | alc_write_coef_idx(codec, 0x1b, 0x080b); | 3846 | alc_write_coef_idx(codec, 0x1b, 0x080b); |
3847 | alc_write_coef_idx(codec, 0x46, 0x0004); | 3847 | alc_write_coef_idx(codec, 0x46, 0x0004); |
3848 | alc_write_coef_idx(codec, 0x1b, 0x0c0b); | 3848 | alc_write_coef_idx(codec, 0x1b, 0x0c0b); |
3849 | msleep(30); | 3849 | msleep(30); |
3850 | } | 3850 | } |
3851 | 3851 | ||
3852 | static void alc_fixup_headset_mode_alc255(struct hda_codec *codec, | 3852 | static void alc_fixup_headset_mode_alc255(struct hda_codec *codec, |
3853 | const struct hda_fixup *fix, int action) | 3853 | const struct hda_fixup *fix, int action) |
3854 | { | 3854 | { |
3855 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | 3855 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
3856 | alc255_set_default_jack_type(codec); | 3856 | alc255_set_default_jack_type(codec); |
3857 | } | 3857 | } |
3858 | alc_fixup_headset_mode(codec, fix, action); | 3858 | alc_fixup_headset_mode(codec, fix, action); |
3859 | } | 3859 | } |
3860 | 3860 | ||
3861 | static void alc_fixup_headset_mode_alc255_no_hp_mic(struct hda_codec *codec, | 3861 | static void alc_fixup_headset_mode_alc255_no_hp_mic(struct hda_codec *codec, |
3862 | const struct hda_fixup *fix, int action) | 3862 | const struct hda_fixup *fix, int action) |
3863 | { | 3863 | { |
3864 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | 3864 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
3865 | struct alc_spec *spec = codec->spec; | 3865 | struct alc_spec *spec = codec->spec; |
3866 | spec->parse_flags |= HDA_PINCFG_HEADSET_MIC; | 3866 | spec->parse_flags |= HDA_PINCFG_HEADSET_MIC; |
3867 | alc255_set_default_jack_type(codec); | 3867 | alc255_set_default_jack_type(codec); |
3868 | } | 3868 | } |
3869 | else | 3869 | else |
3870 | alc_fixup_headset_mode(codec, fix, action); | 3870 | alc_fixup_headset_mode(codec, fix, action); |
3871 | } | 3871 | } |
3872 | 3872 | ||
3873 | static void alc_fixup_auto_mute_via_amp(struct hda_codec *codec, | 3873 | static void alc_fixup_auto_mute_via_amp(struct hda_codec *codec, |
3874 | const struct hda_fixup *fix, int action) | 3874 | const struct hda_fixup *fix, int action) |
3875 | { | 3875 | { |
3876 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | 3876 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
3877 | struct alc_spec *spec = codec->spec; | 3877 | struct alc_spec *spec = codec->spec; |
3878 | spec->gen.auto_mute_via_amp = 1; | 3878 | spec->gen.auto_mute_via_amp = 1; |
3879 | } | 3879 | } |
3880 | } | 3880 | } |
3881 | 3881 | ||
3882 | static void alc_no_shutup(struct hda_codec *codec) | 3882 | static void alc_no_shutup(struct hda_codec *codec) |
3883 | { | 3883 | { |
3884 | } | 3884 | } |
3885 | 3885 | ||
3886 | static void alc_fixup_no_shutup(struct hda_codec *codec, | 3886 | static void alc_fixup_no_shutup(struct hda_codec *codec, |
3887 | const struct hda_fixup *fix, int action) | 3887 | const struct hda_fixup *fix, int action) |
3888 | { | 3888 | { |
3889 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | 3889 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
3890 | struct alc_spec *spec = codec->spec; | 3890 | struct alc_spec *spec = codec->spec; |
3891 | spec->shutup = alc_no_shutup; | 3891 | spec->shutup = alc_no_shutup; |
3892 | } | 3892 | } |
3893 | } | 3893 | } |
3894 | 3894 | ||
3895 | static void alc_fixup_headset_mode_alc668(struct hda_codec *codec, | 3895 | static void alc_fixup_headset_mode_alc668(struct hda_codec *codec, |
3896 | const struct hda_fixup *fix, int action) | 3896 | const struct hda_fixup *fix, int action) |
3897 | { | 3897 | { |
3898 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | 3898 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
3899 | int val; | 3899 | int val; |
3900 | alc_write_coef_idx(codec, 0xc4, 0x8000); | 3900 | alc_write_coef_idx(codec, 0xc4, 0x8000); |
3901 | val = alc_read_coef_idx(codec, 0xc2); | 3901 | val = alc_read_coef_idx(codec, 0xc2); |
3902 | alc_write_coef_idx(codec, 0xc2, val & 0xfe); | 3902 | alc_write_coef_idx(codec, 0xc2, val & 0xfe); |
3903 | snd_hda_set_pin_ctl_cache(codec, 0x18, 0); | 3903 | snd_hda_set_pin_ctl_cache(codec, 0x18, 0); |
3904 | } | 3904 | } |
3905 | alc_fixup_headset_mode(codec, fix, action); | 3905 | alc_fixup_headset_mode(codec, fix, action); |
3906 | } | 3906 | } |
3907 | 3907 | ||
3908 | /* Returns the nid of the external mic input pin, or 0 if it cannot be found. */ | 3908 | /* Returns the nid of the external mic input pin, or 0 if it cannot be found. */ |
3909 | static int find_ext_mic_pin(struct hda_codec *codec) | 3909 | static int find_ext_mic_pin(struct hda_codec *codec) |
3910 | { | 3910 | { |
3911 | struct alc_spec *spec = codec->spec; | 3911 | struct alc_spec *spec = codec->spec; |
3912 | struct auto_pin_cfg *cfg = &spec->gen.autocfg; | 3912 | struct auto_pin_cfg *cfg = &spec->gen.autocfg; |
3913 | hda_nid_t nid; | 3913 | hda_nid_t nid; |
3914 | unsigned int defcfg; | 3914 | unsigned int defcfg; |
3915 | int i; | 3915 | int i; |
3916 | 3916 | ||
3917 | for (i = 0; i < cfg->num_inputs; i++) { | 3917 | for (i = 0; i < cfg->num_inputs; i++) { |
3918 | if (cfg->inputs[i].type != AUTO_PIN_MIC) | 3918 | if (cfg->inputs[i].type != AUTO_PIN_MIC) |
3919 | continue; | 3919 | continue; |
3920 | nid = cfg->inputs[i].pin; | 3920 | nid = cfg->inputs[i].pin; |
3921 | defcfg = snd_hda_codec_get_pincfg(codec, nid); | 3921 | defcfg = snd_hda_codec_get_pincfg(codec, nid); |
3922 | if (snd_hda_get_input_pin_attr(defcfg) == INPUT_PIN_ATTR_INT) | 3922 | if (snd_hda_get_input_pin_attr(defcfg) == INPUT_PIN_ATTR_INT) |
3923 | continue; | 3923 | continue; |
3924 | return nid; | 3924 | return nid; |
3925 | } | 3925 | } |
3926 | 3926 | ||
3927 | return 0; | 3927 | return 0; |
3928 | } | 3928 | } |
3929 | 3929 | ||
3930 | static void alc271_hp_gate_mic_jack(struct hda_codec *codec, | 3930 | static void alc271_hp_gate_mic_jack(struct hda_codec *codec, |
3931 | const struct hda_fixup *fix, | 3931 | const struct hda_fixup *fix, |
3932 | int action) | 3932 | int action) |
3933 | { | 3933 | { |
3934 | struct alc_spec *spec = codec->spec; | 3934 | struct alc_spec *spec = codec->spec; |
3935 | 3935 | ||
3936 | if (action == HDA_FIXUP_ACT_PROBE) { | 3936 | if (action == HDA_FIXUP_ACT_PROBE) { |
3937 | int mic_pin = find_ext_mic_pin(codec); | 3937 | int mic_pin = find_ext_mic_pin(codec); |
3938 | int hp_pin = spec->gen.autocfg.hp_pins[0]; | 3938 | int hp_pin = spec->gen.autocfg.hp_pins[0]; |
3939 | 3939 | ||
3940 | if (snd_BUG_ON(!mic_pin || !hp_pin)) | 3940 | if (snd_BUG_ON(!mic_pin || !hp_pin)) |
3941 | return; | 3941 | return; |
3942 | snd_hda_jack_set_gating_jack(codec, mic_pin, hp_pin); | 3942 | snd_hda_jack_set_gating_jack(codec, mic_pin, hp_pin); |
3943 | } | 3943 | } |
3944 | } | 3944 | } |
3945 | 3945 | ||
3946 | static void alc269_fixup_limit_int_mic_boost(struct hda_codec *codec, | 3946 | static void alc269_fixup_limit_int_mic_boost(struct hda_codec *codec, |
3947 | const struct hda_fixup *fix, | 3947 | const struct hda_fixup *fix, |
3948 | int action) | 3948 | int action) |
3949 | { | 3949 | { |
3950 | struct alc_spec *spec = codec->spec; | 3950 | struct alc_spec *spec = codec->spec; |
3951 | struct auto_pin_cfg *cfg = &spec->gen.autocfg; | 3951 | struct auto_pin_cfg *cfg = &spec->gen.autocfg; |
3952 | int i; | 3952 | int i; |
3953 | 3953 | ||
3954 | /* The mic boosts on level 2 and 3 are too noisy | 3954 | /* The mic boosts on level 2 and 3 are too noisy |
3955 | on the internal mic input. | 3955 | on the internal mic input. |
3956 | Therefore limit the boost to 0 or 1. */ | 3956 | Therefore limit the boost to 0 or 1. */ |
3957 | 3957 | ||
3958 | if (action != HDA_FIXUP_ACT_PROBE) | 3958 | if (action != HDA_FIXUP_ACT_PROBE) |
3959 | return; | 3959 | return; |
3960 | 3960 | ||
3961 | for (i = 0; i < cfg->num_inputs; i++) { | 3961 | for (i = 0; i < cfg->num_inputs; i++) { |
3962 | hda_nid_t nid = cfg->inputs[i].pin; | 3962 | hda_nid_t nid = cfg->inputs[i].pin; |
3963 | unsigned int defcfg; | 3963 | unsigned int defcfg; |
3964 | if (cfg->inputs[i].type != AUTO_PIN_MIC) | 3964 | if (cfg->inputs[i].type != AUTO_PIN_MIC) |
3965 | continue; | 3965 | continue; |
3966 | defcfg = snd_hda_codec_get_pincfg(codec, nid); | 3966 | defcfg = snd_hda_codec_get_pincfg(codec, nid); |
3967 | if (snd_hda_get_input_pin_attr(defcfg) != INPUT_PIN_ATTR_INT) | 3967 | if (snd_hda_get_input_pin_attr(defcfg) != INPUT_PIN_ATTR_INT) |
3968 | continue; | 3968 | continue; |
3969 | 3969 | ||
3970 | snd_hda_override_amp_caps(codec, nid, HDA_INPUT, | 3970 | snd_hda_override_amp_caps(codec, nid, HDA_INPUT, |
3971 | (0x00 << AC_AMPCAP_OFFSET_SHIFT) | | 3971 | (0x00 << AC_AMPCAP_OFFSET_SHIFT) | |
3972 | (0x01 << AC_AMPCAP_NUM_STEPS_SHIFT) | | 3972 | (0x01 << AC_AMPCAP_NUM_STEPS_SHIFT) | |
3973 | (0x2f << AC_AMPCAP_STEP_SIZE_SHIFT) | | 3973 | (0x2f << AC_AMPCAP_STEP_SIZE_SHIFT) | |
3974 | (0 << AC_AMPCAP_MUTE_SHIFT)); | 3974 | (0 << AC_AMPCAP_MUTE_SHIFT)); |
3975 | } | 3975 | } |
3976 | } | 3976 | } |
3977 | 3977 | ||
3978 | static void alc283_hp_automute_hook(struct hda_codec *codec, | 3978 | static void alc283_hp_automute_hook(struct hda_codec *codec, |
3979 | struct hda_jack_tbl *jack) | 3979 | struct hda_jack_tbl *jack) |
3980 | { | 3980 | { |
3981 | struct alc_spec *spec = codec->spec; | 3981 | struct alc_spec *spec = codec->spec; |
3982 | int vref; | 3982 | int vref; |
3983 | 3983 | ||
3984 | msleep(200); | 3984 | msleep(200); |
3985 | snd_hda_gen_hp_automute(codec, jack); | 3985 | snd_hda_gen_hp_automute(codec, jack); |
3986 | 3986 | ||
3987 | vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0; | 3987 | vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0; |
3988 | 3988 | ||
3989 | msleep(600); | 3989 | msleep(600); |
3990 | snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | 3990 | snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, |
3991 | vref); | 3991 | vref); |
3992 | } | 3992 | } |
3993 | 3993 | ||
3994 | static void alc283_fixup_chromebook(struct hda_codec *codec, | 3994 | static void alc283_fixup_chromebook(struct hda_codec *codec, |
3995 | const struct hda_fixup *fix, int action) | 3995 | const struct hda_fixup *fix, int action) |
3996 | { | 3996 | { |
3997 | struct alc_spec *spec = codec->spec; | 3997 | struct alc_spec *spec = codec->spec; |
3998 | int val; | 3998 | int val; |
3999 | 3999 | ||
4000 | switch (action) { | 4000 | switch (action) { |
4001 | case HDA_FIXUP_ACT_PRE_PROBE: | 4001 | case HDA_FIXUP_ACT_PRE_PROBE: |
4002 | snd_hda_override_wcaps(codec, 0x03, 0); | 4002 | snd_hda_override_wcaps(codec, 0x03, 0); |
4003 | /* Disable AA-loopback as it causes white noise */ | 4003 | /* Disable AA-loopback as it causes white noise */ |
4004 | spec->gen.mixer_nid = 0; | 4004 | spec->gen.mixer_nid = 0; |
4005 | break; | 4005 | break; |
4006 | case HDA_FIXUP_ACT_INIT: | 4006 | case HDA_FIXUP_ACT_INIT: |
4007 | /* MIC2-VREF control */ | 4007 | /* MIC2-VREF control */ |
4008 | /* Set to manual mode */ | 4008 | /* Set to manual mode */ |
4009 | val = alc_read_coef_idx(codec, 0x06); | 4009 | val = alc_read_coef_idx(codec, 0x06); |
4010 | alc_write_coef_idx(codec, 0x06, val & ~0x000c); | 4010 | alc_write_coef_idx(codec, 0x06, val & ~0x000c); |
4011 | /* Enable Line1 input control by verb */ | 4011 | /* Enable Line1 input control by verb */ |
4012 | val = alc_read_coef_idx(codec, 0x1a); | 4012 | val = alc_read_coef_idx(codec, 0x1a); |
4013 | alc_write_coef_idx(codec, 0x1a, val | (1 << 4)); | 4013 | alc_write_coef_idx(codec, 0x1a, val | (1 << 4)); |
4014 | break; | 4014 | break; |
4015 | } | 4015 | } |
4016 | } | 4016 | } |
4017 | 4017 | ||
4018 | static void alc283_fixup_sense_combo_jack(struct hda_codec *codec, | 4018 | static void alc283_fixup_sense_combo_jack(struct hda_codec *codec, |
4019 | const struct hda_fixup *fix, int action) | 4019 | const struct hda_fixup *fix, int action) |
4020 | { | 4020 | { |
4021 | struct alc_spec *spec = codec->spec; | 4021 | struct alc_spec *spec = codec->spec; |
4022 | int val; | 4022 | int val; |
4023 | 4023 | ||
4024 | switch (action) { | 4024 | switch (action) { |
4025 | case HDA_FIXUP_ACT_PRE_PROBE: | 4025 | case HDA_FIXUP_ACT_PRE_PROBE: |
4026 | spec->gen.hp_automute_hook = alc283_hp_automute_hook; | 4026 | spec->gen.hp_automute_hook = alc283_hp_automute_hook; |
4027 | break; | 4027 | break; |
4028 | case HDA_FIXUP_ACT_INIT: | 4028 | case HDA_FIXUP_ACT_INIT: |
4029 | /* MIC2-VREF control */ | 4029 | /* MIC2-VREF control */ |
4030 | /* Set to manual mode */ | 4030 | /* Set to manual mode */ |
4031 | val = alc_read_coef_idx(codec, 0x06); | 4031 | val = alc_read_coef_idx(codec, 0x06); |
4032 | alc_write_coef_idx(codec, 0x06, val & ~0x000c); | 4032 | alc_write_coef_idx(codec, 0x06, val & ~0x000c); |
4033 | break; | 4033 | break; |
4034 | } | 4034 | } |
4035 | } | 4035 | } |
4036 | 4036 | ||
4037 | /* mute tablet speaker pin (0x14) via dock plugging in addition */ | 4037 | /* mute tablet speaker pin (0x14) via dock plugging in addition */ |
4038 | static void asus_tx300_automute(struct hda_codec *codec) | 4038 | static void asus_tx300_automute(struct hda_codec *codec) |
4039 | { | 4039 | { |
4040 | struct alc_spec *spec = codec->spec; | 4040 | struct alc_spec *spec = codec->spec; |
4041 | snd_hda_gen_update_outputs(codec); | 4041 | snd_hda_gen_update_outputs(codec); |
4042 | if (snd_hda_jack_detect(codec, 0x1b)) | 4042 | if (snd_hda_jack_detect(codec, 0x1b)) |
4043 | spec->gen.mute_bits |= (1ULL << 0x14); | 4043 | spec->gen.mute_bits |= (1ULL << 0x14); |
4044 | } | 4044 | } |
4045 | 4045 | ||
4046 | static void alc282_fixup_asus_tx300(struct hda_codec *codec, | 4046 | static void alc282_fixup_asus_tx300(struct hda_codec *codec, |
4047 | const struct hda_fixup *fix, int action) | 4047 | const struct hda_fixup *fix, int action) |
4048 | { | 4048 | { |
4049 | struct alc_spec *spec = codec->spec; | 4049 | struct alc_spec *spec = codec->spec; |
4050 | /* TX300 needs to set up GPIO2 for the speaker amp */ | 4050 | /* TX300 needs to set up GPIO2 for the speaker amp */ |
4051 | static const struct hda_verb gpio2_verbs[] = { | 4051 | static const struct hda_verb gpio2_verbs[] = { |
4052 | { 0x01, AC_VERB_SET_GPIO_MASK, 0x04 }, | 4052 | { 0x01, AC_VERB_SET_GPIO_MASK, 0x04 }, |
4053 | { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04 }, | 4053 | { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04 }, |
4054 | { 0x01, AC_VERB_SET_GPIO_DATA, 0x04 }, | 4054 | { 0x01, AC_VERB_SET_GPIO_DATA, 0x04 }, |
4055 | {} | 4055 | {} |
4056 | }; | 4056 | }; |
4057 | static const struct hda_pintbl dock_pins[] = { | 4057 | static const struct hda_pintbl dock_pins[] = { |
4058 | { 0x1b, 0x21114000 }, /* dock speaker pin */ | 4058 | { 0x1b, 0x21114000 }, /* dock speaker pin */ |
4059 | {} | 4059 | {} |
4060 | }; | 4060 | }; |
4061 | struct snd_kcontrol *kctl; | 4061 | struct snd_kcontrol *kctl; |
4062 | 4062 | ||
4063 | switch (action) { | 4063 | switch (action) { |
4064 | case HDA_FIXUP_ACT_PRE_PROBE: | 4064 | case HDA_FIXUP_ACT_PRE_PROBE: |
4065 | snd_hda_add_verbs(codec, gpio2_verbs); | 4065 | snd_hda_add_verbs(codec, gpio2_verbs); |
4066 | snd_hda_apply_pincfgs(codec, dock_pins); | 4066 | snd_hda_apply_pincfgs(codec, dock_pins); |
4067 | spec->gen.auto_mute_via_amp = 1; | 4067 | spec->gen.auto_mute_via_amp = 1; |
4068 | spec->gen.automute_hook = asus_tx300_automute; | 4068 | spec->gen.automute_hook = asus_tx300_automute; |
4069 | snd_hda_jack_detect_enable_callback(codec, 0x1b, | 4069 | snd_hda_jack_detect_enable_callback(codec, 0x1b, |
4070 | HDA_GEN_HP_EVENT, | 4070 | HDA_GEN_HP_EVENT, |
4071 | snd_hda_gen_hp_automute); | 4071 | snd_hda_gen_hp_automute); |
4072 | break; | 4072 | break; |
4073 | case HDA_FIXUP_ACT_BUILD: | 4073 | case HDA_FIXUP_ACT_BUILD: |
4074 | /* this is a bit tricky; give more sane names for the main | 4074 | /* this is a bit tricky; give more sane names for the main |
4075 | * (tablet) speaker and the dock speaker, respectively | 4075 | * (tablet) speaker and the dock speaker, respectively |
4076 | */ | 4076 | */ |
4077 | kctl = snd_hda_find_mixer_ctl(codec, "Speaker Playback Switch"); | 4077 | kctl = snd_hda_find_mixer_ctl(codec, "Speaker Playback Switch"); |
4078 | if (kctl) | 4078 | if (kctl) |
4079 | strcpy(kctl->id.name, "Dock Speaker Playback Switch"); | 4079 | strcpy(kctl->id.name, "Dock Speaker Playback Switch"); |
4080 | kctl = snd_hda_find_mixer_ctl(codec, "Bass Speaker Playback Switch"); | 4080 | kctl = snd_hda_find_mixer_ctl(codec, "Bass Speaker Playback Switch"); |
4081 | if (kctl) | 4081 | if (kctl) |
4082 | strcpy(kctl->id.name, "Speaker Playback Switch"); | 4082 | strcpy(kctl->id.name, "Speaker Playback Switch"); |
4083 | break; | 4083 | break; |
4084 | } | 4084 | } |
4085 | } | 4085 | } |
4086 | 4086 | ||
4087 | static void alc290_fixup_mono_speakers(struct hda_codec *codec, | 4087 | static void alc290_fixup_mono_speakers(struct hda_codec *codec, |
4088 | const struct hda_fixup *fix, int action) | 4088 | const struct hda_fixup *fix, int action) |
4089 | { | 4089 | { |
4090 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | 4090 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
4091 | /* DAC node 0x03 is giving mono output. We therefore want to | 4091 | /* DAC node 0x03 is giving mono output. We therefore want to |
4092 | make sure 0x14 (front speaker) and 0x15 (headphones) use the | 4092 | make sure 0x14 (front speaker) and 0x15 (headphones) use the |
4093 | stereo DAC, while leaving 0x17 (bass speaker) for node 0x03. */ | 4093 | stereo DAC, while leaving 0x17 (bass speaker) for node 0x03. */ |
4094 | hda_nid_t conn1[2] = { 0x0c }; | 4094 | hda_nid_t conn1[2] = { 0x0c }; |
4095 | snd_hda_override_conn_list(codec, 0x14, 1, conn1); | 4095 | snd_hda_override_conn_list(codec, 0x14, 1, conn1); |
4096 | snd_hda_override_conn_list(codec, 0x15, 1, conn1); | 4096 | snd_hda_override_conn_list(codec, 0x15, 1, conn1); |
4097 | } | 4097 | } |
4098 | } | 4098 | } |
4099 | 4099 | ||
4100 | /* for hda_fixup_thinkpad_acpi() */ | 4100 | /* for hda_fixup_thinkpad_acpi() */ |
4101 | #include "thinkpad_helper.c" | 4101 | #include "thinkpad_helper.c" |
4102 | 4102 | ||
4103 | enum { | 4103 | enum { |
4104 | ALC269_FIXUP_SONY_VAIO, | 4104 | ALC269_FIXUP_SONY_VAIO, |
4105 | ALC275_FIXUP_SONY_VAIO_GPIO2, | 4105 | ALC275_FIXUP_SONY_VAIO_GPIO2, |
4106 | ALC269_FIXUP_DELL_M101Z, | 4106 | ALC269_FIXUP_DELL_M101Z, |
4107 | ALC269_FIXUP_SKU_IGNORE, | 4107 | ALC269_FIXUP_SKU_IGNORE, |
4108 | ALC269_FIXUP_ASUS_G73JW, | 4108 | ALC269_FIXUP_ASUS_G73JW, |
4109 | ALC269_FIXUP_LENOVO_EAPD, | 4109 | ALC269_FIXUP_LENOVO_EAPD, |
4110 | ALC275_FIXUP_SONY_HWEQ, | 4110 | ALC275_FIXUP_SONY_HWEQ, |
4111 | ALC271_FIXUP_DMIC, | 4111 | ALC271_FIXUP_DMIC, |
4112 | ALC269_FIXUP_PCM_44K, | 4112 | ALC269_FIXUP_PCM_44K, |
4113 | ALC269_FIXUP_STEREO_DMIC, | 4113 | ALC269_FIXUP_STEREO_DMIC, |
4114 | ALC269_FIXUP_HEADSET_MIC, | 4114 | ALC269_FIXUP_HEADSET_MIC, |
4115 | ALC269_FIXUP_QUANTA_MUTE, | 4115 | ALC269_FIXUP_QUANTA_MUTE, |
4116 | ALC269_FIXUP_LIFEBOOK, | 4116 | ALC269_FIXUP_LIFEBOOK, |
4117 | ALC269_FIXUP_AMIC, | 4117 | ALC269_FIXUP_AMIC, |
4118 | ALC269_FIXUP_DMIC, | 4118 | ALC269_FIXUP_DMIC, |
4119 | ALC269VB_FIXUP_AMIC, | 4119 | ALC269VB_FIXUP_AMIC, |
4120 | ALC269VB_FIXUP_DMIC, | 4120 | ALC269VB_FIXUP_DMIC, |
4121 | ALC269_FIXUP_HP_MUTE_LED, | 4121 | ALC269_FIXUP_HP_MUTE_LED, |
4122 | ALC269_FIXUP_HP_MUTE_LED_MIC1, | 4122 | ALC269_FIXUP_HP_MUTE_LED_MIC1, |
4123 | ALC269_FIXUP_HP_MUTE_LED_MIC2, | 4123 | ALC269_FIXUP_HP_MUTE_LED_MIC2, |
4124 | ALC269_FIXUP_HP_GPIO_LED, | 4124 | ALC269_FIXUP_HP_GPIO_LED, |
4125 | ALC269_FIXUP_INV_DMIC, | 4125 | ALC269_FIXUP_INV_DMIC, |
4126 | ALC269_FIXUP_LENOVO_DOCK, | 4126 | ALC269_FIXUP_LENOVO_DOCK, |
4127 | ALC269_FIXUP_NO_SHUTUP, | 4127 | ALC269_FIXUP_NO_SHUTUP, |
4128 | ALC286_FIXUP_SONY_MIC_NO_PRESENCE, | 4128 | ALC286_FIXUP_SONY_MIC_NO_PRESENCE, |
4129 | ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT, | 4129 | ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT, |
4130 | ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, | 4130 | ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, |
4131 | ALC269_FIXUP_DELL2_MIC_NO_PRESENCE, | 4131 | ALC269_FIXUP_DELL2_MIC_NO_PRESENCE, |
4132 | ALC269_FIXUP_DELL3_MIC_NO_PRESENCE, | 4132 | ALC269_FIXUP_DELL3_MIC_NO_PRESENCE, |
4133 | ALC269_FIXUP_HEADSET_MODE, | 4133 | ALC269_FIXUP_HEADSET_MODE, |
4134 | ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC, | 4134 | ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC, |
4135 | ALC269_FIXUP_ASUS_X101_FUNC, | 4135 | ALC269_FIXUP_ASUS_X101_FUNC, |
4136 | ALC269_FIXUP_ASUS_X101_VERB, | 4136 | ALC269_FIXUP_ASUS_X101_VERB, |
4137 | ALC269_FIXUP_ASUS_X101, | 4137 | ALC269_FIXUP_ASUS_X101, |
4138 | ALC271_FIXUP_AMIC_MIC2, | 4138 | ALC271_FIXUP_AMIC_MIC2, |
4139 | ALC271_FIXUP_HP_GATE_MIC_JACK, | 4139 | ALC271_FIXUP_HP_GATE_MIC_JACK, |
4140 | ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572, | 4140 | ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572, |
4141 | ALC269_FIXUP_ACER_AC700, | 4141 | ALC269_FIXUP_ACER_AC700, |
4142 | ALC269_FIXUP_LIMIT_INT_MIC_BOOST, | 4142 | ALC269_FIXUP_LIMIT_INT_MIC_BOOST, |
4143 | ALC269VB_FIXUP_ASUS_ZENBOOK, | 4143 | ALC269VB_FIXUP_ASUS_ZENBOOK, |
4144 | ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A, | 4144 | ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A, |
4145 | ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED, | 4145 | ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED, |
4146 | ALC269VB_FIXUP_ORDISSIMO_EVE2, | 4146 | ALC269VB_FIXUP_ORDISSIMO_EVE2, |
4147 | ALC283_FIXUP_CHROME_BOOK, | 4147 | ALC283_FIXUP_CHROME_BOOK, |
4148 | ALC283_FIXUP_SENSE_COMBO_JACK, | 4148 | ALC283_FIXUP_SENSE_COMBO_JACK, |
4149 | ALC282_FIXUP_ASUS_TX300, | 4149 | ALC282_FIXUP_ASUS_TX300, |
4150 | ALC283_FIXUP_INT_MIC, | 4150 | ALC283_FIXUP_INT_MIC, |
4151 | ALC290_FIXUP_MONO_SPEAKERS, | 4151 | ALC290_FIXUP_MONO_SPEAKERS, |
4152 | ALC290_FIXUP_MONO_SPEAKERS_HSJACK, | 4152 | ALC290_FIXUP_MONO_SPEAKERS_HSJACK, |
4153 | ALC290_FIXUP_SUBWOOFER, | 4153 | ALC290_FIXUP_SUBWOOFER, |
4154 | ALC290_FIXUP_SUBWOOFER_HSJACK, | 4154 | ALC290_FIXUP_SUBWOOFER_HSJACK, |
4155 | ALC269_FIXUP_THINKPAD_ACPI, | 4155 | ALC269_FIXUP_THINKPAD_ACPI, |
4156 | ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, | 4156 | ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, |
4157 | ALC255_FIXUP_DELL2_MIC_NO_PRESENCE, | 4157 | ALC255_FIXUP_DELL2_MIC_NO_PRESENCE, |
4158 | ALC255_FIXUP_HEADSET_MODE, | 4158 | ALC255_FIXUP_HEADSET_MODE, |
4159 | ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC, | 4159 | ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC, |
4160 | }; | 4160 | }; |
4161 | 4161 | ||
4162 | static const struct hda_fixup alc269_fixups[] = { | 4162 | static const struct hda_fixup alc269_fixups[] = { |
4163 | [ALC269_FIXUP_SONY_VAIO] = { | 4163 | [ALC269_FIXUP_SONY_VAIO] = { |
4164 | .type = HDA_FIXUP_PINCTLS, | 4164 | .type = HDA_FIXUP_PINCTLS, |
4165 | .v.pins = (const struct hda_pintbl[]) { | 4165 | .v.pins = (const struct hda_pintbl[]) { |
4166 | {0x19, PIN_VREFGRD}, | 4166 | {0x19, PIN_VREFGRD}, |
4167 | {} | 4167 | {} |
4168 | } | 4168 | } |
4169 | }, | 4169 | }, |
4170 | [ALC275_FIXUP_SONY_VAIO_GPIO2] = { | 4170 | [ALC275_FIXUP_SONY_VAIO_GPIO2] = { |
4171 | .type = HDA_FIXUP_VERBS, | 4171 | .type = HDA_FIXUP_VERBS, |
4172 | .v.verbs = (const struct hda_verb[]) { | 4172 | .v.verbs = (const struct hda_verb[]) { |
4173 | {0x01, AC_VERB_SET_GPIO_MASK, 0x04}, | 4173 | {0x01, AC_VERB_SET_GPIO_MASK, 0x04}, |
4174 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04}, | 4174 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04}, |
4175 | {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, | 4175 | {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, |
4176 | { } | 4176 | { } |
4177 | }, | 4177 | }, |
4178 | .chained = true, | 4178 | .chained = true, |
4179 | .chain_id = ALC269_FIXUP_SONY_VAIO | 4179 | .chain_id = ALC269_FIXUP_SONY_VAIO |
4180 | }, | 4180 | }, |
4181 | [ALC269_FIXUP_DELL_M101Z] = { | 4181 | [ALC269_FIXUP_DELL_M101Z] = { |
4182 | .type = HDA_FIXUP_VERBS, | 4182 | .type = HDA_FIXUP_VERBS, |
4183 | .v.verbs = (const struct hda_verb[]) { | 4183 | .v.verbs = (const struct hda_verb[]) { |
4184 | /* Enables internal speaker */ | 4184 | /* Enables internal speaker */ |
4185 | {0x20, AC_VERB_SET_COEF_INDEX, 13}, | 4185 | {0x20, AC_VERB_SET_COEF_INDEX, 13}, |
4186 | {0x20, AC_VERB_SET_PROC_COEF, 0x4040}, | 4186 | {0x20, AC_VERB_SET_PROC_COEF, 0x4040}, |
4187 | {} | 4187 | {} |
4188 | } | 4188 | } |
4189 | }, | 4189 | }, |
4190 | [ALC269_FIXUP_SKU_IGNORE] = { | 4190 | [ALC269_FIXUP_SKU_IGNORE] = { |
4191 | .type = HDA_FIXUP_FUNC, | 4191 | .type = HDA_FIXUP_FUNC, |
4192 | .v.func = alc_fixup_sku_ignore, | 4192 | .v.func = alc_fixup_sku_ignore, |
4193 | }, | 4193 | }, |
4194 | [ALC269_FIXUP_ASUS_G73JW] = { | 4194 | [ALC269_FIXUP_ASUS_G73JW] = { |
4195 | .type = HDA_FIXUP_PINS, | 4195 | .type = HDA_FIXUP_PINS, |
4196 | .v.pins = (const struct hda_pintbl[]) { | 4196 | .v.pins = (const struct hda_pintbl[]) { |
4197 | { 0x17, 0x99130111 }, /* subwoofer */ | 4197 | { 0x17, 0x99130111 }, /* subwoofer */ |
4198 | { } | 4198 | { } |
4199 | } | 4199 | } |
4200 | }, | 4200 | }, |
4201 | [ALC269_FIXUP_LENOVO_EAPD] = { | 4201 | [ALC269_FIXUP_LENOVO_EAPD] = { |
4202 | .type = HDA_FIXUP_VERBS, | 4202 | .type = HDA_FIXUP_VERBS, |
4203 | .v.verbs = (const struct hda_verb[]) { | 4203 | .v.verbs = (const struct hda_verb[]) { |
4204 | {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0}, | 4204 | {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0}, |
4205 | {} | 4205 | {} |
4206 | } | 4206 | } |
4207 | }, | 4207 | }, |
4208 | [ALC275_FIXUP_SONY_HWEQ] = { | 4208 | [ALC275_FIXUP_SONY_HWEQ] = { |
4209 | .type = HDA_FIXUP_FUNC, | 4209 | .type = HDA_FIXUP_FUNC, |
4210 | .v.func = alc269_fixup_hweq, | 4210 | .v.func = alc269_fixup_hweq, |
4211 | .chained = true, | 4211 | .chained = true, |
4212 | .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2 | 4212 | .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2 |
4213 | }, | 4213 | }, |
4214 | [ALC271_FIXUP_DMIC] = { | 4214 | [ALC271_FIXUP_DMIC] = { |
4215 | .type = HDA_FIXUP_FUNC, | 4215 | .type = HDA_FIXUP_FUNC, |
4216 | .v.func = alc271_fixup_dmic, | 4216 | .v.func = alc271_fixup_dmic, |
4217 | }, | 4217 | }, |
4218 | [ALC269_FIXUP_PCM_44K] = { | 4218 | [ALC269_FIXUP_PCM_44K] = { |
4219 | .type = HDA_FIXUP_FUNC, | 4219 | .type = HDA_FIXUP_FUNC, |
4220 | .v.func = alc269_fixup_pcm_44k, | 4220 | .v.func = alc269_fixup_pcm_44k, |
4221 | .chained = true, | 4221 | .chained = true, |
4222 | .chain_id = ALC269_FIXUP_QUANTA_MUTE | 4222 | .chain_id = ALC269_FIXUP_QUANTA_MUTE |
4223 | }, | 4223 | }, |
4224 | [ALC269_FIXUP_STEREO_DMIC] = { | 4224 | [ALC269_FIXUP_STEREO_DMIC] = { |
4225 | .type = HDA_FIXUP_FUNC, | 4225 | .type = HDA_FIXUP_FUNC, |
4226 | .v.func = alc269_fixup_stereo_dmic, | 4226 | .v.func = alc269_fixup_stereo_dmic, |
4227 | }, | 4227 | }, |
4228 | [ALC269_FIXUP_HEADSET_MIC] = { | 4228 | [ALC269_FIXUP_HEADSET_MIC] = { |
4229 | .type = HDA_FIXUP_FUNC, | 4229 | .type = HDA_FIXUP_FUNC, |
4230 | .v.func = alc269_fixup_headset_mic, | 4230 | .v.func = alc269_fixup_headset_mic, |
4231 | }, | 4231 | }, |
4232 | [ALC269_FIXUP_QUANTA_MUTE] = { | 4232 | [ALC269_FIXUP_QUANTA_MUTE] = { |
4233 | .type = HDA_FIXUP_FUNC, | 4233 | .type = HDA_FIXUP_FUNC, |
4234 | .v.func = alc269_fixup_quanta_mute, | 4234 | .v.func = alc269_fixup_quanta_mute, |
4235 | }, | 4235 | }, |
4236 | [ALC269_FIXUP_LIFEBOOK] = { | 4236 | [ALC269_FIXUP_LIFEBOOK] = { |
4237 | .type = HDA_FIXUP_PINS, | 4237 | .type = HDA_FIXUP_PINS, |
4238 | .v.pins = (const struct hda_pintbl[]) { | 4238 | .v.pins = (const struct hda_pintbl[]) { |
4239 | { 0x1a, 0x2101103f }, /* dock line-out */ | 4239 | { 0x1a, 0x2101103f }, /* dock line-out */ |
4240 | { 0x1b, 0x23a11040 }, /* dock mic-in */ | 4240 | { 0x1b, 0x23a11040 }, /* dock mic-in */ |
4241 | { } | 4241 | { } |
4242 | }, | 4242 | }, |
4243 | .chained = true, | 4243 | .chained = true, |
4244 | .chain_id = ALC269_FIXUP_QUANTA_MUTE | 4244 | .chain_id = ALC269_FIXUP_QUANTA_MUTE |
4245 | }, | 4245 | }, |
4246 | [ALC269_FIXUP_AMIC] = { | 4246 | [ALC269_FIXUP_AMIC] = { |
4247 | .type = HDA_FIXUP_PINS, | 4247 | .type = HDA_FIXUP_PINS, |
4248 | .v.pins = (const struct hda_pintbl[]) { | 4248 | .v.pins = (const struct hda_pintbl[]) { |
4249 | { 0x14, 0x99130110 }, /* speaker */ | 4249 | { 0x14, 0x99130110 }, /* speaker */ |
4250 | { 0x15, 0x0121401f }, /* HP out */ | 4250 | { 0x15, 0x0121401f }, /* HP out */ |
4251 | { 0x18, 0x01a19c20 }, /* mic */ | 4251 | { 0x18, 0x01a19c20 }, /* mic */ |
4252 | { 0x19, 0x99a3092f }, /* int-mic */ | 4252 | { 0x19, 0x99a3092f }, /* int-mic */ |
4253 | { } | 4253 | { } |
4254 | }, | 4254 | }, |
4255 | }, | 4255 | }, |
4256 | [ALC269_FIXUP_DMIC] = { | 4256 | [ALC269_FIXUP_DMIC] = { |
4257 | .type = HDA_FIXUP_PINS, | 4257 | .type = HDA_FIXUP_PINS, |
4258 | .v.pins = (const struct hda_pintbl[]) { | 4258 | .v.pins = (const struct hda_pintbl[]) { |
4259 | { 0x12, 0x99a3092f }, /* int-mic */ | 4259 | { 0x12, 0x99a3092f }, /* int-mic */ |
4260 | { 0x14, 0x99130110 }, /* speaker */ | 4260 | { 0x14, 0x99130110 }, /* speaker */ |
4261 | { 0x15, 0x0121401f }, /* HP out */ | 4261 | { 0x15, 0x0121401f }, /* HP out */ |
4262 | { 0x18, 0x01a19c20 }, /* mic */ | 4262 | { 0x18, 0x01a19c20 }, /* mic */ |
4263 | { } | 4263 | { } |
4264 | }, | 4264 | }, |
4265 | }, | 4265 | }, |
4266 | [ALC269VB_FIXUP_AMIC] = { | 4266 | [ALC269VB_FIXUP_AMIC] = { |
4267 | .type = HDA_FIXUP_PINS, | 4267 | .type = HDA_FIXUP_PINS, |
4268 | .v.pins = (const struct hda_pintbl[]) { | 4268 | .v.pins = (const struct hda_pintbl[]) { |
4269 | { 0x14, 0x99130110 }, /* speaker */ | 4269 | { 0x14, 0x99130110 }, /* speaker */ |
4270 | { 0x18, 0x01a19c20 }, /* mic */ | 4270 | { 0x18, 0x01a19c20 }, /* mic */ |
4271 | { 0x19, 0x99a3092f }, /* int-mic */ | 4271 | { 0x19, 0x99a3092f }, /* int-mic */ |
4272 | { 0x21, 0x0121401f }, /* HP out */ | 4272 | { 0x21, 0x0121401f }, /* HP out */ |
4273 | { } | 4273 | { } |
4274 | }, | 4274 | }, |
4275 | }, | 4275 | }, |
4276 | [ALC269VB_FIXUP_DMIC] = { | 4276 | [ALC269VB_FIXUP_DMIC] = { |
4277 | .type = HDA_FIXUP_PINS, | 4277 | .type = HDA_FIXUP_PINS, |
4278 | .v.pins = (const struct hda_pintbl[]) { | 4278 | .v.pins = (const struct hda_pintbl[]) { |
4279 | { 0x12, 0x99a3092f }, /* int-mic */ | 4279 | { 0x12, 0x99a3092f }, /* int-mic */ |
4280 | { 0x14, 0x99130110 }, /* speaker */ | 4280 | { 0x14, 0x99130110 }, /* speaker */ |
4281 | { 0x18, 0x01a19c20 }, /* mic */ | 4281 | { 0x18, 0x01a19c20 }, /* mic */ |
4282 | { 0x21, 0x0121401f }, /* HP out */ | 4282 | { 0x21, 0x0121401f }, /* HP out */ |
4283 | { } | 4283 | { } |
4284 | }, | 4284 | }, |
4285 | }, | 4285 | }, |
4286 | [ALC269_FIXUP_HP_MUTE_LED] = { | 4286 | [ALC269_FIXUP_HP_MUTE_LED] = { |
4287 | .type = HDA_FIXUP_FUNC, | 4287 | .type = HDA_FIXUP_FUNC, |
4288 | .v.func = alc269_fixup_hp_mute_led, | 4288 | .v.func = alc269_fixup_hp_mute_led, |
4289 | }, | 4289 | }, |
4290 | [ALC269_FIXUP_HP_MUTE_LED_MIC1] = { | 4290 | [ALC269_FIXUP_HP_MUTE_LED_MIC1] = { |
4291 | .type = HDA_FIXUP_FUNC, | 4291 | .type = HDA_FIXUP_FUNC, |
4292 | .v.func = alc269_fixup_hp_mute_led_mic1, | 4292 | .v.func = alc269_fixup_hp_mute_led_mic1, |
4293 | }, | 4293 | }, |
4294 | [ALC269_FIXUP_HP_MUTE_LED_MIC2] = { | 4294 | [ALC269_FIXUP_HP_MUTE_LED_MIC2] = { |
4295 | .type = HDA_FIXUP_FUNC, | 4295 | .type = HDA_FIXUP_FUNC, |
4296 | .v.func = alc269_fixup_hp_mute_led_mic2, | 4296 | .v.func = alc269_fixup_hp_mute_led_mic2, |
4297 | }, | 4297 | }, |
4298 | [ALC269_FIXUP_HP_GPIO_LED] = { | 4298 | [ALC269_FIXUP_HP_GPIO_LED] = { |
4299 | .type = HDA_FIXUP_FUNC, | 4299 | .type = HDA_FIXUP_FUNC, |
4300 | .v.func = alc269_fixup_hp_gpio_led, | 4300 | .v.func = alc269_fixup_hp_gpio_led, |
4301 | }, | 4301 | }, |
4302 | [ALC269_FIXUP_INV_DMIC] = { | 4302 | [ALC269_FIXUP_INV_DMIC] = { |
4303 | .type = HDA_FIXUP_FUNC, | 4303 | .type = HDA_FIXUP_FUNC, |
4304 | .v.func = alc_fixup_inv_dmic_0x12, | 4304 | .v.func = alc_fixup_inv_dmic_0x12, |
4305 | }, | 4305 | }, |
4306 | [ALC269_FIXUP_NO_SHUTUP] = { | 4306 | [ALC269_FIXUP_NO_SHUTUP] = { |
4307 | .type = HDA_FIXUP_FUNC, | 4307 | .type = HDA_FIXUP_FUNC, |
4308 | .v.func = alc_fixup_no_shutup, | 4308 | .v.func = alc_fixup_no_shutup, |
4309 | }, | 4309 | }, |
4310 | [ALC269_FIXUP_LENOVO_DOCK] = { | 4310 | [ALC269_FIXUP_LENOVO_DOCK] = { |
4311 | .type = HDA_FIXUP_PINS, | 4311 | .type = HDA_FIXUP_PINS, |
4312 | .v.pins = (const struct hda_pintbl[]) { | 4312 | .v.pins = (const struct hda_pintbl[]) { |
4313 | { 0x19, 0x23a11040 }, /* dock mic */ | 4313 | { 0x19, 0x23a11040 }, /* dock mic */ |
4314 | { 0x1b, 0x2121103f }, /* dock headphone */ | 4314 | { 0x1b, 0x2121103f }, /* dock headphone */ |
4315 | { } | 4315 | { } |
4316 | }, | 4316 | }, |
4317 | .chained = true, | 4317 | .chained = true, |
4318 | .chain_id = ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT | 4318 | .chain_id = ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT |
4319 | }, | 4319 | }, |
4320 | [ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT] = { | 4320 | [ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT] = { |
4321 | .type = HDA_FIXUP_FUNC, | 4321 | .type = HDA_FIXUP_FUNC, |
4322 | .v.func = alc269_fixup_pincfg_no_hp_to_lineout, | 4322 | .v.func = alc269_fixup_pincfg_no_hp_to_lineout, |
4323 | .chained = true, | 4323 | .chained = true, |
4324 | .chain_id = ALC269_FIXUP_THINKPAD_ACPI, | 4324 | .chain_id = ALC269_FIXUP_THINKPAD_ACPI, |
4325 | }, | 4325 | }, |
4326 | [ALC269_FIXUP_DELL1_MIC_NO_PRESENCE] = { | 4326 | [ALC269_FIXUP_DELL1_MIC_NO_PRESENCE] = { |
4327 | .type = HDA_FIXUP_PINS, | 4327 | .type = HDA_FIXUP_PINS, |
4328 | .v.pins = (const struct hda_pintbl[]) { | 4328 | .v.pins = (const struct hda_pintbl[]) { |
4329 | { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */ | 4329 | { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */ |
4330 | { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */ | 4330 | { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */ |
4331 | { } | 4331 | { } |
4332 | }, | 4332 | }, |
4333 | .chained = true, | 4333 | .chained = true, |
4334 | .chain_id = ALC269_FIXUP_HEADSET_MODE | 4334 | .chain_id = ALC269_FIXUP_HEADSET_MODE |
4335 | }, | 4335 | }, |
4336 | [ALC269_FIXUP_DELL2_MIC_NO_PRESENCE] = { | 4336 | [ALC269_FIXUP_DELL2_MIC_NO_PRESENCE] = { |
4337 | .type = HDA_FIXUP_PINS, | 4337 | .type = HDA_FIXUP_PINS, |
4338 | .v.pins = (const struct hda_pintbl[]) { | 4338 | .v.pins = (const struct hda_pintbl[]) { |
4339 | { 0x16, 0x21014020 }, /* dock line out */ | 4339 | { 0x16, 0x21014020 }, /* dock line out */ |
4340 | { 0x19, 0x21a19030 }, /* dock mic */ | 4340 | { 0x19, 0x21a19030 }, /* dock mic */ |
4341 | { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */ | 4341 | { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */ |
4342 | { } | 4342 | { } |
4343 | }, | 4343 | }, |
4344 | .chained = true, | 4344 | .chained = true, |
4345 | .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC | 4345 | .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC |
4346 | }, | 4346 | }, |
4347 | [ALC269_FIXUP_DELL3_MIC_NO_PRESENCE] = { | 4347 | [ALC269_FIXUP_DELL3_MIC_NO_PRESENCE] = { |
4348 | .type = HDA_FIXUP_PINS, | 4348 | .type = HDA_FIXUP_PINS, |
4349 | .v.pins = (const struct hda_pintbl[]) { | 4349 | .v.pins = (const struct hda_pintbl[]) { |
4350 | { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */ | 4350 | { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */ |
4351 | { } | 4351 | { } |
4352 | }, | 4352 | }, |
4353 | .chained = true, | 4353 | .chained = true, |
4354 | .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC | 4354 | .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC |
4355 | }, | 4355 | }, |
4356 | [ALC269_FIXUP_HEADSET_MODE] = { | 4356 | [ALC269_FIXUP_HEADSET_MODE] = { |
4357 | .type = HDA_FIXUP_FUNC, | 4357 | .type = HDA_FIXUP_FUNC, |
4358 | .v.func = alc_fixup_headset_mode, | 4358 | .v.func = alc_fixup_headset_mode, |
4359 | }, | 4359 | }, |
4360 | [ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC] = { | 4360 | [ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC] = { |
4361 | .type = HDA_FIXUP_FUNC, | 4361 | .type = HDA_FIXUP_FUNC, |
4362 | .v.func = alc_fixup_headset_mode_no_hp_mic, | 4362 | .v.func = alc_fixup_headset_mode_no_hp_mic, |
4363 | }, | 4363 | }, |
4364 | [ALC286_FIXUP_SONY_MIC_NO_PRESENCE] = { | 4364 | [ALC286_FIXUP_SONY_MIC_NO_PRESENCE] = { |
4365 | .type = HDA_FIXUP_PINS, | 4365 | .type = HDA_FIXUP_PINS, |
4366 | .v.pins = (const struct hda_pintbl[]) { | 4366 | .v.pins = (const struct hda_pintbl[]) { |
4367 | { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */ | 4367 | { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */ |
4368 | { } | 4368 | { } |
4369 | }, | 4369 | }, |
4370 | .chained = true, | 4370 | .chained = true, |
4371 | .chain_id = ALC269_FIXUP_HEADSET_MIC | 4371 | .chain_id = ALC269_FIXUP_HEADSET_MIC |
4372 | }, | 4372 | }, |
4373 | [ALC269_FIXUP_ASUS_X101_FUNC] = { | 4373 | [ALC269_FIXUP_ASUS_X101_FUNC] = { |
4374 | .type = HDA_FIXUP_FUNC, | 4374 | .type = HDA_FIXUP_FUNC, |
4375 | .v.func = alc269_fixup_x101_headset_mic, | 4375 | .v.func = alc269_fixup_x101_headset_mic, |
4376 | }, | 4376 | }, |
4377 | [ALC269_FIXUP_ASUS_X101_VERB] = { | 4377 | [ALC269_FIXUP_ASUS_X101_VERB] = { |
4378 | .type = HDA_FIXUP_VERBS, | 4378 | .type = HDA_FIXUP_VERBS, |
4379 | .v.verbs = (const struct hda_verb[]) { | 4379 | .v.verbs = (const struct hda_verb[]) { |
4380 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | 4380 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, |
4381 | {0x20, AC_VERB_SET_COEF_INDEX, 0x08}, | 4381 | {0x20, AC_VERB_SET_COEF_INDEX, 0x08}, |
4382 | {0x20, AC_VERB_SET_PROC_COEF, 0x0310}, | 4382 | {0x20, AC_VERB_SET_PROC_COEF, 0x0310}, |
4383 | { } | 4383 | { } |
4384 | }, | 4384 | }, |
4385 | .chained = true, | 4385 | .chained = true, |
4386 | .chain_id = ALC269_FIXUP_ASUS_X101_FUNC | 4386 | .chain_id = ALC269_FIXUP_ASUS_X101_FUNC |
4387 | }, | 4387 | }, |
4388 | [ALC269_FIXUP_ASUS_X101] = { | 4388 | [ALC269_FIXUP_ASUS_X101] = { |
4389 | .type = HDA_FIXUP_PINS, | 4389 | .type = HDA_FIXUP_PINS, |
4390 | .v.pins = (const struct hda_pintbl[]) { | 4390 | .v.pins = (const struct hda_pintbl[]) { |
4391 | { 0x18, 0x04a1182c }, /* Headset mic */ | 4391 | { 0x18, 0x04a1182c }, /* Headset mic */ |
4392 | { } | 4392 | { } |
4393 | }, | 4393 | }, |
4394 | .chained = true, | 4394 | .chained = true, |
4395 | .chain_id = ALC269_FIXUP_ASUS_X101_VERB | 4395 | .chain_id = ALC269_FIXUP_ASUS_X101_VERB |
4396 | }, | 4396 | }, |
4397 | [ALC271_FIXUP_AMIC_MIC2] = { | 4397 | [ALC271_FIXUP_AMIC_MIC2] = { |
4398 | .type = HDA_FIXUP_PINS, | 4398 | .type = HDA_FIXUP_PINS, |
4399 | .v.pins = (const struct hda_pintbl[]) { | 4399 | .v.pins = (const struct hda_pintbl[]) { |
4400 | { 0x14, 0x99130110 }, /* speaker */ | 4400 | { 0x14, 0x99130110 }, /* speaker */ |
4401 | { 0x19, 0x01a19c20 }, /* mic */ | 4401 | { 0x19, 0x01a19c20 }, /* mic */ |
4402 | { 0x1b, 0x99a7012f }, /* int-mic */ | 4402 | { 0x1b, 0x99a7012f }, /* int-mic */ |
4403 | { 0x21, 0x0121401f }, /* HP out */ | 4403 | { 0x21, 0x0121401f }, /* HP out */ |
4404 | { } | 4404 | { } |
4405 | }, | 4405 | }, |
4406 | }, | 4406 | }, |
4407 | [ALC271_FIXUP_HP_GATE_MIC_JACK] = { | 4407 | [ALC271_FIXUP_HP_GATE_MIC_JACK] = { |
4408 | .type = HDA_FIXUP_FUNC, | 4408 | .type = HDA_FIXUP_FUNC, |
4409 | .v.func = alc271_hp_gate_mic_jack, | 4409 | .v.func = alc271_hp_gate_mic_jack, |
4410 | .chained = true, | 4410 | .chained = true, |
4411 | .chain_id = ALC271_FIXUP_AMIC_MIC2, | 4411 | .chain_id = ALC271_FIXUP_AMIC_MIC2, |
4412 | }, | 4412 | }, |
4413 | [ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572] = { | 4413 | [ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572] = { |
4414 | .type = HDA_FIXUP_FUNC, | 4414 | .type = HDA_FIXUP_FUNC, |
4415 | .v.func = alc269_fixup_limit_int_mic_boost, | 4415 | .v.func = alc269_fixup_limit_int_mic_boost, |
4416 | .chained = true, | 4416 | .chained = true, |
4417 | .chain_id = ALC271_FIXUP_HP_GATE_MIC_JACK, | 4417 | .chain_id = ALC271_FIXUP_HP_GATE_MIC_JACK, |
4418 | }, | 4418 | }, |
4419 | [ALC269_FIXUP_ACER_AC700] = { | 4419 | [ALC269_FIXUP_ACER_AC700] = { |
4420 | .type = HDA_FIXUP_PINS, | 4420 | .type = HDA_FIXUP_PINS, |
4421 | .v.pins = (const struct hda_pintbl[]) { | 4421 | .v.pins = (const struct hda_pintbl[]) { |
4422 | { 0x12, 0x99a3092f }, /* int-mic */ | 4422 | { 0x12, 0x99a3092f }, /* int-mic */ |
4423 | { 0x14, 0x99130110 }, /* speaker */ | 4423 | { 0x14, 0x99130110 }, /* speaker */ |
4424 | { 0x18, 0x03a11c20 }, /* mic */ | 4424 | { 0x18, 0x03a11c20 }, /* mic */ |
4425 | { 0x1e, 0x0346101e }, /* SPDIF1 */ | 4425 | { 0x1e, 0x0346101e }, /* SPDIF1 */ |
4426 | { 0x21, 0x0321101f }, /* HP out */ | 4426 | { 0x21, 0x0321101f }, /* HP out */ |
4427 | { } | 4427 | { } |
4428 | }, | 4428 | }, |
4429 | .chained = true, | 4429 | .chained = true, |
4430 | .chain_id = ALC271_FIXUP_DMIC, | 4430 | .chain_id = ALC271_FIXUP_DMIC, |
4431 | }, | 4431 | }, |
4432 | [ALC269_FIXUP_LIMIT_INT_MIC_BOOST] = { | 4432 | [ALC269_FIXUP_LIMIT_INT_MIC_BOOST] = { |
4433 | .type = HDA_FIXUP_FUNC, | 4433 | .type = HDA_FIXUP_FUNC, |
4434 | .v.func = alc269_fixup_limit_int_mic_boost, | 4434 | .v.func = alc269_fixup_limit_int_mic_boost, |
4435 | .chained = true, | 4435 | .chained = true, |
4436 | .chain_id = ALC269_FIXUP_THINKPAD_ACPI, | 4436 | .chain_id = ALC269_FIXUP_THINKPAD_ACPI, |
4437 | }, | 4437 | }, |
4438 | [ALC269VB_FIXUP_ASUS_ZENBOOK] = { | 4438 | [ALC269VB_FIXUP_ASUS_ZENBOOK] = { |
4439 | .type = HDA_FIXUP_FUNC, | 4439 | .type = HDA_FIXUP_FUNC, |
4440 | .v.func = alc269_fixup_limit_int_mic_boost, | 4440 | .v.func = alc269_fixup_limit_int_mic_boost, |
4441 | .chained = true, | 4441 | .chained = true, |
4442 | .chain_id = ALC269VB_FIXUP_DMIC, | 4442 | .chain_id = ALC269VB_FIXUP_DMIC, |
4443 | }, | 4443 | }, |
4444 | [ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A] = { | 4444 | [ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A] = { |
4445 | .type = HDA_FIXUP_VERBS, | 4445 | .type = HDA_FIXUP_VERBS, |
4446 | .v.verbs = (const struct hda_verb[]) { | 4446 | .v.verbs = (const struct hda_verb[]) { |
4447 | /* class-D output amp +5dB */ | 4447 | /* class-D output amp +5dB */ |
4448 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x12 }, | 4448 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x12 }, |
4449 | { 0x20, AC_VERB_SET_PROC_COEF, 0x2800 }, | 4449 | { 0x20, AC_VERB_SET_PROC_COEF, 0x2800 }, |
4450 | {} | 4450 | {} |
4451 | }, | 4451 | }, |
4452 | .chained = true, | 4452 | .chained = true, |
4453 | .chain_id = ALC269VB_FIXUP_ASUS_ZENBOOK, | 4453 | .chain_id = ALC269VB_FIXUP_ASUS_ZENBOOK, |
4454 | }, | 4454 | }, |
4455 | [ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED] = { | 4455 | [ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED] = { |
4456 | .type = HDA_FIXUP_FUNC, | 4456 | .type = HDA_FIXUP_FUNC, |
4457 | .v.func = alc269_fixup_limit_int_mic_boost, | 4457 | .v.func = alc269_fixup_limit_int_mic_boost, |
4458 | .chained = true, | 4458 | .chained = true, |
4459 | .chain_id = ALC269_FIXUP_HP_MUTE_LED_MIC1, | 4459 | .chain_id = ALC269_FIXUP_HP_MUTE_LED_MIC1, |
4460 | }, | 4460 | }, |
4461 | [ALC269VB_FIXUP_ORDISSIMO_EVE2] = { | 4461 | [ALC269VB_FIXUP_ORDISSIMO_EVE2] = { |
4462 | .type = HDA_FIXUP_PINS, | 4462 | .type = HDA_FIXUP_PINS, |
4463 | .v.pins = (const struct hda_pintbl[]) { | 4463 | .v.pins = (const struct hda_pintbl[]) { |
4464 | { 0x12, 0x99a3092f }, /* int-mic */ | 4464 | { 0x12, 0x99a3092f }, /* int-mic */ |
4465 | { 0x18, 0x03a11d20 }, /* mic */ | 4465 | { 0x18, 0x03a11d20 }, /* mic */ |
4466 | { 0x19, 0x411111f0 }, /* Unused bogus pin */ | 4466 | { 0x19, 0x411111f0 }, /* Unused bogus pin */ |
4467 | { } | 4467 | { } |
4468 | }, | 4468 | }, |
4469 | }, | 4469 | }, |
4470 | [ALC283_FIXUP_CHROME_BOOK] = { | 4470 | [ALC283_FIXUP_CHROME_BOOK] = { |
4471 | .type = HDA_FIXUP_FUNC, | 4471 | .type = HDA_FIXUP_FUNC, |
4472 | .v.func = alc283_fixup_chromebook, | 4472 | .v.func = alc283_fixup_chromebook, |
4473 | }, | 4473 | }, |
4474 | [ALC283_FIXUP_SENSE_COMBO_JACK] = { | 4474 | [ALC283_FIXUP_SENSE_COMBO_JACK] = { |
4475 | .type = HDA_FIXUP_FUNC, | 4475 | .type = HDA_FIXUP_FUNC, |
4476 | .v.func = alc283_fixup_sense_combo_jack, | 4476 | .v.func = alc283_fixup_sense_combo_jack, |
4477 | .chained = true, | 4477 | .chained = true, |
4478 | .chain_id = ALC283_FIXUP_CHROME_BOOK, | 4478 | .chain_id = ALC283_FIXUP_CHROME_BOOK, |
4479 | }, | 4479 | }, |
4480 | [ALC282_FIXUP_ASUS_TX300] = { | 4480 | [ALC282_FIXUP_ASUS_TX300] = { |
4481 | .type = HDA_FIXUP_FUNC, | 4481 | .type = HDA_FIXUP_FUNC, |
4482 | .v.func = alc282_fixup_asus_tx300, | 4482 | .v.func = alc282_fixup_asus_tx300, |
4483 | }, | 4483 | }, |
4484 | [ALC283_FIXUP_INT_MIC] = { | 4484 | [ALC283_FIXUP_INT_MIC] = { |
4485 | .type = HDA_FIXUP_VERBS, | 4485 | .type = HDA_FIXUP_VERBS, |
4486 | .v.verbs = (const struct hda_verb[]) { | 4486 | .v.verbs = (const struct hda_verb[]) { |
4487 | {0x20, AC_VERB_SET_COEF_INDEX, 0x1a}, | 4487 | {0x20, AC_VERB_SET_COEF_INDEX, 0x1a}, |
4488 | {0x20, AC_VERB_SET_PROC_COEF, 0x0011}, | 4488 | {0x20, AC_VERB_SET_PROC_COEF, 0x0011}, |
4489 | { } | 4489 | { } |
4490 | }, | 4490 | }, |
4491 | .chained = true, | 4491 | .chained = true, |
4492 | .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST | 4492 | .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST |
4493 | }, | 4493 | }, |
4494 | [ALC290_FIXUP_SUBWOOFER_HSJACK] = { | 4494 | [ALC290_FIXUP_SUBWOOFER_HSJACK] = { |
4495 | .type = HDA_FIXUP_PINS, | 4495 | .type = HDA_FIXUP_PINS, |
4496 | .v.pins = (const struct hda_pintbl[]) { | 4496 | .v.pins = (const struct hda_pintbl[]) { |
4497 | { 0x17, 0x90170112 }, /* subwoofer */ | 4497 | { 0x17, 0x90170112 }, /* subwoofer */ |
4498 | { } | 4498 | { } |
4499 | }, | 4499 | }, |
4500 | .chained = true, | 4500 | .chained = true, |
4501 | .chain_id = ALC290_FIXUP_MONO_SPEAKERS_HSJACK, | 4501 | .chain_id = ALC290_FIXUP_MONO_SPEAKERS_HSJACK, |
4502 | }, | 4502 | }, |
4503 | [ALC290_FIXUP_SUBWOOFER] = { | 4503 | [ALC290_FIXUP_SUBWOOFER] = { |
4504 | .type = HDA_FIXUP_PINS, | 4504 | .type = HDA_FIXUP_PINS, |
4505 | .v.pins = (const struct hda_pintbl[]) { | 4505 | .v.pins = (const struct hda_pintbl[]) { |
4506 | { 0x17, 0x90170112 }, /* subwoofer */ | 4506 | { 0x17, 0x90170112 }, /* subwoofer */ |
4507 | { } | 4507 | { } |
4508 | }, | 4508 | }, |
4509 | .chained = true, | 4509 | .chained = true, |
4510 | .chain_id = ALC290_FIXUP_MONO_SPEAKERS, | 4510 | .chain_id = ALC290_FIXUP_MONO_SPEAKERS, |
4511 | }, | 4511 | }, |
4512 | [ALC290_FIXUP_MONO_SPEAKERS] = { | 4512 | [ALC290_FIXUP_MONO_SPEAKERS] = { |
4513 | .type = HDA_FIXUP_FUNC, | 4513 | .type = HDA_FIXUP_FUNC, |
4514 | .v.func = alc290_fixup_mono_speakers, | 4514 | .v.func = alc290_fixup_mono_speakers, |
4515 | }, | 4515 | }, |
4516 | [ALC290_FIXUP_MONO_SPEAKERS_HSJACK] = { | 4516 | [ALC290_FIXUP_MONO_SPEAKERS_HSJACK] = { |
4517 | .type = HDA_FIXUP_FUNC, | 4517 | .type = HDA_FIXUP_FUNC, |
4518 | .v.func = alc290_fixup_mono_speakers, | 4518 | .v.func = alc290_fixup_mono_speakers, |
4519 | .chained = true, | 4519 | .chained = true, |
4520 | .chain_id = ALC269_FIXUP_DELL3_MIC_NO_PRESENCE, | 4520 | .chain_id = ALC269_FIXUP_DELL3_MIC_NO_PRESENCE, |
4521 | }, | 4521 | }, |
4522 | [ALC269_FIXUP_THINKPAD_ACPI] = { | 4522 | [ALC269_FIXUP_THINKPAD_ACPI] = { |
4523 | .type = HDA_FIXUP_FUNC, | 4523 | .type = HDA_FIXUP_FUNC, |
4524 | .v.func = hda_fixup_thinkpad_acpi, | 4524 | .v.func = hda_fixup_thinkpad_acpi, |
4525 | }, | 4525 | }, |
4526 | [ALC255_FIXUP_DELL1_MIC_NO_PRESENCE] = { | 4526 | [ALC255_FIXUP_DELL1_MIC_NO_PRESENCE] = { |
4527 | .type = HDA_FIXUP_PINS, | 4527 | .type = HDA_FIXUP_PINS, |
4528 | .v.pins = (const struct hda_pintbl[]) { | 4528 | .v.pins = (const struct hda_pintbl[]) { |
4529 | { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */ | 4529 | { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */ |
4530 | { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */ | 4530 | { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */ |
4531 | { } | 4531 | { } |
4532 | }, | 4532 | }, |
4533 | .chained = true, | 4533 | .chained = true, |
4534 | .chain_id = ALC255_FIXUP_HEADSET_MODE | 4534 | .chain_id = ALC255_FIXUP_HEADSET_MODE |
4535 | }, | 4535 | }, |
4536 | [ALC255_FIXUP_DELL2_MIC_NO_PRESENCE] = { | 4536 | [ALC255_FIXUP_DELL2_MIC_NO_PRESENCE] = { |
4537 | .type = HDA_FIXUP_PINS, | 4537 | .type = HDA_FIXUP_PINS, |
4538 | .v.pins = (const struct hda_pintbl[]) { | 4538 | .v.pins = (const struct hda_pintbl[]) { |
4539 | { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */ | 4539 | { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */ |
4540 | { } | 4540 | { } |
4541 | }, | 4541 | }, |
4542 | .chained = true, | 4542 | .chained = true, |
4543 | .chain_id = ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC | 4543 | .chain_id = ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC |
4544 | }, | 4544 | }, |
4545 | [ALC255_FIXUP_HEADSET_MODE] = { | 4545 | [ALC255_FIXUP_HEADSET_MODE] = { |
4546 | .type = HDA_FIXUP_FUNC, | 4546 | .type = HDA_FIXUP_FUNC, |
4547 | .v.func = alc_fixup_headset_mode_alc255, | 4547 | .v.func = alc_fixup_headset_mode_alc255, |
4548 | }, | 4548 | }, |
4549 | [ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC] = { | 4549 | [ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC] = { |
4550 | .type = HDA_FIXUP_FUNC, | 4550 | .type = HDA_FIXUP_FUNC, |
4551 | .v.func = alc_fixup_headset_mode_alc255_no_hp_mic, | 4551 | .v.func = alc_fixup_headset_mode_alc255_no_hp_mic, |
4552 | }, | 4552 | }, |
4553 | }; | 4553 | }; |
4554 | 4554 | ||
4555 | static const struct snd_pci_quirk alc269_fixup_tbl[] = { | 4555 | static const struct snd_pci_quirk alc269_fixup_tbl[] = { |
4556 | SND_PCI_QUIRK(0x1025, 0x0283, "Acer TravelMate 8371", ALC269_FIXUP_INV_DMIC), | 4556 | SND_PCI_QUIRK(0x1025, 0x0283, "Acer TravelMate 8371", ALC269_FIXUP_INV_DMIC), |
4557 | SND_PCI_QUIRK(0x1025, 0x029b, "Acer 1810TZ", ALC269_FIXUP_INV_DMIC), | 4557 | SND_PCI_QUIRK(0x1025, 0x029b, "Acer 1810TZ", ALC269_FIXUP_INV_DMIC), |
4558 | SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC), | 4558 | SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC), |
4559 | SND_PCI_QUIRK(0x1025, 0x047c, "Acer AC700", ALC269_FIXUP_ACER_AC700), | 4559 | SND_PCI_QUIRK(0x1025, 0x047c, "Acer AC700", ALC269_FIXUP_ACER_AC700), |
4560 | SND_PCI_QUIRK(0x1025, 0x0740, "Acer AO725", ALC271_FIXUP_HP_GATE_MIC_JACK), | 4560 | SND_PCI_QUIRK(0x1025, 0x0740, "Acer AO725", ALC271_FIXUP_HP_GATE_MIC_JACK), |
4561 | SND_PCI_QUIRK(0x1025, 0x0742, "Acer AO756", ALC271_FIXUP_HP_GATE_MIC_JACK), | 4561 | SND_PCI_QUIRK(0x1025, 0x0742, "Acer AO756", ALC271_FIXUP_HP_GATE_MIC_JACK), |
4562 | SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC), | 4562 | SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC), |
4563 | SND_PCI_QUIRK(0x1025, 0x0775, "Acer Aspire E1-572", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572), | 4563 | SND_PCI_QUIRK(0x1025, 0x0775, "Acer Aspire E1-572", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572), |
4564 | SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), | 4564 | SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), |
4565 | SND_PCI_QUIRK(0x1028, 0x05bd, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), | 4565 | SND_PCI_QUIRK(0x1028, 0x05bd, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), |
4566 | SND_PCI_QUIRK(0x1028, 0x05be, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), | 4566 | SND_PCI_QUIRK(0x1028, 0x05be, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), |
4567 | SND_PCI_QUIRK(0x1028, 0x05c4, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4567 | SND_PCI_QUIRK(0x1028, 0x05c4, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4568 | SND_PCI_QUIRK(0x1028, 0x05c5, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4568 | SND_PCI_QUIRK(0x1028, 0x05c5, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4569 | SND_PCI_QUIRK(0x1028, 0x05c6, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4569 | SND_PCI_QUIRK(0x1028, 0x05c6, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4570 | SND_PCI_QUIRK(0x1028, 0x05c7, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4570 | SND_PCI_QUIRK(0x1028, 0x05c7, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4571 | SND_PCI_QUIRK(0x1028, 0x05c8, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4571 | SND_PCI_QUIRK(0x1028, 0x05c8, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4572 | SND_PCI_QUIRK(0x1028, 0x05c9, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4572 | SND_PCI_QUIRK(0x1028, 0x05c9, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4573 | SND_PCI_QUIRK(0x1028, 0x05ca, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), | 4573 | SND_PCI_QUIRK(0x1028, 0x05ca, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), |
4574 | SND_PCI_QUIRK(0x1028, 0x05cb, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), | 4574 | SND_PCI_QUIRK(0x1028, 0x05cb, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), |
4575 | SND_PCI_QUIRK(0x1028, 0x05cc, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), | 4575 | SND_PCI_QUIRK(0x1028, 0x05cc, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), |
4576 | SND_PCI_QUIRK(0x1028, 0x05cd, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), | 4576 | SND_PCI_QUIRK(0x1028, 0x05cd, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), |
4577 | SND_PCI_QUIRK(0x1028, 0x05da, "Dell Vostro 5460", ALC290_FIXUP_SUBWOOFER), | 4577 | SND_PCI_QUIRK(0x1028, 0x05da, "Dell Vostro 5460", ALC290_FIXUP_SUBWOOFER), |
4578 | SND_PCI_QUIRK(0x1028, 0x05de, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), | 4578 | SND_PCI_QUIRK(0x1028, 0x05de, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), |
4579 | SND_PCI_QUIRK(0x1028, 0x05e0, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), | 4579 | SND_PCI_QUIRK(0x1028, 0x05e0, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), |
4580 | SND_PCI_QUIRK(0x1028, 0x05e9, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4580 | SND_PCI_QUIRK(0x1028, 0x05e9, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4581 | SND_PCI_QUIRK(0x1028, 0x05ea, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4581 | SND_PCI_QUIRK(0x1028, 0x05ea, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4582 | SND_PCI_QUIRK(0x1028, 0x05eb, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4582 | SND_PCI_QUIRK(0x1028, 0x05eb, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4583 | SND_PCI_QUIRK(0x1028, 0x05ec, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4583 | SND_PCI_QUIRK(0x1028, 0x05ec, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4584 | SND_PCI_QUIRK(0x1028, 0x05ed, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4584 | SND_PCI_QUIRK(0x1028, 0x05ed, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4585 | SND_PCI_QUIRK(0x1028, 0x05ee, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4585 | SND_PCI_QUIRK(0x1028, 0x05ee, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4586 | SND_PCI_QUIRK(0x1028, 0x05f3, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4586 | SND_PCI_QUIRK(0x1028, 0x05f3, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4587 | SND_PCI_QUIRK(0x1028, 0x05f4, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4587 | SND_PCI_QUIRK(0x1028, 0x05f4, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4588 | SND_PCI_QUIRK(0x1028, 0x05f5, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4588 | SND_PCI_QUIRK(0x1028, 0x05f5, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4589 | SND_PCI_QUIRK(0x1028, 0x05f6, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4589 | SND_PCI_QUIRK(0x1028, 0x05f6, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4590 | SND_PCI_QUIRK(0x1028, 0x05f8, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4590 | SND_PCI_QUIRK(0x1028, 0x05f8, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4591 | SND_PCI_QUIRK(0x1028, 0x05f9, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4591 | SND_PCI_QUIRK(0x1028, 0x05f9, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4592 | SND_PCI_QUIRK(0x1028, 0x05fb, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4592 | SND_PCI_QUIRK(0x1028, 0x05fb, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4593 | SND_PCI_QUIRK(0x1028, 0x0606, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4593 | SND_PCI_QUIRK(0x1028, 0x0606, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4594 | SND_PCI_QUIRK(0x1028, 0x0608, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4594 | SND_PCI_QUIRK(0x1028, 0x0608, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4595 | SND_PCI_QUIRK(0x1028, 0x0609, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4595 | SND_PCI_QUIRK(0x1028, 0x0609, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4596 | SND_PCI_QUIRK(0x1028, 0x060f, "Dell", ALC269_FIXUP_DELL3_MIC_NO_PRESENCE), | 4596 | SND_PCI_QUIRK(0x1028, 0x060f, "Dell", ALC269_FIXUP_DELL3_MIC_NO_PRESENCE), |
4597 | SND_PCI_QUIRK(0x1028, 0x0610, "Dell", ALC269_FIXUP_DELL3_MIC_NO_PRESENCE), | 4597 | SND_PCI_QUIRK(0x1028, 0x0610, "Dell", ALC269_FIXUP_DELL3_MIC_NO_PRESENCE), |
4598 | SND_PCI_QUIRK(0x1028, 0x0613, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4598 | SND_PCI_QUIRK(0x1028, 0x0613, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4599 | SND_PCI_QUIRK(0x1028, 0x0614, "Dell Inspiron 3135", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4599 | SND_PCI_QUIRK(0x1028, 0x0614, "Dell Inspiron 3135", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4600 | SND_PCI_QUIRK(0x1028, 0x0615, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK), | 4600 | SND_PCI_QUIRK(0x1028, 0x0615, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK), |
4601 | SND_PCI_QUIRK(0x1028, 0x0616, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK), | 4601 | SND_PCI_QUIRK(0x1028, 0x0616, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK), |
4602 | SND_PCI_QUIRK(0x1028, 0x061f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4602 | SND_PCI_QUIRK(0x1028, 0x061f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4603 | SND_PCI_QUIRK(0x1028, 0x0629, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4603 | SND_PCI_QUIRK(0x1028, 0x0629, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4604 | SND_PCI_QUIRK(0x1028, 0x062c, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4604 | SND_PCI_QUIRK(0x1028, 0x062c, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4605 | SND_PCI_QUIRK(0x1028, 0x062e, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4605 | SND_PCI_QUIRK(0x1028, 0x062e, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4606 | SND_PCI_QUIRK(0x1028, 0x0632, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4606 | SND_PCI_QUIRK(0x1028, 0x0632, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4607 | SND_PCI_QUIRK(0x1028, 0x0638, "Dell Inspiron 5439", ALC290_FIXUP_MONO_SPEAKERS_HSJACK), | 4607 | SND_PCI_QUIRK(0x1028, 0x0638, "Dell Inspiron 5439", ALC290_FIXUP_MONO_SPEAKERS_HSJACK), |
4608 | SND_PCI_QUIRK(0x1028, 0x063e, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4608 | SND_PCI_QUIRK(0x1028, 0x063e, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4609 | SND_PCI_QUIRK(0x1028, 0x063f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4609 | SND_PCI_QUIRK(0x1028, 0x063f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4610 | SND_PCI_QUIRK(0x1028, 0x0640, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4610 | SND_PCI_QUIRK(0x1028, 0x0640, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4611 | SND_PCI_QUIRK(0x1028, 0x064d, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4611 | SND_PCI_QUIRK(0x1028, 0x064d, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4612 | SND_PCI_QUIRK(0x1028, 0x0651, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4612 | SND_PCI_QUIRK(0x1028, 0x0651, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4613 | SND_PCI_QUIRK(0x1028, 0x0652, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4613 | SND_PCI_QUIRK(0x1028, 0x0652, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4614 | SND_PCI_QUIRK(0x1028, 0x0653, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4614 | SND_PCI_QUIRK(0x1028, 0x0653, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4615 | SND_PCI_QUIRK(0x1028, 0x0657, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4615 | SND_PCI_QUIRK(0x1028, 0x0657, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4616 | SND_PCI_QUIRK(0x1028, 0x0658, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4616 | SND_PCI_QUIRK(0x1028, 0x0658, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4617 | SND_PCI_QUIRK(0x1028, 0x065c, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4617 | SND_PCI_QUIRK(0x1028, 0x065c, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4618 | SND_PCI_QUIRK(0x1028, 0x065f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4618 | SND_PCI_QUIRK(0x1028, 0x065f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4619 | SND_PCI_QUIRK(0x1028, 0x0662, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4619 | SND_PCI_QUIRK(0x1028, 0x0662, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4620 | SND_PCI_QUIRK(0x1028, 0x0667, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4620 | SND_PCI_QUIRK(0x1028, 0x0667, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4621 | SND_PCI_QUIRK(0x1028, 0x0668, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE), | 4621 | SND_PCI_QUIRK(0x1028, 0x0668, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE), |
4622 | SND_PCI_QUIRK(0x1028, 0x0669, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE), | 4622 | SND_PCI_QUIRK(0x1028, 0x0669, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE), |
4623 | SND_PCI_QUIRK(0x1028, 0x0674, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4623 | SND_PCI_QUIRK(0x1028, 0x0674, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4624 | SND_PCI_QUIRK(0x1028, 0x067e, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4624 | SND_PCI_QUIRK(0x1028, 0x067e, "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, 0x067f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4626 | SND_PCI_QUIRK(0x1028, 0x0680, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4626 | SND_PCI_QUIRK(0x1028, 0x0680, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4627 | SND_PCI_QUIRK(0x1028, 0x0684, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), | 4627 | SND_PCI_QUIRK(0x1028, 0x0684, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), |
4628 | SND_PCI_QUIRK(0x1028, 0x15cc, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), | 4628 | SND_PCI_QUIRK(0x1028, 0x15cc, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), |
4629 | SND_PCI_QUIRK(0x1028, 0x15cd, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), | 4629 | SND_PCI_QUIRK(0x1028, 0x15cd, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), |
4630 | SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2), | 4630 | SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2), |
4631 | SND_PCI_QUIRK(0x103c, 0x18e6, "HP", ALC269_FIXUP_HP_GPIO_LED), | 4631 | SND_PCI_QUIRK(0x103c, 0x18e6, "HP", ALC269_FIXUP_HP_GPIO_LED), |
4632 | SND_PCI_QUIRK(0x103c, 0x1973, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4632 | SND_PCI_QUIRK(0x103c, 0x1973, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4633 | SND_PCI_QUIRK(0x103c, 0x1983, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4633 | SND_PCI_QUIRK(0x103c, 0x1983, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4634 | SND_PCI_QUIRK(0x103c, 0x218b, "HP", ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED), | 4634 | SND_PCI_QUIRK(0x103c, 0x218b, "HP", ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED), |
4635 | /* ALC282 */ | 4635 | /* ALC282 */ |
4636 | SND_PCI_QUIRK(0x103c, 0x220f, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4636 | SND_PCI_QUIRK(0x103c, 0x220f, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4637 | SND_PCI_QUIRK(0x103c, 0x2213, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4637 | SND_PCI_QUIRK(0x103c, 0x2213, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4638 | SND_PCI_QUIRK(0x103c, 0x2266, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4638 | SND_PCI_QUIRK(0x103c, 0x2266, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4639 | SND_PCI_QUIRK(0x103c, 0x2267, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4639 | SND_PCI_QUIRK(0x103c, 0x2267, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4640 | SND_PCI_QUIRK(0x103c, 0x2268, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4640 | SND_PCI_QUIRK(0x103c, 0x2268, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4641 | SND_PCI_QUIRK(0x103c, 0x2269, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4641 | SND_PCI_QUIRK(0x103c, 0x2269, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4642 | SND_PCI_QUIRK(0x103c, 0x226a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4642 | SND_PCI_QUIRK(0x103c, 0x226a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4643 | SND_PCI_QUIRK(0x103c, 0x226b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4643 | SND_PCI_QUIRK(0x103c, 0x226b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4644 | SND_PCI_QUIRK(0x103c, 0x227a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4644 | SND_PCI_QUIRK(0x103c, 0x227a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4645 | SND_PCI_QUIRK(0x103c, 0x227b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4645 | SND_PCI_QUIRK(0x103c, 0x227b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4646 | SND_PCI_QUIRK(0x103c, 0x229e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4646 | SND_PCI_QUIRK(0x103c, 0x229e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4647 | SND_PCI_QUIRK(0x103c, 0x22a0, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4647 | SND_PCI_QUIRK(0x103c, 0x22a0, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4648 | SND_PCI_QUIRK(0x103c, 0x22b2, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4648 | SND_PCI_QUIRK(0x103c, 0x22b2, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4649 | SND_PCI_QUIRK(0x103c, 0x22b7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4649 | SND_PCI_QUIRK(0x103c, 0x22b7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4650 | SND_PCI_QUIRK(0x103c, 0x22bf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4650 | SND_PCI_QUIRK(0x103c, 0x22bf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4651 | SND_PCI_QUIRK(0x103c, 0x22c0, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4651 | SND_PCI_QUIRK(0x103c, 0x22c0, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4652 | SND_PCI_QUIRK(0x103c, 0x22c1, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4652 | SND_PCI_QUIRK(0x103c, 0x22c1, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4653 | SND_PCI_QUIRK(0x103c, 0x22c2, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4653 | SND_PCI_QUIRK(0x103c, 0x22c2, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4654 | SND_PCI_QUIRK(0x103c, 0x22cd, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4654 | SND_PCI_QUIRK(0x103c, 0x22cd, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4655 | SND_PCI_QUIRK(0x103c, 0x22ce, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4655 | SND_PCI_QUIRK(0x103c, 0x22ce, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4656 | SND_PCI_QUIRK(0x103c, 0x22cf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4656 | SND_PCI_QUIRK(0x103c, 0x22cf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4657 | SND_PCI_QUIRK(0x103c, 0x22d0, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4657 | SND_PCI_QUIRK(0x103c, 0x22d0, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4658 | /* ALC290 */ | 4658 | /* ALC290 */ |
4659 | SND_PCI_QUIRK(0x103c, 0x2260, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4659 | SND_PCI_QUIRK(0x103c, 0x2260, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4660 | SND_PCI_QUIRK(0x103c, 0x2261, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4660 | SND_PCI_QUIRK(0x103c, 0x2261, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4661 | SND_PCI_QUIRK(0x103c, 0x2262, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4661 | SND_PCI_QUIRK(0x103c, 0x2262, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4662 | SND_PCI_QUIRK(0x103c, 0x2263, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4662 | SND_PCI_QUIRK(0x103c, 0x2263, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4663 | SND_PCI_QUIRK(0x103c, 0x2264, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4663 | SND_PCI_QUIRK(0x103c, 0x2264, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4664 | SND_PCI_QUIRK(0x103c, 0x2265, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4664 | SND_PCI_QUIRK(0x103c, 0x2265, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4665 | SND_PCI_QUIRK(0x103c, 0x227d, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4665 | SND_PCI_QUIRK(0x103c, 0x227d, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4666 | SND_PCI_QUIRK(0x103c, 0x227e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4666 | SND_PCI_QUIRK(0x103c, 0x227e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4667 | SND_PCI_QUIRK(0x103c, 0x227f, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4667 | SND_PCI_QUIRK(0x103c, 0x227f, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4668 | SND_PCI_QUIRK(0x103c, 0x2280, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4668 | SND_PCI_QUIRK(0x103c, 0x2280, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4669 | SND_PCI_QUIRK(0x103c, 0x2281, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4669 | SND_PCI_QUIRK(0x103c, 0x2281, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4670 | SND_PCI_QUIRK(0x103c, 0x2282, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4670 | SND_PCI_QUIRK(0x103c, 0x2282, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4671 | SND_PCI_QUIRK(0x103c, 0x2289, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4671 | SND_PCI_QUIRK(0x103c, 0x2289, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4672 | SND_PCI_QUIRK(0x103c, 0x228a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4672 | SND_PCI_QUIRK(0x103c, 0x228a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4673 | SND_PCI_QUIRK(0x103c, 0x228b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4673 | SND_PCI_QUIRK(0x103c, 0x228b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4674 | SND_PCI_QUIRK(0x103c, 0x228c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4674 | SND_PCI_QUIRK(0x103c, 0x228c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4675 | SND_PCI_QUIRK(0x103c, 0x228d, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4675 | SND_PCI_QUIRK(0x103c, 0x228d, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4676 | SND_PCI_QUIRK(0x103c, 0x228e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4676 | SND_PCI_QUIRK(0x103c, 0x228e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4677 | SND_PCI_QUIRK(0x103c, 0x22c5, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4677 | SND_PCI_QUIRK(0x103c, 0x22c5, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4678 | SND_PCI_QUIRK(0x103c, 0x22c6, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4678 | SND_PCI_QUIRK(0x103c, 0x22c6, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4679 | SND_PCI_QUIRK(0x103c, 0x22c7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4679 | SND_PCI_QUIRK(0x103c, 0x22c7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4680 | SND_PCI_QUIRK(0x103c, 0x22c8, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4680 | SND_PCI_QUIRK(0x103c, 0x22c8, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4681 | SND_PCI_QUIRK(0x103c, 0x22c3, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4681 | SND_PCI_QUIRK(0x103c, 0x22c3, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4682 | SND_PCI_QUIRK(0x103c, 0x22c4, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4682 | SND_PCI_QUIRK(0x103c, 0x22c4, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4683 | SND_PCI_QUIRK_VENDOR(0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED), | 4683 | SND_PCI_QUIRK_VENDOR(0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED), |
4684 | SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300), | 4684 | SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300), |
4685 | SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), | 4685 | SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
4686 | SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), | 4686 | SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
4687 | SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK), | 4687 | SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK), |
4688 | SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A), | 4688 | SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A), |
4689 | SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC), | 4689 | SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC), |
4690 | SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), | 4690 | SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), |
4691 | SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC), | 4691 | SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC), |
4692 | SND_PCI_QUIRK(0x1043, 0x1c23, "Asus X55U", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), | 4692 | SND_PCI_QUIRK(0x1043, 0x1c23, "Asus X55U", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
4693 | SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC), | 4693 | SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC), |
4694 | SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC), | 4694 | SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC), |
4695 | SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC), | 4695 | SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC), |
4696 | SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC), | 4696 | SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC), |
4697 | SND_PCI_QUIRK(0x1043, 0x8516, "ASUS X101CH", ALC269_FIXUP_ASUS_X101), | 4697 | SND_PCI_QUIRK(0x1043, 0x8516, "ASUS X101CH", ALC269_FIXUP_ASUS_X101), |
4698 | SND_PCI_QUIRK(0x104d, 0x90b5, "Sony VAIO Pro 11", ALC286_FIXUP_SONY_MIC_NO_PRESENCE), | 4698 | SND_PCI_QUIRK(0x104d, 0x90b5, "Sony VAIO Pro 11", ALC286_FIXUP_SONY_MIC_NO_PRESENCE), |
4699 | SND_PCI_QUIRK(0x104d, 0x90b6, "Sony VAIO Pro 13", ALC286_FIXUP_SONY_MIC_NO_PRESENCE), | 4699 | SND_PCI_QUIRK(0x104d, 0x90b6, "Sony VAIO Pro 13", ALC286_FIXUP_SONY_MIC_NO_PRESENCE), |
4700 | SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2), | 4700 | SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2), |
4701 | SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), | 4701 | SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), |
4702 | SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), | 4702 | SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), |
4703 | SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), | 4703 | SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), |
4704 | SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook", ALC269_FIXUP_LIFEBOOK), | 4704 | SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook", ALC269_FIXUP_LIFEBOOK), |
4705 | SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE), | 4705 | SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE), |
4706 | SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE), | 4706 | SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE), |
4707 | SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE), | 4707 | SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE), |
4708 | SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE), | 4708 | SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE), |
4709 | SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE), | 4709 | SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE), |
4710 | SND_PCI_QUIRK(0x17aa, 0x21f6, "Thinkpad T530", ALC269_FIXUP_LENOVO_DOCK), | 4710 | SND_PCI_QUIRK(0x17aa, 0x21f6, "Thinkpad T530", ALC269_FIXUP_LENOVO_DOCK), |
4711 | SND_PCI_QUIRK(0x17aa, 0x21fa, "Thinkpad X230", ALC269_FIXUP_LENOVO_DOCK), | 4711 | SND_PCI_QUIRK(0x17aa, 0x21fa, "Thinkpad X230", ALC269_FIXUP_LENOVO_DOCK), |
4712 | SND_PCI_QUIRK(0x17aa, 0x21f3, "Thinkpad T430", ALC269_FIXUP_LENOVO_DOCK), | 4712 | SND_PCI_QUIRK(0x17aa, 0x21f3, "Thinkpad T430", ALC269_FIXUP_LENOVO_DOCK), |
4713 | SND_PCI_QUIRK(0x17aa, 0x21fb, "Thinkpad T430s", ALC269_FIXUP_LENOVO_DOCK), | 4713 | SND_PCI_QUIRK(0x17aa, 0x21fb, "Thinkpad T430s", ALC269_FIXUP_LENOVO_DOCK), |
4714 | SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK), | 4714 | SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK), |
4715 | SND_PCI_QUIRK(0x17aa, 0x2208, "Thinkpad T431s", ALC269_FIXUP_LENOVO_DOCK), | 4715 | SND_PCI_QUIRK(0x17aa, 0x2208, "Thinkpad T431s", ALC269_FIXUP_LENOVO_DOCK), |
4716 | SND_PCI_QUIRK(0x17aa, 0x220c, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), | 4716 | SND_PCI_QUIRK(0x17aa, 0x220c, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
4717 | SND_PCI_QUIRK(0x17aa, 0x2212, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), | 4717 | SND_PCI_QUIRK(0x17aa, 0x2212, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
4718 | SND_PCI_QUIRK(0x17aa, 0x2214, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), | 4718 | SND_PCI_QUIRK(0x17aa, 0x2214, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
4719 | SND_PCI_QUIRK(0x17aa, 0x2215, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), | 4719 | SND_PCI_QUIRK(0x17aa, 0x2215, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
4720 | SND_PCI_QUIRK(0x17aa, 0x3978, "IdeaPad Y410P", ALC269_FIXUP_NO_SHUTUP), | 4720 | SND_PCI_QUIRK(0x17aa, 0x3978, "IdeaPad Y410P", ALC269_FIXUP_NO_SHUTUP), |
4721 | SND_PCI_QUIRK(0x17aa, 0x5013, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), | 4721 | SND_PCI_QUIRK(0x17aa, 0x5013, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
4722 | SND_PCI_QUIRK(0x17aa, 0x501a, "Thinkpad", ALC283_FIXUP_INT_MIC), | 4722 | SND_PCI_QUIRK(0x17aa, 0x501a, "Thinkpad", ALC283_FIXUP_INT_MIC), |
4723 | SND_PCI_QUIRK(0x17aa, 0x5026, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), | 4723 | SND_PCI_QUIRK(0x17aa, 0x5026, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
4724 | SND_PCI_QUIRK(0x17aa, 0x5109, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), | 4724 | SND_PCI_QUIRK(0x17aa, 0x5109, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
4725 | SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K), | 4725 | SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K), |
4726 | SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD), | 4726 | SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD), |
4727 | SND_PCI_QUIRK_VENDOR(0x17aa, "Thinkpad", ALC269_FIXUP_THINKPAD_ACPI), | 4727 | SND_PCI_QUIRK_VENDOR(0x17aa, "Thinkpad", ALC269_FIXUP_THINKPAD_ACPI), |
4728 | SND_PCI_QUIRK(0x1b7d, 0xa831, "Ordissimo EVE2 ", ALC269VB_FIXUP_ORDISSIMO_EVE2), /* Also known as Malata PC-B1303 */ | 4728 | SND_PCI_QUIRK(0x1b7d, 0xa831, "Ordissimo EVE2 ", ALC269VB_FIXUP_ORDISSIMO_EVE2), /* Also known as Malata PC-B1303 */ |
4729 | 4729 | ||
4730 | #if 0 | 4730 | #if 0 |
4731 | /* Below is a quirk table taken from the old code. | 4731 | /* Below is a quirk table taken from the old code. |
4732 | * Basically the device should work as is without the fixup table. | 4732 | * Basically the device should work as is without the fixup table. |
4733 | * If BIOS doesn't give a proper info, enable the corresponding | 4733 | * If BIOS doesn't give a proper info, enable the corresponding |
4734 | * fixup entry. | 4734 | * fixup entry. |
4735 | */ | 4735 | */ |
4736 | SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A", | 4736 | SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A", |
4737 | ALC269_FIXUP_AMIC), | 4737 | ALC269_FIXUP_AMIC), |
4738 | SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269_FIXUP_AMIC), | 4738 | SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269_FIXUP_AMIC), |
4739 | SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269_FIXUP_AMIC), | 4739 | SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269_FIXUP_AMIC), |
4740 | SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_FIXUP_AMIC), | 4740 | SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_FIXUP_AMIC), |
4741 | SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269_FIXUP_AMIC), | 4741 | SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269_FIXUP_AMIC), |
4742 | SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269_FIXUP_AMIC), | 4742 | SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269_FIXUP_AMIC), |
4743 | SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269_FIXUP_AMIC), | 4743 | SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269_FIXUP_AMIC), |
4744 | SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269_FIXUP_AMIC), | 4744 | SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269_FIXUP_AMIC), |
4745 | SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_FIXUP_AMIC), | 4745 | SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_FIXUP_AMIC), |
4746 | SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269_FIXUP_AMIC), | 4746 | SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269_FIXUP_AMIC), |
4747 | SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_FIXUP_AMIC), | 4747 | SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_FIXUP_AMIC), |
4748 | SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_FIXUP_AMIC), | 4748 | SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_FIXUP_AMIC), |
4749 | SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_FIXUP_AMIC), | 4749 | SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_FIXUP_AMIC), |
4750 | SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_FIXUP_AMIC), | 4750 | SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_FIXUP_AMIC), |
4751 | SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_FIXUP_AMIC), | 4751 | SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_FIXUP_AMIC), |
4752 | SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_FIXUP_AMIC), | 4752 | SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_FIXUP_AMIC), |
4753 | SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_FIXUP_AMIC), | 4753 | SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_FIXUP_AMIC), |
4754 | SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_FIXUP_AMIC), | 4754 | SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_FIXUP_AMIC), |
4755 | SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_FIXUP_AMIC), | 4755 | SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_FIXUP_AMIC), |
4756 | SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_FIXUP_AMIC), | 4756 | SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_FIXUP_AMIC), |
4757 | SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_FIXUP_AMIC), | 4757 | SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_FIXUP_AMIC), |
4758 | SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_FIXUP_AMIC), | 4758 | SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_FIXUP_AMIC), |
4759 | SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_FIXUP_AMIC), | 4759 | SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_FIXUP_AMIC), |
4760 | SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_FIXUP_AMIC), | 4760 | SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_FIXUP_AMIC), |
4761 | SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_FIXUP_AMIC), | 4761 | SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_FIXUP_AMIC), |
4762 | SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_FIXUP_AMIC), | 4762 | SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_FIXUP_AMIC), |
4763 | SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_FIXUP_AMIC), | 4763 | SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_FIXUP_AMIC), |
4764 | SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_FIXUP_AMIC), | 4764 | SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_FIXUP_AMIC), |
4765 | SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_FIXUP_AMIC), | 4765 | SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_FIXUP_AMIC), |
4766 | SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_FIXUP_AMIC), | 4766 | SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_FIXUP_AMIC), |
4767 | SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_FIXUP_AMIC), | 4767 | SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_FIXUP_AMIC), |
4768 | SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_FIXUP_AMIC), | 4768 | SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_FIXUP_AMIC), |
4769 | SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_FIXUP_AMIC), | 4769 | SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_FIXUP_AMIC), |
4770 | SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_FIXUP_AMIC), | 4770 | SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_FIXUP_AMIC), |
4771 | SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_FIXUP_AMIC), | 4771 | SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_FIXUP_AMIC), |
4772 | SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_FIXUP_DMIC), | 4772 | SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_FIXUP_DMIC), |
4773 | SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_FIXUP_AMIC), | 4773 | SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_FIXUP_AMIC), |
4774 | SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_AMIC), | 4774 | SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_AMIC), |
4775 | SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_FIXUP_DMIC), | 4775 | SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_FIXUP_DMIC), |
4776 | SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_FIXUP_DMIC), | 4776 | SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_FIXUP_DMIC), |
4777 | #endif | 4777 | #endif |
4778 | {} | 4778 | {} |
4779 | }; | 4779 | }; |
4780 | 4780 | ||
4781 | static const struct hda_model_fixup alc269_fixup_models[] = { | 4781 | static const struct hda_model_fixup alc269_fixup_models[] = { |
4782 | {.id = ALC269_FIXUP_AMIC, .name = "laptop-amic"}, | 4782 | {.id = ALC269_FIXUP_AMIC, .name = "laptop-amic"}, |
4783 | {.id = ALC269_FIXUP_DMIC, .name = "laptop-dmic"}, | 4783 | {.id = ALC269_FIXUP_DMIC, .name = "laptop-dmic"}, |
4784 | {.id = ALC269_FIXUP_STEREO_DMIC, .name = "alc269-dmic"}, | 4784 | {.id = ALC269_FIXUP_STEREO_DMIC, .name = "alc269-dmic"}, |
4785 | {.id = ALC271_FIXUP_DMIC, .name = "alc271-dmic"}, | 4785 | {.id = ALC271_FIXUP_DMIC, .name = "alc271-dmic"}, |
4786 | {.id = ALC269_FIXUP_INV_DMIC, .name = "inv-dmic"}, | 4786 | {.id = ALC269_FIXUP_INV_DMIC, .name = "inv-dmic"}, |
4787 | {.id = ALC269_FIXUP_HEADSET_MIC, .name = "headset-mic"}, | 4787 | {.id = ALC269_FIXUP_HEADSET_MIC, .name = "headset-mic"}, |
4788 | {.id = ALC269_FIXUP_LENOVO_DOCK, .name = "lenovo-dock"}, | 4788 | {.id = ALC269_FIXUP_LENOVO_DOCK, .name = "lenovo-dock"}, |
4789 | {.id = ALC269_FIXUP_HP_GPIO_LED, .name = "hp-gpio-led"}, | 4789 | {.id = ALC269_FIXUP_HP_GPIO_LED, .name = "hp-gpio-led"}, |
4790 | {.id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "dell-headset-multi"}, | 4790 | {.id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "dell-headset-multi"}, |
4791 | {.id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE, .name = "dell-headset-dock"}, | 4791 | {.id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE, .name = "dell-headset-dock"}, |
4792 | {.id = ALC283_FIXUP_CHROME_BOOK, .name = "alc283-dac-wcaps"}, | 4792 | {.id = ALC283_FIXUP_CHROME_BOOK, .name = "alc283-dac-wcaps"}, |
4793 | {.id = ALC283_FIXUP_SENSE_COMBO_JACK, .name = "alc283-sense-combo"}, | 4793 | {.id = ALC283_FIXUP_SENSE_COMBO_JACK, .name = "alc283-sense-combo"}, |
4794 | {} | 4794 | {} |
4795 | }; | 4795 | }; |
4796 | 4796 | ||
4797 | 4797 | ||
4798 | static void alc269_fill_coef(struct hda_codec *codec) | 4798 | static void alc269_fill_coef(struct hda_codec *codec) |
4799 | { | 4799 | { |
4800 | struct alc_spec *spec = codec->spec; | 4800 | struct alc_spec *spec = codec->spec; |
4801 | int val; | 4801 | int val; |
4802 | 4802 | ||
4803 | if (spec->codec_variant != ALC269_TYPE_ALC269VB) | 4803 | if (spec->codec_variant != ALC269_TYPE_ALC269VB) |
4804 | return; | 4804 | return; |
4805 | 4805 | ||
4806 | if ((alc_get_coef0(codec) & 0x00ff) < 0x015) { | 4806 | if ((alc_get_coef0(codec) & 0x00ff) < 0x015) { |
4807 | alc_write_coef_idx(codec, 0xf, 0x960b); | 4807 | alc_write_coef_idx(codec, 0xf, 0x960b); |
4808 | alc_write_coef_idx(codec, 0xe, 0x8817); | 4808 | alc_write_coef_idx(codec, 0xe, 0x8817); |
4809 | } | 4809 | } |
4810 | 4810 | ||
4811 | if ((alc_get_coef0(codec) & 0x00ff) == 0x016) { | 4811 | if ((alc_get_coef0(codec) & 0x00ff) == 0x016) { |
4812 | alc_write_coef_idx(codec, 0xf, 0x960b); | 4812 | alc_write_coef_idx(codec, 0xf, 0x960b); |
4813 | alc_write_coef_idx(codec, 0xe, 0x8814); | 4813 | alc_write_coef_idx(codec, 0xe, 0x8814); |
4814 | } | 4814 | } |
4815 | 4815 | ||
4816 | if ((alc_get_coef0(codec) & 0x00ff) == 0x017) { | 4816 | if ((alc_get_coef0(codec) & 0x00ff) == 0x017) { |
4817 | val = alc_read_coef_idx(codec, 0x04); | 4817 | val = alc_read_coef_idx(codec, 0x04); |
4818 | /* Power up output pin */ | 4818 | /* Power up output pin */ |
4819 | alc_write_coef_idx(codec, 0x04, val | (1<<11)); | 4819 | alc_write_coef_idx(codec, 0x04, val | (1<<11)); |
4820 | } | 4820 | } |
4821 | 4821 | ||
4822 | if ((alc_get_coef0(codec) & 0x00ff) == 0x018) { | 4822 | if ((alc_get_coef0(codec) & 0x00ff) == 0x018) { |
4823 | val = alc_read_coef_idx(codec, 0xd); | 4823 | val = alc_read_coef_idx(codec, 0xd); |
4824 | if ((val & 0x0c00) >> 10 != 0x1) { | 4824 | if ((val & 0x0c00) >> 10 != 0x1) { |
4825 | /* Capless ramp up clock control */ | 4825 | /* Capless ramp up clock control */ |
4826 | alc_write_coef_idx(codec, 0xd, val | (1<<10)); | 4826 | alc_write_coef_idx(codec, 0xd, val | (1<<10)); |
4827 | } | 4827 | } |
4828 | val = alc_read_coef_idx(codec, 0x17); | 4828 | val = alc_read_coef_idx(codec, 0x17); |
4829 | if ((val & 0x01c0) >> 6 != 0x4) { | 4829 | if ((val & 0x01c0) >> 6 != 0x4) { |
4830 | /* Class D power on reset */ | 4830 | /* Class D power on reset */ |
4831 | alc_write_coef_idx(codec, 0x17, val | (1<<7)); | 4831 | alc_write_coef_idx(codec, 0x17, val | (1<<7)); |
4832 | } | 4832 | } |
4833 | } | 4833 | } |
4834 | 4834 | ||
4835 | val = alc_read_coef_idx(codec, 0xd); /* Class D */ | 4835 | val = alc_read_coef_idx(codec, 0xd); /* Class D */ |
4836 | alc_write_coef_idx(codec, 0xd, val | (1<<14)); | 4836 | alc_write_coef_idx(codec, 0xd, val | (1<<14)); |
4837 | 4837 | ||
4838 | val = alc_read_coef_idx(codec, 0x4); /* HP */ | 4838 | val = alc_read_coef_idx(codec, 0x4); /* HP */ |
4839 | alc_write_coef_idx(codec, 0x4, val | (1<<11)); | 4839 | alc_write_coef_idx(codec, 0x4, val | (1<<11)); |
4840 | } | 4840 | } |
4841 | 4841 | ||
4842 | /* | 4842 | /* |
4843 | */ | 4843 | */ |
4844 | static int patch_alc269(struct hda_codec *codec) | 4844 | static int patch_alc269(struct hda_codec *codec) |
4845 | { | 4845 | { |
4846 | struct alc_spec *spec; | 4846 | struct alc_spec *spec; |
4847 | int err; | 4847 | int err; |
4848 | 4848 | ||
4849 | err = alc_alloc_spec(codec, 0x0b); | 4849 | err = alc_alloc_spec(codec, 0x0b); |
4850 | if (err < 0) | 4850 | if (err < 0) |
4851 | return err; | 4851 | return err; |
4852 | 4852 | ||
4853 | spec = codec->spec; | 4853 | spec = codec->spec; |
4854 | spec->gen.shared_mic_vref_pin = 0x18; | 4854 | spec->gen.shared_mic_vref_pin = 0x18; |
4855 | 4855 | ||
4856 | snd_hda_pick_fixup(codec, alc269_fixup_models, | 4856 | snd_hda_pick_fixup(codec, alc269_fixup_models, |
4857 | alc269_fixup_tbl, alc269_fixups); | 4857 | alc269_fixup_tbl, alc269_fixups); |
4858 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); | 4858 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); |
4859 | 4859 | ||
4860 | alc_auto_parse_customize_define(codec); | 4860 | alc_auto_parse_customize_define(codec); |
4861 | 4861 | ||
4862 | if (has_cdefine_beep(codec)) | 4862 | if (has_cdefine_beep(codec)) |
4863 | spec->gen.beep_nid = 0x01; | 4863 | spec->gen.beep_nid = 0x01; |
4864 | 4864 | ||
4865 | switch (codec->vendor_id) { | 4865 | switch (codec->vendor_id) { |
4866 | case 0x10ec0269: | 4866 | case 0x10ec0269: |
4867 | spec->codec_variant = ALC269_TYPE_ALC269VA; | 4867 | spec->codec_variant = ALC269_TYPE_ALC269VA; |
4868 | switch (alc_get_coef0(codec) & 0x00f0) { | 4868 | switch (alc_get_coef0(codec) & 0x00f0) { |
4869 | case 0x0010: | 4869 | case 0x0010: |
4870 | if (codec->bus->pci && | 4870 | if (codec->bus->pci && |
4871 | codec->bus->pci->subsystem_vendor == 0x1025 && | 4871 | codec->bus->pci->subsystem_vendor == 0x1025 && |
4872 | spec->cdefine.platform_type == 1) | 4872 | spec->cdefine.platform_type == 1) |
4873 | err = alc_codec_rename(codec, "ALC271X"); | 4873 | err = alc_codec_rename(codec, "ALC271X"); |
4874 | spec->codec_variant = ALC269_TYPE_ALC269VB; | 4874 | spec->codec_variant = ALC269_TYPE_ALC269VB; |
4875 | break; | 4875 | break; |
4876 | case 0x0020: | 4876 | case 0x0020: |
4877 | if (codec->bus->pci && | 4877 | if (codec->bus->pci && |
4878 | codec->bus->pci->subsystem_vendor == 0x17aa && | 4878 | codec->bus->pci->subsystem_vendor == 0x17aa && |
4879 | codec->bus->pci->subsystem_device == 0x21f3) | 4879 | codec->bus->pci->subsystem_device == 0x21f3) |
4880 | err = alc_codec_rename(codec, "ALC3202"); | 4880 | err = alc_codec_rename(codec, "ALC3202"); |
4881 | spec->codec_variant = ALC269_TYPE_ALC269VC; | 4881 | spec->codec_variant = ALC269_TYPE_ALC269VC; |
4882 | break; | 4882 | break; |
4883 | case 0x0030: | 4883 | case 0x0030: |
4884 | spec->codec_variant = ALC269_TYPE_ALC269VD; | 4884 | spec->codec_variant = ALC269_TYPE_ALC269VD; |
4885 | break; | 4885 | break; |
4886 | default: | 4886 | default: |
4887 | alc_fix_pll_init(codec, 0x20, 0x04, 15); | 4887 | alc_fix_pll_init(codec, 0x20, 0x04, 15); |
4888 | } | 4888 | } |
4889 | if (err < 0) | 4889 | if (err < 0) |
4890 | goto error; | 4890 | goto error; |
4891 | spec->init_hook = alc269_fill_coef; | 4891 | spec->init_hook = alc269_fill_coef; |
4892 | alc269_fill_coef(codec); | 4892 | alc269_fill_coef(codec); |
4893 | break; | 4893 | break; |
4894 | 4894 | ||
4895 | case 0x10ec0280: | 4895 | case 0x10ec0280: |
4896 | case 0x10ec0290: | 4896 | case 0x10ec0290: |
4897 | spec->codec_variant = ALC269_TYPE_ALC280; | 4897 | spec->codec_variant = ALC269_TYPE_ALC280; |
4898 | break; | 4898 | break; |
4899 | case 0x10ec0282: | 4899 | case 0x10ec0282: |
4900 | spec->codec_variant = ALC269_TYPE_ALC282; | 4900 | spec->codec_variant = ALC269_TYPE_ALC282; |
4901 | spec->shutup = alc282_shutup; | 4901 | spec->shutup = alc282_shutup; |
4902 | spec->init_hook = alc282_init; | 4902 | spec->init_hook = alc282_init; |
4903 | break; | 4903 | break; |
4904 | case 0x10ec0233: | 4904 | case 0x10ec0233: |
4905 | case 0x10ec0283: | 4905 | case 0x10ec0283: |
4906 | spec->codec_variant = ALC269_TYPE_ALC283; | 4906 | spec->codec_variant = ALC269_TYPE_ALC283; |
4907 | spec->shutup = alc283_shutup; | 4907 | spec->shutup = alc283_shutup; |
4908 | spec->init_hook = alc283_init; | 4908 | spec->init_hook = alc283_init; |
4909 | break; | 4909 | break; |
4910 | case 0x10ec0284: | 4910 | case 0x10ec0284: |
4911 | case 0x10ec0292: | 4911 | case 0x10ec0292: |
4912 | spec->codec_variant = ALC269_TYPE_ALC284; | 4912 | spec->codec_variant = ALC269_TYPE_ALC284; |
4913 | break; | 4913 | break; |
4914 | case 0x10ec0285: | 4914 | case 0x10ec0285: |
4915 | case 0x10ec0293: | 4915 | case 0x10ec0293: |
4916 | spec->codec_variant = ALC269_TYPE_ALC285; | 4916 | spec->codec_variant = ALC269_TYPE_ALC285; |
4917 | break; | 4917 | break; |
4918 | case 0x10ec0286: | 4918 | case 0x10ec0286: |
4919 | case 0x10ec0288: | 4919 | case 0x10ec0288: |
4920 | spec->codec_variant = ALC269_TYPE_ALC286; | 4920 | spec->codec_variant = ALC269_TYPE_ALC286; |
4921 | break; | 4921 | break; |
4922 | case 0x10ec0255: | 4922 | case 0x10ec0255: |
4923 | spec->codec_variant = ALC269_TYPE_ALC255; | 4923 | spec->codec_variant = ALC269_TYPE_ALC255; |
4924 | break; | 4924 | break; |
4925 | } | 4925 | } |
4926 | 4926 | ||
4927 | if (snd_hda_codec_read(codec, 0x51, 0, AC_VERB_PARAMETERS, 0) == 0x10ec5505) { | 4927 | if (snd_hda_codec_read(codec, 0x51, 0, AC_VERB_PARAMETERS, 0) == 0x10ec5505) { |
4928 | spec->has_alc5505_dsp = 1; | 4928 | spec->has_alc5505_dsp = 1; |
4929 | spec->init_hook = alc5505_dsp_init; | 4929 | spec->init_hook = alc5505_dsp_init; |
4930 | } | 4930 | } |
4931 | 4931 | ||
4932 | /* automatic parse from the BIOS config */ | 4932 | /* automatic parse from the BIOS config */ |
4933 | err = alc269_parse_auto_config(codec); | 4933 | err = alc269_parse_auto_config(codec); |
4934 | if (err < 0) | 4934 | if (err < 0) |
4935 | goto error; | 4935 | goto error; |
4936 | 4936 | ||
4937 | if (!spec->gen.no_analog && spec->gen.beep_nid) | 4937 | if (!spec->gen.no_analog && spec->gen.beep_nid) |
4938 | set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); | 4938 | set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); |
4939 | 4939 | ||
4940 | codec->patch_ops = alc_patch_ops; | 4940 | codec->patch_ops = alc_patch_ops; |
4941 | #ifdef CONFIG_PM | 4941 | #ifdef CONFIG_PM |
4942 | codec->patch_ops.suspend = alc269_suspend; | 4942 | codec->patch_ops.suspend = alc269_suspend; |
4943 | codec->patch_ops.resume = alc269_resume; | 4943 | codec->patch_ops.resume = alc269_resume; |
4944 | #endif | 4944 | #endif |
4945 | if (!spec->shutup) | 4945 | if (!spec->shutup) |
4946 | spec->shutup = alc269_shutup; | 4946 | spec->shutup = alc269_shutup; |
4947 | 4947 | ||
4948 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); | 4948 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); |
4949 | 4949 | ||
4950 | return 0; | 4950 | return 0; |
4951 | 4951 | ||
4952 | error: | 4952 | error: |
4953 | alc_free(codec); | 4953 | alc_free(codec); |
4954 | return err; | 4954 | return err; |
4955 | } | 4955 | } |
4956 | 4956 | ||
4957 | /* | 4957 | /* |
4958 | * ALC861 | 4958 | * ALC861 |
4959 | */ | 4959 | */ |
4960 | 4960 | ||
4961 | static int alc861_parse_auto_config(struct hda_codec *codec) | 4961 | static int alc861_parse_auto_config(struct hda_codec *codec) |
4962 | { | 4962 | { |
4963 | static const hda_nid_t alc861_ignore[] = { 0x1d, 0 }; | 4963 | static const hda_nid_t alc861_ignore[] = { 0x1d, 0 }; |
4964 | static const hda_nid_t alc861_ssids[] = { 0x0e, 0x0f, 0x0b, 0 }; | 4964 | static const hda_nid_t alc861_ssids[] = { 0x0e, 0x0f, 0x0b, 0 }; |
4965 | return alc_parse_auto_config(codec, alc861_ignore, alc861_ssids); | 4965 | return alc_parse_auto_config(codec, alc861_ignore, alc861_ssids); |
4966 | } | 4966 | } |
4967 | 4967 | ||
4968 | /* Pin config fixes */ | 4968 | /* Pin config fixes */ |
4969 | enum { | 4969 | enum { |
4970 | ALC861_FIXUP_FSC_AMILO_PI1505, | 4970 | ALC861_FIXUP_FSC_AMILO_PI1505, |
4971 | ALC861_FIXUP_AMP_VREF_0F, | 4971 | ALC861_FIXUP_AMP_VREF_0F, |
4972 | ALC861_FIXUP_NO_JACK_DETECT, | 4972 | ALC861_FIXUP_NO_JACK_DETECT, |
4973 | ALC861_FIXUP_ASUS_A6RP, | 4973 | ALC861_FIXUP_ASUS_A6RP, |
4974 | ALC660_FIXUP_ASUS_W7J, | 4974 | ALC660_FIXUP_ASUS_W7J, |
4975 | }; | 4975 | }; |
4976 | 4976 | ||
4977 | /* On some laptops, VREF of pin 0x0f is abused for controlling the main amp */ | 4977 | /* On some laptops, VREF of pin 0x0f is abused for controlling the main amp */ |
4978 | static void alc861_fixup_asus_amp_vref_0f(struct hda_codec *codec, | 4978 | static void alc861_fixup_asus_amp_vref_0f(struct hda_codec *codec, |
4979 | const struct hda_fixup *fix, int action) | 4979 | const struct hda_fixup *fix, int action) |
4980 | { | 4980 | { |
4981 | struct alc_spec *spec = codec->spec; | 4981 | struct alc_spec *spec = codec->spec; |
4982 | unsigned int val; | 4982 | unsigned int val; |
4983 | 4983 | ||
4984 | if (action != HDA_FIXUP_ACT_INIT) | 4984 | if (action != HDA_FIXUP_ACT_INIT) |
4985 | return; | 4985 | return; |
4986 | val = snd_hda_codec_get_pin_target(codec, 0x0f); | 4986 | val = snd_hda_codec_get_pin_target(codec, 0x0f); |
4987 | if (!(val & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN))) | 4987 | if (!(val & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN))) |
4988 | val |= AC_PINCTL_IN_EN; | 4988 | val |= AC_PINCTL_IN_EN; |
4989 | val |= AC_PINCTL_VREF_50; | 4989 | val |= AC_PINCTL_VREF_50; |
4990 | snd_hda_set_pin_ctl(codec, 0x0f, val); | 4990 | snd_hda_set_pin_ctl(codec, 0x0f, val); |
4991 | spec->gen.keep_vref_in_automute = 1; | 4991 | spec->gen.keep_vref_in_automute = 1; |
4992 | } | 4992 | } |
4993 | 4993 | ||
4994 | /* suppress the jack-detection */ | 4994 | /* suppress the jack-detection */ |
4995 | static void alc_fixup_no_jack_detect(struct hda_codec *codec, | 4995 | static void alc_fixup_no_jack_detect(struct hda_codec *codec, |
4996 | const struct hda_fixup *fix, int action) | 4996 | const struct hda_fixup *fix, int action) |
4997 | { | 4997 | { |
4998 | if (action == HDA_FIXUP_ACT_PRE_PROBE) | 4998 | if (action == HDA_FIXUP_ACT_PRE_PROBE) |
4999 | codec->no_jack_detect = 1; | 4999 | codec->no_jack_detect = 1; |
5000 | } | 5000 | } |
5001 | 5001 | ||
5002 | static const struct hda_fixup alc861_fixups[] = { | 5002 | static const struct hda_fixup alc861_fixups[] = { |
5003 | [ALC861_FIXUP_FSC_AMILO_PI1505] = { | 5003 | [ALC861_FIXUP_FSC_AMILO_PI1505] = { |
5004 | .type = HDA_FIXUP_PINS, | 5004 | .type = HDA_FIXUP_PINS, |
5005 | .v.pins = (const struct hda_pintbl[]) { | 5005 | .v.pins = (const struct hda_pintbl[]) { |
5006 | { 0x0b, 0x0221101f }, /* HP */ | 5006 | { 0x0b, 0x0221101f }, /* HP */ |
5007 | { 0x0f, 0x90170310 }, /* speaker */ | 5007 | { 0x0f, 0x90170310 }, /* speaker */ |
5008 | { } | 5008 | { } |
5009 | } | 5009 | } |
5010 | }, | 5010 | }, |
5011 | [ALC861_FIXUP_AMP_VREF_0F] = { | 5011 | [ALC861_FIXUP_AMP_VREF_0F] = { |
5012 | .type = HDA_FIXUP_FUNC, | 5012 | .type = HDA_FIXUP_FUNC, |
5013 | .v.func = alc861_fixup_asus_amp_vref_0f, | 5013 | .v.func = alc861_fixup_asus_amp_vref_0f, |
5014 | }, | 5014 | }, |
5015 | [ALC861_FIXUP_NO_JACK_DETECT] = { | 5015 | [ALC861_FIXUP_NO_JACK_DETECT] = { |
5016 | .type = HDA_FIXUP_FUNC, | 5016 | .type = HDA_FIXUP_FUNC, |
5017 | .v.func = alc_fixup_no_jack_detect, | 5017 | .v.func = alc_fixup_no_jack_detect, |
5018 | }, | 5018 | }, |
5019 | [ALC861_FIXUP_ASUS_A6RP] = { | 5019 | [ALC861_FIXUP_ASUS_A6RP] = { |
5020 | .type = HDA_FIXUP_FUNC, | 5020 | .type = HDA_FIXUP_FUNC, |
5021 | .v.func = alc861_fixup_asus_amp_vref_0f, | 5021 | .v.func = alc861_fixup_asus_amp_vref_0f, |
5022 | .chained = true, | 5022 | .chained = true, |
5023 | .chain_id = ALC861_FIXUP_NO_JACK_DETECT, | 5023 | .chain_id = ALC861_FIXUP_NO_JACK_DETECT, |
5024 | }, | 5024 | }, |
5025 | [ALC660_FIXUP_ASUS_W7J] = { | 5025 | [ALC660_FIXUP_ASUS_W7J] = { |
5026 | .type = HDA_FIXUP_VERBS, | 5026 | .type = HDA_FIXUP_VERBS, |
5027 | .v.verbs = (const struct hda_verb[]) { | 5027 | .v.verbs = (const struct hda_verb[]) { |
5028 | /* ASUS W7J needs a magic pin setup on unused NID 0x10 | 5028 | /* ASUS W7J needs a magic pin setup on unused NID 0x10 |
5029 | * for enabling outputs | 5029 | * for enabling outputs |
5030 | */ | 5030 | */ |
5031 | {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, | 5031 | {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, |
5032 | { } | 5032 | { } |
5033 | }, | 5033 | }, |
5034 | } | 5034 | } |
5035 | }; | 5035 | }; |
5036 | 5036 | ||
5037 | static const struct snd_pci_quirk alc861_fixup_tbl[] = { | 5037 | static const struct snd_pci_quirk alc861_fixup_tbl[] = { |
5038 | SND_PCI_QUIRK(0x1043, 0x1253, "ASUS W7J", ALC660_FIXUP_ASUS_W7J), | 5038 | SND_PCI_QUIRK(0x1043, 0x1253, "ASUS W7J", ALC660_FIXUP_ASUS_W7J), |
5039 | SND_PCI_QUIRK(0x1043, 0x1263, "ASUS Z35HL", ALC660_FIXUP_ASUS_W7J), | 5039 | SND_PCI_QUIRK(0x1043, 0x1263, "ASUS Z35HL", ALC660_FIXUP_ASUS_W7J), |
5040 | SND_PCI_QUIRK(0x1043, 0x1393, "ASUS A6Rp", ALC861_FIXUP_ASUS_A6RP), | 5040 | SND_PCI_QUIRK(0x1043, 0x1393, "ASUS A6Rp", ALC861_FIXUP_ASUS_A6RP), |
5041 | SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", ALC861_FIXUP_AMP_VREF_0F), | 5041 | SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", ALC861_FIXUP_AMP_VREF_0F), |
5042 | SND_PCI_QUIRK(0x1462, 0x7254, "HP DX2200", ALC861_FIXUP_NO_JACK_DETECT), | 5042 | SND_PCI_QUIRK(0x1462, 0x7254, "HP DX2200", ALC861_FIXUP_NO_JACK_DETECT), |
5043 | SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", ALC861_FIXUP_AMP_VREF_0F), | 5043 | SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", ALC861_FIXUP_AMP_VREF_0F), |
5044 | SND_PCI_QUIRK(0x1584, 0x0000, "Uniwill ECS M31EI", ALC861_FIXUP_AMP_VREF_0F), | 5044 | SND_PCI_QUIRK(0x1584, 0x0000, "Uniwill ECS M31EI", ALC861_FIXUP_AMP_VREF_0F), |
5045 | SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", ALC861_FIXUP_FSC_AMILO_PI1505), | 5045 | SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", ALC861_FIXUP_FSC_AMILO_PI1505), |
5046 | {} | 5046 | {} |
5047 | }; | 5047 | }; |
5048 | 5048 | ||
5049 | /* | 5049 | /* |
5050 | */ | 5050 | */ |
5051 | static int patch_alc861(struct hda_codec *codec) | 5051 | static int patch_alc861(struct hda_codec *codec) |
5052 | { | 5052 | { |
5053 | struct alc_spec *spec; | 5053 | struct alc_spec *spec; |
5054 | int err; | 5054 | int err; |
5055 | 5055 | ||
5056 | err = alc_alloc_spec(codec, 0x15); | 5056 | err = alc_alloc_spec(codec, 0x15); |
5057 | if (err < 0) | 5057 | if (err < 0) |
5058 | return err; | 5058 | return err; |
5059 | 5059 | ||
5060 | spec = codec->spec; | 5060 | spec = codec->spec; |
5061 | spec->gen.beep_nid = 0x23; | 5061 | spec->gen.beep_nid = 0x23; |
5062 | 5062 | ||
5063 | snd_hda_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups); | 5063 | snd_hda_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups); |
5064 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); | 5064 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); |
5065 | 5065 | ||
5066 | /* automatic parse from the BIOS config */ | 5066 | /* automatic parse from the BIOS config */ |
5067 | err = alc861_parse_auto_config(codec); | 5067 | err = alc861_parse_auto_config(codec); |
5068 | if (err < 0) | 5068 | if (err < 0) |
5069 | goto error; | 5069 | goto error; |
5070 | 5070 | ||
5071 | if (!spec->gen.no_analog) | 5071 | if (!spec->gen.no_analog) |
5072 | set_beep_amp(spec, 0x23, 0, HDA_OUTPUT); | 5072 | set_beep_amp(spec, 0x23, 0, HDA_OUTPUT); |
5073 | 5073 | ||
5074 | codec->patch_ops = alc_patch_ops; | 5074 | codec->patch_ops = alc_patch_ops; |
5075 | #ifdef CONFIG_PM | 5075 | #ifdef CONFIG_PM |
5076 | spec->power_hook = alc_power_eapd; | 5076 | spec->power_hook = alc_power_eapd; |
5077 | #endif | 5077 | #endif |
5078 | 5078 | ||
5079 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); | 5079 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); |
5080 | 5080 | ||
5081 | return 0; | 5081 | return 0; |
5082 | 5082 | ||
5083 | error: | 5083 | error: |
5084 | alc_free(codec); | 5084 | alc_free(codec); |
5085 | return err; | 5085 | return err; |
5086 | } | 5086 | } |
5087 | 5087 | ||
5088 | /* | 5088 | /* |
5089 | * ALC861-VD support | 5089 | * ALC861-VD support |
5090 | * | 5090 | * |
5091 | * Based on ALC882 | 5091 | * Based on ALC882 |
5092 | * | 5092 | * |
5093 | * In addition, an independent DAC | 5093 | * In addition, an independent DAC |
5094 | */ | 5094 | */ |
5095 | static int alc861vd_parse_auto_config(struct hda_codec *codec) | 5095 | static int alc861vd_parse_auto_config(struct hda_codec *codec) |
5096 | { | 5096 | { |
5097 | static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 }; | 5097 | static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 }; |
5098 | static const hda_nid_t alc861vd_ssids[] = { 0x15, 0x1b, 0x14, 0 }; | 5098 | static const hda_nid_t alc861vd_ssids[] = { 0x15, 0x1b, 0x14, 0 }; |
5099 | return alc_parse_auto_config(codec, alc861vd_ignore, alc861vd_ssids); | 5099 | return alc_parse_auto_config(codec, alc861vd_ignore, alc861vd_ssids); |
5100 | } | 5100 | } |
5101 | 5101 | ||
5102 | enum { | 5102 | enum { |
5103 | ALC660VD_FIX_ASUS_GPIO1, | 5103 | ALC660VD_FIX_ASUS_GPIO1, |
5104 | ALC861VD_FIX_DALLAS, | 5104 | ALC861VD_FIX_DALLAS, |
5105 | }; | 5105 | }; |
5106 | 5106 | ||
5107 | /* exclude VREF80 */ | 5107 | /* exclude VREF80 */ |
5108 | static void alc861vd_fixup_dallas(struct hda_codec *codec, | 5108 | static void alc861vd_fixup_dallas(struct hda_codec *codec, |
5109 | const struct hda_fixup *fix, int action) | 5109 | const struct hda_fixup *fix, int action) |
5110 | { | 5110 | { |
5111 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | 5111 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
5112 | snd_hda_override_pin_caps(codec, 0x18, 0x00000734); | 5112 | snd_hda_override_pin_caps(codec, 0x18, 0x00000734); |
5113 | snd_hda_override_pin_caps(codec, 0x19, 0x0000073c); | 5113 | snd_hda_override_pin_caps(codec, 0x19, 0x0000073c); |
5114 | } | 5114 | } |
5115 | } | 5115 | } |
5116 | 5116 | ||
5117 | static const struct hda_fixup alc861vd_fixups[] = { | 5117 | static const struct hda_fixup alc861vd_fixups[] = { |
5118 | [ALC660VD_FIX_ASUS_GPIO1] = { | 5118 | [ALC660VD_FIX_ASUS_GPIO1] = { |
5119 | .type = HDA_FIXUP_VERBS, | 5119 | .type = HDA_FIXUP_VERBS, |
5120 | .v.verbs = (const struct hda_verb[]) { | 5120 | .v.verbs = (const struct hda_verb[]) { |
5121 | /* reset GPIO1 */ | 5121 | /* reset GPIO1 */ |
5122 | {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, | 5122 | {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, |
5123 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, | 5123 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, |
5124 | {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, | 5124 | {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, |
5125 | { } | 5125 | { } |
5126 | } | 5126 | } |
5127 | }, | 5127 | }, |
5128 | [ALC861VD_FIX_DALLAS] = { | 5128 | [ALC861VD_FIX_DALLAS] = { |
5129 | .type = HDA_FIXUP_FUNC, | 5129 | .type = HDA_FIXUP_FUNC, |
5130 | .v.func = alc861vd_fixup_dallas, | 5130 | .v.func = alc861vd_fixup_dallas, |
5131 | }, | 5131 | }, |
5132 | }; | 5132 | }; |
5133 | 5133 | ||
5134 | static const struct snd_pci_quirk alc861vd_fixup_tbl[] = { | 5134 | static const struct snd_pci_quirk alc861vd_fixup_tbl[] = { |
5135 | SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_FIX_DALLAS), | 5135 | SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_FIX_DALLAS), |
5136 | SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1), | 5136 | SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1), |
5137 | SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_FIX_DALLAS), | 5137 | SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_FIX_DALLAS), |
5138 | {} | 5138 | {} |
5139 | }; | 5139 | }; |
5140 | 5140 | ||
5141 | /* | 5141 | /* |
5142 | */ | 5142 | */ |
5143 | static int patch_alc861vd(struct hda_codec *codec) | 5143 | static int patch_alc861vd(struct hda_codec *codec) |
5144 | { | 5144 | { |
5145 | struct alc_spec *spec; | 5145 | struct alc_spec *spec; |
5146 | int err; | 5146 | int err; |
5147 | 5147 | ||
5148 | err = alc_alloc_spec(codec, 0x0b); | 5148 | err = alc_alloc_spec(codec, 0x0b); |
5149 | if (err < 0) | 5149 | if (err < 0) |
5150 | return err; | 5150 | return err; |
5151 | 5151 | ||
5152 | spec = codec->spec; | 5152 | spec = codec->spec; |
5153 | spec->gen.beep_nid = 0x23; | 5153 | spec->gen.beep_nid = 0x23; |
5154 | 5154 | ||
5155 | snd_hda_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups); | 5155 | snd_hda_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups); |
5156 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); | 5156 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); |
5157 | 5157 | ||
5158 | /* automatic parse from the BIOS config */ | 5158 | /* automatic parse from the BIOS config */ |
5159 | err = alc861vd_parse_auto_config(codec); | 5159 | err = alc861vd_parse_auto_config(codec); |
5160 | if (err < 0) | 5160 | if (err < 0) |
5161 | goto error; | 5161 | goto error; |
5162 | 5162 | ||
5163 | if (!spec->gen.no_analog) | 5163 | if (!spec->gen.no_analog) |
5164 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); | 5164 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); |
5165 | 5165 | ||
5166 | codec->patch_ops = alc_patch_ops; | 5166 | codec->patch_ops = alc_patch_ops; |
5167 | 5167 | ||
5168 | spec->shutup = alc_eapd_shutup; | 5168 | spec->shutup = alc_eapd_shutup; |
5169 | 5169 | ||
5170 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); | 5170 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); |
5171 | 5171 | ||
5172 | return 0; | 5172 | return 0; |
5173 | 5173 | ||
5174 | error: | 5174 | error: |
5175 | alc_free(codec); | 5175 | alc_free(codec); |
5176 | return err; | 5176 | return err; |
5177 | } | 5177 | } |
5178 | 5178 | ||
5179 | /* | 5179 | /* |
5180 | * ALC662 support | 5180 | * ALC662 support |
5181 | * | 5181 | * |
5182 | * ALC662 is almost identical with ALC880 but has cleaner and more flexible | 5182 | * ALC662 is almost identical with ALC880 but has cleaner and more flexible |
5183 | * configuration. Each pin widget can choose any input DACs and a mixer. | 5183 | * configuration. Each pin widget can choose any input DACs and a mixer. |
5184 | * Each ADC is connected from a mixer of all inputs. This makes possible | 5184 | * Each ADC is connected from a mixer of all inputs. This makes possible |
5185 | * 6-channel independent captures. | 5185 | * 6-channel independent captures. |
5186 | * | 5186 | * |
5187 | * In addition, an independent DAC for the multi-playback (not used in this | 5187 | * In addition, an independent DAC for the multi-playback (not used in this |
5188 | * driver yet). | 5188 | * driver yet). |
5189 | */ | 5189 | */ |
5190 | 5190 | ||
5191 | /* | 5191 | /* |
5192 | * BIOS auto configuration | 5192 | * BIOS auto configuration |
5193 | */ | 5193 | */ |
5194 | 5194 | ||
5195 | static int alc662_parse_auto_config(struct hda_codec *codec) | 5195 | static int alc662_parse_auto_config(struct hda_codec *codec) |
5196 | { | 5196 | { |
5197 | static const hda_nid_t alc662_ignore[] = { 0x1d, 0 }; | 5197 | static const hda_nid_t alc662_ignore[] = { 0x1d, 0 }; |
5198 | static const hda_nid_t alc663_ssids[] = { 0x15, 0x1b, 0x14, 0x21 }; | 5198 | static const hda_nid_t alc663_ssids[] = { 0x15, 0x1b, 0x14, 0x21 }; |
5199 | static const hda_nid_t alc662_ssids[] = { 0x15, 0x1b, 0x14, 0 }; | 5199 | static const hda_nid_t alc662_ssids[] = { 0x15, 0x1b, 0x14, 0 }; |
5200 | const hda_nid_t *ssids; | 5200 | const hda_nid_t *ssids; |
5201 | 5201 | ||
5202 | if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 || | 5202 | if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 || |
5203 | codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670 || | 5203 | codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670 || |
5204 | codec->vendor_id == 0x10ec0671) | 5204 | codec->vendor_id == 0x10ec0671) |
5205 | ssids = alc663_ssids; | 5205 | ssids = alc663_ssids; |
5206 | else | 5206 | else |
5207 | ssids = alc662_ssids; | 5207 | ssids = alc662_ssids; |
5208 | return alc_parse_auto_config(codec, alc662_ignore, ssids); | 5208 | return alc_parse_auto_config(codec, alc662_ignore, ssids); |
5209 | } | 5209 | } |
5210 | 5210 | ||
5211 | static void alc272_fixup_mario(struct hda_codec *codec, | 5211 | static void alc272_fixup_mario(struct hda_codec *codec, |
5212 | const struct hda_fixup *fix, int action) | 5212 | const struct hda_fixup *fix, int action) |
5213 | { | 5213 | { |
5214 | if (action != HDA_FIXUP_ACT_PRE_PROBE) | 5214 | if (action != HDA_FIXUP_ACT_PRE_PROBE) |
5215 | return; | 5215 | return; |
5216 | if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT, | 5216 | if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT, |
5217 | (0x3b << AC_AMPCAP_OFFSET_SHIFT) | | 5217 | (0x3b << AC_AMPCAP_OFFSET_SHIFT) | |
5218 | (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) | | 5218 | (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) | |
5219 | (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) | | 5219 | (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) | |
5220 | (0 << AC_AMPCAP_MUTE_SHIFT))) | 5220 | (0 << AC_AMPCAP_MUTE_SHIFT))) |
5221 | codec_warn(codec, "failed to override amp caps for NID 0x2\n"); | 5221 | codec_warn(codec, "failed to override amp caps for NID 0x2\n"); |
5222 | } | 5222 | } |
5223 | 5223 | ||
5224 | static const struct snd_pcm_chmap_elem asus_pcm_2_1_chmaps[] = { | 5224 | static const struct snd_pcm_chmap_elem asus_pcm_2_1_chmaps[] = { |
5225 | { .channels = 2, | 5225 | { .channels = 2, |
5226 | .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } }, | 5226 | .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } }, |
5227 | { .channels = 4, | 5227 | { .channels = 4, |
5228 | .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, | 5228 | .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, |
5229 | SNDRV_CHMAP_NA, SNDRV_CHMAP_LFE } }, /* LFE only on right */ | 5229 | SNDRV_CHMAP_NA, SNDRV_CHMAP_LFE } }, /* LFE only on right */ |
5230 | { } | 5230 | { } |
5231 | }; | 5231 | }; |
5232 | 5232 | ||
5233 | /* override the 2.1 chmap */ | 5233 | /* override the 2.1 chmap */ |
5234 | static void alc_fixup_bass_chmap(struct hda_codec *codec, | 5234 | static void alc_fixup_bass_chmap(struct hda_codec *codec, |
5235 | const struct hda_fixup *fix, int action) | 5235 | const struct hda_fixup *fix, int action) |
5236 | { | 5236 | { |
5237 | if (action == HDA_FIXUP_ACT_BUILD) { | 5237 | if (action == HDA_FIXUP_ACT_BUILD) { |
5238 | struct alc_spec *spec = codec->spec; | 5238 | struct alc_spec *spec = codec->spec; |
5239 | spec->gen.pcm_rec[0].stream[0].chmap = asus_pcm_2_1_chmaps; | 5239 | spec->gen.pcm_rec[0].stream[0].chmap = asus_pcm_2_1_chmaps; |
5240 | } | 5240 | } |
5241 | } | 5241 | } |
5242 | 5242 | ||
5243 | /* turn on/off mute LED per vmaster hook */ | 5243 | /* turn on/off mute LED per vmaster hook */ |
5244 | static void alc662_led_gpio1_mute_hook(void *private_data, int enabled) | 5244 | static void alc662_led_gpio1_mute_hook(void *private_data, int enabled) |
5245 | { | 5245 | { |
5246 | struct hda_codec *codec = private_data; | 5246 | struct hda_codec *codec = private_data; |
5247 | struct alc_spec *spec = codec->spec; | 5247 | struct alc_spec *spec = codec->spec; |
5248 | unsigned int oldval = spec->gpio_led; | 5248 | unsigned int oldval = spec->gpio_led; |
5249 | 5249 | ||
5250 | if (enabled) | 5250 | if (enabled) |
5251 | spec->gpio_led &= ~0x01; | 5251 | spec->gpio_led &= ~0x01; |
5252 | else | 5252 | else |
5253 | spec->gpio_led |= 0x01; | 5253 | spec->gpio_led |= 0x01; |
5254 | if (spec->gpio_led != oldval) | 5254 | if (spec->gpio_led != oldval) |
5255 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, | 5255 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, |
5256 | spec->gpio_led); | 5256 | spec->gpio_led); |
5257 | } | 5257 | } |
5258 | 5258 | ||
5259 | /* avoid D3 for keeping GPIO up */ | 5259 | /* avoid D3 for keeping GPIO up */ |
5260 | static unsigned int gpio_led_power_filter(struct hda_codec *codec, | 5260 | static unsigned int gpio_led_power_filter(struct hda_codec *codec, |
5261 | hda_nid_t nid, | 5261 | hda_nid_t nid, |
5262 | unsigned int power_state) | 5262 | unsigned int power_state) |
5263 | { | 5263 | { |
5264 | struct alc_spec *spec = codec->spec; | 5264 | struct alc_spec *spec = codec->spec; |
5265 | if (nid == codec->afg && power_state == AC_PWRST_D3 && spec->gpio_led) | 5265 | if (nid == codec->afg && power_state == AC_PWRST_D3 && spec->gpio_led) |
5266 | return AC_PWRST_D0; | 5266 | return AC_PWRST_D0; |
5267 | return power_state; | 5267 | return power_state; |
5268 | } | 5268 | } |
5269 | 5269 | ||
5270 | static void alc662_fixup_led_gpio1(struct hda_codec *codec, | 5270 | static void alc662_fixup_led_gpio1(struct hda_codec *codec, |
5271 | const struct hda_fixup *fix, int action) | 5271 | const struct hda_fixup *fix, int action) |
5272 | { | 5272 | { |
5273 | struct alc_spec *spec = codec->spec; | 5273 | struct alc_spec *spec = codec->spec; |
5274 | static const struct hda_verb gpio_init[] = { | 5274 | static const struct hda_verb gpio_init[] = { |
5275 | { 0x01, AC_VERB_SET_GPIO_MASK, 0x01 }, | 5275 | { 0x01, AC_VERB_SET_GPIO_MASK, 0x01 }, |
5276 | { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01 }, | 5276 | { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01 }, |
5277 | {} | 5277 | {} |
5278 | }; | 5278 | }; |
5279 | 5279 | ||
5280 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | 5280 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
5281 | spec->gen.vmaster_mute.hook = alc662_led_gpio1_mute_hook; | 5281 | spec->gen.vmaster_mute.hook = alc662_led_gpio1_mute_hook; |
5282 | spec->gpio_led = 0; | 5282 | spec->gpio_led = 0; |
5283 | snd_hda_add_verbs(codec, gpio_init); | 5283 | snd_hda_add_verbs(codec, gpio_init); |
5284 | codec->power_filter = gpio_led_power_filter; | 5284 | codec->power_filter = gpio_led_power_filter; |
5285 | } | 5285 | } |
5286 | } | 5286 | } |
5287 | 5287 | ||
5288 | enum { | 5288 | enum { |
5289 | ALC662_FIXUP_ASPIRE, | 5289 | ALC662_FIXUP_ASPIRE, |
5290 | ALC662_FIXUP_LED_GPIO1, | 5290 | ALC662_FIXUP_LED_GPIO1, |
5291 | ALC662_FIXUP_IDEAPAD, | 5291 | ALC662_FIXUP_IDEAPAD, |
5292 | ALC272_FIXUP_MARIO, | 5292 | ALC272_FIXUP_MARIO, |
5293 | ALC662_FIXUP_CZC_P10T, | 5293 | ALC662_FIXUP_CZC_P10T, |
5294 | ALC662_FIXUP_SKU_IGNORE, | 5294 | ALC662_FIXUP_SKU_IGNORE, |
5295 | ALC662_FIXUP_HP_RP5800, | 5295 | ALC662_FIXUP_HP_RP5800, |
5296 | ALC662_FIXUP_ASUS_MODE1, | 5296 | ALC662_FIXUP_ASUS_MODE1, |
5297 | ALC662_FIXUP_ASUS_MODE2, | 5297 | ALC662_FIXUP_ASUS_MODE2, |
5298 | ALC662_FIXUP_ASUS_MODE3, | 5298 | ALC662_FIXUP_ASUS_MODE3, |
5299 | ALC662_FIXUP_ASUS_MODE4, | 5299 | ALC662_FIXUP_ASUS_MODE4, |
5300 | ALC662_FIXUP_ASUS_MODE5, | 5300 | ALC662_FIXUP_ASUS_MODE5, |
5301 | ALC662_FIXUP_ASUS_MODE6, | 5301 | ALC662_FIXUP_ASUS_MODE6, |
5302 | ALC662_FIXUP_ASUS_MODE7, | 5302 | ALC662_FIXUP_ASUS_MODE7, |
5303 | ALC662_FIXUP_ASUS_MODE8, | 5303 | ALC662_FIXUP_ASUS_MODE8, |
5304 | ALC662_FIXUP_NO_JACK_DETECT, | 5304 | ALC662_FIXUP_NO_JACK_DETECT, |
5305 | ALC662_FIXUP_ZOTAC_Z68, | 5305 | ALC662_FIXUP_ZOTAC_Z68, |
5306 | ALC662_FIXUP_INV_DMIC, | 5306 | ALC662_FIXUP_INV_DMIC, |
5307 | ALC668_FIXUP_DELL_MIC_NO_PRESENCE, | 5307 | ALC668_FIXUP_DELL_MIC_NO_PRESENCE, |
5308 | ALC668_FIXUP_HEADSET_MODE, | 5308 | ALC668_FIXUP_HEADSET_MODE, |
5309 | ALC662_FIXUP_BASS_MODE4_CHMAP, | 5309 | ALC662_FIXUP_BASS_MODE4_CHMAP, |
5310 | ALC662_FIXUP_BASS_16, | 5310 | ALC662_FIXUP_BASS_16, |
5311 | ALC662_FIXUP_BASS_1A, | 5311 | ALC662_FIXUP_BASS_1A, |
5312 | ALC662_FIXUP_BASS_CHMAP, | 5312 | ALC662_FIXUP_BASS_CHMAP, |
5313 | ALC668_FIXUP_AUTO_MUTE, | 5313 | ALC668_FIXUP_AUTO_MUTE, |
5314 | }; | 5314 | }; |
5315 | 5315 | ||
5316 | static const struct hda_fixup alc662_fixups[] = { | 5316 | static const struct hda_fixup alc662_fixups[] = { |
5317 | [ALC662_FIXUP_ASPIRE] = { | 5317 | [ALC662_FIXUP_ASPIRE] = { |
5318 | .type = HDA_FIXUP_PINS, | 5318 | .type = HDA_FIXUP_PINS, |
5319 | .v.pins = (const struct hda_pintbl[]) { | 5319 | .v.pins = (const struct hda_pintbl[]) { |
5320 | { 0x15, 0x99130112 }, /* subwoofer */ | 5320 | { 0x15, 0x99130112 }, /* subwoofer */ |
5321 | { } | 5321 | { } |
5322 | } | 5322 | } |
5323 | }, | 5323 | }, |
5324 | [ALC662_FIXUP_LED_GPIO1] = { | 5324 | [ALC662_FIXUP_LED_GPIO1] = { |
5325 | .type = HDA_FIXUP_FUNC, | 5325 | .type = HDA_FIXUP_FUNC, |
5326 | .v.func = alc662_fixup_led_gpio1, | 5326 | .v.func = alc662_fixup_led_gpio1, |
5327 | }, | 5327 | }, |
5328 | [ALC662_FIXUP_IDEAPAD] = { | 5328 | [ALC662_FIXUP_IDEAPAD] = { |
5329 | .type = HDA_FIXUP_PINS, | 5329 | .type = HDA_FIXUP_PINS, |
5330 | .v.pins = (const struct hda_pintbl[]) { | 5330 | .v.pins = (const struct hda_pintbl[]) { |
5331 | { 0x17, 0x99130112 }, /* subwoofer */ | 5331 | { 0x17, 0x99130112 }, /* subwoofer */ |
5332 | { } | 5332 | { } |
5333 | }, | 5333 | }, |
5334 | .chained = true, | 5334 | .chained = true, |
5335 | .chain_id = ALC662_FIXUP_LED_GPIO1, | 5335 | .chain_id = ALC662_FIXUP_LED_GPIO1, |
5336 | }, | 5336 | }, |
5337 | [ALC272_FIXUP_MARIO] = { | 5337 | [ALC272_FIXUP_MARIO] = { |
5338 | .type = HDA_FIXUP_FUNC, | 5338 | .type = HDA_FIXUP_FUNC, |
5339 | .v.func = alc272_fixup_mario, | 5339 | .v.func = alc272_fixup_mario, |
5340 | }, | 5340 | }, |
5341 | [ALC662_FIXUP_CZC_P10T] = { | 5341 | [ALC662_FIXUP_CZC_P10T] = { |
5342 | .type = HDA_FIXUP_VERBS, | 5342 | .type = HDA_FIXUP_VERBS, |
5343 | .v.verbs = (const struct hda_verb[]) { | 5343 | .v.verbs = (const struct hda_verb[]) { |
5344 | {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0}, | 5344 | {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0}, |
5345 | {} | 5345 | {} |
5346 | } | 5346 | } |
5347 | }, | 5347 | }, |
5348 | [ALC662_FIXUP_SKU_IGNORE] = { | 5348 | [ALC662_FIXUP_SKU_IGNORE] = { |
5349 | .type = HDA_FIXUP_FUNC, | 5349 | .type = HDA_FIXUP_FUNC, |
5350 | .v.func = alc_fixup_sku_ignore, | 5350 | .v.func = alc_fixup_sku_ignore, |
5351 | }, | 5351 | }, |
5352 | [ALC662_FIXUP_HP_RP5800] = { | 5352 | [ALC662_FIXUP_HP_RP5800] = { |
5353 | .type = HDA_FIXUP_PINS, | 5353 | .type = HDA_FIXUP_PINS, |
5354 | .v.pins = (const struct hda_pintbl[]) { | 5354 | .v.pins = (const struct hda_pintbl[]) { |
5355 | { 0x14, 0x0221201f }, /* HP out */ | 5355 | { 0x14, 0x0221201f }, /* HP out */ |
5356 | { } | 5356 | { } |
5357 | }, | 5357 | }, |
5358 | .chained = true, | 5358 | .chained = true, |
5359 | .chain_id = ALC662_FIXUP_SKU_IGNORE | 5359 | .chain_id = ALC662_FIXUP_SKU_IGNORE |
5360 | }, | 5360 | }, |
5361 | [ALC662_FIXUP_ASUS_MODE1] = { | 5361 | [ALC662_FIXUP_ASUS_MODE1] = { |
5362 | .type = HDA_FIXUP_PINS, | 5362 | .type = HDA_FIXUP_PINS, |
5363 | .v.pins = (const struct hda_pintbl[]) { | 5363 | .v.pins = (const struct hda_pintbl[]) { |
5364 | { 0x14, 0x99130110 }, /* speaker */ | 5364 | { 0x14, 0x99130110 }, /* speaker */ |
5365 | { 0x18, 0x01a19c20 }, /* mic */ | 5365 | { 0x18, 0x01a19c20 }, /* mic */ |
5366 | { 0x19, 0x99a3092f }, /* int-mic */ | 5366 | { 0x19, 0x99a3092f }, /* int-mic */ |
5367 | { 0x21, 0x0121401f }, /* HP out */ | 5367 | { 0x21, 0x0121401f }, /* HP out */ |
5368 | { } | 5368 | { } |
5369 | }, | 5369 | }, |
5370 | .chained = true, | 5370 | .chained = true, |
5371 | .chain_id = ALC662_FIXUP_SKU_IGNORE | 5371 | .chain_id = ALC662_FIXUP_SKU_IGNORE |
5372 | }, | 5372 | }, |
5373 | [ALC662_FIXUP_ASUS_MODE2] = { | 5373 | [ALC662_FIXUP_ASUS_MODE2] = { |
5374 | .type = HDA_FIXUP_PINS, | 5374 | .type = HDA_FIXUP_PINS, |
5375 | .v.pins = (const struct hda_pintbl[]) { | 5375 | .v.pins = (const struct hda_pintbl[]) { |
5376 | { 0x14, 0x99130110 }, /* speaker */ | 5376 | { 0x14, 0x99130110 }, /* speaker */ |
5377 | { 0x18, 0x01a19820 }, /* mic */ | 5377 | { 0x18, 0x01a19820 }, /* mic */ |
5378 | { 0x19, 0x99a3092f }, /* int-mic */ | 5378 | { 0x19, 0x99a3092f }, /* int-mic */ |
5379 | { 0x1b, 0x0121401f }, /* HP out */ | 5379 | { 0x1b, 0x0121401f }, /* HP out */ |
5380 | { } | 5380 | { } |
5381 | }, | 5381 | }, |
5382 | .chained = true, | 5382 | .chained = true, |
5383 | .chain_id = ALC662_FIXUP_SKU_IGNORE | 5383 | .chain_id = ALC662_FIXUP_SKU_IGNORE |
5384 | }, | 5384 | }, |
5385 | [ALC662_FIXUP_ASUS_MODE3] = { | 5385 | [ALC662_FIXUP_ASUS_MODE3] = { |
5386 | .type = HDA_FIXUP_PINS, | 5386 | .type = HDA_FIXUP_PINS, |
5387 | .v.pins = (const struct hda_pintbl[]) { | 5387 | .v.pins = (const struct hda_pintbl[]) { |
5388 | { 0x14, 0x99130110 }, /* speaker */ | 5388 | { 0x14, 0x99130110 }, /* speaker */ |
5389 | { 0x15, 0x0121441f }, /* HP */ | 5389 | { 0x15, 0x0121441f }, /* HP */ |
5390 | { 0x18, 0x01a19840 }, /* mic */ | 5390 | { 0x18, 0x01a19840 }, /* mic */ |
5391 | { 0x19, 0x99a3094f }, /* int-mic */ | 5391 | { 0x19, 0x99a3094f }, /* int-mic */ |
5392 | { 0x21, 0x01211420 }, /* HP2 */ | 5392 | { 0x21, 0x01211420 }, /* HP2 */ |
5393 | { } | 5393 | { } |
5394 | }, | 5394 | }, |
5395 | .chained = true, | 5395 | .chained = true, |
5396 | .chain_id = ALC662_FIXUP_SKU_IGNORE | 5396 | .chain_id = ALC662_FIXUP_SKU_IGNORE |
5397 | }, | 5397 | }, |
5398 | [ALC662_FIXUP_ASUS_MODE4] = { | 5398 | [ALC662_FIXUP_ASUS_MODE4] = { |
5399 | .type = HDA_FIXUP_PINS, | 5399 | .type = HDA_FIXUP_PINS, |
5400 | .v.pins = (const struct hda_pintbl[]) { | 5400 | .v.pins = (const struct hda_pintbl[]) { |
5401 | { 0x14, 0x99130110 }, /* speaker */ | 5401 | { 0x14, 0x99130110 }, /* speaker */ |
5402 | { 0x16, 0x99130111 }, /* speaker */ | 5402 | { 0x16, 0x99130111 }, /* speaker */ |
5403 | { 0x18, 0x01a19840 }, /* mic */ | 5403 | { 0x18, 0x01a19840 }, /* mic */ |
5404 | { 0x19, 0x99a3094f }, /* int-mic */ | 5404 | { 0x19, 0x99a3094f }, /* int-mic */ |
5405 | { 0x21, 0x0121441f }, /* HP */ | 5405 | { 0x21, 0x0121441f }, /* HP */ |
5406 | { } | 5406 | { } |
5407 | }, | 5407 | }, |
5408 | .chained = true, | 5408 | .chained = true, |
5409 | .chain_id = ALC662_FIXUP_SKU_IGNORE | 5409 | .chain_id = ALC662_FIXUP_SKU_IGNORE |
5410 | }, | 5410 | }, |
5411 | [ALC662_FIXUP_ASUS_MODE5] = { | 5411 | [ALC662_FIXUP_ASUS_MODE5] = { |
5412 | .type = HDA_FIXUP_PINS, | 5412 | .type = HDA_FIXUP_PINS, |
5413 | .v.pins = (const struct hda_pintbl[]) { | 5413 | .v.pins = (const struct hda_pintbl[]) { |
5414 | { 0x14, 0x99130110 }, /* speaker */ | 5414 | { 0x14, 0x99130110 }, /* speaker */ |
5415 | { 0x15, 0x0121441f }, /* HP */ | 5415 | { 0x15, 0x0121441f }, /* HP */ |
5416 | { 0x16, 0x99130111 }, /* speaker */ | 5416 | { 0x16, 0x99130111 }, /* speaker */ |
5417 | { 0x18, 0x01a19840 }, /* mic */ | 5417 | { 0x18, 0x01a19840 }, /* mic */ |
5418 | { 0x19, 0x99a3094f }, /* int-mic */ | 5418 | { 0x19, 0x99a3094f }, /* int-mic */ |
5419 | { } | 5419 | { } |
5420 | }, | 5420 | }, |
5421 | .chained = true, | 5421 | .chained = true, |
5422 | .chain_id = ALC662_FIXUP_SKU_IGNORE | 5422 | .chain_id = ALC662_FIXUP_SKU_IGNORE |
5423 | }, | 5423 | }, |
5424 | [ALC662_FIXUP_ASUS_MODE6] = { | 5424 | [ALC662_FIXUP_ASUS_MODE6] = { |
5425 | .type = HDA_FIXUP_PINS, | 5425 | .type = HDA_FIXUP_PINS, |
5426 | .v.pins = (const struct hda_pintbl[]) { | 5426 | .v.pins = (const struct hda_pintbl[]) { |
5427 | { 0x14, 0x99130110 }, /* speaker */ | 5427 | { 0x14, 0x99130110 }, /* speaker */ |
5428 | { 0x15, 0x01211420 }, /* HP2 */ | 5428 | { 0x15, 0x01211420 }, /* HP2 */ |
5429 | { 0x18, 0x01a19840 }, /* mic */ | 5429 | { 0x18, 0x01a19840 }, /* mic */ |
5430 | { 0x19, 0x99a3094f }, /* int-mic */ | 5430 | { 0x19, 0x99a3094f }, /* int-mic */ |
5431 | { 0x1b, 0x0121441f }, /* HP */ | 5431 | { 0x1b, 0x0121441f }, /* HP */ |
5432 | { } | 5432 | { } |
5433 | }, | 5433 | }, |
5434 | .chained = true, | 5434 | .chained = true, |
5435 | .chain_id = ALC662_FIXUP_SKU_IGNORE | 5435 | .chain_id = ALC662_FIXUP_SKU_IGNORE |
5436 | }, | 5436 | }, |
5437 | [ALC662_FIXUP_ASUS_MODE7] = { | 5437 | [ALC662_FIXUP_ASUS_MODE7] = { |
5438 | .type = HDA_FIXUP_PINS, | 5438 | .type = HDA_FIXUP_PINS, |
5439 | .v.pins = (const struct hda_pintbl[]) { | 5439 | .v.pins = (const struct hda_pintbl[]) { |
5440 | { 0x14, 0x99130110 }, /* speaker */ | 5440 | { 0x14, 0x99130110 }, /* speaker */ |
5441 | { 0x17, 0x99130111 }, /* speaker */ | 5441 | { 0x17, 0x99130111 }, /* speaker */ |
5442 | { 0x18, 0x01a19840 }, /* mic */ | 5442 | { 0x18, 0x01a19840 }, /* mic */ |
5443 | { 0x19, 0x99a3094f }, /* int-mic */ | 5443 | { 0x19, 0x99a3094f }, /* int-mic */ |
5444 | { 0x1b, 0x01214020 }, /* HP */ | 5444 | { 0x1b, 0x01214020 }, /* HP */ |
5445 | { 0x21, 0x0121401f }, /* HP */ | 5445 | { 0x21, 0x0121401f }, /* HP */ |
5446 | { } | 5446 | { } |
5447 | }, | 5447 | }, |
5448 | .chained = true, | 5448 | .chained = true, |
5449 | .chain_id = ALC662_FIXUP_SKU_IGNORE | 5449 | .chain_id = ALC662_FIXUP_SKU_IGNORE |
5450 | }, | 5450 | }, |
5451 | [ALC662_FIXUP_ASUS_MODE8] = { | 5451 | [ALC662_FIXUP_ASUS_MODE8] = { |
5452 | .type = HDA_FIXUP_PINS, | 5452 | .type = HDA_FIXUP_PINS, |
5453 | .v.pins = (const struct hda_pintbl[]) { | 5453 | .v.pins = (const struct hda_pintbl[]) { |
5454 | { 0x14, 0x99130110 }, /* speaker */ | 5454 | { 0x14, 0x99130110 }, /* speaker */ |
5455 | { 0x12, 0x99a30970 }, /* int-mic */ | 5455 | { 0x12, 0x99a30970 }, /* int-mic */ |
5456 | { 0x15, 0x01214020 }, /* HP */ | 5456 | { 0x15, 0x01214020 }, /* HP */ |
5457 | { 0x17, 0x99130111 }, /* speaker */ | 5457 | { 0x17, 0x99130111 }, /* speaker */ |
5458 | { 0x18, 0x01a19840 }, /* mic */ | 5458 | { 0x18, 0x01a19840 }, /* mic */ |
5459 | { 0x21, 0x0121401f }, /* HP */ | 5459 | { 0x21, 0x0121401f }, /* HP */ |
5460 | { } | 5460 | { } |
5461 | }, | 5461 | }, |
5462 | .chained = true, | 5462 | .chained = true, |
5463 | .chain_id = ALC662_FIXUP_SKU_IGNORE | 5463 | .chain_id = ALC662_FIXUP_SKU_IGNORE |
5464 | }, | 5464 | }, |
5465 | [ALC662_FIXUP_NO_JACK_DETECT] = { | 5465 | [ALC662_FIXUP_NO_JACK_DETECT] = { |
5466 | .type = HDA_FIXUP_FUNC, | 5466 | .type = HDA_FIXUP_FUNC, |
5467 | .v.func = alc_fixup_no_jack_detect, | 5467 | .v.func = alc_fixup_no_jack_detect, |
5468 | }, | 5468 | }, |
5469 | [ALC662_FIXUP_ZOTAC_Z68] = { | 5469 | [ALC662_FIXUP_ZOTAC_Z68] = { |
5470 | .type = HDA_FIXUP_PINS, | 5470 | .type = HDA_FIXUP_PINS, |
5471 | .v.pins = (const struct hda_pintbl[]) { | 5471 | .v.pins = (const struct hda_pintbl[]) { |
5472 | { 0x1b, 0x02214020 }, /* Front HP */ | 5472 | { 0x1b, 0x02214020 }, /* Front HP */ |
5473 | { } | 5473 | { } |
5474 | } | 5474 | } |
5475 | }, | 5475 | }, |
5476 | [ALC662_FIXUP_INV_DMIC] = { | 5476 | [ALC662_FIXUP_INV_DMIC] = { |
5477 | .type = HDA_FIXUP_FUNC, | 5477 | .type = HDA_FIXUP_FUNC, |
5478 | .v.func = alc_fixup_inv_dmic_0x12, | 5478 | .v.func = alc_fixup_inv_dmic_0x12, |
5479 | }, | 5479 | }, |
5480 | [ALC668_FIXUP_AUTO_MUTE] = { | 5480 | [ALC668_FIXUP_AUTO_MUTE] = { |
5481 | .type = HDA_FIXUP_FUNC, | 5481 | .type = HDA_FIXUP_FUNC, |
5482 | .v.func = alc_fixup_auto_mute_via_amp, | 5482 | .v.func = alc_fixup_auto_mute_via_amp, |
5483 | .chained = true, | 5483 | .chained = true, |
5484 | .chain_id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE | 5484 | .chain_id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE |
5485 | }, | 5485 | }, |
5486 | [ALC668_FIXUP_DELL_MIC_NO_PRESENCE] = { | 5486 | [ALC668_FIXUP_DELL_MIC_NO_PRESENCE] = { |
5487 | .type = HDA_FIXUP_PINS, | 5487 | .type = HDA_FIXUP_PINS, |
5488 | .v.pins = (const struct hda_pintbl[]) { | 5488 | .v.pins = (const struct hda_pintbl[]) { |
5489 | { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */ | 5489 | { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */ |
5490 | { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */ | 5490 | { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */ |
5491 | { } | 5491 | { } |
5492 | }, | 5492 | }, |
5493 | .chained = true, | 5493 | .chained = true, |
5494 | .chain_id = ALC668_FIXUP_HEADSET_MODE | 5494 | .chain_id = ALC668_FIXUP_HEADSET_MODE |
5495 | }, | 5495 | }, |
5496 | [ALC668_FIXUP_HEADSET_MODE] = { | 5496 | [ALC668_FIXUP_HEADSET_MODE] = { |
5497 | .type = HDA_FIXUP_FUNC, | 5497 | .type = HDA_FIXUP_FUNC, |
5498 | .v.func = alc_fixup_headset_mode_alc668, | 5498 | .v.func = alc_fixup_headset_mode_alc668, |
5499 | }, | 5499 | }, |
5500 | [ALC662_FIXUP_BASS_MODE4_CHMAP] = { | 5500 | [ALC662_FIXUP_BASS_MODE4_CHMAP] = { |
5501 | .type = HDA_FIXUP_FUNC, | 5501 | .type = HDA_FIXUP_FUNC, |
5502 | .v.func = alc_fixup_bass_chmap, | 5502 | .v.func = alc_fixup_bass_chmap, |
5503 | .chained = true, | 5503 | .chained = true, |
5504 | .chain_id = ALC662_FIXUP_ASUS_MODE4 | 5504 | .chain_id = ALC662_FIXUP_ASUS_MODE4 |
5505 | }, | 5505 | }, |
5506 | [ALC662_FIXUP_BASS_16] = { | 5506 | [ALC662_FIXUP_BASS_16] = { |
5507 | .type = HDA_FIXUP_PINS, | 5507 | .type = HDA_FIXUP_PINS, |
5508 | .v.pins = (const struct hda_pintbl[]) { | 5508 | .v.pins = (const struct hda_pintbl[]) { |
5509 | {0x16, 0x80106111}, /* bass speaker */ | 5509 | {0x16, 0x80106111}, /* bass speaker */ |
5510 | {} | 5510 | {} |
5511 | }, | 5511 | }, |
5512 | .chained = true, | 5512 | .chained = true, |
5513 | .chain_id = ALC662_FIXUP_BASS_CHMAP, | 5513 | .chain_id = ALC662_FIXUP_BASS_CHMAP, |
5514 | }, | 5514 | }, |
5515 | [ALC662_FIXUP_BASS_1A] = { | 5515 | [ALC662_FIXUP_BASS_1A] = { |
5516 | .type = HDA_FIXUP_PINS, | 5516 | .type = HDA_FIXUP_PINS, |
5517 | .v.pins = (const struct hda_pintbl[]) { | 5517 | .v.pins = (const struct hda_pintbl[]) { |
5518 | {0x1a, 0x80106111}, /* bass speaker */ | 5518 | {0x1a, 0x80106111}, /* bass speaker */ |
5519 | {} | 5519 | {} |
5520 | }, | 5520 | }, |
5521 | .chained = true, | 5521 | .chained = true, |
5522 | .chain_id = ALC662_FIXUP_BASS_CHMAP, | 5522 | .chain_id = ALC662_FIXUP_BASS_CHMAP, |
5523 | }, | 5523 | }, |
5524 | [ALC662_FIXUP_BASS_CHMAP] = { | 5524 | [ALC662_FIXUP_BASS_CHMAP] = { |
5525 | .type = HDA_FIXUP_FUNC, | 5525 | .type = HDA_FIXUP_FUNC, |
5526 | .v.func = alc_fixup_bass_chmap, | 5526 | .v.func = alc_fixup_bass_chmap, |
5527 | }, | 5527 | }, |
5528 | }; | 5528 | }; |
5529 | 5529 | ||
5530 | static const struct snd_pci_quirk alc662_fixup_tbl[] = { | 5530 | static const struct snd_pci_quirk alc662_fixup_tbl[] = { |
5531 | SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_FIXUP_ASUS_MODE2), | 5531 | SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_FIXUP_ASUS_MODE2), |
5532 | SND_PCI_QUIRK(0x1025, 0x022f, "Acer Aspire One", ALC662_FIXUP_INV_DMIC), | 5532 | SND_PCI_QUIRK(0x1025, 0x022f, "Acer Aspire One", ALC662_FIXUP_INV_DMIC), |
5533 | SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE), | 5533 | SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE), |
5534 | SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE), | 5534 | SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE), |
5535 | SND_PCI_QUIRK(0x1025, 0x0349, "eMachines eM250", ALC662_FIXUP_INV_DMIC), | 5535 | SND_PCI_QUIRK(0x1025, 0x0349, "eMachines eM250", ALC662_FIXUP_INV_DMIC), |
5536 | SND_PCI_QUIRK(0x1025, 0x034a, "Gateway LT27", ALC662_FIXUP_INV_DMIC), | 5536 | SND_PCI_QUIRK(0x1025, 0x034a, "Gateway LT27", ALC662_FIXUP_INV_DMIC), |
5537 | SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), | 5537 | SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), |
5538 | SND_PCI_QUIRK(0x1028, 0x05d8, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), | 5538 | SND_PCI_QUIRK(0x1028, 0x05d8, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), |
5539 | SND_PCI_QUIRK(0x1028, 0x05db, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), | 5539 | SND_PCI_QUIRK(0x1028, 0x05db, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), |
5540 | SND_PCI_QUIRK(0x1028, 0x060a, "Dell XPS 13", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), | 5540 | SND_PCI_QUIRK(0x1028, 0x060a, "Dell XPS 13", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), |
5541 | SND_PCI_QUIRK(0x1028, 0x0623, "Dell", ALC668_FIXUP_AUTO_MUTE), | 5541 | SND_PCI_QUIRK(0x1028, 0x0623, "Dell", ALC668_FIXUP_AUTO_MUTE), |
5542 | SND_PCI_QUIRK(0x1028, 0x0624, "Dell", ALC668_FIXUP_AUTO_MUTE), | 5542 | SND_PCI_QUIRK(0x1028, 0x0624, "Dell", ALC668_FIXUP_AUTO_MUTE), |
5543 | SND_PCI_QUIRK(0x1028, 0x0625, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), | 5543 | SND_PCI_QUIRK(0x1028, 0x0625, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), |
5544 | SND_PCI_QUIRK(0x1028, 0x0626, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), | 5544 | SND_PCI_QUIRK(0x1028, 0x0626, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), |
5545 | SND_PCI_QUIRK(0x1028, 0x0628, "Dell", ALC668_FIXUP_AUTO_MUTE), | 5545 | SND_PCI_QUIRK(0x1028, 0x0628, "Dell", ALC668_FIXUP_AUTO_MUTE), |
5546 | SND_PCI_QUIRK(0x1028, 0x064e, "Dell", ALC668_FIXUP_AUTO_MUTE), | 5546 | SND_PCI_QUIRK(0x1028, 0x064e, "Dell", ALC668_FIXUP_AUTO_MUTE), |
5547 | SND_PCI_QUIRK(0x1028, 0x0696, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), | 5547 | SND_PCI_QUIRK(0x1028, 0x0696, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), |
5548 | SND_PCI_QUIRK(0x1028, 0x0698, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), | 5548 | SND_PCI_QUIRK(0x1028, 0x0698, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), |
5549 | SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800), | 5549 | SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800), |
5550 | SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_BASS_1A), | 5550 | SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_BASS_1A), |
5551 | SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_BASS_MODE4_CHMAP), | 5551 | SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_BASS_MODE4_CHMAP), |
5552 | SND_PCI_QUIRK(0x1043, 0x15a7, "ASUS UX51VZH", ALC662_FIXUP_BASS_16), | 5552 | SND_PCI_QUIRK(0x1043, 0x15a7, "ASUS UX51VZH", ALC662_FIXUP_BASS_16), |
5553 | SND_PCI_QUIRK(0x1043, 0x1b73, "ASUS N55SF", ALC662_FIXUP_BASS_16), | 5553 | SND_PCI_QUIRK(0x1043, 0x1b73, "ASUS N55SF", ALC662_FIXUP_BASS_16), |
5554 | SND_PCI_QUIRK(0x1043, 0x1bf3, "ASUS N76VZ", ALC662_FIXUP_BASS_MODE4_CHMAP), | 5554 | SND_PCI_QUIRK(0x1043, 0x1bf3, "ASUS N76VZ", ALC662_FIXUP_BASS_MODE4_CHMAP), |
5555 | SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT), | 5555 | SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT), |
5556 | SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2), | 5556 | SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2), |
5557 | SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD), | 5557 | SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD), |
5558 | SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD), | 5558 | SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD), |
5559 | SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD), | 5559 | SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD), |
5560 | SND_PCI_QUIRK(0x19da, 0xa130, "Zotac Z68", ALC662_FIXUP_ZOTAC_Z68), | 5560 | SND_PCI_QUIRK(0x19da, 0xa130, "Zotac Z68", ALC662_FIXUP_ZOTAC_Z68), |
5561 | SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T), | 5561 | SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T), |
5562 | 5562 | ||
5563 | #if 0 | 5563 | #if 0 |
5564 | /* Below is a quirk table taken from the old code. | 5564 | /* Below is a quirk table taken from the old code. |
5565 | * Basically the device should work as is without the fixup table. | 5565 | * Basically the device should work as is without the fixup table. |
5566 | * If BIOS doesn't give a proper info, enable the corresponding | 5566 | * If BIOS doesn't give a proper info, enable the corresponding |
5567 | * fixup entry. | 5567 | * fixup entry. |
5568 | */ | 5568 | */ |
5569 | SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC662_FIXUP_ASUS_MODE1), | 5569 | SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC662_FIXUP_ASUS_MODE1), |
5570 | SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC662_FIXUP_ASUS_MODE3), | 5570 | SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC662_FIXUP_ASUS_MODE3), |
5571 | SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC662_FIXUP_ASUS_MODE1), | 5571 | SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC662_FIXUP_ASUS_MODE1), |
5572 | SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC662_FIXUP_ASUS_MODE3), | 5572 | SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC662_FIXUP_ASUS_MODE3), |
5573 | SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1), | 5573 | SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1), |
5574 | SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), | 5574 | SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), |
5575 | SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC662_FIXUP_ASUS_MODE1), | 5575 | SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC662_FIXUP_ASUS_MODE1), |
5576 | SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC662_FIXUP_ASUS_MODE1), | 5576 | SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC662_FIXUP_ASUS_MODE1), |
5577 | SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC662_FIXUP_ASUS_MODE1), | 5577 | SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC662_FIXUP_ASUS_MODE1), |
5578 | SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), | 5578 | SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), |
5579 | SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC662_FIXUP_ASUS_MODE7), | 5579 | SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC662_FIXUP_ASUS_MODE7), |
5580 | SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC662_FIXUP_ASUS_MODE7), | 5580 | SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC662_FIXUP_ASUS_MODE7), |
5581 | SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC662_FIXUP_ASUS_MODE8), | 5581 | SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC662_FIXUP_ASUS_MODE8), |
5582 | SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC662_FIXUP_ASUS_MODE3), | 5582 | SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC662_FIXUP_ASUS_MODE3), |
5583 | SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC662_FIXUP_ASUS_MODE1), | 5583 | SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC662_FIXUP_ASUS_MODE1), |
5584 | SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), | 5584 | SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), |
5585 | SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_FIXUP_ASUS_MODE2), | 5585 | SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_FIXUP_ASUS_MODE2), |
5586 | SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC662_FIXUP_ASUS_MODE1), | 5586 | SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC662_FIXUP_ASUS_MODE1), |
5587 | SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), | 5587 | SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), |
5588 | SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC662_FIXUP_ASUS_MODE6), | 5588 | SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC662_FIXUP_ASUS_MODE6), |
5589 | SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC662_FIXUP_ASUS_MODE6), | 5589 | SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC662_FIXUP_ASUS_MODE6), |
5590 | SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), | 5590 | SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), |
5591 | SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC662_FIXUP_ASUS_MODE1), | 5591 | SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC662_FIXUP_ASUS_MODE1), |
5592 | SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC662_FIXUP_ASUS_MODE3), | 5592 | SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC662_FIXUP_ASUS_MODE3), |
5593 | SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_FIXUP_ASUS_MODE2), | 5593 | SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_FIXUP_ASUS_MODE2), |
5594 | SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), | 5594 | SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), |
5595 | SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC662_FIXUP_ASUS_MODE5), | 5595 | SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC662_FIXUP_ASUS_MODE5), |
5596 | SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC662_FIXUP_ASUS_MODE6), | 5596 | SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC662_FIXUP_ASUS_MODE6), |
5597 | SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), | 5597 | SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), |
5598 | SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC662_FIXUP_ASUS_MODE1), | 5598 | SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC662_FIXUP_ASUS_MODE1), |
5599 | SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), | 5599 | SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), |
5600 | SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), | 5600 | SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), |
5601 | SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC662_FIXUP_ASUS_MODE3), | 5601 | SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC662_FIXUP_ASUS_MODE3), |
5602 | SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC662_FIXUP_ASUS_MODE3), | 5602 | SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC662_FIXUP_ASUS_MODE3), |
5603 | SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC662_FIXUP_ASUS_MODE1), | 5603 | SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC662_FIXUP_ASUS_MODE1), |
5604 | SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC662_FIXUP_ASUS_MODE1), | 5604 | SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC662_FIXUP_ASUS_MODE1), |
5605 | SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC662_FIXUP_ASUS_MODE1), | 5605 | SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC662_FIXUP_ASUS_MODE1), |
5606 | SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC662_FIXUP_ASUS_MODE1), | 5606 | SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC662_FIXUP_ASUS_MODE1), |
5607 | SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC662_FIXUP_ASUS_MODE1), | 5607 | SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC662_FIXUP_ASUS_MODE1), |
5608 | SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), | 5608 | SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), |
5609 | SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_FIXUP_ASUS_MODE2), | 5609 | SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_FIXUP_ASUS_MODE2), |
5610 | SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC662_FIXUP_ASUS_MODE1), | 5610 | SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC662_FIXUP_ASUS_MODE1), |
5611 | SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC662_FIXUP_ASUS_MODE1), | 5611 | SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC662_FIXUP_ASUS_MODE1), |
5612 | SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC662_FIXUP_ASUS_MODE3), | 5612 | SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC662_FIXUP_ASUS_MODE3), |
5613 | SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC662_FIXUP_ASUS_MODE1), | 5613 | SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC662_FIXUP_ASUS_MODE1), |
5614 | SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC662_FIXUP_ASUS_MODE1), | 5614 | SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC662_FIXUP_ASUS_MODE1), |
5615 | SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC662_FIXUP_ASUS_MODE1), | 5615 | SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC662_FIXUP_ASUS_MODE1), |
5616 | SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_FIXUP_ASUS_MODE2), | 5616 | SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_FIXUP_ASUS_MODE2), |
5617 | SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1), | 5617 | SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1), |
5618 | SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE4), | 5618 | SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE4), |
5619 | #endif | 5619 | #endif |
5620 | {} | 5620 | {} |
5621 | }; | 5621 | }; |
5622 | 5622 | ||
5623 | static const struct hda_model_fixup alc662_fixup_models[] = { | 5623 | static const struct hda_model_fixup alc662_fixup_models[] = { |
5624 | {.id = ALC272_FIXUP_MARIO, .name = "mario"}, | 5624 | {.id = ALC272_FIXUP_MARIO, .name = "mario"}, |
5625 | {.id = ALC662_FIXUP_ASUS_MODE1, .name = "asus-mode1"}, | 5625 | {.id = ALC662_FIXUP_ASUS_MODE1, .name = "asus-mode1"}, |
5626 | {.id = ALC662_FIXUP_ASUS_MODE2, .name = "asus-mode2"}, | 5626 | {.id = ALC662_FIXUP_ASUS_MODE2, .name = "asus-mode2"}, |
5627 | {.id = ALC662_FIXUP_ASUS_MODE3, .name = "asus-mode3"}, | 5627 | {.id = ALC662_FIXUP_ASUS_MODE3, .name = "asus-mode3"}, |
5628 | {.id = ALC662_FIXUP_ASUS_MODE4, .name = "asus-mode4"}, | 5628 | {.id = ALC662_FIXUP_ASUS_MODE4, .name = "asus-mode4"}, |
5629 | {.id = ALC662_FIXUP_ASUS_MODE5, .name = "asus-mode5"}, | 5629 | {.id = ALC662_FIXUP_ASUS_MODE5, .name = "asus-mode5"}, |
5630 | {.id = ALC662_FIXUP_ASUS_MODE6, .name = "asus-mode6"}, | 5630 | {.id = ALC662_FIXUP_ASUS_MODE6, .name = "asus-mode6"}, |
5631 | {.id = ALC662_FIXUP_ASUS_MODE7, .name = "asus-mode7"}, | 5631 | {.id = ALC662_FIXUP_ASUS_MODE7, .name = "asus-mode7"}, |
5632 | {.id = ALC662_FIXUP_ASUS_MODE8, .name = "asus-mode8"}, | 5632 | {.id = ALC662_FIXUP_ASUS_MODE8, .name = "asus-mode8"}, |
5633 | {.id = ALC662_FIXUP_INV_DMIC, .name = "inv-dmic"}, | 5633 | {.id = ALC662_FIXUP_INV_DMIC, .name = "inv-dmic"}, |
5634 | {.id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE, .name = "dell-headset-multi"}, | 5634 | {.id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE, .name = "dell-headset-multi"}, |
5635 | {} | 5635 | {} |
5636 | }; | 5636 | }; |
5637 | 5637 | ||
5638 | static void alc662_fill_coef(struct hda_codec *codec) | 5638 | static void alc662_fill_coef(struct hda_codec *codec) |
5639 | { | 5639 | { |
5640 | int val, coef; | 5640 | int val, coef; |
5641 | 5641 | ||
5642 | coef = alc_get_coef0(codec); | 5642 | coef = alc_get_coef0(codec); |
5643 | 5643 | ||
5644 | switch (codec->vendor_id) { | 5644 | switch (codec->vendor_id) { |
5645 | case 0x10ec0662: | 5645 | case 0x10ec0662: |
5646 | if ((coef & 0x00f0) == 0x0030) { | 5646 | if ((coef & 0x00f0) == 0x0030) { |
5647 | val = alc_read_coef_idx(codec, 0x4); /* EAPD Ctrl */ | 5647 | val = alc_read_coef_idx(codec, 0x4); /* EAPD Ctrl */ |
5648 | alc_write_coef_idx(codec, 0x4, val & ~(1<<10)); | 5648 | alc_write_coef_idx(codec, 0x4, val & ~(1<<10)); |
5649 | } | 5649 | } |
5650 | break; | 5650 | break; |
5651 | case 0x10ec0272: | 5651 | case 0x10ec0272: |
5652 | case 0x10ec0273: | 5652 | case 0x10ec0273: |
5653 | case 0x10ec0663: | 5653 | case 0x10ec0663: |
5654 | case 0x10ec0665: | 5654 | case 0x10ec0665: |
5655 | case 0x10ec0670: | 5655 | case 0x10ec0670: |
5656 | case 0x10ec0671: | 5656 | case 0x10ec0671: |
5657 | case 0x10ec0672: | 5657 | case 0x10ec0672: |
5658 | val = alc_read_coef_idx(codec, 0xd); /* EAPD Ctrl */ | 5658 | val = alc_read_coef_idx(codec, 0xd); /* EAPD Ctrl */ |
5659 | alc_write_coef_idx(codec, 0xd, val | (1<<14)); | 5659 | alc_write_coef_idx(codec, 0xd, val | (1<<14)); |
5660 | break; | 5660 | break; |
5661 | } | 5661 | } |
5662 | } | 5662 | } |
5663 | 5663 | ||
5664 | /* | 5664 | /* |
5665 | */ | 5665 | */ |
5666 | static int patch_alc662(struct hda_codec *codec) | 5666 | static int patch_alc662(struct hda_codec *codec) |
5667 | { | 5667 | { |
5668 | struct alc_spec *spec; | 5668 | struct alc_spec *spec; |
5669 | int err; | 5669 | int err; |
5670 | 5670 | ||
5671 | err = alc_alloc_spec(codec, 0x0b); | 5671 | err = alc_alloc_spec(codec, 0x0b); |
5672 | if (err < 0) | 5672 | if (err < 0) |
5673 | return err; | 5673 | return err; |
5674 | 5674 | ||
5675 | spec = codec->spec; | 5675 | spec = codec->spec; |
5676 | 5676 | ||
5677 | /* handle multiple HPs as is */ | 5677 | /* handle multiple HPs as is */ |
5678 | spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP; | 5678 | spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP; |
5679 | 5679 | ||
5680 | alc_fix_pll_init(codec, 0x20, 0x04, 15); | 5680 | alc_fix_pll_init(codec, 0x20, 0x04, 15); |
5681 | 5681 | ||
5682 | spec->init_hook = alc662_fill_coef; | 5682 | spec->init_hook = alc662_fill_coef; |
5683 | alc662_fill_coef(codec); | 5683 | alc662_fill_coef(codec); |
5684 | 5684 | ||
5685 | snd_hda_pick_fixup(codec, alc662_fixup_models, | 5685 | snd_hda_pick_fixup(codec, alc662_fixup_models, |
5686 | alc662_fixup_tbl, alc662_fixups); | 5686 | alc662_fixup_tbl, alc662_fixups); |
5687 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); | 5687 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); |
5688 | 5688 | ||
5689 | alc_auto_parse_customize_define(codec); | 5689 | alc_auto_parse_customize_define(codec); |
5690 | 5690 | ||
5691 | if (has_cdefine_beep(codec)) | 5691 | if (has_cdefine_beep(codec)) |
5692 | spec->gen.beep_nid = 0x01; | 5692 | spec->gen.beep_nid = 0x01; |
5693 | 5693 | ||
5694 | if ((alc_get_coef0(codec) & (1 << 14)) && | 5694 | if ((alc_get_coef0(codec) & (1 << 14)) && |
5695 | codec->bus->pci && codec->bus->pci->subsystem_vendor == 0x1025 && | 5695 | codec->bus->pci && codec->bus->pci->subsystem_vendor == 0x1025 && |
5696 | spec->cdefine.platform_type == 1) { | 5696 | spec->cdefine.platform_type == 1) { |
5697 | err = alc_codec_rename(codec, "ALC272X"); | 5697 | err = alc_codec_rename(codec, "ALC272X"); |
5698 | if (err < 0) | 5698 | if (err < 0) |
5699 | goto error; | 5699 | goto error; |
5700 | } | 5700 | } |
5701 | 5701 | ||
5702 | /* automatic parse from the BIOS config */ | 5702 | /* automatic parse from the BIOS config */ |
5703 | err = alc662_parse_auto_config(codec); | 5703 | err = alc662_parse_auto_config(codec); |
5704 | if (err < 0) | 5704 | if (err < 0) |
5705 | goto error; | 5705 | goto error; |
5706 | 5706 | ||
5707 | if (!spec->gen.no_analog && spec->gen.beep_nid) { | 5707 | if (!spec->gen.no_analog && spec->gen.beep_nid) { |
5708 | switch (codec->vendor_id) { | 5708 | switch (codec->vendor_id) { |
5709 | case 0x10ec0662: | 5709 | case 0x10ec0662: |
5710 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); | 5710 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); |
5711 | break; | 5711 | break; |
5712 | case 0x10ec0272: | 5712 | case 0x10ec0272: |
5713 | case 0x10ec0663: | 5713 | case 0x10ec0663: |
5714 | case 0x10ec0665: | 5714 | case 0x10ec0665: |
5715 | case 0x10ec0668: | 5715 | case 0x10ec0668: |
5716 | set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); | 5716 | set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); |
5717 | break; | 5717 | break; |
5718 | case 0x10ec0273: | 5718 | case 0x10ec0273: |
5719 | set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT); | 5719 | set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT); |
5720 | break; | 5720 | break; |
5721 | } | 5721 | } |
5722 | } | 5722 | } |
5723 | 5723 | ||
5724 | codec->patch_ops = alc_patch_ops; | 5724 | codec->patch_ops = alc_patch_ops; |
5725 | spec->shutup = alc_eapd_shutup; | 5725 | spec->shutup = alc_eapd_shutup; |
5726 | 5726 | ||
5727 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); | 5727 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); |
5728 | 5728 | ||
5729 | return 0; | 5729 | return 0; |
5730 | 5730 | ||
5731 | error: | 5731 | error: |
5732 | alc_free(codec); | 5732 | alc_free(codec); |
5733 | return err; | 5733 | return err; |
5734 | } | 5734 | } |
5735 | 5735 | ||
5736 | /* | 5736 | /* |
5737 | * ALC680 support | 5737 | * ALC680 support |
5738 | */ | 5738 | */ |
5739 | 5739 | ||
5740 | static int alc680_parse_auto_config(struct hda_codec *codec) | 5740 | static int alc680_parse_auto_config(struct hda_codec *codec) |
5741 | { | 5741 | { |
5742 | return alc_parse_auto_config(codec, NULL, NULL); | 5742 | return alc_parse_auto_config(codec, NULL, NULL); |
5743 | } | 5743 | } |
5744 | 5744 | ||
5745 | /* | 5745 | /* |
5746 | */ | 5746 | */ |
5747 | static int patch_alc680(struct hda_codec *codec) | 5747 | static int patch_alc680(struct hda_codec *codec) |
5748 | { | 5748 | { |
5749 | int err; | 5749 | int err; |
5750 | 5750 | ||
5751 | /* ALC680 has no aa-loopback mixer */ | 5751 | /* ALC680 has no aa-loopback mixer */ |
5752 | err = alc_alloc_spec(codec, 0); | 5752 | err = alc_alloc_spec(codec, 0); |
5753 | if (err < 0) | 5753 | if (err < 0) |
5754 | return err; | 5754 | return err; |
5755 | 5755 | ||
5756 | /* automatic parse from the BIOS config */ | 5756 | /* automatic parse from the BIOS config */ |
5757 | err = alc680_parse_auto_config(codec); | 5757 | err = alc680_parse_auto_config(codec); |
5758 | if (err < 0) { | 5758 | if (err < 0) { |
5759 | alc_free(codec); | 5759 | alc_free(codec); |
5760 | return err; | 5760 | return err; |
5761 | } | 5761 | } |
5762 | 5762 | ||
5763 | codec->patch_ops = alc_patch_ops; | 5763 | codec->patch_ops = alc_patch_ops; |
5764 | 5764 | ||
5765 | return 0; | 5765 | return 0; |
5766 | } | 5766 | } |
5767 | 5767 | ||
5768 | /* | 5768 | /* |
5769 | * patch entries | 5769 | * patch entries |
5770 | */ | 5770 | */ |
5771 | static const struct hda_codec_preset snd_hda_preset_realtek[] = { | 5771 | static const struct hda_codec_preset snd_hda_preset_realtek[] = { |
5772 | { .id = 0x10ec0221, .name = "ALC221", .patch = patch_alc269 }, | 5772 | { .id = 0x10ec0221, .name = "ALC221", .patch = patch_alc269 }, |
5773 | { .id = 0x10ec0231, .name = "ALC231", .patch = patch_alc269 }, | 5773 | { .id = 0x10ec0231, .name = "ALC231", .patch = patch_alc269 }, |
5774 | { .id = 0x10ec0233, .name = "ALC233", .patch = patch_alc269 }, | 5774 | { .id = 0x10ec0233, .name = "ALC233", .patch = patch_alc269 }, |
5775 | { .id = 0x10ec0255, .name = "ALC255", .patch = patch_alc269 }, | 5775 | { .id = 0x10ec0255, .name = "ALC255", .patch = patch_alc269 }, |
5776 | { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 }, | 5776 | { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 }, |
5777 | { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 }, | 5777 | { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 }, |
5778 | { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 }, | 5778 | { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 }, |
5779 | { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 }, | 5779 | { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 }, |
5780 | { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 }, | 5780 | { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 }, |
5781 | { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 }, | 5781 | { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 }, |
5782 | { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 }, | 5782 | { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 }, |
5783 | { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 }, | 5783 | { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 }, |
5784 | { .id = 0x10ec0276, .name = "ALC276", .patch = patch_alc269 }, | 5784 | { .id = 0x10ec0276, .name = "ALC276", .patch = patch_alc269 }, |
5785 | { .id = 0x10ec0280, .name = "ALC280", .patch = patch_alc269 }, | 5785 | { .id = 0x10ec0280, .name = "ALC280", .patch = patch_alc269 }, |
5786 | { .id = 0x10ec0282, .name = "ALC282", .patch = patch_alc269 }, | 5786 | { .id = 0x10ec0282, .name = "ALC282", .patch = patch_alc269 }, |
5787 | { .id = 0x10ec0283, .name = "ALC283", .patch = patch_alc269 }, | 5787 | { .id = 0x10ec0283, .name = "ALC283", .patch = patch_alc269 }, |
5788 | { .id = 0x10ec0284, .name = "ALC284", .patch = patch_alc269 }, | 5788 | { .id = 0x10ec0284, .name = "ALC284", .patch = patch_alc269 }, |
5789 | { .id = 0x10ec0285, .name = "ALC285", .patch = patch_alc269 }, | 5789 | { .id = 0x10ec0285, .name = "ALC285", .patch = patch_alc269 }, |
5790 | { .id = 0x10ec0286, .name = "ALC286", .patch = patch_alc269 }, | 5790 | { .id = 0x10ec0286, .name = "ALC286", .patch = patch_alc269 }, |
5791 | { .id = 0x10ec0288, .name = "ALC288", .patch = patch_alc269 }, | 5791 | { .id = 0x10ec0288, .name = "ALC288", .patch = patch_alc269 }, |
5792 | { .id = 0x10ec0290, .name = "ALC290", .patch = patch_alc269 }, | 5792 | { .id = 0x10ec0290, .name = "ALC290", .patch = patch_alc269 }, |
5793 | { .id = 0x10ec0292, .name = "ALC292", .patch = patch_alc269 }, | 5793 | { .id = 0x10ec0292, .name = "ALC292", .patch = patch_alc269 }, |
5794 | { .id = 0x10ec0293, .name = "ALC293", .patch = patch_alc269 }, | 5794 | { .id = 0x10ec0293, .name = "ALC293", .patch = patch_alc269 }, |
5795 | { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", | 5795 | { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", |
5796 | .patch = patch_alc861 }, | 5796 | .patch = patch_alc861 }, |
5797 | { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd }, | 5797 | { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd }, |
5798 | { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 }, | 5798 | { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 }, |
5799 | { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd }, | 5799 | { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd }, |
5800 | { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2", | 5800 | { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2", |
5801 | .patch = patch_alc882 }, | 5801 | .patch = patch_alc882 }, |
5802 | { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1", | 5802 | { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1", |
5803 | .patch = patch_alc662 }, | 5803 | .patch = patch_alc662 }, |
5804 | { .id = 0x10ec0662, .rev = 0x100300, .name = "ALC662 rev3", | 5804 | { .id = 0x10ec0662, .rev = 0x100300, .name = "ALC662 rev3", |
5805 | .patch = patch_alc662 }, | 5805 | .patch = patch_alc662 }, |
5806 | { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 }, | 5806 | { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 }, |
5807 | { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 }, | 5807 | { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 }, |
5808 | { .id = 0x10ec0668, .name = "ALC668", .patch = patch_alc662 }, | 5808 | { .id = 0x10ec0668, .name = "ALC668", .patch = patch_alc662 }, |
5809 | { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 }, | 5809 | { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 }, |
5810 | { .id = 0x10ec0671, .name = "ALC671", .patch = patch_alc662 }, | 5810 | { .id = 0x10ec0671, .name = "ALC671", .patch = patch_alc662 }, |
5811 | { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 }, | 5811 | { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 }, |
5812 | { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, | 5812 | { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, |
5813 | { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, | 5813 | { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, |
5814 | { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 }, | 5814 | { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 }, |
5815 | { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A", | 5815 | { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A", |
5816 | .patch = patch_alc882 }, | 5816 | .patch = patch_alc882 }, |
5817 | { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A", | 5817 | { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A", |
5818 | .patch = patch_alc882 }, | 5818 | .patch = patch_alc882 }, |
5819 | { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 }, | 5819 | { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 }, |
5820 | { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 }, | 5820 | { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 }, |
5821 | { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200", | 5821 | { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200", |
5822 | .patch = patch_alc882 }, | 5822 | .patch = patch_alc882 }, |
5823 | { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc882 }, | 5823 | { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc882 }, |
5824 | { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 }, | 5824 | { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 }, |
5825 | { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 }, | 5825 | { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 }, |
5826 | { .id = 0x10ec0899, .name = "ALC898", .patch = patch_alc882 }, | 5826 | { .id = 0x10ec0899, .name = "ALC898", .patch = patch_alc882 }, |
5827 | { .id = 0x10ec0900, .name = "ALC1150", .patch = patch_alc882 }, | 5827 | { .id = 0x10ec0900, .name = "ALC1150", .patch = patch_alc882 }, |
5828 | {} /* terminator */ | 5828 | {} /* terminator */ |
5829 | }; | 5829 | }; |
5830 | 5830 | ||
5831 | MODULE_ALIAS("snd-hda-codec-id:10ec*"); | 5831 | MODULE_ALIAS("snd-hda-codec-id:10ec*"); |
5832 | 5832 | ||
5833 | MODULE_LICENSE("GPL"); | 5833 | MODULE_LICENSE("GPL"); |
5834 | MODULE_DESCRIPTION("Realtek HD-audio codec"); | 5834 | MODULE_DESCRIPTION("Realtek HD-audio codec"); |
5835 | 5835 | ||
5836 | static struct hda_codec_preset_list realtek_list = { | 5836 | static struct hda_codec_preset_list realtek_list = { |
5837 | .preset = snd_hda_preset_realtek, | 5837 | .preset = snd_hda_preset_realtek, |
5838 | .owner = THIS_MODULE, | 5838 | .owner = THIS_MODULE, |
5839 | }; | 5839 | }; |
5840 | 5840 | ||
5841 | static int __init patch_realtek_init(void) | 5841 | static int __init patch_realtek_init(void) |
5842 | { | 5842 | { |
5843 | return snd_hda_add_codec_preset(&realtek_list); | 5843 | return snd_hda_add_codec_preset(&realtek_list); |
5844 | } | 5844 | } |
5845 | 5845 | ||
5846 | static void __exit patch_realtek_exit(void) | 5846 | static void __exit patch_realtek_exit(void) |
5847 | { | 5847 | { |
5848 | snd_hda_delete_codec_preset(&realtek_list); | 5848 | snd_hda_delete_codec_preset(&realtek_list); |
5849 | } | 5849 | } |
5850 | 5850 | ||
5851 | module_init(patch_realtek_init) | 5851 | module_init(patch_realtek_init) |
5852 | module_exit(patch_realtek_exit) | 5852 | module_exit(patch_realtek_exit) |
5853 | 5853 |