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