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