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