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