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