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