1
2
3
4
5
6
7
8
9
10
11
12
13#include <linux/init.h>
14#include <linux/delay.h>
15#include <linux/slab.h>
16#include <linux/pci.h>
17#include <linux/dmi.h>
18#include <linux/module.h>
19#include <linux/input.h>
20#include <sound/core.h>
21#include <sound/jack.h>
22#include <sound/hda_codec.h>
23#include "hda_local.h"
24#include "hda_auto_parser.h"
25#include "hda_jack.h"
26#include "hda_generic.h"
27
28
29#define HALT_REALTEK_ALC5505
30
31
32enum {
33 ALC_INIT_UNDEFINED,
34 ALC_INIT_NONE,
35 ALC_INIT_DEFAULT,
36};
37
38enum {
39 ALC_HEADSET_MODE_UNKNOWN,
40 ALC_HEADSET_MODE_UNPLUGGED,
41 ALC_HEADSET_MODE_HEADSET,
42 ALC_HEADSET_MODE_MIC,
43 ALC_HEADSET_MODE_HEADPHONE,
44};
45
46enum {
47 ALC_HEADSET_TYPE_UNKNOWN,
48 ALC_HEADSET_TYPE_CTIA,
49 ALC_HEADSET_TYPE_OMTP,
50};
51
52enum {
53 ALC_KEY_MICMUTE_INDEX,
54};
55
56struct alc_customize_define {
57 unsigned int sku_cfg;
58 unsigned char port_connectivity;
59 unsigned char check_sum;
60 unsigned char customization;
61 unsigned char external_amp;
62 unsigned int enable_pcbeep:1;
63 unsigned int platform_type:1;
64 unsigned int swap:1;
65 unsigned int override:1;
66 unsigned int fixup:1;
67};
68
69struct alc_spec {
70 struct hda_gen_spec gen;
71
72
73 struct alc_customize_define cdefine;
74 unsigned int parse_flags;
75
76
77 unsigned int gpio_mask;
78 unsigned int gpio_dir;
79 unsigned int gpio_data;
80 bool gpio_write_delay;
81
82
83 int mute_led_polarity;
84 hda_nid_t mute_led_nid;
85 hda_nid_t cap_mute_led_nid;
86
87 unsigned int gpio_mute_led_mask;
88 unsigned int gpio_mic_led_mask;
89
90 hda_nid_t headset_mic_pin;
91 hda_nid_t headphone_mic_pin;
92 int current_headset_mode;
93 int current_headset_type;
94
95
96 void (*init_hook)(struct hda_codec *codec);
97#ifdef CONFIG_PM
98 void (*power_hook)(struct hda_codec *codec);
99#endif
100 void (*shutup)(struct hda_codec *codec);
101 void (*reboot_notify)(struct hda_codec *codec);
102
103 int init_amp;
104 int codec_variant;
105 unsigned int has_alc5505_dsp:1;
106 unsigned int no_depop_delay:1;
107 unsigned int done_hp_init:1;
108 unsigned int no_shutup_pins:1;
109 unsigned int ultra_low_power:1;
110
111
112 hda_nid_t pll_nid;
113 unsigned int pll_coef_idx, pll_coef_bit;
114 unsigned int coef0;
115 struct input_dev *kb_dev;
116 u8 alc_mute_keycode_map[1];
117};
118
119
120
121
122
123static int alc_read_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
124 unsigned int coef_idx)
125{
126 unsigned int val;
127
128 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, coef_idx);
129 val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PROC_COEF, 0);
130 return val;
131}
132
133#define alc_read_coef_idx(codec, coef_idx) \
134 alc_read_coefex_idx(codec, 0x20, coef_idx)
135
136static void alc_write_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
137 unsigned int coef_idx, unsigned int coef_val)
138{
139 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, coef_idx);
140 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PROC_COEF, coef_val);
141}
142
143#define alc_write_coef_idx(codec, coef_idx, coef_val) \
144 alc_write_coefex_idx(codec, 0x20, coef_idx, coef_val)
145
146static void alc_update_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
147 unsigned int coef_idx, unsigned int mask,
148 unsigned int bits_set)
149{
150 unsigned int val = alc_read_coefex_idx(codec, nid, coef_idx);
151
152 if (val != -1)
153 alc_write_coefex_idx(codec, nid, coef_idx,
154 (val & ~mask) | bits_set);
155}
156
157#define alc_update_coef_idx(codec, coef_idx, mask, bits_set) \
158 alc_update_coefex_idx(codec, 0x20, coef_idx, mask, bits_set)
159
160
161static unsigned int alc_get_coef0(struct hda_codec *codec)
162{
163 struct alc_spec *spec = codec->spec;
164
165 if (!spec->coef0)
166 spec->coef0 = alc_read_coef_idx(codec, 0);
167 return spec->coef0;
168}
169
170
171struct coef_fw {
172 unsigned char nid;
173 unsigned char idx;
174 unsigned short mask;
175 unsigned short val;
176};
177
178#define UPDATE_COEFEX(_nid, _idx, _mask, _val) \
179 { .nid = (_nid), .idx = (_idx), .mask = (_mask), .val = (_val) }
180#define WRITE_COEFEX(_nid, _idx, _val) UPDATE_COEFEX(_nid, _idx, -1, _val)
181#define WRITE_COEF(_idx, _val) WRITE_COEFEX(0x20, _idx, _val)
182#define UPDATE_COEF(_idx, _mask, _val) UPDATE_COEFEX(0x20, _idx, _mask, _val)
183
184static void alc_process_coef_fw(struct hda_codec *codec,
185 const struct coef_fw *fw)
186{
187 for (; fw->nid; fw++) {
188 if (fw->mask == (unsigned short)-1)
189 alc_write_coefex_idx(codec, fw->nid, fw->idx, fw->val);
190 else
191 alc_update_coefex_idx(codec, fw->nid, fw->idx,
192 fw->mask, fw->val);
193 }
194}
195
196
197
198
199
200
201static void alc_setup_gpio(struct hda_codec *codec, unsigned int mask)
202{
203 struct alc_spec *spec = codec->spec;
204
205 spec->gpio_mask |= mask;
206 spec->gpio_dir |= mask;
207 spec->gpio_data |= mask;
208}
209
210static void alc_write_gpio_data(struct hda_codec *codec)
211{
212 struct alc_spec *spec = codec->spec;
213
214 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
215 spec->gpio_data);
216}
217
218static void alc_update_gpio_data(struct hda_codec *codec, unsigned int mask,
219 bool on)
220{
221 struct alc_spec *spec = codec->spec;
222 unsigned int oldval = spec->gpio_data;
223
224 if (on)
225 spec->gpio_data |= mask;
226 else
227 spec->gpio_data &= ~mask;
228 if (oldval != spec->gpio_data)
229 alc_write_gpio_data(codec);
230}
231
232static void alc_write_gpio(struct hda_codec *codec)
233{
234 struct alc_spec *spec = codec->spec;
235
236 if (!spec->gpio_mask)
237 return;
238
239 snd_hda_codec_write(codec, codec->core.afg, 0,
240 AC_VERB_SET_GPIO_MASK, spec->gpio_mask);
241 snd_hda_codec_write(codec, codec->core.afg, 0,
242 AC_VERB_SET_GPIO_DIRECTION, spec->gpio_dir);
243 if (spec->gpio_write_delay)
244 msleep(1);
245 alc_write_gpio_data(codec);
246}
247
248static void alc_fixup_gpio(struct hda_codec *codec, int action,
249 unsigned int mask)
250{
251 if (action == HDA_FIXUP_ACT_PRE_PROBE)
252 alc_setup_gpio(codec, mask);
253}
254
255static void alc_fixup_gpio1(struct hda_codec *codec,
256 const struct hda_fixup *fix, int action)
257{
258 alc_fixup_gpio(codec, action, 0x01);
259}
260
261static void alc_fixup_gpio2(struct hda_codec *codec,
262 const struct hda_fixup *fix, int action)
263{
264 alc_fixup_gpio(codec, action, 0x02);
265}
266
267static void alc_fixup_gpio3(struct hda_codec *codec,
268 const struct hda_fixup *fix, int action)
269{
270 alc_fixup_gpio(codec, action, 0x03);
271}
272
273static void alc_fixup_gpio4(struct hda_codec *codec,
274 const struct hda_fixup *fix, int action)
275{
276 alc_fixup_gpio(codec, action, 0x04);
277}
278
279
280
281
282
283
284static void alc_fix_pll(struct hda_codec *codec)
285{
286 struct alc_spec *spec = codec->spec;
287
288 if (spec->pll_nid)
289 alc_update_coefex_idx(codec, spec->pll_nid, spec->pll_coef_idx,
290 1 << spec->pll_coef_bit, 0);
291}
292
293static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
294 unsigned int coef_idx, unsigned int coef_bit)
295{
296 struct alc_spec *spec = codec->spec;
297 spec->pll_nid = nid;
298 spec->pll_coef_idx = coef_idx;
299 spec->pll_coef_bit = coef_bit;
300 alc_fix_pll(codec);
301}
302
303
304static void alc_update_knob_master(struct hda_codec *codec,
305 struct hda_jack_callback *jack)
306{
307 unsigned int val;
308 struct snd_kcontrol *kctl;
309 struct snd_ctl_elem_value *uctl;
310
311 kctl = snd_hda_find_mixer_ctl(codec, "Master Playback Volume");
312 if (!kctl)
313 return;
314 uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
315 if (!uctl)
316 return;
317 val = snd_hda_codec_read(codec, jack->nid, 0,
318 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
319 val &= HDA_AMP_VOLMASK;
320 uctl->value.integer.value[0] = val;
321 uctl->value.integer.value[1] = val;
322 kctl->put(kctl, uctl);
323 kfree(uctl);
324}
325
326static void alc880_unsol_event(struct hda_codec *codec, unsigned int res)
327{
328
329
330 snd_hda_jack_unsol_event(codec, res >> 2);
331}
332
333
334static void alc_fill_eapd_coef(struct hda_codec *codec)
335{
336 int coef;
337
338 coef = alc_get_coef0(codec);
339
340 switch (codec->core.vendor_id) {
341 case 0x10ec0262:
342 alc_update_coef_idx(codec, 0x7, 0, 1<<5);
343 break;
344 case 0x10ec0267:
345 case 0x10ec0268:
346 alc_update_coef_idx(codec, 0x7, 0, 1<<13);
347 break;
348 case 0x10ec0269:
349 if ((coef & 0x00f0) == 0x0010)
350 alc_update_coef_idx(codec, 0xd, 0, 1<<14);
351 if ((coef & 0x00f0) == 0x0020)
352 alc_update_coef_idx(codec, 0x4, 1<<15, 0);
353 if ((coef & 0x00f0) == 0x0030)
354 alc_update_coef_idx(codec, 0x10, 1<<9, 0);
355 break;
356 case 0x10ec0280:
357 case 0x10ec0284:
358 case 0x10ec0290:
359 case 0x10ec0292:
360 alc_update_coef_idx(codec, 0x4, 1<<15, 0);
361 break;
362 case 0x10ec0225:
363 case 0x10ec0295:
364 case 0x10ec0299:
365 alc_update_coef_idx(codec, 0x67, 0xf000, 0x3000);
366
367 case 0x10ec0215:
368 case 0x10ec0233:
369 case 0x10ec0235:
370 case 0x10ec0236:
371 case 0x10ec0255:
372 case 0x10ec0256:
373 case 0x10ec0257:
374 case 0x10ec0282:
375 case 0x10ec0283:
376 case 0x10ec0286:
377 case 0x10ec0288:
378 case 0x10ec0285:
379 case 0x10ec0298:
380 case 0x10ec0289:
381 case 0x10ec0300:
382 alc_update_coef_idx(codec, 0x10, 1<<9, 0);
383 break;
384 case 0x10ec0275:
385 alc_update_coef_idx(codec, 0xe, 0, 1<<0);
386 break;
387 case 0x10ec0293:
388 alc_update_coef_idx(codec, 0xa, 1<<13, 0);
389 break;
390 case 0x10ec0234:
391 case 0x10ec0274:
392 case 0x10ec0294:
393 case 0x10ec0700:
394 case 0x10ec0701:
395 case 0x10ec0703:
396 case 0x10ec0711:
397 alc_update_coef_idx(codec, 0x10, 1<<15, 0);
398 break;
399 case 0x10ec0662:
400 if ((coef & 0x00f0) == 0x0030)
401 alc_update_coef_idx(codec, 0x4, 1<<10, 0);
402 break;
403 case 0x10ec0272:
404 case 0x10ec0273:
405 case 0x10ec0663:
406 case 0x10ec0665:
407 case 0x10ec0670:
408 case 0x10ec0671:
409 case 0x10ec0672:
410 alc_update_coef_idx(codec, 0xd, 0, 1<<14);
411 break;
412 case 0x10ec0623:
413 alc_update_coef_idx(codec, 0x19, 1<<13, 0);
414 break;
415 case 0x10ec0668:
416 alc_update_coef_idx(codec, 0x7, 3<<13, 0);
417 break;
418 case 0x10ec0867:
419 alc_update_coef_idx(codec, 0x4, 1<<10, 0);
420 break;
421 case 0x10ec0888:
422 if ((coef & 0x00f0) == 0x0020 || (coef & 0x00f0) == 0x0030)
423 alc_update_coef_idx(codec, 0x7, 1<<5, 0);
424 break;
425 case 0x10ec0892:
426 alc_update_coef_idx(codec, 0x7, 1<<5, 0);
427 break;
428 case 0x10ec0899:
429 case 0x10ec0900:
430 case 0x10ec1168:
431 case 0x10ec1220:
432 alc_update_coef_idx(codec, 0x7, 1<<1, 0);
433 break;
434 }
435}
436
437
438static void alc888_coef_init(struct hda_codec *codec)
439{
440 switch (alc_get_coef0(codec) & 0x00f0) {
441
442 case 0x00:
443
444 case 0x10:
445 alc_update_coef_idx(codec, 7, 0, 0x2030);
446 break;
447 }
448}
449
450
451static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
452{
453 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
454 return;
455 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
456 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
457 on ? 2 : 0);
458}
459
460
461static void alc_auto_setup_eapd(struct hda_codec *codec, bool on)
462{
463
464 static hda_nid_t pins[] = {
465 0x0f, 0x10, 0x14, 0x15, 0x17, 0
466 };
467 hda_nid_t *p;
468 for (p = pins; *p; p++)
469 set_eapd(codec, *p, on);
470}
471
472static int find_ext_mic_pin(struct hda_codec *codec);
473
474static void alc_headset_mic_no_shutup(struct hda_codec *codec)
475{
476 const struct hda_pincfg *pin;
477 int mic_pin = find_ext_mic_pin(codec);
478 int i;
479
480
481
482
483 if (codec->bus->shutdown)
484 return;
485
486 snd_array_for_each(&codec->init_pins, i, pin) {
487
488 if (pin->nid != mic_pin)
489 snd_hda_codec_read(codec, pin->nid, 0,
490 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
491 }
492
493 codec->pins_shutup = 1;
494}
495
496static void alc_shutup_pins(struct hda_codec *codec)
497{
498 struct alc_spec *spec = codec->spec;
499
500 switch (codec->core.vendor_id) {
501 case 0x10ec0286:
502 case 0x10ec0288:
503 case 0x10ec0298:
504 alc_headset_mic_no_shutup(codec);
505 break;
506 default:
507 if (!spec->no_shutup_pins)
508 snd_hda_shutup_pins(codec);
509 break;
510 }
511}
512
513
514
515
516static void alc_eapd_shutup(struct hda_codec *codec)
517{
518 struct alc_spec *spec = codec->spec;
519
520 alc_auto_setup_eapd(codec, false);
521 if (!spec->no_depop_delay)
522 msleep(200);
523 alc_shutup_pins(codec);
524}
525
526
527static void alc_auto_init_amp(struct hda_codec *codec, int type)
528{
529 alc_auto_setup_eapd(codec, true);
530 alc_write_gpio(codec);
531 switch (type) {
532 case ALC_INIT_DEFAULT:
533 switch (codec->core.vendor_id) {
534 case 0x10ec0260:
535 alc_update_coefex_idx(codec, 0x1a, 7, 0, 0x2010);
536 break;
537 case 0x10ec0880:
538 case 0x10ec0882:
539 case 0x10ec0883:
540 case 0x10ec0885:
541 alc_update_coef_idx(codec, 7, 0, 0x2030);
542 break;
543 case 0x10ec0888:
544 alc888_coef_init(codec);
545 break;
546 }
547 break;
548 }
549}
550
551
552static hda_nid_t alc_get_hp_pin(struct alc_spec *spec)
553{
554 if (spec->gen.autocfg.hp_pins[0])
555 return spec->gen.autocfg.hp_pins[0];
556 if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
557 return spec->gen.autocfg.line_out_pins[0];
558 return 0;
559}
560
561
562
563
564
565
566
567
568#define ALC_FIXUP_SKU_IGNORE (2)
569
570static void alc_fixup_sku_ignore(struct hda_codec *codec,
571 const struct hda_fixup *fix, int action)
572{
573 struct alc_spec *spec = codec->spec;
574 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
575 spec->cdefine.fixup = 1;
576 spec->cdefine.sku_cfg = ALC_FIXUP_SKU_IGNORE;
577 }
578}
579
580static void alc_fixup_no_depop_delay(struct hda_codec *codec,
581 const struct hda_fixup *fix, int action)
582{
583 struct alc_spec *spec = codec->spec;
584
585 if (action == HDA_FIXUP_ACT_PROBE) {
586 spec->no_depop_delay = 1;
587 codec->depop_delay = 0;
588 }
589}
590
591static int alc_auto_parse_customize_define(struct hda_codec *codec)
592{
593 unsigned int ass, tmp, i;
594 unsigned nid = 0;
595 struct alc_spec *spec = codec->spec;
596
597 spec->cdefine.enable_pcbeep = 1;
598
599 if (spec->cdefine.fixup) {
600 ass = spec->cdefine.sku_cfg;
601 if (ass == ALC_FIXUP_SKU_IGNORE)
602 return -1;
603 goto do_sku;
604 }
605
606 if (!codec->bus->pci)
607 return -1;
608 ass = codec->core.subsystem_id & 0xffff;
609 if (ass != codec->bus->pci->subsystem_device && (ass & 1))
610 goto do_sku;
611
612 nid = 0x1d;
613 if (codec->core.vendor_id == 0x10ec0260)
614 nid = 0x17;
615 ass = snd_hda_codec_get_pincfg(codec, nid);
616
617 if (!(ass & 1)) {
618 codec_info(codec, "%s: SKU not ready 0x%08x\n",
619 codec->core.chip_name, ass);
620 return -1;
621 }
622
623
624 tmp = 0;
625 for (i = 1; i < 16; i++) {
626 if ((ass >> i) & 1)
627 tmp++;
628 }
629 if (((ass >> 16) & 0xf) != tmp)
630 return -1;
631
632 spec->cdefine.port_connectivity = ass >> 30;
633 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
634 spec->cdefine.check_sum = (ass >> 16) & 0xf;
635 spec->cdefine.customization = ass >> 8;
636do_sku:
637 spec->cdefine.sku_cfg = ass;
638 spec->cdefine.external_amp = (ass & 0x38) >> 3;
639 spec->cdefine.platform_type = (ass & 0x4) >> 2;
640 spec->cdefine.swap = (ass & 0x2) >> 1;
641 spec->cdefine.override = ass & 0x1;
642
643 codec_dbg(codec, "SKU: Nid=0x%x sku_cfg=0x%08x\n",
644 nid, spec->cdefine.sku_cfg);
645 codec_dbg(codec, "SKU: port_connectivity=0x%x\n",
646 spec->cdefine.port_connectivity);
647 codec_dbg(codec, "SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
648 codec_dbg(codec, "SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
649 codec_dbg(codec, "SKU: customization=0x%08x\n", spec->cdefine.customization);
650 codec_dbg(codec, "SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
651 codec_dbg(codec, "SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
652 codec_dbg(codec, "SKU: swap=0x%x\n", spec->cdefine.swap);
653 codec_dbg(codec, "SKU: override=0x%x\n", spec->cdefine.override);
654
655 return 0;
656}
657
658
659static int find_idx_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
660{
661 int i;
662 for (i = 0; i < nums; i++)
663 if (list[i] == nid)
664 return i;
665 return -1;
666}
667
668static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
669{
670 return find_idx_in_nid_list(nid, list, nums) >= 0;
671}
672
673
674
675
676
677
678
679
680
681
682static int alc_subsystem_id(struct hda_codec *codec, const hda_nid_t *ports)
683{
684 unsigned int ass, tmp, i;
685 unsigned nid;
686 struct alc_spec *spec = codec->spec;
687
688 if (spec->cdefine.fixup) {
689 ass = spec->cdefine.sku_cfg;
690 if (ass == ALC_FIXUP_SKU_IGNORE)
691 return 0;
692 goto do_sku;
693 }
694
695 ass = codec->core.subsystem_id & 0xffff;
696 if (codec->bus->pci &&
697 ass != codec->bus->pci->subsystem_device && (ass & 1))
698 goto do_sku;
699
700
701
702
703
704
705
706
707
708
709 nid = 0x1d;
710 if (codec->core.vendor_id == 0x10ec0260)
711 nid = 0x17;
712 ass = snd_hda_codec_get_pincfg(codec, nid);
713 codec_dbg(codec,
714 "realtek: No valid SSID, checking pincfg 0x%08x for NID 0x%x\n",
715 ass, nid);
716 if (!(ass & 1))
717 return 0;
718 if ((ass >> 30) != 1)
719 return 0;
720
721
722 tmp = 0;
723 for (i = 1; i < 16; i++) {
724 if ((ass >> i) & 1)
725 tmp++;
726 }
727 if (((ass >> 16) & 0xf) != tmp)
728 return 0;
729do_sku:
730 codec_dbg(codec, "realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
731 ass & 0xffff, codec->core.vendor_id);
732
733
734
735
736
737
738
739 tmp = (ass & 0x38) >> 3;
740 if (spec->init_amp == ALC_INIT_UNDEFINED) {
741 switch (tmp) {
742 case 1:
743 alc_setup_gpio(codec, 0x01);
744 break;
745 case 3:
746 alc_setup_gpio(codec, 0x02);
747 break;
748 case 7:
749 alc_setup_gpio(codec, 0x03);
750 break;
751 case 5:
752 default:
753 spec->init_amp = ALC_INIT_DEFAULT;
754 break;
755 }
756 }
757
758
759
760
761 if (!(ass & 0x8000))
762 return 1;
763
764
765
766
767
768
769
770 if (!alc_get_hp_pin(spec)) {
771 hda_nid_t nid;
772 tmp = (ass >> 11) & 0x3;
773 nid = ports[tmp];
774 if (found_in_nid_list(nid, spec->gen.autocfg.line_out_pins,
775 spec->gen.autocfg.line_outs))
776 return 1;
777 spec->gen.autocfg.hp_pins[0] = nid;
778 }
779 return 1;
780}
781
782
783
784static void alc_ssid_check(struct hda_codec *codec, const hda_nid_t *ports)
785{
786 if (!alc_subsystem_id(codec, ports)) {
787 struct alc_spec *spec = codec->spec;
788 codec_dbg(codec,
789 "realtek: Enable default setup for auto mode as fallback\n");
790 spec->init_amp = ALC_INIT_DEFAULT;
791 }
792}
793
794
795
796
797static void alc_fixup_inv_dmic(struct hda_codec *codec,
798 const struct hda_fixup *fix, int action)
799{
800 struct alc_spec *spec = codec->spec;
801
802 spec->gen.inv_dmic_split = 1;
803}
804
805
806static int alc_build_controls(struct hda_codec *codec)
807{
808 int err;
809
810 err = snd_hda_gen_build_controls(codec);
811 if (err < 0)
812 return err;
813
814 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_BUILD);
815 return 0;
816}
817
818
819
820
821
822
823static void alc_pre_init(struct hda_codec *codec)
824{
825 alc_fill_eapd_coef(codec);
826}
827
828#define is_s3_resume(codec) \
829 ((codec)->core.dev.power.power_state.event == PM_EVENT_RESUME)
830#define is_s4_resume(codec) \
831 ((codec)->core.dev.power.power_state.event == PM_EVENT_RESTORE)
832
833static int alc_init(struct hda_codec *codec)
834{
835 struct alc_spec *spec = codec->spec;
836
837
838 if (is_s4_resume(codec))
839 alc_pre_init(codec);
840
841 if (spec->init_hook)
842 spec->init_hook(codec);
843
844 spec->gen.skip_verbs = 1;
845 snd_hda_gen_init(codec);
846 alc_fix_pll(codec);
847 alc_auto_init_amp(codec, spec->init_amp);
848 snd_hda_apply_verbs(codec);
849
850 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_INIT);
851
852 return 0;
853}
854
855static inline void alc_shutup(struct hda_codec *codec)
856{
857 struct alc_spec *spec = codec->spec;
858
859 if (!snd_hda_get_bool_hint(codec, "shutup"))
860 return;
861
862 if (spec && spec->shutup)
863 spec->shutup(codec);
864 else
865 alc_shutup_pins(codec);
866}
867
868static void alc_reboot_notify(struct hda_codec *codec)
869{
870 struct alc_spec *spec = codec->spec;
871
872 if (spec && spec->reboot_notify)
873 spec->reboot_notify(codec);
874 else
875 alc_shutup(codec);
876}
877
878#define alc_free snd_hda_gen_free
879
880#ifdef CONFIG_PM
881static void alc_power_eapd(struct hda_codec *codec)
882{
883 alc_auto_setup_eapd(codec, false);
884}
885
886static int alc_suspend(struct hda_codec *codec)
887{
888 struct alc_spec *spec = codec->spec;
889 alc_shutup(codec);
890 if (spec && spec->power_hook)
891 spec->power_hook(codec);
892 return 0;
893}
894#endif
895
896#ifdef CONFIG_PM
897static int alc_resume(struct hda_codec *codec)
898{
899 struct alc_spec *spec = codec->spec;
900
901 if (!spec->no_depop_delay)
902 msleep(150);
903 codec->patch_ops.init(codec);
904 regcache_sync(codec->core.regmap);
905 hda_call_check_power_status(codec, 0x01);
906 return 0;
907}
908#endif
909
910
911
912static const struct hda_codec_ops alc_patch_ops = {
913 .build_controls = alc_build_controls,
914 .build_pcms = snd_hda_gen_build_pcms,
915 .init = alc_init,
916 .free = alc_free,
917 .unsol_event = snd_hda_jack_unsol_event,
918#ifdef CONFIG_PM
919 .resume = alc_resume,
920 .suspend = alc_suspend,
921 .check_power_status = snd_hda_gen_check_power_status,
922#endif
923 .reboot_notify = alc_reboot_notify,
924};
925
926
927#define alc_codec_rename(codec, name) snd_hda_codec_set_name(codec, name)
928
929
930
931
932struct alc_codec_rename_table {
933 unsigned int vendor_id;
934 unsigned short coef_mask;
935 unsigned short coef_bits;
936 const char *name;
937};
938
939struct alc_codec_rename_pci_table {
940 unsigned int codec_vendor_id;
941 unsigned short pci_subvendor;
942 unsigned short pci_subdevice;
943 const char *name;
944};
945
946static struct alc_codec_rename_table rename_tbl[] = {
947 { 0x10ec0221, 0xf00f, 0x1003, "ALC231" },
948 { 0x10ec0269, 0xfff0, 0x3010, "ALC277" },
949 { 0x10ec0269, 0xf0f0, 0x2010, "ALC259" },
950 { 0x10ec0269, 0xf0f0, 0x3010, "ALC258" },
951 { 0x10ec0269, 0x00f0, 0x0010, "ALC269VB" },
952 { 0x10ec0269, 0xffff, 0xa023, "ALC259" },
953 { 0x10ec0269, 0xffff, 0x6023, "ALC281X" },
954 { 0x10ec0269, 0x00f0, 0x0020, "ALC269VC" },
955 { 0x10ec0269, 0x00f0, 0x0030, "ALC269VD" },
956 { 0x10ec0662, 0xffff, 0x4020, "ALC656" },
957 { 0x10ec0887, 0x00f0, 0x0030, "ALC887-VD" },
958 { 0x10ec0888, 0x00f0, 0x0030, "ALC888-VD" },
959 { 0x10ec0888, 0xf0f0, 0x3020, "ALC886" },
960 { 0x10ec0899, 0x2000, 0x2000, "ALC899" },
961 { 0x10ec0892, 0xffff, 0x8020, "ALC661" },
962 { 0x10ec0892, 0xffff, 0x8011, "ALC661" },
963 { 0x10ec0892, 0xffff, 0x4011, "ALC656" },
964 { }
965};
966
967static struct alc_codec_rename_pci_table rename_pci_tbl[] = {
968 { 0x10ec0280, 0x1028, 0, "ALC3220" },
969 { 0x10ec0282, 0x1028, 0, "ALC3221" },
970 { 0x10ec0283, 0x1028, 0, "ALC3223" },
971 { 0x10ec0288, 0x1028, 0, "ALC3263" },
972 { 0x10ec0292, 0x1028, 0, "ALC3226" },
973 { 0x10ec0293, 0x1028, 0, "ALC3235" },
974 { 0x10ec0255, 0x1028, 0, "ALC3234" },
975 { 0x10ec0668, 0x1028, 0, "ALC3661" },
976 { 0x10ec0275, 0x1028, 0, "ALC3260" },
977 { 0x10ec0899, 0x1028, 0, "ALC3861" },
978 { 0x10ec0298, 0x1028, 0, "ALC3266" },
979 { 0x10ec0236, 0x1028, 0, "ALC3204" },
980 { 0x10ec0256, 0x1028, 0, "ALC3246" },
981 { 0x10ec0225, 0x1028, 0, "ALC3253" },
982 { 0x10ec0295, 0x1028, 0, "ALC3254" },
983 { 0x10ec0299, 0x1028, 0, "ALC3271" },
984 { 0x10ec0670, 0x1025, 0, "ALC669X" },
985 { 0x10ec0676, 0x1025, 0, "ALC679X" },
986 { 0x10ec0282, 0x1043, 0, "ALC3229" },
987 { 0x10ec0233, 0x1043, 0, "ALC3236" },
988 { 0x10ec0280, 0x103c, 0, "ALC3228" },
989 { 0x10ec0282, 0x103c, 0, "ALC3227" },
990 { 0x10ec0286, 0x103c, 0, "ALC3242" },
991 { 0x10ec0290, 0x103c, 0, "ALC3241" },
992 { 0x10ec0668, 0x103c, 0, "ALC3662" },
993 { 0x10ec0283, 0x17aa, 0, "ALC3239" },
994 { 0x10ec0292, 0x17aa, 0, "ALC3232" },
995 { }
996};
997
998static int alc_codec_rename_from_preset(struct hda_codec *codec)
999{
1000 const struct alc_codec_rename_table *p;
1001 const struct alc_codec_rename_pci_table *q;
1002
1003 for (p = rename_tbl; p->vendor_id; p++) {
1004 if (p->vendor_id != codec->core.vendor_id)
1005 continue;
1006 if ((alc_get_coef0(codec) & p->coef_mask) == p->coef_bits)
1007 return alc_codec_rename(codec, p->name);
1008 }
1009
1010 if (!codec->bus->pci)
1011 return 0;
1012 for (q = rename_pci_tbl; q->codec_vendor_id; q++) {
1013 if (q->codec_vendor_id != codec->core.vendor_id)
1014 continue;
1015 if (q->pci_subvendor != codec->bus->pci->subsystem_vendor)
1016 continue;
1017 if (!q->pci_subdevice ||
1018 q->pci_subdevice == codec->bus->pci->subsystem_device)
1019 return alc_codec_rename(codec, q->name);
1020 }
1021
1022 return 0;
1023}
1024
1025
1026
1027
1028
1029#ifdef CONFIG_SND_HDA_INPUT_BEEP
1030
1031
1032static const struct snd_kcontrol_new alc_beep_mixer[] = {
1033 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
1034 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
1035};
1036
1037
1038static int set_beep_amp(struct alc_spec *spec, hda_nid_t nid,
1039 int idx, int dir)
1040{
1041 struct snd_kcontrol_new *knew;
1042 unsigned int beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir);
1043 int i;
1044
1045 for (i = 0; i < ARRAY_SIZE(alc_beep_mixer); i++) {
1046 knew = snd_hda_gen_add_kctl(&spec->gen, NULL,
1047 &alc_beep_mixer[i]);
1048 if (!knew)
1049 return -ENOMEM;
1050 knew->private_value = beep_amp;
1051 }
1052 return 0;
1053}
1054
1055static const struct snd_pci_quirk beep_white_list[] = {
1056 SND_PCI_QUIRK(0x1043, 0x103c, "ASUS", 1),
1057 SND_PCI_QUIRK(0x1043, 0x115d, "ASUS", 1),
1058 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
1059 SND_PCI_QUIRK(0x1043, 0x8376, "EeePC", 1),
1060 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
1061 SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1),
1062 SND_PCI_QUIRK(0x1043, 0x834a, "EeePC", 1),
1063 SND_PCI_QUIRK(0x1458, 0xa002, "GA-MA790X", 1),
1064 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
1065
1066 SND_PCI_QUIRK(0x17aa, 0x309e, "Lenovo ThinkCentre M73", 0),
1067 SND_PCI_QUIRK(0x17aa, 0x30a3, "Lenovo ThinkCentre M93", 0),
1068 {}
1069};
1070
1071static inline int has_cdefine_beep(struct hda_codec *codec)
1072{
1073 struct alc_spec *spec = codec->spec;
1074 const struct snd_pci_quirk *q;
1075 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
1076 if (q)
1077 return q->value;
1078 return spec->cdefine.enable_pcbeep;
1079}
1080#else
1081#define set_beep_amp(spec, nid, idx, dir) 0
1082#define has_cdefine_beep(codec) 0
1083#endif
1084
1085
1086
1087
1088
1089static int alc_parse_auto_config(struct hda_codec *codec,
1090 const hda_nid_t *ignore_nids,
1091 const hda_nid_t *ssid_nids)
1092{
1093 struct alc_spec *spec = codec->spec;
1094 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
1095 int err;
1096
1097 err = snd_hda_parse_pin_defcfg(codec, cfg, ignore_nids,
1098 spec->parse_flags);
1099 if (err < 0)
1100 return err;
1101
1102 if (ssid_nids)
1103 alc_ssid_check(codec, ssid_nids);
1104
1105 err = snd_hda_gen_parse_auto_config(codec, cfg);
1106 if (err < 0)
1107 return err;
1108
1109 return 1;
1110}
1111
1112
1113static int alc_alloc_spec(struct hda_codec *codec, hda_nid_t mixer_nid)
1114{
1115 struct alc_spec *spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1116 int err;
1117
1118 if (!spec)
1119 return -ENOMEM;
1120 codec->spec = spec;
1121 snd_hda_gen_spec_init(&spec->gen);
1122 spec->gen.mixer_nid = mixer_nid;
1123 spec->gen.own_eapd_ctl = 1;
1124 codec->single_adc_amp = 1;
1125
1126 codec->spdif_status_reset = 1;
1127 codec->patch_ops = alc_patch_ops;
1128
1129 err = alc_codec_rename_from_preset(codec);
1130 if (err < 0) {
1131 kfree(spec);
1132 return err;
1133 }
1134 return 0;
1135}
1136
1137static int alc880_parse_auto_config(struct hda_codec *codec)
1138{
1139 static const hda_nid_t alc880_ignore[] = { 0x1d, 0 };
1140 static const hda_nid_t alc880_ssids[] = { 0x15, 0x1b, 0x14, 0 };
1141 return alc_parse_auto_config(codec, alc880_ignore, alc880_ssids);
1142}
1143
1144
1145
1146
1147enum {
1148 ALC880_FIXUP_GPIO1,
1149 ALC880_FIXUP_GPIO2,
1150 ALC880_FIXUP_MEDION_RIM,
1151 ALC880_FIXUP_LG,
1152 ALC880_FIXUP_LG_LW25,
1153 ALC880_FIXUP_W810,
1154 ALC880_FIXUP_EAPD_COEF,
1155 ALC880_FIXUP_TCL_S700,
1156 ALC880_FIXUP_VOL_KNOB,
1157 ALC880_FIXUP_FUJITSU,
1158 ALC880_FIXUP_F1734,
1159 ALC880_FIXUP_UNIWILL,
1160 ALC880_FIXUP_UNIWILL_DIG,
1161 ALC880_FIXUP_Z71V,
1162 ALC880_FIXUP_ASUS_W5A,
1163 ALC880_FIXUP_3ST_BASE,
1164 ALC880_FIXUP_3ST,
1165 ALC880_FIXUP_3ST_DIG,
1166 ALC880_FIXUP_5ST_BASE,
1167 ALC880_FIXUP_5ST,
1168 ALC880_FIXUP_5ST_DIG,
1169 ALC880_FIXUP_6ST_BASE,
1170 ALC880_FIXUP_6ST,
1171 ALC880_FIXUP_6ST_DIG,
1172 ALC880_FIXUP_6ST_AUTOMUTE,
1173};
1174
1175
1176static void alc880_fixup_vol_knob(struct hda_codec *codec,
1177 const struct hda_fixup *fix, int action)
1178{
1179 if (action == HDA_FIXUP_ACT_PROBE)
1180 snd_hda_jack_detect_enable_callback(codec, 0x21,
1181 alc_update_knob_master);
1182}
1183
1184static const struct hda_fixup alc880_fixups[] = {
1185 [ALC880_FIXUP_GPIO1] = {
1186 .type = HDA_FIXUP_FUNC,
1187 .v.func = alc_fixup_gpio1,
1188 },
1189 [ALC880_FIXUP_GPIO2] = {
1190 .type = HDA_FIXUP_FUNC,
1191 .v.func = alc_fixup_gpio2,
1192 },
1193 [ALC880_FIXUP_MEDION_RIM] = {
1194 .type = HDA_FIXUP_VERBS,
1195 .v.verbs = (const struct hda_verb[]) {
1196 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
1197 { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
1198 { }
1199 },
1200 .chained = true,
1201 .chain_id = ALC880_FIXUP_GPIO2,
1202 },
1203 [ALC880_FIXUP_LG] = {
1204 .type = HDA_FIXUP_PINS,
1205 .v.pins = (const struct hda_pintbl[]) {
1206
1207 { 0x16, 0x411111f0 },
1208 { 0x18, 0x411111f0 },
1209 { 0x1a, 0x411111f0 },
1210 { }
1211 }
1212 },
1213 [ALC880_FIXUP_LG_LW25] = {
1214 .type = HDA_FIXUP_PINS,
1215 .v.pins = (const struct hda_pintbl[]) {
1216 { 0x1a, 0x0181344f },
1217 { 0x1b, 0x0321403f },
1218 { }
1219 }
1220 },
1221 [ALC880_FIXUP_W810] = {
1222 .type = HDA_FIXUP_PINS,
1223 .v.pins = (const struct hda_pintbl[]) {
1224
1225 { 0x17, 0x411111f0 },
1226 { }
1227 },
1228 .chained = true,
1229 .chain_id = ALC880_FIXUP_GPIO2,
1230 },
1231 [ALC880_FIXUP_EAPD_COEF] = {
1232 .type = HDA_FIXUP_VERBS,
1233 .v.verbs = (const struct hda_verb[]) {
1234
1235 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
1236 { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
1237 {}
1238 },
1239 },
1240 [ALC880_FIXUP_TCL_S700] = {
1241 .type = HDA_FIXUP_VERBS,
1242 .v.verbs = (const struct hda_verb[]) {
1243
1244 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
1245 { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
1246 {}
1247 },
1248 .chained = true,
1249 .chain_id = ALC880_FIXUP_GPIO2,
1250 },
1251 [ALC880_FIXUP_VOL_KNOB] = {
1252 .type = HDA_FIXUP_FUNC,
1253 .v.func = alc880_fixup_vol_knob,
1254 },
1255 [ALC880_FIXUP_FUJITSU] = {
1256
1257 .type = HDA_FIXUP_PINS,
1258 .v.pins = (const struct hda_pintbl[]) {
1259 { 0x14, 0x0121401f },
1260 { 0x15, 0x99030120 },
1261 { 0x16, 0x99030130 },
1262 { 0x17, 0x411111f0 },
1263 { 0x18, 0x411111f0 },
1264 { 0x19, 0x01a19950 },
1265 { 0x1a, 0x411111f0 },
1266 { 0x1b, 0x411111f0 },
1267 { 0x1c, 0x411111f0 },
1268 { 0x1d, 0x411111f0 },
1269 { 0x1e, 0x01454140 },
1270 { }
1271 },
1272 .chained = true,
1273 .chain_id = ALC880_FIXUP_VOL_KNOB,
1274 },
1275 [ALC880_FIXUP_F1734] = {
1276
1277 .type = HDA_FIXUP_PINS,
1278 .v.pins = (const struct hda_pintbl[]) {
1279 { 0x14, 0x0121401f },
1280 { 0x15, 0x99030120 },
1281 { 0x16, 0x411111f0 },
1282 { 0x17, 0x411111f0 },
1283 { 0x18, 0x411111f0 },
1284 { 0x19, 0x01a19950 },
1285 { 0x1a, 0x411111f0 },
1286 { 0x1b, 0x411111f0 },
1287 { 0x1c, 0x411111f0 },
1288 { 0x1d, 0x411111f0 },
1289 { 0x1e, 0x411111f0 },
1290 { }
1291 },
1292 .chained = true,
1293 .chain_id = ALC880_FIXUP_VOL_KNOB,
1294 },
1295 [ALC880_FIXUP_UNIWILL] = {
1296
1297 .type = HDA_FIXUP_PINS,
1298 .v.pins = (const struct hda_pintbl[]) {
1299 { 0x14, 0x0121411f },
1300 { 0x15, 0x99030120 },
1301 { 0x16, 0x99030130 },
1302 { }
1303 },
1304 },
1305 [ALC880_FIXUP_UNIWILL_DIG] = {
1306 .type = HDA_FIXUP_PINS,
1307 .v.pins = (const struct hda_pintbl[]) {
1308
1309 { 0x17, 0x411111f0 },
1310 { 0x19, 0x411111f0 },
1311 { 0x1b, 0x411111f0 },
1312 { 0x1f, 0x411111f0 },
1313 { }
1314 }
1315 },
1316 [ALC880_FIXUP_Z71V] = {
1317 .type = HDA_FIXUP_PINS,
1318 .v.pins = (const struct hda_pintbl[]) {
1319
1320 { 0x14, 0x99030120 },
1321 { 0x15, 0x0121411f },
1322 { 0x16, 0x411111f0 },
1323 { 0x17, 0x411111f0 },
1324 { 0x18, 0x01a19950 },
1325 { 0x19, 0x411111f0 },
1326 { 0x1a, 0x01813031 },
1327 { 0x1b, 0x411111f0 },
1328 { 0x1c, 0x411111f0 },
1329 { 0x1d, 0x411111f0 },
1330 { 0x1e, 0x0144111e },
1331 { }
1332 }
1333 },
1334 [ALC880_FIXUP_ASUS_W5A] = {
1335 .type = HDA_FIXUP_PINS,
1336 .v.pins = (const struct hda_pintbl[]) {
1337
1338 { 0x14, 0x0121411f },
1339 { 0x15, 0x411111f0 },
1340 { 0x16, 0x411111f0 },
1341 { 0x17, 0x411111f0 },
1342 { 0x18, 0x90a60160 },
1343 { 0x19, 0x411111f0 },
1344 { 0x1a, 0x411111f0 },
1345 { 0x1b, 0x411111f0 },
1346 { 0x1c, 0x411111f0 },
1347 { 0x1d, 0x411111f0 },
1348 { 0x1e, 0xb743111e },
1349 { }
1350 },
1351 .chained = true,
1352 .chain_id = ALC880_FIXUP_GPIO1,
1353 },
1354 [ALC880_FIXUP_3ST_BASE] = {
1355 .type = HDA_FIXUP_PINS,
1356 .v.pins = (const struct hda_pintbl[]) {
1357 { 0x14, 0x01014010 },
1358 { 0x15, 0x411111f0 },
1359 { 0x16, 0x411111f0 },
1360 { 0x17, 0x411111f0 },
1361 { 0x18, 0x01a19c30 },
1362 { 0x19, 0x0121411f },
1363 { 0x1a, 0x01813031 },
1364 { 0x1b, 0x02a19c40 },
1365 { 0x1c, 0x411111f0 },
1366 { 0x1d, 0x411111f0 },
1367
1368 { 0x1f, 0x411111f0 },
1369 { }
1370 }
1371 },
1372 [ALC880_FIXUP_3ST] = {
1373 .type = HDA_FIXUP_PINS,
1374 .v.pins = (const struct hda_pintbl[]) {
1375 { 0x1e, 0x411111f0 },
1376 { }
1377 },
1378 .chained = true,
1379 .chain_id = ALC880_FIXUP_3ST_BASE,
1380 },
1381 [ALC880_FIXUP_3ST_DIG] = {
1382 .type = HDA_FIXUP_PINS,
1383 .v.pins = (const struct hda_pintbl[]) {
1384 { 0x1e, 0x0144111e },
1385 { }
1386 },
1387 .chained = true,
1388 .chain_id = ALC880_FIXUP_3ST_BASE,
1389 },
1390 [ALC880_FIXUP_5ST_BASE] = {
1391 .type = HDA_FIXUP_PINS,
1392 .v.pins = (const struct hda_pintbl[]) {
1393 { 0x14, 0x01014010 },
1394 { 0x15, 0x411111f0 },
1395 { 0x16, 0x01011411 },
1396 { 0x17, 0x01016412 },
1397 { 0x18, 0x01a19c30 },
1398 { 0x19, 0x0121411f },
1399 { 0x1a, 0x01813031 },
1400 { 0x1b, 0x02a19c40 },
1401 { 0x1c, 0x411111f0 },
1402 { 0x1d, 0x411111f0 },
1403
1404 { 0x1f, 0x411111f0 },
1405 { }
1406 }
1407 },
1408 [ALC880_FIXUP_5ST] = {
1409 .type = HDA_FIXUP_PINS,
1410 .v.pins = (const struct hda_pintbl[]) {
1411 { 0x1e, 0x411111f0 },
1412 { }
1413 },
1414 .chained = true,
1415 .chain_id = ALC880_FIXUP_5ST_BASE,
1416 },
1417 [ALC880_FIXUP_5ST_DIG] = {
1418 .type = HDA_FIXUP_PINS,
1419 .v.pins = (const struct hda_pintbl[]) {
1420 { 0x1e, 0x0144111e },
1421 { }
1422 },
1423 .chained = true,
1424 .chain_id = ALC880_FIXUP_5ST_BASE,
1425 },
1426 [ALC880_FIXUP_6ST_BASE] = {
1427 .type = HDA_FIXUP_PINS,
1428 .v.pins = (const struct hda_pintbl[]) {
1429 { 0x14, 0x01014010 },
1430 { 0x15, 0x01016412 },
1431 { 0x16, 0x01011411 },
1432 { 0x17, 0x01012414 },
1433 { 0x18, 0x01a19c30 },
1434 { 0x19, 0x02a19c40 },
1435 { 0x1a, 0x01813031 },
1436 { 0x1b, 0x0121411f },
1437 { 0x1c, 0x411111f0 },
1438 { 0x1d, 0x411111f0 },
1439
1440 { 0x1f, 0x411111f0 },
1441 { }
1442 }
1443 },
1444 [ALC880_FIXUP_6ST] = {
1445 .type = HDA_FIXUP_PINS,
1446 .v.pins = (const struct hda_pintbl[]) {
1447 { 0x1e, 0x411111f0 },
1448 { }
1449 },
1450 .chained = true,
1451 .chain_id = ALC880_FIXUP_6ST_BASE,
1452 },
1453 [ALC880_FIXUP_6ST_DIG] = {
1454 .type = HDA_FIXUP_PINS,
1455 .v.pins = (const struct hda_pintbl[]) {
1456 { 0x1e, 0x0144111e },
1457 { }
1458 },
1459 .chained = true,
1460 .chain_id = ALC880_FIXUP_6ST_BASE,
1461 },
1462 [ALC880_FIXUP_6ST_AUTOMUTE] = {
1463 .type = HDA_FIXUP_PINS,
1464 .v.pins = (const struct hda_pintbl[]) {
1465 { 0x1b, 0x0121401f },
1466 { }
1467 },
1468 .chained_before = true,
1469 .chain_id = ALC880_FIXUP_6ST_BASE,
1470 },
1471};
1472
1473static const struct snd_pci_quirk alc880_fixup_tbl[] = {
1474 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_FIXUP_W810),
1475 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS W5A", ALC880_FIXUP_ASUS_W5A),
1476 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_FIXUP_Z71V),
1477 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_FIXUP_GPIO1),
1478 SND_PCI_QUIRK(0x147b, 0x1045, "ABit AA8XE", ALC880_FIXUP_6ST_AUTOMUTE),
1479 SND_PCI_QUIRK(0x1558, 0x5401, "Clevo GPIO2", ALC880_FIXUP_GPIO2),
1480 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo", ALC880_FIXUP_EAPD_COEF),
1481 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_FIXUP_UNIWILL_DIG),
1482 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_FIXUP_F1734),
1483 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_FIXUP_UNIWILL),
1484 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_FIXUP_VOL_KNOB),
1485 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_FIXUP_W810),
1486 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_FIXUP_MEDION_RIM),
1487 SND_PCI_QUIRK(0x1631, 0xe011, "PB 13201056", ALC880_FIXUP_6ST_AUTOMUTE),
1488 SND_PCI_QUIRK(0x1734, 0x107c, "FSC Amilo M1437", ALC880_FIXUP_FUJITSU),
1489 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FIXUP_FUJITSU),
1490 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_FIXUP_F1734),
1491 SND_PCI_QUIRK(0x1734, 0x10b0, "FSC Amilo Pi1556", ALC880_FIXUP_FUJITSU),
1492 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_FIXUP_LG),
1493 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_FIXUP_LG),
1494 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_FIXUP_LG),
1495 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_FIXUP_LG_LW25),
1496 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_FIXUP_TCL_S700),
1497
1498
1499
1500
1501
1502
1503
1504 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_FIXUP_5ST_DIG),
1505 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_FIXUP_6ST),
1506 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_FIXUP_3ST_DIG),
1507 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_FIXUP_6ST_DIG),
1508 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_FIXUP_6ST_DIG),
1509 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_FIXUP_6ST_DIG),
1510 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_FIXUP_3ST_DIG),
1511 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_FIXUP_3ST),
1512 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_FIXUP_6ST_DIG),
1513 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_FIXUP_3ST),
1514 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_FIXUP_3ST),
1515 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_FIXUP_5ST),
1516 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_FIXUP_5ST),
1517 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_FIXUP_5ST),
1518 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_FIXUP_6ST_DIG),
1519 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_FIXUP_6ST_DIG),
1520 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_FIXUP_6ST_DIG),
1521 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_FIXUP_6ST_DIG),
1522 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_FIXUP_5ST_DIG),
1523 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_FIXUP_5ST_DIG),
1524 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_FIXUP_5ST_DIG),
1525 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_FIXUP_6ST_DIG),
1526 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_FIXUP_6ST_DIG),
1527 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1528 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1529 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1530 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_FIXUP_3ST_DIG),
1531 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1532 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_FIXUP_3ST_DIG),
1533 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_FIXUP_3ST_DIG),
1534 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1535 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1536 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1537
1538 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_FIXUP_3ST),
1539 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_FIXUP_5ST_DIG),
1540 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_FIXUP_6ST_DIG),
1541 {}
1542};
1543
1544static const struct hda_model_fixup alc880_fixup_models[] = {
1545 {.id = ALC880_FIXUP_3ST, .name = "3stack"},
1546 {.id = ALC880_FIXUP_3ST_DIG, .name = "3stack-digout"},
1547 {.id = ALC880_FIXUP_5ST, .name = "5stack"},
1548 {.id = ALC880_FIXUP_5ST_DIG, .name = "5stack-digout"},
1549 {.id = ALC880_FIXUP_6ST, .name = "6stack"},
1550 {.id = ALC880_FIXUP_6ST_DIG, .name = "6stack-digout"},
1551 {.id = ALC880_FIXUP_6ST_AUTOMUTE, .name = "6stack-automute"},
1552 {}
1553};
1554
1555
1556
1557
1558
1559static int patch_alc880(struct hda_codec *codec)
1560{
1561 struct alc_spec *spec;
1562 int err;
1563
1564 err = alc_alloc_spec(codec, 0x0b);
1565 if (err < 0)
1566 return err;
1567
1568 spec = codec->spec;
1569 spec->gen.need_dac_fix = 1;
1570 spec->gen.beep_nid = 0x01;
1571
1572 codec->patch_ops.unsol_event = alc880_unsol_event;
1573
1574 alc_pre_init(codec);
1575
1576 snd_hda_pick_fixup(codec, alc880_fixup_models, alc880_fixup_tbl,
1577 alc880_fixups);
1578 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
1579
1580
1581 err = alc880_parse_auto_config(codec);
1582 if (err < 0)
1583 goto error;
1584
1585 if (!spec->gen.no_analog) {
1586 err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
1587 if (err < 0)
1588 goto error;
1589 }
1590
1591 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
1592
1593 return 0;
1594
1595 error:
1596 alc_free(codec);
1597 return err;
1598}
1599
1600
1601
1602
1603
1604static int alc260_parse_auto_config(struct hda_codec *codec)
1605{
1606 static const hda_nid_t alc260_ignore[] = { 0x17, 0 };
1607 static const hda_nid_t alc260_ssids[] = { 0x10, 0x15, 0x0f, 0 };
1608 return alc_parse_auto_config(codec, alc260_ignore, alc260_ssids);
1609}
1610
1611
1612
1613
1614enum {
1615 ALC260_FIXUP_HP_DC5750,
1616 ALC260_FIXUP_HP_PIN_0F,
1617 ALC260_FIXUP_COEF,
1618 ALC260_FIXUP_GPIO1,
1619 ALC260_FIXUP_GPIO1_TOGGLE,
1620 ALC260_FIXUP_REPLACER,
1621 ALC260_FIXUP_HP_B1900,
1622 ALC260_FIXUP_KN1,
1623 ALC260_FIXUP_FSC_S7020,
1624 ALC260_FIXUP_FSC_S7020_JWSE,
1625 ALC260_FIXUP_VAIO_PINS,
1626};
1627
1628static void alc260_gpio1_automute(struct hda_codec *codec)
1629{
1630 struct alc_spec *spec = codec->spec;
1631
1632 alc_update_gpio_data(codec, 0x01, spec->gen.hp_jack_present);
1633}
1634
1635static void alc260_fixup_gpio1_toggle(struct hda_codec *codec,
1636 const struct hda_fixup *fix, int action)
1637{
1638 struct alc_spec *spec = codec->spec;
1639 if (action == HDA_FIXUP_ACT_PROBE) {
1640
1641
1642
1643 spec->gen.automute_hook = alc260_gpio1_automute;
1644 spec->gen.detect_hp = 1;
1645 spec->gen.automute_speaker = 1;
1646 spec->gen.autocfg.hp_pins[0] = 0x0f;
1647 snd_hda_jack_detect_enable_callback(codec, 0x0f,
1648 snd_hda_gen_hp_automute);
1649 alc_setup_gpio(codec, 0x01);
1650 }
1651}
1652
1653static void alc260_fixup_kn1(struct hda_codec *codec,
1654 const struct hda_fixup *fix, int action)
1655{
1656 struct alc_spec *spec = codec->spec;
1657 static const struct hda_pintbl pincfgs[] = {
1658 { 0x0f, 0x02214000 },
1659 { 0x12, 0x90a60160 },
1660 { 0x13, 0x02a19000 },
1661 { 0x18, 0x01446000 },
1662
1663 { 0x10, 0x411111f0 },
1664 { 0x11, 0x411111f0 },
1665 { 0x14, 0x411111f0 },
1666 { 0x15, 0x411111f0 },
1667 { 0x16, 0x411111f0 },
1668 { 0x17, 0x411111f0 },
1669 { 0x19, 0x411111f0 },
1670 { }
1671 };
1672
1673 switch (action) {
1674 case HDA_FIXUP_ACT_PRE_PROBE:
1675 snd_hda_apply_pincfgs(codec, pincfgs);
1676 spec->init_amp = ALC_INIT_NONE;
1677 break;
1678 }
1679}
1680
1681static void alc260_fixup_fsc_s7020(struct hda_codec *codec,
1682 const struct hda_fixup *fix, int action)
1683{
1684 struct alc_spec *spec = codec->spec;
1685 if (action == HDA_FIXUP_ACT_PRE_PROBE)
1686 spec->init_amp = ALC_INIT_NONE;
1687}
1688
1689static void alc260_fixup_fsc_s7020_jwse(struct hda_codec *codec,
1690 const struct hda_fixup *fix, int action)
1691{
1692 struct alc_spec *spec = codec->spec;
1693 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
1694 spec->gen.add_jack_modes = 1;
1695 spec->gen.hp_mic = 1;
1696 }
1697}
1698
1699static const struct hda_fixup alc260_fixups[] = {
1700 [ALC260_FIXUP_HP_DC5750] = {
1701 .type = HDA_FIXUP_PINS,
1702 .v.pins = (const struct hda_pintbl[]) {
1703 { 0x11, 0x90130110 },
1704 { }
1705 }
1706 },
1707 [ALC260_FIXUP_HP_PIN_0F] = {
1708 .type = HDA_FIXUP_PINS,
1709 .v.pins = (const struct hda_pintbl[]) {
1710 { 0x0f, 0x01214000 },
1711 { }
1712 }
1713 },
1714 [ALC260_FIXUP_COEF] = {
1715 .type = HDA_FIXUP_VERBS,
1716 .v.verbs = (const struct hda_verb[]) {
1717 { 0x1a, AC_VERB_SET_COEF_INDEX, 0x07 },
1718 { 0x1a, AC_VERB_SET_PROC_COEF, 0x3040 },
1719 { }
1720 },
1721 },
1722 [ALC260_FIXUP_GPIO1] = {
1723 .type = HDA_FIXUP_FUNC,
1724 .v.func = alc_fixup_gpio1,
1725 },
1726 [ALC260_FIXUP_GPIO1_TOGGLE] = {
1727 .type = HDA_FIXUP_FUNC,
1728 .v.func = alc260_fixup_gpio1_toggle,
1729 .chained = true,
1730 .chain_id = ALC260_FIXUP_HP_PIN_0F,
1731 },
1732 [ALC260_FIXUP_REPLACER] = {
1733 .type = HDA_FIXUP_VERBS,
1734 .v.verbs = (const struct hda_verb[]) {
1735 { 0x1a, AC_VERB_SET_COEF_INDEX, 0x07 },
1736 { 0x1a, AC_VERB_SET_PROC_COEF, 0x3050 },
1737 { }
1738 },
1739 .chained = true,
1740 .chain_id = ALC260_FIXUP_GPIO1_TOGGLE,
1741 },
1742 [ALC260_FIXUP_HP_B1900] = {
1743 .type = HDA_FIXUP_FUNC,
1744 .v.func = alc260_fixup_gpio1_toggle,
1745 .chained = true,
1746 .chain_id = ALC260_FIXUP_COEF,
1747 },
1748 [ALC260_FIXUP_KN1] = {
1749 .type = HDA_FIXUP_FUNC,
1750 .v.func = alc260_fixup_kn1,
1751 },
1752 [ALC260_FIXUP_FSC_S7020] = {
1753 .type = HDA_FIXUP_FUNC,
1754 .v.func = alc260_fixup_fsc_s7020,
1755 },
1756 [ALC260_FIXUP_FSC_S7020_JWSE] = {
1757 .type = HDA_FIXUP_FUNC,
1758 .v.func = alc260_fixup_fsc_s7020_jwse,
1759 .chained = true,
1760 .chain_id = ALC260_FIXUP_FSC_S7020,
1761 },
1762 [ALC260_FIXUP_VAIO_PINS] = {
1763 .type = HDA_FIXUP_PINS,
1764 .v.pins = (const struct hda_pintbl[]) {
1765
1766 { 0x0f, 0x01211020 },
1767 { 0x10, 0x0001003f },
1768 { 0x11, 0x411111f0 },
1769 { 0x12, 0x01a15930 },
1770 { 0x13, 0x411111f0 },
1771 { 0x14, 0x411111f0 },
1772 { 0x15, 0x411111f0 },
1773 { 0x16, 0x411111f0 },
1774 { 0x17, 0x411111f0 },
1775 { 0x18, 0x411111f0 },
1776 { 0x19, 0x411111f0 },
1777 { }
1778 }
1779 },
1780};
1781
1782static const struct snd_pci_quirk alc260_fixup_tbl[] = {
1783 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_FIXUP_GPIO1),
1784 SND_PCI_QUIRK(0x1025, 0x007f, "Acer Aspire 9500", ALC260_FIXUP_COEF),
1785 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_FIXUP_GPIO1),
1786 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", ALC260_FIXUP_HP_DC5750),
1787 SND_PCI_QUIRK(0x103c, 0x30ba, "HP Presario B1900", ALC260_FIXUP_HP_B1900),
1788 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_FIXUP_VAIO_PINS),
1789 SND_PCI_QUIRK(0x104d, 0x81e2, "Sony VAIO TX", ALC260_FIXUP_HP_PIN_0F),
1790 SND_PCI_QUIRK(0x10cf, 0x1326, "FSC LifeBook S7020", ALC260_FIXUP_FSC_S7020),
1791 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FIXUP_GPIO1),
1792 SND_PCI_QUIRK(0x152d, 0x0729, "Quanta KN1", ALC260_FIXUP_KN1),
1793 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_FIXUP_REPLACER),
1794 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_FIXUP_COEF),
1795 {}
1796};
1797
1798static const struct hda_model_fixup alc260_fixup_models[] = {
1799 {.id = ALC260_FIXUP_GPIO1, .name = "gpio1"},
1800 {.id = ALC260_FIXUP_COEF, .name = "coef"},
1801 {.id = ALC260_FIXUP_FSC_S7020, .name = "fujitsu"},
1802 {.id = ALC260_FIXUP_FSC_S7020_JWSE, .name = "fujitsu-jwse"},
1803 {}
1804};
1805
1806
1807
1808static int patch_alc260(struct hda_codec *codec)
1809{
1810 struct alc_spec *spec;
1811 int err;
1812
1813 err = alc_alloc_spec(codec, 0x07);
1814 if (err < 0)
1815 return err;
1816
1817 spec = codec->spec;
1818
1819
1820
1821
1822 spec->gen.prefer_hp_amp = 1;
1823 spec->gen.beep_nid = 0x01;
1824
1825 spec->shutup = alc_eapd_shutup;
1826
1827 alc_pre_init(codec);
1828
1829 snd_hda_pick_fixup(codec, alc260_fixup_models, alc260_fixup_tbl,
1830 alc260_fixups);
1831 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
1832
1833
1834 err = alc260_parse_auto_config(codec);
1835 if (err < 0)
1836 goto error;
1837
1838 if (!spec->gen.no_analog) {
1839 err = set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
1840 if (err < 0)
1841 goto error;
1842 }
1843
1844 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
1845
1846 return 0;
1847
1848 error:
1849 alc_free(codec);
1850 return err;
1851}
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869enum {
1870 ALC882_FIXUP_ABIT_AW9D_MAX,
1871 ALC882_FIXUP_LENOVO_Y530,
1872 ALC882_FIXUP_PB_M5210,
1873 ALC882_FIXUP_ACER_ASPIRE_7736,
1874 ALC882_FIXUP_ASUS_W90V,
1875 ALC889_FIXUP_CD,
1876 ALC889_FIXUP_FRONT_HP_NO_PRESENCE,
1877 ALC889_FIXUP_VAIO_TT,
1878 ALC888_FIXUP_EEE1601,
1879 ALC882_FIXUP_EAPD,
1880 ALC883_FIXUP_EAPD,
1881 ALC883_FIXUP_ACER_EAPD,
1882 ALC882_FIXUP_GPIO1,
1883 ALC882_FIXUP_GPIO2,
1884 ALC882_FIXUP_GPIO3,
1885 ALC889_FIXUP_COEF,
1886 ALC882_FIXUP_ASUS_W2JC,
1887 ALC882_FIXUP_ACER_ASPIRE_4930G,
1888 ALC882_FIXUP_ACER_ASPIRE_8930G,
1889 ALC882_FIXUP_ASPIRE_8930G_VERBS,
1890 ALC885_FIXUP_MACPRO_GPIO,
1891 ALC889_FIXUP_DAC_ROUTE,
1892 ALC889_FIXUP_MBP_VREF,
1893 ALC889_FIXUP_IMAC91_VREF,
1894 ALC889_FIXUP_MBA11_VREF,
1895 ALC889_FIXUP_MBA21_VREF,
1896 ALC889_FIXUP_MP11_VREF,
1897 ALC889_FIXUP_MP41_VREF,
1898 ALC882_FIXUP_INV_DMIC,
1899 ALC882_FIXUP_NO_PRIMARY_HP,
1900 ALC887_FIXUP_ASUS_BASS,
1901 ALC887_FIXUP_BASS_CHMAP,
1902 ALC1220_FIXUP_GB_DUAL_CODECS,
1903 ALC1220_FIXUP_CLEVO_P950,
1904 ALC1220_FIXUP_CLEVO_PB51ED,
1905 ALC1220_FIXUP_CLEVO_PB51ED_PINS,
1906};
1907
1908static void alc889_fixup_coef(struct hda_codec *codec,
1909 const struct hda_fixup *fix, int action)
1910{
1911 if (action != HDA_FIXUP_ACT_INIT)
1912 return;
1913 alc_update_coef_idx(codec, 7, 0, 0x2030);
1914}
1915
1916
1917static void alc885_fixup_macpro_gpio(struct hda_codec *codec,
1918 const struct hda_fixup *fix, int action)
1919{
1920 struct alc_spec *spec = codec->spec;
1921
1922 spec->gpio_write_delay = true;
1923 alc_fixup_gpio3(codec, fix, action);
1924}
1925
1926
1927
1928
1929
1930static void alc889_fixup_dac_route(struct hda_codec *codec,
1931 const struct hda_fixup *fix, int action)
1932{
1933 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
1934
1935 hda_nid_t conn1[2] = { 0x0c, 0x0d };
1936 hda_nid_t conn2[2] = { 0x0e, 0x0f };
1937 snd_hda_override_conn_list(codec, 0x14, 2, conn1);
1938 snd_hda_override_conn_list(codec, 0x15, 2, conn1);
1939 snd_hda_override_conn_list(codec, 0x18, 2, conn2);
1940 snd_hda_override_conn_list(codec, 0x1a, 2, conn2);
1941 } else if (action == HDA_FIXUP_ACT_PROBE) {
1942
1943 hda_nid_t conn[5] = { 0x0c, 0x0d, 0x0e, 0x0f, 0x26 };
1944 snd_hda_override_conn_list(codec, 0x14, 5, conn);
1945 snd_hda_override_conn_list(codec, 0x15, 5, conn);
1946 snd_hda_override_conn_list(codec, 0x18, 5, conn);
1947 snd_hda_override_conn_list(codec, 0x1a, 5, conn);
1948 }
1949}
1950
1951
1952static void alc889_fixup_mbp_vref(struct hda_codec *codec,
1953 const struct hda_fixup *fix, int action)
1954{
1955 struct alc_spec *spec = codec->spec;
1956 static hda_nid_t nids[3] = { 0x14, 0x15, 0x19 };
1957 int i;
1958
1959 if (action != HDA_FIXUP_ACT_INIT)
1960 return;
1961 for (i = 0; i < ARRAY_SIZE(nids); i++) {
1962 unsigned int val = snd_hda_codec_get_pincfg(codec, nids[i]);
1963 if (get_defcfg_device(val) != AC_JACK_HP_OUT)
1964 continue;
1965 val = snd_hda_codec_get_pin_target(codec, nids[i]);
1966 val |= AC_PINCTL_VREF_80;
1967 snd_hda_set_pin_ctl(codec, nids[i], val);
1968 spec->gen.keep_vref_in_automute = 1;
1969 break;
1970 }
1971}
1972
1973static void alc889_fixup_mac_pins(struct hda_codec *codec,
1974 const hda_nid_t *nids, int num_nids)
1975{
1976 struct alc_spec *spec = codec->spec;
1977 int i;
1978
1979 for (i = 0; i < num_nids; i++) {
1980 unsigned int val;
1981 val = snd_hda_codec_get_pin_target(codec, nids[i]);
1982 val |= AC_PINCTL_VREF_50;
1983 snd_hda_set_pin_ctl(codec, nids[i], val);
1984 }
1985 spec->gen.keep_vref_in_automute = 1;
1986}
1987
1988
1989static void alc889_fixup_imac91_vref(struct hda_codec *codec,
1990 const struct hda_fixup *fix, int action)
1991{
1992 static hda_nid_t nids[2] = { 0x18, 0x1a };
1993
1994 if (action == HDA_FIXUP_ACT_INIT)
1995 alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
1996}
1997
1998
1999static void alc889_fixup_mba11_vref(struct hda_codec *codec,
2000 const struct hda_fixup *fix, int action)
2001{
2002 static hda_nid_t nids[1] = { 0x18 };
2003
2004 if (action == HDA_FIXUP_ACT_INIT)
2005 alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
2006}
2007
2008
2009static void alc889_fixup_mba21_vref(struct hda_codec *codec,
2010 const struct hda_fixup *fix, int action)
2011{
2012 static hda_nid_t nids[2] = { 0x18, 0x19 };
2013
2014 if (action == HDA_FIXUP_ACT_INIT)
2015 alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
2016}
2017
2018
2019
2020
2021
2022static void alc882_fixup_no_primary_hp(struct hda_codec *codec,
2023 const struct hda_fixup *fix, int action)
2024{
2025 struct alc_spec *spec = codec->spec;
2026 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
2027 spec->gen.no_primary_hp = 1;
2028 spec->gen.no_multi_io = 1;
2029 }
2030}
2031
2032static void alc_fixup_bass_chmap(struct hda_codec *codec,
2033 const struct hda_fixup *fix, int action);
2034
2035
2036
2037
2038static void alc_fixup_dual_codecs(struct hda_codec *codec,
2039 const struct hda_fixup *fix, int action)
2040{
2041 struct alc_spec *spec = codec->spec;
2042
2043 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2044 return;
2045
2046 spec->gen.suppress_vmaster = 1;
2047
2048 spec->gen.suppress_auto_mute = 1;
2049 spec->gen.suppress_auto_mic = 1;
2050
2051 spec->gen.mixer_nid = 0;
2052
2053 codec->force_pin_prefix = 1;
2054}
2055
2056static void rename_ctl(struct hda_codec *codec, const char *oldname,
2057 const char *newname)
2058{
2059 struct snd_kcontrol *kctl;
2060
2061 kctl = snd_hda_find_mixer_ctl(codec, oldname);
2062 if (kctl)
2063 strcpy(kctl->id.name, newname);
2064}
2065
2066static void alc1220_fixup_gb_dual_codecs(struct hda_codec *codec,
2067 const struct hda_fixup *fix,
2068 int action)
2069{
2070 alc_fixup_dual_codecs(codec, fix, action);
2071 switch (action) {
2072 case HDA_FIXUP_ACT_PRE_PROBE:
2073
2074 strcpy(codec->card->longname, "HDAudio-Gigabyte-ALC1220DualCodecs");
2075 break;
2076 case HDA_FIXUP_ACT_BUILD:
2077
2078 rename_ctl(codec, "Capture Volume",
2079 codec->addr == 0 ?
2080 "Rear-Panel Capture Volume" :
2081 "Front-Panel Capture Volume");
2082 rename_ctl(codec, "Capture Switch",
2083 codec->addr == 0 ?
2084 "Rear-Panel Capture Switch" :
2085 "Front-Panel Capture Switch");
2086 break;
2087 }
2088}
2089
2090static void alc1220_fixup_clevo_p950(struct hda_codec *codec,
2091 const struct hda_fixup *fix,
2092 int action)
2093{
2094 hda_nid_t conn1[1] = { 0x0c };
2095
2096 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2097 return;
2098
2099 alc_update_coef_idx(codec, 0x7, 0, 0x3c3);
2100
2101
2102
2103 snd_hda_override_conn_list(codec, 0x14, 1, conn1);
2104 snd_hda_override_conn_list(codec, 0x1b, 1, conn1);
2105}
2106
2107static void alc_fixup_headset_mode_no_hp_mic(struct hda_codec *codec,
2108 const struct hda_fixup *fix, int action);
2109
2110static void alc1220_fixup_clevo_pb51ed(struct hda_codec *codec,
2111 const struct hda_fixup *fix,
2112 int action)
2113{
2114 alc1220_fixup_clevo_p950(codec, fix, action);
2115 alc_fixup_headset_mode_no_hp_mic(codec, fix, action);
2116}
2117
2118static const struct hda_fixup alc882_fixups[] = {
2119 [ALC882_FIXUP_ABIT_AW9D_MAX] = {
2120 .type = HDA_FIXUP_PINS,
2121 .v.pins = (const struct hda_pintbl[]) {
2122 { 0x15, 0x01080104 },
2123 { 0x16, 0x01011012 },
2124 { 0x17, 0x01016011 },
2125 { }
2126 }
2127 },
2128 [ALC882_FIXUP_LENOVO_Y530] = {
2129 .type = HDA_FIXUP_PINS,
2130 .v.pins = (const struct hda_pintbl[]) {
2131 { 0x15, 0x99130112 },
2132 { 0x16, 0x99130111 },
2133 { }
2134 }
2135 },
2136 [ALC882_FIXUP_PB_M5210] = {
2137 .type = HDA_FIXUP_PINCTLS,
2138 .v.pins = (const struct hda_pintbl[]) {
2139 { 0x19, PIN_VREF50 },
2140 {}
2141 }
2142 },
2143 [ALC882_FIXUP_ACER_ASPIRE_7736] = {
2144 .type = HDA_FIXUP_FUNC,
2145 .v.func = alc_fixup_sku_ignore,
2146 },
2147 [ALC882_FIXUP_ASUS_W90V] = {
2148 .type = HDA_FIXUP_PINS,
2149 .v.pins = (const struct hda_pintbl[]) {
2150 { 0x16, 0x99130110 },
2151 { }
2152 }
2153 },
2154 [ALC889_FIXUP_CD] = {
2155 .type = HDA_FIXUP_PINS,
2156 .v.pins = (const struct hda_pintbl[]) {
2157 { 0x1c, 0x993301f0 },
2158 { }
2159 }
2160 },
2161 [ALC889_FIXUP_FRONT_HP_NO_PRESENCE] = {
2162 .type = HDA_FIXUP_PINS,
2163 .v.pins = (const struct hda_pintbl[]) {
2164 { 0x1b, 0x02214120 },
2165 { }
2166 },
2167 .chained = true,
2168 .chain_id = ALC889_FIXUP_CD,
2169 },
2170 [ALC889_FIXUP_VAIO_TT] = {
2171 .type = HDA_FIXUP_PINS,
2172 .v.pins = (const struct hda_pintbl[]) {
2173 { 0x17, 0x90170111 },
2174 { }
2175 }
2176 },
2177 [ALC888_FIXUP_EEE1601] = {
2178 .type = HDA_FIXUP_VERBS,
2179 .v.verbs = (const struct hda_verb[]) {
2180 { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b },
2181 { 0x20, AC_VERB_SET_PROC_COEF, 0x0838 },
2182 { }
2183 }
2184 },
2185 [ALC882_FIXUP_EAPD] = {
2186 .type = HDA_FIXUP_VERBS,
2187 .v.verbs = (const struct hda_verb[]) {
2188
2189 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2190 { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
2191 { }
2192 }
2193 },
2194 [ALC883_FIXUP_EAPD] = {
2195 .type = HDA_FIXUP_VERBS,
2196 .v.verbs = (const struct hda_verb[]) {
2197
2198 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2199 { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
2200 { }
2201 }
2202 },
2203 [ALC883_FIXUP_ACER_EAPD] = {
2204 .type = HDA_FIXUP_VERBS,
2205 .v.verbs = (const struct hda_verb[]) {
2206
2207 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2208 { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
2209 { }
2210 }
2211 },
2212 [ALC882_FIXUP_GPIO1] = {
2213 .type = HDA_FIXUP_FUNC,
2214 .v.func = alc_fixup_gpio1,
2215 },
2216 [ALC882_FIXUP_GPIO2] = {
2217 .type = HDA_FIXUP_FUNC,
2218 .v.func = alc_fixup_gpio2,
2219 },
2220 [ALC882_FIXUP_GPIO3] = {
2221 .type = HDA_FIXUP_FUNC,
2222 .v.func = alc_fixup_gpio3,
2223 },
2224 [ALC882_FIXUP_ASUS_W2JC] = {
2225 .type = HDA_FIXUP_FUNC,
2226 .v.func = alc_fixup_gpio1,
2227 .chained = true,
2228 .chain_id = ALC882_FIXUP_EAPD,
2229 },
2230 [ALC889_FIXUP_COEF] = {
2231 .type = HDA_FIXUP_FUNC,
2232 .v.func = alc889_fixup_coef,
2233 },
2234 [ALC882_FIXUP_ACER_ASPIRE_4930G] = {
2235 .type = HDA_FIXUP_PINS,
2236 .v.pins = (const struct hda_pintbl[]) {
2237 { 0x16, 0x99130111 },
2238 { 0x17, 0x99130112 },
2239 { }
2240 },
2241 .chained = true,
2242 .chain_id = ALC882_FIXUP_GPIO1,
2243 },
2244 [ALC882_FIXUP_ACER_ASPIRE_8930G] = {
2245 .type = HDA_FIXUP_PINS,
2246 .v.pins = (const struct hda_pintbl[]) {
2247 { 0x16, 0x99130111 },
2248 { 0x1b, 0x99130112 },
2249 { }
2250 },
2251 .chained = true,
2252 .chain_id = ALC882_FIXUP_ASPIRE_8930G_VERBS,
2253 },
2254 [ALC882_FIXUP_ASPIRE_8930G_VERBS] = {
2255
2256 .type = HDA_FIXUP_VERBS,
2257 .v.verbs = (const struct hda_verb[]) {
2258
2259
2260
2261
2262 { 0x20, AC_VERB_SET_COEF_INDEX, 0x03 },
2263 { 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
2264
2265
2266
2267 { 0x20, AC_VERB_SET_COEF_INDEX, 0x08 },
2268 { 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280 { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b },
2281 { 0x20, AC_VERB_SET_PROC_COEF, 0x0003 },
2282 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2283 { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
2284 { }
2285 },
2286 .chained = true,
2287 .chain_id = ALC882_FIXUP_GPIO1,
2288 },
2289 [ALC885_FIXUP_MACPRO_GPIO] = {
2290 .type = HDA_FIXUP_FUNC,
2291 .v.func = alc885_fixup_macpro_gpio,
2292 },
2293 [ALC889_FIXUP_DAC_ROUTE] = {
2294 .type = HDA_FIXUP_FUNC,
2295 .v.func = alc889_fixup_dac_route,
2296 },
2297 [ALC889_FIXUP_MBP_VREF] = {
2298 .type = HDA_FIXUP_FUNC,
2299 .v.func = alc889_fixup_mbp_vref,
2300 .chained = true,
2301 .chain_id = ALC882_FIXUP_GPIO1,
2302 },
2303 [ALC889_FIXUP_IMAC91_VREF] = {
2304 .type = HDA_FIXUP_FUNC,
2305 .v.func = alc889_fixup_imac91_vref,
2306 .chained = true,
2307 .chain_id = ALC882_FIXUP_GPIO1,
2308 },
2309 [ALC889_FIXUP_MBA11_VREF] = {
2310 .type = HDA_FIXUP_FUNC,
2311 .v.func = alc889_fixup_mba11_vref,
2312 .chained = true,
2313 .chain_id = ALC889_FIXUP_MBP_VREF,
2314 },
2315 [ALC889_FIXUP_MBA21_VREF] = {
2316 .type = HDA_FIXUP_FUNC,
2317 .v.func = alc889_fixup_mba21_vref,
2318 .chained = true,
2319 .chain_id = ALC889_FIXUP_MBP_VREF,
2320 },
2321 [ALC889_FIXUP_MP11_VREF] = {
2322 .type = HDA_FIXUP_FUNC,
2323 .v.func = alc889_fixup_mba11_vref,
2324 .chained = true,
2325 .chain_id = ALC885_FIXUP_MACPRO_GPIO,
2326 },
2327 [ALC889_FIXUP_MP41_VREF] = {
2328 .type = HDA_FIXUP_FUNC,
2329 .v.func = alc889_fixup_mbp_vref,
2330 .chained = true,
2331 .chain_id = ALC885_FIXUP_MACPRO_GPIO,
2332 },
2333 [ALC882_FIXUP_INV_DMIC] = {
2334 .type = HDA_FIXUP_FUNC,
2335 .v.func = alc_fixup_inv_dmic,
2336 },
2337 [ALC882_FIXUP_NO_PRIMARY_HP] = {
2338 .type = HDA_FIXUP_FUNC,
2339 .v.func = alc882_fixup_no_primary_hp,
2340 },
2341 [ALC887_FIXUP_ASUS_BASS] = {
2342 .type = HDA_FIXUP_PINS,
2343 .v.pins = (const struct hda_pintbl[]) {
2344 {0x16, 0x99130130},
2345 {}
2346 },
2347 .chained = true,
2348 .chain_id = ALC887_FIXUP_BASS_CHMAP,
2349 },
2350 [ALC887_FIXUP_BASS_CHMAP] = {
2351 .type = HDA_FIXUP_FUNC,
2352 .v.func = alc_fixup_bass_chmap,
2353 },
2354 [ALC1220_FIXUP_GB_DUAL_CODECS] = {
2355 .type = HDA_FIXUP_FUNC,
2356 .v.func = alc1220_fixup_gb_dual_codecs,
2357 },
2358 [ALC1220_FIXUP_CLEVO_P950] = {
2359 .type = HDA_FIXUP_FUNC,
2360 .v.func = alc1220_fixup_clevo_p950,
2361 },
2362 [ALC1220_FIXUP_CLEVO_PB51ED] = {
2363 .type = HDA_FIXUP_FUNC,
2364 .v.func = alc1220_fixup_clevo_pb51ed,
2365 },
2366 [ALC1220_FIXUP_CLEVO_PB51ED_PINS] = {
2367 .type = HDA_FIXUP_PINS,
2368 .v.pins = (const struct hda_pintbl[]) {
2369 { 0x19, 0x01a1913c },
2370 {}
2371 },
2372 .chained = true,
2373 .chain_id = ALC1220_FIXUP_CLEVO_PB51ED,
2374 },
2375};
2376
2377static const struct snd_pci_quirk alc882_fixup_tbl[] = {
2378 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_FIXUP_ACER_EAPD),
2379 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
2380 SND_PCI_QUIRK(0x1025, 0x0107, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
2381 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_FIXUP_ACER_EAPD),
2382 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
2383 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_FIXUP_ACER_EAPD),
2384 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_FIXUP_ACER_EAPD),
2385 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
2386 ALC882_FIXUP_ACER_ASPIRE_4930G),
2387 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
2388 ALC882_FIXUP_ACER_ASPIRE_4930G),
2389 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
2390 ALC882_FIXUP_ACER_ASPIRE_8930G),
2391 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
2392 ALC882_FIXUP_ACER_ASPIRE_8930G),
2393 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
2394 ALC882_FIXUP_ACER_ASPIRE_4930G),
2395 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
2396 ALC882_FIXUP_ACER_ASPIRE_4930G),
2397 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
2398 ALC882_FIXUP_ACER_ASPIRE_4930G),
2399 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", ALC882_FIXUP_PB_M5210),
2400 SND_PCI_QUIRK(0x1025, 0x021e, "Acer Aspire 5739G",
2401 ALC882_FIXUP_ACER_ASPIRE_4930G),
2402 SND_PCI_QUIRK(0x1025, 0x0259, "Acer Aspire 5935", ALC889_FIXUP_DAC_ROUTE),
2403 SND_PCI_QUIRK(0x1025, 0x026b, "Acer Aspire 8940G", ALC882_FIXUP_ACER_ASPIRE_8930G),
2404 SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", ALC882_FIXUP_ACER_ASPIRE_7736),
2405 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_FIXUP_EAPD),
2406 SND_PCI_QUIRK(0x1043, 0x1873, "ASUS W90V", ALC882_FIXUP_ASUS_W90V),
2407 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_FIXUP_ASUS_W2JC),
2408 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_FIXUP_EEE1601),
2409 SND_PCI_QUIRK(0x1043, 0x84bc, "ASUS ET2700", ALC887_FIXUP_ASUS_BASS),
2410 SND_PCI_QUIRK(0x1043, 0x8691, "ASUS ROG Ranger VIII", ALC882_FIXUP_GPIO3),
2411 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT),
2412 SND_PCI_QUIRK(0x104d, 0x905a, "Sony Vaio Z", ALC882_FIXUP_NO_PRIMARY_HP),
2413 SND_PCI_QUIRK(0x104d, 0x9060, "Sony Vaio VPCL14M1R", ALC882_FIXUP_NO_PRIMARY_HP),
2414 SND_PCI_QUIRK(0x104d, 0x9043, "Sony Vaio VGC-LN51JGB", ALC882_FIXUP_NO_PRIMARY_HP),
2415 SND_PCI_QUIRK(0x104d, 0x9044, "Sony VAIO AiO", ALC882_FIXUP_NO_PRIMARY_HP),
2416
2417
2418 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC889_FIXUP_MBP_VREF),
2419 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC889_FIXUP_MBP_VREF),
2420 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF),
2421 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC889_FIXUP_MP11_VREF),
2422 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_FIXUP_MACPRO_GPIO),
2423 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_FIXUP_MACPRO_GPIO),
2424 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC889_FIXUP_MBP_VREF),
2425 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889_FIXUP_MBP_VREF),
2426 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_FIXUP_EAPD),
2427 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC889_FIXUP_MBA11_VREF),
2428 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC889_FIXUP_MBA21_VREF),
2429 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889_FIXUP_MBP_VREF),
2430 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF),
2431 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_FIXUP_MACPRO_GPIO),
2432 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC889_FIXUP_IMAC91_VREF),
2433 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC889_FIXUP_IMAC91_VREF),
2434 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC889_FIXUP_IMAC91_VREF),
2435 SND_PCI_QUIRK(0x106b, 0x4200, "Mac Pro 4,1/5,1", ALC889_FIXUP_MP41_VREF),
2436 SND_PCI_QUIRK(0x106b, 0x4300, "iMac 9,1", ALC889_FIXUP_IMAC91_VREF),
2437 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC889_FIXUP_IMAC91_VREF),
2438 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC889_FIXUP_IMAC91_VREF),
2439 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC889_FIXUP_MBA11_VREF),
2440
2441 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC882_FIXUP_EAPD),
2442 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3/Z87X-UD3H", ALC889_FIXUP_FRONT_HP_NO_PRESENCE),
2443 SND_PCI_QUIRK(0x1458, 0xa0b8, "Gigabyte AZ370-Gaming", ALC1220_FIXUP_GB_DUAL_CODECS),
2444 SND_PCI_QUIRK(0x1462, 0x7350, "MSI-7350", ALC889_FIXUP_CD),
2445 SND_PCI_QUIRK(0x1462, 0xda57, "MSI Z270-Gaming", ALC1220_FIXUP_GB_DUAL_CODECS),
2446 SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3),
2447 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX),
2448 SND_PCI_QUIRK(0x1558, 0x9501, "Clevo P950HR", ALC1220_FIXUP_CLEVO_P950),
2449 SND_PCI_QUIRK(0x1558, 0x95e1, "Clevo P95xER", ALC1220_FIXUP_CLEVO_P950),
2450 SND_PCI_QUIRK(0x1558, 0x95e2, "Clevo P950ER", ALC1220_FIXUP_CLEVO_P950),
2451 SND_PCI_QUIRK(0x1558, 0x96e1, "Clevo P960[ER][CDFN]-K", ALC1220_FIXUP_CLEVO_P950),
2452 SND_PCI_QUIRK(0x1558, 0x97e1, "Clevo P970[ER][CDFN]", ALC1220_FIXUP_CLEVO_P950),
2453 SND_PCI_QUIRK(0x1558, 0x65d1, "Clevo PB51[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
2454 SND_PCI_QUIRK(0x1558, 0x67d1, "Clevo PB71[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
2455 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD),
2456 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD),
2457 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", ALC882_FIXUP_LENOVO_Y530),
2458 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_FIXUP_COEF),
2459 {}
2460};
2461
2462static const struct hda_model_fixup alc882_fixup_models[] = {
2463 {.id = ALC882_FIXUP_ABIT_AW9D_MAX, .name = "abit-aw9d"},
2464 {.id = ALC882_FIXUP_LENOVO_Y530, .name = "lenovo-y530"},
2465 {.id = ALC882_FIXUP_ACER_ASPIRE_7736, .name = "acer-aspire-7736"},
2466 {.id = ALC882_FIXUP_ASUS_W90V, .name = "asus-w90v"},
2467 {.id = ALC889_FIXUP_CD, .name = "cd"},
2468 {.id = ALC889_FIXUP_FRONT_HP_NO_PRESENCE, .name = "no-front-hp"},
2469 {.id = ALC889_FIXUP_VAIO_TT, .name = "vaio-tt"},
2470 {.id = ALC888_FIXUP_EEE1601, .name = "eee1601"},
2471 {.id = ALC882_FIXUP_EAPD, .name = "alc882-eapd"},
2472 {.id = ALC883_FIXUP_EAPD, .name = "alc883-eapd"},
2473 {.id = ALC882_FIXUP_GPIO1, .name = "gpio1"},
2474 {.id = ALC882_FIXUP_GPIO2, .name = "gpio2"},
2475 {.id = ALC882_FIXUP_GPIO3, .name = "gpio3"},
2476 {.id = ALC889_FIXUP_COEF, .name = "alc889-coef"},
2477 {.id = ALC882_FIXUP_ASUS_W2JC, .name = "asus-w2jc"},
2478 {.id = ALC882_FIXUP_ACER_ASPIRE_4930G, .name = "acer-aspire-4930g"},
2479 {.id = ALC882_FIXUP_ACER_ASPIRE_8930G, .name = "acer-aspire-8930g"},
2480 {.id = ALC883_FIXUP_ACER_EAPD, .name = "acer-aspire"},
2481 {.id = ALC885_FIXUP_MACPRO_GPIO, .name = "macpro-gpio"},
2482 {.id = ALC889_FIXUP_DAC_ROUTE, .name = "dac-route"},
2483 {.id = ALC889_FIXUP_MBP_VREF, .name = "mbp-vref"},
2484 {.id = ALC889_FIXUP_IMAC91_VREF, .name = "imac91-vref"},
2485 {.id = ALC889_FIXUP_MBA11_VREF, .name = "mba11-vref"},
2486 {.id = ALC889_FIXUP_MBA21_VREF, .name = "mba21-vref"},
2487 {.id = ALC889_FIXUP_MP11_VREF, .name = "mp11-vref"},
2488 {.id = ALC889_FIXUP_MP41_VREF, .name = "mp41-vref"},
2489 {.id = ALC882_FIXUP_INV_DMIC, .name = "inv-dmic"},
2490 {.id = ALC882_FIXUP_NO_PRIMARY_HP, .name = "no-primary-hp"},
2491 {.id = ALC887_FIXUP_ASUS_BASS, .name = "asus-bass"},
2492 {.id = ALC1220_FIXUP_GB_DUAL_CODECS, .name = "dual-codecs"},
2493 {.id = ALC1220_FIXUP_CLEVO_P950, .name = "clevo-p950"},
2494 {}
2495};
2496
2497
2498
2499
2500
2501static int alc882_parse_auto_config(struct hda_codec *codec)
2502{
2503 static const hda_nid_t alc882_ignore[] = { 0x1d, 0 };
2504 static const hda_nid_t alc882_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2505 return alc_parse_auto_config(codec, alc882_ignore, alc882_ssids);
2506}
2507
2508
2509
2510static int patch_alc882(struct hda_codec *codec)
2511{
2512 struct alc_spec *spec;
2513 int err;
2514
2515 err = alc_alloc_spec(codec, 0x0b);
2516 if (err < 0)
2517 return err;
2518
2519 spec = codec->spec;
2520
2521 switch (codec->core.vendor_id) {
2522 case 0x10ec0882:
2523 case 0x10ec0885:
2524 case 0x10ec0900:
2525 case 0x10ec1220:
2526 break;
2527 default:
2528
2529 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
2530 break;
2531 }
2532
2533 alc_pre_init(codec);
2534
2535 snd_hda_pick_fixup(codec, alc882_fixup_models, alc882_fixup_tbl,
2536 alc882_fixups);
2537 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
2538
2539 alc_auto_parse_customize_define(codec);
2540
2541 if (has_cdefine_beep(codec))
2542 spec->gen.beep_nid = 0x01;
2543
2544
2545 err = alc882_parse_auto_config(codec);
2546 if (err < 0)
2547 goto error;
2548
2549 if (!spec->gen.no_analog && spec->gen.beep_nid) {
2550 err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
2551 if (err < 0)
2552 goto error;
2553 }
2554
2555 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
2556
2557 return 0;
2558
2559 error:
2560 alc_free(codec);
2561 return err;
2562}
2563
2564
2565
2566
2567
2568static int alc262_parse_auto_config(struct hda_codec *codec)
2569{
2570 static const hda_nid_t alc262_ignore[] = { 0x1d, 0 };
2571 static const hda_nid_t alc262_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2572 return alc_parse_auto_config(codec, alc262_ignore, alc262_ssids);
2573}
2574
2575
2576
2577
2578enum {
2579 ALC262_FIXUP_FSC_H270,
2580 ALC262_FIXUP_FSC_S7110,
2581 ALC262_FIXUP_HP_Z200,
2582 ALC262_FIXUP_TYAN,
2583 ALC262_FIXUP_LENOVO_3000,
2584 ALC262_FIXUP_BENQ,
2585 ALC262_FIXUP_BENQ_T31,
2586 ALC262_FIXUP_INV_DMIC,
2587 ALC262_FIXUP_INTEL_BAYLEYBAY,
2588};
2589
2590static const struct hda_fixup alc262_fixups[] = {
2591 [ALC262_FIXUP_FSC_H270] = {
2592 .type = HDA_FIXUP_PINS,
2593 .v.pins = (const struct hda_pintbl[]) {
2594 { 0x14, 0x99130110 },
2595 { 0x15, 0x0221142f },
2596 { 0x1b, 0x0121141f },
2597 { }
2598 }
2599 },
2600 [ALC262_FIXUP_FSC_S7110] = {
2601 .type = HDA_FIXUP_PINS,
2602 .v.pins = (const struct hda_pintbl[]) {
2603 { 0x15, 0x90170110 },
2604 { }
2605 },
2606 .chained = true,
2607 .chain_id = ALC262_FIXUP_BENQ,
2608 },
2609 [ALC262_FIXUP_HP_Z200] = {
2610 .type = HDA_FIXUP_PINS,
2611 .v.pins = (const struct hda_pintbl[]) {
2612 { 0x16, 0x99130120 },
2613 { }
2614 }
2615 },
2616 [ALC262_FIXUP_TYAN] = {
2617 .type = HDA_FIXUP_PINS,
2618 .v.pins = (const struct hda_pintbl[]) {
2619 { 0x14, 0x1993e1f0 },
2620 { }
2621 }
2622 },
2623 [ALC262_FIXUP_LENOVO_3000] = {
2624 .type = HDA_FIXUP_PINCTLS,
2625 .v.pins = (const struct hda_pintbl[]) {
2626 { 0x19, PIN_VREF50 },
2627 {}
2628 },
2629 .chained = true,
2630 .chain_id = ALC262_FIXUP_BENQ,
2631 },
2632 [ALC262_FIXUP_BENQ] = {
2633 .type = HDA_FIXUP_VERBS,
2634 .v.verbs = (const struct hda_verb[]) {
2635 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2636 { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
2637 {}
2638 }
2639 },
2640 [ALC262_FIXUP_BENQ_T31] = {
2641 .type = HDA_FIXUP_VERBS,
2642 .v.verbs = (const struct hda_verb[]) {
2643 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2644 { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
2645 {}
2646 }
2647 },
2648 [ALC262_FIXUP_INV_DMIC] = {
2649 .type = HDA_FIXUP_FUNC,
2650 .v.func = alc_fixup_inv_dmic,
2651 },
2652 [ALC262_FIXUP_INTEL_BAYLEYBAY] = {
2653 .type = HDA_FIXUP_FUNC,
2654 .v.func = alc_fixup_no_depop_delay,
2655 },
2656};
2657
2658static const struct snd_pci_quirk alc262_fixup_tbl[] = {
2659 SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", ALC262_FIXUP_HP_Z200),
2660 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu Lifebook S7110", ALC262_FIXUP_FSC_S7110),
2661 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FIXUP_BENQ),
2662 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_FIXUP_TYAN),
2663 SND_PCI_QUIRK(0x1734, 0x1141, "FSC ESPRIMO U9210", ALC262_FIXUP_FSC_H270),
2664 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", ALC262_FIXUP_FSC_H270),
2665 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000", ALC262_FIXUP_LENOVO_3000),
2666 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_FIXUP_BENQ),
2667 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_FIXUP_BENQ_T31),
2668 SND_PCI_QUIRK(0x8086, 0x7270, "BayleyBay", ALC262_FIXUP_INTEL_BAYLEYBAY),
2669 {}
2670};
2671
2672static const struct hda_model_fixup alc262_fixup_models[] = {
2673 {.id = ALC262_FIXUP_INV_DMIC, .name = "inv-dmic"},
2674 {.id = ALC262_FIXUP_FSC_H270, .name = "fsc-h270"},
2675 {.id = ALC262_FIXUP_FSC_S7110, .name = "fsc-s7110"},
2676 {.id = ALC262_FIXUP_HP_Z200, .name = "hp-z200"},
2677 {.id = ALC262_FIXUP_TYAN, .name = "tyan"},
2678 {.id = ALC262_FIXUP_LENOVO_3000, .name = "lenovo-3000"},
2679 {.id = ALC262_FIXUP_BENQ, .name = "benq"},
2680 {.id = ALC262_FIXUP_BENQ_T31, .name = "benq-t31"},
2681 {.id = ALC262_FIXUP_INTEL_BAYLEYBAY, .name = "bayleybay"},
2682 {}
2683};
2684
2685
2686
2687static int patch_alc262(struct hda_codec *codec)
2688{
2689 struct alc_spec *spec;
2690 int err;
2691
2692 err = alc_alloc_spec(codec, 0x0b);
2693 if (err < 0)
2694 return err;
2695
2696 spec = codec->spec;
2697 spec->gen.shared_mic_vref_pin = 0x18;
2698
2699 spec->shutup = alc_eapd_shutup;
2700
2701#if 0
2702
2703
2704
2705 alc_update_coefex_idx(codec, 0x1a, 7, 0, 0x80);
2706#endif
2707 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
2708
2709 alc_pre_init(codec);
2710
2711 snd_hda_pick_fixup(codec, alc262_fixup_models, alc262_fixup_tbl,
2712 alc262_fixups);
2713 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
2714
2715 alc_auto_parse_customize_define(codec);
2716
2717 if (has_cdefine_beep(codec))
2718 spec->gen.beep_nid = 0x01;
2719
2720
2721 err = alc262_parse_auto_config(codec);
2722 if (err < 0)
2723 goto error;
2724
2725 if (!spec->gen.no_analog && spec->gen.beep_nid) {
2726 err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
2727 if (err < 0)
2728 goto error;
2729 }
2730
2731 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
2732
2733 return 0;
2734
2735 error:
2736 alc_free(codec);
2737 return err;
2738}
2739
2740
2741
2742
2743
2744static int alc268_beep_switch_put(struct snd_kcontrol *kcontrol,
2745 struct snd_ctl_elem_value *ucontrol)
2746{
2747 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2748 unsigned long pval;
2749 int err;
2750
2751 mutex_lock(&codec->control_mutex);
2752 pval = kcontrol->private_value;
2753 kcontrol->private_value = (pval & ~0xff) | 0x0f;
2754 err = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
2755 if (err >= 0) {
2756 kcontrol->private_value = (pval & ~0xff) | 0x10;
2757 err = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
2758 }
2759 kcontrol->private_value = pval;
2760 mutex_unlock(&codec->control_mutex);
2761 return err;
2762}
2763
2764static const struct snd_kcontrol_new alc268_beep_mixer[] = {
2765 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
2766 {
2767 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2768 .name = "Beep Playback Switch",
2769 .subdevice = HDA_SUBDEV_AMP_FLAG,
2770 .info = snd_hda_mixer_amp_switch_info,
2771 .get = snd_hda_mixer_amp_switch_get,
2772 .put = alc268_beep_switch_put,
2773 .private_value = HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT)
2774 },
2775};
2776
2777
2778static const struct hda_verb alc268_beep_init_verbs[] = {
2779 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2780 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2781 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2782 { }
2783};
2784
2785enum {
2786 ALC268_FIXUP_INV_DMIC,
2787 ALC268_FIXUP_HP_EAPD,
2788 ALC268_FIXUP_SPDIF,
2789};
2790
2791static const struct hda_fixup alc268_fixups[] = {
2792 [ALC268_FIXUP_INV_DMIC] = {
2793 .type = HDA_FIXUP_FUNC,
2794 .v.func = alc_fixup_inv_dmic,
2795 },
2796 [ALC268_FIXUP_HP_EAPD] = {
2797 .type = HDA_FIXUP_VERBS,
2798 .v.verbs = (const struct hda_verb[]) {
2799 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 0},
2800 {}
2801 }
2802 },
2803 [ALC268_FIXUP_SPDIF] = {
2804 .type = HDA_FIXUP_PINS,
2805 .v.pins = (const struct hda_pintbl[]) {
2806 { 0x1e, 0x014b1180 },
2807 {}
2808 }
2809 },
2810};
2811
2812static const struct hda_model_fixup alc268_fixup_models[] = {
2813 {.id = ALC268_FIXUP_INV_DMIC, .name = "inv-dmic"},
2814 {.id = ALC268_FIXUP_HP_EAPD, .name = "hp-eapd"},
2815 {.id = ALC268_FIXUP_SPDIF, .name = "spdif"},
2816 {}
2817};
2818
2819static const struct snd_pci_quirk alc268_fixup_tbl[] = {
2820 SND_PCI_QUIRK(0x1025, 0x0139, "Acer TravelMate 6293", ALC268_FIXUP_SPDIF),
2821 SND_PCI_QUIRK(0x1025, 0x015b, "Acer AOA 150 (ZG5)", ALC268_FIXUP_INV_DMIC),
2822
2823
2824
2825 SND_PCI_QUIRK(0x1179, 0xff06, "Toshiba P200", ALC268_FIXUP_HP_EAPD),
2826 {}
2827};
2828
2829
2830
2831
2832static int alc268_parse_auto_config(struct hda_codec *codec)
2833{
2834 static const hda_nid_t alc268_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2835 return alc_parse_auto_config(codec, NULL, alc268_ssids);
2836}
2837
2838
2839
2840static int patch_alc268(struct hda_codec *codec)
2841{
2842 struct alc_spec *spec;
2843 int i, err;
2844
2845
2846 err = alc_alloc_spec(codec, 0);
2847 if (err < 0)
2848 return err;
2849
2850 spec = codec->spec;
2851 if (has_cdefine_beep(codec))
2852 spec->gen.beep_nid = 0x01;
2853
2854 spec->shutup = alc_eapd_shutup;
2855
2856 alc_pre_init(codec);
2857
2858 snd_hda_pick_fixup(codec, alc268_fixup_models, alc268_fixup_tbl, alc268_fixups);
2859 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
2860
2861
2862 err = alc268_parse_auto_config(codec);
2863 if (err < 0)
2864 goto error;
2865
2866 if (err > 0 && !spec->gen.no_analog &&
2867 spec->gen.autocfg.speaker_pins[0] != 0x1d) {
2868 for (i = 0; i < ARRAY_SIZE(alc268_beep_mixer); i++) {
2869 if (!snd_hda_gen_add_kctl(&spec->gen, NULL,
2870 &alc268_beep_mixer[i])) {
2871 err = -ENOMEM;
2872 goto error;
2873 }
2874 }
2875 snd_hda_add_verbs(codec, alc268_beep_init_verbs);
2876 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
2877
2878 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
2879 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
2880 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
2881 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
2882 (0 << AC_AMPCAP_MUTE_SHIFT));
2883 }
2884
2885 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
2886
2887 return 0;
2888
2889 error:
2890 alc_free(codec);
2891 return err;
2892}
2893
2894
2895
2896
2897
2898static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
2899 .rates = SNDRV_PCM_RATE_44100,
2900};
2901
2902static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
2903 .rates = SNDRV_PCM_RATE_44100,
2904};
2905
2906
2907enum {
2908 ALC269_TYPE_ALC269VA,
2909 ALC269_TYPE_ALC269VB,
2910 ALC269_TYPE_ALC269VC,
2911 ALC269_TYPE_ALC269VD,
2912 ALC269_TYPE_ALC280,
2913 ALC269_TYPE_ALC282,
2914 ALC269_TYPE_ALC283,
2915 ALC269_TYPE_ALC284,
2916 ALC269_TYPE_ALC293,
2917 ALC269_TYPE_ALC286,
2918 ALC269_TYPE_ALC298,
2919 ALC269_TYPE_ALC255,
2920 ALC269_TYPE_ALC256,
2921 ALC269_TYPE_ALC257,
2922 ALC269_TYPE_ALC215,
2923 ALC269_TYPE_ALC225,
2924 ALC269_TYPE_ALC294,
2925 ALC269_TYPE_ALC300,
2926 ALC269_TYPE_ALC623,
2927 ALC269_TYPE_ALC700,
2928};
2929
2930
2931
2932
2933static int alc269_parse_auto_config(struct hda_codec *codec)
2934{
2935 static const hda_nid_t alc269_ignore[] = { 0x1d, 0 };
2936 static const hda_nid_t alc269_ssids[] = { 0, 0x1b, 0x14, 0x21 };
2937 static const hda_nid_t alc269va_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2938 struct alc_spec *spec = codec->spec;
2939 const hda_nid_t *ssids;
2940
2941 switch (spec->codec_variant) {
2942 case ALC269_TYPE_ALC269VA:
2943 case ALC269_TYPE_ALC269VC:
2944 case ALC269_TYPE_ALC280:
2945 case ALC269_TYPE_ALC284:
2946 case ALC269_TYPE_ALC293:
2947 ssids = alc269va_ssids;
2948 break;
2949 case ALC269_TYPE_ALC269VB:
2950 case ALC269_TYPE_ALC269VD:
2951 case ALC269_TYPE_ALC282:
2952 case ALC269_TYPE_ALC283:
2953 case ALC269_TYPE_ALC286:
2954 case ALC269_TYPE_ALC298:
2955 case ALC269_TYPE_ALC255:
2956 case ALC269_TYPE_ALC256:
2957 case ALC269_TYPE_ALC257:
2958 case ALC269_TYPE_ALC215:
2959 case ALC269_TYPE_ALC225:
2960 case ALC269_TYPE_ALC294:
2961 case ALC269_TYPE_ALC300:
2962 case ALC269_TYPE_ALC623:
2963 case ALC269_TYPE_ALC700:
2964 ssids = alc269_ssids;
2965 break;
2966 default:
2967 ssids = alc269_ssids;
2968 break;
2969 }
2970
2971 return alc_parse_auto_config(codec, alc269_ignore, ssids);
2972}
2973
2974static void alc269vb_toggle_power_output(struct hda_codec *codec, int power_up)
2975{
2976 alc_update_coef_idx(codec, 0x04, 1 << 11, power_up ? (1 << 11) : 0);
2977}
2978
2979static void alc269_shutup(struct hda_codec *codec)
2980{
2981 struct alc_spec *spec = codec->spec;
2982
2983 if (spec->codec_variant == ALC269_TYPE_ALC269VB)
2984 alc269vb_toggle_power_output(codec, 0);
2985 if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
2986 (alc_get_coef0(codec) & 0x00ff) == 0x018) {
2987 msleep(150);
2988 }
2989 alc_shutup_pins(codec);
2990}
2991
2992static struct coef_fw alc282_coefs[] = {
2993 WRITE_COEF(0x03, 0x0002),
2994 UPDATE_COEF(0x05, 0xff3f, 0x0700),
2995 WRITE_COEF(0x07, 0x0200),
2996 UPDATE_COEF(0x06, 0x00f0, 0),
2997 UPDATE_COEF(0x08, 0xfffc, 0x0c2c),
2998 WRITE_COEF(0x0a, 0xcccc),
2999 WRITE_COEF(0x0b, 0xcccc),
3000 WRITE_COEF(0x0e, 0x6e00),
3001 UPDATE_COEF(0x0f, 0xf800, 0x1000),
3002 UPDATE_COEF(0x10, 0xfc00, 0x0c00),
3003 WRITE_COEF(0x6f, 0x0),
3004 UPDATE_COEF(0x0c, 0xfe00, 0),
3005 WRITE_COEF(0x34, 0xa0c0),
3006 UPDATE_COEF(0x16, 0x0008, 0),
3007 UPDATE_COEF(0x1d, 0x00e0, 0),
3008 UPDATE_COEF(0x1f, 0x00e0, 0),
3009 WRITE_COEF(0x21, 0x8804),
3010 WRITE_COEF(0x63, 0x2902),
3011 WRITE_COEF(0x68, 0xa080),
3012 WRITE_COEF(0x69, 0x3400),
3013 WRITE_COEF(0x6a, 0x2f3e),
3014 WRITE_COEF(0x6b, 0x0),
3015 UPDATE_COEF(0x6d, 0x0fff, 0x0900),
3016 WRITE_COEF(0x6e, 0x110a),
3017 UPDATE_COEF(0x70, 0x00f8, 0x00d8),
3018 WRITE_COEF(0x71, 0x0014),
3019 WRITE_COEF(0x72, 0xc2ba),
3020 UPDATE_COEF(0x77, 0x0f80, 0),
3021 WRITE_COEF(0x6c, 0xfc06),
3022 {}
3023};
3024
3025static void alc282_restore_default_value(struct hda_codec *codec)
3026{
3027 alc_process_coef_fw(codec, alc282_coefs);
3028}
3029
3030static void alc282_init(struct hda_codec *codec)
3031{
3032 struct alc_spec *spec = codec->spec;
3033 hda_nid_t hp_pin = alc_get_hp_pin(spec);
3034 bool hp_pin_sense;
3035 int coef78;
3036
3037 alc282_restore_default_value(codec);
3038
3039 if (!hp_pin)
3040 return;
3041 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3042 coef78 = alc_read_coef_idx(codec, 0x78);
3043
3044
3045
3046 alc_write_coef_idx(codec, 0x78, 0x9004);
3047
3048 if (hp_pin_sense)
3049 msleep(2);
3050
3051 snd_hda_codec_write(codec, hp_pin, 0,
3052 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3053
3054 if (hp_pin_sense)
3055 msleep(85);
3056
3057 snd_hda_codec_write(codec, hp_pin, 0,
3058 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3059
3060 if (hp_pin_sense)
3061 msleep(100);
3062
3063
3064 alc_write_coef_idx(codec, 0x78, coef78);
3065}
3066
3067static void alc282_shutup(struct hda_codec *codec)
3068{
3069 struct alc_spec *spec = codec->spec;
3070 hda_nid_t hp_pin = alc_get_hp_pin(spec);
3071 bool hp_pin_sense;
3072 int coef78;
3073
3074 if (!hp_pin) {
3075 alc269_shutup(codec);
3076 return;
3077 }
3078
3079 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3080 coef78 = alc_read_coef_idx(codec, 0x78);
3081 alc_write_coef_idx(codec, 0x78, 0x9004);
3082
3083 if (hp_pin_sense)
3084 msleep(2);
3085
3086 snd_hda_codec_write(codec, hp_pin, 0,
3087 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3088
3089 if (hp_pin_sense)
3090 msleep(85);
3091
3092 if (!spec->no_shutup_pins)
3093 snd_hda_codec_write(codec, hp_pin, 0,
3094 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
3095
3096 if (hp_pin_sense)
3097 msleep(100);
3098
3099 alc_auto_setup_eapd(codec, false);
3100 alc_shutup_pins(codec);
3101 alc_write_coef_idx(codec, 0x78, coef78);
3102}
3103
3104static struct coef_fw alc283_coefs[] = {
3105 WRITE_COEF(0x03, 0x0002),
3106 UPDATE_COEF(0x05, 0xff3f, 0x0700),
3107 WRITE_COEF(0x07, 0x0200),
3108 UPDATE_COEF(0x06, 0x00f0, 0),
3109 UPDATE_COEF(0x08, 0xfffc, 0x0c2c),
3110 WRITE_COEF(0x0a, 0xcccc),
3111 WRITE_COEF(0x0b, 0xcccc),
3112 WRITE_COEF(0x0e, 0x6fc0),
3113 UPDATE_COEF(0x0f, 0xf800, 0x1000),
3114 UPDATE_COEF(0x10, 0xfc00, 0x0c00),
3115 WRITE_COEF(0x3a, 0x0),
3116 UPDATE_COEF(0x0c, 0xfe00, 0x0),
3117 WRITE_COEF(0x22, 0xa0c0),
3118 UPDATE_COEFEX(0x53, 0x01, 0x000f, 0x0008),
3119 UPDATE_COEF(0x1d, 0x00e0, 0),
3120 UPDATE_COEF(0x1f, 0x00e0, 0),
3121 WRITE_COEF(0x21, 0x8804),
3122 WRITE_COEF(0x2e, 0x2902),
3123 WRITE_COEF(0x33, 0xa080),
3124 WRITE_COEF(0x34, 0x3400),
3125 WRITE_COEF(0x35, 0x2f3e),
3126 WRITE_COEF(0x36, 0x0),
3127 UPDATE_COEF(0x38, 0x0fff, 0x0900),
3128 WRITE_COEF(0x39, 0x110a),
3129 UPDATE_COEF(0x3b, 0x00f8, 0x00d8),
3130 WRITE_COEF(0x3c, 0x0014),
3131 WRITE_COEF(0x3d, 0xc2ba),
3132 UPDATE_COEF(0x42, 0x0f80, 0x0),
3133 WRITE_COEF(0x49, 0x0),
3134 UPDATE_COEF(0x40, 0xf800, 0x9800),
3135 UPDATE_COEF(0x42, 0xf000, 0x2000),
3136 WRITE_COEF(0x37, 0xfc06),
3137 UPDATE_COEF(0x1b, 0x8000, 0),
3138 {}
3139};
3140
3141static void alc283_restore_default_value(struct hda_codec *codec)
3142{
3143 alc_process_coef_fw(codec, alc283_coefs);
3144}
3145
3146static void alc283_init(struct hda_codec *codec)
3147{
3148 struct alc_spec *spec = codec->spec;
3149 hda_nid_t hp_pin = alc_get_hp_pin(spec);
3150 bool hp_pin_sense;
3151
3152 alc283_restore_default_value(codec);
3153
3154 if (!hp_pin)
3155 return;
3156
3157 msleep(30);
3158 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3159
3160
3161
3162 alc_write_coef_idx(codec, 0x43, 0x9004);
3163
3164 snd_hda_codec_write(codec, hp_pin, 0,
3165 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3166
3167 if (hp_pin_sense)
3168 msleep(85);
3169
3170 snd_hda_codec_write(codec, hp_pin, 0,
3171 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3172
3173 if (hp_pin_sense)
3174 msleep(85);
3175
3176
3177 alc_update_coef_idx(codec, 0x46, 3 << 12, 0);
3178
3179 alc_write_coef_idx(codec, 0x43, 0x9614);
3180}
3181
3182static void alc283_shutup(struct hda_codec *codec)
3183{
3184 struct alc_spec *spec = codec->spec;
3185 hda_nid_t hp_pin = alc_get_hp_pin(spec);
3186 bool hp_pin_sense;
3187
3188 if (!hp_pin) {
3189 alc269_shutup(codec);
3190 return;
3191 }
3192
3193 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3194
3195 alc_write_coef_idx(codec, 0x43, 0x9004);
3196
3197
3198 alc_write_coef_idx(codec, 0x06, 0x2100);
3199
3200 snd_hda_codec_write(codec, hp_pin, 0,
3201 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3202
3203 if (hp_pin_sense)
3204 msleep(100);
3205
3206 if (!spec->no_shutup_pins)
3207 snd_hda_codec_write(codec, hp_pin, 0,
3208 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
3209
3210 alc_update_coef_idx(codec, 0x46, 0, 3 << 12);
3211
3212 if (hp_pin_sense)
3213 msleep(100);
3214 alc_auto_setup_eapd(codec, false);
3215 alc_shutup_pins(codec);
3216 alc_write_coef_idx(codec, 0x43, 0x9614);
3217}
3218
3219static void alc256_init(struct hda_codec *codec)
3220{
3221 struct alc_spec *spec = codec->spec;
3222 hda_nid_t hp_pin = alc_get_hp_pin(spec);
3223 bool hp_pin_sense;
3224
3225 if (!hp_pin)
3226 hp_pin = 0x21;
3227
3228 msleep(30);
3229
3230 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3231
3232 if (hp_pin_sense)
3233 msleep(2);
3234
3235 alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1);
3236 if (spec->ultra_low_power) {
3237 alc_update_coef_idx(codec, 0x03, 1<<1, 1<<1);
3238 alc_update_coef_idx(codec, 0x08, 3<<2, 3<<2);
3239 alc_update_coef_idx(codec, 0x08, 7<<4, 0);
3240 alc_update_coef_idx(codec, 0x3b, 1<<15, 0);
3241 alc_update_coef_idx(codec, 0x0e, 7<<6, 7<<6);
3242 msleep(30);
3243 }
3244
3245 snd_hda_codec_write(codec, hp_pin, 0,
3246 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3247
3248 if (hp_pin_sense || spec->ultra_low_power)
3249 msleep(85);
3250
3251 snd_hda_codec_write(codec, hp_pin, 0,
3252 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3253
3254 if (hp_pin_sense || spec->ultra_low_power)
3255 msleep(100);
3256
3257 alc_update_coef_idx(codec, 0x46, 3 << 12, 0);
3258 alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x4);
3259 alc_update_coefex_idx(codec, 0x53, 0x02, 0x8000, 1 << 15);
3260 alc_update_coefex_idx(codec, 0x53, 0x02, 0x8000, 0 << 15);
3261 alc_update_coef_idx(codec, 0x36, 1 << 13, 1 << 5);
3262}
3263
3264static void alc256_shutup(struct hda_codec *codec)
3265{
3266 struct alc_spec *spec = codec->spec;
3267 hda_nid_t hp_pin = alc_get_hp_pin(spec);
3268 bool hp_pin_sense;
3269
3270 if (!hp_pin)
3271 hp_pin = 0x21;
3272
3273 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3274
3275 if (hp_pin_sense)
3276 msleep(2);
3277
3278 snd_hda_codec_write(codec, hp_pin, 0,
3279 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3280
3281 if (hp_pin_sense || spec->ultra_low_power)
3282 msleep(85);
3283
3284
3285
3286 alc_update_coef_idx(codec, 0x46, 0, 3 << 12);
3287
3288 if (!spec->no_shutup_pins)
3289 snd_hda_codec_write(codec, hp_pin, 0,
3290 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
3291
3292 if (hp_pin_sense || spec->ultra_low_power)
3293 msleep(100);
3294
3295 alc_auto_setup_eapd(codec, false);
3296 alc_shutup_pins(codec);
3297 if (spec->ultra_low_power) {
3298 msleep(50);
3299 alc_update_coef_idx(codec, 0x03, 1<<1, 0);
3300 alc_update_coef_idx(codec, 0x08, 7<<4, 7<<4);
3301 alc_update_coef_idx(codec, 0x08, 3<<2, 0);
3302 alc_update_coef_idx(codec, 0x3b, 1<<15, 1<<15);
3303 alc_update_coef_idx(codec, 0x0e, 7<<6, 0);
3304 msleep(30);
3305 }
3306}
3307
3308static void alc225_init(struct hda_codec *codec)
3309{
3310 struct alc_spec *spec = codec->spec;
3311 hda_nid_t hp_pin = alc_get_hp_pin(spec);
3312 bool hp1_pin_sense, hp2_pin_sense;
3313
3314 if (!hp_pin)
3315 hp_pin = 0x21;
3316 msleep(30);
3317
3318 hp1_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3319 hp2_pin_sense = snd_hda_jack_detect(codec, 0x16);
3320
3321 if (hp1_pin_sense || hp2_pin_sense)
3322 msleep(2);
3323
3324 alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1);
3325 if (spec->ultra_low_power) {
3326 alc_update_coef_idx(codec, 0x08, 0x0f << 2, 3<<2);
3327 alc_update_coef_idx(codec, 0x0e, 7<<6, 7<<6);
3328 alc_update_coef_idx(codec, 0x33, 1<<11, 0);
3329 msleep(30);
3330 }
3331
3332 if (hp1_pin_sense || spec->ultra_low_power)
3333 snd_hda_codec_write(codec, hp_pin, 0,
3334 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3335 if (hp2_pin_sense)
3336 snd_hda_codec_write(codec, 0x16, 0,
3337 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3338
3339 if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power)
3340 msleep(85);
3341
3342 if (hp1_pin_sense || spec->ultra_low_power)
3343 snd_hda_codec_write(codec, hp_pin, 0,
3344 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3345 if (hp2_pin_sense)
3346 snd_hda_codec_write(codec, 0x16, 0,
3347 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3348
3349 if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power)
3350 msleep(100);
3351
3352 alc_update_coef_idx(codec, 0x4a, 3 << 10, 0);
3353 alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x4);
3354}
3355
3356static void alc225_shutup(struct hda_codec *codec)
3357{
3358 struct alc_spec *spec = codec->spec;
3359 hda_nid_t hp_pin = alc_get_hp_pin(spec);
3360 bool hp1_pin_sense, hp2_pin_sense;
3361
3362 if (!hp_pin)
3363 hp_pin = 0x21;
3364
3365 alc_update_coef_idx(codec, 0x4a, 0, 3 << 10);
3366
3367 hp1_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3368 hp2_pin_sense = snd_hda_jack_detect(codec, 0x16);
3369
3370 if (hp1_pin_sense || hp2_pin_sense)
3371 msleep(2);
3372
3373 if (hp1_pin_sense || spec->ultra_low_power)
3374 snd_hda_codec_write(codec, hp_pin, 0,
3375 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3376 if (hp2_pin_sense)
3377 snd_hda_codec_write(codec, 0x16, 0,
3378 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3379
3380 if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power)
3381 msleep(85);
3382
3383 if (hp1_pin_sense || spec->ultra_low_power)
3384 snd_hda_codec_write(codec, hp_pin, 0,
3385 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
3386 if (hp2_pin_sense)
3387 snd_hda_codec_write(codec, 0x16, 0,
3388 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
3389
3390 if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power)
3391 msleep(100);
3392
3393 alc_auto_setup_eapd(codec, false);
3394 alc_shutup_pins(codec);
3395 if (spec->ultra_low_power) {
3396 msleep(50);
3397 alc_update_coef_idx(codec, 0x08, 0x0f << 2, 0x0c << 2);
3398 alc_update_coef_idx(codec, 0x0e, 7<<6, 0);
3399 alc_update_coef_idx(codec, 0x33, 1<<11, 1<<11);
3400 alc_update_coef_idx(codec, 0x4a, 3<<4, 2<<4);
3401 msleep(30);
3402 }
3403}
3404
3405static void alc_default_init(struct hda_codec *codec)
3406{
3407 struct alc_spec *spec = codec->spec;
3408 hda_nid_t hp_pin = alc_get_hp_pin(spec);
3409 bool hp_pin_sense;
3410
3411 if (!hp_pin)
3412 return;
3413
3414 msleep(30);
3415
3416 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3417
3418 if (hp_pin_sense)
3419 msleep(2);
3420
3421 snd_hda_codec_write(codec, hp_pin, 0,
3422 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3423
3424 if (hp_pin_sense)
3425 msleep(85);
3426
3427 snd_hda_codec_write(codec, hp_pin, 0,
3428 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3429
3430 if (hp_pin_sense)
3431 msleep(100);
3432}
3433
3434static void alc_default_shutup(struct hda_codec *codec)
3435{
3436 struct alc_spec *spec = codec->spec;
3437 hda_nid_t hp_pin = alc_get_hp_pin(spec);
3438 bool hp_pin_sense;
3439
3440 if (!hp_pin) {
3441 alc269_shutup(codec);
3442 return;
3443 }
3444
3445 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3446
3447 if (hp_pin_sense)
3448 msleep(2);
3449
3450 snd_hda_codec_write(codec, hp_pin, 0,
3451 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3452
3453 if (hp_pin_sense)
3454 msleep(85);
3455
3456 if (!spec->no_shutup_pins)
3457 snd_hda_codec_write(codec, hp_pin, 0,
3458 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
3459
3460 if (hp_pin_sense)
3461 msleep(100);
3462
3463 alc_auto_setup_eapd(codec, false);
3464 alc_shutup_pins(codec);
3465}
3466
3467static void alc294_hp_init(struct hda_codec *codec)
3468{
3469 struct alc_spec *spec = codec->spec;
3470 hda_nid_t hp_pin = alc_get_hp_pin(spec);
3471 int i, val;
3472
3473 if (!hp_pin)
3474 return;
3475
3476 snd_hda_codec_write(codec, hp_pin, 0,
3477 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3478
3479 msleep(100);
3480
3481 if (!spec->no_shutup_pins)
3482 snd_hda_codec_write(codec, hp_pin, 0,
3483 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
3484
3485 alc_update_coef_idx(codec, 0x6f, 0x000f, 0);
3486 alc_update_coefex_idx(codec, 0x58, 0x00, 0x8000, 0x8000);
3487
3488
3489 val = alc_read_coefex_idx(codec, 0x58, 0x01);
3490 for (i = 0; i < 20 && val & 0x0080; i++) {
3491 msleep(50);
3492 val = alc_read_coefex_idx(codec, 0x58, 0x01);
3493 }
3494
3495 alc_update_coef_idx(codec, 0x6f, 0x000f, 0x000b);
3496 msleep(50);
3497}
3498
3499static void alc294_init(struct hda_codec *codec)
3500{
3501 struct alc_spec *spec = codec->spec;
3502
3503
3504 if (!spec->done_hp_init ||
3505 codec->core.dev.power.power_state.event == PM_EVENT_RESTORE) {
3506 alc294_hp_init(codec);
3507 spec->done_hp_init = true;
3508 }
3509 alc_default_init(codec);
3510}
3511
3512static void alc5505_coef_set(struct hda_codec *codec, unsigned int index_reg,
3513 unsigned int val)
3514{
3515 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_COEF_INDEX, index_reg >> 1);
3516 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_PROC_COEF, val & 0xffff);
3517 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_PROC_COEF, val >> 16);
3518}
3519
3520static int alc5505_coef_get(struct hda_codec *codec, unsigned int index_reg)
3521{
3522 unsigned int val;
3523
3524 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_COEF_INDEX, index_reg >> 1);
3525 val = snd_hda_codec_read(codec, 0x51, 0, AC_VERB_GET_PROC_COEF, 0)
3526 & 0xffff;
3527 val |= snd_hda_codec_read(codec, 0x51, 0, AC_VERB_GET_PROC_COEF, 0)
3528 << 16;
3529 return val;
3530}
3531
3532static void alc5505_dsp_halt(struct hda_codec *codec)
3533{
3534 unsigned int val;
3535
3536 alc5505_coef_set(codec, 0x3000, 0x000c);
3537 alc5505_coef_set(codec, 0x880c, 0x0008);
3538 alc5505_coef_set(codec, 0x61c0, 0x11110080);
3539 alc5505_coef_set(codec, 0x6230, 0xfc0d4011);
3540 alc5505_coef_set(codec, 0x61b4, 0x040a2b03);
3541 alc5505_coef_set(codec, 0x61b0, 0x00005b17);
3542 alc5505_coef_set(codec, 0x61b8, 0x04133303);
3543 val = alc5505_coef_get(codec, 0x6220);
3544 alc5505_coef_set(codec, 0x6220, (val | 0x3000));
3545}
3546
3547static void alc5505_dsp_back_from_halt(struct hda_codec *codec)
3548{
3549 alc5505_coef_set(codec, 0x61b8, 0x04133302);
3550 alc5505_coef_set(codec, 0x61b0, 0x00005b16);
3551 alc5505_coef_set(codec, 0x61b4, 0x040a2b02);
3552 alc5505_coef_set(codec, 0x6230, 0xf80d4011);
3553 alc5505_coef_set(codec, 0x6220, 0x2002010f);
3554 alc5505_coef_set(codec, 0x880c, 0x00000004);
3555}
3556
3557static void alc5505_dsp_init(struct hda_codec *codec)
3558{
3559 unsigned int val;
3560
3561 alc5505_dsp_halt(codec);
3562 alc5505_dsp_back_from_halt(codec);
3563 alc5505_coef_set(codec, 0x61b0, 0x5b14);
3564 alc5505_coef_set(codec, 0x61b0, 0x5b16);
3565 alc5505_coef_set(codec, 0x61b4, 0x04132b00);
3566 alc5505_coef_set(codec, 0x61b4, 0x04132b02);
3567 alc5505_coef_set(codec, 0x61b8, 0x041f3300);
3568 alc5505_coef_set(codec, 0x61b8, 0x041f3302);
3569 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_CODEC_RESET, 0);
3570 alc5505_coef_set(codec, 0x61b8, 0x041b3302);
3571 alc5505_coef_set(codec, 0x61b8, 0x04173302);
3572 alc5505_coef_set(codec, 0x61b8, 0x04163302);
3573 alc5505_coef_set(codec, 0x8800, 0x348b328b);
3574 alc5505_coef_set(codec, 0x8808, 0x00020022);
3575 alc5505_coef_set(codec, 0x8818, 0x00000400);
3576
3577 val = alc5505_coef_get(codec, 0x6200) >> 16;
3578 if (val <= 3)
3579 alc5505_coef_set(codec, 0x6220, 0x2002010f);
3580 else
3581 alc5505_coef_set(codec, 0x6220, 0x6002018f);
3582
3583 alc5505_coef_set(codec, 0x61ac, 0x055525f0);
3584 alc5505_coef_set(codec, 0x61c0, 0x12230080);
3585 alc5505_coef_set(codec, 0x61b4, 0x040e2b02);
3586 alc5505_coef_set(codec, 0x61bc, 0x010234f8);
3587 alc5505_coef_set(codec, 0x880c, 0x00000004);
3588 alc5505_coef_set(codec, 0x880c, 0x00000003);
3589 alc5505_coef_set(codec, 0x880c, 0x00000010);
3590
3591#ifdef HALT_REALTEK_ALC5505
3592 alc5505_dsp_halt(codec);
3593#endif
3594}
3595
3596#ifdef HALT_REALTEK_ALC5505
3597#define alc5505_dsp_suspend(codec)
3598#define alc5505_dsp_resume(codec)
3599#else
3600#define alc5505_dsp_suspend(codec) alc5505_dsp_halt(codec)
3601#define alc5505_dsp_resume(codec) alc5505_dsp_back_from_halt(codec)
3602#endif
3603
3604#ifdef CONFIG_PM
3605static int alc269_suspend(struct hda_codec *codec)
3606{
3607 struct alc_spec *spec = codec->spec;
3608
3609 if (spec->has_alc5505_dsp)
3610 alc5505_dsp_suspend(codec);
3611 return alc_suspend(codec);
3612}
3613
3614static int alc269_resume(struct hda_codec *codec)
3615{
3616 struct alc_spec *spec = codec->spec;
3617
3618 if (spec->codec_variant == ALC269_TYPE_ALC269VB)
3619 alc269vb_toggle_power_output(codec, 0);
3620 if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
3621 (alc_get_coef0(codec) & 0x00ff) == 0x018) {
3622 msleep(150);
3623 }
3624
3625 codec->patch_ops.init(codec);
3626
3627 if (spec->codec_variant == ALC269_TYPE_ALC269VB)
3628 alc269vb_toggle_power_output(codec, 1);
3629 if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
3630 (alc_get_coef0(codec) & 0x00ff) == 0x017) {
3631 msleep(200);
3632 }
3633
3634 regcache_sync(codec->core.regmap);
3635 hda_call_check_power_status(codec, 0x01);
3636
3637
3638
3639
3640
3641 if (spec->gpio_data)
3642 alc_write_gpio_data(codec);
3643
3644 if (spec->has_alc5505_dsp)
3645 alc5505_dsp_resume(codec);
3646
3647 return 0;
3648}
3649#endif
3650
3651static void alc269_fixup_pincfg_no_hp_to_lineout(struct hda_codec *codec,
3652 const struct hda_fixup *fix, int action)
3653{
3654 struct alc_spec *spec = codec->spec;
3655
3656 if (action == HDA_FIXUP_ACT_PRE_PROBE)
3657 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
3658}
3659
3660static void alc269_fixup_pincfg_U7x7_headset_mic(struct hda_codec *codec,
3661 const struct hda_fixup *fix,
3662 int action)
3663{
3664 unsigned int cfg_headphone = snd_hda_codec_get_pincfg(codec, 0x21);
3665 unsigned int cfg_headset_mic = snd_hda_codec_get_pincfg(codec, 0x19);
3666
3667 if (cfg_headphone && cfg_headset_mic == 0x411111f0)
3668 snd_hda_codec_set_pincfg(codec, 0x19,
3669 (cfg_headphone & ~AC_DEFCFG_DEVICE) |
3670 (AC_JACK_MIC_IN << AC_DEFCFG_DEVICE_SHIFT));
3671}
3672
3673static void alc269_fixup_hweq(struct hda_codec *codec,
3674 const struct hda_fixup *fix, int action)
3675{
3676 if (action == HDA_FIXUP_ACT_INIT)
3677 alc_update_coef_idx(codec, 0x1e, 0, 0x80);
3678}
3679
3680static void alc269_fixup_headset_mic(struct hda_codec *codec,
3681 const struct hda_fixup *fix, int action)
3682{
3683 struct alc_spec *spec = codec->spec;
3684
3685 if (action == HDA_FIXUP_ACT_PRE_PROBE)
3686 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
3687}
3688
3689static void alc271_fixup_dmic(struct hda_codec *codec,
3690 const struct hda_fixup *fix, int action)
3691{
3692 static const struct hda_verb verbs[] = {
3693 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
3694 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
3695 {}
3696 };
3697 unsigned int cfg;
3698
3699 if (strcmp(codec->core.chip_name, "ALC271X") &&
3700 strcmp(codec->core.chip_name, "ALC269VB"))
3701 return;
3702 cfg = snd_hda_codec_get_pincfg(codec, 0x12);
3703 if (get_defcfg_connect(cfg) == AC_JACK_PORT_FIXED)
3704 snd_hda_sequence_write(codec, verbs);
3705}
3706
3707static void alc269_fixup_pcm_44k(struct hda_codec *codec,
3708 const struct hda_fixup *fix, int action)
3709{
3710 struct alc_spec *spec = codec->spec;
3711
3712 if (action != HDA_FIXUP_ACT_PROBE)
3713 return;
3714
3715
3716
3717
3718 spec->gen.stream_analog_playback = &alc269_44k_pcm_analog_playback;
3719 spec->gen.stream_analog_capture = &alc269_44k_pcm_analog_capture;
3720}
3721
3722static void alc269_fixup_stereo_dmic(struct hda_codec *codec,
3723 const struct hda_fixup *fix, int action)
3724{
3725
3726
3727
3728
3729
3730 if (action == HDA_FIXUP_ACT_INIT)
3731 alc_update_coef_idx(codec, 0x07, 0, 0x80);
3732}
3733
3734static void alc269_quanta_automute(struct hda_codec *codec)
3735{
3736 snd_hda_gen_update_outputs(codec);
3737
3738 alc_write_coef_idx(codec, 0x0c, 0x680);
3739 alc_write_coef_idx(codec, 0x0c, 0x480);
3740}
3741
3742static void alc269_fixup_quanta_mute(struct hda_codec *codec,
3743 const struct hda_fixup *fix, int action)
3744{
3745 struct alc_spec *spec = codec->spec;
3746 if (action != HDA_FIXUP_ACT_PROBE)
3747 return;
3748 spec->gen.automute_hook = alc269_quanta_automute;
3749}
3750
3751static void alc269_x101_hp_automute_hook(struct hda_codec *codec,
3752 struct hda_jack_callback *jack)
3753{
3754 struct alc_spec *spec = codec->spec;
3755 int vref;
3756 msleep(200);
3757 snd_hda_gen_hp_automute(codec, jack);
3758
3759 vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0;
3760 msleep(100);
3761 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3762 vref);
3763 msleep(500);
3764 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3765 vref);
3766}
3767
3768
3769
3770
3771struct hda_alc298_mbxinit {
3772 unsigned char value_0x23;
3773 unsigned char value_0x25;
3774};
3775
3776static void alc298_huawei_mbx_stereo_seq(struct hda_codec *codec,
3777 const struct hda_alc298_mbxinit *initval,
3778 bool first)
3779{
3780 snd_hda_codec_write(codec, 0x06, 0, AC_VERB_SET_DIGI_CONVERT_3, 0x0);
3781 alc_write_coef_idx(codec, 0x26, 0xb000);
3782
3783 if (first)
3784 snd_hda_codec_write(codec, 0x21, 0, AC_VERB_GET_PIN_SENSE, 0x0);
3785
3786 snd_hda_codec_write(codec, 0x6, 0, AC_VERB_SET_DIGI_CONVERT_3, 0x80);
3787 alc_write_coef_idx(codec, 0x26, 0xf000);
3788 alc_write_coef_idx(codec, 0x23, initval->value_0x23);
3789
3790 if (initval->value_0x23 != 0x1e)
3791 alc_write_coef_idx(codec, 0x25, initval->value_0x25);
3792
3793 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0x26);
3794 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, 0xb010);
3795}
3796
3797static void alc298_fixup_huawei_mbx_stereo(struct hda_codec *codec,
3798 const struct hda_fixup *fix,
3799 int action)
3800{
3801
3802 static const struct hda_alc298_mbxinit dac_init[] = {
3803 {0x0c, 0x00}, {0x0d, 0x00}, {0x0e, 0x00}, {0x0f, 0x00},
3804 {0x10, 0x00}, {0x1a, 0x40}, {0x1b, 0x82}, {0x1c, 0x00},
3805 {0x1d, 0x00}, {0x1e, 0x00}, {0x1f, 0x00},
3806 {0x20, 0xc2}, {0x21, 0xc8}, {0x22, 0x26}, {0x23, 0x24},
3807 {0x27, 0xff}, {0x28, 0xff}, {0x29, 0xff}, {0x2a, 0x8f},
3808 {0x2b, 0x02}, {0x2c, 0x48}, {0x2d, 0x34}, {0x2e, 0x00},
3809 {0x2f, 0x00},
3810 {0x30, 0x00}, {0x31, 0x00}, {0x32, 0x00}, {0x33, 0x00},
3811 {0x34, 0x00}, {0x35, 0x01}, {0x36, 0x93}, {0x37, 0x0c},
3812 {0x38, 0x00}, {0x39, 0x00}, {0x3a, 0xf8}, {0x38, 0x80},
3813 {}
3814 };
3815 const struct hda_alc298_mbxinit *seq;
3816
3817 if (action != HDA_FIXUP_ACT_INIT)
3818 return;
3819
3820
3821 snd_hda_codec_write(codec, 0x06, 0, AC_VERB_SET_DIGI_CONVERT_3, 0x00);
3822 snd_hda_codec_write(codec, 0x06, 0, AC_VERB_SET_DIGI_CONVERT_3, 0x80);
3823 alc_write_coef_idx(codec, 0x26, 0xf000);
3824 alc_write_coef_idx(codec, 0x22, 0x31);
3825 alc_write_coef_idx(codec, 0x23, 0x0b);
3826 alc_write_coef_idx(codec, 0x25, 0x00);
3827 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0x26);
3828 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, 0xb010);
3829
3830 for (seq = dac_init; seq->value_0x23; seq++)
3831 alc298_huawei_mbx_stereo_seq(codec, seq, seq == dac_init);
3832}
3833
3834static void alc269_fixup_x101_headset_mic(struct hda_codec *codec,
3835 const struct hda_fixup *fix, int action)
3836{
3837 struct alc_spec *spec = codec->spec;
3838 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3839 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
3840 spec->gen.hp_automute_hook = alc269_x101_hp_automute_hook;
3841 }
3842}
3843
3844
3845
3846static void alc269_fixup_mic_mute_hook(void *private_data, int enabled)
3847{
3848 struct hda_codec *codec = private_data;
3849 struct alc_spec *spec = codec->spec;
3850 unsigned int pinval;
3851
3852 if (spec->mute_led_polarity)
3853 enabled = !enabled;
3854 pinval = snd_hda_codec_get_pin_target(codec, spec->mute_led_nid);
3855 pinval &= ~AC_PINCTL_VREFEN;
3856 pinval |= enabled ? AC_PINCTL_VREF_HIZ : AC_PINCTL_VREF_80;
3857 if (spec->mute_led_nid) {
3858
3859 snd_hda_power_up_pm(codec);
3860 snd_hda_set_pin_ctl_cache(codec, spec->mute_led_nid, pinval);
3861 snd_hda_power_down_pm(codec);
3862 }
3863}
3864
3865
3866static unsigned int led_power_filter(struct hda_codec *codec,
3867 hda_nid_t nid,
3868 unsigned int power_state)
3869{
3870 struct alc_spec *spec = codec->spec;
3871
3872 if (power_state != AC_PWRST_D3 || nid == 0 ||
3873 (nid != spec->mute_led_nid && nid != spec->cap_mute_led_nid))
3874 return power_state;
3875
3876
3877 snd_hda_set_pin_ctl(codec, nid,
3878 snd_hda_codec_get_pin_target(codec, nid));
3879
3880 return snd_hda_gen_path_power_filter(codec, nid, power_state);
3881}
3882
3883static void alc269_fixup_hp_mute_led(struct hda_codec *codec,
3884 const struct hda_fixup *fix, int action)
3885{
3886 struct alc_spec *spec = codec->spec;
3887 const struct dmi_device *dev = NULL;
3888
3889 if (action != HDA_FIXUP_ACT_PRE_PROBE)
3890 return;
3891
3892 while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) {
3893 int pol, pin;
3894 if (sscanf(dev->name, "HP_Mute_LED_%d_%x", &pol, &pin) != 2)
3895 continue;
3896 if (pin < 0x0a || pin >= 0x10)
3897 break;
3898 spec->mute_led_polarity = pol;
3899 spec->mute_led_nid = pin - 0x0a + 0x18;
3900 spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook;
3901 spec->gen.vmaster_mute_enum = 1;
3902 codec->power_filter = led_power_filter;
3903 codec_dbg(codec,
3904 "Detected mute LED for %x:%d\n", spec->mute_led_nid,
3905 spec->mute_led_polarity);
3906 break;
3907 }
3908}
3909
3910static void alc269_fixup_hp_mute_led_micx(struct hda_codec *codec,
3911 const struct hda_fixup *fix,
3912 int action, hda_nid_t pin)
3913{
3914 struct alc_spec *spec = codec->spec;
3915
3916 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3917 spec->mute_led_polarity = 0;
3918 spec->mute_led_nid = pin;
3919 spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook;
3920 spec->gen.vmaster_mute_enum = 1;
3921 codec->power_filter = led_power_filter;
3922 }
3923}
3924
3925static void alc269_fixup_hp_mute_led_mic1(struct hda_codec *codec,
3926 const struct hda_fixup *fix, int action)
3927{
3928 alc269_fixup_hp_mute_led_micx(codec, fix, action, 0x18);
3929}
3930
3931static void alc269_fixup_hp_mute_led_mic2(struct hda_codec *codec,
3932 const struct hda_fixup *fix, int action)
3933{
3934 alc269_fixup_hp_mute_led_micx(codec, fix, action, 0x19);
3935}
3936
3937static void alc269_fixup_hp_mute_led_mic3(struct hda_codec *codec,
3938 const struct hda_fixup *fix, int action)
3939{
3940 alc269_fixup_hp_mute_led_micx(codec, fix, action, 0x1b);
3941}
3942
3943
3944static void alc_update_gpio_led(struct hda_codec *codec, unsigned int mask,
3945 bool enabled)
3946{
3947 struct alc_spec *spec = codec->spec;
3948
3949 if (spec->mute_led_polarity)
3950 enabled = !enabled;
3951 alc_update_gpio_data(codec, mask, !enabled);
3952}
3953
3954
3955static void alc_fixup_gpio_mute_hook(void *private_data, int enabled)
3956{
3957 struct hda_codec *codec = private_data;
3958 struct alc_spec *spec = codec->spec;
3959
3960 alc_update_gpio_led(codec, spec->gpio_mute_led_mask, enabled);
3961}
3962
3963
3964static void alc_gpio_micmute_update(struct hda_codec *codec)
3965{
3966 struct alc_spec *spec = codec->spec;
3967
3968 alc_update_gpio_led(codec, spec->gpio_mic_led_mask,
3969 spec->gen.micmute_led.led_value);
3970}
3971
3972
3973static void alc_fixup_hp_gpio_led(struct hda_codec *codec,
3974 int action,
3975 unsigned int mute_mask,
3976 unsigned int micmute_mask)
3977{
3978 struct alc_spec *spec = codec->spec;
3979
3980 alc_fixup_gpio(codec, action, mute_mask | micmute_mask);
3981
3982 if (action != HDA_FIXUP_ACT_PRE_PROBE)
3983 return;
3984 if (mute_mask) {
3985 spec->gpio_mute_led_mask = mute_mask;
3986 spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook;
3987 }
3988 if (micmute_mask) {
3989 spec->gpio_mic_led_mask = micmute_mask;
3990 snd_hda_gen_add_micmute_led(codec, alc_gpio_micmute_update);
3991 }
3992}
3993
3994static void alc269_fixup_hp_gpio_led(struct hda_codec *codec,
3995 const struct hda_fixup *fix, int action)
3996{
3997 alc_fixup_hp_gpio_led(codec, action, 0x08, 0x10);
3998}
3999
4000static void alc286_fixup_hp_gpio_led(struct hda_codec *codec,
4001 const struct hda_fixup *fix, int action)
4002{
4003 alc_fixup_hp_gpio_led(codec, action, 0x02, 0x20);
4004}
4005
4006
4007static void alc_cap_micmute_update(struct hda_codec *codec)
4008{
4009 struct alc_spec *spec = codec->spec;
4010 unsigned int pinval;
4011
4012 if (!spec->cap_mute_led_nid)
4013 return;
4014 pinval = snd_hda_codec_get_pin_target(codec, spec->cap_mute_led_nid);
4015 pinval &= ~AC_PINCTL_VREFEN;
4016 if (spec->gen.micmute_led.led_value)
4017 pinval |= AC_PINCTL_VREF_80;
4018 else
4019 pinval |= AC_PINCTL_VREF_HIZ;
4020 snd_hda_set_pin_ctl_cache(codec, spec->cap_mute_led_nid, pinval);
4021}
4022
4023static void alc269_fixup_hp_gpio_mic1_led(struct hda_codec *codec,
4024 const struct hda_fixup *fix, int action)
4025{
4026 struct alc_spec *spec = codec->spec;
4027
4028 alc_fixup_hp_gpio_led(codec, action, 0x08, 0);
4029 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4030
4031
4032
4033 spec->gpio_mask |= 0x10;
4034 spec->gpio_dir |= 0x10;
4035 spec->cap_mute_led_nid = 0x18;
4036 snd_hda_gen_add_micmute_led(codec, alc_cap_micmute_update);
4037 codec->power_filter = led_power_filter;
4038 }
4039}
4040
4041static void alc280_fixup_hp_gpio4(struct hda_codec *codec,
4042 const struct hda_fixup *fix, int action)
4043{
4044 struct alc_spec *spec = codec->spec;
4045
4046 alc_fixup_hp_gpio_led(codec, action, 0x08, 0);
4047 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4048 spec->cap_mute_led_nid = 0x18;
4049 snd_hda_gen_add_micmute_led(codec, alc_cap_micmute_update);
4050 codec->power_filter = led_power_filter;
4051 }
4052}
4053
4054#if IS_REACHABLE(CONFIG_INPUT)
4055static void gpio2_mic_hotkey_event(struct hda_codec *codec,
4056 struct hda_jack_callback *event)
4057{
4058 struct alc_spec *spec = codec->spec;
4059
4060
4061
4062 input_report_key(spec->kb_dev, spec->alc_mute_keycode_map[ALC_KEY_MICMUTE_INDEX], 1);
4063 input_sync(spec->kb_dev);
4064 input_report_key(spec->kb_dev, spec->alc_mute_keycode_map[ALC_KEY_MICMUTE_INDEX], 0);
4065 input_sync(spec->kb_dev);
4066}
4067
4068static int alc_register_micmute_input_device(struct hda_codec *codec)
4069{
4070 struct alc_spec *spec = codec->spec;
4071 int i;
4072
4073 spec->kb_dev = input_allocate_device();
4074 if (!spec->kb_dev) {
4075 codec_err(codec, "Out of memory (input_allocate_device)\n");
4076 return -ENOMEM;
4077 }
4078
4079 spec->alc_mute_keycode_map[ALC_KEY_MICMUTE_INDEX] = KEY_MICMUTE;
4080
4081 spec->kb_dev->name = "Microphone Mute Button";
4082 spec->kb_dev->evbit[0] = BIT_MASK(EV_KEY);
4083 spec->kb_dev->keycodesize = sizeof(spec->alc_mute_keycode_map[0]);
4084 spec->kb_dev->keycodemax = ARRAY_SIZE(spec->alc_mute_keycode_map);
4085 spec->kb_dev->keycode = spec->alc_mute_keycode_map;
4086 for (i = 0; i < ARRAY_SIZE(spec->alc_mute_keycode_map); i++)
4087 set_bit(spec->alc_mute_keycode_map[i], spec->kb_dev->keybit);
4088
4089 if (input_register_device(spec->kb_dev)) {
4090 codec_err(codec, "input_register_device failed\n");
4091 input_free_device(spec->kb_dev);
4092 spec->kb_dev = NULL;
4093 return -ENOMEM;
4094 }
4095
4096 return 0;
4097}
4098
4099
4100
4101
4102
4103
4104static void alc280_fixup_hp_gpio2_mic_hotkey(struct hda_codec *codec,
4105 const struct hda_fixup *fix, int action)
4106{
4107 struct alc_spec *spec = codec->spec;
4108
4109 alc_fixup_hp_gpio_led(codec, action, 0x08, 0x10);
4110 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4111 spec->init_amp = ALC_INIT_DEFAULT;
4112 if (alc_register_micmute_input_device(codec) != 0)
4113 return;
4114
4115 spec->gpio_mask |= 0x06;
4116 spec->gpio_dir |= 0x02;
4117 spec->gpio_data |= 0x02;
4118 snd_hda_codec_write_cache(codec, codec->core.afg, 0,
4119 AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x04);
4120 snd_hda_jack_detect_enable_callback(codec, codec->core.afg,
4121 gpio2_mic_hotkey_event);
4122 return;
4123 }
4124
4125 if (!spec->kb_dev)
4126 return;
4127
4128 switch (action) {
4129 case HDA_FIXUP_ACT_FREE:
4130 input_unregister_device(spec->kb_dev);
4131 spec->kb_dev = NULL;
4132 }
4133}
4134
4135
4136
4137
4138static void alc233_fixup_lenovo_line2_mic_hotkey(struct hda_codec *codec,
4139 const struct hda_fixup *fix, int action)
4140{
4141 struct alc_spec *spec = codec->spec;
4142
4143 alc_fixup_hp_gpio_led(codec, action, 0, 0x04);
4144 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4145 spec->init_amp = ALC_INIT_DEFAULT;
4146 if (alc_register_micmute_input_device(codec) != 0)
4147 return;
4148
4149 snd_hda_jack_detect_enable_callback(codec, 0x1b,
4150 gpio2_mic_hotkey_event);
4151 return;
4152 }
4153
4154 if (!spec->kb_dev)
4155 return;
4156
4157 switch (action) {
4158 case HDA_FIXUP_ACT_FREE:
4159 input_unregister_device(spec->kb_dev);
4160 spec->kb_dev = NULL;
4161 }
4162}
4163#else
4164#define alc280_fixup_hp_gpio2_mic_hotkey NULL
4165#define alc233_fixup_lenovo_line2_mic_hotkey NULL
4166#endif
4167
4168static void alc269_fixup_hp_line1_mic1_led(struct hda_codec *codec,
4169 const struct hda_fixup *fix, int action)
4170{
4171 struct alc_spec *spec = codec->spec;
4172
4173 alc269_fixup_hp_mute_led_micx(codec, fix, action, 0x1a);
4174 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4175 spec->cap_mute_led_nid = 0x18;
4176 snd_hda_gen_add_micmute_led(codec, alc_cap_micmute_update);
4177 }
4178}
4179
4180static struct coef_fw alc225_pre_hsmode[] = {
4181 UPDATE_COEF(0x4a, 1<<8, 0),
4182 UPDATE_COEFEX(0x57, 0x05, 1<<14, 0),
4183 UPDATE_COEF(0x63, 3<<14, 3<<14),
4184 UPDATE_COEF(0x4a, 3<<4, 2<<4),
4185 UPDATE_COEF(0x4a, 3<<10, 3<<10),
4186 UPDATE_COEF(0x45, 0x3f<<10, 0x34<<10),
4187 UPDATE_COEF(0x4a, 3<<10, 0),
4188 {}
4189};
4190
4191static void alc_headset_mode_unplugged(struct hda_codec *codec)
4192{
4193 static struct coef_fw coef0255[] = {
4194 WRITE_COEF(0x1b, 0x0c0b),
4195 WRITE_COEF(0x45, 0xd089),
4196 UPDATE_COEFEX(0x57, 0x05, 1<<14, 0),
4197 WRITE_COEF(0x06, 0x6104),
4198 WRITE_COEFEX(0x57, 0x03, 0x8aa6),
4199 {}
4200 };
4201 static struct coef_fw coef0256[] = {
4202 WRITE_COEF(0x1b, 0x0c4b),
4203 WRITE_COEF(0x45, 0xd089),
4204 WRITE_COEF(0x06, 0x6104),
4205 WRITE_COEFEX(0x57, 0x03, 0x09a3),
4206 UPDATE_COEFEX(0x57, 0x05, 1<<14, 0),
4207 {}
4208 };
4209 static struct coef_fw coef0233[] = {
4210 WRITE_COEF(0x1b, 0x0c0b),
4211 WRITE_COEF(0x45, 0xc429),
4212 UPDATE_COEF(0x35, 0x4000, 0),
4213 WRITE_COEF(0x06, 0x2104),
4214 WRITE_COEF(0x1a, 0x0001),
4215 WRITE_COEF(0x26, 0x0004),
4216 WRITE_COEF(0x32, 0x42a3),
4217 {}
4218 };
4219 static struct coef_fw coef0288[] = {
4220 UPDATE_COEF(0x4f, 0xfcc0, 0xc400),
4221 UPDATE_COEF(0x50, 0x2000, 0x2000),
4222 UPDATE_COEF(0x56, 0x0006, 0x0006),
4223 UPDATE_COEF(0x66, 0x0008, 0),
4224 UPDATE_COEF(0x67, 0x2000, 0),
4225 {}
4226 };
4227 static struct coef_fw coef0298[] = {
4228 UPDATE_COEF(0x19, 0x1300, 0x0300),
4229 {}
4230 };
4231 static struct coef_fw coef0292[] = {
4232 WRITE_COEF(0x76, 0x000e),
4233 WRITE_COEF(0x6c, 0x2400),
4234 WRITE_COEF(0x18, 0x7308),
4235 WRITE_COEF(0x6b, 0xc429),
4236 {}
4237 };
4238 static struct coef_fw coef0293[] = {
4239 UPDATE_COEF(0x10, 7<<8, 6<<8),
4240 UPDATE_COEFEX(0x57, 0x05, 1<<15|1<<13, 0x0),
4241 UPDATE_COEFEX(0x57, 0x03, 1<<10, 1<<10),
4242 UPDATE_COEF(0x1a, 1<<3, 1<<3),
4243 WRITE_COEF(0x45, 0xc429),
4244 UPDATE_COEF(0x4a, 0x000f, 0x000e),
4245 {}
4246 };
4247 static struct coef_fw coef0668[] = {
4248 WRITE_COEF(0x15, 0x0d40),
4249 WRITE_COEF(0xb7, 0x802b),
4250 {}
4251 };
4252 static struct coef_fw coef0225[] = {
4253 UPDATE_COEF(0x63, 3<<14, 0),
4254 {}
4255 };
4256 static struct coef_fw coef0274[] = {
4257 UPDATE_COEF(0x4a, 0x0100, 0),
4258 UPDATE_COEFEX(0x57, 0x05, 0x4000, 0),
4259 UPDATE_COEF(0x6b, 0xf000, 0x5000),
4260 UPDATE_COEF(0x4a, 0x0010, 0),
4261 UPDATE_COEF(0x4a, 0x0c00, 0x0c00),
4262 WRITE_COEF(0x45, 0x5289),
4263 UPDATE_COEF(0x4a, 0x0c00, 0),
4264 {}
4265 };
4266
4267 switch (codec->core.vendor_id) {
4268 case 0x10ec0255:
4269 alc_process_coef_fw(codec, coef0255);
4270 break;
4271 case 0x10ec0236:
4272 case 0x10ec0256:
4273 alc_process_coef_fw(codec, coef0256);
4274 break;
4275 case 0x10ec0234:
4276 case 0x10ec0274:
4277 case 0x10ec0294:
4278 alc_process_coef_fw(codec, coef0274);
4279 break;
4280 case 0x10ec0233:
4281 case 0x10ec0283:
4282 alc_process_coef_fw(codec, coef0233);
4283 break;
4284 case 0x10ec0286:
4285 case 0x10ec0288:
4286 alc_process_coef_fw(codec, coef0288);
4287 break;
4288 case 0x10ec0298:
4289 alc_process_coef_fw(codec, coef0298);
4290 alc_process_coef_fw(codec, coef0288);
4291 break;
4292 case 0x10ec0292:
4293 alc_process_coef_fw(codec, coef0292);
4294 break;
4295 case 0x10ec0293:
4296 alc_process_coef_fw(codec, coef0293);
4297 break;
4298 case 0x10ec0668:
4299 alc_process_coef_fw(codec, coef0668);
4300 break;
4301 case 0x10ec0215:
4302 case 0x10ec0225:
4303 case 0x10ec0285:
4304 case 0x10ec0295:
4305 case 0x10ec0289:
4306 case 0x10ec0299:
4307 alc_process_coef_fw(codec, alc225_pre_hsmode);
4308 alc_process_coef_fw(codec, coef0225);
4309 break;
4310 case 0x10ec0867:
4311 alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
4312 break;
4313 }
4314 codec_dbg(codec, "Headset jack set to unplugged mode.\n");
4315}
4316
4317
4318static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin,
4319 hda_nid_t mic_pin)
4320{
4321 static struct coef_fw coef0255[] = {
4322 WRITE_COEFEX(0x57, 0x03, 0x8aa6),
4323 WRITE_COEF(0x06, 0x6100),
4324 {}
4325 };
4326 static struct coef_fw coef0256[] = {
4327 UPDATE_COEFEX(0x57, 0x05, 1<<14, 1<<14),
4328 WRITE_COEFEX(0x57, 0x03, 0x09a3),
4329 WRITE_COEF(0x06, 0x6100),
4330 {}
4331 };
4332 static struct coef_fw coef0233[] = {
4333 UPDATE_COEF(0x35, 0, 1<<14),
4334 WRITE_COEF(0x06, 0x2100),
4335 WRITE_COEF(0x1a, 0x0021),
4336 WRITE_COEF(0x26, 0x008c),
4337 {}
4338 };
4339 static struct coef_fw coef0288[] = {
4340 UPDATE_COEF(0x4f, 0x00c0, 0),
4341 UPDATE_COEF(0x50, 0x2000, 0),
4342 UPDATE_COEF(0x56, 0x0006, 0),
4343 UPDATE_COEF(0x4f, 0xfcc0, 0xc400),
4344 UPDATE_COEF(0x66, 0x0008, 0x0008),
4345 UPDATE_COEF(0x67, 0x2000, 0x2000),
4346 {}
4347 };
4348 static struct coef_fw coef0292[] = {
4349 WRITE_COEF(0x19, 0xa208),
4350 WRITE_COEF(0x2e, 0xacf0),
4351 {}
4352 };
4353 static struct coef_fw coef0293[] = {
4354 UPDATE_COEFEX(0x57, 0x05, 0, 1<<15|1<<13),
4355 UPDATE_COEFEX(0x57, 0x03, 1<<10, 0),
4356 UPDATE_COEF(0x1a, 1<<3, 0),
4357 {}
4358 };
4359 static struct coef_fw coef0688[] = {
4360 WRITE_COEF(0xb7, 0x802b),
4361 WRITE_COEF(0xb5, 0x1040),
4362 UPDATE_COEF(0xc3, 0, 1<<12),
4363 {}
4364 };
4365 static struct coef_fw coef0225[] = {
4366 UPDATE_COEFEX(0x57, 0x05, 1<<14, 1<<14),
4367 UPDATE_COEF(0x4a, 3<<4, 2<<4),
4368 UPDATE_COEF(0x63, 3<<14, 0),
4369 {}
4370 };
4371 static struct coef_fw coef0274[] = {
4372 UPDATE_COEFEX(0x57, 0x05, 0x4000, 0x4000),
4373 UPDATE_COEF(0x4a, 0x0010, 0),
4374 UPDATE_COEF(0x6b, 0xf000, 0),
4375 {}
4376 };
4377
4378 switch (codec->core.vendor_id) {
4379 case 0x10ec0255:
4380 alc_write_coef_idx(codec, 0x45, 0xc489);
4381 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4382 alc_process_coef_fw(codec, coef0255);
4383 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4384 break;
4385 case 0x10ec0236:
4386 case 0x10ec0256:
4387 alc_write_coef_idx(codec, 0x45, 0xc489);
4388 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4389 alc_process_coef_fw(codec, coef0256);
4390 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4391 break;
4392 case 0x10ec0234:
4393 case 0x10ec0274:
4394 case 0x10ec0294:
4395 alc_write_coef_idx(codec, 0x45, 0x4689);
4396 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4397 alc_process_coef_fw(codec, coef0274);
4398 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4399 break;
4400 case 0x10ec0233:
4401 case 0x10ec0283:
4402 alc_write_coef_idx(codec, 0x45, 0xc429);
4403 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4404 alc_process_coef_fw(codec, coef0233);
4405 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4406 break;
4407 case 0x10ec0286:
4408 case 0x10ec0288:
4409 case 0x10ec0298:
4410 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4411 alc_process_coef_fw(codec, coef0288);
4412 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4413 break;
4414 case 0x10ec0292:
4415 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4416 alc_process_coef_fw(codec, coef0292);
4417 break;
4418 case 0x10ec0293:
4419
4420 alc_write_coef_idx(codec, 0x45, 0xc429);
4421 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4422 alc_process_coef_fw(codec, coef0293);
4423 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4424 break;
4425 case 0x10ec0867:
4426 alc_update_coefex_idx(codec, 0x57, 0x5, 0, 1<<14);
4427
4428 case 0x10ec0221:
4429 case 0x10ec0662:
4430 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4431 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4432 break;
4433 case 0x10ec0668:
4434 alc_write_coef_idx(codec, 0x11, 0x0001);
4435 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4436 alc_process_coef_fw(codec, coef0688);
4437 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4438 break;
4439 case 0x10ec0215:
4440 case 0x10ec0225:
4441 case 0x10ec0285:
4442 case 0x10ec0295:
4443 case 0x10ec0289:
4444 case 0x10ec0299:
4445 alc_process_coef_fw(codec, alc225_pre_hsmode);
4446 alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x31<<10);
4447 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4448 alc_process_coef_fw(codec, coef0225);
4449 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4450 break;
4451 }
4452 codec_dbg(codec, "Headset jack set to mic-in mode.\n");
4453}
4454
4455static void alc_headset_mode_default(struct hda_codec *codec)
4456{
4457 static struct coef_fw coef0225[] = {
4458 UPDATE_COEF(0x45, 0x3f<<10, 0x30<<10),
4459 UPDATE_COEF(0x45, 0x3f<<10, 0x31<<10),
4460 UPDATE_COEF(0x49, 3<<8, 0<<8),
4461 UPDATE_COEF(0x4a, 3<<4, 3<<4),
4462 UPDATE_COEF(0x63, 3<<14, 0),
4463 UPDATE_COEF(0x67, 0xf000, 0x3000),
4464 {}
4465 };
4466 static struct coef_fw coef0255[] = {
4467 WRITE_COEF(0x45, 0xc089),
4468 WRITE_COEF(0x45, 0xc489),
4469 WRITE_COEFEX(0x57, 0x03, 0x8ea6),
4470 WRITE_COEF(0x49, 0x0049),
4471 {}
4472 };
4473 static struct coef_fw coef0256[] = {
4474 WRITE_COEF(0x45, 0xc489),
4475 WRITE_COEFEX(0x57, 0x03, 0x0da3),
4476 WRITE_COEF(0x49, 0x0049),
4477 UPDATE_COEFEX(0x57, 0x05, 1<<14, 0),
4478 WRITE_COEF(0x06, 0x6100),
4479 {}
4480 };
4481 static struct coef_fw coef0233[] = {
4482 WRITE_COEF(0x06, 0x2100),
4483 WRITE_COEF(0x32, 0x4ea3),
4484 {}
4485 };
4486 static struct coef_fw coef0288[] = {
4487 UPDATE_COEF(0x4f, 0xfcc0, 0xc400),
4488 UPDATE_COEF(0x50, 0x2000, 0x2000),
4489 UPDATE_COEF(0x56, 0x0006, 0x0006),
4490 UPDATE_COEF(0x66, 0x0008, 0),
4491 UPDATE_COEF(0x67, 0x2000, 0),
4492 {}
4493 };
4494 static struct coef_fw coef0292[] = {
4495 WRITE_COEF(0x76, 0x000e),
4496 WRITE_COEF(0x6c, 0x2400),
4497 WRITE_COEF(0x6b, 0xc429),
4498 WRITE_COEF(0x18, 0x7308),
4499 {}
4500 };
4501 static struct coef_fw coef0293[] = {
4502 UPDATE_COEF(0x4a, 0x000f, 0x000e),
4503 WRITE_COEF(0x45, 0xC429),
4504 UPDATE_COEF(0x1a, 1<<3, 0),
4505 {}
4506 };
4507 static struct coef_fw coef0688[] = {
4508 WRITE_COEF(0x11, 0x0041),
4509 WRITE_COEF(0x15, 0x0d40),
4510 WRITE_COEF(0xb7, 0x802b),
4511 {}
4512 };
4513 static struct coef_fw coef0274[] = {
4514 WRITE_COEF(0x45, 0x4289),
4515 UPDATE_COEF(0x4a, 0x0010, 0x0010),
4516 UPDATE_COEF(0x6b, 0x0f00, 0),
4517 UPDATE_COEF(0x49, 0x0300, 0x0300),
4518 {}
4519 };
4520
4521 switch (codec->core.vendor_id) {
4522 case 0x10ec0215:
4523 case 0x10ec0225:
4524 case 0x10ec0285:
4525 case 0x10ec0295:
4526 case 0x10ec0289:
4527 case 0x10ec0299:
4528 alc_process_coef_fw(codec, alc225_pre_hsmode);
4529 alc_process_coef_fw(codec, coef0225);
4530 break;
4531 case 0x10ec0255:
4532 alc_process_coef_fw(codec, coef0255);
4533 break;
4534 case 0x10ec0236:
4535 case 0x10ec0256:
4536 alc_write_coef_idx(codec, 0x1b, 0x0e4b);
4537 alc_write_coef_idx(codec, 0x45, 0xc089);
4538 msleep(50);
4539 alc_process_coef_fw(codec, coef0256);
4540 break;
4541 case 0x10ec0234:
4542 case 0x10ec0274:
4543 case 0x10ec0294:
4544 alc_process_coef_fw(codec, coef0274);
4545 break;
4546 case 0x10ec0233:
4547 case 0x10ec0283:
4548 alc_process_coef_fw(codec, coef0233);
4549 break;
4550 case 0x10ec0286:
4551 case 0x10ec0288:
4552 case 0x10ec0298:
4553 alc_process_coef_fw(codec, coef0288);
4554 break;
4555 case 0x10ec0292:
4556 alc_process_coef_fw(codec, coef0292);
4557 break;
4558 case 0x10ec0293:
4559 alc_process_coef_fw(codec, coef0293);
4560 break;
4561 case 0x10ec0668:
4562 alc_process_coef_fw(codec, coef0688);
4563 break;
4564 case 0x10ec0867:
4565 alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
4566 break;
4567 }
4568 codec_dbg(codec, "Headset jack set to headphone (default) mode.\n");
4569}
4570
4571
4572static void alc_headset_mode_ctia(struct hda_codec *codec)
4573{
4574 int val;
4575
4576 static struct coef_fw coef0255[] = {
4577 WRITE_COEF(0x45, 0xd489),
4578 WRITE_COEF(0x1b, 0x0c2b),
4579 WRITE_COEFEX(0x57, 0x03, 0x8ea6),
4580 {}
4581 };
4582 static struct coef_fw coef0256[] = {
4583 WRITE_COEF(0x45, 0xd489),
4584 WRITE_COEF(0x1b, 0x0e6b),
4585 {}
4586 };
4587 static struct coef_fw coef0233[] = {
4588 WRITE_COEF(0x45, 0xd429),
4589 WRITE_COEF(0x1b, 0x0c2b),
4590 WRITE_COEF(0x32, 0x4ea3),
4591 {}
4592 };
4593 static struct coef_fw coef0288[] = {
4594 UPDATE_COEF(0x50, 0x2000, 0x2000),
4595 UPDATE_COEF(0x56, 0x0006, 0x0006),
4596 UPDATE_COEF(0x66, 0x0008, 0),
4597 UPDATE_COEF(0x67, 0x2000, 0),
4598 {}
4599 };
4600 static struct coef_fw coef0292[] = {
4601 WRITE_COEF(0x6b, 0xd429),
4602 WRITE_COEF(0x76, 0x0008),
4603 WRITE_COEF(0x18, 0x7388),
4604 {}
4605 };
4606 static struct coef_fw coef0293[] = {
4607 WRITE_COEF(0x45, 0xd429),
4608 UPDATE_COEF(0x10, 7<<8, 7<<8),
4609 {}
4610 };
4611 static struct coef_fw coef0688[] = {
4612 WRITE_COEF(0x11, 0x0001),
4613 WRITE_COEF(0x15, 0x0d60),
4614 WRITE_COEF(0xc3, 0x0000),
4615 {}
4616 };
4617 static struct coef_fw coef0225_1[] = {
4618 UPDATE_COEF(0x45, 0x3f<<10, 0x35<<10),
4619 UPDATE_COEF(0x63, 3<<14, 2<<14),
4620 {}
4621 };
4622 static struct coef_fw coef0225_2[] = {
4623 UPDATE_COEF(0x45, 0x3f<<10, 0x35<<10),
4624 UPDATE_COEF(0x63, 3<<14, 1<<14),
4625 {}
4626 };
4627
4628 switch (codec->core.vendor_id) {
4629 case 0x10ec0255:
4630 alc_process_coef_fw(codec, coef0255);
4631 break;
4632 case 0x10ec0236:
4633 case 0x10ec0256:
4634 alc_process_coef_fw(codec, coef0256);
4635 break;
4636 case 0x10ec0234:
4637 case 0x10ec0274:
4638 case 0x10ec0294:
4639 alc_write_coef_idx(codec, 0x45, 0xd689);
4640 break;
4641 case 0x10ec0233:
4642 case 0x10ec0283:
4643 alc_process_coef_fw(codec, coef0233);
4644 break;
4645 case 0x10ec0298:
4646 val = alc_read_coef_idx(codec, 0x50);
4647 if (val & (1 << 12)) {
4648 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0020);
4649 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400);
4650 msleep(300);
4651 } else {
4652 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0010);
4653 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400);
4654 msleep(300);
4655 }
4656 break;
4657 case 0x10ec0286:
4658 case 0x10ec0288:
4659 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400);
4660 msleep(300);
4661 alc_process_coef_fw(codec, coef0288);
4662 break;
4663 case 0x10ec0292:
4664 alc_process_coef_fw(codec, coef0292);
4665 break;
4666 case 0x10ec0293:
4667 alc_process_coef_fw(codec, coef0293);
4668 break;
4669 case 0x10ec0668:
4670 alc_process_coef_fw(codec, coef0688);
4671 break;
4672 case 0x10ec0215:
4673 case 0x10ec0225:
4674 case 0x10ec0285:
4675 case 0x10ec0295:
4676 case 0x10ec0289:
4677 case 0x10ec0299:
4678 val = alc_read_coef_idx(codec, 0x45);
4679 if (val & (1 << 9))
4680 alc_process_coef_fw(codec, coef0225_2);
4681 else
4682 alc_process_coef_fw(codec, coef0225_1);
4683 break;
4684 case 0x10ec0867:
4685 alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
4686 break;
4687 }
4688 codec_dbg(codec, "Headset jack set to iPhone-style headset mode.\n");
4689}
4690
4691
4692static void alc_headset_mode_omtp(struct hda_codec *codec)
4693{
4694 static struct coef_fw coef0255[] = {
4695 WRITE_COEF(0x45, 0xe489),
4696 WRITE_COEF(0x1b, 0x0c2b),
4697 WRITE_COEFEX(0x57, 0x03, 0x8ea6),
4698 {}
4699 };
4700 static struct coef_fw coef0256[] = {
4701 WRITE_COEF(0x45, 0xe489),
4702 WRITE_COEF(0x1b, 0x0e6b),
4703 {}
4704 };
4705 static struct coef_fw coef0233[] = {
4706 WRITE_COEF(0x45, 0xe429),
4707 WRITE_COEF(0x1b, 0x0c2b),
4708 WRITE_COEF(0x32, 0x4ea3),
4709 {}
4710 };
4711 static struct coef_fw coef0288[] = {
4712 UPDATE_COEF(0x50, 0x2000, 0x2000),
4713 UPDATE_COEF(0x56, 0x0006, 0x0006),
4714 UPDATE_COEF(0x66, 0x0008, 0),
4715 UPDATE_COEF(0x67, 0x2000, 0),
4716 {}
4717 };
4718 static struct coef_fw coef0292[] = {
4719 WRITE_COEF(0x6b, 0xe429),
4720 WRITE_COEF(0x76, 0x0008),
4721 WRITE_COEF(0x18, 0x7388),
4722 {}
4723 };
4724 static struct coef_fw coef0293[] = {
4725 WRITE_COEF(0x45, 0xe429),
4726 UPDATE_COEF(0x10, 7<<8, 7<<8),
4727 {}
4728 };
4729 static struct coef_fw coef0688[] = {
4730 WRITE_COEF(0x11, 0x0001),
4731 WRITE_COEF(0x15, 0x0d50),
4732 WRITE_COEF(0xc3, 0x0000),
4733 {}
4734 };
4735 static struct coef_fw coef0225[] = {
4736 UPDATE_COEF(0x45, 0x3f<<10, 0x39<<10),
4737 UPDATE_COEF(0x63, 3<<14, 2<<14),
4738 {}
4739 };
4740
4741 switch (codec->core.vendor_id) {
4742 case 0x10ec0255:
4743 alc_process_coef_fw(codec, coef0255);
4744 break;
4745 case 0x10ec0236:
4746 case 0x10ec0256:
4747 alc_process_coef_fw(codec, coef0256);
4748 break;
4749 case 0x10ec0234:
4750 case 0x10ec0274:
4751 case 0x10ec0294:
4752 alc_write_coef_idx(codec, 0x45, 0xe689);
4753 break;
4754 case 0x10ec0233:
4755 case 0x10ec0283:
4756 alc_process_coef_fw(codec, coef0233);
4757 break;
4758 case 0x10ec0298:
4759 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0010);
4760 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xe400);
4761 msleep(300);
4762 break;
4763 case 0x10ec0286:
4764 case 0x10ec0288:
4765 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xe400);
4766 msleep(300);
4767 alc_process_coef_fw(codec, coef0288);
4768 break;
4769 case 0x10ec0292:
4770 alc_process_coef_fw(codec, coef0292);
4771 break;
4772 case 0x10ec0293:
4773 alc_process_coef_fw(codec, coef0293);
4774 break;
4775 case 0x10ec0668:
4776 alc_process_coef_fw(codec, coef0688);
4777 break;
4778 case 0x10ec0215:
4779 case 0x10ec0225:
4780 case 0x10ec0285:
4781 case 0x10ec0295:
4782 case 0x10ec0289:
4783 case 0x10ec0299:
4784 alc_process_coef_fw(codec, coef0225);
4785 break;
4786 }
4787 codec_dbg(codec, "Headset jack set to Nokia-style headset mode.\n");
4788}
4789
4790static void alc_determine_headset_type(struct hda_codec *codec)
4791{
4792 int val;
4793 bool is_ctia = false;
4794 struct alc_spec *spec = codec->spec;
4795 static struct coef_fw coef0255[] = {
4796 WRITE_COEF(0x45, 0xd089),
4797 WRITE_COEF(0x49, 0x0149),
4798
4799 {}
4800 };
4801 static struct coef_fw coef0288[] = {
4802 UPDATE_COEF(0x4f, 0xfcc0, 0xd400),
4803 {}
4804 };
4805 static struct coef_fw coef0298[] = {
4806 UPDATE_COEF(0x50, 0x2000, 0x2000),
4807 UPDATE_COEF(0x56, 0x0006, 0x0006),
4808 UPDATE_COEF(0x66, 0x0008, 0),
4809 UPDATE_COEF(0x67, 0x2000, 0),
4810 UPDATE_COEF(0x19, 0x1300, 0x1300),
4811 {}
4812 };
4813 static struct coef_fw coef0293[] = {
4814 UPDATE_COEF(0x4a, 0x000f, 0x0008),
4815 WRITE_COEF(0x45, 0xD429),
4816 {}
4817 };
4818 static struct coef_fw coef0688[] = {
4819 WRITE_COEF(0x11, 0x0001),
4820 WRITE_COEF(0xb7, 0x802b),
4821 WRITE_COEF(0x15, 0x0d60),
4822 WRITE_COEF(0xc3, 0x0c00),
4823 {}
4824 };
4825 static struct coef_fw coef0274[] = {
4826 UPDATE_COEF(0x4a, 0x0010, 0),
4827 UPDATE_COEF(0x4a, 0x8000, 0),
4828 WRITE_COEF(0x45, 0xd289),
4829 UPDATE_COEF(0x49, 0x0300, 0x0300),
4830 {}
4831 };
4832
4833 switch (codec->core.vendor_id) {
4834 case 0x10ec0255:
4835 alc_process_coef_fw(codec, coef0255);
4836 msleep(300);
4837 val = alc_read_coef_idx(codec, 0x46);
4838 is_ctia = (val & 0x0070) == 0x0070;
4839 break;
4840 case 0x10ec0236:
4841 case 0x10ec0256:
4842 alc_write_coef_idx(codec, 0x1b, 0x0e4b);
4843 alc_write_coef_idx(codec, 0x06, 0x6104);
4844 alc_write_coefex_idx(codec, 0x57, 0x3, 0x09a3);
4845
4846 snd_hda_codec_write(codec, 0x21, 0,
4847 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
4848 msleep(80);
4849 snd_hda_codec_write(codec, 0x21, 0,
4850 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
4851
4852 alc_process_coef_fw(codec, coef0255);
4853 msleep(300);
4854 val = alc_read_coef_idx(codec, 0x46);
4855 is_ctia = (val & 0x0070) == 0x0070;
4856
4857 alc_write_coefex_idx(codec, 0x57, 0x3, 0x0da3);
4858 alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
4859
4860 snd_hda_codec_write(codec, 0x21, 0,
4861 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
4862 msleep(80);
4863 snd_hda_codec_write(codec, 0x21, 0,
4864 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
4865 break;
4866 case 0x10ec0234:
4867 case 0x10ec0274:
4868 case 0x10ec0294:
4869 alc_process_coef_fw(codec, coef0274);
4870 msleep(80);
4871 val = alc_read_coef_idx(codec, 0x46);
4872 is_ctia = (val & 0x00f0) == 0x00f0;
4873 break;
4874 case 0x10ec0233:
4875 case 0x10ec0283:
4876 alc_write_coef_idx(codec, 0x45, 0xd029);
4877 msleep(300);
4878 val = alc_read_coef_idx(codec, 0x46);
4879 is_ctia = (val & 0x0070) == 0x0070;
4880 break;
4881 case 0x10ec0298:
4882 snd_hda_codec_write(codec, 0x21, 0,
4883 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
4884 msleep(100);
4885 snd_hda_codec_write(codec, 0x21, 0,
4886 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
4887 msleep(200);
4888
4889 val = alc_read_coef_idx(codec, 0x50);
4890 if (val & (1 << 12)) {
4891 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0020);
4892 alc_process_coef_fw(codec, coef0288);
4893 msleep(350);
4894 val = alc_read_coef_idx(codec, 0x50);
4895 is_ctia = (val & 0x0070) == 0x0070;
4896 } else {
4897 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0010);
4898 alc_process_coef_fw(codec, coef0288);
4899 msleep(350);
4900 val = alc_read_coef_idx(codec, 0x50);
4901 is_ctia = (val & 0x0070) == 0x0070;
4902 }
4903 alc_process_coef_fw(codec, coef0298);
4904 snd_hda_codec_write(codec, 0x21, 0,
4905 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP);
4906 msleep(75);
4907 snd_hda_codec_write(codec, 0x21, 0,
4908 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
4909 break;
4910 case 0x10ec0286:
4911 case 0x10ec0288:
4912 alc_process_coef_fw(codec, coef0288);
4913 msleep(350);
4914 val = alc_read_coef_idx(codec, 0x50);
4915 is_ctia = (val & 0x0070) == 0x0070;
4916 break;
4917 case 0x10ec0292:
4918 alc_write_coef_idx(codec, 0x6b, 0xd429);
4919 msleep(300);
4920 val = alc_read_coef_idx(codec, 0x6c);
4921 is_ctia = (val & 0x001c) == 0x001c;
4922 break;
4923 case 0x10ec0293:
4924 alc_process_coef_fw(codec, coef0293);
4925 msleep(300);
4926 val = alc_read_coef_idx(codec, 0x46);
4927 is_ctia = (val & 0x0070) == 0x0070;
4928 break;
4929 case 0x10ec0668:
4930 alc_process_coef_fw(codec, coef0688);
4931 msleep(300);
4932 val = alc_read_coef_idx(codec, 0xbe);
4933 is_ctia = (val & 0x1c02) == 0x1c02;
4934 break;
4935 case 0x10ec0215:
4936 case 0x10ec0225:
4937 case 0x10ec0285:
4938 case 0x10ec0295:
4939 case 0x10ec0289:
4940 case 0x10ec0299:
4941 snd_hda_codec_write(codec, 0x21, 0,
4942 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
4943 msleep(80);
4944 snd_hda_codec_write(codec, 0x21, 0,
4945 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
4946
4947 alc_process_coef_fw(codec, alc225_pre_hsmode);
4948 alc_update_coef_idx(codec, 0x67, 0xf000, 0x1000);
4949 val = alc_read_coef_idx(codec, 0x45);
4950 if (val & (1 << 9)) {
4951 alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x34<<10);
4952 alc_update_coef_idx(codec, 0x49, 3<<8, 2<<8);
4953 msleep(800);
4954 val = alc_read_coef_idx(codec, 0x46);
4955 is_ctia = (val & 0x00f0) == 0x00f0;
4956 } else {
4957 alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x34<<10);
4958 alc_update_coef_idx(codec, 0x49, 3<<8, 1<<8);
4959 msleep(800);
4960 val = alc_read_coef_idx(codec, 0x46);
4961 is_ctia = (val & 0x00f0) == 0x00f0;
4962 }
4963 alc_update_coef_idx(codec, 0x4a, 7<<6, 7<<6);
4964 alc_update_coef_idx(codec, 0x4a, 3<<4, 3<<4);
4965 alc_update_coef_idx(codec, 0x67, 0xf000, 0x3000);
4966
4967 snd_hda_codec_write(codec, 0x21, 0,
4968 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
4969 msleep(80);
4970 snd_hda_codec_write(codec, 0x21, 0,
4971 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
4972 break;
4973 case 0x10ec0867:
4974 is_ctia = true;
4975 break;
4976 }
4977
4978 codec_dbg(codec, "Headset jack detected iPhone-style headset: %s\n",
4979 is_ctia ? "yes" : "no");
4980 spec->current_headset_type = is_ctia ? ALC_HEADSET_TYPE_CTIA : ALC_HEADSET_TYPE_OMTP;
4981}
4982
4983static void alc_update_headset_mode(struct hda_codec *codec)
4984{
4985 struct alc_spec *spec = codec->spec;
4986
4987 hda_nid_t mux_pin = spec->gen.imux_pins[spec->gen.cur_mux[0]];
4988 hda_nid_t hp_pin = alc_get_hp_pin(spec);
4989
4990 int new_headset_mode;
4991
4992 if (!snd_hda_jack_detect(codec, hp_pin))
4993 new_headset_mode = ALC_HEADSET_MODE_UNPLUGGED;
4994 else if (mux_pin == spec->headset_mic_pin)
4995 new_headset_mode = ALC_HEADSET_MODE_HEADSET;
4996 else if (mux_pin == spec->headphone_mic_pin)
4997 new_headset_mode = ALC_HEADSET_MODE_MIC;
4998 else
4999 new_headset_mode = ALC_HEADSET_MODE_HEADPHONE;
5000
5001 if (new_headset_mode == spec->current_headset_mode) {
5002 snd_hda_gen_update_outputs(codec);
5003 return;
5004 }
5005
5006 switch (new_headset_mode) {
5007 case ALC_HEADSET_MODE_UNPLUGGED:
5008 alc_headset_mode_unplugged(codec);
5009 spec->current_headset_mode = ALC_HEADSET_MODE_UNKNOWN;
5010 spec->current_headset_type = ALC_HEADSET_TYPE_UNKNOWN;
5011 spec->gen.hp_jack_present = false;
5012 break;
5013 case ALC_HEADSET_MODE_HEADSET:
5014 if (spec->current_headset_type == ALC_HEADSET_TYPE_UNKNOWN)
5015 alc_determine_headset_type(codec);
5016 if (spec->current_headset_type == ALC_HEADSET_TYPE_CTIA)
5017 alc_headset_mode_ctia(codec);
5018 else if (spec->current_headset_type == ALC_HEADSET_TYPE_OMTP)
5019 alc_headset_mode_omtp(codec);
5020 spec->gen.hp_jack_present = true;
5021 break;
5022 case ALC_HEADSET_MODE_MIC:
5023 alc_headset_mode_mic_in(codec, hp_pin, spec->headphone_mic_pin);
5024 spec->gen.hp_jack_present = false;
5025 break;
5026 case ALC_HEADSET_MODE_HEADPHONE:
5027 alc_headset_mode_default(codec);
5028 spec->gen.hp_jack_present = true;
5029 break;
5030 }
5031 if (new_headset_mode != ALC_HEADSET_MODE_MIC) {
5032 snd_hda_set_pin_ctl_cache(codec, hp_pin,
5033 AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN);
5034 if (spec->headphone_mic_pin && spec->headphone_mic_pin != hp_pin)
5035 snd_hda_set_pin_ctl_cache(codec, spec->headphone_mic_pin,
5036 PIN_VREFHIZ);
5037 }
5038 spec->current_headset_mode = new_headset_mode;
5039
5040 snd_hda_gen_update_outputs(codec);
5041}
5042
5043static void alc_update_headset_mode_hook(struct hda_codec *codec,
5044 struct snd_kcontrol *kcontrol,
5045 struct snd_ctl_elem_value *ucontrol)
5046{
5047 alc_update_headset_mode(codec);
5048}
5049
5050static void alc_update_headset_jack_cb(struct hda_codec *codec,
5051 struct hda_jack_callback *jack)
5052{
5053 snd_hda_gen_hp_automute(codec, jack);
5054}
5055
5056static void alc_probe_headset_mode(struct hda_codec *codec)
5057{
5058 int i;
5059 struct alc_spec *spec = codec->spec;
5060 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
5061
5062
5063 for (i = 0; i < cfg->num_inputs; i++) {
5064 if (cfg->inputs[i].is_headset_mic && !spec->headset_mic_pin)
5065 spec->headset_mic_pin = cfg->inputs[i].pin;
5066 if (cfg->inputs[i].is_headphone_mic && !spec->headphone_mic_pin)
5067 spec->headphone_mic_pin = cfg->inputs[i].pin;
5068 }
5069
5070 WARN_ON(spec->gen.cap_sync_hook);
5071 spec->gen.cap_sync_hook = alc_update_headset_mode_hook;
5072 spec->gen.automute_hook = alc_update_headset_mode;
5073 spec->gen.hp_automute_hook = alc_update_headset_jack_cb;
5074}
5075
5076static void alc_fixup_headset_mode(struct hda_codec *codec,
5077 const struct hda_fixup *fix, int action)
5078{
5079 struct alc_spec *spec = codec->spec;
5080
5081 switch (action) {
5082 case HDA_FIXUP_ACT_PRE_PROBE:
5083 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC | HDA_PINCFG_HEADPHONE_MIC;
5084 break;
5085 case HDA_FIXUP_ACT_PROBE:
5086 alc_probe_headset_mode(codec);
5087 break;
5088 case HDA_FIXUP_ACT_INIT:
5089 if (is_s3_resume(codec) || is_s4_resume(codec)) {
5090 spec->current_headset_mode = ALC_HEADSET_MODE_UNKNOWN;
5091 spec->current_headset_type = ALC_HEADSET_TYPE_UNKNOWN;
5092 }
5093 alc_update_headset_mode(codec);
5094 break;
5095 }
5096}
5097
5098static void alc_fixup_headset_mode_no_hp_mic(struct hda_codec *codec,
5099 const struct hda_fixup *fix, int action)
5100{
5101 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5102 struct alc_spec *spec = codec->spec;
5103 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
5104 }
5105 else
5106 alc_fixup_headset_mode(codec, fix, action);
5107}
5108
5109static void alc255_set_default_jack_type(struct hda_codec *codec)
5110{
5111
5112 static struct coef_fw alc255fw[] = {
5113 WRITE_COEF(0x1b, 0x880b),
5114 WRITE_COEF(0x45, 0xd089),
5115 WRITE_COEF(0x1b, 0x080b),
5116 WRITE_COEF(0x46, 0x0004),
5117 WRITE_COEF(0x1b, 0x0c0b),
5118 {}
5119 };
5120 static struct coef_fw alc256fw[] = {
5121 WRITE_COEF(0x1b, 0x884b),
5122 WRITE_COEF(0x45, 0xd089),
5123 WRITE_COEF(0x1b, 0x084b),
5124 WRITE_COEF(0x46, 0x0004),
5125 WRITE_COEF(0x1b, 0x0c4b),
5126 {}
5127 };
5128 switch (codec->core.vendor_id) {
5129 case 0x10ec0255:
5130 alc_process_coef_fw(codec, alc255fw);
5131 break;
5132 case 0x10ec0236:
5133 case 0x10ec0256:
5134 alc_process_coef_fw(codec, alc256fw);
5135 break;
5136 }
5137 msleep(30);
5138}
5139
5140static void alc_fixup_headset_mode_alc255(struct hda_codec *codec,
5141 const struct hda_fixup *fix, int action)
5142{
5143 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5144 alc255_set_default_jack_type(codec);
5145 }
5146 alc_fixup_headset_mode(codec, fix, action);
5147}
5148
5149static void alc_fixup_headset_mode_alc255_no_hp_mic(struct hda_codec *codec,
5150 const struct hda_fixup *fix, int action)
5151{
5152 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5153 struct alc_spec *spec = codec->spec;
5154 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
5155 alc255_set_default_jack_type(codec);
5156 }
5157 else
5158 alc_fixup_headset_mode(codec, fix, action);
5159}
5160
5161static void alc288_update_headset_jack_cb(struct hda_codec *codec,
5162 struct hda_jack_callback *jack)
5163{
5164 struct alc_spec *spec = codec->spec;
5165
5166 alc_update_headset_jack_cb(codec, jack);
5167
5168 alc_update_gpio_data(codec, 0x40, spec->gen.hp_jack_present);
5169}
5170
5171static void alc_fixup_headset_mode_dell_alc288(struct hda_codec *codec,
5172 const struct hda_fixup *fix, int action)
5173{
5174 alc_fixup_headset_mode(codec, fix, action);
5175 if (action == HDA_FIXUP_ACT_PROBE) {
5176 struct alc_spec *spec = codec->spec;
5177
5178 spec->gpio_mask |= 0x40;
5179 spec->gpio_dir |= 0x40;
5180 spec->gen.hp_automute_hook = alc288_update_headset_jack_cb;
5181 }
5182}
5183
5184static void alc_fixup_auto_mute_via_amp(struct hda_codec *codec,
5185 const struct hda_fixup *fix, int action)
5186{
5187 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5188 struct alc_spec *spec = codec->spec;
5189 spec->gen.auto_mute_via_amp = 1;
5190 }
5191}
5192
5193static void alc_fixup_no_shutup(struct hda_codec *codec,
5194 const struct hda_fixup *fix, int action)
5195{
5196 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5197 struct alc_spec *spec = codec->spec;
5198 spec->no_shutup_pins = 1;
5199 }
5200}
5201
5202static void alc_fixup_disable_aamix(struct hda_codec *codec,
5203 const struct hda_fixup *fix, int action)
5204{
5205 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5206 struct alc_spec *spec = codec->spec;
5207
5208 spec->gen.mixer_nid = 0;
5209 }
5210}
5211
5212
5213static void alc_fixup_tpt440_dock(struct hda_codec *codec,
5214 const struct hda_fixup *fix, int action)
5215{
5216 static const struct hda_pintbl pincfgs[] = {
5217 { 0x16, 0x21211010 },
5218 { 0x19, 0x21a11010 },
5219 { }
5220 };
5221 struct alc_spec *spec = codec->spec;
5222
5223 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5224 spec->reboot_notify = snd_hda_gen_reboot_notify;
5225 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
5226 codec->power_save_node = 0;
5227 snd_hda_apply_pincfgs(codec, pincfgs);
5228 }
5229}
5230
5231static void alc_fixup_tpt470_dock(struct hda_codec *codec,
5232 const struct hda_fixup *fix, int action)
5233{
5234 static const struct hda_pintbl pincfgs[] = {
5235 { 0x17, 0x21211010 },
5236 { 0x19, 0x21a11010 },
5237 { }
5238 };
5239
5240
5241
5242
5243 static hda_nid_t preferred_pairs[] = {
5244 0x14, 0x03, 0x17, 0x02, 0x21, 0x02,
5245 0
5246 };
5247 struct alc_spec *spec = codec->spec;
5248
5249 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5250 spec->gen.preferred_dacs = preferred_pairs;
5251 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
5252 snd_hda_apply_pincfgs(codec, pincfgs);
5253 } else if (action == HDA_FIXUP_ACT_INIT) {
5254
5255 snd_hda_codec_write(codec, 0x17, 0,
5256 AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0);
5257
5258 snd_hda_codec_write(codec, 0x19, 0,
5259 AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0);
5260 }
5261}
5262
5263static void alc_shutup_dell_xps13(struct hda_codec *codec)
5264{
5265 struct alc_spec *spec = codec->spec;
5266 int hp_pin = alc_get_hp_pin(spec);
5267
5268
5269 snd_hda_codec_write(codec, hp_pin, 0,
5270 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
5271 msleep(20);
5272}
5273
5274static void alc_fixup_dell_xps13(struct hda_codec *codec,
5275 const struct hda_fixup *fix, int action)
5276{
5277 struct alc_spec *spec = codec->spec;
5278 struct hda_input_mux *imux = &spec->gen.input_mux;
5279 int i;
5280
5281 switch (action) {
5282 case HDA_FIXUP_ACT_PRE_PROBE:
5283
5284
5285
5286 snd_hda_codec_set_pin_target(codec, 0x19, PIN_VREFHIZ);
5287 spec->shutup = alc_shutup_dell_xps13;
5288 break;
5289 case HDA_FIXUP_ACT_PROBE:
5290
5291 for (i = 0; i < imux->num_items; i++) {
5292 if (spec->gen.imux_pins[i] == 0x12) {
5293 spec->gen.cur_mux[0] = i;
5294 break;
5295 }
5296 }
5297 break;
5298 }
5299}
5300
5301static void alc_fixup_headset_mode_alc662(struct hda_codec *codec,
5302 const struct hda_fixup *fix, int action)
5303{
5304 struct alc_spec *spec = codec->spec;
5305
5306 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5307 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
5308 spec->gen.hp_mic = 1;
5309
5310
5311
5312 snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000);
5313 snd_hda_override_wcaps(codec, 0x1b, get_wcaps(codec, 0x1b) & ~AC_WCAP_IN_AMP);
5314 } else
5315 alc_fixup_headset_mode(codec, fix, action);
5316}
5317
5318static void alc_fixup_headset_mode_alc668(struct hda_codec *codec,
5319 const struct hda_fixup *fix, int action)
5320{
5321 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5322 alc_write_coef_idx(codec, 0xc4, 0x8000);
5323 alc_update_coef_idx(codec, 0xc2, ~0xfe, 0);
5324 snd_hda_set_pin_ctl_cache(codec, 0x18, 0);
5325 }
5326 alc_fixup_headset_mode(codec, fix, action);
5327}
5328
5329
5330static int find_ext_mic_pin(struct hda_codec *codec)
5331{
5332 struct alc_spec *spec = codec->spec;
5333 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
5334 hda_nid_t nid;
5335 unsigned int defcfg;
5336 int i;
5337
5338 for (i = 0; i < cfg->num_inputs; i++) {
5339 if (cfg->inputs[i].type != AUTO_PIN_MIC)
5340 continue;
5341 nid = cfg->inputs[i].pin;
5342 defcfg = snd_hda_codec_get_pincfg(codec, nid);
5343 if (snd_hda_get_input_pin_attr(defcfg) == INPUT_PIN_ATTR_INT)
5344 continue;
5345 return nid;
5346 }
5347
5348 return 0;
5349}
5350
5351static void alc271_hp_gate_mic_jack(struct hda_codec *codec,
5352 const struct hda_fixup *fix,
5353 int action)
5354{
5355 struct alc_spec *spec = codec->spec;
5356
5357 if (action == HDA_FIXUP_ACT_PROBE) {
5358 int mic_pin = find_ext_mic_pin(codec);
5359 int hp_pin = alc_get_hp_pin(spec);
5360
5361 if (snd_BUG_ON(!mic_pin || !hp_pin))
5362 return;
5363 snd_hda_jack_set_gating_jack(codec, mic_pin, hp_pin);
5364 }
5365}
5366
5367static void alc256_fixup_dell_xps_13_headphone_noise2(struct hda_codec *codec,
5368 const struct hda_fixup *fix,
5369 int action)
5370{
5371 if (action != HDA_FIXUP_ACT_PRE_PROBE)
5372 return;
5373
5374 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 0, HDA_AMP_VOLMASK, 1);
5375 snd_hda_override_wcaps(codec, 0x1a, get_wcaps(codec, 0x1a) & ~AC_WCAP_IN_AMP);
5376}
5377
5378static void alc269_fixup_limit_int_mic_boost(struct hda_codec *codec,
5379 const struct hda_fixup *fix,
5380 int action)
5381{
5382 struct alc_spec *spec = codec->spec;
5383 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
5384 int i;
5385
5386
5387
5388
5389
5390 if (action != HDA_FIXUP_ACT_PROBE)
5391 return;
5392
5393 for (i = 0; i < cfg->num_inputs; i++) {
5394 hda_nid_t nid = cfg->inputs[i].pin;
5395 unsigned int defcfg;
5396 if (cfg->inputs[i].type != AUTO_PIN_MIC)
5397 continue;
5398 defcfg = snd_hda_codec_get_pincfg(codec, nid);
5399 if (snd_hda_get_input_pin_attr(defcfg) != INPUT_PIN_ATTR_INT)
5400 continue;
5401
5402 snd_hda_override_amp_caps(codec, nid, HDA_INPUT,
5403 (0x00 << AC_AMPCAP_OFFSET_SHIFT) |
5404 (0x01 << AC_AMPCAP_NUM_STEPS_SHIFT) |
5405 (0x2f << AC_AMPCAP_STEP_SIZE_SHIFT) |
5406 (0 << AC_AMPCAP_MUTE_SHIFT));
5407 }
5408}
5409
5410static void alc283_hp_automute_hook(struct hda_codec *codec,
5411 struct hda_jack_callback *jack)
5412{
5413 struct alc_spec *spec = codec->spec;
5414 int vref;
5415
5416 msleep(200);
5417 snd_hda_gen_hp_automute(codec, jack);
5418
5419 vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0;
5420
5421 msleep(600);
5422 snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5423 vref);
5424}
5425
5426static void alc283_fixup_chromebook(struct hda_codec *codec,
5427 const struct hda_fixup *fix, int action)
5428{
5429 struct alc_spec *spec = codec->spec;
5430
5431 switch (action) {
5432 case HDA_FIXUP_ACT_PRE_PROBE:
5433 snd_hda_override_wcaps(codec, 0x03, 0);
5434
5435 spec->gen.mixer_nid = 0;
5436 break;
5437 case HDA_FIXUP_ACT_INIT:
5438
5439
5440 alc_update_coef_idx(codec, 0x06, 0x000c, 0);
5441
5442 alc_update_coef_idx(codec, 0x1a, 0, 1 << 4);
5443 break;
5444 }
5445}
5446
5447static void alc283_fixup_sense_combo_jack(struct hda_codec *codec,
5448 const struct hda_fixup *fix, int action)
5449{
5450 struct alc_spec *spec = codec->spec;
5451
5452 switch (action) {
5453 case HDA_FIXUP_ACT_PRE_PROBE:
5454 spec->gen.hp_automute_hook = alc283_hp_automute_hook;
5455 break;
5456 case HDA_FIXUP_ACT_INIT:
5457
5458
5459 alc_update_coef_idx(codec, 0x06, 0x000c, 0);
5460 break;
5461 }
5462}
5463
5464
5465static void asus_tx300_automute(struct hda_codec *codec)
5466{
5467 struct alc_spec *spec = codec->spec;
5468 snd_hda_gen_update_outputs(codec);
5469 if (snd_hda_jack_detect(codec, 0x1b))
5470 spec->gen.mute_bits |= (1ULL << 0x14);