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