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