Merge branches 'acpi-resources', 'acpi-battery', 'acpi-doc' and 'acpi-pnp'
[linux-2.6-block.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{
3e1b0c4a
TI
4193 struct alc_spec *spec = codec->spec;
4194 struct hda_input_mux *imux = &spec->gen.input_mux;
4195 int i;
f38663ab 4196
3e1b0c4a
TI
4197 switch (action) {
4198 case HDA_FIXUP_ACT_PRE_PROBE:
4199 /* mic pin 0x19 must be initialized with Vref Hi-Z, otherwise
4200 * it causes a click noise at start up
4201 */
4202 snd_hda_codec_set_pin_target(codec, 0x19, PIN_VREFHIZ);
4203 break;
4204 case HDA_FIXUP_ACT_PROBE:
9476d369 4205 spec->shutup = alc_shutup_dell_xps13;
f38663ab
GM
4206
4207 /* Make the internal mic the default input source. */
4208 for (i = 0; i < imux->num_items; i++) {
4209 if (spec->gen.imux_pins[i] == 0x12) {
4210 spec->gen.cur_mux[0] = i;
4211 break;
4212 }
4213 }
3e1b0c4a 4214 break;
033b0a7c
GM
4215 }
4216}
4217
73bdd597
DH
4218static void alc_fixup_headset_mode_alc668(struct hda_codec *codec,
4219 const struct hda_fixup *fix, int action)
4220{
4221 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
73bdd597 4222 alc_write_coef_idx(codec, 0xc4, 0x8000);
98b24883 4223 alc_update_coef_idx(codec, 0xc2, ~0xfe, 0);
73bdd597
DH
4224 snd_hda_set_pin_ctl_cache(codec, 0x18, 0);
4225 }
4226 alc_fixup_headset_mode(codec, fix, action);
4227}
4228
bde7bc60
CCC
4229/* Returns the nid of the external mic input pin, or 0 if it cannot be found. */
4230static int find_ext_mic_pin(struct hda_codec *codec)
4231{
4232 struct alc_spec *spec = codec->spec;
4233 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
4234 hda_nid_t nid;
4235 unsigned int defcfg;
4236 int i;
4237
4238 for (i = 0; i < cfg->num_inputs; i++) {
4239 if (cfg->inputs[i].type != AUTO_PIN_MIC)
4240 continue;
4241 nid = cfg->inputs[i].pin;
4242 defcfg = snd_hda_codec_get_pincfg(codec, nid);
4243 if (snd_hda_get_input_pin_attr(defcfg) == INPUT_PIN_ATTR_INT)
4244 continue;
4245 return nid;
4246 }
4247
4248 return 0;
4249}
4250
08a978db 4251static void alc271_hp_gate_mic_jack(struct hda_codec *codec,
1727a771 4252 const struct hda_fixup *fix,
08a978db
DR
4253 int action)
4254{
4255 struct alc_spec *spec = codec->spec;
4256
0db75790 4257 if (action == HDA_FIXUP_ACT_PROBE) {
bde7bc60
CCC
4258 int mic_pin = find_ext_mic_pin(codec);
4259 int hp_pin = spec->gen.autocfg.hp_pins[0];
4260
4261 if (snd_BUG_ON(!mic_pin || !hp_pin))
0db75790 4262 return;
bde7bc60 4263 snd_hda_jack_set_gating_jack(codec, mic_pin, hp_pin);
0db75790 4264 }
08a978db 4265}
693b613d 4266
3e0d611b
DH
4267static void alc269_fixup_limit_int_mic_boost(struct hda_codec *codec,
4268 const struct hda_fixup *fix,
4269 int action)
4270{
4271 struct alc_spec *spec = codec->spec;
4272 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
4273 int i;
4274
4275 /* The mic boosts on level 2 and 3 are too noisy
4276 on the internal mic input.
4277 Therefore limit the boost to 0 or 1. */
4278
4279 if (action != HDA_FIXUP_ACT_PROBE)
4280 return;
4281
4282 for (i = 0; i < cfg->num_inputs; i++) {
4283 hda_nid_t nid = cfg->inputs[i].pin;
4284 unsigned int defcfg;
4285 if (cfg->inputs[i].type != AUTO_PIN_MIC)
4286 continue;
4287 defcfg = snd_hda_codec_get_pincfg(codec, nid);
4288 if (snd_hda_get_input_pin_attr(defcfg) != INPUT_PIN_ATTR_INT)
4289 continue;
4290
4291 snd_hda_override_amp_caps(codec, nid, HDA_INPUT,
4292 (0x00 << AC_AMPCAP_OFFSET_SHIFT) |
4293 (0x01 << AC_AMPCAP_NUM_STEPS_SHIFT) |
4294 (0x2f << AC_AMPCAP_STEP_SIZE_SHIFT) |
4295 (0 << AC_AMPCAP_MUTE_SHIFT));
4296 }
4297}
4298
cd217a63 4299static void alc283_hp_automute_hook(struct hda_codec *codec,
1a4f69d5 4300 struct hda_jack_callback *jack)
cd217a63
KY
4301{
4302 struct alc_spec *spec = codec->spec;
4303 int vref;
4304
4305 msleep(200);
4306 snd_hda_gen_hp_automute(codec, jack);
4307
4308 vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0;
4309
4310 msleep(600);
4311 snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4312 vref);
4313}
4314
cd217a63
KY
4315static void alc283_fixup_chromebook(struct hda_codec *codec,
4316 const struct hda_fixup *fix, int action)
4317{
4318 struct alc_spec *spec = codec->spec;
cd217a63
KY
4319
4320 switch (action) {
4321 case HDA_FIXUP_ACT_PRE_PROBE:
0202e99c 4322 snd_hda_override_wcaps(codec, 0x03, 0);
d2e92709
TI
4323 /* Disable AA-loopback as it causes white noise */
4324 spec->gen.mixer_nid = 0;
38070219 4325 break;
0202e99c 4326 case HDA_FIXUP_ACT_INIT:
de9481cb
KY
4327 /* MIC2-VREF control */
4328 /* Set to manual mode */
98b24883 4329 alc_update_coef_idx(codec, 0x06, 0x000c, 0);
0202e99c 4330 /* Enable Line1 input control by verb */
98b24883 4331 alc_update_coef_idx(codec, 0x1a, 0, 1 << 4);
0202e99c
KY
4332 break;
4333 }
4334}
4335
4336static void alc283_fixup_sense_combo_jack(struct hda_codec *codec,
4337 const struct hda_fixup *fix, int action)
4338{
4339 struct alc_spec *spec = codec->spec;
0202e99c
KY
4340
4341 switch (action) {
4342 case HDA_FIXUP_ACT_PRE_PROBE:
cd217a63 4343 spec->gen.hp_automute_hook = alc283_hp_automute_hook;
38070219
KY
4344 break;
4345 case HDA_FIXUP_ACT_INIT:
cd217a63
KY
4346 /* MIC2-VREF control */
4347 /* Set to manual mode */
98b24883 4348 alc_update_coef_idx(codec, 0x06, 0x000c, 0);
cd217a63
KY
4349 break;
4350 }
4351}
4352
7bba2157
TI
4353/* mute tablet speaker pin (0x14) via dock plugging in addition */
4354static void asus_tx300_automute(struct hda_codec *codec)
4355{
4356 struct alc_spec *spec = codec->spec;
4357 snd_hda_gen_update_outputs(codec);
4358 if (snd_hda_jack_detect(codec, 0x1b))
4359 spec->gen.mute_bits |= (1ULL << 0x14);
4360}
4361
4362static void alc282_fixup_asus_tx300(struct hda_codec *codec,
4363 const struct hda_fixup *fix, int action)
4364{
4365 struct alc_spec *spec = codec->spec;
4366 /* TX300 needs to set up GPIO2 for the speaker amp */
4367 static const struct hda_verb gpio2_verbs[] = {
4368 { 0x01, AC_VERB_SET_GPIO_MASK, 0x04 },
4369 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04 },
4370 { 0x01, AC_VERB_SET_GPIO_DATA, 0x04 },
4371 {}
4372 };
4373 static const struct hda_pintbl dock_pins[] = {
4374 { 0x1b, 0x21114000 }, /* dock speaker pin */
4375 {}
4376 };
4377 struct snd_kcontrol *kctl;
4378
4379 switch (action) {
4380 case HDA_FIXUP_ACT_PRE_PROBE:
4381 snd_hda_add_verbs(codec, gpio2_verbs);
4382 snd_hda_apply_pincfgs(codec, dock_pins);
4383 spec->gen.auto_mute_via_amp = 1;
4384 spec->gen.automute_hook = asus_tx300_automute;
4385 snd_hda_jack_detect_enable_callback(codec, 0x1b,
7bba2157
TI
4386 snd_hda_gen_hp_automute);
4387 break;
4388 case HDA_FIXUP_ACT_BUILD:
4389 /* this is a bit tricky; give more sane names for the main
4390 * (tablet) speaker and the dock speaker, respectively
4391 */
4392 kctl = snd_hda_find_mixer_ctl(codec, "Speaker Playback Switch");
4393 if (kctl)
4394 strcpy(kctl->id.name, "Dock Speaker Playback Switch");
4395 kctl = snd_hda_find_mixer_ctl(codec, "Bass Speaker Playback Switch");
4396 if (kctl)
4397 strcpy(kctl->id.name, "Speaker Playback Switch");
4398 break;
4399 }
4400}
4401
338cae56
DH
4402static void alc290_fixup_mono_speakers(struct hda_codec *codec,
4403 const struct hda_fixup *fix, int action)
4404{
0f4881dc
DH
4405 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4406 /* DAC node 0x03 is giving mono output. We therefore want to
4407 make sure 0x14 (front speaker) and 0x15 (headphones) use the
4408 stereo DAC, while leaving 0x17 (bass speaker) for node 0x03. */
4409 hda_nid_t conn1[2] = { 0x0c };
4410 snd_hda_override_conn_list(codec, 0x14, 1, conn1);
4411 snd_hda_override_conn_list(codec, 0x15, 1, conn1);
4412 }
338cae56
DH
4413}
4414
b317b032
TI
4415/* for hda_fixup_thinkpad_acpi() */
4416#include "thinkpad_helper.c"
b67ae3f1 4417
00ef9940
HW
4418/* for dell wmi mic mute led */
4419#include "dell_wmi_helper.c"
4420
1d045db9
TI
4421enum {
4422 ALC269_FIXUP_SONY_VAIO,
4423 ALC275_FIXUP_SONY_VAIO_GPIO2,
4424 ALC269_FIXUP_DELL_M101Z,
4425 ALC269_FIXUP_SKU_IGNORE,
4426 ALC269_FIXUP_ASUS_G73JW,
4427 ALC269_FIXUP_LENOVO_EAPD,
4428 ALC275_FIXUP_SONY_HWEQ,
e9bd7d5c 4429 ALC275_FIXUP_SONY_DISABLE_AAMIX,
1d045db9 4430 ALC271_FIXUP_DMIC,
017f2a10 4431 ALC269_FIXUP_PCM_44K,
adabb3ec 4432 ALC269_FIXUP_STEREO_DMIC,
7c478f03 4433 ALC269_FIXUP_HEADSET_MIC,
24519911
TI
4434 ALC269_FIXUP_QUANTA_MUTE,
4435 ALC269_FIXUP_LIFEBOOK,
2041d564 4436 ALC269_FIXUP_LIFEBOOK_EXTMIC,
cc7016ab 4437 ALC269_FIXUP_LIFEBOOK_HP_PIN,
a4297b5d
TI
4438 ALC269_FIXUP_AMIC,
4439 ALC269_FIXUP_DMIC,
4440 ALC269VB_FIXUP_AMIC,
4441 ALC269VB_FIXUP_DMIC,
08fb0d0e 4442 ALC269_FIXUP_HP_MUTE_LED,
d06ac143 4443 ALC269_FIXUP_HP_MUTE_LED_MIC1,
08fb0d0e 4444 ALC269_FIXUP_HP_MUTE_LED_MIC2,
9f5c6faf 4445 ALC269_FIXUP_HP_GPIO_LED,
9c5dc3bf
KY
4446 ALC269_FIXUP_HP_GPIO_MIC1_LED,
4447 ALC269_FIXUP_HP_LINE1_MIC1_LED,
693b613d 4448 ALC269_FIXUP_INV_DMIC,
108cc108 4449 ALC269_FIXUP_LENOVO_DOCK,
9b745ab8 4450 ALC269_FIXUP_NO_SHUTUP,
88cfcf86 4451 ALC286_FIXUP_SONY_MIC_NO_PRESENCE,
108cc108 4452 ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT,
73bdd597
DH
4453 ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
4454 ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
338cae56 4455 ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
73bdd597
DH
4456 ALC269_FIXUP_HEADSET_MODE,
4457 ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC,
d240d1dc
DH
4458 ALC269_FIXUP_ASUS_X101_FUNC,
4459 ALC269_FIXUP_ASUS_X101_VERB,
4460 ALC269_FIXUP_ASUS_X101,
08a978db
DR
4461 ALC271_FIXUP_AMIC_MIC2,
4462 ALC271_FIXUP_HP_GATE_MIC_JACK,
b1e8972e 4463 ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572,
42397004 4464 ALC269_FIXUP_ACER_AC700,
3e0d611b 4465 ALC269_FIXUP_LIMIT_INT_MIC_BOOST,
2cede303 4466 ALC269VB_FIXUP_ASUS_ZENBOOK,
23870831 4467 ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A,
8e35cd4a 4468 ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED,
02b504d9 4469 ALC269VB_FIXUP_ORDISSIMO_EVE2,
cd217a63 4470 ALC283_FIXUP_CHROME_BOOK,
0202e99c 4471 ALC283_FIXUP_SENSE_COMBO_JACK,
7bba2157 4472 ALC282_FIXUP_ASUS_TX300,
1bb3e062 4473 ALC283_FIXUP_INT_MIC,
338cae56 4474 ALC290_FIXUP_MONO_SPEAKERS,
0f4881dc
DH
4475 ALC290_FIXUP_MONO_SPEAKERS_HSJACK,
4476 ALC290_FIXUP_SUBWOOFER,
4477 ALC290_FIXUP_SUBWOOFER_HSJACK,
b67ae3f1 4478 ALC269_FIXUP_THINKPAD_ACPI,
9a22a8f5 4479 ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
31278997 4480 ALC255_FIXUP_DELL2_MIC_NO_PRESENCE,
9a22a8f5 4481 ALC255_FIXUP_HEADSET_MODE,
31278997 4482 ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC,
a22aa26f 4483 ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
1c37c223 4484 ALC292_FIXUP_TPT440_DOCK,
9dc12862 4485 ALC283_FIXUP_BXBT2807_MIC,
00ef9940 4486 ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED,
1a22e775 4487 ALC282_FIXUP_ASPIRE_V5_PINS,
7a5255f1 4488 ALC280_FIXUP_HP_GPIO4,
eaa8e5ef 4489 ALC286_FIXUP_HP_GPIO_LED,
33f4acd3 4490 ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY,
b4b33f9d 4491 ALC280_FIXUP_HP_DOCK_PINS,
e1e62b98
KY
4492 ALC288_FIXUP_DELL_HEADSET_MODE,
4493 ALC288_FIXUP_DELL1_MIC_NO_PRESENCE,
4494 ALC288_FIXUP_DELL_XPS_13_GPIO6,
f1d4e28b
KY
4495};
4496
1727a771 4497static const struct hda_fixup alc269_fixups[] = {
1d045db9 4498 [ALC269_FIXUP_SONY_VAIO] = {
fd108215
TI
4499 .type = HDA_FIXUP_PINCTLS,
4500 .v.pins = (const struct hda_pintbl[]) {
4501 {0x19, PIN_VREFGRD},
1d045db9
TI
4502 {}
4503 }
f1d4e28b 4504 },
1d045db9 4505 [ALC275_FIXUP_SONY_VAIO_GPIO2] = {
1727a771 4506 .type = HDA_FIXUP_VERBS,
1d045db9
TI
4507 .v.verbs = (const struct hda_verb[]) {
4508 {0x01, AC_VERB_SET_GPIO_MASK, 0x04},
4509 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04},
4510 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4511 { }
4512 },
4513 .chained = true,
4514 .chain_id = ALC269_FIXUP_SONY_VAIO
4515 },
4516 [ALC269_FIXUP_DELL_M101Z] = {
1727a771 4517 .type = HDA_FIXUP_VERBS,
1d045db9
TI
4518 .v.verbs = (const struct hda_verb[]) {
4519 /* Enables internal speaker */
4520 {0x20, AC_VERB_SET_COEF_INDEX, 13},
4521 {0x20, AC_VERB_SET_PROC_COEF, 0x4040},
4522 {}
4523 }
4524 },
4525 [ALC269_FIXUP_SKU_IGNORE] = {
1727a771 4526 .type = HDA_FIXUP_FUNC,
23d30f28 4527 .v.func = alc_fixup_sku_ignore,
1d045db9
TI
4528 },
4529 [ALC269_FIXUP_ASUS_G73JW] = {
1727a771
TI
4530 .type = HDA_FIXUP_PINS,
4531 .v.pins = (const struct hda_pintbl[]) {
1d045db9
TI
4532 { 0x17, 0x99130111 }, /* subwoofer */
4533 { }
4534 }
4535 },
4536 [ALC269_FIXUP_LENOVO_EAPD] = {
1727a771 4537 .type = HDA_FIXUP_VERBS,
1d045db9
TI
4538 .v.verbs = (const struct hda_verb[]) {
4539 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
4540 {}
4541 }
4542 },
4543 [ALC275_FIXUP_SONY_HWEQ] = {
1727a771 4544 .type = HDA_FIXUP_FUNC,
1d045db9
TI
4545 .v.func = alc269_fixup_hweq,
4546 .chained = true,
4547 .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2
4548 },
e9bd7d5c
TI
4549 [ALC275_FIXUP_SONY_DISABLE_AAMIX] = {
4550 .type = HDA_FIXUP_FUNC,
4551 .v.func = alc_fixup_disable_aamix,
4552 .chained = true,
4553 .chain_id = ALC269_FIXUP_SONY_VAIO
4554 },
1d045db9 4555 [ALC271_FIXUP_DMIC] = {
1727a771 4556 .type = HDA_FIXUP_FUNC,
1d045db9 4557 .v.func = alc271_fixup_dmic,
f1d4e28b 4558 },
017f2a10 4559 [ALC269_FIXUP_PCM_44K] = {
1727a771 4560 .type = HDA_FIXUP_FUNC,
017f2a10 4561 .v.func = alc269_fixup_pcm_44k,
012e7eb1
DH
4562 .chained = true,
4563 .chain_id = ALC269_FIXUP_QUANTA_MUTE
017f2a10 4564 },
adabb3ec 4565 [ALC269_FIXUP_STEREO_DMIC] = {
1727a771 4566 .type = HDA_FIXUP_FUNC,
adabb3ec
TI
4567 .v.func = alc269_fixup_stereo_dmic,
4568 },
7c478f03
DH
4569 [ALC269_FIXUP_HEADSET_MIC] = {
4570 .type = HDA_FIXUP_FUNC,
4571 .v.func = alc269_fixup_headset_mic,
4572 },
24519911 4573 [ALC269_FIXUP_QUANTA_MUTE] = {
1727a771 4574 .type = HDA_FIXUP_FUNC,
24519911
TI
4575 .v.func = alc269_fixup_quanta_mute,
4576 },
4577 [ALC269_FIXUP_LIFEBOOK] = {
1727a771
TI
4578 .type = HDA_FIXUP_PINS,
4579 .v.pins = (const struct hda_pintbl[]) {
24519911
TI
4580 { 0x1a, 0x2101103f }, /* dock line-out */
4581 { 0x1b, 0x23a11040 }, /* dock mic-in */
4582 { }
4583 },
4584 .chained = true,
4585 .chain_id = ALC269_FIXUP_QUANTA_MUTE
4586 },
2041d564
DH
4587 [ALC269_FIXUP_LIFEBOOK_EXTMIC] = {
4588 .type = HDA_FIXUP_PINS,
4589 .v.pins = (const struct hda_pintbl[]) {
4590 { 0x19, 0x01a1903c }, /* headset mic, with jack detect */
4591 { }
4592 },
4593 },
cc7016ab
TI
4594 [ALC269_FIXUP_LIFEBOOK_HP_PIN] = {
4595 .type = HDA_FIXUP_PINS,
4596 .v.pins = (const struct hda_pintbl[]) {
4597 { 0x21, 0x0221102f }, /* HP out */
4598 { }
4599 },
4600 },
a4297b5d 4601 [ALC269_FIXUP_AMIC] = {
1727a771
TI
4602 .type = HDA_FIXUP_PINS,
4603 .v.pins = (const struct hda_pintbl[]) {
a4297b5d
TI
4604 { 0x14, 0x99130110 }, /* speaker */
4605 { 0x15, 0x0121401f }, /* HP out */
4606 { 0x18, 0x01a19c20 }, /* mic */
4607 { 0x19, 0x99a3092f }, /* int-mic */
4608 { }
4609 },
4610 },
4611 [ALC269_FIXUP_DMIC] = {
1727a771
TI
4612 .type = HDA_FIXUP_PINS,
4613 .v.pins = (const struct hda_pintbl[]) {
a4297b5d
TI
4614 { 0x12, 0x99a3092f }, /* int-mic */
4615 { 0x14, 0x99130110 }, /* speaker */
4616 { 0x15, 0x0121401f }, /* HP out */
4617 { 0x18, 0x01a19c20 }, /* mic */
4618 { }
4619 },
4620 },
4621 [ALC269VB_FIXUP_AMIC] = {
1727a771
TI
4622 .type = HDA_FIXUP_PINS,
4623 .v.pins = (const struct hda_pintbl[]) {
a4297b5d
TI
4624 { 0x14, 0x99130110 }, /* speaker */
4625 { 0x18, 0x01a19c20 }, /* mic */
4626 { 0x19, 0x99a3092f }, /* int-mic */
4627 { 0x21, 0x0121401f }, /* HP out */
4628 { }
4629 },
4630 },
2267ea97 4631 [ALC269VB_FIXUP_DMIC] = {
1727a771
TI
4632 .type = HDA_FIXUP_PINS,
4633 .v.pins = (const struct hda_pintbl[]) {
a4297b5d
TI
4634 { 0x12, 0x99a3092f }, /* int-mic */
4635 { 0x14, 0x99130110 }, /* speaker */
4636 { 0x18, 0x01a19c20 }, /* mic */
4637 { 0x21, 0x0121401f }, /* HP out */
4638 { }
4639 },
4640 },
08fb0d0e 4641 [ALC269_FIXUP_HP_MUTE_LED] = {
1727a771 4642 .type = HDA_FIXUP_FUNC,
08fb0d0e 4643 .v.func = alc269_fixup_hp_mute_led,
6d3cd5d4 4644 },
d06ac143
DH
4645 [ALC269_FIXUP_HP_MUTE_LED_MIC1] = {
4646 .type = HDA_FIXUP_FUNC,
4647 .v.func = alc269_fixup_hp_mute_led_mic1,
4648 },
08fb0d0e 4649 [ALC269_FIXUP_HP_MUTE_LED_MIC2] = {
1727a771 4650 .type = HDA_FIXUP_FUNC,
08fb0d0e 4651 .v.func = alc269_fixup_hp_mute_led_mic2,
420b0feb 4652 },
9f5c6faf
TI
4653 [ALC269_FIXUP_HP_GPIO_LED] = {
4654 .type = HDA_FIXUP_FUNC,
4655 .v.func = alc269_fixup_hp_gpio_led,
4656 },
9c5dc3bf
KY
4657 [ALC269_FIXUP_HP_GPIO_MIC1_LED] = {
4658 .type = HDA_FIXUP_FUNC,
4659 .v.func = alc269_fixup_hp_gpio_mic1_led,
4660 },
4661 [ALC269_FIXUP_HP_LINE1_MIC1_LED] = {
4662 .type = HDA_FIXUP_FUNC,
4663 .v.func = alc269_fixup_hp_line1_mic1_led,
4664 },
693b613d 4665 [ALC269_FIXUP_INV_DMIC] = {
1727a771 4666 .type = HDA_FIXUP_FUNC,
9d36a7dc 4667 .v.func = alc_fixup_inv_dmic,
693b613d 4668 },
9b745ab8
TI
4669 [ALC269_FIXUP_NO_SHUTUP] = {
4670 .type = HDA_FIXUP_FUNC,
4671 .v.func = alc_fixup_no_shutup,
4672 },
108cc108 4673 [ALC269_FIXUP_LENOVO_DOCK] = {
1727a771
TI
4674 .type = HDA_FIXUP_PINS,
4675 .v.pins = (const struct hda_pintbl[]) {
108cc108
DH
4676 { 0x19, 0x23a11040 }, /* dock mic */
4677 { 0x1b, 0x2121103f }, /* dock headphone */
4678 { }
4679 },
4680 .chained = true,
4681 .chain_id = ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT
4682 },
4683 [ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT] = {
1727a771 4684 .type = HDA_FIXUP_FUNC,
108cc108 4685 .v.func = alc269_fixup_pincfg_no_hp_to_lineout,
52129000
DH
4686 .chained = true,
4687 .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
108cc108 4688 },
73bdd597
DH
4689 [ALC269_FIXUP_DELL1_MIC_NO_PRESENCE] = {
4690 .type = HDA_FIXUP_PINS,
4691 .v.pins = (const struct hda_pintbl[]) {
4692 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
4693 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
4694 { }
4695 },
4696 .chained = true,
4697 .chain_id = ALC269_FIXUP_HEADSET_MODE
4698 },
4699 [ALC269_FIXUP_DELL2_MIC_NO_PRESENCE] = {
4700 .type = HDA_FIXUP_PINS,
4701 .v.pins = (const struct hda_pintbl[]) {
4702 { 0x16, 0x21014020 }, /* dock line out */
4703 { 0x19, 0x21a19030 }, /* dock mic */
4704 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
4705 { }
4706 },
4707 .chained = true,
4708 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
4709 },
338cae56
DH
4710 [ALC269_FIXUP_DELL3_MIC_NO_PRESENCE] = {
4711 .type = HDA_FIXUP_PINS,
4712 .v.pins = (const struct hda_pintbl[]) {
4713 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
4714 { }
4715 },
4716 .chained = true,
4717 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
4718 },
73bdd597
DH
4719 [ALC269_FIXUP_HEADSET_MODE] = {
4720 .type = HDA_FIXUP_FUNC,
4721 .v.func = alc_fixup_headset_mode,
6676f308
HW
4722 .chained = true,
4723 .chain_id = ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED
73bdd597
DH
4724 },
4725 [ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC] = {
4726 .type = HDA_FIXUP_FUNC,
4727 .v.func = alc_fixup_headset_mode_no_hp_mic,
4728 },
88cfcf86
DH
4729 [ALC286_FIXUP_SONY_MIC_NO_PRESENCE] = {
4730 .type = HDA_FIXUP_PINS,
4731 .v.pins = (const struct hda_pintbl[]) {
4732 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
4733 { }
4734 },
fbc78ad6
DH
4735 .chained = true,
4736 .chain_id = ALC269_FIXUP_HEADSET_MIC
88cfcf86 4737 },
d240d1dc
DH
4738 [ALC269_FIXUP_ASUS_X101_FUNC] = {
4739 .type = HDA_FIXUP_FUNC,
4740 .v.func = alc269_fixup_x101_headset_mic,
4741 },
4742 [ALC269_FIXUP_ASUS_X101_VERB] = {
4743 .type = HDA_FIXUP_VERBS,
4744 .v.verbs = (const struct hda_verb[]) {
4745 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4746 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
4747 {0x20, AC_VERB_SET_PROC_COEF, 0x0310},
4748 { }
4749 },
4750 .chained = true,
4751 .chain_id = ALC269_FIXUP_ASUS_X101_FUNC
4752 },
4753 [ALC269_FIXUP_ASUS_X101] = {
4754 .type = HDA_FIXUP_PINS,
4755 .v.pins = (const struct hda_pintbl[]) {
4756 { 0x18, 0x04a1182c }, /* Headset mic */
4757 { }
4758 },
4759 .chained = true,
4760 .chain_id = ALC269_FIXUP_ASUS_X101_VERB
4761 },
08a978db 4762 [ALC271_FIXUP_AMIC_MIC2] = {
1727a771
TI
4763 .type = HDA_FIXUP_PINS,
4764 .v.pins = (const struct hda_pintbl[]) {
08a978db
DR
4765 { 0x14, 0x99130110 }, /* speaker */
4766 { 0x19, 0x01a19c20 }, /* mic */
4767 { 0x1b, 0x99a7012f }, /* int-mic */
4768 { 0x21, 0x0121401f }, /* HP out */
4769 { }
4770 },
4771 },
4772 [ALC271_FIXUP_HP_GATE_MIC_JACK] = {
1727a771 4773 .type = HDA_FIXUP_FUNC,
08a978db
DR
4774 .v.func = alc271_hp_gate_mic_jack,
4775 .chained = true,
4776 .chain_id = ALC271_FIXUP_AMIC_MIC2,
4777 },
b1e8972e
OR
4778 [ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572] = {
4779 .type = HDA_FIXUP_FUNC,
4780 .v.func = alc269_fixup_limit_int_mic_boost,
4781 .chained = true,
4782 .chain_id = ALC271_FIXUP_HP_GATE_MIC_JACK,
4783 },
42397004
DR
4784 [ALC269_FIXUP_ACER_AC700] = {
4785 .type = HDA_FIXUP_PINS,
4786 .v.pins = (const struct hda_pintbl[]) {
4787 { 0x12, 0x99a3092f }, /* int-mic */
4788 { 0x14, 0x99130110 }, /* speaker */
4789 { 0x18, 0x03a11c20 }, /* mic */
4790 { 0x1e, 0x0346101e }, /* SPDIF1 */
4791 { 0x21, 0x0321101f }, /* HP out */
4792 { }
4793 },
4794 .chained = true,
4795 .chain_id = ALC271_FIXUP_DMIC,
4796 },
3e0d611b
DH
4797 [ALC269_FIXUP_LIMIT_INT_MIC_BOOST] = {
4798 .type = HDA_FIXUP_FUNC,
4799 .v.func = alc269_fixup_limit_int_mic_boost,
2793769f
DH
4800 .chained = true,
4801 .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
3e0d611b 4802 },
2cede303
OR
4803 [ALC269VB_FIXUP_ASUS_ZENBOOK] = {
4804 .type = HDA_FIXUP_FUNC,
4805 .v.func = alc269_fixup_limit_int_mic_boost,
4806 .chained = true,
4807 .chain_id = ALC269VB_FIXUP_DMIC,
4808 },
23870831
TI
4809 [ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A] = {
4810 .type = HDA_FIXUP_VERBS,
4811 .v.verbs = (const struct hda_verb[]) {
4812 /* class-D output amp +5dB */
4813 { 0x20, AC_VERB_SET_COEF_INDEX, 0x12 },
4814 { 0x20, AC_VERB_SET_PROC_COEF, 0x2800 },
4815 {}
4816 },
4817 .chained = true,
4818 .chain_id = ALC269VB_FIXUP_ASUS_ZENBOOK,
4819 },
8e35cd4a
DH
4820 [ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED] = {
4821 .type = HDA_FIXUP_FUNC,
4822 .v.func = alc269_fixup_limit_int_mic_boost,
4823 .chained = true,
4824 .chain_id = ALC269_FIXUP_HP_MUTE_LED_MIC1,
4825 },
02b504d9
AA
4826 [ALC269VB_FIXUP_ORDISSIMO_EVE2] = {
4827 .type = HDA_FIXUP_PINS,
4828 .v.pins = (const struct hda_pintbl[]) {
4829 { 0x12, 0x99a3092f }, /* int-mic */
4830 { 0x18, 0x03a11d20 }, /* mic */
4831 { 0x19, 0x411111f0 }, /* Unused bogus pin */
4832 { }
4833 },
4834 },
cd217a63
KY
4835 [ALC283_FIXUP_CHROME_BOOK] = {
4836 .type = HDA_FIXUP_FUNC,
4837 .v.func = alc283_fixup_chromebook,
4838 },
0202e99c
KY
4839 [ALC283_FIXUP_SENSE_COMBO_JACK] = {
4840 .type = HDA_FIXUP_FUNC,
4841 .v.func = alc283_fixup_sense_combo_jack,
4842 .chained = true,
4843 .chain_id = ALC283_FIXUP_CHROME_BOOK,
4844 },
7bba2157
TI
4845 [ALC282_FIXUP_ASUS_TX300] = {
4846 .type = HDA_FIXUP_FUNC,
4847 .v.func = alc282_fixup_asus_tx300,
4848 },
1bb3e062
KY
4849 [ALC283_FIXUP_INT_MIC] = {
4850 .type = HDA_FIXUP_VERBS,
4851 .v.verbs = (const struct hda_verb[]) {
4852 {0x20, AC_VERB_SET_COEF_INDEX, 0x1a},
4853 {0x20, AC_VERB_SET_PROC_COEF, 0x0011},
4854 { }
4855 },
4856 .chained = true,
4857 .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST
4858 },
0f4881dc
DH
4859 [ALC290_FIXUP_SUBWOOFER_HSJACK] = {
4860 .type = HDA_FIXUP_PINS,
4861 .v.pins = (const struct hda_pintbl[]) {
4862 { 0x17, 0x90170112 }, /* subwoofer */
4863 { }
4864 },
4865 .chained = true,
4866 .chain_id = ALC290_FIXUP_MONO_SPEAKERS_HSJACK,
4867 },
4868 [ALC290_FIXUP_SUBWOOFER] = {
4869 .type = HDA_FIXUP_PINS,
4870 .v.pins = (const struct hda_pintbl[]) {
4871 { 0x17, 0x90170112 }, /* subwoofer */
4872 { }
4873 },
4874 .chained = true,
4875 .chain_id = ALC290_FIXUP_MONO_SPEAKERS,
4876 },
338cae56
DH
4877 [ALC290_FIXUP_MONO_SPEAKERS] = {
4878 .type = HDA_FIXUP_FUNC,
4879 .v.func = alc290_fixup_mono_speakers,
0f4881dc
DH
4880 },
4881 [ALC290_FIXUP_MONO_SPEAKERS_HSJACK] = {
4882 .type = HDA_FIXUP_FUNC,
4883 .v.func = alc290_fixup_mono_speakers,
338cae56
DH
4884 .chained = true,
4885 .chain_id = ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
4886 },
b67ae3f1
DH
4887 [ALC269_FIXUP_THINKPAD_ACPI] = {
4888 .type = HDA_FIXUP_FUNC,
b317b032 4889 .v.func = hda_fixup_thinkpad_acpi,
b67ae3f1 4890 },
9a22a8f5
KY
4891 [ALC255_FIXUP_DELL1_MIC_NO_PRESENCE] = {
4892 .type = HDA_FIXUP_PINS,
4893 .v.pins = (const struct hda_pintbl[]) {
4894 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
4895 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
4896 { }
4897 },
4898 .chained = true,
4899 .chain_id = ALC255_FIXUP_HEADSET_MODE
4900 },
31278997
KY
4901 [ALC255_FIXUP_DELL2_MIC_NO_PRESENCE] = {
4902 .type = HDA_FIXUP_PINS,
4903 .v.pins = (const struct hda_pintbl[]) {
4904 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
4905 { }
4906 },
4907 .chained = true,
4908 .chain_id = ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC
4909 },
9a22a8f5
KY
4910 [ALC255_FIXUP_HEADSET_MODE] = {
4911 .type = HDA_FIXUP_FUNC,
4912 .v.func = alc_fixup_headset_mode_alc255,
4a83d42a
HW
4913 .chained = true,
4914 .chain_id = ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED
9a22a8f5 4915 },
31278997
KY
4916 [ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC] = {
4917 .type = HDA_FIXUP_FUNC,
4918 .v.func = alc_fixup_headset_mode_alc255_no_hp_mic,
4919 },
a22aa26f
KY
4920 [ALC293_FIXUP_DELL1_MIC_NO_PRESENCE] = {
4921 .type = HDA_FIXUP_PINS,
4922 .v.pins = (const struct hda_pintbl[]) {
4923 { 0x18, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
4924 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
4925 { }
4926 },
4927 .chained = true,
4928 .chain_id = ALC269_FIXUP_HEADSET_MODE
4929 },
1c37c223
TI
4930 [ALC292_FIXUP_TPT440_DOCK] = {
4931 .type = HDA_FIXUP_PINS,
4932 .v.pins = (const struct hda_pintbl[]) {
4933 { 0x16, 0x21211010 }, /* dock headphone */
4934 { 0x19, 0x21a11010 }, /* dock mic */
4935 { }
4936 },
4937 .chained = true,
4938 .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST
4939 },
9dc12862
DD
4940 [ALC283_FIXUP_BXBT2807_MIC] = {
4941 .type = HDA_FIXUP_PINS,
4942 .v.pins = (const struct hda_pintbl[]) {
4943 { 0x19, 0x04a110f0 },
4944 { },
4945 },
4946 },
00ef9940
HW
4947 [ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED] = {
4948 .type = HDA_FIXUP_FUNC,
4949 .v.func = alc_fixup_dell_wmi,
00ef9940 4950 },
1a22e775
TI
4951 [ALC282_FIXUP_ASPIRE_V5_PINS] = {
4952 .type = HDA_FIXUP_PINS,
4953 .v.pins = (const struct hda_pintbl[]) {
4954 { 0x12, 0x90a60130 },
4955 { 0x14, 0x90170110 },
4956 { 0x17, 0x40000008 },
4957 { 0x18, 0x411111f0 },
4958 { 0x19, 0x411111f0 },
4959 { 0x1a, 0x411111f0 },
4960 { 0x1b, 0x411111f0 },
4961 { 0x1d, 0x40f89b2d },
4962 { 0x1e, 0x411111f0 },
4963 { 0x21, 0x0321101f },
4964 { },
4965 },
4966 },
7a5255f1
DH
4967 [ALC280_FIXUP_HP_GPIO4] = {
4968 .type = HDA_FIXUP_FUNC,
4969 .v.func = alc280_fixup_hp_gpio4,
4970 },
eaa8e5ef
KY
4971 [ALC286_FIXUP_HP_GPIO_LED] = {
4972 .type = HDA_FIXUP_FUNC,
4973 .v.func = alc286_fixup_hp_gpio_led,
4974 },
33f4acd3
DH
4975 [ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY] = {
4976 .type = HDA_FIXUP_FUNC,
4977 .v.func = alc280_fixup_hp_gpio2_mic_hotkey,
4978 },
b4b33f9d
TC
4979 [ALC280_FIXUP_HP_DOCK_PINS] = {
4980 .type = HDA_FIXUP_PINS,
4981 .v.pins = (const struct hda_pintbl[]) {
4982 { 0x1b, 0x21011020 }, /* line-out */
4983 { 0x1a, 0x01a1903c }, /* headset mic */
4984 { 0x18, 0x2181103f }, /* line-in */
4985 { },
4986 },
4987 .chained = true,
4988 .chain_id = ALC280_FIXUP_HP_GPIO4
4989 },
e1e62b98
KY
4990 [ALC288_FIXUP_DELL_HEADSET_MODE] = {
4991 .type = HDA_FIXUP_FUNC,
4992 .v.func = alc_fixup_headset_mode_dell_alc288,
4993 .chained = true,
4994 .chain_id = ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED
4995 },
4996 [ALC288_FIXUP_DELL1_MIC_NO_PRESENCE] = {
4997 .type = HDA_FIXUP_PINS,
4998 .v.pins = (const struct hda_pintbl[]) {
4999 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5000 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
5001 { }
5002 },
5003 .chained = true,
5004 .chain_id = ALC288_FIXUP_DELL_HEADSET_MODE
5005 },
5006 [ALC288_FIXUP_DELL_XPS_13_GPIO6] = {
5007 .type = HDA_FIXUP_VERBS,
5008 .v.verbs = (const struct hda_verb[]) {
5009 {0x01, AC_VERB_SET_GPIO_MASK, 0x40},
5010 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x40},
5011 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5012 { }
5013 },
5014 .chained = true,
5015 .chain_id = ALC288_FIXUP_DELL1_MIC_NO_PRESENCE
5016 },
f1d4e28b
KY
5017};
5018
1d045db9 5019static const struct snd_pci_quirk alc269_fixup_tbl[] = {
a6b92b66 5020 SND_PCI_QUIRK(0x1025, 0x0283, "Acer TravelMate 8371", ALC269_FIXUP_INV_DMIC),
693b613d
DH
5021 SND_PCI_QUIRK(0x1025, 0x029b, "Acer 1810TZ", ALC269_FIXUP_INV_DMIC),
5022 SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC),
aaedfb47
DH
5023 SND_PCI_QUIRK(0x1025, 0x047c, "Acer AC700", ALC269_FIXUP_ACER_AC700),
5024 SND_PCI_QUIRK(0x1025, 0x0740, "Acer AO725", ALC271_FIXUP_HP_GATE_MIC_JACK),
5025 SND_PCI_QUIRK(0x1025, 0x0742, "Acer AO756", ALC271_FIXUP_HP_GATE_MIC_JACK),
b1e8972e 5026 SND_PCI_QUIRK(0x1025, 0x0775, "Acer Aspire E1-572", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572),
1a22e775 5027 SND_PCI_QUIRK(0x1025, 0x079b, "Acer Aspire V5-573G", ALC282_FIXUP_ASPIRE_V5_PINS),
aaedfb47 5028 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
0f4881dc 5029 SND_PCI_QUIRK(0x1028, 0x05da, "Dell Vostro 5460", ALC290_FIXUP_SUBWOOFER),
73bdd597
DH
5030 SND_PCI_QUIRK(0x1028, 0x05f4, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
5031 SND_PCI_QUIRK(0x1028, 0x05f5, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
5032 SND_PCI_QUIRK(0x1028, 0x05f6, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
0f4881dc
DH
5033 SND_PCI_QUIRK(0x1028, 0x0615, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK),
5034 SND_PCI_QUIRK(0x1028, 0x0616, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK),
0f4881dc 5035 SND_PCI_QUIRK(0x1028, 0x0638, "Dell Inspiron 5439", ALC290_FIXUP_MONO_SPEAKERS_HSJACK),
a22aa26f
KY
5036 SND_PCI_QUIRK(0x1028, 0x064a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
5037 SND_PCI_QUIRK(0x1028, 0x064b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
8b72415d 5038 SND_PCI_QUIRK(0x1028, 0x06c7, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
b734304f
KY
5039 SND_PCI_QUIRK(0x1028, 0x06d9, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
5040 SND_PCI_QUIRK(0x1028, 0x06da, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
a22aa26f
KY
5041 SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
5042 SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
08fb0d0e 5043 SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
9f5c6faf 5044 SND_PCI_QUIRK(0x103c, 0x18e6, "HP", ALC269_FIXUP_HP_GPIO_LED),
8e35cd4a 5045 SND_PCI_QUIRK(0x103c, 0x218b, "HP", ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED),
33f4acd3 5046 SND_PCI_QUIRK(0x103c, 0x225f, "HP", ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY),
c60666bd 5047 /* ALC282 */
7976eb49 5048 SND_PCI_QUIRK(0x103c, 0x21f9, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
8a02b164 5049 SND_PCI_QUIRK(0x103c, 0x2210, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
8a02b164 5050 SND_PCI_QUIRK(0x103c, 0x2214, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
9c5dc3bf
KY
5051 SND_PCI_QUIRK(0x103c, 0x2236, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
5052 SND_PCI_QUIRK(0x103c, 0x2237, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
5053 SND_PCI_QUIRK(0x103c, 0x2238, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
5054 SND_PCI_QUIRK(0x103c, 0x2239, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
9c5dc3bf 5055 SND_PCI_QUIRK(0x103c, 0x224b, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
c60666bd 5056 SND_PCI_QUIRK(0x103c, 0x2268, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
c60666bd
KY
5057 SND_PCI_QUIRK(0x103c, 0x226a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5058 SND_PCI_QUIRK(0x103c, 0x226b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
8a02b164 5059 SND_PCI_QUIRK(0x103c, 0x226e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
eaa8e5ef 5060 SND_PCI_QUIRK(0x103c, 0x2271, "HP", ALC286_FIXUP_HP_GPIO_LED),
b4b33f9d 5061 SND_PCI_QUIRK(0x103c, 0x2272, "HP", ALC280_FIXUP_HP_DOCK_PINS),
3271cb22 5062 SND_PCI_QUIRK(0x103c, 0x2273, "HP", ALC280_FIXUP_HP_DOCK_PINS),
c60666bd 5063 SND_PCI_QUIRK(0x103c, 0x229e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
c60666bd
KY
5064 SND_PCI_QUIRK(0x103c, 0x22b2, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5065 SND_PCI_QUIRK(0x103c, 0x22b7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5066 SND_PCI_QUIRK(0x103c, 0x22bf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
c60666bd 5067 SND_PCI_QUIRK(0x103c, 0x22cf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
9c5dc3bf
KY
5068 SND_PCI_QUIRK(0x103c, 0x22dc, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5069 SND_PCI_QUIRK(0x103c, 0x22fb, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
c60666bd 5070 /* ALC290 */
9c5dc3bf 5071 SND_PCI_QUIRK(0x103c, 0x221b, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
9c5dc3bf 5072 SND_PCI_QUIRK(0x103c, 0x2221, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
9c5dc3bf 5073 SND_PCI_QUIRK(0x103c, 0x2225, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
9c5dc3bf
KY
5074 SND_PCI_QUIRK(0x103c, 0x2253, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5075 SND_PCI_QUIRK(0x103c, 0x2254, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5076 SND_PCI_QUIRK(0x103c, 0x2255, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5077 SND_PCI_QUIRK(0x103c, 0x2256, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5078 SND_PCI_QUIRK(0x103c, 0x2257, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
9c5dc3bf
KY
5079 SND_PCI_QUIRK(0x103c, 0x2259, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5080 SND_PCI_QUIRK(0x103c, 0x225a, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
c60666bd 5081 SND_PCI_QUIRK(0x103c, 0x2260, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
c60666bd
KY
5082 SND_PCI_QUIRK(0x103c, 0x2263, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5083 SND_PCI_QUIRK(0x103c, 0x2264, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5084 SND_PCI_QUIRK(0x103c, 0x2265, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
9c5dc3bf
KY
5085 SND_PCI_QUIRK(0x103c, 0x2272, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5086 SND_PCI_QUIRK(0x103c, 0x2273, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
9c5dc3bf 5087 SND_PCI_QUIRK(0x103c, 0x2278, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
c60666bd 5088 SND_PCI_QUIRK(0x103c, 0x227f, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
c60666bd 5089 SND_PCI_QUIRK(0x103c, 0x2282, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
c60666bd 5090 SND_PCI_QUIRK(0x103c, 0x228b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
c60666bd
KY
5091 SND_PCI_QUIRK(0x103c, 0x228e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5092 SND_PCI_QUIRK(0x103c, 0x22c5, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
c60666bd
KY
5093 SND_PCI_QUIRK(0x103c, 0x22c7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5094 SND_PCI_QUIRK(0x103c, 0x22c8, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
c60666bd 5095 SND_PCI_QUIRK(0x103c, 0x22c4, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
8a02b164
KY
5096 SND_PCI_QUIRK(0x103c, 0x2334, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5097 SND_PCI_QUIRK(0x103c, 0x2335, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5098 SND_PCI_QUIRK(0x103c, 0x2336, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5099 SND_PCI_QUIRK(0x103c, 0x2337, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7bba2157 5100 SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300),
3e0d611b
DH
5101 SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
5102 SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
2cede303 5103 SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK),
23870831 5104 SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A),
3e0d611b 5105 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC),
017f2a10 5106 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
693b613d 5107 SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC),
3e0d611b 5108 SND_PCI_QUIRK(0x1043, 0x1c23, "Asus X55U", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
adabb3ec
TI
5109 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC),
5110 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC),
5111 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
5112 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
d240d1dc 5113 SND_PCI_QUIRK(0x1043, 0x8516, "ASUS X101CH", ALC269_FIXUP_ASUS_X101),
f88abaa0 5114 SND_PCI_QUIRK(0x104d, 0x90b5, "Sony VAIO Pro 11", ALC286_FIXUP_SONY_MIC_NO_PRESENCE),
88cfcf86 5115 SND_PCI_QUIRK(0x104d, 0x90b6, "Sony VAIO Pro 13", ALC286_FIXUP_SONY_MIC_NO_PRESENCE),
1d045db9
TI
5116 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
5117 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
5118 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
e9bd7d5c 5119 SND_PCI_QUIRK(0x104d, 0x9099, "Sony VAIO S13", ALC275_FIXUP_SONY_DISABLE_AAMIX),
24519911 5120 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook", ALC269_FIXUP_LIFEBOOK),
cc7016ab 5121 SND_PCI_QUIRK(0x10cf, 0x15dc, "Lifebook T731", ALC269_FIXUP_LIFEBOOK_HP_PIN),
2041d564 5122 SND_PCI_QUIRK(0x10cf, 0x1845, "Lifebook U904", ALC269_FIXUP_LIFEBOOK_EXTMIC),
a33cc48d 5123 SND_PCI_QUIRK(0x144d, 0xc109, "Samsung Ativ book 9 (NP900X3G)", ALC269_FIXUP_INV_DMIC),
9dc12862 5124 SND_PCI_QUIRK(0x1458, 0xfa53, "Gigabyte BXBT-2807", ALC283_FIXUP_BXBT2807_MIC),
1d045db9
TI
5125 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
5126 SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
5127 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
5128 SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
5129 SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
707fba3f 5130 SND_PCI_QUIRK(0x17aa, 0x21f6, "Thinkpad T530", ALC269_FIXUP_LENOVO_DOCK),
c8415a48 5131 SND_PCI_QUIRK(0x17aa, 0x21fa, "Thinkpad X230", ALC269_FIXUP_LENOVO_DOCK),
84f98fdf 5132 SND_PCI_QUIRK(0x17aa, 0x21f3, "Thinkpad T430", ALC269_FIXUP_LENOVO_DOCK),
4407be6b 5133 SND_PCI_QUIRK(0x17aa, 0x21fb, "Thinkpad T430s", ALC269_FIXUP_LENOVO_DOCK),
108cc108 5134 SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK),
aaedfb47 5135 SND_PCI_QUIRK(0x17aa, 0x2208, "Thinkpad T431s", ALC269_FIXUP_LENOVO_DOCK),
1c37c223
TI
5136 SND_PCI_QUIRK(0x17aa, 0x220c, "Thinkpad T440s", ALC292_FIXUP_TPT440_DOCK),
5137 SND_PCI_QUIRK(0x17aa, 0x220e, "Thinkpad T440p", ALC292_FIXUP_TPT440_DOCK),
a12137e7 5138 SND_PCI_QUIRK(0x17aa, 0x2210, "Thinkpad T540p", ALC292_FIXUP_TPT440_DOCK),
6d16941a 5139 SND_PCI_QUIRK(0x17aa, 0x2212, "Thinkpad T440", ALC292_FIXUP_TPT440_DOCK),
7c21539c 5140 SND_PCI_QUIRK(0x17aa, 0x2214, "Thinkpad X240", ALC292_FIXUP_TPT440_DOCK),
a4a9e082 5141 SND_PCI_QUIRK(0x17aa, 0x2215, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
c0278669 5142 SND_PCI_QUIRK(0x17aa, 0x2226, "ThinkPad X250", ALC292_FIXUP_TPT440_DOCK),
fedb2245 5143 SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC),
9b745ab8 5144 SND_PCI_QUIRK(0x17aa, 0x3978, "IdeaPad Y410P", ALC269_FIXUP_NO_SHUTUP),
a4a9e082 5145 SND_PCI_QUIRK(0x17aa, 0x5013, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
1bb3e062 5146 SND_PCI_QUIRK(0x17aa, 0x501a, "Thinkpad", ALC283_FIXUP_INT_MIC),
c497d9f9 5147 SND_PCI_QUIRK(0x17aa, 0x501e, "Thinkpad L440", ALC292_FIXUP_TPT440_DOCK),
cd5302c0 5148 SND_PCI_QUIRK(0x17aa, 0x5026, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
f2aa1110 5149 SND_PCI_QUIRK(0x17aa, 0x5034, "Thinkpad T450", ALC292_FIXUP_TPT440_DOCK),
80b311d3 5150 SND_PCI_QUIRK(0x17aa, 0x5036, "Thinkpad T450s", ALC292_FIXUP_TPT440_DOCK),
cd5302c0 5151 SND_PCI_QUIRK(0x17aa, 0x5109, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
012e7eb1 5152 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K),
1d045db9 5153 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
02b504d9 5154 SND_PCI_QUIRK(0x1b7d, 0xa831, "Ordissimo EVE2 ", ALC269VB_FIXUP_ORDISSIMO_EVE2), /* Also known as Malata PC-B1303 */
a4297b5d 5155
a7f3eedc 5156#if 0
a4297b5d
TI
5157 /* Below is a quirk table taken from the old code.
5158 * Basically the device should work as is without the fixup table.
5159 * If BIOS doesn't give a proper info, enable the corresponding
5160 * fixup entry.
7d7eb9ea 5161 */
a4297b5d
TI
5162 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
5163 ALC269_FIXUP_AMIC),
5164 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269_FIXUP_AMIC),
a4297b5d
TI
5165 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269_FIXUP_AMIC),
5166 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_FIXUP_AMIC),
5167 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269_FIXUP_AMIC),
5168 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269_FIXUP_AMIC),
5169 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269_FIXUP_AMIC),
5170 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269_FIXUP_AMIC),
5171 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_FIXUP_AMIC),
5172 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269_FIXUP_AMIC),
5173 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_FIXUP_AMIC),
5174 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_FIXUP_AMIC),
5175 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_FIXUP_AMIC),
5176 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_FIXUP_AMIC),
5177 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_FIXUP_AMIC),
5178 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_FIXUP_AMIC),
5179 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_FIXUP_AMIC),
5180 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_FIXUP_AMIC),
5181 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_FIXUP_AMIC),
5182 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_FIXUP_AMIC),
5183 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_FIXUP_AMIC),
5184 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_FIXUP_AMIC),
5185 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_FIXUP_AMIC),
5186 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_FIXUP_AMIC),
5187 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_FIXUP_AMIC),
5188 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_FIXUP_AMIC),
5189 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_FIXUP_AMIC),
5190 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_FIXUP_AMIC),
5191 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_FIXUP_AMIC),
5192 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_FIXUP_AMIC),
5193 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_FIXUP_AMIC),
5194 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_FIXUP_AMIC),
5195 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_FIXUP_AMIC),
5196 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_FIXUP_AMIC),
5197 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_FIXUP_AMIC),
5198 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_FIXUP_DMIC),
5199 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_FIXUP_AMIC),
5200 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_AMIC),
5201 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_FIXUP_DMIC),
5202 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_FIXUP_DMIC),
5203#endif
5204 {}
5205};
5206
214eef76
DH
5207static const struct snd_pci_quirk alc269_fixup_vendor_tbl[] = {
5208 SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC),
5209 SND_PCI_QUIRK_VENDOR(0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED),
5210 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
5211 SND_PCI_QUIRK_VENDOR(0x17aa, "Thinkpad", ALC269_FIXUP_THINKPAD_ACPI),
5212 {}
5213};
5214
1727a771 5215static const struct hda_model_fixup alc269_fixup_models[] = {
a4297b5d
TI
5216 {.id = ALC269_FIXUP_AMIC, .name = "laptop-amic"},
5217 {.id = ALC269_FIXUP_DMIC, .name = "laptop-dmic"},
6e72aa5f
TI
5218 {.id = ALC269_FIXUP_STEREO_DMIC, .name = "alc269-dmic"},
5219 {.id = ALC271_FIXUP_DMIC, .name = "alc271-dmic"},
5220 {.id = ALC269_FIXUP_INV_DMIC, .name = "inv-dmic"},
7c478f03 5221 {.id = ALC269_FIXUP_HEADSET_MIC, .name = "headset-mic"},
108cc108 5222 {.id = ALC269_FIXUP_LENOVO_DOCK, .name = "lenovo-dock"},
9f5c6faf 5223 {.id = ALC269_FIXUP_HP_GPIO_LED, .name = "hp-gpio-led"},
e32aa85a
DH
5224 {.id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "dell-headset-multi"},
5225 {.id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE, .name = "dell-headset-dock"},
be8ef16a 5226 {.id = ALC283_FIXUP_CHROME_BOOK, .name = "alc283-dac-wcaps"},
0202e99c 5227 {.id = ALC283_FIXUP_SENSE_COMBO_JACK, .name = "alc283-sense-combo"},
1c37c223 5228 {.id = ALC292_FIXUP_TPT440_DOCK, .name = "tpt440-dock"},
1d045db9 5229 {}
6dda9f4a
KY
5230};
5231
fea185e2
DH
5232#define ALC255_STANDARD_PINS \
5233 {0x18, 0x411111f0}, \
5234 {0x19, 0x411111f0}, \
5235 {0x1a, 0x411111f0}, \
5236 {0x1b, 0x411111f0}, \
5237 {0x1e, 0x411111f0}
5238
e8191a8e
HW
5239#define ALC256_STANDARD_PINS \
5240 {0x12, 0x90a60140}, \
5241 {0x14, 0x90170110}, \
5242 {0x19, 0x411111f0}, \
5243 {0x1a, 0x411111f0}, \
5244 {0x1b, 0x411111f0}, \
5245 {0x1d, 0x40700001}, \
5246 {0x1e, 0x411111f0}, \
5247 {0x21, 0x02211020}
5248
fea185e2
DH
5249#define ALC282_STANDARD_PINS \
5250 {0x14, 0x90170110}, \
5251 {0x18, 0x411111f0}, \
5252 {0x1a, 0x411111f0}, \
5253 {0x1b, 0x411111f0}, \
5254 {0x1e, 0x411111f0}
5255
e1e62b98
KY
5256#define ALC288_STANDARD_PINS \
5257 {0x17, 0x411111f0}, \
5258 {0x18, 0x411111f0}, \
5259 {0x19, 0x411111f0}, \
5260 {0x1a, 0x411111f0}, \
5261 {0x1e, 0x411111f0}
5262
fea185e2
DH
5263#define ALC290_STANDARD_PINS \
5264 {0x12, 0x99a30130}, \
5265 {0x13, 0x40000000}, \
5266 {0x16, 0x411111f0}, \
5267 {0x17, 0x411111f0}, \
5268 {0x19, 0x411111f0}, \
5269 {0x1b, 0x411111f0}, \
5270 {0x1e, 0x411111f0}
5271
5272#define ALC292_STANDARD_PINS \
5273 {0x14, 0x90170110}, \
5274 {0x15, 0x0221401f}, \
5275 {0x1a, 0x411111f0}, \
5276 {0x1b, 0x411111f0}, \
5277 {0x1d, 0x40700001}, \
5278 {0x1e, 0x411111f0}
5279
e1918938 5280static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
c77900e6 5281 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE,
aec856d0 5282 ALC255_STANDARD_PINS,
c77900e6
HW
5283 {0x12, 0x40300000},
5284 {0x14, 0x90170110},
5285 {0x17, 0x411111f0},
c77900e6 5286 {0x1d, 0x40538029},
c77900e6 5287 {0x21, 0x02211020}),
76c2132e 5288 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
aec856d0 5289 ALC255_STANDARD_PINS,
76c2132e
DH
5290 {0x12, 0x90a60140},
5291 {0x14, 0x90170110},
5292 {0x17, 0x40000000},
76c2132e 5293 {0x1d, 0x40700001},
76c2132e
DH
5294 {0x21, 0x02211020}),
5295 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
aec856d0 5296 ALC255_STANDARD_PINS,
76c2132e
DH
5297 {0x12, 0x90a60160},
5298 {0x14, 0x90170120},
5299 {0x17, 0x40000000},
76c2132e 5300 {0x1d, 0x40700001},
76c2132e
DH
5301 {0x21, 0x02211030}),
5302 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
5303 {0x12, 0x90a60160},
5304 {0x14, 0x90170120},
5305 {0x17, 0x90170140},
5306 {0x18, 0x40000000},
5307 {0x19, 0x411111f0},
5308 {0x1a, 0x411111f0},
5309 {0x1b, 0x411111f0},
5310 {0x1d, 0x41163b05},
5311 {0x1e, 0x411111f0},
5312 {0x21, 0x0321102f}),
5313 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
aec856d0 5314 ALC255_STANDARD_PINS,
76c2132e
DH
5315 {0x12, 0x90a60160},
5316 {0x14, 0x90170130},
5317 {0x17, 0x40000000},
76c2132e 5318 {0x1d, 0x40700001},
76c2132e
DH
5319 {0x21, 0x02211040}),
5320 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
aec856d0 5321 ALC255_STANDARD_PINS,
76c2132e
DH
5322 {0x12, 0x90a60160},
5323 {0x14, 0x90170140},
5324 {0x17, 0x40000000},
76c2132e 5325 {0x1d, 0x40700001},
76c2132e
DH
5326 {0x21, 0x02211050}),
5327 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
aec856d0 5328 ALC255_STANDARD_PINS,
76c2132e
DH
5329 {0x12, 0x90a60170},
5330 {0x14, 0x90170120},
5331 {0x17, 0x40000000},
76c2132e 5332 {0x1d, 0x40700001},
76c2132e
DH
5333 {0x21, 0x02211030}),
5334 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
aec856d0 5335 ALC255_STANDARD_PINS,
76c2132e
DH
5336 {0x12, 0x90a60170},
5337 {0x14, 0x90170130},
5338 {0x17, 0x40000000},
76c2132e 5339 {0x1d, 0x40700001},
76c2132e 5340 {0x21, 0x02211040}),
70658b99
HW
5341 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
5342 ALC255_STANDARD_PINS,
5343 {0x12, 0x90a60170},
5344 {0x14, 0x90170140},
5345 {0x17, 0x40000000},
5346 {0x1d, 0x40700001},
5347 {0x21, 0x02211050}),
7081adf3 5348 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
e8191a8e
HW
5349 ALC256_STANDARD_PINS,
5350 {0x13, 0x40000000}),
5351 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
5352 ALC256_STANDARD_PINS,
5353 {0x13, 0x411111f0}),
cf51eb9d
DH
5354 SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC280_FIXUP_HP_GPIO4,
5355 {0x12, 0x90a60130},
5356 {0x13, 0x40000000},
5357 {0x14, 0x90170110},
5358 {0x15, 0x0421101f},
5359 {0x16, 0x411111f0},
5360 {0x17, 0x411111f0},
5361 {0x18, 0x411111f0},
5362 {0x19, 0x411111f0},
5363 {0x1a, 0x04a11020},
5364 {0x1b, 0x411111f0},
5365 {0x1d, 0x40748605},
5366 {0x1e, 0x411111f0}),
0279661b
HW
5367 SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED,
5368 {0x12, 0x90a60140},
5369 {0x13, 0x40000000},
5370 {0x14, 0x90170110},
5371 {0x15, 0x0421101f},
5372 {0x16, 0x411111f0},
5373 {0x17, 0x411111f0},
5374 {0x18, 0x02811030},
5375 {0x19, 0x411111f0},
5376 {0x1a, 0x04a1103f},
5377 {0x1b, 0x02011020},
5378 {0x1d, 0x40700001},
5379 {0x1e, 0x411111f0}),
42304474 5380 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP 15 Touchsmart", ALC269_FIXUP_HP_MUTE_LED_MIC1,
aec856d0 5381 ALC282_STANDARD_PINS,
42304474 5382 {0x12, 0x99a30130},
42304474 5383 {0x17, 0x40000000},
42304474 5384 {0x19, 0x03a11020},
42304474 5385 {0x1d, 0x40f41905},
42304474 5386 {0x21, 0x0321101f}),
2c609999 5387 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
aec856d0 5388 ALC282_STANDARD_PINS,
2c609999 5389 {0x12, 0x99a30130},
2c609999 5390 {0x17, 0x40020008},
2c609999 5391 {0x19, 0x03a11020},
2c609999 5392 {0x1d, 0x40e00001},
2c609999
HW
5393 {0x21, 0x03211040}),
5394 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
aec856d0 5395 ALC282_STANDARD_PINS,
2c609999 5396 {0x12, 0x99a30130},
2c609999 5397 {0x17, 0x40000000},
2c609999 5398 {0x19, 0x03a11030},
2c609999 5399 {0x1d, 0x40e00001},
2c609999
HW
5400 {0x21, 0x03211020}),
5401 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
aec856d0 5402 ALC282_STANDARD_PINS,
2c609999 5403 {0x12, 0x99a30130},
2c609999 5404 {0x17, 0x40000000},
2c609999 5405 {0x19, 0x03a11030},
2c609999 5406 {0x1d, 0x40f00001},
2c609999
HW
5407 {0x21, 0x03211020}),
5408 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
aec856d0 5409 ALC282_STANDARD_PINS,
2c609999 5410 {0x12, 0x99a30130},
2c609999 5411 {0x17, 0x40000000},
2c609999 5412 {0x19, 0x04a11020},
2c609999 5413 {0x1d, 0x40f00001},
2c609999
HW
5414 {0x21, 0x0421101f}),
5415 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
aec856d0 5416 ALC282_STANDARD_PINS,
2c609999 5417 {0x12, 0x99a30130},
2c609999 5418 {0x17, 0x40000000},
2c609999 5419 {0x19, 0x03a11030},
2c609999 5420 {0x1d, 0x40f00001},
2c609999 5421 {0x21, 0x04211020}),
200afc09 5422 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED,
aec856d0 5423 ALC282_STANDARD_PINS,
200afc09 5424 {0x12, 0x90a60140},
200afc09 5425 {0x17, 0x40000000},
200afc09 5426 {0x19, 0x04a11030},
200afc09 5427 {0x1d, 0x40f00001},
200afc09 5428 {0x21, 0x04211020}),
76c2132e 5429 SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
aec856d0 5430 ALC282_STANDARD_PINS,
76c2132e 5431 {0x12, 0x90a60130},
76c2132e 5432 {0x17, 0x40020008},
76c2132e 5433 {0x19, 0x411111f0},
76c2132e 5434 {0x1d, 0x40e00001},
76c2132e
DH
5435 {0x21, 0x0321101f}),
5436 SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
5437 {0x12, 0x90a60160},
5438 {0x14, 0x90170120},
5439 {0x17, 0x40000000},
5440 {0x18, 0x411111f0},
5441 {0x19, 0x411111f0},
5442 {0x1a, 0x411111f0},
5443 {0x1b, 0x411111f0},
5444 {0x1d, 0x40700001},
5445 {0x1e, 0x411111f0},
5446 {0x21, 0x02211030}),
bc262179 5447 SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
aec856d0 5448 ALC282_STANDARD_PINS,
bc262179 5449 {0x12, 0x90a60130},
bc262179 5450 {0x17, 0x40020008},
bc262179 5451 {0x19, 0x03a11020},
bc262179 5452 {0x1d, 0x40e00001},
bc262179 5453 {0x21, 0x0321101f}),
e1e62b98
KY
5454 SND_HDA_PIN_QUIRK(0x10ec0288, 0x1028, "Dell", ALC288_FIXUP_DELL_XPS_13_GPIO6,
5455 ALC288_STANDARD_PINS,
5456 {0x12, 0x90a60120},
5457 {0x13, 0x40000000},
5458 {0x14, 0x90170110},
5459 {0x1d, 0x4076832d},
5460 {0x21, 0x0321101f}),
e4442bcf 5461 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
aec856d0 5462 ALC290_STANDARD_PINS,
e4442bcf
HW
5463 {0x14, 0x411111f0},
5464 {0x15, 0x04211040},
e4442bcf 5465 {0x18, 0x90170112},
e4442bcf 5466 {0x1a, 0x04a11020},
aec856d0 5467 {0x1d, 0x4075812d}),
e4442bcf 5468 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
aec856d0 5469 ALC290_STANDARD_PINS,
e4442bcf
HW
5470 {0x14, 0x411111f0},
5471 {0x15, 0x04211040},
e4442bcf 5472 {0x18, 0x90170110},
e4442bcf 5473 {0x1a, 0x04a11020},
aec856d0 5474 {0x1d, 0x4075812d}),
e4442bcf 5475 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
aec856d0 5476 ALC290_STANDARD_PINS,
e4442bcf
HW
5477 {0x14, 0x411111f0},
5478 {0x15, 0x0421101f},
e4442bcf 5479 {0x18, 0x411111f0},
e4442bcf 5480 {0x1a, 0x04a11020},
aec856d0 5481 {0x1d, 0x4075812d}),
e4442bcf 5482 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
aec856d0 5483 ALC290_STANDARD_PINS,
e4442bcf
HW
5484 {0x14, 0x411111f0},
5485 {0x15, 0x04211020},
e4442bcf 5486 {0x18, 0x411111f0},
e4442bcf 5487 {0x1a, 0x04a11040},
aec856d0 5488 {0x1d, 0x4076a12d}),
e4442bcf 5489 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
aec856d0 5490 ALC290_STANDARD_PINS,
e4442bcf
HW
5491 {0x14, 0x90170110},
5492 {0x15, 0x04211020},
e4442bcf 5493 {0x18, 0x411111f0},
e4442bcf 5494 {0x1a, 0x04a11040},
aec856d0 5495 {0x1d, 0x4076a12d}),
e4442bcf 5496 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
aec856d0 5497 ALC290_STANDARD_PINS,
e4442bcf
HW
5498 {0x14, 0x90170110},
5499 {0x15, 0x04211020},
e4442bcf 5500 {0x18, 0x411111f0},
e4442bcf 5501 {0x1a, 0x04a11020},
aec856d0 5502 {0x1d, 0x4076a12d}),
e4442bcf 5503 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
aec856d0 5504 ALC290_STANDARD_PINS,
e4442bcf
HW
5505 {0x14, 0x90170110},
5506 {0x15, 0x0421101f},
e4442bcf 5507 {0x18, 0x411111f0},
e4442bcf 5508 {0x1a, 0x04a11020},
aec856d0 5509 {0x1d, 0x4075812d}),
e8818fa8 5510 SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
aec856d0 5511 ALC292_STANDARD_PINS,
e8818fa8
HW
5512 {0x12, 0x90a60140},
5513 {0x13, 0x411111f0},
e8818fa8
HW
5514 {0x16, 0x01014020},
5515 {0x18, 0x411111f0},
aec856d0 5516 {0x19, 0x01a19030}),
e8818fa8 5517 SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
aec856d0 5518 ALC292_STANDARD_PINS,
e8818fa8
HW
5519 {0x12, 0x90a60140},
5520 {0x13, 0x411111f0},
e8818fa8
HW
5521 {0x16, 0x01014020},
5522 {0x18, 0x02a19031},
aec856d0 5523 {0x19, 0x01a1903e}),
76c2132e 5524 SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
aec856d0 5525 ALC292_STANDARD_PINS,
76c2132e
DH
5526 {0x12, 0x90a60140},
5527 {0x13, 0x411111f0},
76c2132e
DH
5528 {0x16, 0x411111f0},
5529 {0x18, 0x411111f0},
aec856d0 5530 {0x19, 0x411111f0}),
76c2132e 5531 SND_HDA_PIN_QUIRK(0x10ec0293, 0x1028, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
aec856d0 5532 ALC292_STANDARD_PINS,
76c2132e
DH
5533 {0x12, 0x40000000},
5534 {0x13, 0x90a60140},
76c2132e
DH
5535 {0x16, 0x21014020},
5536 {0x18, 0x411111f0},
aec856d0 5537 {0x19, 0x21a19030}),
e03fdbde 5538 SND_HDA_PIN_QUIRK(0x10ec0293, 0x1028, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
aec856d0 5539 ALC292_STANDARD_PINS,
e03fdbde
DH
5540 {0x12, 0x40000000},
5541 {0x13, 0x90a60140},
e03fdbde
DH
5542 {0x16, 0x411111f0},
5543 {0x18, 0x411111f0},
aec856d0 5544 {0x19, 0x411111f0}),
e1918938
HW
5545 {}
5546};
6dda9f4a 5547
546bb678 5548static void alc269_fill_coef(struct hda_codec *codec)
1d045db9 5549{
526af6eb 5550 struct alc_spec *spec = codec->spec;
1d045db9 5551 int val;
ebb83eeb 5552
526af6eb 5553 if (spec->codec_variant != ALC269_TYPE_ALC269VB)
546bb678 5554 return;
526af6eb 5555
1bb7e43e 5556 if ((alc_get_coef0(codec) & 0x00ff) < 0x015) {
1d045db9
TI
5557 alc_write_coef_idx(codec, 0xf, 0x960b);
5558 alc_write_coef_idx(codec, 0xe, 0x8817);
5559 }
ebb83eeb 5560
1bb7e43e 5561 if ((alc_get_coef0(codec) & 0x00ff) == 0x016) {
1d045db9
TI
5562 alc_write_coef_idx(codec, 0xf, 0x960b);
5563 alc_write_coef_idx(codec, 0xe, 0x8814);
5564 }
ebb83eeb 5565
1bb7e43e 5566 if ((alc_get_coef0(codec) & 0x00ff) == 0x017) {
1d045db9 5567 /* Power up output pin */
98b24883 5568 alc_update_coef_idx(codec, 0x04, 0, 1<<11);
1d045db9 5569 }
ebb83eeb 5570
1bb7e43e 5571 if ((alc_get_coef0(codec) & 0x00ff) == 0x018) {
1d045db9 5572 val = alc_read_coef_idx(codec, 0xd);
f3ee07d8 5573 if (val != -1 && (val & 0x0c00) >> 10 != 0x1) {
1d045db9
TI
5574 /* Capless ramp up clock control */
5575 alc_write_coef_idx(codec, 0xd, val | (1<<10));
5576 }
5577 val = alc_read_coef_idx(codec, 0x17);
f3ee07d8 5578 if (val != -1 && (val & 0x01c0) >> 6 != 0x4) {
1d045db9
TI
5579 /* Class D power on reset */
5580 alc_write_coef_idx(codec, 0x17, val | (1<<7));
5581 }
5582 }
ebb83eeb 5583
98b24883
TI
5584 /* HP */
5585 alc_update_coef_idx(codec, 0x4, 0, 1<<11);
1d045db9 5586}
a7f2371f 5587
1d045db9
TI
5588/*
5589 */
1d045db9
TI
5590static int patch_alc269(struct hda_codec *codec)
5591{
5592 struct alc_spec *spec;
3de95173 5593 int err;
f1d4e28b 5594
3de95173 5595 err = alc_alloc_spec(codec, 0x0b);
e16fb6d1 5596 if (err < 0)
3de95173
TI
5597 return err;
5598
5599 spec = codec->spec;
08c189f2 5600 spec->gen.shared_mic_vref_pin = 0x18;
382fd7be 5601 codec->power_save_node = 1;
e16fb6d1 5602
1727a771 5603 snd_hda_pick_fixup(codec, alc269_fixup_models,
9f720bb9 5604 alc269_fixup_tbl, alc269_fixups);
e1918938 5605 snd_hda_pick_pin_fixup(codec, alc269_pin_fixup_tbl, alc269_fixups);
214eef76
DH
5606 snd_hda_pick_fixup(codec, NULL, alc269_fixup_vendor_tbl,
5607 alc269_fixups);
1727a771 5608 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
9f720bb9
HRK
5609
5610 alc_auto_parse_customize_define(codec);
5611
7504b6cd
TI
5612 if (has_cdefine_beep(codec))
5613 spec->gen.beep_nid = 0x01;
5614
7639a06c 5615 switch (codec->core.vendor_id) {
065380f0 5616 case 0x10ec0269:
1d045db9 5617 spec->codec_variant = ALC269_TYPE_ALC269VA;
1bb7e43e
TI
5618 switch (alc_get_coef0(codec) & 0x00f0) {
5619 case 0x0010:
5100cd07
TI
5620 if (codec->bus->pci &&
5621 codec->bus->pci->subsystem_vendor == 0x1025 &&
e16fb6d1 5622 spec->cdefine.platform_type == 1)
20ca0c35 5623 err = alc_codec_rename(codec, "ALC271X");
1d045db9 5624 spec->codec_variant = ALC269_TYPE_ALC269VB;
1bb7e43e
TI
5625 break;
5626 case 0x0020:
5100cd07
TI
5627 if (codec->bus->pci &&
5628 codec->bus->pci->subsystem_vendor == 0x17aa &&
e16fb6d1 5629 codec->bus->pci->subsystem_device == 0x21f3)
20ca0c35 5630 err = alc_codec_rename(codec, "ALC3202");
1d045db9 5631 spec->codec_variant = ALC269_TYPE_ALC269VC;
1bb7e43e 5632 break;
adcc70b2
KY
5633 case 0x0030:
5634 spec->codec_variant = ALC269_TYPE_ALC269VD;
5635 break;
1bb7e43e 5636 default:
1d045db9 5637 alc_fix_pll_init(codec, 0x20, 0x04, 15);
1bb7e43e 5638 }
e16fb6d1
TI
5639 if (err < 0)
5640 goto error;
546bb678 5641 spec->init_hook = alc269_fill_coef;
1d045db9 5642 alc269_fill_coef(codec);
065380f0
KY
5643 break;
5644
5645 case 0x10ec0280:
5646 case 0x10ec0290:
5647 spec->codec_variant = ALC269_TYPE_ALC280;
5648 break;
5649 case 0x10ec0282:
065380f0 5650 spec->codec_variant = ALC269_TYPE_ALC282;
7b5c7a02
KY
5651 spec->shutup = alc282_shutup;
5652 spec->init_hook = alc282_init;
065380f0 5653 break;
2af02be7
KY
5654 case 0x10ec0233:
5655 case 0x10ec0283:
5656 spec->codec_variant = ALC269_TYPE_ALC283;
5657 spec->shutup = alc283_shutup;
5658 spec->init_hook = alc283_init;
5659 break;
065380f0
KY
5660 case 0x10ec0284:
5661 case 0x10ec0292:
5662 spec->codec_variant = ALC269_TYPE_ALC284;
5663 break;
161ebf29
KY
5664 case 0x10ec0285:
5665 case 0x10ec0293:
5666 spec->codec_variant = ALC269_TYPE_ALC285;
5667 break;
7fc7d047 5668 case 0x10ec0286:
7c665932 5669 case 0x10ec0288:
7fc7d047 5670 spec->codec_variant = ALC269_TYPE_ALC286;
f7ae9ba0 5671 spec->shutup = alc286_shutup;
7fc7d047 5672 break;
506b62c3
KY
5673 case 0x10ec0298:
5674 spec->codec_variant = ALC269_TYPE_ALC298;
5675 break;
1d04c9de
KY
5676 case 0x10ec0255:
5677 spec->codec_variant = ALC269_TYPE_ALC255;
5678 break;
4344aec8
KY
5679 case 0x10ec0256:
5680 spec->codec_variant = ALC269_TYPE_ALC256;
7d1b6e29 5681 spec->gen.mixer_nid = 0; /* ALC256 does not have any loopback mixer path */
d32b6666 5682 alc_update_coef_idx(codec, 0x36, 1 << 13, 1 << 5); /* Switch pcbeep path to Line in path*/
4344aec8 5683 break;
1d045db9 5684 }
6dda9f4a 5685
ad60d502 5686 if (snd_hda_codec_read(codec, 0x51, 0, AC_VERB_PARAMETERS, 0) == 0x10ec5505) {
97a26570 5687 spec->has_alc5505_dsp = 1;
ad60d502
KY
5688 spec->init_hook = alc5505_dsp_init;
5689 }
5690
a4297b5d
TI
5691 /* automatic parse from the BIOS config */
5692 err = alc269_parse_auto_config(codec);
e16fb6d1
TI
5693 if (err < 0)
5694 goto error;
6dda9f4a 5695
7d1b6e29
DH
5696 if (!spec->gen.no_analog && spec->gen.beep_nid && spec->gen.mixer_nid)
5697 set_beep_amp(spec, spec->gen.mixer_nid, 0x04, HDA_INPUT);
f1d4e28b 5698
1d045db9 5699 codec->patch_ops = alc_patch_ops;
f4d3129c 5700 codec->patch_ops.stream_pm = snd_hda_gen_stream_pm;
2a43952a 5701#ifdef CONFIG_PM
ad60d502 5702 codec->patch_ops.suspend = alc269_suspend;
1d045db9
TI
5703 codec->patch_ops.resume = alc269_resume;
5704#endif
c5177c86
KY
5705 if (!spec->shutup)
5706 spec->shutup = alc269_shutup;
ebb83eeb 5707
1727a771 5708 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
589876e2 5709
1d045db9 5710 return 0;
e16fb6d1
TI
5711
5712 error:
5713 alc_free(codec);
5714 return err;
1d045db9 5715}
f1d4e28b 5716
1d045db9
TI
5717/*
5718 * ALC861
5719 */
622e84cd 5720
1d045db9 5721static int alc861_parse_auto_config(struct hda_codec *codec)
6dda9f4a 5722{
1d045db9 5723 static const hda_nid_t alc861_ignore[] = { 0x1d, 0 };
3e6179b8
TI
5724 static const hda_nid_t alc861_ssids[] = { 0x0e, 0x0f, 0x0b, 0 };
5725 return alc_parse_auto_config(codec, alc861_ignore, alc861_ssids);
604401a9
TI
5726}
5727
1d045db9
TI
5728/* Pin config fixes */
5729enum {
e652f4c8
TI
5730 ALC861_FIXUP_FSC_AMILO_PI1505,
5731 ALC861_FIXUP_AMP_VREF_0F,
5732 ALC861_FIXUP_NO_JACK_DETECT,
5733 ALC861_FIXUP_ASUS_A6RP,
6ddf0fd1 5734 ALC660_FIXUP_ASUS_W7J,
1d045db9 5735};
7085ec12 5736
31150f23
TI
5737/* On some laptops, VREF of pin 0x0f is abused for controlling the main amp */
5738static void alc861_fixup_asus_amp_vref_0f(struct hda_codec *codec,
1727a771 5739 const struct hda_fixup *fix, int action)
31150f23
TI
5740{
5741 struct alc_spec *spec = codec->spec;
5742 unsigned int val;
5743
1727a771 5744 if (action != HDA_FIXUP_ACT_INIT)
31150f23 5745 return;
d3f02d60 5746 val = snd_hda_codec_get_pin_target(codec, 0x0f);
31150f23
TI
5747 if (!(val & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN)))
5748 val |= AC_PINCTL_IN_EN;
5749 val |= AC_PINCTL_VREF_50;
cdd03ced 5750 snd_hda_set_pin_ctl(codec, 0x0f, val);
08c189f2 5751 spec->gen.keep_vref_in_automute = 1;
31150f23
TI
5752}
5753
e652f4c8
TI
5754/* suppress the jack-detection */
5755static void alc_fixup_no_jack_detect(struct hda_codec *codec,
1727a771 5756 const struct hda_fixup *fix, int action)
e652f4c8 5757{
1727a771 5758 if (action == HDA_FIXUP_ACT_PRE_PROBE)
e652f4c8 5759 codec->no_jack_detect = 1;
7d7eb9ea 5760}
e652f4c8 5761
1727a771 5762static const struct hda_fixup alc861_fixups[] = {
e652f4c8 5763 [ALC861_FIXUP_FSC_AMILO_PI1505] = {
1727a771
TI
5764 .type = HDA_FIXUP_PINS,
5765 .v.pins = (const struct hda_pintbl[]) {
1d045db9
TI
5766 { 0x0b, 0x0221101f }, /* HP */
5767 { 0x0f, 0x90170310 }, /* speaker */
5768 { }
5769 }
5770 },
e652f4c8 5771 [ALC861_FIXUP_AMP_VREF_0F] = {
1727a771 5772 .type = HDA_FIXUP_FUNC,
31150f23 5773 .v.func = alc861_fixup_asus_amp_vref_0f,
3b25eb69 5774 },
e652f4c8 5775 [ALC861_FIXUP_NO_JACK_DETECT] = {
1727a771 5776 .type = HDA_FIXUP_FUNC,
e652f4c8
TI
5777 .v.func = alc_fixup_no_jack_detect,
5778 },
5779 [ALC861_FIXUP_ASUS_A6RP] = {
1727a771 5780 .type = HDA_FIXUP_FUNC,
e652f4c8
TI
5781 .v.func = alc861_fixup_asus_amp_vref_0f,
5782 .chained = true,
5783 .chain_id = ALC861_FIXUP_NO_JACK_DETECT,
6ddf0fd1
TI
5784 },
5785 [ALC660_FIXUP_ASUS_W7J] = {
5786 .type = HDA_FIXUP_VERBS,
5787 .v.verbs = (const struct hda_verb[]) {
5788 /* ASUS W7J needs a magic pin setup on unused NID 0x10
5789 * for enabling outputs
5790 */
5791 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5792 { }
5793 },
e652f4c8 5794 }
1d045db9 5795};
7085ec12 5796
1d045db9 5797static const struct snd_pci_quirk alc861_fixup_tbl[] = {
6ddf0fd1 5798 SND_PCI_QUIRK(0x1043, 0x1253, "ASUS W7J", ALC660_FIXUP_ASUS_W7J),
e7ca237b 5799 SND_PCI_QUIRK(0x1043, 0x1263, "ASUS Z35HL", ALC660_FIXUP_ASUS_W7J),
e652f4c8
TI
5800 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS A6Rp", ALC861_FIXUP_ASUS_A6RP),
5801 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", ALC861_FIXUP_AMP_VREF_0F),
5802 SND_PCI_QUIRK(0x1462, 0x7254, "HP DX2200", ALC861_FIXUP_NO_JACK_DETECT),
5803 SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", ALC861_FIXUP_AMP_VREF_0F),
5804 SND_PCI_QUIRK(0x1584, 0x0000, "Uniwill ECS M31EI", ALC861_FIXUP_AMP_VREF_0F),
5805 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", ALC861_FIXUP_FSC_AMILO_PI1505),
1d045db9
TI
5806 {}
5807};
3af9ee6b 5808
1d045db9
TI
5809/*
5810 */
1d045db9 5811static int patch_alc861(struct hda_codec *codec)
7085ec12 5812{
1d045db9 5813 struct alc_spec *spec;
1d045db9 5814 int err;
7085ec12 5815
3de95173
TI
5816 err = alc_alloc_spec(codec, 0x15);
5817 if (err < 0)
5818 return err;
1d045db9 5819
3de95173 5820 spec = codec->spec;
7504b6cd 5821 spec->gen.beep_nid = 0x23;
1d045db9 5822
1727a771
TI
5823 snd_hda_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
5824 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
3af9ee6b 5825
cb4e4824
TI
5826 /* automatic parse from the BIOS config */
5827 err = alc861_parse_auto_config(codec);
e16fb6d1
TI
5828 if (err < 0)
5829 goto error;
3af9ee6b 5830
7504b6cd 5831 if (!spec->gen.no_analog)
3e6179b8 5832 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
7085ec12 5833
1d045db9 5834 codec->patch_ops = alc_patch_ops;
83012a7c 5835#ifdef CONFIG_PM
cb4e4824 5836 spec->power_hook = alc_power_eapd;
1d045db9
TI
5837#endif
5838
1727a771 5839 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
589876e2 5840
1d045db9 5841 return 0;
e16fb6d1
TI
5842
5843 error:
5844 alc_free(codec);
5845 return err;
7085ec12
TI
5846}
5847
1d045db9
TI
5848/*
5849 * ALC861-VD support
5850 *
5851 * Based on ALC882
5852 *
5853 * In addition, an independent DAC
5854 */
1d045db9 5855static int alc861vd_parse_auto_config(struct hda_codec *codec)
bc9f98a9 5856{
1d045db9 5857 static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
3e6179b8
TI
5858 static const hda_nid_t alc861vd_ssids[] = { 0x15, 0x1b, 0x14, 0 };
5859 return alc_parse_auto_config(codec, alc861vd_ignore, alc861vd_ssids);
ce764ab2
TI
5860}
5861
1d045db9 5862enum {
8fdcb6fe
TI
5863 ALC660VD_FIX_ASUS_GPIO1,
5864 ALC861VD_FIX_DALLAS,
1d045db9 5865};
ce764ab2 5866
8fdcb6fe
TI
5867/* exclude VREF80 */
5868static void alc861vd_fixup_dallas(struct hda_codec *codec,
1727a771 5869 const struct hda_fixup *fix, int action)
8fdcb6fe 5870{
1727a771 5871 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
b78562b1
TI
5872 snd_hda_override_pin_caps(codec, 0x18, 0x00000734);
5873 snd_hda_override_pin_caps(codec, 0x19, 0x0000073c);
8fdcb6fe
TI
5874 }
5875}
5876
1727a771 5877static const struct hda_fixup alc861vd_fixups[] = {
1d045db9 5878 [ALC660VD_FIX_ASUS_GPIO1] = {
1727a771 5879 .type = HDA_FIXUP_VERBS,
1d045db9 5880 .v.verbs = (const struct hda_verb[]) {
8fdcb6fe 5881 /* reset GPIO1 */
1d045db9
TI
5882 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
5883 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5884 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
5885 { }
5886 }
5887 },
8fdcb6fe 5888 [ALC861VD_FIX_DALLAS] = {
1727a771 5889 .type = HDA_FIXUP_FUNC,
8fdcb6fe
TI
5890 .v.func = alc861vd_fixup_dallas,
5891 },
1d045db9 5892};
ce764ab2 5893
1d045db9 5894static const struct snd_pci_quirk alc861vd_fixup_tbl[] = {
8fdcb6fe 5895 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_FIX_DALLAS),
1d045db9 5896 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
8fdcb6fe 5897 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_FIX_DALLAS),
1d045db9
TI
5898 {}
5899};
ce764ab2 5900
1d045db9
TI
5901/*
5902 */
1d045db9 5903static int patch_alc861vd(struct hda_codec *codec)
ce764ab2 5904{
1d045db9 5905 struct alc_spec *spec;
cb4e4824 5906 int err;
ce764ab2 5907
3de95173
TI
5908 err = alc_alloc_spec(codec, 0x0b);
5909 if (err < 0)
5910 return err;
1d045db9 5911
3de95173 5912 spec = codec->spec;
7504b6cd 5913 spec->gen.beep_nid = 0x23;
1d045db9 5914
1727a771
TI
5915 snd_hda_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
5916 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
1d045db9 5917
cb4e4824
TI
5918 /* automatic parse from the BIOS config */
5919 err = alc861vd_parse_auto_config(codec);
e16fb6d1
TI
5920 if (err < 0)
5921 goto error;
ce764ab2 5922
7504b6cd 5923 if (!spec->gen.no_analog)
3e6179b8 5924 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
1d045db9 5925
1d045db9
TI
5926 codec->patch_ops = alc_patch_ops;
5927
1d045db9 5928 spec->shutup = alc_eapd_shutup;
1d045db9 5929
1727a771 5930 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
589876e2 5931
ce764ab2 5932 return 0;
e16fb6d1
TI
5933
5934 error:
5935 alc_free(codec);
5936 return err;
ce764ab2
TI
5937}
5938
1d045db9
TI
5939/*
5940 * ALC662 support
5941 *
5942 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
5943 * configuration. Each pin widget can choose any input DACs and a mixer.
5944 * Each ADC is connected from a mixer of all inputs. This makes possible
5945 * 6-channel independent captures.
5946 *
5947 * In addition, an independent DAC for the multi-playback (not used in this
5948 * driver yet).
5949 */
1d045db9
TI
5950
5951/*
5952 * BIOS auto configuration
5953 */
5954
bc9f98a9
KY
5955static int alc662_parse_auto_config(struct hda_codec *codec)
5956{
4c6d72d1 5957 static const hda_nid_t alc662_ignore[] = { 0x1d, 0 };
3e6179b8
TI
5958 static const hda_nid_t alc663_ssids[] = { 0x15, 0x1b, 0x14, 0x21 };
5959 static const hda_nid_t alc662_ssids[] = { 0x15, 0x1b, 0x14, 0 };
5960 const hda_nid_t *ssids;
ee979a14 5961
7639a06c
TI
5962 if (codec->core.vendor_id == 0x10ec0272 || codec->core.vendor_id == 0x10ec0663 ||
5963 codec->core.vendor_id == 0x10ec0665 || codec->core.vendor_id == 0x10ec0670 ||
5964 codec->core.vendor_id == 0x10ec0671)
3e6179b8 5965 ssids = alc663_ssids;
6227cdce 5966 else
3e6179b8
TI
5967 ssids = alc662_ssids;
5968 return alc_parse_auto_config(codec, alc662_ignore, ssids);
bc9f98a9
KY
5969}
5970
6be7948f 5971static void alc272_fixup_mario(struct hda_codec *codec,
1727a771 5972 const struct hda_fixup *fix, int action)
6fc398cb 5973{
9bb1f06f 5974 if (action != HDA_FIXUP_ACT_PRE_PROBE)
6fc398cb 5975 return;
6be7948f
TB
5976 if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT,
5977 (0x3b << AC_AMPCAP_OFFSET_SHIFT) |
5978 (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) |
5979 (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) |
5980 (0 << AC_AMPCAP_MUTE_SHIFT)))
4e76a883 5981 codec_warn(codec, "failed to override amp caps for NID 0x2\n");
6be7948f
TB
5982}
5983
8e383953
TI
5984static const struct snd_pcm_chmap_elem asus_pcm_2_1_chmaps[] = {
5985 { .channels = 2,
5986 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } },
5987 { .channels = 4,
5988 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR,
5989 SNDRV_CHMAP_NA, SNDRV_CHMAP_LFE } }, /* LFE only on right */
5990 { }
5991};
5992
5993/* override the 2.1 chmap */
eb9ca3ab 5994static void alc_fixup_bass_chmap(struct hda_codec *codec,
8e383953
TI
5995 const struct hda_fixup *fix, int action)
5996{
5997 if (action == HDA_FIXUP_ACT_BUILD) {
5998 struct alc_spec *spec = codec->spec;
bbbc7e85 5999 spec->gen.pcm_rec[0]->stream[0].chmap = asus_pcm_2_1_chmaps;
8e383953
TI
6000 }
6001}
6002
bf68665d
TI
6003/* avoid D3 for keeping GPIO up */
6004static unsigned int gpio_led_power_filter(struct hda_codec *codec,
6005 hda_nid_t nid,
6006 unsigned int power_state)
6007{
6008 struct alc_spec *spec = codec->spec;
7639a06c 6009 if (nid == codec->core.afg && power_state == AC_PWRST_D3 && spec->gpio_led)
bf68665d
TI
6010 return AC_PWRST_D0;
6011 return power_state;
6012}
6013
3e887f37
TI
6014static void alc662_fixup_led_gpio1(struct hda_codec *codec,
6015 const struct hda_fixup *fix, int action)
6016{
6017 struct alc_spec *spec = codec->spec;
6018 static const struct hda_verb gpio_init[] = {
6019 { 0x01, AC_VERB_SET_GPIO_MASK, 0x01 },
6020 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01 },
6021 {}
6022 };
6023
6024 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
0f32fd19 6025 spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook;
3e887f37 6026 spec->gpio_led = 0;
0f32fd19
TI
6027 spec->mute_led_polarity = 1;
6028 spec->gpio_mute_led_mask = 0x01;
3e887f37 6029 snd_hda_add_verbs(codec, gpio_init);
bf68665d 6030 codec->power_filter = gpio_led_power_filter;
3e887f37
TI
6031 }
6032}
6033
f3f9185f
KY
6034static struct coef_fw alc668_coefs[] = {
6035 WRITE_COEF(0x01, 0xbebe), WRITE_COEF(0x02, 0xaaaa), WRITE_COEF(0x03, 0x0),
6036 WRITE_COEF(0x04, 0x0180), WRITE_COEF(0x06, 0x0), WRITE_COEF(0x07, 0x0f80),
6037 WRITE_COEF(0x08, 0x0031), WRITE_COEF(0x0a, 0x0060), WRITE_COEF(0x0b, 0x0),
6038 WRITE_COEF(0x0c, 0x7cf7), WRITE_COEF(0x0d, 0x1080), WRITE_COEF(0x0e, 0x7f7f),
6039 WRITE_COEF(0x0f, 0xcccc), WRITE_COEF(0x10, 0xddcc), WRITE_COEF(0x11, 0x0001),
6040 WRITE_COEF(0x13, 0x0), WRITE_COEF(0x14, 0x2aa0), WRITE_COEF(0x17, 0xa940),
6041 WRITE_COEF(0x19, 0x0), WRITE_COEF(0x1a, 0x0), WRITE_COEF(0x1b, 0x0),
6042 WRITE_COEF(0x1c, 0x0), WRITE_COEF(0x1d, 0x0), WRITE_COEF(0x1e, 0x7418),
6043 WRITE_COEF(0x1f, 0x0804), WRITE_COEF(0x20, 0x4200), WRITE_COEF(0x21, 0x0468),
6044 WRITE_COEF(0x22, 0x8ccc), WRITE_COEF(0x23, 0x0250), WRITE_COEF(0x24, 0x7418),
6045 WRITE_COEF(0x27, 0x0), WRITE_COEF(0x28, 0x8ccc), WRITE_COEF(0x2a, 0xff00),
6046 WRITE_COEF(0x2b, 0x8000), WRITE_COEF(0xa7, 0xff00), WRITE_COEF(0xa8, 0x8000),
6047 WRITE_COEF(0xaa, 0x2e17), WRITE_COEF(0xab, 0xa0c0), WRITE_COEF(0xac, 0x0),
6048 WRITE_COEF(0xad, 0x0), WRITE_COEF(0xae, 0x2ac6), WRITE_COEF(0xaf, 0xa480),
6049 WRITE_COEF(0xb0, 0x0), WRITE_COEF(0xb1, 0x0), WRITE_COEF(0xb2, 0x0),
6050 WRITE_COEF(0xb3, 0x0), WRITE_COEF(0xb4, 0x0), WRITE_COEF(0xb5, 0x1040),
6051 WRITE_COEF(0xb6, 0xd697), WRITE_COEF(0xb7, 0x902b), WRITE_COEF(0xb8, 0xd697),
6052 WRITE_COEF(0xb9, 0x902b), WRITE_COEF(0xba, 0xb8ba), WRITE_COEF(0xbb, 0xaaab),
6053 WRITE_COEF(0xbc, 0xaaaf), WRITE_COEF(0xbd, 0x6aaa), WRITE_COEF(0xbe, 0x1c02),
6054 WRITE_COEF(0xc0, 0x00ff), WRITE_COEF(0xc1, 0x0fa6),
6055 {}
6056};
6057
6058static void alc668_restore_default_value(struct hda_codec *codec)
6059{
6060 alc_process_coef_fw(codec, alc668_coefs);
6061}
6062
6cb3b707 6063enum {
2df03514 6064 ALC662_FIXUP_ASPIRE,
3e887f37 6065 ALC662_FIXUP_LED_GPIO1,
6cb3b707 6066 ALC662_FIXUP_IDEAPAD,
6be7948f 6067 ALC272_FIXUP_MARIO,
d2ebd479 6068 ALC662_FIXUP_CZC_P10T,
94024cd1 6069 ALC662_FIXUP_SKU_IGNORE,
e59ea3ed 6070 ALC662_FIXUP_HP_RP5800,
53c334ad
TI
6071 ALC662_FIXUP_ASUS_MODE1,
6072 ALC662_FIXUP_ASUS_MODE2,
6073 ALC662_FIXUP_ASUS_MODE3,
6074 ALC662_FIXUP_ASUS_MODE4,
6075 ALC662_FIXUP_ASUS_MODE5,
6076 ALC662_FIXUP_ASUS_MODE6,
6077 ALC662_FIXUP_ASUS_MODE7,
6078 ALC662_FIXUP_ASUS_MODE8,
1565cc35 6079 ALC662_FIXUP_NO_JACK_DETECT,
edfe3bfc 6080 ALC662_FIXUP_ZOTAC_Z68,
125821ae 6081 ALC662_FIXUP_INV_DMIC,
73bdd597
DH
6082 ALC668_FIXUP_DELL_MIC_NO_PRESENCE,
6083 ALC668_FIXUP_HEADSET_MODE,
8e54b4ac 6084 ALC662_FIXUP_BASS_MODE4_CHMAP,
61a75f13 6085 ALC662_FIXUP_BASS_16,
a30c9aaa 6086 ALC662_FIXUP_BASS_1A,
8e54b4ac 6087 ALC662_FIXUP_BASS_CHMAP,
493a52a9 6088 ALC668_FIXUP_AUTO_MUTE,
5e6db669 6089 ALC668_FIXUP_DELL_DISABLE_AAMIX,
033b0a7c 6090 ALC668_FIXUP_DELL_XPS13,
6cb3b707
DH
6091};
6092
1727a771 6093static const struct hda_fixup alc662_fixups[] = {
2df03514 6094 [ALC662_FIXUP_ASPIRE] = {
1727a771
TI
6095 .type = HDA_FIXUP_PINS,
6096 .v.pins = (const struct hda_pintbl[]) {
2df03514
DC
6097 { 0x15, 0x99130112 }, /* subwoofer */
6098 { }
6099 }
6100 },
3e887f37
TI
6101 [ALC662_FIXUP_LED_GPIO1] = {
6102 .type = HDA_FIXUP_FUNC,
6103 .v.func = alc662_fixup_led_gpio1,
6104 },
6cb3b707 6105 [ALC662_FIXUP_IDEAPAD] = {
1727a771
TI
6106 .type = HDA_FIXUP_PINS,
6107 .v.pins = (const struct hda_pintbl[]) {
6cb3b707
DH
6108 { 0x17, 0x99130112 }, /* subwoofer */
6109 { }
3e887f37
TI
6110 },
6111 .chained = true,
6112 .chain_id = ALC662_FIXUP_LED_GPIO1,
6cb3b707 6113 },
6be7948f 6114 [ALC272_FIXUP_MARIO] = {
1727a771 6115 .type = HDA_FIXUP_FUNC,
b5bfbc67 6116 .v.func = alc272_fixup_mario,
d2ebd479
AA
6117 },
6118 [ALC662_FIXUP_CZC_P10T] = {
1727a771 6119 .type = HDA_FIXUP_VERBS,
d2ebd479
AA
6120 .v.verbs = (const struct hda_verb[]) {
6121 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
6122 {}
6123 }
6124 },
94024cd1 6125 [ALC662_FIXUP_SKU_IGNORE] = {
1727a771 6126 .type = HDA_FIXUP_FUNC,
23d30f28 6127 .v.func = alc_fixup_sku_ignore,
c6b35874 6128 },
e59ea3ed 6129 [ALC662_FIXUP_HP_RP5800] = {
1727a771
TI
6130 .type = HDA_FIXUP_PINS,
6131 .v.pins = (const struct hda_pintbl[]) {
e59ea3ed
TI
6132 { 0x14, 0x0221201f }, /* HP out */
6133 { }
6134 },
6135 .chained = true,
6136 .chain_id = ALC662_FIXUP_SKU_IGNORE
6137 },
53c334ad 6138 [ALC662_FIXUP_ASUS_MODE1] = {
1727a771
TI
6139 .type = HDA_FIXUP_PINS,
6140 .v.pins = (const struct hda_pintbl[]) {
53c334ad
TI
6141 { 0x14, 0x99130110 }, /* speaker */
6142 { 0x18, 0x01a19c20 }, /* mic */
6143 { 0x19, 0x99a3092f }, /* int-mic */
6144 { 0x21, 0x0121401f }, /* HP out */
6145 { }
6146 },
6147 .chained = true,
6148 .chain_id = ALC662_FIXUP_SKU_IGNORE
6149 },
6150 [ALC662_FIXUP_ASUS_MODE2] = {
1727a771
TI
6151 .type = HDA_FIXUP_PINS,
6152 .v.pins = (const struct hda_pintbl[]) {
2996bdba
TI
6153 { 0x14, 0x99130110 }, /* speaker */
6154 { 0x18, 0x01a19820 }, /* mic */
6155 { 0x19, 0x99a3092f }, /* int-mic */
6156 { 0x1b, 0x0121401f }, /* HP out */
6157 { }
6158 },
53c334ad
TI
6159 .chained = true,
6160 .chain_id = ALC662_FIXUP_SKU_IGNORE
6161 },
6162 [ALC662_FIXUP_ASUS_MODE3] = {
1727a771
TI
6163 .type = HDA_FIXUP_PINS,
6164 .v.pins = (const struct hda_pintbl[]) {
53c334ad
TI
6165 { 0x14, 0x99130110 }, /* speaker */
6166 { 0x15, 0x0121441f }, /* HP */
6167 { 0x18, 0x01a19840 }, /* mic */
6168 { 0x19, 0x99a3094f }, /* int-mic */
6169 { 0x21, 0x01211420 }, /* HP2 */
6170 { }
6171 },
6172 .chained = true,
6173 .chain_id = ALC662_FIXUP_SKU_IGNORE
6174 },
6175 [ALC662_FIXUP_ASUS_MODE4] = {
1727a771
TI
6176 .type = HDA_FIXUP_PINS,
6177 .v.pins = (const struct hda_pintbl[]) {
53c334ad
TI
6178 { 0x14, 0x99130110 }, /* speaker */
6179 { 0x16, 0x99130111 }, /* speaker */
6180 { 0x18, 0x01a19840 }, /* mic */
6181 { 0x19, 0x99a3094f }, /* int-mic */
6182 { 0x21, 0x0121441f }, /* HP */
6183 { }
6184 },
6185 .chained = true,
6186 .chain_id = ALC662_FIXUP_SKU_IGNORE
6187 },
6188 [ALC662_FIXUP_ASUS_MODE5] = {
1727a771
TI
6189 .type = HDA_FIXUP_PINS,
6190 .v.pins = (const struct hda_pintbl[]) {
53c334ad
TI
6191 { 0x14, 0x99130110 }, /* speaker */
6192 { 0x15, 0x0121441f }, /* HP */
6193 { 0x16, 0x99130111 }, /* speaker */
6194 { 0x18, 0x01a19840 }, /* mic */
6195 { 0x19, 0x99a3094f }, /* int-mic */
6196 { }
6197 },
6198 .chained = true,
6199 .chain_id = ALC662_FIXUP_SKU_IGNORE
6200 },
6201 [ALC662_FIXUP_ASUS_MODE6] = {
1727a771
TI
6202 .type = HDA_FIXUP_PINS,
6203 .v.pins = (const struct hda_pintbl[]) {
53c334ad
TI
6204 { 0x14, 0x99130110 }, /* speaker */
6205 { 0x15, 0x01211420 }, /* HP2 */
6206 { 0x18, 0x01a19840 }, /* mic */
6207 { 0x19, 0x99a3094f }, /* int-mic */
6208 { 0x1b, 0x0121441f }, /* HP */
6209 { }
6210 },
6211 .chained = true,
6212 .chain_id = ALC662_FIXUP_SKU_IGNORE
6213 },
6214 [ALC662_FIXUP_ASUS_MODE7] = {
1727a771
TI
6215 .type = HDA_FIXUP_PINS,
6216 .v.pins = (const struct hda_pintbl[]) {
53c334ad
TI
6217 { 0x14, 0x99130110 }, /* speaker */
6218 { 0x17, 0x99130111 }, /* speaker */
6219 { 0x18, 0x01a19840 }, /* mic */
6220 { 0x19, 0x99a3094f }, /* int-mic */
6221 { 0x1b, 0x01214020 }, /* HP */
6222 { 0x21, 0x0121401f }, /* HP */
6223 { }
6224 },
6225 .chained = true,
6226 .chain_id = ALC662_FIXUP_SKU_IGNORE
6227 },
6228 [ALC662_FIXUP_ASUS_MODE8] = {
1727a771
TI
6229 .type = HDA_FIXUP_PINS,
6230 .v.pins = (const struct hda_pintbl[]) {
53c334ad
TI
6231 { 0x14, 0x99130110 }, /* speaker */
6232 { 0x12, 0x99a30970 }, /* int-mic */
6233 { 0x15, 0x01214020 }, /* HP */
6234 { 0x17, 0x99130111 }, /* speaker */
6235 { 0x18, 0x01a19840 }, /* mic */
6236 { 0x21, 0x0121401f }, /* HP */
6237 { }
6238 },
6239 .chained = true,
6240 .chain_id = ALC662_FIXUP_SKU_IGNORE
2996bdba 6241 },
1565cc35 6242 [ALC662_FIXUP_NO_JACK_DETECT] = {
1727a771 6243 .type = HDA_FIXUP_FUNC,
1565cc35
TI
6244 .v.func = alc_fixup_no_jack_detect,
6245 },
edfe3bfc 6246 [ALC662_FIXUP_ZOTAC_Z68] = {
1727a771
TI
6247 .type = HDA_FIXUP_PINS,
6248 .v.pins = (const struct hda_pintbl[]) {
edfe3bfc
DH
6249 { 0x1b, 0x02214020 }, /* Front HP */
6250 { }
6251 }
6252 },
125821ae 6253 [ALC662_FIXUP_INV_DMIC] = {
1727a771 6254 .type = HDA_FIXUP_FUNC,
9d36a7dc 6255 .v.func = alc_fixup_inv_dmic,
125821ae 6256 },
033b0a7c
GM
6257 [ALC668_FIXUP_DELL_XPS13] = {
6258 .type = HDA_FIXUP_FUNC,
6259 .v.func = alc_fixup_dell_xps13,
6260 .chained = true,
6261 .chain_id = ALC668_FIXUP_DELL_DISABLE_AAMIX
6262 },
5e6db669
GM
6263 [ALC668_FIXUP_DELL_DISABLE_AAMIX] = {
6264 .type = HDA_FIXUP_FUNC,
6265 .v.func = alc_fixup_disable_aamix,
6266 .chained = true,
6267 .chain_id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE
6268 },
493a52a9
HW
6269 [ALC668_FIXUP_AUTO_MUTE] = {
6270 .type = HDA_FIXUP_FUNC,
6271 .v.func = alc_fixup_auto_mute_via_amp,
6272 .chained = true,
6273 .chain_id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE
6274 },
73bdd597
DH
6275 [ALC668_FIXUP_DELL_MIC_NO_PRESENCE] = {
6276 .type = HDA_FIXUP_PINS,
6277 .v.pins = (const struct hda_pintbl[]) {
6278 { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
6279 { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */
6280 { }
6281 },
6282 .chained = true,
6283 .chain_id = ALC668_FIXUP_HEADSET_MODE
6284 },
6285 [ALC668_FIXUP_HEADSET_MODE] = {
6286 .type = HDA_FIXUP_FUNC,
6287 .v.func = alc_fixup_headset_mode_alc668,
6288 },
8e54b4ac 6289 [ALC662_FIXUP_BASS_MODE4_CHMAP] = {
8e383953 6290 .type = HDA_FIXUP_FUNC,
eb9ca3ab 6291 .v.func = alc_fixup_bass_chmap,
8e383953
TI
6292 .chained = true,
6293 .chain_id = ALC662_FIXUP_ASUS_MODE4
6294 },
61a75f13
DH
6295 [ALC662_FIXUP_BASS_16] = {
6296 .type = HDA_FIXUP_PINS,
6297 .v.pins = (const struct hda_pintbl[]) {
6298 {0x16, 0x80106111}, /* bass speaker */
6299 {}
6300 },
6301 .chained = true,
6302 .chain_id = ALC662_FIXUP_BASS_CHMAP,
6303 },
a30c9aaa
TI
6304 [ALC662_FIXUP_BASS_1A] = {
6305 .type = HDA_FIXUP_PINS,
6306 .v.pins = (const struct hda_pintbl[]) {
6307 {0x1a, 0x80106111}, /* bass speaker */
6308 {}
6309 },
8e54b4ac
DH
6310 .chained = true,
6311 .chain_id = ALC662_FIXUP_BASS_CHMAP,
a30c9aaa 6312 },
8e54b4ac 6313 [ALC662_FIXUP_BASS_CHMAP] = {
a30c9aaa 6314 .type = HDA_FIXUP_FUNC,
eb9ca3ab 6315 .v.func = alc_fixup_bass_chmap,
a30c9aaa 6316 },
6cb3b707
DH
6317};
6318
a9111321 6319static const struct snd_pci_quirk alc662_fixup_tbl[] = {
53c334ad 6320 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_FIXUP_ASUS_MODE2),
d3d3835c 6321 SND_PCI_QUIRK(0x1025, 0x022f, "Acer Aspire One", ALC662_FIXUP_INV_DMIC),
a6c47a85 6322 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
94024cd1 6323 SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
125821ae 6324 SND_PCI_QUIRK(0x1025, 0x0349, "eMachines eM250", ALC662_FIXUP_INV_DMIC),
1801928e 6325 SND_PCI_QUIRK(0x1025, 0x034a, "Gateway LT27", ALC662_FIXUP_INV_DMIC),
2df03514 6326 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
73bdd597
DH
6327 SND_PCI_QUIRK(0x1028, 0x05d8, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
6328 SND_PCI_QUIRK(0x1028, 0x05db, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
c5d019c3 6329 SND_PCI_QUIRK(0x1028, 0x05fe, "Dell XPS 15", ALC668_FIXUP_DELL_XPS13),
033b0a7c 6330 SND_PCI_QUIRK(0x1028, 0x060a, "Dell XPS 13", ALC668_FIXUP_DELL_XPS13),
09d2014f 6331 SND_PCI_QUIRK(0x1028, 0x0625, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
ad8ff99e 6332 SND_PCI_QUIRK(0x1028, 0x0626, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
8dc9abb9
KY
6333 SND_PCI_QUIRK(0x1028, 0x0696, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
6334 SND_PCI_QUIRK(0x1028, 0x0698, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
6a98e34b 6335 SND_PCI_QUIRK(0x1028, 0x069f, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
e59ea3ed 6336 SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800),
8e54b4ac
DH
6337 SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_BASS_1A),
6338 SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
61a75f13
DH
6339 SND_PCI_QUIRK(0x1043, 0x15a7, "ASUS UX51VZH", ALC662_FIXUP_BASS_16),
6340 SND_PCI_QUIRK(0x1043, 0x1b73, "ASUS N55SF", ALC662_FIXUP_BASS_16),
8e54b4ac 6341 SND_PCI_QUIRK(0x1043, 0x1bf3, "ASUS N76VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
1565cc35 6342 SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT),
53c334ad 6343 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2),
a0e90acc 6344 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
d4118588 6345 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
6cb3b707 6346 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
edfe3bfc 6347 SND_PCI_QUIRK(0x19da, 0xa130, "Zotac Z68", ALC662_FIXUP_ZOTAC_Z68),
d2ebd479 6348 SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
53c334ad
TI
6349
6350#if 0
6351 /* Below is a quirk table taken from the old code.
6352 * Basically the device should work as is without the fixup table.
6353 * If BIOS doesn't give a proper info, enable the corresponding
6354 * fixup entry.
7d7eb9ea 6355 */
53c334ad
TI
6356 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC662_FIXUP_ASUS_MODE1),
6357 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC662_FIXUP_ASUS_MODE3),
6358 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC662_FIXUP_ASUS_MODE1),
6359 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC662_FIXUP_ASUS_MODE3),
6360 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
6361 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
6362 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
6363 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC662_FIXUP_ASUS_MODE1),
6364 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC662_FIXUP_ASUS_MODE1),
6365 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
6366 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC662_FIXUP_ASUS_MODE7),
6367 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC662_FIXUP_ASUS_MODE7),
6368 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC662_FIXUP_ASUS_MODE8),
6369 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC662_FIXUP_ASUS_MODE3),
6370 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC662_FIXUP_ASUS_MODE1),
6371 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
6372 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_FIXUP_ASUS_MODE2),
6373 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC662_FIXUP_ASUS_MODE1),
6374 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
6375 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
6376 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
6377 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
6378 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC662_FIXUP_ASUS_MODE1),
6379 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC662_FIXUP_ASUS_MODE3),
6380 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_FIXUP_ASUS_MODE2),
6381 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
6382 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC662_FIXUP_ASUS_MODE5),
6383 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
6384 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
6385 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC662_FIXUP_ASUS_MODE1),
6386 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
6387 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
6388 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC662_FIXUP_ASUS_MODE3),
6389 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC662_FIXUP_ASUS_MODE3),
6390 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC662_FIXUP_ASUS_MODE1),
6391 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC662_FIXUP_ASUS_MODE1),
6392 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC662_FIXUP_ASUS_MODE1),
6393 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC662_FIXUP_ASUS_MODE1),
6394 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC662_FIXUP_ASUS_MODE1),
6395 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
6396 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_FIXUP_ASUS_MODE2),
6397 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC662_FIXUP_ASUS_MODE1),
6398 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
6399 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC662_FIXUP_ASUS_MODE3),
6400 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC662_FIXUP_ASUS_MODE1),
6401 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC662_FIXUP_ASUS_MODE1),
6402 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC662_FIXUP_ASUS_MODE1),
6403 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_FIXUP_ASUS_MODE2),
6404 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
6405 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE4),
6406#endif
6cb3b707
DH
6407 {}
6408};
6409
1727a771 6410static const struct hda_model_fixup alc662_fixup_models[] = {
6be7948f 6411 {.id = ALC272_FIXUP_MARIO, .name = "mario"},
53c334ad
TI
6412 {.id = ALC662_FIXUP_ASUS_MODE1, .name = "asus-mode1"},
6413 {.id = ALC662_FIXUP_ASUS_MODE2, .name = "asus-mode2"},
6414 {.id = ALC662_FIXUP_ASUS_MODE3, .name = "asus-mode3"},
6415 {.id = ALC662_FIXUP_ASUS_MODE4, .name = "asus-mode4"},
6416 {.id = ALC662_FIXUP_ASUS_MODE5, .name = "asus-mode5"},
6417 {.id = ALC662_FIXUP_ASUS_MODE6, .name = "asus-mode6"},
6418 {.id = ALC662_FIXUP_ASUS_MODE7, .name = "asus-mode7"},
6419 {.id = ALC662_FIXUP_ASUS_MODE8, .name = "asus-mode8"},
6e72aa5f 6420 {.id = ALC662_FIXUP_INV_DMIC, .name = "inv-dmic"},
e32aa85a 6421 {.id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE, .name = "dell-headset-multi"},
6be7948f
TB
6422 {}
6423};
6cb3b707 6424
532895c5 6425static const struct snd_hda_pin_quirk alc662_pin_fixup_tbl[] = {
76c2132e
DH
6426 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
6427 {0x12, 0x99a30130},
6428 {0x14, 0x90170110},
6429 {0x15, 0x0321101f},
6430 {0x16, 0x03011020},
6431 {0x18, 0x40000008},
6432 {0x19, 0x411111f0},
6433 {0x1a, 0x411111f0},
6434 {0x1b, 0x411111f0},
6435 {0x1d, 0x41000001},
6436 {0x1e, 0x411111f0},
6437 {0x1f, 0x411111f0}),
6438 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
6439 {0x12, 0x99a30140},
6440 {0x14, 0x90170110},
6441 {0x15, 0x0321101f},
6442 {0x16, 0x03011020},
6443 {0x18, 0x40000008},
6444 {0x19, 0x411111f0},
6445 {0x1a, 0x411111f0},
6446 {0x1b, 0x411111f0},
6447 {0x1d, 0x41000001},
6448 {0x1e, 0x411111f0},
6449 {0x1f, 0x411111f0}),
6450 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
6451 {0x12, 0x99a30150},
6452 {0x14, 0x90170110},
6453 {0x15, 0x0321101f},
6454 {0x16, 0x03011020},
6455 {0x18, 0x40000008},
6456 {0x19, 0x411111f0},
6457 {0x1a, 0x411111f0},
6458 {0x1b, 0x411111f0},
6459 {0x1d, 0x41000001},
6460 {0x1e, 0x411111f0},
6461 {0x1f, 0x411111f0}),
6462 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
6463 {0x12, 0x411111f0},
6464 {0x14, 0x90170110},
6465 {0x15, 0x0321101f},
6466 {0x16, 0x03011020},
6467 {0x18, 0x40000008},
6468 {0x19, 0x411111f0},
6469 {0x1a, 0x411111f0},
6470 {0x1b, 0x411111f0},
6471 {0x1d, 0x41000001},
6472 {0x1e, 0x411111f0},
6473 {0x1f, 0x411111f0}),
6474 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell XPS 15", ALC668_FIXUP_AUTO_MUTE,
6475 {0x12, 0x90a60130},
6476 {0x14, 0x90170110},
6477 {0x15, 0x0321101f},
6478 {0x16, 0x40000000},
6479 {0x18, 0x411111f0},
6480 {0x19, 0x411111f0},
6481 {0x1a, 0x411111f0},
6482 {0x1b, 0x411111f0},
6483 {0x1d, 0x40d6832d},
6484 {0x1e, 0x411111f0},
6485 {0x1f, 0x411111f0}),
532895c5
HW
6486 {}
6487};
6488
1d045db9
TI
6489/*
6490 */
bc9f98a9
KY
6491static int patch_alc662(struct hda_codec *codec)
6492{
6493 struct alc_spec *spec;
3de95173 6494 int err;
bc9f98a9 6495
3de95173
TI
6496 err = alc_alloc_spec(codec, 0x0b);
6497 if (err < 0)
6498 return err;
bc9f98a9 6499
3de95173 6500 spec = codec->spec;
1f0f4b80 6501
53c334ad
TI
6502 /* handle multiple HPs as is */
6503 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
6504
2c3bf9ab
TI
6505 alc_fix_pll_init(codec, 0x20, 0x04, 15);
6506
7639a06c 6507 switch (codec->core.vendor_id) {
f3f9185f
KY
6508 case 0x10ec0668:
6509 spec->init_hook = alc668_restore_default_value;
6510 break;
f3f9185f 6511 }
8663ff75 6512
1727a771 6513 snd_hda_pick_fixup(codec, alc662_fixup_models,
8e5a0509 6514 alc662_fixup_tbl, alc662_fixups);
532895c5 6515 snd_hda_pick_pin_fixup(codec, alc662_pin_fixup_tbl, alc662_fixups);
1727a771 6516 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
8e5a0509
TI
6517
6518 alc_auto_parse_customize_define(codec);
6519
7504b6cd
TI
6520 if (has_cdefine_beep(codec))
6521 spec->gen.beep_nid = 0x01;
6522
1bb7e43e 6523 if ((alc_get_coef0(codec) & (1 << 14)) &&
5100cd07 6524 codec->bus->pci && codec->bus->pci->subsystem_vendor == 0x1025 &&
e16fb6d1 6525 spec->cdefine.platform_type == 1) {
6134b1a2
WY
6526 err = alc_codec_rename(codec, "ALC272X");
6527 if (err < 0)
e16fb6d1 6528 goto error;
20ca0c35 6529 }
274693f3 6530
b9c5106c
TI
6531 /* automatic parse from the BIOS config */
6532 err = alc662_parse_auto_config(codec);
e16fb6d1
TI
6533 if (err < 0)
6534 goto error;
bc9f98a9 6535
7504b6cd 6536 if (!spec->gen.no_analog && spec->gen.beep_nid) {
7639a06c 6537 switch (codec->core.vendor_id) {
da00c244
KY
6538 case 0x10ec0662:
6539 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
6540 break;
6541 case 0x10ec0272:
6542 case 0x10ec0663:
6543 case 0x10ec0665:
9ad54547 6544 case 0x10ec0668:
da00c244
KY
6545 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
6546 break;
6547 case 0x10ec0273:
6548 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
6549 break;
6550 }
cec27c89 6551 }
2134ea4f 6552
bc9f98a9 6553 codec->patch_ops = alc_patch_ops;
1c716153 6554 spec->shutup = alc_eapd_shutup;
6cb3b707 6555
1727a771 6556 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
589876e2 6557
bc9f98a9 6558 return 0;
801f49d3 6559
e16fb6d1
TI
6560 error:
6561 alc_free(codec);
6562 return err;
b478b998
KY
6563}
6564
d1eb57f4
KY
6565/*
6566 * ALC680 support
6567 */
d1eb57f4 6568
d1eb57f4
KY
6569static int alc680_parse_auto_config(struct hda_codec *codec)
6570{
3e6179b8 6571 return alc_parse_auto_config(codec, NULL, NULL);
d1eb57f4
KY
6572}
6573
d1eb57f4 6574/*
d1eb57f4 6575 */
d1eb57f4
KY
6576static int patch_alc680(struct hda_codec *codec)
6577{
d1eb57f4
KY
6578 int err;
6579
1f0f4b80 6580 /* ALC680 has no aa-loopback mixer */
3de95173
TI
6581 err = alc_alloc_spec(codec, 0);
6582 if (err < 0)
6583 return err;
1f0f4b80 6584
1ebec5f2
TI
6585 /* automatic parse from the BIOS config */
6586 err = alc680_parse_auto_config(codec);
6587 if (err < 0) {
6588 alc_free(codec);
6589 return err;
d1eb57f4
KY
6590 }
6591
d1eb57f4 6592 codec->patch_ops = alc_patch_ops;
d1eb57f4
KY
6593
6594 return 0;
6595}
6596
1da177e4
LT
6597/*
6598 * patch entries
6599 */
a9111321 6600static const struct hda_codec_preset snd_hda_preset_realtek[] = {
296f0338 6601 { .id = 0x10ec0221, .name = "ALC221", .patch = patch_alc269 },
ba4c4d0a 6602 { .id = 0x10ec0231, .name = "ALC231", .patch = patch_alc269 },
84dfd0ac 6603 { .id = 0x10ec0233, .name = "ALC233", .patch = patch_alc269 },
92f974df 6604 { .id = 0x10ec0235, .name = "ALC233", .patch = patch_alc269 },
1d04c9de 6605 { .id = 0x10ec0255, .name = "ALC255", .patch = patch_alc269 },
4344aec8 6606 { .id = 0x10ec0256, .name = "ALC256", .patch = patch_alc269 },
1da177e4 6607 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
df694daa 6608 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
f6a92248 6609 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
a361d84b 6610 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
f6a92248 6611 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
ebb83eeb 6612 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 },
01afd41f 6613 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
ebb83eeb 6614 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
296f0338 6615 { .id = 0x10ec0276, .name = "ALC276", .patch = patch_alc269 },
befae82e 6616 { .id = 0x10ec0280, .name = "ALC280", .patch = patch_alc269 },
4e01ec63 6617 { .id = 0x10ec0282, .name = "ALC282", .patch = patch_alc269 },
7ff34ad8 6618 { .id = 0x10ec0283, .name = "ALC283", .patch = patch_alc269 },
065380f0 6619 { .id = 0x10ec0284, .name = "ALC284", .patch = patch_alc269 },
161ebf29 6620 { .id = 0x10ec0285, .name = "ALC285", .patch = patch_alc269 },
7fc7d047 6621 { .id = 0x10ec0286, .name = "ALC286", .patch = patch_alc269 },
7c665932 6622 { .id = 0x10ec0288, .name = "ALC288", .patch = patch_alc269 },
7ff34ad8 6623 { .id = 0x10ec0290, .name = "ALC290", .patch = patch_alc269 },
af02dde8 6624 { .id = 0x10ec0292, .name = "ALC292", .patch = patch_alc269 },
161ebf29 6625 { .id = 0x10ec0293, .name = "ALC293", .patch = patch_alc269 },
506b62c3 6626 { .id = 0x10ec0298, .name = "ALC298", .patch = patch_alc269 },
f32610ed 6627 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
bc9f98a9 6628 .patch = patch_alc861 },
f32610ed
JS
6629 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
6630 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
6631 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
bc9f98a9 6632 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
4953550a 6633 .patch = patch_alc882 },
bc9f98a9
KY
6634 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
6635 .patch = patch_alc662 },
cc667a72
DH
6636 { .id = 0x10ec0662, .rev = 0x100300, .name = "ALC662 rev3",
6637 .patch = patch_alc662 },
6dda9f4a 6638 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
cec27c89 6639 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
72009433 6640 { .id = 0x10ec0667, .name = "ALC667", .patch = patch_alc662 },
19a62823 6641 { .id = 0x10ec0668, .name = "ALC668", .patch = patch_alc662 },
6227cdce 6642 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
1d87caa6 6643 { .id = 0x10ec0671, .name = "ALC671", .patch = patch_alc662 },
d1eb57f4 6644 { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 },
b6c5fbad 6645 { .id = 0x10ec0867, .name = "ALC891", .patch = patch_alc882 },
f32610ed 6646 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
1da177e4 6647 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
4953550a 6648 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
669faba2 6649 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
4953550a 6650 .patch = patch_alc882 },
cb308f97 6651 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
4953550a 6652 .patch = patch_alc882 },
df694daa 6653 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
e16fb6d1 6654 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 },
4442608d 6655 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
4953550a 6656 .patch = patch_alc882 },
e16fb6d1 6657 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc882 },
4953550a 6658 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
274693f3 6659 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
e16fb6d1 6660 { .id = 0x10ec0899, .name = "ALC898", .patch = patch_alc882 },
19a62823 6661 { .id = 0x10ec0900, .name = "ALC1150", .patch = patch_alc882 },
1da177e4
LT
6662 {} /* terminator */
6663};
1289e9e8
TI
6664
6665MODULE_ALIAS("snd-hda-codec-id:10ec*");
6666
6667MODULE_LICENSE("GPL");
6668MODULE_DESCRIPTION("Realtek HD-audio codec");
6669
d8a766a1 6670static struct hda_codec_driver realtek_driver = {
1289e9e8 6671 .preset = snd_hda_preset_realtek,
1289e9e8
TI
6672};
6673
d8a766a1 6674module_hda_codec_driver(realtek_driver);