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