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