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