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