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