ALSA: hda/realtek - Fix the noise after suspend and resume on ALC282 codec
[deliverable/linux.git] / sound / pci / hda / patch_realtek.c
CommitLineData
1da177e4
LT
1/*
2 * Universal Interface for Intel High Definition Audio Codec
3 *
1d045db9 4 * HD audio interface patch for Realtek ALC codecs
1da177e4 5 *
df694daa
KY
6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7 * PeiSen Hou <pshou@realtek.com.tw>
1da177e4 8 * Takashi Iwai <tiwai@suse.de>
409a3e98 9 * Jonathan Woithe <jwoithe@just42.net>
1da177e4
LT
10 *
11 * This driver is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This driver is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */
25
1da177e4
LT
26#include <linux/init.h>
27#include <linux/delay.h>
28#include <linux/slab.h>
29#include <linux/pci.h>
08fb0d0e 30#include <linux/dmi.h>
da155d5b 31#include <linux/module.h>
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
7b5c7a02
KY
2789static void alc282_init(struct hda_codec *codec)
2790{
2791 struct alc_spec *spec = codec->spec;
2792 hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
2793 bool hp_pin_sense;
2794 int coef78;
2795
2796 if (!hp_pin)
2797 return;
2798 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
2799 coef78 = alc_read_coef_idx(codec, 0x78);
2800
2801 /* Index 0x78 Direct Drive HP AMP LPM Control 1 */
2802 /* Headphone capless set to high power mode */
2803 alc_write_coef_idx(codec, 0x78, 0x9004);
2804
2805 if (hp_pin_sense)
2806 msleep(2);
2807
2808 snd_hda_codec_write(codec, hp_pin, 0,
2809 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
2810
2811 if (hp_pin_sense)
2812 msleep(85);
2813
2814 snd_hda_codec_write(codec, hp_pin, 0,
2815 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
2816
2817 if (hp_pin_sense)
2818 msleep(100);
2819
2820 /* Headphone capless set to normal mode */
2821 alc_write_coef_idx(codec, 0x78, coef78);
2822}
2823
2824static void alc282_shutup(struct hda_codec *codec)
2825{
2826 struct alc_spec *spec = codec->spec;
2827 hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
2828 bool hp_pin_sense;
2829 int coef78;
2830
2831 if (!hp_pin) {
2832 alc269_shutup(codec);
2833 return;
2834 }
2835
2836 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
2837 coef78 = alc_read_coef_idx(codec, 0x78);
2838 alc_write_coef_idx(codec, 0x78, 0x9004);
2839
2840 if (hp_pin_sense)
2841 msleep(2);
2842
2843 snd_hda_codec_write(codec, hp_pin, 0,
2844 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
2845
2846 if (hp_pin_sense)
2847 msleep(85);
2848
2849 snd_hda_codec_write(codec, hp_pin, 0,
2850 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
2851
2852 if (hp_pin_sense)
2853 msleep(100);
2854
2855 alc_auto_setup_eapd(codec, false);
2856 snd_hda_shutup_pins(codec);
2857 alc_write_coef_idx(codec, 0x78, coef78);
2858}
2859
6bd55b04
KY
2860static void alc283_restore_default_value(struct hda_codec *codec)
2861{
2862 int val;
2863
2864 /* Power Down Control */
2865 alc_write_coef_idx(codec, 0x03, 0x0002);
2866 /* FIFO and filter clock */
2867 alc_write_coef_idx(codec, 0x05, 0x0700);
2868 /* DMIC control */
2869 alc_write_coef_idx(codec, 0x07, 0x0200);
2870 /* Analog clock */
2871 val = alc_read_coef_idx(codec, 0x06);
2872 alc_write_coef_idx(codec, 0x06, (val & ~0x00f0) | 0x0);
2873 /* JD */
2874 val = alc_read_coef_idx(codec, 0x08);
2875 alc_write_coef_idx(codec, 0x08, (val & ~0xfffc) | 0x0c2c);
2876 /* JD offset1 */
2877 alc_write_coef_idx(codec, 0x0a, 0xcccc);
2878 /* JD offset2 */
2879 alc_write_coef_idx(codec, 0x0b, 0xcccc);
2880 /* LDO1/2/3, DAC/ADC */
2881 alc_write_coef_idx(codec, 0x0e, 0x6fc0);
2882 /* JD */
2883 val = alc_read_coef_idx(codec, 0x0f);
2884 alc_write_coef_idx(codec, 0x0f, (val & ~0xf800) | 0x1000);
2885 /* Capless */
2886 val = alc_read_coef_idx(codec, 0x10);
2887 alc_write_coef_idx(codec, 0x10, (val & ~0xfc00) | 0x0c00);
2888 /* Class D test 4 */
2889 alc_write_coef_idx(codec, 0x3a, 0x0);
2890 /* IO power down directly */
2891 val = alc_read_coef_idx(codec, 0x0c);
2892 alc_write_coef_idx(codec, 0x0c, (val & ~0xfe00) | 0x0);
2893 /* ANC */
2894 alc_write_coef_idx(codec, 0x22, 0xa0c0);
2895 /* AGC MUX */
2896 val = alc_read_coefex_idx(codec, 0x53, 0x01);
2897 alc_write_coefex_idx(codec, 0x53, 0x01, (val & ~0x000f) | 0x0008);
2898 /* DAC simple content protection */
2899 val = alc_read_coef_idx(codec, 0x1d);
2900 alc_write_coef_idx(codec, 0x1d, (val & ~0x00e0) | 0x0);
2901 /* ADC simple content protection */
2902 val = alc_read_coef_idx(codec, 0x1f);
2903 alc_write_coef_idx(codec, 0x1f, (val & ~0x00e0) | 0x0);
2904 /* DAC ADC Zero Detection */
2905 alc_write_coef_idx(codec, 0x21, 0x8804);
2906 /* PLL */
2907 alc_write_coef_idx(codec, 0x2e, 0x2902);
2908 /* capless control 2 */
2909 alc_write_coef_idx(codec, 0x33, 0xa080);
2910 /* capless control 3 */
2911 alc_write_coef_idx(codec, 0x34, 0x3400);
2912 /* capless control 4 */
2913 alc_write_coef_idx(codec, 0x35, 0x2f3e);
2914 /* capless control 5 */
2915 alc_write_coef_idx(codec, 0x36, 0x0);
2916 /* class D test 2 */
2917 val = alc_read_coef_idx(codec, 0x38);
2918 alc_write_coef_idx(codec, 0x38, (val & ~0x0fff) | 0x0900);
2919 /* class D test 3 */
2920 alc_write_coef_idx(codec, 0x39, 0x110a);
2921 /* class D test 5 */
2922 val = alc_read_coef_idx(codec, 0x3b);
2923 alc_write_coef_idx(codec, 0x3b, (val & ~0x00f8) | 0x00d8);
2924 /* class D test 6 */
2925 alc_write_coef_idx(codec, 0x3c, 0x0014);
2926 /* classD OCP */
2927 alc_write_coef_idx(codec, 0x3d, 0xc2ba);
2928 /* classD pure DC test */
2929 val = alc_read_coef_idx(codec, 0x42);
2930 alc_write_coef_idx(codec, 0x42, (val & ~0x0f80) | 0x0);
2931 /* test mode */
2932 alc_write_coef_idx(codec, 0x49, 0x0);
2933 /* Class D DC enable */
2934 val = alc_read_coef_idx(codec, 0x40);
2935 alc_write_coef_idx(codec, 0x40, (val & ~0xf800) | 0x9800);
2936 /* DC offset */
2937 val = alc_read_coef_idx(codec, 0x42);
2938 alc_write_coef_idx(codec, 0x42, (val & ~0xf000) | 0x2000);
2939 /* Class D amp control */
2940 alc_write_coef_idx(codec, 0x37, 0xfc06);
2941}
2942
2af02be7
KY
2943static void alc283_init(struct hda_codec *codec)
2944{
2945 struct alc_spec *spec = codec->spec;
2946 hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
2947 bool hp_pin_sense;
2948 int val;
2949
6bd55b04
KY
2950 alc283_restore_default_value(codec);
2951
2af02be7
KY
2952 if (!hp_pin)
2953 return;
2954 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
2955
2956 /* Index 0x43 Direct Drive HP AMP LPM Control 1 */
2957 /* Headphone capless set to high power mode */
2958 alc_write_coef_idx(codec, 0x43, 0x9004);
2959
2960 snd_hda_codec_write(codec, hp_pin, 0,
2961 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
2962
2963 if (hp_pin_sense)
2964 msleep(85);
2965
2966 snd_hda_codec_write(codec, hp_pin, 0,
2967 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
2968
2969 if (hp_pin_sense)
2970 msleep(85);
2971 /* Index 0x46 Combo jack auto switch control 2 */
2972 /* 3k pull low control for Headset jack. */
2973 val = alc_read_coef_idx(codec, 0x46);
2974 alc_write_coef_idx(codec, 0x46, val & ~(3 << 12));
2975 /* Headphone capless set to normal mode */
2976 alc_write_coef_idx(codec, 0x43, 0x9614);
2977}
2978
2979static void alc283_shutup(struct hda_codec *codec)
2980{
2981 struct alc_spec *spec = codec->spec;
2982 hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
2983 bool hp_pin_sense;
2984 int val;
2985
2986 if (!hp_pin) {
2987 alc269_shutup(codec);
2988 return;
2989 }
2990
2991 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
2992
2993 alc_write_coef_idx(codec, 0x43, 0x9004);
2994
2995 snd_hda_codec_write(codec, hp_pin, 0,
2996 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
2997
2998 if (hp_pin_sense)
88011c09 2999 msleep(100);
2af02be7
KY
3000
3001 snd_hda_codec_write(codec, hp_pin, 0,
3002 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
3003
3004 val = alc_read_coef_idx(codec, 0x46);
3005 alc_write_coef_idx(codec, 0x46, val | (3 << 12));
3006
3007 if (hp_pin_sense)
88011c09 3008 msleep(100);
2af02be7
KY
3009 snd_hda_shutup_pins(codec);
3010 alc_write_coef_idx(codec, 0x43, 0x9614);
3011}
3012
ad60d502
KY
3013static void alc5505_coef_set(struct hda_codec *codec, unsigned int index_reg,
3014 unsigned int val)
3015{
3016 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_COEF_INDEX, index_reg >> 1);
3017 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_PROC_COEF, val & 0xffff); /* LSB */
3018 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_PROC_COEF, val >> 16); /* MSB */
3019}
3020
3021static int alc5505_coef_get(struct hda_codec *codec, unsigned int index_reg)
3022{
3023 unsigned int val;
3024
3025 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_COEF_INDEX, index_reg >> 1);
3026 val = snd_hda_codec_read(codec, 0x51, 0, AC_VERB_GET_PROC_COEF, 0)
3027 & 0xffff;
3028 val |= snd_hda_codec_read(codec, 0x51, 0, AC_VERB_GET_PROC_COEF, 0)
3029 << 16;
3030 return val;
3031}
3032
3033static void alc5505_dsp_halt(struct hda_codec *codec)
3034{
3035 unsigned int val;
3036
3037 alc5505_coef_set(codec, 0x3000, 0x000c); /* DSP CPU stop */
3038 alc5505_coef_set(codec, 0x880c, 0x0008); /* DDR enter self refresh */
3039 alc5505_coef_set(codec, 0x61c0, 0x11110080); /* Clock control for PLL and CPU */
3040 alc5505_coef_set(codec, 0x6230, 0xfc0d4011); /* Disable Input OP */
3041 alc5505_coef_set(codec, 0x61b4, 0x040a2b03); /* Stop PLL2 */
3042 alc5505_coef_set(codec, 0x61b0, 0x00005b17); /* Stop PLL1 */
3043 alc5505_coef_set(codec, 0x61b8, 0x04133303); /* Stop PLL3 */
3044 val = alc5505_coef_get(codec, 0x6220);
3045 alc5505_coef_set(codec, 0x6220, (val | 0x3000)); /* switch Ringbuffer clock to DBUS clock */
3046}
3047
3048static void alc5505_dsp_back_from_halt(struct hda_codec *codec)
3049{
3050 alc5505_coef_set(codec, 0x61b8, 0x04133302);
3051 alc5505_coef_set(codec, 0x61b0, 0x00005b16);
3052 alc5505_coef_set(codec, 0x61b4, 0x040a2b02);
3053 alc5505_coef_set(codec, 0x6230, 0xf80d4011);
3054 alc5505_coef_set(codec, 0x6220, 0x2002010f);
3055 alc5505_coef_set(codec, 0x880c, 0x00000004);
3056}
3057
3058static void alc5505_dsp_init(struct hda_codec *codec)
3059{
3060 unsigned int val;
3061
3062 alc5505_dsp_halt(codec);
3063 alc5505_dsp_back_from_halt(codec);
3064 alc5505_coef_set(codec, 0x61b0, 0x5b14); /* PLL1 control */
3065 alc5505_coef_set(codec, 0x61b0, 0x5b16);
3066 alc5505_coef_set(codec, 0x61b4, 0x04132b00); /* PLL2 control */
3067 alc5505_coef_set(codec, 0x61b4, 0x04132b02);
3068 alc5505_coef_set(codec, 0x61b8, 0x041f3300); /* PLL3 control*/
3069 alc5505_coef_set(codec, 0x61b8, 0x041f3302);
3070 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_CODEC_RESET, 0); /* Function reset */
3071 alc5505_coef_set(codec, 0x61b8, 0x041b3302);
3072 alc5505_coef_set(codec, 0x61b8, 0x04173302);
3073 alc5505_coef_set(codec, 0x61b8, 0x04163302);
3074 alc5505_coef_set(codec, 0x8800, 0x348b328b); /* DRAM control */
3075 alc5505_coef_set(codec, 0x8808, 0x00020022); /* DRAM control */
3076 alc5505_coef_set(codec, 0x8818, 0x00000400); /* DRAM control */
3077
3078 val = alc5505_coef_get(codec, 0x6200) >> 16; /* Read revision ID */
3079 if (val <= 3)
3080 alc5505_coef_set(codec, 0x6220, 0x2002010f); /* I/O PAD Configuration */
3081 else
3082 alc5505_coef_set(codec, 0x6220, 0x6002018f);
3083
3084 alc5505_coef_set(codec, 0x61ac, 0x055525f0); /**/
3085 alc5505_coef_set(codec, 0x61c0, 0x12230080); /* Clock control */
3086 alc5505_coef_set(codec, 0x61b4, 0x040e2b02); /* PLL2 control */
3087 alc5505_coef_set(codec, 0x61bc, 0x010234f8); /* OSC Control */
3088 alc5505_coef_set(codec, 0x880c, 0x00000004); /* DRAM Function control */
3089 alc5505_coef_set(codec, 0x880c, 0x00000003);
3090 alc5505_coef_set(codec, 0x880c, 0x00000010);
cd63a5ff
TI
3091
3092#ifdef HALT_REALTEK_ALC5505
3093 alc5505_dsp_halt(codec);
3094#endif
ad60d502
KY
3095}
3096
cd63a5ff
TI
3097#ifdef HALT_REALTEK_ALC5505
3098#define alc5505_dsp_suspend(codec) /* NOP */
3099#define alc5505_dsp_resume(codec) /* NOP */
3100#else
3101#define alc5505_dsp_suspend(codec) alc5505_dsp_halt(codec)
3102#define alc5505_dsp_resume(codec) alc5505_dsp_back_from_halt(codec)
3103#endif
3104
2a43952a 3105#ifdef CONFIG_PM
ad60d502
KY
3106static int alc269_suspend(struct hda_codec *codec)
3107{
3108 struct alc_spec *spec = codec->spec;
3109
3110 if (spec->has_alc5505_dsp)
cd63a5ff 3111 alc5505_dsp_suspend(codec);
ad60d502
KY
3112 return alc_suspend(codec);
3113}
3114
1d045db9
TI
3115static int alc269_resume(struct hda_codec *codec)
3116{
adcc70b2
KY
3117 struct alc_spec *spec = codec->spec;
3118
1387e2d1
KY
3119 if (spec->codec_variant == ALC269_TYPE_ALC269VB)
3120 alc269vb_toggle_power_output(codec, 0);
3121 if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
adcc70b2 3122 (alc_get_coef0(codec) & 0x00ff) == 0x018) {
1d045db9
TI
3123 msleep(150);
3124 }
8c427226 3125
1d045db9 3126 codec->patch_ops.init(codec);
f1d4e28b 3127
1387e2d1
KY
3128 if (spec->codec_variant == ALC269_TYPE_ALC269VB)
3129 alc269vb_toggle_power_output(codec, 1);
3130 if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
adcc70b2 3131 (alc_get_coef0(codec) & 0x00ff) == 0x017) {
1d045db9
TI
3132 msleep(200);
3133 }
f1d4e28b 3134
1d045db9
TI
3135 snd_hda_codec_resume_amp(codec);
3136 snd_hda_codec_resume_cache(codec);
0623a889 3137 alc_inv_dmic_sync(codec, true);
1d045db9 3138 hda_call_check_power_status(codec, 0x01);
ad60d502 3139 if (spec->has_alc5505_dsp)
cd63a5ff 3140 alc5505_dsp_resume(codec);
c5177c86 3141
1d045db9
TI
3142 return 0;
3143}
2a43952a 3144#endif /* CONFIG_PM */
f1d4e28b 3145
108cc108 3146static void alc269_fixup_pincfg_no_hp_to_lineout(struct hda_codec *codec,
1727a771 3147 const struct hda_fixup *fix, int action)
108cc108
DH
3148{
3149 struct alc_spec *spec = codec->spec;
3150
1727a771 3151 if (action == HDA_FIXUP_ACT_PRE_PROBE)
108cc108
DH
3152 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
3153}
3154
1d045db9 3155static void alc269_fixup_hweq(struct hda_codec *codec,
1727a771 3156 const struct hda_fixup *fix, int action)
1d045db9
TI
3157{
3158 int coef;
f1d4e28b 3159
1727a771 3160 if (action != HDA_FIXUP_ACT_INIT)
1d045db9
TI
3161 return;
3162 coef = alc_read_coef_idx(codec, 0x1e);
3163 alc_write_coef_idx(codec, 0x1e, coef | 0x80);
3164}
f1d4e28b 3165
7c478f03
DH
3166static void alc269_fixup_headset_mic(struct hda_codec *codec,
3167 const struct hda_fixup *fix, int action)
3168{
3169 struct alc_spec *spec = codec->spec;
3170
3171 if (action == HDA_FIXUP_ACT_PRE_PROBE)
3172 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
3173}
3174
1d045db9 3175static void alc271_fixup_dmic(struct hda_codec *codec,
1727a771 3176 const struct hda_fixup *fix, int action)
1d045db9
TI
3177{
3178 static const struct hda_verb verbs[] = {
3179 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
3180 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
3181 {}
3182 };
3183 unsigned int cfg;
f1d4e28b 3184
42397004
DR
3185 if (strcmp(codec->chip_name, "ALC271X") &&
3186 strcmp(codec->chip_name, "ALC269VB"))
1d045db9
TI
3187 return;
3188 cfg = snd_hda_codec_get_pincfg(codec, 0x12);
3189 if (get_defcfg_connect(cfg) == AC_JACK_PORT_FIXED)
3190 snd_hda_sequence_write(codec, verbs);
3191}
f1d4e28b 3192
017f2a10 3193static void alc269_fixup_pcm_44k(struct hda_codec *codec,
1727a771 3194 const struct hda_fixup *fix, int action)
017f2a10
TI
3195{
3196 struct alc_spec *spec = codec->spec;
3197
1727a771 3198 if (action != HDA_FIXUP_ACT_PROBE)
017f2a10
TI
3199 return;
3200
3201 /* Due to a hardware problem on Lenovo Ideadpad, we need to
3202 * fix the sample rate of analog I/O to 44.1kHz
3203 */
08c189f2
TI
3204 spec->gen.stream_analog_playback = &alc269_44k_pcm_analog_playback;
3205 spec->gen.stream_analog_capture = &alc269_44k_pcm_analog_capture;
017f2a10
TI
3206}
3207
adabb3ec 3208static void alc269_fixup_stereo_dmic(struct hda_codec *codec,
1727a771 3209 const struct hda_fixup *fix, int action)
adabb3ec
TI
3210{
3211 int coef;
3212
1727a771 3213 if (action != HDA_FIXUP_ACT_INIT)
adabb3ec
TI
3214 return;
3215 /* The digital-mic unit sends PDM (differential signal) instead of
3216 * the standard PCM, thus you can't record a valid mono stream as is.
3217 * Below is a workaround specific to ALC269 to control the dmic
3218 * signal source as mono.
3219 */
3220 coef = alc_read_coef_idx(codec, 0x07);
3221 alc_write_coef_idx(codec, 0x07, coef | 0x80);
3222}
3223
24519911
TI
3224static void alc269_quanta_automute(struct hda_codec *codec)
3225{
08c189f2 3226 snd_hda_gen_update_outputs(codec);
24519911
TI
3227
3228 snd_hda_codec_write(codec, 0x20, 0,
3229 AC_VERB_SET_COEF_INDEX, 0x0c);
3230 snd_hda_codec_write(codec, 0x20, 0,
3231 AC_VERB_SET_PROC_COEF, 0x680);
3232
3233 snd_hda_codec_write(codec, 0x20, 0,
3234 AC_VERB_SET_COEF_INDEX, 0x0c);
3235 snd_hda_codec_write(codec, 0x20, 0,
3236 AC_VERB_SET_PROC_COEF, 0x480);
3237}
3238
3239static void alc269_fixup_quanta_mute(struct hda_codec *codec,
1727a771 3240 const struct hda_fixup *fix, int action)
24519911
TI
3241{
3242 struct alc_spec *spec = codec->spec;
1727a771 3243 if (action != HDA_FIXUP_ACT_PROBE)
24519911 3244 return;
08c189f2 3245 spec->gen.automute_hook = alc269_quanta_automute;
24519911
TI
3246}
3247
d240d1dc
DH
3248static void alc269_x101_hp_automute_hook(struct hda_codec *codec,
3249 struct hda_jack_tbl *jack)
3250{
3251 struct alc_spec *spec = codec->spec;
3252 int vref;
3253 msleep(200);
3254 snd_hda_gen_hp_automute(codec, jack);
3255
3256 vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0;
3257 msleep(100);
3258 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3259 vref);
3260 msleep(500);
3261 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3262 vref);
3263}
3264
3265static void alc269_fixup_x101_headset_mic(struct hda_codec *codec,
3266 const struct hda_fixup *fix, int action)
3267{
3268 struct alc_spec *spec = codec->spec;
3269 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3270 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
3271 spec->gen.hp_automute_hook = alc269_x101_hp_automute_hook;
3272 }
3273}
3274
3275
08fb0d0e
TI
3276/* update mute-LED according to the speaker mute state via mic VREF pin */
3277static void alc269_fixup_mic_mute_hook(void *private_data, int enabled)
6d3cd5d4
DH
3278{
3279 struct hda_codec *codec = private_data;
08fb0d0e
TI
3280 struct alc_spec *spec = codec->spec;
3281 unsigned int pinval;
3282
3283 if (spec->mute_led_polarity)
3284 enabled = !enabled;
3285 pinval = AC_PINCTL_IN_EN |
3286 (enabled ? AC_PINCTL_VREF_HIZ : AC_PINCTL_VREF_80);
3287 if (spec->mute_led_nid)
3288 snd_hda_set_pin_ctl_cache(codec, spec->mute_led_nid, pinval);
6d3cd5d4
DH
3289}
3290
d5b6b65e
DH
3291/* Make sure the led works even in runtime suspend */
3292static unsigned int led_power_filter(struct hda_codec *codec,
3293 hda_nid_t nid,
3294 unsigned int power_state)
3295{
3296 struct alc_spec *spec = codec->spec;
3297
3298 if (power_state != AC_PWRST_D3 || nid != spec->mute_led_nid)
3299 return power_state;
3300
3301 /* Set pin ctl again, it might have just been set to 0 */
3302 snd_hda_set_pin_ctl(codec, nid,
3303 snd_hda_codec_get_pin_target(codec, nid));
3304
3305 return AC_PWRST_D0;
3306}
3307
08fb0d0e
TI
3308static void alc269_fixup_hp_mute_led(struct hda_codec *codec,
3309 const struct hda_fixup *fix, int action)
6d3cd5d4
DH
3310{
3311 struct alc_spec *spec = codec->spec;
08fb0d0e
TI
3312 const struct dmi_device *dev = NULL;
3313
3314 if (action != HDA_FIXUP_ACT_PRE_PROBE)
3315 return;
3316
3317 while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) {
3318 int pol, pin;
3319 if (sscanf(dev->name, "HP_Mute_LED_%d_%x", &pol, &pin) != 2)
3320 continue;
3321 if (pin < 0x0a || pin >= 0x10)
3322 break;
3323 spec->mute_led_polarity = pol;
3324 spec->mute_led_nid = pin - 0x0a + 0x18;
3325 spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook;
fd25a97a 3326 spec->gen.vmaster_mute_enum = 1;
d5b6b65e 3327 codec->power_filter = led_power_filter;
08fb0d0e
TI
3328 snd_printd("Detected mute LED for %x:%d\n", spec->mute_led_nid,
3329 spec->mute_led_polarity);
6d3cd5d4
DH
3330 break;
3331 }
3332}
3333
d06ac143
DH
3334static void alc269_fixup_hp_mute_led_mic1(struct hda_codec *codec,
3335 const struct hda_fixup *fix, int action)
3336{
3337 struct alc_spec *spec = codec->spec;
3338 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3339 spec->mute_led_polarity = 0;
3340 spec->mute_led_nid = 0x18;
3341 spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook;
3342 spec->gen.vmaster_mute_enum = 1;
d5b6b65e 3343 codec->power_filter = led_power_filter;
d06ac143
DH
3344 }
3345}
3346
08fb0d0e
TI
3347static void alc269_fixup_hp_mute_led_mic2(struct hda_codec *codec,
3348 const struct hda_fixup *fix, int action)
420b0feb
TI
3349{
3350 struct alc_spec *spec = codec->spec;
9bb1f06f 3351 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
08fb0d0e
TI
3352 spec->mute_led_polarity = 0;
3353 spec->mute_led_nid = 0x19;
3354 spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook;
fd25a97a 3355 spec->gen.vmaster_mute_enum = 1;
d5b6b65e 3356 codec->power_filter = led_power_filter;
420b0feb
TI
3357 }
3358}
3359
9f5c6faf
TI
3360/* turn on/off mute LED per vmaster hook */
3361static void alc269_fixup_hp_gpio_mute_hook(void *private_data, int enabled)
3362{
3363 struct hda_codec *codec = private_data;
3364 struct alc_spec *spec = codec->spec;
3365 unsigned int oldval = spec->gpio_led;
3366
3367 if (enabled)
3368 spec->gpio_led &= ~0x08;
3369 else
3370 spec->gpio_led |= 0x08;
3371 if (spec->gpio_led != oldval)
3372 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
3373 spec->gpio_led);
3374}
3375
3376/* turn on/off mic-mute LED per capture hook */
3377static void alc269_fixup_hp_gpio_mic_mute_hook(struct hda_codec *codec,
7fe30711
TI
3378 struct snd_kcontrol *kcontrol,
3379 struct snd_ctl_elem_value *ucontrol)
9f5c6faf
TI
3380{
3381 struct alc_spec *spec = codec->spec;
3382 unsigned int oldval = spec->gpio_led;
3383
3384 if (!ucontrol)
3385 return;
3386
3387 if (ucontrol->value.integer.value[0] ||
3388 ucontrol->value.integer.value[1])
3389 spec->gpio_led &= ~0x10;
3390 else
3391 spec->gpio_led |= 0x10;
3392 if (spec->gpio_led != oldval)
3393 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
3394 spec->gpio_led);
3395}
3396
3397static void alc269_fixup_hp_gpio_led(struct hda_codec *codec,
3398 const struct hda_fixup *fix, int action)
3399{
3400 struct alc_spec *spec = codec->spec;
3401 static const struct hda_verb gpio_init[] = {
3402 { 0x01, AC_VERB_SET_GPIO_MASK, 0x18 },
3403 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x18 },
3404 {}
3405 };
3406
3407 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3408 spec->gen.vmaster_mute.hook = alc269_fixup_hp_gpio_mute_hook;
3409 spec->gen.cap_sync_hook = alc269_fixup_hp_gpio_mic_mute_hook;
3410 spec->gpio_led = 0;
3411 snd_hda_add_verbs(codec, gpio_init);
3412 }
3413}
3414
73bdd597
DH
3415static void alc_headset_mode_unplugged(struct hda_codec *codec)
3416{
3417 int val;
3418
3419 switch (codec->vendor_id) {
9a22a8f5
KY
3420 case 0x10ec0255:
3421 /* LDO and MISC control */
3422 alc_write_coef_idx(codec, 0x1b, 0x0c0b);
3423 /* UAJ function set to menual mode */
3424 alc_write_coef_idx(codec, 0x45, 0xd089);
3425 /* Direct Drive HP Amp control(Set to verb control)*/
3426 val = alc_read_coefex_idx(codec, 0x57, 0x05);
3427 alc_write_coefex_idx(codec, 0x57, 0x05, val & ~(1<<14));
3428 /* Set MIC2 Vref gate with HP */
3429 alc_write_coef_idx(codec, 0x06, 0x6104);
3430 /* Direct Drive HP Amp control */
3431 alc_write_coefex_idx(codec, 0x57, 0x03, 0x8aa6);
3432 break;
73bdd597
DH
3433 case 0x10ec0283:
3434 alc_write_coef_idx(codec, 0x1b, 0x0c0b);
3435 alc_write_coef_idx(codec, 0x45, 0xc429);
3436 val = alc_read_coef_idx(codec, 0x35);
3437 alc_write_coef_idx(codec, 0x35, val & 0xbfff);
3438 alc_write_coef_idx(codec, 0x06, 0x2104);
3439 alc_write_coef_idx(codec, 0x1a, 0x0001);
3440 alc_write_coef_idx(codec, 0x26, 0x0004);
3441 alc_write_coef_idx(codec, 0x32, 0x42a3);
3442 break;
3443 case 0x10ec0292:
3444 alc_write_coef_idx(codec, 0x76, 0x000e);
3445 alc_write_coef_idx(codec, 0x6c, 0x2400);
3446 alc_write_coef_idx(codec, 0x18, 0x7308);
3447 alc_write_coef_idx(codec, 0x6b, 0xc429);
3448 break;
3449 case 0x10ec0668:
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 unplugged mode.\n");
3455}
3456
3457
3458static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin,
3459 hda_nid_t mic_pin)
3460{
3461 int val;
3462
3463 switch (codec->vendor_id) {
9a22a8f5
KY
3464 case 0x10ec0255:
3465 alc_write_coef_idx(codec, 0x45, 0xc489);
3466 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
3467 alc_write_coefex_idx(codec, 0x57, 0x03, 0x8aa6);
3468 /* Set MIC2 Vref gate to normal */
3469 alc_write_coef_idx(codec, 0x06, 0x6100);
3470 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
3471 break;
73bdd597
DH
3472 case 0x10ec0283:
3473 alc_write_coef_idx(codec, 0x45, 0xc429);
3474 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
3475 val = alc_read_coef_idx(codec, 0x35);
3476 alc_write_coef_idx(codec, 0x35, val | 1<<14);
3477 alc_write_coef_idx(codec, 0x06, 0x2100);
3478 alc_write_coef_idx(codec, 0x1a, 0x0021);
3479 alc_write_coef_idx(codec, 0x26, 0x008c);
3480 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
3481 break;
3482 case 0x10ec0292:
3483 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
3484 alc_write_coef_idx(codec, 0x19, 0xa208);
3485 alc_write_coef_idx(codec, 0x2e, 0xacf0);
3486 break;
3487 case 0x10ec0668:
3488 alc_write_coef_idx(codec, 0x11, 0x0001);
3489 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
3490 alc_write_coef_idx(codec, 0xb7, 0x802b);
3491 alc_write_coef_idx(codec, 0xb5, 0x1040);
3492 val = alc_read_coef_idx(codec, 0xc3);
3493 alc_write_coef_idx(codec, 0xc3, val | 1<<12);
3494 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
3495 break;
3496 }
3497 snd_printdd("Headset jack set to mic-in mode.\n");
3498}
3499
3500static void alc_headset_mode_default(struct hda_codec *codec)
3501{
3502 switch (codec->vendor_id) {
9a22a8f5
KY
3503 case 0x10ec0255:
3504 alc_write_coef_idx(codec, 0x45, 0xc089);
3505 alc_write_coef_idx(codec, 0x45, 0xc489);
3506 alc_write_coefex_idx(codec, 0x57, 0x03, 0x8ea6);
3507 alc_write_coef_idx(codec, 0x49, 0x0049);
3508 break;
73bdd597
DH
3509 case 0x10ec0283:
3510 alc_write_coef_idx(codec, 0x06, 0x2100);
3511 alc_write_coef_idx(codec, 0x32, 0x4ea3);
3512 break;
3513 case 0x10ec0292:
3514 alc_write_coef_idx(codec, 0x76, 0x000e);
3515 alc_write_coef_idx(codec, 0x6c, 0x2400);
3516 alc_write_coef_idx(codec, 0x6b, 0xc429);
3517 alc_write_coef_idx(codec, 0x18, 0x7308);
3518 break;
3519 case 0x10ec0668:
3520 alc_write_coef_idx(codec, 0x11, 0x0041);
3521 alc_write_coef_idx(codec, 0x15, 0x0d40);
3522 alc_write_coef_idx(codec, 0xb7, 0x802b);
3523 break;
3524 }
3525 snd_printdd("Headset jack set to headphone (default) mode.\n");
3526}
3527
3528/* Iphone type */
3529static void alc_headset_mode_ctia(struct hda_codec *codec)
3530{
3531 switch (codec->vendor_id) {
9a22a8f5
KY
3532 case 0x10ec0255:
3533 /* Set to CTIA type */
3534 alc_write_coef_idx(codec, 0x45, 0xd489);
3535 alc_write_coef_idx(codec, 0x1b, 0x0c2b);
3536 alc_write_coefex_idx(codec, 0x57, 0x03, 0x8ea6);
3537 break;
73bdd597
DH
3538 case 0x10ec0283:
3539 alc_write_coef_idx(codec, 0x45, 0xd429);
3540 alc_write_coef_idx(codec, 0x1b, 0x0c2b);
3541 alc_write_coef_idx(codec, 0x32, 0x4ea3);
3542 break;
3543 case 0x10ec0292:
3544 alc_write_coef_idx(codec, 0x6b, 0xd429);
3545 alc_write_coef_idx(codec, 0x76, 0x0008);
3546 alc_write_coef_idx(codec, 0x18, 0x7388);
3547 break;
3548 case 0x10ec0668:
d59915d0 3549 alc_write_coef_idx(codec, 0x11, 0x0001);
73bdd597
DH
3550 alc_write_coef_idx(codec, 0x15, 0x0d60);
3551 alc_write_coef_idx(codec, 0xc3, 0x0000);
3552 break;
3553 }
3554 snd_printdd("Headset jack set to iPhone-style headset mode.\n");
3555}
3556
3557/* Nokia type */
3558static void alc_headset_mode_omtp(struct hda_codec *codec)
3559{
3560 switch (codec->vendor_id) {
9a22a8f5
KY
3561 case 0x10ec0255:
3562 /* Set to OMTP Type */
3563 alc_write_coef_idx(codec, 0x45, 0xe489);
3564 alc_write_coef_idx(codec, 0x1b, 0x0c2b);
3565 alc_write_coefex_idx(codec, 0x57, 0x03, 0x8ea6);
3566 break;
73bdd597
DH
3567 case 0x10ec0283:
3568 alc_write_coef_idx(codec, 0x45, 0xe429);
3569 alc_write_coef_idx(codec, 0x1b, 0x0c2b);
3570 alc_write_coef_idx(codec, 0x32, 0x4ea3);
3571 break;
3572 case 0x10ec0292:
3573 alc_write_coef_idx(codec, 0x6b, 0xe429);
3574 alc_write_coef_idx(codec, 0x76, 0x0008);
3575 alc_write_coef_idx(codec, 0x18, 0x7388);
3576 break;
3577 case 0x10ec0668:
d59915d0 3578 alc_write_coef_idx(codec, 0x11, 0x0001);
73bdd597
DH
3579 alc_write_coef_idx(codec, 0x15, 0x0d50);
3580 alc_write_coef_idx(codec, 0xc3, 0x0000);
3581 break;
3582 }
3583 snd_printdd("Headset jack set to Nokia-style headset mode.\n");
3584}
3585
3586static void alc_determine_headset_type(struct hda_codec *codec)
3587{
3588 int val;
3589 bool is_ctia = false;
3590 struct alc_spec *spec = codec->spec;
3591
3592 switch (codec->vendor_id) {
9a22a8f5
KY
3593 case 0x10ec0255:
3594 /* combo jack auto switch control(Check type)*/
3595 alc_write_coef_idx(codec, 0x45, 0xd089);
3596 /* combo jack auto switch control(Vref conteol) */
3597 alc_write_coef_idx(codec, 0x49, 0x0149);
3598 msleep(300);
3599 val = alc_read_coef_idx(codec, 0x46);
3600 is_ctia = (val & 0x0070) == 0x0070;
3601 break;
73bdd597
DH
3602 case 0x10ec0283:
3603 alc_write_coef_idx(codec, 0x45, 0xd029);
3604 msleep(300);
3605 val = alc_read_coef_idx(codec, 0x46);
3606 is_ctia = (val & 0x0070) == 0x0070;
3607 break;
3608 case 0x10ec0292:
3609 alc_write_coef_idx(codec, 0x6b, 0xd429);
3610 msleep(300);
3611 val = alc_read_coef_idx(codec, 0x6c);
3612 is_ctia = (val & 0x001c) == 0x001c;
3613 break;
3614 case 0x10ec0668:
3615 alc_write_coef_idx(codec, 0x11, 0x0001);
3616 alc_write_coef_idx(codec, 0xb7, 0x802b);
3617 alc_write_coef_idx(codec, 0x15, 0x0d60);
3618 alc_write_coef_idx(codec, 0xc3, 0x0c00);
3619 msleep(300);
3620 val = alc_read_coef_idx(codec, 0xbe);
3621 is_ctia = (val & 0x1c02) == 0x1c02;
3622 break;
3623 }
3624
3625 snd_printdd("Headset jack detected iPhone-style headset: %s\n",
3626 is_ctia ? "yes" : "no");
3627 spec->current_headset_type = is_ctia ? ALC_HEADSET_TYPE_CTIA : ALC_HEADSET_TYPE_OMTP;
3628}
3629
3630static void alc_update_headset_mode(struct hda_codec *codec)
3631{
3632 struct alc_spec *spec = codec->spec;
3633
3634 hda_nid_t mux_pin = spec->gen.imux_pins[spec->gen.cur_mux[0]];
3635 hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
3636
3637 int new_headset_mode;
3638
3639 if (!snd_hda_jack_detect(codec, hp_pin))
3640 new_headset_mode = ALC_HEADSET_MODE_UNPLUGGED;
3641 else if (mux_pin == spec->headset_mic_pin)
3642 new_headset_mode = ALC_HEADSET_MODE_HEADSET;
3643 else if (mux_pin == spec->headphone_mic_pin)
3644 new_headset_mode = ALC_HEADSET_MODE_MIC;
3645 else
3646 new_headset_mode = ALC_HEADSET_MODE_HEADPHONE;
3647
5959a6bc
DH
3648 if (new_headset_mode == spec->current_headset_mode) {
3649 snd_hda_gen_update_outputs(codec);
73bdd597 3650 return;
5959a6bc 3651 }
73bdd597
DH
3652
3653 switch (new_headset_mode) {
3654 case ALC_HEADSET_MODE_UNPLUGGED:
3655 alc_headset_mode_unplugged(codec);
3656 spec->gen.hp_jack_present = false;
3657 break;
3658 case ALC_HEADSET_MODE_HEADSET:
3659 if (spec->current_headset_type == ALC_HEADSET_TYPE_UNKNOWN)
3660 alc_determine_headset_type(codec);
3661 if (spec->current_headset_type == ALC_HEADSET_TYPE_CTIA)
3662 alc_headset_mode_ctia(codec);
3663 else if (spec->current_headset_type == ALC_HEADSET_TYPE_OMTP)
3664 alc_headset_mode_omtp(codec);
3665 spec->gen.hp_jack_present = true;
3666 break;
3667 case ALC_HEADSET_MODE_MIC:
3668 alc_headset_mode_mic_in(codec, hp_pin, spec->headphone_mic_pin);
3669 spec->gen.hp_jack_present = false;
3670 break;
3671 case ALC_HEADSET_MODE_HEADPHONE:
3672 alc_headset_mode_default(codec);
3673 spec->gen.hp_jack_present = true;
3674 break;
3675 }
3676 if (new_headset_mode != ALC_HEADSET_MODE_MIC) {
3677 snd_hda_set_pin_ctl_cache(codec, hp_pin,
3678 AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN);
3679 if (spec->headphone_mic_pin)
3680 snd_hda_set_pin_ctl_cache(codec, spec->headphone_mic_pin,
3681 PIN_VREFHIZ);
3682 }
3683 spec->current_headset_mode = new_headset_mode;
3684
3685 snd_hda_gen_update_outputs(codec);
3686}
3687
3688static void alc_update_headset_mode_hook(struct hda_codec *codec,
7fe30711
TI
3689 struct snd_kcontrol *kcontrol,
3690 struct snd_ctl_elem_value *ucontrol)
73bdd597
DH
3691{
3692 alc_update_headset_mode(codec);
3693}
3694
3695static void alc_update_headset_jack_cb(struct hda_codec *codec, struct hda_jack_tbl *jack)
3696{
3697 struct alc_spec *spec = codec->spec;
5db4d34b 3698 spec->current_headset_type = ALC_HEADSET_TYPE_UNKNOWN;
73bdd597
DH
3699 snd_hda_gen_hp_automute(codec, jack);
3700}
3701
3702static void alc_probe_headset_mode(struct hda_codec *codec)
3703{
3704 int i;
3705 struct alc_spec *spec = codec->spec;
3706 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
3707
3708 /* Find mic pins */
3709 for (i = 0; i < cfg->num_inputs; i++) {
3710 if (cfg->inputs[i].is_headset_mic && !spec->headset_mic_pin)
3711 spec->headset_mic_pin = cfg->inputs[i].pin;
3712 if (cfg->inputs[i].is_headphone_mic && !spec->headphone_mic_pin)
3713 spec->headphone_mic_pin = cfg->inputs[i].pin;
3714 }
3715
3716 spec->gen.cap_sync_hook = alc_update_headset_mode_hook;
3717 spec->gen.automute_hook = alc_update_headset_mode;
3718 spec->gen.hp_automute_hook = alc_update_headset_jack_cb;
3719}
3720
3721static void alc_fixup_headset_mode(struct hda_codec *codec,
3722 const struct hda_fixup *fix, int action)
3723{
3724 struct alc_spec *spec = codec->spec;
3725
3726 switch (action) {
3727 case HDA_FIXUP_ACT_PRE_PROBE:
3728 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC | HDA_PINCFG_HEADPHONE_MIC;
3729 break;
3730 case HDA_FIXUP_ACT_PROBE:
3731 alc_probe_headset_mode(codec);
3732 break;
3733 case HDA_FIXUP_ACT_INIT:
3734 spec->current_headset_mode = 0;
3735 alc_update_headset_mode(codec);
3736 break;
3737 }
3738}
3739
3740static void alc_fixup_headset_mode_no_hp_mic(struct hda_codec *codec,
3741 const struct hda_fixup *fix, int action)
3742{
3743 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3744 struct alc_spec *spec = codec->spec;
3745 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
3746 }
3747 else
3748 alc_fixup_headset_mode(codec, fix, action);
3749}
3750
9a22a8f5
KY
3751static void alc_fixup_headset_mode_alc255(struct hda_codec *codec,
3752 const struct hda_fixup *fix, int action)
3753{
3754 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3755 /* Set to iphone type */
3756 alc_write_coef_idx(codec, 0x1b, 0x880b);
3757 alc_write_coef_idx(codec, 0x45, 0xd089);
3758 alc_write_coef_idx(codec, 0x1b, 0x080b);
3759 alc_write_coef_idx(codec, 0x46, 0x0004);
3760 alc_write_coef_idx(codec, 0x1b, 0x0c0b);
3761 msleep(30);
3762 }
3763 alc_fixup_headset_mode(codec, fix, action);
3764}
3765
493a52a9
HW
3766static void alc_fixup_auto_mute_via_amp(struct hda_codec *codec,
3767 const struct hda_fixup *fix, int action)
3768{
3769 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3770 struct alc_spec *spec = codec->spec;
3771 spec->gen.auto_mute_via_amp = 1;
3772 }
3773}
3774
9b745ab8
TI
3775static void alc_no_shutup(struct hda_codec *codec)
3776{
3777}
3778
3779static void alc_fixup_no_shutup(struct hda_codec *codec,
3780 const struct hda_fixup *fix, int action)
3781{
3782 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3783 struct alc_spec *spec = codec->spec;
3784 spec->shutup = alc_no_shutup;
3785 }
3786}
3787
73bdd597
DH
3788static void alc_fixup_headset_mode_alc668(struct hda_codec *codec,
3789 const struct hda_fixup *fix, int action)
3790{
3791 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3792 int val;
3793 alc_write_coef_idx(codec, 0xc4, 0x8000);
3794 val = alc_read_coef_idx(codec, 0xc2);
3795 alc_write_coef_idx(codec, 0xc2, val & 0xfe);
3796 snd_hda_set_pin_ctl_cache(codec, 0x18, 0);
3797 }
3798 alc_fixup_headset_mode(codec, fix, action);
3799}
3800
bde7bc60
CCC
3801/* Returns the nid of the external mic input pin, or 0 if it cannot be found. */
3802static int find_ext_mic_pin(struct hda_codec *codec)
3803{
3804 struct alc_spec *spec = codec->spec;
3805 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
3806 hda_nid_t nid;
3807 unsigned int defcfg;
3808 int i;
3809
3810 for (i = 0; i < cfg->num_inputs; i++) {
3811 if (cfg->inputs[i].type != AUTO_PIN_MIC)
3812 continue;
3813 nid = cfg->inputs[i].pin;
3814 defcfg = snd_hda_codec_get_pincfg(codec, nid);
3815 if (snd_hda_get_input_pin_attr(defcfg) == INPUT_PIN_ATTR_INT)
3816 continue;
3817 return nid;
3818 }
3819
3820 return 0;
3821}
3822
08a978db 3823static void alc271_hp_gate_mic_jack(struct hda_codec *codec,
1727a771 3824 const struct hda_fixup *fix,
08a978db
DR
3825 int action)
3826{
3827 struct alc_spec *spec = codec->spec;
3828
0db75790 3829 if (action == HDA_FIXUP_ACT_PROBE) {
bde7bc60
CCC
3830 int mic_pin = find_ext_mic_pin(codec);
3831 int hp_pin = spec->gen.autocfg.hp_pins[0];
3832
3833 if (snd_BUG_ON(!mic_pin || !hp_pin))
0db75790 3834 return;
bde7bc60 3835 snd_hda_jack_set_gating_jack(codec, mic_pin, hp_pin);
0db75790 3836 }
08a978db 3837}
693b613d 3838
3e0d611b
DH
3839static void alc269_fixup_limit_int_mic_boost(struct hda_codec *codec,
3840 const struct hda_fixup *fix,
3841 int action)
3842{
3843 struct alc_spec *spec = codec->spec;
3844 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
3845 int i;
3846
3847 /* The mic boosts on level 2 and 3 are too noisy
3848 on the internal mic input.
3849 Therefore limit the boost to 0 or 1. */
3850
3851 if (action != HDA_FIXUP_ACT_PROBE)
3852 return;
3853
3854 for (i = 0; i < cfg->num_inputs; i++) {
3855 hda_nid_t nid = cfg->inputs[i].pin;
3856 unsigned int defcfg;
3857 if (cfg->inputs[i].type != AUTO_PIN_MIC)
3858 continue;
3859 defcfg = snd_hda_codec_get_pincfg(codec, nid);
3860 if (snd_hda_get_input_pin_attr(defcfg) != INPUT_PIN_ATTR_INT)
3861 continue;
3862
3863 snd_hda_override_amp_caps(codec, nid, HDA_INPUT,
3864 (0x00 << AC_AMPCAP_OFFSET_SHIFT) |
3865 (0x01 << AC_AMPCAP_NUM_STEPS_SHIFT) |
3866 (0x2f << AC_AMPCAP_STEP_SIZE_SHIFT) |
3867 (0 << AC_AMPCAP_MUTE_SHIFT));
3868 }
3869}
3870
cd217a63
KY
3871static void alc283_hp_automute_hook(struct hda_codec *codec,
3872 struct hda_jack_tbl *jack)
3873{
3874 struct alc_spec *spec = codec->spec;
3875 int vref;
3876
3877 msleep(200);
3878 snd_hda_gen_hp_automute(codec, jack);
3879
3880 vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0;
3881
3882 msleep(600);
3883 snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3884 vref);
3885}
3886
cd217a63
KY
3887static void alc283_fixup_chromebook(struct hda_codec *codec,
3888 const struct hda_fixup *fix, int action)
3889{
3890 struct alc_spec *spec = codec->spec;
3891 int val;
3892
3893 switch (action) {
3894 case HDA_FIXUP_ACT_PRE_PROBE:
0202e99c 3895 snd_hda_override_wcaps(codec, 0x03, 0);
d2e92709
TI
3896 /* Disable AA-loopback as it causes white noise */
3897 spec->gen.mixer_nid = 0;
38070219 3898 break;
0202e99c
KY
3899 case HDA_FIXUP_ACT_INIT:
3900 /* Enable Line1 input control by verb */
3901 val = alc_read_coef_idx(codec, 0x1a);
3902 alc_write_coef_idx(codec, 0x1a, val | (1 << 4));
3903 break;
3904 }
3905}
3906
3907static void alc283_fixup_sense_combo_jack(struct hda_codec *codec,
3908 const struct hda_fixup *fix, int action)
3909{
3910 struct alc_spec *spec = codec->spec;
3911 int val;
3912
3913 switch (action) {
3914 case HDA_FIXUP_ACT_PRE_PROBE:
cd217a63 3915 spec->gen.hp_automute_hook = alc283_hp_automute_hook;
38070219
KY
3916 break;
3917 case HDA_FIXUP_ACT_INIT:
cd217a63
KY
3918 /* MIC2-VREF control */
3919 /* Set to manual mode */
3920 val = alc_read_coef_idx(codec, 0x06);
3921 alc_write_coef_idx(codec, 0x06, val & ~0x000c);
3922 break;
3923 }
3924}
3925
7bba2157
TI
3926/* mute tablet speaker pin (0x14) via dock plugging in addition */
3927static void asus_tx300_automute(struct hda_codec *codec)
3928{
3929 struct alc_spec *spec = codec->spec;
3930 snd_hda_gen_update_outputs(codec);
3931 if (snd_hda_jack_detect(codec, 0x1b))
3932 spec->gen.mute_bits |= (1ULL << 0x14);
3933}
3934
3935static void alc282_fixup_asus_tx300(struct hda_codec *codec,
3936 const struct hda_fixup *fix, int action)
3937{
3938 struct alc_spec *spec = codec->spec;
3939 /* TX300 needs to set up GPIO2 for the speaker amp */
3940 static const struct hda_verb gpio2_verbs[] = {
3941 { 0x01, AC_VERB_SET_GPIO_MASK, 0x04 },
3942 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04 },
3943 { 0x01, AC_VERB_SET_GPIO_DATA, 0x04 },
3944 {}
3945 };
3946 static const struct hda_pintbl dock_pins[] = {
3947 { 0x1b, 0x21114000 }, /* dock speaker pin */
3948 {}
3949 };
3950 struct snd_kcontrol *kctl;
3951
3952 switch (action) {
3953 case HDA_FIXUP_ACT_PRE_PROBE:
3954 snd_hda_add_verbs(codec, gpio2_verbs);
3955 snd_hda_apply_pincfgs(codec, dock_pins);
3956 spec->gen.auto_mute_via_amp = 1;
3957 spec->gen.automute_hook = asus_tx300_automute;
3958 snd_hda_jack_detect_enable_callback(codec, 0x1b,
3959 HDA_GEN_HP_EVENT,
3960 snd_hda_gen_hp_automute);
3961 break;
3962 case HDA_FIXUP_ACT_BUILD:
3963 /* this is a bit tricky; give more sane names for the main
3964 * (tablet) speaker and the dock speaker, respectively
3965 */
3966 kctl = snd_hda_find_mixer_ctl(codec, "Speaker Playback Switch");
3967 if (kctl)
3968 strcpy(kctl->id.name, "Dock Speaker Playback Switch");
3969 kctl = snd_hda_find_mixer_ctl(codec, "Bass Speaker Playback Switch");
3970 if (kctl)
3971 strcpy(kctl->id.name, "Speaker Playback Switch");
3972 break;
3973 }
3974}
3975
338cae56
DH
3976static void alc290_fixup_mono_speakers(struct hda_codec *codec,
3977 const struct hda_fixup *fix, int action)
3978{
0f4881dc
DH
3979 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3980 /* DAC node 0x03 is giving mono output. We therefore want to
3981 make sure 0x14 (front speaker) and 0x15 (headphones) use the
3982 stereo DAC, while leaving 0x17 (bass speaker) for node 0x03. */
3983 hda_nid_t conn1[2] = { 0x0c };
3984 snd_hda_override_conn_list(codec, 0x14, 1, conn1);
3985 snd_hda_override_conn_list(codec, 0x15, 1, conn1);
3986 }
338cae56
DH
3987}
3988
b317b032
TI
3989/* for hda_fixup_thinkpad_acpi() */
3990#include "thinkpad_helper.c"
b67ae3f1 3991
1d045db9
TI
3992enum {
3993 ALC269_FIXUP_SONY_VAIO,
3994 ALC275_FIXUP_SONY_VAIO_GPIO2,
3995 ALC269_FIXUP_DELL_M101Z,
3996 ALC269_FIXUP_SKU_IGNORE,
3997 ALC269_FIXUP_ASUS_G73JW,
3998 ALC269_FIXUP_LENOVO_EAPD,
3999 ALC275_FIXUP_SONY_HWEQ,
4000 ALC271_FIXUP_DMIC,
017f2a10 4001 ALC269_FIXUP_PCM_44K,
adabb3ec 4002 ALC269_FIXUP_STEREO_DMIC,
7c478f03 4003 ALC269_FIXUP_HEADSET_MIC,
24519911
TI
4004 ALC269_FIXUP_QUANTA_MUTE,
4005 ALC269_FIXUP_LIFEBOOK,
a4297b5d
TI
4006 ALC269_FIXUP_AMIC,
4007 ALC269_FIXUP_DMIC,
4008 ALC269VB_FIXUP_AMIC,
4009 ALC269VB_FIXUP_DMIC,
08fb0d0e 4010 ALC269_FIXUP_HP_MUTE_LED,
d06ac143 4011 ALC269_FIXUP_HP_MUTE_LED_MIC1,
08fb0d0e 4012 ALC269_FIXUP_HP_MUTE_LED_MIC2,
9f5c6faf 4013 ALC269_FIXUP_HP_GPIO_LED,
693b613d 4014 ALC269_FIXUP_INV_DMIC,
108cc108 4015 ALC269_FIXUP_LENOVO_DOCK,
9b745ab8 4016 ALC269_FIXUP_NO_SHUTUP,
88cfcf86 4017 ALC286_FIXUP_SONY_MIC_NO_PRESENCE,
108cc108 4018 ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT,
73bdd597
DH
4019 ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
4020 ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
338cae56 4021 ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
73bdd597
DH
4022 ALC269_FIXUP_HEADSET_MODE,
4023 ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC,
d240d1dc
DH
4024 ALC269_FIXUP_ASUS_X101_FUNC,
4025 ALC269_FIXUP_ASUS_X101_VERB,
4026 ALC269_FIXUP_ASUS_X101,
08a978db
DR
4027 ALC271_FIXUP_AMIC_MIC2,
4028 ALC271_FIXUP_HP_GATE_MIC_JACK,
b1e8972e 4029 ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572,
42397004 4030 ALC269_FIXUP_ACER_AC700,
3e0d611b 4031 ALC269_FIXUP_LIMIT_INT_MIC_BOOST,
2cede303 4032 ALC269VB_FIXUP_ASUS_ZENBOOK,
23870831 4033 ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A,
8e35cd4a 4034 ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED,
02b504d9 4035 ALC269VB_FIXUP_ORDISSIMO_EVE2,
cd217a63 4036 ALC283_FIXUP_CHROME_BOOK,
0202e99c 4037 ALC283_FIXUP_SENSE_COMBO_JACK,
7bba2157 4038 ALC282_FIXUP_ASUS_TX300,
1bb3e062 4039 ALC283_FIXUP_INT_MIC,
338cae56 4040 ALC290_FIXUP_MONO_SPEAKERS,
0f4881dc
DH
4041 ALC290_FIXUP_MONO_SPEAKERS_HSJACK,
4042 ALC290_FIXUP_SUBWOOFER,
4043 ALC290_FIXUP_SUBWOOFER_HSJACK,
b67ae3f1 4044 ALC269_FIXUP_THINKPAD_ACPI,
9a22a8f5
KY
4045 ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
4046 ALC255_FIXUP_HEADSET_MODE,
f1d4e28b
KY
4047};
4048
1727a771 4049static const struct hda_fixup alc269_fixups[] = {
1d045db9 4050 [ALC269_FIXUP_SONY_VAIO] = {
fd108215
TI
4051 .type = HDA_FIXUP_PINCTLS,
4052 .v.pins = (const struct hda_pintbl[]) {
4053 {0x19, PIN_VREFGRD},
1d045db9
TI
4054 {}
4055 }
f1d4e28b 4056 },
1d045db9 4057 [ALC275_FIXUP_SONY_VAIO_GPIO2] = {
1727a771 4058 .type = HDA_FIXUP_VERBS,
1d045db9
TI
4059 .v.verbs = (const struct hda_verb[]) {
4060 {0x01, AC_VERB_SET_GPIO_MASK, 0x04},
4061 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04},
4062 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4063 { }
4064 },
4065 .chained = true,
4066 .chain_id = ALC269_FIXUP_SONY_VAIO
4067 },
4068 [ALC269_FIXUP_DELL_M101Z] = {
1727a771 4069 .type = HDA_FIXUP_VERBS,
1d045db9
TI
4070 .v.verbs = (const struct hda_verb[]) {
4071 /* Enables internal speaker */
4072 {0x20, AC_VERB_SET_COEF_INDEX, 13},
4073 {0x20, AC_VERB_SET_PROC_COEF, 0x4040},
4074 {}
4075 }
4076 },
4077 [ALC269_FIXUP_SKU_IGNORE] = {
1727a771 4078 .type = HDA_FIXUP_FUNC,
23d30f28 4079 .v.func = alc_fixup_sku_ignore,
1d045db9
TI
4080 },
4081 [ALC269_FIXUP_ASUS_G73JW] = {
1727a771
TI
4082 .type = HDA_FIXUP_PINS,
4083 .v.pins = (const struct hda_pintbl[]) {
1d045db9
TI
4084 { 0x17, 0x99130111 }, /* subwoofer */
4085 { }
4086 }
4087 },
4088 [ALC269_FIXUP_LENOVO_EAPD] = {
1727a771 4089 .type = HDA_FIXUP_VERBS,
1d045db9
TI
4090 .v.verbs = (const struct hda_verb[]) {
4091 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
4092 {}
4093 }
4094 },
4095 [ALC275_FIXUP_SONY_HWEQ] = {
1727a771 4096 .type = HDA_FIXUP_FUNC,
1d045db9
TI
4097 .v.func = alc269_fixup_hweq,
4098 .chained = true,
4099 .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2
4100 },
4101 [ALC271_FIXUP_DMIC] = {
1727a771 4102 .type = HDA_FIXUP_FUNC,
1d045db9 4103 .v.func = alc271_fixup_dmic,
f1d4e28b 4104 },
017f2a10 4105 [ALC269_FIXUP_PCM_44K] = {
1727a771 4106 .type = HDA_FIXUP_FUNC,
017f2a10 4107 .v.func = alc269_fixup_pcm_44k,
012e7eb1
DH
4108 .chained = true,
4109 .chain_id = ALC269_FIXUP_QUANTA_MUTE
017f2a10 4110 },
adabb3ec 4111 [ALC269_FIXUP_STEREO_DMIC] = {
1727a771 4112 .type = HDA_FIXUP_FUNC,
adabb3ec
TI
4113 .v.func = alc269_fixup_stereo_dmic,
4114 },
7c478f03
DH
4115 [ALC269_FIXUP_HEADSET_MIC] = {
4116 .type = HDA_FIXUP_FUNC,
4117 .v.func = alc269_fixup_headset_mic,
4118 },
24519911 4119 [ALC269_FIXUP_QUANTA_MUTE] = {
1727a771 4120 .type = HDA_FIXUP_FUNC,
24519911
TI
4121 .v.func = alc269_fixup_quanta_mute,
4122 },
4123 [ALC269_FIXUP_LIFEBOOK] = {
1727a771
TI
4124 .type = HDA_FIXUP_PINS,
4125 .v.pins = (const struct hda_pintbl[]) {
24519911
TI
4126 { 0x1a, 0x2101103f }, /* dock line-out */
4127 { 0x1b, 0x23a11040 }, /* dock mic-in */
4128 { }
4129 },
4130 .chained = true,
4131 .chain_id = ALC269_FIXUP_QUANTA_MUTE
4132 },
a4297b5d 4133 [ALC269_FIXUP_AMIC] = {
1727a771
TI
4134 .type = HDA_FIXUP_PINS,
4135 .v.pins = (const struct hda_pintbl[]) {
a4297b5d
TI
4136 { 0x14, 0x99130110 }, /* speaker */
4137 { 0x15, 0x0121401f }, /* HP out */
4138 { 0x18, 0x01a19c20 }, /* mic */
4139 { 0x19, 0x99a3092f }, /* int-mic */
4140 { }
4141 },
4142 },
4143 [ALC269_FIXUP_DMIC] = {
1727a771
TI
4144 .type = HDA_FIXUP_PINS,
4145 .v.pins = (const struct hda_pintbl[]) {
a4297b5d
TI
4146 { 0x12, 0x99a3092f }, /* int-mic */
4147 { 0x14, 0x99130110 }, /* speaker */
4148 { 0x15, 0x0121401f }, /* HP out */
4149 { 0x18, 0x01a19c20 }, /* mic */
4150 { }
4151 },
4152 },
4153 [ALC269VB_FIXUP_AMIC] = {
1727a771
TI
4154 .type = HDA_FIXUP_PINS,
4155 .v.pins = (const struct hda_pintbl[]) {
a4297b5d
TI
4156 { 0x14, 0x99130110 }, /* speaker */
4157 { 0x18, 0x01a19c20 }, /* mic */
4158 { 0x19, 0x99a3092f }, /* int-mic */
4159 { 0x21, 0x0121401f }, /* HP out */
4160 { }
4161 },
4162 },
2267ea97 4163 [ALC269VB_FIXUP_DMIC] = {
1727a771
TI
4164 .type = HDA_FIXUP_PINS,
4165 .v.pins = (const struct hda_pintbl[]) {
a4297b5d
TI
4166 { 0x12, 0x99a3092f }, /* int-mic */
4167 { 0x14, 0x99130110 }, /* speaker */
4168 { 0x18, 0x01a19c20 }, /* mic */
4169 { 0x21, 0x0121401f }, /* HP out */
4170 { }
4171 },
4172 },
08fb0d0e 4173 [ALC269_FIXUP_HP_MUTE_LED] = {
1727a771 4174 .type = HDA_FIXUP_FUNC,
08fb0d0e 4175 .v.func = alc269_fixup_hp_mute_led,
6d3cd5d4 4176 },
d06ac143
DH
4177 [ALC269_FIXUP_HP_MUTE_LED_MIC1] = {
4178 .type = HDA_FIXUP_FUNC,
4179 .v.func = alc269_fixup_hp_mute_led_mic1,
4180 },
08fb0d0e 4181 [ALC269_FIXUP_HP_MUTE_LED_MIC2] = {
1727a771 4182 .type = HDA_FIXUP_FUNC,
08fb0d0e 4183 .v.func = alc269_fixup_hp_mute_led_mic2,
420b0feb 4184 },
9f5c6faf
TI
4185 [ALC269_FIXUP_HP_GPIO_LED] = {
4186 .type = HDA_FIXUP_FUNC,
4187 .v.func = alc269_fixup_hp_gpio_led,
4188 },
693b613d 4189 [ALC269_FIXUP_INV_DMIC] = {
1727a771 4190 .type = HDA_FIXUP_FUNC,
6e72aa5f 4191 .v.func = alc_fixup_inv_dmic_0x12,
693b613d 4192 },
9b745ab8
TI
4193 [ALC269_FIXUP_NO_SHUTUP] = {
4194 .type = HDA_FIXUP_FUNC,
4195 .v.func = alc_fixup_no_shutup,
4196 },
108cc108 4197 [ALC269_FIXUP_LENOVO_DOCK] = {
1727a771
TI
4198 .type = HDA_FIXUP_PINS,
4199 .v.pins = (const struct hda_pintbl[]) {
108cc108
DH
4200 { 0x19, 0x23a11040 }, /* dock mic */
4201 { 0x1b, 0x2121103f }, /* dock headphone */
4202 { }
4203 },
4204 .chained = true,
4205 .chain_id = ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT
4206 },
4207 [ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT] = {
1727a771 4208 .type = HDA_FIXUP_FUNC,
108cc108 4209 .v.func = alc269_fixup_pincfg_no_hp_to_lineout,
52129000
DH
4210 .chained = true,
4211 .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
108cc108 4212 },
73bdd597
DH
4213 [ALC269_FIXUP_DELL1_MIC_NO_PRESENCE] = {
4214 .type = HDA_FIXUP_PINS,
4215 .v.pins = (const struct hda_pintbl[]) {
4216 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
4217 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
4218 { }
4219 },
4220 .chained = true,
4221 .chain_id = ALC269_FIXUP_HEADSET_MODE
4222 },
4223 [ALC269_FIXUP_DELL2_MIC_NO_PRESENCE] = {
4224 .type = HDA_FIXUP_PINS,
4225 .v.pins = (const struct hda_pintbl[]) {
4226 { 0x16, 0x21014020 }, /* dock line out */
4227 { 0x19, 0x21a19030 }, /* dock mic */
4228 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
4229 { }
4230 },
4231 .chained = true,
4232 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
4233 },
338cae56
DH
4234 [ALC269_FIXUP_DELL3_MIC_NO_PRESENCE] = {
4235 .type = HDA_FIXUP_PINS,
4236 .v.pins = (const struct hda_pintbl[]) {
4237 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
4238 { }
4239 },
4240 .chained = true,
4241 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
4242 },
73bdd597
DH
4243 [ALC269_FIXUP_HEADSET_MODE] = {
4244 .type = HDA_FIXUP_FUNC,
4245 .v.func = alc_fixup_headset_mode,
4246 },
4247 [ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC] = {
4248 .type = HDA_FIXUP_FUNC,
4249 .v.func = alc_fixup_headset_mode_no_hp_mic,
4250 },
88cfcf86
DH
4251 [ALC286_FIXUP_SONY_MIC_NO_PRESENCE] = {
4252 .type = HDA_FIXUP_PINS,
4253 .v.pins = (const struct hda_pintbl[]) {
4254 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
4255 { }
4256 },
fbc78ad6
DH
4257 .chained = true,
4258 .chain_id = ALC269_FIXUP_HEADSET_MIC
88cfcf86 4259 },
d240d1dc
DH
4260 [ALC269_FIXUP_ASUS_X101_FUNC] = {
4261 .type = HDA_FIXUP_FUNC,
4262 .v.func = alc269_fixup_x101_headset_mic,
4263 },
4264 [ALC269_FIXUP_ASUS_X101_VERB] = {
4265 .type = HDA_FIXUP_VERBS,
4266 .v.verbs = (const struct hda_verb[]) {
4267 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4268 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
4269 {0x20, AC_VERB_SET_PROC_COEF, 0x0310},
4270 { }
4271 },
4272 .chained = true,
4273 .chain_id = ALC269_FIXUP_ASUS_X101_FUNC
4274 },
4275 [ALC269_FIXUP_ASUS_X101] = {
4276 .type = HDA_FIXUP_PINS,
4277 .v.pins = (const struct hda_pintbl[]) {
4278 { 0x18, 0x04a1182c }, /* Headset mic */
4279 { }
4280 },
4281 .chained = true,
4282 .chain_id = ALC269_FIXUP_ASUS_X101_VERB
4283 },
08a978db 4284 [ALC271_FIXUP_AMIC_MIC2] = {
1727a771
TI
4285 .type = HDA_FIXUP_PINS,
4286 .v.pins = (const struct hda_pintbl[]) {
08a978db
DR
4287 { 0x14, 0x99130110 }, /* speaker */
4288 { 0x19, 0x01a19c20 }, /* mic */
4289 { 0x1b, 0x99a7012f }, /* int-mic */
4290 { 0x21, 0x0121401f }, /* HP out */
4291 { }
4292 },
4293 },
4294 [ALC271_FIXUP_HP_GATE_MIC_JACK] = {
1727a771 4295 .type = HDA_FIXUP_FUNC,
08a978db
DR
4296 .v.func = alc271_hp_gate_mic_jack,
4297 .chained = true,
4298 .chain_id = ALC271_FIXUP_AMIC_MIC2,
4299 },
b1e8972e
OR
4300 [ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572] = {
4301 .type = HDA_FIXUP_FUNC,
4302 .v.func = alc269_fixup_limit_int_mic_boost,
4303 .chained = true,
4304 .chain_id = ALC271_FIXUP_HP_GATE_MIC_JACK,
4305 },
42397004
DR
4306 [ALC269_FIXUP_ACER_AC700] = {
4307 .type = HDA_FIXUP_PINS,
4308 .v.pins = (const struct hda_pintbl[]) {
4309 { 0x12, 0x99a3092f }, /* int-mic */
4310 { 0x14, 0x99130110 }, /* speaker */
4311 { 0x18, 0x03a11c20 }, /* mic */
4312 { 0x1e, 0x0346101e }, /* SPDIF1 */
4313 { 0x21, 0x0321101f }, /* HP out */
4314 { }
4315 },
4316 .chained = true,
4317 .chain_id = ALC271_FIXUP_DMIC,
4318 },
3e0d611b
DH
4319 [ALC269_FIXUP_LIMIT_INT_MIC_BOOST] = {
4320 .type = HDA_FIXUP_FUNC,
4321 .v.func = alc269_fixup_limit_int_mic_boost,
2793769f
DH
4322 .chained = true,
4323 .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
3e0d611b 4324 },
2cede303
OR
4325 [ALC269VB_FIXUP_ASUS_ZENBOOK] = {
4326 .type = HDA_FIXUP_FUNC,
4327 .v.func = alc269_fixup_limit_int_mic_boost,
4328 .chained = true,
4329 .chain_id = ALC269VB_FIXUP_DMIC,
4330 },
23870831
TI
4331 [ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A] = {
4332 .type = HDA_FIXUP_VERBS,
4333 .v.verbs = (const struct hda_verb[]) {
4334 /* class-D output amp +5dB */
4335 { 0x20, AC_VERB_SET_COEF_INDEX, 0x12 },
4336 { 0x20, AC_VERB_SET_PROC_COEF, 0x2800 },
4337 {}
4338 },
4339 .chained = true,
4340 .chain_id = ALC269VB_FIXUP_ASUS_ZENBOOK,
4341 },
8e35cd4a
DH
4342 [ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED] = {
4343 .type = HDA_FIXUP_FUNC,
4344 .v.func = alc269_fixup_limit_int_mic_boost,
4345 .chained = true,
4346 .chain_id = ALC269_FIXUP_HP_MUTE_LED_MIC1,
4347 },
02b504d9
AA
4348 [ALC269VB_FIXUP_ORDISSIMO_EVE2] = {
4349 .type = HDA_FIXUP_PINS,
4350 .v.pins = (const struct hda_pintbl[]) {
4351 { 0x12, 0x99a3092f }, /* int-mic */
4352 { 0x18, 0x03a11d20 }, /* mic */
4353 { 0x19, 0x411111f0 }, /* Unused bogus pin */
4354 { }
4355 },
4356 },
cd217a63
KY
4357 [ALC283_FIXUP_CHROME_BOOK] = {
4358 .type = HDA_FIXUP_FUNC,
4359 .v.func = alc283_fixup_chromebook,
4360 },
0202e99c
KY
4361 [ALC283_FIXUP_SENSE_COMBO_JACK] = {
4362 .type = HDA_FIXUP_FUNC,
4363 .v.func = alc283_fixup_sense_combo_jack,
4364 .chained = true,
4365 .chain_id = ALC283_FIXUP_CHROME_BOOK,
4366 },
7bba2157
TI
4367 [ALC282_FIXUP_ASUS_TX300] = {
4368 .type = HDA_FIXUP_FUNC,
4369 .v.func = alc282_fixup_asus_tx300,
4370 },
1bb3e062
KY
4371 [ALC283_FIXUP_INT_MIC] = {
4372 .type = HDA_FIXUP_VERBS,
4373 .v.verbs = (const struct hda_verb[]) {
4374 {0x20, AC_VERB_SET_COEF_INDEX, 0x1a},
4375 {0x20, AC_VERB_SET_PROC_COEF, 0x0011},
4376 { }
4377 },
4378 .chained = true,
4379 .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST
4380 },
0f4881dc
DH
4381 [ALC290_FIXUP_SUBWOOFER_HSJACK] = {
4382 .type = HDA_FIXUP_PINS,
4383 .v.pins = (const struct hda_pintbl[]) {
4384 { 0x17, 0x90170112 }, /* subwoofer */
4385 { }
4386 },
4387 .chained = true,
4388 .chain_id = ALC290_FIXUP_MONO_SPEAKERS_HSJACK,
4389 },
4390 [ALC290_FIXUP_SUBWOOFER] = {
4391 .type = HDA_FIXUP_PINS,
4392 .v.pins = (const struct hda_pintbl[]) {
4393 { 0x17, 0x90170112 }, /* subwoofer */
4394 { }
4395 },
4396 .chained = true,
4397 .chain_id = ALC290_FIXUP_MONO_SPEAKERS,
4398 },
338cae56
DH
4399 [ALC290_FIXUP_MONO_SPEAKERS] = {
4400 .type = HDA_FIXUP_FUNC,
4401 .v.func = alc290_fixup_mono_speakers,
0f4881dc
DH
4402 },
4403 [ALC290_FIXUP_MONO_SPEAKERS_HSJACK] = {
4404 .type = HDA_FIXUP_FUNC,
4405 .v.func = alc290_fixup_mono_speakers,
338cae56
DH
4406 .chained = true,
4407 .chain_id = ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
4408 },
b67ae3f1
DH
4409 [ALC269_FIXUP_THINKPAD_ACPI] = {
4410 .type = HDA_FIXUP_FUNC,
b317b032 4411 .v.func = hda_fixup_thinkpad_acpi,
b67ae3f1 4412 },
9a22a8f5
KY
4413 [ALC255_FIXUP_DELL1_MIC_NO_PRESENCE] = {
4414 .type = HDA_FIXUP_PINS,
4415 .v.pins = (const struct hda_pintbl[]) {
4416 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
4417 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
4418 { }
4419 },
4420 .chained = true,
4421 .chain_id = ALC255_FIXUP_HEADSET_MODE
4422 },
4423 [ALC255_FIXUP_HEADSET_MODE] = {
4424 .type = HDA_FIXUP_FUNC,
4425 .v.func = alc_fixup_headset_mode_alc255,
4426 },
f1d4e28b
KY
4427};
4428
1d045db9 4429static const struct snd_pci_quirk alc269_fixup_tbl[] = {
a6b92b66 4430 SND_PCI_QUIRK(0x1025, 0x0283, "Acer TravelMate 8371", ALC269_FIXUP_INV_DMIC),
693b613d
DH
4431 SND_PCI_QUIRK(0x1025, 0x029b, "Acer 1810TZ", ALC269_FIXUP_INV_DMIC),
4432 SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC),
aaedfb47
DH
4433 SND_PCI_QUIRK(0x1025, 0x047c, "Acer AC700", ALC269_FIXUP_ACER_AC700),
4434 SND_PCI_QUIRK(0x1025, 0x0740, "Acer AO725", ALC271_FIXUP_HP_GATE_MIC_JACK),
4435 SND_PCI_QUIRK(0x1025, 0x0742, "Acer AO756", ALC271_FIXUP_HP_GATE_MIC_JACK),
4436 SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC),
b1e8972e 4437 SND_PCI_QUIRK(0x1025, 0x0775, "Acer Aspire E1-572", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572),
aaedfb47 4438 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
73bdd597
DH
4439 SND_PCI_QUIRK(0x1028, 0x05bd, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
4440 SND_PCI_QUIRK(0x1028, 0x05be, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
4441 SND_PCI_QUIRK(0x1028, 0x05c4, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4442 SND_PCI_QUIRK(0x1028, 0x05c5, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4443 SND_PCI_QUIRK(0x1028, 0x05c6, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4444 SND_PCI_QUIRK(0x1028, 0x05c7, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4445 SND_PCI_QUIRK(0x1028, 0x05c8, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4446 SND_PCI_QUIRK(0x1028, 0x05c9, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4447 SND_PCI_QUIRK(0x1028, 0x05ca, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
4448 SND_PCI_QUIRK(0x1028, 0x05cb, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
05843c07
KY
4449 SND_PCI_QUIRK(0x1028, 0x05cc, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
4450 SND_PCI_QUIRK(0x1028, 0x05cd, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
0f4881dc 4451 SND_PCI_QUIRK(0x1028, 0x05da, "Dell Vostro 5460", ALC290_FIXUP_SUBWOOFER),
436c4a0c 4452 SND_PCI_QUIRK(0x1028, 0x05de, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
d81bf8cf 4453 SND_PCI_QUIRK(0x1028, 0x05e0, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
73bdd597
DH
4454 SND_PCI_QUIRK(0x1028, 0x05e9, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4455 SND_PCI_QUIRK(0x1028, 0x05ea, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4456 SND_PCI_QUIRK(0x1028, 0x05eb, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4457 SND_PCI_QUIRK(0x1028, 0x05ec, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4458 SND_PCI_QUIRK(0x1028, 0x05ed, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4459 SND_PCI_QUIRK(0x1028, 0x05ee, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4460 SND_PCI_QUIRK(0x1028, 0x05f3, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4461 SND_PCI_QUIRK(0x1028, 0x05f4, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4462 SND_PCI_QUIRK(0x1028, 0x05f5, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4463 SND_PCI_QUIRK(0x1028, 0x05f6, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
3ee2102f 4464 SND_PCI_QUIRK(0x1028, 0x05f8, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
cd6fb679
DH
4465 SND_PCI_QUIRK(0x1028, 0x05f9, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4466 SND_PCI_QUIRK(0x1028, 0x05fb, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
d81bf8cf
DH
4467 SND_PCI_QUIRK(0x1028, 0x0606, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4468 SND_PCI_QUIRK(0x1028, 0x0608, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
3ee2102f 4469 SND_PCI_QUIRK(0x1028, 0x0609, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
c48ae0ab
HW
4470 SND_PCI_QUIRK(0x1028, 0x060f, "Dell", ALC269_FIXUP_DELL3_MIC_NO_PRESENCE),
4471 SND_PCI_QUIRK(0x1028, 0x0610, "Dell", ALC269_FIXUP_DELL3_MIC_NO_PRESENCE),
6c29d68a 4472 SND_PCI_QUIRK(0x1028, 0x0613, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
b8362e70 4473 SND_PCI_QUIRK(0x1028, 0x0614, "Dell Inspiron 3135", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
0f4881dc
DH
4474 SND_PCI_QUIRK(0x1028, 0x0615, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK),
4475 SND_PCI_QUIRK(0x1028, 0x0616, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK),
9a22a8f5 4476 SND_PCI_QUIRK(0x1028, 0x061f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
c29cb5eb 4477 SND_PCI_QUIRK(0x1028, 0x0629, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
0f4881dc 4478 SND_PCI_QUIRK(0x1028, 0x0638, "Dell Inspiron 5439", ALC290_FIXUP_MONO_SPEAKERS_HSJACK),
c29cb5eb 4479 SND_PCI_QUIRK(0x1028, 0x063e, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
9a22a8f5 4480 SND_PCI_QUIRK(0x1028, 0x063f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
3a6c5d8a 4481 SND_PCI_QUIRK(0x1028, 0x0640, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
5e87d580 4482 SND_PCI_QUIRK(0x1028, 0x064d, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
c48ae0ab
HW
4483 SND_PCI_QUIRK(0x1028, 0x0651, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
4484 SND_PCI_QUIRK(0x1028, 0x0652, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
4485 SND_PCI_QUIRK(0x1028, 0x0653, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
4913e0bf 4486 SND_PCI_QUIRK(0x1028, 0x0657, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
c48ae0ab 4487 SND_PCI_QUIRK(0x1028, 0x0658, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4913e0bf 4488 SND_PCI_QUIRK(0x1028, 0x065f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
c48ae0ab 4489 SND_PCI_QUIRK(0x1028, 0x0662, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
05843c07
KY
4490 SND_PCI_QUIRK(0x1028, 0x15cc, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
4491 SND_PCI_QUIRK(0x1028, 0x15cd, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
08fb0d0e 4492 SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
9f5c6faf 4493 SND_PCI_QUIRK(0x103c, 0x18e6, "HP", ALC269_FIXUP_HP_GPIO_LED),
d06ac143
DH
4494 SND_PCI_QUIRK(0x103c, 0x1973, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4495 SND_PCI_QUIRK(0x103c, 0x1983, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1),
8e35cd4a 4496 SND_PCI_QUIRK(0x103c, 0x218b, "HP", ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED),
c60666bd
KY
4497 /* ALC282 */
4498 SND_PCI_QUIRK(0x103c, 0x220f, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4499 SND_PCI_QUIRK(0x103c, 0x2213, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4500 SND_PCI_QUIRK(0x103c, 0x2266, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4501 SND_PCI_QUIRK(0x103c, 0x2267, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4502 SND_PCI_QUIRK(0x103c, 0x2268, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4503 SND_PCI_QUIRK(0x103c, 0x2269, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4504 SND_PCI_QUIRK(0x103c, 0x226a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4505 SND_PCI_QUIRK(0x103c, 0x226b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4506 SND_PCI_QUIRK(0x103c, 0x227a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4507 SND_PCI_QUIRK(0x103c, 0x227b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4508 SND_PCI_QUIRK(0x103c, 0x229e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4509 SND_PCI_QUIRK(0x103c, 0x22a0, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4510 SND_PCI_QUIRK(0x103c, 0x22b2, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4511 SND_PCI_QUIRK(0x103c, 0x22b7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4512 SND_PCI_QUIRK(0x103c, 0x22bf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4513 SND_PCI_QUIRK(0x103c, 0x22c0, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4514 SND_PCI_QUIRK(0x103c, 0x22c1, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4515 SND_PCI_QUIRK(0x103c, 0x22c2, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4516 SND_PCI_QUIRK(0x103c, 0x22cd, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4517 SND_PCI_QUIRK(0x103c, 0x22ce, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4518 SND_PCI_QUIRK(0x103c, 0x22cf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4519 SND_PCI_QUIRK(0x103c, 0x22d0, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4520 /* ALC290 */
4521 SND_PCI_QUIRK(0x103c, 0x2260, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4522 SND_PCI_QUIRK(0x103c, 0x2261, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4523 SND_PCI_QUIRK(0x103c, 0x2262, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4524 SND_PCI_QUIRK(0x103c, 0x2263, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4525 SND_PCI_QUIRK(0x103c, 0x2264, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4526 SND_PCI_QUIRK(0x103c, 0x2265, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4527 SND_PCI_QUIRK(0x103c, 0x227d, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4528 SND_PCI_QUIRK(0x103c, 0x227e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4529 SND_PCI_QUIRK(0x103c, 0x227f, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4530 SND_PCI_QUIRK(0x103c, 0x2280, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4531 SND_PCI_QUIRK(0x103c, 0x2281, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4532 SND_PCI_QUIRK(0x103c, 0x2282, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4533 SND_PCI_QUIRK(0x103c, 0x2289, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4534 SND_PCI_QUIRK(0x103c, 0x228a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4535 SND_PCI_QUIRK(0x103c, 0x228b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4536 SND_PCI_QUIRK(0x103c, 0x228c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
fce0a0c7 4537 SND_PCI_QUIRK(0x103c, 0x228d, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
c60666bd
KY
4538 SND_PCI_QUIRK(0x103c, 0x228e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4539 SND_PCI_QUIRK(0x103c, 0x22c5, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4540 SND_PCI_QUIRK(0x103c, 0x22c6, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4541 SND_PCI_QUIRK(0x103c, 0x22c7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4542 SND_PCI_QUIRK(0x103c, 0x22c8, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4543 SND_PCI_QUIRK(0x103c, 0x22c3, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4544 SND_PCI_QUIRK(0x103c, 0x22c4, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
08fb0d0e 4545 SND_PCI_QUIRK_VENDOR(0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED),
7bba2157 4546 SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300),
3e0d611b
DH
4547 SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
4548 SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
2cede303 4549 SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK),
23870831 4550 SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A),
3e0d611b 4551 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC),
017f2a10 4552 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
693b613d 4553 SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC),
3e0d611b 4554 SND_PCI_QUIRK(0x1043, 0x1c23, "Asus X55U", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
adabb3ec
TI
4555 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC),
4556 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC),
4557 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
4558 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
d240d1dc 4559 SND_PCI_QUIRK(0x1043, 0x8516, "ASUS X101CH", ALC269_FIXUP_ASUS_X101),
f88abaa0 4560 SND_PCI_QUIRK(0x104d, 0x90b5, "Sony VAIO Pro 11", ALC286_FIXUP_SONY_MIC_NO_PRESENCE),
88cfcf86 4561 SND_PCI_QUIRK(0x104d, 0x90b6, "Sony VAIO Pro 13", ALC286_FIXUP_SONY_MIC_NO_PRESENCE),
1d045db9
TI
4562 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
4563 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
4564 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
4565 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
24519911 4566 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook", ALC269_FIXUP_LIFEBOOK),
1d045db9
TI
4567 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
4568 SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
4569 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
4570 SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
4571 SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
707fba3f 4572 SND_PCI_QUIRK(0x17aa, 0x21f6, "Thinkpad T530", ALC269_FIXUP_LENOVO_DOCK),
c8415a48 4573 SND_PCI_QUIRK(0x17aa, 0x21fa, "Thinkpad X230", ALC269_FIXUP_LENOVO_DOCK),
84f98fdf 4574 SND_PCI_QUIRK(0x17aa, 0x21f3, "Thinkpad T430", ALC269_FIXUP_LENOVO_DOCK),
4407be6b 4575 SND_PCI_QUIRK(0x17aa, 0x21fb, "Thinkpad T430s", ALC269_FIXUP_LENOVO_DOCK),
108cc108 4576 SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK),
aaedfb47 4577 SND_PCI_QUIRK(0x17aa, 0x2208, "Thinkpad T431s", ALC269_FIXUP_LENOVO_DOCK),
cd5302c0
DH
4578 SND_PCI_QUIRK(0x17aa, 0x220c, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
4579 SND_PCI_QUIRK(0x17aa, 0x2212, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
2793769f 4580 SND_PCI_QUIRK(0x17aa, 0x2214, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
a4a9e082 4581 SND_PCI_QUIRK(0x17aa, 0x2215, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
9b745ab8 4582 SND_PCI_QUIRK(0x17aa, 0x3978, "IdeaPad Y410P", ALC269_FIXUP_NO_SHUTUP),
a4a9e082 4583 SND_PCI_QUIRK(0x17aa, 0x5013, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
1bb3e062 4584 SND_PCI_QUIRK(0x17aa, 0x501a, "Thinkpad", ALC283_FIXUP_INT_MIC),
cd5302c0
DH
4585 SND_PCI_QUIRK(0x17aa, 0x5026, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
4586 SND_PCI_QUIRK(0x17aa, 0x5109, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
012e7eb1 4587 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K),
1d045db9 4588 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
2793769f 4589 SND_PCI_QUIRK_VENDOR(0x17aa, "Thinkpad", ALC269_FIXUP_THINKPAD_ACPI),
02b504d9 4590 SND_PCI_QUIRK(0x1b7d, 0xa831, "Ordissimo EVE2 ", ALC269VB_FIXUP_ORDISSIMO_EVE2), /* Also known as Malata PC-B1303 */
a4297b5d 4591
a7f3eedc 4592#if 0
a4297b5d
TI
4593 /* Below is a quirk table taken from the old code.
4594 * Basically the device should work as is without the fixup table.
4595 * If BIOS doesn't give a proper info, enable the corresponding
4596 * fixup entry.
7d7eb9ea 4597 */
a4297b5d
TI
4598 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
4599 ALC269_FIXUP_AMIC),
4600 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269_FIXUP_AMIC),
a4297b5d
TI
4601 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269_FIXUP_AMIC),
4602 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_FIXUP_AMIC),
4603 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269_FIXUP_AMIC),
4604 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269_FIXUP_AMIC),
4605 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269_FIXUP_AMIC),
4606 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269_FIXUP_AMIC),
4607 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_FIXUP_AMIC),
4608 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269_FIXUP_AMIC),
4609 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_FIXUP_AMIC),
4610 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_FIXUP_AMIC),
4611 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_FIXUP_AMIC),
4612 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_FIXUP_AMIC),
4613 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_FIXUP_AMIC),
4614 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_FIXUP_AMIC),
4615 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_FIXUP_AMIC),
4616 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_FIXUP_AMIC),
4617 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_FIXUP_AMIC),
4618 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_FIXUP_AMIC),
4619 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_FIXUP_AMIC),
4620 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_FIXUP_AMIC),
4621 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_FIXUP_AMIC),
4622 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_FIXUP_AMIC),
4623 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_FIXUP_AMIC),
4624 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_FIXUP_AMIC),
4625 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_FIXUP_AMIC),
4626 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_FIXUP_AMIC),
4627 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_FIXUP_AMIC),
4628 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_FIXUP_AMIC),
4629 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_FIXUP_AMIC),
4630 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_FIXUP_AMIC),
4631 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_FIXUP_AMIC),
4632 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_FIXUP_AMIC),
4633 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_FIXUP_AMIC),
4634 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_FIXUP_DMIC),
4635 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_FIXUP_AMIC),
4636 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_AMIC),
4637 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_FIXUP_DMIC),
4638 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_FIXUP_DMIC),
4639#endif
4640 {}
4641};
4642
1727a771 4643static const struct hda_model_fixup alc269_fixup_models[] = {
a4297b5d
TI
4644 {.id = ALC269_FIXUP_AMIC, .name = "laptop-amic"},
4645 {.id = ALC269_FIXUP_DMIC, .name = "laptop-dmic"},
6e72aa5f
TI
4646 {.id = ALC269_FIXUP_STEREO_DMIC, .name = "alc269-dmic"},
4647 {.id = ALC271_FIXUP_DMIC, .name = "alc271-dmic"},
4648 {.id = ALC269_FIXUP_INV_DMIC, .name = "inv-dmic"},
7c478f03 4649 {.id = ALC269_FIXUP_HEADSET_MIC, .name = "headset-mic"},
108cc108 4650 {.id = ALC269_FIXUP_LENOVO_DOCK, .name = "lenovo-dock"},
9f5c6faf 4651 {.id = ALC269_FIXUP_HP_GPIO_LED, .name = "hp-gpio-led"},
e32aa85a
DH
4652 {.id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "dell-headset-multi"},
4653 {.id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE, .name = "dell-headset-dock"},
0202e99c
KY
4654 {.id = ALC283_FIXUP_CHROME_BOOK, .name = "alc283-chrome"},
4655 {.id = ALC283_FIXUP_SENSE_COMBO_JACK, .name = "alc283-sense-combo"},
1d045db9 4656 {}
6dda9f4a
KY
4657};
4658
6dda9f4a 4659
546bb678 4660static void alc269_fill_coef(struct hda_codec *codec)
1d045db9 4661{
526af6eb 4662 struct alc_spec *spec = codec->spec;
1d045db9 4663 int val;
ebb83eeb 4664
526af6eb 4665 if (spec->codec_variant != ALC269_TYPE_ALC269VB)
546bb678 4666 return;
526af6eb 4667
1bb7e43e 4668 if ((alc_get_coef0(codec) & 0x00ff) < 0x015) {
1d045db9
TI
4669 alc_write_coef_idx(codec, 0xf, 0x960b);
4670 alc_write_coef_idx(codec, 0xe, 0x8817);
4671 }
ebb83eeb 4672
1bb7e43e 4673 if ((alc_get_coef0(codec) & 0x00ff) == 0x016) {
1d045db9
TI
4674 alc_write_coef_idx(codec, 0xf, 0x960b);
4675 alc_write_coef_idx(codec, 0xe, 0x8814);
4676 }
ebb83eeb 4677
1bb7e43e 4678 if ((alc_get_coef0(codec) & 0x00ff) == 0x017) {
1d045db9
TI
4679 val = alc_read_coef_idx(codec, 0x04);
4680 /* Power up output pin */
4681 alc_write_coef_idx(codec, 0x04, val | (1<<11));
4682 }
ebb83eeb 4683
1bb7e43e 4684 if ((alc_get_coef0(codec) & 0x00ff) == 0x018) {
1d045db9
TI
4685 val = alc_read_coef_idx(codec, 0xd);
4686 if ((val & 0x0c00) >> 10 != 0x1) {
4687 /* Capless ramp up clock control */
4688 alc_write_coef_idx(codec, 0xd, val | (1<<10));
4689 }
4690 val = alc_read_coef_idx(codec, 0x17);
4691 if ((val & 0x01c0) >> 6 != 0x4) {
4692 /* Class D power on reset */
4693 alc_write_coef_idx(codec, 0x17, val | (1<<7));
4694 }
4695 }
ebb83eeb 4696
1d045db9
TI
4697 val = alc_read_coef_idx(codec, 0xd); /* Class D */
4698 alc_write_coef_idx(codec, 0xd, val | (1<<14));
bc9f98a9 4699
1d045db9
TI
4700 val = alc_read_coef_idx(codec, 0x4); /* HP */
4701 alc_write_coef_idx(codec, 0x4, val | (1<<11));
1d045db9 4702}
a7f2371f 4703
1d045db9
TI
4704/*
4705 */
1d045db9
TI
4706static int patch_alc269(struct hda_codec *codec)
4707{
4708 struct alc_spec *spec;
3de95173 4709 int err;
f1d4e28b 4710
3de95173 4711 err = alc_alloc_spec(codec, 0x0b);
e16fb6d1 4712 if (err < 0)
3de95173
TI
4713 return err;
4714
4715 spec = codec->spec;
08c189f2 4716 spec->gen.shared_mic_vref_pin = 0x18;
e16fb6d1 4717
1727a771 4718 snd_hda_pick_fixup(codec, alc269_fixup_models,
9f720bb9 4719 alc269_fixup_tbl, alc269_fixups);
1727a771 4720 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
9f720bb9
HRK
4721
4722 alc_auto_parse_customize_define(codec);
4723
7504b6cd
TI
4724 if (has_cdefine_beep(codec))
4725 spec->gen.beep_nid = 0x01;
4726
065380f0
KY
4727 switch (codec->vendor_id) {
4728 case 0x10ec0269:
1d045db9 4729 spec->codec_variant = ALC269_TYPE_ALC269VA;
1bb7e43e
TI
4730 switch (alc_get_coef0(codec) & 0x00f0) {
4731 case 0x0010:
1d045db9 4732 if (codec->bus->pci->subsystem_vendor == 0x1025 &&
e16fb6d1 4733 spec->cdefine.platform_type == 1)
20ca0c35 4734 err = alc_codec_rename(codec, "ALC271X");
1d045db9 4735 spec->codec_variant = ALC269_TYPE_ALC269VB;
1bb7e43e
TI
4736 break;
4737 case 0x0020:
e16fb6d1
TI
4738 if (codec->bus->pci->subsystem_vendor == 0x17aa &&
4739 codec->bus->pci->subsystem_device == 0x21f3)
20ca0c35 4740 err = alc_codec_rename(codec, "ALC3202");
1d045db9 4741 spec->codec_variant = ALC269_TYPE_ALC269VC;
1bb7e43e 4742 break;
adcc70b2
KY
4743 case 0x0030:
4744 spec->codec_variant = ALC269_TYPE_ALC269VD;
4745 break;
1bb7e43e 4746 default:
1d045db9 4747 alc_fix_pll_init(codec, 0x20, 0x04, 15);
1bb7e43e 4748 }
e16fb6d1
TI
4749 if (err < 0)
4750 goto error;
546bb678 4751 spec->init_hook = alc269_fill_coef;
1d045db9 4752 alc269_fill_coef(codec);
065380f0
KY
4753 break;
4754
4755 case 0x10ec0280:
4756 case 0x10ec0290:
4757 spec->codec_variant = ALC269_TYPE_ALC280;
4758 break;
4759 case 0x10ec0282:
065380f0 4760 spec->codec_variant = ALC269_TYPE_ALC282;
7b5c7a02
KY
4761 spec->shutup = alc282_shutup;
4762 spec->init_hook = alc282_init;
065380f0 4763 break;
2af02be7
KY
4764 case 0x10ec0233:
4765 case 0x10ec0283:
4766 spec->codec_variant = ALC269_TYPE_ALC283;
4767 spec->shutup = alc283_shutup;
4768 spec->init_hook = alc283_init;
4769 break;
065380f0
KY
4770 case 0x10ec0284:
4771 case 0x10ec0292:
4772 spec->codec_variant = ALC269_TYPE_ALC284;
4773 break;
161ebf29
KY
4774 case 0x10ec0285:
4775 case 0x10ec0293:
4776 spec->codec_variant = ALC269_TYPE_ALC285;
4777 break;
7fc7d047
KY
4778 case 0x10ec0286:
4779 spec->codec_variant = ALC269_TYPE_ALC286;
4780 break;
1d04c9de
KY
4781 case 0x10ec0255:
4782 spec->codec_variant = ALC269_TYPE_ALC255;
4783 break;
1d045db9 4784 }
6dda9f4a 4785
ad60d502 4786 if (snd_hda_codec_read(codec, 0x51, 0, AC_VERB_PARAMETERS, 0) == 0x10ec5505) {
97a26570 4787 spec->has_alc5505_dsp = 1;
ad60d502
KY
4788 spec->init_hook = alc5505_dsp_init;
4789 }
4790
a4297b5d
TI
4791 /* automatic parse from the BIOS config */
4792 err = alc269_parse_auto_config(codec);
e16fb6d1
TI
4793 if (err < 0)
4794 goto error;
6dda9f4a 4795
7504b6cd 4796 if (!spec->gen.no_analog && spec->gen.beep_nid)
1d045db9 4797 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
f1d4e28b 4798
1d045db9 4799 codec->patch_ops = alc_patch_ops;
2a43952a 4800#ifdef CONFIG_PM
ad60d502 4801 codec->patch_ops.suspend = alc269_suspend;
1d045db9
TI
4802 codec->patch_ops.resume = alc269_resume;
4803#endif
c5177c86
KY
4804 if (!spec->shutup)
4805 spec->shutup = alc269_shutup;
ebb83eeb 4806
1727a771 4807 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
589876e2 4808
1d045db9 4809 return 0;
e16fb6d1
TI
4810
4811 error:
4812 alc_free(codec);
4813 return err;
1d045db9 4814}
f1d4e28b 4815
1d045db9
TI
4816/*
4817 * ALC861
4818 */
622e84cd 4819
1d045db9 4820static int alc861_parse_auto_config(struct hda_codec *codec)
6dda9f4a 4821{
1d045db9 4822 static const hda_nid_t alc861_ignore[] = { 0x1d, 0 };
3e6179b8
TI
4823 static const hda_nid_t alc861_ssids[] = { 0x0e, 0x0f, 0x0b, 0 };
4824 return alc_parse_auto_config(codec, alc861_ignore, alc861_ssids);
604401a9
TI
4825}
4826
1d045db9
TI
4827/* Pin config fixes */
4828enum {
e652f4c8
TI
4829 ALC861_FIXUP_FSC_AMILO_PI1505,
4830 ALC861_FIXUP_AMP_VREF_0F,
4831 ALC861_FIXUP_NO_JACK_DETECT,
4832 ALC861_FIXUP_ASUS_A6RP,
6ddf0fd1 4833 ALC660_FIXUP_ASUS_W7J,
1d045db9 4834};
7085ec12 4835
31150f23
TI
4836/* On some laptops, VREF of pin 0x0f is abused for controlling the main amp */
4837static void alc861_fixup_asus_amp_vref_0f(struct hda_codec *codec,
1727a771 4838 const struct hda_fixup *fix, int action)
31150f23
TI
4839{
4840 struct alc_spec *spec = codec->spec;
4841 unsigned int val;
4842
1727a771 4843 if (action != HDA_FIXUP_ACT_INIT)
31150f23 4844 return;
d3f02d60 4845 val = snd_hda_codec_get_pin_target(codec, 0x0f);
31150f23
TI
4846 if (!(val & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN)))
4847 val |= AC_PINCTL_IN_EN;
4848 val |= AC_PINCTL_VREF_50;
cdd03ced 4849 snd_hda_set_pin_ctl(codec, 0x0f, val);
08c189f2 4850 spec->gen.keep_vref_in_automute = 1;
31150f23
TI
4851}
4852
e652f4c8
TI
4853/* suppress the jack-detection */
4854static void alc_fixup_no_jack_detect(struct hda_codec *codec,
1727a771 4855 const struct hda_fixup *fix, int action)
e652f4c8 4856{
1727a771 4857 if (action == HDA_FIXUP_ACT_PRE_PROBE)
e652f4c8 4858 codec->no_jack_detect = 1;
7d7eb9ea 4859}
e652f4c8 4860
1727a771 4861static const struct hda_fixup alc861_fixups[] = {
e652f4c8 4862 [ALC861_FIXUP_FSC_AMILO_PI1505] = {
1727a771
TI
4863 .type = HDA_FIXUP_PINS,
4864 .v.pins = (const struct hda_pintbl[]) {
1d045db9
TI
4865 { 0x0b, 0x0221101f }, /* HP */
4866 { 0x0f, 0x90170310 }, /* speaker */
4867 { }
4868 }
4869 },
e652f4c8 4870 [ALC861_FIXUP_AMP_VREF_0F] = {
1727a771 4871 .type = HDA_FIXUP_FUNC,
31150f23 4872 .v.func = alc861_fixup_asus_amp_vref_0f,
3b25eb69 4873 },
e652f4c8 4874 [ALC861_FIXUP_NO_JACK_DETECT] = {
1727a771 4875 .type = HDA_FIXUP_FUNC,
e652f4c8
TI
4876 .v.func = alc_fixup_no_jack_detect,
4877 },
4878 [ALC861_FIXUP_ASUS_A6RP] = {
1727a771 4879 .type = HDA_FIXUP_FUNC,
e652f4c8
TI
4880 .v.func = alc861_fixup_asus_amp_vref_0f,
4881 .chained = true,
4882 .chain_id = ALC861_FIXUP_NO_JACK_DETECT,
6ddf0fd1
TI
4883 },
4884 [ALC660_FIXUP_ASUS_W7J] = {
4885 .type = HDA_FIXUP_VERBS,
4886 .v.verbs = (const struct hda_verb[]) {
4887 /* ASUS W7J needs a magic pin setup on unused NID 0x10
4888 * for enabling outputs
4889 */
4890 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4891 { }
4892 },
e652f4c8 4893 }
1d045db9 4894};
7085ec12 4895
1d045db9 4896static const struct snd_pci_quirk alc861_fixup_tbl[] = {
6ddf0fd1 4897 SND_PCI_QUIRK(0x1043, 0x1253, "ASUS W7J", ALC660_FIXUP_ASUS_W7J),
e7ca237b 4898 SND_PCI_QUIRK(0x1043, 0x1263, "ASUS Z35HL", ALC660_FIXUP_ASUS_W7J),
e652f4c8
TI
4899 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS A6Rp", ALC861_FIXUP_ASUS_A6RP),
4900 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", ALC861_FIXUP_AMP_VREF_0F),
4901 SND_PCI_QUIRK(0x1462, 0x7254, "HP DX2200", ALC861_FIXUP_NO_JACK_DETECT),
4902 SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", ALC861_FIXUP_AMP_VREF_0F),
4903 SND_PCI_QUIRK(0x1584, 0x0000, "Uniwill ECS M31EI", ALC861_FIXUP_AMP_VREF_0F),
4904 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", ALC861_FIXUP_FSC_AMILO_PI1505),
1d045db9
TI
4905 {}
4906};
3af9ee6b 4907
1d045db9
TI
4908/*
4909 */
1d045db9 4910static int patch_alc861(struct hda_codec *codec)
7085ec12 4911{
1d045db9 4912 struct alc_spec *spec;
1d045db9 4913 int err;
7085ec12 4914
3de95173
TI
4915 err = alc_alloc_spec(codec, 0x15);
4916 if (err < 0)
4917 return err;
1d045db9 4918
3de95173 4919 spec = codec->spec;
7504b6cd 4920 spec->gen.beep_nid = 0x23;
1d045db9 4921
1727a771
TI
4922 snd_hda_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
4923 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
3af9ee6b 4924
cb4e4824
TI
4925 /* automatic parse from the BIOS config */
4926 err = alc861_parse_auto_config(codec);
e16fb6d1
TI
4927 if (err < 0)
4928 goto error;
3af9ee6b 4929
7504b6cd 4930 if (!spec->gen.no_analog)
3e6179b8 4931 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
7085ec12 4932
1d045db9 4933 codec->patch_ops = alc_patch_ops;
83012a7c 4934#ifdef CONFIG_PM
cb4e4824 4935 spec->power_hook = alc_power_eapd;
1d045db9
TI
4936#endif
4937
1727a771 4938 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
589876e2 4939
1d045db9 4940 return 0;
e16fb6d1
TI
4941
4942 error:
4943 alc_free(codec);
4944 return err;
7085ec12
TI
4945}
4946
1d045db9
TI
4947/*
4948 * ALC861-VD support
4949 *
4950 * Based on ALC882
4951 *
4952 * In addition, an independent DAC
4953 */
1d045db9 4954static int alc861vd_parse_auto_config(struct hda_codec *codec)
bc9f98a9 4955{
1d045db9 4956 static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
3e6179b8
TI
4957 static const hda_nid_t alc861vd_ssids[] = { 0x15, 0x1b, 0x14, 0 };
4958 return alc_parse_auto_config(codec, alc861vd_ignore, alc861vd_ssids);
ce764ab2
TI
4959}
4960
1d045db9 4961enum {
8fdcb6fe
TI
4962 ALC660VD_FIX_ASUS_GPIO1,
4963 ALC861VD_FIX_DALLAS,
1d045db9 4964};
ce764ab2 4965
8fdcb6fe
TI
4966/* exclude VREF80 */
4967static void alc861vd_fixup_dallas(struct hda_codec *codec,
1727a771 4968 const struct hda_fixup *fix, int action)
8fdcb6fe 4969{
1727a771 4970 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
b78562b1
TI
4971 snd_hda_override_pin_caps(codec, 0x18, 0x00000734);
4972 snd_hda_override_pin_caps(codec, 0x19, 0x0000073c);
8fdcb6fe
TI
4973 }
4974}
4975
1727a771 4976static const struct hda_fixup alc861vd_fixups[] = {
1d045db9 4977 [ALC660VD_FIX_ASUS_GPIO1] = {
1727a771 4978 .type = HDA_FIXUP_VERBS,
1d045db9 4979 .v.verbs = (const struct hda_verb[]) {
8fdcb6fe 4980 /* reset GPIO1 */
1d045db9
TI
4981 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
4982 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4983 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
4984 { }
4985 }
4986 },
8fdcb6fe 4987 [ALC861VD_FIX_DALLAS] = {
1727a771 4988 .type = HDA_FIXUP_FUNC,
8fdcb6fe
TI
4989 .v.func = alc861vd_fixup_dallas,
4990 },
1d045db9 4991};
ce764ab2 4992
1d045db9 4993static const struct snd_pci_quirk alc861vd_fixup_tbl[] = {
8fdcb6fe 4994 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_FIX_DALLAS),
1d045db9 4995 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
8fdcb6fe 4996 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_FIX_DALLAS),
1d045db9
TI
4997 {}
4998};
ce764ab2 4999
1d045db9
TI
5000/*
5001 */
1d045db9 5002static int patch_alc861vd(struct hda_codec *codec)
ce764ab2 5003{
1d045db9 5004 struct alc_spec *spec;
cb4e4824 5005 int err;
ce764ab2 5006
3de95173
TI
5007 err = alc_alloc_spec(codec, 0x0b);
5008 if (err < 0)
5009 return err;
1d045db9 5010
3de95173 5011 spec = codec->spec;
7504b6cd 5012 spec->gen.beep_nid = 0x23;
1d045db9 5013
1727a771
TI
5014 snd_hda_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
5015 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
1d045db9 5016
cb4e4824
TI
5017 /* automatic parse from the BIOS config */
5018 err = alc861vd_parse_auto_config(codec);
e16fb6d1
TI
5019 if (err < 0)
5020 goto error;
ce764ab2 5021
7504b6cd 5022 if (!spec->gen.no_analog)
3e6179b8 5023 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
1d045db9 5024
1d045db9
TI
5025 codec->patch_ops = alc_patch_ops;
5026
1d045db9 5027 spec->shutup = alc_eapd_shutup;
1d045db9 5028
1727a771 5029 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
589876e2 5030
ce764ab2 5031 return 0;
e16fb6d1
TI
5032
5033 error:
5034 alc_free(codec);
5035 return err;
ce764ab2
TI
5036}
5037
1d045db9
TI
5038/*
5039 * ALC662 support
5040 *
5041 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
5042 * configuration. Each pin widget can choose any input DACs and a mixer.
5043 * Each ADC is connected from a mixer of all inputs. This makes possible
5044 * 6-channel independent captures.
5045 *
5046 * In addition, an independent DAC for the multi-playback (not used in this
5047 * driver yet).
5048 */
1d045db9
TI
5049
5050/*
5051 * BIOS auto configuration
5052 */
5053
bc9f98a9
KY
5054static int alc662_parse_auto_config(struct hda_codec *codec)
5055{
4c6d72d1 5056 static const hda_nid_t alc662_ignore[] = { 0x1d, 0 };
3e6179b8
TI
5057 static const hda_nid_t alc663_ssids[] = { 0x15, 0x1b, 0x14, 0x21 };
5058 static const hda_nid_t alc662_ssids[] = { 0x15, 0x1b, 0x14, 0 };
5059 const hda_nid_t *ssids;
ee979a14 5060
6227cdce 5061 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
1d87caa6
RK
5062 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670 ||
5063 codec->vendor_id == 0x10ec0671)
3e6179b8 5064 ssids = alc663_ssids;
6227cdce 5065 else
3e6179b8
TI
5066 ssids = alc662_ssids;
5067 return alc_parse_auto_config(codec, alc662_ignore, ssids);
bc9f98a9
KY
5068}
5069
6be7948f 5070static void alc272_fixup_mario(struct hda_codec *codec,
1727a771 5071 const struct hda_fixup *fix, int action)
6fc398cb 5072{
9bb1f06f 5073 if (action != HDA_FIXUP_ACT_PRE_PROBE)
6fc398cb 5074 return;
6be7948f
TB
5075 if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT,
5076 (0x3b << AC_AMPCAP_OFFSET_SHIFT) |
5077 (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) |
5078 (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) |
5079 (0 << AC_AMPCAP_MUTE_SHIFT)))
5080 printk(KERN_WARNING
5081 "hda_codec: failed to override amp caps for NID 0x2\n");
5082}
5083
8e383953
TI
5084static const struct snd_pcm_chmap_elem asus_pcm_2_1_chmaps[] = {
5085 { .channels = 2,
5086 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } },
5087 { .channels = 4,
5088 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR,
5089 SNDRV_CHMAP_NA, SNDRV_CHMAP_LFE } }, /* LFE only on right */
5090 { }
5091};
5092
5093/* override the 2.1 chmap */
eb9ca3ab 5094static void alc_fixup_bass_chmap(struct hda_codec *codec,
8e383953
TI
5095 const struct hda_fixup *fix, int action)
5096{
5097 if (action == HDA_FIXUP_ACT_BUILD) {
5098 struct alc_spec *spec = codec->spec;
5099 spec->gen.pcm_rec[0].stream[0].chmap = asus_pcm_2_1_chmaps;
5100 }
5101}
5102
6cb3b707 5103enum {
2df03514 5104 ALC662_FIXUP_ASPIRE,
6cb3b707 5105 ALC662_FIXUP_IDEAPAD,
6be7948f 5106 ALC272_FIXUP_MARIO,
d2ebd479 5107 ALC662_FIXUP_CZC_P10T,
94024cd1 5108 ALC662_FIXUP_SKU_IGNORE,
e59ea3ed 5109 ALC662_FIXUP_HP_RP5800,
53c334ad
TI
5110 ALC662_FIXUP_ASUS_MODE1,
5111 ALC662_FIXUP_ASUS_MODE2,
5112 ALC662_FIXUP_ASUS_MODE3,
5113 ALC662_FIXUP_ASUS_MODE4,
5114 ALC662_FIXUP_ASUS_MODE5,
5115 ALC662_FIXUP_ASUS_MODE6,
5116 ALC662_FIXUP_ASUS_MODE7,
5117 ALC662_FIXUP_ASUS_MODE8,
1565cc35 5118 ALC662_FIXUP_NO_JACK_DETECT,
edfe3bfc 5119 ALC662_FIXUP_ZOTAC_Z68,
125821ae 5120 ALC662_FIXUP_INV_DMIC,
73bdd597
DH
5121 ALC668_FIXUP_DELL_MIC_NO_PRESENCE,
5122 ALC668_FIXUP_HEADSET_MODE,
8e383953 5123 ALC662_FIXUP_BASS_CHMAP,
a30c9aaa
TI
5124 ALC662_FIXUP_BASS_1A,
5125 ALC662_FIXUP_BASS_1A_CHMAP,
493a52a9 5126 ALC668_FIXUP_AUTO_MUTE,
6cb3b707
DH
5127};
5128
1727a771 5129static const struct hda_fixup alc662_fixups[] = {
2df03514 5130 [ALC662_FIXUP_ASPIRE] = {
1727a771
TI
5131 .type = HDA_FIXUP_PINS,
5132 .v.pins = (const struct hda_pintbl[]) {
2df03514
DC
5133 { 0x15, 0x99130112 }, /* subwoofer */
5134 { }
5135 }
5136 },
6cb3b707 5137 [ALC662_FIXUP_IDEAPAD] = {
1727a771
TI
5138 .type = HDA_FIXUP_PINS,
5139 .v.pins = (const struct hda_pintbl[]) {
6cb3b707
DH
5140 { 0x17, 0x99130112 }, /* subwoofer */
5141 { }
5142 }
5143 },
6be7948f 5144 [ALC272_FIXUP_MARIO] = {
1727a771 5145 .type = HDA_FIXUP_FUNC,
b5bfbc67 5146 .v.func = alc272_fixup_mario,
d2ebd479
AA
5147 },
5148 [ALC662_FIXUP_CZC_P10T] = {
1727a771 5149 .type = HDA_FIXUP_VERBS,
d2ebd479
AA
5150 .v.verbs = (const struct hda_verb[]) {
5151 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
5152 {}
5153 }
5154 },
94024cd1 5155 [ALC662_FIXUP_SKU_IGNORE] = {
1727a771 5156 .type = HDA_FIXUP_FUNC,
23d30f28 5157 .v.func = alc_fixup_sku_ignore,
c6b35874 5158 },
e59ea3ed 5159 [ALC662_FIXUP_HP_RP5800] = {
1727a771
TI
5160 .type = HDA_FIXUP_PINS,
5161 .v.pins = (const struct hda_pintbl[]) {
e59ea3ed
TI
5162 { 0x14, 0x0221201f }, /* HP out */
5163 { }
5164 },
5165 .chained = true,
5166 .chain_id = ALC662_FIXUP_SKU_IGNORE
5167 },
53c334ad 5168 [ALC662_FIXUP_ASUS_MODE1] = {
1727a771
TI
5169 .type = HDA_FIXUP_PINS,
5170 .v.pins = (const struct hda_pintbl[]) {
53c334ad
TI
5171 { 0x14, 0x99130110 }, /* speaker */
5172 { 0x18, 0x01a19c20 }, /* mic */
5173 { 0x19, 0x99a3092f }, /* int-mic */
5174 { 0x21, 0x0121401f }, /* HP out */
5175 { }
5176 },
5177 .chained = true,
5178 .chain_id = ALC662_FIXUP_SKU_IGNORE
5179 },
5180 [ALC662_FIXUP_ASUS_MODE2] = {
1727a771
TI
5181 .type = HDA_FIXUP_PINS,
5182 .v.pins = (const struct hda_pintbl[]) {
2996bdba
TI
5183 { 0x14, 0x99130110 }, /* speaker */
5184 { 0x18, 0x01a19820 }, /* mic */
5185 { 0x19, 0x99a3092f }, /* int-mic */
5186 { 0x1b, 0x0121401f }, /* HP out */
5187 { }
5188 },
53c334ad
TI
5189 .chained = true,
5190 .chain_id = ALC662_FIXUP_SKU_IGNORE
5191 },
5192 [ALC662_FIXUP_ASUS_MODE3] = {
1727a771
TI
5193 .type = HDA_FIXUP_PINS,
5194 .v.pins = (const struct hda_pintbl[]) {
53c334ad
TI
5195 { 0x14, 0x99130110 }, /* speaker */
5196 { 0x15, 0x0121441f }, /* HP */
5197 { 0x18, 0x01a19840 }, /* mic */
5198 { 0x19, 0x99a3094f }, /* int-mic */
5199 { 0x21, 0x01211420 }, /* HP2 */
5200 { }
5201 },
5202 .chained = true,
5203 .chain_id = ALC662_FIXUP_SKU_IGNORE
5204 },
5205 [ALC662_FIXUP_ASUS_MODE4] = {
1727a771
TI
5206 .type = HDA_FIXUP_PINS,
5207 .v.pins = (const struct hda_pintbl[]) {
53c334ad
TI
5208 { 0x14, 0x99130110 }, /* speaker */
5209 { 0x16, 0x99130111 }, /* speaker */
5210 { 0x18, 0x01a19840 }, /* mic */
5211 { 0x19, 0x99a3094f }, /* int-mic */
5212 { 0x21, 0x0121441f }, /* HP */
5213 { }
5214 },
5215 .chained = true,
5216 .chain_id = ALC662_FIXUP_SKU_IGNORE
5217 },
5218 [ALC662_FIXUP_ASUS_MODE5] = {
1727a771
TI
5219 .type = HDA_FIXUP_PINS,
5220 .v.pins = (const struct hda_pintbl[]) {
53c334ad
TI
5221 { 0x14, 0x99130110 }, /* speaker */
5222 { 0x15, 0x0121441f }, /* HP */
5223 { 0x16, 0x99130111 }, /* speaker */
5224 { 0x18, 0x01a19840 }, /* mic */
5225 { 0x19, 0x99a3094f }, /* int-mic */
5226 { }
5227 },
5228 .chained = true,
5229 .chain_id = ALC662_FIXUP_SKU_IGNORE
5230 },
5231 [ALC662_FIXUP_ASUS_MODE6] = {
1727a771
TI
5232 .type = HDA_FIXUP_PINS,
5233 .v.pins = (const struct hda_pintbl[]) {
53c334ad
TI
5234 { 0x14, 0x99130110 }, /* speaker */
5235 { 0x15, 0x01211420 }, /* HP2 */
5236 { 0x18, 0x01a19840 }, /* mic */
5237 { 0x19, 0x99a3094f }, /* int-mic */
5238 { 0x1b, 0x0121441f }, /* HP */
5239 { }
5240 },
5241 .chained = true,
5242 .chain_id = ALC662_FIXUP_SKU_IGNORE
5243 },
5244 [ALC662_FIXUP_ASUS_MODE7] = {
1727a771
TI
5245 .type = HDA_FIXUP_PINS,
5246 .v.pins = (const struct hda_pintbl[]) {
53c334ad
TI
5247 { 0x14, 0x99130110 }, /* speaker */
5248 { 0x17, 0x99130111 }, /* speaker */
5249 { 0x18, 0x01a19840 }, /* mic */
5250 { 0x19, 0x99a3094f }, /* int-mic */
5251 { 0x1b, 0x01214020 }, /* HP */
5252 { 0x21, 0x0121401f }, /* HP */
5253 { }
5254 },
5255 .chained = true,
5256 .chain_id = ALC662_FIXUP_SKU_IGNORE
5257 },
5258 [ALC662_FIXUP_ASUS_MODE8] = {
1727a771
TI
5259 .type = HDA_FIXUP_PINS,
5260 .v.pins = (const struct hda_pintbl[]) {
53c334ad
TI
5261 { 0x14, 0x99130110 }, /* speaker */
5262 { 0x12, 0x99a30970 }, /* int-mic */
5263 { 0x15, 0x01214020 }, /* HP */
5264 { 0x17, 0x99130111 }, /* speaker */
5265 { 0x18, 0x01a19840 }, /* mic */
5266 { 0x21, 0x0121401f }, /* HP */
5267 { }
5268 },
5269 .chained = true,
5270 .chain_id = ALC662_FIXUP_SKU_IGNORE
2996bdba 5271 },
1565cc35 5272 [ALC662_FIXUP_NO_JACK_DETECT] = {
1727a771 5273 .type = HDA_FIXUP_FUNC,
1565cc35
TI
5274 .v.func = alc_fixup_no_jack_detect,
5275 },
edfe3bfc 5276 [ALC662_FIXUP_ZOTAC_Z68] = {
1727a771
TI
5277 .type = HDA_FIXUP_PINS,
5278 .v.pins = (const struct hda_pintbl[]) {
edfe3bfc
DH
5279 { 0x1b, 0x02214020 }, /* Front HP */
5280 { }
5281 }
5282 },
125821ae 5283 [ALC662_FIXUP_INV_DMIC] = {
1727a771 5284 .type = HDA_FIXUP_FUNC,
6e72aa5f 5285 .v.func = alc_fixup_inv_dmic_0x12,
125821ae 5286 },
493a52a9
HW
5287 [ALC668_FIXUP_AUTO_MUTE] = {
5288 .type = HDA_FIXUP_FUNC,
5289 .v.func = alc_fixup_auto_mute_via_amp,
5290 .chained = true,
5291 .chain_id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE
5292 },
73bdd597
DH
5293 [ALC668_FIXUP_DELL_MIC_NO_PRESENCE] = {
5294 .type = HDA_FIXUP_PINS,
5295 .v.pins = (const struct hda_pintbl[]) {
5296 { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
5297 { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */
5298 { }
5299 },
5300 .chained = true,
5301 .chain_id = ALC668_FIXUP_HEADSET_MODE
5302 },
5303 [ALC668_FIXUP_HEADSET_MODE] = {
5304 .type = HDA_FIXUP_FUNC,
5305 .v.func = alc_fixup_headset_mode_alc668,
5306 },
8e383953
TI
5307 [ALC662_FIXUP_BASS_CHMAP] = {
5308 .type = HDA_FIXUP_FUNC,
eb9ca3ab 5309 .v.func = alc_fixup_bass_chmap,
8e383953
TI
5310 .chained = true,
5311 .chain_id = ALC662_FIXUP_ASUS_MODE4
5312 },
a30c9aaa
TI
5313 [ALC662_FIXUP_BASS_1A] = {
5314 .type = HDA_FIXUP_PINS,
5315 .v.pins = (const struct hda_pintbl[]) {
5316 {0x1a, 0x80106111}, /* bass speaker */
5317 {}
5318 },
5319 },
5320 [ALC662_FIXUP_BASS_1A_CHMAP] = {
5321 .type = HDA_FIXUP_FUNC,
eb9ca3ab 5322 .v.func = alc_fixup_bass_chmap,
a30c9aaa
TI
5323 .chained = true,
5324 .chain_id = ALC662_FIXUP_BASS_1A,
5325 },
6cb3b707
DH
5326};
5327
a9111321 5328static const struct snd_pci_quirk alc662_fixup_tbl[] = {
53c334ad 5329 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_FIXUP_ASUS_MODE2),
d3d3835c 5330 SND_PCI_QUIRK(0x1025, 0x022f, "Acer Aspire One", ALC662_FIXUP_INV_DMIC),
a6c47a85 5331 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
94024cd1 5332 SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
125821ae 5333 SND_PCI_QUIRK(0x1025, 0x0349, "eMachines eM250", ALC662_FIXUP_INV_DMIC),
1801928e 5334 SND_PCI_QUIRK(0x1025, 0x034a, "Gateway LT27", ALC662_FIXUP_INV_DMIC),
2df03514 5335 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
73bdd597
DH
5336 SND_PCI_QUIRK(0x1028, 0x05d8, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
5337 SND_PCI_QUIRK(0x1028, 0x05db, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
f47e5dc4 5338 SND_PCI_QUIRK(0x1028, 0x060a, "Dell XPS 13", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
493a52a9
HW
5339 SND_PCI_QUIRK(0x1028, 0x0623, "Dell", ALC668_FIXUP_AUTO_MUTE),
5340 SND_PCI_QUIRK(0x1028, 0x0624, "Dell", ALC668_FIXUP_AUTO_MUTE),
09d2014f 5341 SND_PCI_QUIRK(0x1028, 0x0625, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
ad8ff99e 5342 SND_PCI_QUIRK(0x1028, 0x0626, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
493a52a9 5343 SND_PCI_QUIRK(0x1028, 0x0628, "Dell", ALC668_FIXUP_AUTO_MUTE),
3b446752 5344 SND_PCI_QUIRK(0x1028, 0x064e, "Dell", ALC668_FIXUP_AUTO_MUTE),
e59ea3ed 5345 SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800),
a30c9aaa 5346 SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_BASS_1A_CHMAP),
8e383953
TI
5347 SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_BASS_CHMAP),
5348 SND_PCI_QUIRK(0x1043, 0x1bf3, "ASUS N76VZ", ALC662_FIXUP_BASS_CHMAP),
1565cc35 5349 SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT),
53c334ad 5350 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2),
a0e90acc 5351 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
d4118588 5352 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
6cb3b707 5353 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
edfe3bfc 5354 SND_PCI_QUIRK(0x19da, 0xa130, "Zotac Z68", ALC662_FIXUP_ZOTAC_Z68),
d2ebd479 5355 SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
53c334ad
TI
5356
5357#if 0
5358 /* Below is a quirk table taken from the old code.
5359 * Basically the device should work as is without the fixup table.
5360 * If BIOS doesn't give a proper info, enable the corresponding
5361 * fixup entry.
7d7eb9ea 5362 */
53c334ad
TI
5363 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC662_FIXUP_ASUS_MODE1),
5364 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC662_FIXUP_ASUS_MODE3),
5365 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC662_FIXUP_ASUS_MODE1),
5366 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC662_FIXUP_ASUS_MODE3),
5367 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
5368 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
5369 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
5370 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC662_FIXUP_ASUS_MODE1),
5371 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC662_FIXUP_ASUS_MODE1),
5372 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
5373 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC662_FIXUP_ASUS_MODE7),
5374 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC662_FIXUP_ASUS_MODE7),
5375 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC662_FIXUP_ASUS_MODE8),
5376 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC662_FIXUP_ASUS_MODE3),
5377 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC662_FIXUP_ASUS_MODE1),
5378 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
5379 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_FIXUP_ASUS_MODE2),
5380 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC662_FIXUP_ASUS_MODE1),
5381 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
5382 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
5383 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
5384 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
5385 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC662_FIXUP_ASUS_MODE1),
5386 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC662_FIXUP_ASUS_MODE3),
5387 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_FIXUP_ASUS_MODE2),
5388 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
5389 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC662_FIXUP_ASUS_MODE5),
5390 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
5391 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
5392 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC662_FIXUP_ASUS_MODE1),
5393 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
5394 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
5395 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC662_FIXUP_ASUS_MODE3),
5396 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC662_FIXUP_ASUS_MODE3),
5397 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC662_FIXUP_ASUS_MODE1),
5398 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC662_FIXUP_ASUS_MODE1),
5399 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC662_FIXUP_ASUS_MODE1),
5400 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC662_FIXUP_ASUS_MODE1),
5401 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC662_FIXUP_ASUS_MODE1),
5402 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
5403 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_FIXUP_ASUS_MODE2),
5404 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC662_FIXUP_ASUS_MODE1),
5405 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
5406 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC662_FIXUP_ASUS_MODE3),
5407 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC662_FIXUP_ASUS_MODE1),
5408 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC662_FIXUP_ASUS_MODE1),
5409 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC662_FIXUP_ASUS_MODE1),
5410 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_FIXUP_ASUS_MODE2),
5411 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
5412 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE4),
5413#endif
6cb3b707
DH
5414 {}
5415};
5416
1727a771 5417static const struct hda_model_fixup alc662_fixup_models[] = {
6be7948f 5418 {.id = ALC272_FIXUP_MARIO, .name = "mario"},
53c334ad
TI
5419 {.id = ALC662_FIXUP_ASUS_MODE1, .name = "asus-mode1"},
5420 {.id = ALC662_FIXUP_ASUS_MODE2, .name = "asus-mode2"},
5421 {.id = ALC662_FIXUP_ASUS_MODE3, .name = "asus-mode3"},
5422 {.id = ALC662_FIXUP_ASUS_MODE4, .name = "asus-mode4"},
5423 {.id = ALC662_FIXUP_ASUS_MODE5, .name = "asus-mode5"},
5424 {.id = ALC662_FIXUP_ASUS_MODE6, .name = "asus-mode6"},
5425 {.id = ALC662_FIXUP_ASUS_MODE7, .name = "asus-mode7"},
5426 {.id = ALC662_FIXUP_ASUS_MODE8, .name = "asus-mode8"},
6e72aa5f 5427 {.id = ALC662_FIXUP_INV_DMIC, .name = "inv-dmic"},
e32aa85a 5428 {.id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE, .name = "dell-headset-multi"},
6be7948f
TB
5429 {}
5430};
6cb3b707 5431
8663ff75
KY
5432static void alc662_fill_coef(struct hda_codec *codec)
5433{
5434 int val, coef;
5435
5436 coef = alc_get_coef0(codec);
5437
5438 switch (codec->vendor_id) {
5439 case 0x10ec0662:
5440 if ((coef & 0x00f0) == 0x0030) {
5441 val = alc_read_coef_idx(codec, 0x4); /* EAPD Ctrl */
5442 alc_write_coef_idx(codec, 0x4, val & ~(1<<10));
5443 }
5444 break;
5445 case 0x10ec0272:
5446 case 0x10ec0273:
5447 case 0x10ec0663:
5448 case 0x10ec0665:
5449 case 0x10ec0670:
5450 case 0x10ec0671:
5451 case 0x10ec0672:
5452 val = alc_read_coef_idx(codec, 0xd); /* EAPD Ctrl */
5453 alc_write_coef_idx(codec, 0xd, val | (1<<14));
5454 break;
5455 }
5456}
6cb3b707 5457
1d045db9
TI
5458/*
5459 */
bc9f98a9
KY
5460static int patch_alc662(struct hda_codec *codec)
5461{
5462 struct alc_spec *spec;
3de95173 5463 int err;
bc9f98a9 5464
3de95173
TI
5465 err = alc_alloc_spec(codec, 0x0b);
5466 if (err < 0)
5467 return err;
bc9f98a9 5468
3de95173 5469 spec = codec->spec;
1f0f4b80 5470
53c334ad
TI
5471 /* handle multiple HPs as is */
5472 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
5473
2c3bf9ab
TI
5474 alc_fix_pll_init(codec, 0x20, 0x04, 15);
5475
8663ff75
KY
5476 spec->init_hook = alc662_fill_coef;
5477 alc662_fill_coef(codec);
5478
1727a771 5479 snd_hda_pick_fixup(codec, alc662_fixup_models,
8e5a0509 5480 alc662_fixup_tbl, alc662_fixups);
1727a771 5481 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
8e5a0509
TI
5482
5483 alc_auto_parse_customize_define(codec);
5484
7504b6cd
TI
5485 if (has_cdefine_beep(codec))
5486 spec->gen.beep_nid = 0x01;
5487
1bb7e43e 5488 if ((alc_get_coef0(codec) & (1 << 14)) &&
e16fb6d1
TI
5489 codec->bus->pci->subsystem_vendor == 0x1025 &&
5490 spec->cdefine.platform_type == 1) {
6134b1a2
WY
5491 err = alc_codec_rename(codec, "ALC272X");
5492 if (err < 0)
e16fb6d1 5493 goto error;
20ca0c35 5494 }
274693f3 5495
b9c5106c
TI
5496 /* automatic parse from the BIOS config */
5497 err = alc662_parse_auto_config(codec);
e16fb6d1
TI
5498 if (err < 0)
5499 goto error;
bc9f98a9 5500
7504b6cd 5501 if (!spec->gen.no_analog && spec->gen.beep_nid) {
da00c244
KY
5502 switch (codec->vendor_id) {
5503 case 0x10ec0662:
5504 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
5505 break;
5506 case 0x10ec0272:
5507 case 0x10ec0663:
5508 case 0x10ec0665:
9ad54547 5509 case 0x10ec0668:
da00c244
KY
5510 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
5511 break;
5512 case 0x10ec0273:
5513 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
5514 break;
5515 }
cec27c89 5516 }
2134ea4f 5517
bc9f98a9 5518 codec->patch_ops = alc_patch_ops;
1c716153 5519 spec->shutup = alc_eapd_shutup;
6cb3b707 5520
1727a771 5521 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
589876e2 5522
bc9f98a9 5523 return 0;
801f49d3 5524
e16fb6d1
TI
5525 error:
5526 alc_free(codec);
5527 return err;
b478b998
KY
5528}
5529
d1eb57f4
KY
5530/*
5531 * ALC680 support
5532 */
d1eb57f4 5533
d1eb57f4
KY
5534static int alc680_parse_auto_config(struct hda_codec *codec)
5535{
3e6179b8 5536 return alc_parse_auto_config(codec, NULL, NULL);
d1eb57f4
KY
5537}
5538
d1eb57f4 5539/*
d1eb57f4 5540 */
d1eb57f4
KY
5541static int patch_alc680(struct hda_codec *codec)
5542{
d1eb57f4
KY
5543 int err;
5544
1f0f4b80 5545 /* ALC680 has no aa-loopback mixer */
3de95173
TI
5546 err = alc_alloc_spec(codec, 0);
5547 if (err < 0)
5548 return err;
1f0f4b80 5549
1ebec5f2
TI
5550 /* automatic parse from the BIOS config */
5551 err = alc680_parse_auto_config(codec);
5552 if (err < 0) {
5553 alc_free(codec);
5554 return err;
d1eb57f4
KY
5555 }
5556
d1eb57f4 5557 codec->patch_ops = alc_patch_ops;
d1eb57f4
KY
5558
5559 return 0;
5560}
5561
1da177e4
LT
5562/*
5563 * patch entries
5564 */
a9111321 5565static const struct hda_codec_preset snd_hda_preset_realtek[] = {
296f0338 5566 { .id = 0x10ec0221, .name = "ALC221", .patch = patch_alc269 },
ba4c4d0a 5567 { .id = 0x10ec0231, .name = "ALC231", .patch = patch_alc269 },
84dfd0ac 5568 { .id = 0x10ec0233, .name = "ALC233", .patch = patch_alc269 },
1d04c9de 5569 { .id = 0x10ec0255, .name = "ALC255", .patch = patch_alc269 },
1da177e4 5570 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
df694daa 5571 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
f6a92248 5572 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
a361d84b 5573 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
f6a92248 5574 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
ebb83eeb 5575 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 },
01afd41f 5576 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
ebb83eeb 5577 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
296f0338 5578 { .id = 0x10ec0276, .name = "ALC276", .patch = patch_alc269 },
befae82e 5579 { .id = 0x10ec0280, .name = "ALC280", .patch = patch_alc269 },
4e01ec63 5580 { .id = 0x10ec0282, .name = "ALC282", .patch = patch_alc269 },
7ff34ad8 5581 { .id = 0x10ec0283, .name = "ALC283", .patch = patch_alc269 },
065380f0 5582 { .id = 0x10ec0284, .name = "ALC284", .patch = patch_alc269 },
161ebf29 5583 { .id = 0x10ec0285, .name = "ALC285", .patch = patch_alc269 },
7fc7d047 5584 { .id = 0x10ec0286, .name = "ALC286", .patch = patch_alc269 },
7ff34ad8 5585 { .id = 0x10ec0290, .name = "ALC290", .patch = patch_alc269 },
af02dde8 5586 { .id = 0x10ec0292, .name = "ALC292", .patch = patch_alc269 },
161ebf29 5587 { .id = 0x10ec0293, .name = "ALC293", .patch = patch_alc269 },
f32610ed 5588 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
bc9f98a9 5589 .patch = patch_alc861 },
f32610ed
JS
5590 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
5591 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
5592 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
bc9f98a9 5593 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
4953550a 5594 .patch = patch_alc882 },
bc9f98a9
KY
5595 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
5596 .patch = patch_alc662 },
cc667a72
DH
5597 { .id = 0x10ec0662, .rev = 0x100300, .name = "ALC662 rev3",
5598 .patch = patch_alc662 },
6dda9f4a 5599 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
cec27c89 5600 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
19a62823 5601 { .id = 0x10ec0668, .name = "ALC668", .patch = patch_alc662 },
6227cdce 5602 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
1d87caa6 5603 { .id = 0x10ec0671, .name = "ALC671", .patch = patch_alc662 },
d1eb57f4 5604 { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 },
f32610ed 5605 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
1da177e4 5606 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
4953550a 5607 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
669faba2 5608 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
4953550a 5609 .patch = patch_alc882 },
cb308f97 5610 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
4953550a 5611 .patch = patch_alc882 },
df694daa 5612 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
e16fb6d1 5613 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 },
4442608d 5614 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
4953550a 5615 .patch = patch_alc882 },
e16fb6d1 5616 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc882 },
4953550a 5617 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
274693f3 5618 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
e16fb6d1 5619 { .id = 0x10ec0899, .name = "ALC898", .patch = patch_alc882 },
19a62823 5620 { .id = 0x10ec0900, .name = "ALC1150", .patch = patch_alc882 },
1da177e4
LT
5621 {} /* terminator */
5622};
1289e9e8
TI
5623
5624MODULE_ALIAS("snd-hda-codec-id:10ec*");
5625
5626MODULE_LICENSE("GPL");
5627MODULE_DESCRIPTION("Realtek HD-audio codec");
5628
5629static struct hda_codec_preset_list realtek_list = {
5630 .preset = snd_hda_preset_realtek,
5631 .owner = THIS_MODULE,
5632};
5633
5634static int __init patch_realtek_init(void)
5635{
5636 return snd_hda_add_codec_preset(&realtek_list);
5637}
5638
5639static void __exit patch_realtek_exit(void)
5640{
5641 snd_hda_delete_codec_preset(&realtek_list);
5642}
5643
5644module_init(patch_realtek_init)
5645module_exit(patch_realtek_exit)
This page took 3.753558 seconds and 5 git commands to generate.