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