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