1 /*
2 * Universal Interface for Intel High Definition Audio Codec
3 *
4 * HD audio interface patch for Realtek ALC codecs
5 *
6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7 * PeiSen Hou <pshou@realtek.com.tw>
8 * Takashi Iwai <tiwai@suse.de>
9 * Jonathan Woithe <jwoithe@just42.net>
10 *
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
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This driver is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
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
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */
25
26 #include <linux/init.h>
27 #include <linux/delay.h>
28 #include <linux/slab.h>
29 #include <linux/pci.h>
30 #include <linux/dmi.h>
31 #include <linux/module.h>
32 #include <linux/input.h>
33 #include <sound/core.h>
34 #include <sound/jack.h>
35 #include "hda_codec.h"
36 #include "hda_local.h"
37 #include "hda_auto_parser.h"
38 #include "hda_jack.h"
39 #include "hda_generic.h"
40
41 /* keep halting ALC5505 DSP, for power saving */
42 #define HALT_REALTEK_ALC5505
43
44 /* for GPIO Poll */
45 #define GPIO_MASK 0x03
46
47 /* extra amp-initialization sequence types */
48 enum {
49 ALC_INIT_NONE,
50 ALC_INIT_DEFAULT,
51 ALC_INIT_GPIO1,
52 ALC_INIT_GPIO2,
53 ALC_INIT_GPIO3,
54 };
55
56 enum {
57 ALC_HEADSET_MODE_UNKNOWN,
58 ALC_HEADSET_MODE_UNPLUGGED,
59 ALC_HEADSET_MODE_HEADSET,
60 ALC_HEADSET_MODE_MIC,
61 ALC_HEADSET_MODE_HEADPHONE,
62 };
63
64 enum {
65 ALC_HEADSET_TYPE_UNKNOWN,
66 ALC_HEADSET_TYPE_CTIA,
67 ALC_HEADSET_TYPE_OMTP,
68 };
69
70 struct alc_customize_define {
71 unsigned int sku_cfg;
72 unsigned char port_connectivity;
73 unsigned char check_sum;
74 unsigned char customization;
75 unsigned char external_amp;
76 unsigned int enable_pcbeep:1;
77 unsigned int platform_type:1;
78 unsigned int swap:1;
79 unsigned int override:1;
80 unsigned int fixup:1; /* Means that this sku is set by driver, not read from hw */
81 };
82
83 struct alc_spec {
84 struct hda_gen_spec gen; /* must be at head */
85
86 /* codec parameterization */
87 const struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
88 unsigned int num_mixers;
89 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
90
91 struct alc_customize_define cdefine;
92 unsigned int parse_flags; /* flag for snd_hda_parse_pin_defcfg() */
93
94 /* mute LED for HP laptops, see alc269_fixup_mic_mute_hook() */
95 int mute_led_polarity;
96 hda_nid_t mute_led_nid;
97 hda_nid_t cap_mute_led_nid;
98
99 unsigned int gpio_led; /* used for alc269_fixup_hp_gpio_led() */
100 unsigned int gpio_mute_led_mask;
101 unsigned int gpio_mic_led_mask;
102
103 hda_nid_t headset_mic_pin;
104 hda_nid_t headphone_mic_pin;
105 int current_headset_mode;
106 int current_headset_type;
107
108 /* hooks */
109 void (*init_hook)(struct hda_codec *codec);
110 #ifdef CONFIG_PM
111 void (*power_hook)(struct hda_codec *codec);
112 #endif
113 void (*shutup)(struct hda_codec *codec);
114
115 int init_amp;
116 int codec_variant; /* flag for other variants */
117 unsigned int has_alc5505_dsp:1;
118 unsigned int no_depop_delay:1;
119
120 /* for PLL fix */
121 hda_nid_t pll_nid;
122 unsigned int pll_coef_idx, pll_coef_bit;
123 unsigned int coef0;
124 #if IS_ENABLED(CONFIG_INPUT)
125 struct input_dev *kb_dev;
126 #endif
127 };
128
129 /*
130 * COEF access helper functions
131 */
132
alc_read_coefex_idx(struct hda_codec * codec,hda_nid_t nid,unsigned int coef_idx)133 static int alc_read_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
134 unsigned int coef_idx)
135 {
136 unsigned int val;
137
138 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, coef_idx);
139 val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PROC_COEF, 0);
140 return val;
141 }
142
143 #define alc_read_coef_idx(codec, coef_idx) \
144 alc_read_coefex_idx(codec, 0x20, coef_idx)
145
alc_write_coefex_idx(struct hda_codec * codec,hda_nid_t nid,unsigned int coef_idx,unsigned int coef_val)146 static void alc_write_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
147 unsigned int coef_idx, unsigned int coef_val)
148 {
149 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, coef_idx);
150 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PROC_COEF, coef_val);
151 }
152
153 #define alc_write_coef_idx(codec, coef_idx, coef_val) \
154 alc_write_coefex_idx(codec, 0x20, coef_idx, coef_val)
155
alc_update_coefex_idx(struct hda_codec * codec,hda_nid_t nid,unsigned int coef_idx,unsigned int mask,unsigned int bits_set)156 static void alc_update_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
157 unsigned int coef_idx, unsigned int mask,
158 unsigned int bits_set)
159 {
160 unsigned int val = alc_read_coefex_idx(codec, nid, coef_idx);
161
162 if (val != -1)
163 alc_write_coefex_idx(codec, nid, coef_idx,
164 (val & ~mask) | bits_set);
165 }
166
167 #define alc_update_coef_idx(codec, coef_idx, mask, bits_set) \
168 alc_update_coefex_idx(codec, 0x20, coef_idx, mask, bits_set)
169
170 /* a special bypass for COEF 0; read the cached value at the second time */
alc_get_coef0(struct hda_codec * codec)171 static unsigned int alc_get_coef0(struct hda_codec *codec)
172 {
173 struct alc_spec *spec = codec->spec;
174
175 if (!spec->coef0)
176 spec->coef0 = alc_read_coef_idx(codec, 0);
177 return spec->coef0;
178 }
179
180 /* coef writes/updates batch */
181 struct coef_fw {
182 unsigned char nid;
183 unsigned char idx;
184 unsigned short mask;
185 unsigned short val;
186 };
187
188 #define UPDATE_COEFEX(_nid, _idx, _mask, _val) \
189 { .nid = (_nid), .idx = (_idx), .mask = (_mask), .val = (_val) }
190 #define WRITE_COEFEX(_nid, _idx, _val) UPDATE_COEFEX(_nid, _idx, -1, _val)
191 #define WRITE_COEF(_idx, _val) WRITE_COEFEX(0x20, _idx, _val)
192 #define UPDATE_COEF(_idx, _mask, _val) UPDATE_COEFEX(0x20, _idx, _mask, _val)
193
alc_process_coef_fw(struct hda_codec * codec,const struct coef_fw * fw)194 static void alc_process_coef_fw(struct hda_codec *codec,
195 const struct coef_fw *fw)
196 {
197 for (; fw->nid; fw++) {
198 if (fw->mask == (unsigned short)-1)
199 alc_write_coefex_idx(codec, fw->nid, fw->idx, fw->val);
200 else
201 alc_update_coefex_idx(codec, fw->nid, fw->idx,
202 fw->mask, fw->val);
203 }
204 }
205
206 /*
207 * Append the given mixer and verb elements for the later use
208 * The mixer array is referred in build_controls(), and init_verbs are
209 * called in init().
210 */
add_mixer(struct alc_spec * spec,const struct snd_kcontrol_new * mix)211 static void add_mixer(struct alc_spec *spec, const struct snd_kcontrol_new *mix)
212 {
213 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
214 return;
215 spec->mixers[spec->num_mixers++] = mix;
216 }
217
218 /*
219 * GPIO setup tables, used in initialization
220 */
221 /* Enable GPIO mask and set output */
222 static const struct hda_verb alc_gpio1_init_verbs[] = {
223 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
224 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
225 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
226 { }
227 };
228
229 static const struct hda_verb alc_gpio2_init_verbs[] = {
230 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
231 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
232 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
233 { }
234 };
235
236 static const struct hda_verb alc_gpio3_init_verbs[] = {
237 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
238 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
239 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
240 { }
241 };
242
243 /*
244 * Fix hardware PLL issue
245 * On some codecs, the analog PLL gating control must be off while
246 * the default value is 1.
247 */
alc_fix_pll(struct hda_codec * codec)248 static void alc_fix_pll(struct hda_codec *codec)
249 {
250 struct alc_spec *spec = codec->spec;
251
252 if (spec->pll_nid)
253 alc_update_coefex_idx(codec, spec->pll_nid, spec->pll_coef_idx,
254 1 << spec->pll_coef_bit, 0);
255 }
256
alc_fix_pll_init(struct hda_codec * codec,hda_nid_t nid,unsigned int coef_idx,unsigned int coef_bit)257 static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
258 unsigned int coef_idx, unsigned int coef_bit)
259 {
260 struct alc_spec *spec = codec->spec;
261 spec->pll_nid = nid;
262 spec->pll_coef_idx = coef_idx;
263 spec->pll_coef_bit = coef_bit;
264 alc_fix_pll(codec);
265 }
266
267 /* update the master volume per volume-knob's unsol event */
alc_update_knob_master(struct hda_codec * codec,struct hda_jack_callback * jack)268 static void alc_update_knob_master(struct hda_codec *codec,
269 struct hda_jack_callback *jack)
270 {
271 unsigned int val;
272 struct snd_kcontrol *kctl;
273 struct snd_ctl_elem_value *uctl;
274
275 kctl = snd_hda_find_mixer_ctl(codec, "Master Playback Volume");
276 if (!kctl)
277 return;
278 uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
279 if (!uctl)
280 return;
281 val = snd_hda_codec_read(codec, jack->tbl->nid, 0,
282 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
283 val &= HDA_AMP_VOLMASK;
284 uctl->value.integer.value[0] = val;
285 uctl->value.integer.value[1] = val;
286 kctl->put(kctl, uctl);
287 kfree(uctl);
288 }
289
alc880_unsol_event(struct hda_codec * codec,unsigned int res)290 static void alc880_unsol_event(struct hda_codec *codec, unsigned int res)
291 {
292 /* For some reason, the res given from ALC880 is broken.
293 Here we adjust it properly. */
294 snd_hda_jack_unsol_event(codec, res >> 2);
295 }
296
297 /* Change EAPD to verb control */
alc_fill_eapd_coef(struct hda_codec * codec)298 static void alc_fill_eapd_coef(struct hda_codec *codec)
299 {
300 int coef;
301
302 coef = alc_get_coef0(codec);
303
304 switch (codec->vendor_id) {
305 case 0x10ec0262:
306 alc_update_coef_idx(codec, 0x7, 0, 1<<5);
307 break;
308 case 0x10ec0267:
309 case 0x10ec0268:
310 alc_update_coef_idx(codec, 0x7, 0, 1<<13);
311 break;
312 case 0x10ec0269:
313 if ((coef & 0x00f0) == 0x0010)
314 alc_update_coef_idx(codec, 0xd, 0, 1<<14);
315 if ((coef & 0x00f0) == 0x0020)
316 alc_update_coef_idx(codec, 0x4, 1<<15, 0);
317 if ((coef & 0x00f0) == 0x0030)
318 alc_update_coef_idx(codec, 0x10, 1<<9, 0);
319 break;
320 case 0x10ec0280:
321 case 0x10ec0284:
322 case 0x10ec0290:
323 case 0x10ec0292:
324 alc_update_coef_idx(codec, 0x4, 1<<15, 0);
325 break;
326 case 0x10ec0233:
327 case 0x10ec0255:
328 case 0x10ec0256:
329 case 0x10ec0282:
330 case 0x10ec0283:
331 case 0x10ec0286:
332 case 0x10ec0288:
333 case 0x10ec0298:
334 alc_update_coef_idx(codec, 0x10, 1<<9, 0);
335 break;
336 case 0x10ec0285:
337 case 0x10ec0293:
338 alc_update_coef_idx(codec, 0xa, 1<<13, 0);
339 break;
340 case 0x10ec0662:
341 if ((coef & 0x00f0) == 0x0030)
342 alc_update_coef_idx(codec, 0x4, 1<<10, 0); /* EAPD Ctrl */
343 break;
344 case 0x10ec0272:
345 case 0x10ec0273:
346 case 0x10ec0663:
347 case 0x10ec0665:
348 case 0x10ec0670:
349 case 0x10ec0671:
350 case 0x10ec0672:
351 alc_update_coef_idx(codec, 0xd, 0, 1<<14); /* EAPD Ctrl */
352 break;
353 case 0x10ec0668:
354 alc_update_coef_idx(codec, 0x7, 3<<13, 0);
355 break;
356 case 0x10ec0867:
357 alc_update_coef_idx(codec, 0x4, 1<<10, 0);
358 break;
359 case 0x10ec0888:
360 if ((coef & 0x00f0) == 0x0020 || (coef & 0x00f0) == 0x0030)
361 alc_update_coef_idx(codec, 0x7, 1<<5, 0);
362 break;
363 case 0x10ec0892:
364 alc_update_coef_idx(codec, 0x7, 1<<5, 0);
365 break;
366 case 0x10ec0899:
367 case 0x10ec0900:
368 alc_update_coef_idx(codec, 0x7, 1<<1, 0);
369 break;
370 }
371 }
372
373 /* additional initialization for ALC888 variants */
alc888_coef_init(struct hda_codec * codec)374 static void alc888_coef_init(struct hda_codec *codec)
375 {
376 switch (alc_get_coef0(codec) & 0x00f0) {
377 /* alc888-VA */
378 case 0x00:
379 /* alc888-VB */
380 case 0x10:
381 alc_update_coef_idx(codec, 7, 0, 0x2030); /* Turn EAPD to High */
382 break;
383 }
384 }
385
386 /* turn on/off EAPD control (only if available) */
set_eapd(struct hda_codec * codec,hda_nid_t nid,int on)387 static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
388 {
389 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
390 return;
391 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
392 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
393 on ? 2 : 0);
394 }
395
396 /* turn on/off EAPD controls of the codec */
alc_auto_setup_eapd(struct hda_codec * codec,bool on)397 static void alc_auto_setup_eapd(struct hda_codec *codec, bool on)
398 {
399 /* We currently only handle front, HP */
400 static hda_nid_t pins[] = {
401 0x0f, 0x10, 0x14, 0x15, 0x17, 0
402 };
403 hda_nid_t *p;
404 for (p = pins; *p; p++)
405 set_eapd(codec, *p, on);
406 }
407
408 /* generic shutup callback;
409 * just turning off EPAD and a little pause for avoiding pop-noise
410 */
alc_eapd_shutup(struct hda_codec * codec)411 static void alc_eapd_shutup(struct hda_codec *codec)
412 {
413 struct alc_spec *spec = codec->spec;
414
415 alc_auto_setup_eapd(codec, false);
416 if (!spec->no_depop_delay)
417 msleep(200);
418 snd_hda_shutup_pins(codec);
419 }
420
421 /* generic EAPD initialization */
alc_auto_init_amp(struct hda_codec * codec,int type)422 static void alc_auto_init_amp(struct hda_codec *codec, int type)
423 {
424 alc_fill_eapd_coef(codec);
425 alc_auto_setup_eapd(codec, true);
426 switch (type) {
427 case ALC_INIT_GPIO1:
428 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
429 break;
430 case ALC_INIT_GPIO2:
431 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
432 break;
433 case ALC_INIT_GPIO3:
434 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
435 break;
436 case ALC_INIT_DEFAULT:
437 switch (codec->vendor_id) {
438 case 0x10ec0260:
439 alc_update_coefex_idx(codec, 0x1a, 7, 0, 0x2010);
440 break;
441 case 0x10ec0880:
442 case 0x10ec0882:
443 case 0x10ec0883:
444 case 0x10ec0885:
445 alc_update_coef_idx(codec, 7, 0, 0x2030);
446 break;
447 case 0x10ec0888:
448 alc888_coef_init(codec);
449 break;
450 }
451 break;
452 }
453 }
454
455
456 /*
457 * Realtek SSID verification
458 */
459
460 /* Could be any non-zero and even value. When used as fixup, tells
461 * the driver to ignore any present sku defines.
462 */
463 #define ALC_FIXUP_SKU_IGNORE (2)
464
alc_fixup_sku_ignore(struct hda_codec * codec,const struct hda_fixup * fix,int action)465 static void alc_fixup_sku_ignore(struct hda_codec *codec,
466 const struct hda_fixup *fix, int action)
467 {
468 struct alc_spec *spec = codec->spec;
469 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
470 spec->cdefine.fixup = 1;
471 spec->cdefine.sku_cfg = ALC_FIXUP_SKU_IGNORE;
472 }
473 }
474
alc_fixup_no_depop_delay(struct hda_codec * codec,const struct hda_fixup * fix,int action)475 static void alc_fixup_no_depop_delay(struct hda_codec *codec,
476 const struct hda_fixup *fix, int action)
477 {
478 struct alc_spec *spec = codec->spec;
479
480 if (action == HDA_FIXUP_ACT_PROBE) {
481 spec->no_depop_delay = 1;
482 codec->depop_delay = 0;
483 }
484 }
485
alc_auto_parse_customize_define(struct hda_codec * codec)486 static int alc_auto_parse_customize_define(struct hda_codec *codec)
487 {
488 unsigned int ass, tmp, i;
489 unsigned nid = 0;
490 struct alc_spec *spec = codec->spec;
491
492 spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
493
494 if (spec->cdefine.fixup) {
495 ass = spec->cdefine.sku_cfg;
496 if (ass == ALC_FIXUP_SKU_IGNORE)
497 return -1;
498 goto do_sku;
499 }
500
501 if (!codec->bus->pci)
502 return -1;
503 ass = codec->subsystem_id & 0xffff;
504 if (ass != codec->bus->pci->subsystem_device && (ass & 1))
505 goto do_sku;
506
507 nid = 0x1d;
508 if (codec->vendor_id == 0x10ec0260)
509 nid = 0x17;
510 ass = snd_hda_codec_get_pincfg(codec, nid);
511
512 if (!(ass & 1)) {
513 codec_info(codec, "%s: SKU not ready 0x%08x\n",
514 codec->chip_name, ass);
515 return -1;
516 }
517
518 /* check sum */
519 tmp = 0;
520 for (i = 1; i < 16; i++) {
521 if ((ass >> i) & 1)
522 tmp++;
523 }
524 if (((ass >> 16) & 0xf) != tmp)
525 return -1;
526
527 spec->cdefine.port_connectivity = ass >> 30;
528 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
529 spec->cdefine.check_sum = (ass >> 16) & 0xf;
530 spec->cdefine.customization = ass >> 8;
531 do_sku:
532 spec->cdefine.sku_cfg = ass;
533 spec->cdefine.external_amp = (ass & 0x38) >> 3;
534 spec->cdefine.platform_type = (ass & 0x4) >> 2;
535 spec->cdefine.swap = (ass & 0x2) >> 1;
536 spec->cdefine.override = ass & 0x1;
537
538 codec_dbg(codec, "SKU: Nid=0x%x sku_cfg=0x%08x\n",
539 nid, spec->cdefine.sku_cfg);
540 codec_dbg(codec, "SKU: port_connectivity=0x%x\n",
541 spec->cdefine.port_connectivity);
542 codec_dbg(codec, "SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
543 codec_dbg(codec, "SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
544 codec_dbg(codec, "SKU: customization=0x%08x\n", spec->cdefine.customization);
545 codec_dbg(codec, "SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
546 codec_dbg(codec, "SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
547 codec_dbg(codec, "SKU: swap=0x%x\n", spec->cdefine.swap);
548 codec_dbg(codec, "SKU: override=0x%x\n", spec->cdefine.override);
549
550 return 0;
551 }
552
553 /* return the position of NID in the list, or -1 if not found */
find_idx_in_nid_list(hda_nid_t nid,const hda_nid_t * list,int nums)554 static int find_idx_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
555 {
556 int i;
557 for (i = 0; i < nums; i++)
558 if (list[i] == nid)
559 return i;
560 return -1;
561 }
562 /* return true if the given NID is found in the list */
found_in_nid_list(hda_nid_t nid,const hda_nid_t * list,int nums)563 static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
564 {
565 return find_idx_in_nid_list(nid, list, nums) >= 0;
566 }
567
568 /* check subsystem ID and set up device-specific initialization;
569 * return 1 if initialized, 0 if invalid SSID
570 */
571 /* 32-bit subsystem ID for BIOS loading in HD Audio codec.
572 * 31 ~ 16 : Manufacture ID
573 * 15 ~ 8 : SKU ID
574 * 7 ~ 0 : Assembly ID
575 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
576 */
alc_subsystem_id(struct hda_codec * codec,const hda_nid_t * ports)577 static int alc_subsystem_id(struct hda_codec *codec, const hda_nid_t *ports)
578 {
579 unsigned int ass, tmp, i;
580 unsigned nid;
581 struct alc_spec *spec = codec->spec;
582
583 if (spec->cdefine.fixup) {
584 ass = spec->cdefine.sku_cfg;
585 if (ass == ALC_FIXUP_SKU_IGNORE)
586 return 0;
587 goto do_sku;
588 }
589
590 ass = codec->subsystem_id & 0xffff;
591 if (codec->bus->pci &&
592 ass != codec->bus->pci->subsystem_device && (ass & 1))
593 goto do_sku;
594
595 /* invalid SSID, check the special NID pin defcfg instead */
596 /*
597 * 31~30 : port connectivity
598 * 29~21 : reserve
599 * 20 : PCBEEP input
600 * 19~16 : Check sum (15:1)
601 * 15~1 : Custom
602 * 0 : override
603 */
604 nid = 0x1d;
605 if (codec->vendor_id == 0x10ec0260)
606 nid = 0x17;
607 ass = snd_hda_codec_get_pincfg(codec, nid);
608 codec_dbg(codec,
609 "realtek: No valid SSID, checking pincfg 0x%08x for NID 0x%x\n",
610 ass, nid);
611 if (!(ass & 1))
612 return 0;
613 if ((ass >> 30) != 1) /* no physical connection */
614 return 0;
615
616 /* check sum */
617 tmp = 0;
618 for (i = 1; i < 16; i++) {
619 if ((ass >> i) & 1)
620 tmp++;
621 }
622 if (((ass >> 16) & 0xf) != tmp)
623 return 0;
624 do_sku:
625 codec_dbg(codec, "realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
626 ass & 0xffff, codec->vendor_id);
627 /*
628 * 0 : override
629 * 1 : Swap Jack
630 * 2 : 0 --> Desktop, 1 --> Laptop
631 * 3~5 : External Amplifier control
632 * 7~6 : Reserved
633 */
634 tmp = (ass & 0x38) >> 3; /* external Amp control */
635 switch (tmp) {
636 case 1:
637 spec->init_amp = ALC_INIT_GPIO1;
638 break;
639 case 3:
640 spec->init_amp = ALC_INIT_GPIO2;
641 break;
642 case 7:
643 spec->init_amp = ALC_INIT_GPIO3;
644 break;
645 case 5:
646 default:
647 spec->init_amp = ALC_INIT_DEFAULT;
648 break;
649 }
650
651 /* is laptop or Desktop and enable the function "Mute internal speaker
652 * when the external headphone out jack is plugged"
653 */
654 if (!(ass & 0x8000))
655 return 1;
656 /*
657 * 10~8 : Jack location
658 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
659 * 14~13: Resvered
660 * 15 : 1 --> enable the function "Mute internal speaker
661 * when the external headphone out jack is plugged"
662 */
663 if (!spec->gen.autocfg.hp_pins[0] &&
664 !(spec->gen.autocfg.line_out_pins[0] &&
665 spec->gen.autocfg.line_out_type == AUTO_PIN_HP_OUT)) {
666 hda_nid_t nid;
667 tmp = (ass >> 11) & 0x3; /* HP to chassis */
668 nid = ports[tmp];
669 if (found_in_nid_list(nid, spec->gen.autocfg.line_out_pins,
670 spec->gen.autocfg.line_outs))
671 return 1;
672 spec->gen.autocfg.hp_pins[0] = nid;
673 }
674 return 1;
675 }
676
677 /* Check the validity of ALC subsystem-id
678 * ports contains an array of 4 pin NIDs for port-A, E, D and I */
alc_ssid_check(struct hda_codec * codec,const hda_nid_t * ports)679 static void alc_ssid_check(struct hda_codec *codec, const hda_nid_t *ports)
680 {
681 if (!alc_subsystem_id(codec, ports)) {
682 struct alc_spec *spec = codec->spec;
683 codec_dbg(codec,
684 "realtek: Enable default setup for auto mode as fallback\n");
685 spec->init_amp = ALC_INIT_DEFAULT;
686 }
687 }
688
689 /*
690 */
691
alc_fixup_inv_dmic(struct hda_codec * codec,const struct hda_fixup * fix,int action)692 static void alc_fixup_inv_dmic(struct hda_codec *codec,
693 const struct hda_fixup *fix, int action)
694 {
695 struct alc_spec *spec = codec->spec;
696
697 spec->gen.inv_dmic_split = 1;
698 }
699
700
701 #ifdef CONFIG_SND_HDA_INPUT_BEEP
702 /* additional beep mixers; the actual parameters are overwritten at build */
703 static const struct snd_kcontrol_new alc_beep_mixer[] = {
704 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
705 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
706 { } /* end */
707 };
708 #endif
709
alc_build_controls(struct hda_codec * codec)710 static int alc_build_controls(struct hda_codec *codec)
711 {
712 struct alc_spec *spec = codec->spec;
713 int i, err;
714
715 err = snd_hda_gen_build_controls(codec);
716 if (err < 0)
717 return err;
718
719 for (i = 0; i < spec->num_mixers; i++) {
720 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
721 if (err < 0)
722 return err;
723 }
724
725 #ifdef CONFIG_SND_HDA_INPUT_BEEP
726 /* create beep controls if needed */
727 if (spec->beep_amp) {
728 const struct snd_kcontrol_new *knew;
729 for (knew = alc_beep_mixer; knew->name; knew++) {
730 struct snd_kcontrol *kctl;
731 kctl = snd_ctl_new1(knew, codec);
732 if (!kctl)
733 return -ENOMEM;
734 kctl->private_value = spec->beep_amp;
735 err = snd_hda_ctl_add(codec, 0, kctl);
736 if (err < 0)
737 return err;
738 }
739 }
740 #endif
741
742 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_BUILD);
743 return 0;
744 }
745
746
747 /*
748 * Common callbacks
749 */
750
alc_init(struct hda_codec * codec)751 static int alc_init(struct hda_codec *codec)
752 {
753 struct alc_spec *spec = codec->spec;
754
755 if (spec->init_hook)
756 spec->init_hook(codec);
757
758 alc_fix_pll(codec);
759 alc_auto_init_amp(codec, spec->init_amp);
760
761 snd_hda_gen_init(codec);
762
763 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_INIT);
764
765 return 0;
766 }
767
alc_shutup(struct hda_codec * codec)768 static inline void alc_shutup(struct hda_codec *codec)
769 {
770 struct alc_spec *spec = codec->spec;
771
772 if (spec && spec->shutup)
773 spec->shutup(codec);
774 else
775 snd_hda_shutup_pins(codec);
776 }
777
778 #define alc_free snd_hda_gen_free
779
780 #ifdef CONFIG_PM
alc_power_eapd(struct hda_codec * codec)781 static void alc_power_eapd(struct hda_codec *codec)
782 {
783 alc_auto_setup_eapd(codec, false);
784 }
785
alc_suspend(struct hda_codec * codec)786 static int alc_suspend(struct hda_codec *codec)
787 {
788 struct alc_spec *spec = codec->spec;
789 alc_shutup(codec);
790 if (spec && spec->power_hook)
791 spec->power_hook(codec);
792 return 0;
793 }
794 #endif
795
796 #ifdef CONFIG_PM
alc_resume(struct hda_codec * codec)797 static int alc_resume(struct hda_codec *codec)
798 {
799 struct alc_spec *spec = codec->spec;
800
801 if (!spec->no_depop_delay)
802 msleep(150); /* to avoid pop noise */
803 codec->patch_ops.init(codec);
804 snd_hda_codec_resume_amp(codec);
805 snd_hda_codec_resume_cache(codec);
806 hda_call_check_power_status(codec, 0x01);
807 return 0;
808 }
809 #endif
810
811 /*
812 */
813 static const struct hda_codec_ops alc_patch_ops = {
814 .build_controls = alc_build_controls,
815 .build_pcms = snd_hda_gen_build_pcms,
816 .init = alc_init,
817 .free = alc_free,
818 .unsol_event = snd_hda_jack_unsol_event,
819 #ifdef CONFIG_PM
820 .resume = alc_resume,
821 .suspend = alc_suspend,
822 .check_power_status = snd_hda_gen_check_power_status,
823 #endif
824 .reboot_notify = alc_shutup,
825 };
826
827
828 /* replace the codec chip_name with the given string */
alc_codec_rename(struct hda_codec * codec,const char * name)829 static int alc_codec_rename(struct hda_codec *codec, const char *name)
830 {
831 kfree(codec->chip_name);
832 codec->chip_name = kstrdup(name, GFP_KERNEL);
833 if (!codec->chip_name) {
834 alc_free(codec);
835 return -ENOMEM;
836 }
837 return 0;
838 }
839
840 /*
841 * Rename codecs appropriately from COEF value or subvendor id
842 */
843 struct alc_codec_rename_table {
844 unsigned int vendor_id;
845 unsigned short coef_mask;
846 unsigned short coef_bits;
847 const char *name;
848 };
849
850 struct alc_codec_rename_pci_table {
851 unsigned int codec_vendor_id;
852 unsigned short pci_subvendor;
853 unsigned short pci_subdevice;
854 const char *name;
855 };
856
857 static struct alc_codec_rename_table rename_tbl[] = {
858 { 0x10ec0221, 0xf00f, 0x1003, "ALC231" },
859 { 0x10ec0269, 0xfff0, 0x3010, "ALC277" },
860 { 0x10ec0269, 0xf0f0, 0x2010, "ALC259" },
861 { 0x10ec0269, 0xf0f0, 0x3010, "ALC258" },
862 { 0x10ec0269, 0x00f0, 0x0010, "ALC269VB" },
863 { 0x10ec0269, 0xffff, 0xa023, "ALC259" },
864 { 0x10ec0269, 0xffff, 0x6023, "ALC281X" },
865 { 0x10ec0269, 0x00f0, 0x0020, "ALC269VC" },
866 { 0x10ec0269, 0x00f0, 0x0030, "ALC269VD" },
867 { 0x10ec0662, 0xffff, 0x4020, "ALC656" },
868 { 0x10ec0887, 0x00f0, 0x0030, "ALC887-VD" },
869 { 0x10ec0888, 0x00f0, 0x0030, "ALC888-VD" },
870 { 0x10ec0888, 0xf0f0, 0x3020, "ALC886" },
871 { 0x10ec0899, 0x2000, 0x2000, "ALC899" },
872 { 0x10ec0892, 0xffff, 0x8020, "ALC661" },
873 { 0x10ec0892, 0xffff, 0x8011, "ALC661" },
874 { 0x10ec0892, 0xffff, 0x4011, "ALC656" },
875 { } /* terminator */
876 };
877
878 static struct alc_codec_rename_pci_table rename_pci_tbl[] = {
879 { 0x10ec0280, 0x1028, 0, "ALC3220" },
880 { 0x10ec0282, 0x1028, 0, "ALC3221" },
881 { 0x10ec0283, 0x1028, 0, "ALC3223" },
882 { 0x10ec0288, 0x1028, 0, "ALC3263" },
883 { 0x10ec0292, 0x1028, 0, "ALC3226" },
884 { 0x10ec0293, 0x1028, 0, "ALC3235" },
885 { 0x10ec0255, 0x1028, 0, "ALC3234" },
886 { 0x10ec0668, 0x1028, 0, "ALC3661" },
887 { 0x10ec0275, 0x1028, 0, "ALC3260" },
888 { 0x10ec0899, 0x1028, 0, "ALC3861" },
889 { 0x10ec0298, 0x1028, 0, "ALC3266" },
890 { 0x10ec0256, 0x1028, 0, "ALC3246" },
891 { 0x10ec0670, 0x1025, 0, "ALC669X" },
892 { 0x10ec0676, 0x1025, 0, "ALC679X" },
893 { 0x10ec0282, 0x1043, 0, "ALC3229" },
894 { 0x10ec0233, 0x1043, 0, "ALC3236" },
895 { 0x10ec0280, 0x103c, 0, "ALC3228" },
896 { 0x10ec0282, 0x103c, 0, "ALC3227" },
897 { 0x10ec0286, 0x103c, 0, "ALC3242" },
898 { 0x10ec0290, 0x103c, 0, "ALC3241" },
899 { 0x10ec0668, 0x103c, 0, "ALC3662" },
900 { 0x10ec0283, 0x17aa, 0, "ALC3239" },
901 { 0x10ec0292, 0x17aa, 0, "ALC3232" },
902 { } /* terminator */
903 };
904
alc_codec_rename_from_preset(struct hda_codec * codec)905 static int alc_codec_rename_from_preset(struct hda_codec *codec)
906 {
907 const struct alc_codec_rename_table *p;
908 const struct alc_codec_rename_pci_table *q;
909
910 for (p = rename_tbl; p->vendor_id; p++) {
911 if (p->vendor_id != codec->vendor_id)
912 continue;
913 if ((alc_get_coef0(codec) & p->coef_mask) == p->coef_bits)
914 return alc_codec_rename(codec, p->name);
915 }
916
917 if (!codec->bus->pci)
918 return 0;
919 for (q = rename_pci_tbl; q->codec_vendor_id; q++) {
920 if (q->codec_vendor_id != codec->vendor_id)
921 continue;
922 if (q->pci_subvendor != codec->bus->pci->subsystem_vendor)
923 continue;
924 if (!q->pci_subdevice ||
925 q->pci_subdevice == codec->bus->pci->subsystem_device)
926 return alc_codec_rename(codec, q->name);
927 }
928
929 return 0;
930 }
931
932
933 /*
934 * Digital-beep handlers
935 */
936 #ifdef CONFIG_SND_HDA_INPUT_BEEP
937 #define set_beep_amp(spec, nid, idx, dir) \
938 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
939
940 static const struct snd_pci_quirk beep_white_list[] = {
941 SND_PCI_QUIRK(0x1043, 0x103c, "ASUS", 1),
942 SND_PCI_QUIRK(0x1043, 0x115d, "ASUS", 1),
943 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
944 SND_PCI_QUIRK(0x1043, 0x8376, "EeePC", 1),
945 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
946 SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1),
947 SND_PCI_QUIRK(0x1043, 0x834a, "EeePC", 1),
948 SND_PCI_QUIRK(0x1458, 0xa002, "GA-MA790X", 1),
949 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
950 {}
951 };
952
has_cdefine_beep(struct hda_codec * codec)953 static inline int has_cdefine_beep(struct hda_codec *codec)
954 {
955 struct alc_spec *spec = codec->spec;
956 const struct snd_pci_quirk *q;
957 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
958 if (q)
959 return q->value;
960 return spec->cdefine.enable_pcbeep;
961 }
962 #else
963 #define set_beep_amp(spec, nid, idx, dir) /* NOP */
964 #define has_cdefine_beep(codec) 0
965 #endif
966
967 /* parse the BIOS configuration and set up the alc_spec */
968 /* return 1 if successful, 0 if the proper config is not found,
969 * or a negative error code
970 */
alc_parse_auto_config(struct hda_codec * codec,const hda_nid_t * ignore_nids,const hda_nid_t * ssid_nids)971 static int alc_parse_auto_config(struct hda_codec *codec,
972 const hda_nid_t *ignore_nids,
973 const hda_nid_t *ssid_nids)
974 {
975 struct alc_spec *spec = codec->spec;
976 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
977 int err;
978
979 err = snd_hda_parse_pin_defcfg(codec, cfg, ignore_nids,
980 spec->parse_flags);
981 if (err < 0)
982 return err;
983
984 if (ssid_nids)
985 alc_ssid_check(codec, ssid_nids);
986
987 err = snd_hda_gen_parse_auto_config(codec, cfg);
988 if (err < 0)
989 return err;
990
991 return 1;
992 }
993
994 /* common preparation job for alc_spec */
alc_alloc_spec(struct hda_codec * codec,hda_nid_t mixer_nid)995 static int alc_alloc_spec(struct hda_codec *codec, hda_nid_t mixer_nid)
996 {
997 struct alc_spec *spec = kzalloc(sizeof(*spec), GFP_KERNEL);
998 int err;
999
1000 if (!spec)
1001 return -ENOMEM;
1002 codec->spec = spec;
1003 snd_hda_gen_spec_init(&spec->gen);
1004 spec->gen.mixer_nid = mixer_nid;
1005 spec->gen.own_eapd_ctl = 1;
1006 codec->single_adc_amp = 1;
1007 /* FIXME: do we need this for all Realtek codec models? */
1008 codec->spdif_status_reset = 1;
1009
1010 err = alc_codec_rename_from_preset(codec);
1011 if (err < 0) {
1012 kfree(spec);
1013 return err;
1014 }
1015 return 0;
1016 }
1017
alc880_parse_auto_config(struct hda_codec * codec)1018 static int alc880_parse_auto_config(struct hda_codec *codec)
1019 {
1020 static const hda_nid_t alc880_ignore[] = { 0x1d, 0 };
1021 static const hda_nid_t alc880_ssids[] = { 0x15, 0x1b, 0x14, 0 };
1022 return alc_parse_auto_config(codec, alc880_ignore, alc880_ssids);
1023 }
1024
1025 /*
1026 * ALC880 fix-ups
1027 */
1028 enum {
1029 ALC880_FIXUP_GPIO1,
1030 ALC880_FIXUP_GPIO2,
1031 ALC880_FIXUP_MEDION_RIM,
1032 ALC880_FIXUP_LG,
1033 ALC880_FIXUP_LG_LW25,
1034 ALC880_FIXUP_W810,
1035 ALC880_FIXUP_EAPD_COEF,
1036 ALC880_FIXUP_TCL_S700,
1037 ALC880_FIXUP_VOL_KNOB,
1038 ALC880_FIXUP_FUJITSU,
1039 ALC880_FIXUP_F1734,
1040 ALC880_FIXUP_UNIWILL,
1041 ALC880_FIXUP_UNIWILL_DIG,
1042 ALC880_FIXUP_Z71V,
1043 ALC880_FIXUP_ASUS_W5A,
1044 ALC880_FIXUP_3ST_BASE,
1045 ALC880_FIXUP_3ST,
1046 ALC880_FIXUP_3ST_DIG,
1047 ALC880_FIXUP_5ST_BASE,
1048 ALC880_FIXUP_5ST,
1049 ALC880_FIXUP_5ST_DIG,
1050 ALC880_FIXUP_6ST_BASE,
1051 ALC880_FIXUP_6ST,
1052 ALC880_FIXUP_6ST_DIG,
1053 ALC880_FIXUP_6ST_AUTOMUTE,
1054 };
1055
1056 /* enable the volume-knob widget support on NID 0x21 */
alc880_fixup_vol_knob(struct hda_codec * codec,const struct hda_fixup * fix,int action)1057 static void alc880_fixup_vol_knob(struct hda_codec *codec,
1058 const struct hda_fixup *fix, int action)
1059 {
1060 if (action == HDA_FIXUP_ACT_PROBE)
1061 snd_hda_jack_detect_enable_callback(codec, 0x21,
1062 alc_update_knob_master);
1063 }
1064
1065 static const struct hda_fixup alc880_fixups[] = {
1066 [ALC880_FIXUP_GPIO1] = {
1067 .type = HDA_FIXUP_VERBS,
1068 .v.verbs = alc_gpio1_init_verbs,
1069 },
1070 [ALC880_FIXUP_GPIO2] = {
1071 .type = HDA_FIXUP_VERBS,
1072 .v.verbs = alc_gpio2_init_verbs,
1073 },
1074 [ALC880_FIXUP_MEDION_RIM] = {
1075 .type = HDA_FIXUP_VERBS,
1076 .v.verbs = (const struct hda_verb[]) {
1077 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
1078 { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
1079 { }
1080 },
1081 .chained = true,
1082 .chain_id = ALC880_FIXUP_GPIO2,
1083 },
1084 [ALC880_FIXUP_LG] = {
1085 .type = HDA_FIXUP_PINS,
1086 .v.pins = (const struct hda_pintbl[]) {
1087 /* disable bogus unused pins */
1088 { 0x16, 0x411111f0 },
1089 { 0x18, 0x411111f0 },
1090 { 0x1a, 0x411111f0 },
1091 { }
1092 }
1093 },
1094 [ALC880_FIXUP_LG_LW25] = {
1095 .type = HDA_FIXUP_PINS,
1096 .v.pins = (const struct hda_pintbl[]) {
1097 { 0x1a, 0x0181344f }, /* line-in */
1098 { 0x1b, 0x0321403f }, /* headphone */
1099 { }
1100 }
1101 },
1102 [ALC880_FIXUP_W810] = {
1103 .type = HDA_FIXUP_PINS,
1104 .v.pins = (const struct hda_pintbl[]) {
1105 /* disable bogus unused pins */
1106 { 0x17, 0x411111f0 },
1107 { }
1108 },
1109 .chained = true,
1110 .chain_id = ALC880_FIXUP_GPIO2,
1111 },
1112 [ALC880_FIXUP_EAPD_COEF] = {
1113 .type = HDA_FIXUP_VERBS,
1114 .v.verbs = (const struct hda_verb[]) {
1115 /* change to EAPD mode */
1116 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
1117 { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
1118 {}
1119 },
1120 },
1121 [ALC880_FIXUP_TCL_S700] = {
1122 .type = HDA_FIXUP_VERBS,
1123 .v.verbs = (const struct hda_verb[]) {
1124 /* change to EAPD mode */
1125 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
1126 { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
1127 {}
1128 },
1129 .chained = true,
1130 .chain_id = ALC880_FIXUP_GPIO2,
1131 },
1132 [ALC880_FIXUP_VOL_KNOB] = {
1133 .type = HDA_FIXUP_FUNC,
1134 .v.func = alc880_fixup_vol_knob,
1135 },
1136 [ALC880_FIXUP_FUJITSU] = {
1137 /* override all pins as BIOS on old Amilo is broken */
1138 .type = HDA_FIXUP_PINS,
1139 .v.pins = (const struct hda_pintbl[]) {
1140 { 0x14, 0x0121401f }, /* HP */
1141 { 0x15, 0x99030120 }, /* speaker */
1142 { 0x16, 0x99030130 }, /* bass speaker */
1143 { 0x17, 0x411111f0 }, /* N/A */
1144 { 0x18, 0x411111f0 }, /* N/A */
1145 { 0x19, 0x01a19950 }, /* mic-in */
1146 { 0x1a, 0x411111f0 }, /* N/A */
1147 { 0x1b, 0x411111f0 }, /* N/A */
1148 { 0x1c, 0x411111f0 }, /* N/A */
1149 { 0x1d, 0x411111f0 }, /* N/A */
1150 { 0x1e, 0x01454140 }, /* SPDIF out */
1151 { }
1152 },
1153 .chained = true,
1154 .chain_id = ALC880_FIXUP_VOL_KNOB,
1155 },
1156 [ALC880_FIXUP_F1734] = {
1157 /* almost compatible with FUJITSU, but no bass and SPDIF */
1158 .type = HDA_FIXUP_PINS,
1159 .v.pins = (const struct hda_pintbl[]) {
1160 { 0x14, 0x0121401f }, /* HP */
1161 { 0x15, 0x99030120 }, /* speaker */
1162 { 0x16, 0x411111f0 }, /* N/A */
1163 { 0x17, 0x411111f0 }, /* N/A */
1164 { 0x18, 0x411111f0 }, /* N/A */
1165 { 0x19, 0x01a19950 }, /* mic-in */
1166 { 0x1a, 0x411111f0 }, /* N/A */
1167 { 0x1b, 0x411111f0 }, /* N/A */
1168 { 0x1c, 0x411111f0 }, /* N/A */
1169 { 0x1d, 0x411111f0 }, /* N/A */
1170 { 0x1e, 0x411111f0 }, /* N/A */
1171 { }
1172 },
1173 .chained = true,
1174 .chain_id = ALC880_FIXUP_VOL_KNOB,
1175 },
1176 [ALC880_FIXUP_UNIWILL] = {
1177 /* need to fix HP and speaker pins to be parsed correctly */
1178 .type = HDA_FIXUP_PINS,
1179 .v.pins = (const struct hda_pintbl[]) {
1180 { 0x14, 0x0121411f }, /* HP */
1181 { 0x15, 0x99030120 }, /* speaker */
1182 { 0x16, 0x99030130 }, /* bass speaker */
1183 { }
1184 },
1185 },
1186 [ALC880_FIXUP_UNIWILL_DIG] = {
1187 .type = HDA_FIXUP_PINS,
1188 .v.pins = (const struct hda_pintbl[]) {
1189 /* disable bogus unused pins */
1190 { 0x17, 0x411111f0 },
1191 { 0x19, 0x411111f0 },
1192 { 0x1b, 0x411111f0 },
1193 { 0x1f, 0x411111f0 },
1194 { }
1195 }
1196 },
1197 [ALC880_FIXUP_Z71V] = {
1198 .type = HDA_FIXUP_PINS,
1199 .v.pins = (const struct hda_pintbl[]) {
1200 /* set up the whole pins as BIOS is utterly broken */
1201 { 0x14, 0x99030120 }, /* speaker */
1202 { 0x15, 0x0121411f }, /* HP */
1203 { 0x16, 0x411111f0 }, /* N/A */
1204 { 0x17, 0x411111f0 }, /* N/A */
1205 { 0x18, 0x01a19950 }, /* mic-in */
1206 { 0x19, 0x411111f0 }, /* N/A */
1207 { 0x1a, 0x01813031 }, /* line-in */
1208 { 0x1b, 0x411111f0 }, /* N/A */
1209 { 0x1c, 0x411111f0 }, /* N/A */
1210 { 0x1d, 0x411111f0 }, /* N/A */
1211 { 0x1e, 0x0144111e }, /* SPDIF */
1212 { }
1213 }
1214 },
1215 [ALC880_FIXUP_ASUS_W5A] = {
1216 .type = HDA_FIXUP_PINS,
1217 .v.pins = (const struct hda_pintbl[]) {
1218 /* set up the whole pins as BIOS is utterly broken */
1219 { 0x14, 0x0121411f }, /* HP */
1220 { 0x15, 0x411111f0 }, /* N/A */
1221 { 0x16, 0x411111f0 }, /* N/A */
1222 { 0x17, 0x411111f0 }, /* N/A */
1223 { 0x18, 0x90a60160 }, /* mic */
1224 { 0x19, 0x411111f0 }, /* N/A */
1225 { 0x1a, 0x411111f0 }, /* N/A */
1226 { 0x1b, 0x411111f0 }, /* N/A */
1227 { 0x1c, 0x411111f0 }, /* N/A */
1228 { 0x1d, 0x411111f0 }, /* N/A */
1229 { 0x1e, 0xb743111e }, /* SPDIF out */
1230 { }
1231 },
1232 .chained = true,
1233 .chain_id = ALC880_FIXUP_GPIO1,
1234 },
1235 [ALC880_FIXUP_3ST_BASE] = {
1236 .type = HDA_FIXUP_PINS,
1237 .v.pins = (const struct hda_pintbl[]) {
1238 { 0x14, 0x01014010 }, /* line-out */
1239 { 0x15, 0x411111f0 }, /* N/A */
1240 { 0x16, 0x411111f0 }, /* N/A */
1241 { 0x17, 0x411111f0 }, /* N/A */
1242 { 0x18, 0x01a19c30 }, /* mic-in */
1243 { 0x19, 0x0121411f }, /* HP */
1244 { 0x1a, 0x01813031 }, /* line-in */
1245 { 0x1b, 0x02a19c40 }, /* front-mic */
1246 { 0x1c, 0x411111f0 }, /* N/A */
1247 { 0x1d, 0x411111f0 }, /* N/A */
1248 /* 0x1e is filled in below */
1249 { 0x1f, 0x411111f0 }, /* N/A */
1250 { }
1251 }
1252 },
1253 [ALC880_FIXUP_3ST] = {
1254 .type = HDA_FIXUP_PINS,
1255 .v.pins = (const struct hda_pintbl[]) {
1256 { 0x1e, 0x411111f0 }, /* N/A */
1257 { }
1258 },
1259 .chained = true,
1260 .chain_id = ALC880_FIXUP_3ST_BASE,
1261 },
1262 [ALC880_FIXUP_3ST_DIG] = {
1263 .type = HDA_FIXUP_PINS,
1264 .v.pins = (const struct hda_pintbl[]) {
1265 { 0x1e, 0x0144111e }, /* SPDIF */
1266 { }
1267 },
1268 .chained = true,
1269 .chain_id = ALC880_FIXUP_3ST_BASE,
1270 },
1271 [ALC880_FIXUP_5ST_BASE] = {
1272 .type = HDA_FIXUP_PINS,
1273 .v.pins = (const struct hda_pintbl[]) {
1274 { 0x14, 0x01014010 }, /* front */
1275 { 0x15, 0x411111f0 }, /* N/A */
1276 { 0x16, 0x01011411 }, /* CLFE */
1277 { 0x17, 0x01016412 }, /* surr */
1278 { 0x18, 0x01a19c30 }, /* mic-in */
1279 { 0x19, 0x0121411f }, /* HP */
1280 { 0x1a, 0x01813031 }, /* line-in */
1281 { 0x1b, 0x02a19c40 }, /* front-mic */
1282 { 0x1c, 0x411111f0 }, /* N/A */
1283 { 0x1d, 0x411111f0 }, /* N/A */
1284 /* 0x1e is filled in below */
1285 { 0x1f, 0x411111f0 }, /* N/A */
1286 { }
1287 }
1288 },
1289 [ALC880_FIXUP_5ST] = {
1290 .type = HDA_FIXUP_PINS,
1291 .v.pins = (const struct hda_pintbl[]) {
1292 { 0x1e, 0x411111f0 }, /* N/A */
1293 { }
1294 },
1295 .chained = true,
1296 .chain_id = ALC880_FIXUP_5ST_BASE,
1297 },
1298 [ALC880_FIXUP_5ST_DIG] = {
1299 .type = HDA_FIXUP_PINS,
1300 .v.pins = (const struct hda_pintbl[]) {
1301 { 0x1e, 0x0144111e }, /* SPDIF */
1302 { }
1303 },
1304 .chained = true,
1305 .chain_id = ALC880_FIXUP_5ST_BASE,
1306 },
1307 [ALC880_FIXUP_6ST_BASE] = {
1308 .type = HDA_FIXUP_PINS,
1309 .v.pins = (const struct hda_pintbl[]) {
1310 { 0x14, 0x01014010 }, /* front */
1311 { 0x15, 0x01016412 }, /* surr */
1312 { 0x16, 0x01011411 }, /* CLFE */
1313 { 0x17, 0x01012414 }, /* side */
1314 { 0x18, 0x01a19c30 }, /* mic-in */
1315 { 0x19, 0x02a19c40 }, /* front-mic */
1316 { 0x1a, 0x01813031 }, /* line-in */
1317 { 0x1b, 0x0121411f }, /* HP */
1318 { 0x1c, 0x411111f0 }, /* N/A */
1319 { 0x1d, 0x411111f0 }, /* N/A */
1320 /* 0x1e is filled in below */
1321 { 0x1f, 0x411111f0 }, /* N/A */
1322 { }
1323 }
1324 },
1325 [ALC880_FIXUP_6ST] = {
1326 .type = HDA_FIXUP_PINS,
1327 .v.pins = (const struct hda_pintbl[]) {
1328 { 0x1e, 0x411111f0 }, /* N/A */
1329 { }
1330 },
1331 .chained = true,
1332 .chain_id = ALC880_FIXUP_6ST_BASE,
1333 },
1334 [ALC880_FIXUP_6ST_DIG] = {
1335 .type = HDA_FIXUP_PINS,
1336 .v.pins = (const struct hda_pintbl[]) {
1337 { 0x1e, 0x0144111e }, /* SPDIF */
1338 { }
1339 },
1340 .chained = true,
1341 .chain_id = ALC880_FIXUP_6ST_BASE,
1342 },
1343 [ALC880_FIXUP_6ST_AUTOMUTE] = {
1344 .type = HDA_FIXUP_PINS,
1345 .v.pins = (const struct hda_pintbl[]) {
1346 { 0x1b, 0x0121401f }, /* HP with jack detect */
1347 { }
1348 },
1349 .chained_before = true,
1350 .chain_id = ALC880_FIXUP_6ST_BASE,
1351 },
1352 };
1353
1354 static const struct snd_pci_quirk alc880_fixup_tbl[] = {
1355 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_FIXUP_W810),
1356 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS W5A", ALC880_FIXUP_ASUS_W5A),
1357 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_FIXUP_Z71V),
1358 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_FIXUP_GPIO1),
1359 SND_PCI_QUIRK(0x147b, 0x1045, "ABit AA8XE", ALC880_FIXUP_6ST_AUTOMUTE),
1360 SND_PCI_QUIRK(0x1558, 0x5401, "Clevo GPIO2", ALC880_FIXUP_GPIO2),
1361 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo", ALC880_FIXUP_EAPD_COEF),
1362 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_FIXUP_UNIWILL_DIG),
1363 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_FIXUP_F1734),
1364 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_FIXUP_UNIWILL),
1365 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_FIXUP_VOL_KNOB),
1366 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_FIXUP_W810),
1367 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_FIXUP_MEDION_RIM),
1368 SND_PCI_QUIRK(0x1631, 0xe011, "PB 13201056", ALC880_FIXUP_6ST_AUTOMUTE),
1369 SND_PCI_QUIRK(0x1734, 0x107c, "FSC Amilo M1437", ALC880_FIXUP_FUJITSU),
1370 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FIXUP_FUJITSU),
1371 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_FIXUP_F1734),
1372 SND_PCI_QUIRK(0x1734, 0x10b0, "FSC Amilo Pi1556", ALC880_FIXUP_FUJITSU),
1373 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_FIXUP_LG),
1374 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_FIXUP_LG),
1375 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_FIXUP_LG),
1376 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_FIXUP_LG_LW25),
1377 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_FIXUP_TCL_S700),
1378
1379 /* Below is the copied entries from alc880_quirks.c.
1380 * It's not quite sure whether BIOS sets the correct pin-config table
1381 * on these machines, thus they are kept to be compatible with
1382 * the old static quirks. Once when it's confirmed to work without
1383 * these overrides, it'd be better to remove.
1384 */
1385 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_FIXUP_5ST_DIG),
1386 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_FIXUP_6ST),
1387 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_FIXUP_3ST_DIG),
1388 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_FIXUP_6ST_DIG),
1389 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_FIXUP_6ST_DIG),
1390 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_FIXUP_6ST_DIG),
1391 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_FIXUP_3ST_DIG),
1392 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_FIXUP_3ST),
1393 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_FIXUP_6ST_DIG),
1394 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_FIXUP_3ST),
1395 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_FIXUP_3ST),
1396 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_FIXUP_5ST),
1397 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_FIXUP_5ST),
1398 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_FIXUP_5ST),
1399 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_FIXUP_6ST_DIG),
1400 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_FIXUP_6ST_DIG),
1401 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_FIXUP_6ST_DIG),
1402 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_FIXUP_6ST_DIG),
1403 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_FIXUP_5ST_DIG),
1404 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_FIXUP_5ST_DIG),
1405 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_FIXUP_5ST_DIG),
1406 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_FIXUP_6ST_DIG), /* broken BIOS */
1407 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_FIXUP_6ST_DIG),
1408 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1409 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1410 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1411 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_FIXUP_3ST_DIG),
1412 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1413 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_FIXUP_3ST_DIG),
1414 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_FIXUP_3ST_DIG),
1415 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1416 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1417 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1418 /* default Intel */
1419 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_FIXUP_3ST),
1420 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_FIXUP_5ST_DIG),
1421 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_FIXUP_6ST_DIG),
1422 {}
1423 };
1424
1425 static const struct hda_model_fixup alc880_fixup_models[] = {
1426 {.id = ALC880_FIXUP_3ST, .name = "3stack"},
1427 {.id = ALC880_FIXUP_3ST_DIG, .name = "3stack-digout"},
1428 {.id = ALC880_FIXUP_5ST, .name = "5stack"},
1429 {.id = ALC880_FIXUP_5ST_DIG, .name = "5stack-digout"},
1430 {.id = ALC880_FIXUP_6ST, .name = "6stack"},
1431 {.id = ALC880_FIXUP_6ST_DIG, .name = "6stack-digout"},
1432 {.id = ALC880_FIXUP_6ST_AUTOMUTE, .name = "6stack-automute"},
1433 {}
1434 };
1435
1436
1437 /*
1438 * OK, here we have finally the patch for ALC880
1439 */
patch_alc880(struct hda_codec * codec)1440 static int patch_alc880(struct hda_codec *codec)
1441 {
1442 struct alc_spec *spec;
1443 int err;
1444
1445 err = alc_alloc_spec(codec, 0x0b);
1446 if (err < 0)
1447 return err;
1448
1449 spec = codec->spec;
1450 spec->gen.need_dac_fix = 1;
1451 spec->gen.beep_nid = 0x01;
1452
1453 snd_hda_pick_fixup(codec, alc880_fixup_models, alc880_fixup_tbl,
1454 alc880_fixups);
1455 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
1456
1457 /* automatic parse from the BIOS config */
1458 err = alc880_parse_auto_config(codec);
1459 if (err < 0)
1460 goto error;
1461
1462 if (!spec->gen.no_analog)
1463 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
1464
1465 codec->patch_ops = alc_patch_ops;
1466 codec->patch_ops.unsol_event = alc880_unsol_event;
1467
1468
1469 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
1470
1471 return 0;
1472
1473 error:
1474 alc_free(codec);
1475 return err;
1476 }
1477
1478
1479 /*
1480 * ALC260 support
1481 */
alc260_parse_auto_config(struct hda_codec * codec)1482 static int alc260_parse_auto_config(struct hda_codec *codec)
1483 {
1484 static const hda_nid_t alc260_ignore[] = { 0x17, 0 };
1485 static const hda_nid_t alc260_ssids[] = { 0x10, 0x15, 0x0f, 0 };
1486 return alc_parse_auto_config(codec, alc260_ignore, alc260_ssids);
1487 }
1488
1489 /*
1490 * Pin config fixes
1491 */
1492 enum {
1493 ALC260_FIXUP_HP_DC5750,
1494 ALC260_FIXUP_HP_PIN_0F,
1495 ALC260_FIXUP_COEF,
1496 ALC260_FIXUP_GPIO1,
1497 ALC260_FIXUP_GPIO1_TOGGLE,
1498 ALC260_FIXUP_REPLACER,
1499 ALC260_FIXUP_HP_B1900,
1500 ALC260_FIXUP_KN1,
1501 ALC260_FIXUP_FSC_S7020,
1502 ALC260_FIXUP_FSC_S7020_JWSE,
1503 ALC260_FIXUP_VAIO_PINS,
1504 };
1505
alc260_gpio1_automute(struct hda_codec * codec)1506 static void alc260_gpio1_automute(struct hda_codec *codec)
1507 {
1508 struct alc_spec *spec = codec->spec;
1509 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
1510 spec->gen.hp_jack_present);
1511 }
1512
alc260_fixup_gpio1_toggle(struct hda_codec * codec,const struct hda_fixup * fix,int action)1513 static void alc260_fixup_gpio1_toggle(struct hda_codec *codec,
1514 const struct hda_fixup *fix, int action)
1515 {
1516 struct alc_spec *spec = codec->spec;
1517 if (action == HDA_FIXUP_ACT_PROBE) {
1518 /* although the machine has only one output pin, we need to
1519 * toggle GPIO1 according to the jack state
1520 */
1521 spec->gen.automute_hook = alc260_gpio1_automute;
1522 spec->gen.detect_hp = 1;
1523 spec->gen.automute_speaker = 1;
1524 spec->gen.autocfg.hp_pins[0] = 0x0f; /* copy it for automute */
1525 snd_hda_jack_detect_enable_callback(codec, 0x0f,
1526 snd_hda_gen_hp_automute);
1527 snd_hda_add_verbs(codec, alc_gpio1_init_verbs);
1528 }
1529 }
1530
alc260_fixup_kn1(struct hda_codec * codec,const struct hda_fixup * fix,int action)1531 static void alc260_fixup_kn1(struct hda_codec *codec,
1532 const struct hda_fixup *fix, int action)
1533 {
1534 struct alc_spec *spec = codec->spec;
1535 static const struct hda_pintbl pincfgs[] = {
1536 { 0x0f, 0x02214000 }, /* HP/speaker */
1537 { 0x12, 0x90a60160 }, /* int mic */
1538 { 0x13, 0x02a19000 }, /* ext mic */
1539 { 0x18, 0x01446000 }, /* SPDIF out */
1540 /* disable bogus I/O pins */
1541 { 0x10, 0x411111f0 },
1542 { 0x11, 0x411111f0 },
1543 { 0x14, 0x411111f0 },
1544 { 0x15, 0x411111f0 },
1545 { 0x16, 0x411111f0 },
1546 { 0x17, 0x411111f0 },
1547 { 0x19, 0x411111f0 },
1548 { }
1549 };
1550
1551 switch (action) {
1552 case HDA_FIXUP_ACT_PRE_PROBE:
1553 snd_hda_apply_pincfgs(codec, pincfgs);
1554 break;
1555 case HDA_FIXUP_ACT_PROBE:
1556 spec->init_amp = ALC_INIT_NONE;
1557 break;
1558 }
1559 }
1560
alc260_fixup_fsc_s7020(struct hda_codec * codec,const struct hda_fixup * fix,int action)1561 static void alc260_fixup_fsc_s7020(struct hda_codec *codec,
1562 const struct hda_fixup *fix, int action)
1563 {
1564 struct alc_spec *spec = codec->spec;
1565 if (action == HDA_FIXUP_ACT_PROBE)
1566 spec->init_amp = ALC_INIT_NONE;
1567 }
1568
alc260_fixup_fsc_s7020_jwse(struct hda_codec * codec,const struct hda_fixup * fix,int action)1569 static void alc260_fixup_fsc_s7020_jwse(struct hda_codec *codec,
1570 const struct hda_fixup *fix, int action)
1571 {
1572 struct alc_spec *spec = codec->spec;
1573 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
1574 spec->gen.add_jack_modes = 1;
1575 spec->gen.hp_mic = 1;
1576 }
1577 }
1578
1579 static const struct hda_fixup alc260_fixups[] = {
1580 [ALC260_FIXUP_HP_DC5750] = {
1581 .type = HDA_FIXUP_PINS,
1582 .v.pins = (const struct hda_pintbl[]) {
1583 { 0x11, 0x90130110 }, /* speaker */
1584 { }
1585 }
1586 },
1587 [ALC260_FIXUP_HP_PIN_0F] = {
1588 .type = HDA_FIXUP_PINS,
1589 .v.pins = (const struct hda_pintbl[]) {
1590 { 0x0f, 0x01214000 }, /* HP */
1591 { }
1592 }
1593 },
1594 [ALC260_FIXUP_COEF] = {
1595 .type = HDA_FIXUP_VERBS,
1596 .v.verbs = (const struct hda_verb[]) {
1597 { 0x1a, AC_VERB_SET_COEF_INDEX, 0x07 },
1598 { 0x1a, AC_VERB_SET_PROC_COEF, 0x3040 },
1599 { }
1600 },
1601 },
1602 [ALC260_FIXUP_GPIO1] = {
1603 .type = HDA_FIXUP_VERBS,
1604 .v.verbs = alc_gpio1_init_verbs,
1605 },
1606 [ALC260_FIXUP_GPIO1_TOGGLE] = {
1607 .type = HDA_FIXUP_FUNC,
1608 .v.func = alc260_fixup_gpio1_toggle,
1609 .chained = true,
1610 .chain_id = ALC260_FIXUP_HP_PIN_0F,
1611 },
1612 [ALC260_FIXUP_REPLACER] = {
1613 .type = HDA_FIXUP_VERBS,
1614 .v.verbs = (const struct hda_verb[]) {
1615 { 0x1a, AC_VERB_SET_COEF_INDEX, 0x07 },
1616 { 0x1a, AC_VERB_SET_PROC_COEF, 0x3050 },
1617 { }
1618 },
1619 .chained = true,
1620 .chain_id = ALC260_FIXUP_GPIO1_TOGGLE,
1621 },
1622 [ALC260_FIXUP_HP_B1900] = {
1623 .type = HDA_FIXUP_FUNC,
1624 .v.func = alc260_fixup_gpio1_toggle,
1625 .chained = true,
1626 .chain_id = ALC260_FIXUP_COEF,
1627 },
1628 [ALC260_FIXUP_KN1] = {
1629 .type = HDA_FIXUP_FUNC,
1630 .v.func = alc260_fixup_kn1,
1631 },
1632 [ALC260_FIXUP_FSC_S7020] = {
1633 .type = HDA_FIXUP_FUNC,
1634 .v.func = alc260_fixup_fsc_s7020,
1635 },
1636 [ALC260_FIXUP_FSC_S7020_JWSE] = {
1637 .type = HDA_FIXUP_FUNC,
1638 .v.func = alc260_fixup_fsc_s7020_jwse,
1639 .chained = true,
1640 .chain_id = ALC260_FIXUP_FSC_S7020,
1641 },
1642 [ALC260_FIXUP_VAIO_PINS] = {
1643 .type = HDA_FIXUP_PINS,
1644 .v.pins = (const struct hda_pintbl[]) {
1645 /* Pin configs are missing completely on some VAIOs */
1646 { 0x0f, 0x01211020 },
1647 { 0x10, 0x0001003f },
1648 { 0x11, 0x411111f0 },
1649 { 0x12, 0x01a15930 },
1650 { 0x13, 0x411111f0 },
1651 { 0x14, 0x411111f0 },
1652 { 0x15, 0x411111f0 },
1653 { 0x16, 0x411111f0 },
1654 { 0x17, 0x411111f0 },
1655 { 0x18, 0x411111f0 },
1656 { 0x19, 0x411111f0 },
1657 { }
1658 }
1659 },
1660 };
1661
1662 static const struct snd_pci_quirk alc260_fixup_tbl[] = {
1663 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_FIXUP_GPIO1),
1664 SND_PCI_QUIRK(0x1025, 0x007f, "Acer Aspire 9500", ALC260_FIXUP_COEF),
1665 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_FIXUP_GPIO1),
1666 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", ALC260_FIXUP_HP_DC5750),
1667 SND_PCI_QUIRK(0x103c, 0x30ba, "HP Presario B1900", ALC260_FIXUP_HP_B1900),
1668 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_FIXUP_VAIO_PINS),
1669 SND_PCI_QUIRK(0x104d, 0x81e2, "Sony VAIO TX", ALC260_FIXUP_HP_PIN_0F),
1670 SND_PCI_QUIRK(0x10cf, 0x1326, "FSC LifeBook S7020", ALC260_FIXUP_FSC_S7020),
1671 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FIXUP_GPIO1),
1672 SND_PCI_QUIRK(0x152d, 0x0729, "Quanta KN1", ALC260_FIXUP_KN1),
1673 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_FIXUP_REPLACER),
1674 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_FIXUP_COEF),
1675 {}
1676 };
1677
1678 static const struct hda_model_fixup alc260_fixup_models[] = {
1679 {.id = ALC260_FIXUP_GPIO1, .name = "gpio1"},
1680 {.id = ALC260_FIXUP_COEF, .name = "coef"},
1681 {.id = ALC260_FIXUP_FSC_S7020, .name = "fujitsu"},
1682 {.id = ALC260_FIXUP_FSC_S7020_JWSE, .name = "fujitsu-jwse"},
1683 {}
1684 };
1685
1686 /*
1687 */
patch_alc260(struct hda_codec * codec)1688 static int patch_alc260(struct hda_codec *codec)
1689 {
1690 struct alc_spec *spec;
1691 int err;
1692
1693 err = alc_alloc_spec(codec, 0x07);
1694 if (err < 0)
1695 return err;
1696
1697 spec = codec->spec;
1698 /* as quite a few machines require HP amp for speaker outputs,
1699 * it's easier to enable it unconditionally; even if it's unneeded,
1700 * it's almost harmless.
1701 */
1702 spec->gen.prefer_hp_amp = 1;
1703 spec->gen.beep_nid = 0x01;
1704
1705 snd_hda_pick_fixup(codec, alc260_fixup_models, alc260_fixup_tbl,
1706 alc260_fixups);
1707 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
1708
1709 /* automatic parse from the BIOS config */
1710 err = alc260_parse_auto_config(codec);
1711 if (err < 0)
1712 goto error;
1713
1714 if (!spec->gen.no_analog)
1715 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
1716
1717 codec->patch_ops = alc_patch_ops;
1718 spec->shutup = alc_eapd_shutup;
1719
1720 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
1721
1722 return 0;
1723
1724 error:
1725 alc_free(codec);
1726 return err;
1727 }
1728
1729
1730 /*
1731 * ALC882/883/885/888/889 support
1732 *
1733 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
1734 * configuration. Each pin widget can choose any input DACs and a mixer.
1735 * Each ADC is connected from a mixer of all inputs. This makes possible
1736 * 6-channel independent captures.
1737 *
1738 * In addition, an independent DAC for the multi-playback (not used in this
1739 * driver yet).
1740 */
1741
1742 /*
1743 * Pin config fixes
1744 */
1745 enum {
1746 ALC882_FIXUP_ABIT_AW9D_MAX,
1747 ALC882_FIXUP_LENOVO_Y530,
1748 ALC882_FIXUP_PB_M5210,
1749 ALC882_FIXUP_ACER_ASPIRE_7736,
1750 ALC882_FIXUP_ASUS_W90V,
1751 ALC889_FIXUP_CD,
1752 ALC889_FIXUP_FRONT_HP_NO_PRESENCE,
1753 ALC889_FIXUP_VAIO_TT,
1754 ALC888_FIXUP_EEE1601,
1755 ALC882_FIXUP_EAPD,
1756 ALC883_FIXUP_EAPD,
1757 ALC883_FIXUP_ACER_EAPD,
1758 ALC882_FIXUP_GPIO1,
1759 ALC882_FIXUP_GPIO2,
1760 ALC882_FIXUP_GPIO3,
1761 ALC889_FIXUP_COEF,
1762 ALC882_FIXUP_ASUS_W2JC,
1763 ALC882_FIXUP_ACER_ASPIRE_4930G,
1764 ALC882_FIXUP_ACER_ASPIRE_8930G,
1765 ALC882_FIXUP_ASPIRE_8930G_VERBS,
1766 ALC885_FIXUP_MACPRO_GPIO,
1767 ALC889_FIXUP_DAC_ROUTE,
1768 ALC889_FIXUP_MBP_VREF,
1769 ALC889_FIXUP_IMAC91_VREF,
1770 ALC889_FIXUP_MBA11_VREF,
1771 ALC889_FIXUP_MBA21_VREF,
1772 ALC889_FIXUP_MP11_VREF,
1773 ALC882_FIXUP_INV_DMIC,
1774 ALC882_FIXUP_NO_PRIMARY_HP,
1775 ALC887_FIXUP_ASUS_BASS,
1776 ALC887_FIXUP_BASS_CHMAP,
1777 };
1778
alc889_fixup_coef(struct hda_codec * codec,const struct hda_fixup * fix,int action)1779 static void alc889_fixup_coef(struct hda_codec *codec,
1780 const struct hda_fixup *fix, int action)
1781 {
1782 if (action != HDA_FIXUP_ACT_INIT)
1783 return;
1784 alc_update_coef_idx(codec, 7, 0, 0x2030);
1785 }
1786
1787 /* toggle speaker-output according to the hp-jack state */
alc882_gpio_mute(struct hda_codec * codec,int pin,int muted)1788 static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
1789 {
1790 unsigned int gpiostate, gpiomask, gpiodir;
1791
1792 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
1793 AC_VERB_GET_GPIO_DATA, 0);
1794
1795 if (!muted)
1796 gpiostate |= (1 << pin);
1797 else
1798 gpiostate &= ~(1 << pin);
1799
1800 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
1801 AC_VERB_GET_GPIO_MASK, 0);
1802 gpiomask |= (1 << pin);
1803
1804 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
1805 AC_VERB_GET_GPIO_DIRECTION, 0);
1806 gpiodir |= (1 << pin);
1807
1808
1809 snd_hda_codec_write(codec, codec->afg, 0,
1810 AC_VERB_SET_GPIO_MASK, gpiomask);
1811 snd_hda_codec_write(codec, codec->afg, 0,
1812 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
1813
1814 msleep(1);
1815
1816 snd_hda_codec_write(codec, codec->afg, 0,
1817 AC_VERB_SET_GPIO_DATA, gpiostate);
1818 }
1819
1820 /* set up GPIO at initialization */
alc885_fixup_macpro_gpio(struct hda_codec * codec,const struct hda_fixup * fix,int action)1821 static void alc885_fixup_macpro_gpio(struct hda_codec *codec,
1822 const struct hda_fixup *fix, int action)
1823 {
1824 if (action != HDA_FIXUP_ACT_INIT)
1825 return;
1826 alc882_gpio_mute(codec, 0, 0);
1827 alc882_gpio_mute(codec, 1, 0);
1828 }
1829
1830 /* Fix the connection of some pins for ALC889:
1831 * At least, Acer Aspire 5935 shows the connections to DAC3/4 don't
1832 * work correctly (bko#42740)
1833 */
alc889_fixup_dac_route(struct hda_codec * codec,const struct hda_fixup * fix,int action)1834 static void alc889_fixup_dac_route(struct hda_codec *codec,
1835 const struct hda_fixup *fix, int action)
1836 {
1837 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
1838 /* fake the connections during parsing the tree */
1839 hda_nid_t conn1[2] = { 0x0c, 0x0d };
1840 hda_nid_t conn2[2] = { 0x0e, 0x0f };
1841 snd_hda_override_conn_list(codec, 0x14, 2, conn1);
1842 snd_hda_override_conn_list(codec, 0x15, 2, conn1);
1843 snd_hda_override_conn_list(codec, 0x18, 2, conn2);
1844 snd_hda_override_conn_list(codec, 0x1a, 2, conn2);
1845 } else if (action == HDA_FIXUP_ACT_PROBE) {
1846 /* restore the connections */
1847 hda_nid_t conn[5] = { 0x0c, 0x0d, 0x0e, 0x0f, 0x26 };
1848 snd_hda_override_conn_list(codec, 0x14, 5, conn);
1849 snd_hda_override_conn_list(codec, 0x15, 5, conn);
1850 snd_hda_override_conn_list(codec, 0x18, 5, conn);
1851 snd_hda_override_conn_list(codec, 0x1a, 5, conn);
1852 }
1853 }
1854
1855 /* Set VREF on HP pin */
alc889_fixup_mbp_vref(struct hda_codec * codec,const struct hda_fixup * fix,int action)1856 static void alc889_fixup_mbp_vref(struct hda_codec *codec,
1857 const struct hda_fixup *fix, int action)
1858 {
1859 struct alc_spec *spec = codec->spec;
1860 static hda_nid_t nids[2] = { 0x14, 0x15 };
1861 int i;
1862
1863 if (action != HDA_FIXUP_ACT_INIT)
1864 return;
1865 for (i = 0; i < ARRAY_SIZE(nids); i++) {
1866 unsigned int val = snd_hda_codec_get_pincfg(codec, nids[i]);
1867 if (get_defcfg_device(val) != AC_JACK_HP_OUT)
1868 continue;
1869 val = snd_hda_codec_get_pin_target(codec, nids[i]);
1870 val |= AC_PINCTL_VREF_80;
1871 snd_hda_set_pin_ctl(codec, nids[i], val);
1872 spec->gen.keep_vref_in_automute = 1;
1873 break;
1874 }
1875 }
1876
alc889_fixup_mac_pins(struct hda_codec * codec,const hda_nid_t * nids,int num_nids)1877 static void alc889_fixup_mac_pins(struct hda_codec *codec,
1878 const hda_nid_t *nids, int num_nids)
1879 {
1880 struct alc_spec *spec = codec->spec;
1881 int i;
1882
1883 for (i = 0; i < num_nids; i++) {
1884 unsigned int val;
1885 val = snd_hda_codec_get_pin_target(codec, nids[i]);
1886 val |= AC_PINCTL_VREF_50;
1887 snd_hda_set_pin_ctl(codec, nids[i], val);
1888 }
1889 spec->gen.keep_vref_in_automute = 1;
1890 }
1891
1892 /* Set VREF on speaker pins on imac91 */
alc889_fixup_imac91_vref(struct hda_codec * codec,const struct hda_fixup * fix,int action)1893 static void alc889_fixup_imac91_vref(struct hda_codec *codec,
1894 const struct hda_fixup *fix, int action)
1895 {
1896 static hda_nid_t nids[2] = { 0x18, 0x1a };
1897
1898 if (action == HDA_FIXUP_ACT_INIT)
1899 alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
1900 }
1901
1902 /* Set VREF on speaker pins on mba11 */
alc889_fixup_mba11_vref(struct hda_codec * codec,const struct hda_fixup * fix,int action)1903 static void alc889_fixup_mba11_vref(struct hda_codec *codec,
1904 const struct hda_fixup *fix, int action)
1905 {
1906 static hda_nid_t nids[1] = { 0x18 };
1907
1908 if (action == HDA_FIXUP_ACT_INIT)
1909 alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
1910 }
1911
1912 /* Set VREF on speaker pins on mba21 */
alc889_fixup_mba21_vref(struct hda_codec * codec,const struct hda_fixup * fix,int action)1913 static void alc889_fixup_mba21_vref(struct hda_codec *codec,
1914 const struct hda_fixup *fix, int action)
1915 {
1916 static hda_nid_t nids[2] = { 0x18, 0x19 };
1917
1918 if (action == HDA_FIXUP_ACT_INIT)
1919 alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
1920 }
1921
1922 /* Don't take HP output as primary
1923 * Strangely, the speaker output doesn't work on Vaio Z and some Vaio
1924 * all-in-one desktop PCs (for example VGC-LN51JGB) through DAC 0x05
1925 */
alc882_fixup_no_primary_hp(struct hda_codec * codec,const struct hda_fixup * fix,int action)1926 static void alc882_fixup_no_primary_hp(struct hda_codec *codec,
1927 const struct hda_fixup *fix, int action)
1928 {
1929 struct alc_spec *spec = codec->spec;
1930 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
1931 spec->gen.no_primary_hp = 1;
1932 spec->gen.no_multi_io = 1;
1933 }
1934 }
1935
1936 static void alc_fixup_bass_chmap(struct hda_codec *codec,
1937 const struct hda_fixup *fix, int action);
1938
1939 static const struct hda_fixup alc882_fixups[] = {
1940 [ALC882_FIXUP_ABIT_AW9D_MAX] = {
1941 .type = HDA_FIXUP_PINS,
1942 .v.pins = (const struct hda_pintbl[]) {
1943 { 0x15, 0x01080104 }, /* side */
1944 { 0x16, 0x01011012 }, /* rear */
1945 { 0x17, 0x01016011 }, /* clfe */
1946 { }
1947 }
1948 },
1949 [ALC882_FIXUP_LENOVO_Y530] = {
1950 .type = HDA_FIXUP_PINS,
1951 .v.pins = (const struct hda_pintbl[]) {
1952 { 0x15, 0x99130112 }, /* rear int speakers */
1953 { 0x16, 0x99130111 }, /* subwoofer */
1954 { }
1955 }
1956 },
1957 [ALC882_FIXUP_PB_M5210] = {
1958 .type = HDA_FIXUP_PINCTLS,
1959 .v.pins = (const struct hda_pintbl[]) {
1960 { 0x19, PIN_VREF50 },
1961 {}
1962 }
1963 },
1964 [ALC882_FIXUP_ACER_ASPIRE_7736] = {
1965 .type = HDA_FIXUP_FUNC,
1966 .v.func = alc_fixup_sku_ignore,
1967 },
1968 [ALC882_FIXUP_ASUS_W90V] = {
1969 .type = HDA_FIXUP_PINS,
1970 .v.pins = (const struct hda_pintbl[]) {
1971 { 0x16, 0x99130110 }, /* fix sequence for CLFE */
1972 { }
1973 }
1974 },
1975 [ALC889_FIXUP_CD] = {
1976 .type = HDA_FIXUP_PINS,
1977 .v.pins = (const struct hda_pintbl[]) {
1978 { 0x1c, 0x993301f0 }, /* CD */
1979 { }
1980 }
1981 },
1982 [ALC889_FIXUP_FRONT_HP_NO_PRESENCE] = {
1983 .type = HDA_FIXUP_PINS,
1984 .v.pins = (const struct hda_pintbl[]) {
1985 { 0x1b, 0x02214120 }, /* Front HP jack is flaky, disable jack detect */
1986 { }
1987 },
1988 .chained = true,
1989 .chain_id = ALC889_FIXUP_CD,
1990 },
1991 [ALC889_FIXUP_VAIO_TT] = {
1992 .type = HDA_FIXUP_PINS,
1993 .v.pins = (const struct hda_pintbl[]) {
1994 { 0x17, 0x90170111 }, /* hidden surround speaker */
1995 { }
1996 }
1997 },
1998 [ALC888_FIXUP_EEE1601] = {
1999 .type = HDA_FIXUP_VERBS,
2000 .v.verbs = (const struct hda_verb[]) {
2001 { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b },
2002 { 0x20, AC_VERB_SET_PROC_COEF, 0x0838 },
2003 { }
2004 }
2005 },
2006 [ALC882_FIXUP_EAPD] = {
2007 .type = HDA_FIXUP_VERBS,
2008 .v.verbs = (const struct hda_verb[]) {
2009 /* change to EAPD mode */
2010 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2011 { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
2012 { }
2013 }
2014 },
2015 [ALC883_FIXUP_EAPD] = {
2016 .type = HDA_FIXUP_VERBS,
2017 .v.verbs = (const struct hda_verb[]) {
2018 /* change to EAPD mode */
2019 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2020 { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
2021 { }
2022 }
2023 },
2024 [ALC883_FIXUP_ACER_EAPD] = {
2025 .type = HDA_FIXUP_VERBS,
2026 .v.verbs = (const struct hda_verb[]) {
2027 /* eanable EAPD on Acer laptops */
2028 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2029 { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
2030 { }
2031 }
2032 },
2033 [ALC882_FIXUP_GPIO1] = {
2034 .type = HDA_FIXUP_VERBS,
2035 .v.verbs = alc_gpio1_init_verbs,
2036 },
2037 [ALC882_FIXUP_GPIO2] = {
2038 .type = HDA_FIXUP_VERBS,
2039 .v.verbs = alc_gpio2_init_verbs,
2040 },
2041 [ALC882_FIXUP_GPIO3] = {
2042 .type = HDA_FIXUP_VERBS,
2043 .v.verbs = alc_gpio3_init_verbs,
2044 },
2045 [ALC882_FIXUP_ASUS_W2JC] = {
2046 .type = HDA_FIXUP_VERBS,
2047 .v.verbs = alc_gpio1_init_verbs,
2048 .chained = true,
2049 .chain_id = ALC882_FIXUP_EAPD,
2050 },
2051 [ALC889_FIXUP_COEF] = {
2052 .type = HDA_FIXUP_FUNC,
2053 .v.func = alc889_fixup_coef,
2054 },
2055 [ALC882_FIXUP_ACER_ASPIRE_4930G] = {
2056 .type = HDA_FIXUP_PINS,
2057 .v.pins = (const struct hda_pintbl[]) {
2058 { 0x16, 0x99130111 }, /* CLFE speaker */
2059 { 0x17, 0x99130112 }, /* surround speaker */
2060 { }
2061 },
2062 .chained = true,
2063 .chain_id = ALC882_FIXUP_GPIO1,
2064 },
2065 [ALC882_FIXUP_ACER_ASPIRE_8930G] = {
2066 .type = HDA_FIXUP_PINS,
2067 .v.pins = (const struct hda_pintbl[]) {
2068 { 0x16, 0x99130111 }, /* CLFE speaker */
2069 { 0x1b, 0x99130112 }, /* surround speaker */
2070 { }
2071 },
2072 .chained = true,
2073 .chain_id = ALC882_FIXUP_ASPIRE_8930G_VERBS,
2074 },
2075 [ALC882_FIXUP_ASPIRE_8930G_VERBS] = {
2076 /* additional init verbs for Acer Aspire 8930G */
2077 .type = HDA_FIXUP_VERBS,
2078 .v.verbs = (const struct hda_verb[]) {
2079 /* Enable all DACs */
2080 /* DAC DISABLE/MUTE 1? */
2081 /* setting bits 1-5 disables DAC nids 0x02-0x06
2082 * apparently. Init=0x38 */
2083 { 0x20, AC_VERB_SET_COEF_INDEX, 0x03 },
2084 { 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
2085 /* DAC DISABLE/MUTE 2? */
2086 /* some bit here disables the other DACs.
2087 * Init=0x4900 */
2088 { 0x20, AC_VERB_SET_COEF_INDEX, 0x08 },
2089 { 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
2090 /* DMIC fix
2091 * This laptop has a stereo digital microphone.
2092 * The mics are only 1cm apart which makes the stereo
2093 * useless. However, either the mic or the ALC889
2094 * makes the signal become a difference/sum signal
2095 * instead of standard stereo, which is annoying.
2096 * So instead we flip this bit which makes the
2097 * codec replicate the sum signal to both channels,
2098 * turning it into a normal mono mic.
2099 */
2100 /* DMIC_CONTROL? Init value = 0x0001 */
2101 { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b },
2102 { 0x20, AC_VERB_SET_PROC_COEF, 0x0003 },
2103 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2104 { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
2105 { }
2106 },
2107 .chained = true,
2108 .chain_id = ALC882_FIXUP_GPIO1,
2109 },
2110 [ALC885_FIXUP_MACPRO_GPIO] = {
2111 .type = HDA_FIXUP_FUNC,
2112 .v.func = alc885_fixup_macpro_gpio,
2113 },
2114 [ALC889_FIXUP_DAC_ROUTE] = {
2115 .type = HDA_FIXUP_FUNC,
2116 .v.func = alc889_fixup_dac_route,
2117 },
2118 [ALC889_FIXUP_MBP_VREF] = {
2119 .type = HDA_FIXUP_FUNC,
2120 .v.func = alc889_fixup_mbp_vref,
2121 .chained = true,
2122 .chain_id = ALC882_FIXUP_GPIO1,
2123 },
2124 [ALC889_FIXUP_IMAC91_VREF] = {
2125 .type = HDA_FIXUP_FUNC,
2126 .v.func = alc889_fixup_imac91_vref,
2127 .chained = true,
2128 .chain_id = ALC882_FIXUP_GPIO1,
2129 },
2130 [ALC889_FIXUP_MBA11_VREF] = {
2131 .type = HDA_FIXUP_FUNC,
2132 .v.func = alc889_fixup_mba11_vref,
2133 .chained = true,
2134 .chain_id = ALC889_FIXUP_MBP_VREF,
2135 },
2136 [ALC889_FIXUP_MBA21_VREF] = {
2137 .type = HDA_FIXUP_FUNC,
2138 .v.func = alc889_fixup_mba21_vref,
2139 .chained = true,
2140 .chain_id = ALC889_FIXUP_MBP_VREF,
2141 },
2142 [ALC889_FIXUP_MP11_VREF] = {
2143 .type = HDA_FIXUP_FUNC,
2144 .v.func = alc889_fixup_mba11_vref,
2145 .chained = true,
2146 .chain_id = ALC885_FIXUP_MACPRO_GPIO,
2147 },
2148 [ALC882_FIXUP_INV_DMIC] = {
2149 .type = HDA_FIXUP_FUNC,
2150 .v.func = alc_fixup_inv_dmic,
2151 },
2152 [ALC882_FIXUP_NO_PRIMARY_HP] = {
2153 .type = HDA_FIXUP_FUNC,
2154 .v.func = alc882_fixup_no_primary_hp,
2155 },
2156 [ALC887_FIXUP_ASUS_BASS] = {
2157 .type = HDA_FIXUP_PINS,
2158 .v.pins = (const struct hda_pintbl[]) {
2159 {0x16, 0x99130130}, /* bass speaker */
2160 {}
2161 },
2162 .chained = true,
2163 .chain_id = ALC887_FIXUP_BASS_CHMAP,
2164 },
2165 [ALC887_FIXUP_BASS_CHMAP] = {
2166 .type = HDA_FIXUP_FUNC,
2167 .v.func = alc_fixup_bass_chmap,
2168 },
2169 };
2170
2171 static const struct snd_pci_quirk alc882_fixup_tbl[] = {
2172 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_FIXUP_ACER_EAPD),
2173 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
2174 SND_PCI_QUIRK(0x1025, 0x0107, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
2175 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_FIXUP_ACER_EAPD),
2176 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
2177 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_FIXUP_ACER_EAPD),
2178 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_FIXUP_ACER_EAPD),
2179 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
2180 ALC882_FIXUP_ACER_ASPIRE_4930G),
2181 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
2182 ALC882_FIXUP_ACER_ASPIRE_4930G),
2183 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
2184 ALC882_FIXUP_ACER_ASPIRE_8930G),
2185 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
2186 ALC882_FIXUP_ACER_ASPIRE_8930G),
2187 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
2188 ALC882_FIXUP_ACER_ASPIRE_4930G),
2189 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
2190 ALC882_FIXUP_ACER_ASPIRE_4930G),
2191 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
2192 ALC882_FIXUP_ACER_ASPIRE_4930G),
2193 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", ALC882_FIXUP_PB_M5210),
2194 SND_PCI_QUIRK(0x1025, 0x021e, "Acer Aspire 5739G",
2195 ALC882_FIXUP_ACER_ASPIRE_4930G),
2196 SND_PCI_QUIRK(0x1025, 0x0259, "Acer Aspire 5935", ALC889_FIXUP_DAC_ROUTE),
2197 SND_PCI_QUIRK(0x1025, 0x026b, "Acer Aspire 8940G", ALC882_FIXUP_ACER_ASPIRE_8930G),
2198 SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", ALC882_FIXUP_ACER_ASPIRE_7736),
2199 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_FIXUP_EAPD),
2200 SND_PCI_QUIRK(0x1043, 0x1873, "ASUS W90V", ALC882_FIXUP_ASUS_W90V),
2201 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_FIXUP_ASUS_W2JC),
2202 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_FIXUP_EEE1601),
2203 SND_PCI_QUIRK(0x1043, 0x84bc, "ASUS ET2700", ALC887_FIXUP_ASUS_BASS),
2204 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT),
2205 SND_PCI_QUIRK(0x104d, 0x905a, "Sony Vaio Z", ALC882_FIXUP_NO_PRIMARY_HP),
2206 SND_PCI_QUIRK(0x104d, 0x9060, "Sony Vaio VPCL14M1R", ALC882_FIXUP_NO_PRIMARY_HP),
2207 SND_PCI_QUIRK(0x104d, 0x9043, "Sony Vaio VGC-LN51JGB", ALC882_FIXUP_NO_PRIMARY_HP),
2208 SND_PCI_QUIRK(0x104d, 0x9044, "Sony VAIO AiO", ALC882_FIXUP_NO_PRIMARY_HP),
2209
2210 /* All Apple entries are in codec SSIDs */
2211 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC889_FIXUP_MBP_VREF),
2212 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC889_FIXUP_MBP_VREF),
2213 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF),
2214 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC889_FIXUP_MP11_VREF),
2215 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_FIXUP_MACPRO_GPIO),
2216 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_FIXUP_MACPRO_GPIO),
2217 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC889_FIXUP_MBP_VREF),
2218 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889_FIXUP_MBP_VREF),
2219 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_FIXUP_EAPD),
2220 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC889_FIXUP_MBA11_VREF),
2221 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC889_FIXUP_MBA21_VREF),
2222 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889_FIXUP_MBP_VREF),
2223 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF),
2224 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_FIXUP_MACPRO_GPIO),
2225 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC889_FIXUP_IMAC91_VREF),
2226 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC889_FIXUP_IMAC91_VREF),
2227 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC889_FIXUP_IMAC91_VREF),
2228 SND_PCI_QUIRK(0x106b, 0x4200, "Mac Pro 5,1", ALC885_FIXUP_MACPRO_GPIO),
2229 SND_PCI_QUIRK(0x106b, 0x4300, "iMac 9,1", ALC889_FIXUP_IMAC91_VREF),
2230 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC889_FIXUP_IMAC91_VREF),
2231 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC889_FIXUP_IMAC91_VREF),
2232 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC889_FIXUP_MBA11_VREF),
2233
2234 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC882_FIXUP_EAPD),
2235 SND_PCI_QUIRK(0x1462, 0x7350, "MSI-7350", ALC889_FIXUP_CD),
2236 SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3),
2237 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3/Z87X-UD3H", ALC889_FIXUP_FRONT_HP_NO_PRESENCE),
2238 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX),
2239 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD),
2240 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD),
2241 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", ALC882_FIXUP_LENOVO_Y530),
2242 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_FIXUP_COEF),
2243 {}
2244 };
2245
2246 static const struct hda_model_fixup alc882_fixup_models[] = {
2247 {.id = ALC882_FIXUP_ACER_ASPIRE_4930G, .name = "acer-aspire-4930g"},
2248 {.id = ALC882_FIXUP_ACER_ASPIRE_8930G, .name = "acer-aspire-8930g"},
2249 {.id = ALC883_FIXUP_ACER_EAPD, .name = "acer-aspire"},
2250 {.id = ALC882_FIXUP_INV_DMIC, .name = "inv-dmic"},
2251 {.id = ALC882_FIXUP_NO_PRIMARY_HP, .name = "no-primary-hp"},
2252 {}
2253 };
2254
2255 /*
2256 * BIOS auto configuration
2257 */
2258 /* almost identical with ALC880 parser... */
alc882_parse_auto_config(struct hda_codec * codec)2259 static int alc882_parse_auto_config(struct hda_codec *codec)
2260 {
2261 static const hda_nid_t alc882_ignore[] = { 0x1d, 0 };
2262 static const hda_nid_t alc882_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2263 return alc_parse_auto_config(codec, alc882_ignore, alc882_ssids);
2264 }
2265
2266 /*
2267 */
patch_alc882(struct hda_codec * codec)2268 static int patch_alc882(struct hda_codec *codec)
2269 {
2270 struct alc_spec *spec;
2271 int err;
2272
2273 err = alc_alloc_spec(codec, 0x0b);
2274 if (err < 0)
2275 return err;
2276
2277 spec = codec->spec;
2278
2279 switch (codec->vendor_id) {
2280 case 0x10ec0882:
2281 case 0x10ec0885:
2282 case 0x10ec0900:
2283 break;
2284 default:
2285 /* ALC883 and variants */
2286 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
2287 break;
2288 }
2289
2290 snd_hda_pick_fixup(codec, alc882_fixup_models, alc882_fixup_tbl,
2291 alc882_fixups);
2292 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
2293
2294 alc_auto_parse_customize_define(codec);
2295
2296 if (has_cdefine_beep(codec))
2297 spec->gen.beep_nid = 0x01;
2298
2299 /* automatic parse from the BIOS config */
2300 err = alc882_parse_auto_config(codec);
2301 if (err < 0)
2302 goto error;
2303
2304 if (!spec->gen.no_analog && spec->gen.beep_nid)
2305 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
2306
2307 codec->patch_ops = alc_patch_ops;
2308
2309 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
2310
2311 return 0;
2312
2313 error:
2314 alc_free(codec);
2315 return err;
2316 }
2317
2318
2319 /*
2320 * ALC262 support
2321 */
alc262_parse_auto_config(struct hda_codec * codec)2322 static int alc262_parse_auto_config(struct hda_codec *codec)
2323 {
2324 static const hda_nid_t alc262_ignore[] = { 0x1d, 0 };
2325 static const hda_nid_t alc262_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2326 return alc_parse_auto_config(codec, alc262_ignore, alc262_ssids);
2327 }
2328
2329 /*
2330 * Pin config fixes
2331 */
2332 enum {
2333 ALC262_FIXUP_FSC_H270,
2334 ALC262_FIXUP_FSC_S7110,
2335 ALC262_FIXUP_HP_Z200,
2336 ALC262_FIXUP_TYAN,
2337 ALC262_FIXUP_LENOVO_3000,
2338 ALC262_FIXUP_BENQ,
2339 ALC262_FIXUP_BENQ_T31,
2340 ALC262_FIXUP_INV_DMIC,
2341 ALC262_FIXUP_INTEL_BAYLEYBAY,
2342 };
2343
2344 static const struct hda_fixup alc262_fixups[] = {
2345 [ALC262_FIXUP_FSC_H270] = {
2346 .type = HDA_FIXUP_PINS,
2347 .v.pins = (const struct hda_pintbl[]) {
2348 { 0x14, 0x99130110 }, /* speaker */
2349 { 0x15, 0x0221142f }, /* front HP */
2350 { 0x1b, 0x0121141f }, /* rear HP */
2351 { }
2352 }
2353 },
2354 [ALC262_FIXUP_FSC_S7110] = {
2355 .type = HDA_FIXUP_PINS,
2356 .v.pins = (const struct hda_pintbl[]) {
2357 { 0x15, 0x90170110 }, /* speaker */
2358 { }
2359 },
2360 .chained = true,
2361 .chain_id = ALC262_FIXUP_BENQ,
2362 },
2363 [ALC262_FIXUP_HP_Z200] = {
2364 .type = HDA_FIXUP_PINS,
2365 .v.pins = (const struct hda_pintbl[]) {
2366 { 0x16, 0x99130120 }, /* internal speaker */
2367 { }
2368 }
2369 },
2370 [ALC262_FIXUP_TYAN] = {
2371 .type = HDA_FIXUP_PINS,
2372 .v.pins = (const struct hda_pintbl[]) {
2373 { 0x14, 0x1993e1f0 }, /* int AUX */
2374 { }
2375 }
2376 },
2377 [ALC262_FIXUP_LENOVO_3000] = {
2378 .type = HDA_FIXUP_PINCTLS,
2379 .v.pins = (const struct hda_pintbl[]) {
2380 { 0x19, PIN_VREF50 },
2381 {}
2382 },
2383 .chained = true,
2384 .chain_id = ALC262_FIXUP_BENQ,
2385 },
2386 [ALC262_FIXUP_BENQ] = {
2387 .type = HDA_FIXUP_VERBS,
2388 .v.verbs = (const struct hda_verb[]) {
2389 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2390 { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
2391 {}
2392 }
2393 },
2394 [ALC262_FIXUP_BENQ_T31] = {
2395 .type = HDA_FIXUP_VERBS,
2396 .v.verbs = (const struct hda_verb[]) {
2397 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2398 { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
2399 {}
2400 }
2401 },
2402 [ALC262_FIXUP_INV_DMIC] = {
2403 .type = HDA_FIXUP_FUNC,
2404 .v.func = alc_fixup_inv_dmic,
2405 },
2406 [ALC262_FIXUP_INTEL_BAYLEYBAY] = {
2407 .type = HDA_FIXUP_FUNC,
2408 .v.func = alc_fixup_no_depop_delay,
2409 },
2410 };
2411
2412 static const struct snd_pci_quirk alc262_fixup_tbl[] = {
2413 SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", ALC262_FIXUP_HP_Z200),
2414 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu Lifebook S7110", ALC262_FIXUP_FSC_S7110),
2415 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FIXUP_BENQ),
2416 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_FIXUP_TYAN),
2417 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", ALC262_FIXUP_FSC_H270),
2418 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000", ALC262_FIXUP_LENOVO_3000),
2419 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_FIXUP_BENQ),
2420 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_FIXUP_BENQ_T31),
2421 SND_PCI_QUIRK(0x8086, 0x7270, "BayleyBay", ALC262_FIXUP_INTEL_BAYLEYBAY),
2422 {}
2423 };
2424
2425 static const struct hda_model_fixup alc262_fixup_models[] = {
2426 {.id = ALC262_FIXUP_INV_DMIC, .name = "inv-dmic"},
2427 {}
2428 };
2429
2430 /*
2431 */
patch_alc262(struct hda_codec * codec)2432 static int patch_alc262(struct hda_codec *codec)
2433 {
2434 struct alc_spec *spec;
2435 int err;
2436
2437 err = alc_alloc_spec(codec, 0x0b);
2438 if (err < 0)
2439 return err;
2440
2441 spec = codec->spec;
2442 spec->gen.shared_mic_vref_pin = 0x18;
2443
2444 #if 0
2445 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
2446 * under-run
2447 */
2448 alc_update_coefex_idx(codec, 0x1a, 7, 0, 0x80);
2449 #endif
2450 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
2451
2452 snd_hda_pick_fixup(codec, alc262_fixup_models, alc262_fixup_tbl,
2453 alc262_fixups);
2454 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
2455
2456 alc_auto_parse_customize_define(codec);
2457
2458 if (has_cdefine_beep(codec))
2459 spec->gen.beep_nid = 0x01;
2460
2461 /* automatic parse from the BIOS config */
2462 err = alc262_parse_auto_config(codec);
2463 if (err < 0)
2464 goto error;
2465
2466 if (!spec->gen.no_analog && spec->gen.beep_nid)
2467 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
2468
2469 codec->patch_ops = alc_patch_ops;
2470 spec->shutup = alc_eapd_shutup;
2471
2472 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
2473
2474 return 0;
2475
2476 error:
2477 alc_free(codec);
2478 return err;
2479 }
2480
2481 /*
2482 * ALC268
2483 */
2484 /* bind Beep switches of both NID 0x0f and 0x10 */
2485 static const struct hda_bind_ctls alc268_bind_beep_sw = {
2486 .ops = &snd_hda_bind_sw,
2487 .values = {
2488 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
2489 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
2490 0
2491 },
2492 };
2493
2494 static const struct snd_kcontrol_new alc268_beep_mixer[] = {
2495 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
2496 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
2497 { }
2498 };
2499
2500 /* set PCBEEP vol = 0, mute connections */
2501 static const struct hda_verb alc268_beep_init_verbs[] = {
2502 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2503 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2504 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2505 { }
2506 };
2507
2508 enum {
2509 ALC268_FIXUP_INV_DMIC,
2510 ALC268_FIXUP_HP_EAPD,
2511 ALC268_FIXUP_SPDIF,
2512 };
2513
2514 static const struct hda_fixup alc268_fixups[] = {
2515 [ALC268_FIXUP_INV_DMIC] = {
2516 .type = HDA_FIXUP_FUNC,
2517 .v.func = alc_fixup_inv_dmic,
2518 },
2519 [ALC268_FIXUP_HP_EAPD] = {
2520 .type = HDA_FIXUP_VERBS,
2521 .v.verbs = (const struct hda_verb[]) {
2522 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 0},
2523 {}
2524 }
2525 },
2526 [ALC268_FIXUP_SPDIF] = {
2527 .type = HDA_FIXUP_PINS,
2528 .v.pins = (const struct hda_pintbl[]) {
2529 { 0x1e, 0x014b1180 }, /* enable SPDIF out */
2530 {}
2531 }
2532 },
2533 };
2534
2535 static const struct hda_model_fixup alc268_fixup_models[] = {
2536 {.id = ALC268_FIXUP_INV_DMIC, .name = "inv-dmic"},
2537 {.id = ALC268_FIXUP_HP_EAPD, .name = "hp-eapd"},
2538 {}
2539 };
2540
2541 static const struct snd_pci_quirk alc268_fixup_tbl[] = {
2542 SND_PCI_QUIRK(0x1025, 0x0139, "Acer TravelMate 6293", ALC268_FIXUP_SPDIF),
2543 SND_PCI_QUIRK(0x1025, 0x015b, "Acer AOA 150 (ZG5)", ALC268_FIXUP_INV_DMIC),
2544 /* below is codec SSID since multiple Toshiba laptops have the
2545 * same PCI SSID 1179:ff00
2546 */
2547 SND_PCI_QUIRK(0x1179, 0xff06, "Toshiba P200", ALC268_FIXUP_HP_EAPD),
2548 {}
2549 };
2550
2551 /*
2552 * BIOS auto configuration
2553 */
alc268_parse_auto_config(struct hda_codec * codec)2554 static int alc268_parse_auto_config(struct hda_codec *codec)
2555 {
2556 static const hda_nid_t alc268_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2557 return alc_parse_auto_config(codec, NULL, alc268_ssids);
2558 }
2559
2560 /*
2561 */
patch_alc268(struct hda_codec * codec)2562 static int patch_alc268(struct hda_codec *codec)
2563 {
2564 struct alc_spec *spec;
2565 int err;
2566
2567 /* ALC268 has no aa-loopback mixer */
2568 err = alc_alloc_spec(codec, 0);
2569 if (err < 0)
2570 return err;
2571
2572 spec = codec->spec;
2573 spec->gen.beep_nid = 0x01;
2574
2575 snd_hda_pick_fixup(codec, alc268_fixup_models, alc268_fixup_tbl, alc268_fixups);
2576 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
2577
2578 /* automatic parse from the BIOS config */
2579 err = alc268_parse_auto_config(codec);
2580 if (err < 0)
2581 goto error;
2582
2583 if (err > 0 && !spec->gen.no_analog &&
2584 spec->gen.autocfg.speaker_pins[0] != 0x1d) {
2585 add_mixer(spec, alc268_beep_mixer);
2586 snd_hda_add_verbs(codec, alc268_beep_init_verbs);
2587 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
2588 /* override the amp caps for beep generator */
2589 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
2590 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
2591 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
2592 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
2593 (0 << AC_AMPCAP_MUTE_SHIFT));
2594 }
2595
2596 codec->patch_ops = alc_patch_ops;
2597 spec->shutup = alc_eapd_shutup;
2598
2599 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
2600
2601 return 0;
2602
2603 error:
2604 alc_free(codec);
2605 return err;
2606 }
2607
2608 /*
2609 * ALC269
2610 */
2611
playback_pcm_open(struct hda_pcm_stream * hinfo,struct hda_codec * codec,struct snd_pcm_substream * substream)2612 static int playback_pcm_open(struct hda_pcm_stream *hinfo,
2613 struct hda_codec *codec,
2614 struct snd_pcm_substream *substream)
2615 {
2616 struct hda_gen_spec *spec = codec->spec;
2617 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
2618 hinfo);
2619 }
2620
playback_pcm_prepare(struct hda_pcm_stream * hinfo,struct hda_codec * codec,unsigned int stream_tag,unsigned int format,struct snd_pcm_substream * substream)2621 static int playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2622 struct hda_codec *codec,
2623 unsigned int stream_tag,
2624 unsigned int format,
2625 struct snd_pcm_substream *substream)
2626 {
2627 struct hda_gen_spec *spec = codec->spec;
2628 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
2629 stream_tag, format, substream);
2630 }
2631
playback_pcm_cleanup(struct hda_pcm_stream * hinfo,struct hda_codec * codec,struct snd_pcm_substream * substream)2632 static int playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2633 struct hda_codec *codec,
2634 struct snd_pcm_substream *substream)
2635 {
2636 struct hda_gen_spec *spec = codec->spec;
2637 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
2638 }
2639
2640 static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
2641 .substreams = 1,
2642 .channels_min = 2,
2643 .channels_max = 8,
2644 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
2645 /* NID is set in alc_build_pcms */
2646 .ops = {
2647 .open = playback_pcm_open,
2648 .prepare = playback_pcm_prepare,
2649 .cleanup = playback_pcm_cleanup
2650 },
2651 };
2652
2653 static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
2654 .substreams = 1,
2655 .channels_min = 2,
2656 .channels_max = 2,
2657 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
2658 /* NID is set in alc_build_pcms */
2659 };
2660
2661 /* different alc269-variants */
2662 enum {
2663 ALC269_TYPE_ALC269VA,
2664 ALC269_TYPE_ALC269VB,
2665 ALC269_TYPE_ALC269VC,
2666 ALC269_TYPE_ALC269VD,
2667 ALC269_TYPE_ALC280,
2668 ALC269_TYPE_ALC282,
2669 ALC269_TYPE_ALC283,
2670 ALC269_TYPE_ALC284,
2671 ALC269_TYPE_ALC285,
2672 ALC269_TYPE_ALC286,
2673 ALC269_TYPE_ALC298,
2674 ALC269_TYPE_ALC255,
2675 ALC269_TYPE_ALC256,
2676 };
2677
2678 /*
2679 * BIOS auto configuration
2680 */
alc269_parse_auto_config(struct hda_codec * codec)2681 static int alc269_parse_auto_config(struct hda_codec *codec)
2682 {
2683 static const hda_nid_t alc269_ignore[] = { 0x1d, 0 };
2684 static const hda_nid_t alc269_ssids[] = { 0, 0x1b, 0x14, 0x21 };
2685 static const hda_nid_t alc269va_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2686 struct alc_spec *spec = codec->spec;
2687 const hda_nid_t *ssids;
2688
2689 switch (spec->codec_variant) {
2690 case ALC269_TYPE_ALC269VA:
2691 case ALC269_TYPE_ALC269VC:
2692 case ALC269_TYPE_ALC280:
2693 case ALC269_TYPE_ALC284:
2694 case ALC269_TYPE_ALC285:
2695 ssids = alc269va_ssids;
2696 break;
2697 case ALC269_TYPE_ALC269VB:
2698 case ALC269_TYPE_ALC269VD:
2699 case ALC269_TYPE_ALC282:
2700 case ALC269_TYPE_ALC283:
2701 case ALC269_TYPE_ALC286:
2702 case ALC269_TYPE_ALC298:
2703 case ALC269_TYPE_ALC255:
2704 case ALC269_TYPE_ALC256:
2705 ssids = alc269_ssids;
2706 break;
2707 default:
2708 ssids = alc269_ssids;
2709 break;
2710 }
2711
2712 return alc_parse_auto_config(codec, alc269_ignore, ssids);
2713 }
2714
2715 static int find_ext_mic_pin(struct hda_codec *codec);
2716
alc286_shutup(struct hda_codec * codec)2717 static void alc286_shutup(struct hda_codec *codec)
2718 {
2719 int i;
2720 int mic_pin = find_ext_mic_pin(codec);
2721 /* don't shut up pins when unloading the driver; otherwise it breaks
2722 * the default pin setup at the next load of the driver
2723 */
2724 if (codec->bus->shutdown)
2725 return;
2726 for (i = 0; i < codec->init_pins.used; i++) {
2727 struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i);
2728 /* use read here for syncing after issuing each verb */
2729 if (pin->nid != mic_pin)
2730 snd_hda_codec_read(codec, pin->nid, 0,
2731 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
2732 }
2733 codec->pins_shutup = 1;
2734 }
2735
alc269vb_toggle_power_output(struct hda_codec * codec,int power_up)2736 static void alc269vb_toggle_power_output(struct hda_codec *codec, int power_up)
2737 {
2738 alc_update_coef_idx(codec, 0x04, 1 << 11, power_up ? (1 << 11) : 0);
2739 }
2740
alc269_shutup(struct hda_codec * codec)2741 static void alc269_shutup(struct hda_codec *codec)
2742 {
2743 struct alc_spec *spec = codec->spec;
2744
2745 if (spec->codec_variant == ALC269_TYPE_ALC269VB)
2746 alc269vb_toggle_power_output(codec, 0);
2747 if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
2748 (alc_get_coef0(codec) & 0x00ff) == 0x018) {
2749 msleep(150);
2750 }
2751 snd_hda_shutup_pins(codec);
2752 }
2753
2754 static struct coef_fw alc282_coefs[] = {
2755 WRITE_COEF(0x03, 0x0002), /* Power Down Control */
2756 UPDATE_COEF(0x05, 0xff3f, 0x0700), /* FIFO and filter clock */
2757 WRITE_COEF(0x07, 0x0200), /* DMIC control */
2758 UPDATE_COEF(0x06, 0x00f0, 0), /* Analog clock */
2759 UPDATE_COEF(0x08, 0xfffc, 0x0c2c), /* JD */
2760 WRITE_COEF(0x0a, 0xcccc), /* JD offset1 */
2761 WRITE_COEF(0x0b, 0xcccc), /* JD offset2 */
2762 WRITE_COEF(0x0e, 0x6e00), /* LDO1/2/3, DAC/ADC */
2763 UPDATE_COEF(0x0f, 0xf800, 0x1000), /* JD */
2764 UPDATE_COEF(0x10, 0xfc00, 0x0c00), /* Capless */
2765 WRITE_COEF(0x6f, 0x0), /* Class D test 4 */
2766 UPDATE_COEF(0x0c, 0xfe00, 0), /* IO power down directly */
2767 WRITE_COEF(0x34, 0xa0c0), /* ANC */
2768 UPDATE_COEF(0x16, 0x0008, 0), /* AGC MUX */
2769 UPDATE_COEF(0x1d, 0x00e0, 0), /* DAC simple content protection */
2770 UPDATE_COEF(0x1f, 0x00e0, 0), /* ADC simple content protection */
2771 WRITE_COEF(0x21, 0x8804), /* DAC ADC Zero Detection */
2772 WRITE_COEF(0x63, 0x2902), /* PLL */
2773 WRITE_COEF(0x68, 0xa080), /* capless control 2 */
2774 WRITE_COEF(0x69, 0x3400), /* capless control 3 */
2775 WRITE_COEF(0x6a, 0x2f3e), /* capless control 4 */
2776 WRITE_COEF(0x6b, 0x0), /* capless control 5 */
2777 UPDATE_COEF(0x6d, 0x0fff, 0x0900), /* class D test 2 */
2778 WRITE_COEF(0x6e, 0x110a), /* class D test 3 */
2779 UPDATE_COEF(0x70, 0x00f8, 0x00d8), /* class D test 5 */
2780 WRITE_COEF(0x71, 0x0014), /* class D test 6 */
2781 WRITE_COEF(0x72, 0xc2ba), /* classD OCP */
2782 UPDATE_COEF(0x77, 0x0f80, 0), /* classD pure DC test */
2783 WRITE_COEF(0x6c, 0xfc06), /* Class D amp control */
2784 {}
2785 };
2786
alc282_restore_default_value(struct hda_codec * codec)2787 static void alc282_restore_default_value(struct hda_codec *codec)
2788 {
2789 alc_process_coef_fw(codec, alc282_coefs);
2790 }
2791
alc282_init(struct hda_codec * codec)2792 static void alc282_init(struct hda_codec *codec)
2793 {
2794 struct alc_spec *spec = codec->spec;
2795 hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
2796 bool hp_pin_sense;
2797 int coef78;
2798
2799 alc282_restore_default_value(codec);
2800
2801 if (!hp_pin)
2802 return;
2803 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
2804 coef78 = alc_read_coef_idx(codec, 0x78);
2805
2806 /* Index 0x78 Direct Drive HP AMP LPM Control 1 */
2807 /* Headphone capless set to high power mode */
2808 alc_write_coef_idx(codec, 0x78, 0x9004);
2809
2810 if (hp_pin_sense)
2811 msleep(2);
2812
2813 snd_hda_codec_write(codec, hp_pin, 0,
2814 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
2815
2816 if (hp_pin_sense)
2817 msleep(85);
2818
2819 snd_hda_codec_write(codec, hp_pin, 0,
2820 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
2821
2822 if (hp_pin_sense)
2823 msleep(100);
2824
2825 /* Headphone capless set to normal mode */
2826 alc_write_coef_idx(codec, 0x78, coef78);
2827 }
2828
alc282_shutup(struct hda_codec * codec)2829 static void alc282_shutup(struct hda_codec *codec)
2830 {
2831 struct alc_spec *spec = codec->spec;
2832 hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
2833 bool hp_pin_sense;
2834 int coef78;
2835
2836 if (!hp_pin) {
2837 alc269_shutup(codec);
2838 return;
2839 }
2840
2841 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
2842 coef78 = alc_read_coef_idx(codec, 0x78);
2843 alc_write_coef_idx(codec, 0x78, 0x9004);
2844
2845 if (hp_pin_sense)
2846 msleep(2);
2847
2848 snd_hda_codec_write(codec, hp_pin, 0,
2849 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
2850
2851 if (hp_pin_sense)
2852 msleep(85);
2853
2854 snd_hda_codec_write(codec, hp_pin, 0,
2855 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
2856
2857 if (hp_pin_sense)
2858 msleep(100);
2859
2860 alc_auto_setup_eapd(codec, false);
2861 snd_hda_shutup_pins(codec);
2862 alc_write_coef_idx(codec, 0x78, coef78);
2863 }
2864
2865 static struct coef_fw alc283_coefs[] = {
2866 WRITE_COEF(0x03, 0x0002), /* Power Down Control */
2867 UPDATE_COEF(0x05, 0xff3f, 0x0700), /* FIFO and filter clock */
2868 WRITE_COEF(0x07, 0x0200), /* DMIC control */
2869 UPDATE_COEF(0x06, 0x00f0, 0), /* Analog clock */
2870 UPDATE_COEF(0x08, 0xfffc, 0x0c2c), /* JD */
2871 WRITE_COEF(0x0a, 0xcccc), /* JD offset1 */
2872 WRITE_COEF(0x0b, 0xcccc), /* JD offset2 */
2873 WRITE_COEF(0x0e, 0x6fc0), /* LDO1/2/3, DAC/ADC */
2874 UPDATE_COEF(0x0f, 0xf800, 0x1000), /* JD */
2875 UPDATE_COEF(0x10, 0xfc00, 0x0c00), /* Capless */
2876 WRITE_COEF(0x3a, 0x0), /* Class D test 4 */
2877 UPDATE_COEF(0x0c, 0xfe00, 0x0), /* IO power down directly */
2878 WRITE_COEF(0x22, 0xa0c0), /* ANC */
2879 UPDATE_COEFEX(0x53, 0x01, 0x000f, 0x0008), /* AGC MUX */
2880 UPDATE_COEF(0x1d, 0x00e0, 0), /* DAC simple content protection */
2881 UPDATE_COEF(0x1f, 0x00e0, 0), /* ADC simple content protection */
2882 WRITE_COEF(0x21, 0x8804), /* DAC ADC Zero Detection */
2883 WRITE_COEF(0x2e, 0x2902), /* PLL */
2884 WRITE_COEF(0x33, 0xa080), /* capless control 2 */
2885 WRITE_COEF(0x34, 0x3400), /* capless control 3 */
2886 WRITE_COEF(0x35, 0x2f3e), /* capless control 4 */
2887 WRITE_COEF(0x36, 0x0), /* capless control 5 */
2888 UPDATE_COEF(0x38, 0x0fff, 0x0900), /* class D test 2 */
2889 WRITE_COEF(0x39, 0x110a), /* class D test 3 */
2890 UPDATE_COEF(0x3b, 0x00f8, 0x00d8), /* class D test 5 */
2891 WRITE_COEF(0x3c, 0x0014), /* class D test 6 */
2892 WRITE_COEF(0x3d, 0xc2ba), /* classD OCP */
2893 UPDATE_COEF(0x42, 0x0f80, 0x0), /* classD pure DC test */
2894 WRITE_COEF(0x49, 0x0), /* test mode */
2895 UPDATE_COEF(0x40, 0xf800, 0x9800), /* Class D DC enable */
2896 UPDATE_COEF(0x42, 0xf000, 0x2000), /* DC offset */
2897 WRITE_COEF(0x37, 0xfc06), /* Class D amp control */
2898 UPDATE_COEF(0x1b, 0x8000, 0), /* HP JD control */
2899 {}
2900 };
2901
alc283_restore_default_value(struct hda_codec * codec)2902 static void alc283_restore_default_value(struct hda_codec *codec)
2903 {
2904 alc_process_coef_fw(codec, alc283_coefs);
2905 }
2906
alc283_init(struct hda_codec * codec)2907 static void alc283_init(struct hda_codec *codec)
2908 {
2909 struct alc_spec *spec = codec->spec;
2910 hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
2911 bool hp_pin_sense;
2912
2913 if (!spec->gen.autocfg.hp_outs) {
2914 if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
2915 hp_pin = spec->gen.autocfg.line_out_pins[0];
2916 }
2917
2918 alc283_restore_default_value(codec);
2919
2920 if (!hp_pin)
2921 return;
2922
2923 msleep(30);
2924 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
2925
2926 /* Index 0x43 Direct Drive HP AMP LPM Control 1 */
2927 /* Headphone capless set to high power mode */
2928 alc_write_coef_idx(codec, 0x43, 0x9004);
2929
2930 snd_hda_codec_write(codec, hp_pin, 0,
2931 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
2932
2933 if (hp_pin_sense)
2934 msleep(85);
2935
2936 snd_hda_codec_write(codec, hp_pin, 0,
2937 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
2938
2939 if (hp_pin_sense)
2940 msleep(85);
2941 /* Index 0x46 Combo jack auto switch control 2 */
2942 /* 3k pull low control for Headset jack. */
2943 alc_update_coef_idx(codec, 0x46, 3 << 12, 0);
2944 /* Headphone capless set to normal mode */
2945 alc_write_coef_idx(codec, 0x43, 0x9614);
2946 }
2947
alc283_shutup(struct hda_codec * codec)2948 static void alc283_shutup(struct hda_codec *codec)
2949 {
2950 struct alc_spec *spec = codec->spec;
2951 hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
2952 bool hp_pin_sense;
2953
2954 if (!spec->gen.autocfg.hp_outs) {
2955 if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
2956 hp_pin = spec->gen.autocfg.line_out_pins[0];
2957 }
2958
2959 if (!hp_pin) {
2960 alc269_shutup(codec);
2961 return;
2962 }
2963
2964 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
2965
2966 alc_write_coef_idx(codec, 0x43, 0x9004);
2967
2968 /*depop hp during suspend*/
2969 alc_write_coef_idx(codec, 0x06, 0x2100);
2970
2971 snd_hda_codec_write(codec, hp_pin, 0,
2972 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
2973
2974 if (hp_pin_sense)
2975 msleep(100);
2976
2977 snd_hda_codec_write(codec, hp_pin, 0,
2978 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
2979
2980 alc_update_coef_idx(codec, 0x46, 0, 3 << 12);
2981
2982 if (hp_pin_sense)
2983 msleep(100);
2984 alc_auto_setup_eapd(codec, false);
2985 snd_hda_shutup_pins(codec);
2986 alc_write_coef_idx(codec, 0x43, 0x9614);
2987 }
2988
alc5505_coef_set(struct hda_codec * codec,unsigned int index_reg,unsigned int val)2989 static void alc5505_coef_set(struct hda_codec *codec, unsigned int index_reg,
2990 unsigned int val)
2991 {
2992 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_COEF_INDEX, index_reg >> 1);
2993 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_PROC_COEF, val & 0xffff); /* LSB */
2994 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_PROC_COEF, val >> 16); /* MSB */
2995 }
2996
alc5505_coef_get(struct hda_codec * codec,unsigned int index_reg)2997 static int alc5505_coef_get(struct hda_codec *codec, unsigned int index_reg)
2998 {
2999 unsigned int val;
3000
3001 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_COEF_INDEX, index_reg >> 1);
3002 val = snd_hda_codec_read(codec, 0x51, 0, AC_VERB_GET_PROC_COEF, 0)
3003 & 0xffff;
3004 val |= snd_hda_codec_read(codec, 0x51, 0, AC_VERB_GET_PROC_COEF, 0)
3005 << 16;
3006 return val;
3007 }
3008
alc5505_dsp_halt(struct hda_codec * codec)3009 static void alc5505_dsp_halt(struct hda_codec *codec)
3010 {
3011 unsigned int val;
3012
3013 alc5505_coef_set(codec, 0x3000, 0x000c); /* DSP CPU stop */
3014 alc5505_coef_set(codec, 0x880c, 0x0008); /* DDR enter self refresh */
3015 alc5505_coef_set(codec, 0x61c0, 0x11110080); /* Clock control for PLL and CPU */
3016 alc5505_coef_set(codec, 0x6230, 0xfc0d4011); /* Disable Input OP */
3017 alc5505_coef_set(codec, 0x61b4, 0x040a2b03); /* Stop PLL2 */
3018 alc5505_coef_set(codec, 0x61b0, 0x00005b17); /* Stop PLL1 */
3019 alc5505_coef_set(codec, 0x61b8, 0x04133303); /* Stop PLL3 */
3020 val = alc5505_coef_get(codec, 0x6220);
3021 alc5505_coef_set(codec, 0x6220, (val | 0x3000)); /* switch Ringbuffer clock to DBUS clock */
3022 }
3023
alc5505_dsp_back_from_halt(struct hda_codec * codec)3024 static void alc5505_dsp_back_from_halt(struct hda_codec *codec)
3025 {
3026 alc5505_coef_set(codec, 0x61b8, 0x04133302);
3027 alc5505_coef_set(codec, 0x61b0, 0x00005b16);
3028 alc5505_coef_set(codec, 0x61b4, 0x040a2b02);
3029 alc5505_coef_set(codec, 0x6230, 0xf80d4011);
3030 alc5505_coef_set(codec, 0x6220, 0x2002010f);
3031 alc5505_coef_set(codec, 0x880c, 0x00000004);
3032 }
3033
alc5505_dsp_init(struct hda_codec * codec)3034 static void alc5505_dsp_init(struct hda_codec *codec)
3035 {
3036 unsigned int val;
3037
3038 alc5505_dsp_halt(codec);
3039 alc5505_dsp_back_from_halt(codec);
3040 alc5505_coef_set(codec, 0x61b0, 0x5b14); /* PLL1 control */
3041 alc5505_coef_set(codec, 0x61b0, 0x5b16);
3042 alc5505_coef_set(codec, 0x61b4, 0x04132b00); /* PLL2 control */
3043 alc5505_coef_set(codec, 0x61b4, 0x04132b02);
3044 alc5505_coef_set(codec, 0x61b8, 0x041f3300); /* PLL3 control*/
3045 alc5505_coef_set(codec, 0x61b8, 0x041f3302);
3046 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_CODEC_RESET, 0); /* Function reset */
3047 alc5505_coef_set(codec, 0x61b8, 0x041b3302);
3048 alc5505_coef_set(codec, 0x61b8, 0x04173302);
3049 alc5505_coef_set(codec, 0x61b8, 0x04163302);
3050 alc5505_coef_set(codec, 0x8800, 0x348b328b); /* DRAM control */
3051 alc5505_coef_set(codec, 0x8808, 0x00020022); /* DRAM control */
3052 alc5505_coef_set(codec, 0x8818, 0x00000400); /* DRAM control */
3053
3054 val = alc5505_coef_get(codec, 0x6200) >> 16; /* Read revision ID */
3055 if (val <= 3)
3056 alc5505_coef_set(codec, 0x6220, 0x2002010f); /* I/O PAD Configuration */
3057 else
3058 alc5505_coef_set(codec, 0x6220, 0x6002018f);
3059
3060 alc5505_coef_set(codec, 0x61ac, 0x055525f0); /**/
3061 alc5505_coef_set(codec, 0x61c0, 0x12230080); /* Clock control */
3062 alc5505_coef_set(codec, 0x61b4, 0x040e2b02); /* PLL2 control */
3063 alc5505_coef_set(codec, 0x61bc, 0x010234f8); /* OSC Control */
3064 alc5505_coef_set(codec, 0x880c, 0x00000004); /* DRAM Function control */
3065 alc5505_coef_set(codec, 0x880c, 0x00000003);
3066 alc5505_coef_set(codec, 0x880c, 0x00000010);
3067
3068 #ifdef HALT_REALTEK_ALC5505
3069 alc5505_dsp_halt(codec);
3070 #endif
3071 }
3072
3073 #ifdef HALT_REALTEK_ALC5505
3074 #define alc5505_dsp_suspend(codec) /* NOP */
3075 #define alc5505_dsp_resume(codec) /* NOP */
3076 #else
3077 #define alc5505_dsp_suspend(codec) alc5505_dsp_halt(codec)
3078 #define alc5505_dsp_resume(codec) alc5505_dsp_back_from_halt(codec)
3079 #endif
3080
3081 #ifdef CONFIG_PM
alc269_suspend(struct hda_codec * codec)3082 static int alc269_suspend(struct hda_codec *codec)
3083 {
3084 struct alc_spec *spec = codec->spec;
3085
3086 if (spec->has_alc5505_dsp)
3087 alc5505_dsp_suspend(codec);
3088 return alc_suspend(codec);
3089 }
3090
alc269_resume(struct hda_codec * codec)3091 static int alc269_resume(struct hda_codec *codec)
3092 {
3093 struct alc_spec *spec = codec->spec;
3094
3095 if (spec->codec_variant == ALC269_TYPE_ALC269VB)
3096 alc269vb_toggle_power_output(codec, 0);
3097 if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
3098 (alc_get_coef0(codec) & 0x00ff) == 0x018) {
3099 msleep(150);
3100 }
3101
3102 codec->patch_ops.init(codec);
3103
3104 if (spec->codec_variant == ALC269_TYPE_ALC269VB)
3105 alc269vb_toggle_power_output(codec, 1);
3106 if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
3107 (alc_get_coef0(codec) & 0x00ff) == 0x017) {
3108 msleep(200);
3109 }
3110
3111 snd_hda_codec_resume_amp(codec);
3112 snd_hda_codec_resume_cache(codec);
3113 hda_call_check_power_status(codec, 0x01);
3114
3115 /* on some machine, the BIOS will clear the codec gpio data when enter
3116 * suspend, and won't restore the data after resume, so we restore it
3117 * in the driver.
3118 */
3119 if (spec->gpio_led)
3120 snd_hda_codec_write(codec, codec->afg, 0, AC_VERB_SET_GPIO_DATA,
3121 spec->gpio_led);
3122
3123 if (spec->has_alc5505_dsp)
3124 alc5505_dsp_resume(codec);
3125
3126 return 0;
3127 }
3128 #endif /* CONFIG_PM */
3129
alc269_fixup_pincfg_no_hp_to_lineout(struct hda_codec * codec,const struct hda_fixup * fix,int action)3130 static void alc269_fixup_pincfg_no_hp_to_lineout(struct hda_codec *codec,
3131 const struct hda_fixup *fix, int action)
3132 {
3133 struct alc_spec *spec = codec->spec;
3134
3135 if (action == HDA_FIXUP_ACT_PRE_PROBE)
3136 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
3137 }
3138
alc269_fixup_hweq(struct hda_codec * codec,const struct hda_fixup * fix,int action)3139 static void alc269_fixup_hweq(struct hda_codec *codec,
3140 const struct hda_fixup *fix, int action)
3141 {
3142 if (action == HDA_FIXUP_ACT_INIT)
3143 alc_update_coef_idx(codec, 0x1e, 0, 0x80);
3144 }
3145
alc269_fixup_headset_mic(struct hda_codec * codec,const struct hda_fixup * fix,int action)3146 static void alc269_fixup_headset_mic(struct hda_codec *codec,
3147 const struct hda_fixup *fix, int action)
3148 {
3149 struct alc_spec *spec = codec->spec;
3150
3151 if (action == HDA_FIXUP_ACT_PRE_PROBE)
3152 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
3153 }
3154
alc271_fixup_dmic(struct hda_codec * codec,const struct hda_fixup * fix,int action)3155 static void alc271_fixup_dmic(struct hda_codec *codec,
3156 const struct hda_fixup *fix, int action)
3157 {
3158 static const struct hda_verb verbs[] = {
3159 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
3160 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
3161 {}
3162 };
3163 unsigned int cfg;
3164
3165 if (strcmp(codec->chip_name, "ALC271X") &&
3166 strcmp(codec->chip_name, "ALC269VB"))
3167 return;
3168 cfg = snd_hda_codec_get_pincfg(codec, 0x12);
3169 if (get_defcfg_connect(cfg) == AC_JACK_PORT_FIXED)
3170 snd_hda_sequence_write(codec, verbs);
3171 }
3172
alc269_fixup_pcm_44k(struct hda_codec * codec,const struct hda_fixup * fix,int action)3173 static void alc269_fixup_pcm_44k(struct hda_codec *codec,
3174 const struct hda_fixup *fix, int action)
3175 {
3176 struct alc_spec *spec = codec->spec;
3177
3178 if (action != HDA_FIXUP_ACT_PROBE)
3179 return;
3180
3181 /* Due to a hardware problem on Lenovo Ideadpad, we need to
3182 * fix the sample rate of analog I/O to 44.1kHz
3183 */
3184 spec->gen.stream_analog_playback = &alc269_44k_pcm_analog_playback;
3185 spec->gen.stream_analog_capture = &alc269_44k_pcm_analog_capture;
3186 }
3187
alc269_fixup_stereo_dmic(struct hda_codec * codec,const struct hda_fixup * fix,int action)3188 static void alc269_fixup_stereo_dmic(struct hda_codec *codec,
3189 const struct hda_fixup *fix, int action)
3190 {
3191 /* The digital-mic unit sends PDM (differential signal) instead of
3192 * the standard PCM, thus you can't record a valid mono stream as is.
3193 * Below is a workaround specific to ALC269 to control the dmic
3194 * signal source as mono.
3195 */
3196 if (action == HDA_FIXUP_ACT_INIT)
3197 alc_update_coef_idx(codec, 0x07, 0, 0x80);
3198 }
3199
alc269_quanta_automute(struct hda_codec * codec)3200 static void alc269_quanta_automute(struct hda_codec *codec)
3201 {
3202 snd_hda_gen_update_outputs(codec);
3203
3204 alc_write_coef_idx(codec, 0x0c, 0x680);
3205 alc_write_coef_idx(codec, 0x0c, 0x480);
3206 }
3207
alc269_fixup_quanta_mute(struct hda_codec * codec,const struct hda_fixup * fix,int action)3208 static void alc269_fixup_quanta_mute(struct hda_codec *codec,
3209 const struct hda_fixup *fix, int action)
3210 {
3211 struct alc_spec *spec = codec->spec;
3212 if (action != HDA_FIXUP_ACT_PROBE)
3213 return;
3214 spec->gen.automute_hook = alc269_quanta_automute;
3215 }
3216
alc269_x101_hp_automute_hook(struct hda_codec * codec,struct hda_jack_callback * jack)3217 static void alc269_x101_hp_automute_hook(struct hda_codec *codec,
3218 struct hda_jack_callback *jack)
3219 {
3220 struct alc_spec *spec = codec->spec;
3221 int vref;
3222 msleep(200);
3223 snd_hda_gen_hp_automute(codec, jack);
3224
3225 vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0;
3226 msleep(100);
3227 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3228 vref);
3229 msleep(500);
3230 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3231 vref);
3232 }
3233
alc269_fixup_x101_headset_mic(struct hda_codec * codec,const struct hda_fixup * fix,int action)3234 static void alc269_fixup_x101_headset_mic(struct hda_codec *codec,
3235 const struct hda_fixup *fix, int action)
3236 {
3237 struct alc_spec *spec = codec->spec;
3238 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3239 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
3240 spec->gen.hp_automute_hook = alc269_x101_hp_automute_hook;
3241 }
3242 }
3243
3244
3245 /* update mute-LED according to the speaker mute state via mic VREF pin */
alc269_fixup_mic_mute_hook(void * private_data,int enabled)3246 static void alc269_fixup_mic_mute_hook(void *private_data, int enabled)
3247 {
3248 struct hda_codec *codec = private_data;
3249 struct alc_spec *spec = codec->spec;
3250 unsigned int pinval;
3251
3252 if (spec->mute_led_polarity)
3253 enabled = !enabled;
3254 pinval = snd_hda_codec_get_pin_target(codec, spec->mute_led_nid);
3255 pinval &= ~AC_PINCTL_VREFEN;
3256 pinval |= enabled ? AC_PINCTL_VREF_HIZ : AC_PINCTL_VREF_80;
3257 if (spec->mute_led_nid)
3258 snd_hda_set_pin_ctl_cache(codec, spec->mute_led_nid, pinval);
3259 }
3260
3261 /* Make sure the led works even in runtime suspend */
led_power_filter(struct hda_codec * codec,hda_nid_t nid,unsigned int power_state)3262 static unsigned int led_power_filter(struct hda_codec *codec,
3263 hda_nid_t nid,
3264 unsigned int power_state)
3265 {
3266 struct alc_spec *spec = codec->spec;
3267
3268 if (power_state != AC_PWRST_D3 || nid == 0 ||
3269 (nid != spec->mute_led_nid && nid != spec->cap_mute_led_nid))
3270 return power_state;
3271
3272 /* Set pin ctl again, it might have just been set to 0 */
3273 snd_hda_set_pin_ctl(codec, nid,
3274 snd_hda_codec_get_pin_target(codec, nid));
3275
3276 return AC_PWRST_D0;
3277 }
3278
alc269_fixup_hp_mute_led(struct hda_codec * codec,const struct hda_fixup * fix,int action)3279 static void alc269_fixup_hp_mute_led(struct hda_codec *codec,
3280 const struct hda_fixup *fix, int action)
3281 {
3282 struct alc_spec *spec = codec->spec;
3283 const struct dmi_device *dev = NULL;
3284
3285 if (action != HDA_FIXUP_ACT_PRE_PROBE)
3286 return;
3287
3288 while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) {
3289 int pol, pin;
3290 if (sscanf(dev->name, "HP_Mute_LED_%d_%x", &pol, &pin) != 2)
3291 continue;
3292 if (pin < 0x0a || pin >= 0x10)
3293 break;
3294 spec->mute_led_polarity = pol;
3295 spec->mute_led_nid = pin - 0x0a + 0x18;
3296 spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook;
3297 spec->gen.vmaster_mute_enum = 1;
3298 codec->power_filter = led_power_filter;
3299 codec_dbg(codec,
3300 "Detected mute LED for %x:%d\n", spec->mute_led_nid,
3301 spec->mute_led_polarity);
3302 break;
3303 }
3304 }
3305
alc269_fixup_hp_mute_led_mic1(struct hda_codec * codec,const struct hda_fixup * fix,int action)3306 static void alc269_fixup_hp_mute_led_mic1(struct hda_codec *codec,
3307 const struct hda_fixup *fix, int action)
3308 {
3309 struct alc_spec *spec = codec->spec;
3310 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3311 spec->mute_led_polarity = 0;
3312 spec->mute_led_nid = 0x18;
3313 spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook;
3314 spec->gen.vmaster_mute_enum = 1;
3315 codec->power_filter = led_power_filter;
3316 }
3317 }
3318
alc269_fixup_hp_mute_led_mic2(struct hda_codec * codec,const struct hda_fixup * fix,int action)3319 static void alc269_fixup_hp_mute_led_mic2(struct hda_codec *codec,
3320 const struct hda_fixup *fix, int action)
3321 {
3322 struct alc_spec *spec = codec->spec;
3323 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3324 spec->mute_led_polarity = 0;
3325 spec->mute_led_nid = 0x19;
3326 spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook;
3327 spec->gen.vmaster_mute_enum = 1;
3328 codec->power_filter = led_power_filter;
3329 }
3330 }
3331
3332 /* update LED status via GPIO */
alc_update_gpio_led(struct hda_codec * codec,unsigned int mask,bool enabled)3333 static void alc_update_gpio_led(struct hda_codec *codec, unsigned int mask,
3334 bool enabled)
3335 {
3336 struct alc_spec *spec = codec->spec;
3337 unsigned int oldval = spec->gpio_led;
3338
3339 if (spec->mute_led_polarity)
3340 enabled = !enabled;
3341
3342 if (enabled)
3343 spec->gpio_led &= ~mask;
3344 else
3345 spec->gpio_led |= mask;
3346 if (spec->gpio_led != oldval)
3347 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
3348 spec->gpio_led);
3349 }
3350
3351 /* turn on/off mute LED via GPIO per vmaster hook */
alc_fixup_gpio_mute_hook(void * private_data,int enabled)3352 static void alc_fixup_gpio_mute_hook(void *private_data, int enabled)
3353 {
3354 struct hda_codec *codec = private_data;
3355 struct alc_spec *spec = codec->spec;
3356
3357 alc_update_gpio_led(codec, spec->gpio_mute_led_mask, enabled);
3358 }
3359
3360 /* turn on/off mic-mute LED via GPIO per capture hook */
alc_fixup_gpio_mic_mute_hook(struct hda_codec * codec,struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)3361 static void alc_fixup_gpio_mic_mute_hook(struct hda_codec *codec,
3362 struct snd_kcontrol *kcontrol,
3363 struct snd_ctl_elem_value *ucontrol)
3364 {
3365 struct alc_spec *spec = codec->spec;
3366
3367 if (ucontrol)
3368 alc_update_gpio_led(codec, spec->gpio_mic_led_mask,
3369 ucontrol->value.integer.value[0] ||
3370 ucontrol->value.integer.value[1]);
3371 }
3372
alc269_fixup_hp_gpio_led(struct hda_codec * codec,const struct hda_fixup * fix,int action)3373 static void alc269_fixup_hp_gpio_led(struct hda_codec *codec,
3374 const struct hda_fixup *fix, int action)
3375 {
3376 struct alc_spec *spec = codec->spec;
3377 static const struct hda_verb gpio_init[] = {
3378 { 0x01, AC_VERB_SET_GPIO_MASK, 0x18 },
3379 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x18 },
3380 {}
3381 };
3382
3383 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3384 spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook;
3385 spec->gen.cap_sync_hook = alc_fixup_gpio_mic_mute_hook;
3386 spec->gpio_led = 0;
3387 spec->mute_led_polarity = 0;
3388 spec->gpio_mute_led_mask = 0x08;
3389 spec->gpio_mic_led_mask = 0x10;
3390 snd_hda_add_verbs(codec, gpio_init);
3391 }
3392 }
3393
alc286_fixup_hp_gpio_led(struct hda_codec * codec,const struct hda_fixup * fix,int action)3394 static void alc286_fixup_hp_gpio_led(struct hda_codec *codec,
3395 const struct hda_fixup *fix, int action)
3396 {
3397 struct alc_spec *spec = codec->spec;
3398 static const struct hda_verb gpio_init[] = {
3399 { 0x01, AC_VERB_SET_GPIO_MASK, 0x22 },
3400 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x22 },
3401 {}
3402 };
3403
3404 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3405 spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook;
3406 spec->gen.cap_sync_hook = alc_fixup_gpio_mic_mute_hook;
3407 spec->gpio_led = 0;
3408 spec->mute_led_polarity = 0;
3409 spec->gpio_mute_led_mask = 0x02;
3410 spec->gpio_mic_led_mask = 0x20;
3411 snd_hda_add_verbs(codec, gpio_init);
3412 }
3413 }
3414
3415 /* turn on/off mic-mute LED per capture hook */
alc269_fixup_hp_cap_mic_mute_hook(struct hda_codec * codec,struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)3416 static void alc269_fixup_hp_cap_mic_mute_hook(struct hda_codec *codec,
3417 struct snd_kcontrol *kcontrol,
3418 struct snd_ctl_elem_value *ucontrol)
3419 {
3420 struct alc_spec *spec = codec->spec;
3421 unsigned int pinval, enable, disable;
3422
3423 pinval = snd_hda_codec_get_pin_target(codec, spec->cap_mute_led_nid);
3424 pinval &= ~AC_PINCTL_VREFEN;
3425 enable = pinval | AC_PINCTL_VREF_80;
3426 disable = pinval | AC_PINCTL_VREF_HIZ;
3427
3428 if (!ucontrol)
3429 return;
3430
3431 if (ucontrol->value.integer.value[0] ||
3432 ucontrol->value.integer.value[1])
3433 pinval = disable;
3434 else
3435 pinval = enable;
3436
3437 if (spec->cap_mute_led_nid)
3438 snd_hda_set_pin_ctl_cache(codec, spec->cap_mute_led_nid, pinval);
3439 }
3440
alc269_fixup_hp_gpio_mic1_led(struct hda_codec * codec,const struct hda_fixup * fix,int action)3441 static void alc269_fixup_hp_gpio_mic1_led(struct hda_codec *codec,
3442 const struct hda_fixup *fix, int action)
3443 {
3444 struct alc_spec *spec = codec->spec;
3445 static const struct hda_verb gpio_init[] = {
3446 { 0x01, AC_VERB_SET_GPIO_MASK, 0x08 },
3447 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x08 },
3448 {}
3449 };
3450
3451 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3452 spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook;
3453 spec->gen.cap_sync_hook = alc269_fixup_hp_cap_mic_mute_hook;
3454 spec->gpio_led = 0;
3455 spec->mute_led_polarity = 0;
3456 spec->gpio_mute_led_mask = 0x08;
3457 spec->cap_mute_led_nid = 0x18;
3458 snd_hda_add_verbs(codec, gpio_init);
3459 codec->power_filter = led_power_filter;
3460 }
3461 }
3462
alc280_fixup_hp_gpio4(struct hda_codec * codec,const struct hda_fixup * fix,int action)3463 static void alc280_fixup_hp_gpio4(struct hda_codec *codec,
3464 const struct hda_fixup *fix, int action)
3465 {
3466 /* Like hp_gpio_mic1_led, but also needs GPIO4 low to enable headphone amp */
3467 struct alc_spec *spec = codec->spec;
3468 static const struct hda_verb gpio_init[] = {
3469 { 0x01, AC_VERB_SET_GPIO_MASK, 0x18 },
3470 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x18 },
3471 {}
3472 };
3473
3474 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3475 spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook;
3476 spec->gen.cap_sync_hook = alc269_fixup_hp_cap_mic_mute_hook;
3477 spec->gpio_led = 0;
3478 spec->mute_led_polarity = 0;
3479 spec->gpio_mute_led_mask = 0x08;
3480 spec->cap_mute_led_nid = 0x18;
3481 snd_hda_add_verbs(codec, gpio_init);
3482 codec->power_filter = led_power_filter;
3483 }
3484 }
3485
3486 #if IS_ENABLED(CONFIG_INPUT)
gpio2_mic_hotkey_event(struct hda_codec * codec,struct hda_jack_callback * event)3487 static void gpio2_mic_hotkey_event(struct hda_codec *codec,
3488 struct hda_jack_callback *event)
3489 {
3490 struct alc_spec *spec = codec->spec;
3491
3492 /* GPIO2 just toggles on a keypress/keyrelease cycle. Therefore
3493 send both key on and key off event for every interrupt. */
3494 input_report_key(spec->kb_dev, KEY_MICMUTE, 1);
3495 input_sync(spec->kb_dev);
3496 input_report_key(spec->kb_dev, KEY_MICMUTE, 0);
3497 input_sync(spec->kb_dev);
3498 }
3499 #endif
3500
alc_register_micmute_input_device(struct hda_codec * codec)3501 static int alc_register_micmute_input_device(struct hda_codec *codec)
3502 {
3503 struct alc_spec *spec = codec->spec;
3504
3505 spec->kb_dev = input_allocate_device();
3506 if (!spec->kb_dev) {
3507 codec_err(codec, "Out of memory (input_allocate_device)\n");
3508 return -ENOMEM;
3509 }
3510 spec->kb_dev->name = "Microphone Mute Button";
3511 spec->kb_dev->evbit[0] = BIT_MASK(EV_KEY);
3512 spec->kb_dev->keybit[BIT_WORD(KEY_MICMUTE)] = BIT_MASK(KEY_MICMUTE);
3513
3514 if (input_register_device(spec->kb_dev)) {
3515 codec_err(codec, "input_register_device failed\n");
3516 input_free_device(spec->kb_dev);
3517 spec->kb_dev = NULL;
3518 return -ENOMEM;
3519 }
3520
3521 return 0;
3522 }
3523
alc280_fixup_hp_gpio2_mic_hotkey(struct hda_codec * codec,const struct hda_fixup * fix,int action)3524 static void alc280_fixup_hp_gpio2_mic_hotkey(struct hda_codec *codec,
3525 const struct hda_fixup *fix, int action)
3526 {
3527 #if IS_ENABLED(CONFIG_INPUT)
3528 /* GPIO1 = set according to SKU external amp
3529 GPIO2 = mic mute hotkey
3530 GPIO3 = mute LED
3531 GPIO4 = mic mute LED */
3532 static const struct hda_verb gpio_init[] = {
3533 { 0x01, AC_VERB_SET_GPIO_MASK, 0x1e },
3534 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x1a },
3535 { 0x01, AC_VERB_SET_GPIO_DATA, 0x02 },
3536 {}
3537 };
3538
3539 struct alc_spec *spec = codec->spec;
3540
3541 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3542 if (alc_register_micmute_input_device(codec) != 0)
3543 return;
3544
3545 snd_hda_add_verbs(codec, gpio_init);
3546 snd_hda_codec_write_cache(codec, codec->afg, 0,
3547 AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x04);
3548 snd_hda_jack_detect_enable_callback(codec, codec->afg,
3549 gpio2_mic_hotkey_event);
3550
3551 spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook;
3552 spec->gen.cap_sync_hook = alc_fixup_gpio_mic_mute_hook;
3553 spec->gpio_led = 0;
3554 spec->mute_led_polarity = 0;
3555 spec->gpio_mute_led_mask = 0x08;
3556 spec->gpio_mic_led_mask = 0x10;
3557 return;
3558 }
3559
3560 if (!spec->kb_dev)
3561 return;
3562
3563 switch (action) {
3564 case HDA_FIXUP_ACT_PROBE:
3565 spec->init_amp = ALC_INIT_DEFAULT;
3566 break;
3567 case HDA_FIXUP_ACT_FREE:
3568 input_unregister_device(spec->kb_dev);
3569 input_free_device(spec->kb_dev);
3570 spec->kb_dev = NULL;
3571 }
3572 #endif
3573 }
3574
alc233_fixup_lenovo_line2_mic_hotkey(struct hda_codec * codec,const struct hda_fixup * fix,int action)3575 static void alc233_fixup_lenovo_line2_mic_hotkey(struct hda_codec *codec,
3576 const struct hda_fixup *fix, int action)
3577 {
3578 /* Line2 = mic mute hotkey
3579 GPIO2 = mic mute LED */
3580 static const struct hda_verb gpio_init[] = {
3581 { 0x01, AC_VERB_SET_GPIO_MASK, 0x04 },
3582 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04 },
3583 {}
3584 };
3585
3586 struct alc_spec *spec = codec->spec;
3587
3588 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3589 if (alc_register_micmute_input_device(codec) != 0)
3590 return;
3591
3592 snd_hda_add_verbs(codec, gpio_init);
3593 snd_hda_jack_detect_enable_callback(codec, 0x1b,
3594 gpio2_mic_hotkey_event);
3595
3596 spec->gen.cap_sync_hook = alc_fixup_gpio_mic_mute_hook;
3597 spec->gpio_led = 0;
3598 spec->mute_led_polarity = 0;
3599 spec->gpio_mic_led_mask = 0x04;
3600 return;
3601 }
3602
3603 if (!spec->kb_dev)
3604 return;
3605
3606 switch (action) {
3607 case HDA_FIXUP_ACT_PROBE:
3608 spec->init_amp = ALC_INIT_DEFAULT;
3609 break;
3610 case HDA_FIXUP_ACT_FREE:
3611 input_unregister_device(spec->kb_dev);
3612 spec->kb_dev = NULL;
3613 }
3614 }
3615
alc269_fixup_hp_line1_mic1_led(struct hda_codec * codec,const struct hda_fixup * fix,int action)3616 static void alc269_fixup_hp_line1_mic1_led(struct hda_codec *codec,
3617 const struct hda_fixup *fix, int action)
3618 {
3619 struct alc_spec *spec = codec->spec;
3620
3621 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3622 spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook;
3623 spec->gen.cap_sync_hook = alc269_fixup_hp_cap_mic_mute_hook;
3624 spec->mute_led_polarity = 0;
3625 spec->mute_led_nid = 0x1a;
3626 spec->cap_mute_led_nid = 0x18;
3627 spec->gen.vmaster_mute_enum = 1;
3628 codec->power_filter = led_power_filter;
3629 }
3630 }
3631
alc_headset_mode_unplugged(struct hda_codec * codec)3632 static void alc_headset_mode_unplugged(struct hda_codec *codec)
3633 {
3634 static struct coef_fw coef0255[] = {
3635 WRITE_COEF(0x1b, 0x0c0b), /* LDO and MISC control */
3636 WRITE_COEF(0x45, 0xd089), /* UAJ function set to menual mode */
3637 UPDATE_COEFEX(0x57, 0x05, 1<<14, 0), /* Direct Drive HP Amp control(Set to verb control)*/
3638 WRITE_COEF(0x06, 0x6104), /* Set MIC2 Vref gate with HP */
3639 WRITE_COEFEX(0x57, 0x03, 0x8aa6), /* Direct Drive HP Amp control */
3640 {}
3641 };
3642 static struct coef_fw coef0233[] = {
3643 WRITE_COEF(0x1b, 0x0c0b),
3644 WRITE_COEF(0x45, 0xc429),
3645 UPDATE_COEF(0x35, 0x4000, 0),
3646 WRITE_COEF(0x06, 0x2104),
3647 WRITE_COEF(0x1a, 0x0001),
3648 WRITE_COEF(0x26, 0x0004),
3649 WRITE_COEF(0x32, 0x42a3),
3650 {}
3651 };
3652 static struct coef_fw coef0288[] = {
3653 UPDATE_COEF(0x4f, 0xfcc0, 0xc400),
3654 UPDATE_COEF(0x50, 0x2000, 0x2000),
3655 UPDATE_COEF(0x56, 0x0006, 0x0006),
3656 UPDATE_COEF(0x66, 0x0008, 0),
3657 UPDATE_COEF(0x67, 0x2000, 0),
3658 {}
3659 };
3660 static struct coef_fw coef0292[] = {
3661 WRITE_COEF(0x76, 0x000e),
3662 WRITE_COEF(0x6c, 0x2400),
3663 WRITE_COEF(0x18, 0x7308),
3664 WRITE_COEF(0x6b, 0xc429),
3665 {}
3666 };
3667 static struct coef_fw coef0293[] = {
3668 UPDATE_COEF(0x10, 7<<8, 6<<8), /* SET Line1 JD to 0 */
3669 UPDATE_COEFEX(0x57, 0x05, 1<<15|1<<13, 0x0), /* SET charge pump by verb */
3670 UPDATE_COEFEX(0x57, 0x03, 1<<10, 1<<10), /* SET EN_OSW to 1 */
3671 UPDATE_COEF(0x1a, 1<<3, 1<<3), /* Combo JD gating with LINE1-VREFO */
3672 WRITE_COEF(0x45, 0xc429), /* Set to TRS type */
3673 UPDATE_COEF(0x4a, 0x000f, 0x000e), /* Combo Jack auto detect */
3674 {}
3675 };
3676 static struct coef_fw coef0668[] = {
3677 WRITE_COEF(0x15, 0x0d40),
3678 WRITE_COEF(0xb7, 0x802b),
3679 {}
3680 };
3681
3682 switch (codec->vendor_id) {
3683 case 0x10ec0255:
3684 case 0x10ec0256:
3685 alc_process_coef_fw(codec, coef0255);
3686 break;
3687 case 0x10ec0233:
3688 case 0x10ec0283:
3689 alc_process_coef_fw(codec, coef0233);
3690 break;
3691 case 0x10ec0286:
3692 case 0x10ec0288:
3693 case 0x10ec0298:
3694 alc_process_coef_fw(codec, coef0288);
3695 break;
3696 case 0x10ec0292:
3697 alc_process_coef_fw(codec, coef0292);
3698 break;
3699 case 0x10ec0293:
3700 alc_process_coef_fw(codec, coef0293);
3701 break;
3702 case 0x10ec0668:
3703 alc_process_coef_fw(codec, coef0668);
3704 break;
3705 }
3706 codec_dbg(codec, "Headset jack set to unplugged mode.\n");
3707 }
3708
3709
alc_headset_mode_mic_in(struct hda_codec * codec,hda_nid_t hp_pin,hda_nid_t mic_pin)3710 static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin,
3711 hda_nid_t mic_pin)
3712 {
3713 static struct coef_fw coef0255[] = {
3714 WRITE_COEFEX(0x57, 0x03, 0x8aa6),
3715 WRITE_COEF(0x06, 0x6100), /* Set MIC2 Vref gate to normal */
3716 {}
3717 };
3718 static struct coef_fw coef0233[] = {
3719 UPDATE_COEF(0x35, 0, 1<<14),
3720 WRITE_COEF(0x06, 0x2100),
3721 WRITE_COEF(0x1a, 0x0021),
3722 WRITE_COEF(0x26, 0x008c),
3723 {}
3724 };
3725 static struct coef_fw coef0288[] = {
3726 UPDATE_COEF(0x50, 0x2000, 0),
3727 UPDATE_COEF(0x56, 0x0006, 0),
3728 UPDATE_COEF(0x4f, 0xfcc0, 0xc400),
3729 UPDATE_COEF(0x66, 0x0008, 0x0008),
3730 UPDATE_COEF(0x67, 0x2000, 0x2000),
3731 {}
3732 };
3733 static struct coef_fw coef0292[] = {
3734 WRITE_COEF(0x19, 0xa208),
3735 WRITE_COEF(0x2e, 0xacf0),
3736 {}
3737 };
3738 static struct coef_fw coef0293[] = {
3739 UPDATE_COEFEX(0x57, 0x05, 0, 1<<15|1<<13), /* SET charge pump by verb */
3740 UPDATE_COEFEX(0x57, 0x03, 1<<10, 0), /* SET EN_OSW to 0 */
3741 UPDATE_COEF(0x1a, 1<<3, 0), /* Combo JD gating without LINE1-VREFO */
3742 {}
3743 };
3744 static struct coef_fw coef0688[] = {
3745 WRITE_COEF(0xb7, 0x802b),
3746 WRITE_COEF(0xb5, 0x1040),
3747 UPDATE_COEF(0xc3, 0, 1<<12),
3748 {}
3749 };
3750
3751 switch (codec->vendor_id) {
3752 case 0x10ec0255:
3753 case 0x10ec0256:
3754 alc_write_coef_idx(codec, 0x45, 0xc489);
3755 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
3756 alc_process_coef_fw(codec, coef0255);
3757 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
3758 break;
3759 case 0x10ec0233:
3760 case 0x10ec0283:
3761 alc_write_coef_idx(codec, 0x45, 0xc429);
3762 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
3763 alc_process_coef_fw(codec, coef0233);
3764 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
3765 break;
3766 case 0x10ec0286:
3767 case 0x10ec0288:
3768 case 0x10ec0298:
3769 alc_update_coef_idx(codec, 0x4f, 0x000c, 0);
3770 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
3771 alc_process_coef_fw(codec, coef0288);
3772 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
3773 break;
3774 case 0x10ec0292:
3775 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
3776 alc_process_coef_fw(codec, coef0292);
3777 break;
3778 case 0x10ec0293:
3779 /* Set to TRS mode */
3780 alc_write_coef_idx(codec, 0x45, 0xc429);
3781 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
3782 alc_process_coef_fw(codec, coef0293);
3783 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
3784 break;
3785 case 0x10ec0662:
3786 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
3787 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
3788 break;
3789 case 0x10ec0668:
3790 alc_write_coef_idx(codec, 0x11, 0x0001);
3791 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
3792 alc_process_coef_fw(codec, coef0688);
3793 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
3794 break;
3795 }
3796 codec_dbg(codec, "Headset jack set to mic-in mode.\n");
3797 }
3798
alc_headset_mode_default(struct hda_codec * codec)3799 static void alc_headset_mode_default(struct hda_codec *codec)
3800 {
3801 static struct coef_fw coef0225[] = {
3802 UPDATE_COEF(0x45, 0x3f<<10, 0x34<<10),
3803 {}
3804 };
3805 static struct coef_fw coef0255[] = {
3806 WRITE_COEF(0x45, 0xc089),
3807 WRITE_COEF(0x45, 0xc489),
3808 WRITE_COEFEX(0x57, 0x03, 0x8ea6),
3809 WRITE_COEF(0x49, 0x0049),
3810 {}
3811 };
3812 static struct coef_fw coef0233[] = {
3813 WRITE_COEF(0x06, 0x2100),
3814 WRITE_COEF(0x32, 0x4ea3),
3815 {}
3816 };
3817 static struct coef_fw coef0288[] = {
3818 UPDATE_COEF(0x4f, 0xfcc0, 0xc400), /* Set to TRS type */
3819 UPDATE_COEF(0x50, 0x2000, 0x2000),
3820 UPDATE_COEF(0x56, 0x0006, 0x0006),
3821 UPDATE_COEF(0x66, 0x0008, 0),
3822 UPDATE_COEF(0x67, 0x2000, 0),
3823 {}
3824 };
3825 static struct coef_fw coef0292[] = {
3826 WRITE_COEF(0x76, 0x000e),
3827 WRITE_COEF(0x6c, 0x2400),
3828 WRITE_COEF(0x6b, 0xc429),
3829 WRITE_COEF(0x18, 0x7308),
3830 {}
3831 };
3832 static struct coef_fw coef0293[] = {
3833 UPDATE_COEF(0x4a, 0x000f, 0x000e), /* Combo Jack auto detect */
3834 WRITE_COEF(0x45, 0xC429), /* Set to TRS type */
3835 UPDATE_COEF(0x1a, 1<<3, 0), /* Combo JD gating without LINE1-VREFO */
3836 {}
3837 };
3838 static struct coef_fw coef0688[] = {
3839 WRITE_COEF(0x11, 0x0041),
3840 WRITE_COEF(0x15, 0x0d40),
3841 WRITE_COEF(0xb7, 0x802b),
3842 {}
3843 };
3844
3845 switch (codec->vendor_id) {
3846 case 0x10ec0225:
3847 alc_process_coef_fw(codec, coef0225);
3848 break;
3849 case 0x10ec0255:
3850 case 0x10ec0256:
3851 alc_process_coef_fw(codec, coef0255);
3852 break;
3853 case 0x10ec0233:
3854 case 0x10ec0283:
3855 alc_process_coef_fw(codec, coef0233);
3856 break;
3857 case 0x10ec0286:
3858 case 0x10ec0288:
3859 case 0x10ec0298:
3860 alc_process_coef_fw(codec, coef0288);
3861 break;
3862 case 0x10ec0292:
3863 alc_process_coef_fw(codec, coef0292);
3864 break;
3865 case 0x10ec0293:
3866 alc_process_coef_fw(codec, coef0293);
3867 break;
3868 case 0x10ec0668:
3869 alc_process_coef_fw(codec, coef0688);
3870 break;
3871 }
3872 codec_dbg(codec, "Headset jack set to headphone (default) mode.\n");
3873 }
3874
3875 /* Iphone type */
alc_headset_mode_ctia(struct hda_codec * codec)3876 static void alc_headset_mode_ctia(struct hda_codec *codec)
3877 {
3878 static struct coef_fw coef0255[] = {
3879 WRITE_COEF(0x45, 0xd489), /* Set to CTIA type */
3880 WRITE_COEF(0x1b, 0x0c2b),
3881 WRITE_COEFEX(0x57, 0x03, 0x8ea6),
3882 {}
3883 };
3884 static struct coef_fw coef0233[] = {
3885 WRITE_COEF(0x45, 0xd429),
3886 WRITE_COEF(0x1b, 0x0c2b),
3887 WRITE_COEF(0x32, 0x4ea3),
3888 {}
3889 };
3890 static struct coef_fw coef0288[] = {
3891 UPDATE_COEF(0x50, 0x2000, 0x2000),
3892 UPDATE_COEF(0x56, 0x0006, 0x0006),
3893 UPDATE_COEF(0x66, 0x0008, 0),
3894 UPDATE_COEF(0x67, 0x2000, 0),
3895 {}
3896 };
3897 static struct coef_fw coef0292[] = {
3898 WRITE_COEF(0x6b, 0xd429),
3899 WRITE_COEF(0x76, 0x0008),
3900 WRITE_COEF(0x18, 0x7388),
3901 {}
3902 };
3903 static struct coef_fw coef0293[] = {
3904 WRITE_COEF(0x45, 0xd429), /* Set to ctia type */
3905 UPDATE_COEF(0x10, 7<<8, 7<<8), /* SET Line1 JD to 1 */
3906 {}
3907 };
3908 static struct coef_fw coef0688[] = {
3909 WRITE_COEF(0x11, 0x0001),
3910 WRITE_COEF(0x15, 0x0d60),
3911 WRITE_COEF(0xc3, 0x0000),
3912 {}
3913 };
3914
3915 switch (codec->vendor_id) {
3916 case 0x10ec0255:
3917 case 0x10ec0256:
3918 alc_process_coef_fw(codec, coef0255);
3919 break;
3920 case 0x10ec0233:
3921 case 0x10ec0283:
3922 alc_process_coef_fw(codec, coef0233);
3923 break;
3924 case 0x10ec0298:
3925 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0020);/* Headset output enable */
3926 /* ALC298 jack type setting is the same with ALC286/ALC288 */
3927 case 0x10ec0286:
3928 case 0x10ec0288:
3929 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400);
3930 msleep(300);
3931 alc_process_coef_fw(codec, coef0288);
3932 break;
3933 case 0x10ec0292:
3934 alc_process_coef_fw(codec, coef0292);
3935 break;
3936 case 0x10ec0293:
3937 alc_process_coef_fw(codec, coef0293);
3938 break;
3939 case 0x10ec0668:
3940 alc_process_coef_fw(codec, coef0688);
3941 break;
3942 }
3943 codec_dbg(codec, "Headset jack set to iPhone-style headset mode.\n");
3944 }
3945
3946 /* Nokia type */
alc_headset_mode_omtp(struct hda_codec * codec)3947 static void alc_headset_mode_omtp(struct hda_codec *codec)
3948 {
3949 static struct coef_fw coef0255[] = {
3950 WRITE_COEF(0x45, 0xe489), /* Set to OMTP Type */
3951 WRITE_COEF(0x1b, 0x0c2b),
3952 WRITE_COEFEX(0x57, 0x03, 0x8ea6),
3953 {}
3954 };
3955 static struct coef_fw coef0233[] = {
3956 WRITE_COEF(0x45, 0xe429),
3957 WRITE_COEF(0x1b, 0x0c2b),
3958 WRITE_COEF(0x32, 0x4ea3),
3959 {}
3960 };
3961 static struct coef_fw coef0288[] = {
3962 UPDATE_COEF(0x50, 0x2000, 0x2000),
3963 UPDATE_COEF(0x56, 0x0006, 0x0006),
3964 UPDATE_COEF(0x66, 0x0008, 0),
3965 UPDATE_COEF(0x67, 0x2000, 0),
3966 {}
3967 };
3968 static struct coef_fw coef0292[] = {
3969 WRITE_COEF(0x6b, 0xe429),
3970 WRITE_COEF(0x76, 0x0008),
3971 WRITE_COEF(0x18, 0x7388),
3972 {}
3973 };
3974 static struct coef_fw coef0293[] = {
3975 WRITE_COEF(0x45, 0xe429), /* Set to omtp type */
3976 UPDATE_COEF(0x10, 7<<8, 7<<8), /* SET Line1 JD to 1 */
3977 {}
3978 };
3979 static struct coef_fw coef0688[] = {
3980 WRITE_COEF(0x11, 0x0001),
3981 WRITE_COEF(0x15, 0x0d50),
3982 WRITE_COEF(0xc3, 0x0000),
3983 {}
3984 };
3985
3986 switch (codec->vendor_id) {
3987 case 0x10ec0255:
3988 case 0x10ec0256:
3989 alc_process_coef_fw(codec, coef0255);
3990 break;
3991 case 0x10ec0233:
3992 case 0x10ec0283:
3993 alc_process_coef_fw(codec, coef0233);
3994 break;
3995 case 0x10ec0298:
3996 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0010);/* Headset output enable */
3997 /* ALC298 jack type setting is the same with ALC286/ALC288 */
3998 case 0x10ec0286:
3999 case 0x10ec0288:
4000 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xe400);
4001 msleep(300);
4002 alc_process_coef_fw(codec, coef0288);
4003 break;
4004 case 0x10ec0292:
4005 alc_process_coef_fw(codec, coef0292);
4006 break;
4007 case 0x10ec0293:
4008 alc_process_coef_fw(codec, coef0293);
4009 break;
4010 case 0x10ec0668:
4011 alc_process_coef_fw(codec, coef0688);
4012 break;
4013 }
4014 codec_dbg(codec, "Headset jack set to Nokia-style headset mode.\n");
4015 }
4016
alc_determine_headset_type(struct hda_codec * codec)4017 static void alc_determine_headset_type(struct hda_codec *codec)
4018 {
4019 int val;
4020 bool is_ctia = false;
4021 struct alc_spec *spec = codec->spec;
4022 static struct coef_fw coef0255[] = {
4023 WRITE_COEF(0x45, 0xd089), /* combo jack auto switch control(Check type)*/
4024 WRITE_COEF(0x49, 0x0149), /* combo jack auto switch control(Vref
4025 conteol) */
4026 {}
4027 };
4028 static struct coef_fw coef0288[] = {
4029 UPDATE_COEF(0x4f, 0xfcc0, 0xd400), /* Check Type */
4030 {}
4031 };
4032 static struct coef_fw coef0293[] = {
4033 UPDATE_COEF(0x4a, 0x000f, 0x0008), /* Combo Jack auto detect */
4034 WRITE_COEF(0x45, 0xD429), /* Set to ctia type */
4035 {}
4036 };
4037 static struct coef_fw coef0688[] = {
4038 WRITE_COEF(0x11, 0x0001),
4039 WRITE_COEF(0xb7, 0x802b),
4040 WRITE_COEF(0x15, 0x0d60),
4041 WRITE_COEF(0xc3, 0x0c00),
4042 {}
4043 };
4044
4045 switch (codec->vendor_id) {
4046 case 0x10ec0255:
4047 case 0x10ec0256:
4048 alc_process_coef_fw(codec, coef0255);
4049 msleep(300);
4050 val = alc_read_coef_idx(codec, 0x46);
4051 is_ctia = (val & 0x0070) == 0x0070;
4052 break;
4053 case 0x10ec0233:
4054 case 0x10ec0283:
4055 alc_write_coef_idx(codec, 0x45, 0xd029);
4056 msleep(300);
4057 val = alc_read_coef_idx(codec, 0x46);
4058 is_ctia = (val & 0x0070) == 0x0070;
4059 break;
4060 case 0x10ec0298:
4061 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0020); /* Headset output enable */
4062 /* ALC298 check jack type is the same with ALC286/ALC288 */
4063 case 0x10ec0286:
4064 case 0x10ec0288:
4065 alc_process_coef_fw(codec, coef0288);
4066 msleep(350);
4067 val = alc_read_coef_idx(codec, 0x50);
4068 is_ctia = (val & 0x0070) == 0x0070;
4069 break;
4070 case 0x10ec0292:
4071 alc_write_coef_idx(codec, 0x6b, 0xd429);
4072 msleep(300);
4073 val = alc_read_coef_idx(codec, 0x6c);
4074 is_ctia = (val & 0x001c) == 0x001c;
4075 break;
4076 case 0x10ec0293:
4077 alc_process_coef_fw(codec, coef0293);
4078 msleep(300);
4079 val = alc_read_coef_idx(codec, 0x46);
4080 is_ctia = (val & 0x0070) == 0x0070;
4081 break;
4082 case 0x10ec0668:
4083 alc_process_coef_fw(codec, coef0688);
4084 msleep(300);
4085 val = alc_read_coef_idx(codec, 0xbe);
4086 is_ctia = (val & 0x1c02) == 0x1c02;
4087 break;
4088 }
4089
4090 codec_dbg(codec, "Headset jack detected iPhone-style headset: %s\n",
4091 is_ctia ? "yes" : "no");
4092 spec->current_headset_type = is_ctia ? ALC_HEADSET_TYPE_CTIA : ALC_HEADSET_TYPE_OMTP;
4093 }
4094
alc_update_headset_mode(struct hda_codec * codec)4095 static void alc_update_headset_mode(struct hda_codec *codec)
4096 {
4097 struct alc_spec *spec = codec->spec;
4098
4099 hda_nid_t mux_pin = spec->gen.imux_pins[spec->gen.cur_mux[0]];
4100 hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
4101
4102 int new_headset_mode;
4103
4104 if (!snd_hda_jack_detect(codec, hp_pin))
4105 new_headset_mode = ALC_HEADSET_MODE_UNPLUGGED;
4106 else if (mux_pin == spec->headset_mic_pin)
4107 new_headset_mode = ALC_HEADSET_MODE_HEADSET;
4108 else if (mux_pin == spec->headphone_mic_pin)
4109 new_headset_mode = ALC_HEADSET_MODE_MIC;
4110 else
4111 new_headset_mode = ALC_HEADSET_MODE_HEADPHONE;
4112
4113 if (new_headset_mode == spec->current_headset_mode) {
4114 snd_hda_gen_update_outputs(codec);
4115 return;
4116 }
4117
4118 switch (new_headset_mode) {
4119 case ALC_HEADSET_MODE_UNPLUGGED:
4120 alc_headset_mode_unplugged(codec);
4121 spec->gen.hp_jack_present = false;
4122 break;
4123 case ALC_HEADSET_MODE_HEADSET:
4124 if (spec->current_headset_type == ALC_HEADSET_TYPE_UNKNOWN)
4125 alc_determine_headset_type(codec);
4126 if (spec->current_headset_type == ALC_HEADSET_TYPE_CTIA)
4127 alc_headset_mode_ctia(codec);
4128 else if (spec->current_headset_type == ALC_HEADSET_TYPE_OMTP)
4129 alc_headset_mode_omtp(codec);
4130 spec->gen.hp_jack_present = true;
4131 break;
4132 case ALC_HEADSET_MODE_MIC:
4133 alc_headset_mode_mic_in(codec, hp_pin, spec->headphone_mic_pin);
4134 spec->gen.hp_jack_present = false;
4135 break;
4136 case ALC_HEADSET_MODE_HEADPHONE:
4137 alc_headset_mode_default(codec);
4138 spec->gen.hp_jack_present = true;
4139 break;
4140 }
4141 if (new_headset_mode != ALC_HEADSET_MODE_MIC) {
4142 snd_hda_set_pin_ctl_cache(codec, hp_pin,
4143 AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN);
4144 if (spec->headphone_mic_pin && spec->headphone_mic_pin != hp_pin)
4145 snd_hda_set_pin_ctl_cache(codec, spec->headphone_mic_pin,
4146 PIN_VREFHIZ);
4147 }
4148 spec->current_headset_mode = new_headset_mode;
4149
4150 snd_hda_gen_update_outputs(codec);
4151 }
4152
alc_update_headset_mode_hook(struct hda_codec * codec,struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)4153 static void alc_update_headset_mode_hook(struct hda_codec *codec,
4154 struct snd_kcontrol *kcontrol,
4155 struct snd_ctl_elem_value *ucontrol)
4156 {
4157 alc_update_headset_mode(codec);
4158 }
4159
alc_update_headset_jack_cb(struct hda_codec * codec,struct hda_jack_callback * jack)4160 static void alc_update_headset_jack_cb(struct hda_codec *codec,
4161 struct hda_jack_callback *jack)
4162 {
4163 struct alc_spec *spec = codec->spec;
4164 spec->current_headset_type = ALC_HEADSET_TYPE_UNKNOWN;
4165 snd_hda_gen_hp_automute(codec, jack);
4166 }
4167
alc_probe_headset_mode(struct hda_codec * codec)4168 static void alc_probe_headset_mode(struct hda_codec *codec)
4169 {
4170 int i;
4171 struct alc_spec *spec = codec->spec;
4172 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
4173
4174 /* Find mic pins */
4175 for (i = 0; i < cfg->num_inputs; i++) {
4176 if (cfg->inputs[i].is_headset_mic && !spec->headset_mic_pin)
4177 spec->headset_mic_pin = cfg->inputs[i].pin;
4178 if (cfg->inputs[i].is_headphone_mic && !spec->headphone_mic_pin)
4179 spec->headphone_mic_pin = cfg->inputs[i].pin;
4180 }
4181
4182 spec->gen.cap_sync_hook = alc_update_headset_mode_hook;
4183 spec->gen.automute_hook = alc_update_headset_mode;
4184 spec->gen.hp_automute_hook = alc_update_headset_jack_cb;
4185 }
4186
alc_fixup_headset_mode(struct hda_codec * codec,const struct hda_fixup * fix,int action)4187 static void alc_fixup_headset_mode(struct hda_codec *codec,
4188 const struct hda_fixup *fix, int action)
4189 {
4190 struct alc_spec *spec = codec->spec;
4191
4192 switch (action) {
4193 case HDA_FIXUP_ACT_PRE_PROBE:
4194 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC | HDA_PINCFG_HEADPHONE_MIC;
4195 break;
4196 case HDA_FIXUP_ACT_PROBE:
4197 alc_probe_headset_mode(codec);
4198 break;
4199 case HDA_FIXUP_ACT_INIT:
4200 spec->current_headset_mode = 0;
4201 alc_update_headset_mode(codec);
4202 break;
4203 }
4204 }
4205
alc_fixup_headset_mode_no_hp_mic(struct hda_codec * codec,const struct hda_fixup * fix,int action)4206 static void alc_fixup_headset_mode_no_hp_mic(struct hda_codec *codec,
4207 const struct hda_fixup *fix, int action)
4208 {
4209 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4210 struct alc_spec *spec = codec->spec;
4211 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
4212 }
4213 else
4214 alc_fixup_headset_mode(codec, fix, action);
4215 }
4216
alc255_set_default_jack_type(struct hda_codec * codec)4217 static void alc255_set_default_jack_type(struct hda_codec *codec)
4218 {
4219 /* Set to iphone type */
4220 static struct coef_fw fw[] = {
4221 WRITE_COEF(0x1b, 0x880b),
4222 WRITE_COEF(0x45, 0xd089),
4223 WRITE_COEF(0x1b, 0x080b),
4224 WRITE_COEF(0x46, 0x0004),
4225 WRITE_COEF(0x1b, 0x0c0b),
4226 {}
4227 };
4228 alc_process_coef_fw(codec, fw);
4229 msleep(30);
4230 }
4231
alc_fixup_headset_mode_alc255(struct hda_codec * codec,const struct hda_fixup * fix,int action)4232 static void alc_fixup_headset_mode_alc255(struct hda_codec *codec,
4233 const struct hda_fixup *fix, int action)
4234 {
4235 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4236 alc255_set_default_jack_type(codec);
4237 }
4238 alc_fixup_headset_mode(codec, fix, action);
4239 }
4240
alc_fixup_headset_mode_alc255_no_hp_mic(struct hda_codec * codec,const struct hda_fixup * fix,int action)4241 static void alc_fixup_headset_mode_alc255_no_hp_mic(struct hda_codec *codec,
4242 const struct hda_fixup *fix, int action)
4243 {
4244 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4245 struct alc_spec *spec = codec->spec;
4246 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
4247 alc255_set_default_jack_type(codec);
4248 }
4249 else
4250 alc_fixup_headset_mode(codec, fix, action);
4251 }
4252
alc288_update_headset_jack_cb(struct hda_codec * codec,struct hda_jack_callback * jack)4253 static void alc288_update_headset_jack_cb(struct hda_codec *codec,
4254 struct hda_jack_callback *jack)
4255 {
4256 struct alc_spec *spec = codec->spec;
4257 int present;
4258
4259 alc_update_headset_jack_cb(codec, jack);
4260 /* Headset Mic enable or disable, only for Dell Dino */
4261 present = spec->gen.hp_jack_present ? 0x40 : 0;
4262 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
4263 present);
4264 }
4265
alc_fixup_headset_mode_dell_alc288(struct hda_codec * codec,const struct hda_fixup * fix,int action)4266 static void alc_fixup_headset_mode_dell_alc288(struct hda_codec *codec,
4267 const struct hda_fixup *fix, int action)
4268 {
4269 alc_fixup_headset_mode(codec, fix, action);
4270 if (action == HDA_FIXUP_ACT_PROBE) {
4271 struct alc_spec *spec = codec->spec;
4272 spec->gen.hp_automute_hook = alc288_update_headset_jack_cb;
4273 }
4274 }
4275
alc_fixup_auto_mute_via_amp(struct hda_codec * codec,const struct hda_fixup * fix,int action)4276 static void alc_fixup_auto_mute_via_amp(struct hda_codec *codec,
4277 const struct hda_fixup *fix, int action)
4278 {
4279 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4280 struct alc_spec *spec = codec->spec;
4281 spec->gen.auto_mute_via_amp = 1;
4282 }
4283 }
4284
alc_no_shutup(struct hda_codec * codec)4285 static void alc_no_shutup(struct hda_codec *codec)
4286 {
4287 }
4288
alc_fixup_no_shutup(struct hda_codec * codec,const struct hda_fixup * fix,int action)4289 static void alc_fixup_no_shutup(struct hda_codec *codec,
4290 const struct hda_fixup *fix, int action)
4291 {
4292 if (action == HDA_FIXUP_ACT_PROBE) {
4293 struct alc_spec *spec = codec->spec;
4294 spec->shutup = alc_no_shutup;
4295 }
4296 }
4297
alc_fixup_disable_aamix(struct hda_codec * codec,const struct hda_fixup * fix,int action)4298 static void alc_fixup_disable_aamix(struct hda_codec *codec,
4299 const struct hda_fixup *fix, int action)
4300 {
4301 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4302 struct alc_spec *spec = codec->spec;
4303 /* Disable AA-loopback as it causes white noise */
4304 spec->gen.mixer_nid = 0;
4305 }
4306 }
4307
alc_power_filter_xps13(struct hda_codec * codec,hda_nid_t nid,unsigned int power_state)4308 static unsigned int alc_power_filter_xps13(struct hda_codec *codec,
4309 hda_nid_t nid,
4310 unsigned int power_state)
4311 {
4312 struct alc_spec *spec = codec->spec;
4313
4314 /* Avoid pop noises when headphones are plugged in */
4315 if (spec->gen.hp_jack_present)
4316 if (nid == codec->afg || nid == 0x02 || nid == 0x15)
4317 return AC_PWRST_D0;
4318 return power_state;
4319 }
4320
alc_fixup_dell_xps13(struct hda_codec * codec,const struct hda_fixup * fix,int action)4321 static void alc_fixup_dell_xps13(struct hda_codec *codec,
4322 const struct hda_fixup *fix, int action)
4323 {
4324 if (action == HDA_FIXUP_ACT_PROBE) {
4325 struct alc_spec *spec = codec->spec;
4326 struct hda_input_mux *imux = &spec->gen.input_mux;
4327 int i;
4328
4329 spec->shutup = alc_no_shutup;
4330 codec->power_filter = alc_power_filter_xps13;
4331
4332 /* Make the internal mic the default input source. */
4333 for (i = 0; i < imux->num_items; i++) {
4334 if (spec->gen.imux_pins[i] == 0x12) {
4335 spec->gen.cur_mux[0] = i;
4336 break;
4337 }
4338 }
4339 }
4340 }
4341
alc_fixup_headset_mode_alc662(struct hda_codec * codec,const struct hda_fixup * fix,int action)4342 static void alc_fixup_headset_mode_alc662(struct hda_codec *codec,
4343 const struct hda_fixup *fix, int action)
4344 {
4345 struct alc_spec *spec = codec->spec;
4346
4347 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4348 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
4349 spec->gen.hp_mic = 1; /* Mic-in is same pin as headphone */
4350
4351 /* Disable boost for mic-in permanently. (This code is only called
4352 from quirks that guarantee that the headphone is at NID 0x1b.) */
4353 snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000);
4354 snd_hda_override_wcaps(codec, 0x1b, get_wcaps(codec, 0x1b) & ~AC_WCAP_IN_AMP);
4355 } else
4356 alc_fixup_headset_mode(codec, fix, action);
4357 }
4358
alc_fixup_headset_mode_alc668(struct hda_codec * codec,const struct hda_fixup * fix,int action)4359 static void alc_fixup_headset_mode_alc668(struct hda_codec *codec,
4360 const struct hda_fixup *fix, int action)
4361 {
4362 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4363 alc_write_coef_idx(codec, 0xc4, 0x8000);
4364 alc_update_coef_idx(codec, 0xc2, ~0xfe, 0);
4365 snd_hda_set_pin_ctl_cache(codec, 0x18, 0);
4366 }
4367 alc_fixup_headset_mode(codec, fix, action);
4368 }
4369
4370 /* Returns the nid of the external mic input pin, or 0 if it cannot be found. */
find_ext_mic_pin(struct hda_codec * codec)4371 static int find_ext_mic_pin(struct hda_codec *codec)
4372 {
4373 struct alc_spec *spec = codec->spec;
4374 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
4375 hda_nid_t nid;
4376 unsigned int defcfg;
4377 int i;
4378
4379 for (i = 0; i < cfg->num_inputs; i++) {
4380 if (cfg->inputs[i].type != AUTO_PIN_MIC)
4381 continue;
4382 nid = cfg->inputs[i].pin;
4383 defcfg = snd_hda_codec_get_pincfg(codec, nid);
4384 if (snd_hda_get_input_pin_attr(defcfg) == INPUT_PIN_ATTR_INT)
4385 continue;
4386 return nid;
4387 }
4388
4389 return 0;
4390 }
4391
alc271_hp_gate_mic_jack(struct hda_codec * codec,const struct hda_fixup * fix,int action)4392 static void alc271_hp_gate_mic_jack(struct hda_codec *codec,
4393 const struct hda_fixup *fix,
4394 int action)
4395 {
4396 struct alc_spec *spec = codec->spec;
4397
4398 if (action == HDA_FIXUP_ACT_PROBE) {
4399 int mic_pin = find_ext_mic_pin(codec);
4400 int hp_pin = spec->gen.autocfg.hp_pins[0];
4401
4402 if (snd_BUG_ON(!mic_pin || !hp_pin))
4403 return;
4404 snd_hda_jack_set_gating_jack(codec, mic_pin, hp_pin);
4405 }
4406 }
4407
alc269_fixup_limit_int_mic_boost(struct hda_codec * codec,const struct hda_fixup * fix,int action)4408 static void alc269_fixup_limit_int_mic_boost(struct hda_codec *codec,
4409 const struct hda_fixup *fix,
4410 int action)
4411 {
4412 struct alc_spec *spec = codec->spec;
4413 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
4414 int i;
4415
4416 /* The mic boosts on level 2 and 3 are too noisy
4417 on the internal mic input.
4418 Therefore limit the boost to 0 or 1. */
4419
4420 if (action != HDA_FIXUP_ACT_PROBE)
4421 return;
4422
4423 for (i = 0; i < cfg->num_inputs; i++) {
4424 hda_nid_t nid = cfg->inputs[i].pin;
4425 unsigned int defcfg;
4426 if (cfg->inputs[i].type != AUTO_PIN_MIC)
4427 continue;
4428 defcfg = snd_hda_codec_get_pincfg(codec, nid);
4429 if (snd_hda_get_input_pin_attr(defcfg) != INPUT_PIN_ATTR_INT)
4430 continue;
4431
4432 snd_hda_override_amp_caps(codec, nid, HDA_INPUT,
4433 (0x00 << AC_AMPCAP_OFFSET_SHIFT) |
4434 (0x01 << AC_AMPCAP_NUM_STEPS_SHIFT) |
4435 (0x2f << AC_AMPCAP_STEP_SIZE_SHIFT) |
4436 (0 << AC_AMPCAP_MUTE_SHIFT));
4437 }
4438 }
4439
alc283_hp_automute_hook(struct hda_codec * codec,struct hda_jack_callback * jack)4440 static void alc283_hp_automute_hook(struct hda_codec *codec,
4441 struct hda_jack_callback *jack)
4442 {
4443 struct alc_spec *spec = codec->spec;
4444 int vref;
4445
4446 msleep(200);
4447 snd_hda_gen_hp_automute(codec, jack);
4448
4449 vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0;
4450
4451 msleep(600);
4452 snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4453 vref);
4454 }
4455
alc283_fixup_chromebook(struct hda_codec * codec,const struct hda_fixup * fix,int action)4456 static void alc283_fixup_chromebook(struct hda_codec *codec,
4457 const struct hda_fixup *fix, int action)
4458 {
4459 struct alc_spec *spec = codec->spec;
4460
4461 switch (action) {
4462 case HDA_FIXUP_ACT_PRE_PROBE:
4463 snd_hda_override_wcaps(codec, 0x03, 0);
4464 /* Disable AA-loopback as it causes white noise */
4465 spec->gen.mixer_nid = 0;
4466 break;
4467 case HDA_FIXUP_ACT_INIT:
4468 /* MIC2-VREF control */
4469 /* Set to manual mode */
4470 alc_update_coef_idx(codec, 0x06, 0x000c, 0);
4471 /* Enable Line1 input control by verb */
4472 alc_update_coef_idx(codec, 0x1a, 0, 1 << 4);
4473 break;
4474 }
4475 }
4476
alc283_fixup_sense_combo_jack(struct hda_codec * codec,const struct hda_fixup * fix,int action)4477 static void alc283_fixup_sense_combo_jack(struct hda_codec *codec,
4478 const struct hda_fixup *fix, int action)
4479 {
4480 struct alc_spec *spec = codec->spec;
4481
4482 switch (action) {
4483 case HDA_FIXUP_ACT_PRE_PROBE:
4484 spec->gen.hp_automute_hook = alc283_hp_automute_hook;
4485 break;
4486 case HDA_FIXUP_ACT_INIT:
4487 /* MIC2-VREF control */
4488 /* Set to manual mode */
4489 alc_update_coef_idx(codec, 0x06, 0x000c, 0);
4490 break;
4491 }
4492 }
4493
4494 /* mute tablet speaker pin (0x14) via dock plugging in addition */
asus_tx300_automute(struct hda_codec * codec)4495 static void asus_tx300_automute(struct hda_codec *codec)
4496 {
4497 struct alc_spec *spec = codec->spec;
4498 snd_hda_gen_update_outputs(codec);
4499 if (snd_hda_jack_detect(codec, 0x1b))
4500 spec->gen.mute_bits |= (1ULL << 0x14);
4501 }
4502
alc282_fixup_asus_tx300(struct hda_codec * codec,const struct hda_fixup * fix,int action)4503 static void alc282_fixup_asus_tx300(struct hda_codec *codec,
4504 const struct hda_fixup *fix, int action)
4505 {
4506 struct alc_spec *spec = codec->spec;
4507 /* TX300 needs to set up GPIO2 for the speaker amp */
4508 static const struct hda_verb gpio2_verbs[] = {
4509 { 0x01, AC_VERB_SET_GPIO_MASK, 0x04 },
4510 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04 },
4511 { 0x01, AC_VERB_SET_GPIO_DATA, 0x04 },
4512 {}
4513 };
4514 static const struct hda_pintbl dock_pins[] = {
4515 { 0x1b, 0x21114000 }, /* dock speaker pin */
4516 {}
4517 };
4518 struct snd_kcontrol *kctl;
4519
4520 switch (action) {
4521 case HDA_FIXUP_ACT_PRE_PROBE:
4522 snd_hda_add_verbs(codec, gpio2_verbs);
4523 snd_hda_apply_pincfgs(codec, dock_pins);
4524 spec->gen.auto_mute_via_amp = 1;
4525 spec->gen.automute_hook = asus_tx300_automute;
4526 snd_hda_jack_detect_enable_callback(codec, 0x1b,
4527 snd_hda_gen_hp_automute);
4528 break;
4529 case HDA_FIXUP_ACT_BUILD:
4530 /* this is a bit tricky; give more sane names for the main
4531 * (tablet) speaker and the dock speaker, respectively
4532 */
4533 kctl = snd_hda_find_mixer_ctl(codec, "Speaker Playback Switch");
4534 if (kctl)
4535 strcpy(kctl->id.name, "Dock Speaker Playback Switch");
4536 kctl = snd_hda_find_mixer_ctl(codec, "Bass Speaker Playback Switch");
4537 if (kctl)
4538 strcpy(kctl->id.name, "Speaker Playback Switch");
4539 break;
4540 }
4541 }
4542
alc290_fixup_mono_speakers(struct hda_codec * codec,const struct hda_fixup * fix,int action)4543 static void alc290_fixup_mono_speakers(struct hda_codec *codec,
4544 const struct hda_fixup *fix, int action)
4545 {
4546 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4547 /* DAC node 0x03 is giving mono output. We therefore want to
4548 make sure 0x14 (front speaker) and 0x15 (headphones) use the
4549 stereo DAC, while leaving 0x17 (bass speaker) for node 0x03. */
4550 hda_nid_t conn1[2] = { 0x0c };
4551 snd_hda_override_conn_list(codec, 0x14, 1, conn1);
4552 snd_hda_override_conn_list(codec, 0x15, 1, conn1);
4553 }
4554 }
4555
4556 /* Hook to update amp GPIO4 for automute */
alc280_hp_gpio4_automute_hook(struct hda_codec * codec,struct hda_jack_callback * jack)4557 static void alc280_hp_gpio4_automute_hook(struct hda_codec *codec,
4558 struct hda_jack_callback *jack)
4559 {
4560 struct alc_spec *spec = codec->spec;
4561
4562 snd_hda_gen_hp_automute(codec, jack);
4563 /* mute_led_polarity is set to 0, so we pass inverted value here */
4564 alc_update_gpio_led(codec, 0x10, !spec->gen.hp_jack_present);
4565 }
4566
4567 /* Manage GPIOs for HP EliteBook Folio 9480m.
4568 *
4569 * GPIO4 is the headphone amplifier power control
4570 * GPIO3 is the audio output mute indicator LED
4571 */
4572
alc280_fixup_hp_9480m(struct hda_codec * codec,const struct hda_fixup * fix,int action)4573 static void alc280_fixup_hp_9480m(struct hda_codec *codec,
4574 const struct hda_fixup *fix,
4575 int action)
4576 {
4577 struct alc_spec *spec = codec->spec;
4578 static const struct hda_verb gpio_init[] = {
4579 { 0x01, AC_VERB_SET_GPIO_MASK, 0x18 },
4580 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x18 },
4581 {}
4582 };
4583
4584 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4585 /* Set the hooks to turn the headphone amp on/off
4586 * as needed
4587 */
4588 spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook;
4589 spec->gen.hp_automute_hook = alc280_hp_gpio4_automute_hook;
4590
4591 /* The GPIOs are currently off */
4592 spec->gpio_led = 0;
4593
4594 /* GPIO3 is connected to the output mute LED,
4595 * high is on, low is off
4596 */
4597 spec->mute_led_polarity = 0;
4598 spec->gpio_mute_led_mask = 0x08;
4599
4600 /* Initialize GPIO configuration */
4601 snd_hda_add_verbs(codec, gpio_init);
4602 }
4603 }
4604
4605 /* for hda_fixup_thinkpad_acpi() */
4606 #include "thinkpad_helper.c"
4607
4608 /* for dell wmi mic mute led */
4609 #include "dell_wmi_helper.c"
4610
4611 enum {
4612 ALC269_FIXUP_SONY_VAIO,
4613 ALC275_FIXUP_SONY_VAIO_GPIO2,
4614 ALC269_FIXUP_DELL_M101Z,
4615 ALC269_FIXUP_SKU_IGNORE,
4616 ALC269_FIXUP_ASUS_G73JW,
4617 ALC269_FIXUP_LENOVO_EAPD,
4618 ALC275_FIXUP_SONY_HWEQ,
4619 ALC275_FIXUP_SONY_DISABLE_AAMIX,
4620 ALC271_FIXUP_DMIC,
4621 ALC269_FIXUP_PCM_44K,
4622 ALC269_FIXUP_STEREO_DMIC,
4623 ALC269_FIXUP_HEADSET_MIC,
4624 ALC269_FIXUP_QUANTA_MUTE,
4625 ALC269_FIXUP_LIFEBOOK,
4626 ALC269_FIXUP_LIFEBOOK_EXTMIC,
4627 ALC269_FIXUP_LIFEBOOK_HP_PIN,
4628 ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT,
4629 ALC269_FIXUP_AMIC,
4630 ALC269_FIXUP_DMIC,
4631 ALC269VB_FIXUP_AMIC,
4632 ALC269VB_FIXUP_DMIC,
4633 ALC269_FIXUP_HP_MUTE_LED,
4634 ALC269_FIXUP_HP_MUTE_LED_MIC1,
4635 ALC269_FIXUP_HP_MUTE_LED_MIC2,
4636 ALC269_FIXUP_HP_GPIO_LED,
4637 ALC269_FIXUP_HP_GPIO_MIC1_LED,
4638 ALC269_FIXUP_HP_LINE1_MIC1_LED,
4639 ALC269_FIXUP_INV_DMIC,
4640 ALC269_FIXUP_LENOVO_DOCK,
4641 ALC269_FIXUP_NO_SHUTUP,
4642 ALC286_FIXUP_SONY_MIC_NO_PRESENCE,
4643 ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT,
4644 ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
4645 ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
4646 ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
4647 ALC269_FIXUP_HEADSET_MODE,
4648 ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC,
4649 ALC269_FIXUP_ASPIRE_HEADSET_MIC,
4650 ALC269_FIXUP_ASUS_X101_FUNC,
4651 ALC269_FIXUP_ASUS_X101_VERB,
4652 ALC269_FIXUP_ASUS_X101,
4653 ALC271_FIXUP_AMIC_MIC2,
4654 ALC271_FIXUP_HP_GATE_MIC_JACK,
4655 ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572,
4656 ALC269_FIXUP_ACER_AC700,
4657 ALC269_FIXUP_LIMIT_INT_MIC_BOOST,
4658 ALC269VB_FIXUP_ASUS_ZENBOOK,
4659 ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A,
4660 ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED,
4661 ALC269VB_FIXUP_ORDISSIMO_EVE2,
4662 ALC283_FIXUP_CHROME_BOOK,
4663 ALC283_FIXUP_SENSE_COMBO_JACK,
4664 ALC282_FIXUP_ASUS_TX300,
4665 ALC283_FIXUP_INT_MIC,
4666 ALC290_FIXUP_MONO_SPEAKERS,
4667 ALC290_FIXUP_MONO_SPEAKERS_HSJACK,
4668 ALC290_FIXUP_SUBWOOFER,
4669 ALC290_FIXUP_SUBWOOFER_HSJACK,
4670 ALC269_FIXUP_THINKPAD_ACPI,
4671 ALC269_FIXUP_DMIC_THINKPAD_ACPI,
4672 ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
4673 ALC255_FIXUP_DELL2_MIC_NO_PRESENCE,
4674 ALC255_FIXUP_HEADSET_MODE,
4675 ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC,
4676 ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
4677 ALC292_FIXUP_TPT440_DOCK,
4678 ALC292_FIXUP_TPT440_DOCK2,
4679 ALC283_FIXUP_BXBT2807_MIC,
4680 ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED,
4681 ALC282_FIXUP_ASPIRE_V5_PINS,
4682 ALC280_FIXUP_HP_GPIO4,
4683 ALC286_FIXUP_HP_GPIO_LED,
4684 ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY,
4685 ALC280_FIXUP_HP_DOCK_PINS,
4686 ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED,
4687 ALC280_FIXUP_HP_9480M,
4688 ALC288_FIXUP_DELL_HEADSET_MODE,
4689 ALC288_FIXUP_DELL1_MIC_NO_PRESENCE,
4690 ALC288_FIXUP_DELL_XPS_13_GPIO6,
4691 ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
4692 ALC275_FIXUP_DELL_XPS,
4693 ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE,
4694 ALC293_FIXUP_LENOVO_SPK_NOISE,
4695 ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY,
4696 ALC255_FIXUP_DELL_SPK_NOISE,
4697 ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
4698 ALC280_FIXUP_HP_HEADSET_MIC,
4699 ALC221_FIXUP_HP_FRONT_MIC,
4700 };
4701
4702 static const struct hda_fixup alc269_fixups[] = {
4703 [ALC269_FIXUP_SONY_VAIO] = {
4704 .type = HDA_FIXUP_PINCTLS,
4705 .v.pins = (const struct hda_pintbl[]) {
4706 {0x19, PIN_VREFGRD},
4707 {}
4708 }
4709 },
4710 [ALC275_FIXUP_SONY_VAIO_GPIO2] = {
4711 .type = HDA_FIXUP_VERBS,
4712 .v.verbs = (const struct hda_verb[]) {
4713 {0x01, AC_VERB_SET_GPIO_MASK, 0x04},
4714 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04},
4715 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4716 { }
4717 },
4718 .chained = true,
4719 .chain_id = ALC269_FIXUP_SONY_VAIO
4720 },
4721 [ALC269_FIXUP_DELL_M101Z] = {
4722 .type = HDA_FIXUP_VERBS,
4723 .v.verbs = (const struct hda_verb[]) {
4724 /* Enables internal speaker */
4725 {0x20, AC_VERB_SET_COEF_INDEX, 13},
4726 {0x20, AC_VERB_SET_PROC_COEF, 0x4040},
4727 {}
4728 }
4729 },
4730 [ALC269_FIXUP_SKU_IGNORE] = {
4731 .type = HDA_FIXUP_FUNC,
4732 .v.func = alc_fixup_sku_ignore,
4733 },
4734 [ALC269_FIXUP_ASUS_G73JW] = {
4735 .type = HDA_FIXUP_PINS,
4736 .v.pins = (const struct hda_pintbl[]) {
4737 { 0x17, 0x99130111 }, /* subwoofer */
4738 { }
4739 }
4740 },
4741 [ALC269_FIXUP_LENOVO_EAPD] = {
4742 .type = HDA_FIXUP_VERBS,
4743 .v.verbs = (const struct hda_verb[]) {
4744 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
4745 {}
4746 }
4747 },
4748 [ALC275_FIXUP_SONY_HWEQ] = {
4749 .type = HDA_FIXUP_FUNC,
4750 .v.func = alc269_fixup_hweq,
4751 .chained = true,
4752 .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2
4753 },
4754 [ALC275_FIXUP_SONY_DISABLE_AAMIX] = {
4755 .type = HDA_FIXUP_FUNC,
4756 .v.func = alc_fixup_disable_aamix,
4757 .chained = true,
4758 .chain_id = ALC269_FIXUP_SONY_VAIO
4759 },
4760 [ALC271_FIXUP_DMIC] = {
4761 .type = HDA_FIXUP_FUNC,
4762 .v.func = alc271_fixup_dmic,
4763 },
4764 [ALC269_FIXUP_PCM_44K] = {
4765 .type = HDA_FIXUP_FUNC,
4766 .v.func = alc269_fixup_pcm_44k,
4767 .chained = true,
4768 .chain_id = ALC269_FIXUP_QUANTA_MUTE
4769 },
4770 [ALC269_FIXUP_STEREO_DMIC] = {
4771 .type = HDA_FIXUP_FUNC,
4772 .v.func = alc269_fixup_stereo_dmic,
4773 },
4774 [ALC269_FIXUP_HEADSET_MIC] = {
4775 .type = HDA_FIXUP_FUNC,
4776 .v.func = alc269_fixup_headset_mic,
4777 },
4778 [ALC269_FIXUP_QUANTA_MUTE] = {
4779 .type = HDA_FIXUP_FUNC,
4780 .v.func = alc269_fixup_quanta_mute,
4781 },
4782 [ALC269_FIXUP_LIFEBOOK] = {
4783 .type = HDA_FIXUP_PINS,
4784 .v.pins = (const struct hda_pintbl[]) {
4785 { 0x1a, 0x2101103f }, /* dock line-out */
4786 { 0x1b, 0x23a11040 }, /* dock mic-in */
4787 { }
4788 },
4789 .chained = true,
4790 .chain_id = ALC269_FIXUP_QUANTA_MUTE
4791 },
4792 [ALC269_FIXUP_LIFEBOOK_EXTMIC] = {
4793 .type = HDA_FIXUP_PINS,
4794 .v.pins = (const struct hda_pintbl[]) {
4795 { 0x19, 0x01a1903c }, /* headset mic, with jack detect */
4796 { }
4797 },
4798 },
4799 [ALC269_FIXUP_LIFEBOOK_HP_PIN] = {
4800 .type = HDA_FIXUP_PINS,
4801 .v.pins = (const struct hda_pintbl[]) {
4802 { 0x21, 0x0221102f }, /* HP out */
4803 { }
4804 },
4805 },
4806 [ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT] = {
4807 .type = HDA_FIXUP_FUNC,
4808 .v.func = alc269_fixup_pincfg_no_hp_to_lineout,
4809 },
4810 [ALC269_FIXUP_AMIC] = {
4811 .type = HDA_FIXUP_PINS,
4812 .v.pins = (const struct hda_pintbl[]) {
4813 { 0x14, 0x99130110 }, /* speaker */
4814 { 0x15, 0x0121401f }, /* HP out */
4815 { 0x18, 0x01a19c20 }, /* mic */
4816 { 0x19, 0x99a3092f }, /* int-mic */
4817 { }
4818 },
4819 },
4820 [ALC269_FIXUP_DMIC] = {
4821 .type = HDA_FIXUP_PINS,
4822 .v.pins = (const struct hda_pintbl[]) {
4823 { 0x12, 0x99a3092f }, /* int-mic */
4824 { 0x14, 0x99130110 }, /* speaker */
4825 { 0x15, 0x0121401f }, /* HP out */
4826 { 0x18, 0x01a19c20 }, /* mic */
4827 { }
4828 },
4829 },
4830 [ALC269VB_FIXUP_AMIC] = {
4831 .type = HDA_FIXUP_PINS,
4832 .v.pins = (const struct hda_pintbl[]) {
4833 { 0x14, 0x99130110 }, /* speaker */
4834 { 0x18, 0x01a19c20 }, /* mic */
4835 { 0x19, 0x99a3092f }, /* int-mic */
4836 { 0x21, 0x0121401f }, /* HP out */
4837 { }
4838 },
4839 },
4840 [ALC269VB_FIXUP_DMIC] = {
4841 .type = HDA_FIXUP_PINS,
4842 .v.pins = (const struct hda_pintbl[]) {
4843 { 0x12, 0x99a3092f }, /* int-mic */
4844 { 0x14, 0x99130110 }, /* speaker */
4845 { 0x18, 0x01a19c20 }, /* mic */
4846 { 0x21, 0x0121401f }, /* HP out */
4847 { }
4848 },
4849 },
4850 [ALC269_FIXUP_HP_MUTE_LED] = {
4851 .type = HDA_FIXUP_FUNC,
4852 .v.func = alc269_fixup_hp_mute_led,
4853 },
4854 [ALC269_FIXUP_HP_MUTE_LED_MIC1] = {
4855 .type = HDA_FIXUP_FUNC,
4856 .v.func = alc269_fixup_hp_mute_led_mic1,
4857 },
4858 [ALC269_FIXUP_HP_MUTE_LED_MIC2] = {
4859 .type = HDA_FIXUP_FUNC,
4860 .v.func = alc269_fixup_hp_mute_led_mic2,
4861 },
4862 [ALC269_FIXUP_HP_GPIO_LED] = {
4863 .type = HDA_FIXUP_FUNC,
4864 .v.func = alc269_fixup_hp_gpio_led,
4865 },
4866 [ALC269_FIXUP_HP_GPIO_MIC1_LED] = {
4867 .type = HDA_FIXUP_FUNC,
4868 .v.func = alc269_fixup_hp_gpio_mic1_led,
4869 },
4870 [ALC269_FIXUP_HP_LINE1_MIC1_LED] = {
4871 .type = HDA_FIXUP_FUNC,
4872 .v.func = alc269_fixup_hp_line1_mic1_led,
4873 },
4874 [ALC269_FIXUP_INV_DMIC] = {
4875 .type = HDA_FIXUP_FUNC,
4876 .v.func = alc_fixup_inv_dmic,
4877 },
4878 [ALC269_FIXUP_NO_SHUTUP] = {
4879 .type = HDA_FIXUP_FUNC,
4880 .v.func = alc_fixup_no_shutup,
4881 },
4882 [ALC269_FIXUP_LENOVO_DOCK] = {
4883 .type = HDA_FIXUP_PINS,
4884 .v.pins = (const struct hda_pintbl[]) {
4885 { 0x19, 0x23a11040 }, /* dock mic */
4886 { 0x1b, 0x2121103f }, /* dock headphone */
4887 { }
4888 },
4889 .chained = true,
4890 .chain_id = ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT
4891 },
4892 [ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT] = {
4893 .type = HDA_FIXUP_FUNC,
4894 .v.func = alc269_fixup_pincfg_no_hp_to_lineout,
4895 .chained = true,
4896 .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
4897 },
4898 [ALC269_FIXUP_DELL1_MIC_NO_PRESENCE] = {
4899 .type = HDA_FIXUP_PINS,
4900 .v.pins = (const struct hda_pintbl[]) {
4901 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
4902 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
4903 { }
4904 },
4905 .chained = true,
4906 .chain_id = ALC269_FIXUP_HEADSET_MODE
4907 },
4908 [ALC269_FIXUP_DELL2_MIC_NO_PRESENCE] = {
4909 .type = HDA_FIXUP_PINS,
4910 .v.pins = (const struct hda_pintbl[]) {
4911 { 0x16, 0x21014020 }, /* dock line out */
4912 { 0x19, 0x21a19030 }, /* dock mic */
4913 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
4914 { }
4915 },
4916 .chained = true,
4917 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
4918 },
4919 [ALC269_FIXUP_DELL3_MIC_NO_PRESENCE] = {
4920 .type = HDA_FIXUP_PINS,
4921 .v.pins = (const struct hda_pintbl[]) {
4922 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
4923 { }
4924 },
4925 .chained = true,
4926 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
4927 },
4928 [ALC269_FIXUP_HEADSET_MODE] = {
4929 .type = HDA_FIXUP_FUNC,
4930 .v.func = alc_fixup_headset_mode,
4931 .chained = true,
4932 .chain_id = ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED
4933 },
4934 [ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC] = {
4935 .type = HDA_FIXUP_FUNC,
4936 .v.func = alc_fixup_headset_mode_no_hp_mic,
4937 },
4938 [ALC269_FIXUP_ASPIRE_HEADSET_MIC] = {
4939 .type = HDA_FIXUP_PINS,
4940 .v.pins = (const struct hda_pintbl[]) {
4941 { 0x19, 0x01a1913c }, /* headset mic w/o jack detect */
4942 { }
4943 },
4944 .chained = true,
4945 .chain_id = ALC269_FIXUP_HEADSET_MODE,
4946 },
4947 [ALC286_FIXUP_SONY_MIC_NO_PRESENCE] = {
4948 .type = HDA_FIXUP_PINS,
4949 .v.pins = (const struct hda_pintbl[]) {
4950 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
4951 { }
4952 },
4953 .chained = true,
4954 .chain_id = ALC269_FIXUP_HEADSET_MIC
4955 },
4956 [ALC269_FIXUP_ASUS_X101_FUNC] = {
4957 .type = HDA_FIXUP_FUNC,
4958 .v.func = alc269_fixup_x101_headset_mic,
4959 },
4960 [ALC269_FIXUP_ASUS_X101_VERB] = {
4961 .type = HDA_FIXUP_VERBS,
4962 .v.verbs = (const struct hda_verb[]) {
4963 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4964 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
4965 {0x20, AC_VERB_SET_PROC_COEF, 0x0310},
4966 { }
4967 },
4968 .chained = true,
4969 .chain_id = ALC269_FIXUP_ASUS_X101_FUNC
4970 },
4971 [ALC269_FIXUP_ASUS_X101] = {
4972 .type = HDA_FIXUP_PINS,
4973 .v.pins = (const struct hda_pintbl[]) {
4974 { 0x18, 0x04a1182c }, /* Headset mic */
4975 { }
4976 },
4977 .chained = true,
4978 .chain_id = ALC269_FIXUP_ASUS_X101_VERB
4979 },
4980 [ALC271_FIXUP_AMIC_MIC2] = {
4981 .type = HDA_FIXUP_PINS,
4982 .v.pins = (const struct hda_pintbl[]) {
4983 { 0x14, 0x99130110 }, /* speaker */
4984 { 0x19, 0x01a19c20 }, /* mic */
4985 { 0x1b, 0x99a7012f }, /* int-mic */
4986 { 0x21, 0x0121401f }, /* HP out */
4987 { }
4988 },
4989 },
4990 [ALC271_FIXUP_HP_GATE_MIC_JACK] = {
4991 .type = HDA_FIXUP_FUNC,
4992 .v.func = alc271_hp_gate_mic_jack,
4993 .chained = true,
4994 .chain_id = ALC271_FIXUP_AMIC_MIC2,
4995 },
4996 [ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572] = {
4997 .type = HDA_FIXUP_FUNC,
4998 .v.func = alc269_fixup_limit_int_mic_boost,
4999 .chained = true,
5000 .chain_id = ALC271_FIXUP_HP_GATE_MIC_JACK,
5001 },
5002 [ALC269_FIXUP_ACER_AC700] = {
5003 .type = HDA_FIXUP_PINS,
5004 .v.pins = (const struct hda_pintbl[]) {
5005 { 0x12, 0x99a3092f }, /* int-mic */
5006 { 0x14, 0x99130110 }, /* speaker */
5007 { 0x18, 0x03a11c20 }, /* mic */
5008 { 0x1e, 0x0346101e }, /* SPDIF1 */
5009 { 0x21, 0x0321101f }, /* HP out */
5010 { }
5011 },
5012 .chained = true,
5013 .chain_id = ALC271_FIXUP_DMIC,
5014 },
5015 [ALC269_FIXUP_LIMIT_INT_MIC_BOOST] = {
5016 .type = HDA_FIXUP_FUNC,
5017 .v.func = alc269_fixup_limit_int_mic_boost,
5018 .chained = true,
5019 .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
5020 },
5021 [ALC269VB_FIXUP_ASUS_ZENBOOK] = {
5022 .type = HDA_FIXUP_FUNC,
5023 .v.func = alc269_fixup_limit_int_mic_boost,
5024 .chained = true,
5025 .chain_id = ALC269VB_FIXUP_DMIC,
5026 },
5027 [ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A] = {
5028 .type = HDA_FIXUP_VERBS,
5029 .v.verbs = (const struct hda_verb[]) {
5030 /* class-D output amp +5dB */
5031 { 0x20, AC_VERB_SET_COEF_INDEX, 0x12 },
5032 { 0x20, AC_VERB_SET_PROC_COEF, 0x2800 },
5033 {}
5034 },
5035 .chained = true,
5036 .chain_id = ALC269VB_FIXUP_ASUS_ZENBOOK,
5037 },
5038 [ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED] = {
5039 .type = HDA_FIXUP_FUNC,
5040 .v.func = alc269_fixup_limit_int_mic_boost,
5041 .chained = true,
5042 .chain_id = ALC269_FIXUP_HP_MUTE_LED_MIC1,
5043 },
5044 [ALC269VB_FIXUP_ORDISSIMO_EVE2] = {
5045 .type = HDA_FIXUP_PINS,
5046 .v.pins = (const struct hda_pintbl[]) {
5047 { 0x12, 0x99a3092f }, /* int-mic */
5048 { 0x18, 0x03a11d20 }, /* mic */
5049 { 0x19, 0x411111f0 }, /* Unused bogus pin */
5050 { }
5051 },
5052 },
5053 [ALC283_FIXUP_CHROME_BOOK] = {
5054 .type = HDA_FIXUP_FUNC,
5055 .v.func = alc283_fixup_chromebook,
5056 },
5057 [ALC283_FIXUP_SENSE_COMBO_JACK] = {
5058 .type = HDA_FIXUP_FUNC,
5059 .v.func = alc283_fixup_sense_combo_jack,
5060 .chained = true,
5061 .chain_id = ALC283_FIXUP_CHROME_BOOK,
5062 },
5063 [ALC282_FIXUP_ASUS_TX300] = {
5064 .type = HDA_FIXUP_FUNC,
5065 .v.func = alc282_fixup_asus_tx300,
5066 },
5067 [ALC283_FIXUP_INT_MIC] = {
5068 .type = HDA_FIXUP_VERBS,
5069 .v.verbs = (const struct hda_verb[]) {
5070 {0x20, AC_VERB_SET_COEF_INDEX, 0x1a},
5071 {0x20, AC_VERB_SET_PROC_COEF, 0x0011},
5072 { }
5073 },
5074 .chained = true,
5075 .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST
5076 },
5077 [ALC290_FIXUP_SUBWOOFER_HSJACK] = {
5078 .type = HDA_FIXUP_PINS,
5079 .v.pins = (const struct hda_pintbl[]) {
5080 { 0x17, 0x90170112 }, /* subwoofer */
5081 { }
5082 },
5083 .chained = true,
5084 .chain_id = ALC290_FIXUP_MONO_SPEAKERS_HSJACK,
5085 },
5086 [ALC290_FIXUP_SUBWOOFER] = {
5087 .type = HDA_FIXUP_PINS,
5088 .v.pins = (const struct hda_pintbl[]) {
5089 { 0x17, 0x90170112 }, /* subwoofer */
5090 { }
5091 },
5092 .chained = true,
5093 .chain_id = ALC290_FIXUP_MONO_SPEAKERS,
5094 },
5095 [ALC290_FIXUP_MONO_SPEAKERS] = {
5096 .type = HDA_FIXUP_FUNC,
5097 .v.func = alc290_fixup_mono_speakers,
5098 },
5099 [ALC290_FIXUP_MONO_SPEAKERS_HSJACK] = {
5100 .type = HDA_FIXUP_FUNC,
5101 .v.func = alc290_fixup_mono_speakers,
5102 .chained = true,
5103 .chain_id = ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
5104 },
5105 [ALC269_FIXUP_THINKPAD_ACPI] = {
5106 .type = HDA_FIXUP_FUNC,
5107 .v.func = hda_fixup_thinkpad_acpi,
5108 },
5109 [ALC269_FIXUP_DMIC_THINKPAD_ACPI] = {
5110 .type = HDA_FIXUP_FUNC,
5111 .v.func = alc_fixup_inv_dmic,
5112 .chained = true,
5113 .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
5114 },
5115 [ALC255_FIXUP_DELL1_MIC_NO_PRESENCE] = {
5116 .type = HDA_FIXUP_PINS,
5117 .v.pins = (const struct hda_pintbl[]) {
5118 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5119 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
5120 { }
5121 },
5122 .chained = true,
5123 .chain_id = ALC255_FIXUP_HEADSET_MODE
5124 },
5125 [ALC255_FIXUP_DELL2_MIC_NO_PRESENCE] = {
5126 .type = HDA_FIXUP_PINS,
5127 .v.pins = (const struct hda_pintbl[]) {
5128 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5129 { }
5130 },
5131 .chained = true,
5132 .chain_id = ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC
5133 },
5134 [ALC255_FIXUP_HEADSET_MODE] = {
5135 .type = HDA_FIXUP_FUNC,
5136 .v.func = alc_fixup_headset_mode_alc255,
5137 .chained = true,
5138 .chain_id = ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED
5139 },
5140 [ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC] = {
5141 .type = HDA_FIXUP_FUNC,
5142 .v.func = alc_fixup_headset_mode_alc255_no_hp_mic,
5143 },
5144 [ALC293_FIXUP_DELL1_MIC_NO_PRESENCE] = {
5145 .type = HDA_FIXUP_PINS,
5146 .v.pins = (const struct hda_pintbl[]) {
5147 { 0x18, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
5148 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5149 { }
5150 },
5151 .chained = true,
5152 .chain_id = ALC269_FIXUP_HEADSET_MODE
5153 },
5154 [ALC292_FIXUP_TPT440_DOCK] = {
5155 .type = HDA_FIXUP_FUNC,
5156 .v.func = alc269_fixup_pincfg_no_hp_to_lineout,
5157 .chained = true,
5158 .chain_id = ALC292_FIXUP_TPT440_DOCK2
5159 },
5160 [ALC292_FIXUP_TPT440_DOCK2] = {
5161 .type = HDA_FIXUP_PINS,
5162 .v.pins = (const struct hda_pintbl[]) {
5163 { 0x16, 0x21211010 }, /* dock headphone */
5164 { 0x19, 0x21a11010 }, /* dock mic */
5165 { }
5166 },
5167 .chained = true,
5168 .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST
5169 },
5170 [ALC283_FIXUP_BXBT2807_MIC] = {
5171 .type = HDA_FIXUP_PINS,
5172 .v.pins = (const struct hda_pintbl[]) {
5173 { 0x19, 0x04a110f0 },
5174 { },
5175 },
5176 },
5177 [ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED] = {
5178 .type = HDA_FIXUP_FUNC,
5179 .v.func = alc_fixup_dell_wmi,
5180 },
5181 [ALC282_FIXUP_ASPIRE_V5_PINS] = {
5182 .type = HDA_FIXUP_PINS,
5183 .v.pins = (const struct hda_pintbl[]) {
5184 { 0x12, 0x90a60130 },
5185 { 0x14, 0x90170110 },
5186 { 0x17, 0x40000008 },
5187 { 0x18, 0x411111f0 },
5188 { 0x19, 0x411111f0 },
5189 { 0x1a, 0x411111f0 },
5190 { 0x1b, 0x411111f0 },
5191 { 0x1d, 0x40f89b2d },
5192 { 0x1e, 0x411111f0 },
5193 { 0x21, 0x0321101f },
5194 { },
5195 },
5196 },
5197 [ALC280_FIXUP_HP_GPIO4] = {
5198 .type = HDA_FIXUP_FUNC,
5199 .v.func = alc280_fixup_hp_gpio4,
5200 },
5201 [ALC286_FIXUP_HP_GPIO_LED] = {
5202 .type = HDA_FIXUP_FUNC,
5203 .v.func = alc286_fixup_hp_gpio_led,
5204 },
5205 [ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY] = {
5206 .type = HDA_FIXUP_FUNC,
5207 .v.func = alc280_fixup_hp_gpio2_mic_hotkey,
5208 },
5209 [ALC280_FIXUP_HP_DOCK_PINS] = {
5210 .type = HDA_FIXUP_PINS,
5211 .v.pins = (const struct hda_pintbl[]) {
5212 { 0x1b, 0x21011020 }, /* line-out */
5213 { 0x1a, 0x01a1903c }, /* headset mic */
5214 { 0x18, 0x2181103f }, /* line-in */
5215 { },
5216 },
5217 .chained = true,
5218 .chain_id = ALC280_FIXUP_HP_GPIO4
5219 },
5220 [ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED] = {
5221 .type = HDA_FIXUP_PINS,
5222 .v.pins = (const struct hda_pintbl[]) {
5223 { 0x1b, 0x21011020 }, /* line-out */
5224 { 0x18, 0x2181103f }, /* line-in */
5225 { },
5226 },
5227 .chained = true,
5228 .chain_id = ALC269_FIXUP_HP_GPIO_MIC1_LED
5229 },
5230 [ALC280_FIXUP_HP_9480M] = {
5231 .type = HDA_FIXUP_FUNC,
5232 .v.func = alc280_fixup_hp_9480m,
5233 },
5234 [ALC288_FIXUP_DELL_HEADSET_MODE] = {
5235 .type = HDA_FIXUP_FUNC,
5236 .v.func = alc_fixup_headset_mode_dell_alc288,
5237 .chained = true,
5238 .chain_id = ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED
5239 },
5240 [ALC288_FIXUP_DELL1_MIC_NO_PRESENCE] = {
5241 .type = HDA_FIXUP_PINS,
5242 .v.pins = (const struct hda_pintbl[]) {
5243 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5244 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
5245 { }
5246 },
5247 .chained = true,
5248 .chain_id = ALC288_FIXUP_DELL_HEADSET_MODE
5249 },
5250 [ALC288_FIXUP_DELL_XPS_13_GPIO6] = {
5251 .type = HDA_FIXUP_VERBS,
5252 .v.verbs = (const struct hda_verb[]) {
5253 {0x01, AC_VERB_SET_GPIO_MASK, 0x40},
5254 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x40},
5255 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5256 { }
5257 },
5258 .chained = true,
5259 .chain_id = ALC288_FIXUP_DELL1_MIC_NO_PRESENCE
5260 },
5261 [ALC298_FIXUP_DELL1_MIC_NO_PRESENCE] = {
5262 .type = HDA_FIXUP_PINS,
5263 .v.pins = (const struct hda_pintbl[]) {
5264 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5265 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
5266 { }
5267 },
5268 .chained = true,
5269 .chain_id = ALC269_FIXUP_HEADSET_MODE
5270 },
5271 [ALC275_FIXUP_DELL_XPS] = {
5272 .type = HDA_FIXUP_VERBS,
5273 .v.verbs = (const struct hda_verb[]) {
5274 /* Enables internal speaker */
5275 {0x20, AC_VERB_SET_COEF_INDEX, 0x1f},
5276 {0x20, AC_VERB_SET_PROC_COEF, 0x00c0},
5277 {0x20, AC_VERB_SET_COEF_INDEX, 0x30},
5278 {0x20, AC_VERB_SET_PROC_COEF, 0x00b1},
5279 {}
5280 }
5281 },
5282 [ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE] = {
5283 .type = HDA_FIXUP_VERBS,
5284 .v.verbs = (const struct hda_verb[]) {
5285 /* Disable pass-through path for FRONT 14h */
5286 {0x20, AC_VERB_SET_COEF_INDEX, 0x36},
5287 {0x20, AC_VERB_SET_PROC_COEF, 0x1737},
5288 {}
5289 },
5290 .chained = true,
5291 .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
5292 },
5293 [ALC293_FIXUP_LENOVO_SPK_NOISE] = {
5294 .type = HDA_FIXUP_FUNC,
5295 .v.func = alc_fixup_disable_aamix,
5296 .chained = true,
5297 .chain_id = ALC269_FIXUP_THINKPAD_ACPI
5298 },
5299 [ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY] = {
5300 .type = HDA_FIXUP_FUNC,
5301 .v.func = alc233_fixup_lenovo_line2_mic_hotkey,
5302 },
5303 [ALC255_FIXUP_DELL_SPK_NOISE] = {
5304 .type = HDA_FIXUP_FUNC,
5305 .v.func = alc_fixup_disable_aamix,
5306 .chained = true,
5307 .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
5308 },
5309 [ALC225_FIXUP_DELL1_MIC_NO_PRESENCE] = {
5310 .type = HDA_FIXUP_VERBS,
5311 .v.verbs = (const struct hda_verb[]) {
5312 /* Disable pass-through path for FRONT 14h */
5313 { 0x20, AC_VERB_SET_COEF_INDEX, 0x36 },
5314 { 0x20, AC_VERB_SET_PROC_COEF, 0x57d7 },
5315 {}
5316 },
5317 .chained = true,
5318 .chain_id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE
5319 },
5320 [ALC280_FIXUP_HP_HEADSET_MIC] = {
5321 .type = HDA_FIXUP_FUNC,
5322 .v.func = alc_fixup_disable_aamix,
5323 .chained = true,
5324 .chain_id = ALC269_FIXUP_HEADSET_MIC,
5325 },
5326 [ALC221_FIXUP_HP_FRONT_MIC] = {
5327 .type = HDA_FIXUP_PINS,
5328 .v.pins = (const struct hda_pintbl[]) {
5329 { 0x19, 0x02a19020 }, /* Front Mic */
5330 { }
5331 },
5332 },
5333 };
5334
5335 static const struct snd_pci_quirk alc269_fixup_tbl[] = {
5336 SND_PCI_QUIRK(0x1025, 0x0283, "Acer TravelMate 8371", ALC269_FIXUP_INV_DMIC),
5337 SND_PCI_QUIRK(0x1025, 0x029b, "Acer 1810TZ", ALC269_FIXUP_INV_DMIC),
5338 SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC),
5339 SND_PCI_QUIRK(0x1025, 0x047c, "Acer AC700", ALC269_FIXUP_ACER_AC700),
5340 SND_PCI_QUIRK(0x1025, 0x072d, "Acer Aspire V5-571G", ALC269_FIXUP_ASPIRE_HEADSET_MIC),
5341 SND_PCI_QUIRK(0x1025, 0x080d, "Acer Aspire V5-122P", ALC269_FIXUP_ASPIRE_HEADSET_MIC),
5342 SND_PCI_QUIRK(0x1025, 0x0740, "Acer AO725", ALC271_FIXUP_HP_GATE_MIC_JACK),
5343 SND_PCI_QUIRK(0x1025, 0x0742, "Acer AO756", ALC271_FIXUP_HP_GATE_MIC_JACK),
5344 SND_PCI_QUIRK(0x1025, 0x0762, "Acer Aspire E1-472", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572),
5345 SND_PCI_QUIRK(0x1025, 0x0775, "Acer Aspire E1-572", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572),
5346 SND_PCI_QUIRK(0x1025, 0x079b, "Acer Aspire V5-573G", ALC282_FIXUP_ASPIRE_V5_PINS),
5347 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
5348 SND_PCI_QUIRK(0x1028, 0x054b, "Dell XPS one 2710", ALC275_FIXUP_DELL_XPS),
5349 SND_PCI_QUIRK(0x1028, 0x05da, "Dell Vostro 5460", ALC290_FIXUP_SUBWOOFER),
5350 SND_PCI_QUIRK(0x1028, 0x05f4, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
5351 SND_PCI_QUIRK(0x1028, 0x05f5, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
5352 SND_PCI_QUIRK(0x1028, 0x05f6, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
5353 SND_PCI_QUIRK(0x1028, 0x0615, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK),
5354 SND_PCI_QUIRK(0x1028, 0x0616, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK),
5355 SND_PCI_QUIRK(0x1028, 0x0638, "Dell Inspiron 5439", ALC290_FIXUP_MONO_SPEAKERS_HSJACK),
5356 SND_PCI_QUIRK(0x1028, 0x064a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
5357 SND_PCI_QUIRK(0x1028, 0x064b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
5358 SND_PCI_QUIRK(0x1028, 0x06c7, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
5359 SND_PCI_QUIRK(0x1028, 0x06d9, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
5360 SND_PCI_QUIRK(0x1028, 0x06da, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
5361 SND_PCI_QUIRK(0x1028, 0x0704, "Dell XPS 13", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE),
5362 SND_PCI_QUIRK(0x1028, 0x0725, "Dell Inspiron 3162", ALC255_FIXUP_DELL_SPK_NOISE),
5363 SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
5364 SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
5365 SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
5366 SND_PCI_QUIRK(0x103c, 0x18e6, "HP", ALC269_FIXUP_HP_GPIO_LED),
5367 SND_PCI_QUIRK(0x103c, 0x218b, "HP", ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED),
5368 SND_PCI_QUIRK(0x103c, 0x225f, "HP", ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY),
5369 /* ALC282 */
5370 SND_PCI_QUIRK(0x103c, 0x21f9, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5371 SND_PCI_QUIRK(0x103c, 0x2210, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5372 SND_PCI_QUIRK(0x103c, 0x2214, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5373 SND_PCI_QUIRK(0x103c, 0x2236, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
5374 SND_PCI_QUIRK(0x103c, 0x2237, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
5375 SND_PCI_QUIRK(0x103c, 0x2238, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
5376 SND_PCI_QUIRK(0x103c, 0x2239, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
5377 SND_PCI_QUIRK(0x103c, 0x224b, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
5378 SND_PCI_QUIRK(0x103c, 0x2268, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5379 SND_PCI_QUIRK(0x103c, 0x226a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5380 SND_PCI_QUIRK(0x103c, 0x226b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5381 SND_PCI_QUIRK(0x103c, 0x226e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5382 SND_PCI_QUIRK(0x103c, 0x2271, "HP", ALC286_FIXUP_HP_GPIO_LED),
5383 SND_PCI_QUIRK(0x103c, 0x2272, "HP", ALC280_FIXUP_HP_DOCK_PINS),
5384 SND_PCI_QUIRK(0x103c, 0x229e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5385 SND_PCI_QUIRK(0x103c, 0x22b2, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5386 SND_PCI_QUIRK(0x103c, 0x22b7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5387 SND_PCI_QUIRK(0x103c, 0x22bf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5388 SND_PCI_QUIRK(0x103c, 0x22cf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5389 SND_PCI_QUIRK(0x103c, 0x22db, "HP", ALC280_FIXUP_HP_9480M),
5390 SND_PCI_QUIRK(0x103c, 0x22dc, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5391 SND_PCI_QUIRK(0x103c, 0x22fb, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5392 /* ALC290 */
5393 SND_PCI_QUIRK(0x103c, 0x221b, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5394 SND_PCI_QUIRK(0x103c, 0x2221, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5395 SND_PCI_QUIRK(0x103c, 0x2225, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5396 SND_PCI_QUIRK(0x103c, 0x2253, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5397 SND_PCI_QUIRK(0x103c, 0x2254, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5398 SND_PCI_QUIRK(0x103c, 0x2255, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5399 SND_PCI_QUIRK(0x103c, 0x2256, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5400 SND_PCI_QUIRK(0x103c, 0x2257, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5401 SND_PCI_QUIRK(0x103c, 0x2259, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5402 SND_PCI_QUIRK(0x103c, 0x225a, "HP", ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED),
5403 SND_PCI_QUIRK(0x103c, 0x2260, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5404 SND_PCI_QUIRK(0x103c, 0x2263, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5405 SND_PCI_QUIRK(0x103c, 0x2264, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5406 SND_PCI_QUIRK(0x103c, 0x2265, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5407 SND_PCI_QUIRK(0x103c, 0x2272, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5408 SND_PCI_QUIRK(0x103c, 0x2273, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5409 SND_PCI_QUIRK(0x103c, 0x2278, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5410 SND_PCI_QUIRK(0x103c, 0x227f, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5411 SND_PCI_QUIRK(0x103c, 0x2282, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5412 SND_PCI_QUIRK(0x103c, 0x228b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5413 SND_PCI_QUIRK(0x103c, 0x228e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5414 SND_PCI_QUIRK(0x103c, 0x22c5, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5415 SND_PCI_QUIRK(0x103c, 0x22c7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5416 SND_PCI_QUIRK(0x103c, 0x22c8, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5417 SND_PCI_QUIRK(0x103c, 0x22c4, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5418 SND_PCI_QUIRK(0x103c, 0x2334, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5419 SND_PCI_QUIRK(0x103c, 0x2335, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5420 SND_PCI_QUIRK(0x103c, 0x2336, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5421 SND_PCI_QUIRK(0x103c, 0x2337, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5422 SND_PCI_QUIRK(0x103c, 0x221c, "HP EliteBook 755 G2", ALC280_FIXUP_HP_HEADSET_MIC),
5423 SND_PCI_QUIRK(0x103c, 0x8256, "HP", ALC221_FIXUP_HP_FRONT_MIC),
5424 SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300),
5425 SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
5426 SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
5427 SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK),
5428 SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A),
5429 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC),
5430 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
5431 SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC),
5432 SND_PCI_QUIRK(0x1043, 0x1c23, "Asus X55U", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
5433 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC),
5434 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC),
5435 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
5436 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
5437 SND_PCI_QUIRK(0x1043, 0x8516, "ASUS X101CH", ALC269_FIXUP_ASUS_X101),
5438 SND_PCI_QUIRK(0x104d, 0x90b5, "Sony VAIO Pro 11", ALC286_FIXUP_SONY_MIC_NO_PRESENCE),
5439 SND_PCI_QUIRK(0x104d, 0x90b6, "Sony VAIO Pro 13", ALC286_FIXUP_SONY_MIC_NO_PRESENCE),
5440 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
5441 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
5442 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
5443 SND_PCI_QUIRK(0x104d, 0x9099, "Sony VAIO S13", ALC275_FIXUP_SONY_DISABLE_AAMIX),
5444 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook", ALC269_FIXUP_LIFEBOOK),
5445 SND_PCI_QUIRK(0x10cf, 0x159f, "Lifebook E780", ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT),
5446 SND_PCI_QUIRK(0x10cf, 0x15dc, "Lifebook T731", ALC269_FIXUP_LIFEBOOK_HP_PIN),
5447 SND_PCI_QUIRK(0x10cf, 0x1757, "Lifebook E752", ALC269_FIXUP_LIFEBOOK_HP_PIN),
5448 SND_PCI_QUIRK(0x10cf, 0x1845, "Lifebook U904", ALC269_FIXUP_LIFEBOOK_EXTMIC),
5449 SND_PCI_QUIRK(0x144d, 0xc109, "Samsung Ativ book 9 (NP900X3G)", ALC269_FIXUP_INV_DMIC),
5450 SND_PCI_QUIRK(0x1458, 0xfa53, "Gigabyte BXBT-2807", ALC283_FIXUP_BXBT2807_MIC),
5451 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
5452 SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
5453 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
5454 SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
5455 SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
5456 SND_PCI_QUIRK(0x17aa, 0x21f6, "Thinkpad T530", ALC269_FIXUP_LENOVO_DOCK),
5457 SND_PCI_QUIRK(0x17aa, 0x21fa, "Thinkpad X230", ALC269_FIXUP_LENOVO_DOCK),
5458 SND_PCI_QUIRK(0x17aa, 0x21f3, "Thinkpad T430", ALC269_FIXUP_LENOVO_DOCK),
5459 SND_PCI_QUIRK(0x17aa, 0x21fb, "Thinkpad T430s", ALC269_FIXUP_LENOVO_DOCK),
5460 SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK),
5461 SND_PCI_QUIRK(0x17aa, 0x2208, "Thinkpad T431s", ALC269_FIXUP_LENOVO_DOCK),
5462 SND_PCI_QUIRK(0x17aa, 0x220c, "Thinkpad T440s", ALC292_FIXUP_TPT440_DOCK),
5463 SND_PCI_QUIRK(0x17aa, 0x220e, "Thinkpad T440p", ALC292_FIXUP_TPT440_DOCK),
5464 SND_PCI_QUIRK(0x17aa, 0x2210, "Thinkpad T540p", ALC292_FIXUP_TPT440_DOCK),
5465 SND_PCI_QUIRK(0x17aa, 0x2212, "Thinkpad T440", ALC292_FIXUP_TPT440_DOCK),
5466 SND_PCI_QUIRK(0x17aa, 0x2214, "Thinkpad X240", ALC292_FIXUP_TPT440_DOCK),
5467 SND_PCI_QUIRK(0x17aa, 0x2215, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
5468 SND_PCI_QUIRK(0x17aa, 0x2223, "ThinkPad T550", ALC292_FIXUP_TPT440_DOCK),
5469 SND_PCI_QUIRK(0x17aa, 0x2226, "ThinkPad X250", ALC292_FIXUP_TPT440_DOCK),
5470 SND_PCI_QUIRK(0x17aa, 0x2233, "Thinkpad", ALC293_FIXUP_LENOVO_SPK_NOISE),
5471 SND_PCI_QUIRK(0x17aa, 0x30bb, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
5472 SND_PCI_QUIRK(0x17aa, 0x30e2, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
5473 SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
5474 SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC),
5475 SND_PCI_QUIRK(0x17aa, 0x3978, "IdeaPad Y410P", ALC269_FIXUP_NO_SHUTUP),
5476 SND_PCI_QUIRK(0x17aa, 0x5013, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
5477 SND_PCI_QUIRK(0x17aa, 0x501a, "Thinkpad", ALC283_FIXUP_INT_MIC),
5478 SND_PCI_QUIRK(0x17aa, 0x501e, "Thinkpad L440", ALC292_FIXUP_TPT440_DOCK),
5479 SND_PCI_QUIRK(0x17aa, 0x5026, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
5480 SND_PCI_QUIRK(0x17aa, 0x5034, "Thinkpad T450", ALC292_FIXUP_TPT440_DOCK),
5481 SND_PCI_QUIRK(0x17aa, 0x5036, "Thinkpad T450s", ALC292_FIXUP_TPT440_DOCK),
5482 SND_PCI_QUIRK(0x17aa, 0x503c, "Thinkpad L450", ALC292_FIXUP_TPT440_DOCK),
5483 SND_PCI_QUIRK(0x17aa, 0x504a, "ThinkPad X260", ALC292_FIXUP_TPT440_DOCK),
5484 SND_PCI_QUIRK(0x17aa, 0x504b, "Thinkpad", ALC293_FIXUP_LENOVO_SPK_NOISE),
5485 SND_PCI_QUIRK(0x17aa, 0x5109, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
5486 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K),
5487 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
5488 SND_PCI_QUIRK(0x1b7d, 0xa831, "Ordissimo EVE2 ", ALC269VB_FIXUP_ORDISSIMO_EVE2), /* Also known as Malata PC-B1303 */
5489
5490 #if 0
5491 /* Below is a quirk table taken from the old code.
5492 * Basically the device should work as is without the fixup table.
5493 * If BIOS doesn't give a proper info, enable the corresponding
5494 * fixup entry.
5495 */
5496 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
5497 ALC269_FIXUP_AMIC),
5498 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269_FIXUP_AMIC),
5499 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269_FIXUP_AMIC),
5500 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_FIXUP_AMIC),
5501 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269_FIXUP_AMIC),
5502 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269_FIXUP_AMIC),
5503 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269_FIXUP_AMIC),
5504 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269_FIXUP_AMIC),
5505 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_FIXUP_AMIC),
5506 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269_FIXUP_AMIC),
5507 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_FIXUP_AMIC),
5508 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_FIXUP_AMIC),
5509 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_FIXUP_AMIC),
5510 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_FIXUP_AMIC),
5511 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_FIXUP_AMIC),
5512 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_FIXUP_AMIC),
5513 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_FIXUP_AMIC),
5514 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_FIXUP_AMIC),
5515 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_FIXUP_AMIC),
5516 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_FIXUP_AMIC),
5517 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_FIXUP_AMIC),
5518 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_FIXUP_AMIC),
5519 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_FIXUP_AMIC),
5520 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_FIXUP_AMIC),
5521 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_FIXUP_AMIC),
5522 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_FIXUP_AMIC),
5523 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_FIXUP_AMIC),
5524 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_FIXUP_AMIC),
5525 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_FIXUP_AMIC),
5526 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_FIXUP_AMIC),
5527 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_FIXUP_AMIC),
5528 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_FIXUP_AMIC),
5529 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_FIXUP_AMIC),
5530 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_FIXUP_AMIC),
5531 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_FIXUP_AMIC),
5532 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_FIXUP_DMIC),
5533 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_FIXUP_AMIC),
5534 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_AMIC),
5535 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_FIXUP_DMIC),
5536 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_FIXUP_DMIC),
5537 #endif
5538 {}
5539 };
5540
5541 static const struct snd_pci_quirk alc269_fixup_vendor_tbl[] = {
5542 SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC),
5543 SND_PCI_QUIRK_VENDOR(0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED),
5544 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
5545 SND_PCI_QUIRK_VENDOR(0x17aa, "Thinkpad", ALC269_FIXUP_THINKPAD_ACPI),
5546 {}
5547 };
5548
5549 static const struct hda_model_fixup alc269_fixup_models[] = {
5550 {.id = ALC269_FIXUP_AMIC, .name = "laptop-amic"},
5551 {.id = ALC269_FIXUP_DMIC, .name = "laptop-dmic"},
5552 {.id = ALC269_FIXUP_STEREO_DMIC, .name = "alc269-dmic"},
5553 {.id = ALC271_FIXUP_DMIC, .name = "alc271-dmic"},
5554 {.id = ALC269_FIXUP_INV_DMIC, .name = "inv-dmic"},
5555 {.id = ALC269_FIXUP_HEADSET_MIC, .name = "headset-mic"},
5556 {.id = ALC269_FIXUP_LENOVO_DOCK, .name = "lenovo-dock"},
5557 {.id = ALC269_FIXUP_HP_GPIO_LED, .name = "hp-gpio-led"},
5558 {.id = ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED, .name = "hp-dock-gpio-mic1-led"},
5559 {.id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "dell-headset-multi"},
5560 {.id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE, .name = "dell-headset-dock"},
5561 {.id = ALC283_FIXUP_CHROME_BOOK, .name = "alc283-dac-wcaps"},
5562 {.id = ALC283_FIXUP_SENSE_COMBO_JACK, .name = "alc283-sense-combo"},
5563 {.id = ALC292_FIXUP_TPT440_DOCK, .name = "tpt440-dock"},
5564 {}
5565 };
5566 #define ALC225_STANDARD_PINS \
5567 {0x21, 0x04211020}
5568
5569 #define ALC255_STANDARD_PINS \
5570 {0x18, 0x411111f0}, \
5571 {0x19, 0x411111f0}, \
5572 {0x1a, 0x411111f0}, \
5573 {0x1b, 0x411111f0}, \
5574 {0x1e, 0x411111f0}
5575
5576 #define ALC256_STANDARD_PINS \
5577 {0x12, 0x90a60140}, \
5578 {0x14, 0x90170110}, \
5579 {0x19, 0x411111f0}, \
5580 {0x1a, 0x411111f0}, \
5581 {0x1b, 0x411111f0}, \
5582 {0x1d, 0x40700001}, \
5583 {0x1e, 0x411111f0}, \
5584 {0x21, 0x02211020}
5585
5586 #define ALC282_STANDARD_PINS \
5587 {0x14, 0x90170110}, \
5588 {0x18, 0x411111f0}, \
5589 {0x1a, 0x411111f0}, \
5590 {0x1b, 0x411111f0}, \
5591 {0x1e, 0x411111f0}
5592
5593 #define ALC288_STANDARD_PINS \
5594 {0x17, 0x411111f0}, \
5595 {0x18, 0x411111f0}, \
5596 {0x19, 0x411111f0}, \
5597 {0x1a, 0x411111f0}, \
5598 {0x1e, 0x411111f0}
5599
5600 #define ALC290_STANDARD_PINS \
5601 {0x12, 0x99a30130}, \
5602 {0x13, 0x40000000}, \
5603 {0x16, 0x411111f0}, \
5604 {0x17, 0x411111f0}, \
5605 {0x19, 0x411111f0}, \
5606 {0x1b, 0x411111f0}, \
5607 {0x1e, 0x411111f0}
5608
5609 #define ALC292_STANDARD_PINS \
5610 {0x14, 0x90170110}, \
5611 {0x15, 0x0221401f}, \
5612 {0x1a, 0x411111f0}, \
5613 {0x1b, 0x411111f0}, \
5614 {0x1d, 0x40700001}
5615
5616 #define ALC298_STANDARD_PINS \
5617 {0x18, 0x411111f0}, \
5618 {0x19, 0x411111f0}, \
5619 {0x1a, 0x411111f0}, \
5620 {0x1e, 0x411111f0}, \
5621 {0x1f, 0x411111f0}
5622
5623 static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
5624 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
5625 ALC225_STANDARD_PINS,
5626 {0x14, 0x901701a0}),
5627 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
5628 ALC225_STANDARD_PINS,
5629 {0x14, 0x901701b0}),
5630 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
5631 ALC225_STANDARD_PINS,
5632 {0x12, 0xb7a60130},
5633 {0x14, 0x901701a0}),
5634 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
5635 ALC225_STANDARD_PINS,
5636 {0x12, 0xb7a60130},
5637 {0x14, 0x901701b0}),
5638 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
5639 ALC225_STANDARD_PINS,
5640 {0x12, 0xb7a60150},
5641 {0x14, 0x901701a0}),
5642 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
5643 ALC225_STANDARD_PINS,
5644 {0x12, 0xb7a60150},
5645 {0x14, 0x901701b0}),
5646 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
5647 ALC225_STANDARD_PINS,
5648 {0x12, 0xb7a60130},
5649 {0x1b, 0x90170110}),
5650 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE,
5651 ALC255_STANDARD_PINS,
5652 {0x12, 0x40300000},
5653 {0x14, 0x90170110},
5654 {0x17, 0x411111f0},
5655 {0x1d, 0x40538029},
5656 {0x21, 0x02211020}),
5657 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
5658 ALC255_STANDARD_PINS,
5659 {0x12, 0x90a60140},
5660 {0x14, 0x90170110},
5661 {0x17, 0x40000000},
5662 {0x1d, 0x40700001},
5663 {0x21, 0x02211020}),
5664 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
5665 ALC255_STANDARD_PINS,
5666 {0x12, 0x90a60160},
5667 {0x14, 0x90170120},
5668 {0x17, 0x40000000},
5669 {0x1d, 0x40700001},
5670 {0x21, 0x02211030}),
5671 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
5672 {0x12, 0x90a60160},
5673 {0x14, 0x90170120},
5674 {0x17, 0x90170140},
5675 {0x18, 0x40000000},
5676 {0x19, 0x411111f0},
5677 {0x1a, 0x411111f0},
5678 {0x1b, 0x411111f0},
5679 {0x1d, 0x41163b05},
5680 {0x1e, 0x411111f0},
5681 {0x21, 0x0321102f}),
5682 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
5683 ALC255_STANDARD_PINS,
5684 {0x12, 0x90a60160},
5685 {0x14, 0x90170130},
5686 {0x17, 0x40000000},
5687 {0x1d, 0x40700001},
5688 {0x21, 0x02211040}),
5689 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
5690 ALC255_STANDARD_PINS,
5691 {0x12, 0x90a60160},
5692 {0x14, 0x90170140},
5693 {0x17, 0x40000000},
5694 {0x1d, 0x40700001},
5695 {0x21, 0x02211050}),
5696 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
5697 ALC255_STANDARD_PINS,
5698 {0x12, 0x90a60170},
5699 {0x14, 0x90170120},
5700 {0x17, 0x40000000},
5701 {0x1d, 0x40700001},
5702 {0x21, 0x02211030}),
5703 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
5704 ALC255_STANDARD_PINS,
5705 {0x12, 0x90a60170},
5706 {0x14, 0x90170130},
5707 {0x17, 0x40000000},
5708 {0x1d, 0x40700001},
5709 {0x21, 0x02211040}),
5710 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
5711 ALC255_STANDARD_PINS,
5712 {0x12, 0x90a60170},
5713 {0x14, 0x90170140},
5714 {0x17, 0x40000000},
5715 {0x1d, 0x40700001},
5716 {0x21, 0x02211050}),
5717 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell Inspiron 5548", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
5718 ALC255_STANDARD_PINS,
5719 {0x12, 0x90a60180},
5720 {0x14, 0x90170130},
5721 {0x17, 0x40000000},
5722 {0x1d, 0x40700001},
5723 {0x21, 0x02211040}),
5724 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell Inspiron 5565", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
5725 {0x12, 0x90a60180},
5726 {0x14, 0x90170120},
5727 {0x21, 0x02211030}),
5728 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
5729 {0x1b, 0x01011020},
5730 {0x21, 0x02211010}),
5731 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
5732 ALC256_STANDARD_PINS,
5733 {0x13, 0x40000000}),
5734 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
5735 ALC256_STANDARD_PINS,
5736 {0x13, 0x411111f0}),
5737 SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC280_FIXUP_HP_GPIO4,
5738 {0x12, 0x90a60130},
5739 {0x13, 0x40000000},
5740 {0x14, 0x90170110},
5741 {0x15, 0x0421101f},
5742 {0x16, 0x411111f0},
5743 {0x17, 0x411111f0},
5744 {0x18, 0x411111f0},
5745 {0x19, 0x411111f0},
5746 {0x1a, 0x04a11020},
5747 {0x1b, 0x411111f0},
5748 {0x1d, 0x40748605},
5749 {0x1e, 0x411111f0}),
5750 SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED,
5751 {0x12, 0x90a60140},
5752 {0x13, 0x40000000},
5753 {0x14, 0x90170110},
5754 {0x15, 0x0421101f},
5755 {0x16, 0x411111f0},
5756 {0x17, 0x411111f0},
5757 {0x18, 0x02811030},
5758 {0x19, 0x411111f0},
5759 {0x1a, 0x04a1103f},
5760 {0x1b, 0x02011020},
5761 {0x1d, 0x40700001},
5762 {0x1e, 0x411111f0}),
5763 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP 15 Touchsmart", ALC269_FIXUP_HP_MUTE_LED_MIC1,
5764 ALC282_STANDARD_PINS,
5765 {0x12, 0x99a30130},
5766 {0x17, 0x40000000},
5767 {0x19, 0x03a11020},
5768 {0x1d, 0x40f41905},
5769 {0x21, 0x0321101f}),
5770 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
5771 ALC282_STANDARD_PINS,
5772 {0x12, 0x99a30130},
5773 {0x17, 0x40020008},
5774 {0x19, 0x03a11020},
5775 {0x1d, 0x40e00001},
5776 {0x21, 0x03211040}),
5777 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
5778 ALC282_STANDARD_PINS,
5779 {0x12, 0x99a30130},
5780 {0x17, 0x40000000},
5781 {0x19, 0x03a11030},
5782 {0x1d, 0x40e00001},
5783 {0x21, 0x03211020}),
5784 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
5785 ALC282_STANDARD_PINS,
5786 {0x12, 0x99a30130},
5787 {0x17, 0x40000000},
5788 {0x19, 0x03a11030},
5789 {0x1d, 0x40f00001},
5790 {0x21, 0x03211020}),
5791 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
5792 ALC282_STANDARD_PINS,
5793 {0x12, 0x99a30130},
5794 {0x17, 0x40000000},
5795 {0x19, 0x04a11020},
5796 {0x1d, 0x40f00001},
5797 {0x21, 0x0421101f}),
5798 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
5799 ALC282_STANDARD_PINS,
5800 {0x12, 0x99a30130},
5801 {0x17, 0x40000000},
5802 {0x19, 0x03a11030},
5803 {0x1d, 0x40f00001},
5804 {0x21, 0x04211020}),
5805 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED,
5806 ALC282_STANDARD_PINS,
5807 {0x12, 0x90a60140},
5808 {0x17, 0x40000000},
5809 {0x19, 0x04a11030},
5810 {0x1d, 0x40f00001},
5811 {0x21, 0x04211020}),
5812 SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
5813 ALC282_STANDARD_PINS,
5814 {0x12, 0x90a60130},
5815 {0x17, 0x40020008},
5816 {0x19, 0x411111f0},
5817 {0x1d, 0x40e00001},
5818 {0x21, 0x0321101f}),
5819 SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
5820 {0x12, 0x90a60160},
5821 {0x14, 0x90170120},
5822 {0x17, 0x40000000},
5823 {0x18, 0x411111f0},
5824 {0x19, 0x411111f0},
5825 {0x1a, 0x411111f0},
5826 {0x1b, 0x411111f0},
5827 {0x1d, 0x40700001},
5828 {0x1e, 0x411111f0},
5829 {0x21, 0x02211030}),
5830 SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
5831 ALC282_STANDARD_PINS,
5832 {0x12, 0x90a60130},
5833 {0x17, 0x40020008},
5834 {0x19, 0x03a11020},
5835 {0x1d, 0x40e00001},
5836 {0x21, 0x0321101f}),
5837 SND_HDA_PIN_QUIRK(0x10ec0288, 0x1028, "Dell", ALC288_FIXUP_DELL_XPS_13_GPIO6,
5838 ALC288_STANDARD_PINS,
5839 {0x12, 0x90a60120},
5840 {0x13, 0x40000000},
5841 {0x14, 0x90170110},
5842 {0x1d, 0x4076832d},
5843 {0x21, 0x0321101f}),
5844 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
5845 ALC290_STANDARD_PINS,
5846 {0x14, 0x411111f0},
5847 {0x15, 0x04211040},
5848 {0x18, 0x90170112},
5849 {0x1a, 0x04a11020},
5850 {0x1d, 0x4075812d}),
5851 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
5852 ALC290_STANDARD_PINS,
5853 {0x14, 0x411111f0},
5854 {0x15, 0x04211040},
5855 {0x18, 0x90170110},
5856 {0x1a, 0x04a11020},
5857 {0x1d, 0x4075812d}),
5858 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
5859 ALC290_STANDARD_PINS,
5860 {0x14, 0x411111f0},
5861 {0x15, 0x0421101f},
5862 {0x18, 0x411111f0},
5863 {0x1a, 0x04a11020},
5864 {0x1d, 0x4075812d}),
5865 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
5866 ALC290_STANDARD_PINS,
5867 {0x14, 0x411111f0},
5868 {0x15, 0x04211020},
5869 {0x18, 0x411111f0},
5870 {0x1a, 0x04a11040},
5871 {0x1d, 0x4076a12d}),
5872 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
5873 ALC290_STANDARD_PINS,
5874 {0x14, 0x90170110},
5875 {0x15, 0x04211020},
5876 {0x18, 0x411111f0},
5877 {0x1a, 0x04a11040},
5878 {0x1d, 0x4076a12d}),
5879 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
5880 ALC290_STANDARD_PINS,
5881 {0x14, 0x90170110},
5882 {0x15, 0x04211020},
5883 {0x18, 0x411111f0},
5884 {0x1a, 0x04a11020},
5885 {0x1d, 0x4076a12d}),
5886 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
5887 ALC290_STANDARD_PINS,
5888 {0x14, 0x90170110},
5889 {0x15, 0x0421101f},
5890 {0x18, 0x411111f0},
5891 {0x1a, 0x04a11020},
5892 {0x1d, 0x4075812d}),
5893 SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
5894 ALC292_STANDARD_PINS,
5895 {0x12, 0x90a60140},
5896 {0x13, 0x411111f0},
5897 {0x16, 0x01014020},
5898 {0x18, 0x411111f0},
5899 {0x19, 0x01a19030},
5900 {0x1e, 0x411111f0}),
5901 SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
5902 ALC292_STANDARD_PINS,
5903 {0x12, 0x90a60140},
5904 {0x13, 0x411111f0},
5905 {0x16, 0x01014020},
5906 {0x18, 0x02a19031},
5907 {0x19, 0x01a1903e},
5908 {0x1e, 0x411111f0}),
5909 SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
5910 ALC292_STANDARD_PINS,
5911 {0x12, 0x90a60140},
5912 {0x13, 0x411111f0},
5913 {0x16, 0x411111f0},
5914 {0x18, 0x411111f0},
5915 {0x19, 0x411111f0},
5916 {0x1e, 0x411111f0}),
5917 SND_HDA_PIN_QUIRK(0x10ec0293, 0x1028, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
5918 ALC292_STANDARD_PINS,
5919 {0x12, 0x40000000},
5920 {0x13, 0x90a60140},
5921 {0x16, 0x21014020},
5922 {0x18, 0x411111f0},
5923 {0x19, 0x21a19030},
5924 {0x1e, 0x411111f0}),
5925 SND_HDA_PIN_QUIRK(0x10ec0293, 0x1028, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
5926 ALC292_STANDARD_PINS,
5927 {0x12, 0x40000000},
5928 {0x13, 0x90a60140},
5929 {0x16, 0x411111f0},
5930 {0x18, 0x411111f0},
5931 {0x19, 0x411111f0},
5932 {0x1e, 0x411111f0}),
5933 SND_HDA_PIN_QUIRK(0x10ec0293, 0x1028, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
5934 ALC292_STANDARD_PINS,
5935 {0x12, 0x40000000},
5936 {0x13, 0x90a60140},
5937 {0x16, 0x21014020},
5938 {0x18, 0x411111f0},
5939 {0x19, 0x21a19030},
5940 {0x1e, 0x411111ff}),
5941 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
5942 ALC298_STANDARD_PINS,
5943 {0x12, 0x90a60130},
5944 {0x13, 0x40000000},
5945 {0x14, 0x411111f0},
5946 {0x17, 0x90170140},
5947 {0x1d, 0x4068a36d},
5948 {0x21, 0x03211020}),
5949 {}
5950 };
5951
alc269_fill_coef(struct hda_codec * codec)5952 static void alc269_fill_coef(struct hda_codec *codec)
5953 {
5954 struct alc_spec *spec = codec->spec;
5955 int val;
5956
5957 if (spec->codec_variant != ALC269_TYPE_ALC269VB)
5958 return;
5959
5960 if ((alc_get_coef0(codec) & 0x00ff) < 0x015) {
5961 alc_write_coef_idx(codec, 0xf, 0x960b);
5962 alc_write_coef_idx(codec, 0xe, 0x8817);
5963 }
5964
5965 if ((alc_get_coef0(codec) & 0x00ff) == 0x016) {
5966 alc_write_coef_idx(codec, 0xf, 0x960b);
5967 alc_write_coef_idx(codec, 0xe, 0x8814);
5968 }
5969
5970 if ((alc_get_coef0(codec) & 0x00ff) == 0x017) {
5971 /* Power up output pin */
5972 alc_update_coef_idx(codec, 0x04, 0, 1<<11);
5973 }
5974
5975 if ((alc_get_coef0(codec) & 0x00ff) == 0x018) {
5976 val = alc_read_coef_idx(codec, 0xd);
5977 if (val != -1 && (val & 0x0c00) >> 10 != 0x1) {
5978 /* Capless ramp up clock control */
5979 alc_write_coef_idx(codec, 0xd, val | (1<<10));
5980 }
5981 val = alc_read_coef_idx(codec, 0x17);
5982 if (val != -1 && (val & 0x01c0) >> 6 != 0x4) {
5983 /* Class D power on reset */
5984 alc_write_coef_idx(codec, 0x17, val | (1<<7));
5985 }
5986 }
5987
5988 /* HP */
5989 alc_update_coef_idx(codec, 0x4, 0, 1<<11);
5990 }
5991
5992 /*
5993 */
patch_alc269(struct hda_codec * codec)5994 static int patch_alc269(struct hda_codec *codec)
5995 {
5996 struct alc_spec *spec;
5997 int err;
5998
5999 err = alc_alloc_spec(codec, 0x0b);
6000 if (err < 0)
6001 return err;
6002
6003 spec = codec->spec;
6004 spec->gen.shared_mic_vref_pin = 0x18;
6005
6006 snd_hda_pick_fixup(codec, alc269_fixup_models,
6007 alc269_fixup_tbl, alc269_fixups);
6008 snd_hda_pick_pin_fixup(codec, alc269_pin_fixup_tbl, alc269_fixups);
6009 snd_hda_pick_fixup(codec, NULL, alc269_fixup_vendor_tbl,
6010 alc269_fixups);
6011 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
6012
6013 alc_auto_parse_customize_define(codec);
6014
6015 if (has_cdefine_beep(codec))
6016 spec->gen.beep_nid = 0x01;
6017
6018 switch (codec->vendor_id) {
6019 case 0x10ec0269:
6020 spec->codec_variant = ALC269_TYPE_ALC269VA;
6021 switch (alc_get_coef0(codec) & 0x00f0) {
6022 case 0x0010:
6023 if (codec->bus->pci &&
6024 codec->bus->pci->subsystem_vendor == 0x1025 &&
6025 spec->cdefine.platform_type == 1)
6026 err = alc_codec_rename(codec, "ALC271X");
6027 spec->codec_variant = ALC269_TYPE_ALC269VB;
6028 break;
6029 case 0x0020:
6030 if (codec->bus->pci &&
6031 codec->bus->pci->subsystem_vendor == 0x17aa &&
6032 codec->bus->pci->subsystem_device == 0x21f3)
6033 err = alc_codec_rename(codec, "ALC3202");
6034 spec->codec_variant = ALC269_TYPE_ALC269VC;
6035 break;
6036 case 0x0030:
6037 spec->codec_variant = ALC269_TYPE_ALC269VD;
6038 break;
6039 default:
6040 alc_fix_pll_init(codec, 0x20, 0x04, 15);
6041 }
6042 if (err < 0)
6043 goto error;
6044 spec->init_hook = alc269_fill_coef;
6045 alc269_fill_coef(codec);
6046 break;
6047
6048 case 0x10ec0280:
6049 case 0x10ec0290:
6050 spec->codec_variant = ALC269_TYPE_ALC280;
6051 break;
6052 case 0x10ec0282:
6053 spec->codec_variant = ALC269_TYPE_ALC282;
6054 spec->shutup = alc282_shutup;
6055 spec->init_hook = alc282_init;
6056 break;
6057 case 0x10ec0233:
6058 case 0x10ec0283:
6059 spec->codec_variant = ALC269_TYPE_ALC283;
6060 spec->shutup = alc283_shutup;
6061 spec->init_hook = alc283_init;
6062 break;
6063 case 0x10ec0284:
6064 case 0x10ec0292:
6065 spec->codec_variant = ALC269_TYPE_ALC284;
6066 break;
6067 case 0x10ec0285:
6068 case 0x10ec0293:
6069 spec->codec_variant = ALC269_TYPE_ALC285;
6070 break;
6071 case 0x10ec0286:
6072 case 0x10ec0288:
6073 spec->codec_variant = ALC269_TYPE_ALC286;
6074 spec->shutup = alc286_shutup;
6075 break;
6076 case 0x10ec0298:
6077 spec->codec_variant = ALC269_TYPE_ALC298;
6078 break;
6079 case 0x10ec0255:
6080 spec->codec_variant = ALC269_TYPE_ALC255;
6081 break;
6082 case 0x10ec0256:
6083 spec->codec_variant = ALC269_TYPE_ALC256;
6084 spec->gen.mixer_nid = 0; /* ALC256 does not have any loopback mixer path */
6085 alc_update_coef_idx(codec, 0x36, 1 << 13, 1 << 5); /* Switch pcbeep path to Line in path*/
6086 break;
6087 }
6088
6089 if (snd_hda_codec_read(codec, 0x51, 0, AC_VERB_PARAMETERS, 0) == 0x10ec5505) {
6090 spec->has_alc5505_dsp = 1;
6091 spec->init_hook = alc5505_dsp_init;
6092 }
6093
6094 /* automatic parse from the BIOS config */
6095 err = alc269_parse_auto_config(codec);
6096 if (err < 0)
6097 goto error;
6098
6099 if (!spec->gen.no_analog && spec->gen.beep_nid && spec->gen.mixer_nid)
6100 set_beep_amp(spec, spec->gen.mixer_nid, 0x04, HDA_INPUT);
6101
6102 codec->patch_ops = alc_patch_ops;
6103 #ifdef CONFIG_PM
6104 codec->patch_ops.suspend = alc269_suspend;
6105 codec->patch_ops.resume = alc269_resume;
6106 #endif
6107 if (!spec->shutup)
6108 spec->shutup = alc269_shutup;
6109
6110 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
6111
6112 return 0;
6113
6114 error:
6115 alc_free(codec);
6116 return err;
6117 }
6118
6119 /*
6120 * ALC861
6121 */
6122
alc861_parse_auto_config(struct hda_codec * codec)6123 static int alc861_parse_auto_config(struct hda_codec *codec)
6124 {
6125 static const hda_nid_t alc861_ignore[] = { 0x1d, 0 };
6126 static const hda_nid_t alc861_ssids[] = { 0x0e, 0x0f, 0x0b, 0 };
6127 return alc_parse_auto_config(codec, alc861_ignore, alc861_ssids);
6128 }
6129
6130 /* Pin config fixes */
6131 enum {
6132 ALC861_FIXUP_FSC_AMILO_PI1505,
6133 ALC861_FIXUP_AMP_VREF_0F,
6134 ALC861_FIXUP_NO_JACK_DETECT,
6135 ALC861_FIXUP_ASUS_A6RP,
6136 ALC660_FIXUP_ASUS_W7J,
6137 };
6138
6139 /* On some laptops, VREF of pin 0x0f is abused for controlling the main amp */
alc861_fixup_asus_amp_vref_0f(struct hda_codec * codec,const struct hda_fixup * fix,int action)6140 static void alc861_fixup_asus_amp_vref_0f(struct hda_codec *codec,
6141 const struct hda_fixup *fix, int action)
6142 {
6143 struct alc_spec *spec = codec->spec;
6144 unsigned int val;
6145
6146 if (action != HDA_FIXUP_ACT_INIT)
6147 return;
6148 val = snd_hda_codec_get_pin_target(codec, 0x0f);
6149 if (!(val & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN)))
6150 val |= AC_PINCTL_IN_EN;
6151 val |= AC_PINCTL_VREF_50;
6152 snd_hda_set_pin_ctl(codec, 0x0f, val);
6153 spec->gen.keep_vref_in_automute = 1;
6154 }
6155
6156 /* suppress the jack-detection */
alc_fixup_no_jack_detect(struct hda_codec * codec,const struct hda_fixup * fix,int action)6157 static void alc_fixup_no_jack_detect(struct hda_codec *codec,
6158 const struct hda_fixup *fix, int action)
6159 {
6160 if (action == HDA_FIXUP_ACT_PRE_PROBE)
6161 codec->no_jack_detect = 1;
6162 }
6163
6164 static const struct hda_fixup alc861_fixups[] = {
6165 [ALC861_FIXUP_FSC_AMILO_PI1505] = {
6166 .type = HDA_FIXUP_PINS,
6167 .v.pins = (const struct hda_pintbl[]) {
6168 { 0x0b, 0x0221101f }, /* HP */
6169 { 0x0f, 0x90170310 }, /* speaker */
6170 { }
6171 }
6172 },
6173 [ALC861_FIXUP_AMP_VREF_0F] = {
6174 .type = HDA_FIXUP_FUNC,
6175 .v.func = alc861_fixup_asus_amp_vref_0f,
6176 },
6177 [ALC861_FIXUP_NO_JACK_DETECT] = {
6178 .type = HDA_FIXUP_FUNC,
6179 .v.func = alc_fixup_no_jack_detect,
6180 },
6181 [ALC861_FIXUP_ASUS_A6RP] = {
6182 .type = HDA_FIXUP_FUNC,
6183 .v.func = alc861_fixup_asus_amp_vref_0f,
6184 .chained = true,
6185 .chain_id = ALC861_FIXUP_NO_JACK_DETECT,
6186 },
6187 [ALC660_FIXUP_ASUS_W7J] = {
6188 .type = HDA_FIXUP_VERBS,
6189 .v.verbs = (const struct hda_verb[]) {
6190 /* ASUS W7J needs a magic pin setup on unused NID 0x10
6191 * for enabling outputs
6192 */
6193 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6194 { }
6195 },
6196 }
6197 };
6198
6199 static const struct snd_pci_quirk alc861_fixup_tbl[] = {
6200 SND_PCI_QUIRK(0x1043, 0x1253, "ASUS W7J", ALC660_FIXUP_ASUS_W7J),
6201 SND_PCI_QUIRK(0x1043, 0x1263, "ASUS Z35HL", ALC660_FIXUP_ASUS_W7J),
6202 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS A6Rp", ALC861_FIXUP_ASUS_A6RP),
6203 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", ALC861_FIXUP_AMP_VREF_0F),
6204 SND_PCI_QUIRK(0x1462, 0x7254, "HP DX2200", ALC861_FIXUP_NO_JACK_DETECT),
6205 SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", ALC861_FIXUP_AMP_VREF_0F),
6206 SND_PCI_QUIRK(0x1584, 0x0000, "Uniwill ECS M31EI", ALC861_FIXUP_AMP_VREF_0F),
6207 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", ALC861_FIXUP_FSC_AMILO_PI1505),
6208 {}
6209 };
6210
6211 /*
6212 */
patch_alc861(struct hda_codec * codec)6213 static int patch_alc861(struct hda_codec *codec)
6214 {
6215 struct alc_spec *spec;
6216 int err;
6217
6218 err = alc_alloc_spec(codec, 0x15);
6219 if (err < 0)
6220 return err;
6221
6222 spec = codec->spec;
6223 spec->gen.beep_nid = 0x23;
6224
6225 snd_hda_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
6226 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
6227
6228 /* automatic parse from the BIOS config */
6229 err = alc861_parse_auto_config(codec);
6230 if (err < 0)
6231 goto error;
6232
6233 if (!spec->gen.no_analog)
6234 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
6235
6236 codec->patch_ops = alc_patch_ops;
6237 #ifdef CONFIG_PM
6238 spec->power_hook = alc_power_eapd;
6239 #endif
6240
6241 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
6242
6243 return 0;
6244
6245 error:
6246 alc_free(codec);
6247 return err;
6248 }
6249
6250 /*
6251 * ALC861-VD support
6252 *
6253 * Based on ALC882
6254 *
6255 * In addition, an independent DAC
6256 */
alc861vd_parse_auto_config(struct hda_codec * codec)6257 static int alc861vd_parse_auto_config(struct hda_codec *codec)
6258 {
6259 static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
6260 static const hda_nid_t alc861vd_ssids[] = { 0x15, 0x1b, 0x14, 0 };
6261 return alc_parse_auto_config(codec, alc861vd_ignore, alc861vd_ssids);
6262 }
6263
6264 enum {
6265 ALC660VD_FIX_ASUS_GPIO1,
6266 ALC861VD_FIX_DALLAS,
6267 };
6268
6269 /* exclude VREF80 */
alc861vd_fixup_dallas(struct hda_codec * codec,const struct hda_fixup * fix,int action)6270 static void alc861vd_fixup_dallas(struct hda_codec *codec,
6271 const struct hda_fixup *fix, int action)
6272 {
6273 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
6274 snd_hda_override_pin_caps(codec, 0x18, 0x00000734);
6275 snd_hda_override_pin_caps(codec, 0x19, 0x0000073c);
6276 }
6277 }
6278
6279 static const struct hda_fixup alc861vd_fixups[] = {
6280 [ALC660VD_FIX_ASUS_GPIO1] = {
6281 .type = HDA_FIXUP_VERBS,
6282 .v.verbs = (const struct hda_verb[]) {
6283 /* reset GPIO1 */
6284 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
6285 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6286 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6287 { }
6288 }
6289 },
6290 [ALC861VD_FIX_DALLAS] = {
6291 .type = HDA_FIXUP_FUNC,
6292 .v.func = alc861vd_fixup_dallas,
6293 },
6294 };
6295
6296 static const struct snd_pci_quirk alc861vd_fixup_tbl[] = {
6297 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_FIX_DALLAS),
6298 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
6299 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_FIX_DALLAS),
6300 {}
6301 };
6302
6303 /*
6304 */
patch_alc861vd(struct hda_codec * codec)6305 static int patch_alc861vd(struct hda_codec *codec)
6306 {
6307 struct alc_spec *spec;
6308 int err;
6309
6310 err = alc_alloc_spec(codec, 0x0b);
6311 if (err < 0)
6312 return err;
6313
6314 spec = codec->spec;
6315 spec->gen.beep_nid = 0x23;
6316
6317 snd_hda_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
6318 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
6319
6320 /* automatic parse from the BIOS config */
6321 err = alc861vd_parse_auto_config(codec);
6322 if (err < 0)
6323 goto error;
6324
6325 if (!spec->gen.no_analog)
6326 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
6327
6328 codec->patch_ops = alc_patch_ops;
6329
6330 spec->shutup = alc_eapd_shutup;
6331
6332 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
6333
6334 return 0;
6335
6336 error:
6337 alc_free(codec);
6338 return err;
6339 }
6340
6341 /*
6342 * ALC662 support
6343 *
6344 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
6345 * configuration. Each pin widget can choose any input DACs and a mixer.
6346 * Each ADC is connected from a mixer of all inputs. This makes possible
6347 * 6-channel independent captures.
6348 *
6349 * In addition, an independent DAC for the multi-playback (not used in this
6350 * driver yet).
6351 */
6352
6353 /*
6354 * BIOS auto configuration
6355 */
6356
alc662_parse_auto_config(struct hda_codec * codec)6357 static int alc662_parse_auto_config(struct hda_codec *codec)
6358 {
6359 static const hda_nid_t alc662_ignore[] = { 0x1d, 0 };
6360 static const hda_nid_t alc663_ssids[] = { 0x15, 0x1b, 0x14, 0x21 };
6361 static const hda_nid_t alc662_ssids[] = { 0x15, 0x1b, 0x14, 0 };
6362 const hda_nid_t *ssids;
6363
6364 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
6365 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670 ||
6366 codec->vendor_id == 0x10ec0671)
6367 ssids = alc663_ssids;
6368 else
6369 ssids = alc662_ssids;
6370 return alc_parse_auto_config(codec, alc662_ignore, ssids);
6371 }
6372
alc272_fixup_mario(struct hda_codec * codec,const struct hda_fixup * fix,int action)6373 static void alc272_fixup_mario(struct hda_codec *codec,
6374 const struct hda_fixup *fix, int action)
6375 {
6376 if (action != HDA_FIXUP_ACT_PRE_PROBE)
6377 return;
6378 if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT,
6379 (0x3b << AC_AMPCAP_OFFSET_SHIFT) |
6380 (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) |
6381 (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) |
6382 (0 << AC_AMPCAP_MUTE_SHIFT)))
6383 codec_warn(codec, "failed to override amp caps for NID 0x2\n");
6384 }
6385
6386 static const struct snd_pcm_chmap_elem asus_pcm_2_1_chmaps[] = {
6387 { .channels = 2,
6388 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } },
6389 { .channels = 4,
6390 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR,
6391 SNDRV_CHMAP_NA, SNDRV_CHMAP_LFE } }, /* LFE only on right */
6392 { }
6393 };
6394
6395 /* override the 2.1 chmap */
alc_fixup_bass_chmap(struct hda_codec * codec,const struct hda_fixup * fix,int action)6396 static void alc_fixup_bass_chmap(struct hda_codec *codec,
6397 const struct hda_fixup *fix, int action)
6398 {
6399 if (action == HDA_FIXUP_ACT_BUILD) {
6400 struct alc_spec *spec = codec->spec;
6401 spec->gen.pcm_rec[0].stream[0].chmap = asus_pcm_2_1_chmaps;
6402 }
6403 }
6404
6405 /* avoid D3 for keeping GPIO up */
gpio_led_power_filter(struct hda_codec * codec,hda_nid_t nid,unsigned int power_state)6406 static unsigned int gpio_led_power_filter(struct hda_codec *codec,
6407 hda_nid_t nid,
6408 unsigned int power_state)
6409 {
6410 struct alc_spec *spec = codec->spec;
6411 if (nid == codec->afg && power_state == AC_PWRST_D3 && spec->gpio_led)
6412 return AC_PWRST_D0;
6413 return power_state;
6414 }
6415
alc662_fixup_led_gpio1(struct hda_codec * codec,const struct hda_fixup * fix,int action)6416 static void alc662_fixup_led_gpio1(struct hda_codec *codec,
6417 const struct hda_fixup *fix, int action)
6418 {
6419 struct alc_spec *spec = codec->spec;
6420 static const struct hda_verb gpio_init[] = {
6421 { 0x01, AC_VERB_SET_GPIO_MASK, 0x01 },
6422 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01 },
6423 {}
6424 };
6425
6426 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
6427 spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook;
6428 spec->gpio_led = 0;
6429 spec->mute_led_polarity = 1;
6430 spec->gpio_mute_led_mask = 0x01;
6431 snd_hda_add_verbs(codec, gpio_init);
6432 codec->power_filter = gpio_led_power_filter;
6433 }
6434 }
6435
6436 static struct coef_fw alc668_coefs[] = {
6437 WRITE_COEF(0x01, 0xbebe), WRITE_COEF(0x02, 0xaaaa), WRITE_COEF(0x03, 0x0),
6438 WRITE_COEF(0x04, 0x0180), WRITE_COEF(0x06, 0x0), WRITE_COEF(0x07, 0x0f80),
6439 WRITE_COEF(0x08, 0x0031), WRITE_COEF(0x0a, 0x0060), WRITE_COEF(0x0b, 0x0),
6440 WRITE_COEF(0x0c, 0x7cf7), WRITE_COEF(0x0d, 0x1080), WRITE_COEF(0x0e, 0x7f7f),
6441 WRITE_COEF(0x0f, 0xcccc), WRITE_COEF(0x10, 0xddcc), WRITE_COEF(0x11, 0x0001),
6442 WRITE_COEF(0x13, 0x0), WRITE_COEF(0x14, 0x2aa0), WRITE_COEF(0x17, 0xa940),
6443 WRITE_COEF(0x19, 0x0), WRITE_COEF(0x1a, 0x0), WRITE_COEF(0x1b, 0x0),
6444 WRITE_COEF(0x1c, 0x0), WRITE_COEF(0x1d, 0x0), WRITE_COEF(0x1e, 0x7418),
6445 WRITE_COEF(0x1f, 0x0804), WRITE_COEF(0x20, 0x4200), WRITE_COEF(0x21, 0x0468),
6446 WRITE_COEF(0x22, 0x8ccc), WRITE_COEF(0x23, 0x0250), WRITE_COEF(0x24, 0x7418),
6447 WRITE_COEF(0x27, 0x0), WRITE_COEF(0x28, 0x8ccc), WRITE_COEF(0x2a, 0xff00),
6448 WRITE_COEF(0x2b, 0x8000), WRITE_COEF(0xa7, 0xff00), WRITE_COEF(0xa8, 0x8000),
6449 WRITE_COEF(0xaa, 0x2e17), WRITE_COEF(0xab, 0xa0c0), WRITE_COEF(0xac, 0x0),
6450 WRITE_COEF(0xad, 0x0), WRITE_COEF(0xae, 0x2ac6), WRITE_COEF(0xaf, 0xa480),
6451 WRITE_COEF(0xb0, 0x0), WRITE_COEF(0xb1, 0x0), WRITE_COEF(0xb2, 0x0),
6452 WRITE_COEF(0xb3, 0x0), WRITE_COEF(0xb4, 0x0), WRITE_COEF(0xb5, 0x1040),
6453 WRITE_COEF(0xb6, 0xd697), WRITE_COEF(0xb7, 0x902b), WRITE_COEF(0xb8, 0xd697),
6454 WRITE_COEF(0xb9, 0x902b), WRITE_COEF(0xba, 0xb8ba), WRITE_COEF(0xbb, 0xaaab),
6455 WRITE_COEF(0xbc, 0xaaaf), WRITE_COEF(0xbd, 0x6aaa), WRITE_COEF(0xbe, 0x1c02),
6456 WRITE_COEF(0xc0, 0x00ff), WRITE_COEF(0xc1, 0x0fa6),
6457 {}
6458 };
6459
alc668_restore_default_value(struct hda_codec * codec)6460 static void alc668_restore_default_value(struct hda_codec *codec)
6461 {
6462 alc_process_coef_fw(codec, alc668_coefs);
6463 }
6464
6465 enum {
6466 ALC662_FIXUP_ASPIRE,
6467 ALC662_FIXUP_LED_GPIO1,
6468 ALC662_FIXUP_IDEAPAD,
6469 ALC272_FIXUP_MARIO,
6470 ALC662_FIXUP_CZC_P10T,
6471 ALC662_FIXUP_SKU_IGNORE,
6472 ALC662_FIXUP_HP_RP5800,
6473 ALC662_FIXUP_ASUS_MODE1,
6474 ALC662_FIXUP_ASUS_MODE2,
6475 ALC662_FIXUP_ASUS_MODE3,
6476 ALC662_FIXUP_ASUS_MODE4,
6477 ALC662_FIXUP_ASUS_MODE5,
6478 ALC662_FIXUP_ASUS_MODE6,
6479 ALC662_FIXUP_ASUS_MODE7,
6480 ALC662_FIXUP_ASUS_MODE8,
6481 ALC662_FIXUP_NO_JACK_DETECT,
6482 ALC662_FIXUP_ZOTAC_Z68,
6483 ALC662_FIXUP_INV_DMIC,
6484 ALC662_FIXUP_DELL_MIC_NO_PRESENCE,
6485 ALC668_FIXUP_DELL_MIC_NO_PRESENCE,
6486 ALC662_FIXUP_HEADSET_MODE,
6487 ALC668_FIXUP_HEADSET_MODE,
6488 ALC662_FIXUP_BASS_MODE4_CHMAP,
6489 ALC662_FIXUP_BASS_16,
6490 ALC662_FIXUP_BASS_1A,
6491 ALC662_FIXUP_BASS_CHMAP,
6492 ALC668_FIXUP_AUTO_MUTE,
6493 ALC668_FIXUP_DELL_DISABLE_AAMIX,
6494 ALC668_FIXUP_DELL_XPS13,
6495 ALC662_FIXUP_ASUS_Nx50,
6496 ALC668_FIXUP_ASUS_Nx51,
6497 };
6498
6499 static const struct hda_fixup alc662_fixups[] = {
6500 [ALC662_FIXUP_ASPIRE] = {
6501 .type = HDA_FIXUP_PINS,
6502 .v.pins = (const struct hda_pintbl[]) {
6503 { 0x15, 0x99130112 }, /* subwoofer */
6504 { }
6505 }
6506 },
6507 [ALC662_FIXUP_LED_GPIO1] = {
6508 .type = HDA_FIXUP_FUNC,
6509 .v.func = alc662_fixup_led_gpio1,
6510 },
6511 [ALC662_FIXUP_IDEAPAD] = {
6512 .type = HDA_FIXUP_PINS,
6513 .v.pins = (const struct hda_pintbl[]) {
6514 { 0x17, 0x99130112 }, /* subwoofer */
6515 { }
6516 },
6517 .chained = true,
6518 .chain_id = ALC662_FIXUP_LED_GPIO1,
6519 },
6520 [ALC272_FIXUP_MARIO] = {
6521 .type = HDA_FIXUP_FUNC,
6522 .v.func = alc272_fixup_mario,
6523 },
6524 [ALC662_FIXUP_CZC_P10T] = {
6525 .type = HDA_FIXUP_VERBS,
6526 .v.verbs = (const struct hda_verb[]) {
6527 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
6528 {}
6529 }
6530 },
6531 [ALC662_FIXUP_SKU_IGNORE] = {
6532 .type = HDA_FIXUP_FUNC,
6533 .v.func = alc_fixup_sku_ignore,
6534 },
6535 [ALC662_FIXUP_HP_RP5800] = {
6536 .type = HDA_FIXUP_PINS,
6537 .v.pins = (const struct hda_pintbl[]) {
6538 { 0x14, 0x0221201f }, /* HP out */
6539 { }
6540 },
6541 .chained = true,
6542 .chain_id = ALC662_FIXUP_SKU_IGNORE
6543 },
6544 [ALC662_FIXUP_ASUS_MODE1] = {
6545 .type = HDA_FIXUP_PINS,
6546 .v.pins = (const struct hda_pintbl[]) {
6547 { 0x14, 0x99130110 }, /* speaker */
6548 { 0x18, 0x01a19c20 }, /* mic */
6549 { 0x19, 0x99a3092f }, /* int-mic */
6550 { 0x21, 0x0121401f }, /* HP out */
6551 { }
6552 },
6553 .chained = true,
6554 .chain_id = ALC662_FIXUP_SKU_IGNORE
6555 },
6556 [ALC662_FIXUP_ASUS_MODE2] = {
6557 .type = HDA_FIXUP_PINS,
6558 .v.pins = (const struct hda_pintbl[]) {
6559 { 0x14, 0x99130110 }, /* speaker */
6560 { 0x18, 0x01a19820 }, /* mic */
6561 { 0x19, 0x99a3092f }, /* int-mic */
6562 { 0x1b, 0x0121401f }, /* HP out */
6563 { }
6564 },
6565 .chained = true,
6566 .chain_id = ALC662_FIXUP_SKU_IGNORE
6567 },
6568 [ALC662_FIXUP_ASUS_MODE3] = {
6569 .type = HDA_FIXUP_PINS,
6570 .v.pins = (const struct hda_pintbl[]) {
6571 { 0x14, 0x99130110 }, /* speaker */
6572 { 0x15, 0x0121441f }, /* HP */
6573 { 0x18, 0x01a19840 }, /* mic */
6574 { 0x19, 0x99a3094f }, /* int-mic */
6575 { 0x21, 0x01211420 }, /* HP2 */
6576 { }
6577 },
6578 .chained = true,
6579 .chain_id = ALC662_FIXUP_SKU_IGNORE
6580 },
6581 [ALC662_FIXUP_ASUS_MODE4] = {
6582 .type = HDA_FIXUP_PINS,
6583 .v.pins = (const struct hda_pintbl[]) {
6584 { 0x14, 0x99130110 }, /* speaker */
6585 { 0x16, 0x99130111 }, /* speaker */
6586 { 0x18, 0x01a19840 }, /* mic */
6587 { 0x19, 0x99a3094f }, /* int-mic */
6588 { 0x21, 0x0121441f }, /* HP */
6589 { }
6590 },
6591 .chained = true,
6592 .chain_id = ALC662_FIXUP_SKU_IGNORE
6593 },
6594 [ALC662_FIXUP_ASUS_MODE5] = {
6595 .type = HDA_FIXUP_PINS,
6596 .v.pins = (const struct hda_pintbl[]) {
6597 { 0x14, 0x99130110 }, /* speaker */
6598 { 0x15, 0x0121441f }, /* HP */
6599 { 0x16, 0x99130111 }, /* speaker */
6600 { 0x18, 0x01a19840 }, /* mic */
6601 { 0x19, 0x99a3094f }, /* int-mic */
6602 { }
6603 },
6604 .chained = true,
6605 .chain_id = ALC662_FIXUP_SKU_IGNORE
6606 },
6607 [ALC662_FIXUP_ASUS_MODE6] = {
6608 .type = HDA_FIXUP_PINS,
6609 .v.pins = (const struct hda_pintbl[]) {
6610 { 0x14, 0x99130110 }, /* speaker */
6611 { 0x15, 0x01211420 }, /* HP2 */
6612 { 0x18, 0x01a19840 }, /* mic */
6613 { 0x19, 0x99a3094f }, /* int-mic */
6614 { 0x1b, 0x0121441f }, /* HP */
6615 { }
6616 },
6617 .chained = true,
6618 .chain_id = ALC662_FIXUP_SKU_IGNORE
6619 },
6620 [ALC662_FIXUP_ASUS_MODE7] = {
6621 .type = HDA_FIXUP_PINS,
6622 .v.pins = (const struct hda_pintbl[]) {
6623 { 0x14, 0x99130110 }, /* speaker */
6624 { 0x17, 0x99130111 }, /* speaker */
6625 { 0x18, 0x01a19840 }, /* mic */
6626 { 0x19, 0x99a3094f }, /* int-mic */
6627 { 0x1b, 0x01214020 }, /* HP */
6628 { 0x21, 0x0121401f }, /* HP */
6629 { }
6630 },
6631 .chained = true,
6632 .chain_id = ALC662_FIXUP_SKU_IGNORE
6633 },
6634 [ALC662_FIXUP_ASUS_MODE8] = {
6635 .type = HDA_FIXUP_PINS,
6636 .v.pins = (const struct hda_pintbl[]) {
6637 { 0x14, 0x99130110 }, /* speaker */
6638 { 0x12, 0x99a30970 }, /* int-mic */
6639 { 0x15, 0x01214020 }, /* HP */
6640 { 0x17, 0x99130111 }, /* speaker */
6641 { 0x18, 0x01a19840 }, /* mic */
6642 { 0x21, 0x0121401f }, /* HP */
6643 { }
6644 },
6645 .chained = true,
6646 .chain_id = ALC662_FIXUP_SKU_IGNORE
6647 },
6648 [ALC662_FIXUP_NO_JACK_DETECT] = {
6649 .type = HDA_FIXUP_FUNC,
6650 .v.func = alc_fixup_no_jack_detect,
6651 },
6652 [ALC662_FIXUP_ZOTAC_Z68] = {
6653 .type = HDA_FIXUP_PINS,
6654 .v.pins = (const struct hda_pintbl[]) {
6655 { 0x1b, 0x02214020 }, /* Front HP */
6656 { }
6657 }
6658 },
6659 [ALC662_FIXUP_INV_DMIC] = {
6660 .type = HDA_FIXUP_FUNC,
6661 .v.func = alc_fixup_inv_dmic,
6662 },
6663 [ALC668_FIXUP_DELL_XPS13] = {
6664 .type = HDA_FIXUP_FUNC,
6665 .v.func = alc_fixup_dell_xps13,
6666 .chained = true,
6667 .chain_id = ALC668_FIXUP_DELL_DISABLE_AAMIX
6668 },
6669 [ALC668_FIXUP_DELL_DISABLE_AAMIX] = {
6670 .type = HDA_FIXUP_FUNC,
6671 .v.func = alc_fixup_disable_aamix,
6672 .chained = true,
6673 .chain_id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE
6674 },
6675 [ALC668_FIXUP_AUTO_MUTE] = {
6676 .type = HDA_FIXUP_FUNC,
6677 .v.func = alc_fixup_auto_mute_via_amp,
6678 .chained = true,
6679 .chain_id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE
6680 },
6681 [ALC662_FIXUP_DELL_MIC_NO_PRESENCE] = {
6682 .type = HDA_FIXUP_PINS,
6683 .v.pins = (const struct hda_pintbl[]) {
6684 { 0x19, 0x03a1113c }, /* use as headset mic, without its own jack detect */
6685 /* headphone mic by setting pin control of 0x1b (headphone out) to in + vref_50 */
6686 { }
6687 },
6688 .chained = true,
6689 .chain_id = ALC662_FIXUP_HEADSET_MODE
6690 },
6691 [ALC662_FIXUP_HEADSET_MODE] = {
6692 .type = HDA_FIXUP_FUNC,
6693 .v.func = alc_fixup_headset_mode_alc662,
6694 },
6695 [ALC668_FIXUP_DELL_MIC_NO_PRESENCE] = {
6696 .type = HDA_FIXUP_PINS,
6697 .v.pins = (const struct hda_pintbl[]) {
6698 { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
6699 { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */
6700 { }
6701 },
6702 .chained = true,
6703 .chain_id = ALC668_FIXUP_HEADSET_MODE
6704 },
6705 [ALC668_FIXUP_HEADSET_MODE] = {
6706 .type = HDA_FIXUP_FUNC,
6707 .v.func = alc_fixup_headset_mode_alc668,
6708 },
6709 [ALC662_FIXUP_BASS_MODE4_CHMAP] = {
6710 .type = HDA_FIXUP_FUNC,
6711 .v.func = alc_fixup_bass_chmap,
6712 .chained = true,
6713 .chain_id = ALC662_FIXUP_ASUS_MODE4
6714 },
6715 [ALC662_FIXUP_BASS_16] = {
6716 .type = HDA_FIXUP_PINS,
6717 .v.pins = (const struct hda_pintbl[]) {
6718 {0x16, 0x80106111}, /* bass speaker */
6719 {}
6720 },
6721 .chained = true,
6722 .chain_id = ALC662_FIXUP_BASS_CHMAP,
6723 },
6724 [ALC662_FIXUP_BASS_1A] = {
6725 .type = HDA_FIXUP_PINS,
6726 .v.pins = (const struct hda_pintbl[]) {
6727 {0x1a, 0x80106111}, /* bass speaker */
6728 {}
6729 },
6730 .chained = true,
6731 .chain_id = ALC662_FIXUP_BASS_CHMAP,
6732 },
6733 [ALC662_FIXUP_BASS_CHMAP] = {
6734 .type = HDA_FIXUP_FUNC,
6735 .v.func = alc_fixup_bass_chmap,
6736 },
6737 [ALC662_FIXUP_ASUS_Nx50] = {
6738 .type = HDA_FIXUP_FUNC,
6739 .v.func = alc_fixup_auto_mute_via_amp,
6740 .chained = true,
6741 .chain_id = ALC662_FIXUP_BASS_1A
6742 },
6743 [ALC668_FIXUP_ASUS_Nx51] = {
6744 .type = HDA_FIXUP_PINS,
6745 .v.pins = (const struct hda_pintbl[]) {
6746 {0x1a, 0x90170151}, /* bass speaker */
6747 {}
6748 },
6749 .chained = true,
6750 .chain_id = ALC662_FIXUP_BASS_CHMAP,
6751 },
6752 };
6753
6754 static const struct snd_pci_quirk alc662_fixup_tbl[] = {
6755 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_FIXUP_ASUS_MODE2),
6756 SND_PCI_QUIRK(0x1025, 0x022f, "Acer Aspire One", ALC662_FIXUP_INV_DMIC),
6757 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
6758 SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
6759 SND_PCI_QUIRK(0x1025, 0x0349, "eMachines eM250", ALC662_FIXUP_INV_DMIC),
6760 SND_PCI_QUIRK(0x1025, 0x034a, "Gateway LT27", ALC662_FIXUP_INV_DMIC),
6761 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
6762 SND_PCI_QUIRK(0x1028, 0x05d8, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
6763 SND_PCI_QUIRK(0x1028, 0x05db, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
6764 SND_PCI_QUIRK(0x1028, 0x05fe, "Dell XPS 15", ALC668_FIXUP_DELL_XPS13),
6765 SND_PCI_QUIRK(0x1028, 0x060a, "Dell XPS 13", ALC668_FIXUP_DELL_XPS13),
6766 SND_PCI_QUIRK(0x1028, 0x0625, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
6767 SND_PCI_QUIRK(0x1028, 0x0626, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
6768 SND_PCI_QUIRK(0x1028, 0x0696, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
6769 SND_PCI_QUIRK(0x1028, 0x0698, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
6770 SND_PCI_QUIRK(0x1028, 0x069f, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
6771 SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800),
6772 SND_PCI_QUIRK(0x1043, 0x1080, "Asus UX501VW", ALC668_FIXUP_HEADSET_MODE),
6773 SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_ASUS_Nx50),
6774 SND_PCI_QUIRK(0x1043, 0x13df, "Asus N550JX", ALC662_FIXUP_BASS_1A),
6775 SND_PCI_QUIRK(0x1043, 0x129d, "Asus N750", ALC662_FIXUP_ASUS_Nx50),
6776 SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
6777 SND_PCI_QUIRK(0x1043, 0x15a7, "ASUS UX51VZH", ALC662_FIXUP_BASS_16),
6778 SND_PCI_QUIRK(0x1043, 0x177d, "ASUS N551", ALC668_FIXUP_ASUS_Nx51),
6779 SND_PCI_QUIRK(0x1043, 0x17bd, "ASUS N751", ALC668_FIXUP_ASUS_Nx51),
6780 SND_PCI_QUIRK(0x1043, 0x1b73, "ASUS N55SF", ALC662_FIXUP_BASS_16),
6781 SND_PCI_QUIRK(0x1043, 0x1bf3, "ASUS N76VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
6782 SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT),
6783 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2),
6784 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
6785 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
6786 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
6787 SND_PCI_QUIRK(0x19da, 0xa130, "Zotac Z68", ALC662_FIXUP_ZOTAC_Z68),
6788 SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
6789
6790 #if 0
6791 /* Below is a quirk table taken from the old code.
6792 * Basically the device should work as is without the fixup table.
6793 * If BIOS doesn't give a proper info, enable the corresponding
6794 * fixup entry.
6795 */
6796 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC662_FIXUP_ASUS_MODE1),
6797 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC662_FIXUP_ASUS_MODE3),
6798 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC662_FIXUP_ASUS_MODE1),
6799 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC662_FIXUP_ASUS_MODE3),
6800 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
6801 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
6802 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
6803 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC662_FIXUP_ASUS_MODE1),
6804 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC662_FIXUP_ASUS_MODE1),
6805 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
6806 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC662_FIXUP_ASUS_MODE7),
6807 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC662_FIXUP_ASUS_MODE7),
6808 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC662_FIXUP_ASUS_MODE8),
6809 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC662_FIXUP_ASUS_MODE3),
6810 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC662_FIXUP_ASUS_MODE1),
6811 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
6812 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_FIXUP_ASUS_MODE2),
6813 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC662_FIXUP_ASUS_MODE1),
6814 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
6815 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
6816 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
6817 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
6818 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC662_FIXUP_ASUS_MODE1),
6819 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC662_FIXUP_ASUS_MODE3),
6820 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_FIXUP_ASUS_MODE2),
6821 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
6822 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC662_FIXUP_ASUS_MODE5),
6823 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
6824 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
6825 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC662_FIXUP_ASUS_MODE1),
6826 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
6827 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
6828 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC662_FIXUP_ASUS_MODE3),
6829 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC662_FIXUP_ASUS_MODE3),
6830 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC662_FIXUP_ASUS_MODE1),
6831 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC662_FIXUP_ASUS_MODE1),
6832 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC662_FIXUP_ASUS_MODE1),
6833 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC662_FIXUP_ASUS_MODE1),
6834 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC662_FIXUP_ASUS_MODE1),
6835 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
6836 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_FIXUP_ASUS_MODE2),
6837 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC662_FIXUP_ASUS_MODE1),
6838 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
6839 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC662_FIXUP_ASUS_MODE3),
6840 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC662_FIXUP_ASUS_MODE1),
6841 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC662_FIXUP_ASUS_MODE1),
6842 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC662_FIXUP_ASUS_MODE1),
6843 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_FIXUP_ASUS_MODE2),
6844 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
6845 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE4),
6846 #endif
6847 {}
6848 };
6849
6850 static const struct hda_model_fixup alc662_fixup_models[] = {
6851 {.id = ALC272_FIXUP_MARIO, .name = "mario"},
6852 {.id = ALC662_FIXUP_ASUS_MODE1, .name = "asus-mode1"},
6853 {.id = ALC662_FIXUP_ASUS_MODE2, .name = "asus-mode2"},
6854 {.id = ALC662_FIXUP_ASUS_MODE3, .name = "asus-mode3"},
6855 {.id = ALC662_FIXUP_ASUS_MODE4, .name = "asus-mode4"},
6856 {.id = ALC662_FIXUP_ASUS_MODE5, .name = "asus-mode5"},
6857 {.id = ALC662_FIXUP_ASUS_MODE6, .name = "asus-mode6"},
6858 {.id = ALC662_FIXUP_ASUS_MODE7, .name = "asus-mode7"},
6859 {.id = ALC662_FIXUP_ASUS_MODE8, .name = "asus-mode8"},
6860 {.id = ALC662_FIXUP_INV_DMIC, .name = "inv-dmic"},
6861 {.id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE, .name = "dell-headset-multi"},
6862 {}
6863 };
6864
6865 static const struct snd_hda_pin_quirk alc662_pin_fixup_tbl[] = {
6866 SND_HDA_PIN_QUIRK(0x10ec0662, 0x1028, "Dell", ALC662_FIXUP_DELL_MIC_NO_PRESENCE,
6867 {0x12, 0x4004c000},
6868 {0x14, 0x01014010},
6869 {0x15, 0x411111f0},
6870 {0x16, 0x411111f0},
6871 {0x18, 0x01a19020},
6872 {0x19, 0x411111f0},
6873 {0x1a, 0x0181302f},
6874 {0x1b, 0x0221401f},
6875 {0x1c, 0x411111f0},
6876 {0x1d, 0x4054c601},
6877 {0x1e, 0x411111f0}),
6878 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
6879 {0x12, 0x99a30130},
6880 {0x14, 0x90170110},
6881 {0x15, 0x0321101f},
6882 {0x16, 0x03011020},
6883 {0x18, 0x40000008},
6884 {0x19, 0x411111f0},
6885 {0x1a, 0x411111f0},
6886 {0x1b, 0x411111f0},
6887 {0x1d, 0x41000001},
6888 {0x1e, 0x411111f0},
6889 {0x1f, 0x411111f0}),
6890 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
6891 {0x12, 0x99a30140},
6892 {0x14, 0x90170110},
6893 {0x15, 0x0321101f},
6894 {0x16, 0x03011020},
6895 {0x18, 0x40000008},
6896 {0x19, 0x411111f0},
6897 {0x1a, 0x411111f0},
6898 {0x1b, 0x411111f0},
6899 {0x1d, 0x41000001},
6900 {0x1e, 0x411111f0},
6901 {0x1f, 0x411111f0}),
6902 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
6903 {0x12, 0x99a30150},
6904 {0x14, 0x90170110},
6905 {0x15, 0x0321101f},
6906 {0x16, 0x03011020},
6907 {0x18, 0x40000008},
6908 {0x19, 0x411111f0},
6909 {0x1a, 0x411111f0},
6910 {0x1b, 0x411111f0},
6911 {0x1d, 0x41000001},
6912 {0x1e, 0x411111f0},
6913 {0x1f, 0x411111f0}),
6914 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
6915 {0x12, 0x411111f0},
6916 {0x14, 0x90170110},
6917 {0x15, 0x0321101f},
6918 {0x16, 0x03011020},
6919 {0x18, 0x40000008},
6920 {0x19, 0x411111f0},
6921 {0x1a, 0x411111f0},
6922 {0x1b, 0x411111f0},
6923 {0x1d, 0x41000001},
6924 {0x1e, 0x411111f0},
6925 {0x1f, 0x411111f0}),
6926 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell XPS 15", ALC668_FIXUP_AUTO_MUTE,
6927 {0x12, 0x90a60130},
6928 {0x14, 0x90170110},
6929 {0x15, 0x0321101f},
6930 {0x16, 0x40000000},
6931 {0x18, 0x411111f0},
6932 {0x19, 0x411111f0},
6933 {0x1a, 0x411111f0},
6934 {0x1b, 0x411111f0},
6935 {0x1d, 0x40d6832d},
6936 {0x1e, 0x411111f0},
6937 {0x1f, 0x411111f0}),
6938 {}
6939 };
6940
6941 /*
6942 */
patch_alc662(struct hda_codec * codec)6943 static int patch_alc662(struct hda_codec *codec)
6944 {
6945 struct alc_spec *spec;
6946 int err;
6947
6948 err = alc_alloc_spec(codec, 0x0b);
6949 if (err < 0)
6950 return err;
6951
6952 spec = codec->spec;
6953
6954 /* handle multiple HPs as is */
6955 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
6956
6957 alc_fix_pll_init(codec, 0x20, 0x04, 15);
6958
6959 switch (codec->vendor_id) {
6960 case 0x10ec0668:
6961 spec->init_hook = alc668_restore_default_value;
6962 break;
6963 }
6964
6965 snd_hda_pick_fixup(codec, alc662_fixup_models,
6966 alc662_fixup_tbl, alc662_fixups);
6967 snd_hda_pick_pin_fixup(codec, alc662_pin_fixup_tbl, alc662_fixups);
6968 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
6969
6970 alc_auto_parse_customize_define(codec);
6971
6972 if (has_cdefine_beep(codec))
6973 spec->gen.beep_nid = 0x01;
6974
6975 if ((alc_get_coef0(codec) & (1 << 14)) &&
6976 codec->bus->pci && codec->bus->pci->subsystem_vendor == 0x1025 &&
6977 spec->cdefine.platform_type == 1) {
6978 err = alc_codec_rename(codec, "ALC272X");
6979 if (err < 0)
6980 goto error;
6981 }
6982
6983 /* automatic parse from the BIOS config */
6984 err = alc662_parse_auto_config(codec);
6985 if (err < 0)
6986 goto error;
6987
6988 if (!spec->gen.no_analog && spec->gen.beep_nid) {
6989 switch (codec->vendor_id) {
6990 case 0x10ec0662:
6991 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
6992 break;
6993 case 0x10ec0272:
6994 case 0x10ec0663:
6995 case 0x10ec0665:
6996 case 0x10ec0668:
6997 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
6998 break;
6999 case 0x10ec0273:
7000 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
7001 break;
7002 }
7003 }
7004
7005 codec->patch_ops = alc_patch_ops;
7006 spec->shutup = alc_eapd_shutup;
7007
7008 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
7009
7010 return 0;
7011
7012 error:
7013 alc_free(codec);
7014 return err;
7015 }
7016
7017 /*
7018 * ALC680 support
7019 */
7020
alc680_parse_auto_config(struct hda_codec * codec)7021 static int alc680_parse_auto_config(struct hda_codec *codec)
7022 {
7023 return alc_parse_auto_config(codec, NULL, NULL);
7024 }
7025
7026 /*
7027 */
patch_alc680(struct hda_codec * codec)7028 static int patch_alc680(struct hda_codec *codec)
7029 {
7030 int err;
7031
7032 /* ALC680 has no aa-loopback mixer */
7033 err = alc_alloc_spec(codec, 0);
7034 if (err < 0)
7035 return err;
7036
7037 /* automatic parse from the BIOS config */
7038 err = alc680_parse_auto_config(codec);
7039 if (err < 0) {
7040 alc_free(codec);
7041 return err;
7042 }
7043
7044 codec->patch_ops = alc_patch_ops;
7045
7046 return 0;
7047 }
7048
7049 /*
7050 * patch entries
7051 */
7052 static const struct hda_codec_preset snd_hda_preset_realtek[] = {
7053 { .id = 0x10ec0221, .name = "ALC221", .patch = patch_alc269 },
7054 { .id = 0x10ec0231, .name = "ALC231", .patch = patch_alc269 },
7055 { .id = 0x10ec0233, .name = "ALC233", .patch = patch_alc269 },
7056 { .id = 0x10ec0235, .name = "ALC233", .patch = patch_alc269 },
7057 { .id = 0x10ec0255, .name = "ALC255", .patch = patch_alc269 },
7058 { .id = 0x10ec0256, .name = "ALC256", .patch = patch_alc269 },
7059 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
7060 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
7061 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
7062 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
7063 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
7064 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 },
7065 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
7066 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
7067 { .id = 0x10ec0276, .name = "ALC276", .patch = patch_alc269 },
7068 { .id = 0x10ec0280, .name = "ALC280", .patch = patch_alc269 },
7069 { .id = 0x10ec0282, .name = "ALC282", .patch = patch_alc269 },
7070 { .id = 0x10ec0283, .name = "ALC283", .patch = patch_alc269 },
7071 { .id = 0x10ec0284, .name = "ALC284", .patch = patch_alc269 },
7072 { .id = 0x10ec0285, .name = "ALC285", .patch = patch_alc269 },
7073 { .id = 0x10ec0286, .name = "ALC286", .patch = patch_alc269 },
7074 { .id = 0x10ec0288, .name = "ALC288", .patch = patch_alc269 },
7075 { .id = 0x10ec0290, .name = "ALC290", .patch = patch_alc269 },
7076 { .id = 0x10ec0292, .name = "ALC292", .patch = patch_alc269 },
7077 { .id = 0x10ec0293, .name = "ALC293", .patch = patch_alc269 },
7078 { .id = 0x10ec0298, .name = "ALC298", .patch = patch_alc269 },
7079 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
7080 .patch = patch_alc861 },
7081 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
7082 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
7083 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
7084 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
7085 .patch = patch_alc882 },
7086 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
7087 .patch = patch_alc662 },
7088 { .id = 0x10ec0662, .rev = 0x100300, .name = "ALC662 rev3",
7089 .patch = patch_alc662 },
7090 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
7091 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
7092 { .id = 0x10ec0667, .name = "ALC667", .patch = patch_alc662 },
7093 { .id = 0x10ec0668, .name = "ALC668", .patch = patch_alc662 },
7094 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
7095 { .id = 0x10ec0671, .name = "ALC671", .patch = patch_alc662 },
7096 { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 },
7097 { .id = 0x10ec0867, .name = "ALC891", .patch = patch_alc882 },
7098 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
7099 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
7100 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
7101 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
7102 .patch = patch_alc882 },
7103 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
7104 .patch = patch_alc882 },
7105 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
7106 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 },
7107 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
7108 .patch = patch_alc882 },
7109 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc882 },
7110 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
7111 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
7112 { .id = 0x10ec0899, .name = "ALC898", .patch = patch_alc882 },
7113 { .id = 0x10ec0900, .name = "ALC1150", .patch = patch_alc882 },
7114 {} /* terminator */
7115 };
7116
7117 MODULE_ALIAS("snd-hda-codec-id:10ec*");
7118
7119 MODULE_LICENSE("GPL");
7120 MODULE_DESCRIPTION("Realtek HD-audio codec");
7121
7122 static struct hda_codec_preset_list realtek_list = {
7123 .preset = snd_hda_preset_realtek,
7124 .owner = THIS_MODULE,
7125 };
7126
patch_realtek_init(void)7127 static int __init patch_realtek_init(void)
7128 {
7129 return snd_hda_add_codec_preset(&realtek_list);
7130 }
7131
patch_realtek_exit(void)7132 static void __exit patch_realtek_exit(void)
7133 {
7134 snd_hda_delete_codec_preset(&realtek_list);
7135 }
7136
7137 module_init(patch_realtek_init)
7138 module_exit(patch_realtek_exit)
7139