blob: abe371c01fba27bbc962216e3bbae4510c99be09 [file] [log] [blame]
David Brazdil0f672f62019-12-10 10:32:29 +00001// SPDX-License-Identifier: GPL-2.0-or-later
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002/*
3 * Universal Interface for Intel High Definition Audio Codec
4 *
5 * HD audio interface patch for Realtek ALC codecs
6 *
7 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
8 * PeiSen Hou <pshou@realtek.com.tw>
9 * Takashi Iwai <tiwai@suse.de>
10 * Jonathan Woithe <jwoithe@just42.net>
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000011 */
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>
David Brazdil0f672f62019-12-10 10:32:29 +000022#include <sound/hda_codec.h>
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000023#include "hda_local.h"
24#include "hda_auto_parser.h"
25#include "hda_jack.h"
26#include "hda_generic.h"
27
28/* keep halting ALC5505 DSP, for power saving */
29#define HALT_REALTEK_ALC5505
30
31/* extra amp-initialization sequence types */
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; /* Means that this sku is set by driver, not read from hw */
67};
68
69struct alc_spec {
70 struct hda_gen_spec gen; /* must be at head */
71
72 /* codec parameterization */
73 struct alc_customize_define cdefine;
74 unsigned int parse_flags; /* flag for snd_hda_parse_pin_defcfg() */
75
76 /* GPIO bits */
77 unsigned int gpio_mask;
78 unsigned int gpio_dir;
79 unsigned int gpio_data;
80 bool gpio_write_delay; /* add a delay before writing gpio_data */
81
82 /* mute LED for HP laptops, see alc269_fixup_mic_mute_hook() */
83 int mute_led_polarity;
Olivier Deprez0e641232021-09-23 10:07:05 +020084 int micmute_led_polarity;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000085 hda_nid_t mute_led_nid;
86 hda_nid_t cap_mute_led_nid;
87
88 unsigned int gpio_mute_led_mask;
89 unsigned int gpio_mic_led_mask;
Olivier Deprez0e641232021-09-23 10:07:05 +020090 unsigned int mute_led_coef_idx;
91 unsigned int mute_led_coefbit_mask;
92 unsigned int mute_led_coefbit_on;
93 unsigned int mute_led_coefbit_off;
94 unsigned int mic_led_coef_idx;
95 unsigned int mic_led_coefbit_mask;
96 unsigned int mic_led_coefbit_on;
97 unsigned int mic_led_coefbit_off;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000098
99 hda_nid_t headset_mic_pin;
100 hda_nid_t headphone_mic_pin;
101 int current_headset_mode;
102 int current_headset_type;
103
104 /* hooks */
105 void (*init_hook)(struct hda_codec *codec);
106#ifdef CONFIG_PM
107 void (*power_hook)(struct hda_codec *codec);
108#endif
109 void (*shutup)(struct hda_codec *codec);
110 void (*reboot_notify)(struct hda_codec *codec);
111
112 int init_amp;
113 int codec_variant; /* flag for other variants */
114 unsigned int has_alc5505_dsp:1;
115 unsigned int no_depop_delay:1;
David Brazdil0f672f62019-12-10 10:32:29 +0000116 unsigned int done_hp_init:1;
117 unsigned int no_shutup_pins:1;
118 unsigned int ultra_low_power:1;
Olivier Deprez0e641232021-09-23 10:07:05 +0200119 unsigned int has_hs_key:1;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000120
121 /* for PLL fix */
122 hda_nid_t pll_nid;
123 unsigned int pll_coef_idx, pll_coef_bit;
124 unsigned int coef0;
125 struct input_dev *kb_dev;
126 u8 alc_mute_keycode_map[1];
127};
128
129/*
130 * COEF access helper functions
131 */
132
133static int alc_read_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
134 unsigned int coef_idx)
135{
136 unsigned int val;
137
138 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, coef_idx);
139 val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PROC_COEF, 0);
140 return val;
141}
142
143#define alc_read_coef_idx(codec, coef_idx) \
144 alc_read_coefex_idx(codec, 0x20, coef_idx)
145
146static void alc_write_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
147 unsigned int coef_idx, unsigned int coef_val)
148{
149 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, coef_idx);
150 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PROC_COEF, coef_val);
151}
152
153#define alc_write_coef_idx(codec, coef_idx, coef_val) \
154 alc_write_coefex_idx(codec, 0x20, coef_idx, coef_val)
155
156static void alc_update_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
157 unsigned int coef_idx, unsigned int mask,
158 unsigned int bits_set)
159{
160 unsigned int val = alc_read_coefex_idx(codec, nid, coef_idx);
161
162 if (val != -1)
163 alc_write_coefex_idx(codec, nid, coef_idx,
164 (val & ~mask) | bits_set);
165}
166
167#define alc_update_coef_idx(codec, coef_idx, mask, bits_set) \
168 alc_update_coefex_idx(codec, 0x20, coef_idx, mask, bits_set)
169
170/* a special bypass for COEF 0; read the cached value at the second time */
171static unsigned int alc_get_coef0(struct hda_codec *codec)
172{
173 struct alc_spec *spec = codec->spec;
174
175 if (!spec->coef0)
176 spec->coef0 = alc_read_coef_idx(codec, 0);
177 return spec->coef0;
178}
179
180/* coef writes/updates batch */
181struct coef_fw {
182 unsigned char nid;
183 unsigned char idx;
184 unsigned short mask;
185 unsigned short val;
186};
187
188#define UPDATE_COEFEX(_nid, _idx, _mask, _val) \
189 { .nid = (_nid), .idx = (_idx), .mask = (_mask), .val = (_val) }
190#define WRITE_COEFEX(_nid, _idx, _val) UPDATE_COEFEX(_nid, _idx, -1, _val)
191#define WRITE_COEF(_idx, _val) WRITE_COEFEX(0x20, _idx, _val)
192#define UPDATE_COEF(_idx, _mask, _val) UPDATE_COEFEX(0x20, _idx, _mask, _val)
193
194static void alc_process_coef_fw(struct hda_codec *codec,
195 const struct coef_fw *fw)
196{
197 for (; fw->nid; fw++) {
198 if (fw->mask == (unsigned short)-1)
199 alc_write_coefex_idx(codec, fw->nid, fw->idx, fw->val);
200 else
201 alc_update_coefex_idx(codec, fw->nid, fw->idx,
202 fw->mask, fw->val);
203 }
204}
205
206/*
207 * GPIO setup tables, used in initialization
208 */
209
210/* Enable GPIO mask and set output */
211static void alc_setup_gpio(struct hda_codec *codec, unsigned int mask)
212{
213 struct alc_spec *spec = codec->spec;
214
215 spec->gpio_mask |= mask;
216 spec->gpio_dir |= mask;
217 spec->gpio_data |= mask;
218}
219
220static void alc_write_gpio_data(struct hda_codec *codec)
221{
222 struct alc_spec *spec = codec->spec;
223
224 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
225 spec->gpio_data);
226}
227
228static void alc_update_gpio_data(struct hda_codec *codec, unsigned int mask,
229 bool on)
230{
231 struct alc_spec *spec = codec->spec;
232 unsigned int oldval = spec->gpio_data;
233
234 if (on)
235 spec->gpio_data |= mask;
236 else
237 spec->gpio_data &= ~mask;
238 if (oldval != spec->gpio_data)
239 alc_write_gpio_data(codec);
240}
241
242static void alc_write_gpio(struct hda_codec *codec)
243{
244 struct alc_spec *spec = codec->spec;
245
246 if (!spec->gpio_mask)
247 return;
248
249 snd_hda_codec_write(codec, codec->core.afg, 0,
250 AC_VERB_SET_GPIO_MASK, spec->gpio_mask);
251 snd_hda_codec_write(codec, codec->core.afg, 0,
252 AC_VERB_SET_GPIO_DIRECTION, spec->gpio_dir);
253 if (spec->gpio_write_delay)
254 msleep(1);
255 alc_write_gpio_data(codec);
256}
257
258static void alc_fixup_gpio(struct hda_codec *codec, int action,
259 unsigned int mask)
260{
261 if (action == HDA_FIXUP_ACT_PRE_PROBE)
262 alc_setup_gpio(codec, mask);
263}
264
265static void alc_fixup_gpio1(struct hda_codec *codec,
266 const struct hda_fixup *fix, int action)
267{
268 alc_fixup_gpio(codec, action, 0x01);
269}
270
271static void alc_fixup_gpio2(struct hda_codec *codec,
272 const struct hda_fixup *fix, int action)
273{
274 alc_fixup_gpio(codec, action, 0x02);
275}
276
277static void alc_fixup_gpio3(struct hda_codec *codec,
278 const struct hda_fixup *fix, int action)
279{
280 alc_fixup_gpio(codec, action, 0x03);
281}
282
283static void alc_fixup_gpio4(struct hda_codec *codec,
284 const struct hda_fixup *fix, int action)
285{
286 alc_fixup_gpio(codec, action, 0x04);
287}
288
289/*
290 * Fix hardware PLL issue
291 * On some codecs, the analog PLL gating control must be off while
292 * the default value is 1.
293 */
294static void alc_fix_pll(struct hda_codec *codec)
295{
296 struct alc_spec *spec = codec->spec;
297
298 if (spec->pll_nid)
299 alc_update_coefex_idx(codec, spec->pll_nid, spec->pll_coef_idx,
300 1 << spec->pll_coef_bit, 0);
301}
302
303static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
304 unsigned int coef_idx, unsigned int coef_bit)
305{
306 struct alc_spec *spec = codec->spec;
307 spec->pll_nid = nid;
308 spec->pll_coef_idx = coef_idx;
309 spec->pll_coef_bit = coef_bit;
310 alc_fix_pll(codec);
311}
312
313/* update the master volume per volume-knob's unsol event */
314static void alc_update_knob_master(struct hda_codec *codec,
315 struct hda_jack_callback *jack)
316{
317 unsigned int val;
318 struct snd_kcontrol *kctl;
319 struct snd_ctl_elem_value *uctl;
320
321 kctl = snd_hda_find_mixer_ctl(codec, "Master Playback Volume");
322 if (!kctl)
323 return;
324 uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
325 if (!uctl)
326 return;
327 val = snd_hda_codec_read(codec, jack->nid, 0,
328 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
329 val &= HDA_AMP_VOLMASK;
330 uctl->value.integer.value[0] = val;
331 uctl->value.integer.value[1] = val;
332 kctl->put(kctl, uctl);
333 kfree(uctl);
334}
335
336static void alc880_unsol_event(struct hda_codec *codec, unsigned int res)
337{
338 /* For some reason, the res given from ALC880 is broken.
339 Here we adjust it properly. */
340 snd_hda_jack_unsol_event(codec, res >> 2);
341}
342
343/* Change EAPD to verb control */
344static void alc_fill_eapd_coef(struct hda_codec *codec)
345{
346 int coef;
347
348 coef = alc_get_coef0(codec);
349
350 switch (codec->core.vendor_id) {
351 case 0x10ec0262:
352 alc_update_coef_idx(codec, 0x7, 0, 1<<5);
353 break;
354 case 0x10ec0267:
355 case 0x10ec0268:
356 alc_update_coef_idx(codec, 0x7, 0, 1<<13);
357 break;
358 case 0x10ec0269:
359 if ((coef & 0x00f0) == 0x0010)
360 alc_update_coef_idx(codec, 0xd, 0, 1<<14);
361 if ((coef & 0x00f0) == 0x0020)
362 alc_update_coef_idx(codec, 0x4, 1<<15, 0);
363 if ((coef & 0x00f0) == 0x0030)
364 alc_update_coef_idx(codec, 0x10, 1<<9, 0);
365 break;
366 case 0x10ec0280:
367 case 0x10ec0284:
368 case 0x10ec0290:
369 case 0x10ec0292:
370 alc_update_coef_idx(codec, 0x4, 1<<15, 0);
371 break;
372 case 0x10ec0225:
373 case 0x10ec0295:
374 case 0x10ec0299:
375 alc_update_coef_idx(codec, 0x67, 0xf000, 0x3000);
376 /* fallthrough */
377 case 0x10ec0215:
Olivier Deprez0e641232021-09-23 10:07:05 +0200378 case 0x10ec0230:
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000379 case 0x10ec0233:
380 case 0x10ec0235:
381 case 0x10ec0236:
Olivier Deprez0e641232021-09-23 10:07:05 +0200382 case 0x10ec0245:
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000383 case 0x10ec0255:
384 case 0x10ec0256:
385 case 0x10ec0257:
386 case 0x10ec0282:
387 case 0x10ec0283:
388 case 0x10ec0286:
389 case 0x10ec0288:
390 case 0x10ec0285:
391 case 0x10ec0298:
392 case 0x10ec0289:
393 case 0x10ec0300:
394 alc_update_coef_idx(codec, 0x10, 1<<9, 0);
395 break;
396 case 0x10ec0275:
397 alc_update_coef_idx(codec, 0xe, 0, 1<<0);
398 break;
Olivier Deprez0e641232021-09-23 10:07:05 +0200399 case 0x10ec0287:
400 alc_update_coef_idx(codec, 0x10, 1<<9, 0);
401 alc_write_coef_idx(codec, 0x8, 0x4ab7);
402 break;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000403 case 0x10ec0293:
404 alc_update_coef_idx(codec, 0xa, 1<<13, 0);
405 break;
406 case 0x10ec0234:
407 case 0x10ec0274:
408 case 0x10ec0294:
409 case 0x10ec0700:
410 case 0x10ec0701:
411 case 0x10ec0703:
David Brazdil0f672f62019-12-10 10:32:29 +0000412 case 0x10ec0711:
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000413 alc_update_coef_idx(codec, 0x10, 1<<15, 0);
414 break;
415 case 0x10ec0662:
416 if ((coef & 0x00f0) == 0x0030)
417 alc_update_coef_idx(codec, 0x4, 1<<10, 0); /* EAPD Ctrl */
418 break;
419 case 0x10ec0272:
420 case 0x10ec0273:
421 case 0x10ec0663:
422 case 0x10ec0665:
423 case 0x10ec0670:
424 case 0x10ec0671:
425 case 0x10ec0672:
426 alc_update_coef_idx(codec, 0xd, 0, 1<<14); /* EAPD Ctrl */
427 break;
Olivier Deprez0e641232021-09-23 10:07:05 +0200428 case 0x10ec0222:
David Brazdil0f672f62019-12-10 10:32:29 +0000429 case 0x10ec0623:
430 alc_update_coef_idx(codec, 0x19, 1<<13, 0);
431 break;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000432 case 0x10ec0668:
433 alc_update_coef_idx(codec, 0x7, 3<<13, 0);
434 break;
435 case 0x10ec0867:
436 alc_update_coef_idx(codec, 0x4, 1<<10, 0);
437 break;
438 case 0x10ec0888:
439 if ((coef & 0x00f0) == 0x0020 || (coef & 0x00f0) == 0x0030)
440 alc_update_coef_idx(codec, 0x7, 1<<5, 0);
441 break;
442 case 0x10ec0892:
Olivier Deprez0e641232021-09-23 10:07:05 +0200443 case 0x10ec0897:
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000444 alc_update_coef_idx(codec, 0x7, 1<<5, 0);
445 break;
446 case 0x10ec0899:
447 case 0x10ec0900:
Olivier Deprez0e641232021-09-23 10:07:05 +0200448 case 0x10ec0b00:
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000449 case 0x10ec1168:
450 case 0x10ec1220:
451 alc_update_coef_idx(codec, 0x7, 1<<1, 0);
452 break;
453 }
454}
455
456/* additional initialization for ALC888 variants */
457static void alc888_coef_init(struct hda_codec *codec)
458{
459 switch (alc_get_coef0(codec) & 0x00f0) {
460 /* alc888-VA */
461 case 0x00:
462 /* alc888-VB */
463 case 0x10:
464 alc_update_coef_idx(codec, 7, 0, 0x2030); /* Turn EAPD to High */
465 break;
466 }
467}
468
469/* turn on/off EAPD control (only if available) */
470static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
471{
472 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
473 return;
474 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
475 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
476 on ? 2 : 0);
477}
478
479/* turn on/off EAPD controls of the codec */
480static void alc_auto_setup_eapd(struct hda_codec *codec, bool on)
481{
482 /* We currently only handle front, HP */
Olivier Deprez0e641232021-09-23 10:07:05 +0200483 static const hda_nid_t pins[] = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000484 0x0f, 0x10, 0x14, 0x15, 0x17, 0
485 };
Olivier Deprez0e641232021-09-23 10:07:05 +0200486 const hda_nid_t *p;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000487 for (p = pins; *p; p++)
488 set_eapd(codec, *p, on);
489}
490
David Brazdil0f672f62019-12-10 10:32:29 +0000491static int find_ext_mic_pin(struct hda_codec *codec);
492
493static void alc_headset_mic_no_shutup(struct hda_codec *codec)
494{
495 const struct hda_pincfg *pin;
496 int mic_pin = find_ext_mic_pin(codec);
497 int i;
498
499 /* don't shut up pins when unloading the driver; otherwise it breaks
500 * the default pin setup at the next load of the driver
501 */
502 if (codec->bus->shutdown)
503 return;
504
505 snd_array_for_each(&codec->init_pins, i, pin) {
506 /* use read here for syncing after issuing each verb */
507 if (pin->nid != mic_pin)
508 snd_hda_codec_read(codec, pin->nid, 0,
509 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
510 }
511
512 codec->pins_shutup = 1;
513}
514
515static void alc_shutup_pins(struct hda_codec *codec)
516{
517 struct alc_spec *spec = codec->spec;
518
519 switch (codec->core.vendor_id) {
Olivier Deprez0e641232021-09-23 10:07:05 +0200520 case 0x10ec0283:
David Brazdil0f672f62019-12-10 10:32:29 +0000521 case 0x10ec0286:
522 case 0x10ec0288:
523 case 0x10ec0298:
524 alc_headset_mic_no_shutup(codec);
525 break;
526 default:
527 if (!spec->no_shutup_pins)
528 snd_hda_shutup_pins(codec);
529 break;
530 }
531}
532
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000533/* generic shutup callback;
534 * just turning off EAPD and a little pause for avoiding pop-noise
535 */
536static void alc_eapd_shutup(struct hda_codec *codec)
537{
538 struct alc_spec *spec = codec->spec;
539
540 alc_auto_setup_eapd(codec, false);
541 if (!spec->no_depop_delay)
542 msleep(200);
David Brazdil0f672f62019-12-10 10:32:29 +0000543 alc_shutup_pins(codec);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000544}
545
546/* generic EAPD initialization */
547static void alc_auto_init_amp(struct hda_codec *codec, int type)
548{
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000549 alc_auto_setup_eapd(codec, true);
550 alc_write_gpio(codec);
551 switch (type) {
552 case ALC_INIT_DEFAULT:
553 switch (codec->core.vendor_id) {
554 case 0x10ec0260:
555 alc_update_coefex_idx(codec, 0x1a, 7, 0, 0x2010);
556 break;
557 case 0x10ec0880:
558 case 0x10ec0882:
559 case 0x10ec0883:
560 case 0x10ec0885:
561 alc_update_coef_idx(codec, 7, 0, 0x2030);
562 break;
563 case 0x10ec0888:
564 alc888_coef_init(codec);
565 break;
566 }
567 break;
568 }
569}
570
David Brazdil0f672f62019-12-10 10:32:29 +0000571/* get a primary headphone pin if available */
572static hda_nid_t alc_get_hp_pin(struct alc_spec *spec)
573{
574 if (spec->gen.autocfg.hp_pins[0])
575 return spec->gen.autocfg.hp_pins[0];
576 if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
577 return spec->gen.autocfg.line_out_pins[0];
578 return 0;
579}
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000580
581/*
582 * Realtek SSID verification
583 */
584
585/* Could be any non-zero and even value. When used as fixup, tells
586 * the driver to ignore any present sku defines.
587 */
588#define ALC_FIXUP_SKU_IGNORE (2)
589
590static void alc_fixup_sku_ignore(struct hda_codec *codec,
591 const struct hda_fixup *fix, int action)
592{
593 struct alc_spec *spec = codec->spec;
594 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
595 spec->cdefine.fixup = 1;
596 spec->cdefine.sku_cfg = ALC_FIXUP_SKU_IGNORE;
597 }
598}
599
600static void alc_fixup_no_depop_delay(struct hda_codec *codec,
601 const struct hda_fixup *fix, int action)
602{
603 struct alc_spec *spec = codec->spec;
604
605 if (action == HDA_FIXUP_ACT_PROBE) {
606 spec->no_depop_delay = 1;
607 codec->depop_delay = 0;
608 }
609}
610
611static int alc_auto_parse_customize_define(struct hda_codec *codec)
612{
613 unsigned int ass, tmp, i;
614 unsigned nid = 0;
615 struct alc_spec *spec = codec->spec;
616
617 spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
618
619 if (spec->cdefine.fixup) {
620 ass = spec->cdefine.sku_cfg;
621 if (ass == ALC_FIXUP_SKU_IGNORE)
622 return -1;
623 goto do_sku;
624 }
625
626 if (!codec->bus->pci)
627 return -1;
628 ass = codec->core.subsystem_id & 0xffff;
629 if (ass != codec->bus->pci->subsystem_device && (ass & 1))
630 goto do_sku;
631
632 nid = 0x1d;
633 if (codec->core.vendor_id == 0x10ec0260)
634 nid = 0x17;
635 ass = snd_hda_codec_get_pincfg(codec, nid);
636
637 if (!(ass & 1)) {
638 codec_info(codec, "%s: SKU not ready 0x%08x\n",
639 codec->core.chip_name, ass);
640 return -1;
641 }
642
643 /* check sum */
644 tmp = 0;
645 for (i = 1; i < 16; i++) {
646 if ((ass >> i) & 1)
647 tmp++;
648 }
649 if (((ass >> 16) & 0xf) != tmp)
650 return -1;
651
652 spec->cdefine.port_connectivity = ass >> 30;
653 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
654 spec->cdefine.check_sum = (ass >> 16) & 0xf;
655 spec->cdefine.customization = ass >> 8;
656do_sku:
657 spec->cdefine.sku_cfg = ass;
658 spec->cdefine.external_amp = (ass & 0x38) >> 3;
659 spec->cdefine.platform_type = (ass & 0x4) >> 2;
660 spec->cdefine.swap = (ass & 0x2) >> 1;
661 spec->cdefine.override = ass & 0x1;
662
663 codec_dbg(codec, "SKU: Nid=0x%x sku_cfg=0x%08x\n",
664 nid, spec->cdefine.sku_cfg);
665 codec_dbg(codec, "SKU: port_connectivity=0x%x\n",
666 spec->cdefine.port_connectivity);
667 codec_dbg(codec, "SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
668 codec_dbg(codec, "SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
669 codec_dbg(codec, "SKU: customization=0x%08x\n", spec->cdefine.customization);
670 codec_dbg(codec, "SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
671 codec_dbg(codec, "SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
672 codec_dbg(codec, "SKU: swap=0x%x\n", spec->cdefine.swap);
673 codec_dbg(codec, "SKU: override=0x%x\n", spec->cdefine.override);
674
675 return 0;
676}
677
678/* return the position of NID in the list, or -1 if not found */
679static int find_idx_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
680{
681 int i;
682 for (i = 0; i < nums; i++)
683 if (list[i] == nid)
684 return i;
685 return -1;
686}
687/* return true if the given NID is found in the list */
688static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
689{
690 return find_idx_in_nid_list(nid, list, nums) >= 0;
691}
692
693/* check subsystem ID and set up device-specific initialization;
694 * return 1 if initialized, 0 if invalid SSID
695 */
696/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
697 * 31 ~ 16 : Manufacture ID
698 * 15 ~ 8 : SKU ID
699 * 7 ~ 0 : Assembly ID
700 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
701 */
702static int alc_subsystem_id(struct hda_codec *codec, const hda_nid_t *ports)
703{
704 unsigned int ass, tmp, i;
705 unsigned nid;
706 struct alc_spec *spec = codec->spec;
707
708 if (spec->cdefine.fixup) {
709 ass = spec->cdefine.sku_cfg;
710 if (ass == ALC_FIXUP_SKU_IGNORE)
711 return 0;
712 goto do_sku;
713 }
714
715 ass = codec->core.subsystem_id & 0xffff;
716 if (codec->bus->pci &&
717 ass != codec->bus->pci->subsystem_device && (ass & 1))
718 goto do_sku;
719
720 /* invalid SSID, check the special NID pin defcfg instead */
721 /*
722 * 31~30 : port connectivity
723 * 29~21 : reserve
724 * 20 : PCBEEP input
725 * 19~16 : Check sum (15:1)
726 * 15~1 : Custom
727 * 0 : override
728 */
729 nid = 0x1d;
730 if (codec->core.vendor_id == 0x10ec0260)
731 nid = 0x17;
732 ass = snd_hda_codec_get_pincfg(codec, nid);
733 codec_dbg(codec,
734 "realtek: No valid SSID, checking pincfg 0x%08x for NID 0x%x\n",
735 ass, nid);
736 if (!(ass & 1))
737 return 0;
738 if ((ass >> 30) != 1) /* no physical connection */
739 return 0;
740
741 /* check sum */
742 tmp = 0;
743 for (i = 1; i < 16; i++) {
744 if ((ass >> i) & 1)
745 tmp++;
746 }
747 if (((ass >> 16) & 0xf) != tmp)
748 return 0;
749do_sku:
750 codec_dbg(codec, "realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
751 ass & 0xffff, codec->core.vendor_id);
752 /*
753 * 0 : override
754 * 1 : Swap Jack
755 * 2 : 0 --> Desktop, 1 --> Laptop
756 * 3~5 : External Amplifier control
757 * 7~6 : Reserved
758 */
759 tmp = (ass & 0x38) >> 3; /* external Amp control */
760 if (spec->init_amp == ALC_INIT_UNDEFINED) {
761 switch (tmp) {
762 case 1:
763 alc_setup_gpio(codec, 0x01);
764 break;
765 case 3:
766 alc_setup_gpio(codec, 0x02);
767 break;
768 case 7:
769 alc_setup_gpio(codec, 0x03);
770 break;
771 case 5:
772 default:
773 spec->init_amp = ALC_INIT_DEFAULT;
774 break;
775 }
776 }
777
778 /* is laptop or Desktop and enable the function "Mute internal speaker
779 * when the external headphone out jack is plugged"
780 */
781 if (!(ass & 0x8000))
782 return 1;
783 /*
784 * 10~8 : Jack location
785 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
786 * 14~13: Resvered
787 * 15 : 1 --> enable the function "Mute internal speaker
788 * when the external headphone out jack is plugged"
789 */
David Brazdil0f672f62019-12-10 10:32:29 +0000790 if (!alc_get_hp_pin(spec)) {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000791 hda_nid_t nid;
792 tmp = (ass >> 11) & 0x3; /* HP to chassis */
793 nid = ports[tmp];
794 if (found_in_nid_list(nid, spec->gen.autocfg.line_out_pins,
795 spec->gen.autocfg.line_outs))
796 return 1;
797 spec->gen.autocfg.hp_pins[0] = nid;
798 }
799 return 1;
800}
801
802/* Check the validity of ALC subsystem-id
803 * ports contains an array of 4 pin NIDs for port-A, E, D and I */
804static void alc_ssid_check(struct hda_codec *codec, const hda_nid_t *ports)
805{
806 if (!alc_subsystem_id(codec, ports)) {
807 struct alc_spec *spec = codec->spec;
Olivier Deprez0e641232021-09-23 10:07:05 +0200808 if (spec->init_amp == ALC_INIT_UNDEFINED) {
809 codec_dbg(codec,
810 "realtek: Enable default setup for auto mode as fallback\n");
811 spec->init_amp = ALC_INIT_DEFAULT;
812 }
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000813 }
814}
815
816/*
817 */
818
819static void alc_fixup_inv_dmic(struct hda_codec *codec,
820 const struct hda_fixup *fix, int action)
821{
822 struct alc_spec *spec = codec->spec;
823
824 spec->gen.inv_dmic_split = 1;
825}
826
827
828static int alc_build_controls(struct hda_codec *codec)
829{
830 int err;
831
832 err = snd_hda_gen_build_controls(codec);
833 if (err < 0)
834 return err;
835
836 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_BUILD);
837 return 0;
838}
839
840
841/*
842 * Common callbacks
843 */
844
David Brazdil0f672f62019-12-10 10:32:29 +0000845static void alc_pre_init(struct hda_codec *codec)
846{
847 alc_fill_eapd_coef(codec);
848}
849
850#define is_s3_resume(codec) \
851 ((codec)->core.dev.power.power_state.event == PM_EVENT_RESUME)
852#define is_s4_resume(codec) \
853 ((codec)->core.dev.power.power_state.event == PM_EVENT_RESTORE)
854
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000855static int alc_init(struct hda_codec *codec)
856{
857 struct alc_spec *spec = codec->spec;
858
David Brazdil0f672f62019-12-10 10:32:29 +0000859 /* hibernation resume needs the full chip initialization */
860 if (is_s4_resume(codec))
861 alc_pre_init(codec);
862
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000863 if (spec->init_hook)
864 spec->init_hook(codec);
865
David Brazdil0f672f62019-12-10 10:32:29 +0000866 spec->gen.skip_verbs = 1; /* applied in below */
867 snd_hda_gen_init(codec);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000868 alc_fix_pll(codec);
869 alc_auto_init_amp(codec, spec->init_amp);
David Brazdil0f672f62019-12-10 10:32:29 +0000870 snd_hda_apply_verbs(codec); /* apply verbs here after own init */
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000871
872 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_INIT);
873
874 return 0;
875}
876
877static inline void alc_shutup(struct hda_codec *codec)
878{
879 struct alc_spec *spec = codec->spec;
880
881 if (!snd_hda_get_bool_hint(codec, "shutup"))
882 return; /* disabled explicitly by hints */
883
884 if (spec && spec->shutup)
885 spec->shutup(codec);
886 else
David Brazdil0f672f62019-12-10 10:32:29 +0000887 alc_shutup_pins(codec);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000888}
889
890static void alc_reboot_notify(struct hda_codec *codec)
891{
892 struct alc_spec *spec = codec->spec;
893
894 if (spec && spec->reboot_notify)
895 spec->reboot_notify(codec);
896 else
897 alc_shutup(codec);
898}
899
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000900#define alc_free snd_hda_gen_free
901
902#ifdef CONFIG_PM
903static void alc_power_eapd(struct hda_codec *codec)
904{
905 alc_auto_setup_eapd(codec, false);
906}
907
908static int alc_suspend(struct hda_codec *codec)
909{
910 struct alc_spec *spec = codec->spec;
911 alc_shutup(codec);
912 if (spec && spec->power_hook)
913 spec->power_hook(codec);
914 return 0;
915}
916#endif
917
918#ifdef CONFIG_PM
919static int alc_resume(struct hda_codec *codec)
920{
921 struct alc_spec *spec = codec->spec;
922
923 if (!spec->no_depop_delay)
924 msleep(150); /* to avoid pop noise */
925 codec->patch_ops.init(codec);
Olivier Deprez0e641232021-09-23 10:07:05 +0200926 snd_hda_regmap_sync(codec);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000927 hda_call_check_power_status(codec, 0x01);
928 return 0;
929}
930#endif
931
932/*
933 */
934static const struct hda_codec_ops alc_patch_ops = {
935 .build_controls = alc_build_controls,
936 .build_pcms = snd_hda_gen_build_pcms,
937 .init = alc_init,
938 .free = alc_free,
939 .unsol_event = snd_hda_jack_unsol_event,
940#ifdef CONFIG_PM
941 .resume = alc_resume,
942 .suspend = alc_suspend,
943 .check_power_status = snd_hda_gen_check_power_status,
944#endif
945 .reboot_notify = alc_reboot_notify,
946};
947
948
949#define alc_codec_rename(codec, name) snd_hda_codec_set_name(codec, name)
950
951/*
952 * Rename codecs appropriately from COEF value or subvendor id
953 */
954struct alc_codec_rename_table {
955 unsigned int vendor_id;
956 unsigned short coef_mask;
957 unsigned short coef_bits;
958 const char *name;
959};
960
961struct alc_codec_rename_pci_table {
962 unsigned int codec_vendor_id;
963 unsigned short pci_subvendor;
964 unsigned short pci_subdevice;
965 const char *name;
966};
967
Olivier Deprez0e641232021-09-23 10:07:05 +0200968static const struct alc_codec_rename_table rename_tbl[] = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000969 { 0x10ec0221, 0xf00f, 0x1003, "ALC231" },
970 { 0x10ec0269, 0xfff0, 0x3010, "ALC277" },
971 { 0x10ec0269, 0xf0f0, 0x2010, "ALC259" },
972 { 0x10ec0269, 0xf0f0, 0x3010, "ALC258" },
973 { 0x10ec0269, 0x00f0, 0x0010, "ALC269VB" },
974 { 0x10ec0269, 0xffff, 0xa023, "ALC259" },
975 { 0x10ec0269, 0xffff, 0x6023, "ALC281X" },
976 { 0x10ec0269, 0x00f0, 0x0020, "ALC269VC" },
977 { 0x10ec0269, 0x00f0, 0x0030, "ALC269VD" },
978 { 0x10ec0662, 0xffff, 0x4020, "ALC656" },
979 { 0x10ec0887, 0x00f0, 0x0030, "ALC887-VD" },
980 { 0x10ec0888, 0x00f0, 0x0030, "ALC888-VD" },
981 { 0x10ec0888, 0xf0f0, 0x3020, "ALC886" },
982 { 0x10ec0899, 0x2000, 0x2000, "ALC899" },
983 { 0x10ec0892, 0xffff, 0x8020, "ALC661" },
984 { 0x10ec0892, 0xffff, 0x8011, "ALC661" },
985 { 0x10ec0892, 0xffff, 0x4011, "ALC656" },
986 { } /* terminator */
987};
988
Olivier Deprez0e641232021-09-23 10:07:05 +0200989static const struct alc_codec_rename_pci_table rename_pci_tbl[] = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000990 { 0x10ec0280, 0x1028, 0, "ALC3220" },
991 { 0x10ec0282, 0x1028, 0, "ALC3221" },
992 { 0x10ec0283, 0x1028, 0, "ALC3223" },
993 { 0x10ec0288, 0x1028, 0, "ALC3263" },
994 { 0x10ec0292, 0x1028, 0, "ALC3226" },
995 { 0x10ec0293, 0x1028, 0, "ALC3235" },
996 { 0x10ec0255, 0x1028, 0, "ALC3234" },
997 { 0x10ec0668, 0x1028, 0, "ALC3661" },
998 { 0x10ec0275, 0x1028, 0, "ALC3260" },
999 { 0x10ec0899, 0x1028, 0, "ALC3861" },
1000 { 0x10ec0298, 0x1028, 0, "ALC3266" },
1001 { 0x10ec0236, 0x1028, 0, "ALC3204" },
1002 { 0x10ec0256, 0x1028, 0, "ALC3246" },
1003 { 0x10ec0225, 0x1028, 0, "ALC3253" },
1004 { 0x10ec0295, 0x1028, 0, "ALC3254" },
1005 { 0x10ec0299, 0x1028, 0, "ALC3271" },
1006 { 0x10ec0670, 0x1025, 0, "ALC669X" },
1007 { 0x10ec0676, 0x1025, 0, "ALC679X" },
1008 { 0x10ec0282, 0x1043, 0, "ALC3229" },
1009 { 0x10ec0233, 0x1043, 0, "ALC3236" },
1010 { 0x10ec0280, 0x103c, 0, "ALC3228" },
1011 { 0x10ec0282, 0x103c, 0, "ALC3227" },
1012 { 0x10ec0286, 0x103c, 0, "ALC3242" },
1013 { 0x10ec0290, 0x103c, 0, "ALC3241" },
1014 { 0x10ec0668, 0x103c, 0, "ALC3662" },
1015 { 0x10ec0283, 0x17aa, 0, "ALC3239" },
1016 { 0x10ec0292, 0x17aa, 0, "ALC3232" },
1017 { } /* terminator */
1018};
1019
1020static int alc_codec_rename_from_preset(struct hda_codec *codec)
1021{
1022 const struct alc_codec_rename_table *p;
1023 const struct alc_codec_rename_pci_table *q;
1024
1025 for (p = rename_tbl; p->vendor_id; p++) {
1026 if (p->vendor_id != codec->core.vendor_id)
1027 continue;
1028 if ((alc_get_coef0(codec) & p->coef_mask) == p->coef_bits)
1029 return alc_codec_rename(codec, p->name);
1030 }
1031
1032 if (!codec->bus->pci)
1033 return 0;
1034 for (q = rename_pci_tbl; q->codec_vendor_id; q++) {
1035 if (q->codec_vendor_id != codec->core.vendor_id)
1036 continue;
1037 if (q->pci_subvendor != codec->bus->pci->subsystem_vendor)
1038 continue;
1039 if (!q->pci_subdevice ||
1040 q->pci_subdevice == codec->bus->pci->subsystem_device)
1041 return alc_codec_rename(codec, q->name);
1042 }
1043
1044 return 0;
1045}
1046
1047
1048/*
1049 * Digital-beep handlers
1050 */
1051#ifdef CONFIG_SND_HDA_INPUT_BEEP
1052
1053/* additional beep mixers; private_value will be overwritten */
1054static const struct snd_kcontrol_new alc_beep_mixer[] = {
1055 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
1056 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
1057};
1058
1059/* set up and create beep controls */
1060static int set_beep_amp(struct alc_spec *spec, hda_nid_t nid,
1061 int idx, int dir)
1062{
1063 struct snd_kcontrol_new *knew;
1064 unsigned int beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir);
1065 int i;
1066
1067 for (i = 0; i < ARRAY_SIZE(alc_beep_mixer); i++) {
1068 knew = snd_hda_gen_add_kctl(&spec->gen, NULL,
1069 &alc_beep_mixer[i]);
1070 if (!knew)
1071 return -ENOMEM;
1072 knew->private_value = beep_amp;
1073 }
1074 return 0;
1075}
1076
1077static const struct snd_pci_quirk beep_white_list[] = {
1078 SND_PCI_QUIRK(0x1043, 0x103c, "ASUS", 1),
1079 SND_PCI_QUIRK(0x1043, 0x115d, "ASUS", 1),
1080 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
1081 SND_PCI_QUIRK(0x1043, 0x8376, "EeePC", 1),
1082 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
1083 SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1),
1084 SND_PCI_QUIRK(0x1043, 0x834a, "EeePC", 1),
1085 SND_PCI_QUIRK(0x1458, 0xa002, "GA-MA790X", 1),
1086 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
David Brazdil0f672f62019-12-10 10:32:29 +00001087 /* blacklist -- no beep available */
1088 SND_PCI_QUIRK(0x17aa, 0x309e, "Lenovo ThinkCentre M73", 0),
1089 SND_PCI_QUIRK(0x17aa, 0x30a3, "Lenovo ThinkCentre M93", 0),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001090 {}
1091};
1092
1093static inline int has_cdefine_beep(struct hda_codec *codec)
1094{
1095 struct alc_spec *spec = codec->spec;
1096 const struct snd_pci_quirk *q;
1097 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
1098 if (q)
1099 return q->value;
1100 return spec->cdefine.enable_pcbeep;
1101}
1102#else
1103#define set_beep_amp(spec, nid, idx, dir) 0
1104#define has_cdefine_beep(codec) 0
1105#endif
1106
1107/* parse the BIOS configuration and set up the alc_spec */
1108/* return 1 if successful, 0 if the proper config is not found,
1109 * or a negative error code
1110 */
1111static int alc_parse_auto_config(struct hda_codec *codec,
1112 const hda_nid_t *ignore_nids,
1113 const hda_nid_t *ssid_nids)
1114{
1115 struct alc_spec *spec = codec->spec;
1116 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
1117 int err;
1118
1119 err = snd_hda_parse_pin_defcfg(codec, cfg, ignore_nids,
1120 spec->parse_flags);
1121 if (err < 0)
1122 return err;
1123
1124 if (ssid_nids)
1125 alc_ssid_check(codec, ssid_nids);
1126
1127 err = snd_hda_gen_parse_auto_config(codec, cfg);
1128 if (err < 0)
1129 return err;
1130
1131 return 1;
1132}
1133
1134/* common preparation job for alc_spec */
1135static int alc_alloc_spec(struct hda_codec *codec, hda_nid_t mixer_nid)
1136{
1137 struct alc_spec *spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1138 int err;
1139
1140 if (!spec)
1141 return -ENOMEM;
1142 codec->spec = spec;
1143 snd_hda_gen_spec_init(&spec->gen);
1144 spec->gen.mixer_nid = mixer_nid;
1145 spec->gen.own_eapd_ctl = 1;
1146 codec->single_adc_amp = 1;
1147 /* FIXME: do we need this for all Realtek codec models? */
1148 codec->spdif_status_reset = 1;
Olivier Deprez0e641232021-09-23 10:07:05 +02001149 codec->forced_resume = 1;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001150 codec->patch_ops = alc_patch_ops;
1151
1152 err = alc_codec_rename_from_preset(codec);
1153 if (err < 0) {
1154 kfree(spec);
1155 return err;
1156 }
1157 return 0;
1158}
1159
1160static int alc880_parse_auto_config(struct hda_codec *codec)
1161{
1162 static const hda_nid_t alc880_ignore[] = { 0x1d, 0 };
1163 static const hda_nid_t alc880_ssids[] = { 0x15, 0x1b, 0x14, 0 };
1164 return alc_parse_auto_config(codec, alc880_ignore, alc880_ssids);
1165}
1166
1167/*
1168 * ALC880 fix-ups
1169 */
1170enum {
1171 ALC880_FIXUP_GPIO1,
1172 ALC880_FIXUP_GPIO2,
1173 ALC880_FIXUP_MEDION_RIM,
1174 ALC880_FIXUP_LG,
1175 ALC880_FIXUP_LG_LW25,
1176 ALC880_FIXUP_W810,
1177 ALC880_FIXUP_EAPD_COEF,
1178 ALC880_FIXUP_TCL_S700,
1179 ALC880_FIXUP_VOL_KNOB,
1180 ALC880_FIXUP_FUJITSU,
1181 ALC880_FIXUP_F1734,
1182 ALC880_FIXUP_UNIWILL,
1183 ALC880_FIXUP_UNIWILL_DIG,
1184 ALC880_FIXUP_Z71V,
1185 ALC880_FIXUP_ASUS_W5A,
1186 ALC880_FIXUP_3ST_BASE,
1187 ALC880_FIXUP_3ST,
1188 ALC880_FIXUP_3ST_DIG,
1189 ALC880_FIXUP_5ST_BASE,
1190 ALC880_FIXUP_5ST,
1191 ALC880_FIXUP_5ST_DIG,
1192 ALC880_FIXUP_6ST_BASE,
1193 ALC880_FIXUP_6ST,
1194 ALC880_FIXUP_6ST_DIG,
1195 ALC880_FIXUP_6ST_AUTOMUTE,
1196};
1197
1198/* enable the volume-knob widget support on NID 0x21 */
1199static void alc880_fixup_vol_knob(struct hda_codec *codec,
1200 const struct hda_fixup *fix, int action)
1201{
1202 if (action == HDA_FIXUP_ACT_PROBE)
1203 snd_hda_jack_detect_enable_callback(codec, 0x21,
1204 alc_update_knob_master);
1205}
1206
1207static const struct hda_fixup alc880_fixups[] = {
1208 [ALC880_FIXUP_GPIO1] = {
1209 .type = HDA_FIXUP_FUNC,
1210 .v.func = alc_fixup_gpio1,
1211 },
1212 [ALC880_FIXUP_GPIO2] = {
1213 .type = HDA_FIXUP_FUNC,
1214 .v.func = alc_fixup_gpio2,
1215 },
1216 [ALC880_FIXUP_MEDION_RIM] = {
1217 .type = HDA_FIXUP_VERBS,
1218 .v.verbs = (const struct hda_verb[]) {
1219 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
1220 { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
1221 { }
1222 },
1223 .chained = true,
1224 .chain_id = ALC880_FIXUP_GPIO2,
1225 },
1226 [ALC880_FIXUP_LG] = {
1227 .type = HDA_FIXUP_PINS,
1228 .v.pins = (const struct hda_pintbl[]) {
1229 /* disable bogus unused pins */
1230 { 0x16, 0x411111f0 },
1231 { 0x18, 0x411111f0 },
1232 { 0x1a, 0x411111f0 },
1233 { }
1234 }
1235 },
1236 [ALC880_FIXUP_LG_LW25] = {
1237 .type = HDA_FIXUP_PINS,
1238 .v.pins = (const struct hda_pintbl[]) {
1239 { 0x1a, 0x0181344f }, /* line-in */
1240 { 0x1b, 0x0321403f }, /* headphone */
1241 { }
1242 }
1243 },
1244 [ALC880_FIXUP_W810] = {
1245 .type = HDA_FIXUP_PINS,
1246 .v.pins = (const struct hda_pintbl[]) {
1247 /* disable bogus unused pins */
1248 { 0x17, 0x411111f0 },
1249 { }
1250 },
1251 .chained = true,
1252 .chain_id = ALC880_FIXUP_GPIO2,
1253 },
1254 [ALC880_FIXUP_EAPD_COEF] = {
1255 .type = HDA_FIXUP_VERBS,
1256 .v.verbs = (const struct hda_verb[]) {
1257 /* change to EAPD mode */
1258 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
1259 { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
1260 {}
1261 },
1262 },
1263 [ALC880_FIXUP_TCL_S700] = {
1264 .type = HDA_FIXUP_VERBS,
1265 .v.verbs = (const struct hda_verb[]) {
1266 /* change to EAPD mode */
1267 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
1268 { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
1269 {}
1270 },
1271 .chained = true,
1272 .chain_id = ALC880_FIXUP_GPIO2,
1273 },
1274 [ALC880_FIXUP_VOL_KNOB] = {
1275 .type = HDA_FIXUP_FUNC,
1276 .v.func = alc880_fixup_vol_knob,
1277 },
1278 [ALC880_FIXUP_FUJITSU] = {
1279 /* override all pins as BIOS on old Amilo is broken */
1280 .type = HDA_FIXUP_PINS,
1281 .v.pins = (const struct hda_pintbl[]) {
1282 { 0x14, 0x0121401f }, /* HP */
1283 { 0x15, 0x99030120 }, /* speaker */
1284 { 0x16, 0x99030130 }, /* bass speaker */
1285 { 0x17, 0x411111f0 }, /* N/A */
1286 { 0x18, 0x411111f0 }, /* N/A */
1287 { 0x19, 0x01a19950 }, /* mic-in */
1288 { 0x1a, 0x411111f0 }, /* N/A */
1289 { 0x1b, 0x411111f0 }, /* N/A */
1290 { 0x1c, 0x411111f0 }, /* N/A */
1291 { 0x1d, 0x411111f0 }, /* N/A */
1292 { 0x1e, 0x01454140 }, /* SPDIF out */
1293 { }
1294 },
1295 .chained = true,
1296 .chain_id = ALC880_FIXUP_VOL_KNOB,
1297 },
1298 [ALC880_FIXUP_F1734] = {
1299 /* almost compatible with FUJITSU, but no bass and SPDIF */
1300 .type = HDA_FIXUP_PINS,
1301 .v.pins = (const struct hda_pintbl[]) {
1302 { 0x14, 0x0121401f }, /* HP */
1303 { 0x15, 0x99030120 }, /* speaker */
1304 { 0x16, 0x411111f0 }, /* N/A */
1305 { 0x17, 0x411111f0 }, /* N/A */
1306 { 0x18, 0x411111f0 }, /* N/A */
1307 { 0x19, 0x01a19950 }, /* mic-in */
1308 { 0x1a, 0x411111f0 }, /* N/A */
1309 { 0x1b, 0x411111f0 }, /* N/A */
1310 { 0x1c, 0x411111f0 }, /* N/A */
1311 { 0x1d, 0x411111f0 }, /* N/A */
1312 { 0x1e, 0x411111f0 }, /* N/A */
1313 { }
1314 },
1315 .chained = true,
1316 .chain_id = ALC880_FIXUP_VOL_KNOB,
1317 },
1318 [ALC880_FIXUP_UNIWILL] = {
1319 /* need to fix HP and speaker pins to be parsed correctly */
1320 .type = HDA_FIXUP_PINS,
1321 .v.pins = (const struct hda_pintbl[]) {
1322 { 0x14, 0x0121411f }, /* HP */
1323 { 0x15, 0x99030120 }, /* speaker */
1324 { 0x16, 0x99030130 }, /* bass speaker */
1325 { }
1326 },
1327 },
1328 [ALC880_FIXUP_UNIWILL_DIG] = {
1329 .type = HDA_FIXUP_PINS,
1330 .v.pins = (const struct hda_pintbl[]) {
1331 /* disable bogus unused pins */
1332 { 0x17, 0x411111f0 },
1333 { 0x19, 0x411111f0 },
1334 { 0x1b, 0x411111f0 },
1335 { 0x1f, 0x411111f0 },
1336 { }
1337 }
1338 },
1339 [ALC880_FIXUP_Z71V] = {
1340 .type = HDA_FIXUP_PINS,
1341 .v.pins = (const struct hda_pintbl[]) {
1342 /* set up the whole pins as BIOS is utterly broken */
1343 { 0x14, 0x99030120 }, /* speaker */
1344 { 0x15, 0x0121411f }, /* HP */
1345 { 0x16, 0x411111f0 }, /* N/A */
1346 { 0x17, 0x411111f0 }, /* N/A */
1347 { 0x18, 0x01a19950 }, /* mic-in */
1348 { 0x19, 0x411111f0 }, /* N/A */
1349 { 0x1a, 0x01813031 }, /* line-in */
1350 { 0x1b, 0x411111f0 }, /* N/A */
1351 { 0x1c, 0x411111f0 }, /* N/A */
1352 { 0x1d, 0x411111f0 }, /* N/A */
1353 { 0x1e, 0x0144111e }, /* SPDIF */
1354 { }
1355 }
1356 },
1357 [ALC880_FIXUP_ASUS_W5A] = {
1358 .type = HDA_FIXUP_PINS,
1359 .v.pins = (const struct hda_pintbl[]) {
1360 /* set up the whole pins as BIOS is utterly broken */
1361 { 0x14, 0x0121411f }, /* HP */
1362 { 0x15, 0x411111f0 }, /* N/A */
1363 { 0x16, 0x411111f0 }, /* N/A */
1364 { 0x17, 0x411111f0 }, /* N/A */
1365 { 0x18, 0x90a60160 }, /* mic */
1366 { 0x19, 0x411111f0 }, /* N/A */
1367 { 0x1a, 0x411111f0 }, /* N/A */
1368 { 0x1b, 0x411111f0 }, /* N/A */
1369 { 0x1c, 0x411111f0 }, /* N/A */
1370 { 0x1d, 0x411111f0 }, /* N/A */
1371 { 0x1e, 0xb743111e }, /* SPDIF out */
1372 { }
1373 },
1374 .chained = true,
1375 .chain_id = ALC880_FIXUP_GPIO1,
1376 },
1377 [ALC880_FIXUP_3ST_BASE] = {
1378 .type = HDA_FIXUP_PINS,
1379 .v.pins = (const struct hda_pintbl[]) {
1380 { 0x14, 0x01014010 }, /* line-out */
1381 { 0x15, 0x411111f0 }, /* N/A */
1382 { 0x16, 0x411111f0 }, /* N/A */
1383 { 0x17, 0x411111f0 }, /* N/A */
1384 { 0x18, 0x01a19c30 }, /* mic-in */
1385 { 0x19, 0x0121411f }, /* HP */
1386 { 0x1a, 0x01813031 }, /* line-in */
1387 { 0x1b, 0x02a19c40 }, /* front-mic */
1388 { 0x1c, 0x411111f0 }, /* N/A */
1389 { 0x1d, 0x411111f0 }, /* N/A */
1390 /* 0x1e is filled in below */
1391 { 0x1f, 0x411111f0 }, /* N/A */
1392 { }
1393 }
1394 },
1395 [ALC880_FIXUP_3ST] = {
1396 .type = HDA_FIXUP_PINS,
1397 .v.pins = (const struct hda_pintbl[]) {
1398 { 0x1e, 0x411111f0 }, /* N/A */
1399 { }
1400 },
1401 .chained = true,
1402 .chain_id = ALC880_FIXUP_3ST_BASE,
1403 },
1404 [ALC880_FIXUP_3ST_DIG] = {
1405 .type = HDA_FIXUP_PINS,
1406 .v.pins = (const struct hda_pintbl[]) {
1407 { 0x1e, 0x0144111e }, /* SPDIF */
1408 { }
1409 },
1410 .chained = true,
1411 .chain_id = ALC880_FIXUP_3ST_BASE,
1412 },
1413 [ALC880_FIXUP_5ST_BASE] = {
1414 .type = HDA_FIXUP_PINS,
1415 .v.pins = (const struct hda_pintbl[]) {
1416 { 0x14, 0x01014010 }, /* front */
1417 { 0x15, 0x411111f0 }, /* N/A */
1418 { 0x16, 0x01011411 }, /* CLFE */
1419 { 0x17, 0x01016412 }, /* surr */
1420 { 0x18, 0x01a19c30 }, /* mic-in */
1421 { 0x19, 0x0121411f }, /* HP */
1422 { 0x1a, 0x01813031 }, /* line-in */
1423 { 0x1b, 0x02a19c40 }, /* front-mic */
1424 { 0x1c, 0x411111f0 }, /* N/A */
1425 { 0x1d, 0x411111f0 }, /* N/A */
1426 /* 0x1e is filled in below */
1427 { 0x1f, 0x411111f0 }, /* N/A */
1428 { }
1429 }
1430 },
1431 [ALC880_FIXUP_5ST] = {
1432 .type = HDA_FIXUP_PINS,
1433 .v.pins = (const struct hda_pintbl[]) {
1434 { 0x1e, 0x411111f0 }, /* N/A */
1435 { }
1436 },
1437 .chained = true,
1438 .chain_id = ALC880_FIXUP_5ST_BASE,
1439 },
1440 [ALC880_FIXUP_5ST_DIG] = {
1441 .type = HDA_FIXUP_PINS,
1442 .v.pins = (const struct hda_pintbl[]) {
1443 { 0x1e, 0x0144111e }, /* SPDIF */
1444 { }
1445 },
1446 .chained = true,
1447 .chain_id = ALC880_FIXUP_5ST_BASE,
1448 },
1449 [ALC880_FIXUP_6ST_BASE] = {
1450 .type = HDA_FIXUP_PINS,
1451 .v.pins = (const struct hda_pintbl[]) {
1452 { 0x14, 0x01014010 }, /* front */
1453 { 0x15, 0x01016412 }, /* surr */
1454 { 0x16, 0x01011411 }, /* CLFE */
1455 { 0x17, 0x01012414 }, /* side */
1456 { 0x18, 0x01a19c30 }, /* mic-in */
1457 { 0x19, 0x02a19c40 }, /* front-mic */
1458 { 0x1a, 0x01813031 }, /* line-in */
1459 { 0x1b, 0x0121411f }, /* HP */
1460 { 0x1c, 0x411111f0 }, /* N/A */
1461 { 0x1d, 0x411111f0 }, /* N/A */
1462 /* 0x1e is filled in below */
1463 { 0x1f, 0x411111f0 }, /* N/A */
1464 { }
1465 }
1466 },
1467 [ALC880_FIXUP_6ST] = {
1468 .type = HDA_FIXUP_PINS,
1469 .v.pins = (const struct hda_pintbl[]) {
1470 { 0x1e, 0x411111f0 }, /* N/A */
1471 { }
1472 },
1473 .chained = true,
1474 .chain_id = ALC880_FIXUP_6ST_BASE,
1475 },
1476 [ALC880_FIXUP_6ST_DIG] = {
1477 .type = HDA_FIXUP_PINS,
1478 .v.pins = (const struct hda_pintbl[]) {
1479 { 0x1e, 0x0144111e }, /* SPDIF */
1480 { }
1481 },
1482 .chained = true,
1483 .chain_id = ALC880_FIXUP_6ST_BASE,
1484 },
1485 [ALC880_FIXUP_6ST_AUTOMUTE] = {
1486 .type = HDA_FIXUP_PINS,
1487 .v.pins = (const struct hda_pintbl[]) {
1488 { 0x1b, 0x0121401f }, /* HP with jack detect */
1489 { }
1490 },
1491 .chained_before = true,
1492 .chain_id = ALC880_FIXUP_6ST_BASE,
1493 },
1494};
1495
1496static const struct snd_pci_quirk alc880_fixup_tbl[] = {
1497 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_FIXUP_W810),
1498 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS W5A", ALC880_FIXUP_ASUS_W5A),
1499 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_FIXUP_Z71V),
1500 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_FIXUP_GPIO1),
1501 SND_PCI_QUIRK(0x147b, 0x1045, "ABit AA8XE", ALC880_FIXUP_6ST_AUTOMUTE),
1502 SND_PCI_QUIRK(0x1558, 0x5401, "Clevo GPIO2", ALC880_FIXUP_GPIO2),
1503 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo", ALC880_FIXUP_EAPD_COEF),
1504 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_FIXUP_UNIWILL_DIG),
1505 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_FIXUP_F1734),
1506 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_FIXUP_UNIWILL),
1507 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_FIXUP_VOL_KNOB),
1508 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_FIXUP_W810),
1509 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_FIXUP_MEDION_RIM),
1510 SND_PCI_QUIRK(0x1631, 0xe011, "PB 13201056", ALC880_FIXUP_6ST_AUTOMUTE),
1511 SND_PCI_QUIRK(0x1734, 0x107c, "FSC Amilo M1437", ALC880_FIXUP_FUJITSU),
1512 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FIXUP_FUJITSU),
1513 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_FIXUP_F1734),
1514 SND_PCI_QUIRK(0x1734, 0x10b0, "FSC Amilo Pi1556", ALC880_FIXUP_FUJITSU),
1515 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_FIXUP_LG),
1516 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_FIXUP_LG),
1517 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_FIXUP_LG),
1518 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_FIXUP_LG_LW25),
1519 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_FIXUP_TCL_S700),
1520
1521 /* Below is the copied entries from alc880_quirks.c.
1522 * It's not quite sure whether BIOS sets the correct pin-config table
1523 * on these machines, thus they are kept to be compatible with
1524 * the old static quirks. Once when it's confirmed to work without
1525 * these overrides, it'd be better to remove.
1526 */
1527 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_FIXUP_5ST_DIG),
1528 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_FIXUP_6ST),
1529 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_FIXUP_3ST_DIG),
1530 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_FIXUP_6ST_DIG),
1531 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_FIXUP_6ST_DIG),
1532 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_FIXUP_6ST_DIG),
1533 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_FIXUP_3ST_DIG),
1534 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_FIXUP_3ST),
1535 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_FIXUP_6ST_DIG),
1536 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_FIXUP_3ST),
1537 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_FIXUP_3ST),
1538 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_FIXUP_5ST),
1539 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_FIXUP_5ST),
1540 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_FIXUP_5ST),
1541 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_FIXUP_6ST_DIG),
1542 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_FIXUP_6ST_DIG),
1543 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_FIXUP_6ST_DIG),
1544 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_FIXUP_6ST_DIG),
1545 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_FIXUP_5ST_DIG),
1546 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_FIXUP_5ST_DIG),
1547 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_FIXUP_5ST_DIG),
1548 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_FIXUP_6ST_DIG), /* broken BIOS */
1549 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_FIXUP_6ST_DIG),
1550 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1551 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1552 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1553 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_FIXUP_3ST_DIG),
1554 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1555 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_FIXUP_3ST_DIG),
1556 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_FIXUP_3ST_DIG),
1557 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1558 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1559 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1560 /* default Intel */
1561 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_FIXUP_3ST),
1562 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_FIXUP_5ST_DIG),
1563 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_FIXUP_6ST_DIG),
1564 {}
1565};
1566
1567static const struct hda_model_fixup alc880_fixup_models[] = {
1568 {.id = ALC880_FIXUP_3ST, .name = "3stack"},
1569 {.id = ALC880_FIXUP_3ST_DIG, .name = "3stack-digout"},
1570 {.id = ALC880_FIXUP_5ST, .name = "5stack"},
1571 {.id = ALC880_FIXUP_5ST_DIG, .name = "5stack-digout"},
1572 {.id = ALC880_FIXUP_6ST, .name = "6stack"},
1573 {.id = ALC880_FIXUP_6ST_DIG, .name = "6stack-digout"},
1574 {.id = ALC880_FIXUP_6ST_AUTOMUTE, .name = "6stack-automute"},
1575 {}
1576};
1577
1578
1579/*
1580 * OK, here we have finally the patch for ALC880
1581 */
1582static int patch_alc880(struct hda_codec *codec)
1583{
1584 struct alc_spec *spec;
1585 int err;
1586
1587 err = alc_alloc_spec(codec, 0x0b);
1588 if (err < 0)
1589 return err;
1590
1591 spec = codec->spec;
1592 spec->gen.need_dac_fix = 1;
1593 spec->gen.beep_nid = 0x01;
1594
1595 codec->patch_ops.unsol_event = alc880_unsol_event;
1596
David Brazdil0f672f62019-12-10 10:32:29 +00001597 alc_pre_init(codec);
1598
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001599 snd_hda_pick_fixup(codec, alc880_fixup_models, alc880_fixup_tbl,
1600 alc880_fixups);
1601 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
1602
1603 /* automatic parse from the BIOS config */
1604 err = alc880_parse_auto_config(codec);
1605 if (err < 0)
1606 goto error;
1607
1608 if (!spec->gen.no_analog) {
1609 err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
1610 if (err < 0)
1611 goto error;
1612 }
1613
1614 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
1615
1616 return 0;
1617
1618 error:
1619 alc_free(codec);
1620 return err;
1621}
1622
1623
1624/*
1625 * ALC260 support
1626 */
1627static int alc260_parse_auto_config(struct hda_codec *codec)
1628{
1629 static const hda_nid_t alc260_ignore[] = { 0x17, 0 };
1630 static const hda_nid_t alc260_ssids[] = { 0x10, 0x15, 0x0f, 0 };
1631 return alc_parse_auto_config(codec, alc260_ignore, alc260_ssids);
1632}
1633
1634/*
1635 * Pin config fixes
1636 */
1637enum {
1638 ALC260_FIXUP_HP_DC5750,
1639 ALC260_FIXUP_HP_PIN_0F,
1640 ALC260_FIXUP_COEF,
1641 ALC260_FIXUP_GPIO1,
1642 ALC260_FIXUP_GPIO1_TOGGLE,
1643 ALC260_FIXUP_REPLACER,
1644 ALC260_FIXUP_HP_B1900,
1645 ALC260_FIXUP_KN1,
1646 ALC260_FIXUP_FSC_S7020,
1647 ALC260_FIXUP_FSC_S7020_JWSE,
1648 ALC260_FIXUP_VAIO_PINS,
1649};
1650
1651static void alc260_gpio1_automute(struct hda_codec *codec)
1652{
1653 struct alc_spec *spec = codec->spec;
1654
1655 alc_update_gpio_data(codec, 0x01, spec->gen.hp_jack_present);
1656}
1657
1658static void alc260_fixup_gpio1_toggle(struct hda_codec *codec,
1659 const struct hda_fixup *fix, int action)
1660{
1661 struct alc_spec *spec = codec->spec;
1662 if (action == HDA_FIXUP_ACT_PROBE) {
1663 /* although the machine has only one output pin, we need to
1664 * toggle GPIO1 according to the jack state
1665 */
1666 spec->gen.automute_hook = alc260_gpio1_automute;
1667 spec->gen.detect_hp = 1;
1668 spec->gen.automute_speaker = 1;
1669 spec->gen.autocfg.hp_pins[0] = 0x0f; /* copy it for automute */
1670 snd_hda_jack_detect_enable_callback(codec, 0x0f,
1671 snd_hda_gen_hp_automute);
1672 alc_setup_gpio(codec, 0x01);
1673 }
1674}
1675
1676static void alc260_fixup_kn1(struct hda_codec *codec,
1677 const struct hda_fixup *fix, int action)
1678{
1679 struct alc_spec *spec = codec->spec;
1680 static const struct hda_pintbl pincfgs[] = {
1681 { 0x0f, 0x02214000 }, /* HP/speaker */
1682 { 0x12, 0x90a60160 }, /* int mic */
1683 { 0x13, 0x02a19000 }, /* ext mic */
1684 { 0x18, 0x01446000 }, /* SPDIF out */
1685 /* disable bogus I/O pins */
1686 { 0x10, 0x411111f0 },
1687 { 0x11, 0x411111f0 },
1688 { 0x14, 0x411111f0 },
1689 { 0x15, 0x411111f0 },
1690 { 0x16, 0x411111f0 },
1691 { 0x17, 0x411111f0 },
1692 { 0x19, 0x411111f0 },
1693 { }
1694 };
1695
1696 switch (action) {
1697 case HDA_FIXUP_ACT_PRE_PROBE:
1698 snd_hda_apply_pincfgs(codec, pincfgs);
1699 spec->init_amp = ALC_INIT_NONE;
1700 break;
1701 }
1702}
1703
1704static void alc260_fixup_fsc_s7020(struct hda_codec *codec,
1705 const struct hda_fixup *fix, int action)
1706{
1707 struct alc_spec *spec = codec->spec;
1708 if (action == HDA_FIXUP_ACT_PRE_PROBE)
1709 spec->init_amp = ALC_INIT_NONE;
1710}
1711
1712static void alc260_fixup_fsc_s7020_jwse(struct hda_codec *codec,
1713 const struct hda_fixup *fix, int action)
1714{
1715 struct alc_spec *spec = codec->spec;
1716 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
1717 spec->gen.add_jack_modes = 1;
1718 spec->gen.hp_mic = 1;
1719 }
1720}
1721
1722static const struct hda_fixup alc260_fixups[] = {
1723 [ALC260_FIXUP_HP_DC5750] = {
1724 .type = HDA_FIXUP_PINS,
1725 .v.pins = (const struct hda_pintbl[]) {
1726 { 0x11, 0x90130110 }, /* speaker */
1727 { }
1728 }
1729 },
1730 [ALC260_FIXUP_HP_PIN_0F] = {
1731 .type = HDA_FIXUP_PINS,
1732 .v.pins = (const struct hda_pintbl[]) {
1733 { 0x0f, 0x01214000 }, /* HP */
1734 { }
1735 }
1736 },
1737 [ALC260_FIXUP_COEF] = {
1738 .type = HDA_FIXUP_VERBS,
1739 .v.verbs = (const struct hda_verb[]) {
1740 { 0x1a, AC_VERB_SET_COEF_INDEX, 0x07 },
1741 { 0x1a, AC_VERB_SET_PROC_COEF, 0x3040 },
1742 { }
1743 },
1744 },
1745 [ALC260_FIXUP_GPIO1] = {
1746 .type = HDA_FIXUP_FUNC,
1747 .v.func = alc_fixup_gpio1,
1748 },
1749 [ALC260_FIXUP_GPIO1_TOGGLE] = {
1750 .type = HDA_FIXUP_FUNC,
1751 .v.func = alc260_fixup_gpio1_toggle,
1752 .chained = true,
1753 .chain_id = ALC260_FIXUP_HP_PIN_0F,
1754 },
1755 [ALC260_FIXUP_REPLACER] = {
1756 .type = HDA_FIXUP_VERBS,
1757 .v.verbs = (const struct hda_verb[]) {
1758 { 0x1a, AC_VERB_SET_COEF_INDEX, 0x07 },
1759 { 0x1a, AC_VERB_SET_PROC_COEF, 0x3050 },
1760 { }
1761 },
1762 .chained = true,
1763 .chain_id = ALC260_FIXUP_GPIO1_TOGGLE,
1764 },
1765 [ALC260_FIXUP_HP_B1900] = {
1766 .type = HDA_FIXUP_FUNC,
1767 .v.func = alc260_fixup_gpio1_toggle,
1768 .chained = true,
1769 .chain_id = ALC260_FIXUP_COEF,
1770 },
1771 [ALC260_FIXUP_KN1] = {
1772 .type = HDA_FIXUP_FUNC,
1773 .v.func = alc260_fixup_kn1,
1774 },
1775 [ALC260_FIXUP_FSC_S7020] = {
1776 .type = HDA_FIXUP_FUNC,
1777 .v.func = alc260_fixup_fsc_s7020,
1778 },
1779 [ALC260_FIXUP_FSC_S7020_JWSE] = {
1780 .type = HDA_FIXUP_FUNC,
1781 .v.func = alc260_fixup_fsc_s7020_jwse,
1782 .chained = true,
1783 .chain_id = ALC260_FIXUP_FSC_S7020,
1784 },
1785 [ALC260_FIXUP_VAIO_PINS] = {
1786 .type = HDA_FIXUP_PINS,
1787 .v.pins = (const struct hda_pintbl[]) {
1788 /* Pin configs are missing completely on some VAIOs */
1789 { 0x0f, 0x01211020 },
1790 { 0x10, 0x0001003f },
1791 { 0x11, 0x411111f0 },
1792 { 0x12, 0x01a15930 },
1793 { 0x13, 0x411111f0 },
1794 { 0x14, 0x411111f0 },
1795 { 0x15, 0x411111f0 },
1796 { 0x16, 0x411111f0 },
1797 { 0x17, 0x411111f0 },
1798 { 0x18, 0x411111f0 },
1799 { 0x19, 0x411111f0 },
1800 { }
1801 }
1802 },
1803};
1804
1805static const struct snd_pci_quirk alc260_fixup_tbl[] = {
1806 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_FIXUP_GPIO1),
1807 SND_PCI_QUIRK(0x1025, 0x007f, "Acer Aspire 9500", ALC260_FIXUP_COEF),
1808 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_FIXUP_GPIO1),
1809 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", ALC260_FIXUP_HP_DC5750),
1810 SND_PCI_QUIRK(0x103c, 0x30ba, "HP Presario B1900", ALC260_FIXUP_HP_B1900),
1811 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_FIXUP_VAIO_PINS),
1812 SND_PCI_QUIRK(0x104d, 0x81e2, "Sony VAIO TX", ALC260_FIXUP_HP_PIN_0F),
1813 SND_PCI_QUIRK(0x10cf, 0x1326, "FSC LifeBook S7020", ALC260_FIXUP_FSC_S7020),
1814 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FIXUP_GPIO1),
1815 SND_PCI_QUIRK(0x152d, 0x0729, "Quanta KN1", ALC260_FIXUP_KN1),
1816 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_FIXUP_REPLACER),
1817 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_FIXUP_COEF),
1818 {}
1819};
1820
1821static const struct hda_model_fixup alc260_fixup_models[] = {
1822 {.id = ALC260_FIXUP_GPIO1, .name = "gpio1"},
1823 {.id = ALC260_FIXUP_COEF, .name = "coef"},
1824 {.id = ALC260_FIXUP_FSC_S7020, .name = "fujitsu"},
1825 {.id = ALC260_FIXUP_FSC_S7020_JWSE, .name = "fujitsu-jwse"},
1826 {}
1827};
1828
1829/*
1830 */
1831static int patch_alc260(struct hda_codec *codec)
1832{
1833 struct alc_spec *spec;
1834 int err;
1835
1836 err = alc_alloc_spec(codec, 0x07);
1837 if (err < 0)
1838 return err;
1839
1840 spec = codec->spec;
1841 /* as quite a few machines require HP amp for speaker outputs,
1842 * it's easier to enable it unconditionally; even if it's unneeded,
1843 * it's almost harmless.
1844 */
1845 spec->gen.prefer_hp_amp = 1;
1846 spec->gen.beep_nid = 0x01;
1847
1848 spec->shutup = alc_eapd_shutup;
1849
David Brazdil0f672f62019-12-10 10:32:29 +00001850 alc_pre_init(codec);
1851
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001852 snd_hda_pick_fixup(codec, alc260_fixup_models, alc260_fixup_tbl,
1853 alc260_fixups);
1854 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
1855
1856 /* automatic parse from the BIOS config */
1857 err = alc260_parse_auto_config(codec);
1858 if (err < 0)
1859 goto error;
1860
1861 if (!spec->gen.no_analog) {
1862 err = set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
1863 if (err < 0)
1864 goto error;
1865 }
1866
1867 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
1868
1869 return 0;
1870
1871 error:
1872 alc_free(codec);
1873 return err;
1874}
1875
1876
1877/*
1878 * ALC882/883/885/888/889 support
1879 *
1880 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
1881 * configuration. Each pin widget can choose any input DACs and a mixer.
1882 * Each ADC is connected from a mixer of all inputs. This makes possible
1883 * 6-channel independent captures.
1884 *
1885 * In addition, an independent DAC for the multi-playback (not used in this
1886 * driver yet).
1887 */
1888
1889/*
1890 * Pin config fixes
1891 */
1892enum {
1893 ALC882_FIXUP_ABIT_AW9D_MAX,
1894 ALC882_FIXUP_LENOVO_Y530,
1895 ALC882_FIXUP_PB_M5210,
1896 ALC882_FIXUP_ACER_ASPIRE_7736,
1897 ALC882_FIXUP_ASUS_W90V,
1898 ALC889_FIXUP_CD,
1899 ALC889_FIXUP_FRONT_HP_NO_PRESENCE,
1900 ALC889_FIXUP_VAIO_TT,
1901 ALC888_FIXUP_EEE1601,
Olivier Deprez0e641232021-09-23 10:07:05 +02001902 ALC886_FIXUP_EAPD,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001903 ALC882_FIXUP_EAPD,
1904 ALC883_FIXUP_EAPD,
1905 ALC883_FIXUP_ACER_EAPD,
1906 ALC882_FIXUP_GPIO1,
1907 ALC882_FIXUP_GPIO2,
1908 ALC882_FIXUP_GPIO3,
1909 ALC889_FIXUP_COEF,
1910 ALC882_FIXUP_ASUS_W2JC,
1911 ALC882_FIXUP_ACER_ASPIRE_4930G,
1912 ALC882_FIXUP_ACER_ASPIRE_8930G,
1913 ALC882_FIXUP_ASPIRE_8930G_VERBS,
1914 ALC885_FIXUP_MACPRO_GPIO,
1915 ALC889_FIXUP_DAC_ROUTE,
1916 ALC889_FIXUP_MBP_VREF,
1917 ALC889_FIXUP_IMAC91_VREF,
1918 ALC889_FIXUP_MBA11_VREF,
1919 ALC889_FIXUP_MBA21_VREF,
1920 ALC889_FIXUP_MP11_VREF,
1921 ALC889_FIXUP_MP41_VREF,
1922 ALC882_FIXUP_INV_DMIC,
1923 ALC882_FIXUP_NO_PRIMARY_HP,
1924 ALC887_FIXUP_ASUS_BASS,
1925 ALC887_FIXUP_BASS_CHMAP,
1926 ALC1220_FIXUP_GB_DUAL_CODECS,
1927 ALC1220_FIXUP_CLEVO_P950,
David Brazdil0f672f62019-12-10 10:32:29 +00001928 ALC1220_FIXUP_CLEVO_PB51ED,
1929 ALC1220_FIXUP_CLEVO_PB51ED_PINS,
Olivier Deprez0e641232021-09-23 10:07:05 +02001930 ALC887_FIXUP_ASUS_AUDIO,
1931 ALC887_FIXUP_ASUS_HMIC,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001932};
1933
1934static void alc889_fixup_coef(struct hda_codec *codec,
1935 const struct hda_fixup *fix, int action)
1936{
1937 if (action != HDA_FIXUP_ACT_INIT)
1938 return;
1939 alc_update_coef_idx(codec, 7, 0, 0x2030);
1940}
1941
1942/* set up GPIO at initialization */
1943static void alc885_fixup_macpro_gpio(struct hda_codec *codec,
1944 const struct hda_fixup *fix, int action)
1945{
1946 struct alc_spec *spec = codec->spec;
1947
1948 spec->gpio_write_delay = true;
1949 alc_fixup_gpio3(codec, fix, action);
1950}
1951
1952/* Fix the connection of some pins for ALC889:
1953 * At least, Acer Aspire 5935 shows the connections to DAC3/4 don't
1954 * work correctly (bko#42740)
1955 */
1956static void alc889_fixup_dac_route(struct hda_codec *codec,
1957 const struct hda_fixup *fix, int action)
1958{
1959 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
1960 /* fake the connections during parsing the tree */
Olivier Deprez0e641232021-09-23 10:07:05 +02001961 static const hda_nid_t conn1[] = { 0x0c, 0x0d };
1962 static const hda_nid_t conn2[] = { 0x0e, 0x0f };
1963 snd_hda_override_conn_list(codec, 0x14, ARRAY_SIZE(conn1), conn1);
1964 snd_hda_override_conn_list(codec, 0x15, ARRAY_SIZE(conn1), conn1);
1965 snd_hda_override_conn_list(codec, 0x18, ARRAY_SIZE(conn2), conn2);
1966 snd_hda_override_conn_list(codec, 0x1a, ARRAY_SIZE(conn2), conn2);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001967 } else if (action == HDA_FIXUP_ACT_PROBE) {
1968 /* restore the connections */
Olivier Deprez0e641232021-09-23 10:07:05 +02001969 static const hda_nid_t conn[] = { 0x0c, 0x0d, 0x0e, 0x0f, 0x26 };
1970 snd_hda_override_conn_list(codec, 0x14, ARRAY_SIZE(conn), conn);
1971 snd_hda_override_conn_list(codec, 0x15, ARRAY_SIZE(conn), conn);
1972 snd_hda_override_conn_list(codec, 0x18, ARRAY_SIZE(conn), conn);
1973 snd_hda_override_conn_list(codec, 0x1a, ARRAY_SIZE(conn), conn);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001974 }
1975}
1976
1977/* Set VREF on HP pin */
1978static void alc889_fixup_mbp_vref(struct hda_codec *codec,
1979 const struct hda_fixup *fix, int action)
1980{
Olivier Deprez0e641232021-09-23 10:07:05 +02001981 static const hda_nid_t nids[] = { 0x14, 0x15, 0x19 };
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001982 struct alc_spec *spec = codec->spec;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001983 int i;
1984
1985 if (action != HDA_FIXUP_ACT_INIT)
1986 return;
1987 for (i = 0; i < ARRAY_SIZE(nids); i++) {
1988 unsigned int val = snd_hda_codec_get_pincfg(codec, nids[i]);
1989 if (get_defcfg_device(val) != AC_JACK_HP_OUT)
1990 continue;
1991 val = snd_hda_codec_get_pin_target(codec, nids[i]);
1992 val |= AC_PINCTL_VREF_80;
1993 snd_hda_set_pin_ctl(codec, nids[i], val);
1994 spec->gen.keep_vref_in_automute = 1;
1995 break;
1996 }
1997}
1998
1999static void alc889_fixup_mac_pins(struct hda_codec *codec,
2000 const hda_nid_t *nids, int num_nids)
2001{
2002 struct alc_spec *spec = codec->spec;
2003 int i;
2004
2005 for (i = 0; i < num_nids; i++) {
2006 unsigned int val;
2007 val = snd_hda_codec_get_pin_target(codec, nids[i]);
2008 val |= AC_PINCTL_VREF_50;
2009 snd_hda_set_pin_ctl(codec, nids[i], val);
2010 }
2011 spec->gen.keep_vref_in_automute = 1;
2012}
2013
2014/* Set VREF on speaker pins on imac91 */
2015static void alc889_fixup_imac91_vref(struct hda_codec *codec,
2016 const struct hda_fixup *fix, int action)
2017{
Olivier Deprez0e641232021-09-23 10:07:05 +02002018 static const hda_nid_t nids[] = { 0x18, 0x1a };
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002019
2020 if (action == HDA_FIXUP_ACT_INIT)
2021 alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
2022}
2023
2024/* Set VREF on speaker pins on mba11 */
2025static void alc889_fixup_mba11_vref(struct hda_codec *codec,
2026 const struct hda_fixup *fix, int action)
2027{
Olivier Deprez0e641232021-09-23 10:07:05 +02002028 static const hda_nid_t nids[] = { 0x18 };
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002029
2030 if (action == HDA_FIXUP_ACT_INIT)
2031 alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
2032}
2033
2034/* Set VREF on speaker pins on mba21 */
2035static void alc889_fixup_mba21_vref(struct hda_codec *codec,
2036 const struct hda_fixup *fix, int action)
2037{
Olivier Deprez0e641232021-09-23 10:07:05 +02002038 static const hda_nid_t nids[] = { 0x18, 0x19 };
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002039
2040 if (action == HDA_FIXUP_ACT_INIT)
2041 alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
2042}
2043
2044/* Don't take HP output as primary
2045 * Strangely, the speaker output doesn't work on Vaio Z and some Vaio
2046 * all-in-one desktop PCs (for example VGC-LN51JGB) through DAC 0x05
2047 */
2048static void alc882_fixup_no_primary_hp(struct hda_codec *codec,
2049 const struct hda_fixup *fix, int action)
2050{
2051 struct alc_spec *spec = codec->spec;
2052 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
2053 spec->gen.no_primary_hp = 1;
2054 spec->gen.no_multi_io = 1;
2055 }
2056}
2057
2058static void alc_fixup_bass_chmap(struct hda_codec *codec,
2059 const struct hda_fixup *fix, int action);
2060
2061/* For dual-codec configuration, we need to disable some features to avoid
2062 * conflicts of kctls and PCM streams
2063 */
2064static void alc_fixup_dual_codecs(struct hda_codec *codec,
2065 const struct hda_fixup *fix, int action)
2066{
2067 struct alc_spec *spec = codec->spec;
2068
2069 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2070 return;
2071 /* disable vmaster */
2072 spec->gen.suppress_vmaster = 1;
2073 /* auto-mute and auto-mic switch don't work with multiple codecs */
2074 spec->gen.suppress_auto_mute = 1;
2075 spec->gen.suppress_auto_mic = 1;
2076 /* disable aamix as well */
2077 spec->gen.mixer_nid = 0;
2078 /* add location prefix to avoid conflicts */
2079 codec->force_pin_prefix = 1;
2080}
2081
2082static void rename_ctl(struct hda_codec *codec, const char *oldname,
2083 const char *newname)
2084{
2085 struct snd_kcontrol *kctl;
2086
2087 kctl = snd_hda_find_mixer_ctl(codec, oldname);
2088 if (kctl)
2089 strcpy(kctl->id.name, newname);
2090}
2091
2092static void alc1220_fixup_gb_dual_codecs(struct hda_codec *codec,
2093 const struct hda_fixup *fix,
2094 int action)
2095{
2096 alc_fixup_dual_codecs(codec, fix, action);
2097 switch (action) {
2098 case HDA_FIXUP_ACT_PRE_PROBE:
2099 /* override card longname to provide a unique UCM profile */
2100 strcpy(codec->card->longname, "HDAudio-Gigabyte-ALC1220DualCodecs");
2101 break;
2102 case HDA_FIXUP_ACT_BUILD:
2103 /* rename Capture controls depending on the codec */
2104 rename_ctl(codec, "Capture Volume",
2105 codec->addr == 0 ?
2106 "Rear-Panel Capture Volume" :
2107 "Front-Panel Capture Volume");
2108 rename_ctl(codec, "Capture Switch",
2109 codec->addr == 0 ?
2110 "Rear-Panel Capture Switch" :
2111 "Front-Panel Capture Switch");
2112 break;
2113 }
2114}
2115
2116static void alc1220_fixup_clevo_p950(struct hda_codec *codec,
2117 const struct hda_fixup *fix,
2118 int action)
2119{
Olivier Deprez0e641232021-09-23 10:07:05 +02002120 static const hda_nid_t conn1[] = { 0x0c };
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002121
2122 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2123 return;
2124
2125 alc_update_coef_idx(codec, 0x7, 0, 0x3c3);
2126 /* We therefore want to make sure 0x14 (front headphone) and
2127 * 0x1b (speakers) use the stereo DAC 0x02
2128 */
Olivier Deprez0e641232021-09-23 10:07:05 +02002129 snd_hda_override_conn_list(codec, 0x14, ARRAY_SIZE(conn1), conn1);
2130 snd_hda_override_conn_list(codec, 0x1b, ARRAY_SIZE(conn1), conn1);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002131}
2132
David Brazdil0f672f62019-12-10 10:32:29 +00002133static void alc_fixup_headset_mode_no_hp_mic(struct hda_codec *codec,
2134 const struct hda_fixup *fix, int action);
2135
2136static void alc1220_fixup_clevo_pb51ed(struct hda_codec *codec,
2137 const struct hda_fixup *fix,
2138 int action)
2139{
2140 alc1220_fixup_clevo_p950(codec, fix, action);
2141 alc_fixup_headset_mode_no_hp_mic(codec, fix, action);
2142}
2143
Olivier Deprez0e641232021-09-23 10:07:05 +02002144static void alc887_asus_hp_automute_hook(struct hda_codec *codec,
2145 struct hda_jack_callback *jack)
2146{
2147 struct alc_spec *spec = codec->spec;
2148 unsigned int vref;
2149
2150 snd_hda_gen_hp_automute(codec, jack);
2151
2152 if (spec->gen.hp_jack_present)
2153 vref = AC_PINCTL_VREF_80;
2154 else
2155 vref = AC_PINCTL_VREF_HIZ;
2156 snd_hda_set_pin_ctl(codec, 0x19, PIN_HP | vref);
2157}
2158
2159static void alc887_fixup_asus_jack(struct hda_codec *codec,
2160 const struct hda_fixup *fix, int action)
2161{
2162 struct alc_spec *spec = codec->spec;
2163 if (action != HDA_FIXUP_ACT_PROBE)
2164 return;
2165 snd_hda_set_pin_ctl_cache(codec, 0x1b, PIN_HP);
2166 spec->gen.hp_automute_hook = alc887_asus_hp_automute_hook;
2167}
2168
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002169static const struct hda_fixup alc882_fixups[] = {
2170 [ALC882_FIXUP_ABIT_AW9D_MAX] = {
2171 .type = HDA_FIXUP_PINS,
2172 .v.pins = (const struct hda_pintbl[]) {
2173 { 0x15, 0x01080104 }, /* side */
2174 { 0x16, 0x01011012 }, /* rear */
2175 { 0x17, 0x01016011 }, /* clfe */
2176 { }
2177 }
2178 },
2179 [ALC882_FIXUP_LENOVO_Y530] = {
2180 .type = HDA_FIXUP_PINS,
2181 .v.pins = (const struct hda_pintbl[]) {
2182 { 0x15, 0x99130112 }, /* rear int speakers */
2183 { 0x16, 0x99130111 }, /* subwoofer */
2184 { }
2185 }
2186 },
2187 [ALC882_FIXUP_PB_M5210] = {
2188 .type = HDA_FIXUP_PINCTLS,
2189 .v.pins = (const struct hda_pintbl[]) {
2190 { 0x19, PIN_VREF50 },
2191 {}
2192 }
2193 },
2194 [ALC882_FIXUP_ACER_ASPIRE_7736] = {
2195 .type = HDA_FIXUP_FUNC,
2196 .v.func = alc_fixup_sku_ignore,
2197 },
2198 [ALC882_FIXUP_ASUS_W90V] = {
2199 .type = HDA_FIXUP_PINS,
2200 .v.pins = (const struct hda_pintbl[]) {
2201 { 0x16, 0x99130110 }, /* fix sequence for CLFE */
2202 { }
2203 }
2204 },
2205 [ALC889_FIXUP_CD] = {
2206 .type = HDA_FIXUP_PINS,
2207 .v.pins = (const struct hda_pintbl[]) {
2208 { 0x1c, 0x993301f0 }, /* CD */
2209 { }
2210 }
2211 },
2212 [ALC889_FIXUP_FRONT_HP_NO_PRESENCE] = {
2213 .type = HDA_FIXUP_PINS,
2214 .v.pins = (const struct hda_pintbl[]) {
2215 { 0x1b, 0x02214120 }, /* Front HP jack is flaky, disable jack detect */
2216 { }
2217 },
2218 .chained = true,
2219 .chain_id = ALC889_FIXUP_CD,
2220 },
2221 [ALC889_FIXUP_VAIO_TT] = {
2222 .type = HDA_FIXUP_PINS,
2223 .v.pins = (const struct hda_pintbl[]) {
2224 { 0x17, 0x90170111 }, /* hidden surround speaker */
2225 { }
2226 }
2227 },
2228 [ALC888_FIXUP_EEE1601] = {
2229 .type = HDA_FIXUP_VERBS,
2230 .v.verbs = (const struct hda_verb[]) {
2231 { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b },
2232 { 0x20, AC_VERB_SET_PROC_COEF, 0x0838 },
2233 { }
2234 }
2235 },
Olivier Deprez0e641232021-09-23 10:07:05 +02002236 [ALC886_FIXUP_EAPD] = {
2237 .type = HDA_FIXUP_VERBS,
2238 .v.verbs = (const struct hda_verb[]) {
2239 /* change to EAPD mode */
2240 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2241 { 0x20, AC_VERB_SET_PROC_COEF, 0x0068 },
2242 { }
2243 }
2244 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002245 [ALC882_FIXUP_EAPD] = {
2246 .type = HDA_FIXUP_VERBS,
2247 .v.verbs = (const struct hda_verb[]) {
2248 /* change to EAPD mode */
2249 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2250 { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
2251 { }
2252 }
2253 },
2254 [ALC883_FIXUP_EAPD] = {
2255 .type = HDA_FIXUP_VERBS,
2256 .v.verbs = (const struct hda_verb[]) {
2257 /* change to EAPD mode */
2258 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2259 { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
2260 { }
2261 }
2262 },
2263 [ALC883_FIXUP_ACER_EAPD] = {
2264 .type = HDA_FIXUP_VERBS,
2265 .v.verbs = (const struct hda_verb[]) {
2266 /* eanable EAPD on Acer laptops */
2267 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2268 { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
2269 { }
2270 }
2271 },
2272 [ALC882_FIXUP_GPIO1] = {
2273 .type = HDA_FIXUP_FUNC,
2274 .v.func = alc_fixup_gpio1,
2275 },
2276 [ALC882_FIXUP_GPIO2] = {
2277 .type = HDA_FIXUP_FUNC,
2278 .v.func = alc_fixup_gpio2,
2279 },
2280 [ALC882_FIXUP_GPIO3] = {
2281 .type = HDA_FIXUP_FUNC,
2282 .v.func = alc_fixup_gpio3,
2283 },
2284 [ALC882_FIXUP_ASUS_W2JC] = {
2285 .type = HDA_FIXUP_FUNC,
2286 .v.func = alc_fixup_gpio1,
2287 .chained = true,
2288 .chain_id = ALC882_FIXUP_EAPD,
2289 },
2290 [ALC889_FIXUP_COEF] = {
2291 .type = HDA_FIXUP_FUNC,
2292 .v.func = alc889_fixup_coef,
2293 },
2294 [ALC882_FIXUP_ACER_ASPIRE_4930G] = {
2295 .type = HDA_FIXUP_PINS,
2296 .v.pins = (const struct hda_pintbl[]) {
2297 { 0x16, 0x99130111 }, /* CLFE speaker */
2298 { 0x17, 0x99130112 }, /* surround speaker */
2299 { }
2300 },
2301 .chained = true,
2302 .chain_id = ALC882_FIXUP_GPIO1,
2303 },
2304 [ALC882_FIXUP_ACER_ASPIRE_8930G] = {
2305 .type = HDA_FIXUP_PINS,
2306 .v.pins = (const struct hda_pintbl[]) {
2307 { 0x16, 0x99130111 }, /* CLFE speaker */
2308 { 0x1b, 0x99130112 }, /* surround speaker */
2309 { }
2310 },
2311 .chained = true,
2312 .chain_id = ALC882_FIXUP_ASPIRE_8930G_VERBS,
2313 },
2314 [ALC882_FIXUP_ASPIRE_8930G_VERBS] = {
2315 /* additional init verbs for Acer Aspire 8930G */
2316 .type = HDA_FIXUP_VERBS,
2317 .v.verbs = (const struct hda_verb[]) {
2318 /* Enable all DACs */
2319 /* DAC DISABLE/MUTE 1? */
2320 /* setting bits 1-5 disables DAC nids 0x02-0x06
2321 * apparently. Init=0x38 */
2322 { 0x20, AC_VERB_SET_COEF_INDEX, 0x03 },
2323 { 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
2324 /* DAC DISABLE/MUTE 2? */
2325 /* some bit here disables the other DACs.
2326 * Init=0x4900 */
2327 { 0x20, AC_VERB_SET_COEF_INDEX, 0x08 },
2328 { 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
2329 /* DMIC fix
2330 * This laptop has a stereo digital microphone.
2331 * The mics are only 1cm apart which makes the stereo
2332 * useless. However, either the mic or the ALC889
2333 * makes the signal become a difference/sum signal
2334 * instead of standard stereo, which is annoying.
2335 * So instead we flip this bit which makes the
2336 * codec replicate the sum signal to both channels,
2337 * turning it into a normal mono mic.
2338 */
2339 /* DMIC_CONTROL? Init value = 0x0001 */
2340 { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b },
2341 { 0x20, AC_VERB_SET_PROC_COEF, 0x0003 },
2342 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2343 { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
2344 { }
2345 },
2346 .chained = true,
2347 .chain_id = ALC882_FIXUP_GPIO1,
2348 },
2349 [ALC885_FIXUP_MACPRO_GPIO] = {
2350 .type = HDA_FIXUP_FUNC,
2351 .v.func = alc885_fixup_macpro_gpio,
2352 },
2353 [ALC889_FIXUP_DAC_ROUTE] = {
2354 .type = HDA_FIXUP_FUNC,
2355 .v.func = alc889_fixup_dac_route,
2356 },
2357 [ALC889_FIXUP_MBP_VREF] = {
2358 .type = HDA_FIXUP_FUNC,
2359 .v.func = alc889_fixup_mbp_vref,
2360 .chained = true,
2361 .chain_id = ALC882_FIXUP_GPIO1,
2362 },
2363 [ALC889_FIXUP_IMAC91_VREF] = {
2364 .type = HDA_FIXUP_FUNC,
2365 .v.func = alc889_fixup_imac91_vref,
2366 .chained = true,
2367 .chain_id = ALC882_FIXUP_GPIO1,
2368 },
2369 [ALC889_FIXUP_MBA11_VREF] = {
2370 .type = HDA_FIXUP_FUNC,
2371 .v.func = alc889_fixup_mba11_vref,
2372 .chained = true,
2373 .chain_id = ALC889_FIXUP_MBP_VREF,
2374 },
2375 [ALC889_FIXUP_MBA21_VREF] = {
2376 .type = HDA_FIXUP_FUNC,
2377 .v.func = alc889_fixup_mba21_vref,
2378 .chained = true,
2379 .chain_id = ALC889_FIXUP_MBP_VREF,
2380 },
2381 [ALC889_FIXUP_MP11_VREF] = {
2382 .type = HDA_FIXUP_FUNC,
2383 .v.func = alc889_fixup_mba11_vref,
2384 .chained = true,
2385 .chain_id = ALC885_FIXUP_MACPRO_GPIO,
2386 },
2387 [ALC889_FIXUP_MP41_VREF] = {
2388 .type = HDA_FIXUP_FUNC,
2389 .v.func = alc889_fixup_mbp_vref,
2390 .chained = true,
2391 .chain_id = ALC885_FIXUP_MACPRO_GPIO,
2392 },
2393 [ALC882_FIXUP_INV_DMIC] = {
2394 .type = HDA_FIXUP_FUNC,
2395 .v.func = alc_fixup_inv_dmic,
2396 },
2397 [ALC882_FIXUP_NO_PRIMARY_HP] = {
2398 .type = HDA_FIXUP_FUNC,
2399 .v.func = alc882_fixup_no_primary_hp,
2400 },
2401 [ALC887_FIXUP_ASUS_BASS] = {
2402 .type = HDA_FIXUP_PINS,
2403 .v.pins = (const struct hda_pintbl[]) {
2404 {0x16, 0x99130130}, /* bass speaker */
2405 {}
2406 },
2407 .chained = true,
2408 .chain_id = ALC887_FIXUP_BASS_CHMAP,
2409 },
2410 [ALC887_FIXUP_BASS_CHMAP] = {
2411 .type = HDA_FIXUP_FUNC,
2412 .v.func = alc_fixup_bass_chmap,
2413 },
2414 [ALC1220_FIXUP_GB_DUAL_CODECS] = {
2415 .type = HDA_FIXUP_FUNC,
2416 .v.func = alc1220_fixup_gb_dual_codecs,
2417 },
2418 [ALC1220_FIXUP_CLEVO_P950] = {
2419 .type = HDA_FIXUP_FUNC,
2420 .v.func = alc1220_fixup_clevo_p950,
2421 },
David Brazdil0f672f62019-12-10 10:32:29 +00002422 [ALC1220_FIXUP_CLEVO_PB51ED] = {
2423 .type = HDA_FIXUP_FUNC,
2424 .v.func = alc1220_fixup_clevo_pb51ed,
2425 },
2426 [ALC1220_FIXUP_CLEVO_PB51ED_PINS] = {
2427 .type = HDA_FIXUP_PINS,
2428 .v.pins = (const struct hda_pintbl[]) {
2429 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
2430 {}
2431 },
2432 .chained = true,
2433 .chain_id = ALC1220_FIXUP_CLEVO_PB51ED,
2434 },
Olivier Deprez0e641232021-09-23 10:07:05 +02002435 [ALC887_FIXUP_ASUS_AUDIO] = {
2436 .type = HDA_FIXUP_PINS,
2437 .v.pins = (const struct hda_pintbl[]) {
2438 { 0x15, 0x02a14150 }, /* use as headset mic, without its own jack detect */
2439 { 0x19, 0x22219420 },
2440 {}
2441 },
2442 },
2443 [ALC887_FIXUP_ASUS_HMIC] = {
2444 .type = HDA_FIXUP_FUNC,
2445 .v.func = alc887_fixup_asus_jack,
2446 .chained = true,
2447 .chain_id = ALC887_FIXUP_ASUS_AUDIO,
2448 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002449};
2450
2451static const struct snd_pci_quirk alc882_fixup_tbl[] = {
2452 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_FIXUP_ACER_EAPD),
2453 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
2454 SND_PCI_QUIRK(0x1025, 0x0107, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
2455 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_FIXUP_ACER_EAPD),
2456 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
2457 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_FIXUP_ACER_EAPD),
2458 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_FIXUP_ACER_EAPD),
2459 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
2460 ALC882_FIXUP_ACER_ASPIRE_4930G),
2461 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
2462 ALC882_FIXUP_ACER_ASPIRE_4930G),
2463 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
2464 ALC882_FIXUP_ACER_ASPIRE_8930G),
2465 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
2466 ALC882_FIXUP_ACER_ASPIRE_8930G),
Olivier Deprez0e641232021-09-23 10:07:05 +02002467 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
2468 ALC882_FIXUP_ACER_ASPIRE_4930G),
2469 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", ALC882_FIXUP_PB_M5210),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002470 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
2471 ALC882_FIXUP_ACER_ASPIRE_4930G),
2472 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
2473 ALC882_FIXUP_ACER_ASPIRE_4930G),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002474 SND_PCI_QUIRK(0x1025, 0x021e, "Acer Aspire 5739G",
2475 ALC882_FIXUP_ACER_ASPIRE_4930G),
2476 SND_PCI_QUIRK(0x1025, 0x0259, "Acer Aspire 5935", ALC889_FIXUP_DAC_ROUTE),
2477 SND_PCI_QUIRK(0x1025, 0x026b, "Acer Aspire 8940G", ALC882_FIXUP_ACER_ASPIRE_8930G),
2478 SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", ALC882_FIXUP_ACER_ASPIRE_7736),
2479 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_FIXUP_EAPD),
2480 SND_PCI_QUIRK(0x1043, 0x1873, "ASUS W90V", ALC882_FIXUP_ASUS_W90V),
2481 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_FIXUP_ASUS_W2JC),
Olivier Deprez0e641232021-09-23 10:07:05 +02002482 SND_PCI_QUIRK(0x1043, 0x2390, "Asus D700SA", ALC887_FIXUP_ASUS_HMIC),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002483 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_FIXUP_EEE1601),
2484 SND_PCI_QUIRK(0x1043, 0x84bc, "ASUS ET2700", ALC887_FIXUP_ASUS_BASS),
2485 SND_PCI_QUIRK(0x1043, 0x8691, "ASUS ROG Ranger VIII", ALC882_FIXUP_GPIO3),
Olivier Deprez0e641232021-09-23 10:07:05 +02002486 SND_PCI_QUIRK(0x104d, 0x9043, "Sony Vaio VGC-LN51JGB", ALC882_FIXUP_NO_PRIMARY_HP),
2487 SND_PCI_QUIRK(0x104d, 0x9044, "Sony VAIO AiO", ALC882_FIXUP_NO_PRIMARY_HP),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002488 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT),
2489 SND_PCI_QUIRK(0x104d, 0x905a, "Sony Vaio Z", ALC882_FIXUP_NO_PRIMARY_HP),
2490 SND_PCI_QUIRK(0x104d, 0x9060, "Sony Vaio VPCL14M1R", ALC882_FIXUP_NO_PRIMARY_HP),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002491
2492 /* All Apple entries are in codec SSIDs */
2493 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC889_FIXUP_MBP_VREF),
2494 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC889_FIXUP_MBP_VREF),
2495 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF),
2496 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC889_FIXUP_MP11_VREF),
2497 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_FIXUP_MACPRO_GPIO),
2498 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_FIXUP_MACPRO_GPIO),
2499 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC889_FIXUP_MBP_VREF),
2500 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889_FIXUP_MBP_VREF),
2501 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_FIXUP_EAPD),
2502 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC889_FIXUP_MBA11_VREF),
2503 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC889_FIXUP_MBA21_VREF),
2504 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889_FIXUP_MBP_VREF),
2505 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF),
2506 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_FIXUP_MACPRO_GPIO),
2507 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC889_FIXUP_IMAC91_VREF),
2508 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC889_FIXUP_IMAC91_VREF),
2509 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC889_FIXUP_IMAC91_VREF),
2510 SND_PCI_QUIRK(0x106b, 0x4200, "Mac Pro 4,1/5,1", ALC889_FIXUP_MP41_VREF),
2511 SND_PCI_QUIRK(0x106b, 0x4300, "iMac 9,1", ALC889_FIXUP_IMAC91_VREF),
2512 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC889_FIXUP_IMAC91_VREF),
2513 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC889_FIXUP_IMAC91_VREF),
2514 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC889_FIXUP_MBA11_VREF),
2515
2516 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC882_FIXUP_EAPD),
Olivier Deprez0e641232021-09-23 10:07:05 +02002517 SND_PCI_QUIRK(0x13fe, 0x1009, "Advantech MIT-W101", ALC886_FIXUP_EAPD),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002518 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3/Z87X-UD3H", ALC889_FIXUP_FRONT_HP_NO_PRESENCE),
2519 SND_PCI_QUIRK(0x1458, 0xa0b8, "Gigabyte AZ370-Gaming", ALC1220_FIXUP_GB_DUAL_CODECS),
Olivier Deprez0e641232021-09-23 10:07:05 +02002520 SND_PCI_QUIRK(0x1458, 0xa0cd, "Gigabyte X570 Aorus Master", ALC1220_FIXUP_CLEVO_P950),
2521 SND_PCI_QUIRK(0x1458, 0xa0ce, "Gigabyte X570 Aorus Xtreme", ALC1220_FIXUP_CLEVO_P950),
2522 SND_PCI_QUIRK(0x1462, 0x11f7, "MSI-GE63", ALC1220_FIXUP_CLEVO_P950),
2523 SND_PCI_QUIRK(0x1462, 0x1228, "MSI-GP63", ALC1220_FIXUP_CLEVO_P950),
2524 SND_PCI_QUIRK(0x1462, 0x1229, "MSI-GP73", ALC1220_FIXUP_CLEVO_P950),
2525 SND_PCI_QUIRK(0x1462, 0x1275, "MSI-GL63", ALC1220_FIXUP_CLEVO_P950),
2526 SND_PCI_QUIRK(0x1462, 0x1276, "MSI-GL73", ALC1220_FIXUP_CLEVO_P950),
2527 SND_PCI_QUIRK(0x1462, 0x1293, "MSI-GP65", ALC1220_FIXUP_CLEVO_P950),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002528 SND_PCI_QUIRK(0x1462, 0x7350, "MSI-7350", ALC889_FIXUP_CD),
Olivier Deprez0e641232021-09-23 10:07:05 +02002529 SND_PCI_QUIRK(0x1462, 0xcc34, "MSI Godlike X570", ALC1220_FIXUP_GB_DUAL_CODECS),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002530 SND_PCI_QUIRK(0x1462, 0xda57, "MSI Z270-Gaming", ALC1220_FIXUP_GB_DUAL_CODECS),
2531 SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3),
2532 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX),
Olivier Deprez0e641232021-09-23 10:07:05 +02002533 SND_PCI_QUIRK(0x1558, 0x50d3, "Clevo PC50[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
2534 SND_PCI_QUIRK(0x1558, 0x65d1, "Clevo PB51[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
2535 SND_PCI_QUIRK(0x1558, 0x65d2, "Clevo PB51R[CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
2536 SND_PCI_QUIRK(0x1558, 0x65e1, "Clevo PB51[ED][DF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
2537 SND_PCI_QUIRK(0x1558, 0x65e5, "Clevo PC50D[PRS](?:-D|-G)?", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
2538 SND_PCI_QUIRK(0x1558, 0x67d1, "Clevo PB71[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
2539 SND_PCI_QUIRK(0x1558, 0x67e1, "Clevo PB71[DE][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
2540 SND_PCI_QUIRK(0x1558, 0x67e5, "Clevo PC70D[PRS](?:-D|-G)?", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
2541 SND_PCI_QUIRK(0x1558, 0x70d1, "Clevo PC70[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
2542 SND_PCI_QUIRK(0x1558, 0x7714, "Clevo X170", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002543 SND_PCI_QUIRK(0x1558, 0x9501, "Clevo P950HR", ALC1220_FIXUP_CLEVO_P950),
Olivier Deprez0e641232021-09-23 10:07:05 +02002544 SND_PCI_QUIRK(0x1558, 0x9506, "Clevo P955HQ", ALC1220_FIXUP_CLEVO_P950),
2545 SND_PCI_QUIRK(0x1558, 0x950a, "Clevo P955H[PR]", ALC1220_FIXUP_CLEVO_P950),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002546 SND_PCI_QUIRK(0x1558, 0x95e1, "Clevo P95xER", ALC1220_FIXUP_CLEVO_P950),
2547 SND_PCI_QUIRK(0x1558, 0x95e2, "Clevo P950ER", ALC1220_FIXUP_CLEVO_P950),
Olivier Deprez0e641232021-09-23 10:07:05 +02002548 SND_PCI_QUIRK(0x1558, 0x95e3, "Clevo P955[ER]T", ALC1220_FIXUP_CLEVO_P950),
2549 SND_PCI_QUIRK(0x1558, 0x95e4, "Clevo P955ER", ALC1220_FIXUP_CLEVO_P950),
2550 SND_PCI_QUIRK(0x1558, 0x95e5, "Clevo P955EE6", ALC1220_FIXUP_CLEVO_P950),
2551 SND_PCI_QUIRK(0x1558, 0x95e6, "Clevo P950R[CDF]", ALC1220_FIXUP_CLEVO_P950),
David Brazdil0f672f62019-12-10 10:32:29 +00002552 SND_PCI_QUIRK(0x1558, 0x96e1, "Clevo P960[ER][CDFN]-K", ALC1220_FIXUP_CLEVO_P950),
2553 SND_PCI_QUIRK(0x1558, 0x97e1, "Clevo P970[ER][CDFN]", ALC1220_FIXUP_CLEVO_P950),
Olivier Deprez0e641232021-09-23 10:07:05 +02002554 SND_PCI_QUIRK(0x1558, 0x97e2, "Clevo P970RC-M", ALC1220_FIXUP_CLEVO_P950),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002555 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD),
2556 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD),
2557 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", ALC882_FIXUP_LENOVO_Y530),
2558 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_FIXUP_COEF),
2559 {}
2560};
2561
2562static const struct hda_model_fixup alc882_fixup_models[] = {
2563 {.id = ALC882_FIXUP_ABIT_AW9D_MAX, .name = "abit-aw9d"},
2564 {.id = ALC882_FIXUP_LENOVO_Y530, .name = "lenovo-y530"},
2565 {.id = ALC882_FIXUP_ACER_ASPIRE_7736, .name = "acer-aspire-7736"},
2566 {.id = ALC882_FIXUP_ASUS_W90V, .name = "asus-w90v"},
2567 {.id = ALC889_FIXUP_CD, .name = "cd"},
2568 {.id = ALC889_FIXUP_FRONT_HP_NO_PRESENCE, .name = "no-front-hp"},
2569 {.id = ALC889_FIXUP_VAIO_TT, .name = "vaio-tt"},
2570 {.id = ALC888_FIXUP_EEE1601, .name = "eee1601"},
2571 {.id = ALC882_FIXUP_EAPD, .name = "alc882-eapd"},
2572 {.id = ALC883_FIXUP_EAPD, .name = "alc883-eapd"},
2573 {.id = ALC882_FIXUP_GPIO1, .name = "gpio1"},
2574 {.id = ALC882_FIXUP_GPIO2, .name = "gpio2"},
2575 {.id = ALC882_FIXUP_GPIO3, .name = "gpio3"},
2576 {.id = ALC889_FIXUP_COEF, .name = "alc889-coef"},
2577 {.id = ALC882_FIXUP_ASUS_W2JC, .name = "asus-w2jc"},
2578 {.id = ALC882_FIXUP_ACER_ASPIRE_4930G, .name = "acer-aspire-4930g"},
2579 {.id = ALC882_FIXUP_ACER_ASPIRE_8930G, .name = "acer-aspire-8930g"},
2580 {.id = ALC883_FIXUP_ACER_EAPD, .name = "acer-aspire"},
2581 {.id = ALC885_FIXUP_MACPRO_GPIO, .name = "macpro-gpio"},
2582 {.id = ALC889_FIXUP_DAC_ROUTE, .name = "dac-route"},
2583 {.id = ALC889_FIXUP_MBP_VREF, .name = "mbp-vref"},
2584 {.id = ALC889_FIXUP_IMAC91_VREF, .name = "imac91-vref"},
2585 {.id = ALC889_FIXUP_MBA11_VREF, .name = "mba11-vref"},
2586 {.id = ALC889_FIXUP_MBA21_VREF, .name = "mba21-vref"},
2587 {.id = ALC889_FIXUP_MP11_VREF, .name = "mp11-vref"},
2588 {.id = ALC889_FIXUP_MP41_VREF, .name = "mp41-vref"},
2589 {.id = ALC882_FIXUP_INV_DMIC, .name = "inv-dmic"},
2590 {.id = ALC882_FIXUP_NO_PRIMARY_HP, .name = "no-primary-hp"},
2591 {.id = ALC887_FIXUP_ASUS_BASS, .name = "asus-bass"},
2592 {.id = ALC1220_FIXUP_GB_DUAL_CODECS, .name = "dual-codecs"},
2593 {.id = ALC1220_FIXUP_CLEVO_P950, .name = "clevo-p950"},
2594 {}
2595};
2596
Olivier Deprez0e641232021-09-23 10:07:05 +02002597static const struct snd_hda_pin_quirk alc882_pin_fixup_tbl[] = {
2598 SND_HDA_PIN_QUIRK(0x10ec1220, 0x1043, "ASUS", ALC1220_FIXUP_CLEVO_P950,
2599 {0x14, 0x01014010},
2600 {0x15, 0x01011012},
2601 {0x16, 0x01016011},
2602 {0x18, 0x01a19040},
2603 {0x19, 0x02a19050},
2604 {0x1a, 0x0181304f},
2605 {0x1b, 0x0221401f},
2606 {0x1e, 0x01456130}),
2607 SND_HDA_PIN_QUIRK(0x10ec1220, 0x1462, "MS-7C35", ALC1220_FIXUP_CLEVO_P950,
2608 {0x14, 0x01015010},
2609 {0x15, 0x01011012},
2610 {0x16, 0x01011011},
2611 {0x18, 0x01a11040},
2612 {0x19, 0x02a19050},
2613 {0x1a, 0x0181104f},
2614 {0x1b, 0x0221401f},
2615 {0x1e, 0x01451130}),
2616 {}
2617};
2618
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002619/*
2620 * BIOS auto configuration
2621 */
2622/* almost identical with ALC880 parser... */
2623static int alc882_parse_auto_config(struct hda_codec *codec)
2624{
2625 static const hda_nid_t alc882_ignore[] = { 0x1d, 0 };
2626 static const hda_nid_t alc882_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2627 return alc_parse_auto_config(codec, alc882_ignore, alc882_ssids);
2628}
2629
2630/*
2631 */
2632static int patch_alc882(struct hda_codec *codec)
2633{
2634 struct alc_spec *spec;
2635 int err;
2636
2637 err = alc_alloc_spec(codec, 0x0b);
2638 if (err < 0)
2639 return err;
2640
2641 spec = codec->spec;
2642
2643 switch (codec->core.vendor_id) {
2644 case 0x10ec0882:
2645 case 0x10ec0885:
2646 case 0x10ec0900:
Olivier Deprez0e641232021-09-23 10:07:05 +02002647 case 0x10ec0b00:
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002648 case 0x10ec1220:
2649 break;
2650 default:
2651 /* ALC883 and variants */
2652 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
2653 break;
2654 }
2655
David Brazdil0f672f62019-12-10 10:32:29 +00002656 alc_pre_init(codec);
2657
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002658 snd_hda_pick_fixup(codec, alc882_fixup_models, alc882_fixup_tbl,
2659 alc882_fixups);
Olivier Deprez0e641232021-09-23 10:07:05 +02002660 snd_hda_pick_pin_fixup(codec, alc882_pin_fixup_tbl, alc882_fixups, true);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002661 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
2662
2663 alc_auto_parse_customize_define(codec);
2664
2665 if (has_cdefine_beep(codec))
2666 spec->gen.beep_nid = 0x01;
2667
2668 /* automatic parse from the BIOS config */
2669 err = alc882_parse_auto_config(codec);
2670 if (err < 0)
2671 goto error;
2672
2673 if (!spec->gen.no_analog && spec->gen.beep_nid) {
2674 err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
2675 if (err < 0)
2676 goto error;
2677 }
2678
2679 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
2680
2681 return 0;
2682
2683 error:
2684 alc_free(codec);
2685 return err;
2686}
2687
2688
2689/*
2690 * ALC262 support
2691 */
2692static int alc262_parse_auto_config(struct hda_codec *codec)
2693{
2694 static const hda_nid_t alc262_ignore[] = { 0x1d, 0 };
2695 static const hda_nid_t alc262_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2696 return alc_parse_auto_config(codec, alc262_ignore, alc262_ssids);
2697}
2698
2699/*
2700 * Pin config fixes
2701 */
2702enum {
2703 ALC262_FIXUP_FSC_H270,
2704 ALC262_FIXUP_FSC_S7110,
2705 ALC262_FIXUP_HP_Z200,
2706 ALC262_FIXUP_TYAN,
2707 ALC262_FIXUP_LENOVO_3000,
2708 ALC262_FIXUP_BENQ,
2709 ALC262_FIXUP_BENQ_T31,
2710 ALC262_FIXUP_INV_DMIC,
2711 ALC262_FIXUP_INTEL_BAYLEYBAY,
2712};
2713
2714static const struct hda_fixup alc262_fixups[] = {
2715 [ALC262_FIXUP_FSC_H270] = {
2716 .type = HDA_FIXUP_PINS,
2717 .v.pins = (const struct hda_pintbl[]) {
2718 { 0x14, 0x99130110 }, /* speaker */
2719 { 0x15, 0x0221142f }, /* front HP */
2720 { 0x1b, 0x0121141f }, /* rear HP */
2721 { }
2722 }
2723 },
2724 [ALC262_FIXUP_FSC_S7110] = {
2725 .type = HDA_FIXUP_PINS,
2726 .v.pins = (const struct hda_pintbl[]) {
2727 { 0x15, 0x90170110 }, /* speaker */
2728 { }
2729 },
2730 .chained = true,
2731 .chain_id = ALC262_FIXUP_BENQ,
2732 },
2733 [ALC262_FIXUP_HP_Z200] = {
2734 .type = HDA_FIXUP_PINS,
2735 .v.pins = (const struct hda_pintbl[]) {
2736 { 0x16, 0x99130120 }, /* internal speaker */
2737 { }
2738 }
2739 },
2740 [ALC262_FIXUP_TYAN] = {
2741 .type = HDA_FIXUP_PINS,
2742 .v.pins = (const struct hda_pintbl[]) {
2743 { 0x14, 0x1993e1f0 }, /* int AUX */
2744 { }
2745 }
2746 },
2747 [ALC262_FIXUP_LENOVO_3000] = {
2748 .type = HDA_FIXUP_PINCTLS,
2749 .v.pins = (const struct hda_pintbl[]) {
2750 { 0x19, PIN_VREF50 },
2751 {}
2752 },
2753 .chained = true,
2754 .chain_id = ALC262_FIXUP_BENQ,
2755 },
2756 [ALC262_FIXUP_BENQ] = {
2757 .type = HDA_FIXUP_VERBS,
2758 .v.verbs = (const struct hda_verb[]) {
2759 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2760 { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
2761 {}
2762 }
2763 },
2764 [ALC262_FIXUP_BENQ_T31] = {
2765 .type = HDA_FIXUP_VERBS,
2766 .v.verbs = (const struct hda_verb[]) {
2767 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2768 { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
2769 {}
2770 }
2771 },
2772 [ALC262_FIXUP_INV_DMIC] = {
2773 .type = HDA_FIXUP_FUNC,
2774 .v.func = alc_fixup_inv_dmic,
2775 },
2776 [ALC262_FIXUP_INTEL_BAYLEYBAY] = {
2777 .type = HDA_FIXUP_FUNC,
2778 .v.func = alc_fixup_no_depop_delay,
2779 },
2780};
2781
2782static const struct snd_pci_quirk alc262_fixup_tbl[] = {
2783 SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", ALC262_FIXUP_HP_Z200),
2784 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu Lifebook S7110", ALC262_FIXUP_FSC_S7110),
2785 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FIXUP_BENQ),
2786 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_FIXUP_TYAN),
2787 SND_PCI_QUIRK(0x1734, 0x1141, "FSC ESPRIMO U9210", ALC262_FIXUP_FSC_H270),
2788 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", ALC262_FIXUP_FSC_H270),
2789 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000", ALC262_FIXUP_LENOVO_3000),
2790 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_FIXUP_BENQ),
2791 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_FIXUP_BENQ_T31),
2792 SND_PCI_QUIRK(0x8086, 0x7270, "BayleyBay", ALC262_FIXUP_INTEL_BAYLEYBAY),
2793 {}
2794};
2795
2796static const struct hda_model_fixup alc262_fixup_models[] = {
2797 {.id = ALC262_FIXUP_INV_DMIC, .name = "inv-dmic"},
2798 {.id = ALC262_FIXUP_FSC_H270, .name = "fsc-h270"},
2799 {.id = ALC262_FIXUP_FSC_S7110, .name = "fsc-s7110"},
2800 {.id = ALC262_FIXUP_HP_Z200, .name = "hp-z200"},
2801 {.id = ALC262_FIXUP_TYAN, .name = "tyan"},
2802 {.id = ALC262_FIXUP_LENOVO_3000, .name = "lenovo-3000"},
2803 {.id = ALC262_FIXUP_BENQ, .name = "benq"},
2804 {.id = ALC262_FIXUP_BENQ_T31, .name = "benq-t31"},
2805 {.id = ALC262_FIXUP_INTEL_BAYLEYBAY, .name = "bayleybay"},
2806 {}
2807};
2808
2809/*
2810 */
2811static int patch_alc262(struct hda_codec *codec)
2812{
2813 struct alc_spec *spec;
2814 int err;
2815
2816 err = alc_alloc_spec(codec, 0x0b);
2817 if (err < 0)
2818 return err;
2819
2820 spec = codec->spec;
2821 spec->gen.shared_mic_vref_pin = 0x18;
2822
2823 spec->shutup = alc_eapd_shutup;
2824
2825#if 0
2826 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
2827 * under-run
2828 */
2829 alc_update_coefex_idx(codec, 0x1a, 7, 0, 0x80);
2830#endif
2831 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
2832
David Brazdil0f672f62019-12-10 10:32:29 +00002833 alc_pre_init(codec);
2834
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002835 snd_hda_pick_fixup(codec, alc262_fixup_models, alc262_fixup_tbl,
2836 alc262_fixups);
2837 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
2838
2839 alc_auto_parse_customize_define(codec);
2840
2841 if (has_cdefine_beep(codec))
2842 spec->gen.beep_nid = 0x01;
2843
2844 /* automatic parse from the BIOS config */
2845 err = alc262_parse_auto_config(codec);
2846 if (err < 0)
2847 goto error;
2848
2849 if (!spec->gen.no_analog && spec->gen.beep_nid) {
2850 err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
2851 if (err < 0)
2852 goto error;
2853 }
2854
2855 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
2856
2857 return 0;
2858
2859 error:
2860 alc_free(codec);
2861 return err;
2862}
2863
2864/*
2865 * ALC268
2866 */
2867/* bind Beep switches of both NID 0x0f and 0x10 */
2868static int alc268_beep_switch_put(struct snd_kcontrol *kcontrol,
2869 struct snd_ctl_elem_value *ucontrol)
2870{
2871 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2872 unsigned long pval;
2873 int err;
2874
2875 mutex_lock(&codec->control_mutex);
2876 pval = kcontrol->private_value;
2877 kcontrol->private_value = (pval & ~0xff) | 0x0f;
2878 err = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
2879 if (err >= 0) {
2880 kcontrol->private_value = (pval & ~0xff) | 0x10;
2881 err = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
2882 }
2883 kcontrol->private_value = pval;
2884 mutex_unlock(&codec->control_mutex);
2885 return err;
2886}
2887
2888static const struct snd_kcontrol_new alc268_beep_mixer[] = {
2889 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
2890 {
2891 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2892 .name = "Beep Playback Switch",
2893 .subdevice = HDA_SUBDEV_AMP_FLAG,
2894 .info = snd_hda_mixer_amp_switch_info,
2895 .get = snd_hda_mixer_amp_switch_get,
2896 .put = alc268_beep_switch_put,
2897 .private_value = HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT)
2898 },
2899};
2900
2901/* set PCBEEP vol = 0, mute connections */
2902static const struct hda_verb alc268_beep_init_verbs[] = {
2903 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2904 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2905 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2906 { }
2907};
2908
2909enum {
2910 ALC268_FIXUP_INV_DMIC,
2911 ALC268_FIXUP_HP_EAPD,
2912 ALC268_FIXUP_SPDIF,
2913};
2914
2915static const struct hda_fixup alc268_fixups[] = {
2916 [ALC268_FIXUP_INV_DMIC] = {
2917 .type = HDA_FIXUP_FUNC,
2918 .v.func = alc_fixup_inv_dmic,
2919 },
2920 [ALC268_FIXUP_HP_EAPD] = {
2921 .type = HDA_FIXUP_VERBS,
2922 .v.verbs = (const struct hda_verb[]) {
2923 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 0},
2924 {}
2925 }
2926 },
2927 [ALC268_FIXUP_SPDIF] = {
2928 .type = HDA_FIXUP_PINS,
2929 .v.pins = (const struct hda_pintbl[]) {
2930 { 0x1e, 0x014b1180 }, /* enable SPDIF out */
2931 {}
2932 }
2933 },
2934};
2935
2936static const struct hda_model_fixup alc268_fixup_models[] = {
2937 {.id = ALC268_FIXUP_INV_DMIC, .name = "inv-dmic"},
2938 {.id = ALC268_FIXUP_HP_EAPD, .name = "hp-eapd"},
2939 {.id = ALC268_FIXUP_SPDIF, .name = "spdif"},
2940 {}
2941};
2942
2943static const struct snd_pci_quirk alc268_fixup_tbl[] = {
2944 SND_PCI_QUIRK(0x1025, 0x0139, "Acer TravelMate 6293", ALC268_FIXUP_SPDIF),
2945 SND_PCI_QUIRK(0x1025, 0x015b, "Acer AOA 150 (ZG5)", ALC268_FIXUP_INV_DMIC),
2946 /* below is codec SSID since multiple Toshiba laptops have the
2947 * same PCI SSID 1179:ff00
2948 */
2949 SND_PCI_QUIRK(0x1179, 0xff06, "Toshiba P200", ALC268_FIXUP_HP_EAPD),
2950 {}
2951};
2952
2953/*
2954 * BIOS auto configuration
2955 */
2956static int alc268_parse_auto_config(struct hda_codec *codec)
2957{
2958 static const hda_nid_t alc268_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2959 return alc_parse_auto_config(codec, NULL, alc268_ssids);
2960}
2961
2962/*
2963 */
2964static int patch_alc268(struct hda_codec *codec)
2965{
2966 struct alc_spec *spec;
2967 int i, err;
2968
2969 /* ALC268 has no aa-loopback mixer */
2970 err = alc_alloc_spec(codec, 0);
2971 if (err < 0)
2972 return err;
2973
2974 spec = codec->spec;
David Brazdil0f672f62019-12-10 10:32:29 +00002975 if (has_cdefine_beep(codec))
2976 spec->gen.beep_nid = 0x01;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002977
2978 spec->shutup = alc_eapd_shutup;
2979
David Brazdil0f672f62019-12-10 10:32:29 +00002980 alc_pre_init(codec);
2981
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002982 snd_hda_pick_fixup(codec, alc268_fixup_models, alc268_fixup_tbl, alc268_fixups);
2983 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
2984
2985 /* automatic parse from the BIOS config */
2986 err = alc268_parse_auto_config(codec);
2987 if (err < 0)
2988 goto error;
2989
2990 if (err > 0 && !spec->gen.no_analog &&
2991 spec->gen.autocfg.speaker_pins[0] != 0x1d) {
2992 for (i = 0; i < ARRAY_SIZE(alc268_beep_mixer); i++) {
2993 if (!snd_hda_gen_add_kctl(&spec->gen, NULL,
2994 &alc268_beep_mixer[i])) {
2995 err = -ENOMEM;
2996 goto error;
2997 }
2998 }
2999 snd_hda_add_verbs(codec, alc268_beep_init_verbs);
3000 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
3001 /* override the amp caps for beep generator */
3002 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
3003 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
3004 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
3005 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
3006 (0 << AC_AMPCAP_MUTE_SHIFT));
3007 }
3008
3009 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
3010
3011 return 0;
3012
3013 error:
3014 alc_free(codec);
3015 return err;
3016}
3017
3018/*
3019 * ALC269
3020 */
3021
3022static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
3023 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
3024};
3025
3026static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
3027 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
3028};
3029
3030/* different alc269-variants */
3031enum {
3032 ALC269_TYPE_ALC269VA,
3033 ALC269_TYPE_ALC269VB,
3034 ALC269_TYPE_ALC269VC,
3035 ALC269_TYPE_ALC269VD,
3036 ALC269_TYPE_ALC280,
3037 ALC269_TYPE_ALC282,
3038 ALC269_TYPE_ALC283,
3039 ALC269_TYPE_ALC284,
3040 ALC269_TYPE_ALC293,
3041 ALC269_TYPE_ALC286,
3042 ALC269_TYPE_ALC298,
3043 ALC269_TYPE_ALC255,
3044 ALC269_TYPE_ALC256,
3045 ALC269_TYPE_ALC257,
3046 ALC269_TYPE_ALC215,
3047 ALC269_TYPE_ALC225,
3048 ALC269_TYPE_ALC294,
3049 ALC269_TYPE_ALC300,
David Brazdil0f672f62019-12-10 10:32:29 +00003050 ALC269_TYPE_ALC623,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00003051 ALC269_TYPE_ALC700,
3052};
3053
3054/*
3055 * BIOS auto configuration
3056 */
3057static int alc269_parse_auto_config(struct hda_codec *codec)
3058{
3059 static const hda_nid_t alc269_ignore[] = { 0x1d, 0 };
3060 static const hda_nid_t alc269_ssids[] = { 0, 0x1b, 0x14, 0x21 };
3061 static const hda_nid_t alc269va_ssids[] = { 0x15, 0x1b, 0x14, 0 };
3062 struct alc_spec *spec = codec->spec;
3063 const hda_nid_t *ssids;
3064
3065 switch (spec->codec_variant) {
3066 case ALC269_TYPE_ALC269VA:
3067 case ALC269_TYPE_ALC269VC:
3068 case ALC269_TYPE_ALC280:
3069 case ALC269_TYPE_ALC284:
3070 case ALC269_TYPE_ALC293:
3071 ssids = alc269va_ssids;
3072 break;
3073 case ALC269_TYPE_ALC269VB:
3074 case ALC269_TYPE_ALC269VD:
3075 case ALC269_TYPE_ALC282:
3076 case ALC269_TYPE_ALC283:
3077 case ALC269_TYPE_ALC286:
3078 case ALC269_TYPE_ALC298:
3079 case ALC269_TYPE_ALC255:
3080 case ALC269_TYPE_ALC256:
3081 case ALC269_TYPE_ALC257:
3082 case ALC269_TYPE_ALC215:
3083 case ALC269_TYPE_ALC225:
3084 case ALC269_TYPE_ALC294:
3085 case ALC269_TYPE_ALC300:
David Brazdil0f672f62019-12-10 10:32:29 +00003086 case ALC269_TYPE_ALC623:
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00003087 case ALC269_TYPE_ALC700:
3088 ssids = alc269_ssids;
3089 break;
3090 default:
3091 ssids = alc269_ssids;
3092 break;
3093 }
3094
3095 return alc_parse_auto_config(codec, alc269_ignore, ssids);
3096}
3097
Olivier Deprez0e641232021-09-23 10:07:05 +02003098static const struct hda_jack_keymap alc_headset_btn_keymap[] = {
3099 { SND_JACK_BTN_0, KEY_PLAYPAUSE },
3100 { SND_JACK_BTN_1, KEY_VOICECOMMAND },
3101 { SND_JACK_BTN_2, KEY_VOLUMEUP },
3102 { SND_JACK_BTN_3, KEY_VOLUMEDOWN },
3103 {}
3104};
3105
3106static void alc_headset_btn_callback(struct hda_codec *codec,
3107 struct hda_jack_callback *jack)
3108{
3109 int report = 0;
3110
3111 if (jack->unsol_res & (7 << 13))
3112 report |= SND_JACK_BTN_0;
3113
3114 if (jack->unsol_res & (1 << 16 | 3 << 8))
3115 report |= SND_JACK_BTN_1;
3116
3117 /* Volume up key */
3118 if (jack->unsol_res & (7 << 23))
3119 report |= SND_JACK_BTN_2;
3120
3121 /* Volume down key */
3122 if (jack->unsol_res & (7 << 10))
3123 report |= SND_JACK_BTN_3;
3124
3125 jack->jack->button_state = report;
3126}
3127
3128static void alc_disable_headset_jack_key(struct hda_codec *codec)
3129{
3130 struct alc_spec *spec = codec->spec;
3131
3132 if (!spec->has_hs_key)
3133 return;
3134
3135 switch (codec->core.vendor_id) {
3136 case 0x10ec0215:
3137 case 0x10ec0225:
3138 case 0x10ec0285:
3139 case 0x10ec0287:
3140 case 0x10ec0295:
3141 case 0x10ec0289:
3142 case 0x10ec0299:
3143 alc_write_coef_idx(codec, 0x48, 0x0);
3144 alc_update_coef_idx(codec, 0x49, 0x0045, 0x0);
3145 alc_update_coef_idx(codec, 0x44, 0x0045 << 8, 0x0);
3146 break;
3147 case 0x10ec0230:
3148 case 0x10ec0236:
3149 case 0x10ec0256:
3150 alc_write_coef_idx(codec, 0x48, 0x0);
3151 alc_update_coef_idx(codec, 0x49, 0x0045, 0x0);
3152 break;
3153 }
3154}
3155
3156static void alc_enable_headset_jack_key(struct hda_codec *codec)
3157{
3158 struct alc_spec *spec = codec->spec;
3159
3160 if (!spec->has_hs_key)
3161 return;
3162
3163 switch (codec->core.vendor_id) {
3164 case 0x10ec0215:
3165 case 0x10ec0225:
3166 case 0x10ec0285:
3167 case 0x10ec0287:
3168 case 0x10ec0295:
3169 case 0x10ec0289:
3170 case 0x10ec0299:
3171 alc_write_coef_idx(codec, 0x48, 0xd011);
3172 alc_update_coef_idx(codec, 0x49, 0x007f, 0x0045);
3173 alc_update_coef_idx(codec, 0x44, 0x007f << 8, 0x0045 << 8);
3174 break;
3175 case 0x10ec0230:
3176 case 0x10ec0236:
3177 case 0x10ec0256:
3178 alc_write_coef_idx(codec, 0x48, 0xd011);
3179 alc_update_coef_idx(codec, 0x49, 0x007f, 0x0045);
3180 break;
3181 }
3182}
3183
3184static void alc_fixup_headset_jack(struct hda_codec *codec,
3185 const struct hda_fixup *fix, int action)
3186{
3187 struct alc_spec *spec = codec->spec;
3188
3189 switch (action) {
3190 case HDA_FIXUP_ACT_PRE_PROBE:
3191 spec->has_hs_key = 1;
3192 snd_hda_jack_detect_enable_callback(codec, 0x55,
3193 alc_headset_btn_callback);
3194 snd_hda_jack_add_kctl(codec, 0x55, "Headset Jack", false,
3195 SND_JACK_HEADSET, alc_headset_btn_keymap);
3196 break;
3197 case HDA_FIXUP_ACT_INIT:
3198 alc_enable_headset_jack_key(codec);
3199 break;
3200 }
3201}
3202
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00003203static void alc269vb_toggle_power_output(struct hda_codec *codec, int power_up)
3204{
3205 alc_update_coef_idx(codec, 0x04, 1 << 11, power_up ? (1 << 11) : 0);
3206}
3207
3208static void alc269_shutup(struct hda_codec *codec)
3209{
3210 struct alc_spec *spec = codec->spec;
3211
3212 if (spec->codec_variant == ALC269_TYPE_ALC269VB)
3213 alc269vb_toggle_power_output(codec, 0);
3214 if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
3215 (alc_get_coef0(codec) & 0x00ff) == 0x018) {
3216 msleep(150);
3217 }
David Brazdil0f672f62019-12-10 10:32:29 +00003218 alc_shutup_pins(codec);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00003219}
3220
Olivier Deprez0e641232021-09-23 10:07:05 +02003221static const struct coef_fw alc282_coefs[] = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00003222 WRITE_COEF(0x03, 0x0002), /* Power Down Control */
3223 UPDATE_COEF(0x05, 0xff3f, 0x0700), /* FIFO and filter clock */
3224 WRITE_COEF(0x07, 0x0200), /* DMIC control */
3225 UPDATE_COEF(0x06, 0x00f0, 0), /* Analog clock */
3226 UPDATE_COEF(0x08, 0xfffc, 0x0c2c), /* JD */
3227 WRITE_COEF(0x0a, 0xcccc), /* JD offset1 */
3228 WRITE_COEF(0x0b, 0xcccc), /* JD offset2 */
3229 WRITE_COEF(0x0e, 0x6e00), /* LDO1/2/3, DAC/ADC */
3230 UPDATE_COEF(0x0f, 0xf800, 0x1000), /* JD */
3231 UPDATE_COEF(0x10, 0xfc00, 0x0c00), /* Capless */
3232 WRITE_COEF(0x6f, 0x0), /* Class D test 4 */
3233 UPDATE_COEF(0x0c, 0xfe00, 0), /* IO power down directly */
3234 WRITE_COEF(0x34, 0xa0c0), /* ANC */
3235 UPDATE_COEF(0x16, 0x0008, 0), /* AGC MUX */
3236 UPDATE_COEF(0x1d, 0x00e0, 0), /* DAC simple content protection */
3237 UPDATE_COEF(0x1f, 0x00e0, 0), /* ADC simple content protection */
3238 WRITE_COEF(0x21, 0x8804), /* DAC ADC Zero Detection */
3239 WRITE_COEF(0x63, 0x2902), /* PLL */
3240 WRITE_COEF(0x68, 0xa080), /* capless control 2 */
3241 WRITE_COEF(0x69, 0x3400), /* capless control 3 */
3242 WRITE_COEF(0x6a, 0x2f3e), /* capless control 4 */
3243 WRITE_COEF(0x6b, 0x0), /* capless control 5 */
3244 UPDATE_COEF(0x6d, 0x0fff, 0x0900), /* class D test 2 */
3245 WRITE_COEF(0x6e, 0x110a), /* class D test 3 */
3246 UPDATE_COEF(0x70, 0x00f8, 0x00d8), /* class D test 5 */
3247 WRITE_COEF(0x71, 0x0014), /* class D test 6 */
3248 WRITE_COEF(0x72, 0xc2ba), /* classD OCP */
3249 UPDATE_COEF(0x77, 0x0f80, 0), /* classD pure DC test */
3250 WRITE_COEF(0x6c, 0xfc06), /* Class D amp control */
3251 {}
3252};
3253
3254static void alc282_restore_default_value(struct hda_codec *codec)
3255{
3256 alc_process_coef_fw(codec, alc282_coefs);
3257}
3258
3259static void alc282_init(struct hda_codec *codec)
3260{
3261 struct alc_spec *spec = codec->spec;
David Brazdil0f672f62019-12-10 10:32:29 +00003262 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00003263 bool hp_pin_sense;
3264 int coef78;
3265
3266 alc282_restore_default_value(codec);
3267
3268 if (!hp_pin)
3269 return;
3270 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3271 coef78 = alc_read_coef_idx(codec, 0x78);
3272
3273 /* Index 0x78 Direct Drive HP AMP LPM Control 1 */
3274 /* Headphone capless set to high power mode */
3275 alc_write_coef_idx(codec, 0x78, 0x9004);
3276
3277 if (hp_pin_sense)
3278 msleep(2);
3279
3280 snd_hda_codec_write(codec, hp_pin, 0,
3281 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3282
3283 if (hp_pin_sense)
3284 msleep(85);
3285
3286 snd_hda_codec_write(codec, hp_pin, 0,
3287 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3288
3289 if (hp_pin_sense)
3290 msleep(100);
3291
3292 /* Headphone capless set to normal mode */
3293 alc_write_coef_idx(codec, 0x78, coef78);
3294}
3295
3296static void alc282_shutup(struct hda_codec *codec)
3297{
3298 struct alc_spec *spec = codec->spec;
David Brazdil0f672f62019-12-10 10:32:29 +00003299 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00003300 bool hp_pin_sense;
3301 int coef78;
3302
3303 if (!hp_pin) {
3304 alc269_shutup(codec);
3305 return;
3306 }
3307
3308 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3309 coef78 = alc_read_coef_idx(codec, 0x78);
3310 alc_write_coef_idx(codec, 0x78, 0x9004);
3311
3312 if (hp_pin_sense)
3313 msleep(2);
3314
3315 snd_hda_codec_write(codec, hp_pin, 0,
3316 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3317
3318 if (hp_pin_sense)
3319 msleep(85);
3320
David Brazdil0f672f62019-12-10 10:32:29 +00003321 if (!spec->no_shutup_pins)
3322 snd_hda_codec_write(codec, hp_pin, 0,
3323 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00003324
3325 if (hp_pin_sense)
3326 msleep(100);
3327
3328 alc_auto_setup_eapd(codec, false);
David Brazdil0f672f62019-12-10 10:32:29 +00003329 alc_shutup_pins(codec);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00003330 alc_write_coef_idx(codec, 0x78, coef78);
3331}
3332
Olivier Deprez0e641232021-09-23 10:07:05 +02003333static const struct coef_fw alc283_coefs[] = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00003334 WRITE_COEF(0x03, 0x0002), /* Power Down Control */
3335 UPDATE_COEF(0x05, 0xff3f, 0x0700), /* FIFO and filter clock */
3336 WRITE_COEF(0x07, 0x0200), /* DMIC control */
3337 UPDATE_COEF(0x06, 0x00f0, 0), /* Analog clock */
3338 UPDATE_COEF(0x08, 0xfffc, 0x0c2c), /* JD */
3339 WRITE_COEF(0x0a, 0xcccc), /* JD offset1 */
3340 WRITE_COEF(0x0b, 0xcccc), /* JD offset2 */
3341 WRITE_COEF(0x0e, 0x6fc0), /* LDO1/2/3, DAC/ADC */
3342 UPDATE_COEF(0x0f, 0xf800, 0x1000), /* JD */
3343 UPDATE_COEF(0x10, 0xfc00, 0x0c00), /* Capless */
3344 WRITE_COEF(0x3a, 0x0), /* Class D test 4 */
3345 UPDATE_COEF(0x0c, 0xfe00, 0x0), /* IO power down directly */
3346 WRITE_COEF(0x22, 0xa0c0), /* ANC */
3347 UPDATE_COEFEX(0x53, 0x01, 0x000f, 0x0008), /* AGC MUX */
3348 UPDATE_COEF(0x1d, 0x00e0, 0), /* DAC simple content protection */
3349 UPDATE_COEF(0x1f, 0x00e0, 0), /* ADC simple content protection */
3350 WRITE_COEF(0x21, 0x8804), /* DAC ADC Zero Detection */
3351 WRITE_COEF(0x2e, 0x2902), /* PLL */
3352 WRITE_COEF(0x33, 0xa080), /* capless control 2 */
3353 WRITE_COEF(0x34, 0x3400), /* capless control 3 */
3354 WRITE_COEF(0x35, 0x2f3e), /* capless control 4 */
3355 WRITE_COEF(0x36, 0x0), /* capless control 5 */
3356 UPDATE_COEF(0x38, 0x0fff, 0x0900), /* class D test 2 */
3357 WRITE_COEF(0x39, 0x110a), /* class D test 3 */
3358 UPDATE_COEF(0x3b, 0x00f8, 0x00d8), /* class D test 5 */
3359 WRITE_COEF(0x3c, 0x0014), /* class D test 6 */
3360 WRITE_COEF(0x3d, 0xc2ba), /* classD OCP */
3361 UPDATE_COEF(0x42, 0x0f80, 0x0), /* classD pure DC test */
3362 WRITE_COEF(0x49, 0x0), /* test mode */
3363 UPDATE_COEF(0x40, 0xf800, 0x9800), /* Class D DC enable */
3364 UPDATE_COEF(0x42, 0xf000, 0x2000), /* DC offset */
3365 WRITE_COEF(0x37, 0xfc06), /* Class D amp control */
3366 UPDATE_COEF(0x1b, 0x8000, 0), /* HP JD control */
3367 {}
3368};
3369
3370static void alc283_restore_default_value(struct hda_codec *codec)
3371{
3372 alc_process_coef_fw(codec, alc283_coefs);
3373}
3374
3375static void alc283_init(struct hda_codec *codec)
3376{
3377 struct alc_spec *spec = codec->spec;
David Brazdil0f672f62019-12-10 10:32:29 +00003378 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00003379 bool hp_pin_sense;
3380
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00003381 alc283_restore_default_value(codec);
3382
3383 if (!hp_pin)
3384 return;
3385
3386 msleep(30);
3387 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3388
3389 /* Index 0x43 Direct Drive HP AMP LPM Control 1 */
3390 /* Headphone capless set to high power mode */
3391 alc_write_coef_idx(codec, 0x43, 0x9004);
3392
3393 snd_hda_codec_write(codec, hp_pin, 0,
3394 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3395
3396 if (hp_pin_sense)
3397 msleep(85);
3398
3399 snd_hda_codec_write(codec, hp_pin, 0,
3400 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3401
3402 if (hp_pin_sense)
3403 msleep(85);
3404 /* Index 0x46 Combo jack auto switch control 2 */
3405 /* 3k pull low control for Headset jack. */
3406 alc_update_coef_idx(codec, 0x46, 3 << 12, 0);
3407 /* Headphone capless set to normal mode */
3408 alc_write_coef_idx(codec, 0x43, 0x9614);
3409}
3410
3411static void alc283_shutup(struct hda_codec *codec)
3412{
3413 struct alc_spec *spec = codec->spec;
David Brazdil0f672f62019-12-10 10:32:29 +00003414 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00003415 bool hp_pin_sense;
3416
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00003417 if (!hp_pin) {
3418 alc269_shutup(codec);
3419 return;
3420 }
3421
3422 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3423
3424 alc_write_coef_idx(codec, 0x43, 0x9004);
3425
3426 /*depop hp during suspend*/
3427 alc_write_coef_idx(codec, 0x06, 0x2100);
3428
3429 snd_hda_codec_write(codec, hp_pin, 0,
3430 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3431
3432 if (hp_pin_sense)
3433 msleep(100);
3434
David Brazdil0f672f62019-12-10 10:32:29 +00003435 if (!spec->no_shutup_pins)
3436 snd_hda_codec_write(codec, hp_pin, 0,
3437 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00003438
3439 alc_update_coef_idx(codec, 0x46, 0, 3 << 12);
3440
3441 if (hp_pin_sense)
3442 msleep(100);
3443 alc_auto_setup_eapd(codec, false);
David Brazdil0f672f62019-12-10 10:32:29 +00003444 alc_shutup_pins(codec);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00003445 alc_write_coef_idx(codec, 0x43, 0x9614);
3446}
3447
3448static void alc256_init(struct hda_codec *codec)
3449{
3450 struct alc_spec *spec = codec->spec;
David Brazdil0f672f62019-12-10 10:32:29 +00003451 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00003452 bool hp_pin_sense;
3453
3454 if (!hp_pin)
David Brazdil0f672f62019-12-10 10:32:29 +00003455 hp_pin = 0x21;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00003456
3457 msleep(30);
3458
3459 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3460
3461 if (hp_pin_sense)
3462 msleep(2);
3463
3464 alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */
David Brazdil0f672f62019-12-10 10:32:29 +00003465 if (spec->ultra_low_power) {
3466 alc_update_coef_idx(codec, 0x03, 1<<1, 1<<1);
3467 alc_update_coef_idx(codec, 0x08, 3<<2, 3<<2);
3468 alc_update_coef_idx(codec, 0x08, 7<<4, 0);
3469 alc_update_coef_idx(codec, 0x3b, 1<<15, 0);
3470 alc_update_coef_idx(codec, 0x0e, 7<<6, 7<<6);
3471 msleep(30);
3472 }
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00003473
3474 snd_hda_codec_write(codec, hp_pin, 0,
3475 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3476
David Brazdil0f672f62019-12-10 10:32:29 +00003477 if (hp_pin_sense || spec->ultra_low_power)
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00003478 msleep(85);
3479
3480 snd_hda_codec_write(codec, hp_pin, 0,
3481 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3482
David Brazdil0f672f62019-12-10 10:32:29 +00003483 if (hp_pin_sense || spec->ultra_low_power)
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00003484 msleep(100);
3485
3486 alc_update_coef_idx(codec, 0x46, 3 << 12, 0);
3487 alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x4); /* Hight power */
3488 alc_update_coefex_idx(codec, 0x53, 0x02, 0x8000, 1 << 15); /* Clear bit */
3489 alc_update_coefex_idx(codec, 0x53, 0x02, 0x8000, 0 << 15);
Olivier Deprez0e641232021-09-23 10:07:05 +02003490 /*
3491 * Expose headphone mic (or possibly Line In on some machines) instead
3492 * of PC Beep on 1Ah, and disable 1Ah loopback for all outputs. See
3493 * Documentation/sound/hd-audio/realtek-pc-beep.rst for details of
3494 * this register.
3495 */
3496 alc_write_coef_idx(codec, 0x36, 0x5757);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00003497}
3498
3499static void alc256_shutup(struct hda_codec *codec)
3500{
3501 struct alc_spec *spec = codec->spec;
David Brazdil0f672f62019-12-10 10:32:29 +00003502 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00003503 bool hp_pin_sense;
3504
David Brazdil0f672f62019-12-10 10:32:29 +00003505 if (!hp_pin)
3506 hp_pin = 0x21;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00003507
3508 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3509
3510 if (hp_pin_sense)
3511 msleep(2);
3512
3513 snd_hda_codec_write(codec, hp_pin, 0,
3514 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3515
David Brazdil0f672f62019-12-10 10:32:29 +00003516 if (hp_pin_sense || spec->ultra_low_power)
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00003517 msleep(85);
3518
3519 /* 3k pull low control for Headset jack. */
3520 /* NOTE: call this before clearing the pin, otherwise codec stalls */
Olivier Deprez0e641232021-09-23 10:07:05 +02003521 /* If disable 3k pulldown control for alc257, the Mic detection will not work correctly
3522 * when booting with headset plugged. So skip setting it for the codec alc257
3523 */
3524 if (codec->core.vendor_id != 0x10ec0257)
3525 alc_update_coef_idx(codec, 0x46, 0, 3 << 12);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00003526
David Brazdil0f672f62019-12-10 10:32:29 +00003527 if (!spec->no_shutup_pins)
3528 snd_hda_codec_write(codec, hp_pin, 0,
3529 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00003530
David Brazdil0f672f62019-12-10 10:32:29 +00003531 if (hp_pin_sense || spec->ultra_low_power)
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00003532 msleep(100);
3533
3534 alc_auto_setup_eapd(codec, false);
David Brazdil0f672f62019-12-10 10:32:29 +00003535 alc_shutup_pins(codec);
3536 if (spec->ultra_low_power) {
3537 msleep(50);
3538 alc_update_coef_idx(codec, 0x03, 1<<1, 0);
3539 alc_update_coef_idx(codec, 0x08, 7<<4, 7<<4);
3540 alc_update_coef_idx(codec, 0x08, 3<<2, 0);
3541 alc_update_coef_idx(codec, 0x3b, 1<<15, 1<<15);
3542 alc_update_coef_idx(codec, 0x0e, 7<<6, 0);
3543 msleep(30);
3544 }
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00003545}
3546
3547static void alc225_init(struct hda_codec *codec)
3548{
3549 struct alc_spec *spec = codec->spec;
David Brazdil0f672f62019-12-10 10:32:29 +00003550 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00003551 bool hp1_pin_sense, hp2_pin_sense;
3552
3553 if (!hp_pin)
David Brazdil0f672f62019-12-10 10:32:29 +00003554 hp_pin = 0x21;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00003555 msleep(30);
3556
3557 hp1_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3558 hp2_pin_sense = snd_hda_jack_detect(codec, 0x16);
3559
3560 if (hp1_pin_sense || hp2_pin_sense)
3561 msleep(2);
3562
3563 alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */
David Brazdil0f672f62019-12-10 10:32:29 +00003564 if (spec->ultra_low_power) {
3565 alc_update_coef_idx(codec, 0x08, 0x0f << 2, 3<<2);
3566 alc_update_coef_idx(codec, 0x0e, 7<<6, 7<<6);
3567 alc_update_coef_idx(codec, 0x33, 1<<11, 0);
3568 msleep(30);
3569 }
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00003570
David Brazdil0f672f62019-12-10 10:32:29 +00003571 if (hp1_pin_sense || spec->ultra_low_power)
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00003572 snd_hda_codec_write(codec, hp_pin, 0,
3573 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3574 if (hp2_pin_sense)
3575 snd_hda_codec_write(codec, 0x16, 0,
3576 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3577
David Brazdil0f672f62019-12-10 10:32:29 +00003578 if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power)
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00003579 msleep(85);
3580
David Brazdil0f672f62019-12-10 10:32:29 +00003581 if (hp1_pin_sense || spec->ultra_low_power)
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00003582 snd_hda_codec_write(codec, hp_pin, 0,
3583 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3584 if (hp2_pin_sense)
3585 snd_hda_codec_write(codec, 0x16, 0,
3586 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3587
David Brazdil0f672f62019-12-10 10:32:29 +00003588 if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power)
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00003589 msleep(100);
3590
3591 alc_update_coef_idx(codec, 0x4a, 3 << 10, 0);
3592 alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x4); /* Hight power */
3593}
3594
3595static void alc225_shutup(struct hda_codec *codec)
3596{
3597 struct alc_spec *spec = codec->spec;
David Brazdil0f672f62019-12-10 10:32:29 +00003598 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00003599 bool hp1_pin_sense, hp2_pin_sense;
3600
David Brazdil0f672f62019-12-10 10:32:29 +00003601 if (!hp_pin)
3602 hp_pin = 0x21;
Olivier Deprez0e641232021-09-23 10:07:05 +02003603
3604 alc_disable_headset_jack_key(codec);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00003605 /* 3k pull low control for Headset jack. */
3606 alc_update_coef_idx(codec, 0x4a, 0, 3 << 10);
3607
3608 hp1_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3609 hp2_pin_sense = snd_hda_jack_detect(codec, 0x16);
3610
3611 if (hp1_pin_sense || hp2_pin_sense)
3612 msleep(2);
3613
David Brazdil0f672f62019-12-10 10:32:29 +00003614 if (hp1_pin_sense || spec->ultra_low_power)
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00003615 snd_hda_codec_write(codec, hp_pin, 0,
3616 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3617 if (hp2_pin_sense)
3618 snd_hda_codec_write(codec, 0x16, 0,
3619 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3620
David Brazdil0f672f62019-12-10 10:32:29 +00003621 if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power)
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00003622 msleep(85);
3623
David Brazdil0f672f62019-12-10 10:32:29 +00003624 if (hp1_pin_sense || spec->ultra_low_power)
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00003625 snd_hda_codec_write(codec, hp_pin, 0,
3626 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
3627 if (hp2_pin_sense)
3628 snd_hda_codec_write(codec, 0x16, 0,
3629 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
3630
David Brazdil0f672f62019-12-10 10:32:29 +00003631 if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power)
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00003632 msleep(100);
3633
3634 alc_auto_setup_eapd(codec, false);
David Brazdil0f672f62019-12-10 10:32:29 +00003635 alc_shutup_pins(codec);
3636 if (spec->ultra_low_power) {
3637 msleep(50);
3638 alc_update_coef_idx(codec, 0x08, 0x0f << 2, 0x0c << 2);
3639 alc_update_coef_idx(codec, 0x0e, 7<<6, 0);
3640 alc_update_coef_idx(codec, 0x33, 1<<11, 1<<11);
3641 alc_update_coef_idx(codec, 0x4a, 3<<4, 2<<4);
3642 msleep(30);
3643 }
Olivier Deprez0e641232021-09-23 10:07:05 +02003644
3645 alc_update_coef_idx(codec, 0x4a, 3 << 10, 0);
3646 alc_enable_headset_jack_key(codec);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00003647}
3648
3649static void alc_default_init(struct hda_codec *codec)
3650{
3651 struct alc_spec *spec = codec->spec;
David Brazdil0f672f62019-12-10 10:32:29 +00003652 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00003653 bool hp_pin_sense;
3654
3655 if (!hp_pin)
3656 return;
3657
3658 msleep(30);
3659
3660 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3661
3662 if (hp_pin_sense)
3663 msleep(2);
3664
3665 snd_hda_codec_write(codec, hp_pin, 0,
3666 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3667
3668 if (hp_pin_sense)
3669 msleep(85);
3670
3671 snd_hda_codec_write(codec, hp_pin, 0,
3672 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3673
3674 if (hp_pin_sense)
3675 msleep(100);
3676}
3677
3678static void alc_default_shutup(struct hda_codec *codec)
3679{
3680 struct alc_spec *spec = codec->spec;
David Brazdil0f672f62019-12-10 10:32:29 +00003681 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00003682 bool hp_pin_sense;
3683
3684 if (!hp_pin) {
3685 alc269_shutup(codec);
3686 return;
3687 }
3688
3689 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3690
3691 if (hp_pin_sense)
3692 msleep(2);
3693
3694 snd_hda_codec_write(codec, hp_pin, 0,
3695 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3696
3697 if (hp_pin_sense)
3698 msleep(85);
3699
David Brazdil0f672f62019-12-10 10:32:29 +00003700 if (!spec->no_shutup_pins)
3701 snd_hda_codec_write(codec, hp_pin, 0,
3702 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00003703
3704 if (hp_pin_sense)
3705 msleep(100);
3706
3707 alc_auto_setup_eapd(codec, false);
David Brazdil0f672f62019-12-10 10:32:29 +00003708 alc_shutup_pins(codec);
3709}
3710
3711static void alc294_hp_init(struct hda_codec *codec)
3712{
3713 struct alc_spec *spec = codec->spec;
3714 hda_nid_t hp_pin = alc_get_hp_pin(spec);
3715 int i, val;
3716
3717 if (!hp_pin)
3718 return;
3719
3720 snd_hda_codec_write(codec, hp_pin, 0,
3721 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3722
3723 msleep(100);
3724
3725 if (!spec->no_shutup_pins)
3726 snd_hda_codec_write(codec, hp_pin, 0,
3727 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
3728
3729 alc_update_coef_idx(codec, 0x6f, 0x000f, 0);/* Set HP depop to manual mode */
3730 alc_update_coefex_idx(codec, 0x58, 0x00, 0x8000, 0x8000); /* HP depop procedure start */
3731
3732 /* Wait for depop procedure finish */
3733 val = alc_read_coefex_idx(codec, 0x58, 0x01);
3734 for (i = 0; i < 20 && val & 0x0080; i++) {
3735 msleep(50);
3736 val = alc_read_coefex_idx(codec, 0x58, 0x01);
3737 }
3738 /* Set HP depop to auto mode */
3739 alc_update_coef_idx(codec, 0x6f, 0x000f, 0x000b);
3740 msleep(50);
3741}
3742
3743static void alc294_init(struct hda_codec *codec)
3744{
3745 struct alc_spec *spec = codec->spec;
3746
3747 /* required only at boot or S4 resume time */
3748 if (!spec->done_hp_init ||
3749 codec->core.dev.power.power_state.event == PM_EVENT_RESTORE) {
3750 alc294_hp_init(codec);
3751 spec->done_hp_init = true;
3752 }
3753 alc_default_init(codec);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00003754}
3755
3756static void alc5505_coef_set(struct hda_codec *codec, unsigned int index_reg,
3757 unsigned int val)
3758{
3759 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_COEF_INDEX, index_reg >> 1);
3760 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_PROC_COEF, val & 0xffff); /* LSB */
3761 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_PROC_COEF, val >> 16); /* MSB */
3762}
3763
3764static int alc5505_coef_get(struct hda_codec *codec, unsigned int index_reg)
3765{
3766 unsigned int val;
3767
3768 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_COEF_INDEX, index_reg >> 1);
3769 val = snd_hda_codec_read(codec, 0x51, 0, AC_VERB_GET_PROC_COEF, 0)
3770 & 0xffff;
3771 val |= snd_hda_codec_read(codec, 0x51, 0, AC_VERB_GET_PROC_COEF, 0)
3772 << 16;
3773 return val;
3774}
3775
3776static void alc5505_dsp_halt(struct hda_codec *codec)
3777{
3778 unsigned int val;
3779
3780 alc5505_coef_set(codec, 0x3000, 0x000c); /* DSP CPU stop */
3781 alc5505_coef_set(codec, 0x880c, 0x0008); /* DDR enter self refresh */
3782 alc5505_coef_set(codec, 0x61c0, 0x11110080); /* Clock control for PLL and CPU */
3783 alc5505_coef_set(codec, 0x6230, 0xfc0d4011); /* Disable Input OP */
3784 alc5505_coef_set(codec, 0x61b4, 0x040a2b03); /* Stop PLL2 */
3785 alc5505_coef_set(codec, 0x61b0, 0x00005b17); /* Stop PLL1 */
3786 alc5505_coef_set(codec, 0x61b8, 0x04133303); /* Stop PLL3 */
3787 val = alc5505_coef_get(codec, 0x6220);
3788 alc5505_coef_set(codec, 0x6220, (val | 0x3000)); /* switch Ringbuffer clock to DBUS clock */
3789}
3790
3791static void alc5505_dsp_back_from_halt(struct hda_codec *codec)
3792{
3793 alc5505_coef_set(codec, 0x61b8, 0x04133302);
3794 alc5505_coef_set(codec, 0x61b0, 0x00005b16);
3795 alc5505_coef_set(codec, 0x61b4, 0x040a2b02);
3796 alc5505_coef_set(codec, 0x6230, 0xf80d4011);
3797 alc5505_coef_set(codec, 0x6220, 0x2002010f);
3798 alc5505_coef_set(codec, 0x880c, 0x00000004);
3799}
3800
3801static void alc5505_dsp_init(struct hda_codec *codec)
3802{
3803 unsigned int val;
3804
3805 alc5505_dsp_halt(codec);
3806 alc5505_dsp_back_from_halt(codec);
3807 alc5505_coef_set(codec, 0x61b0, 0x5b14); /* PLL1 control */
3808 alc5505_coef_set(codec, 0x61b0, 0x5b16);
3809 alc5505_coef_set(codec, 0x61b4, 0x04132b00); /* PLL2 control */
3810 alc5505_coef_set(codec, 0x61b4, 0x04132b02);
3811 alc5505_coef_set(codec, 0x61b8, 0x041f3300); /* PLL3 control*/
3812 alc5505_coef_set(codec, 0x61b8, 0x041f3302);
3813 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_CODEC_RESET, 0); /* Function reset */
3814 alc5505_coef_set(codec, 0x61b8, 0x041b3302);
3815 alc5505_coef_set(codec, 0x61b8, 0x04173302);
3816 alc5505_coef_set(codec, 0x61b8, 0x04163302);
3817 alc5505_coef_set(codec, 0x8800, 0x348b328b); /* DRAM control */
3818 alc5505_coef_set(codec, 0x8808, 0x00020022); /* DRAM control */
3819 alc5505_coef_set(codec, 0x8818, 0x00000400); /* DRAM control */
3820
3821 val = alc5505_coef_get(codec, 0x6200) >> 16; /* Read revision ID */
3822 if (val <= 3)
3823 alc5505_coef_set(codec, 0x6220, 0x2002010f); /* I/O PAD Configuration */
3824 else
3825 alc5505_coef_set(codec, 0x6220, 0x6002018f);
3826
3827 alc5505_coef_set(codec, 0x61ac, 0x055525f0); /**/
3828 alc5505_coef_set(codec, 0x61c0, 0x12230080); /* Clock control */
3829 alc5505_coef_set(codec, 0x61b4, 0x040e2b02); /* PLL2 control */
3830 alc5505_coef_set(codec, 0x61bc, 0x010234f8); /* OSC Control */
3831 alc5505_coef_set(codec, 0x880c, 0x00000004); /* DRAM Function control */
3832 alc5505_coef_set(codec, 0x880c, 0x00000003);
3833 alc5505_coef_set(codec, 0x880c, 0x00000010);
3834
3835#ifdef HALT_REALTEK_ALC5505
3836 alc5505_dsp_halt(codec);
3837#endif
3838}
3839
3840#ifdef HALT_REALTEK_ALC5505
Olivier Deprez0e641232021-09-23 10:07:05 +02003841#define alc5505_dsp_suspend(codec) do { } while (0) /* NOP */
3842#define alc5505_dsp_resume(codec) do { } while (0) /* NOP */
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00003843#else
3844#define alc5505_dsp_suspend(codec) alc5505_dsp_halt(codec)
3845#define alc5505_dsp_resume(codec) alc5505_dsp_back_from_halt(codec)
3846#endif
3847
3848#ifdef CONFIG_PM
3849static int alc269_suspend(struct hda_codec *codec)
3850{
3851 struct alc_spec *spec = codec->spec;
3852
3853 if (spec->has_alc5505_dsp)
3854 alc5505_dsp_suspend(codec);
3855 return alc_suspend(codec);
3856}
3857
3858static int alc269_resume(struct hda_codec *codec)
3859{
3860 struct alc_spec *spec = codec->spec;
3861
3862 if (spec->codec_variant == ALC269_TYPE_ALC269VB)
3863 alc269vb_toggle_power_output(codec, 0);
3864 if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
3865 (alc_get_coef0(codec) & 0x00ff) == 0x018) {
3866 msleep(150);
3867 }
3868
3869 codec->patch_ops.init(codec);
3870
3871 if (spec->codec_variant == ALC269_TYPE_ALC269VB)
3872 alc269vb_toggle_power_output(codec, 1);
3873 if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
3874 (alc_get_coef0(codec) & 0x00ff) == 0x017) {
3875 msleep(200);
3876 }
3877
Olivier Deprez0e641232021-09-23 10:07:05 +02003878 snd_hda_regmap_sync(codec);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00003879 hda_call_check_power_status(codec, 0x01);
3880
3881 /* on some machine, the BIOS will clear the codec gpio data when enter
3882 * suspend, and won't restore the data after resume, so we restore it
3883 * in the driver.
3884 */
3885 if (spec->gpio_data)
3886 alc_write_gpio_data(codec);
3887
3888 if (spec->has_alc5505_dsp)
3889 alc5505_dsp_resume(codec);
3890
3891 return 0;
3892}
3893#endif /* CONFIG_PM */
3894
3895static void alc269_fixup_pincfg_no_hp_to_lineout(struct hda_codec *codec,
3896 const struct hda_fixup *fix, int action)
3897{
3898 struct alc_spec *spec = codec->spec;
3899
3900 if (action == HDA_FIXUP_ACT_PRE_PROBE)
3901 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
3902}
3903
3904static void alc269_fixup_pincfg_U7x7_headset_mic(struct hda_codec *codec,
3905 const struct hda_fixup *fix,
3906 int action)
3907{
3908 unsigned int cfg_headphone = snd_hda_codec_get_pincfg(codec, 0x21);
3909 unsigned int cfg_headset_mic = snd_hda_codec_get_pincfg(codec, 0x19);
3910
3911 if (cfg_headphone && cfg_headset_mic == 0x411111f0)
3912 snd_hda_codec_set_pincfg(codec, 0x19,
3913 (cfg_headphone & ~AC_DEFCFG_DEVICE) |
3914 (AC_JACK_MIC_IN << AC_DEFCFG_DEVICE_SHIFT));
3915}
3916
3917static void alc269_fixup_hweq(struct hda_codec *codec,
3918 const struct hda_fixup *fix, int action)
3919{
3920 if (action == HDA_FIXUP_ACT_INIT)
3921 alc_update_coef_idx(codec, 0x1e, 0, 0x80);
3922}
3923
3924static void alc269_fixup_headset_mic(struct hda_codec *codec,
3925 const struct hda_fixup *fix, int action)
3926{
3927 struct alc_spec *spec = codec->spec;
3928
3929 if (action == HDA_FIXUP_ACT_PRE_PROBE)
3930 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
3931}
3932
3933static void alc271_fixup_dmic(struct hda_codec *codec,
3934 const struct hda_fixup *fix, int action)
3935{
3936 static const struct hda_verb verbs[] = {
3937 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
3938 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
3939 {}
3940 };
3941 unsigned int cfg;
3942
3943 if (strcmp(codec->core.chip_name, "ALC271X") &&
3944 strcmp(codec->core.chip_name, "ALC269VB"))
3945 return;
3946 cfg = snd_hda_codec_get_pincfg(codec, 0x12);
3947 if (get_defcfg_connect(cfg) == AC_JACK_PORT_FIXED)
3948 snd_hda_sequence_write(codec, verbs);
3949}
3950
Olivier Deprez0e641232021-09-23 10:07:05 +02003951/* Fix the speaker amp after resume, etc */
3952static void alc269vb_fixup_aspire_e1_coef(struct hda_codec *codec,
3953 const struct hda_fixup *fix,
3954 int action)
3955{
3956 if (action == HDA_FIXUP_ACT_INIT)
3957 alc_update_coef_idx(codec, 0x0d, 0x6000, 0x6000);
3958}
3959
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00003960static void alc269_fixup_pcm_44k(struct hda_codec *codec,
3961 const struct hda_fixup *fix, int action)
3962{
3963 struct alc_spec *spec = codec->spec;
3964
3965 if (action != HDA_FIXUP_ACT_PROBE)
3966 return;
3967
3968 /* Due to a hardware problem on Lenovo Ideadpad, we need to
3969 * fix the sample rate of analog I/O to 44.1kHz
3970 */
3971 spec->gen.stream_analog_playback = &alc269_44k_pcm_analog_playback;
3972 spec->gen.stream_analog_capture = &alc269_44k_pcm_analog_capture;
3973}
3974
3975static void alc269_fixup_stereo_dmic(struct hda_codec *codec,
3976 const struct hda_fixup *fix, int action)
3977{
3978 /* The digital-mic unit sends PDM (differential signal) instead of
3979 * the standard PCM, thus you can't record a valid mono stream as is.
3980 * Below is a workaround specific to ALC269 to control the dmic
3981 * signal source as mono.
3982 */
3983 if (action == HDA_FIXUP_ACT_INIT)
3984 alc_update_coef_idx(codec, 0x07, 0, 0x80);
3985}
3986
3987static void alc269_quanta_automute(struct hda_codec *codec)
3988{
3989 snd_hda_gen_update_outputs(codec);
3990
3991 alc_write_coef_idx(codec, 0x0c, 0x680);
3992 alc_write_coef_idx(codec, 0x0c, 0x480);
3993}
3994
3995static void alc269_fixup_quanta_mute(struct hda_codec *codec,
3996 const struct hda_fixup *fix, int action)
3997{
3998 struct alc_spec *spec = codec->spec;
3999 if (action != HDA_FIXUP_ACT_PROBE)
4000 return;
4001 spec->gen.automute_hook = alc269_quanta_automute;
4002}
4003
4004static void alc269_x101_hp_automute_hook(struct hda_codec *codec,
4005 struct hda_jack_callback *jack)
4006{
4007 struct alc_spec *spec = codec->spec;
4008 int vref;
4009 msleep(200);
4010 snd_hda_gen_hp_automute(codec, jack);
4011
4012 vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0;
4013 msleep(100);
4014 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4015 vref);
4016 msleep(500);
4017 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4018 vref);
4019}
4020
David Brazdil0f672f62019-12-10 10:32:29 +00004021/*
4022 * Magic sequence to make Huawei Matebook X right speaker working (bko#197801)
4023 */
4024struct hda_alc298_mbxinit {
4025 unsigned char value_0x23;
4026 unsigned char value_0x25;
4027};
4028
4029static void alc298_huawei_mbx_stereo_seq(struct hda_codec *codec,
4030 const struct hda_alc298_mbxinit *initval,
4031 bool first)
4032{
4033 snd_hda_codec_write(codec, 0x06, 0, AC_VERB_SET_DIGI_CONVERT_3, 0x0);
4034 alc_write_coef_idx(codec, 0x26, 0xb000);
4035
4036 if (first)
4037 snd_hda_codec_write(codec, 0x21, 0, AC_VERB_GET_PIN_SENSE, 0x0);
4038
4039 snd_hda_codec_write(codec, 0x6, 0, AC_VERB_SET_DIGI_CONVERT_3, 0x80);
4040 alc_write_coef_idx(codec, 0x26, 0xf000);
4041 alc_write_coef_idx(codec, 0x23, initval->value_0x23);
4042
4043 if (initval->value_0x23 != 0x1e)
4044 alc_write_coef_idx(codec, 0x25, initval->value_0x25);
4045
4046 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0x26);
4047 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, 0xb010);
4048}
4049
4050static void alc298_fixup_huawei_mbx_stereo(struct hda_codec *codec,
4051 const struct hda_fixup *fix,
4052 int action)
4053{
4054 /* Initialization magic */
4055 static const struct hda_alc298_mbxinit dac_init[] = {
4056 {0x0c, 0x00}, {0x0d, 0x00}, {0x0e, 0x00}, {0x0f, 0x00},
4057 {0x10, 0x00}, {0x1a, 0x40}, {0x1b, 0x82}, {0x1c, 0x00},
4058 {0x1d, 0x00}, {0x1e, 0x00}, {0x1f, 0x00},
4059 {0x20, 0xc2}, {0x21, 0xc8}, {0x22, 0x26}, {0x23, 0x24},
4060 {0x27, 0xff}, {0x28, 0xff}, {0x29, 0xff}, {0x2a, 0x8f},
4061 {0x2b, 0x02}, {0x2c, 0x48}, {0x2d, 0x34}, {0x2e, 0x00},
4062 {0x2f, 0x00},
4063 {0x30, 0x00}, {0x31, 0x00}, {0x32, 0x00}, {0x33, 0x00},
4064 {0x34, 0x00}, {0x35, 0x01}, {0x36, 0x93}, {0x37, 0x0c},
4065 {0x38, 0x00}, {0x39, 0x00}, {0x3a, 0xf8}, {0x38, 0x80},
4066 {}
4067 };
4068 const struct hda_alc298_mbxinit *seq;
4069
4070 if (action != HDA_FIXUP_ACT_INIT)
4071 return;
4072
4073 /* Start */
4074 snd_hda_codec_write(codec, 0x06, 0, AC_VERB_SET_DIGI_CONVERT_3, 0x00);
4075 snd_hda_codec_write(codec, 0x06, 0, AC_VERB_SET_DIGI_CONVERT_3, 0x80);
4076 alc_write_coef_idx(codec, 0x26, 0xf000);
4077 alc_write_coef_idx(codec, 0x22, 0x31);
4078 alc_write_coef_idx(codec, 0x23, 0x0b);
4079 alc_write_coef_idx(codec, 0x25, 0x00);
4080 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0x26);
4081 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, 0xb010);
4082
4083 for (seq = dac_init; seq->value_0x23; seq++)
4084 alc298_huawei_mbx_stereo_seq(codec, seq, seq == dac_init);
4085}
4086
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00004087static void alc269_fixup_x101_headset_mic(struct hda_codec *codec,
4088 const struct hda_fixup *fix, int action)
4089{
4090 struct alc_spec *spec = codec->spec;
4091 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4092 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
4093 spec->gen.hp_automute_hook = alc269_x101_hp_automute_hook;
4094 }
4095}
4096
4097
4098/* update mute-LED according to the speaker mute state via mic VREF pin */
4099static void alc269_fixup_mic_mute_hook(void *private_data, int enabled)
4100{
4101 struct hda_codec *codec = private_data;
4102 struct alc_spec *spec = codec->spec;
4103 unsigned int pinval;
4104
4105 if (spec->mute_led_polarity)
4106 enabled = !enabled;
4107 pinval = snd_hda_codec_get_pin_target(codec, spec->mute_led_nid);
4108 pinval &= ~AC_PINCTL_VREFEN;
4109 pinval |= enabled ? AC_PINCTL_VREF_HIZ : AC_PINCTL_VREF_80;
4110 if (spec->mute_led_nid) {
4111 /* temporarily power up/down for setting VREF */
4112 snd_hda_power_up_pm(codec);
4113 snd_hda_set_pin_ctl_cache(codec, spec->mute_led_nid, pinval);
4114 snd_hda_power_down_pm(codec);
4115 }
4116}
4117
4118/* Make sure the led works even in runtime suspend */
4119static unsigned int led_power_filter(struct hda_codec *codec,
4120 hda_nid_t nid,
4121 unsigned int power_state)
4122{
4123 struct alc_spec *spec = codec->spec;
4124
4125 if (power_state != AC_PWRST_D3 || nid == 0 ||
4126 (nid != spec->mute_led_nid && nid != spec->cap_mute_led_nid))
4127 return power_state;
4128
4129 /* Set pin ctl again, it might have just been set to 0 */
4130 snd_hda_set_pin_ctl(codec, nid,
4131 snd_hda_codec_get_pin_target(codec, nid));
4132
4133 return snd_hda_gen_path_power_filter(codec, nid, power_state);
4134}
4135
4136static void alc269_fixup_hp_mute_led(struct hda_codec *codec,
4137 const struct hda_fixup *fix, int action)
4138{
4139 struct alc_spec *spec = codec->spec;
4140 const struct dmi_device *dev = NULL;
4141
4142 if (action != HDA_FIXUP_ACT_PRE_PROBE)
4143 return;
4144
4145 while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) {
4146 int pol, pin;
4147 if (sscanf(dev->name, "HP_Mute_LED_%d_%x", &pol, &pin) != 2)
4148 continue;
4149 if (pin < 0x0a || pin >= 0x10)
4150 break;
4151 spec->mute_led_polarity = pol;
4152 spec->mute_led_nid = pin - 0x0a + 0x18;
4153 spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook;
4154 spec->gen.vmaster_mute_enum = 1;
4155 codec->power_filter = led_power_filter;
4156 codec_dbg(codec,
4157 "Detected mute LED for %x:%d\n", spec->mute_led_nid,
4158 spec->mute_led_polarity);
4159 break;
4160 }
4161}
4162
4163static void alc269_fixup_hp_mute_led_micx(struct hda_codec *codec,
4164 const struct hda_fixup *fix,
4165 int action, hda_nid_t pin)
4166{
4167 struct alc_spec *spec = codec->spec;
4168
4169 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4170 spec->mute_led_polarity = 0;
4171 spec->mute_led_nid = pin;
4172 spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook;
4173 spec->gen.vmaster_mute_enum = 1;
4174 codec->power_filter = led_power_filter;
4175 }
4176}
4177
4178static void alc269_fixup_hp_mute_led_mic1(struct hda_codec *codec,
4179 const struct hda_fixup *fix, int action)
4180{
4181 alc269_fixup_hp_mute_led_micx(codec, fix, action, 0x18);
4182}
4183
4184static void alc269_fixup_hp_mute_led_mic2(struct hda_codec *codec,
4185 const struct hda_fixup *fix, int action)
4186{
4187 alc269_fixup_hp_mute_led_micx(codec, fix, action, 0x19);
4188}
4189
4190static void alc269_fixup_hp_mute_led_mic3(struct hda_codec *codec,
4191 const struct hda_fixup *fix, int action)
4192{
4193 alc269_fixup_hp_mute_led_micx(codec, fix, action, 0x1b);
4194}
4195
4196/* update LED status via GPIO */
4197static void alc_update_gpio_led(struct hda_codec *codec, unsigned int mask,
Olivier Deprez0e641232021-09-23 10:07:05 +02004198 int polarity, bool enabled)
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00004199{
Olivier Deprez0e641232021-09-23 10:07:05 +02004200 if (polarity)
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00004201 enabled = !enabled;
4202 alc_update_gpio_data(codec, mask, !enabled); /* muted -> LED on */
4203}
4204
4205/* turn on/off mute LED via GPIO per vmaster hook */
4206static void alc_fixup_gpio_mute_hook(void *private_data, int enabled)
4207{
4208 struct hda_codec *codec = private_data;
4209 struct alc_spec *spec = codec->spec;
4210
Olivier Deprez0e641232021-09-23 10:07:05 +02004211 alc_update_gpio_led(codec, spec->gpio_mute_led_mask,
4212 spec->mute_led_polarity, enabled);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00004213}
4214
4215/* turn on/off mic-mute LED via GPIO per capture hook */
4216static void alc_gpio_micmute_update(struct hda_codec *codec)
4217{
4218 struct alc_spec *spec = codec->spec;
4219
4220 alc_update_gpio_led(codec, spec->gpio_mic_led_mask,
Olivier Deprez0e641232021-09-23 10:07:05 +02004221 spec->micmute_led_polarity,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00004222 spec->gen.micmute_led.led_value);
4223}
4224
4225/* setup mute and mic-mute GPIO bits, add hooks appropriately */
4226static void alc_fixup_hp_gpio_led(struct hda_codec *codec,
4227 int action,
4228 unsigned int mute_mask,
4229 unsigned int micmute_mask)
4230{
4231 struct alc_spec *spec = codec->spec;
4232
4233 alc_fixup_gpio(codec, action, mute_mask | micmute_mask);
4234
4235 if (action != HDA_FIXUP_ACT_PRE_PROBE)
4236 return;
4237 if (mute_mask) {
4238 spec->gpio_mute_led_mask = mute_mask;
4239 spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook;
4240 }
4241 if (micmute_mask) {
4242 spec->gpio_mic_led_mask = micmute_mask;
4243 snd_hda_gen_add_micmute_led(codec, alc_gpio_micmute_update);
4244 }
4245}
4246
4247static void alc269_fixup_hp_gpio_led(struct hda_codec *codec,
4248 const struct hda_fixup *fix, int action)
4249{
4250 alc_fixup_hp_gpio_led(codec, action, 0x08, 0x10);
4251}
4252
Olivier Deprez0e641232021-09-23 10:07:05 +02004253static void alc285_fixup_hp_gpio_led(struct hda_codec *codec,
4254 const struct hda_fixup *fix, int action)
4255{
4256 alc_fixup_hp_gpio_led(codec, action, 0x04, 0x00);
4257}
4258
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00004259static void alc286_fixup_hp_gpio_led(struct hda_codec *codec,
4260 const struct hda_fixup *fix, int action)
4261{
4262 alc_fixup_hp_gpio_led(codec, action, 0x02, 0x20);
4263}
4264
4265/* turn on/off mic-mute LED per capture hook */
4266static void alc_cap_micmute_update(struct hda_codec *codec)
4267{
4268 struct alc_spec *spec = codec->spec;
4269 unsigned int pinval;
4270
4271 if (!spec->cap_mute_led_nid)
4272 return;
4273 pinval = snd_hda_codec_get_pin_target(codec, spec->cap_mute_led_nid);
4274 pinval &= ~AC_PINCTL_VREFEN;
4275 if (spec->gen.micmute_led.led_value)
4276 pinval |= AC_PINCTL_VREF_80;
4277 else
4278 pinval |= AC_PINCTL_VREF_HIZ;
4279 snd_hda_set_pin_ctl_cache(codec, spec->cap_mute_led_nid, pinval);
4280}
4281
4282static void alc269_fixup_hp_gpio_mic1_led(struct hda_codec *codec,
4283 const struct hda_fixup *fix, int action)
4284{
4285 struct alc_spec *spec = codec->spec;
4286
4287 alc_fixup_hp_gpio_led(codec, action, 0x08, 0);
4288 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4289 /* Like hp_gpio_mic1_led, but also needs GPIO4 low to
4290 * enable headphone amp
4291 */
4292 spec->gpio_mask |= 0x10;
4293 spec->gpio_dir |= 0x10;
4294 spec->cap_mute_led_nid = 0x18;
4295 snd_hda_gen_add_micmute_led(codec, alc_cap_micmute_update);
4296 codec->power_filter = led_power_filter;
4297 }
4298}
4299
4300static void alc280_fixup_hp_gpio4(struct hda_codec *codec,
4301 const struct hda_fixup *fix, int action)
4302{
4303 struct alc_spec *spec = codec->spec;
4304
4305 alc_fixup_hp_gpio_led(codec, action, 0x08, 0);
4306 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4307 spec->cap_mute_led_nid = 0x18;
4308 snd_hda_gen_add_micmute_led(codec, alc_cap_micmute_update);
4309 codec->power_filter = led_power_filter;
4310 }
4311}
4312
Olivier Deprez0e641232021-09-23 10:07:05 +02004313/* update mute-LED according to the speaker mute state via COEF bit */
4314static void alc_fixup_mute_led_coefbit_hook(void *private_data, int enabled)
4315{
4316 struct hda_codec *codec = private_data;
4317 struct alc_spec *spec = codec->spec;
4318
4319 if (spec->mute_led_polarity)
4320 enabled = !enabled;
4321
4322 /* temporarily power up/down for setting COEF bit */
4323 enabled ? alc_update_coef_idx(codec, spec->mute_led_coef_idx,
4324 spec->mute_led_coefbit_mask, spec->mute_led_coefbit_off) :
4325 alc_update_coef_idx(codec, spec->mute_led_coef_idx,
4326 spec->mute_led_coefbit_mask, spec->mute_led_coefbit_on);
4327}
4328
4329static void alc285_fixup_hp_mute_led_coefbit(struct hda_codec *codec,
4330 const struct hda_fixup *fix,
4331 int action)
4332{
4333 struct alc_spec *spec = codec->spec;
4334
4335 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4336 spec->mute_led_polarity = 0;
4337 spec->mute_led_coef_idx = 0x0b;
4338 spec->mute_led_coefbit_mask = 1<<3;
4339 spec->mute_led_coefbit_on = 1<<3;
4340 spec->mute_led_coefbit_off = 0;
4341 spec->gen.vmaster_mute.hook = alc_fixup_mute_led_coefbit_hook;
4342 spec->gen.vmaster_mute_enum = 1;
4343 }
4344}
4345
4346static void alc236_fixup_hp_mute_led_coefbit(struct hda_codec *codec,
4347 const struct hda_fixup *fix,
4348 int action)
4349{
4350 struct alc_spec *spec = codec->spec;
4351
4352 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4353 spec->mute_led_polarity = 0;
4354 spec->mute_led_coef_idx = 0x34;
4355 spec->mute_led_coefbit_mask = 1<<5;
4356 spec->mute_led_coefbit_on = 0;
4357 spec->mute_led_coefbit_off = 1<<5;
4358 spec->gen.vmaster_mute.hook = alc_fixup_mute_led_coefbit_hook;
4359 spec->gen.vmaster_mute_enum = 1;
4360 }
4361}
4362
4363/* turn on/off mic-mute LED per capture hook by coef bit */
4364static void alc_hp_cap_micmute_update(struct hda_codec *codec)
4365{
4366 struct alc_spec *spec = codec->spec;
4367
4368 if (spec->gen.micmute_led.led_value)
4369 alc_update_coef_idx(codec, spec->mic_led_coef_idx,
4370 spec->mic_led_coefbit_mask, spec->mic_led_coefbit_on);
4371 else
4372 alc_update_coef_idx(codec, spec->mic_led_coef_idx,
4373 spec->mic_led_coefbit_mask, spec->mic_led_coefbit_off);
4374}
4375
4376static void alc285_fixup_hp_coef_micmute_led(struct hda_codec *codec,
4377 const struct hda_fixup *fix, int action)
4378{
4379 struct alc_spec *spec = codec->spec;
4380
4381 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4382 spec->mic_led_coef_idx = 0x19;
4383 spec->mic_led_coefbit_mask = 1<<13;
4384 spec->mic_led_coefbit_on = 1<<13;
4385 spec->mic_led_coefbit_off = 0;
4386 snd_hda_gen_add_micmute_led(codec, alc_hp_cap_micmute_update);
4387 }
4388}
4389
4390static void alc236_fixup_hp_coef_micmute_led(struct hda_codec *codec,
4391 const struct hda_fixup *fix, int action)
4392{
4393 struct alc_spec *spec = codec->spec;
4394
4395 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4396 spec->mic_led_coef_idx = 0x35;
4397 spec->mic_led_coefbit_mask = 3<<2;
4398 spec->mic_led_coefbit_on = 2<<2;
4399 spec->mic_led_coefbit_off = 1<<2;
4400 snd_hda_gen_add_micmute_led(codec, alc_hp_cap_micmute_update);
4401 }
4402}
4403
4404static void alc285_fixup_hp_mute_led(struct hda_codec *codec,
4405 const struct hda_fixup *fix, int action)
4406{
4407 alc285_fixup_hp_mute_led_coefbit(codec, fix, action);
4408 alc285_fixup_hp_coef_micmute_led(codec, fix, action);
4409}
4410
4411static void alc236_fixup_hp_mute_led(struct hda_codec *codec,
4412 const struct hda_fixup *fix, int action)
4413{
4414 alc236_fixup_hp_mute_led_coefbit(codec, fix, action);
4415 alc236_fixup_hp_coef_micmute_led(codec, fix, action);
4416}
4417
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00004418#if IS_REACHABLE(CONFIG_INPUT)
4419static void gpio2_mic_hotkey_event(struct hda_codec *codec,
4420 struct hda_jack_callback *event)
4421{
4422 struct alc_spec *spec = codec->spec;
4423
4424 /* GPIO2 just toggles on a keypress/keyrelease cycle. Therefore
4425 send both key on and key off event for every interrupt. */
4426 input_report_key(spec->kb_dev, spec->alc_mute_keycode_map[ALC_KEY_MICMUTE_INDEX], 1);
4427 input_sync(spec->kb_dev);
4428 input_report_key(spec->kb_dev, spec->alc_mute_keycode_map[ALC_KEY_MICMUTE_INDEX], 0);
4429 input_sync(spec->kb_dev);
4430}
4431
4432static int alc_register_micmute_input_device(struct hda_codec *codec)
4433{
4434 struct alc_spec *spec = codec->spec;
4435 int i;
4436
4437 spec->kb_dev = input_allocate_device();
4438 if (!spec->kb_dev) {
4439 codec_err(codec, "Out of memory (input_allocate_device)\n");
4440 return -ENOMEM;
4441 }
4442
4443 spec->alc_mute_keycode_map[ALC_KEY_MICMUTE_INDEX] = KEY_MICMUTE;
4444
4445 spec->kb_dev->name = "Microphone Mute Button";
4446 spec->kb_dev->evbit[0] = BIT_MASK(EV_KEY);
4447 spec->kb_dev->keycodesize = sizeof(spec->alc_mute_keycode_map[0]);
4448 spec->kb_dev->keycodemax = ARRAY_SIZE(spec->alc_mute_keycode_map);
4449 spec->kb_dev->keycode = spec->alc_mute_keycode_map;
4450 for (i = 0; i < ARRAY_SIZE(spec->alc_mute_keycode_map); i++)
4451 set_bit(spec->alc_mute_keycode_map[i], spec->kb_dev->keybit);
4452
4453 if (input_register_device(spec->kb_dev)) {
4454 codec_err(codec, "input_register_device failed\n");
4455 input_free_device(spec->kb_dev);
4456 spec->kb_dev = NULL;
4457 return -ENOMEM;
4458 }
4459
4460 return 0;
4461}
4462
4463/* GPIO1 = set according to SKU external amp
4464 * GPIO2 = mic mute hotkey
4465 * GPIO3 = mute LED
4466 * GPIO4 = mic mute LED
4467 */
4468static void alc280_fixup_hp_gpio2_mic_hotkey(struct hda_codec *codec,
4469 const struct hda_fixup *fix, int action)
4470{
4471 struct alc_spec *spec = codec->spec;
4472
4473 alc_fixup_hp_gpio_led(codec, action, 0x08, 0x10);
4474 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4475 spec->init_amp = ALC_INIT_DEFAULT;
4476 if (alc_register_micmute_input_device(codec) != 0)
4477 return;
4478
4479 spec->gpio_mask |= 0x06;
4480 spec->gpio_dir |= 0x02;
4481 spec->gpio_data |= 0x02;
4482 snd_hda_codec_write_cache(codec, codec->core.afg, 0,
4483 AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x04);
4484 snd_hda_jack_detect_enable_callback(codec, codec->core.afg,
4485 gpio2_mic_hotkey_event);
4486 return;
4487 }
4488
4489 if (!spec->kb_dev)
4490 return;
4491
4492 switch (action) {
4493 case HDA_FIXUP_ACT_FREE:
4494 input_unregister_device(spec->kb_dev);
4495 spec->kb_dev = NULL;
4496 }
4497}
4498
4499/* Line2 = mic mute hotkey
4500 * GPIO2 = mic mute LED
4501 */
4502static void alc233_fixup_lenovo_line2_mic_hotkey(struct hda_codec *codec,
4503 const struct hda_fixup *fix, int action)
4504{
4505 struct alc_spec *spec = codec->spec;
4506
Olivier Deprez0e641232021-09-23 10:07:05 +02004507 spec->micmute_led_polarity = 1;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00004508 alc_fixup_hp_gpio_led(codec, action, 0, 0x04);
4509 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4510 spec->init_amp = ALC_INIT_DEFAULT;
4511 if (alc_register_micmute_input_device(codec) != 0)
4512 return;
4513
4514 snd_hda_jack_detect_enable_callback(codec, 0x1b,
4515 gpio2_mic_hotkey_event);
4516 return;
4517 }
4518
4519 if (!spec->kb_dev)
4520 return;
4521
4522 switch (action) {
4523 case HDA_FIXUP_ACT_FREE:
4524 input_unregister_device(spec->kb_dev);
4525 spec->kb_dev = NULL;
4526 }
4527}
4528#else /* INPUT */
4529#define alc280_fixup_hp_gpio2_mic_hotkey NULL
4530#define alc233_fixup_lenovo_line2_mic_hotkey NULL
4531#endif /* INPUT */
4532
4533static void alc269_fixup_hp_line1_mic1_led(struct hda_codec *codec,
4534 const struct hda_fixup *fix, int action)
4535{
4536 struct alc_spec *spec = codec->spec;
4537
4538 alc269_fixup_hp_mute_led_micx(codec, fix, action, 0x1a);
4539 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4540 spec->cap_mute_led_nid = 0x18;
4541 snd_hda_gen_add_micmute_led(codec, alc_cap_micmute_update);
4542 }
4543}
4544
Olivier Deprez0e641232021-09-23 10:07:05 +02004545static const struct coef_fw alc225_pre_hsmode[] = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00004546 UPDATE_COEF(0x4a, 1<<8, 0),
4547 UPDATE_COEFEX(0x57, 0x05, 1<<14, 0),
4548 UPDATE_COEF(0x63, 3<<14, 3<<14),
4549 UPDATE_COEF(0x4a, 3<<4, 2<<4),
4550 UPDATE_COEF(0x4a, 3<<10, 3<<10),
4551 UPDATE_COEF(0x45, 0x3f<<10, 0x34<<10),
4552 UPDATE_COEF(0x4a, 3<<10, 0),
4553 {}
4554};
4555
4556static void alc_headset_mode_unplugged(struct hda_codec *codec)
4557{
Olivier Deprez0e641232021-09-23 10:07:05 +02004558 static const struct coef_fw coef0255[] = {
David Brazdil0f672f62019-12-10 10:32:29 +00004559 WRITE_COEF(0x1b, 0x0c0b), /* LDO and MISC control */
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00004560 WRITE_COEF(0x45, 0xd089), /* UAJ function set to menual mode */
4561 UPDATE_COEFEX(0x57, 0x05, 1<<14, 0), /* Direct Drive HP Amp control(Set to verb control)*/
4562 WRITE_COEF(0x06, 0x6104), /* Set MIC2 Vref gate with HP */
4563 WRITE_COEFEX(0x57, 0x03, 0x8aa6), /* Direct Drive HP Amp control */
4564 {}
4565 };
Olivier Deprez0e641232021-09-23 10:07:05 +02004566 static const struct coef_fw coef0256[] = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00004567 WRITE_COEF(0x1b, 0x0c4b), /* LDO and MISC control */
David Brazdil0f672f62019-12-10 10:32:29 +00004568 WRITE_COEF(0x45, 0xd089), /* UAJ function set to menual mode */
4569 WRITE_COEF(0x06, 0x6104), /* Set MIC2 Vref gate with HP */
4570 WRITE_COEFEX(0x57, 0x03, 0x09a3), /* Direct Drive HP Amp control */
4571 UPDATE_COEFEX(0x57, 0x05, 1<<14, 0), /* Direct Drive HP Amp control(Set to verb control)*/
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00004572 {}
4573 };
Olivier Deprez0e641232021-09-23 10:07:05 +02004574 static const struct coef_fw coef0233[] = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00004575 WRITE_COEF(0x1b, 0x0c0b),
4576 WRITE_COEF(0x45, 0xc429),
4577 UPDATE_COEF(0x35, 0x4000, 0),
4578 WRITE_COEF(0x06, 0x2104),
4579 WRITE_COEF(0x1a, 0x0001),
4580 WRITE_COEF(0x26, 0x0004),
4581 WRITE_COEF(0x32, 0x42a3),
4582 {}
4583 };
Olivier Deprez0e641232021-09-23 10:07:05 +02004584 static const struct coef_fw coef0288[] = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00004585 UPDATE_COEF(0x4f, 0xfcc0, 0xc400),
4586 UPDATE_COEF(0x50, 0x2000, 0x2000),
4587 UPDATE_COEF(0x56, 0x0006, 0x0006),
4588 UPDATE_COEF(0x66, 0x0008, 0),
4589 UPDATE_COEF(0x67, 0x2000, 0),
4590 {}
4591 };
Olivier Deprez0e641232021-09-23 10:07:05 +02004592 static const struct coef_fw coef0298[] = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00004593 UPDATE_COEF(0x19, 0x1300, 0x0300),
4594 {}
4595 };
Olivier Deprez0e641232021-09-23 10:07:05 +02004596 static const struct coef_fw coef0292[] = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00004597 WRITE_COEF(0x76, 0x000e),
4598 WRITE_COEF(0x6c, 0x2400),
4599 WRITE_COEF(0x18, 0x7308),
4600 WRITE_COEF(0x6b, 0xc429),
4601 {}
4602 };
Olivier Deprez0e641232021-09-23 10:07:05 +02004603 static const struct coef_fw coef0293[] = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00004604 UPDATE_COEF(0x10, 7<<8, 6<<8), /* SET Line1 JD to 0 */
4605 UPDATE_COEFEX(0x57, 0x05, 1<<15|1<<13, 0x0), /* SET charge pump by verb */
4606 UPDATE_COEFEX(0x57, 0x03, 1<<10, 1<<10), /* SET EN_OSW to 1 */
4607 UPDATE_COEF(0x1a, 1<<3, 1<<3), /* Combo JD gating with LINE1-VREFO */
4608 WRITE_COEF(0x45, 0xc429), /* Set to TRS type */
4609 UPDATE_COEF(0x4a, 0x000f, 0x000e), /* Combo Jack auto detect */
4610 {}
4611 };
Olivier Deprez0e641232021-09-23 10:07:05 +02004612 static const struct coef_fw coef0668[] = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00004613 WRITE_COEF(0x15, 0x0d40),
4614 WRITE_COEF(0xb7, 0x802b),
4615 {}
4616 };
Olivier Deprez0e641232021-09-23 10:07:05 +02004617 static const struct coef_fw coef0225[] = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00004618 UPDATE_COEF(0x63, 3<<14, 0),
4619 {}
4620 };
Olivier Deprez0e641232021-09-23 10:07:05 +02004621 static const struct coef_fw coef0274[] = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00004622 UPDATE_COEF(0x4a, 0x0100, 0),
4623 UPDATE_COEFEX(0x57, 0x05, 0x4000, 0),
4624 UPDATE_COEF(0x6b, 0xf000, 0x5000),
4625 UPDATE_COEF(0x4a, 0x0010, 0),
4626 UPDATE_COEF(0x4a, 0x0c00, 0x0c00),
4627 WRITE_COEF(0x45, 0x5289),
4628 UPDATE_COEF(0x4a, 0x0c00, 0),
4629 {}
4630 };
4631
4632 switch (codec->core.vendor_id) {
4633 case 0x10ec0255:
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00004634 alc_process_coef_fw(codec, coef0255);
4635 break;
Olivier Deprez0e641232021-09-23 10:07:05 +02004636 case 0x10ec0230:
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00004637 case 0x10ec0236:
4638 case 0x10ec0256:
4639 alc_process_coef_fw(codec, coef0256);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00004640 break;
4641 case 0x10ec0234:
4642 case 0x10ec0274:
4643 case 0x10ec0294:
4644 alc_process_coef_fw(codec, coef0274);
4645 break;
4646 case 0x10ec0233:
4647 case 0x10ec0283:
4648 alc_process_coef_fw(codec, coef0233);
4649 break;
4650 case 0x10ec0286:
4651 case 0x10ec0288:
4652 alc_process_coef_fw(codec, coef0288);
4653 break;
4654 case 0x10ec0298:
4655 alc_process_coef_fw(codec, coef0298);
4656 alc_process_coef_fw(codec, coef0288);
4657 break;
4658 case 0x10ec0292:
4659 alc_process_coef_fw(codec, coef0292);
4660 break;
4661 case 0x10ec0293:
4662 alc_process_coef_fw(codec, coef0293);
4663 break;
4664 case 0x10ec0668:
4665 alc_process_coef_fw(codec, coef0668);
4666 break;
4667 case 0x10ec0215:
4668 case 0x10ec0225:
4669 case 0x10ec0285:
4670 case 0x10ec0295:
4671 case 0x10ec0289:
4672 case 0x10ec0299:
David Brazdil0f672f62019-12-10 10:32:29 +00004673 alc_process_coef_fw(codec, alc225_pre_hsmode);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00004674 alc_process_coef_fw(codec, coef0225);
4675 break;
4676 case 0x10ec0867:
4677 alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
4678 break;
4679 }
4680 codec_dbg(codec, "Headset jack set to unplugged mode.\n");
4681}
4682
4683
4684static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin,
4685 hda_nid_t mic_pin)
4686{
Olivier Deprez0e641232021-09-23 10:07:05 +02004687 static const struct coef_fw coef0255[] = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00004688 WRITE_COEFEX(0x57, 0x03, 0x8aa6),
4689 WRITE_COEF(0x06, 0x6100), /* Set MIC2 Vref gate to normal */
4690 {}
4691 };
Olivier Deprez0e641232021-09-23 10:07:05 +02004692 static const struct coef_fw coef0256[] = {
David Brazdil0f672f62019-12-10 10:32:29 +00004693 UPDATE_COEFEX(0x57, 0x05, 1<<14, 1<<14), /* Direct Drive HP Amp control(Set to verb control)*/
4694 WRITE_COEFEX(0x57, 0x03, 0x09a3),
4695 WRITE_COEF(0x06, 0x6100), /* Set MIC2 Vref gate to normal */
4696 {}
4697 };
Olivier Deprez0e641232021-09-23 10:07:05 +02004698 static const struct coef_fw coef0233[] = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00004699 UPDATE_COEF(0x35, 0, 1<<14),
4700 WRITE_COEF(0x06, 0x2100),
4701 WRITE_COEF(0x1a, 0x0021),
4702 WRITE_COEF(0x26, 0x008c),
4703 {}
4704 };
Olivier Deprez0e641232021-09-23 10:07:05 +02004705 static const struct coef_fw coef0288[] = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00004706 UPDATE_COEF(0x4f, 0x00c0, 0),
4707 UPDATE_COEF(0x50, 0x2000, 0),
4708 UPDATE_COEF(0x56, 0x0006, 0),
4709 UPDATE_COEF(0x4f, 0xfcc0, 0xc400),
4710 UPDATE_COEF(0x66, 0x0008, 0x0008),
4711 UPDATE_COEF(0x67, 0x2000, 0x2000),
4712 {}
4713 };
Olivier Deprez0e641232021-09-23 10:07:05 +02004714 static const struct coef_fw coef0292[] = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00004715 WRITE_COEF(0x19, 0xa208),
4716 WRITE_COEF(0x2e, 0xacf0),
4717 {}
4718 };
Olivier Deprez0e641232021-09-23 10:07:05 +02004719 static const struct coef_fw coef0293[] = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00004720 UPDATE_COEFEX(0x57, 0x05, 0, 1<<15|1<<13), /* SET charge pump by verb */
4721 UPDATE_COEFEX(0x57, 0x03, 1<<10, 0), /* SET EN_OSW to 0 */
4722 UPDATE_COEF(0x1a, 1<<3, 0), /* Combo JD gating without LINE1-VREFO */
4723 {}
4724 };
Olivier Deprez0e641232021-09-23 10:07:05 +02004725 static const struct coef_fw coef0688[] = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00004726 WRITE_COEF(0xb7, 0x802b),
4727 WRITE_COEF(0xb5, 0x1040),
4728 UPDATE_COEF(0xc3, 0, 1<<12),
4729 {}
4730 };
Olivier Deprez0e641232021-09-23 10:07:05 +02004731 static const struct coef_fw coef0225[] = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00004732 UPDATE_COEFEX(0x57, 0x05, 1<<14, 1<<14),
4733 UPDATE_COEF(0x4a, 3<<4, 2<<4),
4734 UPDATE_COEF(0x63, 3<<14, 0),
4735 {}
4736 };
Olivier Deprez0e641232021-09-23 10:07:05 +02004737 static const struct coef_fw coef0274[] = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00004738 UPDATE_COEFEX(0x57, 0x05, 0x4000, 0x4000),
4739 UPDATE_COEF(0x4a, 0x0010, 0),
4740 UPDATE_COEF(0x6b, 0xf000, 0),
4741 {}
4742 };
4743
4744 switch (codec->core.vendor_id) {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00004745 case 0x10ec0255:
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00004746 alc_write_coef_idx(codec, 0x45, 0xc489);
4747 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4748 alc_process_coef_fw(codec, coef0255);
4749 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4750 break;
Olivier Deprez0e641232021-09-23 10:07:05 +02004751 case 0x10ec0230:
David Brazdil0f672f62019-12-10 10:32:29 +00004752 case 0x10ec0236:
4753 case 0x10ec0256:
4754 alc_write_coef_idx(codec, 0x45, 0xc489);
4755 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4756 alc_process_coef_fw(codec, coef0256);
4757 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4758 break;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00004759 case 0x10ec0234:
4760 case 0x10ec0274:
4761 case 0x10ec0294:
4762 alc_write_coef_idx(codec, 0x45, 0x4689);
4763 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4764 alc_process_coef_fw(codec, coef0274);
4765 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4766 break;
4767 case 0x10ec0233:
4768 case 0x10ec0283:
4769 alc_write_coef_idx(codec, 0x45, 0xc429);
4770 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4771 alc_process_coef_fw(codec, coef0233);
4772 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4773 break;
4774 case 0x10ec0286:
4775 case 0x10ec0288:
4776 case 0x10ec0298:
4777 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4778 alc_process_coef_fw(codec, coef0288);
4779 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4780 break;
4781 case 0x10ec0292:
4782 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4783 alc_process_coef_fw(codec, coef0292);
4784 break;
4785 case 0x10ec0293:
4786 /* Set to TRS mode */
4787 alc_write_coef_idx(codec, 0x45, 0xc429);
4788 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4789 alc_process_coef_fw(codec, coef0293);
4790 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4791 break;
4792 case 0x10ec0867:
4793 alc_update_coefex_idx(codec, 0x57, 0x5, 0, 1<<14);
4794 /* fallthru */
4795 case 0x10ec0221:
4796 case 0x10ec0662:
4797 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4798 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4799 break;
4800 case 0x10ec0668:
4801 alc_write_coef_idx(codec, 0x11, 0x0001);
4802 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4803 alc_process_coef_fw(codec, coef0688);
4804 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4805 break;
4806 case 0x10ec0215:
4807 case 0x10ec0225:
4808 case 0x10ec0285:
4809 case 0x10ec0295:
4810 case 0x10ec0289:
4811 case 0x10ec0299:
4812 alc_process_coef_fw(codec, alc225_pre_hsmode);
4813 alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x31<<10);
4814 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4815 alc_process_coef_fw(codec, coef0225);
4816 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4817 break;
4818 }
4819 codec_dbg(codec, "Headset jack set to mic-in mode.\n");
4820}
4821
4822static void alc_headset_mode_default(struct hda_codec *codec)
4823{
Olivier Deprez0e641232021-09-23 10:07:05 +02004824 static const struct coef_fw coef0225[] = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00004825 UPDATE_COEF(0x45, 0x3f<<10, 0x30<<10),
4826 UPDATE_COEF(0x45, 0x3f<<10, 0x31<<10),
4827 UPDATE_COEF(0x49, 3<<8, 0<<8),
4828 UPDATE_COEF(0x4a, 3<<4, 3<<4),
4829 UPDATE_COEF(0x63, 3<<14, 0),
4830 UPDATE_COEF(0x67, 0xf000, 0x3000),
4831 {}
4832 };
Olivier Deprez0e641232021-09-23 10:07:05 +02004833 static const struct coef_fw coef0255[] = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00004834 WRITE_COEF(0x45, 0xc089),
4835 WRITE_COEF(0x45, 0xc489),
4836 WRITE_COEFEX(0x57, 0x03, 0x8ea6),
4837 WRITE_COEF(0x49, 0x0049),
4838 {}
4839 };
Olivier Deprez0e641232021-09-23 10:07:05 +02004840 static const struct coef_fw coef0256[] = {
David Brazdil0f672f62019-12-10 10:32:29 +00004841 WRITE_COEF(0x45, 0xc489),
4842 WRITE_COEFEX(0x57, 0x03, 0x0da3),
4843 WRITE_COEF(0x49, 0x0049),
4844 UPDATE_COEFEX(0x57, 0x05, 1<<14, 0), /* Direct Drive HP Amp control(Set to verb control)*/
4845 WRITE_COEF(0x06, 0x6100),
4846 {}
4847 };
Olivier Deprez0e641232021-09-23 10:07:05 +02004848 static const struct coef_fw coef0233[] = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00004849 WRITE_COEF(0x06, 0x2100),
4850 WRITE_COEF(0x32, 0x4ea3),
4851 {}
4852 };
Olivier Deprez0e641232021-09-23 10:07:05 +02004853 static const struct coef_fw coef0288[] = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00004854 UPDATE_COEF(0x4f, 0xfcc0, 0xc400), /* Set to TRS type */
4855 UPDATE_COEF(0x50, 0x2000, 0x2000),
4856 UPDATE_COEF(0x56, 0x0006, 0x0006),
4857 UPDATE_COEF(0x66, 0x0008, 0),
4858 UPDATE_COEF(0x67, 0x2000, 0),
4859 {}
4860 };
Olivier Deprez0e641232021-09-23 10:07:05 +02004861 static const struct coef_fw coef0292[] = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00004862 WRITE_COEF(0x76, 0x000e),
4863 WRITE_COEF(0x6c, 0x2400),
4864 WRITE_COEF(0x6b, 0xc429),
4865 WRITE_COEF(0x18, 0x7308),
4866 {}
4867 };
Olivier Deprez0e641232021-09-23 10:07:05 +02004868 static const struct coef_fw coef0293[] = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00004869 UPDATE_COEF(0x4a, 0x000f, 0x000e), /* Combo Jack auto detect */
4870 WRITE_COEF(0x45, 0xC429), /* Set to TRS type */
4871 UPDATE_COEF(0x1a, 1<<3, 0), /* Combo JD gating without LINE1-VREFO */
4872 {}
4873 };
Olivier Deprez0e641232021-09-23 10:07:05 +02004874 static const struct coef_fw coef0688[] = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00004875 WRITE_COEF(0x11, 0x0041),
4876 WRITE_COEF(0x15, 0x0d40),
4877 WRITE_COEF(0xb7, 0x802b),
4878 {}
4879 };
Olivier Deprez0e641232021-09-23 10:07:05 +02004880 static const struct coef_fw coef0274[] = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00004881 WRITE_COEF(0x45, 0x4289),
4882 UPDATE_COEF(0x4a, 0x0010, 0x0010),
4883 UPDATE_COEF(0x6b, 0x0f00, 0),
4884 UPDATE_COEF(0x49, 0x0300, 0x0300),
4885 {}
4886 };
4887
4888 switch (codec->core.vendor_id) {
4889 case 0x10ec0215:
4890 case 0x10ec0225:
4891 case 0x10ec0285:
4892 case 0x10ec0295:
4893 case 0x10ec0289:
4894 case 0x10ec0299:
4895 alc_process_coef_fw(codec, alc225_pre_hsmode);
4896 alc_process_coef_fw(codec, coef0225);
4897 break;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00004898 case 0x10ec0255:
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00004899 alc_process_coef_fw(codec, coef0255);
4900 break;
Olivier Deprez0e641232021-09-23 10:07:05 +02004901 case 0x10ec0230:
David Brazdil0f672f62019-12-10 10:32:29 +00004902 case 0x10ec0236:
4903 case 0x10ec0256:
4904 alc_write_coef_idx(codec, 0x1b, 0x0e4b);
4905 alc_write_coef_idx(codec, 0x45, 0xc089);
4906 msleep(50);
4907 alc_process_coef_fw(codec, coef0256);
4908 break;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00004909 case 0x10ec0234:
4910 case 0x10ec0274:
4911 case 0x10ec0294:
4912 alc_process_coef_fw(codec, coef0274);
4913 break;
4914 case 0x10ec0233:
4915 case 0x10ec0283:
4916 alc_process_coef_fw(codec, coef0233);
4917 break;
4918 case 0x10ec0286:
4919 case 0x10ec0288:
4920 case 0x10ec0298:
4921 alc_process_coef_fw(codec, coef0288);
4922 break;
4923 case 0x10ec0292:
4924 alc_process_coef_fw(codec, coef0292);
4925 break;
4926 case 0x10ec0293:
4927 alc_process_coef_fw(codec, coef0293);
4928 break;
4929 case 0x10ec0668:
4930 alc_process_coef_fw(codec, coef0688);
4931 break;
4932 case 0x10ec0867:
4933 alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
4934 break;
4935 }
4936 codec_dbg(codec, "Headset jack set to headphone (default) mode.\n");
4937}
4938
4939/* Iphone type */
4940static void alc_headset_mode_ctia(struct hda_codec *codec)
4941{
4942 int val;
4943
Olivier Deprez0e641232021-09-23 10:07:05 +02004944 static const struct coef_fw coef0255[] = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00004945 WRITE_COEF(0x45, 0xd489), /* Set to CTIA type */
4946 WRITE_COEF(0x1b, 0x0c2b),
4947 WRITE_COEFEX(0x57, 0x03, 0x8ea6),
4948 {}
4949 };
Olivier Deprez0e641232021-09-23 10:07:05 +02004950 static const struct coef_fw coef0256[] = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00004951 WRITE_COEF(0x45, 0xd489), /* Set to CTIA type */
David Brazdil0f672f62019-12-10 10:32:29 +00004952 WRITE_COEF(0x1b, 0x0e6b),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00004953 {}
4954 };
Olivier Deprez0e641232021-09-23 10:07:05 +02004955 static const struct coef_fw coef0233[] = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00004956 WRITE_COEF(0x45, 0xd429),
4957 WRITE_COEF(0x1b, 0x0c2b),
4958 WRITE_COEF(0x32, 0x4ea3),
4959 {}
4960 };
Olivier Deprez0e641232021-09-23 10:07:05 +02004961 static const struct coef_fw coef0288[] = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00004962 UPDATE_COEF(0x50, 0x2000, 0x2000),
4963 UPDATE_COEF(0x56, 0x0006, 0x0006),
4964 UPDATE_COEF(0x66, 0x0008, 0),
4965 UPDATE_COEF(0x67, 0x2000, 0),
4966 {}
4967 };
Olivier Deprez0e641232021-09-23 10:07:05 +02004968 static const struct coef_fw coef0292[] = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00004969 WRITE_COEF(0x6b, 0xd429),
4970 WRITE_COEF(0x76, 0x0008),
4971 WRITE_COEF(0x18, 0x7388),
4972 {}
4973 };
Olivier Deprez0e641232021-09-23 10:07:05 +02004974 static const struct coef_fw coef0293[] = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00004975 WRITE_COEF(0x45, 0xd429), /* Set to ctia type */
4976 UPDATE_COEF(0x10, 7<<8, 7<<8), /* SET Line1 JD to 1 */
4977 {}
4978 };
Olivier Deprez0e641232021-09-23 10:07:05 +02004979 static const struct coef_fw coef0688[] = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00004980 WRITE_COEF(0x11, 0x0001),
4981 WRITE_COEF(0x15, 0x0d60),
4982 WRITE_COEF(0xc3, 0x0000),
4983 {}
4984 };
Olivier Deprez0e641232021-09-23 10:07:05 +02004985 static const struct coef_fw coef0225_1[] = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00004986 UPDATE_COEF(0x45, 0x3f<<10, 0x35<<10),
4987 UPDATE_COEF(0x63, 3<<14, 2<<14),
4988 {}
4989 };
Olivier Deprez0e641232021-09-23 10:07:05 +02004990 static const struct coef_fw coef0225_2[] = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00004991 UPDATE_COEF(0x45, 0x3f<<10, 0x35<<10),
4992 UPDATE_COEF(0x63, 3<<14, 1<<14),
4993 {}
4994 };
4995
4996 switch (codec->core.vendor_id) {
4997 case 0x10ec0255:
4998 alc_process_coef_fw(codec, coef0255);
4999 break;
Olivier Deprez0e641232021-09-23 10:07:05 +02005000 case 0x10ec0230:
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00005001 case 0x10ec0236:
5002 case 0x10ec0256:
5003 alc_process_coef_fw(codec, coef0256);
5004 break;
5005 case 0x10ec0234:
5006 case 0x10ec0274:
5007 case 0x10ec0294:
5008 alc_write_coef_idx(codec, 0x45, 0xd689);
5009 break;
5010 case 0x10ec0233:
5011 case 0x10ec0283:
5012 alc_process_coef_fw(codec, coef0233);
5013 break;
5014 case 0x10ec0298:
5015 val = alc_read_coef_idx(codec, 0x50);
5016 if (val & (1 << 12)) {
5017 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0020);
5018 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400);
5019 msleep(300);
5020 } else {
5021 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0010);
5022 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400);
5023 msleep(300);
5024 }
5025 break;
5026 case 0x10ec0286:
5027 case 0x10ec0288:
5028 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400);
5029 msleep(300);
5030 alc_process_coef_fw(codec, coef0288);
5031 break;
5032 case 0x10ec0292:
5033 alc_process_coef_fw(codec, coef0292);
5034 break;
5035 case 0x10ec0293:
5036 alc_process_coef_fw(codec, coef0293);
5037 break;
5038 case 0x10ec0668:
5039 alc_process_coef_fw(codec, coef0688);
5040 break;
5041 case 0x10ec0215:
5042 case 0x10ec0225:
5043 case 0x10ec0285:
5044 case 0x10ec0295:
5045 case 0x10ec0289:
5046 case 0x10ec0299:
5047 val = alc_read_coef_idx(codec, 0x45);
5048 if (val & (1 << 9))
5049 alc_process_coef_fw(codec, coef0225_2);
5050 else
5051 alc_process_coef_fw(codec, coef0225_1);
5052 break;
5053 case 0x10ec0867:
5054 alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
5055 break;
5056 }
5057 codec_dbg(codec, "Headset jack set to iPhone-style headset mode.\n");
5058}
5059
5060/* Nokia type */
5061static void alc_headset_mode_omtp(struct hda_codec *codec)
5062{
Olivier Deprez0e641232021-09-23 10:07:05 +02005063 static const struct coef_fw coef0255[] = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00005064 WRITE_COEF(0x45, 0xe489), /* Set to OMTP Type */
5065 WRITE_COEF(0x1b, 0x0c2b),
5066 WRITE_COEFEX(0x57, 0x03, 0x8ea6),
5067 {}
5068 };
Olivier Deprez0e641232021-09-23 10:07:05 +02005069 static const struct coef_fw coef0256[] = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00005070 WRITE_COEF(0x45, 0xe489), /* Set to OMTP Type */
David Brazdil0f672f62019-12-10 10:32:29 +00005071 WRITE_COEF(0x1b, 0x0e6b),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00005072 {}
5073 };
Olivier Deprez0e641232021-09-23 10:07:05 +02005074 static const struct coef_fw coef0233[] = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00005075 WRITE_COEF(0x45, 0xe429),
5076 WRITE_COEF(0x1b, 0x0c2b),
5077 WRITE_COEF(0x32, 0x4ea3),
5078 {}
5079 };
Olivier Deprez0e641232021-09-23 10:07:05 +02005080 static const struct coef_fw coef0288[] = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00005081 UPDATE_COEF(0x50, 0x2000, 0x2000),
5082 UPDATE_COEF(0x56, 0x0006, 0x0006),
5083 UPDATE_COEF(0x66, 0x0008, 0),
5084 UPDATE_COEF(0x67, 0x2000, 0),
5085 {}
5086 };
Olivier Deprez0e641232021-09-23 10:07:05 +02005087 static const struct coef_fw coef0292[] = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00005088 WRITE_COEF(0x6b, 0xe429),
5089 WRITE_COEF(0x76, 0x0008),
5090 WRITE_COEF(0x18, 0x7388),
5091 {}
5092 };
Olivier Deprez0e641232021-09-23 10:07:05 +02005093 static const struct coef_fw coef0293[] = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00005094 WRITE_COEF(0x45, 0xe429), /* Set to omtp type */
5095 UPDATE_COEF(0x10, 7<<8, 7<<8), /* SET Line1 JD to 1 */
5096 {}
5097 };
Olivier Deprez0e641232021-09-23 10:07:05 +02005098 static const struct coef_fw coef0688[] = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00005099 WRITE_COEF(0x11, 0x0001),
5100 WRITE_COEF(0x15, 0x0d50),
5101 WRITE_COEF(0xc3, 0x0000),
5102 {}
5103 };
Olivier Deprez0e641232021-09-23 10:07:05 +02005104 static const struct coef_fw coef0225[] = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00005105 UPDATE_COEF(0x45, 0x3f<<10, 0x39<<10),
5106 UPDATE_COEF(0x63, 3<<14, 2<<14),
5107 {}
5108 };
5109
5110 switch (codec->core.vendor_id) {
5111 case 0x10ec0255:
5112 alc_process_coef_fw(codec, coef0255);
5113 break;
Olivier Deprez0e641232021-09-23 10:07:05 +02005114 case 0x10ec0230:
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00005115 case 0x10ec0236:
5116 case 0x10ec0256:
5117 alc_process_coef_fw(codec, coef0256);
5118 break;
5119 case 0x10ec0234:
5120 case 0x10ec0274:
5121 case 0x10ec0294:
5122 alc_write_coef_idx(codec, 0x45, 0xe689);
5123 break;
5124 case 0x10ec0233:
5125 case 0x10ec0283:
5126 alc_process_coef_fw(codec, coef0233);
5127 break;
5128 case 0x10ec0298:
5129 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0010);/* Headset output enable */
5130 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xe400);
5131 msleep(300);
5132 break;
5133 case 0x10ec0286:
5134 case 0x10ec0288:
5135 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xe400);
5136 msleep(300);
5137 alc_process_coef_fw(codec, coef0288);
5138 break;
5139 case 0x10ec0292:
5140 alc_process_coef_fw(codec, coef0292);
5141 break;
5142 case 0x10ec0293:
5143 alc_process_coef_fw(codec, coef0293);
5144 break;
5145 case 0x10ec0668:
5146 alc_process_coef_fw(codec, coef0688);
5147 break;
5148 case 0x10ec0215:
5149 case 0x10ec0225:
5150 case 0x10ec0285:
5151 case 0x10ec0295:
5152 case 0x10ec0289:
5153 case 0x10ec0299:
5154 alc_process_coef_fw(codec, coef0225);
5155 break;
5156 }
5157 codec_dbg(codec, "Headset jack set to Nokia-style headset mode.\n");
5158}
5159
5160static void alc_determine_headset_type(struct hda_codec *codec)
5161{
5162 int val;
5163 bool is_ctia = false;
5164 struct alc_spec *spec = codec->spec;
Olivier Deprez0e641232021-09-23 10:07:05 +02005165 static const struct coef_fw coef0255[] = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00005166 WRITE_COEF(0x45, 0xd089), /* combo jack auto switch control(Check type)*/
5167 WRITE_COEF(0x49, 0x0149), /* combo jack auto switch control(Vref
5168 conteol) */
5169 {}
5170 };
Olivier Deprez0e641232021-09-23 10:07:05 +02005171 static const struct coef_fw coef0288[] = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00005172 UPDATE_COEF(0x4f, 0xfcc0, 0xd400), /* Check Type */
5173 {}
5174 };
Olivier Deprez0e641232021-09-23 10:07:05 +02005175 static const struct coef_fw coef0298[] = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00005176 UPDATE_COEF(0x50, 0x2000, 0x2000),
5177 UPDATE_COEF(0x56, 0x0006, 0x0006),
5178 UPDATE_COEF(0x66, 0x0008, 0),
5179 UPDATE_COEF(0x67, 0x2000, 0),
5180 UPDATE_COEF(0x19, 0x1300, 0x1300),
5181 {}
5182 };
Olivier Deprez0e641232021-09-23 10:07:05 +02005183 static const struct coef_fw coef0293[] = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00005184 UPDATE_COEF(0x4a, 0x000f, 0x0008), /* Combo Jack auto detect */
5185 WRITE_COEF(0x45, 0xD429), /* Set to ctia type */
5186 {}
5187 };
Olivier Deprez0e641232021-09-23 10:07:05 +02005188 static const struct coef_fw coef0688[] = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00005189 WRITE_COEF(0x11, 0x0001),
5190 WRITE_COEF(0xb7, 0x802b),
5191 WRITE_COEF(0x15, 0x0d60),
5192 WRITE_COEF(0xc3, 0x0c00),
5193 {}
5194 };
Olivier Deprez0e641232021-09-23 10:07:05 +02005195 static const struct coef_fw coef0274[] = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00005196 UPDATE_COEF(0x4a, 0x0010, 0),
5197 UPDATE_COEF(0x4a, 0x8000, 0),
5198 WRITE_COEF(0x45, 0xd289),
5199 UPDATE_COEF(0x49, 0x0300, 0x0300),
5200 {}
5201 };
5202
5203 switch (codec->core.vendor_id) {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00005204 case 0x10ec0255:
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00005205 alc_process_coef_fw(codec, coef0255);
5206 msleep(300);
5207 val = alc_read_coef_idx(codec, 0x46);
5208 is_ctia = (val & 0x0070) == 0x0070;
5209 break;
Olivier Deprez0e641232021-09-23 10:07:05 +02005210 case 0x10ec0230:
David Brazdil0f672f62019-12-10 10:32:29 +00005211 case 0x10ec0236:
5212 case 0x10ec0256:
5213 alc_write_coef_idx(codec, 0x1b, 0x0e4b);
5214 alc_write_coef_idx(codec, 0x06, 0x6104);
5215 alc_write_coefex_idx(codec, 0x57, 0x3, 0x09a3);
5216
5217 snd_hda_codec_write(codec, 0x21, 0,
5218 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
5219 msleep(80);
5220 snd_hda_codec_write(codec, 0x21, 0,
5221 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
5222
5223 alc_process_coef_fw(codec, coef0255);
5224 msleep(300);
5225 val = alc_read_coef_idx(codec, 0x46);
5226 is_ctia = (val & 0x0070) == 0x0070;
5227
5228 alc_write_coefex_idx(codec, 0x57, 0x3, 0x0da3);
5229 alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
5230
5231 snd_hda_codec_write(codec, 0x21, 0,
5232 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
5233 msleep(80);
5234 snd_hda_codec_write(codec, 0x21, 0,
5235 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
5236 break;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00005237 case 0x10ec0234:
5238 case 0x10ec0274:
5239 case 0x10ec0294:
5240 alc_process_coef_fw(codec, coef0274);
Olivier Deprez0e641232021-09-23 10:07:05 +02005241 msleep(850);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00005242 val = alc_read_coef_idx(codec, 0x46);
5243 is_ctia = (val & 0x00f0) == 0x00f0;
5244 break;
5245 case 0x10ec0233:
5246 case 0x10ec0283:
5247 alc_write_coef_idx(codec, 0x45, 0xd029);
5248 msleep(300);
5249 val = alc_read_coef_idx(codec, 0x46);
5250 is_ctia = (val & 0x0070) == 0x0070;
5251 break;
5252 case 0x10ec0298:
5253 snd_hda_codec_write(codec, 0x21, 0,
5254 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
5255 msleep(100);
5256 snd_hda_codec_write(codec, 0x21, 0,
5257 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
5258 msleep(200);
5259
5260 val = alc_read_coef_idx(codec, 0x50);
5261 if (val & (1 << 12)) {
5262 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0020);
5263 alc_process_coef_fw(codec, coef0288);
5264 msleep(350);
5265 val = alc_read_coef_idx(codec, 0x50);
5266 is_ctia = (val & 0x0070) == 0x0070;
5267 } else {
5268 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0010);
5269 alc_process_coef_fw(codec, coef0288);
5270 msleep(350);
5271 val = alc_read_coef_idx(codec, 0x50);
5272 is_ctia = (val & 0x0070) == 0x0070;
5273 }
5274 alc_process_coef_fw(codec, coef0298);
5275 snd_hda_codec_write(codec, 0x21, 0,
5276 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP);
5277 msleep(75);
5278 snd_hda_codec_write(codec, 0x21, 0,
5279 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
5280 break;
5281 case 0x10ec0286:
5282 case 0x10ec0288:
5283 alc_process_coef_fw(codec, coef0288);
5284 msleep(350);
5285 val = alc_read_coef_idx(codec, 0x50);
5286 is_ctia = (val & 0x0070) == 0x0070;
5287 break;
5288 case 0x10ec0292:
5289 alc_write_coef_idx(codec, 0x6b, 0xd429);
5290 msleep(300);
5291 val = alc_read_coef_idx(codec, 0x6c);
5292 is_ctia = (val & 0x001c) == 0x001c;
5293 break;
5294 case 0x10ec0293:
5295 alc_process_coef_fw(codec, coef0293);
5296 msleep(300);
5297 val = alc_read_coef_idx(codec, 0x46);
5298 is_ctia = (val & 0x0070) == 0x0070;
5299 break;
5300 case 0x10ec0668:
5301 alc_process_coef_fw(codec, coef0688);
5302 msleep(300);
5303 val = alc_read_coef_idx(codec, 0xbe);
5304 is_ctia = (val & 0x1c02) == 0x1c02;
5305 break;
5306 case 0x10ec0215:
5307 case 0x10ec0225:
5308 case 0x10ec0285:
5309 case 0x10ec0295:
5310 case 0x10ec0289:
5311 case 0x10ec0299:
5312 snd_hda_codec_write(codec, 0x21, 0,
5313 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
5314 msleep(80);
5315 snd_hda_codec_write(codec, 0x21, 0,
5316 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
5317
5318 alc_process_coef_fw(codec, alc225_pre_hsmode);
5319 alc_update_coef_idx(codec, 0x67, 0xf000, 0x1000);
5320 val = alc_read_coef_idx(codec, 0x45);
5321 if (val & (1 << 9)) {
5322 alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x34<<10);
5323 alc_update_coef_idx(codec, 0x49, 3<<8, 2<<8);
5324 msleep(800);
5325 val = alc_read_coef_idx(codec, 0x46);
5326 is_ctia = (val & 0x00f0) == 0x00f0;
5327 } else {
5328 alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x34<<10);
5329 alc_update_coef_idx(codec, 0x49, 3<<8, 1<<8);
5330 msleep(800);
5331 val = alc_read_coef_idx(codec, 0x46);
5332 is_ctia = (val & 0x00f0) == 0x00f0;
5333 }
5334 alc_update_coef_idx(codec, 0x4a, 7<<6, 7<<6);
5335 alc_update_coef_idx(codec, 0x4a, 3<<4, 3<<4);
5336 alc_update_coef_idx(codec, 0x67, 0xf000, 0x3000);
5337
5338 snd_hda_codec_write(codec, 0x21, 0,
5339 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
5340 msleep(80);
5341 snd_hda_codec_write(codec, 0x21, 0,
5342 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
5343 break;
5344 case 0x10ec0867:
5345 is_ctia = true;
5346 break;
5347 }
5348
5349 codec_dbg(codec, "Headset jack detected iPhone-style headset: %s\n",
5350 is_ctia ? "yes" : "no");
5351 spec->current_headset_type = is_ctia ? ALC_HEADSET_TYPE_CTIA : ALC_HEADSET_TYPE_OMTP;
5352}
5353
5354static void alc_update_headset_mode(struct hda_codec *codec)
5355{
5356 struct alc_spec *spec = codec->spec;
5357
5358 hda_nid_t mux_pin = spec->gen.imux_pins[spec->gen.cur_mux[0]];
David Brazdil0f672f62019-12-10 10:32:29 +00005359 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00005360
5361 int new_headset_mode;
5362
5363 if (!snd_hda_jack_detect(codec, hp_pin))
5364 new_headset_mode = ALC_HEADSET_MODE_UNPLUGGED;
5365 else if (mux_pin == spec->headset_mic_pin)
5366 new_headset_mode = ALC_HEADSET_MODE_HEADSET;
5367 else if (mux_pin == spec->headphone_mic_pin)
5368 new_headset_mode = ALC_HEADSET_MODE_MIC;
5369 else
5370 new_headset_mode = ALC_HEADSET_MODE_HEADPHONE;
5371
5372 if (new_headset_mode == spec->current_headset_mode) {
5373 snd_hda_gen_update_outputs(codec);
5374 return;
5375 }
5376
5377 switch (new_headset_mode) {
5378 case ALC_HEADSET_MODE_UNPLUGGED:
5379 alc_headset_mode_unplugged(codec);
David Brazdil0f672f62019-12-10 10:32:29 +00005380 spec->current_headset_mode = ALC_HEADSET_MODE_UNKNOWN;
5381 spec->current_headset_type = ALC_HEADSET_TYPE_UNKNOWN;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00005382 spec->gen.hp_jack_present = false;
5383 break;
5384 case ALC_HEADSET_MODE_HEADSET:
5385 if (spec->current_headset_type == ALC_HEADSET_TYPE_UNKNOWN)
5386 alc_determine_headset_type(codec);
5387 if (spec->current_headset_type == ALC_HEADSET_TYPE_CTIA)
5388 alc_headset_mode_ctia(codec);
5389 else if (spec->current_headset_type == ALC_HEADSET_TYPE_OMTP)
5390 alc_headset_mode_omtp(codec);
5391 spec->gen.hp_jack_present = true;
5392 break;
5393 case ALC_HEADSET_MODE_MIC:
5394 alc_headset_mode_mic_in(codec, hp_pin, spec->headphone_mic_pin);
5395 spec->gen.hp_jack_present = false;
5396 break;
5397 case ALC_HEADSET_MODE_HEADPHONE:
5398 alc_headset_mode_default(codec);
5399 spec->gen.hp_jack_present = true;
5400 break;
5401 }
5402 if (new_headset_mode != ALC_HEADSET_MODE_MIC) {
5403 snd_hda_set_pin_ctl_cache(codec, hp_pin,
5404 AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN);
5405 if (spec->headphone_mic_pin && spec->headphone_mic_pin != hp_pin)
5406 snd_hda_set_pin_ctl_cache(codec, spec->headphone_mic_pin,
5407 PIN_VREFHIZ);
5408 }
5409 spec->current_headset_mode = new_headset_mode;
5410
5411 snd_hda_gen_update_outputs(codec);
5412}
5413
5414static void alc_update_headset_mode_hook(struct hda_codec *codec,
5415 struct snd_kcontrol *kcontrol,
5416 struct snd_ctl_elem_value *ucontrol)
5417{
5418 alc_update_headset_mode(codec);
5419}
5420
5421static void alc_update_headset_jack_cb(struct hda_codec *codec,
5422 struct hda_jack_callback *jack)
5423{
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00005424 snd_hda_gen_hp_automute(codec, jack);
Olivier Deprez0e641232021-09-23 10:07:05 +02005425 alc_update_headset_mode(codec);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00005426}
5427
5428static void alc_probe_headset_mode(struct hda_codec *codec)
5429{
5430 int i;
5431 struct alc_spec *spec = codec->spec;
5432 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
5433
5434 /* Find mic pins */
5435 for (i = 0; i < cfg->num_inputs; i++) {
5436 if (cfg->inputs[i].is_headset_mic && !spec->headset_mic_pin)
5437 spec->headset_mic_pin = cfg->inputs[i].pin;
5438 if (cfg->inputs[i].is_headphone_mic && !spec->headphone_mic_pin)
5439 spec->headphone_mic_pin = cfg->inputs[i].pin;
5440 }
5441
5442 WARN_ON(spec->gen.cap_sync_hook);
5443 spec->gen.cap_sync_hook = alc_update_headset_mode_hook;
5444 spec->gen.automute_hook = alc_update_headset_mode;
5445 spec->gen.hp_automute_hook = alc_update_headset_jack_cb;
5446}
5447
5448static void alc_fixup_headset_mode(struct hda_codec *codec,
5449 const struct hda_fixup *fix, int action)
5450{
5451 struct alc_spec *spec = codec->spec;
5452
5453 switch (action) {
5454 case HDA_FIXUP_ACT_PRE_PROBE:
5455 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC | HDA_PINCFG_HEADPHONE_MIC;
5456 break;
5457 case HDA_FIXUP_ACT_PROBE:
5458 alc_probe_headset_mode(codec);
5459 break;
5460 case HDA_FIXUP_ACT_INIT:
David Brazdil0f672f62019-12-10 10:32:29 +00005461 if (is_s3_resume(codec) || is_s4_resume(codec)) {
5462 spec->current_headset_mode = ALC_HEADSET_MODE_UNKNOWN;
5463 spec->current_headset_type = ALC_HEADSET_TYPE_UNKNOWN;
5464 }
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00005465 alc_update_headset_mode(codec);
5466 break;
5467 }
5468}
5469
5470static void alc_fixup_headset_mode_no_hp_mic(struct hda_codec *codec,
5471 const struct hda_fixup *fix, int action)
5472{
5473 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5474 struct alc_spec *spec = codec->spec;
5475 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
5476 }
5477 else
5478 alc_fixup_headset_mode(codec, fix, action);
5479}
5480
5481static void alc255_set_default_jack_type(struct hda_codec *codec)
5482{
5483 /* Set to iphone type */
Olivier Deprez0e641232021-09-23 10:07:05 +02005484 static const struct coef_fw alc255fw[] = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00005485 WRITE_COEF(0x1b, 0x880b),
5486 WRITE_COEF(0x45, 0xd089),
5487 WRITE_COEF(0x1b, 0x080b),
5488 WRITE_COEF(0x46, 0x0004),
5489 WRITE_COEF(0x1b, 0x0c0b),
5490 {}
5491 };
Olivier Deprez0e641232021-09-23 10:07:05 +02005492 static const struct coef_fw alc256fw[] = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00005493 WRITE_COEF(0x1b, 0x884b),
5494 WRITE_COEF(0x45, 0xd089),
5495 WRITE_COEF(0x1b, 0x084b),
5496 WRITE_COEF(0x46, 0x0004),
5497 WRITE_COEF(0x1b, 0x0c4b),
5498 {}
5499 };
5500 switch (codec->core.vendor_id) {
5501 case 0x10ec0255:
5502 alc_process_coef_fw(codec, alc255fw);
5503 break;
Olivier Deprez0e641232021-09-23 10:07:05 +02005504 case 0x10ec0230:
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00005505 case 0x10ec0236:
5506 case 0x10ec0256:
5507 alc_process_coef_fw(codec, alc256fw);
5508 break;
5509 }
5510 msleep(30);
5511}
5512
5513static void alc_fixup_headset_mode_alc255(struct hda_codec *codec,
5514 const struct hda_fixup *fix, int action)
5515{
5516 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5517 alc255_set_default_jack_type(codec);
5518 }
5519 alc_fixup_headset_mode(codec, fix, action);
5520}
5521
5522static void alc_fixup_headset_mode_alc255_no_hp_mic(struct hda_codec *codec,
5523 const struct hda_fixup *fix, int action)
5524{
5525 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5526 struct alc_spec *spec = codec->spec;
5527 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
5528 alc255_set_default_jack_type(codec);
5529 }
5530 else
5531 alc_fixup_headset_mode(codec, fix, action);
5532}
5533
5534static void alc288_update_headset_jack_cb(struct hda_codec *codec,
5535 struct hda_jack_callback *jack)
5536{
5537 struct alc_spec *spec = codec->spec;
5538
5539 alc_update_headset_jack_cb(codec, jack);
5540 /* Headset Mic enable or disable, only for Dell Dino */
5541 alc_update_gpio_data(codec, 0x40, spec->gen.hp_jack_present);
5542}
5543
5544static void alc_fixup_headset_mode_dell_alc288(struct hda_codec *codec,
5545 const struct hda_fixup *fix, int action)
5546{
5547 alc_fixup_headset_mode(codec, fix, action);
5548 if (action == HDA_FIXUP_ACT_PROBE) {
5549 struct alc_spec *spec = codec->spec;
5550 /* toggled via hp_automute_hook */
5551 spec->gpio_mask |= 0x40;
5552 spec->gpio_dir |= 0x40;
5553 spec->gen.hp_automute_hook = alc288_update_headset_jack_cb;
5554 }
5555}
5556
5557static void alc_fixup_auto_mute_via_amp(struct hda_codec *codec,
5558 const struct hda_fixup *fix, int action)
5559{
5560 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5561 struct alc_spec *spec = codec->spec;
5562 spec->gen.auto_mute_via_amp = 1;
5563 }
5564}
5565
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00005566static void alc_fixup_no_shutup(struct hda_codec *codec,
5567 const struct hda_fixup *fix, int action)
5568{
5569 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5570 struct alc_spec *spec = codec->spec;
David Brazdil0f672f62019-12-10 10:32:29 +00005571 spec->no_shutup_pins = 1;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00005572 }
5573}
5574
5575static void alc_fixup_disable_aamix(struct hda_codec *codec,
5576 const struct hda_fixup *fix, int action)
5577{
5578 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5579 struct alc_spec *spec = codec->spec;
5580 /* Disable AA-loopback as it causes white noise */
5581 spec->gen.mixer_nid = 0;
5582 }
5583}
5584
5585/* fixup for Thinkpad docks: add dock pins, avoid HP parser fixup */
5586static void alc_fixup_tpt440_dock(struct hda_codec *codec,
5587 const struct hda_fixup *fix, int action)
5588{
5589 static const struct hda_pintbl pincfgs[] = {
5590 { 0x16, 0x21211010 }, /* dock headphone */
5591 { 0x19, 0x21a11010 }, /* dock mic */
5592 { }
5593 };
5594 struct alc_spec *spec = codec->spec;
5595
5596 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
David Brazdil0f672f62019-12-10 10:32:29 +00005597 spec->reboot_notify = snd_hda_gen_reboot_notify; /* reduce noise */
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00005598 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
5599 codec->power_save_node = 0; /* avoid click noises */
5600 snd_hda_apply_pincfgs(codec, pincfgs);
5601 }
5602}
5603
5604static void alc_fixup_tpt470_dock(struct hda_codec *codec,
5605 const struct hda_fixup *fix, int action)
5606{
5607 static const struct hda_pintbl pincfgs[] = {
5608 { 0x17, 0x21211010 }, /* dock headphone */
5609 { 0x19, 0x21a11010 }, /* dock mic */
5610 { }
5611 };
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00005612 struct alc_spec *spec = codec->spec;
5613
5614 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00005615 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
5616 snd_hda_apply_pincfgs(codec, pincfgs);
5617 } else if (action == HDA_FIXUP_ACT_INIT) {
5618 /* Enable DOCK device */
5619 snd_hda_codec_write(codec, 0x17, 0,
5620 AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0);
5621 /* Enable DOCK device */
5622 snd_hda_codec_write(codec, 0x19, 0,
5623 AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0);
5624 }
5625}
5626
Olivier Deprez0e641232021-09-23 10:07:05 +02005627static void alc_fixup_tpt470_dacs(struct hda_codec *codec,
5628 const struct hda_fixup *fix, int action)
5629{
5630 /* Assure the speaker pin to be coupled with DAC NID 0x03; otherwise
5631 * the speaker output becomes too low by some reason on Thinkpads with
5632 * ALC298 codec
5633 */
5634 static const hda_nid_t preferred_pairs[] = {
5635 0x14, 0x03, 0x17, 0x02, 0x21, 0x02,
5636 0
5637 };
5638 struct alc_spec *spec = codec->spec;
5639
5640 if (action == HDA_FIXUP_ACT_PRE_PROBE)
5641 spec->gen.preferred_dacs = preferred_pairs;
5642}
5643
5644static void alc295_fixup_asus_dacs(struct hda_codec *codec,
5645 const struct hda_fixup *fix, int action)
5646{
5647 static const hda_nid_t preferred_pairs[] = {
5648 0x17, 0x02, 0x21, 0x03, 0
5649 };
5650 struct alc_spec *spec = codec->spec;
5651
5652 if (action == HDA_FIXUP_ACT_PRE_PROBE)
5653 spec->gen.preferred_dacs = preferred_pairs;
5654}
5655
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00005656static void alc_shutup_dell_xps13(struct hda_codec *codec)
5657{
5658 struct alc_spec *spec = codec->spec;
David Brazdil0f672f62019-12-10 10:32:29 +00005659 int hp_pin = alc_get_hp_pin(spec);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00005660
5661 /* Prevent pop noises when headphones are plugged in */
5662 snd_hda_codec_write(codec, hp_pin, 0,
5663 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
5664 msleep(20);
5665}
5666
5667static void alc_fixup_dell_xps13(struct hda_codec *codec,
5668 const struct hda_fixup *fix, int action)
5669{
5670 struct alc_spec *spec = codec->spec;
5671 struct hda_input_mux *imux = &spec->gen.input_mux;
5672 int i;
5673
5674 switch (action) {
5675 case HDA_FIXUP_ACT_PRE_PROBE:
5676 /* mic pin 0x19 must be initialized with Vref Hi-Z, otherwise
5677 * it causes a click noise at start up
5678 */
5679 snd_hda_codec_set_pin_target(codec, 0x19, PIN_VREFHIZ);
5680 spec->shutup = alc_shutup_dell_xps13;
5681 break;
5682 case HDA_FIXUP_ACT_PROBE:
5683 /* Make the internal mic the default input source. */
5684 for (i = 0; i < imux->num_items; i++) {
5685 if (spec->gen.imux_pins[i] == 0x12) {
5686 spec->gen.cur_mux[0] = i;
5687 break;
5688 }
5689 }
5690 break;
5691 }
5692}
5693
5694static void alc_fixup_headset_mode_alc662(struct hda_codec *codec,
5695 const struct hda_fixup *fix, int action)
5696{
5697 struct alc_spec *spec = codec->spec;
5698
5699 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5700 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
5701 spec->gen.hp_mic = 1; /* Mic-in is same pin as headphone */
5702
5703 /* Disable boost for mic-in permanently. (This code is only called
5704 from quirks that guarantee that the headphone is at NID 0x1b.) */
5705 snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000);
5706 snd_hda_override_wcaps(codec, 0x1b, get_wcaps(codec, 0x1b) & ~AC_WCAP_IN_AMP);
5707 } else
5708 alc_fixup_headset_mode(codec, fix, action);
5709}
5710
5711static void alc_fixup_headset_mode_alc668(struct hda_codec *codec,
5712 const struct hda_fixup *fix, int action)
5713{
5714 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5715 alc_write_coef_idx(codec, 0xc4, 0x8000);
5716 alc_update_coef_idx(codec, 0xc2, ~0xfe, 0);
5717 snd_hda_set_pin_ctl_cache(codec, 0x18, 0);
5718 }
5719 alc_fixup_headset_mode(codec, fix, action);
5720}
5721
5722/* Returns the nid of the external mic input pin, or 0 if it cannot be found. */
5723static int find_ext_mic_pin(struct hda_codec *codec)
5724{
5725 struct alc_spec *spec = codec->spec;
5726 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
5727 hda_nid_t nid;
5728 unsigned int defcfg;
5729 int i;
5730
5731 for (i = 0; i < cfg->num_inputs; i++) {
5732 if (cfg->inputs[i].type != AUTO_PIN_MIC)
5733 continue;
5734 nid = cfg->inputs[i].pin;
5735 defcfg = snd_hda_codec_get_pincfg(codec, nid);
5736 if (snd_hda_get_input_pin_attr(defcfg) == INPUT_PIN_ATTR_INT)
5737 continue;
5738 return nid;
5739 }
5740
5741 return 0;
5742}
5743
5744static void alc271_hp_gate_mic_jack(struct hda_codec *codec,
5745 const struct hda_fixup *fix,
5746 int action)
5747{
5748 struct alc_spec *spec = codec->spec;
5749
5750 if (action == HDA_FIXUP_ACT_PROBE) {
5751 int mic_pin = find_ext_mic_pin(codec);
David Brazdil0f672f62019-12-10 10:32:29 +00005752 int hp_pin = alc_get_hp_pin(spec);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00005753
5754 if (snd_BUG_ON(!mic_pin || !hp_pin))
5755 return;
5756 snd_hda_jack_set_gating_jack(codec, mic_pin, hp_pin);
5757 }
5758}
5759
5760static void alc269_fixup_limit_int_mic_boost(struct hda_codec *codec,
5761 const struct hda_fixup *fix,
5762 int action)
5763{
5764 struct alc_spec *spec = codec->spec;
5765 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
5766 int i;
5767
5768 /* The mic boosts on level 2 and 3 are too noisy
5769 on the internal mic input.
5770 Therefore limit the boost to 0 or 1. */
5771
5772 if (action != HDA_FIXUP_ACT_PROBE)
5773 return;
5774
5775 for (i = 0; i < cfg->num_inputs; i++) {
5776 hda_nid_t nid = cfg->inputs[i].pin;
5777 unsigned int defcfg;
5778 if (cfg->inputs[i].type != AUTO_PIN_MIC)
5779 continue;
5780 defcfg = snd_hda_codec_get_pincfg(codec, nid);
5781 if (snd_hda_get_input_pin_attr(defcfg) != INPUT_PIN_ATTR_INT)
5782 continue;
5783
5784 snd_hda_override_amp_caps(codec, nid, HDA_INPUT,
5785 (0x00 << AC_AMPCAP_OFFSET_SHIFT) |
5786 (0x01 << AC_AMPCAP_NUM_STEPS_SHIFT) |
5787 (0x2f << AC_AMPCAP_STEP_SIZE_SHIFT) |
5788 (0 << AC_AMPCAP_MUTE_SHIFT));
5789 }
5790}
5791
5792static void alc283_hp_automute_hook(struct hda_codec *codec,
5793 struct hda_jack_callback *jack)
5794{
5795 struct alc_spec *spec = codec->spec;
5796 int vref;
5797
5798 msleep(200);
5799 snd_hda_gen_hp_automute(codec, jack);
5800
5801 vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0;
5802
5803 msleep(600);
5804 snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5805 vref);
5806}
5807
5808static void alc283_fixup_chromebook(struct hda_codec *codec,
5809 const struct hda_fixup *fix, int action)
5810{
5811 struct alc_spec *spec = codec->spec;
5812
5813 switch (action) {
5814 case HDA_FIXUP_ACT_PRE_PROBE:
5815 snd_hda_override_wcaps(codec, 0x03, 0);
5816 /* Disable AA-loopback as it causes white noise */
5817 spec->gen.mixer_nid = 0;
5818 break;
5819 case HDA_FIXUP_ACT_INIT:
5820 /* MIC2-VREF control */
5821 /* Set to manual mode */
5822 alc_update_coef_idx(codec, 0x06, 0x000c, 0);
5823 /* Enable Line1 input control by verb */
5824 alc_update_coef_idx(codec, 0x1a, 0, 1 << 4);
5825 break;
5826 }
5827}
5828
5829static void alc283_fixup_sense_combo_jack(struct hda_codec *codec,
5830 const struct hda_fixup *fix, int action)
5831{
5832 struct alc_spec *spec = codec->spec;
5833
5834 switch (action) {
5835 case HDA_FIXUP_ACT_PRE_PROBE:
5836 spec->gen.hp_automute_hook = alc283_hp_automute_hook;
5837 break;
5838 case HDA_FIXUP_ACT_INIT:
5839 /* MIC2-VREF control */
5840 /* Set to manual mode */
5841 alc_update_coef_idx(codec, 0x06, 0x000c, 0);
5842 break;
5843 }
5844}
5845
5846/* mute tablet speaker pin (0x14) via dock plugging in addition */
5847static void asus_tx300_automute(struct hda_codec *codec)
5848{
5849 struct alc_spec *spec = codec->spec;
5850 snd_hda_gen_update_outputs(codec);
5851 if (snd_hda_jack_detect(codec, 0x1b))
5852 spec->gen.mute_bits |= (1ULL << 0x14);
5853}
5854
5855static void alc282_fixup_asus_tx300(struct hda_codec *codec,
5856 const struct hda_fixup *fix, int action)
5857{
5858 struct alc_spec *spec = codec->spec;
5859 static const struct hda_pintbl dock_pins[] = {
5860 { 0x1b, 0x21114000 }, /* dock speaker pin */
5861 {}
5862 };
5863
5864 switch (action) {
5865 case HDA_FIXUP_ACT_PRE_PROBE:
5866 spec->init_amp = ALC_INIT_DEFAULT;
5867 /* TX300 needs to set up GPIO2 for the speaker amp */
5868 alc_setup_gpio(codec, 0x04);
5869 snd_hda_apply_pincfgs(codec, dock_pins);
5870 spec->gen.auto_mute_via_amp = 1;
5871 spec->gen.automute_hook = asus_tx300_automute;
5872 snd_hda_jack_detect_enable_callback(codec, 0x1b,
5873 snd_hda_gen_hp_automute);
5874 break;
5875 case HDA_FIXUP_ACT_PROBE:
5876 spec->init_amp = ALC_INIT_DEFAULT;
5877 break;
5878 case HDA_FIXUP_ACT_BUILD:
5879 /* this is a bit tricky; give more sane names for the main
5880 * (tablet) speaker and the dock speaker, respectively
5881 */
5882 rename_ctl(codec, "Speaker Playback Switch",
5883 "Dock Speaker Playback Switch");
5884 rename_ctl(codec, "Bass Speaker Playback Switch",
5885 "Speaker Playback Switch");
5886 break;
5887 }
5888}
5889
5890static void alc290_fixup_mono_speakers(struct hda_codec *codec,
5891 const struct hda_fixup *fix, int action)
5892{
5893 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5894 /* DAC node 0x03 is giving mono output. We therefore want to
5895 make sure 0x14 (front speaker) and 0x15 (headphones) use the
5896 stereo DAC, while leaving 0x17 (bass speaker) for node 0x03. */
Olivier Deprez0e641232021-09-23 10:07:05 +02005897 static const hda_nid_t conn1[] = { 0x0c };
5898 snd_hda_override_conn_list(codec, 0x14, ARRAY_SIZE(conn1), conn1);
5899 snd_hda_override_conn_list(codec, 0x15, ARRAY_SIZE(conn1), conn1);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00005900 }
5901}
5902
5903static void alc298_fixup_speaker_volume(struct hda_codec *codec,
5904 const struct hda_fixup *fix, int action)
5905{
5906 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5907 /* The speaker is routed to the Node 0x06 by a mistake, as a result
5908 we can't adjust the speaker's volume since this node does not has
5909 Amp-out capability. we change the speaker's route to:
5910 Node 0x02 (Audio Output) -> Node 0x0c (Audio Mixer) -> Node 0x17 (
5911 Pin Complex), since Node 0x02 has Amp-out caps, we can adjust
5912 speaker's volume now. */
5913
Olivier Deprez0e641232021-09-23 10:07:05 +02005914 static const hda_nid_t conn1[] = { 0x0c };
5915 snd_hda_override_conn_list(codec, 0x17, ARRAY_SIZE(conn1), conn1);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00005916 }
5917}
5918
5919/* disable DAC3 (0x06) selection on NID 0x17 as it has no volume amp control */
5920static void alc295_fixup_disable_dac3(struct hda_codec *codec,
5921 const struct hda_fixup *fix, int action)
5922{
5923 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Olivier Deprez0e641232021-09-23 10:07:05 +02005924 static const hda_nid_t conn[] = { 0x02, 0x03 };
5925 snd_hda_override_conn_list(codec, 0x17, ARRAY_SIZE(conn), conn);
5926 }
5927}
5928
5929/* force NID 0x17 (Bass Speaker) to DAC1 to share it with the main speaker */
5930static void alc285_fixup_speaker2_to_dac1(struct hda_codec *codec,
5931 const struct hda_fixup *fix, int action)
5932{
5933 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5934 static const hda_nid_t conn[] = { 0x02 };
5935 snd_hda_override_conn_list(codec, 0x17, ARRAY_SIZE(conn), conn);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00005936 }
5937}
5938
5939/* Hook to update amp GPIO4 for automute */
5940static void alc280_hp_gpio4_automute_hook(struct hda_codec *codec,
5941 struct hda_jack_callback *jack)
5942{
5943 struct alc_spec *spec = codec->spec;
5944
5945 snd_hda_gen_hp_automute(codec, jack);
5946 /* mute_led_polarity is set to 0, so we pass inverted value here */
Olivier Deprez0e641232021-09-23 10:07:05 +02005947 alc_update_gpio_led(codec, 0x10, spec->mute_led_polarity,
5948 !spec->gen.hp_jack_present);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00005949}
5950
5951/* Manage GPIOs for HP EliteBook Folio 9480m.
5952 *
5953 * GPIO4 is the headphone amplifier power control
5954 * GPIO3 is the audio output mute indicator LED
5955 */
5956
5957static void alc280_fixup_hp_9480m(struct hda_codec *codec,
5958 const struct hda_fixup *fix,
5959 int action)
5960{
5961 struct alc_spec *spec = codec->spec;
5962
5963 alc_fixup_hp_gpio_led(codec, action, 0x08, 0);
5964 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5965 /* amp at GPIO4; toggled via alc280_hp_gpio4_automute_hook() */
5966 spec->gpio_mask |= 0x10;
5967 spec->gpio_dir |= 0x10;
5968 spec->gen.hp_automute_hook = alc280_hp_gpio4_automute_hook;
5969 }
5970}
5971
5972static void alc275_fixup_gpio4_off(struct hda_codec *codec,
5973 const struct hda_fixup *fix,
5974 int action)
5975{
5976 struct alc_spec *spec = codec->spec;
5977
5978 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5979 spec->gpio_mask |= 0x04;
5980 spec->gpio_dir |= 0x04;
5981 /* set data bit low */
5982 }
5983}
5984
Olivier Deprez0e641232021-09-23 10:07:05 +02005985/* Quirk for Thinkpad X1 7th and 8th Gen
5986 * The following fixed routing needed
5987 * DAC1 (NID 0x02) -> Speaker (NID 0x14); some eq applied secretly
5988 * DAC2 (NID 0x03) -> Bass (NID 0x17) & Headphone (NID 0x21); sharing a DAC
5989 * DAC3 (NID 0x06) -> Unused, due to the lack of volume amp
5990 */
5991static void alc285_fixup_thinkpad_x1_gen7(struct hda_codec *codec,
5992 const struct hda_fixup *fix, int action)
5993{
5994 static const hda_nid_t conn[] = { 0x02, 0x03 }; /* exclude 0x06 */
5995 static const hda_nid_t preferred_pairs[] = {
5996 0x14, 0x02, 0x17, 0x03, 0x21, 0x03, 0
5997 };
5998 struct alc_spec *spec = codec->spec;
5999
6000 switch (action) {
6001 case HDA_FIXUP_ACT_PRE_PROBE:
6002 snd_hda_override_conn_list(codec, 0x17, ARRAY_SIZE(conn), conn);
6003 spec->gen.preferred_dacs = preferred_pairs;
6004 break;
6005 case HDA_FIXUP_ACT_BUILD:
6006 /* The generic parser creates somewhat unintuitive volume ctls
6007 * with the fixed routing above, and the shared DAC2 may be
6008 * confusing for PA.
6009 * Rename those to unique names so that PA doesn't touch them
6010 * and use only Master volume.
6011 */
6012 rename_ctl(codec, "Front Playback Volume", "DAC1 Playback Volume");
6013 rename_ctl(codec, "Bass Speaker Playback Volume", "DAC2 Playback Volume");
6014 break;
6015 }
6016}
6017
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00006018static void alc233_alc662_fixup_lenovo_dual_codecs(struct hda_codec *codec,
6019 const struct hda_fixup *fix,
6020 int action)
6021{
6022 alc_fixup_dual_codecs(codec, fix, action);
6023 switch (action) {
6024 case HDA_FIXUP_ACT_PRE_PROBE:
6025 /* override card longname to provide a unique UCM profile */
6026 strcpy(codec->card->longname, "HDAudio-Lenovo-DualCodecs");
6027 break;
6028 case HDA_FIXUP_ACT_BUILD:
6029 /* rename Capture controls depending on the codec */
6030 rename_ctl(codec, "Capture Volume",
6031 codec->addr == 0 ?
6032 "Rear-Panel Capture Volume" :
6033 "Front-Panel Capture Volume");
6034 rename_ctl(codec, "Capture Switch",
6035 codec->addr == 0 ?
6036 "Rear-Panel Capture Switch" :
6037 "Front-Panel Capture Switch");
6038 break;
6039 }
6040}
6041
Olivier Deprez0e641232021-09-23 10:07:05 +02006042static void alc225_fixup_s3_pop_noise(struct hda_codec *codec,
6043 const struct hda_fixup *fix, int action)
6044{
6045 if (action != HDA_FIXUP_ACT_PRE_PROBE)
6046 return;
6047
6048 codec->power_save_node = 1;
6049}
6050
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00006051/* Forcibly assign NID 0x03 to HP/LO while NID 0x02 to SPK for EQ */
6052static void alc274_fixup_bind_dacs(struct hda_codec *codec,
6053 const struct hda_fixup *fix, int action)
6054{
6055 struct alc_spec *spec = codec->spec;
Olivier Deprez0e641232021-09-23 10:07:05 +02006056 static const hda_nid_t preferred_pairs[] = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00006057 0x21, 0x03, 0x1b, 0x03, 0x16, 0x02,
6058 0
6059 };
6060
6061 if (action != HDA_FIXUP_ACT_PRE_PROBE)
6062 return;
6063
6064 spec->gen.preferred_dacs = preferred_pairs;
David Brazdil0f672f62019-12-10 10:32:29 +00006065 spec->gen.auto_mute_via_amp = 1;
6066 codec->power_save_node = 0;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00006067}
6068
Olivier Deprez0e641232021-09-23 10:07:05 +02006069/* avoid DAC 0x06 for bass speaker 0x17; it has no volume control */
6070static void alc289_fixup_asus_ga401(struct hda_codec *codec,
6071 const struct hda_fixup *fix, int action)
6072{
6073 static const hda_nid_t preferred_pairs[] = {
6074 0x14, 0x02, 0x17, 0x02, 0x21, 0x03, 0
6075 };
6076 struct alc_spec *spec = codec->spec;
6077
6078 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
6079 spec->gen.preferred_dacs = preferred_pairs;
6080 spec->gen.obey_preferred_dacs = 1;
6081 }
6082}
6083
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00006084/* The DAC of NID 0x3 will introduce click/pop noise on headphones, so invalidate it */
6085static void alc285_fixup_invalidate_dacs(struct hda_codec *codec,
6086 const struct hda_fixup *fix, int action)
6087{
6088 if (action != HDA_FIXUP_ACT_PRE_PROBE)
6089 return;
6090
6091 snd_hda_override_wcaps(codec, 0x03, 0);
6092}
6093
Olivier Deprez0e641232021-09-23 10:07:05 +02006094static void alc_combo_jack_hp_jd_restart(struct hda_codec *codec)
David Brazdil0f672f62019-12-10 10:32:29 +00006095{
Olivier Deprez0e641232021-09-23 10:07:05 +02006096 switch (codec->core.vendor_id) {
6097 case 0x10ec0274:
6098 case 0x10ec0294:
6099 case 0x10ec0225:
6100 case 0x10ec0295:
6101 case 0x10ec0299:
6102 alc_update_coef_idx(codec, 0x4a, 0x8000, 1 << 15); /* Reset HP JD */
6103 alc_update_coef_idx(codec, 0x4a, 0x8000, 0 << 15);
David Brazdil0f672f62019-12-10 10:32:29 +00006104 break;
Olivier Deprez0e641232021-09-23 10:07:05 +02006105 case 0x10ec0230:
6106 case 0x10ec0235:
6107 case 0x10ec0236:
6108 case 0x10ec0255:
6109 case 0x10ec0256:
6110 alc_update_coef_idx(codec, 0x1b, 0x8000, 1 << 15); /* Reset HP JD */
6111 alc_update_coef_idx(codec, 0x1b, 0x8000, 0 << 15);
David Brazdil0f672f62019-12-10 10:32:29 +00006112 break;
6113 }
6114}
6115
6116static void alc295_fixup_chromebook(struct hda_codec *codec,
6117 const struct hda_fixup *fix, int action)
6118{
6119 struct alc_spec *spec = codec->spec;
6120
6121 switch (action) {
6122 case HDA_FIXUP_ACT_PRE_PROBE:
6123 spec->ultra_low_power = true;
6124 break;
6125 case HDA_FIXUP_ACT_INIT:
Olivier Deprez0e641232021-09-23 10:07:05 +02006126 alc_combo_jack_hp_jd_restart(codec);
David Brazdil0f672f62019-12-10 10:32:29 +00006127 break;
6128 }
6129}
6130
6131static void alc_fixup_disable_mic_vref(struct hda_codec *codec,
6132 const struct hda_fixup *fix, int action)
6133{
6134 if (action == HDA_FIXUP_ACT_PRE_PROBE)
6135 snd_hda_codec_set_pin_target(codec, 0x19, PIN_VREFHIZ);
6136}
6137
Olivier Deprez0e641232021-09-23 10:07:05 +02006138
6139static void alc294_gx502_toggle_output(struct hda_codec *codec,
6140 struct hda_jack_callback *cb)
6141{
6142 /* The Windows driver sets the codec up in a very different way where
6143 * it appears to leave 0x10 = 0x8a20 set. For Linux we need to toggle it
6144 */
6145 if (snd_hda_jack_detect_state(codec, 0x21) == HDA_JACK_PRESENT)
6146 alc_write_coef_idx(codec, 0x10, 0x8a20);
6147 else
6148 alc_write_coef_idx(codec, 0x10, 0x0a20);
6149}
6150
6151static void alc294_fixup_gx502_hp(struct hda_codec *codec,
6152 const struct hda_fixup *fix, int action)
6153{
6154 /* Pin 0x21: headphones/headset mic */
6155 if (!is_jack_detectable(codec, 0x21))
6156 return;
6157
6158 switch (action) {
6159 case HDA_FIXUP_ACT_PRE_PROBE:
6160 snd_hda_jack_detect_enable_callback(codec, 0x21,
6161 alc294_gx502_toggle_output);
6162 break;
6163 case HDA_FIXUP_ACT_INIT:
6164 /* Make sure to start in a correct state, i.e. if
6165 * headphones have been plugged in before powering up the system
6166 */
6167 alc294_gx502_toggle_output(codec, NULL);
6168 break;
6169 }
6170}
6171
6172static void alc294_gu502_toggle_output(struct hda_codec *codec,
6173 struct hda_jack_callback *cb)
6174{
6175 /* Windows sets 0x10 to 0x8420 for Node 0x20 which is
6176 * responsible from changes between speakers and headphones
6177 */
6178 if (snd_hda_jack_detect_state(codec, 0x21) == HDA_JACK_PRESENT)
6179 alc_write_coef_idx(codec, 0x10, 0x8420);
6180 else
6181 alc_write_coef_idx(codec, 0x10, 0x0a20);
6182}
6183
6184static void alc294_fixup_gu502_hp(struct hda_codec *codec,
6185 const struct hda_fixup *fix, int action)
6186{
6187 if (!is_jack_detectable(codec, 0x21))
6188 return;
6189
6190 switch (action) {
6191 case HDA_FIXUP_ACT_PRE_PROBE:
6192 snd_hda_jack_detect_enable_callback(codec, 0x21,
6193 alc294_gu502_toggle_output);
6194 break;
6195 case HDA_FIXUP_ACT_INIT:
6196 alc294_gu502_toggle_output(codec, NULL);
6197 break;
6198 }
6199}
6200
6201static void alc285_fixup_hp_gpio_amp_init(struct hda_codec *codec,
6202 const struct hda_fixup *fix, int action)
6203{
6204 if (action != HDA_FIXUP_ACT_INIT)
6205 return;
6206
6207 msleep(100);
6208 alc_write_coef_idx(codec, 0x65, 0x0);
6209}
6210
6211static void alc274_fixup_hp_headset_mic(struct hda_codec *codec,
6212 const struct hda_fixup *fix, int action)
6213{
6214 switch (action) {
6215 case HDA_FIXUP_ACT_INIT:
6216 alc_combo_jack_hp_jd_restart(codec);
6217 break;
6218 }
6219}
6220
6221static void alc285_fixup_hp_spectre_x360(struct hda_codec *codec,
6222 const struct hda_fixup *fix, int action)
6223{
6224 static const hda_nid_t conn[] = { 0x02 };
6225 static const struct hda_pintbl pincfgs[] = {
6226 { 0x14, 0x90170110 }, /* rear speaker */
6227 { }
6228 };
6229
6230 switch (action) {
6231 case HDA_FIXUP_ACT_PRE_PROBE:
6232 snd_hda_apply_pincfgs(codec, pincfgs);
6233 /* force front speaker to DAC1 */
6234 snd_hda_override_conn_list(codec, 0x17, ARRAY_SIZE(conn), conn);
6235 break;
6236 }
6237}
6238
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00006239/* for hda_fixup_thinkpad_acpi() */
6240#include "thinkpad_helper.c"
6241
6242static void alc_fixup_thinkpad_acpi(struct hda_codec *codec,
6243 const struct hda_fixup *fix, int action)
6244{
6245 alc_fixup_no_shutup(codec, fix, action); /* reduce click noise */
6246 hda_fixup_thinkpad_acpi(codec, fix, action);
6247}
6248
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00006249/* for alc295_fixup_hp_top_speakers */
6250#include "hp_x360_helper.c"
6251
6252enum {
Olivier Deprez0e641232021-09-23 10:07:05 +02006253 ALC269_FIXUP_GPIO2,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00006254 ALC269_FIXUP_SONY_VAIO,
6255 ALC275_FIXUP_SONY_VAIO_GPIO2,
6256 ALC269_FIXUP_DELL_M101Z,
6257 ALC269_FIXUP_SKU_IGNORE,
6258 ALC269_FIXUP_ASUS_G73JW,
6259 ALC269_FIXUP_LENOVO_EAPD,
6260 ALC275_FIXUP_SONY_HWEQ,
6261 ALC275_FIXUP_SONY_DISABLE_AAMIX,
6262 ALC271_FIXUP_DMIC,
6263 ALC269_FIXUP_PCM_44K,
6264 ALC269_FIXUP_STEREO_DMIC,
6265 ALC269_FIXUP_HEADSET_MIC,
6266 ALC269_FIXUP_QUANTA_MUTE,
6267 ALC269_FIXUP_LIFEBOOK,
6268 ALC269_FIXUP_LIFEBOOK_EXTMIC,
6269 ALC269_FIXUP_LIFEBOOK_HP_PIN,
6270 ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT,
6271 ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC,
6272 ALC269_FIXUP_AMIC,
6273 ALC269_FIXUP_DMIC,
6274 ALC269VB_FIXUP_AMIC,
6275 ALC269VB_FIXUP_DMIC,
6276 ALC269_FIXUP_HP_MUTE_LED,
6277 ALC269_FIXUP_HP_MUTE_LED_MIC1,
6278 ALC269_FIXUP_HP_MUTE_LED_MIC2,
6279 ALC269_FIXUP_HP_MUTE_LED_MIC3,
6280 ALC269_FIXUP_HP_GPIO_LED,
6281 ALC269_FIXUP_HP_GPIO_MIC1_LED,
6282 ALC269_FIXUP_HP_LINE1_MIC1_LED,
6283 ALC269_FIXUP_INV_DMIC,
6284 ALC269_FIXUP_LENOVO_DOCK,
Olivier Deprez0e641232021-09-23 10:07:05 +02006285 ALC269_FIXUP_LENOVO_DOCK_LIMIT_BOOST,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00006286 ALC269_FIXUP_NO_SHUTUP,
6287 ALC286_FIXUP_SONY_MIC_NO_PRESENCE,
6288 ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT,
6289 ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
6290 ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
6291 ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
6292 ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
6293 ALC269_FIXUP_HEADSET_MODE,
6294 ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC,
6295 ALC269_FIXUP_ASPIRE_HEADSET_MIC,
6296 ALC269_FIXUP_ASUS_X101_FUNC,
6297 ALC269_FIXUP_ASUS_X101_VERB,
6298 ALC269_FIXUP_ASUS_X101,
6299 ALC271_FIXUP_AMIC_MIC2,
6300 ALC271_FIXUP_HP_GATE_MIC_JACK,
6301 ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572,
6302 ALC269_FIXUP_ACER_AC700,
6303 ALC269_FIXUP_LIMIT_INT_MIC_BOOST,
6304 ALC269VB_FIXUP_ASUS_ZENBOOK,
6305 ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A,
6306 ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED,
6307 ALC269VB_FIXUP_ORDISSIMO_EVE2,
6308 ALC283_FIXUP_CHROME_BOOK,
6309 ALC283_FIXUP_SENSE_COMBO_JACK,
6310 ALC282_FIXUP_ASUS_TX300,
6311 ALC283_FIXUP_INT_MIC,
6312 ALC290_FIXUP_MONO_SPEAKERS,
6313 ALC290_FIXUP_MONO_SPEAKERS_HSJACK,
6314 ALC290_FIXUP_SUBWOOFER,
6315 ALC290_FIXUP_SUBWOOFER_HSJACK,
6316 ALC269_FIXUP_THINKPAD_ACPI,
6317 ALC269_FIXUP_DMIC_THINKPAD_ACPI,
6318 ALC255_FIXUP_ACER_MIC_NO_PRESENCE,
6319 ALC255_FIXUP_ASUS_MIC_NO_PRESENCE,
6320 ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6321 ALC255_FIXUP_DELL2_MIC_NO_PRESENCE,
6322 ALC255_FIXUP_HEADSET_MODE,
6323 ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC,
6324 ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
6325 ALC292_FIXUP_TPT440_DOCK,
6326 ALC292_FIXUP_TPT440,
6327 ALC283_FIXUP_HEADSET_MIC,
David Brazdil0f672f62019-12-10 10:32:29 +00006328 ALC255_FIXUP_MIC_MUTE_LED,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00006329 ALC282_FIXUP_ASPIRE_V5_PINS,
Olivier Deprez0e641232021-09-23 10:07:05 +02006330 ALC269VB_FIXUP_ASPIRE_E1_COEF,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00006331 ALC280_FIXUP_HP_GPIO4,
6332 ALC286_FIXUP_HP_GPIO_LED,
6333 ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY,
6334 ALC280_FIXUP_HP_DOCK_PINS,
6335 ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED,
6336 ALC280_FIXUP_HP_9480M,
6337 ALC288_FIXUP_DELL_HEADSET_MODE,
6338 ALC288_FIXUP_DELL1_MIC_NO_PRESENCE,
6339 ALC288_FIXUP_DELL_XPS_13,
6340 ALC288_FIXUP_DISABLE_AAMIX,
Olivier Deprez0e641232021-09-23 10:07:05 +02006341 ALC292_FIXUP_DELL_E7X_AAMIX,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00006342 ALC292_FIXUP_DELL_E7X,
6343 ALC292_FIXUP_DISABLE_AAMIX,
6344 ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK,
David Brazdil0f672f62019-12-10 10:32:29 +00006345 ALC298_FIXUP_ALIENWARE_MIC_NO_PRESENCE,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00006346 ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
6347 ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE,
6348 ALC275_FIXUP_DELL_XPS,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00006349 ALC293_FIXUP_LENOVO_SPK_NOISE,
6350 ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY,
6351 ALC255_FIXUP_DELL_SPK_NOISE,
David Brazdil0f672f62019-12-10 10:32:29 +00006352 ALC225_FIXUP_DISABLE_MIC_VREF,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00006353 ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
6354 ALC295_FIXUP_DISABLE_DAC3,
Olivier Deprez0e641232021-09-23 10:07:05 +02006355 ALC285_FIXUP_SPEAKER2_TO_DAC1,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00006356 ALC280_FIXUP_HP_HEADSET_MIC,
6357 ALC221_FIXUP_HP_FRONT_MIC,
6358 ALC292_FIXUP_TPT460,
6359 ALC298_FIXUP_SPK_VOLUME,
Olivier Deprez0e641232021-09-23 10:07:05 +02006360 ALC298_FIXUP_LENOVO_SPK_VOLUME,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00006361 ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER,
6362 ALC269_FIXUP_ATIV_BOOK_8,
6363 ALC221_FIXUP_HP_MIC_NO_PRESENCE,
6364 ALC256_FIXUP_ASUS_HEADSET_MODE,
6365 ALC256_FIXUP_ASUS_MIC,
6366 ALC256_FIXUP_ASUS_AIO_GPIO2,
6367 ALC233_FIXUP_ASUS_MIC_NO_PRESENCE,
6368 ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE,
6369 ALC233_FIXUP_LENOVO_MULTI_CODECS,
David Brazdil0f672f62019-12-10 10:32:29 +00006370 ALC233_FIXUP_ACER_HEADSET_MIC,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00006371 ALC294_FIXUP_LENOVO_MIC_LOCATION,
6372 ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE,
Olivier Deprez0e641232021-09-23 10:07:05 +02006373 ALC225_FIXUP_S3_POP_NOISE,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00006374 ALC700_FIXUP_INTEL_REFERENCE,
6375 ALC274_FIXUP_DELL_BIND_DACS,
6376 ALC274_FIXUP_DELL_AIO_LINEOUT_VERB,
Olivier Deprez0e641232021-09-23 10:07:05 +02006377 ALC298_FIXUP_TPT470_DOCK_FIX,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00006378 ALC298_FIXUP_TPT470_DOCK,
6379 ALC255_FIXUP_DUMMY_LINEOUT_VERB,
6380 ALC255_FIXUP_DELL_HEADSET_MIC,
David Brazdil0f672f62019-12-10 10:32:29 +00006381 ALC256_FIXUP_HUAWEI_MACH_WX9_PINS,
6382 ALC298_FIXUP_HUAWEI_MBX_STEREO,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00006383 ALC295_FIXUP_HP_X360,
6384 ALC221_FIXUP_HP_HEADSET_MIC,
6385 ALC285_FIXUP_LENOVO_HEADPHONE_NOISE,
6386 ALC295_FIXUP_HP_AUTO_MUTE,
6387 ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE,
6388 ALC294_FIXUP_ASUS_MIC,
6389 ALC294_FIXUP_ASUS_HEADSET_MIC,
6390 ALC294_FIXUP_ASUS_SPK,
David Brazdil0f672f62019-12-10 10:32:29 +00006391 ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE,
6392 ALC285_FIXUP_LENOVO_PC_BEEP_IN_NOISE,
6393 ALC255_FIXUP_ACER_HEADSET_MIC,
6394 ALC295_FIXUP_CHROME_BOOK,
6395 ALC225_FIXUP_HEADSET_JACK,
6396 ALC225_FIXUP_DELL_WYSE_AIO_MIC_NO_PRESENCE,
6397 ALC225_FIXUP_WYSE_AUTO_MUTE,
6398 ALC225_FIXUP_WYSE_DISABLE_MIC_VREF,
6399 ALC286_FIXUP_ACER_AIO_HEADSET_MIC,
6400 ALC256_FIXUP_ASUS_HEADSET_MIC,
6401 ALC256_FIXUP_ASUS_MIC_NO_PRESENCE,
6402 ALC299_FIXUP_PREDATOR_SPK,
David Brazdil0f672f62019-12-10 10:32:29 +00006403 ALC256_FIXUP_MEDION_HEADSET_NO_PRESENCE,
Olivier Deprez0e641232021-09-23 10:07:05 +02006404 ALC289_FIXUP_DELL_SPK2,
6405 ALC289_FIXUP_DUAL_SPK,
6406 ALC294_FIXUP_SPK2_TO_DAC1,
6407 ALC294_FIXUP_ASUS_DUAL_SPK,
6408 ALC285_FIXUP_THINKPAD_X1_GEN7,
6409 ALC285_FIXUP_THINKPAD_HEADSET_JACK,
6410 ALC294_FIXUP_ASUS_HPE,
6411 ALC294_FIXUP_ASUS_COEF_1B,
6412 ALC294_FIXUP_ASUS_GX502_HP,
6413 ALC294_FIXUP_ASUS_GX502_PINS,
6414 ALC294_FIXUP_ASUS_GX502_VERBS,
6415 ALC294_FIXUP_ASUS_GU502_HP,
6416 ALC294_FIXUP_ASUS_GU502_PINS,
6417 ALC294_FIXUP_ASUS_GU502_VERBS,
6418 ALC285_FIXUP_HP_GPIO_LED,
6419 ALC285_FIXUP_HP_MUTE_LED,
6420 ALC236_FIXUP_HP_MUTE_LED,
6421 ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET,
6422 ALC295_FIXUP_ASUS_MIC_NO_PRESENCE,
6423 ALC269VC_FIXUP_ACER_VCOPPERBOX_PINS,
6424 ALC269VC_FIXUP_ACER_HEADSET_MIC,
6425 ALC269VC_FIXUP_ACER_MIC_NO_PRESENCE,
6426 ALC289_FIXUP_ASUS_GA401,
6427 ALC289_FIXUP_ASUS_GA502,
6428 ALC256_FIXUP_ACER_MIC_NO_PRESENCE,
6429 ALC285_FIXUP_HP_GPIO_AMP_INIT,
6430 ALC269_FIXUP_CZC_B20,
6431 ALC269_FIXUP_CZC_TMI,
6432 ALC269_FIXUP_CZC_L101,
6433 ALC269_FIXUP_LEMOTE_A1802,
6434 ALC269_FIXUP_LEMOTE_A190X,
6435 ALC256_FIXUP_INTEL_NUC8_RUGGED,
6436 ALC233_FIXUP_INTEL_NUC8_DMIC,
6437 ALC233_FIXUP_INTEL_NUC8_BOOST,
6438 ALC256_FIXUP_INTEL_NUC10,
6439 ALC255_FIXUP_XIAOMI_HEADSET_MIC,
6440 ALC274_FIXUP_HP_MIC,
6441 ALC274_FIXUP_HP_HEADSET_MIC,
6442 ALC256_FIXUP_ASUS_HPE,
6443 ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK,
6444 ALC295_FIXUP_ASUS_DACS,
6445 ALC295_FIXUP_HP_OMEN,
6446 ALC285_FIXUP_HP_SPECTRE_X360,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00006447};
6448
6449static const struct hda_fixup alc269_fixups[] = {
Olivier Deprez0e641232021-09-23 10:07:05 +02006450 [ALC269_FIXUP_GPIO2] = {
6451 .type = HDA_FIXUP_FUNC,
6452 .v.func = alc_fixup_gpio2,
6453 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00006454 [ALC269_FIXUP_SONY_VAIO] = {
6455 .type = HDA_FIXUP_PINCTLS,
6456 .v.pins = (const struct hda_pintbl[]) {
6457 {0x19, PIN_VREFGRD},
6458 {}
6459 }
6460 },
6461 [ALC275_FIXUP_SONY_VAIO_GPIO2] = {
6462 .type = HDA_FIXUP_FUNC,
6463 .v.func = alc275_fixup_gpio4_off,
6464 .chained = true,
6465 .chain_id = ALC269_FIXUP_SONY_VAIO
6466 },
6467 [ALC269_FIXUP_DELL_M101Z] = {
6468 .type = HDA_FIXUP_VERBS,
6469 .v.verbs = (const struct hda_verb[]) {
6470 /* Enables internal speaker */
6471 {0x20, AC_VERB_SET_COEF_INDEX, 13},
6472 {0x20, AC_VERB_SET_PROC_COEF, 0x4040},
6473 {}
6474 }
6475 },
6476 [ALC269_FIXUP_SKU_IGNORE] = {
6477 .type = HDA_FIXUP_FUNC,
6478 .v.func = alc_fixup_sku_ignore,
6479 },
6480 [ALC269_FIXUP_ASUS_G73JW] = {
6481 .type = HDA_FIXUP_PINS,
6482 .v.pins = (const struct hda_pintbl[]) {
6483 { 0x17, 0x99130111 }, /* subwoofer */
6484 { }
6485 }
6486 },
6487 [ALC269_FIXUP_LENOVO_EAPD] = {
6488 .type = HDA_FIXUP_VERBS,
6489 .v.verbs = (const struct hda_verb[]) {
6490 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
6491 {}
6492 }
6493 },
6494 [ALC275_FIXUP_SONY_HWEQ] = {
6495 .type = HDA_FIXUP_FUNC,
6496 .v.func = alc269_fixup_hweq,
6497 .chained = true,
6498 .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2
6499 },
6500 [ALC275_FIXUP_SONY_DISABLE_AAMIX] = {
6501 .type = HDA_FIXUP_FUNC,
6502 .v.func = alc_fixup_disable_aamix,
6503 .chained = true,
6504 .chain_id = ALC269_FIXUP_SONY_VAIO
6505 },
6506 [ALC271_FIXUP_DMIC] = {
6507 .type = HDA_FIXUP_FUNC,
6508 .v.func = alc271_fixup_dmic,
6509 },
6510 [ALC269_FIXUP_PCM_44K] = {
6511 .type = HDA_FIXUP_FUNC,
6512 .v.func = alc269_fixup_pcm_44k,
6513 .chained = true,
6514 .chain_id = ALC269_FIXUP_QUANTA_MUTE
6515 },
6516 [ALC269_FIXUP_STEREO_DMIC] = {
6517 .type = HDA_FIXUP_FUNC,
6518 .v.func = alc269_fixup_stereo_dmic,
6519 },
6520 [ALC269_FIXUP_HEADSET_MIC] = {
6521 .type = HDA_FIXUP_FUNC,
6522 .v.func = alc269_fixup_headset_mic,
6523 },
6524 [ALC269_FIXUP_QUANTA_MUTE] = {
6525 .type = HDA_FIXUP_FUNC,
6526 .v.func = alc269_fixup_quanta_mute,
6527 },
6528 [ALC269_FIXUP_LIFEBOOK] = {
6529 .type = HDA_FIXUP_PINS,
6530 .v.pins = (const struct hda_pintbl[]) {
6531 { 0x1a, 0x2101103f }, /* dock line-out */
6532 { 0x1b, 0x23a11040 }, /* dock mic-in */
6533 { }
6534 },
6535 .chained = true,
6536 .chain_id = ALC269_FIXUP_QUANTA_MUTE
6537 },
6538 [ALC269_FIXUP_LIFEBOOK_EXTMIC] = {
6539 .type = HDA_FIXUP_PINS,
6540 .v.pins = (const struct hda_pintbl[]) {
6541 { 0x19, 0x01a1903c }, /* headset mic, with jack detect */
6542 { }
6543 },
6544 },
6545 [ALC269_FIXUP_LIFEBOOK_HP_PIN] = {
6546 .type = HDA_FIXUP_PINS,
6547 .v.pins = (const struct hda_pintbl[]) {
6548 { 0x21, 0x0221102f }, /* HP out */
6549 { }
6550 },
6551 },
6552 [ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT] = {
6553 .type = HDA_FIXUP_FUNC,
6554 .v.func = alc269_fixup_pincfg_no_hp_to_lineout,
6555 },
6556 [ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC] = {
6557 .type = HDA_FIXUP_FUNC,
6558 .v.func = alc269_fixup_pincfg_U7x7_headset_mic,
6559 },
6560 [ALC269_FIXUP_AMIC] = {
6561 .type = HDA_FIXUP_PINS,
6562 .v.pins = (const struct hda_pintbl[]) {
6563 { 0x14, 0x99130110 }, /* speaker */
6564 { 0x15, 0x0121401f }, /* HP out */
6565 { 0x18, 0x01a19c20 }, /* mic */
6566 { 0x19, 0x99a3092f }, /* int-mic */
6567 { }
6568 },
6569 },
6570 [ALC269_FIXUP_DMIC] = {
6571 .type = HDA_FIXUP_PINS,
6572 .v.pins = (const struct hda_pintbl[]) {
6573 { 0x12, 0x99a3092f }, /* int-mic */
6574 { 0x14, 0x99130110 }, /* speaker */
6575 { 0x15, 0x0121401f }, /* HP out */
6576 { 0x18, 0x01a19c20 }, /* mic */
6577 { }
6578 },
6579 },
6580 [ALC269VB_FIXUP_AMIC] = {
6581 .type = HDA_FIXUP_PINS,
6582 .v.pins = (const struct hda_pintbl[]) {
6583 { 0x14, 0x99130110 }, /* speaker */
6584 { 0x18, 0x01a19c20 }, /* mic */
6585 { 0x19, 0x99a3092f }, /* int-mic */
6586 { 0x21, 0x0121401f }, /* HP out */
6587 { }
6588 },
6589 },
6590 [ALC269VB_FIXUP_DMIC] = {
6591 .type = HDA_FIXUP_PINS,
6592 .v.pins = (const struct hda_pintbl[]) {
6593 { 0x12, 0x99a3092f }, /* int-mic */
6594 { 0x14, 0x99130110 }, /* speaker */
6595 { 0x18, 0x01a19c20 }, /* mic */
6596 { 0x21, 0x0121401f }, /* HP out */
6597 { }
6598 },
6599 },
6600 [ALC269_FIXUP_HP_MUTE_LED] = {
6601 .type = HDA_FIXUP_FUNC,
6602 .v.func = alc269_fixup_hp_mute_led,
6603 },
6604 [ALC269_FIXUP_HP_MUTE_LED_MIC1] = {
6605 .type = HDA_FIXUP_FUNC,
6606 .v.func = alc269_fixup_hp_mute_led_mic1,
6607 },
6608 [ALC269_FIXUP_HP_MUTE_LED_MIC2] = {
6609 .type = HDA_FIXUP_FUNC,
6610 .v.func = alc269_fixup_hp_mute_led_mic2,
6611 },
6612 [ALC269_FIXUP_HP_MUTE_LED_MIC3] = {
6613 .type = HDA_FIXUP_FUNC,
6614 .v.func = alc269_fixup_hp_mute_led_mic3,
6615 .chained = true,
6616 .chain_id = ALC295_FIXUP_HP_AUTO_MUTE
6617 },
6618 [ALC269_FIXUP_HP_GPIO_LED] = {
6619 .type = HDA_FIXUP_FUNC,
6620 .v.func = alc269_fixup_hp_gpio_led,
6621 },
6622 [ALC269_FIXUP_HP_GPIO_MIC1_LED] = {
6623 .type = HDA_FIXUP_FUNC,
6624 .v.func = alc269_fixup_hp_gpio_mic1_led,
6625 },
6626 [ALC269_FIXUP_HP_LINE1_MIC1_LED] = {
6627 .type = HDA_FIXUP_FUNC,
6628 .v.func = alc269_fixup_hp_line1_mic1_led,
6629 },
6630 [ALC269_FIXUP_INV_DMIC] = {
6631 .type = HDA_FIXUP_FUNC,
6632 .v.func = alc_fixup_inv_dmic,
6633 },
6634 [ALC269_FIXUP_NO_SHUTUP] = {
6635 .type = HDA_FIXUP_FUNC,
6636 .v.func = alc_fixup_no_shutup,
6637 },
6638 [ALC269_FIXUP_LENOVO_DOCK] = {
6639 .type = HDA_FIXUP_PINS,
6640 .v.pins = (const struct hda_pintbl[]) {
6641 { 0x19, 0x23a11040 }, /* dock mic */
6642 { 0x1b, 0x2121103f }, /* dock headphone */
6643 { }
6644 },
6645 .chained = true,
6646 .chain_id = ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT
6647 },
Olivier Deprez0e641232021-09-23 10:07:05 +02006648 [ALC269_FIXUP_LENOVO_DOCK_LIMIT_BOOST] = {
6649 .type = HDA_FIXUP_FUNC,
6650 .v.func = alc269_fixup_limit_int_mic_boost,
6651 .chained = true,
6652 .chain_id = ALC269_FIXUP_LENOVO_DOCK,
6653 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00006654 [ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT] = {
6655 .type = HDA_FIXUP_FUNC,
6656 .v.func = alc269_fixup_pincfg_no_hp_to_lineout,
6657 .chained = true,
6658 .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
6659 },
6660 [ALC269_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6661 .type = HDA_FIXUP_PINS,
6662 .v.pins = (const struct hda_pintbl[]) {
6663 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6664 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6665 { }
6666 },
6667 .chained = true,
6668 .chain_id = ALC269_FIXUP_HEADSET_MODE
6669 },
6670 [ALC269_FIXUP_DELL2_MIC_NO_PRESENCE] = {
6671 .type = HDA_FIXUP_PINS,
6672 .v.pins = (const struct hda_pintbl[]) {
6673 { 0x16, 0x21014020 }, /* dock line out */
6674 { 0x19, 0x21a19030 }, /* dock mic */
6675 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6676 { }
6677 },
6678 .chained = true,
6679 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
6680 },
6681 [ALC269_FIXUP_DELL3_MIC_NO_PRESENCE] = {
6682 .type = HDA_FIXUP_PINS,
6683 .v.pins = (const struct hda_pintbl[]) {
6684 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6685 { }
6686 },
6687 .chained = true,
6688 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
6689 },
6690 [ALC269_FIXUP_DELL4_MIC_NO_PRESENCE] = {
6691 .type = HDA_FIXUP_PINS,
6692 .v.pins = (const struct hda_pintbl[]) {
6693 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6694 { 0x1b, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6695 { }
6696 },
6697 .chained = true,
6698 .chain_id = ALC269_FIXUP_HEADSET_MODE
6699 },
6700 [ALC269_FIXUP_HEADSET_MODE] = {
6701 .type = HDA_FIXUP_FUNC,
6702 .v.func = alc_fixup_headset_mode,
6703 .chained = true,
David Brazdil0f672f62019-12-10 10:32:29 +00006704 .chain_id = ALC255_FIXUP_MIC_MUTE_LED
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00006705 },
6706 [ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC] = {
6707 .type = HDA_FIXUP_FUNC,
6708 .v.func = alc_fixup_headset_mode_no_hp_mic,
6709 },
6710 [ALC269_FIXUP_ASPIRE_HEADSET_MIC] = {
6711 .type = HDA_FIXUP_PINS,
6712 .v.pins = (const struct hda_pintbl[]) {
6713 { 0x19, 0x01a1913c }, /* headset mic w/o jack detect */
6714 { }
6715 },
6716 .chained = true,
6717 .chain_id = ALC269_FIXUP_HEADSET_MODE,
6718 },
6719 [ALC286_FIXUP_SONY_MIC_NO_PRESENCE] = {
6720 .type = HDA_FIXUP_PINS,
6721 .v.pins = (const struct hda_pintbl[]) {
6722 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6723 { }
6724 },
6725 .chained = true,
6726 .chain_id = ALC269_FIXUP_HEADSET_MIC
6727 },
David Brazdil0f672f62019-12-10 10:32:29 +00006728 [ALC256_FIXUP_HUAWEI_MACH_WX9_PINS] = {
6729 .type = HDA_FIXUP_PINS,
6730 .v.pins = (const struct hda_pintbl[]) {
6731 {0x12, 0x90a60130},
6732 {0x13, 0x40000000},
6733 {0x14, 0x90170110},
6734 {0x18, 0x411111f0},
6735 {0x19, 0x04a11040},
6736 {0x1a, 0x411111f0},
6737 {0x1b, 0x90170112},
6738 {0x1d, 0x40759a05},
6739 {0x1e, 0x411111f0},
6740 {0x21, 0x04211020},
6741 { }
6742 },
6743 .chained = true,
6744 .chain_id = ALC255_FIXUP_MIC_MUTE_LED
6745 },
6746 [ALC298_FIXUP_HUAWEI_MBX_STEREO] = {
6747 .type = HDA_FIXUP_FUNC,
6748 .v.func = alc298_fixup_huawei_mbx_stereo,
6749 .chained = true,
6750 .chain_id = ALC255_FIXUP_MIC_MUTE_LED
6751 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00006752 [ALC269_FIXUP_ASUS_X101_FUNC] = {
6753 .type = HDA_FIXUP_FUNC,
6754 .v.func = alc269_fixup_x101_headset_mic,
6755 },
6756 [ALC269_FIXUP_ASUS_X101_VERB] = {
6757 .type = HDA_FIXUP_VERBS,
6758 .v.verbs = (const struct hda_verb[]) {
6759 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6760 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
6761 {0x20, AC_VERB_SET_PROC_COEF, 0x0310},
6762 { }
6763 },
6764 .chained = true,
6765 .chain_id = ALC269_FIXUP_ASUS_X101_FUNC
6766 },
6767 [ALC269_FIXUP_ASUS_X101] = {
6768 .type = HDA_FIXUP_PINS,
6769 .v.pins = (const struct hda_pintbl[]) {
6770 { 0x18, 0x04a1182c }, /* Headset mic */
6771 { }
6772 },
6773 .chained = true,
6774 .chain_id = ALC269_FIXUP_ASUS_X101_VERB
6775 },
6776 [ALC271_FIXUP_AMIC_MIC2] = {
6777 .type = HDA_FIXUP_PINS,
6778 .v.pins = (const struct hda_pintbl[]) {
6779 { 0x14, 0x99130110 }, /* speaker */
6780 { 0x19, 0x01a19c20 }, /* mic */
6781 { 0x1b, 0x99a7012f }, /* int-mic */
6782 { 0x21, 0x0121401f }, /* HP out */
6783 { }
6784 },
6785 },
6786 [ALC271_FIXUP_HP_GATE_MIC_JACK] = {
6787 .type = HDA_FIXUP_FUNC,
6788 .v.func = alc271_hp_gate_mic_jack,
6789 .chained = true,
6790 .chain_id = ALC271_FIXUP_AMIC_MIC2,
6791 },
6792 [ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572] = {
6793 .type = HDA_FIXUP_FUNC,
6794 .v.func = alc269_fixup_limit_int_mic_boost,
6795 .chained = true,
6796 .chain_id = ALC271_FIXUP_HP_GATE_MIC_JACK,
6797 },
6798 [ALC269_FIXUP_ACER_AC700] = {
6799 .type = HDA_FIXUP_PINS,
6800 .v.pins = (const struct hda_pintbl[]) {
6801 { 0x12, 0x99a3092f }, /* int-mic */
6802 { 0x14, 0x99130110 }, /* speaker */
6803 { 0x18, 0x03a11c20 }, /* mic */
6804 { 0x1e, 0x0346101e }, /* SPDIF1 */
6805 { 0x21, 0x0321101f }, /* HP out */
6806 { }
6807 },
6808 .chained = true,
6809 .chain_id = ALC271_FIXUP_DMIC,
6810 },
6811 [ALC269_FIXUP_LIMIT_INT_MIC_BOOST] = {
6812 .type = HDA_FIXUP_FUNC,
6813 .v.func = alc269_fixup_limit_int_mic_boost,
6814 .chained = true,
6815 .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
6816 },
6817 [ALC269VB_FIXUP_ASUS_ZENBOOK] = {
6818 .type = HDA_FIXUP_FUNC,
6819 .v.func = alc269_fixup_limit_int_mic_boost,
6820 .chained = true,
6821 .chain_id = ALC269VB_FIXUP_DMIC,
6822 },
6823 [ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A] = {
6824 .type = HDA_FIXUP_VERBS,
6825 .v.verbs = (const struct hda_verb[]) {
6826 /* class-D output amp +5dB */
6827 { 0x20, AC_VERB_SET_COEF_INDEX, 0x12 },
6828 { 0x20, AC_VERB_SET_PROC_COEF, 0x2800 },
6829 {}
6830 },
6831 .chained = true,
6832 .chain_id = ALC269VB_FIXUP_ASUS_ZENBOOK,
6833 },
6834 [ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED] = {
6835 .type = HDA_FIXUP_FUNC,
6836 .v.func = alc269_fixup_limit_int_mic_boost,
6837 .chained = true,
6838 .chain_id = ALC269_FIXUP_HP_MUTE_LED_MIC1,
6839 },
6840 [ALC269VB_FIXUP_ORDISSIMO_EVE2] = {
6841 .type = HDA_FIXUP_PINS,
6842 .v.pins = (const struct hda_pintbl[]) {
6843 { 0x12, 0x99a3092f }, /* int-mic */
6844 { 0x18, 0x03a11d20 }, /* mic */
6845 { 0x19, 0x411111f0 }, /* Unused bogus pin */
6846 { }
6847 },
6848 },
6849 [ALC283_FIXUP_CHROME_BOOK] = {
6850 .type = HDA_FIXUP_FUNC,
6851 .v.func = alc283_fixup_chromebook,
6852 },
6853 [ALC283_FIXUP_SENSE_COMBO_JACK] = {
6854 .type = HDA_FIXUP_FUNC,
6855 .v.func = alc283_fixup_sense_combo_jack,
6856 .chained = true,
6857 .chain_id = ALC283_FIXUP_CHROME_BOOK,
6858 },
6859 [ALC282_FIXUP_ASUS_TX300] = {
6860 .type = HDA_FIXUP_FUNC,
6861 .v.func = alc282_fixup_asus_tx300,
6862 },
6863 [ALC283_FIXUP_INT_MIC] = {
6864 .type = HDA_FIXUP_VERBS,
6865 .v.verbs = (const struct hda_verb[]) {
6866 {0x20, AC_VERB_SET_COEF_INDEX, 0x1a},
6867 {0x20, AC_VERB_SET_PROC_COEF, 0x0011},
6868 { }
6869 },
6870 .chained = true,
6871 .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST
6872 },
6873 [ALC290_FIXUP_SUBWOOFER_HSJACK] = {
6874 .type = HDA_FIXUP_PINS,
6875 .v.pins = (const struct hda_pintbl[]) {
6876 { 0x17, 0x90170112 }, /* subwoofer */
6877 { }
6878 },
6879 .chained = true,
6880 .chain_id = ALC290_FIXUP_MONO_SPEAKERS_HSJACK,
6881 },
6882 [ALC290_FIXUP_SUBWOOFER] = {
6883 .type = HDA_FIXUP_PINS,
6884 .v.pins = (const struct hda_pintbl[]) {
6885 { 0x17, 0x90170112 }, /* subwoofer */
6886 { }
6887 },
6888 .chained = true,
6889 .chain_id = ALC290_FIXUP_MONO_SPEAKERS,
6890 },
6891 [ALC290_FIXUP_MONO_SPEAKERS] = {
6892 .type = HDA_FIXUP_FUNC,
6893 .v.func = alc290_fixup_mono_speakers,
6894 },
6895 [ALC290_FIXUP_MONO_SPEAKERS_HSJACK] = {
6896 .type = HDA_FIXUP_FUNC,
6897 .v.func = alc290_fixup_mono_speakers,
6898 .chained = true,
6899 .chain_id = ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
6900 },
6901 [ALC269_FIXUP_THINKPAD_ACPI] = {
6902 .type = HDA_FIXUP_FUNC,
6903 .v.func = alc_fixup_thinkpad_acpi,
6904 .chained = true,
6905 .chain_id = ALC269_FIXUP_SKU_IGNORE,
6906 },
6907 [ALC269_FIXUP_DMIC_THINKPAD_ACPI] = {
6908 .type = HDA_FIXUP_FUNC,
6909 .v.func = alc_fixup_inv_dmic,
6910 .chained = true,
6911 .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
6912 },
6913 [ALC255_FIXUP_ACER_MIC_NO_PRESENCE] = {
6914 .type = HDA_FIXUP_PINS,
6915 .v.pins = (const struct hda_pintbl[]) {
6916 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6917 { }
6918 },
6919 .chained = true,
6920 .chain_id = ALC255_FIXUP_HEADSET_MODE
6921 },
6922 [ALC255_FIXUP_ASUS_MIC_NO_PRESENCE] = {
6923 .type = HDA_FIXUP_PINS,
6924 .v.pins = (const struct hda_pintbl[]) {
6925 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6926 { }
6927 },
6928 .chained = true,
6929 .chain_id = ALC255_FIXUP_HEADSET_MODE
6930 },
6931 [ALC255_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6932 .type = HDA_FIXUP_PINS,
6933 .v.pins = (const struct hda_pintbl[]) {
6934 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6935 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6936 { }
6937 },
6938 .chained = true,
6939 .chain_id = ALC255_FIXUP_HEADSET_MODE
6940 },
6941 [ALC255_FIXUP_DELL2_MIC_NO_PRESENCE] = {
6942 .type = HDA_FIXUP_PINS,
6943 .v.pins = (const struct hda_pintbl[]) {
6944 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6945 { }
6946 },
6947 .chained = true,
6948 .chain_id = ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC
6949 },
6950 [ALC255_FIXUP_HEADSET_MODE] = {
6951 .type = HDA_FIXUP_FUNC,
6952 .v.func = alc_fixup_headset_mode_alc255,
6953 .chained = true,
David Brazdil0f672f62019-12-10 10:32:29 +00006954 .chain_id = ALC255_FIXUP_MIC_MUTE_LED
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00006955 },
6956 [ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC] = {
6957 .type = HDA_FIXUP_FUNC,
6958 .v.func = alc_fixup_headset_mode_alc255_no_hp_mic,
6959 },
6960 [ALC293_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6961 .type = HDA_FIXUP_PINS,
6962 .v.pins = (const struct hda_pintbl[]) {
6963 { 0x18, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6964 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6965 { }
6966 },
6967 .chained = true,
6968 .chain_id = ALC269_FIXUP_HEADSET_MODE
6969 },
6970 [ALC292_FIXUP_TPT440_DOCK] = {
6971 .type = HDA_FIXUP_FUNC,
6972 .v.func = alc_fixup_tpt440_dock,
6973 .chained = true,
6974 .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST
6975 },
6976 [ALC292_FIXUP_TPT440] = {
6977 .type = HDA_FIXUP_FUNC,
6978 .v.func = alc_fixup_disable_aamix,
6979 .chained = true,
6980 .chain_id = ALC292_FIXUP_TPT440_DOCK,
6981 },
6982 [ALC283_FIXUP_HEADSET_MIC] = {
6983 .type = HDA_FIXUP_PINS,
6984 .v.pins = (const struct hda_pintbl[]) {
6985 { 0x19, 0x04a110f0 },
6986 { },
6987 },
6988 },
David Brazdil0f672f62019-12-10 10:32:29 +00006989 [ALC255_FIXUP_MIC_MUTE_LED] = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00006990 .type = HDA_FIXUP_FUNC,
David Brazdil0f672f62019-12-10 10:32:29 +00006991 .v.func = snd_hda_gen_fixup_micmute_led,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00006992 },
6993 [ALC282_FIXUP_ASPIRE_V5_PINS] = {
6994 .type = HDA_FIXUP_PINS,
6995 .v.pins = (const struct hda_pintbl[]) {
6996 { 0x12, 0x90a60130 },
6997 { 0x14, 0x90170110 },
6998 { 0x17, 0x40000008 },
6999 { 0x18, 0x411111f0 },
7000 { 0x19, 0x01a1913c },
7001 { 0x1a, 0x411111f0 },
7002 { 0x1b, 0x411111f0 },
7003 { 0x1d, 0x40f89b2d },
7004 { 0x1e, 0x411111f0 },
7005 { 0x21, 0x0321101f },
7006 { },
7007 },
7008 },
Olivier Deprez0e641232021-09-23 10:07:05 +02007009 [ALC269VB_FIXUP_ASPIRE_E1_COEF] = {
7010 .type = HDA_FIXUP_FUNC,
7011 .v.func = alc269vb_fixup_aspire_e1_coef,
7012 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00007013 [ALC280_FIXUP_HP_GPIO4] = {
7014 .type = HDA_FIXUP_FUNC,
7015 .v.func = alc280_fixup_hp_gpio4,
7016 },
7017 [ALC286_FIXUP_HP_GPIO_LED] = {
7018 .type = HDA_FIXUP_FUNC,
7019 .v.func = alc286_fixup_hp_gpio_led,
7020 },
7021 [ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY] = {
7022 .type = HDA_FIXUP_FUNC,
7023 .v.func = alc280_fixup_hp_gpio2_mic_hotkey,
7024 },
7025 [ALC280_FIXUP_HP_DOCK_PINS] = {
7026 .type = HDA_FIXUP_PINS,
7027 .v.pins = (const struct hda_pintbl[]) {
7028 { 0x1b, 0x21011020 }, /* line-out */
7029 { 0x1a, 0x01a1903c }, /* headset mic */
7030 { 0x18, 0x2181103f }, /* line-in */
7031 { },
7032 },
7033 .chained = true,
7034 .chain_id = ALC280_FIXUP_HP_GPIO4
7035 },
7036 [ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED] = {
7037 .type = HDA_FIXUP_PINS,
7038 .v.pins = (const struct hda_pintbl[]) {
7039 { 0x1b, 0x21011020 }, /* line-out */
7040 { 0x18, 0x2181103f }, /* line-in */
7041 { },
7042 },
7043 .chained = true,
7044 .chain_id = ALC269_FIXUP_HP_GPIO_MIC1_LED
7045 },
7046 [ALC280_FIXUP_HP_9480M] = {
7047 .type = HDA_FIXUP_FUNC,
7048 .v.func = alc280_fixup_hp_9480m,
7049 },
7050 [ALC288_FIXUP_DELL_HEADSET_MODE] = {
7051 .type = HDA_FIXUP_FUNC,
7052 .v.func = alc_fixup_headset_mode_dell_alc288,
7053 .chained = true,
David Brazdil0f672f62019-12-10 10:32:29 +00007054 .chain_id = ALC255_FIXUP_MIC_MUTE_LED
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00007055 },
7056 [ALC288_FIXUP_DELL1_MIC_NO_PRESENCE] = {
7057 .type = HDA_FIXUP_PINS,
7058 .v.pins = (const struct hda_pintbl[]) {
7059 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
7060 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
7061 { }
7062 },
7063 .chained = true,
7064 .chain_id = ALC288_FIXUP_DELL_HEADSET_MODE
7065 },
7066 [ALC288_FIXUP_DISABLE_AAMIX] = {
7067 .type = HDA_FIXUP_FUNC,
7068 .v.func = alc_fixup_disable_aamix,
7069 .chained = true,
7070 .chain_id = ALC288_FIXUP_DELL1_MIC_NO_PRESENCE
7071 },
7072 [ALC288_FIXUP_DELL_XPS_13] = {
7073 .type = HDA_FIXUP_FUNC,
7074 .v.func = alc_fixup_dell_xps13,
7075 .chained = true,
7076 .chain_id = ALC288_FIXUP_DISABLE_AAMIX
7077 },
7078 [ALC292_FIXUP_DISABLE_AAMIX] = {
7079 .type = HDA_FIXUP_FUNC,
7080 .v.func = alc_fixup_disable_aamix,
7081 .chained = true,
7082 .chain_id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE
7083 },
7084 [ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK] = {
7085 .type = HDA_FIXUP_FUNC,
7086 .v.func = alc_fixup_disable_aamix,
7087 .chained = true,
7088 .chain_id = ALC293_FIXUP_DELL1_MIC_NO_PRESENCE
7089 },
Olivier Deprez0e641232021-09-23 10:07:05 +02007090 [ALC292_FIXUP_DELL_E7X_AAMIX] = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00007091 .type = HDA_FIXUP_FUNC,
7092 .v.func = alc_fixup_dell_xps13,
7093 .chained = true,
7094 .chain_id = ALC292_FIXUP_DISABLE_AAMIX
7095 },
Olivier Deprez0e641232021-09-23 10:07:05 +02007096 [ALC292_FIXUP_DELL_E7X] = {
7097 .type = HDA_FIXUP_FUNC,
7098 .v.func = snd_hda_gen_fixup_micmute_led,
7099 /* micmute fixup must be applied at last */
7100 .chained_before = true,
7101 .chain_id = ALC292_FIXUP_DELL_E7X_AAMIX,
7102 },
David Brazdil0f672f62019-12-10 10:32:29 +00007103 [ALC298_FIXUP_ALIENWARE_MIC_NO_PRESENCE] = {
7104 .type = HDA_FIXUP_PINS,
7105 .v.pins = (const struct hda_pintbl[]) {
7106 { 0x18, 0x01a1913c }, /* headset mic w/o jack detect */
7107 { }
7108 },
7109 .chained_before = true,
7110 .chain_id = ALC269_FIXUP_HEADSET_MODE,
7111 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00007112 [ALC298_FIXUP_DELL1_MIC_NO_PRESENCE] = {
7113 .type = HDA_FIXUP_PINS,
7114 .v.pins = (const struct hda_pintbl[]) {
7115 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
7116 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
7117 { }
7118 },
7119 .chained = true,
7120 .chain_id = ALC269_FIXUP_HEADSET_MODE
7121 },
7122 [ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE] = {
7123 .type = HDA_FIXUP_PINS,
7124 .v.pins = (const struct hda_pintbl[]) {
7125 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
7126 { }
7127 },
7128 .chained = true,
7129 .chain_id = ALC269_FIXUP_HEADSET_MODE
7130 },
7131 [ALC275_FIXUP_DELL_XPS] = {
7132 .type = HDA_FIXUP_VERBS,
7133 .v.verbs = (const struct hda_verb[]) {
7134 /* Enables internal speaker */
7135 {0x20, AC_VERB_SET_COEF_INDEX, 0x1f},
7136 {0x20, AC_VERB_SET_PROC_COEF, 0x00c0},
7137 {0x20, AC_VERB_SET_COEF_INDEX, 0x30},
7138 {0x20, AC_VERB_SET_PROC_COEF, 0x00b1},
7139 {}
7140 }
7141 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00007142 [ALC293_FIXUP_LENOVO_SPK_NOISE] = {
7143 .type = HDA_FIXUP_FUNC,
7144 .v.func = alc_fixup_disable_aamix,
7145 .chained = true,
7146 .chain_id = ALC269_FIXUP_THINKPAD_ACPI
7147 },
7148 [ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY] = {
7149 .type = HDA_FIXUP_FUNC,
7150 .v.func = alc233_fixup_lenovo_line2_mic_hotkey,
7151 },
Olivier Deprez0e641232021-09-23 10:07:05 +02007152 [ALC233_FIXUP_INTEL_NUC8_DMIC] = {
7153 .type = HDA_FIXUP_FUNC,
7154 .v.func = alc_fixup_inv_dmic,
7155 .chained = true,
7156 .chain_id = ALC233_FIXUP_INTEL_NUC8_BOOST,
7157 },
7158 [ALC233_FIXUP_INTEL_NUC8_BOOST] = {
7159 .type = HDA_FIXUP_FUNC,
7160 .v.func = alc269_fixup_limit_int_mic_boost
7161 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00007162 [ALC255_FIXUP_DELL_SPK_NOISE] = {
7163 .type = HDA_FIXUP_FUNC,
7164 .v.func = alc_fixup_disable_aamix,
7165 .chained = true,
7166 .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
7167 },
David Brazdil0f672f62019-12-10 10:32:29 +00007168 [ALC225_FIXUP_DISABLE_MIC_VREF] = {
7169 .type = HDA_FIXUP_FUNC,
7170 .v.func = alc_fixup_disable_mic_vref,
7171 .chained = true,
7172 .chain_id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE
7173 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00007174 [ALC225_FIXUP_DELL1_MIC_NO_PRESENCE] = {
7175 .type = HDA_FIXUP_VERBS,
7176 .v.verbs = (const struct hda_verb[]) {
7177 /* Disable pass-through path for FRONT 14h */
7178 { 0x20, AC_VERB_SET_COEF_INDEX, 0x36 },
7179 { 0x20, AC_VERB_SET_PROC_COEF, 0x57d7 },
7180 {}
7181 },
7182 .chained = true,
David Brazdil0f672f62019-12-10 10:32:29 +00007183 .chain_id = ALC225_FIXUP_DISABLE_MIC_VREF
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00007184 },
7185 [ALC280_FIXUP_HP_HEADSET_MIC] = {
7186 .type = HDA_FIXUP_FUNC,
7187 .v.func = alc_fixup_disable_aamix,
7188 .chained = true,
7189 .chain_id = ALC269_FIXUP_HEADSET_MIC,
7190 },
7191 [ALC221_FIXUP_HP_FRONT_MIC] = {
7192 .type = HDA_FIXUP_PINS,
7193 .v.pins = (const struct hda_pintbl[]) {
7194 { 0x19, 0x02a19020 }, /* Front Mic */
7195 { }
7196 },
7197 },
7198 [ALC292_FIXUP_TPT460] = {
7199 .type = HDA_FIXUP_FUNC,
7200 .v.func = alc_fixup_tpt440_dock,
7201 .chained = true,
7202 .chain_id = ALC293_FIXUP_LENOVO_SPK_NOISE,
7203 },
7204 [ALC298_FIXUP_SPK_VOLUME] = {
7205 .type = HDA_FIXUP_FUNC,
7206 .v.func = alc298_fixup_speaker_volume,
7207 .chained = true,
7208 .chain_id = ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE,
7209 },
Olivier Deprez0e641232021-09-23 10:07:05 +02007210 [ALC298_FIXUP_LENOVO_SPK_VOLUME] = {
7211 .type = HDA_FIXUP_FUNC,
7212 .v.func = alc298_fixup_speaker_volume,
7213 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00007214 [ALC295_FIXUP_DISABLE_DAC3] = {
7215 .type = HDA_FIXUP_FUNC,
7216 .v.func = alc295_fixup_disable_dac3,
7217 },
Olivier Deprez0e641232021-09-23 10:07:05 +02007218 [ALC285_FIXUP_SPEAKER2_TO_DAC1] = {
7219 .type = HDA_FIXUP_FUNC,
7220 .v.func = alc285_fixup_speaker2_to_dac1,
7221 .chained = true,
7222 .chain_id = ALC269_FIXUP_THINKPAD_ACPI
7223 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00007224 [ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER] = {
7225 .type = HDA_FIXUP_PINS,
7226 .v.pins = (const struct hda_pintbl[]) {
7227 { 0x1b, 0x90170151 },
7228 { }
7229 },
7230 .chained = true,
7231 .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
7232 },
7233 [ALC269_FIXUP_ATIV_BOOK_8] = {
7234 .type = HDA_FIXUP_FUNC,
7235 .v.func = alc_fixup_auto_mute_via_amp,
7236 .chained = true,
7237 .chain_id = ALC269_FIXUP_NO_SHUTUP
7238 },
7239 [ALC221_FIXUP_HP_MIC_NO_PRESENCE] = {
7240 .type = HDA_FIXUP_PINS,
7241 .v.pins = (const struct hda_pintbl[]) {
7242 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
7243 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
7244 { }
7245 },
7246 .chained = true,
7247 .chain_id = ALC269_FIXUP_HEADSET_MODE
7248 },
7249 [ALC256_FIXUP_ASUS_HEADSET_MODE] = {
7250 .type = HDA_FIXUP_FUNC,
7251 .v.func = alc_fixup_headset_mode,
7252 },
7253 [ALC256_FIXUP_ASUS_MIC] = {
7254 .type = HDA_FIXUP_PINS,
7255 .v.pins = (const struct hda_pintbl[]) {
7256 { 0x13, 0x90a60160 }, /* use as internal mic */
7257 { 0x19, 0x04a11120 }, /* use as headset mic, without its own jack detect */
7258 { }
7259 },
7260 .chained = true,
7261 .chain_id = ALC256_FIXUP_ASUS_HEADSET_MODE
7262 },
7263 [ALC256_FIXUP_ASUS_AIO_GPIO2] = {
7264 .type = HDA_FIXUP_FUNC,
7265 /* Set up GPIO2 for the speaker amp */
7266 .v.func = alc_fixup_gpio4,
7267 },
7268 [ALC233_FIXUP_ASUS_MIC_NO_PRESENCE] = {
7269 .type = HDA_FIXUP_PINS,
7270 .v.pins = (const struct hda_pintbl[]) {
7271 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
7272 { }
7273 },
7274 .chained = true,
7275 .chain_id = ALC269_FIXUP_HEADSET_MIC
7276 },
7277 [ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE] = {
7278 .type = HDA_FIXUP_VERBS,
7279 .v.verbs = (const struct hda_verb[]) {
7280 /* Enables internal speaker */
7281 {0x20, AC_VERB_SET_COEF_INDEX, 0x40},
7282 {0x20, AC_VERB_SET_PROC_COEF, 0x8800},
7283 {}
7284 },
7285 .chained = true,
7286 .chain_id = ALC233_FIXUP_ASUS_MIC_NO_PRESENCE
7287 },
7288 [ALC233_FIXUP_LENOVO_MULTI_CODECS] = {
7289 .type = HDA_FIXUP_FUNC,
7290 .v.func = alc233_alc662_fixup_lenovo_dual_codecs,
Olivier Deprez0e641232021-09-23 10:07:05 +02007291 .chained = true,
7292 .chain_id = ALC269_FIXUP_GPIO2
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00007293 },
David Brazdil0f672f62019-12-10 10:32:29 +00007294 [ALC233_FIXUP_ACER_HEADSET_MIC] = {
7295 .type = HDA_FIXUP_VERBS,
7296 .v.verbs = (const struct hda_verb[]) {
7297 { 0x20, AC_VERB_SET_COEF_INDEX, 0x45 },
7298 { 0x20, AC_VERB_SET_PROC_COEF, 0x5089 },
7299 { }
7300 },
7301 .chained = true,
7302 .chain_id = ALC233_FIXUP_ASUS_MIC_NO_PRESENCE
7303 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00007304 [ALC294_FIXUP_LENOVO_MIC_LOCATION] = {
7305 .type = HDA_FIXUP_PINS,
7306 .v.pins = (const struct hda_pintbl[]) {
7307 /* Change the mic location from front to right, otherwise there are
7308 two front mics with the same name, pulseaudio can't handle them.
7309 This is just a temporary workaround, after applying this fixup,
7310 there will be one "Front Mic" and one "Mic" in this machine.
7311 */
7312 { 0x1a, 0x04a19040 },
7313 { }
7314 },
7315 },
7316 [ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE] = {
7317 .type = HDA_FIXUP_PINS,
7318 .v.pins = (const struct hda_pintbl[]) {
7319 { 0x16, 0x0101102f }, /* Rear Headset HP */
7320 { 0x19, 0x02a1913c }, /* use as Front headset mic, without its own jack detect */
7321 { 0x1a, 0x01a19030 }, /* Rear Headset MIC */
7322 { 0x1b, 0x02011020 },
7323 { }
7324 },
7325 .chained = true,
Olivier Deprez0e641232021-09-23 10:07:05 +02007326 .chain_id = ALC225_FIXUP_S3_POP_NOISE
7327 },
7328 [ALC225_FIXUP_S3_POP_NOISE] = {
7329 .type = HDA_FIXUP_FUNC,
7330 .v.func = alc225_fixup_s3_pop_noise,
7331 .chained = true,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00007332 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
7333 },
7334 [ALC700_FIXUP_INTEL_REFERENCE] = {
7335 .type = HDA_FIXUP_VERBS,
7336 .v.verbs = (const struct hda_verb[]) {
7337 /* Enables internal speaker */
7338 {0x20, AC_VERB_SET_COEF_INDEX, 0x45},
7339 {0x20, AC_VERB_SET_PROC_COEF, 0x5289},
7340 {0x20, AC_VERB_SET_COEF_INDEX, 0x4A},
7341 {0x20, AC_VERB_SET_PROC_COEF, 0x001b},
7342 {0x58, AC_VERB_SET_COEF_INDEX, 0x00},
7343 {0x58, AC_VERB_SET_PROC_COEF, 0x3888},
7344 {0x20, AC_VERB_SET_COEF_INDEX, 0x6f},
7345 {0x20, AC_VERB_SET_PROC_COEF, 0x2c0b},
7346 {}
7347 }
7348 },
7349 [ALC274_FIXUP_DELL_BIND_DACS] = {
7350 .type = HDA_FIXUP_FUNC,
7351 .v.func = alc274_fixup_bind_dacs,
7352 .chained = true,
7353 .chain_id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE
7354 },
7355 [ALC274_FIXUP_DELL_AIO_LINEOUT_VERB] = {
7356 .type = HDA_FIXUP_PINS,
7357 .v.pins = (const struct hda_pintbl[]) {
7358 { 0x1b, 0x0401102f },
7359 { }
7360 },
7361 .chained = true,
7362 .chain_id = ALC274_FIXUP_DELL_BIND_DACS
7363 },
Olivier Deprez0e641232021-09-23 10:07:05 +02007364 [ALC298_FIXUP_TPT470_DOCK_FIX] = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00007365 .type = HDA_FIXUP_FUNC,
7366 .v.func = alc_fixup_tpt470_dock,
7367 .chained = true,
7368 .chain_id = ALC293_FIXUP_LENOVO_SPK_NOISE
7369 },
Olivier Deprez0e641232021-09-23 10:07:05 +02007370 [ALC298_FIXUP_TPT470_DOCK] = {
7371 .type = HDA_FIXUP_FUNC,
7372 .v.func = alc_fixup_tpt470_dacs,
7373 .chained = true,
7374 .chain_id = ALC298_FIXUP_TPT470_DOCK_FIX
7375 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00007376 [ALC255_FIXUP_DUMMY_LINEOUT_VERB] = {
7377 .type = HDA_FIXUP_PINS,
7378 .v.pins = (const struct hda_pintbl[]) {
7379 { 0x14, 0x0201101f },
7380 { }
7381 },
7382 .chained = true,
7383 .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
7384 },
7385 [ALC255_FIXUP_DELL_HEADSET_MIC] = {
7386 .type = HDA_FIXUP_PINS,
7387 .v.pins = (const struct hda_pintbl[]) {
7388 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
7389 { }
7390 },
7391 .chained = true,
7392 .chain_id = ALC269_FIXUP_HEADSET_MIC
7393 },
7394 [ALC295_FIXUP_HP_X360] = {
7395 .type = HDA_FIXUP_FUNC,
7396 .v.func = alc295_fixup_hp_top_speakers,
7397 .chained = true,
7398 .chain_id = ALC269_FIXUP_HP_MUTE_LED_MIC3
7399 },
7400 [ALC221_FIXUP_HP_HEADSET_MIC] = {
7401 .type = HDA_FIXUP_PINS,
7402 .v.pins = (const struct hda_pintbl[]) {
7403 { 0x19, 0x0181313f},
7404 { }
7405 },
7406 .chained = true,
7407 .chain_id = ALC269_FIXUP_HEADSET_MIC
7408 },
7409 [ALC285_FIXUP_LENOVO_HEADPHONE_NOISE] = {
7410 .type = HDA_FIXUP_FUNC,
7411 .v.func = alc285_fixup_invalidate_dacs,
7412 .chained = true,
7413 .chain_id = ALC269_FIXUP_THINKPAD_ACPI
7414 },
7415 [ALC295_FIXUP_HP_AUTO_MUTE] = {
7416 .type = HDA_FIXUP_FUNC,
7417 .v.func = alc_fixup_auto_mute_via_amp,
7418 },
7419 [ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE] = {
7420 .type = HDA_FIXUP_PINS,
7421 .v.pins = (const struct hda_pintbl[]) {
7422 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
7423 { }
7424 },
7425 .chained = true,
7426 .chain_id = ALC269_FIXUP_HEADSET_MIC
7427 },
7428 [ALC294_FIXUP_ASUS_MIC] = {
7429 .type = HDA_FIXUP_PINS,
7430 .v.pins = (const struct hda_pintbl[]) {
7431 { 0x13, 0x90a60160 }, /* use as internal mic */
7432 { 0x19, 0x04a11120 }, /* use as headset mic, without its own jack detect */
7433 { }
7434 },
7435 .chained = true,
Olivier Deprez0e641232021-09-23 10:07:05 +02007436 .chain_id = ALC269_FIXUP_HEADSET_MIC
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00007437 },
7438 [ALC294_FIXUP_ASUS_HEADSET_MIC] = {
7439 .type = HDA_FIXUP_PINS,
7440 .v.pins = (const struct hda_pintbl[]) {
David Brazdil0f672f62019-12-10 10:32:29 +00007441 { 0x19, 0x01a1103c }, /* use as headset mic */
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00007442 { }
7443 },
7444 .chained = true,
Olivier Deprez0e641232021-09-23 10:07:05 +02007445 .chain_id = ALC269_FIXUP_HEADSET_MIC
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00007446 },
7447 [ALC294_FIXUP_ASUS_SPK] = {
7448 .type = HDA_FIXUP_VERBS,
7449 .v.verbs = (const struct hda_verb[]) {
7450 /* Set EAPD high */
7451 { 0x20, AC_VERB_SET_COEF_INDEX, 0x40 },
7452 { 0x20, AC_VERB_SET_PROC_COEF, 0x8800 },
Olivier Deprez0e641232021-09-23 10:07:05 +02007453 { 0x20, AC_VERB_SET_COEF_INDEX, 0x0f },
7454 { 0x20, AC_VERB_SET_PROC_COEF, 0x7774 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00007455 { }
7456 },
7457 .chained = true,
7458 .chain_id = ALC294_FIXUP_ASUS_HEADSET_MIC
7459 },
David Brazdil0f672f62019-12-10 10:32:29 +00007460 [ALC295_FIXUP_CHROME_BOOK] = {
7461 .type = HDA_FIXUP_FUNC,
7462 .v.func = alc295_fixup_chromebook,
7463 .chained = true,
7464 .chain_id = ALC225_FIXUP_HEADSET_JACK
7465 },
7466 [ALC225_FIXUP_HEADSET_JACK] = {
7467 .type = HDA_FIXUP_FUNC,
7468 .v.func = alc_fixup_headset_jack,
7469 },
7470 [ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE] = {
7471 .type = HDA_FIXUP_PINS,
7472 .v.pins = (const struct hda_pintbl[]) {
7473 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
7474 { }
7475 },
7476 .chained = true,
7477 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
7478 },
7479 [ALC285_FIXUP_LENOVO_PC_BEEP_IN_NOISE] = {
7480 .type = HDA_FIXUP_VERBS,
7481 .v.verbs = (const struct hda_verb[]) {
7482 /* Disable PCBEEP-IN passthrough */
7483 { 0x20, AC_VERB_SET_COEF_INDEX, 0x36 },
7484 { 0x20, AC_VERB_SET_PROC_COEF, 0x57d7 },
7485 { }
7486 },
7487 .chained = true,
7488 .chain_id = ALC285_FIXUP_LENOVO_HEADPHONE_NOISE
7489 },
7490 [ALC255_FIXUP_ACER_HEADSET_MIC] = {
7491 .type = HDA_FIXUP_PINS,
7492 .v.pins = (const struct hda_pintbl[]) {
7493 { 0x19, 0x03a11130 },
7494 { 0x1a, 0x90a60140 }, /* use as internal mic */
7495 { }
7496 },
7497 .chained = true,
7498 .chain_id = ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC
7499 },
7500 [ALC225_FIXUP_DELL_WYSE_AIO_MIC_NO_PRESENCE] = {
7501 .type = HDA_FIXUP_PINS,
7502 .v.pins = (const struct hda_pintbl[]) {
7503 { 0x16, 0x01011020 }, /* Rear Line out */
7504 { 0x19, 0x01a1913c }, /* use as Front headset mic, without its own jack detect */
7505 { }
7506 },
7507 .chained = true,
7508 .chain_id = ALC225_FIXUP_WYSE_AUTO_MUTE
7509 },
7510 [ALC225_FIXUP_WYSE_AUTO_MUTE] = {
7511 .type = HDA_FIXUP_FUNC,
7512 .v.func = alc_fixup_auto_mute_via_amp,
7513 .chained = true,
7514 .chain_id = ALC225_FIXUP_WYSE_DISABLE_MIC_VREF
7515 },
7516 [ALC225_FIXUP_WYSE_DISABLE_MIC_VREF] = {
7517 .type = HDA_FIXUP_FUNC,
7518 .v.func = alc_fixup_disable_mic_vref,
7519 .chained = true,
7520 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
7521 },
7522 [ALC286_FIXUP_ACER_AIO_HEADSET_MIC] = {
7523 .type = HDA_FIXUP_VERBS,
7524 .v.verbs = (const struct hda_verb[]) {
7525 { 0x20, AC_VERB_SET_COEF_INDEX, 0x4f },
7526 { 0x20, AC_VERB_SET_PROC_COEF, 0x5029 },
7527 { }
7528 },
7529 .chained = true,
7530 .chain_id = ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE
7531 },
7532 [ALC256_FIXUP_ASUS_HEADSET_MIC] = {
7533 .type = HDA_FIXUP_PINS,
7534 .v.pins = (const struct hda_pintbl[]) {
7535 { 0x19, 0x03a11020 }, /* headset mic with jack detect */
7536 { }
7537 },
7538 .chained = true,
7539 .chain_id = ALC256_FIXUP_ASUS_HEADSET_MODE
7540 },
7541 [ALC256_FIXUP_ASUS_MIC_NO_PRESENCE] = {
7542 .type = HDA_FIXUP_PINS,
7543 .v.pins = (const struct hda_pintbl[]) {
7544 { 0x19, 0x04a11120 }, /* use as headset mic, without its own jack detect */
7545 { }
7546 },
7547 .chained = true,
7548 .chain_id = ALC256_FIXUP_ASUS_HEADSET_MODE
7549 },
7550 [ALC299_FIXUP_PREDATOR_SPK] = {
7551 .type = HDA_FIXUP_PINS,
7552 .v.pins = (const struct hda_pintbl[]) {
7553 { 0x21, 0x90170150 }, /* use as headset mic, without its own jack detect */
7554 { }
7555 }
7556 },
David Brazdil0f672f62019-12-10 10:32:29 +00007557 [ALC256_FIXUP_MEDION_HEADSET_NO_PRESENCE] = {
7558 .type = HDA_FIXUP_PINS,
7559 .v.pins = (const struct hda_pintbl[]) {
7560 { 0x19, 0x04a11040 },
7561 { 0x21, 0x04211020 },
7562 { }
7563 },
7564 .chained = true,
7565 .chain_id = ALC256_FIXUP_ASUS_HEADSET_MODE
7566 },
Olivier Deprez0e641232021-09-23 10:07:05 +02007567 [ALC289_FIXUP_DELL_SPK2] = {
7568 .type = HDA_FIXUP_PINS,
7569 .v.pins = (const struct hda_pintbl[]) {
7570 { 0x17, 0x90170130 }, /* bass spk */
7571 { }
7572 },
7573 .chained = true,
7574 .chain_id = ALC269_FIXUP_DELL4_MIC_NO_PRESENCE
7575 },
7576 [ALC289_FIXUP_DUAL_SPK] = {
7577 .type = HDA_FIXUP_FUNC,
7578 .v.func = alc285_fixup_speaker2_to_dac1,
7579 .chained = true,
7580 .chain_id = ALC289_FIXUP_DELL_SPK2
7581 },
7582 [ALC294_FIXUP_SPK2_TO_DAC1] = {
7583 .type = HDA_FIXUP_FUNC,
7584 .v.func = alc285_fixup_speaker2_to_dac1,
7585 .chained = true,
7586 .chain_id = ALC294_FIXUP_ASUS_HEADSET_MIC
7587 },
7588 [ALC294_FIXUP_ASUS_DUAL_SPK] = {
7589 .type = HDA_FIXUP_FUNC,
7590 /* The GPIO must be pulled to initialize the AMP */
7591 .v.func = alc_fixup_gpio4,
7592 .chained = true,
7593 .chain_id = ALC294_FIXUP_SPK2_TO_DAC1
7594 },
7595 [ALC285_FIXUP_THINKPAD_X1_GEN7] = {
7596 .type = HDA_FIXUP_FUNC,
7597 .v.func = alc285_fixup_thinkpad_x1_gen7,
7598 .chained = true,
7599 .chain_id = ALC269_FIXUP_THINKPAD_ACPI
7600 },
7601 [ALC285_FIXUP_THINKPAD_HEADSET_JACK] = {
7602 .type = HDA_FIXUP_FUNC,
7603 .v.func = alc_fixup_headset_jack,
7604 .chained = true,
7605 .chain_id = ALC285_FIXUP_THINKPAD_X1_GEN7
7606 },
7607 [ALC294_FIXUP_ASUS_HPE] = {
7608 .type = HDA_FIXUP_VERBS,
7609 .v.verbs = (const struct hda_verb[]) {
7610 /* Set EAPD high */
7611 { 0x20, AC_VERB_SET_COEF_INDEX, 0x0f },
7612 { 0x20, AC_VERB_SET_PROC_COEF, 0x7774 },
7613 { }
7614 },
7615 .chained = true,
7616 .chain_id = ALC294_FIXUP_ASUS_HEADSET_MIC
7617 },
7618 [ALC294_FIXUP_ASUS_GX502_PINS] = {
7619 .type = HDA_FIXUP_PINS,
7620 .v.pins = (const struct hda_pintbl[]) {
7621 { 0x19, 0x03a11050 }, /* front HP mic */
7622 { 0x1a, 0x01a11830 }, /* rear external mic */
7623 { 0x21, 0x03211020 }, /* front HP out */
7624 { }
7625 },
7626 .chained = true,
7627 .chain_id = ALC294_FIXUP_ASUS_GX502_VERBS
7628 },
7629 [ALC294_FIXUP_ASUS_GX502_VERBS] = {
7630 .type = HDA_FIXUP_VERBS,
7631 .v.verbs = (const struct hda_verb[]) {
7632 /* set 0x15 to HP-OUT ctrl */
7633 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
7634 /* unmute the 0x15 amp */
7635 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000 },
7636 { }
7637 },
7638 .chained = true,
7639 .chain_id = ALC294_FIXUP_ASUS_GX502_HP
7640 },
7641 [ALC294_FIXUP_ASUS_GX502_HP] = {
7642 .type = HDA_FIXUP_FUNC,
7643 .v.func = alc294_fixup_gx502_hp,
7644 },
7645 [ALC294_FIXUP_ASUS_GU502_PINS] = {
7646 .type = HDA_FIXUP_PINS,
7647 .v.pins = (const struct hda_pintbl[]) {
7648 { 0x19, 0x01a11050 }, /* rear HP mic */
7649 { 0x1a, 0x01a11830 }, /* rear external mic */
7650 { 0x21, 0x012110f0 }, /* rear HP out */
7651 { }
7652 },
7653 .chained = true,
7654 .chain_id = ALC294_FIXUP_ASUS_GU502_VERBS
7655 },
7656 [ALC294_FIXUP_ASUS_GU502_VERBS] = {
7657 .type = HDA_FIXUP_VERBS,
7658 .v.verbs = (const struct hda_verb[]) {
7659 /* set 0x15 to HP-OUT ctrl */
7660 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
7661 /* unmute the 0x15 amp */
7662 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000 },
7663 /* set 0x1b to HP-OUT */
7664 { 0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7665 { }
7666 },
7667 .chained = true,
7668 .chain_id = ALC294_FIXUP_ASUS_GU502_HP
7669 },
7670 [ALC294_FIXUP_ASUS_GU502_HP] = {
7671 .type = HDA_FIXUP_FUNC,
7672 .v.func = alc294_fixup_gu502_hp,
7673 },
7674 [ALC294_FIXUP_ASUS_COEF_1B] = {
7675 .type = HDA_FIXUP_VERBS,
7676 .v.verbs = (const struct hda_verb[]) {
7677 /* Set bit 10 to correct noisy output after reboot from
7678 * Windows 10 (due to pop noise reduction?)
7679 */
7680 { 0x20, AC_VERB_SET_COEF_INDEX, 0x1b },
7681 { 0x20, AC_VERB_SET_PROC_COEF, 0x4e4b },
7682 { }
7683 },
7684 .chained = true,
7685 .chain_id = ALC289_FIXUP_ASUS_GA401,
7686 },
7687 [ALC285_FIXUP_HP_GPIO_LED] = {
7688 .type = HDA_FIXUP_FUNC,
7689 .v.func = alc285_fixup_hp_gpio_led,
7690 },
7691 [ALC285_FIXUP_HP_MUTE_LED] = {
7692 .type = HDA_FIXUP_FUNC,
7693 .v.func = alc285_fixup_hp_mute_led,
7694 },
7695 [ALC236_FIXUP_HP_MUTE_LED] = {
7696 .type = HDA_FIXUP_FUNC,
7697 .v.func = alc236_fixup_hp_mute_led,
7698 },
7699 [ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET] = {
7700 .type = HDA_FIXUP_VERBS,
7701 .v.verbs = (const struct hda_verb[]) {
7702 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc5 },
7703 { }
7704 },
7705 },
7706 [ALC295_FIXUP_ASUS_MIC_NO_PRESENCE] = {
7707 .type = HDA_FIXUP_PINS,
7708 .v.pins = (const struct hda_pintbl[]) {
7709 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
7710 { }
7711 },
7712 .chained = true,
7713 .chain_id = ALC269_FIXUP_HEADSET_MODE
7714 },
7715 [ALC269VC_FIXUP_ACER_VCOPPERBOX_PINS] = {
7716 .type = HDA_FIXUP_PINS,
7717 .v.pins = (const struct hda_pintbl[]) {
7718 { 0x14, 0x90100120 }, /* use as internal speaker */
7719 { 0x18, 0x02a111f0 }, /* use as headset mic, without its own jack detect */
7720 { 0x1a, 0x01011020 }, /* use as line out */
7721 { },
7722 },
7723 .chained = true,
7724 .chain_id = ALC269_FIXUP_HEADSET_MIC
7725 },
7726 [ALC269VC_FIXUP_ACER_HEADSET_MIC] = {
7727 .type = HDA_FIXUP_PINS,
7728 .v.pins = (const struct hda_pintbl[]) {
7729 { 0x18, 0x02a11030 }, /* use as headset mic */
7730 { }
7731 },
7732 .chained = true,
7733 .chain_id = ALC269_FIXUP_HEADSET_MIC
7734 },
7735 [ALC269VC_FIXUP_ACER_MIC_NO_PRESENCE] = {
7736 .type = HDA_FIXUP_PINS,
7737 .v.pins = (const struct hda_pintbl[]) {
7738 { 0x18, 0x01a11130 }, /* use as headset mic, without its own jack detect */
7739 { }
7740 },
7741 .chained = true,
7742 .chain_id = ALC269_FIXUP_HEADSET_MIC
7743 },
7744 [ALC289_FIXUP_ASUS_GA401] = {
7745 .type = HDA_FIXUP_FUNC,
7746 .v.func = alc289_fixup_asus_ga401,
7747 .chained = true,
7748 .chain_id = ALC289_FIXUP_ASUS_GA502,
7749 },
7750 [ALC289_FIXUP_ASUS_GA502] = {
7751 .type = HDA_FIXUP_PINS,
7752 .v.pins = (const struct hda_pintbl[]) {
7753 { 0x19, 0x03a11020 }, /* headset mic with jack detect */
7754 { }
7755 },
7756 },
7757 [ALC256_FIXUP_ACER_MIC_NO_PRESENCE] = {
7758 .type = HDA_FIXUP_PINS,
7759 .v.pins = (const struct hda_pintbl[]) {
7760 { 0x19, 0x02a11120 }, /* use as headset mic, without its own jack detect */
7761 { }
7762 },
7763 .chained = true,
7764 .chain_id = ALC256_FIXUP_ASUS_HEADSET_MODE
7765 },
7766 [ALC285_FIXUP_HP_GPIO_AMP_INIT] = {
7767 .type = HDA_FIXUP_FUNC,
7768 .v.func = alc285_fixup_hp_gpio_amp_init,
7769 .chained = true,
7770 .chain_id = ALC285_FIXUP_HP_GPIO_LED
7771 },
7772 [ALC269_FIXUP_CZC_B20] = {
7773 .type = HDA_FIXUP_PINS,
7774 .v.pins = (const struct hda_pintbl[]) {
7775 { 0x12, 0x411111f0 },
7776 { 0x14, 0x90170110 }, /* speaker */
7777 { 0x15, 0x032f1020 }, /* HP out */
7778 { 0x17, 0x411111f0 },
7779 { 0x18, 0x03ab1040 }, /* mic */
7780 { 0x19, 0xb7a7013f },
7781 { 0x1a, 0x0181305f },
7782 { 0x1b, 0x411111f0 },
7783 { 0x1d, 0x411111f0 },
7784 { 0x1e, 0x411111f0 },
7785 { }
7786 },
7787 .chain_id = ALC269_FIXUP_DMIC,
7788 },
7789 [ALC269_FIXUP_CZC_TMI] = {
7790 .type = HDA_FIXUP_PINS,
7791 .v.pins = (const struct hda_pintbl[]) {
7792 { 0x12, 0x4000c000 },
7793 { 0x14, 0x90170110 }, /* speaker */
7794 { 0x15, 0x0421401f }, /* HP out */
7795 { 0x17, 0x411111f0 },
7796 { 0x18, 0x04a19020 }, /* mic */
7797 { 0x19, 0x411111f0 },
7798 { 0x1a, 0x411111f0 },
7799 { 0x1b, 0x411111f0 },
7800 { 0x1d, 0x40448505 },
7801 { 0x1e, 0x411111f0 },
7802 { 0x20, 0x8000ffff },
7803 { }
7804 },
7805 .chain_id = ALC269_FIXUP_DMIC,
7806 },
7807 [ALC269_FIXUP_CZC_L101] = {
7808 .type = HDA_FIXUP_PINS,
7809 .v.pins = (const struct hda_pintbl[]) {
7810 { 0x12, 0x40000000 },
7811 { 0x14, 0x01014010 }, /* speaker */
7812 { 0x15, 0x411111f0 }, /* HP out */
7813 { 0x16, 0x411111f0 },
7814 { 0x18, 0x01a19020 }, /* mic */
7815 { 0x19, 0x02a19021 },
7816 { 0x1a, 0x0181302f },
7817 { 0x1b, 0x0221401f },
7818 { 0x1c, 0x411111f0 },
7819 { 0x1d, 0x4044c601 },
7820 { 0x1e, 0x411111f0 },
7821 { }
7822 },
7823 .chain_id = ALC269_FIXUP_DMIC,
7824 },
7825 [ALC269_FIXUP_LEMOTE_A1802] = {
7826 .type = HDA_FIXUP_PINS,
7827 .v.pins = (const struct hda_pintbl[]) {
7828 { 0x12, 0x40000000 },
7829 { 0x14, 0x90170110 }, /* speaker */
7830 { 0x17, 0x411111f0 },
7831 { 0x18, 0x03a19040 }, /* mic1 */
7832 { 0x19, 0x90a70130 }, /* mic2 */
7833 { 0x1a, 0x411111f0 },
7834 { 0x1b, 0x411111f0 },
7835 { 0x1d, 0x40489d2d },
7836 { 0x1e, 0x411111f0 },
7837 { 0x20, 0x0003ffff },
7838 { 0x21, 0x03214020 },
7839 { }
7840 },
7841 .chain_id = ALC269_FIXUP_DMIC,
7842 },
7843 [ALC269_FIXUP_LEMOTE_A190X] = {
7844 .type = HDA_FIXUP_PINS,
7845 .v.pins = (const struct hda_pintbl[]) {
7846 { 0x14, 0x99130110 }, /* speaker */
7847 { 0x15, 0x0121401f }, /* HP out */
7848 { 0x18, 0x01a19c20 }, /* rear mic */
7849 { 0x19, 0x99a3092f }, /* front mic */
7850 { 0x1b, 0x0201401f }, /* front lineout */
7851 { }
7852 },
7853 .chain_id = ALC269_FIXUP_DMIC,
7854 },
7855 [ALC256_FIXUP_INTEL_NUC8_RUGGED] = {
7856 .type = HDA_FIXUP_PINS,
7857 .v.pins = (const struct hda_pintbl[]) {
7858 { 0x1b, 0x01a1913c }, /* use as headset mic, without its own jack detect */
7859 { }
7860 },
7861 .chained = true,
7862 .chain_id = ALC269_FIXUP_HEADSET_MODE
7863 },
7864 [ALC256_FIXUP_INTEL_NUC10] = {
7865 .type = HDA_FIXUP_PINS,
7866 .v.pins = (const struct hda_pintbl[]) {
7867 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
7868 { }
7869 },
7870 .chained = true,
7871 .chain_id = ALC269_FIXUP_HEADSET_MODE
7872 },
7873 [ALC255_FIXUP_XIAOMI_HEADSET_MIC] = {
7874 .type = HDA_FIXUP_VERBS,
7875 .v.verbs = (const struct hda_verb[]) {
7876 { 0x20, AC_VERB_SET_COEF_INDEX, 0x45 },
7877 { 0x20, AC_VERB_SET_PROC_COEF, 0x5089 },
7878 { }
7879 },
7880 .chained = true,
7881 .chain_id = ALC289_FIXUP_ASUS_GA502
7882 },
7883 [ALC274_FIXUP_HP_MIC] = {
7884 .type = HDA_FIXUP_VERBS,
7885 .v.verbs = (const struct hda_verb[]) {
7886 { 0x20, AC_VERB_SET_COEF_INDEX, 0x45 },
7887 { 0x20, AC_VERB_SET_PROC_COEF, 0x5089 },
7888 { }
7889 },
7890 },
7891 [ALC274_FIXUP_HP_HEADSET_MIC] = {
7892 .type = HDA_FIXUP_FUNC,
7893 .v.func = alc274_fixup_hp_headset_mic,
7894 .chained = true,
7895 .chain_id = ALC274_FIXUP_HP_MIC
7896 },
7897 [ALC256_FIXUP_ASUS_HPE] = {
7898 .type = HDA_FIXUP_VERBS,
7899 .v.verbs = (const struct hda_verb[]) {
7900 /* Set EAPD high */
7901 { 0x20, AC_VERB_SET_COEF_INDEX, 0x0f },
7902 { 0x20, AC_VERB_SET_PROC_COEF, 0x7778 },
7903 { }
7904 },
7905 .chained = true,
7906 .chain_id = ALC294_FIXUP_ASUS_HEADSET_MIC
7907 },
7908 [ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK] = {
7909 .type = HDA_FIXUP_FUNC,
7910 .v.func = alc_fixup_headset_jack,
7911 .chained = true,
7912 .chain_id = ALC269_FIXUP_THINKPAD_ACPI
7913 },
7914 [ALC295_FIXUP_ASUS_DACS] = {
7915 .type = HDA_FIXUP_FUNC,
7916 .v.func = alc295_fixup_asus_dacs,
7917 },
7918 [ALC295_FIXUP_HP_OMEN] = {
7919 .type = HDA_FIXUP_PINS,
7920 .v.pins = (const struct hda_pintbl[]) {
7921 { 0x12, 0xb7a60130 },
7922 { 0x13, 0x40000000 },
7923 { 0x14, 0x411111f0 },
7924 { 0x16, 0x411111f0 },
7925 { 0x17, 0x90170110 },
7926 { 0x18, 0x411111f0 },
7927 { 0x19, 0x02a11030 },
7928 { 0x1a, 0x411111f0 },
7929 { 0x1b, 0x04a19030 },
7930 { 0x1d, 0x40600001 },
7931 { 0x1e, 0x411111f0 },
7932 { 0x21, 0x03211020 },
7933 {}
7934 },
7935 .chained = true,
7936 .chain_id = ALC269_FIXUP_HP_LINE1_MIC1_LED,
7937 },
7938 [ALC285_FIXUP_HP_SPECTRE_X360] = {
7939 .type = HDA_FIXUP_FUNC,
7940 .v.func = alc285_fixup_hp_spectre_x360,
7941 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00007942};
7943
7944static const struct snd_pci_quirk alc269_fixup_tbl[] = {
7945 SND_PCI_QUIRK(0x1025, 0x0283, "Acer TravelMate 8371", ALC269_FIXUP_INV_DMIC),
7946 SND_PCI_QUIRK(0x1025, 0x029b, "Acer 1810TZ", ALC269_FIXUP_INV_DMIC),
7947 SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC),
7948 SND_PCI_QUIRK(0x1025, 0x047c, "Acer AC700", ALC269_FIXUP_ACER_AC700),
7949 SND_PCI_QUIRK(0x1025, 0x072d, "Acer Aspire V5-571G", ALC269_FIXUP_ASPIRE_HEADSET_MIC),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00007950 SND_PCI_QUIRK(0x1025, 0x0740, "Acer AO725", ALC271_FIXUP_HP_GATE_MIC_JACK),
7951 SND_PCI_QUIRK(0x1025, 0x0742, "Acer AO756", ALC271_FIXUP_HP_GATE_MIC_JACK),
7952 SND_PCI_QUIRK(0x1025, 0x0762, "Acer Aspire E1-472", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572),
7953 SND_PCI_QUIRK(0x1025, 0x0775, "Acer Aspire E1-572", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572),
7954 SND_PCI_QUIRK(0x1025, 0x079b, "Acer Aspire V5-573G", ALC282_FIXUP_ASPIRE_V5_PINS),
Olivier Deprez0e641232021-09-23 10:07:05 +02007955 SND_PCI_QUIRK(0x1025, 0x080d, "Acer Aspire V5-122P", ALC269_FIXUP_ASPIRE_HEADSET_MIC),
7956 SND_PCI_QUIRK(0x1025, 0x0840, "Acer Aspire E1", ALC269VB_FIXUP_ASPIRE_E1_COEF),
7957 SND_PCI_QUIRK(0x1025, 0x101c, "Acer Veriton N2510G", ALC269_FIXUP_LIFEBOOK),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00007958 SND_PCI_QUIRK(0x1025, 0x102b, "Acer Aspire C24-860", ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE),
Olivier Deprez0e641232021-09-23 10:07:05 +02007959 SND_PCI_QUIRK(0x1025, 0x1065, "Acer Aspire C20-820", ALC269VC_FIXUP_ACER_HEADSET_MIC),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00007960 SND_PCI_QUIRK(0x1025, 0x106d, "Acer Cloudbook 14", ALC283_FIXUP_CHROME_BOOK),
David Brazdil0f672f62019-12-10 10:32:29 +00007961 SND_PCI_QUIRK(0x1025, 0x1099, "Acer Aspire E5-523G", ALC255_FIXUP_ACER_MIC_NO_PRESENCE),
7962 SND_PCI_QUIRK(0x1025, 0x110e, "Acer Aspire ES1-432", ALC255_FIXUP_ACER_MIC_NO_PRESENCE),
Olivier Deprez0e641232021-09-23 10:07:05 +02007963 SND_PCI_QUIRK(0x1025, 0x1166, "Acer Veriton N4640G", ALC269_FIXUP_LIFEBOOK),
7964 SND_PCI_QUIRK(0x1025, 0x1167, "Acer Veriton N6640G", ALC269_FIXUP_LIFEBOOK),
David Brazdil0f672f62019-12-10 10:32:29 +00007965 SND_PCI_QUIRK(0x1025, 0x1246, "Acer Predator Helios 500", ALC299_FIXUP_PREDATOR_SPK),
Olivier Deprez0e641232021-09-23 10:07:05 +02007966 SND_PCI_QUIRK(0x1025, 0x1247, "Acer vCopperbox", ALC269VC_FIXUP_ACER_VCOPPERBOX_PINS),
7967 SND_PCI_QUIRK(0x1025, 0x1248, "Acer Veriton N4660G", ALC269VC_FIXUP_ACER_MIC_NO_PRESENCE),
David Brazdil0f672f62019-12-10 10:32:29 +00007968 SND_PCI_QUIRK(0x1025, 0x128f, "Acer Veriton Z6860G", ALC286_FIXUP_ACER_AIO_HEADSET_MIC),
7969 SND_PCI_QUIRK(0x1025, 0x1290, "Acer Veriton Z4860G", ALC286_FIXUP_ACER_AIO_HEADSET_MIC),
7970 SND_PCI_QUIRK(0x1025, 0x1291, "Acer Veriton Z4660G", ALC286_FIXUP_ACER_AIO_HEADSET_MIC),
7971 SND_PCI_QUIRK(0x1025, 0x1308, "Acer Aspire Z24-890", ALC286_FIXUP_ACER_AIO_HEADSET_MIC),
7972 SND_PCI_QUIRK(0x1025, 0x132a, "Acer TravelMate B114-21", ALC233_FIXUP_ACER_HEADSET_MIC),
7973 SND_PCI_QUIRK(0x1025, 0x1330, "Acer TravelMate X514-51T", ALC255_FIXUP_ACER_HEADSET_MIC),
Olivier Deprez0e641232021-09-23 10:07:05 +02007974 SND_PCI_QUIRK(0x1025, 0x142b, "Acer Swift SF314-42", ALC255_FIXUP_ACER_MIC_NO_PRESENCE),
7975 SND_PCI_QUIRK(0x1025, 0x1430, "Acer TravelMate B311R-31", ALC256_FIXUP_ACER_MIC_NO_PRESENCE),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00007976 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
7977 SND_PCI_QUIRK(0x1028, 0x054b, "Dell XPS one 2710", ALC275_FIXUP_DELL_XPS),
7978 SND_PCI_QUIRK(0x1028, 0x05bd, "Dell Latitude E6440", ALC292_FIXUP_DELL_E7X),
7979 SND_PCI_QUIRK(0x1028, 0x05be, "Dell Latitude E6540", ALC292_FIXUP_DELL_E7X),
7980 SND_PCI_QUIRK(0x1028, 0x05ca, "Dell Latitude E7240", ALC292_FIXUP_DELL_E7X),
7981 SND_PCI_QUIRK(0x1028, 0x05cb, "Dell Latitude E7440", ALC292_FIXUP_DELL_E7X),
7982 SND_PCI_QUIRK(0x1028, 0x05da, "Dell Vostro 5460", ALC290_FIXUP_SUBWOOFER),
7983 SND_PCI_QUIRK(0x1028, 0x05f4, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
7984 SND_PCI_QUIRK(0x1028, 0x05f5, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
7985 SND_PCI_QUIRK(0x1028, 0x05f6, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
7986 SND_PCI_QUIRK(0x1028, 0x0615, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK),
7987 SND_PCI_QUIRK(0x1028, 0x0616, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK),
7988 SND_PCI_QUIRK(0x1028, 0x062c, "Dell Latitude E5550", ALC292_FIXUP_DELL_E7X),
7989 SND_PCI_QUIRK(0x1028, 0x062e, "Dell Latitude E7450", ALC292_FIXUP_DELL_E7X),
7990 SND_PCI_QUIRK(0x1028, 0x0638, "Dell Inspiron 5439", ALC290_FIXUP_MONO_SPEAKERS_HSJACK),
7991 SND_PCI_QUIRK(0x1028, 0x064a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
7992 SND_PCI_QUIRK(0x1028, 0x064b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
7993 SND_PCI_QUIRK(0x1028, 0x0665, "Dell XPS 13", ALC288_FIXUP_DELL_XPS_13),
7994 SND_PCI_QUIRK(0x1028, 0x0669, "Dell Optiplex 9020m", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
7995 SND_PCI_QUIRK(0x1028, 0x069a, "Dell Vostro 5480", ALC290_FIXUP_SUBWOOFER_HSJACK),
7996 SND_PCI_QUIRK(0x1028, 0x06c7, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
7997 SND_PCI_QUIRK(0x1028, 0x06d9, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
7998 SND_PCI_QUIRK(0x1028, 0x06da, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
7999 SND_PCI_QUIRK(0x1028, 0x06db, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
8000 SND_PCI_QUIRK(0x1028, 0x06dd, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
8001 SND_PCI_QUIRK(0x1028, 0x06de, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
8002 SND_PCI_QUIRK(0x1028, 0x06df, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
8003 SND_PCI_QUIRK(0x1028, 0x06e0, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008004 SND_PCI_QUIRK(0x1028, 0x0706, "Dell Inspiron 7559", ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER),
8005 SND_PCI_QUIRK(0x1028, 0x0725, "Dell Inspiron 3162", ALC255_FIXUP_DELL_SPK_NOISE),
David Brazdil0f672f62019-12-10 10:32:29 +00008006 SND_PCI_QUIRK(0x1028, 0x0738, "Dell Precision 5820", ALC269_FIXUP_NO_SHUTUP),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008007 SND_PCI_QUIRK(0x1028, 0x075c, "Dell XPS 27 7760", ALC298_FIXUP_SPK_VOLUME),
8008 SND_PCI_QUIRK(0x1028, 0x075d, "Dell AIO", ALC298_FIXUP_SPK_VOLUME),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008009 SND_PCI_QUIRK(0x1028, 0x0798, "Dell Inspiron 17 7000 Gaming", ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER),
Olivier Deprez0e641232021-09-23 10:07:05 +02008010 SND_PCI_QUIRK(0x1028, 0x07b0, "Dell Precision 7520", ALC295_FIXUP_DISABLE_DAC3),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008011 SND_PCI_QUIRK(0x1028, 0x080c, "Dell WYSE", ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008012 SND_PCI_QUIRK(0x1028, 0x084b, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB),
8013 SND_PCI_QUIRK(0x1028, 0x084e, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB),
8014 SND_PCI_QUIRK(0x1028, 0x0871, "Dell Precision 3630", ALC255_FIXUP_DELL_HEADSET_MIC),
8015 SND_PCI_QUIRK(0x1028, 0x0872, "Dell Precision 3630", ALC255_FIXUP_DELL_HEADSET_MIC),
8016 SND_PCI_QUIRK(0x1028, 0x0873, "Dell Precision 3930", ALC255_FIXUP_DUMMY_LINEOUT_VERB),
David Brazdil0f672f62019-12-10 10:32:29 +00008017 SND_PCI_QUIRK(0x1028, 0x08ad, "Dell WYSE AIO", ALC225_FIXUP_DELL_WYSE_AIO_MIC_NO_PRESENCE),
8018 SND_PCI_QUIRK(0x1028, 0x08ae, "Dell WYSE NB", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE),
8019 SND_PCI_QUIRK(0x1028, 0x0935, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB),
Olivier Deprez0e641232021-09-23 10:07:05 +02008020 SND_PCI_QUIRK(0x1028, 0x097d, "Dell Precision", ALC289_FIXUP_DUAL_SPK),
8021 SND_PCI_QUIRK(0x1028, 0x097e, "Dell Precision", ALC289_FIXUP_DUAL_SPK),
8022 SND_PCI_QUIRK(0x1028, 0x098d, "Dell Precision", ALC233_FIXUP_ASUS_MIC_NO_PRESENCE),
8023 SND_PCI_QUIRK(0x1028, 0x09bf, "Dell Precision", ALC233_FIXUP_ASUS_MIC_NO_PRESENCE),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008024 SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
8025 SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
8026 SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
8027 SND_PCI_QUIRK(0x103c, 0x18e6, "HP", ALC269_FIXUP_HP_GPIO_LED),
8028 SND_PCI_QUIRK(0x103c, 0x218b, "HP", ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008029 SND_PCI_QUIRK(0x103c, 0x21f9, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
8030 SND_PCI_QUIRK(0x103c, 0x2210, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
8031 SND_PCI_QUIRK(0x103c, 0x2214, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Olivier Deprez0e641232021-09-23 10:07:05 +02008032 SND_PCI_QUIRK(0x103c, 0x221b, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
8033 SND_PCI_QUIRK(0x103c, 0x221c, "HP EliteBook 755 G2", ALC280_FIXUP_HP_HEADSET_MIC),
8034 SND_PCI_QUIRK(0x103c, 0x2221, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
8035 SND_PCI_QUIRK(0x103c, 0x2225, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008036 SND_PCI_QUIRK(0x103c, 0x2236, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
8037 SND_PCI_QUIRK(0x103c, 0x2237, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
8038 SND_PCI_QUIRK(0x103c, 0x2238, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
8039 SND_PCI_QUIRK(0x103c, 0x2239, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
8040 SND_PCI_QUIRK(0x103c, 0x224b, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008041 SND_PCI_QUIRK(0x103c, 0x2253, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
8042 SND_PCI_QUIRK(0x103c, 0x2254, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
8043 SND_PCI_QUIRK(0x103c, 0x2255, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
8044 SND_PCI_QUIRK(0x103c, 0x2256, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
8045 SND_PCI_QUIRK(0x103c, 0x2257, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
8046 SND_PCI_QUIRK(0x103c, 0x2259, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
8047 SND_PCI_QUIRK(0x103c, 0x225a, "HP", ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED),
Olivier Deprez0e641232021-09-23 10:07:05 +02008048 SND_PCI_QUIRK(0x103c, 0x225f, "HP", ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008049 SND_PCI_QUIRK(0x103c, 0x2260, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
8050 SND_PCI_QUIRK(0x103c, 0x2263, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
8051 SND_PCI_QUIRK(0x103c, 0x2264, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
8052 SND_PCI_QUIRK(0x103c, 0x2265, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Olivier Deprez0e641232021-09-23 10:07:05 +02008053 SND_PCI_QUIRK(0x103c, 0x2268, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
8054 SND_PCI_QUIRK(0x103c, 0x226a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
8055 SND_PCI_QUIRK(0x103c, 0x226b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
8056 SND_PCI_QUIRK(0x103c, 0x226e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
8057 SND_PCI_QUIRK(0x103c, 0x2271, "HP", ALC286_FIXUP_HP_GPIO_LED),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008058 SND_PCI_QUIRK(0x103c, 0x2272, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Olivier Deprez0e641232021-09-23 10:07:05 +02008059 SND_PCI_QUIRK(0x103c, 0x2272, "HP", ALC280_FIXUP_HP_DOCK_PINS),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008060 SND_PCI_QUIRK(0x103c, 0x2273, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Olivier Deprez0e641232021-09-23 10:07:05 +02008061 SND_PCI_QUIRK(0x103c, 0x2273, "HP", ALC280_FIXUP_HP_DOCK_PINS),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008062 SND_PCI_QUIRK(0x103c, 0x2278, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
8063 SND_PCI_QUIRK(0x103c, 0x227f, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
8064 SND_PCI_QUIRK(0x103c, 0x2282, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
8065 SND_PCI_QUIRK(0x103c, 0x228b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
8066 SND_PCI_QUIRK(0x103c, 0x228e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Olivier Deprez0e641232021-09-23 10:07:05 +02008067 SND_PCI_QUIRK(0x103c, 0x229e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
8068 SND_PCI_QUIRK(0x103c, 0x22b2, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
8069 SND_PCI_QUIRK(0x103c, 0x22b7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
8070 SND_PCI_QUIRK(0x103c, 0x22bf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
8071 SND_PCI_QUIRK(0x103c, 0x22c4, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008072 SND_PCI_QUIRK(0x103c, 0x22c5, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
8073 SND_PCI_QUIRK(0x103c, 0x22c7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
8074 SND_PCI_QUIRK(0x103c, 0x22c8, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Olivier Deprez0e641232021-09-23 10:07:05 +02008075 SND_PCI_QUIRK(0x103c, 0x22cf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
8076 SND_PCI_QUIRK(0x103c, 0x22db, "HP", ALC280_FIXUP_HP_9480M),
8077 SND_PCI_QUIRK(0x103c, 0x22dc, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
8078 SND_PCI_QUIRK(0x103c, 0x22fb, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008079 SND_PCI_QUIRK(0x103c, 0x2334, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
8080 SND_PCI_QUIRK(0x103c, 0x2335, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
8081 SND_PCI_QUIRK(0x103c, 0x2336, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
8082 SND_PCI_QUIRK(0x103c, 0x2337, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
David Brazdil0f672f62019-12-10 10:32:29 +00008083 SND_PCI_QUIRK(0x103c, 0x802e, "HP Z240 SFF", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
8084 SND_PCI_QUIRK(0x103c, 0x802f, "HP Z240", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008085 SND_PCI_QUIRK(0x103c, 0x820d, "HP Pavilion 15", ALC269_FIXUP_HP_MUTE_LED_MIC3),
8086 SND_PCI_QUIRK(0x103c, 0x8256, "HP", ALC221_FIXUP_HP_FRONT_MIC),
8087 SND_PCI_QUIRK(0x103c, 0x827e, "HP x360", ALC295_FIXUP_HP_X360),
Olivier Deprez0e641232021-09-23 10:07:05 +02008088 SND_PCI_QUIRK(0x103c, 0x827f, "HP x360", ALC269_FIXUP_HP_MUTE_LED_MIC3),
David Brazdil0f672f62019-12-10 10:32:29 +00008089 SND_PCI_QUIRK(0x103c, 0x82bf, "HP G3 mini", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
8090 SND_PCI_QUIRK(0x103c, 0x82c0, "HP G3 mini premium", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008091 SND_PCI_QUIRK(0x103c, 0x83b9, "HP Spectre x360", ALC269_FIXUP_HP_MUTE_LED_MIC3),
Olivier Deprez0e641232021-09-23 10:07:05 +02008092 SND_PCI_QUIRK(0x103c, 0x841c, "HP Pavilion 15-CK0xx", ALC269_FIXUP_HP_MUTE_LED_MIC3),
David Brazdil0f672f62019-12-10 10:32:29 +00008093 SND_PCI_QUIRK(0x103c, 0x8497, "HP Envy x360", ALC269_FIXUP_HP_MUTE_LED_MIC3),
Olivier Deprez0e641232021-09-23 10:07:05 +02008094 SND_PCI_QUIRK(0x103c, 0x84da, "HP OMEN dc0019-ur", ALC295_FIXUP_HP_OMEN),
David Brazdil0f672f62019-12-10 10:32:29 +00008095 SND_PCI_QUIRK(0x103c, 0x84e7, "HP Pavilion 15", ALC269_FIXUP_HP_MUTE_LED_MIC3),
Olivier Deprez0e641232021-09-23 10:07:05 +02008096 SND_PCI_QUIRK(0x103c, 0x8519, "HP Spectre x360 15-df0xxx", ALC285_FIXUP_HP_SPECTRE_X360),
8097 SND_PCI_QUIRK(0x103c, 0x861f, "HP Elite Dragonfly G1", ALC285_FIXUP_HP_GPIO_AMP_INIT),
8098 SND_PCI_QUIRK(0x103c, 0x869d, "HP", ALC236_FIXUP_HP_MUTE_LED),
8099 SND_PCI_QUIRK(0x103c, 0x8724, "HP EliteBook 850 G7", ALC285_FIXUP_HP_GPIO_LED),
8100 SND_PCI_QUIRK(0x103c, 0x8729, "HP", ALC285_FIXUP_HP_GPIO_LED),
8101 SND_PCI_QUIRK(0x103c, 0x8736, "HP", ALC285_FIXUP_HP_GPIO_AMP_INIT),
8102 SND_PCI_QUIRK(0x103c, 0x8760, "HP", ALC285_FIXUP_HP_MUTE_LED),
8103 SND_PCI_QUIRK(0x103c, 0x877a, "HP", ALC285_FIXUP_HP_MUTE_LED),
8104 SND_PCI_QUIRK(0x103c, 0x877d, "HP", ALC236_FIXUP_HP_MUTE_LED),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008105 SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC),
8106 SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300),
8107 SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
David Brazdil0f672f62019-12-10 10:32:29 +00008108 SND_PCI_QUIRK(0x1043, 0x10a1, "ASUS UX391UA", ALC294_FIXUP_ASUS_SPK),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008109 SND_PCI_QUIRK(0x1043, 0x10c0, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC),
8110 SND_PCI_QUIRK(0x1043, 0x10d0, "ASUS X540LA/X540LJ", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
8111 SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
8112 SND_PCI_QUIRK(0x1043, 0x11c0, "ASUS X556UR", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
Olivier Deprez0e641232021-09-23 10:07:05 +02008113 SND_PCI_QUIRK(0x1043, 0x125e, "ASUS Q524UQK", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
8114 SND_PCI_QUIRK(0x1043, 0x1271, "ASUS X430UN", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008115 SND_PCI_QUIRK(0x1043, 0x1290, "ASUS X441SA", ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE),
8116 SND_PCI_QUIRK(0x1043, 0x12a0, "ASUS X441UV", ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008117 SND_PCI_QUIRK(0x1043, 0x12e0, "ASUS X541SA", ALC256_FIXUP_ASUS_MIC),
Olivier Deprez0e641232021-09-23 10:07:05 +02008118 SND_PCI_QUIRK(0x1043, 0x12f0, "ASUS X541UV", ALC256_FIXUP_ASUS_MIC),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008119 SND_PCI_QUIRK(0x1043, 0x13b0, "ASUS Z550SA", ALC256_FIXUP_ASUS_MIC),
8120 SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008121 SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A),
8122 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC),
Olivier Deprez0e641232021-09-23 10:07:05 +02008123 SND_PCI_QUIRK(0x1043, 0x1740, "ASUS UX430UA", ALC295_FIXUP_ASUS_DACS),
8124 SND_PCI_QUIRK(0x1043, 0x17d1, "ASUS UX431FL", ALC294_FIXUP_ASUS_DUAL_SPK),
8125 SND_PCI_QUIRK(0x1043, 0x1662, "ASUS GV301QH", ALC294_FIXUP_ASUS_DUAL_SPK),
8126 SND_PCI_QUIRK(0x1043, 0x1881, "ASUS Zephyrus S/M", ALC294_FIXUP_ASUS_GX502_PINS),
David Brazdil0f672f62019-12-10 10:32:29 +00008127 SND_PCI_QUIRK(0x1043, 0x18b1, "Asus MJ401TA", ALC256_FIXUP_ASUS_HEADSET_MIC),
Olivier Deprez0e641232021-09-23 10:07:05 +02008128 SND_PCI_QUIRK(0x1043, 0x18f1, "Asus FX505DT", ALC256_FIXUP_ASUS_HEADSET_MIC),
8129 SND_PCI_QUIRK(0x1043, 0x194e, "ASUS UX563FD", ALC294_FIXUP_ASUS_HPE),
8130 SND_PCI_QUIRK(0x1043, 0x1982, "ASUS B1400CEPE", ALC256_FIXUP_ASUS_HPE),
8131 SND_PCI_QUIRK(0x1043, 0x19ce, "ASUS B9450FA", ALC294_FIXUP_ASUS_HPE),
8132 SND_PCI_QUIRK(0x1043, 0x19e1, "ASUS UX581LV", ALC295_FIXUP_ASUS_MIC_NO_PRESENCE),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008133 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
8134 SND_PCI_QUIRK(0x1043, 0x1a30, "ASUS X705UD", ALC256_FIXUP_ASUS_MIC),
Olivier Deprez0e641232021-09-23 10:07:05 +02008135 SND_PCI_QUIRK(0x1043, 0x1b11, "ASUS UX431DA", ALC294_FIXUP_ASUS_COEF_1B),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008136 SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC),
8137 SND_PCI_QUIRK(0x1043, 0x1bbd, "ASUS Z550MA", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
8138 SND_PCI_QUIRK(0x1043, 0x1c23, "Asus X55U", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
8139 SND_PCI_QUIRK(0x1043, 0x1ccd, "ASUS X555UB", ALC256_FIXUP_ASUS_MIC),
Olivier Deprez0e641232021-09-23 10:07:05 +02008140 SND_PCI_QUIRK(0x1043, 0x1d4e, "ASUS TM420", ALC256_FIXUP_ASUS_HPE),
8141 SND_PCI_QUIRK(0x1043, 0x1e11, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA502),
8142 SND_PCI_QUIRK(0x1043, 0x1e51, "ASUS Zephyrus M15", ALC294_FIXUP_ASUS_GU502_PINS),
8143 SND_PCI_QUIRK(0x1043, 0x1e8e, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA401),
8144 SND_PCI_QUIRK(0x1043, 0x1f11, "ASUS Zephyrus G14", ALC289_FIXUP_ASUS_GA401),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008145 SND_PCI_QUIRK(0x1043, 0x3030, "ASUS ZN270IE", ALC256_FIXUP_ASUS_AIO_GPIO2),
8146 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC),
8147 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC),
8148 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
8149 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
8150 SND_PCI_QUIRK(0x1043, 0x8516, "ASUS X101CH", ALC269_FIXUP_ASUS_X101),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008151 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
8152 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
8153 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
8154 SND_PCI_QUIRK(0x104d, 0x9099, "Sony VAIO S13", ALC275_FIXUP_SONY_DISABLE_AAMIX),
Olivier Deprez0e641232021-09-23 10:07:05 +02008155 SND_PCI_QUIRK(0x104d, 0x90b5, "Sony VAIO Pro 11", ALC286_FIXUP_SONY_MIC_NO_PRESENCE),
8156 SND_PCI_QUIRK(0x104d, 0x90b6, "Sony VAIO Pro 13", ALC286_FIXUP_SONY_MIC_NO_PRESENCE),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008157 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook", ALC269_FIXUP_LIFEBOOK),
8158 SND_PCI_QUIRK(0x10cf, 0x159f, "Lifebook E780", ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT),
8159 SND_PCI_QUIRK(0x10cf, 0x15dc, "Lifebook T731", ALC269_FIXUP_LIFEBOOK_HP_PIN),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008160 SND_PCI_QUIRK(0x10cf, 0x1629, "Lifebook U7x7", ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC),
Olivier Deprez0e641232021-09-23 10:07:05 +02008161 SND_PCI_QUIRK(0x10cf, 0x1757, "Lifebook E752", ALC269_FIXUP_LIFEBOOK_HP_PIN),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008162 SND_PCI_QUIRK(0x10cf, 0x1845, "Lifebook U904", ALC269_FIXUP_LIFEBOOK_EXTMIC),
8163 SND_PCI_QUIRK(0x10ec, 0x10f2, "Intel Reference board", ALC700_FIXUP_INTEL_REFERENCE),
Olivier Deprez0e641232021-09-23 10:07:05 +02008164 SND_PCI_QUIRK(0x10ec, 0x118c, "Medion EE4254 MD62100", ALC256_FIXUP_MEDION_HEADSET_NO_PRESENCE),
8165 SND_PCI_QUIRK(0x10ec, 0x1230, "Intel Reference board", ALC295_FIXUP_CHROME_BOOK),
8166 SND_PCI_QUIRK(0x10ec, 0x1252, "Intel Reference board", ALC295_FIXUP_CHROME_BOOK),
8167 SND_PCI_QUIRK(0x10ec, 0x1254, "Intel Reference board", ALC295_FIXUP_CHROME_BOOK),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008168 SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-SZ6", ALC269_FIXUP_HEADSET_MODE),
8169 SND_PCI_QUIRK(0x144d, 0xc109, "Samsung Ativ book 9 (NP900X3G)", ALC269_FIXUP_INV_DMIC),
Olivier Deprez0e641232021-09-23 10:07:05 +02008170 SND_PCI_QUIRK(0x144d, 0xc169, "Samsung Notebook 9 Pen (NP930SBE-K01US)", ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET),
8171 SND_PCI_QUIRK(0x144d, 0xc176, "Samsung Notebook 9 Pro (NP930MBE-K04US)", ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET),
8172 SND_PCI_QUIRK(0x144d, 0xc189, "Samsung Galaxy Flex Book (NT950QCG-X716)", ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET),
8173 SND_PCI_QUIRK(0x144d, 0xc18a, "Samsung Galaxy Book Ion (NP930XCJ-K01US)", ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008174 SND_PCI_QUIRK(0x144d, 0xc740, "Samsung Ativ book 8 (NP870Z5G)", ALC269_FIXUP_ATIV_BOOK_8),
Olivier Deprez0e641232021-09-23 10:07:05 +02008175 SND_PCI_QUIRK(0x144d, 0xc812, "Samsung Notebook Pen S (NT950SBE-X58)", ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET),
8176 SND_PCI_QUIRK(0x144d, 0xc830, "Samsung Galaxy Book Ion (NT950XCJ-X716A)", ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008177 SND_PCI_QUIRK(0x1458, 0xfa53, "Gigabyte BXBT-2807", ALC283_FIXUP_HEADSET_MIC),
8178 SND_PCI_QUIRK(0x1462, 0xb120, "MSI Cubi MS-B120", ALC283_FIXUP_HEADSET_MIC),
8179 SND_PCI_QUIRK(0x1462, 0xb171, "Cubi N 8GL (MS-B171)", ALC283_FIXUP_HEADSET_MIC),
Olivier Deprez0e641232021-09-23 10:07:05 +02008180 SND_PCI_QUIRK(0x152d, 0x1082, "Quanta NL3", ALC269_FIXUP_LIFEBOOK),
8181 SND_PCI_QUIRK(0x1558, 0x1323, "Clevo N130ZU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
David Brazdil0f672f62019-12-10 10:32:29 +00008182 SND_PCI_QUIRK(0x1558, 0x1325, "System76 Darter Pro (darp5)", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
Olivier Deprez0e641232021-09-23 10:07:05 +02008183 SND_PCI_QUIRK(0x1558, 0x1401, "Clevo L140[CZ]U", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
8184 SND_PCI_QUIRK(0x1558, 0x1403, "Clevo N140CU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
8185 SND_PCI_QUIRK(0x1558, 0x1404, "Clevo N150CU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
8186 SND_PCI_QUIRK(0x1558, 0x14a1, "Clevo L141MU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
8187 SND_PCI_QUIRK(0x1558, 0x4018, "Clevo NV40M[BE]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
8188 SND_PCI_QUIRK(0x1558, 0x4019, "Clevo NV40MZ", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
8189 SND_PCI_QUIRK(0x1558, 0x4020, "Clevo NV40MB", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
8190 SND_PCI_QUIRK(0x1558, 0x40a1, "Clevo NL40GU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
8191 SND_PCI_QUIRK(0x1558, 0x40c1, "Clevo NL40[CZ]U", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
8192 SND_PCI_QUIRK(0x1558, 0x40d1, "Clevo NL41DU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
8193 SND_PCI_QUIRK(0x1558, 0x50a3, "Clevo NJ51GU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
8194 SND_PCI_QUIRK(0x1558, 0x50b3, "Clevo NK50S[BEZ]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
8195 SND_PCI_QUIRK(0x1558, 0x50b6, "Clevo NK50S5", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
8196 SND_PCI_QUIRK(0x1558, 0x50b8, "Clevo NK50SZ", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
8197 SND_PCI_QUIRK(0x1558, 0x50d5, "Clevo NP50D5", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
8198 SND_PCI_QUIRK(0x1558, 0x50f0, "Clevo NH50A[CDF]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
8199 SND_PCI_QUIRK(0x1558, 0x50f2, "Clevo NH50E[PR]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
8200 SND_PCI_QUIRK(0x1558, 0x50f3, "Clevo NH58DPQ", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
8201 SND_PCI_QUIRK(0x1558, 0x50f5, "Clevo NH55EPY", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
8202 SND_PCI_QUIRK(0x1558, 0x50f6, "Clevo NH55DPQ", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
8203 SND_PCI_QUIRK(0x1558, 0x5101, "Clevo S510WU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
8204 SND_PCI_QUIRK(0x1558, 0x5157, "Clevo W517GU1", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
8205 SND_PCI_QUIRK(0x1558, 0x51a1, "Clevo NS50MU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
8206 SND_PCI_QUIRK(0x1558, 0x70a1, "Clevo NB70T[HJK]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
8207 SND_PCI_QUIRK(0x1558, 0x70b3, "Clevo NK70SB", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
8208 SND_PCI_QUIRK(0x1558, 0x70f2, "Clevo NH79EPY", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
8209 SND_PCI_QUIRK(0x1558, 0x70f3, "Clevo NH77DPQ", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
8210 SND_PCI_QUIRK(0x1558, 0x70f4, "Clevo NH77EPY", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
8211 SND_PCI_QUIRK(0x1558, 0x70f6, "Clevo NH77DPQ-Y", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
8212 SND_PCI_QUIRK(0x1558, 0x8228, "Clevo NR40BU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
8213 SND_PCI_QUIRK(0x1558, 0x8520, "Clevo NH50D[CD]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
8214 SND_PCI_QUIRK(0x1558, 0x8521, "Clevo NH77D[CD]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
8215 SND_PCI_QUIRK(0x1558, 0x8535, "Clevo NH50D[BE]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
8216 SND_PCI_QUIRK(0x1558, 0x8536, "Clevo NH79D[BE]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
David Brazdil0f672f62019-12-10 10:32:29 +00008217 SND_PCI_QUIRK(0x1558, 0x8550, "System76 Gazelle (gaze14)", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
8218 SND_PCI_QUIRK(0x1558, 0x8551, "System76 Gazelle (gaze14)", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
8219 SND_PCI_QUIRK(0x1558, 0x8560, "System76 Gazelle (gaze14)", ALC269_FIXUP_HEADSET_MIC),
8220 SND_PCI_QUIRK(0x1558, 0x8561, "System76 Gazelle (gaze14)", ALC269_FIXUP_HEADSET_MIC),
Olivier Deprez0e641232021-09-23 10:07:05 +02008221 SND_PCI_QUIRK(0x1558, 0x8562, "Clevo NH[5|7][0-9]RZ[Q]", ALC269_FIXUP_DMIC),
8222 SND_PCI_QUIRK(0x1558, 0x8668, "Clevo NP50B[BE]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
8223 SND_PCI_QUIRK(0x1558, 0x8680, "Clevo NJ50LU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
8224 SND_PCI_QUIRK(0x1558, 0x8686, "Clevo NH50[CZ]U", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
8225 SND_PCI_QUIRK(0x1558, 0x8a20, "Clevo NH55DCQ-Y", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
8226 SND_PCI_QUIRK(0x1558, 0x8a51, "Clevo NH70RCQ-Y", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
8227 SND_PCI_QUIRK(0x1558, 0x8d50, "Clevo NH55RCQ-M", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
8228 SND_PCI_QUIRK(0x1558, 0x951d, "Clevo N950T[CDF]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
8229 SND_PCI_QUIRK(0x1558, 0x9600, "Clevo N960K[PR]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
8230 SND_PCI_QUIRK(0x1558, 0x961d, "Clevo N960S[CDF]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
8231 SND_PCI_QUIRK(0x1558, 0x971d, "Clevo N970T[CDF]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
8232 SND_PCI_QUIRK(0x1558, 0xa500, "Clevo NL53RU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
8233 SND_PCI_QUIRK(0x1558, 0xa600, "Clevo NL5XNU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
8234 SND_PCI_QUIRK(0x1558, 0xb018, "Clevo NP50D[BE]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
8235 SND_PCI_QUIRK(0x1558, 0xb019, "Clevo NH77D[BE]Q", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
8236 SND_PCI_QUIRK(0x1558, 0xb022, "Clevo NH77D[DC][QW]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
8237 SND_PCI_QUIRK(0x1558, 0xc018, "Clevo NP50D[BE]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
8238 SND_PCI_QUIRK(0x1558, 0xc019, "Clevo NH77D[BE]Q", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
8239 SND_PCI_QUIRK(0x1558, 0xc022, "Clevo NH77[DC][QW]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008240 SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC233_FIXUP_LENOVO_MULTI_CODECS),
Olivier Deprez0e641232021-09-23 10:07:05 +02008241 SND_PCI_QUIRK(0x17aa, 0x1048, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008242 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
8243 SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
8244 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
8245 SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
8246 SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008247 SND_PCI_QUIRK(0x17aa, 0x21f3, "Thinkpad T430", ALC269_FIXUP_LENOVO_DOCK),
Olivier Deprez0e641232021-09-23 10:07:05 +02008248 SND_PCI_QUIRK(0x17aa, 0x21f6, "Thinkpad T530", ALC269_FIXUP_LENOVO_DOCK_LIMIT_BOOST),
8249 SND_PCI_QUIRK(0x17aa, 0x21fa, "Thinkpad X230", ALC269_FIXUP_LENOVO_DOCK),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008250 SND_PCI_QUIRK(0x17aa, 0x21fb, "Thinkpad T430s", ALC269_FIXUP_LENOVO_DOCK),
8251 SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK),
8252 SND_PCI_QUIRK(0x17aa, 0x2208, "Thinkpad T431s", ALC269_FIXUP_LENOVO_DOCK),
8253 SND_PCI_QUIRK(0x17aa, 0x220c, "Thinkpad T440s", ALC292_FIXUP_TPT440),
8254 SND_PCI_QUIRK(0x17aa, 0x220e, "Thinkpad T440p", ALC292_FIXUP_TPT440_DOCK),
8255 SND_PCI_QUIRK(0x17aa, 0x2210, "Thinkpad T540p", ALC292_FIXUP_TPT440_DOCK),
8256 SND_PCI_QUIRK(0x17aa, 0x2211, "Thinkpad W541", ALC292_FIXUP_TPT440_DOCK),
8257 SND_PCI_QUIRK(0x17aa, 0x2212, "Thinkpad T440", ALC292_FIXUP_TPT440_DOCK),
8258 SND_PCI_QUIRK(0x17aa, 0x2214, "Thinkpad X240", ALC292_FIXUP_TPT440_DOCK),
8259 SND_PCI_QUIRK(0x17aa, 0x2215, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
8260 SND_PCI_QUIRK(0x17aa, 0x2218, "Thinkpad X1 Carbon 2nd", ALC292_FIXUP_TPT440_DOCK),
8261 SND_PCI_QUIRK(0x17aa, 0x2223, "ThinkPad T550", ALC292_FIXUP_TPT440_DOCK),
8262 SND_PCI_QUIRK(0x17aa, 0x2226, "ThinkPad X250", ALC292_FIXUP_TPT440_DOCK),
8263 SND_PCI_QUIRK(0x17aa, 0x222d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
8264 SND_PCI_QUIRK(0x17aa, 0x222e, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
8265 SND_PCI_QUIRK(0x17aa, 0x2231, "Thinkpad T560", ALC292_FIXUP_TPT460),
8266 SND_PCI_QUIRK(0x17aa, 0x2233, "Thinkpad", ALC292_FIXUP_TPT460),
8267 SND_PCI_QUIRK(0x17aa, 0x2245, "Thinkpad T470", ALC298_FIXUP_TPT470_DOCK),
8268 SND_PCI_QUIRK(0x17aa, 0x2246, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
8269 SND_PCI_QUIRK(0x17aa, 0x2247, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
8270 SND_PCI_QUIRK(0x17aa, 0x2249, "Thinkpad", ALC292_FIXUP_TPT460),
8271 SND_PCI_QUIRK(0x17aa, 0x224b, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
8272 SND_PCI_QUIRK(0x17aa, 0x224c, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
8273 SND_PCI_QUIRK(0x17aa, 0x224d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
8274 SND_PCI_QUIRK(0x17aa, 0x225d, "Thinkpad T480", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Olivier Deprez0e641232021-09-23 10:07:05 +02008275 SND_PCI_QUIRK(0x17aa, 0x2292, "Thinkpad X1 Carbon 7th", ALC285_FIXUP_THINKPAD_HEADSET_JACK),
8276 SND_PCI_QUIRK(0x17aa, 0x22be, "Thinkpad X1 Carbon 8th", ALC285_FIXUP_THINKPAD_HEADSET_JACK),
8277 SND_PCI_QUIRK(0x17aa, 0x22c1, "Thinkpad P1 Gen 3", ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK),
8278 SND_PCI_QUIRK(0x17aa, 0x22c2, "Thinkpad X1 Extreme Gen 3", ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008279 SND_PCI_QUIRK(0x17aa, 0x30bb, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
8280 SND_PCI_QUIRK(0x17aa, 0x30e2, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
8281 SND_PCI_QUIRK(0x17aa, 0x310c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
David Brazdil0f672f62019-12-10 10:32:29 +00008282 SND_PCI_QUIRK(0x17aa, 0x3111, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008283 SND_PCI_QUIRK(0x17aa, 0x312a, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
8284 SND_PCI_QUIRK(0x17aa, 0x312f, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
8285 SND_PCI_QUIRK(0x17aa, 0x313c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
David Brazdil0f672f62019-12-10 10:32:29 +00008286 SND_PCI_QUIRK(0x17aa, 0x3151, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC),
8287 SND_PCI_QUIRK(0x17aa, 0x3176, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC),
8288 SND_PCI_QUIRK(0x17aa, 0x3178, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC),
Olivier Deprez0e641232021-09-23 10:07:05 +02008289 SND_PCI_QUIRK(0x17aa, 0x3818, "Lenovo C940", ALC298_FIXUP_LENOVO_SPK_VOLUME),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008290 SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
8291 SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC),
David Brazdil0f672f62019-12-10 10:32:29 +00008292 SND_PCI_QUIRK(0x17aa, 0x3978, "Lenovo B50-70", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
Olivier Deprez0e641232021-09-23 10:07:05 +02008293 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008294 SND_PCI_QUIRK(0x17aa, 0x5013, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
8295 SND_PCI_QUIRK(0x17aa, 0x501a, "Thinkpad", ALC283_FIXUP_INT_MIC),
8296 SND_PCI_QUIRK(0x17aa, 0x501e, "Thinkpad L440", ALC292_FIXUP_TPT440_DOCK),
8297 SND_PCI_QUIRK(0x17aa, 0x5026, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
8298 SND_PCI_QUIRK(0x17aa, 0x5034, "Thinkpad T450", ALC292_FIXUP_TPT440_DOCK),
8299 SND_PCI_QUIRK(0x17aa, 0x5036, "Thinkpad T450s", ALC292_FIXUP_TPT440_DOCK),
8300 SND_PCI_QUIRK(0x17aa, 0x503c, "Thinkpad L450", ALC292_FIXUP_TPT440_DOCK),
8301 SND_PCI_QUIRK(0x17aa, 0x504a, "ThinkPad X260", ALC292_FIXUP_TPT440_DOCK),
8302 SND_PCI_QUIRK(0x17aa, 0x504b, "Thinkpad", ALC293_FIXUP_LENOVO_SPK_NOISE),
8303 SND_PCI_QUIRK(0x17aa, 0x5050, "Thinkpad T560p", ALC292_FIXUP_TPT460),
8304 SND_PCI_QUIRK(0x17aa, 0x5051, "Thinkpad L460", ALC292_FIXUP_TPT460),
8305 SND_PCI_QUIRK(0x17aa, 0x5053, "Thinkpad T460", ALC292_FIXUP_TPT460),
8306 SND_PCI_QUIRK(0x17aa, 0x505d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
8307 SND_PCI_QUIRK(0x17aa, 0x505f, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
8308 SND_PCI_QUIRK(0x17aa, 0x5062, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
8309 SND_PCI_QUIRK(0x17aa, 0x5109, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
8310 SND_PCI_QUIRK(0x17aa, 0x511e, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
8311 SND_PCI_QUIRK(0x17aa, 0x511f, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008312 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
David Brazdil0f672f62019-12-10 10:32:29 +00008313 SND_PCI_QUIRK(0x19e5, 0x3204, "Huawei MACH-WX9", ALC256_FIXUP_HUAWEI_MACH_WX9_PINS),
Olivier Deprez0e641232021-09-23 10:07:05 +02008314 SND_PCI_QUIRK(0x1b35, 0x1235, "CZC B20", ALC269_FIXUP_CZC_B20),
8315 SND_PCI_QUIRK(0x1b35, 0x1236, "CZC TMI", ALC269_FIXUP_CZC_TMI),
8316 SND_PCI_QUIRK(0x1b35, 0x1237, "CZC L101", ALC269_FIXUP_CZC_L101),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008317 SND_PCI_QUIRK(0x1b7d, 0xa831, "Ordissimo EVE2 ", ALC269VB_FIXUP_ORDISSIMO_EVE2), /* Also known as Malata PC-B1303 */
Olivier Deprez0e641232021-09-23 10:07:05 +02008318 SND_PCI_QUIRK(0x1c06, 0x2013, "Lemote A1802", ALC269_FIXUP_LEMOTE_A1802),
8319 SND_PCI_QUIRK(0x1c06, 0x2015, "Lemote A190X", ALC269_FIXUP_LEMOTE_A190X),
8320 SND_PCI_QUIRK(0x1d72, 0x1602, "RedmiBook", ALC255_FIXUP_XIAOMI_HEADSET_MIC),
8321 SND_PCI_QUIRK(0x1d72, 0x1701, "XiaomiNotebook Pro", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE),
8322 SND_PCI_QUIRK(0x1d72, 0x1901, "RedmiBook 14", ALC256_FIXUP_ASUS_HEADSET_MIC),
8323 SND_PCI_QUIRK(0x1d72, 0x1947, "RedmiBook Air", ALC255_FIXUP_XIAOMI_HEADSET_MIC),
8324 SND_PCI_QUIRK(0x8086, 0x2074, "Intel NUC 8", ALC233_FIXUP_INTEL_NUC8_DMIC),
8325 SND_PCI_QUIRK(0x8086, 0x2080, "Intel NUC 8 Rugged", ALC256_FIXUP_INTEL_NUC8_RUGGED),
8326 SND_PCI_QUIRK(0x8086, 0x2081, "Intel NUC 10", ALC256_FIXUP_INTEL_NUC10),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008327
8328#if 0
8329 /* Below is a quirk table taken from the old code.
8330 * Basically the device should work as is without the fixup table.
8331 * If BIOS doesn't give a proper info, enable the corresponding
8332 * fixup entry.
8333 */
8334 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
8335 ALC269_FIXUP_AMIC),
8336 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269_FIXUP_AMIC),
8337 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269_FIXUP_AMIC),
8338 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_FIXUP_AMIC),
8339 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269_FIXUP_AMIC),
8340 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269_FIXUP_AMIC),
8341 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269_FIXUP_AMIC),
8342 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269_FIXUP_AMIC),
8343 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_FIXUP_AMIC),
8344 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269_FIXUP_AMIC),
8345 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_FIXUP_AMIC),
8346 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_FIXUP_AMIC),
8347 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_FIXUP_AMIC),
8348 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_FIXUP_AMIC),
8349 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_FIXUP_AMIC),
8350 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_FIXUP_AMIC),
8351 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_FIXUP_AMIC),
8352 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_FIXUP_AMIC),
8353 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_FIXUP_AMIC),
8354 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_FIXUP_AMIC),
8355 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_FIXUP_AMIC),
8356 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_FIXUP_AMIC),
8357 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_FIXUP_AMIC),
8358 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_FIXUP_AMIC),
8359 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_FIXUP_AMIC),
8360 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_FIXUP_AMIC),
8361 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_FIXUP_AMIC),
8362 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_FIXUP_AMIC),
8363 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_FIXUP_AMIC),
8364 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_FIXUP_AMIC),
8365 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_FIXUP_AMIC),
8366 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_FIXUP_AMIC),
8367 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_FIXUP_AMIC),
8368 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_FIXUP_AMIC),
8369 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_FIXUP_AMIC),
8370 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_FIXUP_DMIC),
8371 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_FIXUP_AMIC),
8372 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_AMIC),
8373 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_FIXUP_DMIC),
8374 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_FIXUP_DMIC),
8375#endif
8376 {}
8377};
8378
8379static const struct snd_pci_quirk alc269_fixup_vendor_tbl[] = {
8380 SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC),
8381 SND_PCI_QUIRK_VENDOR(0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED),
8382 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
8383 SND_PCI_QUIRK_VENDOR(0x17aa, "Thinkpad", ALC269_FIXUP_THINKPAD_ACPI),
David Brazdil0f672f62019-12-10 10:32:29 +00008384 SND_PCI_QUIRK_VENDOR(0x19e5, "Huawei Matebook", ALC255_FIXUP_MIC_MUTE_LED),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008385 {}
8386};
8387
8388static const struct hda_model_fixup alc269_fixup_models[] = {
8389 {.id = ALC269_FIXUP_AMIC, .name = "laptop-amic"},
8390 {.id = ALC269_FIXUP_DMIC, .name = "laptop-dmic"},
8391 {.id = ALC269_FIXUP_STEREO_DMIC, .name = "alc269-dmic"},
8392 {.id = ALC271_FIXUP_DMIC, .name = "alc271-dmic"},
8393 {.id = ALC269_FIXUP_INV_DMIC, .name = "inv-dmic"},
8394 {.id = ALC269_FIXUP_HEADSET_MIC, .name = "headset-mic"},
8395 {.id = ALC269_FIXUP_HEADSET_MODE, .name = "headset-mode"},
8396 {.id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC, .name = "headset-mode-no-hp-mic"},
8397 {.id = ALC269_FIXUP_LENOVO_DOCK, .name = "lenovo-dock"},
Olivier Deprez0e641232021-09-23 10:07:05 +02008398 {.id = ALC269_FIXUP_LENOVO_DOCK_LIMIT_BOOST, .name = "lenovo-dock-limit-boost"},
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008399 {.id = ALC269_FIXUP_HP_GPIO_LED, .name = "hp-gpio-led"},
8400 {.id = ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED, .name = "hp-dock-gpio-mic1-led"},
8401 {.id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "dell-headset-multi"},
8402 {.id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE, .name = "dell-headset-dock"},
8403 {.id = ALC269_FIXUP_DELL3_MIC_NO_PRESENCE, .name = "dell-headset3"},
8404 {.id = ALC269_FIXUP_DELL4_MIC_NO_PRESENCE, .name = "dell-headset4"},
8405 {.id = ALC283_FIXUP_CHROME_BOOK, .name = "alc283-dac-wcaps"},
8406 {.id = ALC283_FIXUP_SENSE_COMBO_JACK, .name = "alc283-sense-combo"},
8407 {.id = ALC292_FIXUP_TPT440_DOCK, .name = "tpt440-dock"},
8408 {.id = ALC292_FIXUP_TPT440, .name = "tpt440"},
8409 {.id = ALC292_FIXUP_TPT460, .name = "tpt460"},
Olivier Deprez0e641232021-09-23 10:07:05 +02008410 {.id = ALC298_FIXUP_TPT470_DOCK_FIX, .name = "tpt470-dock-fix"},
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008411 {.id = ALC298_FIXUP_TPT470_DOCK, .name = "tpt470-dock"},
8412 {.id = ALC233_FIXUP_LENOVO_MULTI_CODECS, .name = "dual-codecs"},
8413 {.id = ALC700_FIXUP_INTEL_REFERENCE, .name = "alc700-ref"},
8414 {.id = ALC269_FIXUP_SONY_VAIO, .name = "vaio"},
8415 {.id = ALC269_FIXUP_DELL_M101Z, .name = "dell-m101z"},
8416 {.id = ALC269_FIXUP_ASUS_G73JW, .name = "asus-g73jw"},
8417 {.id = ALC269_FIXUP_LENOVO_EAPD, .name = "lenovo-eapd"},
8418 {.id = ALC275_FIXUP_SONY_HWEQ, .name = "sony-hweq"},
8419 {.id = ALC269_FIXUP_PCM_44K, .name = "pcm44k"},
8420 {.id = ALC269_FIXUP_LIFEBOOK, .name = "lifebook"},
8421 {.id = ALC269_FIXUP_LIFEBOOK_EXTMIC, .name = "lifebook-extmic"},
8422 {.id = ALC269_FIXUP_LIFEBOOK_HP_PIN, .name = "lifebook-hp-pin"},
8423 {.id = ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC, .name = "lifebook-u7x7"},
8424 {.id = ALC269VB_FIXUP_AMIC, .name = "alc269vb-amic"},
8425 {.id = ALC269VB_FIXUP_DMIC, .name = "alc269vb-dmic"},
8426 {.id = ALC269_FIXUP_HP_MUTE_LED_MIC1, .name = "hp-mute-led-mic1"},
8427 {.id = ALC269_FIXUP_HP_MUTE_LED_MIC2, .name = "hp-mute-led-mic2"},
8428 {.id = ALC269_FIXUP_HP_MUTE_LED_MIC3, .name = "hp-mute-led-mic3"},
8429 {.id = ALC269_FIXUP_HP_GPIO_MIC1_LED, .name = "hp-gpio-mic1"},
8430 {.id = ALC269_FIXUP_HP_LINE1_MIC1_LED, .name = "hp-line1-mic1"},
8431 {.id = ALC269_FIXUP_NO_SHUTUP, .name = "noshutup"},
8432 {.id = ALC286_FIXUP_SONY_MIC_NO_PRESENCE, .name = "sony-nomic"},
8433 {.id = ALC269_FIXUP_ASPIRE_HEADSET_MIC, .name = "aspire-headset-mic"},
8434 {.id = ALC269_FIXUP_ASUS_X101, .name = "asus-x101"},
8435 {.id = ALC271_FIXUP_HP_GATE_MIC_JACK, .name = "acer-ao7xx"},
8436 {.id = ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572, .name = "acer-aspire-e1"},
8437 {.id = ALC269_FIXUP_ACER_AC700, .name = "acer-ac700"},
8438 {.id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST, .name = "limit-mic-boost"},
8439 {.id = ALC269VB_FIXUP_ASUS_ZENBOOK, .name = "asus-zenbook"},
8440 {.id = ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A, .name = "asus-zenbook-ux31a"},
8441 {.id = ALC269VB_FIXUP_ORDISSIMO_EVE2, .name = "ordissimo"},
8442 {.id = ALC282_FIXUP_ASUS_TX300, .name = "asus-tx300"},
8443 {.id = ALC283_FIXUP_INT_MIC, .name = "alc283-int-mic"},
8444 {.id = ALC290_FIXUP_MONO_SPEAKERS_HSJACK, .name = "mono-speakers"},
8445 {.id = ALC290_FIXUP_SUBWOOFER_HSJACK, .name = "alc290-subwoofer"},
8446 {.id = ALC269_FIXUP_THINKPAD_ACPI, .name = "thinkpad"},
8447 {.id = ALC269_FIXUP_DMIC_THINKPAD_ACPI, .name = "dmic-thinkpad"},
8448 {.id = ALC255_FIXUP_ACER_MIC_NO_PRESENCE, .name = "alc255-acer"},
8449 {.id = ALC255_FIXUP_ASUS_MIC_NO_PRESENCE, .name = "alc255-asus"},
8450 {.id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc255-dell1"},
8451 {.id = ALC255_FIXUP_DELL2_MIC_NO_PRESENCE, .name = "alc255-dell2"},
8452 {.id = ALC293_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc293-dell1"},
8453 {.id = ALC283_FIXUP_HEADSET_MIC, .name = "alc283-headset"},
David Brazdil0f672f62019-12-10 10:32:29 +00008454 {.id = ALC255_FIXUP_MIC_MUTE_LED, .name = "alc255-dell-mute"},
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008455 {.id = ALC282_FIXUP_ASPIRE_V5_PINS, .name = "aspire-v5"},
Olivier Deprez0e641232021-09-23 10:07:05 +02008456 {.id = ALC269VB_FIXUP_ASPIRE_E1_COEF, .name = "aspire-e1-coef"},
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008457 {.id = ALC280_FIXUP_HP_GPIO4, .name = "hp-gpio4"},
8458 {.id = ALC286_FIXUP_HP_GPIO_LED, .name = "hp-gpio-led"},
8459 {.id = ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY, .name = "hp-gpio2-hotkey"},
8460 {.id = ALC280_FIXUP_HP_DOCK_PINS, .name = "hp-dock-pins"},
8461 {.id = ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED, .name = "hp-dock-gpio-mic"},
8462 {.id = ALC280_FIXUP_HP_9480M, .name = "hp-9480m"},
8463 {.id = ALC288_FIXUP_DELL_HEADSET_MODE, .name = "alc288-dell-headset"},
8464 {.id = ALC288_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc288-dell1"},
8465 {.id = ALC288_FIXUP_DELL_XPS_13, .name = "alc288-dell-xps13"},
8466 {.id = ALC292_FIXUP_DELL_E7X, .name = "dell-e7x"},
8467 {.id = ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK, .name = "alc293-dell"},
8468 {.id = ALC298_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc298-dell1"},
8469 {.id = ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE, .name = "alc298-dell-aio"},
8470 {.id = ALC275_FIXUP_DELL_XPS, .name = "alc275-dell-xps"},
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008471 {.id = ALC293_FIXUP_LENOVO_SPK_NOISE, .name = "lenovo-spk-noise"},
8472 {.id = ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY, .name = "lenovo-hotkey"},
8473 {.id = ALC255_FIXUP_DELL_SPK_NOISE, .name = "dell-spk-noise"},
David Brazdil0f672f62019-12-10 10:32:29 +00008474 {.id = ALC225_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc225-dell1"},
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008475 {.id = ALC295_FIXUP_DISABLE_DAC3, .name = "alc295-disable-dac3"},
Olivier Deprez0e641232021-09-23 10:07:05 +02008476 {.id = ALC285_FIXUP_SPEAKER2_TO_DAC1, .name = "alc285-speaker2-to-dac1"},
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008477 {.id = ALC280_FIXUP_HP_HEADSET_MIC, .name = "alc280-hp-headset"},
8478 {.id = ALC221_FIXUP_HP_FRONT_MIC, .name = "alc221-hp-mic"},
8479 {.id = ALC298_FIXUP_SPK_VOLUME, .name = "alc298-spk-volume"},
8480 {.id = ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER, .name = "dell-inspiron-7559"},
8481 {.id = ALC269_FIXUP_ATIV_BOOK_8, .name = "ativ-book"},
8482 {.id = ALC221_FIXUP_HP_MIC_NO_PRESENCE, .name = "alc221-hp-mic"},
8483 {.id = ALC256_FIXUP_ASUS_HEADSET_MODE, .name = "alc256-asus-headset"},
8484 {.id = ALC256_FIXUP_ASUS_MIC, .name = "alc256-asus-mic"},
8485 {.id = ALC256_FIXUP_ASUS_AIO_GPIO2, .name = "alc256-asus-aio"},
8486 {.id = ALC233_FIXUP_ASUS_MIC_NO_PRESENCE, .name = "alc233-asus"},
8487 {.id = ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE, .name = "alc233-eapd"},
8488 {.id = ALC294_FIXUP_LENOVO_MIC_LOCATION, .name = "alc294-lenovo-mic"},
8489 {.id = ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE, .name = "alc225-wyse"},
8490 {.id = ALC274_FIXUP_DELL_AIO_LINEOUT_VERB, .name = "alc274-dell-aio"},
8491 {.id = ALC255_FIXUP_DUMMY_LINEOUT_VERB, .name = "alc255-dummy-lineout"},
8492 {.id = ALC255_FIXUP_DELL_HEADSET_MIC, .name = "alc255-dell-headset"},
8493 {.id = ALC295_FIXUP_HP_X360, .name = "alc295-hp-x360"},
David Brazdil0f672f62019-12-10 10:32:29 +00008494 {.id = ALC225_FIXUP_HEADSET_JACK, .name = "alc-headset-jack"},
8495 {.id = ALC295_FIXUP_CHROME_BOOK, .name = "alc-chrome-book"},
8496 {.id = ALC299_FIXUP_PREDATOR_SPK, .name = "predator-spk"},
8497 {.id = ALC298_FIXUP_HUAWEI_MBX_STEREO, .name = "huawei-mbx-stereo"},
8498 {.id = ALC256_FIXUP_MEDION_HEADSET_NO_PRESENCE, .name = "alc256-medion-headset"},
Olivier Deprez0e641232021-09-23 10:07:05 +02008499 {.id = ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET, .name = "alc298-samsung-headphone"},
8500 {.id = ALC255_FIXUP_XIAOMI_HEADSET_MIC, .name = "alc255-xiaomi-headset"},
8501 {.id = ALC274_FIXUP_HP_MIC, .name = "alc274-hp-mic-detect"},
8502 {.id = ALC295_FIXUP_HP_OMEN, .name = "alc295-hp-omen"},
8503 {.id = ALC285_FIXUP_HP_SPECTRE_X360, .name = "alc285-hp-spectre-x360"},
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008504 {}
8505};
8506#define ALC225_STANDARD_PINS \
8507 {0x21, 0x04211020}
8508
8509#define ALC256_STANDARD_PINS \
8510 {0x12, 0x90a60140}, \
8511 {0x14, 0x90170110}, \
8512 {0x21, 0x02211020}
8513
8514#define ALC282_STANDARD_PINS \
8515 {0x14, 0x90170110}
8516
8517#define ALC290_STANDARD_PINS \
8518 {0x12, 0x99a30130}
8519
8520#define ALC292_STANDARD_PINS \
8521 {0x14, 0x90170110}, \
8522 {0x15, 0x0221401f}
8523
8524#define ALC295_STANDARD_PINS \
8525 {0x12, 0xb7a60130}, \
8526 {0x14, 0x90170110}, \
8527 {0x21, 0x04211020}
8528
8529#define ALC298_STANDARD_PINS \
8530 {0x12, 0x90a60130}, \
8531 {0x21, 0x03211020}
8532
8533static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
8534 SND_HDA_PIN_QUIRK(0x10ec0221, 0x103c, "HP Workstation", ALC221_FIXUP_HP_HEADSET_MIC,
8535 {0x14, 0x01014020},
8536 {0x17, 0x90170110},
8537 {0x18, 0x02a11030},
8538 {0x19, 0x0181303F},
8539 {0x21, 0x0221102f}),
8540 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1025, "Acer", ALC255_FIXUP_ACER_MIC_NO_PRESENCE,
8541 {0x12, 0x90a601c0},
8542 {0x14, 0x90171120},
8543 {0x21, 0x02211030}),
8544 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1043, "ASUS", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE,
8545 {0x14, 0x90170110},
8546 {0x1b, 0x90a70130},
8547 {0x21, 0x03211020}),
8548 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1043, "ASUS", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE,
8549 {0x1a, 0x90a70130},
8550 {0x1b, 0x90170110},
8551 {0x21, 0x03211020}),
8552 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
8553 ALC225_STANDARD_PINS,
8554 {0x12, 0xb7a60130},
8555 {0x14, 0x901701a0}),
8556 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
8557 ALC225_STANDARD_PINS,
8558 {0x12, 0xb7a60130},
8559 {0x14, 0x901701b0}),
8560 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
8561 ALC225_STANDARD_PINS,
8562 {0x12, 0xb7a60150},
8563 {0x14, 0x901701a0}),
8564 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
8565 ALC225_STANDARD_PINS,
8566 {0x12, 0xb7a60150},
8567 {0x14, 0x901701b0}),
8568 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
8569 ALC225_STANDARD_PINS,
8570 {0x12, 0xb7a60130},
8571 {0x1b, 0x90170110}),
8572 SND_HDA_PIN_QUIRK(0x10ec0233, 0x8086, "Intel NUC Skull Canyon", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
8573 {0x1b, 0x01111010},
8574 {0x1e, 0x01451130},
8575 {0x21, 0x02211020}),
8576 SND_HDA_PIN_QUIRK(0x10ec0235, 0x17aa, "Lenovo", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY,
8577 {0x12, 0x90a60140},
8578 {0x14, 0x90170110},
8579 {0x19, 0x02a11030},
8580 {0x21, 0x02211020}),
8581 SND_HDA_PIN_QUIRK(0x10ec0235, 0x17aa, "Lenovo", ALC294_FIXUP_LENOVO_MIC_LOCATION,
8582 {0x14, 0x90170110},
8583 {0x19, 0x02a11030},
8584 {0x1a, 0x02a11040},
8585 {0x1b, 0x01014020},
8586 {0x21, 0x0221101f}),
8587 SND_HDA_PIN_QUIRK(0x10ec0235, 0x17aa, "Lenovo", ALC294_FIXUP_LENOVO_MIC_LOCATION,
8588 {0x14, 0x90170110},
8589 {0x19, 0x02a11030},
8590 {0x1a, 0x02a11040},
8591 {0x1b, 0x01011020},
8592 {0x21, 0x0221101f}),
8593 SND_HDA_PIN_QUIRK(0x10ec0235, 0x17aa, "Lenovo", ALC294_FIXUP_LENOVO_MIC_LOCATION,
8594 {0x14, 0x90170110},
8595 {0x19, 0x02a11020},
8596 {0x1a, 0x02a11030},
8597 {0x21, 0x0221101f}),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008598 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE,
8599 {0x14, 0x90170110},
8600 {0x21, 0x02211020}),
8601 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
8602 {0x14, 0x90170130},
8603 {0x21, 0x02211040}),
8604 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
8605 {0x12, 0x90a60140},
8606 {0x14, 0x90170110},
8607 {0x21, 0x02211020}),
8608 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
8609 {0x12, 0x90a60160},
8610 {0x14, 0x90170120},
8611 {0x21, 0x02211030}),
8612 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
8613 {0x14, 0x90170110},
8614 {0x1b, 0x02011020},
8615 {0x21, 0x0221101f}),
8616 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
8617 {0x14, 0x90170110},
8618 {0x1b, 0x01011020},
8619 {0x21, 0x0221101f}),
8620 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
8621 {0x14, 0x90170130},
8622 {0x1b, 0x01014020},
8623 {0x21, 0x0221103f}),
8624 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
8625 {0x14, 0x90170130},
8626 {0x1b, 0x01011020},
8627 {0x21, 0x0221103f}),
8628 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
8629 {0x14, 0x90170130},
8630 {0x1b, 0x02011020},
8631 {0x21, 0x0221103f}),
8632 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
8633 {0x14, 0x90170150},
8634 {0x1b, 0x02011020},
8635 {0x21, 0x0221105f}),
8636 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
8637 {0x14, 0x90170110},
8638 {0x1b, 0x01014020},
8639 {0x21, 0x0221101f}),
8640 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
8641 {0x12, 0x90a60160},
8642 {0x14, 0x90170120},
8643 {0x17, 0x90170140},
8644 {0x21, 0x0321102f}),
8645 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
8646 {0x12, 0x90a60160},
8647 {0x14, 0x90170130},
8648 {0x21, 0x02211040}),
8649 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
8650 {0x12, 0x90a60160},
8651 {0x14, 0x90170140},
8652 {0x21, 0x02211050}),
8653 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
8654 {0x12, 0x90a60170},
8655 {0x14, 0x90170120},
8656 {0x21, 0x02211030}),
8657 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
8658 {0x12, 0x90a60170},
8659 {0x14, 0x90170130},
8660 {0x21, 0x02211040}),
8661 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
8662 {0x12, 0x90a60170},
8663 {0x14, 0x90171130},
8664 {0x21, 0x02211040}),
8665 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
8666 {0x12, 0x90a60170},
8667 {0x14, 0x90170140},
8668 {0x21, 0x02211050}),
8669 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell Inspiron 5548", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
8670 {0x12, 0x90a60180},
8671 {0x14, 0x90170130},
8672 {0x21, 0x02211040}),
8673 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell Inspiron 5565", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
8674 {0x12, 0x90a60180},
8675 {0x14, 0x90170120},
8676 {0x21, 0x02211030}),
8677 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
8678 {0x1b, 0x01011020},
8679 {0x21, 0x02211010}),
8680 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
8681 {0x12, 0x90a60130},
8682 {0x14, 0x90170110},
8683 {0x1b, 0x01011020},
8684 {0x21, 0x0221101f}),
8685 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
8686 {0x12, 0x90a60160},
8687 {0x14, 0x90170120},
8688 {0x21, 0x02211030}),
8689 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
8690 {0x12, 0x90a60170},
8691 {0x14, 0x90170120},
8692 {0x21, 0x02211030}),
8693 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell Inspiron 5468", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
8694 {0x12, 0x90a60180},
8695 {0x14, 0x90170120},
8696 {0x21, 0x02211030}),
8697 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
8698 {0x12, 0xb7a60130},
8699 {0x14, 0x90170110},
8700 {0x21, 0x02211020}),
8701 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
8702 {0x12, 0x90a60130},
8703 {0x14, 0x90170110},
8704 {0x14, 0x01011020},
8705 {0x21, 0x0221101f}),
8706 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
8707 ALC256_STANDARD_PINS),
David Brazdil0f672f62019-12-10 10:32:29 +00008708 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
8709 {0x14, 0x90170110},
8710 {0x1b, 0x01011020},
8711 {0x21, 0x0221101f}),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008712 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC,
8713 {0x14, 0x90170110},
8714 {0x1b, 0x90a70130},
8715 {0x21, 0x04211020}),
8716 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC,
8717 {0x14, 0x90170110},
8718 {0x1b, 0x90a70130},
8719 {0x21, 0x03211020}),
David Brazdil0f672f62019-12-10 10:32:29 +00008720 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE,
8721 {0x12, 0x90a60130},
8722 {0x14, 0x90170110},
8723 {0x21, 0x03211020}),
8724 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE,
8725 {0x12, 0x90a60130},
8726 {0x14, 0x90170110},
8727 {0x21, 0x04211020}),
8728 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE,
8729 {0x1a, 0x90a70130},
8730 {0x1b, 0x90170110},
8731 {0x21, 0x03211020}),
Olivier Deprez0e641232021-09-23 10:07:05 +02008732 SND_HDA_PIN_QUIRK(0x10ec0274, 0x103c, "HP", ALC274_FIXUP_HP_HEADSET_MIC,
8733 {0x17, 0x90170110},
8734 {0x19, 0x03a11030},
8735 {0x21, 0x03211020}),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008736 SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC280_FIXUP_HP_GPIO4,
8737 {0x12, 0x90a60130},
8738 {0x14, 0x90170110},
8739 {0x15, 0x0421101f},
8740 {0x1a, 0x04a11020}),
8741 SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED,
8742 {0x12, 0x90a60140},
8743 {0x14, 0x90170110},
8744 {0x15, 0x0421101f},
8745 {0x18, 0x02811030},
8746 {0x1a, 0x04a1103f},
8747 {0x1b, 0x02011020}),
8748 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP 15 Touchsmart", ALC269_FIXUP_HP_MUTE_LED_MIC1,
8749 ALC282_STANDARD_PINS,
8750 {0x12, 0x99a30130},
8751 {0x19, 0x03a11020},
8752 {0x21, 0x0321101f}),
8753 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
8754 ALC282_STANDARD_PINS,
8755 {0x12, 0x99a30130},
8756 {0x19, 0x03a11020},
8757 {0x21, 0x03211040}),
8758 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
8759 ALC282_STANDARD_PINS,
8760 {0x12, 0x99a30130},
8761 {0x19, 0x03a11030},
8762 {0x21, 0x03211020}),
8763 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
8764 ALC282_STANDARD_PINS,
8765 {0x12, 0x99a30130},
8766 {0x19, 0x04a11020},
8767 {0x21, 0x0421101f}),
8768 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED,
8769 ALC282_STANDARD_PINS,
8770 {0x12, 0x90a60140},
8771 {0x19, 0x04a11030},
8772 {0x21, 0x04211020}),
8773 SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
8774 ALC282_STANDARD_PINS,
8775 {0x12, 0x90a60130},
8776 {0x21, 0x0321101f}),
8777 SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
8778 {0x12, 0x90a60160},
8779 {0x14, 0x90170120},
8780 {0x21, 0x02211030}),
8781 SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
8782 ALC282_STANDARD_PINS,
8783 {0x12, 0x90a60130},
8784 {0x19, 0x03a11020},
8785 {0x21, 0x0321101f}),
David Brazdil0f672f62019-12-10 10:32:29 +00008786 SND_HDA_PIN_QUIRK(0x10ec0285, 0x17aa, "Lenovo", ALC285_FIXUP_LENOVO_PC_BEEP_IN_NOISE,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008787 {0x12, 0x90a60130},
8788 {0x14, 0x90170110},
8789 {0x19, 0x04a11040},
8790 {0x21, 0x04211020}),
Olivier Deprez0e641232021-09-23 10:07:05 +02008791 SND_HDA_PIN_QUIRK(0x10ec0285, 0x17aa, "Lenovo", ALC285_FIXUP_LENOVO_PC_BEEP_IN_NOISE,
8792 {0x14, 0x90170110},
8793 {0x19, 0x04a11040},
8794 {0x1d, 0x40600001},
8795 {0x21, 0x04211020}),
8796 SND_HDA_PIN_QUIRK(0x10ec0285, 0x17aa, "Lenovo", ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK,
8797 {0x14, 0x90170110},
8798 {0x19, 0x04a11040},
8799 {0x21, 0x04211020}),
8800 SND_HDA_PIN_QUIRK(0x10ec0287, 0x17aa, "Lenovo", ALC285_FIXUP_THINKPAD_HEADSET_JACK,
8801 {0x14, 0x90170110},
8802 {0x17, 0x90170111},
8803 {0x19, 0x03a11030},
8804 {0x21, 0x03211020}),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008805 SND_HDA_PIN_QUIRK(0x10ec0286, 0x1025, "Acer", ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE,
8806 {0x12, 0x90a60130},
8807 {0x17, 0x90170110},
8808 {0x21, 0x02211020}),
8809 SND_HDA_PIN_QUIRK(0x10ec0288, 0x1028, "Dell", ALC288_FIXUP_DELL1_MIC_NO_PRESENCE,
8810 {0x12, 0x90a60120},
8811 {0x14, 0x90170110},
8812 {0x21, 0x0321101f}),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008813 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
8814 ALC290_STANDARD_PINS,
8815 {0x15, 0x04211040},
8816 {0x18, 0x90170112},
8817 {0x1a, 0x04a11020}),
8818 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
8819 ALC290_STANDARD_PINS,
8820 {0x15, 0x04211040},
8821 {0x18, 0x90170110},
8822 {0x1a, 0x04a11020}),
8823 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
8824 ALC290_STANDARD_PINS,
8825 {0x15, 0x0421101f},
8826 {0x1a, 0x04a11020}),
8827 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
8828 ALC290_STANDARD_PINS,
8829 {0x15, 0x04211020},
8830 {0x1a, 0x04a11040}),
8831 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
8832 ALC290_STANDARD_PINS,
8833 {0x14, 0x90170110},
8834 {0x15, 0x04211020},
8835 {0x1a, 0x04a11040}),
8836 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
8837 ALC290_STANDARD_PINS,
8838 {0x14, 0x90170110},
8839 {0x15, 0x04211020},
8840 {0x1a, 0x04a11020}),
8841 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
8842 ALC290_STANDARD_PINS,
8843 {0x14, 0x90170110},
8844 {0x15, 0x0421101f},
8845 {0x1a, 0x04a11020}),
8846 SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
8847 ALC292_STANDARD_PINS,
8848 {0x12, 0x90a60140},
8849 {0x16, 0x01014020},
8850 {0x19, 0x01a19030}),
8851 SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
8852 ALC292_STANDARD_PINS,
8853 {0x12, 0x90a60140},
8854 {0x16, 0x01014020},
8855 {0x18, 0x02a19031},
8856 {0x19, 0x01a1903e}),
8857 SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
8858 ALC292_STANDARD_PINS,
8859 {0x12, 0x90a60140}),
8860 SND_HDA_PIN_QUIRK(0x10ec0293, 0x1028, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
8861 ALC292_STANDARD_PINS,
8862 {0x13, 0x90a60140},
8863 {0x16, 0x21014020},
8864 {0x19, 0x21a19030}),
8865 SND_HDA_PIN_QUIRK(0x10ec0293, 0x1028, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
8866 ALC292_STANDARD_PINS,
8867 {0x13, 0x90a60140}),
Olivier Deprez0e641232021-09-23 10:07:05 +02008868 SND_HDA_PIN_QUIRK(0x10ec0294, 0x1043, "ASUS", ALC294_FIXUP_ASUS_HPE,
8869 {0x17, 0x90170110},
8870 {0x21, 0x04211020}),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008871 SND_HDA_PIN_QUIRK(0x10ec0294, 0x1043, "ASUS", ALC294_FIXUP_ASUS_MIC,
8872 {0x14, 0x90170110},
8873 {0x1b, 0x90a70130},
8874 {0x21, 0x04211020}),
8875 SND_HDA_PIN_QUIRK(0x10ec0294, 0x1043, "ASUS", ALC294_FIXUP_ASUS_SPK,
8876 {0x12, 0x90a60130},
8877 {0x17, 0x90170110},
David Brazdil0f672f62019-12-10 10:32:29 +00008878 {0x21, 0x03211020}),
8879 SND_HDA_PIN_QUIRK(0x10ec0294, 0x1043, "ASUS", ALC294_FIXUP_ASUS_SPK,
8880 {0x12, 0x90a60130},
8881 {0x17, 0x90170110},
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008882 {0x21, 0x04211020}),
David Brazdil0f672f62019-12-10 10:32:29 +00008883 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1043, "ASUS", ALC294_FIXUP_ASUS_SPK,
8884 {0x12, 0x90a60130},
8885 {0x17, 0x90170110},
8886 {0x21, 0x03211020}),
Olivier Deprez0e641232021-09-23 10:07:05 +02008887 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1043, "ASUS", ALC295_FIXUP_ASUS_MIC_NO_PRESENCE,
8888 {0x12, 0x90a60120},
8889 {0x17, 0x90170110},
8890 {0x21, 0x04211030}),
8891 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1043, "ASUS", ALC295_FIXUP_ASUS_MIC_NO_PRESENCE,
8892 {0x12, 0x90a60130},
8893 {0x17, 0x90170110},
8894 {0x21, 0x03211020}),
8895 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1043, "ASUS", ALC295_FIXUP_ASUS_MIC_NO_PRESENCE,
8896 {0x12, 0x90a60130},
8897 {0x17, 0x90170110},
8898 {0x21, 0x03211020}),
David Brazdil0f672f62019-12-10 10:32:29 +00008899 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
8900 {0x14, 0x90170110},
8901 {0x21, 0x04211020}),
8902 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
8903 {0x14, 0x90170110},
8904 {0x21, 0x04211030}),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008905 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
8906 ALC295_STANDARD_PINS,
8907 {0x17, 0x21014020},
8908 {0x18, 0x21a19030}),
8909 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
8910 ALC295_STANDARD_PINS,
8911 {0x17, 0x21014040},
8912 {0x18, 0x21a19050}),
8913 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
8914 ALC295_STANDARD_PINS),
8915 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
8916 ALC298_STANDARD_PINS,
8917 {0x17, 0x90170110}),
8918 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
8919 ALC298_STANDARD_PINS,
8920 {0x17, 0x90170140}),
8921 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
8922 ALC298_STANDARD_PINS,
8923 {0x17, 0x90170150}),
8924 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_SPK_VOLUME,
8925 {0x12, 0xb7a60140},
8926 {0x13, 0xb7a60150},
8927 {0x17, 0x90170110},
8928 {0x1a, 0x03011020},
8929 {0x21, 0x03211030}),
David Brazdil0f672f62019-12-10 10:32:29 +00008930 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_ALIENWARE_MIC_NO_PRESENCE,
8931 {0x12, 0xb7a60140},
8932 {0x17, 0x90170110},
8933 {0x1a, 0x03a11030},
8934 {0x21, 0x03211020}),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008935 SND_HDA_PIN_QUIRK(0x10ec0299, 0x1028, "Dell", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
8936 ALC225_STANDARD_PINS,
8937 {0x12, 0xb7a60130},
8938 {0x17, 0x90170110}),
Olivier Deprez0e641232021-09-23 10:07:05 +02008939 SND_HDA_PIN_QUIRK(0x10ec0623, 0x17aa, "Lenovo", ALC283_FIXUP_HEADSET_MIC,
8940 {0x14, 0x01014010},
8941 {0x17, 0x90170120},
8942 {0x18, 0x02a11030},
8943 {0x19, 0x02a1103f},
8944 {0x21, 0x0221101f}),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008945 {}
8946};
8947
David Brazdil0f672f62019-12-10 10:32:29 +00008948/* This is the fallback pin_fixup_tbl for alc269 family, to make the tbl match
8949 * more machines, don't need to match all valid pins, just need to match
8950 * all the pins defined in the tbl. Just because of this reason, it is possible
8951 * that a single machine matches multiple tbls, so there is one limitation:
8952 * at most one tbl is allowed to define for the same vendor and same codec
8953 */
8954static const struct snd_hda_pin_quirk alc269_fallback_pin_fixup_tbl[] = {
8955 SND_HDA_PIN_QUIRK(0x10ec0289, 0x1028, "Dell", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
8956 {0x19, 0x40000000},
8957 {0x1b, 0x40000000}),
Olivier Deprez0e641232021-09-23 10:07:05 +02008958 SND_HDA_PIN_QUIRK(0x10ec0274, 0x1028, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB,
8959 {0x19, 0x40000000},
8960 {0x1a, 0x40000000}),
8961 SND_HDA_PIN_QUIRK(0x10ec0236, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
8962 {0x19, 0x40000000},
8963 {0x1a, 0x40000000}),
David Brazdil0f672f62019-12-10 10:32:29 +00008964 {}
8965};
8966
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00008967static void alc269_fill_coef(struct hda_codec *codec)
8968{
8969 struct alc_spec *spec = codec->spec;
8970 int val;
8971
8972 if (spec->codec_variant != ALC269_TYPE_ALC269VB)
8973 return;
8974
8975 if ((alc_get_coef0(codec) & 0x00ff) < 0x015) {
8976 alc_write_coef_idx(codec, 0xf, 0x960b);
8977 alc_write_coef_idx(codec, 0xe, 0x8817);
8978 }
8979
8980 if ((alc_get_coef0(codec) & 0x00ff) == 0x016) {
8981 alc_write_coef_idx(codec, 0xf, 0x960b);
8982 alc_write_coef_idx(codec, 0xe, 0x8814);
8983 }
8984
8985 if ((alc_get_coef0(codec) & 0x00ff) == 0x017) {
8986 /* Power up output pin */
8987 alc_update_coef_idx(codec, 0x04, 0, 1<<11);
8988 }
8989
8990 if ((alc_get_coef0(codec) & 0x00ff) == 0x018) {
8991 val = alc_read_coef_idx(codec, 0xd);
8992 if (val != -1 && (val & 0x0c00) >> 10 != 0x1) {
8993 /* Capless ramp up clock control */
8994 alc_write_coef_idx(codec, 0xd, val | (1<<10));
8995 }
8996 val = alc_read_coef_idx(codec, 0x17);
8997 if (val != -1 && (val & 0x01c0) >> 6 != 0x4) {
8998 /* Class D power on reset */
8999 alc_write_coef_idx(codec, 0x17, val | (1<<7));
9000 }
9001 }
9002
9003 /* HP */
9004 alc_update_coef_idx(codec, 0x4, 0, 1<<11);
9005}
9006
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00009007/*
9008 */
9009static int patch_alc269(struct hda_codec *codec)
9010{
9011 struct alc_spec *spec;
9012 int err;
9013
9014 err = alc_alloc_spec(codec, 0x0b);
9015 if (err < 0)
9016 return err;
9017
9018 spec = codec->spec;
9019 spec->gen.shared_mic_vref_pin = 0x18;
David Brazdil0f672f62019-12-10 10:32:29 +00009020 codec->power_save_node = 0;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00009021
9022#ifdef CONFIG_PM
9023 codec->patch_ops.suspend = alc269_suspend;
9024 codec->patch_ops.resume = alc269_resume;
9025#endif
9026 spec->shutup = alc_default_shutup;
9027 spec->init_hook = alc_default_init;
9028
9029 switch (codec->core.vendor_id) {
9030 case 0x10ec0269:
9031 spec->codec_variant = ALC269_TYPE_ALC269VA;
9032 switch (alc_get_coef0(codec) & 0x00f0) {
9033 case 0x0010:
9034 if (codec->bus->pci &&
9035 codec->bus->pci->subsystem_vendor == 0x1025 &&
9036 spec->cdefine.platform_type == 1)
9037 err = alc_codec_rename(codec, "ALC271X");
9038 spec->codec_variant = ALC269_TYPE_ALC269VB;
9039 break;
9040 case 0x0020:
9041 if (codec->bus->pci &&
9042 codec->bus->pci->subsystem_vendor == 0x17aa &&
9043 codec->bus->pci->subsystem_device == 0x21f3)
9044 err = alc_codec_rename(codec, "ALC3202");
9045 spec->codec_variant = ALC269_TYPE_ALC269VC;
9046 break;
9047 case 0x0030:
9048 spec->codec_variant = ALC269_TYPE_ALC269VD;
9049 break;
9050 default:
9051 alc_fix_pll_init(codec, 0x20, 0x04, 15);
9052 }
9053 if (err < 0)
9054 goto error;
9055 spec->shutup = alc269_shutup;
9056 spec->init_hook = alc269_fill_coef;
9057 alc269_fill_coef(codec);
9058 break;
9059
9060 case 0x10ec0280:
9061 case 0x10ec0290:
9062 spec->codec_variant = ALC269_TYPE_ALC280;
9063 break;
9064 case 0x10ec0282:
9065 spec->codec_variant = ALC269_TYPE_ALC282;
9066 spec->shutup = alc282_shutup;
9067 spec->init_hook = alc282_init;
9068 break;
9069 case 0x10ec0233:
9070 case 0x10ec0283:
9071 spec->codec_variant = ALC269_TYPE_ALC283;
9072 spec->shutup = alc283_shutup;
9073 spec->init_hook = alc283_init;
9074 break;
9075 case 0x10ec0284:
9076 case 0x10ec0292:
9077 spec->codec_variant = ALC269_TYPE_ALC284;
9078 break;
9079 case 0x10ec0293:
9080 spec->codec_variant = ALC269_TYPE_ALC293;
9081 break;
9082 case 0x10ec0286:
9083 case 0x10ec0288:
9084 spec->codec_variant = ALC269_TYPE_ALC286;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00009085 break;
9086 case 0x10ec0298:
9087 spec->codec_variant = ALC269_TYPE_ALC298;
9088 break;
9089 case 0x10ec0235:
9090 case 0x10ec0255:
9091 spec->codec_variant = ALC269_TYPE_ALC255;
9092 spec->shutup = alc256_shutup;
9093 spec->init_hook = alc256_init;
9094 break;
Olivier Deprez0e641232021-09-23 10:07:05 +02009095 case 0x10ec0230:
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00009096 case 0x10ec0236:
9097 case 0x10ec0256:
9098 spec->codec_variant = ALC269_TYPE_ALC256;
9099 spec->shutup = alc256_shutup;
9100 spec->init_hook = alc256_init;
9101 spec->gen.mixer_nid = 0; /* ALC256 does not have any loopback mixer path */
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00009102 break;
9103 case 0x10ec0257:
9104 spec->codec_variant = ALC269_TYPE_ALC257;
9105 spec->shutup = alc256_shutup;
9106 spec->init_hook = alc256_init;
9107 spec->gen.mixer_nid = 0;
9108 break;
9109 case 0x10ec0215:
Olivier Deprez0e641232021-09-23 10:07:05 +02009110 case 0x10ec0245:
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00009111 case 0x10ec0285:
Olivier Deprez0e641232021-09-23 10:07:05 +02009112 case 0x10ec0287:
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00009113 case 0x10ec0289:
9114 spec->codec_variant = ALC269_TYPE_ALC215;
9115 spec->shutup = alc225_shutup;
9116 spec->init_hook = alc225_init;
9117 spec->gen.mixer_nid = 0;
9118 break;
9119 case 0x10ec0225:
9120 case 0x10ec0295:
9121 case 0x10ec0299:
9122 spec->codec_variant = ALC269_TYPE_ALC225;
9123 spec->shutup = alc225_shutup;
9124 spec->init_hook = alc225_init;
9125 spec->gen.mixer_nid = 0; /* no loopback on ALC225, ALC295 and ALC299 */
9126 break;
9127 case 0x10ec0234:
9128 case 0x10ec0274:
9129 case 0x10ec0294:
9130 spec->codec_variant = ALC269_TYPE_ALC294;
9131 spec->gen.mixer_nid = 0; /* ALC2x4 does not have any loopback mixer path */
9132 alc_update_coef_idx(codec, 0x6b, 0x0018, (1<<4) | (1<<3)); /* UAJ MIC Vref control by verb */
David Brazdil0f672f62019-12-10 10:32:29 +00009133 spec->init_hook = alc294_init;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00009134 break;
9135 case 0x10ec0300:
9136 spec->codec_variant = ALC269_TYPE_ALC300;
9137 spec->gen.mixer_nid = 0; /* no loopback on ALC300 */
9138 break;
David Brazdil0f672f62019-12-10 10:32:29 +00009139 case 0x10ec0623:
9140 spec->codec_variant = ALC269_TYPE_ALC623;
9141 break;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00009142 case 0x10ec0700:
9143 case 0x10ec0701:
9144 case 0x10ec0703:
David Brazdil0f672f62019-12-10 10:32:29 +00009145 case 0x10ec0711:
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00009146 spec->codec_variant = ALC269_TYPE_ALC700;
9147 spec->gen.mixer_nid = 0; /* ALC700 does not have any loopback mixer path */
9148 alc_update_coef_idx(codec, 0x4a, 1 << 15, 0); /* Combo jack auto trigger control */
David Brazdil0f672f62019-12-10 10:32:29 +00009149 spec->init_hook = alc294_init;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00009150 break;
9151
9152 }
9153
9154 if (snd_hda_codec_read(codec, 0x51, 0, AC_VERB_PARAMETERS, 0) == 0x10ec5505) {
9155 spec->has_alc5505_dsp = 1;
9156 spec->init_hook = alc5505_dsp_init;
9157 }
9158
David Brazdil0f672f62019-12-10 10:32:29 +00009159 alc_pre_init(codec);
9160
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00009161 snd_hda_pick_fixup(codec, alc269_fixup_models,
9162 alc269_fixup_tbl, alc269_fixups);
Olivier Deprez0e641232021-09-23 10:07:05 +02009163 /* FIXME: both TX300 and ROG Strix G17 have the same SSID, and
9164 * the quirk breaks the latter (bko#214101).
9165 * Clear the wrong entry.
9166 */
9167 if (codec->fixup_id == ALC282_FIXUP_ASUS_TX300 &&
9168 codec->core.vendor_id == 0x10ec0294) {
9169 codec_dbg(codec, "Clear wrong fixup for ASUS ROG Strix G17\n");
9170 codec->fixup_id = HDA_FIXUP_ID_NOT_SET;
9171 }
9172
David Brazdil0f672f62019-12-10 10:32:29 +00009173 snd_hda_pick_pin_fixup(codec, alc269_pin_fixup_tbl, alc269_fixups, true);
9174 snd_hda_pick_pin_fixup(codec, alc269_fallback_pin_fixup_tbl, alc269_fixups, false);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00009175 snd_hda_pick_fixup(codec, NULL, alc269_fixup_vendor_tbl,
9176 alc269_fixups);
9177 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
9178
9179 alc_auto_parse_customize_define(codec);
9180
9181 if (has_cdefine_beep(codec))
9182 spec->gen.beep_nid = 0x01;
9183
9184 /* automatic parse from the BIOS config */
9185 err = alc269_parse_auto_config(codec);
9186 if (err < 0)
9187 goto error;
9188
9189 if (!spec->gen.no_analog && spec->gen.beep_nid && spec->gen.mixer_nid) {
9190 err = set_beep_amp(spec, spec->gen.mixer_nid, 0x04, HDA_INPUT);
9191 if (err < 0)
9192 goto error;
9193 }
9194
9195 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
9196
9197 return 0;
9198
9199 error:
9200 alc_free(codec);
9201 return err;
9202}
9203
9204/*
9205 * ALC861
9206 */
9207
9208static int alc861_parse_auto_config(struct hda_codec *codec)
9209{
9210 static const hda_nid_t alc861_ignore[] = { 0x1d, 0 };
9211 static const hda_nid_t alc861_ssids[] = { 0x0e, 0x0f, 0x0b, 0 };
9212 return alc_parse_auto_config(codec, alc861_ignore, alc861_ssids);
9213}
9214
9215/* Pin config fixes */
9216enum {
9217 ALC861_FIXUP_FSC_AMILO_PI1505,
9218 ALC861_FIXUP_AMP_VREF_0F,
9219 ALC861_FIXUP_NO_JACK_DETECT,
9220 ALC861_FIXUP_ASUS_A6RP,
9221 ALC660_FIXUP_ASUS_W7J,
9222};
9223
9224/* On some laptops, VREF of pin 0x0f is abused for controlling the main amp */
9225static void alc861_fixup_asus_amp_vref_0f(struct hda_codec *codec,
9226 const struct hda_fixup *fix, int action)
9227{
9228 struct alc_spec *spec = codec->spec;
9229 unsigned int val;
9230
9231 if (action != HDA_FIXUP_ACT_INIT)
9232 return;
9233 val = snd_hda_codec_get_pin_target(codec, 0x0f);
9234 if (!(val & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN)))
9235 val |= AC_PINCTL_IN_EN;
9236 val |= AC_PINCTL_VREF_50;
9237 snd_hda_set_pin_ctl(codec, 0x0f, val);
9238 spec->gen.keep_vref_in_automute = 1;
9239}
9240
9241/* suppress the jack-detection */
9242static void alc_fixup_no_jack_detect(struct hda_codec *codec,
9243 const struct hda_fixup *fix, int action)
9244{
9245 if (action == HDA_FIXUP_ACT_PRE_PROBE)
9246 codec->no_jack_detect = 1;
9247}
9248
9249static const struct hda_fixup alc861_fixups[] = {
9250 [ALC861_FIXUP_FSC_AMILO_PI1505] = {
9251 .type = HDA_FIXUP_PINS,
9252 .v.pins = (const struct hda_pintbl[]) {
9253 { 0x0b, 0x0221101f }, /* HP */
9254 { 0x0f, 0x90170310 }, /* speaker */
9255 { }
9256 }
9257 },
9258 [ALC861_FIXUP_AMP_VREF_0F] = {
9259 .type = HDA_FIXUP_FUNC,
9260 .v.func = alc861_fixup_asus_amp_vref_0f,
9261 },
9262 [ALC861_FIXUP_NO_JACK_DETECT] = {
9263 .type = HDA_FIXUP_FUNC,
9264 .v.func = alc_fixup_no_jack_detect,
9265 },
9266 [ALC861_FIXUP_ASUS_A6RP] = {
9267 .type = HDA_FIXUP_FUNC,
9268 .v.func = alc861_fixup_asus_amp_vref_0f,
9269 .chained = true,
9270 .chain_id = ALC861_FIXUP_NO_JACK_DETECT,
9271 },
9272 [ALC660_FIXUP_ASUS_W7J] = {
9273 .type = HDA_FIXUP_VERBS,
9274 .v.verbs = (const struct hda_verb[]) {
9275 /* ASUS W7J needs a magic pin setup on unused NID 0x10
9276 * for enabling outputs
9277 */
9278 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9279 { }
9280 },
9281 }
9282};
9283
9284static const struct snd_pci_quirk alc861_fixup_tbl[] = {
9285 SND_PCI_QUIRK(0x1043, 0x1253, "ASUS W7J", ALC660_FIXUP_ASUS_W7J),
9286 SND_PCI_QUIRK(0x1043, 0x1263, "ASUS Z35HL", ALC660_FIXUP_ASUS_W7J),
9287 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS A6Rp", ALC861_FIXUP_ASUS_A6RP),
9288 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", ALC861_FIXUP_AMP_VREF_0F),
9289 SND_PCI_QUIRK(0x1462, 0x7254, "HP DX2200", ALC861_FIXUP_NO_JACK_DETECT),
Olivier Deprez0e641232021-09-23 10:07:05 +02009290 SND_PCI_QUIRK_VENDOR(0x1584, "Haier/Uniwill", ALC861_FIXUP_AMP_VREF_0F),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00009291 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", ALC861_FIXUP_FSC_AMILO_PI1505),
9292 {}
9293};
9294
9295/*
9296 */
9297static int patch_alc861(struct hda_codec *codec)
9298{
9299 struct alc_spec *spec;
9300 int err;
9301
9302 err = alc_alloc_spec(codec, 0x15);
9303 if (err < 0)
9304 return err;
9305
9306 spec = codec->spec;
David Brazdil0f672f62019-12-10 10:32:29 +00009307 if (has_cdefine_beep(codec))
9308 spec->gen.beep_nid = 0x23;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00009309
9310#ifdef CONFIG_PM
9311 spec->power_hook = alc_power_eapd;
9312#endif
9313
David Brazdil0f672f62019-12-10 10:32:29 +00009314 alc_pre_init(codec);
9315
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00009316 snd_hda_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
9317 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
9318
9319 /* automatic parse from the BIOS config */
9320 err = alc861_parse_auto_config(codec);
9321 if (err < 0)
9322 goto error;
9323
9324 if (!spec->gen.no_analog) {
9325 err = set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
9326 if (err < 0)
9327 goto error;
9328 }
9329
9330 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
9331
9332 return 0;
9333
9334 error:
9335 alc_free(codec);
9336 return err;
9337}
9338
9339/*
9340 * ALC861-VD support
9341 *
9342 * Based on ALC882
9343 *
9344 * In addition, an independent DAC
9345 */
9346static int alc861vd_parse_auto_config(struct hda_codec *codec)
9347{
9348 static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
9349 static const hda_nid_t alc861vd_ssids[] = { 0x15, 0x1b, 0x14, 0 };
9350 return alc_parse_auto_config(codec, alc861vd_ignore, alc861vd_ssids);
9351}
9352
9353enum {
9354 ALC660VD_FIX_ASUS_GPIO1,
9355 ALC861VD_FIX_DALLAS,
9356};
9357
9358/* exclude VREF80 */
9359static void alc861vd_fixup_dallas(struct hda_codec *codec,
9360 const struct hda_fixup *fix, int action)
9361{
9362 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
9363 snd_hda_override_pin_caps(codec, 0x18, 0x00000734);
9364 snd_hda_override_pin_caps(codec, 0x19, 0x0000073c);
9365 }
9366}
9367
9368/* reset GPIO1 */
9369static void alc660vd_fixup_asus_gpio1(struct hda_codec *codec,
9370 const struct hda_fixup *fix, int action)
9371{
9372 struct alc_spec *spec = codec->spec;
9373
9374 if (action == HDA_FIXUP_ACT_PRE_PROBE)
9375 spec->gpio_mask |= 0x02;
9376 alc_fixup_gpio(codec, action, 0x01);
9377}
9378
9379static const struct hda_fixup alc861vd_fixups[] = {
9380 [ALC660VD_FIX_ASUS_GPIO1] = {
9381 .type = HDA_FIXUP_FUNC,
9382 .v.func = alc660vd_fixup_asus_gpio1,
9383 },
9384 [ALC861VD_FIX_DALLAS] = {
9385 .type = HDA_FIXUP_FUNC,
9386 .v.func = alc861vd_fixup_dallas,
9387 },
9388};
9389
9390static const struct snd_pci_quirk alc861vd_fixup_tbl[] = {
9391 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_FIX_DALLAS),
9392 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
9393 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_FIX_DALLAS),
9394 {}
9395};
9396
9397/*
9398 */
9399static int patch_alc861vd(struct hda_codec *codec)
9400{
9401 struct alc_spec *spec;
9402 int err;
9403
9404 err = alc_alloc_spec(codec, 0x0b);
9405 if (err < 0)
9406 return err;
9407
9408 spec = codec->spec;
David Brazdil0f672f62019-12-10 10:32:29 +00009409 if (has_cdefine_beep(codec))
9410 spec->gen.beep_nid = 0x23;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00009411
9412 spec->shutup = alc_eapd_shutup;
9413
David Brazdil0f672f62019-12-10 10:32:29 +00009414 alc_pre_init(codec);
9415
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00009416 snd_hda_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
9417 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
9418
9419 /* automatic parse from the BIOS config */
9420 err = alc861vd_parse_auto_config(codec);
9421 if (err < 0)
9422 goto error;
9423
9424 if (!spec->gen.no_analog) {
9425 err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
9426 if (err < 0)
9427 goto error;
9428 }
9429
9430 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
9431
9432 return 0;
9433
9434 error:
9435 alc_free(codec);
9436 return err;
9437}
9438
9439/*
9440 * ALC662 support
9441 *
9442 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
9443 * configuration. Each pin widget can choose any input DACs and a mixer.
9444 * Each ADC is connected from a mixer of all inputs. This makes possible
9445 * 6-channel independent captures.
9446 *
9447 * In addition, an independent DAC for the multi-playback (not used in this
9448 * driver yet).
9449 */
9450
9451/*
9452 * BIOS auto configuration
9453 */
9454
9455static int alc662_parse_auto_config(struct hda_codec *codec)
9456{
9457 static const hda_nid_t alc662_ignore[] = { 0x1d, 0 };
9458 static const hda_nid_t alc663_ssids[] = { 0x15, 0x1b, 0x14, 0x21 };
9459 static const hda_nid_t alc662_ssids[] = { 0x15, 0x1b, 0x14, 0 };
9460 const hda_nid_t *ssids;
9461
9462 if (codec->core.vendor_id == 0x10ec0272 || codec->core.vendor_id == 0x10ec0663 ||
9463 codec->core.vendor_id == 0x10ec0665 || codec->core.vendor_id == 0x10ec0670 ||
9464 codec->core.vendor_id == 0x10ec0671)
9465 ssids = alc663_ssids;
9466 else
9467 ssids = alc662_ssids;
9468 return alc_parse_auto_config(codec, alc662_ignore, ssids);
9469}
9470
9471static void alc272_fixup_mario(struct hda_codec *codec,
9472 const struct hda_fixup *fix, int action)
9473{
9474 if (action != HDA_FIXUP_ACT_PRE_PROBE)
9475 return;
9476 if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT,
9477 (0x3b << AC_AMPCAP_OFFSET_SHIFT) |
9478 (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) |
9479 (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) |
9480 (0 << AC_AMPCAP_MUTE_SHIFT)))
9481 codec_warn(codec, "failed to override amp caps for NID 0x2\n");
9482}
9483
9484static const struct snd_pcm_chmap_elem asus_pcm_2_1_chmaps[] = {
9485 { .channels = 2,
9486 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } },
9487 { .channels = 4,
9488 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR,
9489 SNDRV_CHMAP_NA, SNDRV_CHMAP_LFE } }, /* LFE only on right */
9490 { }
9491};
9492
9493/* override the 2.1 chmap */
9494static void alc_fixup_bass_chmap(struct hda_codec *codec,
9495 const struct hda_fixup *fix, int action)
9496{
9497 if (action == HDA_FIXUP_ACT_BUILD) {
9498 struct alc_spec *spec = codec->spec;
9499 spec->gen.pcm_rec[0]->stream[0].chmap = asus_pcm_2_1_chmaps;
9500 }
9501}
9502
9503/* avoid D3 for keeping GPIO up */
9504static unsigned int gpio_led_power_filter(struct hda_codec *codec,
9505 hda_nid_t nid,
9506 unsigned int power_state)
9507{
9508 struct alc_spec *spec = codec->spec;
9509 if (nid == codec->core.afg && power_state == AC_PWRST_D3 && spec->gpio_data)
9510 return AC_PWRST_D0;
9511 return power_state;
9512}
9513
9514static void alc662_fixup_led_gpio1(struct hda_codec *codec,
9515 const struct hda_fixup *fix, int action)
9516{
9517 struct alc_spec *spec = codec->spec;
9518
9519 alc_fixup_hp_gpio_led(codec, action, 0x01, 0);
9520 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
9521 spec->mute_led_polarity = 1;
9522 codec->power_filter = gpio_led_power_filter;
9523 }
9524}
9525
9526static void alc662_usi_automute_hook(struct hda_codec *codec,
9527 struct hda_jack_callback *jack)
9528{
9529 struct alc_spec *spec = codec->spec;
9530 int vref;
9531 msleep(200);
9532 snd_hda_gen_hp_automute(codec, jack);
9533
9534 vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0;
9535 msleep(100);
9536 snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
9537 vref);
9538}
9539
9540static void alc662_fixup_usi_headset_mic(struct hda_codec *codec,
9541 const struct hda_fixup *fix, int action)
9542{
9543 struct alc_spec *spec = codec->spec;
9544 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
9545 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
9546 spec->gen.hp_automute_hook = alc662_usi_automute_hook;
9547 }
9548}
9549
David Brazdil0f672f62019-12-10 10:32:29 +00009550static void alc662_aspire_ethos_mute_speakers(struct hda_codec *codec,
9551 struct hda_jack_callback *cb)
9552{
9553 /* surround speakers at 0x1b already get muted automatically when
9554 * headphones are plugged in, but we have to mute/unmute the remaining
9555 * channels manually:
9556 * 0x15 - front left/front right
9557 * 0x18 - front center/ LFE
9558 */
9559 if (snd_hda_jack_detect_state(codec, 0x1b) == HDA_JACK_PRESENT) {
9560 snd_hda_set_pin_ctl_cache(codec, 0x15, 0);
9561 snd_hda_set_pin_ctl_cache(codec, 0x18, 0);
9562 } else {
9563 snd_hda_set_pin_ctl_cache(codec, 0x15, PIN_OUT);
9564 snd_hda_set_pin_ctl_cache(codec, 0x18, PIN_OUT);
9565 }
9566}
9567
9568static void alc662_fixup_aspire_ethos_hp(struct hda_codec *codec,
9569 const struct hda_fixup *fix, int action)
9570{
9571 /* Pin 0x1b: shared headphones jack and surround speakers */
9572 if (!is_jack_detectable(codec, 0x1b))
9573 return;
9574
9575 switch (action) {
9576 case HDA_FIXUP_ACT_PRE_PROBE:
9577 snd_hda_jack_detect_enable_callback(codec, 0x1b,
9578 alc662_aspire_ethos_mute_speakers);
Olivier Deprez0e641232021-09-23 10:07:05 +02009579 /* subwoofer needs an extra GPIO setting to become audible */
9580 alc_setup_gpio(codec, 0x02);
David Brazdil0f672f62019-12-10 10:32:29 +00009581 break;
9582 case HDA_FIXUP_ACT_INIT:
9583 /* Make sure to start in a correct state, i.e. if
9584 * headphones have been plugged in before powering up the system
9585 */
9586 alc662_aspire_ethos_mute_speakers(codec, NULL);
9587 break;
9588 }
9589}
9590
Olivier Deprez0e641232021-09-23 10:07:05 +02009591static void alc671_fixup_hp_headset_mic2(struct hda_codec *codec,
9592 const struct hda_fixup *fix, int action)
9593{
9594 struct alc_spec *spec = codec->spec;
9595
9596 static const struct hda_pintbl pincfgs[] = {
9597 { 0x19, 0x02a11040 }, /* use as headset mic, with its own jack detect */
9598 { 0x1b, 0x0181304f },
9599 { }
9600 };
9601
9602 switch (action) {
9603 case HDA_FIXUP_ACT_PRE_PROBE:
9604 spec->gen.mixer_nid = 0;
9605 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
9606 snd_hda_apply_pincfgs(codec, pincfgs);
9607 break;
9608 case HDA_FIXUP_ACT_INIT:
9609 alc_write_coef_idx(codec, 0x19, 0xa054);
9610 break;
9611 }
9612}
9613
9614static const struct coef_fw alc668_coefs[] = {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00009615 WRITE_COEF(0x01, 0xbebe), WRITE_COEF(0x02, 0xaaaa), WRITE_COEF(0x03, 0x0),
9616 WRITE_COEF(0x04, 0x0180), WRITE_COEF(0x06, 0x0), WRITE_COEF(0x07, 0x0f80),
9617 WRITE_COEF(0x08, 0x0031), WRITE_COEF(0x0a, 0x0060), WRITE_COEF(0x0b, 0x0),
9618 WRITE_COEF(0x0c, 0x7cf7), WRITE_COEF(0x0d, 0x1080), WRITE_COEF(0x0e, 0x7f7f),
9619 WRITE_COEF(0x0f, 0xcccc), WRITE_COEF(0x10, 0xddcc), WRITE_COEF(0x11, 0x0001),
9620 WRITE_COEF(0x13, 0x0), WRITE_COEF(0x14, 0x2aa0), WRITE_COEF(0x17, 0xa940),
9621 WRITE_COEF(0x19, 0x0), WRITE_COEF(0x1a, 0x0), WRITE_COEF(0x1b, 0x0),
9622 WRITE_COEF(0x1c, 0x0), WRITE_COEF(0x1d, 0x0), WRITE_COEF(0x1e, 0x7418),
9623 WRITE_COEF(0x1f, 0x0804), WRITE_COEF(0x20, 0x4200), WRITE_COEF(0x21, 0x0468),
9624 WRITE_COEF(0x22, 0x8ccc), WRITE_COEF(0x23, 0x0250), WRITE_COEF(0x24, 0x7418),
9625 WRITE_COEF(0x27, 0x0), WRITE_COEF(0x28, 0x8ccc), WRITE_COEF(0x2a, 0xff00),
9626 WRITE_COEF(0x2b, 0x8000), WRITE_COEF(0xa7, 0xff00), WRITE_COEF(0xa8, 0x8000),
9627 WRITE_COEF(0xaa, 0x2e17), WRITE_COEF(0xab, 0xa0c0), WRITE_COEF(0xac, 0x0),
9628 WRITE_COEF(0xad, 0x0), WRITE_COEF(0xae, 0x2ac6), WRITE_COEF(0xaf, 0xa480),
9629 WRITE_COEF(0xb0, 0x0), WRITE_COEF(0xb1, 0x0), WRITE_COEF(0xb2, 0x0),
9630 WRITE_COEF(0xb3, 0x0), WRITE_COEF(0xb4, 0x0), WRITE_COEF(0xb5, 0x1040),
9631 WRITE_COEF(0xb6, 0xd697), WRITE_COEF(0xb7, 0x902b), WRITE_COEF(0xb8, 0xd697),
9632 WRITE_COEF(0xb9, 0x902b), WRITE_COEF(0xba, 0xb8ba), WRITE_COEF(0xbb, 0xaaab),
9633 WRITE_COEF(0xbc, 0xaaaf), WRITE_COEF(0xbd, 0x6aaa), WRITE_COEF(0xbe, 0x1c02),
9634 WRITE_COEF(0xc0, 0x00ff), WRITE_COEF(0xc1, 0x0fa6),
9635 {}
9636};
9637
9638static void alc668_restore_default_value(struct hda_codec *codec)
9639{
9640 alc_process_coef_fw(codec, alc668_coefs);
9641}
9642
9643enum {
9644 ALC662_FIXUP_ASPIRE,
9645 ALC662_FIXUP_LED_GPIO1,
9646 ALC662_FIXUP_IDEAPAD,
9647 ALC272_FIXUP_MARIO,
Olivier Deprez0e641232021-09-23 10:07:05 +02009648 ALC662_FIXUP_CZC_ET26,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00009649 ALC662_FIXUP_CZC_P10T,
9650 ALC662_FIXUP_SKU_IGNORE,
9651 ALC662_FIXUP_HP_RP5800,
9652 ALC662_FIXUP_ASUS_MODE1,
9653 ALC662_FIXUP_ASUS_MODE2,
9654 ALC662_FIXUP_ASUS_MODE3,
9655 ALC662_FIXUP_ASUS_MODE4,
9656 ALC662_FIXUP_ASUS_MODE5,
9657 ALC662_FIXUP_ASUS_MODE6,
9658 ALC662_FIXUP_ASUS_MODE7,
9659 ALC662_FIXUP_ASUS_MODE8,
9660 ALC662_FIXUP_NO_JACK_DETECT,
9661 ALC662_FIXUP_ZOTAC_Z68,
9662 ALC662_FIXUP_INV_DMIC,
9663 ALC662_FIXUP_DELL_MIC_NO_PRESENCE,
9664 ALC668_FIXUP_DELL_MIC_NO_PRESENCE,
9665 ALC662_FIXUP_HEADSET_MODE,
9666 ALC668_FIXUP_HEADSET_MODE,
9667 ALC662_FIXUP_BASS_MODE4_CHMAP,
9668 ALC662_FIXUP_BASS_16,
9669 ALC662_FIXUP_BASS_1A,
9670 ALC662_FIXUP_BASS_CHMAP,
9671 ALC668_FIXUP_AUTO_MUTE,
9672 ALC668_FIXUP_DELL_DISABLE_AAMIX,
9673 ALC668_FIXUP_DELL_XPS13,
9674 ALC662_FIXUP_ASUS_Nx50,
9675 ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE,
9676 ALC668_FIXUP_ASUS_Nx51,
9677 ALC668_FIXUP_MIC_COEF,
9678 ALC668_FIXUP_ASUS_G751,
9679 ALC891_FIXUP_HEADSET_MODE,
9680 ALC891_FIXUP_DELL_MIC_NO_PRESENCE,
9681 ALC662_FIXUP_ACER_VERITON,
9682 ALC892_FIXUP_ASROCK_MOBO,
9683 ALC662_FIXUP_USI_FUNC,
9684 ALC662_FIXUP_USI_HEADSET_MODE,
9685 ALC662_FIXUP_LENOVO_MULTI_CODECS,
David Brazdil0f672f62019-12-10 10:32:29 +00009686 ALC669_FIXUP_ACER_ASPIRE_ETHOS,
David Brazdil0f672f62019-12-10 10:32:29 +00009687 ALC669_FIXUP_ACER_ASPIRE_ETHOS_HEADSET,
Olivier Deprez0e641232021-09-23 10:07:05 +02009688 ALC671_FIXUP_HP_HEADSET_MIC2,
9689 ALC662_FIXUP_ACER_X2660G_HEADSET_MODE,
9690 ALC662_FIXUP_ACER_NITRO_HEADSET_MODE,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00009691};
9692
9693static const struct hda_fixup alc662_fixups[] = {
9694 [ALC662_FIXUP_ASPIRE] = {
9695 .type = HDA_FIXUP_PINS,
9696 .v.pins = (const struct hda_pintbl[]) {
9697 { 0x15, 0x99130112 }, /* subwoofer */
9698 { }
9699 }
9700 },
9701 [ALC662_FIXUP_LED_GPIO1] = {
9702 .type = HDA_FIXUP_FUNC,
9703 .v.func = alc662_fixup_led_gpio1,
9704 },
9705 [ALC662_FIXUP_IDEAPAD] = {
9706 .type = HDA_FIXUP_PINS,
9707 .v.pins = (const struct hda_pintbl[]) {
9708 { 0x17, 0x99130112 }, /* subwoofer */
9709 { }
9710 },
9711 .chained = true,
9712 .chain_id = ALC662_FIXUP_LED_GPIO1,
9713 },
9714 [ALC272_FIXUP_MARIO] = {
9715 .type = HDA_FIXUP_FUNC,
9716 .v.func = alc272_fixup_mario,
9717 },
Olivier Deprez0e641232021-09-23 10:07:05 +02009718 [ALC662_FIXUP_CZC_ET26] = {
9719 .type = HDA_FIXUP_PINS,
9720 .v.pins = (const struct hda_pintbl[]) {
9721 {0x12, 0x403cc000},
9722 {0x14, 0x90170110}, /* speaker */
9723 {0x15, 0x411111f0},
9724 {0x16, 0x411111f0},
9725 {0x18, 0x01a19030}, /* mic */
9726 {0x19, 0x90a7013f}, /* int-mic */
9727 {0x1a, 0x01014020},
9728 {0x1b, 0x0121401f},
9729 {0x1c, 0x411111f0},
9730 {0x1d, 0x411111f0},
9731 {0x1e, 0x40478e35},
9732 {}
9733 },
9734 .chained = true,
9735 .chain_id = ALC662_FIXUP_SKU_IGNORE
9736 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00009737 [ALC662_FIXUP_CZC_P10T] = {
9738 .type = HDA_FIXUP_VERBS,
9739 .v.verbs = (const struct hda_verb[]) {
9740 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
9741 {}
9742 }
9743 },
9744 [ALC662_FIXUP_SKU_IGNORE] = {
9745 .type = HDA_FIXUP_FUNC,
9746 .v.func = alc_fixup_sku_ignore,
9747 },
9748 [ALC662_FIXUP_HP_RP5800] = {
9749 .type = HDA_FIXUP_PINS,
9750 .v.pins = (const struct hda_pintbl[]) {
9751 { 0x14, 0x0221201f }, /* HP out */
9752 { }
9753 },
9754 .chained = true,
9755 .chain_id = ALC662_FIXUP_SKU_IGNORE
9756 },
9757 [ALC662_FIXUP_ASUS_MODE1] = {
9758 .type = HDA_FIXUP_PINS,
9759 .v.pins = (const struct hda_pintbl[]) {
9760 { 0x14, 0x99130110 }, /* speaker */
9761 { 0x18, 0x01a19c20 }, /* mic */
9762 { 0x19, 0x99a3092f }, /* int-mic */
9763 { 0x21, 0x0121401f }, /* HP out */
9764 { }
9765 },
9766 .chained = true,
9767 .chain_id = ALC662_FIXUP_SKU_IGNORE
9768 },
9769 [ALC662_FIXUP_ASUS_MODE2] = {
9770 .type = HDA_FIXUP_PINS,
9771 .v.pins = (const struct hda_pintbl[]) {
9772 { 0x14, 0x99130110 }, /* speaker */
9773 { 0x18, 0x01a19820 }, /* mic */
9774 { 0x19, 0x99a3092f }, /* int-mic */
9775 { 0x1b, 0x0121401f }, /* HP out */
9776 { }
9777 },
9778 .chained = true,
9779 .chain_id = ALC662_FIXUP_SKU_IGNORE
9780 },
9781 [ALC662_FIXUP_ASUS_MODE3] = {
9782 .type = HDA_FIXUP_PINS,
9783 .v.pins = (const struct hda_pintbl[]) {
9784 { 0x14, 0x99130110 }, /* speaker */
9785 { 0x15, 0x0121441f }, /* HP */
9786 { 0x18, 0x01a19840 }, /* mic */
9787 { 0x19, 0x99a3094f }, /* int-mic */
9788 { 0x21, 0x01211420 }, /* HP2 */
9789 { }
9790 },
9791 .chained = true,
9792 .chain_id = ALC662_FIXUP_SKU_IGNORE
9793 },
9794 [ALC662_FIXUP_ASUS_MODE4] = {
9795 .type = HDA_FIXUP_PINS,
9796 .v.pins = (const struct hda_pintbl[]) {
9797 { 0x14, 0x99130110 }, /* speaker */
9798 { 0x16, 0x99130111 }, /* speaker */
9799 { 0x18, 0x01a19840 }, /* mic */
9800 { 0x19, 0x99a3094f }, /* int-mic */
9801 { 0x21, 0x0121441f }, /* HP */
9802 { }
9803 },
9804 .chained = true,
9805 .chain_id = ALC662_FIXUP_SKU_IGNORE
9806 },
9807 [ALC662_FIXUP_ASUS_MODE5] = {
9808 .type = HDA_FIXUP_PINS,
9809 .v.pins = (const struct hda_pintbl[]) {
9810 { 0x14, 0x99130110 }, /* speaker */
9811 { 0x15, 0x0121441f }, /* HP */
9812 { 0x16, 0x99130111 }, /* speaker */
9813 { 0x18, 0x01a19840 }, /* mic */
9814 { 0x19, 0x99a3094f }, /* int-mic */
9815 { }
9816 },
9817 .chained = true,
9818 .chain_id = ALC662_FIXUP_SKU_IGNORE
9819 },
9820 [ALC662_FIXUP_ASUS_MODE6] = {
9821 .type = HDA_FIXUP_PINS,
9822 .v.pins = (const struct hda_pintbl[]) {
9823 { 0x14, 0x99130110 }, /* speaker */
9824 { 0x15, 0x01211420 }, /* HP2 */
9825 { 0x18, 0x01a19840 }, /* mic */
9826 { 0x19, 0x99a3094f }, /* int-mic */
9827 { 0x1b, 0x0121441f }, /* HP */
9828 { }
9829 },
9830 .chained = true,
9831 .chain_id = ALC662_FIXUP_SKU_IGNORE
9832 },
9833 [ALC662_FIXUP_ASUS_MODE7] = {
9834 .type = HDA_FIXUP_PINS,
9835 .v.pins = (const struct hda_pintbl[]) {
9836 { 0x14, 0x99130110 }, /* speaker */
9837 { 0x17, 0x99130111 }, /* speaker */
9838 { 0x18, 0x01a19840 }, /* mic */
9839 { 0x19, 0x99a3094f }, /* int-mic */
9840 { 0x1b, 0x01214020 }, /* HP */
9841 { 0x21, 0x0121401f }, /* HP */
9842 { }
9843 },
9844 .chained = true,
9845 .chain_id = ALC662_FIXUP_SKU_IGNORE
9846 },
9847 [ALC662_FIXUP_ASUS_MODE8] = {
9848 .type = HDA_FIXUP_PINS,
9849 .v.pins = (const struct hda_pintbl[]) {
9850 { 0x14, 0x99130110 }, /* speaker */
9851 { 0x12, 0x99a30970 }, /* int-mic */
9852 { 0x15, 0x01214020 }, /* HP */
9853 { 0x17, 0x99130111 }, /* speaker */
9854 { 0x18, 0x01a19840 }, /* mic */
9855 { 0x21, 0x0121401f }, /* HP */
9856 { }
9857 },
9858 .chained = true,
9859 .chain_id = ALC662_FIXUP_SKU_IGNORE
9860 },
9861 [ALC662_FIXUP_NO_JACK_DETECT] = {
9862 .type = HDA_FIXUP_FUNC,
9863 .v.func = alc_fixup_no_jack_detect,
9864 },
9865 [ALC662_FIXUP_ZOTAC_Z68] = {
9866 .type = HDA_FIXUP_PINS,
9867 .v.pins = (const struct hda_pintbl[]) {
9868 { 0x1b, 0x02214020 }, /* Front HP */
9869 { }
9870 }
9871 },
9872 [ALC662_FIXUP_INV_DMIC] = {
9873 .type = HDA_FIXUP_FUNC,
9874 .v.func = alc_fixup_inv_dmic,
9875 },
9876 [ALC668_FIXUP_DELL_XPS13] = {
9877 .type = HDA_FIXUP_FUNC,
9878 .v.func = alc_fixup_dell_xps13,
9879 .chained = true,
9880 .chain_id = ALC668_FIXUP_DELL_DISABLE_AAMIX
9881 },
9882 [ALC668_FIXUP_DELL_DISABLE_AAMIX] = {
9883 .type = HDA_FIXUP_FUNC,
9884 .v.func = alc_fixup_disable_aamix,
9885 .chained = true,
9886 .chain_id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE
9887 },
9888 [ALC668_FIXUP_AUTO_MUTE] = {
9889 .type = HDA_FIXUP_FUNC,
9890 .v.func = alc_fixup_auto_mute_via_amp,
9891 .chained = true,
9892 .chain_id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE
9893 },
9894 [ALC662_FIXUP_DELL_MIC_NO_PRESENCE] = {
9895 .type = HDA_FIXUP_PINS,
9896 .v.pins = (const struct hda_pintbl[]) {
9897 { 0x19, 0x03a1113c }, /* use as headset mic, without its own jack detect */
9898 /* headphone mic by setting pin control of 0x1b (headphone out) to in + vref_50 */
9899 { }
9900 },
9901 .chained = true,
9902 .chain_id = ALC662_FIXUP_HEADSET_MODE
9903 },
9904 [ALC662_FIXUP_HEADSET_MODE] = {
9905 .type = HDA_FIXUP_FUNC,
9906 .v.func = alc_fixup_headset_mode_alc662,
9907 },
9908 [ALC668_FIXUP_DELL_MIC_NO_PRESENCE] = {
9909 .type = HDA_FIXUP_PINS,
9910 .v.pins = (const struct hda_pintbl[]) {
9911 { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
9912 { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */
9913 { }
9914 },
9915 .chained = true,
9916 .chain_id = ALC668_FIXUP_HEADSET_MODE
9917 },
9918 [ALC668_FIXUP_HEADSET_MODE] = {
9919 .type = HDA_FIXUP_FUNC,
9920 .v.func = alc_fixup_headset_mode_alc668,
9921 },
9922 [ALC662_FIXUP_BASS_MODE4_CHMAP] = {
9923 .type = HDA_FIXUP_FUNC,
9924 .v.func = alc_fixup_bass_chmap,
9925 .chained = true,
9926 .chain_id = ALC662_FIXUP_ASUS_MODE4
9927 },
9928 [ALC662_FIXUP_BASS_16] = {
9929 .type = HDA_FIXUP_PINS,
9930 .v.pins = (const struct hda_pintbl[]) {
9931 {0x16, 0x80106111}, /* bass speaker */
9932 {}
9933 },
9934 .chained = true,
9935 .chain_id = ALC662_FIXUP_BASS_CHMAP,
9936 },
9937 [ALC662_FIXUP_BASS_1A] = {
9938 .type = HDA_FIXUP_PINS,
9939 .v.pins = (const struct hda_pintbl[]) {
9940 {0x1a, 0x80106111}, /* bass speaker */
9941 {}
9942 },
9943 .chained = true,
9944 .chain_id = ALC662_FIXUP_BASS_CHMAP,
9945 },
9946 [ALC662_FIXUP_BASS_CHMAP] = {
9947 .type = HDA_FIXUP_FUNC,
9948 .v.func = alc_fixup_bass_chmap,
9949 },
9950 [ALC662_FIXUP_ASUS_Nx50] = {
9951 .type = HDA_FIXUP_FUNC,
9952 .v.func = alc_fixup_auto_mute_via_amp,
9953 .chained = true,
9954 .chain_id = ALC662_FIXUP_BASS_1A
9955 },
9956 [ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE] = {
9957 .type = HDA_FIXUP_FUNC,
9958 .v.func = alc_fixup_headset_mode_alc668,
9959 .chain_id = ALC662_FIXUP_BASS_CHMAP
9960 },
9961 [ALC668_FIXUP_ASUS_Nx51] = {
9962 .type = HDA_FIXUP_PINS,
9963 .v.pins = (const struct hda_pintbl[]) {
9964 { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
9965 { 0x1a, 0x90170151 }, /* bass speaker */
9966 { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */
9967 {}
9968 },
9969 .chained = true,
9970 .chain_id = ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE,
9971 },
9972 [ALC668_FIXUP_MIC_COEF] = {
9973 .type = HDA_FIXUP_VERBS,
9974 .v.verbs = (const struct hda_verb[]) {
9975 { 0x20, AC_VERB_SET_COEF_INDEX, 0xc3 },
9976 { 0x20, AC_VERB_SET_PROC_COEF, 0x4000 },
9977 {}
9978 },
9979 },
9980 [ALC668_FIXUP_ASUS_G751] = {
9981 .type = HDA_FIXUP_PINS,
9982 .v.pins = (const struct hda_pintbl[]) {
9983 { 0x16, 0x0421101f }, /* HP */
9984 {}
9985 },
9986 .chained = true,
9987 .chain_id = ALC668_FIXUP_MIC_COEF
9988 },
9989 [ALC891_FIXUP_HEADSET_MODE] = {
9990 .type = HDA_FIXUP_FUNC,
9991 .v.func = alc_fixup_headset_mode,
9992 },
9993 [ALC891_FIXUP_DELL_MIC_NO_PRESENCE] = {
9994 .type = HDA_FIXUP_PINS,
9995 .v.pins = (const struct hda_pintbl[]) {
9996 { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
9997 { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */
9998 { }
9999 },
10000 .chained = true,
10001 .chain_id = ALC891_FIXUP_HEADSET_MODE
10002 },
10003 [ALC662_FIXUP_ACER_VERITON] = {
10004 .type = HDA_FIXUP_PINS,
10005 .v.pins = (const struct hda_pintbl[]) {
10006 { 0x15, 0x50170120 }, /* no internal speaker */
10007 { }
10008 }
10009 },
10010 [ALC892_FIXUP_ASROCK_MOBO] = {
10011 .type = HDA_FIXUP_PINS,
10012 .v.pins = (const struct hda_pintbl[]) {
10013 { 0x15, 0x40f000f0 }, /* disabled */
10014 { 0x16, 0x40f000f0 }, /* disabled */
10015 { }
10016 }
10017 },
10018 [ALC662_FIXUP_USI_FUNC] = {
10019 .type = HDA_FIXUP_FUNC,
10020 .v.func = alc662_fixup_usi_headset_mic,
10021 },
10022 [ALC662_FIXUP_USI_HEADSET_MODE] = {
10023 .type = HDA_FIXUP_PINS,
10024 .v.pins = (const struct hda_pintbl[]) {
10025 { 0x19, 0x02a1913c }, /* use as headset mic, without its own jack detect */
10026 { 0x18, 0x01a1903d },
10027 { }
10028 },
10029 .chained = true,
10030 .chain_id = ALC662_FIXUP_USI_FUNC
10031 },
10032 [ALC662_FIXUP_LENOVO_MULTI_CODECS] = {
10033 .type = HDA_FIXUP_FUNC,
10034 .v.func = alc233_alc662_fixup_lenovo_dual_codecs,
10035 },
David Brazdil0f672f62019-12-10 10:32:29 +000010036 [ALC669_FIXUP_ACER_ASPIRE_ETHOS_HEADSET] = {
10037 .type = HDA_FIXUP_FUNC,
10038 .v.func = alc662_fixup_aspire_ethos_hp,
10039 },
David Brazdil0f672f62019-12-10 10:32:29 +000010040 [ALC669_FIXUP_ACER_ASPIRE_ETHOS] = {
10041 .type = HDA_FIXUP_PINS,
10042 .v.pins = (const struct hda_pintbl[]) {
10043 { 0x15, 0x92130110 }, /* front speakers */
10044 { 0x18, 0x99130111 }, /* center/subwoofer */
10045 { 0x1b, 0x11130012 }, /* surround plus jack for HP */
10046 { }
10047 },
10048 .chained = true,
Olivier Deprez0e641232021-09-23 10:07:05 +020010049 .chain_id = ALC669_FIXUP_ACER_ASPIRE_ETHOS_HEADSET
10050 },
10051 [ALC671_FIXUP_HP_HEADSET_MIC2] = {
10052 .type = HDA_FIXUP_FUNC,
10053 .v.func = alc671_fixup_hp_headset_mic2,
10054 },
10055 [ALC662_FIXUP_ACER_X2660G_HEADSET_MODE] = {
10056 .type = HDA_FIXUP_PINS,
10057 .v.pins = (const struct hda_pintbl[]) {
10058 { 0x1a, 0x02a1113c }, /* use as headset mic, without its own jack detect */
10059 { }
10060 },
10061 .chained = true,
10062 .chain_id = ALC662_FIXUP_USI_FUNC
10063 },
10064 [ALC662_FIXUP_ACER_NITRO_HEADSET_MODE] = {
10065 .type = HDA_FIXUP_PINS,
10066 .v.pins = (const struct hda_pintbl[]) {
10067 { 0x1a, 0x01a11140 }, /* use as headset mic, without its own jack detect */
10068 { 0x1b, 0x0221144f },
10069 { }
10070 },
10071 .chained = true,
10072 .chain_id = ALC662_FIXUP_USI_FUNC
David Brazdil0f672f62019-12-10 10:32:29 +000010073 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000010074};
10075
10076static const struct snd_pci_quirk alc662_fixup_tbl[] = {
10077 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_FIXUP_ASUS_MODE2),
10078 SND_PCI_QUIRK(0x1025, 0x022f, "Acer Aspire One", ALC662_FIXUP_INV_DMIC),
10079 SND_PCI_QUIRK(0x1025, 0x0241, "Packard Bell DOTS", ALC662_FIXUP_INV_DMIC),
10080 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
10081 SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
10082 SND_PCI_QUIRK(0x1025, 0x0349, "eMachines eM250", ALC662_FIXUP_INV_DMIC),
10083 SND_PCI_QUIRK(0x1025, 0x034a, "Gateway LT27", ALC662_FIXUP_INV_DMIC),
10084 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
Olivier Deprez0e641232021-09-23 10:07:05 +020010085 SND_PCI_QUIRK(0x1025, 0x0566, "Acer Aspire Ethos 8951G", ALC669_FIXUP_ACER_ASPIRE_ETHOS),
10086 SND_PCI_QUIRK(0x1025, 0x123c, "Acer Nitro N50-600", ALC662_FIXUP_ACER_NITRO_HEADSET_MODE),
10087 SND_PCI_QUIRK(0x1025, 0x124e, "Acer 2660G", ALC662_FIXUP_ACER_X2660G_HEADSET_MODE),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000010088 SND_PCI_QUIRK(0x1028, 0x05d8, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
10089 SND_PCI_QUIRK(0x1028, 0x05db, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
10090 SND_PCI_QUIRK(0x1028, 0x05fe, "Dell XPS 15", ALC668_FIXUP_DELL_XPS13),
10091 SND_PCI_QUIRK(0x1028, 0x060a, "Dell XPS 13", ALC668_FIXUP_DELL_XPS13),
10092 SND_PCI_QUIRK(0x1028, 0x060d, "Dell M3800", ALC668_FIXUP_DELL_XPS13),
10093 SND_PCI_QUIRK(0x1028, 0x0625, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
10094 SND_PCI_QUIRK(0x1028, 0x0626, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
10095 SND_PCI_QUIRK(0x1028, 0x0696, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
10096 SND_PCI_QUIRK(0x1028, 0x0698, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
10097 SND_PCI_QUIRK(0x1028, 0x069f, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
10098 SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800),
Olivier Deprez0e641232021-09-23 10:07:05 +020010099 SND_PCI_QUIRK(0x103c, 0x873e, "HP", ALC671_FIXUP_HP_HEADSET_MIC2),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000010100 SND_PCI_QUIRK(0x1043, 0x1080, "Asus UX501VW", ALC668_FIXUP_HEADSET_MODE),
10101 SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_ASUS_Nx50),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000010102 SND_PCI_QUIRK(0x1043, 0x129d, "Asus N750", ALC662_FIXUP_ASUS_Nx50),
10103 SND_PCI_QUIRK(0x1043, 0x12ff, "ASUS G751", ALC668_FIXUP_ASUS_G751),
Olivier Deprez0e641232021-09-23 10:07:05 +020010104 SND_PCI_QUIRK(0x1043, 0x13df, "Asus N550JX", ALC662_FIXUP_BASS_1A),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000010105 SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
10106 SND_PCI_QUIRK(0x1043, 0x15a7, "ASUS UX51VZH", ALC662_FIXUP_BASS_16),
10107 SND_PCI_QUIRK(0x1043, 0x177d, "ASUS N551", ALC668_FIXUP_ASUS_Nx51),
10108 SND_PCI_QUIRK(0x1043, 0x17bd, "ASUS N751", ALC668_FIXUP_ASUS_Nx51),
10109 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71SL", ALC662_FIXUP_ASUS_MODE8),
10110 SND_PCI_QUIRK(0x1043, 0x1b73, "ASUS N55SF", ALC662_FIXUP_BASS_16),
10111 SND_PCI_QUIRK(0x1043, 0x1bf3, "ASUS N76VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
10112 SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT),
10113 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2),
10114 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
10115 SND_PCI_QUIRK(0x14cd, 0x5003, "USI", ALC662_FIXUP_USI_HEADSET_MODE),
10116 SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC662_FIXUP_LENOVO_MULTI_CODECS),
10117 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
10118 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
10119 SND_PCI_QUIRK(0x1849, 0x5892, "ASRock B150M", ALC892_FIXUP_ASROCK_MOBO),
10120 SND_PCI_QUIRK(0x19da, 0xa130, "Zotac Z68", ALC662_FIXUP_ZOTAC_Z68),
10121 SND_PCI_QUIRK(0x1b0a, 0x01b8, "ACER Veriton", ALC662_FIXUP_ACER_VERITON),
Olivier Deprez0e641232021-09-23 10:07:05 +020010122 SND_PCI_QUIRK(0x1b35, 0x1234, "CZC ET26", ALC662_FIXUP_CZC_ET26),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000010123 SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
10124
10125#if 0
10126 /* Below is a quirk table taken from the old code.
10127 * Basically the device should work as is without the fixup table.
10128 * If BIOS doesn't give a proper info, enable the corresponding
10129 * fixup entry.
10130 */
10131 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC662_FIXUP_ASUS_MODE1),
10132 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC662_FIXUP_ASUS_MODE3),
10133 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC662_FIXUP_ASUS_MODE1),
10134 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC662_FIXUP_ASUS_MODE3),
10135 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
10136 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
10137 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
10138 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC662_FIXUP_ASUS_MODE1),
10139 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC662_FIXUP_ASUS_MODE1),
10140 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
10141 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC662_FIXUP_ASUS_MODE7),
10142 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC662_FIXUP_ASUS_MODE7),
10143 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC662_FIXUP_ASUS_MODE8),
10144 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC662_FIXUP_ASUS_MODE3),
10145 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC662_FIXUP_ASUS_MODE1),
10146 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
10147 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_FIXUP_ASUS_MODE2),
10148 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC662_FIXUP_ASUS_MODE1),
10149 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
10150 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
10151 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
10152 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
10153 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC662_FIXUP_ASUS_MODE1),
10154 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC662_FIXUP_ASUS_MODE3),
10155 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_FIXUP_ASUS_MODE2),
10156 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
10157 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC662_FIXUP_ASUS_MODE5),
10158 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
10159 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
10160 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC662_FIXUP_ASUS_MODE1),
10161 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
10162 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
10163 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC662_FIXUP_ASUS_MODE3),
10164 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC662_FIXUP_ASUS_MODE3),
10165 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC662_FIXUP_ASUS_MODE1),
10166 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC662_FIXUP_ASUS_MODE1),
10167 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC662_FIXUP_ASUS_MODE1),
10168 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC662_FIXUP_ASUS_MODE1),
10169 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC662_FIXUP_ASUS_MODE1),
10170 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
10171 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_FIXUP_ASUS_MODE2),
10172 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC662_FIXUP_ASUS_MODE1),
10173 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
10174 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC662_FIXUP_ASUS_MODE3),
10175 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC662_FIXUP_ASUS_MODE1),
10176 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC662_FIXUP_ASUS_MODE1),
10177 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC662_FIXUP_ASUS_MODE1),
10178 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_FIXUP_ASUS_MODE2),
10179 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
10180 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE4),
10181#endif
10182 {}
10183};
10184
10185static const struct hda_model_fixup alc662_fixup_models[] = {
10186 {.id = ALC662_FIXUP_ASPIRE, .name = "aspire"},
10187 {.id = ALC662_FIXUP_IDEAPAD, .name = "ideapad"},
10188 {.id = ALC272_FIXUP_MARIO, .name = "mario"},
10189 {.id = ALC662_FIXUP_HP_RP5800, .name = "hp-rp5800"},
10190 {.id = ALC662_FIXUP_ASUS_MODE1, .name = "asus-mode1"},
10191 {.id = ALC662_FIXUP_ASUS_MODE2, .name = "asus-mode2"},
10192 {.id = ALC662_FIXUP_ASUS_MODE3, .name = "asus-mode3"},
10193 {.id = ALC662_FIXUP_ASUS_MODE4, .name = "asus-mode4"},
10194 {.id = ALC662_FIXUP_ASUS_MODE5, .name = "asus-mode5"},
10195 {.id = ALC662_FIXUP_ASUS_MODE6, .name = "asus-mode6"},
10196 {.id = ALC662_FIXUP_ASUS_MODE7, .name = "asus-mode7"},
10197 {.id = ALC662_FIXUP_ASUS_MODE8, .name = "asus-mode8"},
10198 {.id = ALC662_FIXUP_ZOTAC_Z68, .name = "zotac-z68"},
10199 {.id = ALC662_FIXUP_INV_DMIC, .name = "inv-dmic"},
10200 {.id = ALC662_FIXUP_DELL_MIC_NO_PRESENCE, .name = "alc662-headset-multi"},
10201 {.id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE, .name = "dell-headset-multi"},
10202 {.id = ALC662_FIXUP_HEADSET_MODE, .name = "alc662-headset"},
10203 {.id = ALC668_FIXUP_HEADSET_MODE, .name = "alc668-headset"},
10204 {.id = ALC662_FIXUP_BASS_16, .name = "bass16"},
10205 {.id = ALC662_FIXUP_BASS_1A, .name = "bass1a"},
10206 {.id = ALC668_FIXUP_AUTO_MUTE, .name = "automute"},
10207 {.id = ALC668_FIXUP_DELL_XPS13, .name = "dell-xps13"},
10208 {.id = ALC662_FIXUP_ASUS_Nx50, .name = "asus-nx50"},
10209 {.id = ALC668_FIXUP_ASUS_Nx51, .name = "asus-nx51"},
David Brazdil0f672f62019-12-10 10:32:29 +000010210 {.id = ALC668_FIXUP_ASUS_G751, .name = "asus-g751"},
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000010211 {.id = ALC891_FIXUP_HEADSET_MODE, .name = "alc891-headset"},
10212 {.id = ALC891_FIXUP_DELL_MIC_NO_PRESENCE, .name = "alc891-headset-multi"},
10213 {.id = ALC662_FIXUP_ACER_VERITON, .name = "acer-veriton"},
10214 {.id = ALC892_FIXUP_ASROCK_MOBO, .name = "asrock-mobo"},
10215 {.id = ALC662_FIXUP_USI_HEADSET_MODE, .name = "usi-headset"},
10216 {.id = ALC662_FIXUP_LENOVO_MULTI_CODECS, .name = "dual-codecs"},
David Brazdil0f672f62019-12-10 10:32:29 +000010217 {.id = ALC669_FIXUP_ACER_ASPIRE_ETHOS, .name = "aspire-ethos"},
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000010218 {}
10219};
10220
10221static const struct snd_hda_pin_quirk alc662_pin_fixup_tbl[] = {
10222 SND_HDA_PIN_QUIRK(0x10ec0867, 0x1028, "Dell", ALC891_FIXUP_DELL_MIC_NO_PRESENCE,
10223 {0x17, 0x02211010},
10224 {0x18, 0x01a19030},
10225 {0x1a, 0x01813040},
10226 {0x21, 0x01014020}),
David Brazdil0f672f62019-12-10 10:32:29 +000010227 SND_HDA_PIN_QUIRK(0x10ec0867, 0x1028, "Dell", ALC891_FIXUP_DELL_MIC_NO_PRESENCE,
10228 {0x16, 0x01813030},
10229 {0x17, 0x02211010},
10230 {0x18, 0x01a19040},
10231 {0x21, 0x01014020}),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000010232 SND_HDA_PIN_QUIRK(0x10ec0662, 0x1028, "Dell", ALC662_FIXUP_DELL_MIC_NO_PRESENCE,
10233 {0x14, 0x01014010},
10234 {0x18, 0x01a19020},
10235 {0x1a, 0x0181302f},
10236 {0x1b, 0x0221401f}),
10237 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
10238 {0x12, 0x99a30130},
10239 {0x14, 0x90170110},
10240 {0x15, 0x0321101f},
10241 {0x16, 0x03011020}),
10242 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
10243 {0x12, 0x99a30140},
10244 {0x14, 0x90170110},
10245 {0x15, 0x0321101f},
10246 {0x16, 0x03011020}),
10247 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
10248 {0x12, 0x99a30150},
10249 {0x14, 0x90170110},
10250 {0x15, 0x0321101f},
10251 {0x16, 0x03011020}),
10252 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
10253 {0x14, 0x90170110},
10254 {0x15, 0x0321101f},
10255 {0x16, 0x03011020}),
10256 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell XPS 15", ALC668_FIXUP_AUTO_MUTE,
10257 {0x12, 0x90a60130},
10258 {0x14, 0x90170110},
10259 {0x15, 0x0321101f}),
Olivier Deprez0e641232021-09-23 10:07:05 +020010260 SND_HDA_PIN_QUIRK(0x10ec0671, 0x103c, "HP cPC", ALC671_FIXUP_HP_HEADSET_MIC2,
10261 {0x14, 0x01014010},
10262 {0x17, 0x90170150},
10263 {0x19, 0x02a11060},
10264 {0x1b, 0x01813030},
10265 {0x21, 0x02211020}),
10266 SND_HDA_PIN_QUIRK(0x10ec0671, 0x103c, "HP cPC", ALC671_FIXUP_HP_HEADSET_MIC2,
10267 {0x14, 0x01014010},
10268 {0x18, 0x01a19040},
10269 {0x1b, 0x01813030},
10270 {0x21, 0x02211020}),
10271 SND_HDA_PIN_QUIRK(0x10ec0671, 0x103c, "HP cPC", ALC671_FIXUP_HP_HEADSET_MIC2,
10272 {0x14, 0x01014020},
10273 {0x17, 0x90170110},
10274 {0x18, 0x01a19050},
10275 {0x1b, 0x01813040},
10276 {0x21, 0x02211030}),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000010277 {}
10278};
10279
10280/*
10281 */
10282static int patch_alc662(struct hda_codec *codec)
10283{
10284 struct alc_spec *spec;
10285 int err;
10286
10287 err = alc_alloc_spec(codec, 0x0b);
10288 if (err < 0)
10289 return err;
10290
10291 spec = codec->spec;
10292
10293 spec->shutup = alc_eapd_shutup;
10294
10295 /* handle multiple HPs as is */
10296 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
10297
10298 alc_fix_pll_init(codec, 0x20, 0x04, 15);
10299
10300 switch (codec->core.vendor_id) {
10301 case 0x10ec0668:
10302 spec->init_hook = alc668_restore_default_value;
10303 break;
10304 }
10305
David Brazdil0f672f62019-12-10 10:32:29 +000010306 alc_pre_init(codec);
10307
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000010308 snd_hda_pick_fixup(codec, alc662_fixup_models,
10309 alc662_fixup_tbl, alc662_fixups);
David Brazdil0f672f62019-12-10 10:32:29 +000010310 snd_hda_pick_pin_fixup(codec, alc662_pin_fixup_tbl, alc662_fixups, true);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000010311 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
10312
10313 alc_auto_parse_customize_define(codec);
10314
10315 if (has_cdefine_beep(codec))
10316 spec->gen.beep_nid = 0x01;
10317
10318 if ((alc_get_coef0(codec) & (1 << 14)) &&
10319 codec->bus->pci && codec->bus->pci->subsystem_vendor == 0x1025 &&
10320 spec->cdefine.platform_type == 1) {
10321 err = alc_codec_rename(codec, "ALC272X");
10322 if (err < 0)
10323 goto error;
10324 }
10325
10326 /* automatic parse from the BIOS config */
10327 err = alc662_parse_auto_config(codec);
10328 if (err < 0)
10329 goto error;
10330
10331 if (!spec->gen.no_analog && spec->gen.beep_nid) {
10332 switch (codec->core.vendor_id) {
10333 case 0x10ec0662:
10334 err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
10335 break;
10336 case 0x10ec0272:
10337 case 0x10ec0663:
10338 case 0x10ec0665:
10339 case 0x10ec0668:
10340 err = set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
10341 break;
10342 case 0x10ec0273:
10343 err = set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
10344 break;
10345 }
10346 if (err < 0)
10347 goto error;
10348 }
10349
10350 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
10351
10352 return 0;
10353
10354 error:
10355 alc_free(codec);
10356 return err;
10357}
10358
10359/*
10360 * ALC680 support
10361 */
10362
10363static int alc680_parse_auto_config(struct hda_codec *codec)
10364{
10365 return alc_parse_auto_config(codec, NULL, NULL);
10366}
10367
10368/*
10369 */
10370static int patch_alc680(struct hda_codec *codec)
10371{
10372 int err;
10373
10374 /* ALC680 has no aa-loopback mixer */
10375 err = alc_alloc_spec(codec, 0);
10376 if (err < 0)
10377 return err;
10378
10379 /* automatic parse from the BIOS config */
10380 err = alc680_parse_auto_config(codec);
10381 if (err < 0) {
10382 alc_free(codec);
10383 return err;
10384 }
10385
10386 return 0;
10387}
10388
10389/*
10390 * patch entries
10391 */
10392static const struct hda_device_id snd_hda_id_realtek[] = {
10393 HDA_CODEC_ENTRY(0x10ec0215, "ALC215", patch_alc269),
10394 HDA_CODEC_ENTRY(0x10ec0221, "ALC221", patch_alc269),
David Brazdil0f672f62019-12-10 10:32:29 +000010395 HDA_CODEC_ENTRY(0x10ec0222, "ALC222", patch_alc269),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000010396 HDA_CODEC_ENTRY(0x10ec0225, "ALC225", patch_alc269),
Olivier Deprez0e641232021-09-23 10:07:05 +020010397 HDA_CODEC_ENTRY(0x10ec0230, "ALC236", patch_alc269),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000010398 HDA_CODEC_ENTRY(0x10ec0231, "ALC231", patch_alc269),
10399 HDA_CODEC_ENTRY(0x10ec0233, "ALC233", patch_alc269),
10400 HDA_CODEC_ENTRY(0x10ec0234, "ALC234", patch_alc269),
10401 HDA_CODEC_ENTRY(0x10ec0235, "ALC233", patch_alc269),
10402 HDA_CODEC_ENTRY(0x10ec0236, "ALC236", patch_alc269),
Olivier Deprez0e641232021-09-23 10:07:05 +020010403 HDA_CODEC_ENTRY(0x10ec0245, "ALC245", patch_alc269),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000010404 HDA_CODEC_ENTRY(0x10ec0255, "ALC255", patch_alc269),
10405 HDA_CODEC_ENTRY(0x10ec0256, "ALC256", patch_alc269),
10406 HDA_CODEC_ENTRY(0x10ec0257, "ALC257", patch_alc269),
10407 HDA_CODEC_ENTRY(0x10ec0260, "ALC260", patch_alc260),
10408 HDA_CODEC_ENTRY(0x10ec0262, "ALC262", patch_alc262),
10409 HDA_CODEC_ENTRY(0x10ec0267, "ALC267", patch_alc268),
10410 HDA_CODEC_ENTRY(0x10ec0268, "ALC268", patch_alc268),
10411 HDA_CODEC_ENTRY(0x10ec0269, "ALC269", patch_alc269),
10412 HDA_CODEC_ENTRY(0x10ec0270, "ALC270", patch_alc269),
10413 HDA_CODEC_ENTRY(0x10ec0272, "ALC272", patch_alc662),
10414 HDA_CODEC_ENTRY(0x10ec0274, "ALC274", patch_alc269),
10415 HDA_CODEC_ENTRY(0x10ec0275, "ALC275", patch_alc269),
10416 HDA_CODEC_ENTRY(0x10ec0276, "ALC276", patch_alc269),
10417 HDA_CODEC_ENTRY(0x10ec0280, "ALC280", patch_alc269),
10418 HDA_CODEC_ENTRY(0x10ec0282, "ALC282", patch_alc269),
10419 HDA_CODEC_ENTRY(0x10ec0283, "ALC283", patch_alc269),
10420 HDA_CODEC_ENTRY(0x10ec0284, "ALC284", patch_alc269),
10421 HDA_CODEC_ENTRY(0x10ec0285, "ALC285", patch_alc269),
10422 HDA_CODEC_ENTRY(0x10ec0286, "ALC286", patch_alc269),
Olivier Deprez0e641232021-09-23 10:07:05 +020010423 HDA_CODEC_ENTRY(0x10ec0287, "ALC287", patch_alc269),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000010424 HDA_CODEC_ENTRY(0x10ec0288, "ALC288", patch_alc269),
10425 HDA_CODEC_ENTRY(0x10ec0289, "ALC289", patch_alc269),
10426 HDA_CODEC_ENTRY(0x10ec0290, "ALC290", patch_alc269),
10427 HDA_CODEC_ENTRY(0x10ec0292, "ALC292", patch_alc269),
10428 HDA_CODEC_ENTRY(0x10ec0293, "ALC293", patch_alc269),
10429 HDA_CODEC_ENTRY(0x10ec0294, "ALC294", patch_alc269),
10430 HDA_CODEC_ENTRY(0x10ec0295, "ALC295", patch_alc269),
10431 HDA_CODEC_ENTRY(0x10ec0298, "ALC298", patch_alc269),
10432 HDA_CODEC_ENTRY(0x10ec0299, "ALC299", patch_alc269),
10433 HDA_CODEC_ENTRY(0x10ec0300, "ALC300", patch_alc269),
David Brazdil0f672f62019-12-10 10:32:29 +000010434 HDA_CODEC_ENTRY(0x10ec0623, "ALC623", patch_alc269),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000010435 HDA_CODEC_REV_ENTRY(0x10ec0861, 0x100340, "ALC660", patch_alc861),
10436 HDA_CODEC_ENTRY(0x10ec0660, "ALC660-VD", patch_alc861vd),
10437 HDA_CODEC_ENTRY(0x10ec0861, "ALC861", patch_alc861),
10438 HDA_CODEC_ENTRY(0x10ec0862, "ALC861-VD", patch_alc861vd),
10439 HDA_CODEC_REV_ENTRY(0x10ec0662, 0x100002, "ALC662 rev2", patch_alc882),
10440 HDA_CODEC_REV_ENTRY(0x10ec0662, 0x100101, "ALC662 rev1", patch_alc662),
10441 HDA_CODEC_REV_ENTRY(0x10ec0662, 0x100300, "ALC662 rev3", patch_alc662),
10442 HDA_CODEC_ENTRY(0x10ec0663, "ALC663", patch_alc662),
10443 HDA_CODEC_ENTRY(0x10ec0665, "ALC665", patch_alc662),
10444 HDA_CODEC_ENTRY(0x10ec0667, "ALC667", patch_alc662),
10445 HDA_CODEC_ENTRY(0x10ec0668, "ALC668", patch_alc662),
10446 HDA_CODEC_ENTRY(0x10ec0670, "ALC670", patch_alc662),
10447 HDA_CODEC_ENTRY(0x10ec0671, "ALC671", patch_alc662),
10448 HDA_CODEC_ENTRY(0x10ec0680, "ALC680", patch_alc680),
10449 HDA_CODEC_ENTRY(0x10ec0700, "ALC700", patch_alc269),
10450 HDA_CODEC_ENTRY(0x10ec0701, "ALC701", patch_alc269),
10451 HDA_CODEC_ENTRY(0x10ec0703, "ALC703", patch_alc269),
David Brazdil0f672f62019-12-10 10:32:29 +000010452 HDA_CODEC_ENTRY(0x10ec0711, "ALC711", patch_alc269),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000010453 HDA_CODEC_ENTRY(0x10ec0867, "ALC891", patch_alc662),
10454 HDA_CODEC_ENTRY(0x10ec0880, "ALC880", patch_alc880),
10455 HDA_CODEC_ENTRY(0x10ec0882, "ALC882", patch_alc882),
10456 HDA_CODEC_ENTRY(0x10ec0883, "ALC883", patch_alc882),
10457 HDA_CODEC_REV_ENTRY(0x10ec0885, 0x100101, "ALC889A", patch_alc882),
10458 HDA_CODEC_REV_ENTRY(0x10ec0885, 0x100103, "ALC889A", patch_alc882),
10459 HDA_CODEC_ENTRY(0x10ec0885, "ALC885", patch_alc882),
10460 HDA_CODEC_ENTRY(0x10ec0887, "ALC887", patch_alc882),
10461 HDA_CODEC_REV_ENTRY(0x10ec0888, 0x100101, "ALC1200", patch_alc882),
10462 HDA_CODEC_ENTRY(0x10ec0888, "ALC888", patch_alc882),
10463 HDA_CODEC_ENTRY(0x10ec0889, "ALC889", patch_alc882),
10464 HDA_CODEC_ENTRY(0x10ec0892, "ALC892", patch_alc662),
Olivier Deprez0e641232021-09-23 10:07:05 +020010465 HDA_CODEC_ENTRY(0x10ec0897, "ALC897", patch_alc662),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000010466 HDA_CODEC_ENTRY(0x10ec0899, "ALC898", patch_alc882),
10467 HDA_CODEC_ENTRY(0x10ec0900, "ALC1150", patch_alc882),
Olivier Deprez0e641232021-09-23 10:07:05 +020010468 HDA_CODEC_ENTRY(0x10ec0b00, "ALCS1200A", patch_alc882),
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000010469 HDA_CODEC_ENTRY(0x10ec1168, "ALC1220", patch_alc882),
10470 HDA_CODEC_ENTRY(0x10ec1220, "ALC1220", patch_alc882),
10471 {} /* terminator */
10472};
10473MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_realtek);
10474
10475MODULE_LICENSE("GPL");
10476MODULE_DESCRIPTION("Realtek HD-audio codec");
10477
10478static struct hda_codec_driver realtek_driver = {
10479 .id = snd_hda_id_realtek,
10480};
10481
10482module_hda_codec_driver(realtek_driver);