blob: 8aaf1d9c55cfd5e75ac566d11acb15131f3c2853 [file] [log] [blame]
Thomas Gleixnerd0fa1172019-05-20 19:07:57 +02001// SPDX-License-Identifier: GPL-2.0-or-later
Linus Torvalds1da177e2005-04-16 15:20:36 -07002/*
3 * Universal Interface for Intel High Definition Audio Codec
4 *
Takashi Iwai1d045db2011-07-07 18:23:21 +02005 * HD audio interface patch for Realtek ALC codecs
Linus Torvalds1da177e2005-04-16 15:20:36 -07006 *
Kailang Yangdf694da2005-12-05 19:42:22 +01007 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
8 * PeiSen Hou <pshou@realtek.com.tw>
Linus Torvalds1da177e2005-04-16 15:20:36 -07009 * Takashi Iwai <tiwai@suse.de>
Jonathan Woithe409a3e92012-03-27 13:01:01 +103010 * Jonathan Woithe <jwoithe@just42.net>
Linus Torvalds1da177e2005-04-16 15:20:36 -070011 */
12
Linus Torvalds1da177e2005-04-16 15:20:36 -070013#include <linux/init.h>
14#include <linux/delay.h>
15#include <linux/slab.h>
16#include <linux/pci.h>
Takashi Iwai08fb0d02013-01-10 17:33:58 +010017#include <linux/dmi.h>
Paul Gortmakerda155d52011-07-15 12:38:28 -040018#include <linux/module.h>
David Henningsson33f4acd2015-01-07 15:50:13 +010019#include <linux/input.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070020#include <sound/core.h>
Kailang Yang9ad0e492010-09-14 23:22:00 +020021#include <sound/jack.h>
Pierre-Louis Bossartbe57bff2018-08-22 15:24:57 -050022#include <sound/hda_codec.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070023#include "hda_local.h"
Takashi Iwai23d30f22012-05-07 17:17:32 +020024#include "hda_auto_parser.h"
Takashi Iwai1835a0f2011-10-27 22:12:46 +020025#include "hda_jack.h"
Takashi Iwai08c189f2012-12-19 15:22:24 +010026#include "hda_generic.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070027
Takashi Iwaicd63a5f2013-07-05 12:13:59 +020028/* keep halting ALC5505 DSP, for power saving */
29#define HALT_REALTEK_ALC5505
30
Takashi Iwai4a79ba32009-04-22 16:31:35 +020031/* extra amp-initialization sequence types */
32enum {
Takashi Iwai1c76aa52018-06-21 16:37:54 +020033 ALC_INIT_UNDEFINED,
Takashi Iwai4a79ba32009-04-22 16:31:35 +020034 ALC_INIT_NONE,
35 ALC_INIT_DEFAULT,
Takashi Iwai4a79ba32009-04-22 16:31:35 +020036};
37
David Henningsson73bdd592013-04-15 15:44:14 +020038enum {
39 ALC_HEADSET_MODE_UNKNOWN,
40 ALC_HEADSET_MODE_UNPLUGGED,
41 ALC_HEADSET_MODE_HEADSET,
42 ALC_HEADSET_MODE_MIC,
43 ALC_HEADSET_MODE_HEADPHONE,
44};
45
46enum {
47 ALC_HEADSET_TYPE_UNKNOWN,
48 ALC_HEADSET_TYPE_CTIA,
49 ALC_HEADSET_TYPE_OMTP,
50};
51
Hui Wangc7b60a82015-12-28 11:35:25 +080052enum {
53 ALC_KEY_MICMUTE_INDEX,
54};
55
Kailang Yangda00c242010-03-19 11:23:45 +010056struct alc_customize_define {
57 unsigned int sku_cfg;
58 unsigned char port_connectivity;
59 unsigned char check_sum;
60 unsigned char customization;
61 unsigned char external_amp;
62 unsigned int enable_pcbeep:1;
63 unsigned int platform_type:1;
64 unsigned int swap:1;
65 unsigned int override:1;
David Henningsson90622912010-10-14 14:50:18 +020066 unsigned int fixup:1; /* Means that this sku is set by driver, not read from hw */
Kailang Yangda00c242010-03-19 11:23:45 +010067};
68
Linus Torvalds1da177e2005-04-16 15:20:36 -070069struct alc_spec {
Takashi Iwai08c189f2012-12-19 15:22:24 +010070 struct hda_gen_spec gen; /* must be at head */
Takashi Iwai23d30f22012-05-07 17:17:32 +020071
Linus Torvalds1da177e2005-04-16 15:20:36 -070072 /* codec parameterization */
Kailang Yangda00c242010-03-19 11:23:45 +010073 struct alc_customize_define cdefine;
Takashi Iwai08c189f2012-12-19 15:22:24 +010074 unsigned int parse_flags; /* flag for snd_hda_parse_pin_defcfg() */
75
Takashi Iwai5579cd62018-06-19 22:22:41 +020076 /* GPIO bits */
77 unsigned int gpio_mask;
78 unsigned int gpio_dir;
79 unsigned int gpio_data;
Takashi Iwai215c8502018-06-19 22:34:26 +020080 bool gpio_write_delay; /* add a delay before writing gpio_data */
Takashi Iwai5579cd62018-06-19 22:22:41 +020081
Takashi Iwai08fb0d02013-01-10 17:33:58 +010082 /* mute LED for HP laptops, see alc269_fixup_mic_mute_hook() */
83 int mute_led_polarity;
84 hda_nid_t mute_led_nid;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +080085 hda_nid_t cap_mute_led_nid;
Takashi Iwai08fb0d02013-01-10 17:33:58 +010086
Takashi Iwai0f32fd192014-11-19 12:16:14 +010087 unsigned int gpio_mute_led_mask;
88 unsigned int gpio_mic_led_mask;
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +010089
David Henningsson73bdd592013-04-15 15:44:14 +020090 hda_nid_t headset_mic_pin;
91 hda_nid_t headphone_mic_pin;
92 int current_headset_mode;
93 int current_headset_type;
94
Takashi Iwaiae6b8132006-03-03 16:47:17 +010095 /* hooks */
96 void (*init_hook)(struct hda_codec *codec);
Takashi Iwai83012a72012-08-24 18:38:08 +020097#ifdef CONFIG_PM
Daniel T Chenc97259d2009-12-27 18:52:08 -050098 void (*power_hook)(struct hda_codec *codec);
Hector Martinf5de24b2009-12-20 22:51:31 +010099#endif
Takashi Iwai1c7161532011-04-07 10:37:16 +0200100 void (*shutup)(struct hda_codec *codec);
Takashi Iwai70a09762015-12-15 14:59:58 +0100101 void (*reboot_notify)(struct hda_codec *codec);
Takashi Iwaid922b512011-04-28 12:18:53 +0200102
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200103 int init_amp;
Takashi Iwaid433a672010-09-20 15:11:54 +0200104 int codec_variant; /* flag for other variants */
Kailang Yang97a26572013-11-29 00:35:26 -0500105 unsigned int has_alc5505_dsp:1;
106 unsigned int no_depop_delay:1;
Kailang Yang693abe12019-01-29 15:38:21 +0800107 unsigned int done_hp_init:1;
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +0100108 unsigned int no_shutup_pins:1;
Kailang Yangd3ba58b2019-05-06 15:09:42 +0800109 unsigned int ultra_low_power:1;
Takashi Iwaie64f14f2009-01-20 18:32:55 +0100110
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200111 /* for PLL fix */
112 hda_nid_t pll_nid;
113 unsigned int pll_coef_idx, pll_coef_bit;
Takashi Iwai1bb7e432011-10-17 16:50:59 +0200114 unsigned int coef0;
David Henningsson33f4acd2015-01-07 15:50:13 +0100115 struct input_dev *kb_dev;
Hui Wangc7b60a82015-12-28 11:35:25 +0800116 u8 alc_mute_keycode_map[1];
Kailang Yangdf694da2005-12-05 19:42:22 +0100117};
118
Takashi Iwai23f0c042009-02-26 13:03:58 +0100119/*
Takashi Iwaif2a227c2014-08-18 13:35:22 +0200120 * COEF access helper functions
121 */
122
123static int alc_read_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
124 unsigned int coef_idx)
125{
126 unsigned int val;
127
128 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, coef_idx);
129 val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PROC_COEF, 0);
130 return val;
131}
132
133#define alc_read_coef_idx(codec, coef_idx) \
134 alc_read_coefex_idx(codec, 0x20, coef_idx)
135
136static void alc_write_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
137 unsigned int coef_idx, unsigned int coef_val)
138{
139 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, coef_idx);
140 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PROC_COEF, coef_val);
141}
142
143#define alc_write_coef_idx(codec, coef_idx, coef_val) \
144 alc_write_coefex_idx(codec, 0x20, coef_idx, coef_val)
145
Takashi Iwai98b24882014-08-18 13:47:50 +0200146static void alc_update_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
147 unsigned int coef_idx, unsigned int mask,
148 unsigned int bits_set)
149{
150 unsigned int val = alc_read_coefex_idx(codec, nid, coef_idx);
151
152 if (val != -1)
153 alc_write_coefex_idx(codec, nid, coef_idx,
154 (val & ~mask) | bits_set);
155}
156
157#define alc_update_coef_idx(codec, coef_idx, mask, bits_set) \
158 alc_update_coefex_idx(codec, 0x20, coef_idx, mask, bits_set)
159
Takashi Iwaif2a227c2014-08-18 13:35:22 +0200160/* a special bypass for COEF 0; read the cached value at the second time */
161static unsigned int alc_get_coef0(struct hda_codec *codec)
162{
163 struct alc_spec *spec = codec->spec;
164
165 if (!spec->coef0)
166 spec->coef0 = alc_read_coef_idx(codec, 0);
167 return spec->coef0;
168}
169
Takashi Iwai54db6c32014-08-18 15:11:19 +0200170/* coef writes/updates batch */
171struct coef_fw {
172 unsigned char nid;
173 unsigned char idx;
174 unsigned short mask;
175 unsigned short val;
176};
177
178#define UPDATE_COEFEX(_nid, _idx, _mask, _val) \
179 { .nid = (_nid), .idx = (_idx), .mask = (_mask), .val = (_val) }
180#define WRITE_COEFEX(_nid, _idx, _val) UPDATE_COEFEX(_nid, _idx, -1, _val)
181#define WRITE_COEF(_idx, _val) WRITE_COEFEX(0x20, _idx, _val)
182#define UPDATE_COEF(_idx, _mask, _val) UPDATE_COEFEX(0x20, _idx, _mask, _val)
183
184static void alc_process_coef_fw(struct hda_codec *codec,
185 const struct coef_fw *fw)
186{
187 for (; fw->nid; fw++) {
188 if (fw->mask == (unsigned short)-1)
189 alc_write_coefex_idx(codec, fw->nid, fw->idx, fw->val);
190 else
191 alc_update_coefex_idx(codec, fw->nid, fw->idx,
192 fw->mask, fw->val);
193 }
194}
195
Takashi Iwaif2a227c2014-08-18 13:35:22 +0200196/*
Takashi Iwai1d045db2011-07-07 18:23:21 +0200197 * GPIO setup tables, used in initialization
Kailang Yangdf694da2005-12-05 19:42:22 +0100198 */
Takashi Iwai5579cd62018-06-19 22:22:41 +0200199
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200200/* Enable GPIO mask and set output */
Takashi Iwai5579cd62018-06-19 22:22:41 +0200201static void alc_setup_gpio(struct hda_codec *codec, unsigned int mask)
202{
203 struct alc_spec *spec = codec->spec;
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200204
Takashi Iwai5579cd62018-06-19 22:22:41 +0200205 spec->gpio_mask |= mask;
206 spec->gpio_dir |= mask;
207 spec->gpio_data |= mask;
208}
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200209
Takashi Iwai5579cd62018-06-19 22:22:41 +0200210static void alc_write_gpio_data(struct hda_codec *codec)
211{
212 struct alc_spec *spec = codec->spec;
213
214 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
215 spec->gpio_data);
216}
217
Takashi Iwaiaaf312d2018-06-19 22:28:22 +0200218static void alc_update_gpio_data(struct hda_codec *codec, unsigned int mask,
219 bool on)
220{
221 struct alc_spec *spec = codec->spec;
222 unsigned int oldval = spec->gpio_data;
223
224 if (on)
225 spec->gpio_data |= mask;
226 else
227 spec->gpio_data &= ~mask;
228 if (oldval != spec->gpio_data)
229 alc_write_gpio_data(codec);
230}
231
Takashi Iwai5579cd62018-06-19 22:22:41 +0200232static void alc_write_gpio(struct hda_codec *codec)
233{
234 struct alc_spec *spec = codec->spec;
235
236 if (!spec->gpio_mask)
237 return;
238
239 snd_hda_codec_write(codec, codec->core.afg, 0,
240 AC_VERB_SET_GPIO_MASK, spec->gpio_mask);
241 snd_hda_codec_write(codec, codec->core.afg, 0,
242 AC_VERB_SET_GPIO_DIRECTION, spec->gpio_dir);
Takashi Iwai215c8502018-06-19 22:34:26 +0200243 if (spec->gpio_write_delay)
244 msleep(1);
Takashi Iwai5579cd62018-06-19 22:22:41 +0200245 alc_write_gpio_data(codec);
246}
247
248static void alc_fixup_gpio(struct hda_codec *codec, int action,
249 unsigned int mask)
250{
251 if (action == HDA_FIXUP_ACT_PRE_PROBE)
252 alc_setup_gpio(codec, mask);
253}
254
255static void alc_fixup_gpio1(struct hda_codec *codec,
256 const struct hda_fixup *fix, int action)
257{
258 alc_fixup_gpio(codec, action, 0x01);
259}
260
261static void alc_fixup_gpio2(struct hda_codec *codec,
262 const struct hda_fixup *fix, int action)
263{
264 alc_fixup_gpio(codec, action, 0x02);
265}
266
267static void alc_fixup_gpio3(struct hda_codec *codec,
268 const struct hda_fixup *fix, int action)
269{
270 alc_fixup_gpio(codec, action, 0x03);
271}
Kailang Yangbdd148a2007-05-08 15:19:08 +0200272
Takashi Iwaiae065f12018-06-19 23:00:03 +0200273static void alc_fixup_gpio4(struct hda_codec *codec,
274 const struct hda_fixup *fix, int action)
275{
276 alc_fixup_gpio(codec, action, 0x04);
277}
278
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200279/*
280 * Fix hardware PLL issue
281 * On some codecs, the analog PLL gating control must be off while
282 * the default value is 1.
283 */
284static void alc_fix_pll(struct hda_codec *codec)
285{
286 struct alc_spec *spec = codec->spec;
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200287
Takashi Iwai98b24882014-08-18 13:47:50 +0200288 if (spec->pll_nid)
289 alc_update_coefex_idx(codec, spec->pll_nid, spec->pll_coef_idx,
290 1 << spec->pll_coef_bit, 0);
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200291}
292
293static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
294 unsigned int coef_idx, unsigned int coef_bit)
295{
296 struct alc_spec *spec = codec->spec;
297 spec->pll_nid = nid;
298 spec->pll_coef_idx = coef_idx;
299 spec->pll_coef_bit = coef_bit;
300 alc_fix_pll(codec);
301}
302
Takashi Iwaicf5a2272012-02-20 16:31:07 +0100303/* update the master volume per volume-knob's unsol event */
Takashi Iwai1a4f69d2014-09-11 15:22:46 +0200304static void alc_update_knob_master(struct hda_codec *codec,
305 struct hda_jack_callback *jack)
Takashi Iwaicf5a2272012-02-20 16:31:07 +0100306{
307 unsigned int val;
308 struct snd_kcontrol *kctl;
309 struct snd_ctl_elem_value *uctl;
310
311 kctl = snd_hda_find_mixer_ctl(codec, "Master Playback Volume");
312 if (!kctl)
313 return;
314 uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
315 if (!uctl)
316 return;
Takashi Iwai2ebab402016-02-09 10:23:52 +0100317 val = snd_hda_codec_read(codec, jack->nid, 0,
Takashi Iwaicf5a2272012-02-20 16:31:07 +0100318 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
319 val &= HDA_AMP_VOLMASK;
320 uctl->value.integer.value[0] = val;
321 uctl->value.integer.value[1] = val;
322 kctl->put(kctl, uctl);
323 kfree(uctl);
324}
325
David Henningsson29adc4b2012-09-25 11:31:00 +0200326static void alc880_unsol_event(struct hda_codec *codec, unsigned int res)
Takashi Iwaif21d78e2012-01-19 12:10:29 +0100327{
David Henningsson29adc4b2012-09-25 11:31:00 +0200328 /* For some reason, the res given from ALC880 is broken.
329 Here we adjust it properly. */
330 snd_hda_jack_unsol_event(codec, res >> 2);
Takashi Iwaif21d78e2012-01-19 12:10:29 +0100331}
332
Kailang Yang394c97f2014-11-12 17:38:08 +0800333/* Change EAPD to verb control */
334static void alc_fill_eapd_coef(struct hda_codec *codec)
335{
336 int coef;
337
338 coef = alc_get_coef0(codec);
339
Takashi Iwai7639a062015-03-03 10:07:24 +0100340 switch (codec->core.vendor_id) {
Kailang Yang394c97f2014-11-12 17:38:08 +0800341 case 0x10ec0262:
342 alc_update_coef_idx(codec, 0x7, 0, 1<<5);
343 break;
344 case 0x10ec0267:
345 case 0x10ec0268:
346 alc_update_coef_idx(codec, 0x7, 0, 1<<13);
347 break;
348 case 0x10ec0269:
349 if ((coef & 0x00f0) == 0x0010)
350 alc_update_coef_idx(codec, 0xd, 0, 1<<14);
351 if ((coef & 0x00f0) == 0x0020)
352 alc_update_coef_idx(codec, 0x4, 1<<15, 0);
353 if ((coef & 0x00f0) == 0x0030)
354 alc_update_coef_idx(codec, 0x10, 1<<9, 0);
355 break;
356 case 0x10ec0280:
357 case 0x10ec0284:
358 case 0x10ec0290:
359 case 0x10ec0292:
360 alc_update_coef_idx(codec, 0x4, 1<<15, 0);
361 break;
Kailang Yang42314302016-02-03 15:03:50 +0800362 case 0x10ec0225:
Takashi Iwai44be77c2017-12-27 08:53:59 +0100363 case 0x10ec0295:
364 case 0x10ec0299:
365 alc_update_coef_idx(codec, 0x67, 0xf000, 0x3000);
366 /* fallthrough */
367 case 0x10ec0215:
Kailang Yang394c97f2014-11-12 17:38:08 +0800368 case 0x10ec0233:
Kailang Yangea04a1d2018-04-25 15:31:52 +0800369 case 0x10ec0235:
Kailang Yang736f20a2017-10-20 15:06:34 +0800370 case 0x10ec0236:
Kailang Yang394c97f2014-11-12 17:38:08 +0800371 case 0x10ec0255:
Kailang Yang4344aec2014-12-17 17:39:05 +0800372 case 0x10ec0256:
Kailang Yangf429e7e2017-12-05 15:38:24 +0800373 case 0x10ec0257:
Kailang Yang394c97f2014-11-12 17:38:08 +0800374 case 0x10ec0282:
375 case 0x10ec0283:
376 case 0x10ec0286:
377 case 0x10ec0288:
Kailang Yang0a6f0602017-06-30 16:00:48 +0800378 case 0x10ec0285:
Kailang Yang506b62c2014-12-18 17:07:44 +0800379 case 0x10ec0298:
Kailang Yang0a6f0602017-06-30 16:00:48 +0800380 case 0x10ec0289:
Kailang Yang1078bef2018-11-08 16:36:15 +0800381 case 0x10ec0300:
Kailang Yang394c97f2014-11-12 17:38:08 +0800382 alc_update_coef_idx(codec, 0x10, 1<<9, 0);
383 break;
Kailang Yang3aabf942017-11-08 15:28:33 +0800384 case 0x10ec0275:
385 alc_update_coef_idx(codec, 0xe, 0, 1<<0);
386 break;
Kailang Yang394c97f2014-11-12 17:38:08 +0800387 case 0x10ec0293:
388 alc_update_coef_idx(codec, 0xa, 1<<13, 0);
389 break;
Kailang Yangdcd4f0d2016-05-04 15:50:18 +0800390 case 0x10ec0234:
391 case 0x10ec0274:
392 case 0x10ec0294:
Kailang Yang6fbae352016-05-30 16:44:20 +0800393 case 0x10ec0700:
394 case 0x10ec0701:
395 case 0x10ec0703:
Kailang Yangdcd4f0d2016-05-04 15:50:18 +0800396 alc_update_coef_idx(codec, 0x10, 1<<15, 0);
397 break;
Kailang Yang394c97f2014-11-12 17:38:08 +0800398 case 0x10ec0662:
399 if ((coef & 0x00f0) == 0x0030)
400 alc_update_coef_idx(codec, 0x4, 1<<10, 0); /* EAPD Ctrl */
401 break;
402 case 0x10ec0272:
403 case 0x10ec0273:
404 case 0x10ec0663:
405 case 0x10ec0665:
406 case 0x10ec0670:
407 case 0x10ec0671:
408 case 0x10ec0672:
409 alc_update_coef_idx(codec, 0xd, 0, 1<<14); /* EAPD Ctrl */
410 break;
411 case 0x10ec0668:
412 alc_update_coef_idx(codec, 0x7, 3<<13, 0);
413 break;
414 case 0x10ec0867:
415 alc_update_coef_idx(codec, 0x4, 1<<10, 0);
416 break;
417 case 0x10ec0888:
418 if ((coef & 0x00f0) == 0x0020 || (coef & 0x00f0) == 0x0030)
419 alc_update_coef_idx(codec, 0x7, 1<<5, 0);
420 break;
421 case 0x10ec0892:
422 alc_update_coef_idx(codec, 0x7, 1<<5, 0);
423 break;
424 case 0x10ec0899:
425 case 0x10ec0900:
Kailang Yang65553b12017-07-11 15:15:47 +0800426 case 0x10ec1168:
Kailang Yanga535ad52017-01-16 16:59:26 +0800427 case 0x10ec1220:
Kailang Yang394c97f2014-11-12 17:38:08 +0800428 alc_update_coef_idx(codec, 0x7, 1<<1, 0);
429 break;
430 }
431}
432
Kailang Yangf9423e72008-05-27 12:32:25 +0200433/* additional initialization for ALC888 variants */
434static void alc888_coef_init(struct hda_codec *codec)
435{
Kailang Yang1df88742014-10-29 16:10:13 +0800436 switch (alc_get_coef0(codec) & 0x00f0) {
437 /* alc888-VA */
438 case 0x00:
439 /* alc888-VB */
440 case 0x10:
441 alc_update_coef_idx(codec, 7, 0, 0x2030); /* Turn EAPD to High */
442 break;
443 }
Jaroslav Kysela87a8c372009-07-23 10:58:29 +0200444}
445
Takashi Iwai3fb4a502010-01-19 15:46:37 +0100446/* turn on/off EAPD control (only if available) */
447static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
448{
449 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
450 return;
451 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
452 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
453 on ? 2 : 0);
454}
455
Takashi Iwai691f1fc2011-04-07 10:31:43 +0200456/* turn on/off EAPD controls of the codec */
457static void alc_auto_setup_eapd(struct hda_codec *codec, bool on)
458{
459 /* We currently only handle front, HP */
Takashi Iwai39fa84e2011-06-27 15:28:57 +0200460 static hda_nid_t pins[] = {
Hui Wangaf95b412015-03-26 17:14:55 +0800461 0x0f, 0x10, 0x14, 0x15, 0x17, 0
Takashi Iwai39fa84e2011-06-27 15:28:57 +0200462 };
463 hda_nid_t *p;
464 for (p = pins; *p; p++)
465 set_eapd(codec, *p, on);
Takashi Iwai691f1fc2011-04-07 10:31:43 +0200466}
467
Kailang Yangdad31972019-05-10 16:28:57 +0800468static int find_ext_mic_pin(struct hda_codec *codec);
469
470static void alc_headset_mic_no_shutup(struct hda_codec *codec)
471{
472 const struct hda_pincfg *pin;
473 int mic_pin = find_ext_mic_pin(codec);
474 int i;
475
476 /* don't shut up pins when unloading the driver; otherwise it breaks
477 * the default pin setup at the next load of the driver
478 */
479 if (codec->bus->shutdown)
480 return;
481
482 snd_array_for_each(&codec->init_pins, i, pin) {
483 /* use read here for syncing after issuing each verb */
484 if (pin->nid != mic_pin)
485 snd_hda_codec_read(codec, pin->nid, 0,
486 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
487 }
488
489 codec->pins_shutup = 1;
490}
491
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +0100492static void alc_shutup_pins(struct hda_codec *codec)
493{
494 struct alc_spec *spec = codec->spec;
495
Kailang Yangdad31972019-05-10 16:28:57 +0800496 switch (codec->core.vendor_id) {
497 case 0x10ec0286:
498 case 0x10ec0288:
499 case 0x10ec0298:
500 alc_headset_mic_no_shutup(codec);
501 break;
502 default:
503 if (!spec->no_shutup_pins)
504 snd_hda_shutup_pins(codec);
505 break;
506 }
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +0100507}
508
Takashi Iwai1c7161532011-04-07 10:37:16 +0200509/* generic shutup callback;
Lars-Peter Clausen4ce8e6a2016-11-08 15:48:06 +0100510 * just turning off EAPD and a little pause for avoiding pop-noise
Takashi Iwai1c7161532011-04-07 10:37:16 +0200511 */
512static void alc_eapd_shutup(struct hda_codec *codec)
513{
Kailang Yang97a26572013-11-29 00:35:26 -0500514 struct alc_spec *spec = codec->spec;
515
Takashi Iwai1c7161532011-04-07 10:37:16 +0200516 alc_auto_setup_eapd(codec, false);
Kailang Yang97a26572013-11-29 00:35:26 -0500517 if (!spec->no_depop_delay)
518 msleep(200);
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +0100519 alc_shutup_pins(codec);
Takashi Iwai1c7161532011-04-07 10:37:16 +0200520}
521
Takashi Iwai1d045db2011-07-07 18:23:21 +0200522/* generic EAPD initialization */
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200523static void alc_auto_init_amp(struct hda_codec *codec, int type)
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200524{
Takashi Iwai39fa84e2011-06-27 15:28:57 +0200525 alc_auto_setup_eapd(codec, true);
Takashi Iwai5579cd62018-06-19 22:22:41 +0200526 alc_write_gpio(codec);
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200527 switch (type) {
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200528 case ALC_INIT_DEFAULT:
Takashi Iwai7639a062015-03-03 10:07:24 +0100529 switch (codec->core.vendor_id) {
Kailang Yangc9b58002007-10-16 14:30:01 +0200530 case 0x10ec0260:
Takashi Iwai98b24882014-08-18 13:47:50 +0200531 alc_update_coefex_idx(codec, 0x1a, 7, 0, 0x2010);
Kailang Yangc9b58002007-10-16 14:30:01 +0200532 break;
Kailang Yangc9b58002007-10-16 14:30:01 +0200533 case 0x10ec0880:
534 case 0x10ec0882:
535 case 0x10ec0883:
536 case 0x10ec0885:
Kailang Yang1df88742014-10-29 16:10:13 +0800537 alc_update_coef_idx(codec, 7, 0, 0x2030);
Kailang Yangc9b58002007-10-16 14:30:01 +0200538 break;
Kailang Yangf9423e72008-05-27 12:32:25 +0200539 case 0x10ec0888:
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200540 alc888_coef_init(codec);
Kailang Yangf9423e72008-05-27 12:32:25 +0200541 break;
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200542 }
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200543 break;
544 }
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200545}
Kailang Yangea1fb292008-08-26 12:58:38 +0200546
Takashi Iwai35a39f92019-02-01 11:19:50 +0100547/* get a primary headphone pin if available */
548static hda_nid_t alc_get_hp_pin(struct alc_spec *spec)
549{
550 if (spec->gen.autocfg.hp_pins[0])
551 return spec->gen.autocfg.hp_pins[0];
552 if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
553 return spec->gen.autocfg.line_out_pins[0];
554 return 0;
555}
Takashi Iwai1d045db2011-07-07 18:23:21 +0200556
557/*
558 * Realtek SSID verification
559 */
560
David Henningsson90622912010-10-14 14:50:18 +0200561/* Could be any non-zero and even value. When used as fixup, tells
562 * the driver to ignore any present sku defines.
563 */
564#define ALC_FIXUP_SKU_IGNORE (2)
565
Takashi Iwai23d30f22012-05-07 17:17:32 +0200566static void alc_fixup_sku_ignore(struct hda_codec *codec,
567 const struct hda_fixup *fix, int action)
568{
569 struct alc_spec *spec = codec->spec;
570 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
571 spec->cdefine.fixup = 1;
572 spec->cdefine.sku_cfg = ALC_FIXUP_SKU_IGNORE;
573 }
574}
575
Mengdong Linb5c66112013-11-29 00:35:35 -0500576static void alc_fixup_no_depop_delay(struct hda_codec *codec,
577 const struct hda_fixup *fix, int action)
578{
579 struct alc_spec *spec = codec->spec;
580
Mengdong Lin84d2dc32013-12-02 22:26:03 -0500581 if (action == HDA_FIXUP_ACT_PROBE) {
Mengdong Linb5c66112013-11-29 00:35:35 -0500582 spec->no_depop_delay = 1;
Mengdong Lin84d2dc32013-12-02 22:26:03 -0500583 codec->depop_delay = 0;
584 }
Mengdong Linb5c66112013-11-29 00:35:35 -0500585}
586
Kailang Yangda00c242010-03-19 11:23:45 +0100587static int alc_auto_parse_customize_define(struct hda_codec *codec)
588{
589 unsigned int ass, tmp, i;
Takashi Iwai7fb56222010-03-22 17:09:47 +0100590 unsigned nid = 0;
Kailang Yangda00c242010-03-19 11:23:45 +0100591 struct alc_spec *spec = codec->spec;
592
Takashi Iwaib6cbe512010-07-28 17:43:36 +0200593 spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
594
David Henningsson90622912010-10-14 14:50:18 +0200595 if (spec->cdefine.fixup) {
596 ass = spec->cdefine.sku_cfg;
597 if (ass == ALC_FIXUP_SKU_IGNORE)
598 return -1;
599 goto do_sku;
600 }
601
Takashi Iwai5100cd02014-02-15 10:03:19 +0100602 if (!codec->bus->pci)
603 return -1;
Takashi Iwai7639a062015-03-03 10:07:24 +0100604 ass = codec->core.subsystem_id & 0xffff;
Takashi Iwaib6cbe512010-07-28 17:43:36 +0200605 if (ass != codec->bus->pci->subsystem_device && (ass & 1))
Kailang Yangda00c242010-03-19 11:23:45 +0100606 goto do_sku;
607
608 nid = 0x1d;
Takashi Iwai7639a062015-03-03 10:07:24 +0100609 if (codec->core.vendor_id == 0x10ec0260)
Kailang Yangda00c242010-03-19 11:23:45 +0100610 nid = 0x17;
611 ass = snd_hda_codec_get_pincfg(codec, nid);
612
613 if (!(ass & 1)) {
Takashi Iwai4e76a882014-02-25 12:21:03 +0100614 codec_info(codec, "%s: SKU not ready 0x%08x\n",
Takashi Iwai7639a062015-03-03 10:07:24 +0100615 codec->core.chip_name, ass);
Kailang Yangda00c242010-03-19 11:23:45 +0100616 return -1;
617 }
618
619 /* check sum */
620 tmp = 0;
621 for (i = 1; i < 16; i++) {
622 if ((ass >> i) & 1)
623 tmp++;
624 }
625 if (((ass >> 16) & 0xf) != tmp)
626 return -1;
627
628 spec->cdefine.port_connectivity = ass >> 30;
629 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
630 spec->cdefine.check_sum = (ass >> 16) & 0xf;
631 spec->cdefine.customization = ass >> 8;
632do_sku:
633 spec->cdefine.sku_cfg = ass;
634 spec->cdefine.external_amp = (ass & 0x38) >> 3;
635 spec->cdefine.platform_type = (ass & 0x4) >> 2;
636 spec->cdefine.swap = (ass & 0x2) >> 1;
637 spec->cdefine.override = ass & 0x1;
638
Takashi Iwai4e76a882014-02-25 12:21:03 +0100639 codec_dbg(codec, "SKU: Nid=0x%x sku_cfg=0x%08x\n",
Kailang Yangda00c242010-03-19 11:23:45 +0100640 nid, spec->cdefine.sku_cfg);
Takashi Iwai4e76a882014-02-25 12:21:03 +0100641 codec_dbg(codec, "SKU: port_connectivity=0x%x\n",
Kailang Yangda00c242010-03-19 11:23:45 +0100642 spec->cdefine.port_connectivity);
Takashi Iwai4e76a882014-02-25 12:21:03 +0100643 codec_dbg(codec, "SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
644 codec_dbg(codec, "SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
645 codec_dbg(codec, "SKU: customization=0x%08x\n", spec->cdefine.customization);
646 codec_dbg(codec, "SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
647 codec_dbg(codec, "SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
648 codec_dbg(codec, "SKU: swap=0x%x\n", spec->cdefine.swap);
649 codec_dbg(codec, "SKU: override=0x%x\n", spec->cdefine.override);
Kailang Yangda00c242010-03-19 11:23:45 +0100650
651 return 0;
652}
653
Takashi Iwai08c189f2012-12-19 15:22:24 +0100654/* return the position of NID in the list, or -1 if not found */
655static int find_idx_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
656{
657 int i;
658 for (i = 0; i < nums; i++)
659 if (list[i] == nid)
660 return i;
661 return -1;
662}
Takashi Iwai1d045db2011-07-07 18:23:21 +0200663/* return true if the given NID is found in the list */
Takashi Iwai3af9ee62011-06-27 12:34:01 +0200664static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
665{
Takashi Iwai21268962011-07-07 15:01:13 +0200666 return find_idx_in_nid_list(nid, list, nums) >= 0;
Takashi Iwai3af9ee62011-06-27 12:34:01 +0200667}
668
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200669/* check subsystem ID and set up device-specific initialization;
670 * return 1 if initialized, 0 if invalid SSID
671 */
672/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
673 * 31 ~ 16 : Manufacture ID
674 * 15 ~ 8 : SKU ID
675 * 7 ~ 0 : Assembly ID
676 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
677 */
Takashi Iwai58c57cf2014-01-07 18:22:49 +0100678static int alc_subsystem_id(struct hda_codec *codec, const hda_nid_t *ports)
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200679{
680 unsigned int ass, tmp, i;
681 unsigned nid;
682 struct alc_spec *spec = codec->spec;
683
David Henningsson90622912010-10-14 14:50:18 +0200684 if (spec->cdefine.fixup) {
685 ass = spec->cdefine.sku_cfg;
686 if (ass == ALC_FIXUP_SKU_IGNORE)
687 return 0;
688 goto do_sku;
689 }
690
Takashi Iwai7639a062015-03-03 10:07:24 +0100691 ass = codec->core.subsystem_id & 0xffff;
Takashi Iwai5100cd02014-02-15 10:03:19 +0100692 if (codec->bus->pci &&
693 ass != codec->bus->pci->subsystem_device && (ass & 1))
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200694 goto do_sku;
695
696 /* invalid SSID, check the special NID pin defcfg instead */
697 /*
Sasha Alexandrdef319f2009-06-16 16:00:15 -0400698 * 31~30 : port connectivity
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200699 * 29~21 : reserve
700 * 20 : PCBEEP input
701 * 19~16 : Check sum (15:1)
702 * 15~1 : Custom
703 * 0 : override
704 */
705 nid = 0x1d;
Takashi Iwai7639a062015-03-03 10:07:24 +0100706 if (codec->core.vendor_id == 0x10ec0260)
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200707 nid = 0x17;
708 ass = snd_hda_codec_get_pincfg(codec, nid);
Takashi Iwai4e76a882014-02-25 12:21:03 +0100709 codec_dbg(codec,
710 "realtek: No valid SSID, checking pincfg 0x%08x for NID 0x%x\n",
Takashi Iwaicb6605c2009-04-28 13:03:19 +0200711 ass, nid);
Kailang Yang6227cdc2010-02-25 08:36:52 +0100712 if (!(ass & 1))
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200713 return 0;
714 if ((ass >> 30) != 1) /* no physical connection */
715 return 0;
716
717 /* check sum */
718 tmp = 0;
719 for (i = 1; i < 16; i++) {
720 if ((ass >> i) & 1)
721 tmp++;
722 }
723 if (((ass >> 16) & 0xf) != tmp)
724 return 0;
725do_sku:
Takashi Iwai4e76a882014-02-25 12:21:03 +0100726 codec_dbg(codec, "realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
Takashi Iwai7639a062015-03-03 10:07:24 +0100727 ass & 0xffff, codec->core.vendor_id);
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200728 /*
729 * 0 : override
730 * 1 : Swap Jack
731 * 2 : 0 --> Desktop, 1 --> Laptop
732 * 3~5 : External Amplifier control
733 * 7~6 : Reserved
734 */
735 tmp = (ass & 0x38) >> 3; /* external Amp control */
Takashi Iwai1c76aa52018-06-21 16:37:54 +0200736 if (spec->init_amp == ALC_INIT_UNDEFINED) {
737 switch (tmp) {
738 case 1:
Takashi Iwai5579cd62018-06-19 22:22:41 +0200739 alc_setup_gpio(codec, 0x01);
Takashi Iwai1c76aa52018-06-21 16:37:54 +0200740 break;
741 case 3:
Takashi Iwai5579cd62018-06-19 22:22:41 +0200742 alc_setup_gpio(codec, 0x02);
Takashi Iwai1c76aa52018-06-21 16:37:54 +0200743 break;
744 case 7:
Takashi Iwai5579cd62018-06-19 22:22:41 +0200745 alc_setup_gpio(codec, 0x03);
Takashi Iwai1c76aa52018-06-21 16:37:54 +0200746 break;
747 case 5:
748 default:
749 spec->init_amp = ALC_INIT_DEFAULT;
750 break;
751 }
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200752 }
753
754 /* is laptop or Desktop and enable the function "Mute internal speaker
755 * when the external headphone out jack is plugged"
756 */
757 if (!(ass & 0x8000))
758 return 1;
759 /*
760 * 10~8 : Jack location
761 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
762 * 14~13: Resvered
763 * 15 : 1 --> enable the function "Mute internal speaker
764 * when the external headphone out jack is plugged"
765 */
Takashi Iwai35a39f92019-02-01 11:19:50 +0100766 if (!alc_get_hp_pin(spec)) {
Takashi Iwai01d48252009-10-06 13:21:54 +0200767 hda_nid_t nid;
Kailang Yangc9b58002007-10-16 14:30:01 +0200768 tmp = (ass >> 11) & 0x3; /* HP to chassis */
Takashi Iwai58c57cf2014-01-07 18:22:49 +0100769 nid = ports[tmp];
Takashi Iwai08c189f2012-12-19 15:22:24 +0100770 if (found_in_nid_list(nid, spec->gen.autocfg.line_out_pins,
771 spec->gen.autocfg.line_outs))
Takashi Iwai3af9ee62011-06-27 12:34:01 +0200772 return 1;
Takashi Iwai08c189f2012-12-19 15:22:24 +0100773 spec->gen.autocfg.hp_pins[0] = nid;
Kailang Yangc9b58002007-10-16 14:30:01 +0200774 }
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200775 return 1;
776}
Kailang Yangea1fb292008-08-26 12:58:38 +0200777
Takashi Iwai3e6179b2011-07-08 16:55:13 +0200778/* Check the validity of ALC subsystem-id
779 * ports contains an array of 4 pin NIDs for port-A, E, D and I */
780static void alc_ssid_check(struct hda_codec *codec, const hda_nid_t *ports)
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200781{
Takashi Iwai58c57cf2014-01-07 18:22:49 +0100782 if (!alc_subsystem_id(codec, ports)) {
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200783 struct alc_spec *spec = codec->spec;
Takashi Iwai4e76a882014-02-25 12:21:03 +0100784 codec_dbg(codec,
785 "realtek: Enable default setup for auto mode as fallback\n");
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200786 spec->init_amp = ALC_INIT_DEFAULT;
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200787 }
Takashi Iwai21268962011-07-07 15:01:13 +0200788}
Takashi Iwai1a1455d2011-04-28 17:36:18 +0200789
Takashi Iwai41e41f12005-06-08 14:48:49 +0200790/*
Takashi Iwai1d045db2011-07-07 18:23:21 +0200791 */
792
David Henningsson9d36a7d2014-10-07 10:18:42 +0200793static void alc_fixup_inv_dmic(struct hda_codec *codec,
794 const struct hda_fixup *fix, int action)
Takashi Iwai125821a2012-06-22 14:30:29 +0200795{
796 struct alc_spec *spec = codec->spec;
Takashi Iwai668d1e92012-11-29 14:10:17 +0100797
David Henningsson9d36a7d2014-10-07 10:18:42 +0200798 spec->gen.inv_dmic_split = 1;
Takashi Iwai6e72aa52012-06-25 10:52:25 +0200799}
800
Takashi Iwai603c4012008-07-30 15:01:44 +0200801
Takashi Iwai2eab6942012-12-18 15:30:41 +0100802static int alc_build_controls(struct hda_codec *codec)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700803{
Takashi Iwaia5cb4632018-06-20 12:50:11 +0200804 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700805
Takashi Iwai08c189f2012-12-19 15:22:24 +0100806 err = snd_hda_gen_build_controls(codec);
807 if (err < 0)
808 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700809
Takashi Iwai1727a772013-01-10 09:52:52 +0100810 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_BUILD);
Takashi Iwai420b0fe2012-03-12 12:35:27 +0100811 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700812}
813
Takashi Iwaie9edcee2005-06-13 14:16:38 +0200814
Linus Torvalds1da177e2005-04-16 15:20:36 -0700815/*
Takashi Iwaiae6b8132006-03-03 16:47:17 +0100816 * Common callbacks
Takashi Iwaie9edcee2005-06-13 14:16:38 +0200817 */
Takashi Iwai16ded522005-06-10 19:58:24 +0200818
Takashi Iwaic9af7532019-05-10 11:01:43 +0200819static void alc_pre_init(struct hda_codec *codec)
820{
821 alc_fill_eapd_coef(codec);
822}
823
Kailang Yangaeac1a02019-05-16 16:10:44 +0800824#define is_s3_resume(codec) \
825 ((codec)->core.dev.power.power_state.event == PM_EVENT_RESUME)
Takashi Iwaic9af7532019-05-10 11:01:43 +0200826#define is_s4_resume(codec) \
827 ((codec)->core.dev.power.power_state.event == PM_EVENT_RESTORE)
828
Linus Torvalds1da177e2005-04-16 15:20:36 -0700829static int alc_init(struct hda_codec *codec)
830{
831 struct alc_spec *spec = codec->spec;
Takashi Iwaie9edcee2005-06-13 14:16:38 +0200832
Takashi Iwaic9af7532019-05-10 11:01:43 +0200833 /* hibernation resume needs the full chip initialization */
834 if (is_s4_resume(codec))
835 alc_pre_init(codec);
836
Takashi Iwai546bb672012-03-07 08:37:19 +0100837 if (spec->init_hook)
838 spec->init_hook(codec);
Kailang Yang526af6e2012-03-07 08:25:20 +0100839
Kailang Yang607ca3b2019-04-26 16:35:41 +0800840 snd_hda_gen_init(codec);
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200841 alc_fix_pll(codec);
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200842 alc_auto_init_amp(codec, spec->init_amp);
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200843
Takashi Iwai1727a772013-01-10 09:52:52 +0100844 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_INIT);
Takashi Iwaie08a0072006-09-07 17:52:14 +0200845
Linus Torvalds1da177e2005-04-16 15:20:36 -0700846 return 0;
847}
848
Takashi Iwaia4e09aa2009-12-27 11:22:24 +0100849static inline void alc_shutup(struct hda_codec *codec)
850{
Takashi Iwai1c7161532011-04-07 10:37:16 +0200851 struct alc_spec *spec = codec->spec;
852
Takashi Iwaic7273bd2018-06-12 16:09:57 +0200853 if (!snd_hda_get_bool_hint(codec, "shutup"))
854 return; /* disabled explicitly by hints */
855
Takashi Iwai1c7161532011-04-07 10:37:16 +0200856 if (spec && spec->shutup)
857 spec->shutup(codec);
Takashi Iwai9bfb2842013-07-24 14:31:50 +0200858 else
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +0100859 alc_shutup_pins(codec);
Takashi Iwaia4e09aa2009-12-27 11:22:24 +0100860}
861
Takashi Iwai70a09762015-12-15 14:59:58 +0100862static void alc_reboot_notify(struct hda_codec *codec)
863{
864 struct alc_spec *spec = codec->spec;
865
866 if (spec && spec->reboot_notify)
867 spec->reboot_notify(codec);
868 else
869 alc_shutup(codec);
870}
871
872/* power down codec to D3 at reboot/shutdown; set as reboot_notify ops */
873static void alc_d3_at_reboot(struct hda_codec *codec)
874{
875 snd_hda_codec_set_power_to_all(codec, codec->core.afg, AC_PWRST_D3);
876 snd_hda_codec_write(codec, codec->core.afg, 0,
877 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
878 msleep(10);
879}
880
Takashi Iwai8a02c0c2014-02-10 18:09:45 +0100881#define alc_free snd_hda_gen_free
Linus Torvalds1da177e2005-04-16 15:20:36 -0700882
Takashi Iwai83012a72012-08-24 18:38:08 +0200883#ifdef CONFIG_PM
Daniel T Chenc97259d2009-12-27 18:52:08 -0500884static void alc_power_eapd(struct hda_codec *codec)
885{
Takashi Iwai691f1fc2011-04-07 10:31:43 +0200886 alc_auto_setup_eapd(codec, false);
Daniel T Chenc97259d2009-12-27 18:52:08 -0500887}
888
Takashi Iwai68cb2b52012-07-02 15:20:37 +0200889static int alc_suspend(struct hda_codec *codec)
Hector Martinf5de24b2009-12-20 22:51:31 +0100890{
891 struct alc_spec *spec = codec->spec;
Takashi Iwaia4e09aa2009-12-27 11:22:24 +0100892 alc_shutup(codec);
Hector Martinf5de24b2009-12-20 22:51:31 +0100893 if (spec && spec->power_hook)
Daniel T Chenc97259d2009-12-27 18:52:08 -0500894 spec->power_hook(codec);
Hector Martinf5de24b2009-12-20 22:51:31 +0100895 return 0;
896}
897#endif
898
Takashi Iwai2a439522011-07-26 09:52:50 +0200899#ifdef CONFIG_PM
Takashi Iwaie044c392008-10-27 16:56:24 +0100900static int alc_resume(struct hda_codec *codec)
901{
Kailang Yang97a26572013-11-29 00:35:26 -0500902 struct alc_spec *spec = codec->spec;
903
904 if (!spec->no_depop_delay)
905 msleep(150); /* to avoid pop noise */
Takashi Iwaie044c392008-10-27 16:56:24 +0100906 codec->patch_ops.init(codec);
Takashi Iwaieeecd9d2015-02-25 15:18:50 +0100907 regcache_sync(codec->core.regmap);
Takashi Iwai9e5341b2010-09-21 09:57:06 +0200908 hda_call_check_power_status(codec, 0x01);
Takashi Iwaie044c392008-10-27 16:56:24 +0100909 return 0;
910}
Takashi Iwaie044c392008-10-27 16:56:24 +0100911#endif
912
Linus Torvalds1da177e2005-04-16 15:20:36 -0700913/*
914 */
Takashi Iwaia9111322011-05-02 11:30:18 +0200915static const struct hda_codec_ops alc_patch_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700916 .build_controls = alc_build_controls,
Takashi Iwai08c189f2012-12-19 15:22:24 +0100917 .build_pcms = snd_hda_gen_build_pcms,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700918 .init = alc_init,
919 .free = alc_free,
David Henningsson29adc4b2012-09-25 11:31:00 +0200920 .unsol_event = snd_hda_jack_unsol_event,
Takashi Iwai2a439522011-07-26 09:52:50 +0200921#ifdef CONFIG_PM
Takashi Iwaie044c392008-10-27 16:56:24 +0100922 .resume = alc_resume,
Hector Martinf5de24b2009-12-20 22:51:31 +0100923 .suspend = alc_suspend,
Takashi Iwaifce52a32013-01-07 12:42:48 +0100924 .check_power_status = snd_hda_gen_check_power_status,
Takashi Iwaicb53c622007-08-10 17:21:45 +0200925#endif
Takashi Iwai70a09762015-12-15 14:59:58 +0100926 .reboot_notify = alc_reboot_notify,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700927};
928
David Henningsson29adc4b2012-09-25 11:31:00 +0200929
Takashi Iwaided255b2015-10-01 17:59:43 +0200930#define alc_codec_rename(codec, name) snd_hda_codec_set_name(codec, name)
Kailang Yangc027ddc2010-03-19 11:33:06 +0100931
Takashi Iwai2fa522b2005-05-12 14:51:12 +0200932/*
Kailang Yang4b016932013-11-28 11:55:09 +0100933 * Rename codecs appropriately from COEF value or subvendor id
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200934 */
935struct alc_codec_rename_table {
936 unsigned int vendor_id;
937 unsigned short coef_mask;
938 unsigned short coef_bits;
939 const char *name;
940};
941
Kailang Yang4b016932013-11-28 11:55:09 +0100942struct alc_codec_rename_pci_table {
943 unsigned int codec_vendor_id;
944 unsigned short pci_subvendor;
945 unsigned short pci_subdevice;
946 const char *name;
947};
948
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200949static struct alc_codec_rename_table rename_tbl[] = {
Kailang Yange6e5f7a2014-06-06 16:46:43 +0800950 { 0x10ec0221, 0xf00f, 0x1003, "ALC231" },
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200951 { 0x10ec0269, 0xfff0, 0x3010, "ALC277" },
952 { 0x10ec0269, 0xf0f0, 0x2010, "ALC259" },
953 { 0x10ec0269, 0xf0f0, 0x3010, "ALC258" },
954 { 0x10ec0269, 0x00f0, 0x0010, "ALC269VB" },
955 { 0x10ec0269, 0xffff, 0xa023, "ALC259" },
956 { 0x10ec0269, 0xffff, 0x6023, "ALC281X" },
957 { 0x10ec0269, 0x00f0, 0x0020, "ALC269VC" },
Kailang Yangadcc70b2012-05-25 08:08:38 +0200958 { 0x10ec0269, 0x00f0, 0x0030, "ALC269VD" },
Kailang Yange6e5f7a2014-06-06 16:46:43 +0800959 { 0x10ec0662, 0xffff, 0x4020, "ALC656" },
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200960 { 0x10ec0887, 0x00f0, 0x0030, "ALC887-VD" },
961 { 0x10ec0888, 0x00f0, 0x0030, "ALC888-VD" },
962 { 0x10ec0888, 0xf0f0, 0x3020, "ALC886" },
963 { 0x10ec0899, 0x2000, 0x2000, "ALC899" },
964 { 0x10ec0892, 0xffff, 0x8020, "ALC661" },
965 { 0x10ec0892, 0xffff, 0x8011, "ALC661" },
966 { 0x10ec0892, 0xffff, 0x4011, "ALC656" },
967 { } /* terminator */
968};
969
Kailang Yang4b016932013-11-28 11:55:09 +0100970static struct alc_codec_rename_pci_table rename_pci_tbl[] = {
971 { 0x10ec0280, 0x1028, 0, "ALC3220" },
972 { 0x10ec0282, 0x1028, 0, "ALC3221" },
973 { 0x10ec0283, 0x1028, 0, "ALC3223" },
Kailang Yang193177d2014-04-23 16:06:13 +0800974 { 0x10ec0288, 0x1028, 0, "ALC3263" },
Kailang Yang4b016932013-11-28 11:55:09 +0100975 { 0x10ec0292, 0x1028, 0, "ALC3226" },
Kailang Yang193177d2014-04-23 16:06:13 +0800976 { 0x10ec0293, 0x1028, 0, "ALC3235" },
Kailang Yang4b016932013-11-28 11:55:09 +0100977 { 0x10ec0255, 0x1028, 0, "ALC3234" },
978 { 0x10ec0668, 0x1028, 0, "ALC3661" },
Kailang Yange6e5f7a2014-06-06 16:46:43 +0800979 { 0x10ec0275, 0x1028, 0, "ALC3260" },
980 { 0x10ec0899, 0x1028, 0, "ALC3861" },
Kailang Yang2c674fa2015-05-05 15:02:42 +0800981 { 0x10ec0298, 0x1028, 0, "ALC3266" },
Kailang Yang736f20a2017-10-20 15:06:34 +0800982 { 0x10ec0236, 0x1028, 0, "ALC3204" },
Kailang Yang82324502015-05-25 17:16:49 +0800983 { 0x10ec0256, 0x1028, 0, "ALC3246" },
Kailang Yang42314302016-02-03 15:03:50 +0800984 { 0x10ec0225, 0x1028, 0, "ALC3253" },
Kailang Yang7d727862016-05-24 16:46:07 +0800985 { 0x10ec0295, 0x1028, 0, "ALC3254" },
Kailang Yang28f1f9b2017-01-04 14:49:07 +0800986 { 0x10ec0299, 0x1028, 0, "ALC3271" },
Kailang Yange6e5f7a2014-06-06 16:46:43 +0800987 { 0x10ec0670, 0x1025, 0, "ALC669X" },
988 { 0x10ec0676, 0x1025, 0, "ALC679X" },
989 { 0x10ec0282, 0x1043, 0, "ALC3229" },
990 { 0x10ec0233, 0x1043, 0, "ALC3236" },
991 { 0x10ec0280, 0x103c, 0, "ALC3228" },
992 { 0x10ec0282, 0x103c, 0, "ALC3227" },
993 { 0x10ec0286, 0x103c, 0, "ALC3242" },
994 { 0x10ec0290, 0x103c, 0, "ALC3241" },
995 { 0x10ec0668, 0x103c, 0, "ALC3662" },
996 { 0x10ec0283, 0x17aa, 0, "ALC3239" },
997 { 0x10ec0292, 0x17aa, 0, "ALC3232" },
Kailang Yang4b016932013-11-28 11:55:09 +0100998 { } /* terminator */
999};
1000
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02001001static int alc_codec_rename_from_preset(struct hda_codec *codec)
1002{
1003 const struct alc_codec_rename_table *p;
Kailang Yang4b016932013-11-28 11:55:09 +01001004 const struct alc_codec_rename_pci_table *q;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02001005
1006 for (p = rename_tbl; p->vendor_id; p++) {
Takashi Iwai7639a062015-03-03 10:07:24 +01001007 if (p->vendor_id != codec->core.vendor_id)
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02001008 continue;
Takashi Iwai1bb7e432011-10-17 16:50:59 +02001009 if ((alc_get_coef0(codec) & p->coef_mask) == p->coef_bits)
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02001010 return alc_codec_rename(codec, p->name);
1011 }
Kailang Yang4b016932013-11-28 11:55:09 +01001012
Takashi Iwai5100cd02014-02-15 10:03:19 +01001013 if (!codec->bus->pci)
1014 return 0;
Kailang Yang4b016932013-11-28 11:55:09 +01001015 for (q = rename_pci_tbl; q->codec_vendor_id; q++) {
Takashi Iwai7639a062015-03-03 10:07:24 +01001016 if (q->codec_vendor_id != codec->core.vendor_id)
Kailang Yang4b016932013-11-28 11:55:09 +01001017 continue;
1018 if (q->pci_subvendor != codec->bus->pci->subsystem_vendor)
1019 continue;
1020 if (!q->pci_subdevice ||
1021 q->pci_subdevice == codec->bus->pci->subsystem_device)
1022 return alc_codec_rename(codec, q->name);
1023 }
1024
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02001025 return 0;
1026}
1027
Takashi Iwaie4770622011-07-08 11:11:35 +02001028
1029/*
Takashi Iwai1d045db2011-07-07 18:23:21 +02001030 * Digital-beep handlers
1031 */
1032#ifdef CONFIG_SND_HDA_INPUT_BEEP
Takashi Iwaifea80fa2018-06-20 12:52:46 +02001033
1034/* additional beep mixers; private_value will be overwritten */
1035static const struct snd_kcontrol_new alc_beep_mixer[] = {
1036 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
1037 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
1038};
1039
1040/* set up and create beep controls */
1041static int set_beep_amp(struct alc_spec *spec, hda_nid_t nid,
1042 int idx, int dir)
1043{
1044 struct snd_kcontrol_new *knew;
1045 unsigned int beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir);
1046 int i;
1047
1048 for (i = 0; i < ARRAY_SIZE(alc_beep_mixer); i++) {
1049 knew = snd_hda_gen_add_kctl(&spec->gen, NULL,
1050 &alc_beep_mixer[i]);
1051 if (!knew)
1052 return -ENOMEM;
1053 knew->private_value = beep_amp;
1054 }
1055 return 0;
1056}
Takashi Iwai1d045db2011-07-07 18:23:21 +02001057
1058static const struct snd_pci_quirk beep_white_list[] = {
Duncan Roe71100052012-10-10 14:19:50 +02001059 SND_PCI_QUIRK(0x1043, 0x103c, "ASUS", 1),
W. Trevor Kinga4b7f21d2014-03-29 17:47:24 -07001060 SND_PCI_QUIRK(0x1043, 0x115d, "ASUS", 1),
Takashi Iwai1d045db2011-07-07 18:23:21 +02001061 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
Takashi Iwai8554ee42013-02-25 09:54:43 +01001062 SND_PCI_QUIRK(0x1043, 0x8376, "EeePC", 1),
Takashi Iwai1d045db2011-07-07 18:23:21 +02001063 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
1064 SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1),
1065 SND_PCI_QUIRK(0x1043, 0x834a, "EeePC", 1),
Takashi Iwai78f8baf2012-03-06 14:02:32 +01001066 SND_PCI_QUIRK(0x1458, 0xa002, "GA-MA790X", 1),
Takashi Iwai1d045db2011-07-07 18:23:21 +02001067 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
1068 {}
1069};
1070
1071static inline int has_cdefine_beep(struct hda_codec *codec)
1072{
1073 struct alc_spec *spec = codec->spec;
1074 const struct snd_pci_quirk *q;
1075 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
1076 if (q)
1077 return q->value;
1078 return spec->cdefine.enable_pcbeep;
1079}
1080#else
Takashi Iwaifea80fa2018-06-20 12:52:46 +02001081#define set_beep_amp(spec, nid, idx, dir) 0
Takashi Iwai1d045db2011-07-07 18:23:21 +02001082#define has_cdefine_beep(codec) 0
1083#endif
1084
1085/* parse the BIOS configuration and set up the alc_spec */
1086/* return 1 if successful, 0 if the proper config is not found,
1087 * or a negative error code
1088 */
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001089static int alc_parse_auto_config(struct hda_codec *codec,
1090 const hda_nid_t *ignore_nids,
1091 const hda_nid_t *ssid_nids)
Takashi Iwai1d045db2011-07-07 18:23:21 +02001092{
1093 struct alc_spec *spec = codec->spec;
Takashi Iwai08c189f2012-12-19 15:22:24 +01001094 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001095 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001096
Takashi Iwai53c334a2011-08-23 18:27:14 +02001097 err = snd_hda_parse_pin_defcfg(codec, cfg, ignore_nids,
1098 spec->parse_flags);
Takashi Iwai1d045db2011-07-07 18:23:21 +02001099 if (err < 0)
1100 return err;
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001101
1102 if (ssid_nids)
1103 alc_ssid_check(codec, ssid_nids);
1104
Takashi Iwai08c189f2012-12-19 15:22:24 +01001105 err = snd_hda_gen_parse_auto_config(codec, cfg);
1106 if (err < 0)
1107 return err;
Takashi Iwai070cff42012-02-21 12:54:17 +01001108
Takashi Iwai1d045db2011-07-07 18:23:21 +02001109 return 1;
1110}
1111
Takashi Iwai3de95172012-05-07 18:03:15 +02001112/* common preparation job for alc_spec */
1113static int alc_alloc_spec(struct hda_codec *codec, hda_nid_t mixer_nid)
1114{
1115 struct alc_spec *spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1116 int err;
1117
1118 if (!spec)
1119 return -ENOMEM;
1120 codec->spec = spec;
Takashi Iwai08c189f2012-12-19 15:22:24 +01001121 snd_hda_gen_spec_init(&spec->gen);
1122 spec->gen.mixer_nid = mixer_nid;
1123 spec->gen.own_eapd_ctl = 1;
Takashi Iwai1098b7c2012-12-17 20:03:15 +01001124 codec->single_adc_amp = 1;
Takashi Iwai08c189f2012-12-19 15:22:24 +01001125 /* FIXME: do we need this for all Realtek codec models? */
1126 codec->spdif_status_reset = 1;
Takashi Iwai225068a2015-05-29 10:42:14 +02001127 codec->patch_ops = alc_patch_ops;
Takashi Iwai3de95172012-05-07 18:03:15 +02001128
1129 err = alc_codec_rename_from_preset(codec);
1130 if (err < 0) {
1131 kfree(spec);
1132 return err;
1133 }
1134 return 0;
1135}
1136
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001137static int alc880_parse_auto_config(struct hda_codec *codec)
1138{
1139 static const hda_nid_t alc880_ignore[] = { 0x1d, 0 };
Jesper Juhl7d7eb9e2012-04-12 22:11:25 +02001140 static const hda_nid_t alc880_ssids[] = { 0x15, 0x1b, 0x14, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001141 return alc_parse_auto_config(codec, alc880_ignore, alc880_ssids);
1142}
1143
Takashi Iwai1d045db2011-07-07 18:23:21 +02001144/*
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001145 * ALC880 fix-ups
1146 */
1147enum {
Takashi Iwai411225a2012-02-20 17:48:19 +01001148 ALC880_FIXUP_GPIO1,
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001149 ALC880_FIXUP_GPIO2,
1150 ALC880_FIXUP_MEDION_RIM,
Takashi Iwaidc6af522012-02-17 16:18:59 +01001151 ALC880_FIXUP_LG,
Takashi Iwaidb8a38e2013-08-09 12:34:42 +02001152 ALC880_FIXUP_LG_LW25,
Takashi Iwaif02aab52012-02-17 16:33:56 +01001153 ALC880_FIXUP_W810,
Takashi Iwai27e917f2012-02-17 17:49:54 +01001154 ALC880_FIXUP_EAPD_COEF,
Takashi Iwaib9368f52012-02-17 17:54:44 +01001155 ALC880_FIXUP_TCL_S700,
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001156 ALC880_FIXUP_VOL_KNOB,
1157 ALC880_FIXUP_FUJITSU,
Takashi Iwaiba533812012-02-20 16:36:52 +01001158 ALC880_FIXUP_F1734,
Takashi Iwai817de922012-02-20 17:20:48 +01001159 ALC880_FIXUP_UNIWILL,
Takashi Iwai967b88c2012-02-20 17:31:02 +01001160 ALC880_FIXUP_UNIWILL_DIG,
Takashi Iwai96e225f2012-02-20 17:41:51 +01001161 ALC880_FIXUP_Z71V,
Takashi Iwai487a5882013-11-07 07:29:30 +01001162 ALC880_FIXUP_ASUS_W5A,
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001163 ALC880_FIXUP_3ST_BASE,
1164 ALC880_FIXUP_3ST,
1165 ALC880_FIXUP_3ST_DIG,
1166 ALC880_FIXUP_5ST_BASE,
1167 ALC880_FIXUP_5ST,
1168 ALC880_FIXUP_5ST_DIG,
1169 ALC880_FIXUP_6ST_BASE,
1170 ALC880_FIXUP_6ST,
1171 ALC880_FIXUP_6ST_DIG,
Takashi Iwai53971452013-01-23 18:21:37 +01001172 ALC880_FIXUP_6ST_AUTOMUTE,
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001173};
1174
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001175/* enable the volume-knob widget support on NID 0x21 */
1176static void alc880_fixup_vol_knob(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001177 const struct hda_fixup *fix, int action)
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001178{
Takashi Iwai1727a772013-01-10 09:52:52 +01001179 if (action == HDA_FIXUP_ACT_PROBE)
Takashi Iwai62f949b2014-09-11 14:06:53 +02001180 snd_hda_jack_detect_enable_callback(codec, 0x21,
1181 alc_update_knob_master);
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001182}
1183
Takashi Iwai1727a772013-01-10 09:52:52 +01001184static const struct hda_fixup alc880_fixups[] = {
Takashi Iwai411225a2012-02-20 17:48:19 +01001185 [ALC880_FIXUP_GPIO1] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02001186 .type = HDA_FIXUP_FUNC,
1187 .v.func = alc_fixup_gpio1,
Takashi Iwai411225a2012-02-20 17:48:19 +01001188 },
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001189 [ALC880_FIXUP_GPIO2] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02001190 .type = HDA_FIXUP_FUNC,
1191 .v.func = alc_fixup_gpio2,
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001192 },
1193 [ALC880_FIXUP_MEDION_RIM] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001194 .type = HDA_FIXUP_VERBS,
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001195 .v.verbs = (const struct hda_verb[]) {
1196 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
1197 { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
1198 { }
1199 },
1200 .chained = true,
1201 .chain_id = ALC880_FIXUP_GPIO2,
1202 },
Takashi Iwaidc6af522012-02-17 16:18:59 +01001203 [ALC880_FIXUP_LG] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001204 .type = HDA_FIXUP_PINS,
1205 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaidc6af522012-02-17 16:18:59 +01001206 /* disable bogus unused pins */
1207 { 0x16, 0x411111f0 },
1208 { 0x18, 0x411111f0 },
1209 { 0x1a, 0x411111f0 },
1210 { }
1211 }
1212 },
Takashi Iwaidb8a38e2013-08-09 12:34:42 +02001213 [ALC880_FIXUP_LG_LW25] = {
1214 .type = HDA_FIXUP_PINS,
1215 .v.pins = (const struct hda_pintbl[]) {
1216 { 0x1a, 0x0181344f }, /* line-in */
1217 { 0x1b, 0x0321403f }, /* headphone */
1218 { }
1219 }
1220 },
Takashi Iwaif02aab52012-02-17 16:33:56 +01001221 [ALC880_FIXUP_W810] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001222 .type = HDA_FIXUP_PINS,
1223 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaif02aab52012-02-17 16:33:56 +01001224 /* disable bogus unused pins */
1225 { 0x17, 0x411111f0 },
1226 { }
1227 },
1228 .chained = true,
1229 .chain_id = ALC880_FIXUP_GPIO2,
1230 },
Takashi Iwai27e917f2012-02-17 17:49:54 +01001231 [ALC880_FIXUP_EAPD_COEF] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001232 .type = HDA_FIXUP_VERBS,
Takashi Iwai27e917f2012-02-17 17:49:54 +01001233 .v.verbs = (const struct hda_verb[]) {
1234 /* change to EAPD mode */
1235 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
1236 { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
1237 {}
1238 },
1239 },
Takashi Iwaib9368f52012-02-17 17:54:44 +01001240 [ALC880_FIXUP_TCL_S700] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001241 .type = HDA_FIXUP_VERBS,
Takashi Iwaib9368f52012-02-17 17:54:44 +01001242 .v.verbs = (const struct hda_verb[]) {
1243 /* change to EAPD mode */
1244 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
1245 { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
1246 {}
1247 },
1248 .chained = true,
1249 .chain_id = ALC880_FIXUP_GPIO2,
1250 },
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001251 [ALC880_FIXUP_VOL_KNOB] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001252 .type = HDA_FIXUP_FUNC,
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001253 .v.func = alc880_fixup_vol_knob,
1254 },
1255 [ALC880_FIXUP_FUJITSU] = {
1256 /* override all pins as BIOS on old Amilo is broken */
Takashi Iwai1727a772013-01-10 09:52:52 +01001257 .type = HDA_FIXUP_PINS,
1258 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaibb148bd2015-08-13 18:02:39 +02001259 { 0x14, 0x0121401f }, /* HP */
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001260 { 0x15, 0x99030120 }, /* speaker */
1261 { 0x16, 0x99030130 }, /* bass speaker */
1262 { 0x17, 0x411111f0 }, /* N/A */
1263 { 0x18, 0x411111f0 }, /* N/A */
1264 { 0x19, 0x01a19950 }, /* mic-in */
1265 { 0x1a, 0x411111f0 }, /* N/A */
1266 { 0x1b, 0x411111f0 }, /* N/A */
1267 { 0x1c, 0x411111f0 }, /* N/A */
1268 { 0x1d, 0x411111f0 }, /* N/A */
1269 { 0x1e, 0x01454140 }, /* SPDIF out */
1270 { }
1271 },
1272 .chained = true,
1273 .chain_id = ALC880_FIXUP_VOL_KNOB,
1274 },
Takashi Iwaiba533812012-02-20 16:36:52 +01001275 [ALC880_FIXUP_F1734] = {
1276 /* almost compatible with FUJITSU, but no bass and SPDIF */
Takashi Iwai1727a772013-01-10 09:52:52 +01001277 .type = HDA_FIXUP_PINS,
1278 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaibb148bd2015-08-13 18:02:39 +02001279 { 0x14, 0x0121401f }, /* HP */
Takashi Iwaiba533812012-02-20 16:36:52 +01001280 { 0x15, 0x99030120 }, /* speaker */
1281 { 0x16, 0x411111f0 }, /* N/A */
1282 { 0x17, 0x411111f0 }, /* N/A */
1283 { 0x18, 0x411111f0 }, /* N/A */
1284 { 0x19, 0x01a19950 }, /* mic-in */
1285 { 0x1a, 0x411111f0 }, /* N/A */
1286 { 0x1b, 0x411111f0 }, /* N/A */
1287 { 0x1c, 0x411111f0 }, /* N/A */
1288 { 0x1d, 0x411111f0 }, /* N/A */
1289 { 0x1e, 0x411111f0 }, /* N/A */
1290 { }
1291 },
1292 .chained = true,
1293 .chain_id = ALC880_FIXUP_VOL_KNOB,
1294 },
Takashi Iwai817de922012-02-20 17:20:48 +01001295 [ALC880_FIXUP_UNIWILL] = {
1296 /* need to fix HP and speaker pins to be parsed correctly */
Takashi Iwai1727a772013-01-10 09:52:52 +01001297 .type = HDA_FIXUP_PINS,
1298 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai817de922012-02-20 17:20:48 +01001299 { 0x14, 0x0121411f }, /* HP */
1300 { 0x15, 0x99030120 }, /* speaker */
1301 { 0x16, 0x99030130 }, /* bass speaker */
1302 { }
1303 },
1304 },
Takashi Iwai967b88c2012-02-20 17:31:02 +01001305 [ALC880_FIXUP_UNIWILL_DIG] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001306 .type = HDA_FIXUP_PINS,
1307 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai967b88c2012-02-20 17:31:02 +01001308 /* disable bogus unused pins */
1309 { 0x17, 0x411111f0 },
1310 { 0x19, 0x411111f0 },
1311 { 0x1b, 0x411111f0 },
1312 { 0x1f, 0x411111f0 },
1313 { }
1314 }
1315 },
Takashi Iwai96e225f2012-02-20 17:41:51 +01001316 [ALC880_FIXUP_Z71V] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001317 .type = HDA_FIXUP_PINS,
1318 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai96e225f2012-02-20 17:41:51 +01001319 /* set up the whole pins as BIOS is utterly broken */
1320 { 0x14, 0x99030120 }, /* speaker */
1321 { 0x15, 0x0121411f }, /* HP */
1322 { 0x16, 0x411111f0 }, /* N/A */
1323 { 0x17, 0x411111f0 }, /* N/A */
1324 { 0x18, 0x01a19950 }, /* mic-in */
1325 { 0x19, 0x411111f0 }, /* N/A */
1326 { 0x1a, 0x01813031 }, /* line-in */
1327 { 0x1b, 0x411111f0 }, /* N/A */
1328 { 0x1c, 0x411111f0 }, /* N/A */
1329 { 0x1d, 0x411111f0 }, /* N/A */
1330 { 0x1e, 0x0144111e }, /* SPDIF */
1331 { }
1332 }
1333 },
Takashi Iwai487a5882013-11-07 07:29:30 +01001334 [ALC880_FIXUP_ASUS_W5A] = {
1335 .type = HDA_FIXUP_PINS,
1336 .v.pins = (const struct hda_pintbl[]) {
1337 /* set up the whole pins as BIOS is utterly broken */
1338 { 0x14, 0x0121411f }, /* HP */
1339 { 0x15, 0x411111f0 }, /* N/A */
1340 { 0x16, 0x411111f0 }, /* N/A */
1341 { 0x17, 0x411111f0 }, /* N/A */
1342 { 0x18, 0x90a60160 }, /* mic */
1343 { 0x19, 0x411111f0 }, /* N/A */
1344 { 0x1a, 0x411111f0 }, /* N/A */
1345 { 0x1b, 0x411111f0 }, /* N/A */
1346 { 0x1c, 0x411111f0 }, /* N/A */
1347 { 0x1d, 0x411111f0 }, /* N/A */
1348 { 0x1e, 0xb743111e }, /* SPDIF out */
1349 { }
1350 },
1351 .chained = true,
1352 .chain_id = ALC880_FIXUP_GPIO1,
1353 },
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001354 [ALC880_FIXUP_3ST_BASE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001355 .type = HDA_FIXUP_PINS,
1356 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001357 { 0x14, 0x01014010 }, /* line-out */
1358 { 0x15, 0x411111f0 }, /* N/A */
1359 { 0x16, 0x411111f0 }, /* N/A */
1360 { 0x17, 0x411111f0 }, /* N/A */
1361 { 0x18, 0x01a19c30 }, /* mic-in */
1362 { 0x19, 0x0121411f }, /* HP */
1363 { 0x1a, 0x01813031 }, /* line-in */
1364 { 0x1b, 0x02a19c40 }, /* front-mic */
1365 { 0x1c, 0x411111f0 }, /* N/A */
1366 { 0x1d, 0x411111f0 }, /* N/A */
1367 /* 0x1e is filled in below */
1368 { 0x1f, 0x411111f0 }, /* N/A */
1369 { }
1370 }
1371 },
1372 [ALC880_FIXUP_3ST] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001373 .type = HDA_FIXUP_PINS,
1374 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001375 { 0x1e, 0x411111f0 }, /* N/A */
1376 { }
1377 },
1378 .chained = true,
1379 .chain_id = ALC880_FIXUP_3ST_BASE,
1380 },
1381 [ALC880_FIXUP_3ST_DIG] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001382 .type = HDA_FIXUP_PINS,
1383 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001384 { 0x1e, 0x0144111e }, /* SPDIF */
1385 { }
1386 },
1387 .chained = true,
1388 .chain_id = ALC880_FIXUP_3ST_BASE,
1389 },
1390 [ALC880_FIXUP_5ST_BASE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001391 .type = HDA_FIXUP_PINS,
1392 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001393 { 0x14, 0x01014010 }, /* front */
1394 { 0x15, 0x411111f0 }, /* N/A */
1395 { 0x16, 0x01011411 }, /* CLFE */
1396 { 0x17, 0x01016412 }, /* surr */
1397 { 0x18, 0x01a19c30 }, /* mic-in */
1398 { 0x19, 0x0121411f }, /* HP */
1399 { 0x1a, 0x01813031 }, /* line-in */
1400 { 0x1b, 0x02a19c40 }, /* front-mic */
1401 { 0x1c, 0x411111f0 }, /* N/A */
1402 { 0x1d, 0x411111f0 }, /* N/A */
1403 /* 0x1e is filled in below */
1404 { 0x1f, 0x411111f0 }, /* N/A */
1405 { }
1406 }
1407 },
1408 [ALC880_FIXUP_5ST] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001409 .type = HDA_FIXUP_PINS,
1410 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001411 { 0x1e, 0x411111f0 }, /* N/A */
1412 { }
1413 },
1414 .chained = true,
1415 .chain_id = ALC880_FIXUP_5ST_BASE,
1416 },
1417 [ALC880_FIXUP_5ST_DIG] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001418 .type = HDA_FIXUP_PINS,
1419 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001420 { 0x1e, 0x0144111e }, /* SPDIF */
1421 { }
1422 },
1423 .chained = true,
1424 .chain_id = ALC880_FIXUP_5ST_BASE,
1425 },
1426 [ALC880_FIXUP_6ST_BASE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001427 .type = HDA_FIXUP_PINS,
1428 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001429 { 0x14, 0x01014010 }, /* front */
1430 { 0x15, 0x01016412 }, /* surr */
1431 { 0x16, 0x01011411 }, /* CLFE */
1432 { 0x17, 0x01012414 }, /* side */
1433 { 0x18, 0x01a19c30 }, /* mic-in */
1434 { 0x19, 0x02a19c40 }, /* front-mic */
1435 { 0x1a, 0x01813031 }, /* line-in */
1436 { 0x1b, 0x0121411f }, /* HP */
1437 { 0x1c, 0x411111f0 }, /* N/A */
1438 { 0x1d, 0x411111f0 }, /* N/A */
1439 /* 0x1e is filled in below */
1440 { 0x1f, 0x411111f0 }, /* N/A */
1441 { }
1442 }
1443 },
1444 [ALC880_FIXUP_6ST] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001445 .type = HDA_FIXUP_PINS,
1446 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001447 { 0x1e, 0x411111f0 }, /* N/A */
1448 { }
1449 },
1450 .chained = true,
1451 .chain_id = ALC880_FIXUP_6ST_BASE,
1452 },
1453 [ALC880_FIXUP_6ST_DIG] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001454 .type = HDA_FIXUP_PINS,
1455 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001456 { 0x1e, 0x0144111e }, /* SPDIF */
1457 { }
1458 },
1459 .chained = true,
1460 .chain_id = ALC880_FIXUP_6ST_BASE,
1461 },
Takashi Iwai53971452013-01-23 18:21:37 +01001462 [ALC880_FIXUP_6ST_AUTOMUTE] = {
1463 .type = HDA_FIXUP_PINS,
1464 .v.pins = (const struct hda_pintbl[]) {
1465 { 0x1b, 0x0121401f }, /* HP with jack detect */
1466 { }
1467 },
1468 .chained_before = true,
1469 .chain_id = ALC880_FIXUP_6ST_BASE,
1470 },
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001471};
1472
1473static const struct snd_pci_quirk alc880_fixup_tbl[] = {
Takashi Iwaif02aab52012-02-17 16:33:56 +01001474 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_FIXUP_W810),
Takashi Iwai487a5882013-11-07 07:29:30 +01001475 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS W5A", ALC880_FIXUP_ASUS_W5A),
Takashi Iwai96e225f2012-02-20 17:41:51 +01001476 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_FIXUP_Z71V),
Takashi Iwai29e3fdc2012-02-20 17:56:57 +01001477 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_FIXUP_GPIO1),
David Henningsson6538de02014-06-10 10:52:50 +02001478 SND_PCI_QUIRK(0x147b, 0x1045, "ABit AA8XE", ALC880_FIXUP_6ST_AUTOMUTE),
Takashi Iwai29e3fdc2012-02-20 17:56:57 +01001479 SND_PCI_QUIRK(0x1558, 0x5401, "Clevo GPIO2", ALC880_FIXUP_GPIO2),
Takashi Iwai27e917f2012-02-17 17:49:54 +01001480 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo", ALC880_FIXUP_EAPD_COEF),
Takashi Iwai967b88c2012-02-20 17:31:02 +01001481 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_FIXUP_UNIWILL_DIG),
Takashi Iwaiba533812012-02-20 16:36:52 +01001482 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_FIXUP_F1734),
Takashi Iwai817de922012-02-20 17:20:48 +01001483 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_FIXUP_UNIWILL),
Takashi Iwai7833c7e2012-02-20 17:11:38 +01001484 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_FIXUP_VOL_KNOB),
Takashi Iwaif02aab52012-02-17 16:33:56 +01001485 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_FIXUP_W810),
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001486 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_FIXUP_MEDION_RIM),
Takashi Iwai53971452013-01-23 18:21:37 +01001487 SND_PCI_QUIRK(0x1631, 0xe011, "PB 13201056", ALC880_FIXUP_6ST_AUTOMUTE),
Takashi Iwaia1615742015-08-13 18:05:06 +02001488 SND_PCI_QUIRK(0x1734, 0x107c, "FSC Amilo M1437", ALC880_FIXUP_FUJITSU),
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001489 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FIXUP_FUJITSU),
Takashi Iwaiba533812012-02-20 16:36:52 +01001490 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_FIXUP_F1734),
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001491 SND_PCI_QUIRK(0x1734, 0x10b0, "FSC Amilo Pi1556", ALC880_FIXUP_FUJITSU),
Takashi Iwaidc6af522012-02-17 16:18:59 +01001492 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_FIXUP_LG),
1493 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_FIXUP_LG),
1494 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_FIXUP_LG),
Takashi Iwaidb8a38e2013-08-09 12:34:42 +02001495 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_FIXUP_LG_LW25),
Takashi Iwaib9368f52012-02-17 17:54:44 +01001496 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_FIXUP_TCL_S700),
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001497
1498 /* Below is the copied entries from alc880_quirks.c.
1499 * It's not quite sure whether BIOS sets the correct pin-config table
1500 * on these machines, thus they are kept to be compatible with
1501 * the old static quirks. Once when it's confirmed to work without
1502 * these overrides, it'd be better to remove.
1503 */
1504 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_FIXUP_5ST_DIG),
1505 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_FIXUP_6ST),
1506 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_FIXUP_3ST_DIG),
1507 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_FIXUP_6ST_DIG),
1508 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_FIXUP_6ST_DIG),
1509 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_FIXUP_6ST_DIG),
1510 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_FIXUP_3ST_DIG),
1511 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_FIXUP_3ST),
1512 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_FIXUP_6ST_DIG),
1513 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_FIXUP_3ST),
1514 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_FIXUP_3ST),
1515 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_FIXUP_5ST),
1516 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_FIXUP_5ST),
1517 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_FIXUP_5ST),
1518 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_FIXUP_6ST_DIG),
1519 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_FIXUP_6ST_DIG),
1520 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_FIXUP_6ST_DIG),
1521 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_FIXUP_6ST_DIG),
1522 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_FIXUP_5ST_DIG),
1523 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_FIXUP_5ST_DIG),
1524 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_FIXUP_5ST_DIG),
1525 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_FIXUP_6ST_DIG), /* broken BIOS */
1526 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_FIXUP_6ST_DIG),
1527 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1528 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1529 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1530 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_FIXUP_3ST_DIG),
1531 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1532 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_FIXUP_3ST_DIG),
1533 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_FIXUP_3ST_DIG),
1534 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1535 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1536 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1537 /* default Intel */
1538 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_FIXUP_3ST),
1539 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_FIXUP_5ST_DIG),
1540 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_FIXUP_6ST_DIG),
1541 {}
1542};
1543
Takashi Iwai1727a772013-01-10 09:52:52 +01001544static const struct hda_model_fixup alc880_fixup_models[] = {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001545 {.id = ALC880_FIXUP_3ST, .name = "3stack"},
1546 {.id = ALC880_FIXUP_3ST_DIG, .name = "3stack-digout"},
1547 {.id = ALC880_FIXUP_5ST, .name = "5stack"},
1548 {.id = ALC880_FIXUP_5ST_DIG, .name = "5stack-digout"},
1549 {.id = ALC880_FIXUP_6ST, .name = "6stack"},
1550 {.id = ALC880_FIXUP_6ST_DIG, .name = "6stack-digout"},
Takashi Iwai53971452013-01-23 18:21:37 +01001551 {.id = ALC880_FIXUP_6ST_AUTOMUTE, .name = "6stack-automute"},
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001552 {}
1553};
1554
1555
1556/*
Takashi Iwai1d045db2011-07-07 18:23:21 +02001557 * OK, here we have finally the patch for ALC880
1558 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02001559static int patch_alc880(struct hda_codec *codec)
1560{
1561 struct alc_spec *spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001562 int err;
1563
Takashi Iwai3de95172012-05-07 18:03:15 +02001564 err = alc_alloc_spec(codec, 0x0b);
1565 if (err < 0)
1566 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001567
Takashi Iwai3de95172012-05-07 18:03:15 +02001568 spec = codec->spec;
Takashi Iwai08c189f2012-12-19 15:22:24 +01001569 spec->gen.need_dac_fix = 1;
Takashi Iwai7504b6c2013-03-18 11:25:51 +01001570 spec->gen.beep_nid = 0x01;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001571
Takashi Iwai225068a2015-05-29 10:42:14 +02001572 codec->patch_ops.unsol_event = alc880_unsol_event;
1573
Takashi Iwaic9af7532019-05-10 11:01:43 +02001574 alc_pre_init(codec);
1575
Takashi Iwai1727a772013-01-10 09:52:52 +01001576 snd_hda_pick_fixup(codec, alc880_fixup_models, alc880_fixup_tbl,
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001577 alc880_fixups);
Takashi Iwai1727a772013-01-10 09:52:52 +01001578 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02001579
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001580 /* automatic parse from the BIOS config */
1581 err = alc880_parse_auto_config(codec);
1582 if (err < 0)
1583 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001584
Takashi Iwaifea80fa2018-06-20 12:52:46 +02001585 if (!spec->gen.no_analog) {
1586 err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
1587 if (err < 0)
1588 goto error;
1589 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02001590
Takashi Iwai1727a772013-01-10 09:52:52 +01001591 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01001592
Takashi Iwai1d045db2011-07-07 18:23:21 +02001593 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02001594
1595 error:
1596 alc_free(codec);
1597 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001598}
1599
1600
1601/*
1602 * ALC260 support
1603 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02001604static int alc260_parse_auto_config(struct hda_codec *codec)
1605{
Takashi Iwai1d045db2011-07-07 18:23:21 +02001606 static const hda_nid_t alc260_ignore[] = { 0x17, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001607 static const hda_nid_t alc260_ssids[] = { 0x10, 0x15, 0x0f, 0 };
1608 return alc_parse_auto_config(codec, alc260_ignore, alc260_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02001609}
1610
Takashi Iwai1d045db2011-07-07 18:23:21 +02001611/*
1612 * Pin config fixes
1613 */
1614enum {
Takashi Iwaica8f0422012-02-16 11:51:19 +01001615 ALC260_FIXUP_HP_DC5750,
1616 ALC260_FIXUP_HP_PIN_0F,
1617 ALC260_FIXUP_COEF,
Takashi Iwai15317ab2012-02-16 12:02:53 +01001618 ALC260_FIXUP_GPIO1,
Takashi Iwai20f7d922012-02-16 12:35:16 +01001619 ALC260_FIXUP_GPIO1_TOGGLE,
1620 ALC260_FIXUP_REPLACER,
Takashi Iwai0a1c4fa2012-02-16 12:42:30 +01001621 ALC260_FIXUP_HP_B1900,
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001622 ALC260_FIXUP_KN1,
Takashi Iwai39aedee2013-01-10 17:10:40 +01001623 ALC260_FIXUP_FSC_S7020,
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001624 ALC260_FIXUP_FSC_S7020_JWSE,
Takashi Iwaid08c5ef2013-11-22 08:06:36 +01001625 ALC260_FIXUP_VAIO_PINS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02001626};
1627
Takashi Iwai20f7d922012-02-16 12:35:16 +01001628static void alc260_gpio1_automute(struct hda_codec *codec)
1629{
1630 struct alc_spec *spec = codec->spec;
Takashi Iwaiaaf312d2018-06-19 22:28:22 +02001631
1632 alc_update_gpio_data(codec, 0x01, spec->gen.hp_jack_present);
Takashi Iwai20f7d922012-02-16 12:35:16 +01001633}
1634
1635static void alc260_fixup_gpio1_toggle(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001636 const struct hda_fixup *fix, int action)
Takashi Iwai20f7d922012-02-16 12:35:16 +01001637{
1638 struct alc_spec *spec = codec->spec;
Takashi Iwai1727a772013-01-10 09:52:52 +01001639 if (action == HDA_FIXUP_ACT_PROBE) {
Takashi Iwai20f7d922012-02-16 12:35:16 +01001640 /* although the machine has only one output pin, we need to
1641 * toggle GPIO1 according to the jack state
1642 */
Takashi Iwai08c189f2012-12-19 15:22:24 +01001643 spec->gen.automute_hook = alc260_gpio1_automute;
1644 spec->gen.detect_hp = 1;
1645 spec->gen.automute_speaker = 1;
1646 spec->gen.autocfg.hp_pins[0] = 0x0f; /* copy it for automute */
Takashi Iwai62f949b2014-09-11 14:06:53 +02001647 snd_hda_jack_detect_enable_callback(codec, 0x0f,
Takashi Iwai08c189f2012-12-19 15:22:24 +01001648 snd_hda_gen_hp_automute);
Takashi Iwai5579cd62018-06-19 22:22:41 +02001649 alc_setup_gpio(codec, 0x01);
Takashi Iwai20f7d922012-02-16 12:35:16 +01001650 }
1651}
1652
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001653static void alc260_fixup_kn1(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001654 const struct hda_fixup *fix, int action)
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001655{
1656 struct alc_spec *spec = codec->spec;
Takashi Iwai1727a772013-01-10 09:52:52 +01001657 static const struct hda_pintbl pincfgs[] = {
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001658 { 0x0f, 0x02214000 }, /* HP/speaker */
1659 { 0x12, 0x90a60160 }, /* int mic */
1660 { 0x13, 0x02a19000 }, /* ext mic */
1661 { 0x18, 0x01446000 }, /* SPDIF out */
1662 /* disable bogus I/O pins */
1663 { 0x10, 0x411111f0 },
1664 { 0x11, 0x411111f0 },
1665 { 0x14, 0x411111f0 },
1666 { 0x15, 0x411111f0 },
1667 { 0x16, 0x411111f0 },
1668 { 0x17, 0x411111f0 },
1669 { 0x19, 0x411111f0 },
1670 { }
1671 };
1672
1673 switch (action) {
Takashi Iwai1727a772013-01-10 09:52:52 +01001674 case HDA_FIXUP_ACT_PRE_PROBE:
1675 snd_hda_apply_pincfgs(codec, pincfgs);
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001676 spec->init_amp = ALC_INIT_NONE;
1677 break;
1678 }
1679}
1680
Takashi Iwai39aedee2013-01-10 17:10:40 +01001681static void alc260_fixup_fsc_s7020(struct hda_codec *codec,
1682 const struct hda_fixup *fix, int action)
1683{
1684 struct alc_spec *spec = codec->spec;
Takashi Iwai1c76aa52018-06-21 16:37:54 +02001685 if (action == HDA_FIXUP_ACT_PRE_PROBE)
Takashi Iwaie6e0ee52013-02-18 17:04:20 +01001686 spec->init_amp = ALC_INIT_NONE;
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001687}
1688
1689static void alc260_fixup_fsc_s7020_jwse(struct hda_codec *codec,
1690 const struct hda_fixup *fix, int action)
1691{
1692 struct alc_spec *spec = codec->spec;
1693 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwaif811c3c2013-03-07 18:32:59 +01001694 spec->gen.add_jack_modes = 1;
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001695 spec->gen.hp_mic = 1;
Takashi Iwaie6e0ee52013-02-18 17:04:20 +01001696 }
Takashi Iwai39aedee2013-01-10 17:10:40 +01001697}
1698
Takashi Iwai1727a772013-01-10 09:52:52 +01001699static const struct hda_fixup alc260_fixups[] = {
Takashi Iwaica8f0422012-02-16 11:51:19 +01001700 [ALC260_FIXUP_HP_DC5750] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001701 .type = HDA_FIXUP_PINS,
1702 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02001703 { 0x11, 0x90130110 }, /* speaker */
1704 { }
1705 }
1706 },
Takashi Iwaica8f0422012-02-16 11:51:19 +01001707 [ALC260_FIXUP_HP_PIN_0F] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001708 .type = HDA_FIXUP_PINS,
1709 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaica8f0422012-02-16 11:51:19 +01001710 { 0x0f, 0x01214000 }, /* HP */
1711 { }
1712 }
1713 },
1714 [ALC260_FIXUP_COEF] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001715 .type = HDA_FIXUP_VERBS,
Takashi Iwaica8f0422012-02-16 11:51:19 +01001716 .v.verbs = (const struct hda_verb[]) {
Ronan Marquete30cf2d2014-06-01 18:38:53 +02001717 { 0x1a, AC_VERB_SET_COEF_INDEX, 0x07 },
1718 { 0x1a, AC_VERB_SET_PROC_COEF, 0x3040 },
Takashi Iwaica8f0422012-02-16 11:51:19 +01001719 { }
1720 },
Takashi Iwaica8f0422012-02-16 11:51:19 +01001721 },
Takashi Iwai15317ab2012-02-16 12:02:53 +01001722 [ALC260_FIXUP_GPIO1] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02001723 .type = HDA_FIXUP_FUNC,
1724 .v.func = alc_fixup_gpio1,
Takashi Iwai15317ab2012-02-16 12:02:53 +01001725 },
Takashi Iwai20f7d922012-02-16 12:35:16 +01001726 [ALC260_FIXUP_GPIO1_TOGGLE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001727 .type = HDA_FIXUP_FUNC,
Takashi Iwai20f7d922012-02-16 12:35:16 +01001728 .v.func = alc260_fixup_gpio1_toggle,
1729 .chained = true,
1730 .chain_id = ALC260_FIXUP_HP_PIN_0F,
1731 },
1732 [ALC260_FIXUP_REPLACER] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001733 .type = HDA_FIXUP_VERBS,
Takashi Iwai20f7d922012-02-16 12:35:16 +01001734 .v.verbs = (const struct hda_verb[]) {
Takashi Iwai192a98e2014-06-02 15:16:07 +02001735 { 0x1a, AC_VERB_SET_COEF_INDEX, 0x07 },
1736 { 0x1a, AC_VERB_SET_PROC_COEF, 0x3050 },
Takashi Iwai20f7d922012-02-16 12:35:16 +01001737 { }
1738 },
1739 .chained = true,
1740 .chain_id = ALC260_FIXUP_GPIO1_TOGGLE,
1741 },
Takashi Iwai0a1c4fa2012-02-16 12:42:30 +01001742 [ALC260_FIXUP_HP_B1900] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001743 .type = HDA_FIXUP_FUNC,
Takashi Iwai0a1c4fa2012-02-16 12:42:30 +01001744 .v.func = alc260_fixup_gpio1_toggle,
1745 .chained = true,
1746 .chain_id = ALC260_FIXUP_COEF,
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001747 },
1748 [ALC260_FIXUP_KN1] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001749 .type = HDA_FIXUP_FUNC,
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001750 .v.func = alc260_fixup_kn1,
1751 },
Takashi Iwai39aedee2013-01-10 17:10:40 +01001752 [ALC260_FIXUP_FSC_S7020] = {
1753 .type = HDA_FIXUP_FUNC,
1754 .v.func = alc260_fixup_fsc_s7020,
1755 },
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001756 [ALC260_FIXUP_FSC_S7020_JWSE] = {
1757 .type = HDA_FIXUP_FUNC,
1758 .v.func = alc260_fixup_fsc_s7020_jwse,
1759 .chained = true,
1760 .chain_id = ALC260_FIXUP_FSC_S7020,
1761 },
Takashi Iwaid08c5ef2013-11-22 08:06:36 +01001762 [ALC260_FIXUP_VAIO_PINS] = {
1763 .type = HDA_FIXUP_PINS,
1764 .v.pins = (const struct hda_pintbl[]) {
1765 /* Pin configs are missing completely on some VAIOs */
1766 { 0x0f, 0x01211020 },
1767 { 0x10, 0x0001003f },
1768 { 0x11, 0x411111f0 },
1769 { 0x12, 0x01a15930 },
1770 { 0x13, 0x411111f0 },
1771 { 0x14, 0x411111f0 },
1772 { 0x15, 0x411111f0 },
1773 { 0x16, 0x411111f0 },
1774 { 0x17, 0x411111f0 },
1775 { 0x18, 0x411111f0 },
1776 { 0x19, 0x411111f0 },
1777 { }
1778 }
1779 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02001780};
1781
1782static const struct snd_pci_quirk alc260_fixup_tbl[] = {
Takashi Iwai15317ab2012-02-16 12:02:53 +01001783 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_FIXUP_GPIO1),
Takashi Iwaica8f0422012-02-16 11:51:19 +01001784 SND_PCI_QUIRK(0x1025, 0x007f, "Acer Aspire 9500", ALC260_FIXUP_COEF),
Takashi Iwai15317ab2012-02-16 12:02:53 +01001785 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_FIXUP_GPIO1),
Takashi Iwaica8f0422012-02-16 11:51:19 +01001786 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", ALC260_FIXUP_HP_DC5750),
Takashi Iwai0a1c4fa2012-02-16 12:42:30 +01001787 SND_PCI_QUIRK(0x103c, 0x30ba, "HP Presario B1900", ALC260_FIXUP_HP_B1900),
Takashi Iwaid08c5ef2013-11-22 08:06:36 +01001788 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_FIXUP_VAIO_PINS),
Takashi Iwai0f5a5b82013-11-21 09:12:52 +01001789 SND_PCI_QUIRK(0x104d, 0x81e2, "Sony VAIO TX", ALC260_FIXUP_HP_PIN_0F),
Takashi Iwai39aedee2013-01-10 17:10:40 +01001790 SND_PCI_QUIRK(0x10cf, 0x1326, "FSC LifeBook S7020", ALC260_FIXUP_FSC_S7020),
Takashi Iwaib1f58082012-02-16 12:45:03 +01001791 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FIXUP_GPIO1),
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001792 SND_PCI_QUIRK(0x152d, 0x0729, "Quanta KN1", ALC260_FIXUP_KN1),
Takashi Iwai20f7d922012-02-16 12:35:16 +01001793 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_FIXUP_REPLACER),
Takashi Iwaica8f0422012-02-16 11:51:19 +01001794 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_FIXUP_COEF),
Takashi Iwai1d045db2011-07-07 18:23:21 +02001795 {}
1796};
1797
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001798static const struct hda_model_fixup alc260_fixup_models[] = {
1799 {.id = ALC260_FIXUP_GPIO1, .name = "gpio1"},
1800 {.id = ALC260_FIXUP_COEF, .name = "coef"},
1801 {.id = ALC260_FIXUP_FSC_S7020, .name = "fujitsu"},
1802 {.id = ALC260_FIXUP_FSC_S7020_JWSE, .name = "fujitsu-jwse"},
1803 {}
1804};
1805
Takashi Iwai1d045db2011-07-07 18:23:21 +02001806/*
1807 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02001808static int patch_alc260(struct hda_codec *codec)
1809{
1810 struct alc_spec *spec;
Takashi Iwaic3c2c9e2012-02-16 12:59:55 +01001811 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001812
Takashi Iwai3de95172012-05-07 18:03:15 +02001813 err = alc_alloc_spec(codec, 0x07);
1814 if (err < 0)
1815 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001816
Takashi Iwai3de95172012-05-07 18:03:15 +02001817 spec = codec->spec;
Takashi Iwaiea46c3c2013-01-15 18:45:53 +01001818 /* as quite a few machines require HP amp for speaker outputs,
1819 * it's easier to enable it unconditionally; even if it's unneeded,
1820 * it's almost harmless.
1821 */
1822 spec->gen.prefer_hp_amp = 1;
Takashi Iwai7504b6c2013-03-18 11:25:51 +01001823 spec->gen.beep_nid = 0x01;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001824
Takashi Iwai225068a2015-05-29 10:42:14 +02001825 spec->shutup = alc_eapd_shutup;
1826
Takashi Iwaic9af7532019-05-10 11:01:43 +02001827 alc_pre_init(codec);
1828
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001829 snd_hda_pick_fixup(codec, alc260_fixup_models, alc260_fixup_tbl,
1830 alc260_fixups);
Takashi Iwai1727a772013-01-10 09:52:52 +01001831 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02001832
Takashi Iwaic3c2c9e2012-02-16 12:59:55 +01001833 /* automatic parse from the BIOS config */
1834 err = alc260_parse_auto_config(codec);
1835 if (err < 0)
1836 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001837
Takashi Iwaifea80fa2018-06-20 12:52:46 +02001838 if (!spec->gen.no_analog) {
1839 err = set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
1840 if (err < 0)
1841 goto error;
1842 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02001843
Takashi Iwai1727a772013-01-10 09:52:52 +01001844 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01001845
Takashi Iwai1d045db2011-07-07 18:23:21 +02001846 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02001847
1848 error:
1849 alc_free(codec);
1850 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001851}
1852
1853
1854/*
1855 * ALC882/883/885/888/889 support
1856 *
1857 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
1858 * configuration. Each pin widget can choose any input DACs and a mixer.
1859 * Each ADC is connected from a mixer of all inputs. This makes possible
1860 * 6-channel independent captures.
1861 *
1862 * In addition, an independent DAC for the multi-playback (not used in this
1863 * driver yet).
1864 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02001865
1866/*
1867 * Pin config fixes
1868 */
1869enum {
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01001870 ALC882_FIXUP_ABIT_AW9D_MAX,
1871 ALC882_FIXUP_LENOVO_Y530,
1872 ALC882_FIXUP_PB_M5210,
1873 ALC882_FIXUP_ACER_ASPIRE_7736,
1874 ALC882_FIXUP_ASUS_W90V,
Marton Balint8f239212012-03-05 21:33:23 +01001875 ALC889_FIXUP_CD,
David Henningssonb2c53e22014-01-01 14:01:34 +01001876 ALC889_FIXUP_FRONT_HP_NO_PRESENCE,
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01001877 ALC889_FIXUP_VAIO_TT,
Takashi Iwai0e7cc2e2011-11-09 12:42:48 +01001878 ALC888_FIXUP_EEE1601,
Takashi Iwai177943a2011-11-09 12:55:18 +01001879 ALC882_FIXUP_EAPD,
Takashi Iwai7a6069b2011-11-09 15:22:01 +01001880 ALC883_FIXUP_EAPD,
Takashi Iwai8812c4f2011-11-09 17:39:15 +01001881 ALC883_FIXUP_ACER_EAPD,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001882 ALC882_FIXUP_GPIO1,
1883 ALC882_FIXUP_GPIO2,
Takashi Iwaieb844d52011-11-09 18:03:07 +01001884 ALC882_FIXUP_GPIO3,
Takashi Iwai68ef0562011-11-09 18:24:44 +01001885 ALC889_FIXUP_COEF,
1886 ALC882_FIXUP_ASUS_W2JC,
Takashi Iwaic3e837b2011-11-10 16:01:47 +01001887 ALC882_FIXUP_ACER_ASPIRE_4930G,
1888 ALC882_FIXUP_ACER_ASPIRE_8930G,
1889 ALC882_FIXUP_ASPIRE_8930G_VERBS,
Takashi Iwai56710872011-11-14 17:42:11 +01001890 ALC885_FIXUP_MACPRO_GPIO,
Takashi Iwai02a237b2012-02-13 15:25:07 +01001891 ALC889_FIXUP_DAC_ROUTE,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001892 ALC889_FIXUP_MBP_VREF,
1893 ALC889_FIXUP_IMAC91_VREF,
Adrien Vergée7729a42014-01-24 14:56:14 -05001894 ALC889_FIXUP_MBA11_VREF,
Takashi Iwai0756f092013-12-04 13:59:45 +01001895 ALC889_FIXUP_MBA21_VREF,
Takashi Iwaic20f31e2014-02-03 11:02:10 +01001896 ALC889_FIXUP_MP11_VREF,
Mario Kleiner9f660a12015-12-22 00:45:43 +01001897 ALC889_FIXUP_MP41_VREF,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02001898 ALC882_FIXUP_INV_DMIC,
Takashi Iwaie427c232012-07-29 10:04:08 +02001899 ALC882_FIXUP_NO_PRIMARY_HP,
Takashi Iwai1f0bbf02013-11-28 15:21:21 +01001900 ALC887_FIXUP_ASUS_BASS,
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01001901 ALC887_FIXUP_BASS_CHMAP,
Takashi Iwai7beb3a62017-04-10 18:05:52 +02001902 ALC1220_FIXUP_GB_DUAL_CODECS,
Peisen0202f5c2017-10-26 10:35:36 +08001903 ALC1220_FIXUP_CLEVO_P950,
Richard Sailer80690a22019-04-02 15:52:04 +02001904 ALC1220_FIXUP_CLEVO_PB51ED,
1905 ALC1220_FIXUP_CLEVO_PB51ED_PINS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02001906};
1907
Takashi Iwai68ef0562011-11-09 18:24:44 +01001908static void alc889_fixup_coef(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001909 const struct hda_fixup *fix, int action)
Takashi Iwai68ef0562011-11-09 18:24:44 +01001910{
Takashi Iwai1727a772013-01-10 09:52:52 +01001911 if (action != HDA_FIXUP_ACT_INIT)
Takashi Iwai68ef0562011-11-09 18:24:44 +01001912 return;
Kailang Yang1df88742014-10-29 16:10:13 +08001913 alc_update_coef_idx(codec, 7, 0, 0x2030);
Takashi Iwai68ef0562011-11-09 18:24:44 +01001914}
1915
Takashi Iwai56710872011-11-14 17:42:11 +01001916/* set up GPIO at initialization */
1917static void alc885_fixup_macpro_gpio(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001918 const struct hda_fixup *fix, int action)
Takashi Iwai56710872011-11-14 17:42:11 +01001919{
Takashi Iwai215c8502018-06-19 22:34:26 +02001920 struct alc_spec *spec = codec->spec;
1921
1922 spec->gpio_write_delay = true;
1923 alc_fixup_gpio3(codec, fix, action);
Takashi Iwai56710872011-11-14 17:42:11 +01001924}
1925
Takashi Iwai02a237b2012-02-13 15:25:07 +01001926/* Fix the connection of some pins for ALC889:
1927 * At least, Acer Aspire 5935 shows the connections to DAC3/4 don't
1928 * work correctly (bko#42740)
1929 */
1930static void alc889_fixup_dac_route(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001931 const struct hda_fixup *fix, int action)
Takashi Iwai02a237b2012-02-13 15:25:07 +01001932{
Takashi Iwai1727a772013-01-10 09:52:52 +01001933 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwaief8d60f2012-02-17 10:12:38 +01001934 /* fake the connections during parsing the tree */
Takashi Iwai02a237b2012-02-13 15:25:07 +01001935 hda_nid_t conn1[2] = { 0x0c, 0x0d };
1936 hda_nid_t conn2[2] = { 0x0e, 0x0f };
1937 snd_hda_override_conn_list(codec, 0x14, 2, conn1);
1938 snd_hda_override_conn_list(codec, 0x15, 2, conn1);
1939 snd_hda_override_conn_list(codec, 0x18, 2, conn2);
1940 snd_hda_override_conn_list(codec, 0x1a, 2, conn2);
Takashi Iwai1727a772013-01-10 09:52:52 +01001941 } else if (action == HDA_FIXUP_ACT_PROBE) {
Takashi Iwaief8d60f2012-02-17 10:12:38 +01001942 /* restore the connections */
1943 hda_nid_t conn[5] = { 0x0c, 0x0d, 0x0e, 0x0f, 0x26 };
1944 snd_hda_override_conn_list(codec, 0x14, 5, conn);
1945 snd_hda_override_conn_list(codec, 0x15, 5, conn);
1946 snd_hda_override_conn_list(codec, 0x18, 5, conn);
1947 snd_hda_override_conn_list(codec, 0x1a, 5, conn);
Takashi Iwai02a237b2012-02-13 15:25:07 +01001948 }
1949}
1950
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001951/* Set VREF on HP pin */
1952static void alc889_fixup_mbp_vref(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001953 const struct hda_fixup *fix, int action)
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001954{
1955 struct alc_spec *spec = codec->spec;
Mario Kleiner9f660a12015-12-22 00:45:43 +01001956 static hda_nid_t nids[3] = { 0x14, 0x15, 0x19 };
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001957 int i;
1958
Takashi Iwai1727a772013-01-10 09:52:52 +01001959 if (action != HDA_FIXUP_ACT_INIT)
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001960 return;
1961 for (i = 0; i < ARRAY_SIZE(nids); i++) {
1962 unsigned int val = snd_hda_codec_get_pincfg(codec, nids[i]);
1963 if (get_defcfg_device(val) != AC_JACK_HP_OUT)
1964 continue;
Takashi Iwaid3f02d62013-01-10 10:12:22 +01001965 val = snd_hda_codec_get_pin_target(codec, nids[i]);
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001966 val |= AC_PINCTL_VREF_80;
Takashi Iwaicdd03ce2012-04-20 12:34:50 +02001967 snd_hda_set_pin_ctl(codec, nids[i], val);
Takashi Iwai08c189f2012-12-19 15:22:24 +01001968 spec->gen.keep_vref_in_automute = 1;
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001969 break;
1970 }
1971}
1972
Takashi Iwai0756f092013-12-04 13:59:45 +01001973static void alc889_fixup_mac_pins(struct hda_codec *codec,
1974 const hda_nid_t *nids, int num_nids)
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001975{
1976 struct alc_spec *spec = codec->spec;
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001977 int i;
1978
Takashi Iwai0756f092013-12-04 13:59:45 +01001979 for (i = 0; i < num_nids; i++) {
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001980 unsigned int val;
Takashi Iwaid3f02d62013-01-10 10:12:22 +01001981 val = snd_hda_codec_get_pin_target(codec, nids[i]);
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001982 val |= AC_PINCTL_VREF_50;
Takashi Iwaicdd03ce2012-04-20 12:34:50 +02001983 snd_hda_set_pin_ctl(codec, nids[i], val);
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001984 }
Takashi Iwai08c189f2012-12-19 15:22:24 +01001985 spec->gen.keep_vref_in_automute = 1;
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001986}
1987
Takashi Iwai0756f092013-12-04 13:59:45 +01001988/* Set VREF on speaker pins on imac91 */
1989static void alc889_fixup_imac91_vref(struct hda_codec *codec,
1990 const struct hda_fixup *fix, int action)
1991{
1992 static hda_nid_t nids[2] = { 0x18, 0x1a };
1993
1994 if (action == HDA_FIXUP_ACT_INIT)
1995 alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
1996}
1997
Adrien Vergée7729a42014-01-24 14:56:14 -05001998/* Set VREF on speaker pins on mba11 */
1999static void alc889_fixup_mba11_vref(struct hda_codec *codec,
2000 const struct hda_fixup *fix, int action)
2001{
2002 static hda_nid_t nids[1] = { 0x18 };
2003
2004 if (action == HDA_FIXUP_ACT_INIT)
2005 alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
2006}
2007
Takashi Iwai0756f092013-12-04 13:59:45 +01002008/* Set VREF on speaker pins on mba21 */
2009static void alc889_fixup_mba21_vref(struct hda_codec *codec,
2010 const struct hda_fixup *fix, int action)
2011{
2012 static hda_nid_t nids[2] = { 0x18, 0x19 };
2013
2014 if (action == HDA_FIXUP_ACT_INIT)
2015 alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
2016}
2017
Takashi Iwaie427c232012-07-29 10:04:08 +02002018/* Don't take HP output as primary
Fernando Luis Vázquez Caod9111492013-02-12 16:49:46 +09002019 * Strangely, the speaker output doesn't work on Vaio Z and some Vaio
2020 * all-in-one desktop PCs (for example VGC-LN51JGB) through DAC 0x05
Takashi Iwaie427c232012-07-29 10:04:08 +02002021 */
2022static void alc882_fixup_no_primary_hp(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01002023 const struct hda_fixup *fix, int action)
Takashi Iwaie427c232012-07-29 10:04:08 +02002024{
2025 struct alc_spec *spec = codec->spec;
Takashi Iwaida96fb52013-07-29 16:54:36 +02002026 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai08c189f2012-12-19 15:22:24 +01002027 spec->gen.no_primary_hp = 1;
Takashi Iwaida96fb52013-07-29 16:54:36 +02002028 spec->gen.no_multi_io = 1;
2029 }
Takashi Iwaie427c232012-07-29 10:04:08 +02002030}
2031
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01002032static void alc_fixup_bass_chmap(struct hda_codec *codec,
2033 const struct hda_fixup *fix, int action);
2034
Takashi Iwai7beb3a62017-04-10 18:05:52 +02002035/* For dual-codec configuration, we need to disable some features to avoid
2036 * conflicts of kctls and PCM streams
2037 */
2038static void alc_fixup_dual_codecs(struct hda_codec *codec,
2039 const struct hda_fixup *fix, int action)
2040{
2041 struct alc_spec *spec = codec->spec;
2042
2043 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2044 return;
2045 /* disable vmaster */
2046 spec->gen.suppress_vmaster = 1;
2047 /* auto-mute and auto-mic switch don't work with multiple codecs */
2048 spec->gen.suppress_auto_mute = 1;
2049 spec->gen.suppress_auto_mic = 1;
2050 /* disable aamix as well */
2051 spec->gen.mixer_nid = 0;
2052 /* add location prefix to avoid conflicts */
2053 codec->force_pin_prefix = 1;
2054}
2055
2056static void rename_ctl(struct hda_codec *codec, const char *oldname,
2057 const char *newname)
2058{
2059 struct snd_kcontrol *kctl;
2060
2061 kctl = snd_hda_find_mixer_ctl(codec, oldname);
2062 if (kctl)
2063 strcpy(kctl->id.name, newname);
2064}
2065
2066static void alc1220_fixup_gb_dual_codecs(struct hda_codec *codec,
2067 const struct hda_fixup *fix,
2068 int action)
2069{
2070 alc_fixup_dual_codecs(codec, fix, action);
2071 switch (action) {
2072 case HDA_FIXUP_ACT_PRE_PROBE:
2073 /* override card longname to provide a unique UCM profile */
2074 strcpy(codec->card->longname, "HDAudio-Gigabyte-ALC1220DualCodecs");
2075 break;
2076 case HDA_FIXUP_ACT_BUILD:
2077 /* rename Capture controls depending on the codec */
2078 rename_ctl(codec, "Capture Volume",
2079 codec->addr == 0 ?
2080 "Rear-Panel Capture Volume" :
2081 "Front-Panel Capture Volume");
2082 rename_ctl(codec, "Capture Switch",
2083 codec->addr == 0 ?
2084 "Rear-Panel Capture Switch" :
2085 "Front-Panel Capture Switch");
2086 break;
2087 }
2088}
2089
Peisen0202f5c2017-10-26 10:35:36 +08002090static void alc1220_fixup_clevo_p950(struct hda_codec *codec,
2091 const struct hda_fixup *fix,
2092 int action)
2093{
2094 hda_nid_t conn1[1] = { 0x0c };
2095
2096 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2097 return;
2098
2099 alc_update_coef_idx(codec, 0x7, 0, 0x3c3);
2100 /* We therefore want to make sure 0x14 (front headphone) and
2101 * 0x1b (speakers) use the stereo DAC 0x02
2102 */
2103 snd_hda_override_conn_list(codec, 0x14, 1, conn1);
2104 snd_hda_override_conn_list(codec, 0x1b, 1, conn1);
2105}
2106
Jeremy Soller7f665b12019-02-13 10:56:19 -07002107static void alc_fixup_headset_mode_no_hp_mic(struct hda_codec *codec,
2108 const struct hda_fixup *fix, int action);
2109
Richard Sailer80690a22019-04-02 15:52:04 +02002110static void alc1220_fixup_clevo_pb51ed(struct hda_codec *codec,
Jeremy Soller7f665b12019-02-13 10:56:19 -07002111 const struct hda_fixup *fix,
2112 int action)
2113{
2114 alc1220_fixup_clevo_p950(codec, fix, action);
2115 alc_fixup_headset_mode_no_hp_mic(codec, fix, action);
2116}
2117
Takashi Iwai1727a772013-01-10 09:52:52 +01002118static const struct hda_fixup alc882_fixups[] = {
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002119 [ALC882_FIXUP_ABIT_AW9D_MAX] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002120 .type = HDA_FIXUP_PINS,
2121 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002122 { 0x15, 0x01080104 }, /* side */
2123 { 0x16, 0x01011012 }, /* rear */
2124 { 0x17, 0x01016011 }, /* clfe */
2125 { }
2126 }
2127 },
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002128 [ALC882_FIXUP_LENOVO_Y530] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002129 .type = HDA_FIXUP_PINS,
2130 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002131 { 0x15, 0x99130112 }, /* rear int speakers */
2132 { 0x16, 0x99130111 }, /* subwoofer */
2133 { }
2134 }
2135 },
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002136 [ALC882_FIXUP_PB_M5210] = {
Takashi Iwaifd108212013-01-10 10:18:14 +01002137 .type = HDA_FIXUP_PINCTLS,
2138 .v.pins = (const struct hda_pintbl[]) {
2139 { 0x19, PIN_VREF50 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02002140 {}
2141 }
2142 },
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002143 [ALC882_FIXUP_ACER_ASPIRE_7736] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002144 .type = HDA_FIXUP_FUNC,
Takashi Iwai23d30f22012-05-07 17:17:32 +02002145 .v.func = alc_fixup_sku_ignore,
Takashi Iwai1d045db2011-07-07 18:23:21 +02002146 },
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002147 [ALC882_FIXUP_ASUS_W90V] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002148 .type = HDA_FIXUP_PINS,
2149 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai5cdf7452011-10-26 23:04:08 +02002150 { 0x16, 0x99130110 }, /* fix sequence for CLFE */
2151 { }
2152 }
2153 },
Marton Balint8f239212012-03-05 21:33:23 +01002154 [ALC889_FIXUP_CD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002155 .type = HDA_FIXUP_PINS,
2156 .v.pins = (const struct hda_pintbl[]) {
Marton Balint8f239212012-03-05 21:33:23 +01002157 { 0x1c, 0x993301f0 }, /* CD */
2158 { }
2159 }
2160 },
David Henningssonb2c53e22014-01-01 14:01:34 +01002161 [ALC889_FIXUP_FRONT_HP_NO_PRESENCE] = {
2162 .type = HDA_FIXUP_PINS,
2163 .v.pins = (const struct hda_pintbl[]) {
2164 { 0x1b, 0x02214120 }, /* Front HP jack is flaky, disable jack detect */
2165 { }
2166 },
2167 .chained = true,
2168 .chain_id = ALC889_FIXUP_CD,
2169 },
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002170 [ALC889_FIXUP_VAIO_TT] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002171 .type = HDA_FIXUP_PINS,
2172 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002173 { 0x17, 0x90170111 }, /* hidden surround speaker */
2174 { }
2175 }
2176 },
Takashi Iwai0e7cc2e2011-11-09 12:42:48 +01002177 [ALC888_FIXUP_EEE1601] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002178 .type = HDA_FIXUP_VERBS,
Takashi Iwai0e7cc2e2011-11-09 12:42:48 +01002179 .v.verbs = (const struct hda_verb[]) {
2180 { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b },
2181 { 0x20, AC_VERB_SET_PROC_COEF, 0x0838 },
2182 { }
2183 }
Takashi Iwai177943a2011-11-09 12:55:18 +01002184 },
2185 [ALC882_FIXUP_EAPD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002186 .type = HDA_FIXUP_VERBS,
Takashi Iwai177943a2011-11-09 12:55:18 +01002187 .v.verbs = (const struct hda_verb[]) {
2188 /* change to EAPD mode */
2189 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2190 { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
2191 { }
2192 }
2193 },
Takashi Iwai7a6069b2011-11-09 15:22:01 +01002194 [ALC883_FIXUP_EAPD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002195 .type = HDA_FIXUP_VERBS,
Takashi Iwai7a6069b2011-11-09 15:22:01 +01002196 .v.verbs = (const struct hda_verb[]) {
2197 /* change to EAPD mode */
2198 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2199 { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
2200 { }
2201 }
2202 },
Takashi Iwai8812c4f2011-11-09 17:39:15 +01002203 [ALC883_FIXUP_ACER_EAPD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002204 .type = HDA_FIXUP_VERBS,
Takashi Iwai8812c4f2011-11-09 17:39:15 +01002205 .v.verbs = (const struct hda_verb[]) {
2206 /* eanable EAPD on Acer laptops */
2207 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2208 { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
2209 { }
2210 }
2211 },
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002212 [ALC882_FIXUP_GPIO1] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02002213 .type = HDA_FIXUP_FUNC,
2214 .v.func = alc_fixup_gpio1,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002215 },
2216 [ALC882_FIXUP_GPIO2] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02002217 .type = HDA_FIXUP_FUNC,
2218 .v.func = alc_fixup_gpio2,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002219 },
Takashi Iwaieb844d52011-11-09 18:03:07 +01002220 [ALC882_FIXUP_GPIO3] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02002221 .type = HDA_FIXUP_FUNC,
2222 .v.func = alc_fixup_gpio3,
Takashi Iwaieb844d52011-11-09 18:03:07 +01002223 },
Takashi Iwai68ef0562011-11-09 18:24:44 +01002224 [ALC882_FIXUP_ASUS_W2JC] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02002225 .type = HDA_FIXUP_FUNC,
2226 .v.func = alc_fixup_gpio1,
Takashi Iwai68ef0562011-11-09 18:24:44 +01002227 .chained = true,
2228 .chain_id = ALC882_FIXUP_EAPD,
2229 },
2230 [ALC889_FIXUP_COEF] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002231 .type = HDA_FIXUP_FUNC,
Takashi Iwai68ef0562011-11-09 18:24:44 +01002232 .v.func = alc889_fixup_coef,
2233 },
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002234 [ALC882_FIXUP_ACER_ASPIRE_4930G] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002235 .type = HDA_FIXUP_PINS,
2236 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002237 { 0x16, 0x99130111 }, /* CLFE speaker */
2238 { 0x17, 0x99130112 }, /* surround speaker */
2239 { }
Takashi Iwai038d4fe2012-04-11 17:18:12 +02002240 },
2241 .chained = true,
2242 .chain_id = ALC882_FIXUP_GPIO1,
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002243 },
2244 [ALC882_FIXUP_ACER_ASPIRE_8930G] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002245 .type = HDA_FIXUP_PINS,
2246 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002247 { 0x16, 0x99130111 }, /* CLFE speaker */
2248 { 0x1b, 0x99130112 }, /* surround speaker */
2249 { }
2250 },
2251 .chained = true,
2252 .chain_id = ALC882_FIXUP_ASPIRE_8930G_VERBS,
2253 },
2254 [ALC882_FIXUP_ASPIRE_8930G_VERBS] = {
2255 /* additional init verbs for Acer Aspire 8930G */
Takashi Iwai1727a772013-01-10 09:52:52 +01002256 .type = HDA_FIXUP_VERBS,
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002257 .v.verbs = (const struct hda_verb[]) {
2258 /* Enable all DACs */
2259 /* DAC DISABLE/MUTE 1? */
2260 /* setting bits 1-5 disables DAC nids 0x02-0x06
2261 * apparently. Init=0x38 */
2262 { 0x20, AC_VERB_SET_COEF_INDEX, 0x03 },
2263 { 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
2264 /* DAC DISABLE/MUTE 2? */
2265 /* some bit here disables the other DACs.
2266 * Init=0x4900 */
2267 { 0x20, AC_VERB_SET_COEF_INDEX, 0x08 },
2268 { 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
2269 /* DMIC fix
2270 * This laptop has a stereo digital microphone.
2271 * The mics are only 1cm apart which makes the stereo
2272 * useless. However, either the mic or the ALC889
2273 * makes the signal become a difference/sum signal
2274 * instead of standard stereo, which is annoying.
2275 * So instead we flip this bit which makes the
2276 * codec replicate the sum signal to both channels,
2277 * turning it into a normal mono mic.
2278 */
2279 /* DMIC_CONTROL? Init value = 0x0001 */
2280 { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b },
2281 { 0x20, AC_VERB_SET_PROC_COEF, 0x0003 },
2282 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2283 { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
2284 { }
Takashi Iwai038d4fe2012-04-11 17:18:12 +02002285 },
2286 .chained = true,
2287 .chain_id = ALC882_FIXUP_GPIO1,
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002288 },
Takashi Iwai56710872011-11-14 17:42:11 +01002289 [ALC885_FIXUP_MACPRO_GPIO] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002290 .type = HDA_FIXUP_FUNC,
Takashi Iwai56710872011-11-14 17:42:11 +01002291 .v.func = alc885_fixup_macpro_gpio,
2292 },
Takashi Iwai02a237b2012-02-13 15:25:07 +01002293 [ALC889_FIXUP_DAC_ROUTE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002294 .type = HDA_FIXUP_FUNC,
Takashi Iwai02a237b2012-02-13 15:25:07 +01002295 .v.func = alc889_fixup_dac_route,
2296 },
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002297 [ALC889_FIXUP_MBP_VREF] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002298 .type = HDA_FIXUP_FUNC,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002299 .v.func = alc889_fixup_mbp_vref,
2300 .chained = true,
2301 .chain_id = ALC882_FIXUP_GPIO1,
2302 },
2303 [ALC889_FIXUP_IMAC91_VREF] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002304 .type = HDA_FIXUP_FUNC,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002305 .v.func = alc889_fixup_imac91_vref,
2306 .chained = true,
2307 .chain_id = ALC882_FIXUP_GPIO1,
2308 },
Adrien Vergée7729a42014-01-24 14:56:14 -05002309 [ALC889_FIXUP_MBA11_VREF] = {
2310 .type = HDA_FIXUP_FUNC,
2311 .v.func = alc889_fixup_mba11_vref,
2312 .chained = true,
2313 .chain_id = ALC889_FIXUP_MBP_VREF,
2314 },
Takashi Iwai0756f092013-12-04 13:59:45 +01002315 [ALC889_FIXUP_MBA21_VREF] = {
2316 .type = HDA_FIXUP_FUNC,
2317 .v.func = alc889_fixup_mba21_vref,
2318 .chained = true,
2319 .chain_id = ALC889_FIXUP_MBP_VREF,
2320 },
Takashi Iwaic20f31e2014-02-03 11:02:10 +01002321 [ALC889_FIXUP_MP11_VREF] = {
2322 .type = HDA_FIXUP_FUNC,
2323 .v.func = alc889_fixup_mba11_vref,
2324 .chained = true,
2325 .chain_id = ALC885_FIXUP_MACPRO_GPIO,
2326 },
Mario Kleiner9f660a12015-12-22 00:45:43 +01002327 [ALC889_FIXUP_MP41_VREF] = {
2328 .type = HDA_FIXUP_FUNC,
2329 .v.func = alc889_fixup_mbp_vref,
2330 .chained = true,
2331 .chain_id = ALC885_FIXUP_MACPRO_GPIO,
2332 },
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002333 [ALC882_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002334 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02002335 .v.func = alc_fixup_inv_dmic,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002336 },
Takashi Iwaie427c232012-07-29 10:04:08 +02002337 [ALC882_FIXUP_NO_PRIMARY_HP] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002338 .type = HDA_FIXUP_FUNC,
Takashi Iwaie427c232012-07-29 10:04:08 +02002339 .v.func = alc882_fixup_no_primary_hp,
2340 },
Takashi Iwai1f0bbf02013-11-28 15:21:21 +01002341 [ALC887_FIXUP_ASUS_BASS] = {
2342 .type = HDA_FIXUP_PINS,
2343 .v.pins = (const struct hda_pintbl[]) {
2344 {0x16, 0x99130130}, /* bass speaker */
2345 {}
2346 },
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01002347 .chained = true,
2348 .chain_id = ALC887_FIXUP_BASS_CHMAP,
2349 },
2350 [ALC887_FIXUP_BASS_CHMAP] = {
2351 .type = HDA_FIXUP_FUNC,
2352 .v.func = alc_fixup_bass_chmap,
Takashi Iwai1f0bbf02013-11-28 15:21:21 +01002353 },
Takashi Iwai7beb3a62017-04-10 18:05:52 +02002354 [ALC1220_FIXUP_GB_DUAL_CODECS] = {
2355 .type = HDA_FIXUP_FUNC,
2356 .v.func = alc1220_fixup_gb_dual_codecs,
2357 },
Peisen0202f5c2017-10-26 10:35:36 +08002358 [ALC1220_FIXUP_CLEVO_P950] = {
2359 .type = HDA_FIXUP_FUNC,
2360 .v.func = alc1220_fixup_clevo_p950,
2361 },
Richard Sailer80690a22019-04-02 15:52:04 +02002362 [ALC1220_FIXUP_CLEVO_PB51ED] = {
Jeremy Soller7f665b12019-02-13 10:56:19 -07002363 .type = HDA_FIXUP_FUNC,
Richard Sailer80690a22019-04-02 15:52:04 +02002364 .v.func = alc1220_fixup_clevo_pb51ed,
Jeremy Soller7f665b12019-02-13 10:56:19 -07002365 },
Richard Sailer80690a22019-04-02 15:52:04 +02002366 [ALC1220_FIXUP_CLEVO_PB51ED_PINS] = {
Jeremy Soller7f665b12019-02-13 10:56:19 -07002367 .type = HDA_FIXUP_PINS,
2368 .v.pins = (const struct hda_pintbl[]) {
2369 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
2370 {}
2371 },
2372 .chained = true,
Richard Sailer80690a22019-04-02 15:52:04 +02002373 .chain_id = ALC1220_FIXUP_CLEVO_PB51ED,
Jeremy Soller7f665b12019-02-13 10:56:19 -07002374 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02002375};
2376
2377static const struct snd_pci_quirk alc882_fixup_tbl[] = {
Takashi Iwai8812c4f2011-11-09 17:39:15 +01002378 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_FIXUP_ACER_EAPD),
2379 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
Takashi Iwaib5d724b2015-06-02 19:57:08 +02002380 SND_PCI_QUIRK(0x1025, 0x0107, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
Takashi Iwai8812c4f2011-11-09 17:39:15 +01002381 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_FIXUP_ACER_EAPD),
2382 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
2383 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_FIXUP_ACER_EAPD),
2384 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_FIXUP_ACER_EAPD),
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002385 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
2386 ALC882_FIXUP_ACER_ASPIRE_4930G),
2387 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
2388 ALC882_FIXUP_ACER_ASPIRE_4930G),
2389 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
2390 ALC882_FIXUP_ACER_ASPIRE_8930G),
2391 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
2392 ALC882_FIXUP_ACER_ASPIRE_8930G),
2393 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
2394 ALC882_FIXUP_ACER_ASPIRE_4930G),
2395 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
2396 ALC882_FIXUP_ACER_ASPIRE_4930G),
2397 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
2398 ALC882_FIXUP_ACER_ASPIRE_4930G),
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002399 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", ALC882_FIXUP_PB_M5210),
Takashi Iwaif5c53d82012-05-07 10:07:33 +02002400 SND_PCI_QUIRK(0x1025, 0x021e, "Acer Aspire 5739G",
2401 ALC882_FIXUP_ACER_ASPIRE_4930G),
Takashi Iwai02a237b2012-02-13 15:25:07 +01002402 SND_PCI_QUIRK(0x1025, 0x0259, "Acer Aspire 5935", ALC889_FIXUP_DAC_ROUTE),
Takashi Iwaife97da12012-04-12 08:00:19 +02002403 SND_PCI_QUIRK(0x1025, 0x026b, "Acer Aspire 8940G", ALC882_FIXUP_ACER_ASPIRE_8930G),
Takashi Iwaiac9b1cd2011-11-09 17:45:55 +01002404 SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", ALC882_FIXUP_ACER_ASPIRE_7736),
Takashi Iwai177943a2011-11-09 12:55:18 +01002405 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_FIXUP_EAPD),
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002406 SND_PCI_QUIRK(0x1043, 0x1873, "ASUS W90V", ALC882_FIXUP_ASUS_W90V),
Takashi Iwai68ef0562011-11-09 18:24:44 +01002407 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_FIXUP_ASUS_W2JC),
Takashi Iwai0e7cc2e2011-11-09 12:42:48 +01002408 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_FIXUP_EEE1601),
Takashi Iwai1f0bbf02013-11-28 15:21:21 +01002409 SND_PCI_QUIRK(0x1043, 0x84bc, "ASUS ET2700", ALC887_FIXUP_ASUS_BASS),
Takashi Iwai85bcf962016-12-06 16:20:36 +01002410 SND_PCI_QUIRK(0x1043, 0x8691, "ASUS ROG Ranger VIII", ALC882_FIXUP_GPIO3),
Takashi Iwaiac9b1cd2011-11-09 17:45:55 +01002411 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT),
Takashi Iwaie427c232012-07-29 10:04:08 +02002412 SND_PCI_QUIRK(0x104d, 0x905a, "Sony Vaio Z", ALC882_FIXUP_NO_PRIMARY_HP),
Sergei A. Trusov3f3c3712017-08-02 20:23:48 +10002413 SND_PCI_QUIRK(0x104d, 0x9060, "Sony Vaio VPCL14M1R", ALC882_FIXUP_NO_PRIMARY_HP),
Fernando Luis Vázquez Cao12e31a72013-02-12 16:47:44 +09002414 SND_PCI_QUIRK(0x104d, 0x9043, "Sony Vaio VGC-LN51JGB", ALC882_FIXUP_NO_PRIMARY_HP),
Takashi Iwaic44d9b12016-02-07 09:38:26 +01002415 SND_PCI_QUIRK(0x104d, 0x9044, "Sony VAIO AiO", ALC882_FIXUP_NO_PRIMARY_HP),
Takashi Iwai56710872011-11-14 17:42:11 +01002416
2417 /* All Apple entries are in codec SSIDs */
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002418 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC889_FIXUP_MBP_VREF),
2419 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC889_FIXUP_MBP_VREF),
2420 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF),
Takashi Iwaic20f31e2014-02-03 11:02:10 +01002421 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC889_FIXUP_MP11_VREF),
Takashi Iwai56710872011-11-14 17:42:11 +01002422 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_FIXUP_MACPRO_GPIO),
2423 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_FIXUP_MACPRO_GPIO),
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002424 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC889_FIXUP_MBP_VREF),
2425 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889_FIXUP_MBP_VREF),
Takashi Iwai56710872011-11-14 17:42:11 +01002426 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_FIXUP_EAPD),
Adrien Vergée7729a42014-01-24 14:56:14 -05002427 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC889_FIXUP_MBA11_VREF),
Takashi Iwai0756f092013-12-04 13:59:45 +01002428 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC889_FIXUP_MBA21_VREF),
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002429 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889_FIXUP_MBP_VREF),
2430 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF),
Takashi Iwai56710872011-11-14 17:42:11 +01002431 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_FIXUP_MACPRO_GPIO),
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002432 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC889_FIXUP_IMAC91_VREF),
2433 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC889_FIXUP_IMAC91_VREF),
2434 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC889_FIXUP_IMAC91_VREF),
Mario Kleiner9f660a12015-12-22 00:45:43 +01002435 SND_PCI_QUIRK(0x106b, 0x4200, "Mac Pro 4,1/5,1", ALC889_FIXUP_MP41_VREF),
Takashi Iwai05193632012-11-12 10:07:36 +01002436 SND_PCI_QUIRK(0x106b, 0x4300, "iMac 9,1", ALC889_FIXUP_IMAC91_VREF),
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002437 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC889_FIXUP_IMAC91_VREF),
2438 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC889_FIXUP_IMAC91_VREF),
Takashi Iwai649ccd02015-07-30 22:30:29 +02002439 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC889_FIXUP_MBA11_VREF),
Takashi Iwai56710872011-11-14 17:42:11 +01002440
Takashi Iwai7a6069b2011-11-09 15:22:01 +01002441 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC882_FIXUP_EAPD),
David Henningssonb2c53e22014-01-01 14:01:34 +01002442 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3/Z87X-UD3H", ALC889_FIXUP_FRONT_HP_NO_PRESENCE),
Takashi Iwai7beb3a62017-04-10 18:05:52 +02002443 SND_PCI_QUIRK(0x1458, 0xa0b8, "Gigabyte AZ370-Gaming", ALC1220_FIXUP_GB_DUAL_CODECS),
Takashi Iwaid2c3b142017-06-01 09:35:30 +02002444 SND_PCI_QUIRK(0x1462, 0x7350, "MSI-7350", ALC889_FIXUP_CD),
Takashi Iwai63691582017-05-22 16:32:46 +02002445 SND_PCI_QUIRK(0x1462, 0xda57, "MSI Z270-Gaming", ALC1220_FIXUP_GB_DUAL_CODECS),
Takashi Iwaid2c3b142017-06-01 09:35:30 +02002446 SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3),
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002447 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX),
Peisen0202f5c2017-10-26 10:35:36 +08002448 SND_PCI_QUIRK(0x1558, 0x9501, "Clevo P950HR", ALC1220_FIXUP_CLEVO_P950),
Takashi Iwaif3d737b2018-07-17 17:08:32 +02002449 SND_PCI_QUIRK(0x1558, 0x95e1, "Clevo P95xER", ALC1220_FIXUP_CLEVO_P950),
Jeremy Soller2f0d5202018-05-07 09:28:45 -06002450 SND_PCI_QUIRK(0x1558, 0x95e2, "Clevo P950ER", ALC1220_FIXUP_CLEVO_P950),
Richard Sailer503d90b2019-06-19 13:33:11 +02002451 SND_PCI_QUIRK(0x1558, 0x96e1, "Clevo P960[ER][CDFN]-K", ALC1220_FIXUP_CLEVO_P950),
2452 SND_PCI_QUIRK(0x1558, 0x97e1, "Clevo P970[ER][CDFN]", ALC1220_FIXUP_CLEVO_P950),
2453 SND_PCI_QUIRK(0x1558, 0x65d1, "Clevo PB51[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
2454 SND_PCI_QUIRK(0x1558, 0x67d1, "Clevo PB71[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
Takashi Iwai7a6069b2011-11-09 15:22:01 +01002455 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD),
2456 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD),
Takashi Iwaiac9b1cd2011-11-09 17:45:55 +01002457 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", ALC882_FIXUP_LENOVO_Y530),
Takashi Iwai68ef0562011-11-09 18:24:44 +01002458 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_FIXUP_COEF),
Takashi Iwai1d045db2011-07-07 18:23:21 +02002459 {}
2460};
2461
Takashi Iwai1727a772013-01-10 09:52:52 +01002462static const struct hda_model_fixup alc882_fixup_models[] = {
Takashi Iwai772c2912018-06-26 17:17:53 +02002463 {.id = ALC882_FIXUP_ABIT_AW9D_MAX, .name = "abit-aw9d"},
2464 {.id = ALC882_FIXUP_LENOVO_Y530, .name = "lenovo-y530"},
2465 {.id = ALC882_FIXUP_ACER_ASPIRE_7736, .name = "acer-aspire-7736"},
2466 {.id = ALC882_FIXUP_ASUS_W90V, .name = "asus-w90v"},
2467 {.id = ALC889_FIXUP_CD, .name = "cd"},
2468 {.id = ALC889_FIXUP_FRONT_HP_NO_PRESENCE, .name = "no-front-hp"},
2469 {.id = ALC889_FIXUP_VAIO_TT, .name = "vaio-tt"},
2470 {.id = ALC888_FIXUP_EEE1601, .name = "eee1601"},
2471 {.id = ALC882_FIXUP_EAPD, .name = "alc882-eapd"},
2472 {.id = ALC883_FIXUP_EAPD, .name = "alc883-eapd"},
2473 {.id = ALC882_FIXUP_GPIO1, .name = "gpio1"},
2474 {.id = ALC882_FIXUP_GPIO2, .name = "gpio2"},
2475 {.id = ALC882_FIXUP_GPIO3, .name = "gpio3"},
2476 {.id = ALC889_FIXUP_COEF, .name = "alc889-coef"},
2477 {.id = ALC882_FIXUP_ASUS_W2JC, .name = "asus-w2jc"},
Takashi Iwai912093b2012-04-11 14:03:41 +02002478 {.id = ALC882_FIXUP_ACER_ASPIRE_4930G, .name = "acer-aspire-4930g"},
2479 {.id = ALC882_FIXUP_ACER_ASPIRE_8930G, .name = "acer-aspire-8930g"},
2480 {.id = ALC883_FIXUP_ACER_EAPD, .name = "acer-aspire"},
Takashi Iwai772c2912018-06-26 17:17:53 +02002481 {.id = ALC885_FIXUP_MACPRO_GPIO, .name = "macpro-gpio"},
2482 {.id = ALC889_FIXUP_DAC_ROUTE, .name = "dac-route"},
2483 {.id = ALC889_FIXUP_MBP_VREF, .name = "mbp-vref"},
2484 {.id = ALC889_FIXUP_IMAC91_VREF, .name = "imac91-vref"},
2485 {.id = ALC889_FIXUP_MBA11_VREF, .name = "mba11-vref"},
2486 {.id = ALC889_FIXUP_MBA21_VREF, .name = "mba21-vref"},
2487 {.id = ALC889_FIXUP_MP11_VREF, .name = "mp11-vref"},
2488 {.id = ALC889_FIXUP_MP41_VREF, .name = "mp41-vref"},
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002489 {.id = ALC882_FIXUP_INV_DMIC, .name = "inv-dmic"},
Takashi Iwaie427c232012-07-29 10:04:08 +02002490 {.id = ALC882_FIXUP_NO_PRIMARY_HP, .name = "no-primary-hp"},
Takashi Iwai772c2912018-06-26 17:17:53 +02002491 {.id = ALC887_FIXUP_ASUS_BASS, .name = "asus-bass"},
Takashi Iwaiba90d6a2017-05-22 16:38:47 +02002492 {.id = ALC1220_FIXUP_GB_DUAL_CODECS, .name = "dual-codecs"},
Takashi Iwai772c2912018-06-26 17:17:53 +02002493 {.id = ALC1220_FIXUP_CLEVO_P950, .name = "clevo-p950"},
Takashi Iwai912093b2012-04-11 14:03:41 +02002494 {}
2495};
2496
Takashi Iwai1d045db2011-07-07 18:23:21 +02002497/*
2498 * BIOS auto configuration
2499 */
2500/* almost identical with ALC880 parser... */
2501static int alc882_parse_auto_config(struct hda_codec *codec)
2502{
Takashi Iwai1d045db2011-07-07 18:23:21 +02002503 static const hda_nid_t alc882_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002504 static const hda_nid_t alc882_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2505 return alc_parse_auto_config(codec, alc882_ignore, alc882_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002506}
2507
Takashi Iwai1d045db2011-07-07 18:23:21 +02002508/*
2509 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002510static int patch_alc882(struct hda_codec *codec)
2511{
2512 struct alc_spec *spec;
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002513 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002514
Takashi Iwai3de95172012-05-07 18:03:15 +02002515 err = alc_alloc_spec(codec, 0x0b);
2516 if (err < 0)
2517 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002518
Takashi Iwai3de95172012-05-07 18:03:15 +02002519 spec = codec->spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002520
Takashi Iwai7639a062015-03-03 10:07:24 +01002521 switch (codec->core.vendor_id) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002522 case 0x10ec0882:
2523 case 0x10ec0885:
Takashi Iwaiacf08082014-09-02 07:21:56 +02002524 case 0x10ec0900:
Kailang Yanga535ad52017-01-16 16:59:26 +08002525 case 0x10ec1220:
Takashi Iwai1d045db2011-07-07 18:23:21 +02002526 break;
2527 default:
2528 /* ALC883 and variants */
2529 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
2530 break;
2531 }
2532
Takashi Iwaic9af7532019-05-10 11:01:43 +02002533 alc_pre_init(codec);
2534
Takashi Iwai1727a772013-01-10 09:52:52 +01002535 snd_hda_pick_fixup(codec, alc882_fixup_models, alc882_fixup_tbl,
Takashi Iwai912093b2012-04-11 14:03:41 +02002536 alc882_fixups);
Takashi Iwai1727a772013-01-10 09:52:52 +01002537 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002538
2539 alc_auto_parse_customize_define(codec);
2540
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002541 if (has_cdefine_beep(codec))
2542 spec->gen.beep_nid = 0x01;
2543
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002544 /* automatic parse from the BIOS config */
2545 err = alc882_parse_auto_config(codec);
2546 if (err < 0)
2547 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002548
Takashi Iwaifea80fa2018-06-20 12:52:46 +02002549 if (!spec->gen.no_analog && spec->gen.beep_nid) {
2550 err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
2551 if (err < 0)
2552 goto error;
2553 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02002554
Takashi Iwai1727a772013-01-10 09:52:52 +01002555 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01002556
Takashi Iwai1d045db2011-07-07 18:23:21 +02002557 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02002558
2559 error:
2560 alc_free(codec);
2561 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002562}
2563
2564
2565/*
2566 * ALC262 support
2567 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002568static int alc262_parse_auto_config(struct hda_codec *codec)
2569{
Takashi Iwai1d045db2011-07-07 18:23:21 +02002570 static const hda_nid_t alc262_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002571 static const hda_nid_t alc262_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2572 return alc_parse_auto_config(codec, alc262_ignore, alc262_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002573}
2574
2575/*
2576 * Pin config fixes
2577 */
2578enum {
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002579 ALC262_FIXUP_FSC_H270,
Takashi Iwai7513e6d2013-01-18 15:41:34 +01002580 ALC262_FIXUP_FSC_S7110,
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002581 ALC262_FIXUP_HP_Z200,
2582 ALC262_FIXUP_TYAN,
Takashi Iwaic4701502011-11-07 14:20:07 +01002583 ALC262_FIXUP_LENOVO_3000,
Takashi Iwaib42590b2011-11-07 14:41:01 +01002584 ALC262_FIXUP_BENQ,
2585 ALC262_FIXUP_BENQ_T31,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002586 ALC262_FIXUP_INV_DMIC,
Mengdong Linb5c66112013-11-29 00:35:35 -05002587 ALC262_FIXUP_INTEL_BAYLEYBAY,
Takashi Iwai1d045db2011-07-07 18:23:21 +02002588};
2589
Takashi Iwai1727a772013-01-10 09:52:52 +01002590static const struct hda_fixup alc262_fixups[] = {
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002591 [ALC262_FIXUP_FSC_H270] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002592 .type = HDA_FIXUP_PINS,
2593 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002594 { 0x14, 0x99130110 }, /* speaker */
2595 { 0x15, 0x0221142f }, /* front HP */
2596 { 0x1b, 0x0121141f }, /* rear HP */
2597 { }
2598 }
2599 },
Takashi Iwai7513e6d2013-01-18 15:41:34 +01002600 [ALC262_FIXUP_FSC_S7110] = {
2601 .type = HDA_FIXUP_PINS,
2602 .v.pins = (const struct hda_pintbl[]) {
2603 { 0x15, 0x90170110 }, /* speaker */
2604 { }
2605 },
2606 .chained = true,
2607 .chain_id = ALC262_FIXUP_BENQ,
2608 },
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002609 [ALC262_FIXUP_HP_Z200] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002610 .type = HDA_FIXUP_PINS,
2611 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002612 { 0x16, 0x99130120 }, /* internal speaker */
2613 { }
2614 }
2615 },
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002616 [ALC262_FIXUP_TYAN] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002617 .type = HDA_FIXUP_PINS,
2618 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002619 { 0x14, 0x1993e1f0 }, /* int AUX */
2620 { }
2621 }
2622 },
Takashi Iwaic4701502011-11-07 14:20:07 +01002623 [ALC262_FIXUP_LENOVO_3000] = {
Takashi Iwaifd108212013-01-10 10:18:14 +01002624 .type = HDA_FIXUP_PINCTLS,
2625 .v.pins = (const struct hda_pintbl[]) {
2626 { 0x19, PIN_VREF50 },
Takashi Iwaib42590b2011-11-07 14:41:01 +01002627 {}
2628 },
2629 .chained = true,
2630 .chain_id = ALC262_FIXUP_BENQ,
2631 },
2632 [ALC262_FIXUP_BENQ] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002633 .type = HDA_FIXUP_VERBS,
Takashi Iwaib42590b2011-11-07 14:41:01 +01002634 .v.verbs = (const struct hda_verb[]) {
Takashi Iwaic4701502011-11-07 14:20:07 +01002635 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2636 { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
2637 {}
2638 }
2639 },
Takashi Iwaib42590b2011-11-07 14:41:01 +01002640 [ALC262_FIXUP_BENQ_T31] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002641 .type = HDA_FIXUP_VERBS,
Takashi Iwaib42590b2011-11-07 14:41:01 +01002642 .v.verbs = (const struct hda_verb[]) {
2643 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2644 { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
2645 {}
2646 }
2647 },
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002648 [ALC262_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002649 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02002650 .v.func = alc_fixup_inv_dmic,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002651 },
Mengdong Linb5c66112013-11-29 00:35:35 -05002652 [ALC262_FIXUP_INTEL_BAYLEYBAY] = {
2653 .type = HDA_FIXUP_FUNC,
2654 .v.func = alc_fixup_no_depop_delay,
2655 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02002656};
2657
2658static const struct snd_pci_quirk alc262_fixup_tbl[] = {
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002659 SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", ALC262_FIXUP_HP_Z200),
Takashi Iwai7513e6d2013-01-18 15:41:34 +01002660 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu Lifebook S7110", ALC262_FIXUP_FSC_S7110),
Takashi Iwai3dcd3be2011-11-07 14:59:40 +01002661 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FIXUP_BENQ),
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002662 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_FIXUP_TYAN),
Takashi Iwai275ec0c2018-06-22 12:17:45 +02002663 SND_PCI_QUIRK(0x1734, 0x1141, "FSC ESPRIMO U9210", ALC262_FIXUP_FSC_H270),
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002664 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", ALC262_FIXUP_FSC_H270),
Takashi Iwaic4701502011-11-07 14:20:07 +01002665 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000", ALC262_FIXUP_LENOVO_3000),
Takashi Iwaib42590b2011-11-07 14:41:01 +01002666 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_FIXUP_BENQ),
2667 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_FIXUP_BENQ_T31),
Mengdong Linb5c66112013-11-29 00:35:35 -05002668 SND_PCI_QUIRK(0x8086, 0x7270, "BayleyBay", ALC262_FIXUP_INTEL_BAYLEYBAY),
Takashi Iwai1d045db2011-07-07 18:23:21 +02002669 {}
2670};
2671
Takashi Iwai1727a772013-01-10 09:52:52 +01002672static const struct hda_model_fixup alc262_fixup_models[] = {
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002673 {.id = ALC262_FIXUP_INV_DMIC, .name = "inv-dmic"},
Takashi Iwaie43c44d2018-06-26 17:02:08 +02002674 {.id = ALC262_FIXUP_FSC_H270, .name = "fsc-h270"},
2675 {.id = ALC262_FIXUP_FSC_S7110, .name = "fsc-s7110"},
2676 {.id = ALC262_FIXUP_HP_Z200, .name = "hp-z200"},
2677 {.id = ALC262_FIXUP_TYAN, .name = "tyan"},
2678 {.id = ALC262_FIXUP_LENOVO_3000, .name = "lenovo-3000"},
2679 {.id = ALC262_FIXUP_BENQ, .name = "benq"},
2680 {.id = ALC262_FIXUP_BENQ_T31, .name = "benq-t31"},
2681 {.id = ALC262_FIXUP_INTEL_BAYLEYBAY, .name = "bayleybay"},
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002682 {}
2683};
Takashi Iwai1d045db2011-07-07 18:23:21 +02002684
Takashi Iwai1d045db2011-07-07 18:23:21 +02002685/*
2686 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002687static int patch_alc262(struct hda_codec *codec)
2688{
2689 struct alc_spec *spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002690 int err;
2691
Takashi Iwai3de95172012-05-07 18:03:15 +02002692 err = alc_alloc_spec(codec, 0x0b);
2693 if (err < 0)
2694 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002695
Takashi Iwai3de95172012-05-07 18:03:15 +02002696 spec = codec->spec;
Takashi Iwai08c189f2012-12-19 15:22:24 +01002697 spec->gen.shared_mic_vref_pin = 0x18;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002698
Takashi Iwai225068a2015-05-29 10:42:14 +02002699 spec->shutup = alc_eapd_shutup;
2700
Takashi Iwai1d045db2011-07-07 18:23:21 +02002701#if 0
2702 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
2703 * under-run
2704 */
Takashi Iwai98b24882014-08-18 13:47:50 +02002705 alc_update_coefex_idx(codec, 0x1a, 7, 0, 0x80);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002706#endif
Takashi Iwai1d045db2011-07-07 18:23:21 +02002707 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
2708
Takashi Iwaic9af7532019-05-10 11:01:43 +02002709 alc_pre_init(codec);
2710
Takashi Iwai1727a772013-01-10 09:52:52 +01002711 snd_hda_pick_fixup(codec, alc262_fixup_models, alc262_fixup_tbl,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002712 alc262_fixups);
Takashi Iwai1727a772013-01-10 09:52:52 +01002713 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002714
Takashi Iwaiaf741c12012-05-07 18:09:48 +02002715 alc_auto_parse_customize_define(codec);
2716
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002717 if (has_cdefine_beep(codec))
2718 spec->gen.beep_nid = 0x01;
2719
Takashi Iwai42399f72011-11-07 17:18:44 +01002720 /* automatic parse from the BIOS config */
2721 err = alc262_parse_auto_config(codec);
2722 if (err < 0)
2723 goto error;
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002724
Takashi Iwaifea80fa2018-06-20 12:52:46 +02002725 if (!spec->gen.no_analog && spec->gen.beep_nid) {
2726 err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
2727 if (err < 0)
2728 goto error;
2729 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02002730
Takashi Iwai1727a772013-01-10 09:52:52 +01002731 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01002732
Takashi Iwai1d045db2011-07-07 18:23:21 +02002733 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02002734
2735 error:
2736 alc_free(codec);
2737 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002738}
2739
2740/*
2741 * ALC268
2742 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002743/* bind Beep switches of both NID 0x0f and 0x10 */
Takashi Iwaia7177772017-05-10 12:04:08 +02002744static int alc268_beep_switch_put(struct snd_kcontrol *kcontrol,
2745 struct snd_ctl_elem_value *ucontrol)
2746{
2747 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2748 unsigned long pval;
2749 int err;
2750
2751 mutex_lock(&codec->control_mutex);
2752 pval = kcontrol->private_value;
2753 kcontrol->private_value = (pval & ~0xff) | 0x0f;
2754 err = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
2755 if (err >= 0) {
2756 kcontrol->private_value = (pval & ~0xff) | 0x10;
2757 err = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
2758 }
2759 kcontrol->private_value = pval;
2760 mutex_unlock(&codec->control_mutex);
2761 return err;
2762}
Takashi Iwai1d045db2011-07-07 18:23:21 +02002763
2764static const struct snd_kcontrol_new alc268_beep_mixer[] = {
2765 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
Takashi Iwaia7177772017-05-10 12:04:08 +02002766 {
2767 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2768 .name = "Beep Playback Switch",
2769 .subdevice = HDA_SUBDEV_AMP_FLAG,
2770 .info = snd_hda_mixer_amp_switch_info,
2771 .get = snd_hda_mixer_amp_switch_get,
2772 .put = alc268_beep_switch_put,
2773 .private_value = HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT)
2774 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02002775};
2776
2777/* set PCBEEP vol = 0, mute connections */
2778static const struct hda_verb alc268_beep_init_verbs[] = {
2779 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2780 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2781 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2782 { }
2783};
2784
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002785enum {
2786 ALC268_FIXUP_INV_DMIC,
Takashi Iwaicb766402012-10-20 10:55:21 +02002787 ALC268_FIXUP_HP_EAPD,
Takashi Iwai24eff322013-11-04 18:21:08 +01002788 ALC268_FIXUP_SPDIF,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002789};
2790
Takashi Iwai1727a772013-01-10 09:52:52 +01002791static const struct hda_fixup alc268_fixups[] = {
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002792 [ALC268_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002793 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02002794 .v.func = alc_fixup_inv_dmic,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002795 },
Takashi Iwaicb766402012-10-20 10:55:21 +02002796 [ALC268_FIXUP_HP_EAPD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002797 .type = HDA_FIXUP_VERBS,
Takashi Iwaicb766402012-10-20 10:55:21 +02002798 .v.verbs = (const struct hda_verb[]) {
2799 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 0},
2800 {}
2801 }
2802 },
Takashi Iwai24eff322013-11-04 18:21:08 +01002803 [ALC268_FIXUP_SPDIF] = {
2804 .type = HDA_FIXUP_PINS,
2805 .v.pins = (const struct hda_pintbl[]) {
2806 { 0x1e, 0x014b1180 }, /* enable SPDIF out */
2807 {}
2808 }
2809 },
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002810};
2811
Takashi Iwai1727a772013-01-10 09:52:52 +01002812static const struct hda_model_fixup alc268_fixup_models[] = {
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002813 {.id = ALC268_FIXUP_INV_DMIC, .name = "inv-dmic"},
Takashi Iwaicb766402012-10-20 10:55:21 +02002814 {.id = ALC268_FIXUP_HP_EAPD, .name = "hp-eapd"},
Takashi Iwai03bf11c2018-06-26 16:56:41 +02002815 {.id = ALC268_FIXUP_SPDIF, .name = "spdif"},
Takashi Iwaicb766402012-10-20 10:55:21 +02002816 {}
2817};
2818
2819static const struct snd_pci_quirk alc268_fixup_tbl[] = {
Takashi Iwai24eff322013-11-04 18:21:08 +01002820 SND_PCI_QUIRK(0x1025, 0x0139, "Acer TravelMate 6293", ALC268_FIXUP_SPDIF),
David Henningssonfcd8f3b2013-01-28 05:45:47 +01002821 SND_PCI_QUIRK(0x1025, 0x015b, "Acer AOA 150 (ZG5)", ALC268_FIXUP_INV_DMIC),
Takashi Iwaicb766402012-10-20 10:55:21 +02002822 /* below is codec SSID since multiple Toshiba laptops have the
2823 * same PCI SSID 1179:ff00
2824 */
2825 SND_PCI_QUIRK(0x1179, 0xff06, "Toshiba P200", ALC268_FIXUP_HP_EAPD),
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002826 {}
2827};
2828
Takashi Iwai1d045db2011-07-07 18:23:21 +02002829/*
2830 * BIOS auto configuration
2831 */
2832static int alc268_parse_auto_config(struct hda_codec *codec)
2833{
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002834 static const hda_nid_t alc268_ssids[] = { 0x15, 0x1b, 0x14, 0 };
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002835 return alc_parse_auto_config(codec, NULL, alc268_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002836}
2837
Takashi Iwai1d045db2011-07-07 18:23:21 +02002838/*
2839 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002840static int patch_alc268(struct hda_codec *codec)
2841{
2842 struct alc_spec *spec;
Takashi Iwaia5cb4632018-06-20 12:50:11 +02002843 int i, err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002844
Takashi Iwai1d045db2011-07-07 18:23:21 +02002845 /* ALC268 has no aa-loopback mixer */
Takashi Iwai3de95172012-05-07 18:03:15 +02002846 err = alc_alloc_spec(codec, 0);
2847 if (err < 0)
2848 return err;
2849
2850 spec = codec->spec;
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002851 spec->gen.beep_nid = 0x01;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002852
Takashi Iwai225068a2015-05-29 10:42:14 +02002853 spec->shutup = alc_eapd_shutup;
2854
Takashi Iwaic9af7532019-05-10 11:01:43 +02002855 alc_pre_init(codec);
2856
Takashi Iwai1727a772013-01-10 09:52:52 +01002857 snd_hda_pick_fixup(codec, alc268_fixup_models, alc268_fixup_tbl, alc268_fixups);
2858 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002859
Takashi Iwai6ebb8052011-08-16 15:15:40 +02002860 /* automatic parse from the BIOS config */
2861 err = alc268_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02002862 if (err < 0)
2863 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002864
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002865 if (err > 0 && !spec->gen.no_analog &&
2866 spec->gen.autocfg.speaker_pins[0] != 0x1d) {
Takashi Iwaia5cb4632018-06-20 12:50:11 +02002867 for (i = 0; i < ARRAY_SIZE(alc268_beep_mixer); i++) {
2868 if (!snd_hda_gen_add_kctl(&spec->gen, NULL,
2869 &alc268_beep_mixer[i])) {
2870 err = -ENOMEM;
2871 goto error;
2872 }
2873 }
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002874 snd_hda_add_verbs(codec, alc268_beep_init_verbs);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002875 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
2876 /* override the amp caps for beep generator */
2877 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
2878 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
2879 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
2880 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
2881 (0 << AC_AMPCAP_MUTE_SHIFT));
2882 }
2883
Takashi Iwai1727a772013-01-10 09:52:52 +01002884 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002885
Takashi Iwai1d045db2011-07-07 18:23:21 +02002886 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02002887
2888 error:
2889 alc_free(codec);
2890 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002891}
2892
2893/*
2894 * ALC269
2895 */
Takashi Iwai08c189f2012-12-19 15:22:24 +01002896
Takashi Iwai1d045db2011-07-07 18:23:21 +02002897static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002898 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002899};
2900
2901static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002902 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002903};
2904
Takashi Iwai1d045db2011-07-07 18:23:21 +02002905/* different alc269-variants */
2906enum {
2907 ALC269_TYPE_ALC269VA,
2908 ALC269_TYPE_ALC269VB,
2909 ALC269_TYPE_ALC269VC,
Kailang Yangadcc70b2012-05-25 08:08:38 +02002910 ALC269_TYPE_ALC269VD,
Kailang Yang065380f2013-01-10 10:25:48 +01002911 ALC269_TYPE_ALC280,
2912 ALC269_TYPE_ALC282,
Kailang Yang2af02be2013-08-22 10:03:50 +02002913 ALC269_TYPE_ALC283,
Kailang Yang065380f2013-01-10 10:25:48 +01002914 ALC269_TYPE_ALC284,
Kailang Yang4731d5d2017-06-30 15:22:57 +08002915 ALC269_TYPE_ALC293,
Kailang Yang7fc7d042013-04-25 11:04:43 +02002916 ALC269_TYPE_ALC286,
Kailang Yang506b62c2014-12-18 17:07:44 +08002917 ALC269_TYPE_ALC298,
Kailang Yang1d04c9d2013-10-24 11:35:18 +02002918 ALC269_TYPE_ALC255,
Kailang Yang4344aec2014-12-17 17:39:05 +08002919 ALC269_TYPE_ALC256,
Kailang Yangf429e7e2017-12-05 15:38:24 +08002920 ALC269_TYPE_ALC257,
Kailang Yang0a6f0602017-06-30 16:00:48 +08002921 ALC269_TYPE_ALC215,
Kailang Yang42314302016-02-03 15:03:50 +08002922 ALC269_TYPE_ALC225,
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08002923 ALC269_TYPE_ALC294,
Kailang Yang1078bef2018-11-08 16:36:15 +08002924 ALC269_TYPE_ALC300,
Kailang Yang6fbae352016-05-30 16:44:20 +08002925 ALC269_TYPE_ALC700,
Takashi Iwai1d045db2011-07-07 18:23:21 +02002926};
2927
2928/*
2929 * BIOS auto configuration
2930 */
2931static int alc269_parse_auto_config(struct hda_codec *codec)
2932{
Takashi Iwai1d045db2011-07-07 18:23:21 +02002933 static const hda_nid_t alc269_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002934 static const hda_nid_t alc269_ssids[] = { 0, 0x1b, 0x14, 0x21 };
2935 static const hda_nid_t alc269va_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2936 struct alc_spec *spec = codec->spec;
Kailang Yangadcc70b2012-05-25 08:08:38 +02002937 const hda_nid_t *ssids;
2938
2939 switch (spec->codec_variant) {
2940 case ALC269_TYPE_ALC269VA:
2941 case ALC269_TYPE_ALC269VC:
Kailang Yang065380f2013-01-10 10:25:48 +01002942 case ALC269_TYPE_ALC280:
2943 case ALC269_TYPE_ALC284:
Kailang Yang4731d5d2017-06-30 15:22:57 +08002944 case ALC269_TYPE_ALC293:
Kailang Yangadcc70b2012-05-25 08:08:38 +02002945 ssids = alc269va_ssids;
2946 break;
2947 case ALC269_TYPE_ALC269VB:
2948 case ALC269_TYPE_ALC269VD:
Kailang Yang065380f2013-01-10 10:25:48 +01002949 case ALC269_TYPE_ALC282:
Kailang Yang2af02be2013-08-22 10:03:50 +02002950 case ALC269_TYPE_ALC283:
Kailang Yang7fc7d042013-04-25 11:04:43 +02002951 case ALC269_TYPE_ALC286:
Kailang Yang506b62c2014-12-18 17:07:44 +08002952 case ALC269_TYPE_ALC298:
Kailang Yang1d04c9d2013-10-24 11:35:18 +02002953 case ALC269_TYPE_ALC255:
Kailang Yang4344aec2014-12-17 17:39:05 +08002954 case ALC269_TYPE_ALC256:
Kailang Yangf429e7e2017-12-05 15:38:24 +08002955 case ALC269_TYPE_ALC257:
Kailang Yang0a6f0602017-06-30 16:00:48 +08002956 case ALC269_TYPE_ALC215:
Kailang Yang42314302016-02-03 15:03:50 +08002957 case ALC269_TYPE_ALC225:
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08002958 case ALC269_TYPE_ALC294:
Kailang Yang1078bef2018-11-08 16:36:15 +08002959 case ALC269_TYPE_ALC300:
Kailang Yang6fbae352016-05-30 16:44:20 +08002960 case ALC269_TYPE_ALC700:
Kailang Yangadcc70b2012-05-25 08:08:38 +02002961 ssids = alc269_ssids;
2962 break;
2963 default:
2964 ssids = alc269_ssids;
2965 break;
2966 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02002967
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002968 return alc_parse_auto_config(codec, alc269_ignore, ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002969}
2970
Kailang Yang1387e2d2012-11-08 10:23:18 +01002971static void alc269vb_toggle_power_output(struct hda_codec *codec, int power_up)
Takashi Iwai1d045db2011-07-07 18:23:21 +02002972{
Takashi Iwai98b24882014-08-18 13:47:50 +02002973 alc_update_coef_idx(codec, 0x04, 1 << 11, power_up ? (1 << 11) : 0);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002974}
2975
2976static void alc269_shutup(struct hda_codec *codec)
2977{
Kailang Yangadcc70b2012-05-25 08:08:38 +02002978 struct alc_spec *spec = codec->spec;
2979
Kailang Yang1387e2d2012-11-08 10:23:18 +01002980 if (spec->codec_variant == ALC269_TYPE_ALC269VB)
2981 alc269vb_toggle_power_output(codec, 0);
2982 if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
2983 (alc_get_coef0(codec) & 0x00ff) == 0x018) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002984 msleep(150);
2985 }
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01002986 alc_shutup_pins(codec);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002987}
2988
Takashi Iwai54db6c32014-08-18 15:11:19 +02002989static struct coef_fw alc282_coefs[] = {
2990 WRITE_COEF(0x03, 0x0002), /* Power Down Control */
Kailang Yang32fa7e42014-10-24 16:26:01 +08002991 UPDATE_COEF(0x05, 0xff3f, 0x0700), /* FIFO and filter clock */
Takashi Iwai54db6c32014-08-18 15:11:19 +02002992 WRITE_COEF(0x07, 0x0200), /* DMIC control */
2993 UPDATE_COEF(0x06, 0x00f0, 0), /* Analog clock */
2994 UPDATE_COEF(0x08, 0xfffc, 0x0c2c), /* JD */
2995 WRITE_COEF(0x0a, 0xcccc), /* JD offset1 */
2996 WRITE_COEF(0x0b, 0xcccc), /* JD offset2 */
2997 WRITE_COEF(0x0e, 0x6e00), /* LDO1/2/3, DAC/ADC */
2998 UPDATE_COEF(0x0f, 0xf800, 0x1000), /* JD */
2999 UPDATE_COEF(0x10, 0xfc00, 0x0c00), /* Capless */
3000 WRITE_COEF(0x6f, 0x0), /* Class D test 4 */
3001 UPDATE_COEF(0x0c, 0xfe00, 0), /* IO power down directly */
3002 WRITE_COEF(0x34, 0xa0c0), /* ANC */
3003 UPDATE_COEF(0x16, 0x0008, 0), /* AGC MUX */
3004 UPDATE_COEF(0x1d, 0x00e0, 0), /* DAC simple content protection */
3005 UPDATE_COEF(0x1f, 0x00e0, 0), /* ADC simple content protection */
3006 WRITE_COEF(0x21, 0x8804), /* DAC ADC Zero Detection */
3007 WRITE_COEF(0x63, 0x2902), /* PLL */
3008 WRITE_COEF(0x68, 0xa080), /* capless control 2 */
3009 WRITE_COEF(0x69, 0x3400), /* capless control 3 */
3010 WRITE_COEF(0x6a, 0x2f3e), /* capless control 4 */
3011 WRITE_COEF(0x6b, 0x0), /* capless control 5 */
3012 UPDATE_COEF(0x6d, 0x0fff, 0x0900), /* class D test 2 */
3013 WRITE_COEF(0x6e, 0x110a), /* class D test 3 */
3014 UPDATE_COEF(0x70, 0x00f8, 0x00d8), /* class D test 5 */
3015 WRITE_COEF(0x71, 0x0014), /* class D test 6 */
3016 WRITE_COEF(0x72, 0xc2ba), /* classD OCP */
3017 UPDATE_COEF(0x77, 0x0f80, 0), /* classD pure DC test */
3018 WRITE_COEF(0x6c, 0xfc06), /* Class D amp control */
3019 {}
3020};
3021
Kailang Yangcb149cb2014-03-18 16:45:32 +08003022static void alc282_restore_default_value(struct hda_codec *codec)
3023{
Takashi Iwai54db6c32014-08-18 15:11:19 +02003024 alc_process_coef_fw(codec, alc282_coefs);
Kailang Yangcb149cb2014-03-18 16:45:32 +08003025}
3026
Kailang Yang7b5c7a02014-03-18 16:15:54 +08003027static void alc282_init(struct hda_codec *codec)
3028{
3029 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003030 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang7b5c7a02014-03-18 16:15:54 +08003031 bool hp_pin_sense;
3032 int coef78;
3033
Kailang Yangcb149cb2014-03-18 16:45:32 +08003034 alc282_restore_default_value(codec);
3035
Kailang Yang7b5c7a02014-03-18 16:15:54 +08003036 if (!hp_pin)
3037 return;
3038 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3039 coef78 = alc_read_coef_idx(codec, 0x78);
3040
3041 /* Index 0x78 Direct Drive HP AMP LPM Control 1 */
3042 /* Headphone capless set to high power mode */
3043 alc_write_coef_idx(codec, 0x78, 0x9004);
3044
3045 if (hp_pin_sense)
3046 msleep(2);
3047
3048 snd_hda_codec_write(codec, hp_pin, 0,
3049 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3050
3051 if (hp_pin_sense)
3052 msleep(85);
3053
3054 snd_hda_codec_write(codec, hp_pin, 0,
3055 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3056
3057 if (hp_pin_sense)
3058 msleep(100);
3059
3060 /* Headphone capless set to normal mode */
3061 alc_write_coef_idx(codec, 0x78, coef78);
3062}
3063
3064static void alc282_shutup(struct hda_codec *codec)
3065{
3066 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003067 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang7b5c7a02014-03-18 16:15:54 +08003068 bool hp_pin_sense;
3069 int coef78;
3070
3071 if (!hp_pin) {
3072 alc269_shutup(codec);
3073 return;
3074 }
3075
3076 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3077 coef78 = alc_read_coef_idx(codec, 0x78);
3078 alc_write_coef_idx(codec, 0x78, 0x9004);
3079
3080 if (hp_pin_sense)
3081 msleep(2);
3082
3083 snd_hda_codec_write(codec, hp_pin, 0,
3084 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3085
3086 if (hp_pin_sense)
3087 msleep(85);
3088
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003089 if (!spec->no_shutup_pins)
3090 snd_hda_codec_write(codec, hp_pin, 0,
3091 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
Kailang Yang7b5c7a02014-03-18 16:15:54 +08003092
3093 if (hp_pin_sense)
3094 msleep(100);
3095
3096 alc_auto_setup_eapd(codec, false);
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003097 alc_shutup_pins(codec);
Kailang Yang7b5c7a02014-03-18 16:15:54 +08003098 alc_write_coef_idx(codec, 0x78, coef78);
3099}
3100
Takashi Iwai54db6c32014-08-18 15:11:19 +02003101static struct coef_fw alc283_coefs[] = {
3102 WRITE_COEF(0x03, 0x0002), /* Power Down Control */
Kailang Yang56779862014-10-24 16:17:51 +08003103 UPDATE_COEF(0x05, 0xff3f, 0x0700), /* FIFO and filter clock */
Takashi Iwai54db6c32014-08-18 15:11:19 +02003104 WRITE_COEF(0x07, 0x0200), /* DMIC control */
3105 UPDATE_COEF(0x06, 0x00f0, 0), /* Analog clock */
3106 UPDATE_COEF(0x08, 0xfffc, 0x0c2c), /* JD */
3107 WRITE_COEF(0x0a, 0xcccc), /* JD offset1 */
3108 WRITE_COEF(0x0b, 0xcccc), /* JD offset2 */
3109 WRITE_COEF(0x0e, 0x6fc0), /* LDO1/2/3, DAC/ADC */
3110 UPDATE_COEF(0x0f, 0xf800, 0x1000), /* JD */
3111 UPDATE_COEF(0x10, 0xfc00, 0x0c00), /* Capless */
3112 WRITE_COEF(0x3a, 0x0), /* Class D test 4 */
3113 UPDATE_COEF(0x0c, 0xfe00, 0x0), /* IO power down directly */
3114 WRITE_COEF(0x22, 0xa0c0), /* ANC */
3115 UPDATE_COEFEX(0x53, 0x01, 0x000f, 0x0008), /* AGC MUX */
3116 UPDATE_COEF(0x1d, 0x00e0, 0), /* DAC simple content protection */
3117 UPDATE_COEF(0x1f, 0x00e0, 0), /* ADC simple content protection */
3118 WRITE_COEF(0x21, 0x8804), /* DAC ADC Zero Detection */
3119 WRITE_COEF(0x2e, 0x2902), /* PLL */
3120 WRITE_COEF(0x33, 0xa080), /* capless control 2 */
3121 WRITE_COEF(0x34, 0x3400), /* capless control 3 */
3122 WRITE_COEF(0x35, 0x2f3e), /* capless control 4 */
3123 WRITE_COEF(0x36, 0x0), /* capless control 5 */
3124 UPDATE_COEF(0x38, 0x0fff, 0x0900), /* class D test 2 */
3125 WRITE_COEF(0x39, 0x110a), /* class D test 3 */
3126 UPDATE_COEF(0x3b, 0x00f8, 0x00d8), /* class D test 5 */
3127 WRITE_COEF(0x3c, 0x0014), /* class D test 6 */
3128 WRITE_COEF(0x3d, 0xc2ba), /* classD OCP */
3129 UPDATE_COEF(0x42, 0x0f80, 0x0), /* classD pure DC test */
3130 WRITE_COEF(0x49, 0x0), /* test mode */
3131 UPDATE_COEF(0x40, 0xf800, 0x9800), /* Class D DC enable */
3132 UPDATE_COEF(0x42, 0xf000, 0x2000), /* DC offset */
3133 WRITE_COEF(0x37, 0xfc06), /* Class D amp control */
Kailang Yang56779862014-10-24 16:17:51 +08003134 UPDATE_COEF(0x1b, 0x8000, 0), /* HP JD control */
Takashi Iwai54db6c32014-08-18 15:11:19 +02003135 {}
3136};
3137
Kailang Yang6bd55b02014-03-17 13:51:27 +08003138static void alc283_restore_default_value(struct hda_codec *codec)
3139{
Takashi Iwai54db6c32014-08-18 15:11:19 +02003140 alc_process_coef_fw(codec, alc283_coefs);
Kailang Yang6bd55b02014-03-17 13:51:27 +08003141}
3142
Kailang Yang2af02be2013-08-22 10:03:50 +02003143static void alc283_init(struct hda_codec *codec)
3144{
3145 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003146 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang2af02be2013-08-22 10:03:50 +02003147 bool hp_pin_sense;
Kailang Yang2af02be2013-08-22 10:03:50 +02003148
Kailang Yang6bd55b02014-03-17 13:51:27 +08003149 alc283_restore_default_value(codec);
3150
Kailang Yang2af02be2013-08-22 10:03:50 +02003151 if (!hp_pin)
3152 return;
Kailang Yanga59d7192015-04-08 16:34:00 +08003153
3154 msleep(30);
Kailang Yang2af02be2013-08-22 10:03:50 +02003155 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3156
3157 /* Index 0x43 Direct Drive HP AMP LPM Control 1 */
3158 /* Headphone capless set to high power mode */
3159 alc_write_coef_idx(codec, 0x43, 0x9004);
3160
3161 snd_hda_codec_write(codec, hp_pin, 0,
3162 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3163
3164 if (hp_pin_sense)
3165 msleep(85);
3166
3167 snd_hda_codec_write(codec, hp_pin, 0,
3168 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3169
3170 if (hp_pin_sense)
3171 msleep(85);
3172 /* Index 0x46 Combo jack auto switch control 2 */
3173 /* 3k pull low control for Headset jack. */
Takashi Iwai98b24882014-08-18 13:47:50 +02003174 alc_update_coef_idx(codec, 0x46, 3 << 12, 0);
Kailang Yang2af02be2013-08-22 10:03:50 +02003175 /* Headphone capless set to normal mode */
3176 alc_write_coef_idx(codec, 0x43, 0x9614);
3177}
3178
3179static void alc283_shutup(struct hda_codec *codec)
3180{
3181 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003182 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang2af02be2013-08-22 10:03:50 +02003183 bool hp_pin_sense;
Kailang Yang2af02be2013-08-22 10:03:50 +02003184
3185 if (!hp_pin) {
3186 alc269_shutup(codec);
3187 return;
3188 }
3189
3190 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3191
3192 alc_write_coef_idx(codec, 0x43, 0x9004);
3193
Harsha Priyab450b172014-10-09 11:04:56 +00003194 /*depop hp during suspend*/
3195 alc_write_coef_idx(codec, 0x06, 0x2100);
3196
Kailang Yang2af02be2013-08-22 10:03:50 +02003197 snd_hda_codec_write(codec, hp_pin, 0,
3198 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3199
3200 if (hp_pin_sense)
Kailang Yang88011c092013-10-24 15:45:24 +02003201 msleep(100);
Kailang Yang2af02be2013-08-22 10:03:50 +02003202
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003203 if (!spec->no_shutup_pins)
3204 snd_hda_codec_write(codec, hp_pin, 0,
3205 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
Kailang Yang2af02be2013-08-22 10:03:50 +02003206
Takashi Iwai98b24882014-08-18 13:47:50 +02003207 alc_update_coef_idx(codec, 0x46, 0, 3 << 12);
Kailang Yang2af02be2013-08-22 10:03:50 +02003208
3209 if (hp_pin_sense)
Kailang Yang88011c092013-10-24 15:45:24 +02003210 msleep(100);
Kailang Yang0435b3f2014-04-08 17:14:14 +08003211 alc_auto_setup_eapd(codec, false);
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003212 alc_shutup_pins(codec);
Kailang Yang2af02be2013-08-22 10:03:50 +02003213 alc_write_coef_idx(codec, 0x43, 0x9614);
3214}
3215
Kailang Yang4a219ef2017-06-16 16:54:35 +08003216static void alc256_init(struct hda_codec *codec)
3217{
3218 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003219 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang4a219ef2017-06-16 16:54:35 +08003220 bool hp_pin_sense;
3221
3222 if (!hp_pin)
Kailang Yang6447c962019-05-08 16:27:03 +08003223 hp_pin = 0x21;
Kailang Yang4a219ef2017-06-16 16:54:35 +08003224
3225 msleep(30);
3226
3227 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3228
3229 if (hp_pin_sense)
3230 msleep(2);
3231
3232 alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */
Kailang Yang6447c962019-05-08 16:27:03 +08003233 if (spec->ultra_low_power) {
3234 alc_update_coef_idx(codec, 0x03, 1<<1, 1<<1);
3235 alc_update_coef_idx(codec, 0x08, 3<<2, 3<<2);
3236 alc_update_coef_idx(codec, 0x08, 7<<4, 0);
3237 alc_update_coef_idx(codec, 0x3b, 1<<15, 0);
3238 alc_update_coef_idx(codec, 0x0e, 7<<6, 7<<6);
3239 msleep(30);
3240 }
Kailang Yang4a219ef2017-06-16 16:54:35 +08003241
3242 snd_hda_codec_write(codec, hp_pin, 0,
3243 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3244
Kailang Yang6447c962019-05-08 16:27:03 +08003245 if (hp_pin_sense || spec->ultra_low_power)
Kailang Yang4a219ef2017-06-16 16:54:35 +08003246 msleep(85);
3247
3248 snd_hda_codec_write(codec, hp_pin, 0,
3249 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3250
Kailang Yang6447c962019-05-08 16:27:03 +08003251 if (hp_pin_sense || spec->ultra_low_power)
Kailang Yang4a219ef2017-06-16 16:54:35 +08003252 msleep(100);
3253
3254 alc_update_coef_idx(codec, 0x46, 3 << 12, 0);
3255 alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x4); /* Hight power */
Kailang Yang88d42b22018-03-14 16:08:57 +08003256 alc_update_coefex_idx(codec, 0x53, 0x02, 0x8000, 1 << 15); /* Clear bit */
3257 alc_update_coefex_idx(codec, 0x53, 0x02, 0x8000, 0 << 15);
Kailang Yangd07a9a42019-07-04 16:02:10 +08003258 alc_update_coef_idx(codec, 0x36, 1 << 13, 1 << 5); /* Switch pcbeep path to Line in path*/
Kailang Yang4a219ef2017-06-16 16:54:35 +08003259}
3260
3261static void alc256_shutup(struct hda_codec *codec)
3262{
3263 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003264 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang4a219ef2017-06-16 16:54:35 +08003265 bool hp_pin_sense;
3266
Kailang Yang6447c962019-05-08 16:27:03 +08003267 if (!hp_pin)
3268 hp_pin = 0x21;
Kailang Yang4a219ef2017-06-16 16:54:35 +08003269
3270 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3271
3272 if (hp_pin_sense)
3273 msleep(2);
3274
3275 snd_hda_codec_write(codec, hp_pin, 0,
3276 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3277
Kailang Yang6447c962019-05-08 16:27:03 +08003278 if (hp_pin_sense || spec->ultra_low_power)
Kailang Yang4a219ef2017-06-16 16:54:35 +08003279 msleep(85);
3280
Takashi Iwai1c9609e2018-01-19 14:18:34 +01003281 /* 3k pull low control for Headset jack. */
3282 /* NOTE: call this before clearing the pin, otherwise codec stalls */
3283 alc_update_coef_idx(codec, 0x46, 0, 3 << 12);
3284
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003285 if (!spec->no_shutup_pins)
3286 snd_hda_codec_write(codec, hp_pin, 0,
3287 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
Kailang Yang4a219ef2017-06-16 16:54:35 +08003288
Kailang Yang6447c962019-05-08 16:27:03 +08003289 if (hp_pin_sense || spec->ultra_low_power)
Kailang Yang4a219ef2017-06-16 16:54:35 +08003290 msleep(100);
3291
3292 alc_auto_setup_eapd(codec, false);
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003293 alc_shutup_pins(codec);
Kailang Yang6447c962019-05-08 16:27:03 +08003294 if (spec->ultra_low_power) {
3295 msleep(50);
3296 alc_update_coef_idx(codec, 0x03, 1<<1, 0);
3297 alc_update_coef_idx(codec, 0x08, 7<<4, 7<<4);
3298 alc_update_coef_idx(codec, 0x08, 3<<2, 0);
3299 alc_update_coef_idx(codec, 0x3b, 1<<15, 1<<15);
3300 alc_update_coef_idx(codec, 0x0e, 7<<6, 0);
3301 msleep(30);
3302 }
Kailang Yang4a219ef2017-06-16 16:54:35 +08003303}
3304
Kailang Yangda911b12018-01-05 16:50:08 +08003305static void alc225_init(struct hda_codec *codec)
3306{
3307 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003308 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yangda911b12018-01-05 16:50:08 +08003309 bool hp1_pin_sense, hp2_pin_sense;
3310
3311 if (!hp_pin)
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003312 hp_pin = 0x21;
Kailang Yangda911b12018-01-05 16:50:08 +08003313 msleep(30);
3314
3315 hp1_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3316 hp2_pin_sense = snd_hda_jack_detect(codec, 0x16);
3317
3318 if (hp1_pin_sense || hp2_pin_sense)
3319 msleep(2);
3320
3321 alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003322 if (spec->ultra_low_power) {
3323 alc_update_coef_idx(codec, 0x08, 0x0f << 2, 3<<2);
3324 alc_update_coef_idx(codec, 0x0e, 7<<6, 7<<6);
3325 alc_update_coef_idx(codec, 0x33, 1<<11, 0);
3326 msleep(30);
3327 }
Kailang Yangda911b12018-01-05 16:50:08 +08003328
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003329 if (hp1_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003330 snd_hda_codec_write(codec, hp_pin, 0,
3331 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3332 if (hp2_pin_sense)
3333 snd_hda_codec_write(codec, 0x16, 0,
3334 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3335
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003336 if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003337 msleep(85);
3338
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003339 if (hp1_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003340 snd_hda_codec_write(codec, hp_pin, 0,
3341 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3342 if (hp2_pin_sense)
3343 snd_hda_codec_write(codec, 0x16, 0,
3344 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3345
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003346 if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003347 msleep(100);
3348
3349 alc_update_coef_idx(codec, 0x4a, 3 << 10, 0);
3350 alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x4); /* Hight power */
3351}
3352
3353static void alc225_shutup(struct hda_codec *codec)
3354{
3355 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003356 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yangda911b12018-01-05 16:50:08 +08003357 bool hp1_pin_sense, hp2_pin_sense;
3358
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003359 if (!hp_pin)
3360 hp_pin = 0x21;
Kailang Yangda911b12018-01-05 16:50:08 +08003361 /* 3k pull low control for Headset jack. */
3362 alc_update_coef_idx(codec, 0x4a, 0, 3 << 10);
3363
3364 hp1_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3365 hp2_pin_sense = snd_hda_jack_detect(codec, 0x16);
3366
3367 if (hp1_pin_sense || hp2_pin_sense)
3368 msleep(2);
3369
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003370 if (hp1_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003371 snd_hda_codec_write(codec, hp_pin, 0,
3372 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3373 if (hp2_pin_sense)
3374 snd_hda_codec_write(codec, 0x16, 0,
3375 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3376
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003377 if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003378 msleep(85);
3379
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003380 if (hp1_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003381 snd_hda_codec_write(codec, hp_pin, 0,
3382 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
3383 if (hp2_pin_sense)
3384 snd_hda_codec_write(codec, 0x16, 0,
3385 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
3386
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003387 if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003388 msleep(100);
3389
3390 alc_auto_setup_eapd(codec, false);
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003391 alc_shutup_pins(codec);
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003392 if (spec->ultra_low_power) {
3393 msleep(50);
3394 alc_update_coef_idx(codec, 0x08, 0x0f << 2, 0x0c << 2);
3395 alc_update_coef_idx(codec, 0x0e, 7<<6, 0);
3396 alc_update_coef_idx(codec, 0x33, 1<<11, 1<<11);
3397 alc_update_coef_idx(codec, 0x4a, 3<<4, 2<<4);
3398 msleep(30);
3399 }
Kailang Yangda911b12018-01-05 16:50:08 +08003400}
3401
Kailang Yangc2d6af52017-06-21 14:50:54 +08003402static void alc_default_init(struct hda_codec *codec)
3403{
3404 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003405 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yangc2d6af52017-06-21 14:50:54 +08003406 bool hp_pin_sense;
3407
3408 if (!hp_pin)
3409 return;
3410
3411 msleep(30);
3412
3413 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3414
3415 if (hp_pin_sense)
3416 msleep(2);
3417
3418 snd_hda_codec_write(codec, hp_pin, 0,
3419 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3420
3421 if (hp_pin_sense)
3422 msleep(85);
3423
3424 snd_hda_codec_write(codec, hp_pin, 0,
3425 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3426
3427 if (hp_pin_sense)
3428 msleep(100);
3429}
3430
3431static void alc_default_shutup(struct hda_codec *codec)
3432{
3433 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003434 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yangc2d6af52017-06-21 14:50:54 +08003435 bool hp_pin_sense;
3436
3437 if (!hp_pin) {
3438 alc269_shutup(codec);
3439 return;
3440 }
3441
3442 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3443
3444 if (hp_pin_sense)
3445 msleep(2);
3446
3447 snd_hda_codec_write(codec, hp_pin, 0,
3448 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3449
3450 if (hp_pin_sense)
3451 msleep(85);
3452
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003453 if (!spec->no_shutup_pins)
3454 snd_hda_codec_write(codec, hp_pin, 0,
3455 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
Kailang Yangc2d6af52017-06-21 14:50:54 +08003456
3457 if (hp_pin_sense)
3458 msleep(100);
3459
3460 alc_auto_setup_eapd(codec, false);
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003461 alc_shutup_pins(codec);
Kailang Yangc2d6af52017-06-21 14:50:54 +08003462}
3463
Kailang Yang693abe12019-01-29 15:38:21 +08003464static void alc294_hp_init(struct hda_codec *codec)
3465{
3466 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003467 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang693abe12019-01-29 15:38:21 +08003468 int i, val;
3469
3470 if (!hp_pin)
3471 return;
3472
3473 snd_hda_codec_write(codec, hp_pin, 0,
3474 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3475
3476 msleep(100);
3477
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003478 if (!spec->no_shutup_pins)
3479 snd_hda_codec_write(codec, hp_pin, 0,
3480 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
Kailang Yang693abe12019-01-29 15:38:21 +08003481
3482 alc_update_coef_idx(codec, 0x6f, 0x000f, 0);/* Set HP depop to manual mode */
3483 alc_update_coefex_idx(codec, 0x58, 0x00, 0x8000, 0x8000); /* HP depop procedure start */
3484
3485 /* Wait for depop procedure finish */
3486 val = alc_read_coefex_idx(codec, 0x58, 0x01);
3487 for (i = 0; i < 20 && val & 0x0080; i++) {
3488 msleep(50);
3489 val = alc_read_coefex_idx(codec, 0x58, 0x01);
3490 }
3491 /* Set HP depop to auto mode */
3492 alc_update_coef_idx(codec, 0x6f, 0x000f, 0x000b);
3493 msleep(50);
3494}
3495
3496static void alc294_init(struct hda_codec *codec)
3497{
3498 struct alc_spec *spec = codec->spec;
3499
Takashi Iwaif6ef4e02019-01-29 14:14:51 +01003500 /* required only at boot or S4 resume time */
3501 if (!spec->done_hp_init ||
3502 codec->core.dev.power.power_state.event == PM_EVENT_RESTORE) {
Kailang Yang693abe12019-01-29 15:38:21 +08003503 alc294_hp_init(codec);
3504 spec->done_hp_init = true;
3505 }
3506 alc_default_init(codec);
3507}
3508
Kailang Yangad60d502013-06-28 12:03:01 +02003509static void alc5505_coef_set(struct hda_codec *codec, unsigned int index_reg,
3510 unsigned int val)
3511{
3512 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_COEF_INDEX, index_reg >> 1);
3513 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_PROC_COEF, val & 0xffff); /* LSB */
3514 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_PROC_COEF, val >> 16); /* MSB */
3515}
3516
3517static int alc5505_coef_get(struct hda_codec *codec, unsigned int index_reg)
3518{
3519 unsigned int val;
3520
3521 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_COEF_INDEX, index_reg >> 1);
3522 val = snd_hda_codec_read(codec, 0x51, 0, AC_VERB_GET_PROC_COEF, 0)
3523 & 0xffff;
3524 val |= snd_hda_codec_read(codec, 0x51, 0, AC_VERB_GET_PROC_COEF, 0)
3525 << 16;
3526 return val;
3527}
3528
3529static void alc5505_dsp_halt(struct hda_codec *codec)
3530{
3531 unsigned int val;
3532
3533 alc5505_coef_set(codec, 0x3000, 0x000c); /* DSP CPU stop */
3534 alc5505_coef_set(codec, 0x880c, 0x0008); /* DDR enter self refresh */
3535 alc5505_coef_set(codec, 0x61c0, 0x11110080); /* Clock control for PLL and CPU */
3536 alc5505_coef_set(codec, 0x6230, 0xfc0d4011); /* Disable Input OP */
3537 alc5505_coef_set(codec, 0x61b4, 0x040a2b03); /* Stop PLL2 */
3538 alc5505_coef_set(codec, 0x61b0, 0x00005b17); /* Stop PLL1 */
3539 alc5505_coef_set(codec, 0x61b8, 0x04133303); /* Stop PLL3 */
3540 val = alc5505_coef_get(codec, 0x6220);
3541 alc5505_coef_set(codec, 0x6220, (val | 0x3000)); /* switch Ringbuffer clock to DBUS clock */
3542}
3543
3544static void alc5505_dsp_back_from_halt(struct hda_codec *codec)
3545{
3546 alc5505_coef_set(codec, 0x61b8, 0x04133302);
3547 alc5505_coef_set(codec, 0x61b0, 0x00005b16);
3548 alc5505_coef_set(codec, 0x61b4, 0x040a2b02);
3549 alc5505_coef_set(codec, 0x6230, 0xf80d4011);
3550 alc5505_coef_set(codec, 0x6220, 0x2002010f);
3551 alc5505_coef_set(codec, 0x880c, 0x00000004);
3552}
3553
3554static void alc5505_dsp_init(struct hda_codec *codec)
3555{
3556 unsigned int val;
3557
3558 alc5505_dsp_halt(codec);
3559 alc5505_dsp_back_from_halt(codec);
3560 alc5505_coef_set(codec, 0x61b0, 0x5b14); /* PLL1 control */
3561 alc5505_coef_set(codec, 0x61b0, 0x5b16);
3562 alc5505_coef_set(codec, 0x61b4, 0x04132b00); /* PLL2 control */
3563 alc5505_coef_set(codec, 0x61b4, 0x04132b02);
3564 alc5505_coef_set(codec, 0x61b8, 0x041f3300); /* PLL3 control*/
3565 alc5505_coef_set(codec, 0x61b8, 0x041f3302);
3566 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_CODEC_RESET, 0); /* Function reset */
3567 alc5505_coef_set(codec, 0x61b8, 0x041b3302);
3568 alc5505_coef_set(codec, 0x61b8, 0x04173302);
3569 alc5505_coef_set(codec, 0x61b8, 0x04163302);
3570 alc5505_coef_set(codec, 0x8800, 0x348b328b); /* DRAM control */
3571 alc5505_coef_set(codec, 0x8808, 0x00020022); /* DRAM control */
3572 alc5505_coef_set(codec, 0x8818, 0x00000400); /* DRAM control */
3573
3574 val = alc5505_coef_get(codec, 0x6200) >> 16; /* Read revision ID */
3575 if (val <= 3)
3576 alc5505_coef_set(codec, 0x6220, 0x2002010f); /* I/O PAD Configuration */
3577 else
3578 alc5505_coef_set(codec, 0x6220, 0x6002018f);
3579
3580 alc5505_coef_set(codec, 0x61ac, 0x055525f0); /**/
3581 alc5505_coef_set(codec, 0x61c0, 0x12230080); /* Clock control */
3582 alc5505_coef_set(codec, 0x61b4, 0x040e2b02); /* PLL2 control */
3583 alc5505_coef_set(codec, 0x61bc, 0x010234f8); /* OSC Control */
3584 alc5505_coef_set(codec, 0x880c, 0x00000004); /* DRAM Function control */
3585 alc5505_coef_set(codec, 0x880c, 0x00000003);
3586 alc5505_coef_set(codec, 0x880c, 0x00000010);
Takashi Iwaicd63a5f2013-07-05 12:13:59 +02003587
3588#ifdef HALT_REALTEK_ALC5505
3589 alc5505_dsp_halt(codec);
3590#endif
Kailang Yangad60d502013-06-28 12:03:01 +02003591}
3592
Takashi Iwaicd63a5f2013-07-05 12:13:59 +02003593#ifdef HALT_REALTEK_ALC5505
3594#define alc5505_dsp_suspend(codec) /* NOP */
3595#define alc5505_dsp_resume(codec) /* NOP */
3596#else
3597#define alc5505_dsp_suspend(codec) alc5505_dsp_halt(codec)
3598#define alc5505_dsp_resume(codec) alc5505_dsp_back_from_halt(codec)
3599#endif
3600
Takashi Iwai2a439522011-07-26 09:52:50 +02003601#ifdef CONFIG_PM
Kailang Yangad60d502013-06-28 12:03:01 +02003602static int alc269_suspend(struct hda_codec *codec)
3603{
3604 struct alc_spec *spec = codec->spec;
3605
3606 if (spec->has_alc5505_dsp)
Takashi Iwaicd63a5f2013-07-05 12:13:59 +02003607 alc5505_dsp_suspend(codec);
Kailang Yangad60d502013-06-28 12:03:01 +02003608 return alc_suspend(codec);
3609}
3610
Takashi Iwai1d045db2011-07-07 18:23:21 +02003611static int alc269_resume(struct hda_codec *codec)
3612{
Kailang Yangadcc70b2012-05-25 08:08:38 +02003613 struct alc_spec *spec = codec->spec;
3614
Kailang Yang1387e2d2012-11-08 10:23:18 +01003615 if (spec->codec_variant == ALC269_TYPE_ALC269VB)
3616 alc269vb_toggle_power_output(codec, 0);
3617 if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
Kailang Yangadcc70b2012-05-25 08:08:38 +02003618 (alc_get_coef0(codec) & 0x00ff) == 0x018) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02003619 msleep(150);
3620 }
3621
3622 codec->patch_ops.init(codec);
3623
Kailang Yang1387e2d2012-11-08 10:23:18 +01003624 if (spec->codec_variant == ALC269_TYPE_ALC269VB)
3625 alc269vb_toggle_power_output(codec, 1);
3626 if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
Kailang Yangadcc70b2012-05-25 08:08:38 +02003627 (alc_get_coef0(codec) & 0x00ff) == 0x017) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02003628 msleep(200);
3629 }
3630
Takashi Iwaieeecd9d2015-02-25 15:18:50 +01003631 regcache_sync(codec->core.regmap);
Takashi Iwai1d045db2011-07-07 18:23:21 +02003632 hda_call_check_power_status(codec, 0x01);
Hui Wangf4753712014-08-19 12:07:03 +08003633
3634 /* on some machine, the BIOS will clear the codec gpio data when enter
3635 * suspend, and won't restore the data after resume, so we restore it
3636 * in the driver.
3637 */
Takashi Iwaid261eec2018-06-19 22:32:29 +02003638 if (spec->gpio_data)
3639 alc_write_gpio_data(codec);
Hui Wangf4753712014-08-19 12:07:03 +08003640
Kailang Yangad60d502013-06-28 12:03:01 +02003641 if (spec->has_alc5505_dsp)
Takashi Iwaicd63a5f2013-07-05 12:13:59 +02003642 alc5505_dsp_resume(codec);
Kailang Yangc5177c82013-07-24 14:39:49 +02003643
Takashi Iwai1d045db2011-07-07 18:23:21 +02003644 return 0;
3645}
Takashi Iwai2a439522011-07-26 09:52:50 +02003646#endif /* CONFIG_PM */
Takashi Iwai1d045db2011-07-07 18:23:21 +02003647
David Henningsson108cc102012-07-20 10:37:25 +02003648static void alc269_fixup_pincfg_no_hp_to_lineout(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003649 const struct hda_fixup *fix, int action)
David Henningsson108cc102012-07-20 10:37:25 +02003650{
3651 struct alc_spec *spec = codec->spec;
3652
Takashi Iwai1727a772013-01-10 09:52:52 +01003653 if (action == HDA_FIXUP_ACT_PRE_PROBE)
David Henningsson108cc102012-07-20 10:37:25 +02003654 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
3655}
3656
Jan-Marek Glogowskifdcc9682018-02-14 11:29:15 +01003657static void alc269_fixup_pincfg_U7x7_headset_mic(struct hda_codec *codec,
3658 const struct hda_fixup *fix,
3659 int action)
3660{
3661 unsigned int cfg_headphone = snd_hda_codec_get_pincfg(codec, 0x21);
3662 unsigned int cfg_headset_mic = snd_hda_codec_get_pincfg(codec, 0x19);
3663
3664 if (cfg_headphone && cfg_headset_mic == 0x411111f0)
3665 snd_hda_codec_set_pincfg(codec, 0x19,
3666 (cfg_headphone & ~AC_DEFCFG_DEVICE) |
3667 (AC_JACK_MIC_IN << AC_DEFCFG_DEVICE_SHIFT));
3668}
3669
Takashi Iwai1d045db2011-07-07 18:23:21 +02003670static void alc269_fixup_hweq(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003671 const struct hda_fixup *fix, int action)
Takashi Iwai1d045db2011-07-07 18:23:21 +02003672{
Takashi Iwai98b24882014-08-18 13:47:50 +02003673 if (action == HDA_FIXUP_ACT_INIT)
3674 alc_update_coef_idx(codec, 0x1e, 0, 0x80);
Takashi Iwai1d045db2011-07-07 18:23:21 +02003675}
3676
David Henningsson7c478f02013-10-11 10:18:46 +02003677static void alc269_fixup_headset_mic(struct hda_codec *codec,
3678 const struct hda_fixup *fix, int action)
3679{
3680 struct alc_spec *spec = codec->spec;
3681
3682 if (action == HDA_FIXUP_ACT_PRE_PROBE)
3683 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
3684}
3685
Takashi Iwai1d045db2011-07-07 18:23:21 +02003686static void alc271_fixup_dmic(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003687 const struct hda_fixup *fix, int action)
Takashi Iwai1d045db2011-07-07 18:23:21 +02003688{
3689 static const struct hda_verb verbs[] = {
3690 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
3691 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
3692 {}
3693 };
3694 unsigned int cfg;
3695
Takashi Iwai7639a062015-03-03 10:07:24 +01003696 if (strcmp(codec->core.chip_name, "ALC271X") &&
3697 strcmp(codec->core.chip_name, "ALC269VB"))
Takashi Iwai1d045db2011-07-07 18:23:21 +02003698 return;
3699 cfg = snd_hda_codec_get_pincfg(codec, 0x12);
3700 if (get_defcfg_connect(cfg) == AC_JACK_PORT_FIXED)
3701 snd_hda_sequence_write(codec, verbs);
3702}
3703
Takashi Iwai017f2a12011-07-09 14:42:25 +02003704static void alc269_fixup_pcm_44k(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003705 const struct hda_fixup *fix, int action)
Takashi Iwai017f2a12011-07-09 14:42:25 +02003706{
3707 struct alc_spec *spec = codec->spec;
3708
Takashi Iwai1727a772013-01-10 09:52:52 +01003709 if (action != HDA_FIXUP_ACT_PROBE)
Takashi Iwai017f2a12011-07-09 14:42:25 +02003710 return;
3711
3712 /* Due to a hardware problem on Lenovo Ideadpad, we need to
3713 * fix the sample rate of analog I/O to 44.1kHz
3714 */
Takashi Iwai08c189f2012-12-19 15:22:24 +01003715 spec->gen.stream_analog_playback = &alc269_44k_pcm_analog_playback;
3716 spec->gen.stream_analog_capture = &alc269_44k_pcm_analog_capture;
Takashi Iwai017f2a12011-07-09 14:42:25 +02003717}
3718
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02003719static void alc269_fixup_stereo_dmic(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003720 const struct hda_fixup *fix, int action)
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02003721{
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02003722 /* The digital-mic unit sends PDM (differential signal) instead of
3723 * the standard PCM, thus you can't record a valid mono stream as is.
3724 * Below is a workaround specific to ALC269 to control the dmic
3725 * signal source as mono.
3726 */
Takashi Iwai98b24882014-08-18 13:47:50 +02003727 if (action == HDA_FIXUP_ACT_INIT)
3728 alc_update_coef_idx(codec, 0x07, 0, 0x80);
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02003729}
3730
Takashi Iwai24519912011-08-16 15:08:49 +02003731static void alc269_quanta_automute(struct hda_codec *codec)
3732{
Takashi Iwai08c189f2012-12-19 15:22:24 +01003733 snd_hda_gen_update_outputs(codec);
Takashi Iwai24519912011-08-16 15:08:49 +02003734
Takashi Iwai1687ccc2014-08-18 13:49:35 +02003735 alc_write_coef_idx(codec, 0x0c, 0x680);
3736 alc_write_coef_idx(codec, 0x0c, 0x480);
Takashi Iwai24519912011-08-16 15:08:49 +02003737}
3738
3739static void alc269_fixup_quanta_mute(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003740 const struct hda_fixup *fix, int action)
Takashi Iwai24519912011-08-16 15:08:49 +02003741{
3742 struct alc_spec *spec = codec->spec;
Takashi Iwai1727a772013-01-10 09:52:52 +01003743 if (action != HDA_FIXUP_ACT_PROBE)
Takashi Iwai24519912011-08-16 15:08:49 +02003744 return;
Takashi Iwai08c189f2012-12-19 15:22:24 +01003745 spec->gen.automute_hook = alc269_quanta_automute;
Takashi Iwai24519912011-08-16 15:08:49 +02003746}
3747
David Henningssond240d1d2013-04-15 12:50:02 +02003748static void alc269_x101_hp_automute_hook(struct hda_codec *codec,
Takashi Iwai1a4f69d2014-09-11 15:22:46 +02003749 struct hda_jack_callback *jack)
David Henningssond240d1d2013-04-15 12:50:02 +02003750{
3751 struct alc_spec *spec = codec->spec;
3752 int vref;
3753 msleep(200);
3754 snd_hda_gen_hp_automute(codec, jack);
3755
3756 vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0;
3757 msleep(100);
3758 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3759 vref);
3760 msleep(500);
3761 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3762 vref);
3763}
3764
3765static void alc269_fixup_x101_headset_mic(struct hda_codec *codec,
3766 const struct hda_fixup *fix, int action)
3767{
3768 struct alc_spec *spec = codec->spec;
3769 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3770 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
3771 spec->gen.hp_automute_hook = alc269_x101_hp_automute_hook;
3772 }
3773}
3774
3775
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003776/* update mute-LED according to the speaker mute state via mic VREF pin */
3777static void alc269_fixup_mic_mute_hook(void *private_data, int enabled)
David Henningsson6d3cd5d2013-01-07 12:03:47 +01003778{
3779 struct hda_codec *codec = private_data;
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003780 struct alc_spec *spec = codec->spec;
3781 unsigned int pinval;
3782
3783 if (spec->mute_led_polarity)
3784 enabled = !enabled;
Takashi Iwai415d5552014-04-03 11:51:21 +02003785 pinval = snd_hda_codec_get_pin_target(codec, spec->mute_led_nid);
3786 pinval &= ~AC_PINCTL_VREFEN;
3787 pinval |= enabled ? AC_PINCTL_VREF_HIZ : AC_PINCTL_VREF_80;
Takashi Iwaie40bdb02018-03-17 22:40:18 +01003788 if (spec->mute_led_nid) {
3789 /* temporarily power up/down for setting VREF */
3790 snd_hda_power_up_pm(codec);
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003791 snd_hda_set_pin_ctl_cache(codec, spec->mute_led_nid, pinval);
Takashi Iwaie40bdb02018-03-17 22:40:18 +01003792 snd_hda_power_down_pm(codec);
3793 }
David Henningsson6d3cd5d2013-01-07 12:03:47 +01003794}
3795
David Henningssond5b6b652013-11-06 10:50:44 +01003796/* Make sure the led works even in runtime suspend */
3797static unsigned int led_power_filter(struct hda_codec *codec,
3798 hda_nid_t nid,
3799 unsigned int power_state)
3800{
3801 struct alc_spec *spec = codec->spec;
3802
Hui Wang50dd9052014-07-08 17:56:15 +08003803 if (power_state != AC_PWRST_D3 || nid == 0 ||
3804 (nid != spec->mute_led_nid && nid != spec->cap_mute_led_nid))
David Henningssond5b6b652013-11-06 10:50:44 +01003805 return power_state;
3806
3807 /* Set pin ctl again, it might have just been set to 0 */
3808 snd_hda_set_pin_ctl(codec, nid,
3809 snd_hda_codec_get_pin_target(codec, nid));
3810
Takashi Iwaicffd3962015-04-09 10:30:25 +02003811 return snd_hda_gen_path_power_filter(codec, nid, power_state);
David Henningssond5b6b652013-11-06 10:50:44 +01003812}
3813
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003814static void alc269_fixup_hp_mute_led(struct hda_codec *codec,
3815 const struct hda_fixup *fix, int action)
David Henningsson6d3cd5d2013-01-07 12:03:47 +01003816{
3817 struct alc_spec *spec = codec->spec;
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003818 const struct dmi_device *dev = NULL;
3819
3820 if (action != HDA_FIXUP_ACT_PRE_PROBE)
3821 return;
3822
3823 while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) {
3824 int pol, pin;
3825 if (sscanf(dev->name, "HP_Mute_LED_%d_%x", &pol, &pin) != 2)
3826 continue;
3827 if (pin < 0x0a || pin >= 0x10)
3828 break;
3829 spec->mute_led_polarity = pol;
3830 spec->mute_led_nid = pin - 0x0a + 0x18;
3831 spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook;
Takashi Iwaifd25a972012-12-20 14:57:18 +01003832 spec->gen.vmaster_mute_enum = 1;
David Henningssond5b6b652013-11-06 10:50:44 +01003833 codec->power_filter = led_power_filter;
Takashi Iwai4e76a882014-02-25 12:21:03 +01003834 codec_dbg(codec,
3835 "Detected mute LED for %x:%d\n", spec->mute_led_nid,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003836 spec->mute_led_polarity);
David Henningsson6d3cd5d2013-01-07 12:03:47 +01003837 break;
3838 }
3839}
3840
Takashi Iwai85c467d2018-05-29 11:38:38 +02003841static void alc269_fixup_hp_mute_led_micx(struct hda_codec *codec,
3842 const struct hda_fixup *fix,
3843 int action, hda_nid_t pin)
David Henningssond06ac142013-02-18 11:41:55 +01003844{
3845 struct alc_spec *spec = codec->spec;
Takashi Iwai85c467d2018-05-29 11:38:38 +02003846
David Henningssond06ac142013-02-18 11:41:55 +01003847 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3848 spec->mute_led_polarity = 0;
Takashi Iwai85c467d2018-05-29 11:38:38 +02003849 spec->mute_led_nid = pin;
David Henningssond06ac142013-02-18 11:41:55 +01003850 spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook;
3851 spec->gen.vmaster_mute_enum = 1;
David Henningssond5b6b652013-11-06 10:50:44 +01003852 codec->power_filter = led_power_filter;
David Henningssond06ac142013-02-18 11:41:55 +01003853 }
3854}
3855
Takashi Iwai85c467d2018-05-29 11:38:38 +02003856static void alc269_fixup_hp_mute_led_mic1(struct hda_codec *codec,
3857 const struct hda_fixup *fix, int action)
3858{
3859 alc269_fixup_hp_mute_led_micx(codec, fix, action, 0x18);
3860}
3861
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003862static void alc269_fixup_hp_mute_led_mic2(struct hda_codec *codec,
3863 const struct hda_fixup *fix, int action)
Takashi Iwai420b0fe2012-03-12 12:35:27 +01003864{
Takashi Iwai85c467d2018-05-29 11:38:38 +02003865 alc269_fixup_hp_mute_led_micx(codec, fix, action, 0x19);
Takashi Iwai420b0fe2012-03-12 12:35:27 +01003866}
3867
Tom Briden7f783bd2017-03-25 10:12:01 +00003868static void alc269_fixup_hp_mute_led_mic3(struct hda_codec *codec,
3869 const struct hda_fixup *fix, int action)
3870{
Takashi Iwai85c467d2018-05-29 11:38:38 +02003871 alc269_fixup_hp_mute_led_micx(codec, fix, action, 0x1b);
Tom Briden7f783bd2017-03-25 10:12:01 +00003872}
3873
Takashi Iwai0f32fd192014-11-19 12:16:14 +01003874/* update LED status via GPIO */
3875static void alc_update_gpio_led(struct hda_codec *codec, unsigned int mask,
3876 bool enabled)
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003877{
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003878 struct alc_spec *spec = codec->spec;
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003879
Takashi Iwai0f32fd192014-11-19 12:16:14 +01003880 if (spec->mute_led_polarity)
3881 enabled = !enabled;
Takashi Iwaid261eec2018-06-19 22:32:29 +02003882 alc_update_gpio_data(codec, mask, !enabled); /* muted -> LED on */
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003883}
3884
Takashi Iwai0f32fd192014-11-19 12:16:14 +01003885/* turn on/off mute LED via GPIO per vmaster hook */
3886static void alc_fixup_gpio_mute_hook(void *private_data, int enabled)
3887{
3888 struct hda_codec *codec = private_data;
3889 struct alc_spec *spec = codec->spec;
3890
3891 alc_update_gpio_led(codec, spec->gpio_mute_led_mask, enabled);
3892}
3893
3894/* turn on/off mic-mute LED via GPIO per capture hook */
Takashi Iwaid03abec2018-06-19 12:29:13 +02003895static void alc_gpio_micmute_update(struct hda_codec *codec)
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003896{
3897 struct alc_spec *spec = codec->spec;
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003898
Takashi Iwaid03abec2018-06-19 12:29:13 +02003899 alc_update_gpio_led(codec, spec->gpio_mic_led_mask,
3900 spec->gen.micmute_led.led_value);
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003901}
3902
Takashi Iwai01e4a272018-06-19 22:47:30 +02003903/* setup mute and mic-mute GPIO bits, add hooks appropriately */
3904static void alc_fixup_hp_gpio_led(struct hda_codec *codec,
3905 int action,
3906 unsigned int mute_mask,
3907 unsigned int micmute_mask)
3908{
3909 struct alc_spec *spec = codec->spec;
3910
3911 alc_fixup_gpio(codec, action, mute_mask | micmute_mask);
3912
3913 if (action != HDA_FIXUP_ACT_PRE_PROBE)
3914 return;
3915 if (mute_mask) {
3916 spec->gpio_mute_led_mask = mute_mask;
3917 spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook;
3918 }
3919 if (micmute_mask) {
3920 spec->gpio_mic_led_mask = micmute_mask;
3921 snd_hda_gen_add_micmute_led(codec, alc_gpio_micmute_update);
3922 }
3923}
3924
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003925static void alc269_fixup_hp_gpio_led(struct hda_codec *codec,
3926 const struct hda_fixup *fix, int action)
3927{
Takashi Iwai01e4a272018-06-19 22:47:30 +02003928 alc_fixup_hp_gpio_led(codec, action, 0x08, 0x10);
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003929}
3930
Kailang Yangeaa8e5e2014-11-21 15:49:11 +08003931static void alc286_fixup_hp_gpio_led(struct hda_codec *codec,
3932 const struct hda_fixup *fix, int action)
3933{
Takashi Iwai01e4a272018-06-19 22:47:30 +02003934 alc_fixup_hp_gpio_led(codec, action, 0x02, 0x20);
Takashi Iwai1d045db2011-07-07 18:23:21 +02003935}
3936
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08003937/* turn on/off mic-mute LED per capture hook */
Takashi Iwaid03abec2018-06-19 12:29:13 +02003938static void alc_cap_micmute_update(struct hda_codec *codec)
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08003939{
3940 struct alc_spec *spec = codec->spec;
Takashi Iwaid03abec2018-06-19 12:29:13 +02003941 unsigned int pinval;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08003942
Takashi Iwaid03abec2018-06-19 12:29:13 +02003943 if (!spec->cap_mute_led_nid)
3944 return;
Hui Wangfc1fad92014-07-08 17:56:14 +08003945 pinval = snd_hda_codec_get_pin_target(codec, spec->cap_mute_led_nid);
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08003946 pinval &= ~AC_PINCTL_VREFEN;
Takashi Iwaid03abec2018-06-19 12:29:13 +02003947 if (spec->gen.micmute_led.led_value)
3948 pinval |= AC_PINCTL_VREF_80;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08003949 else
Takashi Iwaid03abec2018-06-19 12:29:13 +02003950 pinval |= AC_PINCTL_VREF_HIZ;
3951 snd_hda_set_pin_ctl_cache(codec, spec->cap_mute_led_nid, pinval);
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08003952}
3953
3954static void alc269_fixup_hp_gpio_mic1_led(struct hda_codec *codec,
3955 const struct hda_fixup *fix, int action)
3956{
3957 struct alc_spec *spec = codec->spec;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08003958
Takashi Iwai01e4a272018-06-19 22:47:30 +02003959 alc_fixup_hp_gpio_led(codec, action, 0x08, 0);
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08003960 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai01e4a272018-06-19 22:47:30 +02003961 /* Like hp_gpio_mic1_led, but also needs GPIO4 low to
3962 * enable headphone amp
3963 */
3964 spec->gpio_mask |= 0x10;
3965 spec->gpio_dir |= 0x10;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08003966 spec->cap_mute_led_nid = 0x18;
Takashi Iwaid03abec2018-06-19 12:29:13 +02003967 snd_hda_gen_add_micmute_led(codec, alc_cap_micmute_update);
Hui Wang50dd9052014-07-08 17:56:15 +08003968 codec->power_filter = led_power_filter;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08003969 }
3970}
3971
David Henningsson7a5255f2014-10-30 08:26:01 +01003972static void alc280_fixup_hp_gpio4(struct hda_codec *codec,
3973 const struct hda_fixup *fix, int action)
3974{
David Henningsson7a5255f2014-10-30 08:26:01 +01003975 struct alc_spec *spec = codec->spec;
David Henningsson7a5255f2014-10-30 08:26:01 +01003976
Takashi Iwai01e4a272018-06-19 22:47:30 +02003977 alc_fixup_hp_gpio_led(codec, action, 0x08, 0);
David Henningsson7a5255f2014-10-30 08:26:01 +01003978 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
David Henningsson7a5255f2014-10-30 08:26:01 +01003979 spec->cap_mute_led_nid = 0x18;
Takashi Iwaid03abec2018-06-19 12:29:13 +02003980 snd_hda_gen_add_micmute_led(codec, alc_cap_micmute_update);
David Henningsson7a5255f2014-10-30 08:26:01 +01003981 codec->power_filter = led_power_filter;
3982 }
3983}
3984
Takashi Iwai6a30aba2018-04-27 17:17:35 +02003985#if IS_REACHABLE(CONFIG_INPUT)
David Henningsson33f4acd2015-01-07 15:50:13 +01003986static void gpio2_mic_hotkey_event(struct hda_codec *codec,
3987 struct hda_jack_callback *event)
3988{
3989 struct alc_spec *spec = codec->spec;
3990
3991 /* GPIO2 just toggles on a keypress/keyrelease cycle. Therefore
3992 send both key on and key off event for every interrupt. */
Hui Wangc7b60a82015-12-28 11:35:25 +08003993 input_report_key(spec->kb_dev, spec->alc_mute_keycode_map[ALC_KEY_MICMUTE_INDEX], 1);
David Henningsson33f4acd2015-01-07 15:50:13 +01003994 input_sync(spec->kb_dev);
Hui Wangc7b60a82015-12-28 11:35:25 +08003995 input_report_key(spec->kb_dev, spec->alc_mute_keycode_map[ALC_KEY_MICMUTE_INDEX], 0);
David Henningsson33f4acd2015-01-07 15:50:13 +01003996 input_sync(spec->kb_dev);
3997}
David Henningsson33f4acd2015-01-07 15:50:13 +01003998
Kailang3694cb22015-12-28 11:35:24 +08003999static int alc_register_micmute_input_device(struct hda_codec *codec)
4000{
4001 struct alc_spec *spec = codec->spec;
Hui Wangc7b60a82015-12-28 11:35:25 +08004002 int i;
Kailang3694cb22015-12-28 11:35:24 +08004003
4004 spec->kb_dev = input_allocate_device();
4005 if (!spec->kb_dev) {
4006 codec_err(codec, "Out of memory (input_allocate_device)\n");
4007 return -ENOMEM;
4008 }
Hui Wangc7b60a82015-12-28 11:35:25 +08004009
4010 spec->alc_mute_keycode_map[ALC_KEY_MICMUTE_INDEX] = KEY_MICMUTE;
4011
Kailang3694cb22015-12-28 11:35:24 +08004012 spec->kb_dev->name = "Microphone Mute Button";
4013 spec->kb_dev->evbit[0] = BIT_MASK(EV_KEY);
Hui Wangc7b60a82015-12-28 11:35:25 +08004014 spec->kb_dev->keycodesize = sizeof(spec->alc_mute_keycode_map[0]);
4015 spec->kb_dev->keycodemax = ARRAY_SIZE(spec->alc_mute_keycode_map);
4016 spec->kb_dev->keycode = spec->alc_mute_keycode_map;
4017 for (i = 0; i < ARRAY_SIZE(spec->alc_mute_keycode_map); i++)
4018 set_bit(spec->alc_mute_keycode_map[i], spec->kb_dev->keybit);
Kailang3694cb22015-12-28 11:35:24 +08004019
4020 if (input_register_device(spec->kb_dev)) {
4021 codec_err(codec, "input_register_device failed\n");
4022 input_free_device(spec->kb_dev);
4023 spec->kb_dev = NULL;
4024 return -ENOMEM;
4025 }
4026
4027 return 0;
4028}
4029
Takashi Iwai01e4a272018-06-19 22:47:30 +02004030/* GPIO1 = set according to SKU external amp
4031 * GPIO2 = mic mute hotkey
4032 * GPIO3 = mute LED
4033 * GPIO4 = mic mute LED
4034 */
David Henningsson33f4acd2015-01-07 15:50:13 +01004035static void alc280_fixup_hp_gpio2_mic_hotkey(struct hda_codec *codec,
4036 const struct hda_fixup *fix, int action)
4037{
David Henningsson33f4acd2015-01-07 15:50:13 +01004038 struct alc_spec *spec = codec->spec;
4039
Takashi Iwai01e4a272018-06-19 22:47:30 +02004040 alc_fixup_hp_gpio_led(codec, action, 0x08, 0x10);
David Henningsson33f4acd2015-01-07 15:50:13 +01004041 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai1c76aa52018-06-21 16:37:54 +02004042 spec->init_amp = ALC_INIT_DEFAULT;
Kailang3694cb22015-12-28 11:35:24 +08004043 if (alc_register_micmute_input_device(codec) != 0)
David Henningsson33f4acd2015-01-07 15:50:13 +01004044 return;
David Henningsson33f4acd2015-01-07 15:50:13 +01004045
Takashi Iwai01e4a272018-06-19 22:47:30 +02004046 spec->gpio_mask |= 0x06;
4047 spec->gpio_dir |= 0x02;
4048 spec->gpio_data |= 0x02;
Takashi Iwai7639a062015-03-03 10:07:24 +01004049 snd_hda_codec_write_cache(codec, codec->core.afg, 0,
David Henningsson33f4acd2015-01-07 15:50:13 +01004050 AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x04);
Takashi Iwai7639a062015-03-03 10:07:24 +01004051 snd_hda_jack_detect_enable_callback(codec, codec->core.afg,
David Henningsson33f4acd2015-01-07 15:50:13 +01004052 gpio2_mic_hotkey_event);
David Henningsson33f4acd2015-01-07 15:50:13 +01004053 return;
4054 }
4055
4056 if (!spec->kb_dev)
4057 return;
4058
4059 switch (action) {
David Henningsson33f4acd2015-01-07 15:50:13 +01004060 case HDA_FIXUP_ACT_FREE:
4061 input_unregister_device(spec->kb_dev);
David Henningsson33f4acd2015-01-07 15:50:13 +01004062 spec->kb_dev = NULL;
4063 }
David Henningsson33f4acd2015-01-07 15:50:13 +01004064}
4065
Takashi Iwai01e4a272018-06-19 22:47:30 +02004066/* Line2 = mic mute hotkey
4067 * GPIO2 = mic mute LED
4068 */
Kailang3694cb22015-12-28 11:35:24 +08004069static void alc233_fixup_lenovo_line2_mic_hotkey(struct hda_codec *codec,
4070 const struct hda_fixup *fix, int action)
4071{
Kailang3694cb22015-12-28 11:35:24 +08004072 struct alc_spec *spec = codec->spec;
4073
Takashi Iwai01e4a272018-06-19 22:47:30 +02004074 alc_fixup_hp_gpio_led(codec, action, 0, 0x04);
Kailang3694cb22015-12-28 11:35:24 +08004075 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai1c76aa52018-06-21 16:37:54 +02004076 spec->init_amp = ALC_INIT_DEFAULT;
Kailang3694cb22015-12-28 11:35:24 +08004077 if (alc_register_micmute_input_device(codec) != 0)
4078 return;
4079
Kailang3694cb22015-12-28 11:35:24 +08004080 snd_hda_jack_detect_enable_callback(codec, 0x1b,
4081 gpio2_mic_hotkey_event);
Kailang3694cb22015-12-28 11:35:24 +08004082 return;
4083 }
4084
4085 if (!spec->kb_dev)
4086 return;
4087
4088 switch (action) {
Kailang3694cb22015-12-28 11:35:24 +08004089 case HDA_FIXUP_ACT_FREE:
4090 input_unregister_device(spec->kb_dev);
4091 spec->kb_dev = NULL;
4092 }
4093}
Takashi Iwaic4696522018-01-15 10:44:35 +01004094#else /* INPUT */
4095#define alc280_fixup_hp_gpio2_mic_hotkey NULL
4096#define alc233_fixup_lenovo_line2_mic_hotkey NULL
4097#endif /* INPUT */
Kailang3694cb22015-12-28 11:35:24 +08004098
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004099static void alc269_fixup_hp_line1_mic1_led(struct hda_codec *codec,
4100 const struct hda_fixup *fix, int action)
4101{
4102 struct alc_spec *spec = codec->spec;
4103
Takashi Iwai1bce62a2018-06-19 23:15:59 +02004104 alc269_fixup_hp_mute_led_micx(codec, fix, action, 0x1a);
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004105 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004106 spec->cap_mute_led_nid = 0x18;
Takashi Iwaid03abec2018-06-19 12:29:13 +02004107 snd_hda_gen_add_micmute_led(codec, alc_cap_micmute_update);
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004108 }
4109}
4110
Kailang Yang5a367672017-07-21 15:23:53 +08004111static struct coef_fw alc225_pre_hsmode[] = {
4112 UPDATE_COEF(0x4a, 1<<8, 0),
4113 UPDATE_COEFEX(0x57, 0x05, 1<<14, 0),
4114 UPDATE_COEF(0x63, 3<<14, 3<<14),
4115 UPDATE_COEF(0x4a, 3<<4, 2<<4),
4116 UPDATE_COEF(0x4a, 3<<10, 3<<10),
4117 UPDATE_COEF(0x45, 0x3f<<10, 0x34<<10),
4118 UPDATE_COEF(0x4a, 3<<10, 0),
4119 {}
4120};
4121
David Henningsson73bdd592013-04-15 15:44:14 +02004122static void alc_headset_mode_unplugged(struct hda_codec *codec)
4123{
Takashi Iwai54db6c32014-08-18 15:11:19 +02004124 static struct coef_fw coef0255[] = {
Kailang Yang717f43d2019-05-31 17:16:53 +08004125 WRITE_COEF(0x1b, 0x0c0b), /* LDO and MISC control */
Takashi Iwai54db6c32014-08-18 15:11:19 +02004126 WRITE_COEF(0x45, 0xd089), /* UAJ function set to menual mode */
4127 UPDATE_COEFEX(0x57, 0x05, 1<<14, 0), /* Direct Drive HP Amp control(Set to verb control)*/
4128 WRITE_COEF(0x06, 0x6104), /* Set MIC2 Vref gate with HP */
4129 WRITE_COEFEX(0x57, 0x03, 0x8aa6), /* Direct Drive HP Amp control */
4130 {}
4131 };
Kailang Yange69e7e02016-05-30 15:58:28 +08004132 static struct coef_fw coef0256[] = {
4133 WRITE_COEF(0x1b, 0x0c4b), /* LDO and MISC control */
Kailang Yang717f43d2019-05-31 17:16:53 +08004134 WRITE_COEF(0x45, 0xd089), /* UAJ function set to menual mode */
4135 WRITE_COEF(0x06, 0x6104), /* Set MIC2 Vref gate with HP */
4136 WRITE_COEFEX(0x57, 0x03, 0x09a3), /* Direct Drive HP Amp control */
4137 UPDATE_COEFEX(0x57, 0x05, 1<<14, 0), /* Direct Drive HP Amp control(Set to verb control)*/
Kailang Yange69e7e02016-05-30 15:58:28 +08004138 {}
4139 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004140 static struct coef_fw coef0233[] = {
4141 WRITE_COEF(0x1b, 0x0c0b),
4142 WRITE_COEF(0x45, 0xc429),
4143 UPDATE_COEF(0x35, 0x4000, 0),
4144 WRITE_COEF(0x06, 0x2104),
4145 WRITE_COEF(0x1a, 0x0001),
4146 WRITE_COEF(0x26, 0x0004),
4147 WRITE_COEF(0x32, 0x42a3),
4148 {}
4149 };
Kailang Yangf3b70332015-04-08 15:01:17 +08004150 static struct coef_fw coef0288[] = {
4151 UPDATE_COEF(0x4f, 0xfcc0, 0xc400),
4152 UPDATE_COEF(0x50, 0x2000, 0x2000),
4153 UPDATE_COEF(0x56, 0x0006, 0x0006),
4154 UPDATE_COEF(0x66, 0x0008, 0),
4155 UPDATE_COEF(0x67, 0x2000, 0),
4156 {}
4157 };
Kailang Yang89542932017-07-17 15:03:43 +08004158 static struct coef_fw coef0298[] = {
4159 UPDATE_COEF(0x19, 0x1300, 0x0300),
4160 {}
4161 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004162 static struct coef_fw coef0292[] = {
4163 WRITE_COEF(0x76, 0x000e),
4164 WRITE_COEF(0x6c, 0x2400),
4165 WRITE_COEF(0x18, 0x7308),
4166 WRITE_COEF(0x6b, 0xc429),
4167 {}
4168 };
4169 static struct coef_fw coef0293[] = {
4170 UPDATE_COEF(0x10, 7<<8, 6<<8), /* SET Line1 JD to 0 */
4171 UPDATE_COEFEX(0x57, 0x05, 1<<15|1<<13, 0x0), /* SET charge pump by verb */
4172 UPDATE_COEFEX(0x57, 0x03, 1<<10, 1<<10), /* SET EN_OSW to 1 */
4173 UPDATE_COEF(0x1a, 1<<3, 1<<3), /* Combo JD gating with LINE1-VREFO */
4174 WRITE_COEF(0x45, 0xc429), /* Set to TRS type */
4175 UPDATE_COEF(0x4a, 0x000f, 0x000e), /* Combo Jack auto detect */
4176 {}
4177 };
4178 static struct coef_fw coef0668[] = {
4179 WRITE_COEF(0x15, 0x0d40),
4180 WRITE_COEF(0xb7, 0x802b),
4181 {}
4182 };
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004183 static struct coef_fw coef0225[] = {
Kailang Yang5a367672017-07-21 15:23:53 +08004184 UPDATE_COEF(0x63, 3<<14, 0),
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004185 {}
4186 };
Kailang Yang71683c32017-06-20 16:33:50 +08004187 static struct coef_fw coef0274[] = {
4188 UPDATE_COEF(0x4a, 0x0100, 0),
4189 UPDATE_COEFEX(0x57, 0x05, 0x4000, 0),
4190 UPDATE_COEF(0x6b, 0xf000, 0x5000),
4191 UPDATE_COEF(0x4a, 0x0010, 0),
4192 UPDATE_COEF(0x4a, 0x0c00, 0x0c00),
4193 WRITE_COEF(0x45, 0x5289),
4194 UPDATE_COEF(0x4a, 0x0c00, 0),
4195 {}
4196 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004197
Takashi Iwai7639a062015-03-03 10:07:24 +01004198 switch (codec->core.vendor_id) {
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004199 case 0x10ec0255:
Kailang Yange69e7e02016-05-30 15:58:28 +08004200 alc_process_coef_fw(codec, coef0255);
4201 break;
Kailang Yang736f20a2017-10-20 15:06:34 +08004202 case 0x10ec0236:
Kailang Yang7081adf2015-03-30 17:05:37 +08004203 case 0x10ec0256:
Kailang Yange69e7e02016-05-30 15:58:28 +08004204 alc_process_coef_fw(codec, coef0256);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004205 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004206 case 0x10ec0234:
4207 case 0x10ec0274:
4208 case 0x10ec0294:
4209 alc_process_coef_fw(codec, coef0274);
4210 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004211 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004212 case 0x10ec0283:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004213 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02004214 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004215 case 0x10ec0286:
4216 case 0x10ec0288:
Kailang Yang89542932017-07-17 15:03:43 +08004217 alc_process_coef_fw(codec, coef0288);
4218 break;
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004219 case 0x10ec0298:
Kailang Yang89542932017-07-17 15:03:43 +08004220 alc_process_coef_fw(codec, coef0298);
Kailang Yangf3b70332015-04-08 15:01:17 +08004221 alc_process_coef_fw(codec, coef0288);
4222 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004223 case 0x10ec0292:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004224 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02004225 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004226 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004227 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004228 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004229 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004230 alc_process_coef_fw(codec, coef0668);
David Henningsson73bdd592013-04-15 15:44:14 +02004231 break;
Kailang Yangc2b691e2018-01-17 15:22:55 +08004232 case 0x10ec0215:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004233 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004234 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08004235 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004236 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08004237 case 0x10ec0299:
Kailang Yang4d4b0c52019-01-09 16:23:37 +08004238 alc_process_coef_fw(codec, alc225_pre_hsmode);
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004239 alc_process_coef_fw(codec, coef0225);
4240 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08004241 case 0x10ec0867:
4242 alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
4243 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004244 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01004245 codec_dbg(codec, "Headset jack set to unplugged mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02004246}
4247
4248
4249static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin,
4250 hda_nid_t mic_pin)
4251{
Takashi Iwai54db6c32014-08-18 15:11:19 +02004252 static struct coef_fw coef0255[] = {
4253 WRITE_COEFEX(0x57, 0x03, 0x8aa6),
4254 WRITE_COEF(0x06, 0x6100), /* Set MIC2 Vref gate to normal */
4255 {}
4256 };
Kailang Yang717f43d2019-05-31 17:16:53 +08004257 static struct coef_fw coef0256[] = {
4258 UPDATE_COEFEX(0x57, 0x05, 1<<14, 1<<14), /* Direct Drive HP Amp control(Set to verb control)*/
4259 WRITE_COEFEX(0x57, 0x03, 0x09a3),
4260 WRITE_COEF(0x06, 0x6100), /* Set MIC2 Vref gate to normal */
4261 {}
4262 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004263 static struct coef_fw coef0233[] = {
4264 UPDATE_COEF(0x35, 0, 1<<14),
4265 WRITE_COEF(0x06, 0x2100),
4266 WRITE_COEF(0x1a, 0x0021),
4267 WRITE_COEF(0x26, 0x008c),
4268 {}
4269 };
Kailang Yangf3b70332015-04-08 15:01:17 +08004270 static struct coef_fw coef0288[] = {
Kailang Yang89542932017-07-17 15:03:43 +08004271 UPDATE_COEF(0x4f, 0x00c0, 0),
Kailang Yangf3b70332015-04-08 15:01:17 +08004272 UPDATE_COEF(0x50, 0x2000, 0),
4273 UPDATE_COEF(0x56, 0x0006, 0),
4274 UPDATE_COEF(0x4f, 0xfcc0, 0xc400),
4275 UPDATE_COEF(0x66, 0x0008, 0x0008),
4276 UPDATE_COEF(0x67, 0x2000, 0x2000),
4277 {}
4278 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004279 static struct coef_fw coef0292[] = {
4280 WRITE_COEF(0x19, 0xa208),
4281 WRITE_COEF(0x2e, 0xacf0),
4282 {}
4283 };
4284 static struct coef_fw coef0293[] = {
4285 UPDATE_COEFEX(0x57, 0x05, 0, 1<<15|1<<13), /* SET charge pump by verb */
4286 UPDATE_COEFEX(0x57, 0x03, 1<<10, 0), /* SET EN_OSW to 0 */
4287 UPDATE_COEF(0x1a, 1<<3, 0), /* Combo JD gating without LINE1-VREFO */
4288 {}
4289 };
4290 static struct coef_fw coef0688[] = {
4291 WRITE_COEF(0xb7, 0x802b),
4292 WRITE_COEF(0xb5, 0x1040),
4293 UPDATE_COEF(0xc3, 0, 1<<12),
4294 {}
4295 };
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004296 static struct coef_fw coef0225[] = {
4297 UPDATE_COEFEX(0x57, 0x05, 1<<14, 1<<14),
4298 UPDATE_COEF(0x4a, 3<<4, 2<<4),
4299 UPDATE_COEF(0x63, 3<<14, 0),
4300 {}
4301 };
Kailang Yang71683c32017-06-20 16:33:50 +08004302 static struct coef_fw coef0274[] = {
4303 UPDATE_COEFEX(0x57, 0x05, 0x4000, 0x4000),
4304 UPDATE_COEF(0x4a, 0x0010, 0),
4305 UPDATE_COEF(0x6b, 0xf000, 0),
4306 {}
4307 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004308
Takashi Iwai7639a062015-03-03 10:07:24 +01004309 switch (codec->core.vendor_id) {
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004310 case 0x10ec0255:
4311 alc_write_coef_idx(codec, 0x45, 0xc489);
4312 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02004313 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004314 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4315 break;
Kailang Yang717f43d2019-05-31 17:16:53 +08004316 case 0x10ec0236:
4317 case 0x10ec0256:
4318 alc_write_coef_idx(codec, 0x45, 0xc489);
4319 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4320 alc_process_coef_fw(codec, coef0256);
4321 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4322 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004323 case 0x10ec0234:
4324 case 0x10ec0274:
4325 case 0x10ec0294:
4326 alc_write_coef_idx(codec, 0x45, 0x4689);
4327 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4328 alc_process_coef_fw(codec, coef0274);
4329 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4330 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004331 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004332 case 0x10ec0283:
4333 alc_write_coef_idx(codec, 0x45, 0xc429);
4334 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02004335 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02004336 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4337 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004338 case 0x10ec0286:
4339 case 0x10ec0288:
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004340 case 0x10ec0298:
Kailang Yangf3b70332015-04-08 15:01:17 +08004341 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4342 alc_process_coef_fw(codec, coef0288);
4343 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4344 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004345 case 0x10ec0292:
4346 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02004347 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02004348 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004349 case 0x10ec0293:
4350 /* Set to TRS mode */
4351 alc_write_coef_idx(codec, 0x45, 0xc429);
4352 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02004353 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004354 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4355 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08004356 case 0x10ec0867:
4357 alc_update_coefex_idx(codec, 0x57, 0x5, 0, 1<<14);
4358 /* fallthru */
Kailang Yang9eb5d0e2017-01-17 15:40:25 +08004359 case 0x10ec0221:
David Henningsson1f8b46c2015-05-12 14:38:15 +02004360 case 0x10ec0662:
4361 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4362 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4363 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004364 case 0x10ec0668:
4365 alc_write_coef_idx(codec, 0x11, 0x0001);
4366 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02004367 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02004368 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4369 break;
Kailang Yangc2b691e2018-01-17 15:22:55 +08004370 case 0x10ec0215:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004371 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004372 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08004373 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004374 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08004375 case 0x10ec0299:
Kailang Yang5a367672017-07-21 15:23:53 +08004376 alc_process_coef_fw(codec, alc225_pre_hsmode);
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004377 alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x31<<10);
4378 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4379 alc_process_coef_fw(codec, coef0225);
4380 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4381 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004382 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01004383 codec_dbg(codec, "Headset jack set to mic-in mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02004384}
4385
4386static void alc_headset_mode_default(struct hda_codec *codec)
4387{
David Henningsson2ae95572016-02-25 09:37:05 +01004388 static struct coef_fw coef0225[] = {
Kailang Yang5a367672017-07-21 15:23:53 +08004389 UPDATE_COEF(0x45, 0x3f<<10, 0x30<<10),
4390 UPDATE_COEF(0x45, 0x3f<<10, 0x31<<10),
4391 UPDATE_COEF(0x49, 3<<8, 0<<8),
4392 UPDATE_COEF(0x4a, 3<<4, 3<<4),
4393 UPDATE_COEF(0x63, 3<<14, 0),
4394 UPDATE_COEF(0x67, 0xf000, 0x3000),
David Henningsson2ae95572016-02-25 09:37:05 +01004395 {}
4396 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004397 static struct coef_fw coef0255[] = {
4398 WRITE_COEF(0x45, 0xc089),
4399 WRITE_COEF(0x45, 0xc489),
4400 WRITE_COEFEX(0x57, 0x03, 0x8ea6),
4401 WRITE_COEF(0x49, 0x0049),
4402 {}
4403 };
Kailang Yang717f43d2019-05-31 17:16:53 +08004404 static struct coef_fw coef0256[] = {
4405 WRITE_COEF(0x45, 0xc489),
4406 WRITE_COEFEX(0x57, 0x03, 0x0da3),
4407 WRITE_COEF(0x49, 0x0049),
4408 UPDATE_COEFEX(0x57, 0x05, 1<<14, 0), /* Direct Drive HP Amp control(Set to verb control)*/
4409 WRITE_COEF(0x06, 0x6100),
4410 {}
4411 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004412 static struct coef_fw coef0233[] = {
4413 WRITE_COEF(0x06, 0x2100),
4414 WRITE_COEF(0x32, 0x4ea3),
4415 {}
4416 };
Kailang Yangf3b70332015-04-08 15:01:17 +08004417 static struct coef_fw coef0288[] = {
4418 UPDATE_COEF(0x4f, 0xfcc0, 0xc400), /* Set to TRS type */
4419 UPDATE_COEF(0x50, 0x2000, 0x2000),
4420 UPDATE_COEF(0x56, 0x0006, 0x0006),
4421 UPDATE_COEF(0x66, 0x0008, 0),
4422 UPDATE_COEF(0x67, 0x2000, 0),
4423 {}
4424 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004425 static struct coef_fw coef0292[] = {
4426 WRITE_COEF(0x76, 0x000e),
4427 WRITE_COEF(0x6c, 0x2400),
4428 WRITE_COEF(0x6b, 0xc429),
4429 WRITE_COEF(0x18, 0x7308),
4430 {}
4431 };
4432 static struct coef_fw coef0293[] = {
4433 UPDATE_COEF(0x4a, 0x000f, 0x000e), /* Combo Jack auto detect */
4434 WRITE_COEF(0x45, 0xC429), /* Set to TRS type */
4435 UPDATE_COEF(0x1a, 1<<3, 0), /* Combo JD gating without LINE1-VREFO */
4436 {}
4437 };
4438 static struct coef_fw coef0688[] = {
4439 WRITE_COEF(0x11, 0x0041),
4440 WRITE_COEF(0x15, 0x0d40),
4441 WRITE_COEF(0xb7, 0x802b),
4442 {}
4443 };
Kailang Yang71683c32017-06-20 16:33:50 +08004444 static struct coef_fw coef0274[] = {
4445 WRITE_COEF(0x45, 0x4289),
4446 UPDATE_COEF(0x4a, 0x0010, 0x0010),
4447 UPDATE_COEF(0x6b, 0x0f00, 0),
4448 UPDATE_COEF(0x49, 0x0300, 0x0300),
4449 {}
4450 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004451
Takashi Iwai7639a062015-03-03 10:07:24 +01004452 switch (codec->core.vendor_id) {
Kailang Yangc2b691e2018-01-17 15:22:55 +08004453 case 0x10ec0215:
David Henningsson2ae95572016-02-25 09:37:05 +01004454 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004455 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08004456 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004457 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08004458 case 0x10ec0299:
Kailang Yang5a367672017-07-21 15:23:53 +08004459 alc_process_coef_fw(codec, alc225_pre_hsmode);
David Henningsson2ae95572016-02-25 09:37:05 +01004460 alc_process_coef_fw(codec, coef0225);
4461 break;
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004462 case 0x10ec0255:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004463 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004464 break;
Kailang Yang717f43d2019-05-31 17:16:53 +08004465 case 0x10ec0236:
4466 case 0x10ec0256:
4467 alc_write_coef_idx(codec, 0x1b, 0x0e4b);
4468 alc_write_coef_idx(codec, 0x45, 0xc089);
4469 msleep(50);
4470 alc_process_coef_fw(codec, coef0256);
4471 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004472 case 0x10ec0234:
4473 case 0x10ec0274:
4474 case 0x10ec0294:
4475 alc_process_coef_fw(codec, coef0274);
4476 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004477 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004478 case 0x10ec0283:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004479 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02004480 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004481 case 0x10ec0286:
4482 case 0x10ec0288:
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004483 case 0x10ec0298:
Kailang Yangf3b70332015-04-08 15:01:17 +08004484 alc_process_coef_fw(codec, coef0288);
4485 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004486 case 0x10ec0292:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004487 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02004488 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004489 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004490 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004491 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004492 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004493 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02004494 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08004495 case 0x10ec0867:
4496 alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
4497 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004498 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01004499 codec_dbg(codec, "Headset jack set to headphone (default) mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02004500}
4501
4502/* Iphone type */
4503static void alc_headset_mode_ctia(struct hda_codec *codec)
4504{
Kailang Yang89542932017-07-17 15:03:43 +08004505 int val;
4506
Takashi Iwai54db6c32014-08-18 15:11:19 +02004507 static struct coef_fw coef0255[] = {
4508 WRITE_COEF(0x45, 0xd489), /* Set to CTIA type */
4509 WRITE_COEF(0x1b, 0x0c2b),
4510 WRITE_COEFEX(0x57, 0x03, 0x8ea6),
4511 {}
4512 };
Kailang Yange69e7e02016-05-30 15:58:28 +08004513 static struct coef_fw coef0256[] = {
4514 WRITE_COEF(0x45, 0xd489), /* Set to CTIA type */
Kailang Yang717f43d2019-05-31 17:16:53 +08004515 WRITE_COEF(0x1b, 0x0e6b),
Kailang Yange69e7e02016-05-30 15:58:28 +08004516 {}
4517 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004518 static struct coef_fw coef0233[] = {
4519 WRITE_COEF(0x45, 0xd429),
4520 WRITE_COEF(0x1b, 0x0c2b),
4521 WRITE_COEF(0x32, 0x4ea3),
4522 {}
4523 };
Kailang Yangf3b70332015-04-08 15:01:17 +08004524 static struct coef_fw coef0288[] = {
4525 UPDATE_COEF(0x50, 0x2000, 0x2000),
4526 UPDATE_COEF(0x56, 0x0006, 0x0006),
4527 UPDATE_COEF(0x66, 0x0008, 0),
4528 UPDATE_COEF(0x67, 0x2000, 0),
4529 {}
4530 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004531 static struct coef_fw coef0292[] = {
4532 WRITE_COEF(0x6b, 0xd429),
4533 WRITE_COEF(0x76, 0x0008),
4534 WRITE_COEF(0x18, 0x7388),
4535 {}
4536 };
4537 static struct coef_fw coef0293[] = {
4538 WRITE_COEF(0x45, 0xd429), /* Set to ctia type */
4539 UPDATE_COEF(0x10, 7<<8, 7<<8), /* SET Line1 JD to 1 */
4540 {}
4541 };
4542 static struct coef_fw coef0688[] = {
4543 WRITE_COEF(0x11, 0x0001),
4544 WRITE_COEF(0x15, 0x0d60),
4545 WRITE_COEF(0xc3, 0x0000),
4546 {}
4547 };
Kailang Yang5a367672017-07-21 15:23:53 +08004548 static struct coef_fw coef0225_1[] = {
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004549 UPDATE_COEF(0x45, 0x3f<<10, 0x35<<10),
Kailang Yang5a367672017-07-21 15:23:53 +08004550 UPDATE_COEF(0x63, 3<<14, 2<<14),
4551 {}
4552 };
4553 static struct coef_fw coef0225_2[] = {
4554 UPDATE_COEF(0x45, 0x3f<<10, 0x35<<10),
4555 UPDATE_COEF(0x63, 3<<14, 1<<14),
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004556 {}
4557 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004558
Takashi Iwai7639a062015-03-03 10:07:24 +01004559 switch (codec->core.vendor_id) {
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004560 case 0x10ec0255:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004561 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004562 break;
Kailang Yang736f20a2017-10-20 15:06:34 +08004563 case 0x10ec0236:
Kailang Yange69e7e02016-05-30 15:58:28 +08004564 case 0x10ec0256:
4565 alc_process_coef_fw(codec, coef0256);
4566 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004567 case 0x10ec0234:
4568 case 0x10ec0274:
4569 case 0x10ec0294:
4570 alc_write_coef_idx(codec, 0x45, 0xd689);
4571 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004572 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004573 case 0x10ec0283:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004574 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02004575 break;
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004576 case 0x10ec0298:
Kailang Yang89542932017-07-17 15:03:43 +08004577 val = alc_read_coef_idx(codec, 0x50);
4578 if (val & (1 << 12)) {
4579 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0020);
4580 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400);
4581 msleep(300);
4582 } else {
4583 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0010);
4584 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400);
4585 msleep(300);
4586 }
4587 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004588 case 0x10ec0286:
4589 case 0x10ec0288:
4590 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400);
4591 msleep(300);
4592 alc_process_coef_fw(codec, coef0288);
4593 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004594 case 0x10ec0292:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004595 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02004596 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004597 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004598 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004599 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004600 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004601 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02004602 break;
Kailang Yangc2b691e2018-01-17 15:22:55 +08004603 case 0x10ec0215:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004604 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004605 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08004606 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004607 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08004608 case 0x10ec0299:
Kailang Yang5a367672017-07-21 15:23:53 +08004609 val = alc_read_coef_idx(codec, 0x45);
4610 if (val & (1 << 9))
4611 alc_process_coef_fw(codec, coef0225_2);
4612 else
4613 alc_process_coef_fw(codec, coef0225_1);
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004614 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08004615 case 0x10ec0867:
4616 alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
4617 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004618 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01004619 codec_dbg(codec, "Headset jack set to iPhone-style headset mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02004620}
4621
4622/* Nokia type */
4623static void alc_headset_mode_omtp(struct hda_codec *codec)
4624{
Takashi Iwai54db6c32014-08-18 15:11:19 +02004625 static struct coef_fw coef0255[] = {
4626 WRITE_COEF(0x45, 0xe489), /* Set to OMTP Type */
4627 WRITE_COEF(0x1b, 0x0c2b),
4628 WRITE_COEFEX(0x57, 0x03, 0x8ea6),
4629 {}
4630 };
Kailang Yange69e7e02016-05-30 15:58:28 +08004631 static struct coef_fw coef0256[] = {
4632 WRITE_COEF(0x45, 0xe489), /* Set to OMTP Type */
Kailang Yang717f43d2019-05-31 17:16:53 +08004633 WRITE_COEF(0x1b, 0x0e6b),
Kailang Yange69e7e02016-05-30 15:58:28 +08004634 {}
4635 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004636 static struct coef_fw coef0233[] = {
4637 WRITE_COEF(0x45, 0xe429),
4638 WRITE_COEF(0x1b, 0x0c2b),
4639 WRITE_COEF(0x32, 0x4ea3),
4640 {}
4641 };
Kailang Yangf3b70332015-04-08 15:01:17 +08004642 static struct coef_fw coef0288[] = {
4643 UPDATE_COEF(0x50, 0x2000, 0x2000),
4644 UPDATE_COEF(0x56, 0x0006, 0x0006),
4645 UPDATE_COEF(0x66, 0x0008, 0),
4646 UPDATE_COEF(0x67, 0x2000, 0),
4647 {}
4648 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004649 static struct coef_fw coef0292[] = {
4650 WRITE_COEF(0x6b, 0xe429),
4651 WRITE_COEF(0x76, 0x0008),
4652 WRITE_COEF(0x18, 0x7388),
4653 {}
4654 };
4655 static struct coef_fw coef0293[] = {
4656 WRITE_COEF(0x45, 0xe429), /* Set to omtp type */
4657 UPDATE_COEF(0x10, 7<<8, 7<<8), /* SET Line1 JD to 1 */
4658 {}
4659 };
4660 static struct coef_fw coef0688[] = {
4661 WRITE_COEF(0x11, 0x0001),
4662 WRITE_COEF(0x15, 0x0d50),
4663 WRITE_COEF(0xc3, 0x0000),
4664 {}
4665 };
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004666 static struct coef_fw coef0225[] = {
4667 UPDATE_COEF(0x45, 0x3f<<10, 0x39<<10),
Kailang Yang5a367672017-07-21 15:23:53 +08004668 UPDATE_COEF(0x63, 3<<14, 2<<14),
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004669 {}
4670 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004671
Takashi Iwai7639a062015-03-03 10:07:24 +01004672 switch (codec->core.vendor_id) {
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004673 case 0x10ec0255:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004674 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004675 break;
Kailang Yang736f20a2017-10-20 15:06:34 +08004676 case 0x10ec0236:
Kailang Yange69e7e02016-05-30 15:58:28 +08004677 case 0x10ec0256:
4678 alc_process_coef_fw(codec, coef0256);
4679 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004680 case 0x10ec0234:
4681 case 0x10ec0274:
4682 case 0x10ec0294:
4683 alc_write_coef_idx(codec, 0x45, 0xe689);
4684 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004685 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004686 case 0x10ec0283:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004687 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02004688 break;
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004689 case 0x10ec0298:
4690 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0010);/* Headset output enable */
Kailang Yang89542932017-07-17 15:03:43 +08004691 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xe400);
4692 msleep(300);
4693 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004694 case 0x10ec0286:
4695 case 0x10ec0288:
4696 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xe400);
4697 msleep(300);
4698 alc_process_coef_fw(codec, coef0288);
4699 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004700 case 0x10ec0292:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004701 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02004702 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004703 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004704 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004705 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004706 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004707 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02004708 break;
Kailang Yangc2b691e2018-01-17 15:22:55 +08004709 case 0x10ec0215:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004710 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004711 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08004712 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004713 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08004714 case 0x10ec0299:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004715 alc_process_coef_fw(codec, coef0225);
4716 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004717 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01004718 codec_dbg(codec, "Headset jack set to Nokia-style headset mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02004719}
4720
4721static void alc_determine_headset_type(struct hda_codec *codec)
4722{
4723 int val;
4724 bool is_ctia = false;
4725 struct alc_spec *spec = codec->spec;
Takashi Iwai54db6c32014-08-18 15:11:19 +02004726 static struct coef_fw coef0255[] = {
4727 WRITE_COEF(0x45, 0xd089), /* combo jack auto switch control(Check type)*/
4728 WRITE_COEF(0x49, 0x0149), /* combo jack auto switch control(Vref
4729 conteol) */
4730 {}
4731 };
Kailang Yangf3b70332015-04-08 15:01:17 +08004732 static struct coef_fw coef0288[] = {
4733 UPDATE_COEF(0x4f, 0xfcc0, 0xd400), /* Check Type */
4734 {}
4735 };
Kailang Yang89542932017-07-17 15:03:43 +08004736 static struct coef_fw coef0298[] = {
4737 UPDATE_COEF(0x50, 0x2000, 0x2000),
4738 UPDATE_COEF(0x56, 0x0006, 0x0006),
4739 UPDATE_COEF(0x66, 0x0008, 0),
4740 UPDATE_COEF(0x67, 0x2000, 0),
4741 UPDATE_COEF(0x19, 0x1300, 0x1300),
4742 {}
4743 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004744 static struct coef_fw coef0293[] = {
4745 UPDATE_COEF(0x4a, 0x000f, 0x0008), /* Combo Jack auto detect */
4746 WRITE_COEF(0x45, 0xD429), /* Set to ctia type */
4747 {}
4748 };
4749 static struct coef_fw coef0688[] = {
4750 WRITE_COEF(0x11, 0x0001),
4751 WRITE_COEF(0xb7, 0x802b),
4752 WRITE_COEF(0x15, 0x0d60),
4753 WRITE_COEF(0xc3, 0x0c00),
4754 {}
4755 };
Kailang Yang71683c32017-06-20 16:33:50 +08004756 static struct coef_fw coef0274[] = {
4757 UPDATE_COEF(0x4a, 0x0010, 0),
4758 UPDATE_COEF(0x4a, 0x8000, 0),
4759 WRITE_COEF(0x45, 0xd289),
4760 UPDATE_COEF(0x49, 0x0300, 0x0300),
4761 {}
4762 };
David Henningsson73bdd592013-04-15 15:44:14 +02004763
Takashi Iwai7639a062015-03-03 10:07:24 +01004764 switch (codec->core.vendor_id) {
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004765 case 0x10ec0255:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004766 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004767 msleep(300);
4768 val = alc_read_coef_idx(codec, 0x46);
4769 is_ctia = (val & 0x0070) == 0x0070;
4770 break;
Kailang Yang717f43d2019-05-31 17:16:53 +08004771 case 0x10ec0236:
4772 case 0x10ec0256:
4773 alc_write_coef_idx(codec, 0x1b, 0x0e4b);
4774 alc_write_coef_idx(codec, 0x06, 0x6104);
4775 alc_write_coefex_idx(codec, 0x57, 0x3, 0x09a3);
4776
4777 snd_hda_codec_write(codec, 0x21, 0,
4778 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
4779 msleep(80);
4780 snd_hda_codec_write(codec, 0x21, 0,
4781 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
4782
4783 alc_process_coef_fw(codec, coef0255);
4784 msleep(300);
4785 val = alc_read_coef_idx(codec, 0x46);
4786 is_ctia = (val & 0x0070) == 0x0070;
4787
4788 alc_write_coefex_idx(codec, 0x57, 0x3, 0x0da3);
4789 alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
4790
4791 snd_hda_codec_write(codec, 0x21, 0,
4792 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
4793 msleep(80);
4794 snd_hda_codec_write(codec, 0x21, 0,
4795 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
4796 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004797 case 0x10ec0234:
4798 case 0x10ec0274:
4799 case 0x10ec0294:
4800 alc_process_coef_fw(codec, coef0274);
4801 msleep(80);
4802 val = alc_read_coef_idx(codec, 0x46);
4803 is_ctia = (val & 0x00f0) == 0x00f0;
4804 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004805 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004806 case 0x10ec0283:
4807 alc_write_coef_idx(codec, 0x45, 0xd029);
4808 msleep(300);
4809 val = alc_read_coef_idx(codec, 0x46);
4810 is_ctia = (val & 0x0070) == 0x0070;
4811 break;
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004812 case 0x10ec0298:
Kailang Yang89542932017-07-17 15:03:43 +08004813 snd_hda_codec_write(codec, 0x21, 0,
4814 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
4815 msleep(100);
4816 snd_hda_codec_write(codec, 0x21, 0,
4817 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
4818 msleep(200);
4819
4820 val = alc_read_coef_idx(codec, 0x50);
4821 if (val & (1 << 12)) {
4822 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0020);
4823 alc_process_coef_fw(codec, coef0288);
4824 msleep(350);
4825 val = alc_read_coef_idx(codec, 0x50);
4826 is_ctia = (val & 0x0070) == 0x0070;
4827 } else {
4828 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0010);
4829 alc_process_coef_fw(codec, coef0288);
4830 msleep(350);
4831 val = alc_read_coef_idx(codec, 0x50);
4832 is_ctia = (val & 0x0070) == 0x0070;
4833 }
4834 alc_process_coef_fw(codec, coef0298);
4835 snd_hda_codec_write(codec, 0x21, 0,
4836 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP);
4837 msleep(75);
4838 snd_hda_codec_write(codec, 0x21, 0,
4839 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
4840 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004841 case 0x10ec0286:
4842 case 0x10ec0288:
4843 alc_process_coef_fw(codec, coef0288);
4844 msleep(350);
4845 val = alc_read_coef_idx(codec, 0x50);
4846 is_ctia = (val & 0x0070) == 0x0070;
4847 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004848 case 0x10ec0292:
4849 alc_write_coef_idx(codec, 0x6b, 0xd429);
4850 msleep(300);
4851 val = alc_read_coef_idx(codec, 0x6c);
4852 is_ctia = (val & 0x001c) == 0x001c;
4853 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004854 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004855 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004856 msleep(300);
4857 val = alc_read_coef_idx(codec, 0x46);
4858 is_ctia = (val & 0x0070) == 0x0070;
4859 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004860 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004861 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02004862 msleep(300);
4863 val = alc_read_coef_idx(codec, 0xbe);
4864 is_ctia = (val & 0x1c02) == 0x1c02;
4865 break;
Kailang Yangc2b691e2018-01-17 15:22:55 +08004866 case 0x10ec0215:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004867 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004868 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08004869 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004870 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08004871 case 0x10ec0299:
Kailang Yangda911b12018-01-05 16:50:08 +08004872 snd_hda_codec_write(codec, 0x21, 0,
4873 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
4874 msleep(80);
4875 snd_hda_codec_write(codec, 0x21, 0,
4876 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
4877
Kailang Yang5a367672017-07-21 15:23:53 +08004878 alc_process_coef_fw(codec, alc225_pre_hsmode);
4879 alc_update_coef_idx(codec, 0x67, 0xf000, 0x1000);
4880 val = alc_read_coef_idx(codec, 0x45);
4881 if (val & (1 << 9)) {
4882 alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x34<<10);
4883 alc_update_coef_idx(codec, 0x49, 3<<8, 2<<8);
4884 msleep(800);
4885 val = alc_read_coef_idx(codec, 0x46);
4886 is_ctia = (val & 0x00f0) == 0x00f0;
4887 } else {
4888 alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x34<<10);
4889 alc_update_coef_idx(codec, 0x49, 3<<8, 1<<8);
4890 msleep(800);
4891 val = alc_read_coef_idx(codec, 0x46);
4892 is_ctia = (val & 0x00f0) == 0x00f0;
4893 }
4894 alc_update_coef_idx(codec, 0x4a, 7<<6, 7<<6);
4895 alc_update_coef_idx(codec, 0x4a, 3<<4, 3<<4);
4896 alc_update_coef_idx(codec, 0x67, 0xf000, 0x3000);
Kailang Yangda911b12018-01-05 16:50:08 +08004897
4898 snd_hda_codec_write(codec, 0x21, 0,
4899 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
4900 msleep(80);
4901 snd_hda_codec_write(codec, 0x21, 0,
4902 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004903 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08004904 case 0x10ec0867:
4905 is_ctia = true;
4906 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004907 }
4908
Takashi Iwai4e76a882014-02-25 12:21:03 +01004909 codec_dbg(codec, "Headset jack detected iPhone-style headset: %s\n",
David Henningsson73bdd592013-04-15 15:44:14 +02004910 is_ctia ? "yes" : "no");
4911 spec->current_headset_type = is_ctia ? ALC_HEADSET_TYPE_CTIA : ALC_HEADSET_TYPE_OMTP;
4912}
4913
4914static void alc_update_headset_mode(struct hda_codec *codec)
4915{
4916 struct alc_spec *spec = codec->spec;
4917
4918 hda_nid_t mux_pin = spec->gen.imux_pins[spec->gen.cur_mux[0]];
Takashi Iwai35a39f92019-02-01 11:19:50 +01004919 hda_nid_t hp_pin = alc_get_hp_pin(spec);
David Henningsson73bdd592013-04-15 15:44:14 +02004920
4921 int new_headset_mode;
4922
4923 if (!snd_hda_jack_detect(codec, hp_pin))
4924 new_headset_mode = ALC_HEADSET_MODE_UNPLUGGED;
4925 else if (mux_pin == spec->headset_mic_pin)
4926 new_headset_mode = ALC_HEADSET_MODE_HEADSET;
4927 else if (mux_pin == spec->headphone_mic_pin)
4928 new_headset_mode = ALC_HEADSET_MODE_MIC;
4929 else
4930 new_headset_mode = ALC_HEADSET_MODE_HEADPHONE;
4931
David Henningsson5959a6b2013-11-12 11:10:57 +01004932 if (new_headset_mode == spec->current_headset_mode) {
4933 snd_hda_gen_update_outputs(codec);
David Henningsson73bdd592013-04-15 15:44:14 +02004934 return;
David Henningsson5959a6b2013-11-12 11:10:57 +01004935 }
David Henningsson73bdd592013-04-15 15:44:14 +02004936
4937 switch (new_headset_mode) {
4938 case ALC_HEADSET_MODE_UNPLUGGED:
4939 alc_headset_mode_unplugged(codec);
Kailang Yangaeac1a02019-05-16 16:10:44 +08004940 spec->current_headset_mode = ALC_HEADSET_MODE_UNKNOWN;
4941 spec->current_headset_type = ALC_HEADSET_TYPE_UNKNOWN;
David Henningsson73bdd592013-04-15 15:44:14 +02004942 spec->gen.hp_jack_present = false;
4943 break;
4944 case ALC_HEADSET_MODE_HEADSET:
4945 if (spec->current_headset_type == ALC_HEADSET_TYPE_UNKNOWN)
4946 alc_determine_headset_type(codec);
4947 if (spec->current_headset_type == ALC_HEADSET_TYPE_CTIA)
4948 alc_headset_mode_ctia(codec);
4949 else if (spec->current_headset_type == ALC_HEADSET_TYPE_OMTP)
4950 alc_headset_mode_omtp(codec);
4951 spec->gen.hp_jack_present = true;
4952 break;
4953 case ALC_HEADSET_MODE_MIC:
4954 alc_headset_mode_mic_in(codec, hp_pin, spec->headphone_mic_pin);
4955 spec->gen.hp_jack_present = false;
4956 break;
4957 case ALC_HEADSET_MODE_HEADPHONE:
4958 alc_headset_mode_default(codec);
4959 spec->gen.hp_jack_present = true;
4960 break;
4961 }
4962 if (new_headset_mode != ALC_HEADSET_MODE_MIC) {
4963 snd_hda_set_pin_ctl_cache(codec, hp_pin,
4964 AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN);
David Henningsson1f8b46c2015-05-12 14:38:15 +02004965 if (spec->headphone_mic_pin && spec->headphone_mic_pin != hp_pin)
David Henningsson73bdd592013-04-15 15:44:14 +02004966 snd_hda_set_pin_ctl_cache(codec, spec->headphone_mic_pin,
4967 PIN_VREFHIZ);
4968 }
4969 spec->current_headset_mode = new_headset_mode;
4970
4971 snd_hda_gen_update_outputs(codec);
4972}
4973
4974static void alc_update_headset_mode_hook(struct hda_codec *codec,
Takashi Iwai7fe30712014-01-30 17:59:02 +01004975 struct snd_kcontrol *kcontrol,
4976 struct snd_ctl_elem_value *ucontrol)
David Henningsson73bdd592013-04-15 15:44:14 +02004977{
4978 alc_update_headset_mode(codec);
4979}
4980
Takashi Iwai1a4f69d2014-09-11 15:22:46 +02004981static void alc_update_headset_jack_cb(struct hda_codec *codec,
4982 struct hda_jack_callback *jack)
David Henningsson73bdd592013-04-15 15:44:14 +02004983{
David Henningsson73bdd592013-04-15 15:44:14 +02004984 snd_hda_gen_hp_automute(codec, jack);
4985}
4986
4987static void alc_probe_headset_mode(struct hda_codec *codec)
4988{
4989 int i;
4990 struct alc_spec *spec = codec->spec;
4991 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
4992
4993 /* Find mic pins */
4994 for (i = 0; i < cfg->num_inputs; i++) {
4995 if (cfg->inputs[i].is_headset_mic && !spec->headset_mic_pin)
4996 spec->headset_mic_pin = cfg->inputs[i].pin;
4997 if (cfg->inputs[i].is_headphone_mic && !spec->headphone_mic_pin)
4998 spec->headphone_mic_pin = cfg->inputs[i].pin;
4999 }
5000
Takashi Iwai0bed2aa2018-06-19 12:45:53 +02005001 WARN_ON(spec->gen.cap_sync_hook);
David Henningsson73bdd592013-04-15 15:44:14 +02005002 spec->gen.cap_sync_hook = alc_update_headset_mode_hook;
5003 spec->gen.automute_hook = alc_update_headset_mode;
5004 spec->gen.hp_automute_hook = alc_update_headset_jack_cb;
5005}
5006
5007static void alc_fixup_headset_mode(struct hda_codec *codec,
5008 const struct hda_fixup *fix, int action)
5009{
5010 struct alc_spec *spec = codec->spec;
5011
5012 switch (action) {
5013 case HDA_FIXUP_ACT_PRE_PROBE:
5014 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC | HDA_PINCFG_HEADPHONE_MIC;
5015 break;
5016 case HDA_FIXUP_ACT_PROBE:
5017 alc_probe_headset_mode(codec);
5018 break;
5019 case HDA_FIXUP_ACT_INIT:
Kailang Yangaeac1a02019-05-16 16:10:44 +08005020 if (is_s3_resume(codec) || is_s4_resume(codec)) {
5021 spec->current_headset_mode = ALC_HEADSET_MODE_UNKNOWN;
5022 spec->current_headset_type = ALC_HEADSET_TYPE_UNKNOWN;
5023 }
David Henningsson73bdd592013-04-15 15:44:14 +02005024 alc_update_headset_mode(codec);
5025 break;
5026 }
5027}
5028
5029static void alc_fixup_headset_mode_no_hp_mic(struct hda_codec *codec,
5030 const struct hda_fixup *fix, int action)
5031{
5032 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5033 struct alc_spec *spec = codec->spec;
5034 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
5035 }
5036 else
5037 alc_fixup_headset_mode(codec, fix, action);
5038}
5039
Kailang Yang31278992014-03-03 15:27:22 +08005040static void alc255_set_default_jack_type(struct hda_codec *codec)
5041{
5042 /* Set to iphone type */
Kailang Yange69e7e02016-05-30 15:58:28 +08005043 static struct coef_fw alc255fw[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02005044 WRITE_COEF(0x1b, 0x880b),
5045 WRITE_COEF(0x45, 0xd089),
5046 WRITE_COEF(0x1b, 0x080b),
5047 WRITE_COEF(0x46, 0x0004),
5048 WRITE_COEF(0x1b, 0x0c0b),
5049 {}
5050 };
Kailang Yange69e7e02016-05-30 15:58:28 +08005051 static struct coef_fw alc256fw[] = {
5052 WRITE_COEF(0x1b, 0x884b),
5053 WRITE_COEF(0x45, 0xd089),
5054 WRITE_COEF(0x1b, 0x084b),
5055 WRITE_COEF(0x46, 0x0004),
5056 WRITE_COEF(0x1b, 0x0c4b),
5057 {}
5058 };
5059 switch (codec->core.vendor_id) {
5060 case 0x10ec0255:
5061 alc_process_coef_fw(codec, alc255fw);
5062 break;
Kailang Yang736f20a2017-10-20 15:06:34 +08005063 case 0x10ec0236:
Kailang Yange69e7e02016-05-30 15:58:28 +08005064 case 0x10ec0256:
5065 alc_process_coef_fw(codec, alc256fw);
5066 break;
5067 }
Kailang Yang31278992014-03-03 15:27:22 +08005068 msleep(30);
5069}
5070
Kailang Yang9a22a8f52013-11-08 15:54:49 +08005071static void alc_fixup_headset_mode_alc255(struct hda_codec *codec,
5072 const struct hda_fixup *fix, int action)
5073{
5074 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Kailang Yang31278992014-03-03 15:27:22 +08005075 alc255_set_default_jack_type(codec);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08005076 }
5077 alc_fixup_headset_mode(codec, fix, action);
5078}
5079
Kailang Yang31278992014-03-03 15:27:22 +08005080static void alc_fixup_headset_mode_alc255_no_hp_mic(struct hda_codec *codec,
5081 const struct hda_fixup *fix, int action)
5082{
5083 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5084 struct alc_spec *spec = codec->spec;
5085 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
5086 alc255_set_default_jack_type(codec);
5087 }
5088 else
5089 alc_fixup_headset_mode(codec, fix, action);
5090}
5091
Kailang Yange1e62b92015-04-08 16:01:22 +08005092static void alc288_update_headset_jack_cb(struct hda_codec *codec,
5093 struct hda_jack_callback *jack)
5094{
5095 struct alc_spec *spec = codec->spec;
Kailang Yange1e62b92015-04-08 16:01:22 +08005096
5097 alc_update_headset_jack_cb(codec, jack);
5098 /* Headset Mic enable or disable, only for Dell Dino */
Takashi Iwaid44a6862018-06-19 23:04:03 +02005099 alc_update_gpio_data(codec, 0x40, spec->gen.hp_jack_present);
Kailang Yange1e62b92015-04-08 16:01:22 +08005100}
5101
5102static void alc_fixup_headset_mode_dell_alc288(struct hda_codec *codec,
5103 const struct hda_fixup *fix, int action)
5104{
5105 alc_fixup_headset_mode(codec, fix, action);
5106 if (action == HDA_FIXUP_ACT_PROBE) {
5107 struct alc_spec *spec = codec->spec;
Takashi Iwaid44a6862018-06-19 23:04:03 +02005108 /* toggled via hp_automute_hook */
5109 spec->gpio_mask |= 0x40;
5110 spec->gpio_dir |= 0x40;
Kailang Yange1e62b92015-04-08 16:01:22 +08005111 spec->gen.hp_automute_hook = alc288_update_headset_jack_cb;
5112 }
5113}
5114
Hui Wang493a52a2014-01-14 14:07:36 +08005115static void alc_fixup_auto_mute_via_amp(struct hda_codec *codec,
5116 const struct hda_fixup *fix, int action)
5117{
5118 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5119 struct alc_spec *spec = codec->spec;
5120 spec->gen.auto_mute_via_amp = 1;
5121 }
5122}
5123
Takashi Iwai9b745ab2014-03-07 08:37:19 +01005124static void alc_fixup_no_shutup(struct hda_codec *codec,
5125 const struct hda_fixup *fix, int action)
5126{
Takashi Iwaiefe55732018-06-15 11:55:02 +02005127 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai9b745ab2014-03-07 08:37:19 +01005128 struct alc_spec *spec = codec->spec;
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01005129 spec->no_shutup_pins = 1;
Takashi Iwai9b745ab2014-03-07 08:37:19 +01005130 }
5131}
5132
Gabriele Mazzotta5e6db662014-05-20 18:58:26 +02005133static void alc_fixup_disable_aamix(struct hda_codec *codec,
5134 const struct hda_fixup *fix, int action)
5135{
5136 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5137 struct alc_spec *spec = codec->spec;
5138 /* Disable AA-loopback as it causes white noise */
5139 spec->gen.mixer_nid = 0;
5140 }
5141}
5142
Takashi Iwai7f57d802015-09-24 17:36:51 +02005143/* fixup for Thinkpad docks: add dock pins, avoid HP parser fixup */
5144static void alc_fixup_tpt440_dock(struct hda_codec *codec,
5145 const struct hda_fixup *fix, int action)
5146{
5147 static const struct hda_pintbl pincfgs[] = {
5148 { 0x16, 0x21211010 }, /* dock headphone */
5149 { 0x19, 0x21a11010 }, /* dock mic */
5150 { }
5151 };
5152 struct alc_spec *spec = codec->spec;
5153
5154 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai70a09762015-12-15 14:59:58 +01005155 spec->reboot_notify = alc_d3_at_reboot; /* reduce noise */
Takashi Iwai7f57d802015-09-24 17:36:51 +02005156 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
5157 codec->power_save_node = 0; /* avoid click noises */
5158 snd_hda_apply_pincfgs(codec, pincfgs);
5159 }
5160}
5161
Kailang Yang61fcf8e2018-02-02 15:26:46 +08005162static void alc_fixup_tpt470_dock(struct hda_codec *codec,
5163 const struct hda_fixup *fix, int action)
5164{
5165 static const struct hda_pintbl pincfgs[] = {
5166 { 0x17, 0x21211010 }, /* dock headphone */
5167 { 0x19, 0x21a11010 }, /* dock mic */
5168 { }
5169 };
Takashi Iwai54947cd2018-12-03 10:44:15 +01005170 /* Assure the speaker pin to be coupled with DAC NID 0x03; otherwise
5171 * the speaker output becomes too low by some reason on Thinkpads with
5172 * ALC298 codec
5173 */
5174 static hda_nid_t preferred_pairs[] = {
5175 0x14, 0x03, 0x17, 0x02, 0x21, 0x02,
5176 0
5177 };
Kailang Yang61fcf8e2018-02-02 15:26:46 +08005178 struct alc_spec *spec = codec->spec;
5179
5180 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai54947cd2018-12-03 10:44:15 +01005181 spec->gen.preferred_dacs = preferred_pairs;
Kailang Yang61fcf8e2018-02-02 15:26:46 +08005182 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
Takashi Iwai71db96d2018-02-26 15:36:38 +01005183 snd_hda_apply_pincfgs(codec, pincfgs);
5184 } else if (action == HDA_FIXUP_ACT_INIT) {
Kailang Yang61fcf8e2018-02-02 15:26:46 +08005185 /* Enable DOCK device */
5186 snd_hda_codec_write(codec, 0x17, 0,
5187 AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0);
5188 /* Enable DOCK device */
5189 snd_hda_codec_write(codec, 0x19, 0,
5190 AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0);
Kailang Yang61fcf8e2018-02-02 15:26:46 +08005191 }
5192}
5193
Gabriele Mazzotta9476d3692015-04-19 19:00:40 +02005194static void alc_shutup_dell_xps13(struct hda_codec *codec)
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02005195{
5196 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01005197 int hp_pin = alc_get_hp_pin(spec);
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02005198
Gabriele Mazzotta9476d3692015-04-19 19:00:40 +02005199 /* Prevent pop noises when headphones are plugged in */
5200 snd_hda_codec_write(codec, hp_pin, 0,
5201 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
5202 msleep(20);
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02005203}
5204
5205static void alc_fixup_dell_xps13(struct hda_codec *codec,
5206 const struct hda_fixup *fix, int action)
5207{
Takashi Iwai3e1b0c42015-04-27 10:43:22 +02005208 struct alc_spec *spec = codec->spec;
5209 struct hda_input_mux *imux = &spec->gen.input_mux;
5210 int i;
Gabriele Mazzottaf38663a2014-08-08 19:34:40 +02005211
Takashi Iwai3e1b0c42015-04-27 10:43:22 +02005212 switch (action) {
5213 case HDA_FIXUP_ACT_PRE_PROBE:
5214 /* mic pin 0x19 must be initialized with Vref Hi-Z, otherwise
5215 * it causes a click noise at start up
5216 */
5217 snd_hda_codec_set_pin_target(codec, 0x19, PIN_VREFHIZ);
Takashi Iwaiefe55732018-06-15 11:55:02 +02005218 spec->shutup = alc_shutup_dell_xps13;
Takashi Iwai3e1b0c42015-04-27 10:43:22 +02005219 break;
5220 case HDA_FIXUP_ACT_PROBE:
Gabriele Mazzottaf38663a2014-08-08 19:34:40 +02005221 /* Make the internal mic the default input source. */
5222 for (i = 0; i < imux->num_items; i++) {
5223 if (spec->gen.imux_pins[i] == 0x12) {
5224 spec->gen.cur_mux[0] = i;
5225 break;
5226 }
5227 }
Takashi Iwai3e1b0c42015-04-27 10:43:22 +02005228 break;
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02005229 }
5230}
5231
David Henningsson1f8b46c2015-05-12 14:38:15 +02005232static void alc_fixup_headset_mode_alc662(struct hda_codec *codec,
5233 const struct hda_fixup *fix, int action)
5234{
5235 struct alc_spec *spec = codec->spec;
5236
5237 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5238 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
5239 spec->gen.hp_mic = 1; /* Mic-in is same pin as headphone */
David Henningssonb40eda62015-05-28 09:40:23 +02005240
5241 /* Disable boost for mic-in permanently. (This code is only called
5242 from quirks that guarantee that the headphone is at NID 0x1b.) */
5243 snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000);
5244 snd_hda_override_wcaps(codec, 0x1b, get_wcaps(codec, 0x1b) & ~AC_WCAP_IN_AMP);
David Henningsson1f8b46c2015-05-12 14:38:15 +02005245 } else
5246 alc_fixup_headset_mode(codec, fix, action);
5247}
5248
David Henningsson73bdd592013-04-15 15:44:14 +02005249static void alc_fixup_headset_mode_alc668(struct hda_codec *codec,
5250 const struct hda_fixup *fix, int action)
5251{
5252 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
David Henningsson73bdd592013-04-15 15:44:14 +02005253 alc_write_coef_idx(codec, 0xc4, 0x8000);
Takashi Iwai98b24882014-08-18 13:47:50 +02005254 alc_update_coef_idx(codec, 0xc2, ~0xfe, 0);
David Henningsson73bdd592013-04-15 15:44:14 +02005255 snd_hda_set_pin_ctl_cache(codec, 0x18, 0);
5256 }
5257 alc_fixup_headset_mode(codec, fix, action);
5258}
5259
Chih-Chung Changbde7bc62013-08-05 16:38:42 +08005260/* Returns the nid of the external mic input pin, or 0 if it cannot be found. */
5261static int find_ext_mic_pin(struct hda_codec *codec)
5262{
5263 struct alc_spec *spec = codec->spec;
5264 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
5265 hda_nid_t nid;
5266 unsigned int defcfg;
5267 int i;
5268
5269 for (i = 0; i < cfg->num_inputs; i++) {
5270 if (cfg->inputs[i].type != AUTO_PIN_MIC)
5271 continue;
5272 nid = cfg->inputs[i].pin;
5273 defcfg = snd_hda_codec_get_pincfg(codec, nid);
5274 if (snd_hda_get_input_pin_attr(defcfg) == INPUT_PIN_ATTR_INT)
5275 continue;
5276 return nid;
5277 }
5278
5279 return 0;
5280}
5281
Dylan Reid08a978d2012-11-18 22:56:40 -08005282static void alc271_hp_gate_mic_jack(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01005283 const struct hda_fixup *fix,
Dylan Reid08a978d2012-11-18 22:56:40 -08005284 int action)
5285{
5286 struct alc_spec *spec = codec->spec;
5287
Takashi Iwai0db75792013-01-23 13:57:20 +01005288 if (action == HDA_FIXUP_ACT_PROBE) {
Chih-Chung Changbde7bc62013-08-05 16:38:42 +08005289 int mic_pin = find_ext_mic_pin(codec);
Takashi Iwai35a39f92019-02-01 11:19:50 +01005290 int hp_pin = alc_get_hp_pin(spec);
Chih-Chung Changbde7bc62013-08-05 16:38:42 +08005291
5292 if (snd_BUG_ON(!mic_pin || !hp_pin))
Takashi Iwai0db75792013-01-23 13:57:20 +01005293 return;
Chih-Chung Changbde7bc62013-08-05 16:38:42 +08005294 snd_hda_jack_set_gating_jack(codec, mic_pin, hp_pin);
Takashi Iwai0db75792013-01-23 13:57:20 +01005295 }
Dylan Reid08a978d2012-11-18 22:56:40 -08005296}
David Henningsson693b6132012-06-22 19:12:10 +02005297
David Henningsson3e0d6112013-04-22 14:30:14 +02005298static void alc269_fixup_limit_int_mic_boost(struct hda_codec *codec,
5299 const struct hda_fixup *fix,
5300 int action)
5301{
5302 struct alc_spec *spec = codec->spec;
5303 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
5304 int i;
5305
5306 /* The mic boosts on level 2 and 3 are too noisy
5307 on the internal mic input.
5308 Therefore limit the boost to 0 or 1. */
5309
5310 if (action != HDA_FIXUP_ACT_PROBE)
5311 return;
5312
5313 for (i = 0; i < cfg->num_inputs; i++) {
5314 hda_nid_t nid = cfg->inputs[i].pin;
5315 unsigned int defcfg;
5316 if (cfg->inputs[i].type != AUTO_PIN_MIC)
5317 continue;
5318 defcfg = snd_hda_codec_get_pincfg(codec, nid);
5319 if (snd_hda_get_input_pin_attr(defcfg) != INPUT_PIN_ATTR_INT)
5320 continue;
5321
5322 snd_hda_override_amp_caps(codec, nid, HDA_INPUT,
5323 (0x00 << AC_AMPCAP_OFFSET_SHIFT) |
5324 (0x01 << AC_AMPCAP_NUM_STEPS_SHIFT) |
5325 (0x2f << AC_AMPCAP_STEP_SIZE_SHIFT) |
5326 (0 << AC_AMPCAP_MUTE_SHIFT));
5327 }
5328}
5329
Kailang Yangcd217a62013-08-22 10:15:24 +02005330static void alc283_hp_automute_hook(struct hda_codec *codec,
Takashi Iwai1a4f69d2014-09-11 15:22:46 +02005331 struct hda_jack_callback *jack)
Kailang Yangcd217a62013-08-22 10:15:24 +02005332{
5333 struct alc_spec *spec = codec->spec;
5334 int vref;
5335
5336 msleep(200);
5337 snd_hda_gen_hp_automute(codec, jack);
5338
5339 vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0;
5340
5341 msleep(600);
5342 snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5343 vref);
5344}
5345
Kailang Yangcd217a62013-08-22 10:15:24 +02005346static void alc283_fixup_chromebook(struct hda_codec *codec,
5347 const struct hda_fixup *fix, int action)
5348{
5349 struct alc_spec *spec = codec->spec;
Kailang Yangcd217a62013-08-22 10:15:24 +02005350
5351 switch (action) {
5352 case HDA_FIXUP_ACT_PRE_PROBE:
Kailang Yang0202e992013-12-02 15:20:15 +08005353 snd_hda_override_wcaps(codec, 0x03, 0);
Takashi Iwaid2e92702013-10-30 07:50:53 +01005354 /* Disable AA-loopback as it causes white noise */
5355 spec->gen.mixer_nid = 0;
Kailang Yang38070212013-11-01 15:57:35 +08005356 break;
5357 case HDA_FIXUP_ACT_INIT:
Kailang Yangde9481c2014-04-07 16:41:52 +08005358 /* MIC2-VREF control */
5359 /* Set to manual mode */
Takashi Iwai98b24882014-08-18 13:47:50 +02005360 alc_update_coef_idx(codec, 0x06, 0x000c, 0);
Kailang Yang0202e992013-12-02 15:20:15 +08005361 /* Enable Line1 input control by verb */
Takashi Iwai98b24882014-08-18 13:47:50 +02005362 alc_update_coef_idx(codec, 0x1a, 0, 1 << 4);
Kailang Yang0202e992013-12-02 15:20:15 +08005363 break;
5364 }
5365}
5366
5367static void alc283_fixup_sense_combo_jack(struct hda_codec *codec,
5368 const struct hda_fixup *fix, int action)
5369{
5370 struct alc_spec *spec = codec->spec;
Kailang Yang0202e992013-12-02 15:20:15 +08005371
5372 switch (action) {
5373 case HDA_FIXUP_ACT_PRE_PROBE:
Kailang Yangcd217a62013-08-22 10:15:24 +02005374 spec->gen.hp_automute_hook = alc283_hp_automute_hook;
5375 break;
5376 case HDA_FIXUP_ACT_INIT:
5377 /* MIC2-VREF control */
5378 /* Set to manual mode */
Takashi Iwai98b24882014-08-18 13:47:50 +02005379 alc_update_coef_idx(codec, 0x06, 0x000c, 0);
Kailang Yangcd217a62013-08-22 10:15:24 +02005380 break;
5381 }
5382}
5383
Takashi Iwai7bba2152013-09-06 15:45:38 +02005384/* mute tablet speaker pin (0x14) via dock plugging in addition */
5385static void asus_tx300_automute(struct hda_codec *codec)
5386{
5387 struct alc_spec *spec = codec->spec;
5388 snd_hda_gen_update_outputs(codec);
5389 if (snd_hda_jack_detect(codec, 0x1b))
5390 spec->gen.mute_bits |= (1ULL << 0x14);
5391}
5392
5393static void alc282_fixup_asus_tx300(struct hda_codec *codec,
5394 const struct hda_fixup *fix, int action)
5395{
5396 struct alc_spec *spec = codec->spec;
Takashi Iwai7bba2152013-09-06 15:45:38 +02005397 static const struct hda_pintbl dock_pins[] = {
5398 { 0x1b, 0x21114000 }, /* dock speaker pin */
5399 {}
5400 };
Takashi Iwai7bba2152013-09-06 15:45:38 +02005401
5402 switch (action) {
5403 case HDA_FIXUP_ACT_PRE_PROBE:
Takashi Iwai1c76aa52018-06-21 16:37:54 +02005404 spec->init_amp = ALC_INIT_DEFAULT;
Takashi Iwaiae065f12018-06-19 23:00:03 +02005405 /* TX300 needs to set up GPIO2 for the speaker amp */
5406 alc_setup_gpio(codec, 0x04);
Takashi Iwai7bba2152013-09-06 15:45:38 +02005407 snd_hda_apply_pincfgs(codec, dock_pins);
5408 spec->gen.auto_mute_via_amp = 1;
5409 spec->gen.automute_hook = asus_tx300_automute;
5410 snd_hda_jack_detect_enable_callback(codec, 0x1b,
Takashi Iwai7bba2152013-09-06 15:45:38 +02005411 snd_hda_gen_hp_automute);
5412 break;
Takashi Iwai5579cd62018-06-19 22:22:41 +02005413 case HDA_FIXUP_ACT_PROBE:
5414 spec->init_amp = ALC_INIT_DEFAULT;
5415 break;
Takashi Iwai7bba2152013-09-06 15:45:38 +02005416 case HDA_FIXUP_ACT_BUILD:
5417 /* this is a bit tricky; give more sane names for the main
5418 * (tablet) speaker and the dock speaker, respectively
5419 */
Takashi Iwai56798e62017-04-11 08:10:52 +02005420 rename_ctl(codec, "Speaker Playback Switch",
5421 "Dock Speaker Playback Switch");
5422 rename_ctl(codec, "Bass Speaker Playback Switch",
5423 "Speaker Playback Switch");
Takashi Iwai7bba2152013-09-06 15:45:38 +02005424 break;
5425 }
5426}
5427
David Henningsson338cae52013-10-07 10:39:59 +02005428static void alc290_fixup_mono_speakers(struct hda_codec *codec,
5429 const struct hda_fixup *fix, int action)
5430{
David Henningsson0f4881d2013-12-20 16:08:13 +01005431 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5432 /* DAC node 0x03 is giving mono output. We therefore want to
5433 make sure 0x14 (front speaker) and 0x15 (headphones) use the
5434 stereo DAC, while leaving 0x17 (bass speaker) for node 0x03. */
5435 hda_nid_t conn1[2] = { 0x0c };
5436 snd_hda_override_conn_list(codec, 0x14, 1, conn1);
5437 snd_hda_override_conn_list(codec, 0x15, 1, conn1);
5438 }
David Henningsson338cae52013-10-07 10:39:59 +02005439}
5440
Hui Wangdd9aa332016-08-01 10:20:32 +08005441static void alc298_fixup_speaker_volume(struct hda_codec *codec,
5442 const struct hda_fixup *fix, int action)
5443{
5444 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5445 /* The speaker is routed to the Node 0x06 by a mistake, as a result
5446 we can't adjust the speaker's volume since this node does not has
5447 Amp-out capability. we change the speaker's route to:
5448 Node 0x02 (Audio Output) -> Node 0x0c (Audio Mixer) -> Node 0x17 (
5449 Pin Complex), since Node 0x02 has Amp-out caps, we can adjust
5450 speaker's volume now. */
5451
5452 hda_nid_t conn1[1] = { 0x0c };
5453 snd_hda_override_conn_list(codec, 0x17, 1, conn1);
5454 }
5455}
5456
Takashi Iwaie312a862018-03-06 12:14:17 +01005457/* disable DAC3 (0x06) selection on NID 0x17 as it has no volume amp control */
5458static void alc295_fixup_disable_dac3(struct hda_codec *codec,
5459 const struct hda_fixup *fix, int action)
5460{
5461 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5462 hda_nid_t conn[2] = { 0x02, 0x03 };
5463 snd_hda_override_conn_list(codec, 0x17, 2, conn);
5464 }
5465}
5466
Keith Packard98973f22015-07-15 12:14:39 -07005467/* Hook to update amp GPIO4 for automute */
5468static void alc280_hp_gpio4_automute_hook(struct hda_codec *codec,
5469 struct hda_jack_callback *jack)
5470{
5471 struct alc_spec *spec = codec->spec;
5472
5473 snd_hda_gen_hp_automute(codec, jack);
5474 /* mute_led_polarity is set to 0, so we pass inverted value here */
5475 alc_update_gpio_led(codec, 0x10, !spec->gen.hp_jack_present);
5476}
5477
5478/* Manage GPIOs for HP EliteBook Folio 9480m.
5479 *
5480 * GPIO4 is the headphone amplifier power control
5481 * GPIO3 is the audio output mute indicator LED
5482 */
5483
5484static void alc280_fixup_hp_9480m(struct hda_codec *codec,
5485 const struct hda_fixup *fix,
5486 int action)
5487{
5488 struct alc_spec *spec = codec->spec;
Keith Packard98973f22015-07-15 12:14:39 -07005489
Takashi Iwai01e4a272018-06-19 22:47:30 +02005490 alc_fixup_hp_gpio_led(codec, action, 0x08, 0);
Keith Packard98973f22015-07-15 12:14:39 -07005491 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai01e4a272018-06-19 22:47:30 +02005492 /* amp at GPIO4; toggled via alc280_hp_gpio4_automute_hook() */
5493 spec->gpio_mask |= 0x10;
5494 spec->gpio_dir |= 0x10;
Keith Packard98973f22015-07-15 12:14:39 -07005495 spec->gen.hp_automute_hook = alc280_hp_gpio4_automute_hook;
Keith Packard98973f22015-07-15 12:14:39 -07005496 }
5497}
5498
Takashi Iwaiae065f12018-06-19 23:00:03 +02005499static void alc275_fixup_gpio4_off(struct hda_codec *codec,
5500 const struct hda_fixup *fix,
5501 int action)
5502{
5503 struct alc_spec *spec = codec->spec;
5504
5505 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5506 spec->gpio_mask |= 0x04;
5507 spec->gpio_dir |= 0x04;
5508 /* set data bit low */
5509 }
5510}
5511
Kailang Yangca169cc2017-04-25 16:17:40 +08005512static void alc233_alc662_fixup_lenovo_dual_codecs(struct hda_codec *codec,
5513 const struct hda_fixup *fix,
5514 int action)
5515{
5516 alc_fixup_dual_codecs(codec, fix, action);
5517 switch (action) {
5518 case HDA_FIXUP_ACT_PRE_PROBE:
5519 /* override card longname to provide a unique UCM profile */
5520 strcpy(codec->card->longname, "HDAudio-Lenovo-DualCodecs");
5521 break;
5522 case HDA_FIXUP_ACT_BUILD:
5523 /* rename Capture controls depending on the codec */
5524 rename_ctl(codec, "Capture Volume",
5525 codec->addr == 0 ?
5526 "Rear-Panel Capture Volume" :
5527 "Front-Panel Capture Volume");
5528 rename_ctl(codec, "Capture Switch",
5529 codec->addr == 0 ?
5530 "Rear-Panel Capture Switch" :
5531 "Front-Panel Capture Switch");
5532 break;
5533 }
5534}
5535
Kailang Yang92266652017-12-14 15:28:58 +08005536/* Forcibly assign NID 0x03 to HP/LO while NID 0x02 to SPK for EQ */
5537static void alc274_fixup_bind_dacs(struct hda_codec *codec,
5538 const struct hda_fixup *fix, int action)
5539{
5540 struct alc_spec *spec = codec->spec;
5541 static hda_nid_t preferred_pairs[] = {
5542 0x21, 0x03, 0x1b, 0x03, 0x16, 0x02,
5543 0
5544 };
5545
5546 if (action != HDA_FIXUP_ACT_PRE_PROBE)
5547 return;
5548
5549 spec->gen.preferred_dacs = preferred_pairs;
Kailang Yang0700d3d2019-04-26 16:13:54 +08005550 spec->gen.auto_mute_via_amp = 1;
5551 codec->power_save_node = 0;
Kailang Yang92266652017-12-14 15:28:58 +08005552}
5553
Hui Wangc4cfcf62018-11-26 14:17:16 +08005554/* The DAC of NID 0x3 will introduce click/pop noise on headphones, so invalidate it */
5555static void alc285_fixup_invalidate_dacs(struct hda_codec *codec,
5556 const struct hda_fixup *fix, int action)
5557{
5558 if (action != HDA_FIXUP_ACT_PRE_PROBE)
5559 return;
5560
5561 snd_hda_override_wcaps(codec, 0x03, 0);
5562}
5563
Kailang Yange8547472018-11-28 15:32:45 +08005564static const struct hda_jack_keymap alc_headset_btn_keymap[] = {
5565 { SND_JACK_BTN_0, KEY_PLAYPAUSE },
5566 { SND_JACK_BTN_1, KEY_VOICECOMMAND },
5567 { SND_JACK_BTN_2, KEY_VOLUMEUP },
5568 { SND_JACK_BTN_3, KEY_VOLUMEDOWN },
5569 {}
5570};
5571
5572static void alc_headset_btn_callback(struct hda_codec *codec,
5573 struct hda_jack_callback *jack)
5574{
5575 int report = 0;
5576
5577 if (jack->unsol_res & (7 << 13))
5578 report |= SND_JACK_BTN_0;
5579
5580 if (jack->unsol_res & (1 << 16 | 3 << 8))
5581 report |= SND_JACK_BTN_1;
5582
5583 /* Volume up key */
5584 if (jack->unsol_res & (7 << 23))
5585 report |= SND_JACK_BTN_2;
5586
5587 /* Volume down key */
5588 if (jack->unsol_res & (7 << 10))
5589 report |= SND_JACK_BTN_3;
5590
5591 jack->jack->button_state = report;
5592}
5593
Kailang Yang8983eb62019-04-03 15:31:49 +08005594static void alc_fixup_headset_jack(struct hda_codec *codec,
Kailang Yange8547472018-11-28 15:32:45 +08005595 const struct hda_fixup *fix, int action)
5596{
5597
5598 switch (action) {
5599 case HDA_FIXUP_ACT_PRE_PROBE:
5600 snd_hda_jack_detect_enable_callback(codec, 0x55,
5601 alc_headset_btn_callback);
5602 snd_hda_jack_add_kctl(codec, 0x55, "Headset Jack", false,
5603 SND_JACK_HEADSET, alc_headset_btn_keymap);
5604 break;
5605 case HDA_FIXUP_ACT_INIT:
5606 switch (codec->core.vendor_id) {
5607 case 0x10ec0225:
5608 case 0x10ec0295:
5609 case 0x10ec0299:
5610 alc_write_coef_idx(codec, 0x48, 0xd011);
5611 alc_update_coef_idx(codec, 0x49, 0x007f, 0x0045);
5612 alc_update_coef_idx(codec, 0x44, 0x007f << 8, 0x0045 << 8);
5613 break;
5614 case 0x10ec0236:
5615 case 0x10ec0256:
5616 alc_write_coef_idx(codec, 0x48, 0xd011);
5617 alc_update_coef_idx(codec, 0x49, 0x007f, 0x0045);
5618 break;
5619 }
5620 break;
5621 }
5622}
5623
Kailang Yang8983eb62019-04-03 15:31:49 +08005624static void alc295_fixup_chromebook(struct hda_codec *codec,
5625 const struct hda_fixup *fix, int action)
5626{
Kailang Yangd3ba58b2019-05-06 15:09:42 +08005627 struct alc_spec *spec = codec->spec;
5628
Kailang Yang8983eb62019-04-03 15:31:49 +08005629 switch (action) {
Kailang Yangd3ba58b2019-05-06 15:09:42 +08005630 case HDA_FIXUP_ACT_PRE_PROBE:
5631 spec->ultra_low_power = true;
5632 break;
Kailang Yang8983eb62019-04-03 15:31:49 +08005633 case HDA_FIXUP_ACT_INIT:
5634 switch (codec->core.vendor_id) {
5635 case 0x10ec0295:
5636 alc_update_coef_idx(codec, 0x4a, 0x8000, 1 << 15); /* Reset HP JD */
5637 alc_update_coef_idx(codec, 0x4a, 0x8000, 0 << 15);
5638 break;
5639 case 0x10ec0236:
5640 alc_update_coef_idx(codec, 0x1b, 0x8000, 1 << 15); /* Reset HP JD */
5641 alc_update_coef_idx(codec, 0x1b, 0x8000, 0 << 15);
5642 break;
5643 }
5644 break;
5645 }
5646}
5647
Kailang Yangd1dd4212019-01-09 17:05:24 +08005648static void alc_fixup_disable_mic_vref(struct hda_codec *codec,
5649 const struct hda_fixup *fix, int action)
5650{
5651 if (action == HDA_FIXUP_ACT_PRE_PROBE)
5652 snd_hda_codec_set_pin_target(codec, 0x19, PIN_VREFHIZ);
5653}
5654
Takashi Iwaib317b032014-01-08 11:44:21 +01005655/* for hda_fixup_thinkpad_acpi() */
5656#include "thinkpad_helper.c"
David Henningssonb67ae3f2013-11-05 13:11:37 +01005657
Takashi Iwaid5a6cab2018-06-13 12:43:10 +02005658static void alc_fixup_thinkpad_acpi(struct hda_codec *codec,
5659 const struct hda_fixup *fix, int action)
5660{
5661 alc_fixup_no_shutup(codec, fix, action); /* reduce click noise */
5662 hda_fixup_thinkpad_acpi(codec, fix, action);
5663}
5664
Tom Bridenbbf8ff62018-05-29 17:34:20 +01005665/* for alc295_fixup_hp_top_speakers */
5666#include "hp_x360_helper.c"
5667
Takashi Iwai1d045db2011-07-07 18:23:21 +02005668enum {
5669 ALC269_FIXUP_SONY_VAIO,
5670 ALC275_FIXUP_SONY_VAIO_GPIO2,
5671 ALC269_FIXUP_DELL_M101Z,
5672 ALC269_FIXUP_SKU_IGNORE,
5673 ALC269_FIXUP_ASUS_G73JW,
5674 ALC269_FIXUP_LENOVO_EAPD,
5675 ALC275_FIXUP_SONY_HWEQ,
Takashi Iwaie9bd7d52014-05-21 11:06:49 +02005676 ALC275_FIXUP_SONY_DISABLE_AAMIX,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005677 ALC271_FIXUP_DMIC,
Takashi Iwai017f2a12011-07-09 14:42:25 +02005678 ALC269_FIXUP_PCM_44K,
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02005679 ALC269_FIXUP_STEREO_DMIC,
David Henningsson7c478f02013-10-11 10:18:46 +02005680 ALC269_FIXUP_HEADSET_MIC,
Takashi Iwai24519912011-08-16 15:08:49 +02005681 ALC269_FIXUP_QUANTA_MUTE,
5682 ALC269_FIXUP_LIFEBOOK,
David Henningsson2041d562014-06-13 11:15:44 +02005683 ALC269_FIXUP_LIFEBOOK_EXTMIC,
Takashi Iwaicc7016a2015-04-08 20:47:55 +02005684 ALC269_FIXUP_LIFEBOOK_HP_PIN,
Takashi Iwai4df3fd12015-06-29 08:38:02 +02005685 ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT,
Jan-Marek Glogowskifdcc9682018-02-14 11:29:15 +01005686 ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC,
Takashi Iwaia4297b52011-08-23 18:40:12 +02005687 ALC269_FIXUP_AMIC,
5688 ALC269_FIXUP_DMIC,
5689 ALC269VB_FIXUP_AMIC,
5690 ALC269VB_FIXUP_DMIC,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01005691 ALC269_FIXUP_HP_MUTE_LED,
David Henningssond06ac142013-02-18 11:41:55 +01005692 ALC269_FIXUP_HP_MUTE_LED_MIC1,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01005693 ALC269_FIXUP_HP_MUTE_LED_MIC2,
Tom Briden7f783bd2017-03-25 10:12:01 +00005694 ALC269_FIXUP_HP_MUTE_LED_MIC3,
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01005695 ALC269_FIXUP_HP_GPIO_LED,
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08005696 ALC269_FIXUP_HP_GPIO_MIC1_LED,
5697 ALC269_FIXUP_HP_LINE1_MIC1_LED,
David Henningsson693b6132012-06-22 19:12:10 +02005698 ALC269_FIXUP_INV_DMIC,
David Henningsson108cc102012-07-20 10:37:25 +02005699 ALC269_FIXUP_LENOVO_DOCK,
Takashi Iwai9b745ab2014-03-07 08:37:19 +01005700 ALC269_FIXUP_NO_SHUTUP,
David Henningsson88cfcf82013-10-11 10:18:45 +02005701 ALC286_FIXUP_SONY_MIC_NO_PRESENCE,
David Henningsson108cc102012-07-20 10:37:25 +02005702 ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT,
David Henningsson73bdd592013-04-15 15:44:14 +02005703 ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
5704 ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
David Henningsson338cae52013-10-07 10:39:59 +02005705 ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
Kailang Yangfcc6c872017-06-29 15:21:27 +08005706 ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
David Henningsson73bdd592013-04-15 15:44:14 +02005707 ALC269_FIXUP_HEADSET_MODE,
5708 ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC,
Takashi Iwai78197172015-06-27 10:21:13 +02005709 ALC269_FIXUP_ASPIRE_HEADSET_MIC,
David Henningssond240d1d2013-04-15 12:50:02 +02005710 ALC269_FIXUP_ASUS_X101_FUNC,
5711 ALC269_FIXUP_ASUS_X101_VERB,
5712 ALC269_FIXUP_ASUS_X101,
Dylan Reid08a978d2012-11-18 22:56:40 -08005713 ALC271_FIXUP_AMIC_MIC2,
5714 ALC271_FIXUP_HP_GATE_MIC_JACK,
Oleksij Rempelb1e89722013-12-04 20:50:53 +01005715 ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572,
Dylan Reid42397002013-04-05 14:58:22 -07005716 ALC269_FIXUP_ACER_AC700,
David Henningsson3e0d6112013-04-22 14:30:14 +02005717 ALC269_FIXUP_LIMIT_INT_MIC_BOOST,
Oleksij Rempel2cede302013-11-27 17:12:03 +01005718 ALC269VB_FIXUP_ASUS_ZENBOOK,
Takashi Iwai23870832013-11-29 14:13:12 +01005719 ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A,
David Henningsson8e35cd42013-11-06 11:20:01 +01005720 ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED,
Anisse Astier02b504d2013-06-03 11:53:10 +02005721 ALC269VB_FIXUP_ORDISSIMO_EVE2,
Kailang Yangcd217a62013-08-22 10:15:24 +02005722 ALC283_FIXUP_CHROME_BOOK,
Kailang Yang0202e992013-12-02 15:20:15 +08005723 ALC283_FIXUP_SENSE_COMBO_JACK,
Takashi Iwai7bba2152013-09-06 15:45:38 +02005724 ALC282_FIXUP_ASUS_TX300,
Kailang Yang1bb3e062013-09-27 13:10:25 +02005725 ALC283_FIXUP_INT_MIC,
David Henningsson338cae52013-10-07 10:39:59 +02005726 ALC290_FIXUP_MONO_SPEAKERS,
David Henningsson0f4881d2013-12-20 16:08:13 +01005727 ALC290_FIXUP_MONO_SPEAKERS_HSJACK,
5728 ALC290_FIXUP_SUBWOOFER,
5729 ALC290_FIXUP_SUBWOOFER_HSJACK,
David Henningssonb67ae3f2013-11-05 13:11:37 +01005730 ALC269_FIXUP_THINKPAD_ACPI,
David Henningsson56f27012016-01-11 09:33:14 +01005731 ALC269_FIXUP_DMIC_THINKPAD_ACPI,
Chris Chiu5824ce82017-02-28 14:17:11 -06005732 ALC255_FIXUP_ACER_MIC_NO_PRESENCE,
Chris Chiu615966a2017-02-28 14:17:12 -06005733 ALC255_FIXUP_ASUS_MIC_NO_PRESENCE,
Kailang Yang9a22a8f52013-11-08 15:54:49 +08005734 ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Kailang Yang31278992014-03-03 15:27:22 +08005735 ALC255_FIXUP_DELL2_MIC_NO_PRESENCE,
Kailang Yang9a22a8f52013-11-08 15:54:49 +08005736 ALC255_FIXUP_HEADSET_MODE,
Kailang Yang31278992014-03-03 15:27:22 +08005737 ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC,
Kailang Yanga22aa262014-04-23 17:34:28 +08005738 ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
Takashi Iwai1c37c222014-05-06 17:34:42 +02005739 ALC292_FIXUP_TPT440_DOCK,
Takashi Iwai9a811232015-12-09 15:17:43 +01005740 ALC292_FIXUP_TPT440,
Anisse Astierabaa22742016-08-24 09:14:13 +02005741 ALC283_FIXUP_HEADSET_MIC,
Takashi Iwaib3802782018-11-26 17:47:46 +01005742 ALC255_FIXUP_MIC_MUTE_LED,
Takashi Iwai1a22e772014-08-27 08:19:05 +02005743 ALC282_FIXUP_ASPIRE_V5_PINS,
David Henningsson7a5255f2014-10-30 08:26:01 +01005744 ALC280_FIXUP_HP_GPIO4,
Kailang Yangeaa8e5e2014-11-21 15:49:11 +08005745 ALC286_FIXUP_HP_GPIO_LED,
David Henningsson33f4acd2015-01-07 15:50:13 +01005746 ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY,
TienFu Chenb4b33f92015-01-20 15:06:21 +01005747 ALC280_FIXUP_HP_DOCK_PINS,
Jaroslav Kysela04d54662017-03-09 13:29:13 +01005748 ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED,
Keith Packard98973f22015-07-15 12:14:39 -07005749 ALC280_FIXUP_HP_9480M,
Kailang Yange1e62b92015-04-08 16:01:22 +08005750 ALC288_FIXUP_DELL_HEADSET_MODE,
5751 ALC288_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang831bfdf92015-06-26 12:35:17 +08005752 ALC288_FIXUP_DELL_XPS_13,
5753 ALC288_FIXUP_DISABLE_AAMIX,
Takashi Iwai8b99aba2015-06-15 11:59:32 +02005754 ALC292_FIXUP_DELL_E7X,
5755 ALC292_FIXUP_DISABLE_AAMIX,
David Henningssonc04017e2015-12-15 14:44:03 +01005756 ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK,
Kailang Yang977e6272015-05-18 15:31:20 +08005757 ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang2f726ae2017-03-31 10:31:40 +08005758 ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE,
Kailang Yang6ed11312015-10-26 15:37:39 +08005759 ALC275_FIXUP_DELL_XPS,
Hui Wang8c697292015-11-24 11:08:18 +08005760 ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE,
Hui Wang23adc192015-12-08 12:27:18 +08005761 ALC293_FIXUP_LENOVO_SPK_NOISE,
Kailang3694cb22015-12-28 11:35:24 +08005762 ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY,
Kai-Heng Feng3b43b712016-02-25 15:19:38 +08005763 ALC255_FIXUP_DELL_SPK_NOISE,
Kailang Yangd1dd4212019-01-09 17:05:24 +08005764 ALC225_FIXUP_DISABLE_MIC_VREF,
David Henningsson2ae95572016-02-25 09:37:05 +01005765 ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
Takashi Iwaie312a862018-03-06 12:14:17 +01005766 ALC295_FIXUP_DISABLE_DAC3,
Takashi Iwaif8839822016-02-25 14:31:59 +01005767 ALC280_FIXUP_HP_HEADSET_MIC,
Hui Wange549d192016-04-01 11:00:15 +08005768 ALC221_FIXUP_HP_FRONT_MIC,
Sven Eckelmannc636b952016-04-11 16:55:26 +02005769 ALC292_FIXUP_TPT460,
Hui Wangdd9aa332016-08-01 10:20:32 +08005770 ALC298_FIXUP_SPK_VOLUME,
Kai-Heng Fengfd06c772016-08-30 15:36:34 +08005771 ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER,
Gabriele Mazzotta823ff162016-12-24 19:50:01 +01005772 ALC269_FIXUP_ATIV_BOOK_8,
Kailang Yang9eb5d0e2017-01-17 15:40:25 +08005773 ALC221_FIXUP_HP_MIC_NO_PRESENCE,
Chris Chiuc1732ed2017-02-28 14:17:13 -06005774 ALC256_FIXUP_ASUS_HEADSET_MODE,
5775 ALC256_FIXUP_ASUS_MIC,
Chris Chiueeed4cd2017-02-28 14:17:15 -06005776 ALC256_FIXUP_ASUS_AIO_GPIO2,
Chris Chiu216d7ae2017-02-28 14:17:14 -06005777 ALC233_FIXUP_ASUS_MIC_NO_PRESENCE,
5778 ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE,
Kailang Yangca169cc2017-04-25 16:17:40 +08005779 ALC233_FIXUP_LENOVO_MULTI_CODECS,
Jian-Hong Panea5c7eb2019-04-01 11:25:05 +08005780 ALC233_FIXUP_ACER_HEADSET_MIC,
Hui Wangf33f79f2017-07-07 12:08:29 +08005781 ALC294_FIXUP_LENOVO_MIC_LOCATION,
Kailang Yang5f364132017-07-25 16:28:16 +08005782 ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE,
PeiSen Houb84e8432017-09-01 15:11:56 +08005783 ALC700_FIXUP_INTEL_REFERENCE,
Kailang Yang92266652017-12-14 15:28:58 +08005784 ALC274_FIXUP_DELL_BIND_DACS,
5785 ALC274_FIXUP_DELL_AIO_LINEOUT_VERB,
Kailang Yang61fcf8e2018-02-02 15:26:46 +08005786 ALC298_FIXUP_TPT470_DOCK,
Kailang Yangae104a22018-02-05 16:07:20 +08005787 ALC255_FIXUP_DUMMY_LINEOUT_VERB,
Kailang Yangf0ba9d62018-03-16 11:46:08 +08005788 ALC255_FIXUP_DELL_HEADSET_MIC,
Ayman Bagabas0fbf21c2019-05-23 05:30:11 -04005789 ALC256_FIXUP_HUAWEI_MACH_WX9_PINS,
Tom Bridenbbf8ff62018-05-29 17:34:20 +01005790 ALC295_FIXUP_HP_X360,
Kailang Yang8a328ac2018-08-21 16:54:41 +08005791 ALC221_FIXUP_HP_HEADSET_MIC,
Hui Wangc4cfcf62018-11-26 14:17:16 +08005792 ALC285_FIXUP_LENOVO_HEADPHONE_NOISE,
Girija Kumar Kasinadhunie8ed64b2018-11-26 13:40:46 -05005793 ALC295_FIXUP_HP_AUTO_MUTE,
Chris Chiu33aaebd2018-12-05 14:48:53 +08005794 ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE,
Chris Chiud8ae4582018-12-07 17:17:11 +08005795 ALC294_FIXUP_ASUS_MIC,
Jian-Hong Pan4e051102018-12-07 17:17:12 +08005796 ALC294_FIXUP_ASUS_HEADSET_MIC,
5797 ALC294_FIXUP_ASUS_SPK,
Jeremy Soller89e3a562019-01-30 16:12:31 -07005798 ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE,
Hui Wangc8c6ee62019-02-14 11:41:33 +08005799 ALC285_FIXUP_LENOVO_PC_BEEP_IN_NOISE,
Jian-Hong Pancbc05fd2019-03-13 17:33:24 +08005800 ALC255_FIXUP_ACER_HEADSET_MIC,
Kailang Yang10f5b1b2019-02-21 16:10:22 +08005801 ALC295_FIXUP_CHROME_BOOK,
Kailang Yang8983eb62019-04-03 15:31:49 +08005802 ALC225_FIXUP_HEADSET_JACK,
Kailang Yang136824e2019-03-14 16:22:45 +08005803 ALC225_FIXUP_DELL_WYSE_AIO_MIC_NO_PRESENCE,
5804 ALC225_FIXUP_WYSE_AUTO_MUTE,
5805 ALC225_FIXUP_WYSE_DISABLE_MIC_VREF,
Jian-Hong Pan667a8f72019-03-15 17:51:09 +08005806 ALC286_FIXUP_ACER_AIO_HEADSET_MIC,
Jian-Hong Pane1037352019-03-22 11:37:18 +08005807 ALC256_FIXUP_ASUS_MIC_NO_PRESENCE,
Bernhard Rosenkraenzere2a829b2019-03-05 00:38:19 +01005808 ALC299_FIXUP_PREDATOR_SPK,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005809};
5810
Takashi Iwai1727a772013-01-10 09:52:52 +01005811static const struct hda_fixup alc269_fixups[] = {
Takashi Iwai1d045db2011-07-07 18:23:21 +02005812 [ALC269_FIXUP_SONY_VAIO] = {
Takashi Iwaifd108212013-01-10 10:18:14 +01005813 .type = HDA_FIXUP_PINCTLS,
5814 .v.pins = (const struct hda_pintbl[]) {
5815 {0x19, PIN_VREFGRD},
Takashi Iwai1d045db2011-07-07 18:23:21 +02005816 {}
5817 }
5818 },
5819 [ALC275_FIXUP_SONY_VAIO_GPIO2] = {
Takashi Iwaiae065f12018-06-19 23:00:03 +02005820 .type = HDA_FIXUP_FUNC,
5821 .v.func = alc275_fixup_gpio4_off,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005822 .chained = true,
5823 .chain_id = ALC269_FIXUP_SONY_VAIO
5824 },
5825 [ALC269_FIXUP_DELL_M101Z] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005826 .type = HDA_FIXUP_VERBS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005827 .v.verbs = (const struct hda_verb[]) {
5828 /* Enables internal speaker */
5829 {0x20, AC_VERB_SET_COEF_INDEX, 13},
5830 {0x20, AC_VERB_SET_PROC_COEF, 0x4040},
5831 {}
5832 }
5833 },
5834 [ALC269_FIXUP_SKU_IGNORE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005835 .type = HDA_FIXUP_FUNC,
Takashi Iwai23d30f22012-05-07 17:17:32 +02005836 .v.func = alc_fixup_sku_ignore,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005837 },
5838 [ALC269_FIXUP_ASUS_G73JW] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005839 .type = HDA_FIXUP_PINS,
5840 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02005841 { 0x17, 0x99130111 }, /* subwoofer */
5842 { }
5843 }
5844 },
5845 [ALC269_FIXUP_LENOVO_EAPD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005846 .type = HDA_FIXUP_VERBS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005847 .v.verbs = (const struct hda_verb[]) {
5848 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
5849 {}
5850 }
5851 },
5852 [ALC275_FIXUP_SONY_HWEQ] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005853 .type = HDA_FIXUP_FUNC,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005854 .v.func = alc269_fixup_hweq,
5855 .chained = true,
5856 .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2
5857 },
Takashi Iwaie9bd7d52014-05-21 11:06:49 +02005858 [ALC275_FIXUP_SONY_DISABLE_AAMIX] = {
5859 .type = HDA_FIXUP_FUNC,
5860 .v.func = alc_fixup_disable_aamix,
5861 .chained = true,
5862 .chain_id = ALC269_FIXUP_SONY_VAIO
5863 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02005864 [ALC271_FIXUP_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005865 .type = HDA_FIXUP_FUNC,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005866 .v.func = alc271_fixup_dmic,
5867 },
Takashi Iwai017f2a12011-07-09 14:42:25 +02005868 [ALC269_FIXUP_PCM_44K] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005869 .type = HDA_FIXUP_FUNC,
Takashi Iwai017f2a12011-07-09 14:42:25 +02005870 .v.func = alc269_fixup_pcm_44k,
David Henningsson012e7eb2012-08-08 08:43:37 +02005871 .chained = true,
5872 .chain_id = ALC269_FIXUP_QUANTA_MUTE
Takashi Iwai017f2a12011-07-09 14:42:25 +02005873 },
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02005874 [ALC269_FIXUP_STEREO_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005875 .type = HDA_FIXUP_FUNC,
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02005876 .v.func = alc269_fixup_stereo_dmic,
5877 },
David Henningsson7c478f02013-10-11 10:18:46 +02005878 [ALC269_FIXUP_HEADSET_MIC] = {
5879 .type = HDA_FIXUP_FUNC,
5880 .v.func = alc269_fixup_headset_mic,
5881 },
Takashi Iwai24519912011-08-16 15:08:49 +02005882 [ALC269_FIXUP_QUANTA_MUTE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005883 .type = HDA_FIXUP_FUNC,
Takashi Iwai24519912011-08-16 15:08:49 +02005884 .v.func = alc269_fixup_quanta_mute,
5885 },
5886 [ALC269_FIXUP_LIFEBOOK] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005887 .type = HDA_FIXUP_PINS,
5888 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai24519912011-08-16 15:08:49 +02005889 { 0x1a, 0x2101103f }, /* dock line-out */
5890 { 0x1b, 0x23a11040 }, /* dock mic-in */
5891 { }
5892 },
5893 .chained = true,
5894 .chain_id = ALC269_FIXUP_QUANTA_MUTE
5895 },
David Henningsson2041d562014-06-13 11:15:44 +02005896 [ALC269_FIXUP_LIFEBOOK_EXTMIC] = {
5897 .type = HDA_FIXUP_PINS,
5898 .v.pins = (const struct hda_pintbl[]) {
5899 { 0x19, 0x01a1903c }, /* headset mic, with jack detect */
5900 { }
5901 },
5902 },
Takashi Iwaicc7016a2015-04-08 20:47:55 +02005903 [ALC269_FIXUP_LIFEBOOK_HP_PIN] = {
5904 .type = HDA_FIXUP_PINS,
5905 .v.pins = (const struct hda_pintbl[]) {
5906 { 0x21, 0x0221102f }, /* HP out */
5907 { }
5908 },
5909 },
Takashi Iwai4df3fd12015-06-29 08:38:02 +02005910 [ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT] = {
5911 .type = HDA_FIXUP_FUNC,
5912 .v.func = alc269_fixup_pincfg_no_hp_to_lineout,
5913 },
Jan-Marek Glogowskifdcc9682018-02-14 11:29:15 +01005914 [ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC] = {
5915 .type = HDA_FIXUP_FUNC,
5916 .v.func = alc269_fixup_pincfg_U7x7_headset_mic,
5917 },
Takashi Iwaia4297b52011-08-23 18:40:12 +02005918 [ALC269_FIXUP_AMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005919 .type = HDA_FIXUP_PINS,
5920 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaia4297b52011-08-23 18:40:12 +02005921 { 0x14, 0x99130110 }, /* speaker */
5922 { 0x15, 0x0121401f }, /* HP out */
5923 { 0x18, 0x01a19c20 }, /* mic */
5924 { 0x19, 0x99a3092f }, /* int-mic */
5925 { }
5926 },
5927 },
5928 [ALC269_FIXUP_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005929 .type = HDA_FIXUP_PINS,
5930 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaia4297b52011-08-23 18:40:12 +02005931 { 0x12, 0x99a3092f }, /* int-mic */
5932 { 0x14, 0x99130110 }, /* speaker */
5933 { 0x15, 0x0121401f }, /* HP out */
5934 { 0x18, 0x01a19c20 }, /* mic */
5935 { }
5936 },
5937 },
5938 [ALC269VB_FIXUP_AMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005939 .type = HDA_FIXUP_PINS,
5940 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaia4297b52011-08-23 18:40:12 +02005941 { 0x14, 0x99130110 }, /* speaker */
5942 { 0x18, 0x01a19c20 }, /* mic */
5943 { 0x19, 0x99a3092f }, /* int-mic */
5944 { 0x21, 0x0121401f }, /* HP out */
5945 { }
5946 },
5947 },
David Henningsson2267ea92012-01-03 08:45:56 +01005948 [ALC269VB_FIXUP_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005949 .type = HDA_FIXUP_PINS,
5950 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaia4297b52011-08-23 18:40:12 +02005951 { 0x12, 0x99a3092f }, /* int-mic */
5952 { 0x14, 0x99130110 }, /* speaker */
5953 { 0x18, 0x01a19c20 }, /* mic */
5954 { 0x21, 0x0121401f }, /* HP out */
5955 { }
5956 },
5957 },
Takashi Iwai08fb0d02013-01-10 17:33:58 +01005958 [ALC269_FIXUP_HP_MUTE_LED] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005959 .type = HDA_FIXUP_FUNC,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01005960 .v.func = alc269_fixup_hp_mute_led,
David Henningsson6d3cd5d2013-01-07 12:03:47 +01005961 },
David Henningssond06ac142013-02-18 11:41:55 +01005962 [ALC269_FIXUP_HP_MUTE_LED_MIC1] = {
5963 .type = HDA_FIXUP_FUNC,
5964 .v.func = alc269_fixup_hp_mute_led_mic1,
5965 },
Takashi Iwai08fb0d02013-01-10 17:33:58 +01005966 [ALC269_FIXUP_HP_MUTE_LED_MIC2] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005967 .type = HDA_FIXUP_FUNC,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01005968 .v.func = alc269_fixup_hp_mute_led_mic2,
Takashi Iwai420b0fe2012-03-12 12:35:27 +01005969 },
Tom Briden7f783bd2017-03-25 10:12:01 +00005970 [ALC269_FIXUP_HP_MUTE_LED_MIC3] = {
5971 .type = HDA_FIXUP_FUNC,
5972 .v.func = alc269_fixup_hp_mute_led_mic3,
Girija Kumar Kasinadhunie8ed64b2018-11-26 13:40:46 -05005973 .chained = true,
5974 .chain_id = ALC295_FIXUP_HP_AUTO_MUTE
Tom Briden7f783bd2017-03-25 10:12:01 +00005975 },
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01005976 [ALC269_FIXUP_HP_GPIO_LED] = {
5977 .type = HDA_FIXUP_FUNC,
5978 .v.func = alc269_fixup_hp_gpio_led,
5979 },
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08005980 [ALC269_FIXUP_HP_GPIO_MIC1_LED] = {
5981 .type = HDA_FIXUP_FUNC,
5982 .v.func = alc269_fixup_hp_gpio_mic1_led,
5983 },
5984 [ALC269_FIXUP_HP_LINE1_MIC1_LED] = {
5985 .type = HDA_FIXUP_FUNC,
5986 .v.func = alc269_fixup_hp_line1_mic1_led,
5987 },
David Henningsson693b6132012-06-22 19:12:10 +02005988 [ALC269_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005989 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02005990 .v.func = alc_fixup_inv_dmic,
David Henningsson693b6132012-06-22 19:12:10 +02005991 },
Takashi Iwai9b745ab2014-03-07 08:37:19 +01005992 [ALC269_FIXUP_NO_SHUTUP] = {
5993 .type = HDA_FIXUP_FUNC,
5994 .v.func = alc_fixup_no_shutup,
5995 },
David Henningsson108cc102012-07-20 10:37:25 +02005996 [ALC269_FIXUP_LENOVO_DOCK] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005997 .type = HDA_FIXUP_PINS,
5998 .v.pins = (const struct hda_pintbl[]) {
David Henningsson108cc102012-07-20 10:37:25 +02005999 { 0x19, 0x23a11040 }, /* dock mic */
6000 { 0x1b, 0x2121103f }, /* dock headphone */
6001 { }
6002 },
6003 .chained = true,
6004 .chain_id = ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT
6005 },
6006 [ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006007 .type = HDA_FIXUP_FUNC,
David Henningsson108cc102012-07-20 10:37:25 +02006008 .v.func = alc269_fixup_pincfg_no_hp_to_lineout,
David Henningsson52129002013-11-19 10:25:53 +01006009 .chained = true,
6010 .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
David Henningsson108cc102012-07-20 10:37:25 +02006011 },
David Henningsson73bdd592013-04-15 15:44:14 +02006012 [ALC269_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6013 .type = HDA_FIXUP_PINS,
6014 .v.pins = (const struct hda_pintbl[]) {
6015 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6016 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6017 { }
6018 },
6019 .chained = true,
6020 .chain_id = ALC269_FIXUP_HEADSET_MODE
6021 },
6022 [ALC269_FIXUP_DELL2_MIC_NO_PRESENCE] = {
6023 .type = HDA_FIXUP_PINS,
6024 .v.pins = (const struct hda_pintbl[]) {
6025 { 0x16, 0x21014020 }, /* dock line out */
6026 { 0x19, 0x21a19030 }, /* dock mic */
6027 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6028 { }
6029 },
6030 .chained = true,
6031 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
6032 },
David Henningsson338cae52013-10-07 10:39:59 +02006033 [ALC269_FIXUP_DELL3_MIC_NO_PRESENCE] = {
6034 .type = HDA_FIXUP_PINS,
6035 .v.pins = (const struct hda_pintbl[]) {
6036 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6037 { }
6038 },
6039 .chained = true,
6040 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
6041 },
Kailang Yangfcc6c872017-06-29 15:21:27 +08006042 [ALC269_FIXUP_DELL4_MIC_NO_PRESENCE] = {
6043 .type = HDA_FIXUP_PINS,
6044 .v.pins = (const struct hda_pintbl[]) {
6045 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6046 { 0x1b, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6047 { }
6048 },
6049 .chained = true,
6050 .chain_id = ALC269_FIXUP_HEADSET_MODE
6051 },
David Henningsson73bdd592013-04-15 15:44:14 +02006052 [ALC269_FIXUP_HEADSET_MODE] = {
6053 .type = HDA_FIXUP_FUNC,
6054 .v.func = alc_fixup_headset_mode,
Hui Wang6676f302014-11-18 17:57:41 +08006055 .chained = true,
Takashi Iwaib3802782018-11-26 17:47:46 +01006056 .chain_id = ALC255_FIXUP_MIC_MUTE_LED
David Henningsson73bdd592013-04-15 15:44:14 +02006057 },
6058 [ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC] = {
6059 .type = HDA_FIXUP_FUNC,
6060 .v.func = alc_fixup_headset_mode_no_hp_mic,
6061 },
Takashi Iwai78197172015-06-27 10:21:13 +02006062 [ALC269_FIXUP_ASPIRE_HEADSET_MIC] = {
6063 .type = HDA_FIXUP_PINS,
6064 .v.pins = (const struct hda_pintbl[]) {
6065 { 0x19, 0x01a1913c }, /* headset mic w/o jack detect */
6066 { }
6067 },
6068 .chained = true,
6069 .chain_id = ALC269_FIXUP_HEADSET_MODE,
6070 },
David Henningsson88cfcf82013-10-11 10:18:45 +02006071 [ALC286_FIXUP_SONY_MIC_NO_PRESENCE] = {
6072 .type = HDA_FIXUP_PINS,
6073 .v.pins = (const struct hda_pintbl[]) {
6074 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6075 { }
6076 },
David Henningssonfbc78ad2013-10-11 13:46:04 +02006077 .chained = true,
6078 .chain_id = ALC269_FIXUP_HEADSET_MIC
David Henningsson88cfcf82013-10-11 10:18:45 +02006079 },
Ayman Bagabas0fbf21c2019-05-23 05:30:11 -04006080 [ALC256_FIXUP_HUAWEI_MACH_WX9_PINS] = {
Ayman Bagabas8ac51bb2018-12-12 18:07:57 -05006081 .type = HDA_FIXUP_PINS,
6082 .v.pins = (const struct hda_pintbl[]) {
6083 {0x12, 0x90a60130},
6084 {0x13, 0x40000000},
6085 {0x14, 0x90170110},
6086 {0x18, 0x411111f0},
6087 {0x19, 0x04a11040},
6088 {0x1a, 0x411111f0},
6089 {0x1b, 0x90170112},
6090 {0x1d, 0x40759a05},
6091 {0x1e, 0x411111f0},
6092 {0x21, 0x04211020},
6093 { }
6094 },
Ayman Bagabase2744fd2018-12-12 18:07:59 -05006095 .chained = true,
6096 .chain_id = ALC255_FIXUP_MIC_MUTE_LED
Ayman Bagabas8ac51bb2018-12-12 18:07:57 -05006097 },
David Henningssond240d1d2013-04-15 12:50:02 +02006098 [ALC269_FIXUP_ASUS_X101_FUNC] = {
6099 .type = HDA_FIXUP_FUNC,
6100 .v.func = alc269_fixup_x101_headset_mic,
6101 },
6102 [ALC269_FIXUP_ASUS_X101_VERB] = {
6103 .type = HDA_FIXUP_VERBS,
6104 .v.verbs = (const struct hda_verb[]) {
6105 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6106 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
6107 {0x20, AC_VERB_SET_PROC_COEF, 0x0310},
6108 { }
6109 },
6110 .chained = true,
6111 .chain_id = ALC269_FIXUP_ASUS_X101_FUNC
6112 },
6113 [ALC269_FIXUP_ASUS_X101] = {
6114 .type = HDA_FIXUP_PINS,
6115 .v.pins = (const struct hda_pintbl[]) {
6116 { 0x18, 0x04a1182c }, /* Headset mic */
6117 { }
6118 },
6119 .chained = true,
6120 .chain_id = ALC269_FIXUP_ASUS_X101_VERB
6121 },
Dylan Reid08a978d2012-11-18 22:56:40 -08006122 [ALC271_FIXUP_AMIC_MIC2] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006123 .type = HDA_FIXUP_PINS,
6124 .v.pins = (const struct hda_pintbl[]) {
Dylan Reid08a978d2012-11-18 22:56:40 -08006125 { 0x14, 0x99130110 }, /* speaker */
6126 { 0x19, 0x01a19c20 }, /* mic */
6127 { 0x1b, 0x99a7012f }, /* int-mic */
6128 { 0x21, 0x0121401f }, /* HP out */
6129 { }
6130 },
6131 },
6132 [ALC271_FIXUP_HP_GATE_MIC_JACK] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006133 .type = HDA_FIXUP_FUNC,
Dylan Reid08a978d2012-11-18 22:56:40 -08006134 .v.func = alc271_hp_gate_mic_jack,
6135 .chained = true,
6136 .chain_id = ALC271_FIXUP_AMIC_MIC2,
6137 },
Oleksij Rempelb1e89722013-12-04 20:50:53 +01006138 [ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572] = {
6139 .type = HDA_FIXUP_FUNC,
6140 .v.func = alc269_fixup_limit_int_mic_boost,
6141 .chained = true,
6142 .chain_id = ALC271_FIXUP_HP_GATE_MIC_JACK,
6143 },
Dylan Reid42397002013-04-05 14:58:22 -07006144 [ALC269_FIXUP_ACER_AC700] = {
6145 .type = HDA_FIXUP_PINS,
6146 .v.pins = (const struct hda_pintbl[]) {
6147 { 0x12, 0x99a3092f }, /* int-mic */
6148 { 0x14, 0x99130110 }, /* speaker */
6149 { 0x18, 0x03a11c20 }, /* mic */
6150 { 0x1e, 0x0346101e }, /* SPDIF1 */
6151 { 0x21, 0x0321101f }, /* HP out */
6152 { }
6153 },
6154 .chained = true,
6155 .chain_id = ALC271_FIXUP_DMIC,
6156 },
David Henningsson3e0d6112013-04-22 14:30:14 +02006157 [ALC269_FIXUP_LIMIT_INT_MIC_BOOST] = {
6158 .type = HDA_FIXUP_FUNC,
6159 .v.func = alc269_fixup_limit_int_mic_boost,
David Henningsson27937692013-11-18 11:51:47 +01006160 .chained = true,
6161 .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
David Henningsson3e0d6112013-04-22 14:30:14 +02006162 },
Oleksij Rempel2cede302013-11-27 17:12:03 +01006163 [ALC269VB_FIXUP_ASUS_ZENBOOK] = {
6164 .type = HDA_FIXUP_FUNC,
6165 .v.func = alc269_fixup_limit_int_mic_boost,
6166 .chained = true,
6167 .chain_id = ALC269VB_FIXUP_DMIC,
6168 },
Takashi Iwai23870832013-11-29 14:13:12 +01006169 [ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A] = {
6170 .type = HDA_FIXUP_VERBS,
6171 .v.verbs = (const struct hda_verb[]) {
6172 /* class-D output amp +5dB */
6173 { 0x20, AC_VERB_SET_COEF_INDEX, 0x12 },
6174 { 0x20, AC_VERB_SET_PROC_COEF, 0x2800 },
6175 {}
6176 },
6177 .chained = true,
6178 .chain_id = ALC269VB_FIXUP_ASUS_ZENBOOK,
6179 },
David Henningsson8e35cd42013-11-06 11:20:01 +01006180 [ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED] = {
6181 .type = HDA_FIXUP_FUNC,
6182 .v.func = alc269_fixup_limit_int_mic_boost,
6183 .chained = true,
6184 .chain_id = ALC269_FIXUP_HP_MUTE_LED_MIC1,
6185 },
Anisse Astier02b504d2013-06-03 11:53:10 +02006186 [ALC269VB_FIXUP_ORDISSIMO_EVE2] = {
6187 .type = HDA_FIXUP_PINS,
6188 .v.pins = (const struct hda_pintbl[]) {
6189 { 0x12, 0x99a3092f }, /* int-mic */
6190 { 0x18, 0x03a11d20 }, /* mic */
6191 { 0x19, 0x411111f0 }, /* Unused bogus pin */
6192 { }
6193 },
6194 },
Kailang Yangcd217a62013-08-22 10:15:24 +02006195 [ALC283_FIXUP_CHROME_BOOK] = {
6196 .type = HDA_FIXUP_FUNC,
6197 .v.func = alc283_fixup_chromebook,
6198 },
Kailang Yang0202e992013-12-02 15:20:15 +08006199 [ALC283_FIXUP_SENSE_COMBO_JACK] = {
6200 .type = HDA_FIXUP_FUNC,
6201 .v.func = alc283_fixup_sense_combo_jack,
6202 .chained = true,
6203 .chain_id = ALC283_FIXUP_CHROME_BOOK,
6204 },
Takashi Iwai7bba2152013-09-06 15:45:38 +02006205 [ALC282_FIXUP_ASUS_TX300] = {
6206 .type = HDA_FIXUP_FUNC,
6207 .v.func = alc282_fixup_asus_tx300,
6208 },
Kailang Yang1bb3e062013-09-27 13:10:25 +02006209 [ALC283_FIXUP_INT_MIC] = {
6210 .type = HDA_FIXUP_VERBS,
6211 .v.verbs = (const struct hda_verb[]) {
6212 {0x20, AC_VERB_SET_COEF_INDEX, 0x1a},
6213 {0x20, AC_VERB_SET_PROC_COEF, 0x0011},
6214 { }
6215 },
6216 .chained = true,
6217 .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST
6218 },
David Henningsson0f4881d2013-12-20 16:08:13 +01006219 [ALC290_FIXUP_SUBWOOFER_HSJACK] = {
6220 .type = HDA_FIXUP_PINS,
6221 .v.pins = (const struct hda_pintbl[]) {
6222 { 0x17, 0x90170112 }, /* subwoofer */
6223 { }
6224 },
6225 .chained = true,
6226 .chain_id = ALC290_FIXUP_MONO_SPEAKERS_HSJACK,
6227 },
6228 [ALC290_FIXUP_SUBWOOFER] = {
6229 .type = HDA_FIXUP_PINS,
6230 .v.pins = (const struct hda_pintbl[]) {
6231 { 0x17, 0x90170112 }, /* subwoofer */
6232 { }
6233 },
6234 .chained = true,
6235 .chain_id = ALC290_FIXUP_MONO_SPEAKERS,
6236 },
David Henningsson338cae52013-10-07 10:39:59 +02006237 [ALC290_FIXUP_MONO_SPEAKERS] = {
6238 .type = HDA_FIXUP_FUNC,
6239 .v.func = alc290_fixup_mono_speakers,
David Henningsson0f4881d2013-12-20 16:08:13 +01006240 },
6241 [ALC290_FIXUP_MONO_SPEAKERS_HSJACK] = {
6242 .type = HDA_FIXUP_FUNC,
6243 .v.func = alc290_fixup_mono_speakers,
David Henningsson338cae52013-10-07 10:39:59 +02006244 .chained = true,
6245 .chain_id = ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
6246 },
David Henningssonb67ae3f2013-11-05 13:11:37 +01006247 [ALC269_FIXUP_THINKPAD_ACPI] = {
6248 .type = HDA_FIXUP_FUNC,
Takashi Iwaid5a6cab2018-06-13 12:43:10 +02006249 .v.func = alc_fixup_thinkpad_acpi,
Takashi Iwai09da1112016-09-08 12:15:02 +02006250 .chained = true,
6251 .chain_id = ALC269_FIXUP_SKU_IGNORE,
David Henningssonb67ae3f2013-11-05 13:11:37 +01006252 },
David Henningsson56f27012016-01-11 09:33:14 +01006253 [ALC269_FIXUP_DMIC_THINKPAD_ACPI] = {
6254 .type = HDA_FIXUP_FUNC,
6255 .v.func = alc_fixup_inv_dmic,
6256 .chained = true,
6257 .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
6258 },
Chris Chiu5824ce82017-02-28 14:17:11 -06006259 [ALC255_FIXUP_ACER_MIC_NO_PRESENCE] = {
Hui Wang17d30462019-06-14 16:44:12 +08006260 .type = HDA_FIXUP_PINS,
6261 .v.pins = (const struct hda_pintbl[]) {
6262 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6263 { }
Chris Chiu5824ce82017-02-28 14:17:11 -06006264 },
6265 .chained = true,
Hui Wang17d30462019-06-14 16:44:12 +08006266 .chain_id = ALC255_FIXUP_HEADSET_MODE
Chris Chiu5824ce82017-02-28 14:17:11 -06006267 },
Chris Chiu615966a2017-02-28 14:17:12 -06006268 [ALC255_FIXUP_ASUS_MIC_NO_PRESENCE] = {
6269 .type = HDA_FIXUP_PINS,
6270 .v.pins = (const struct hda_pintbl[]) {
6271 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6272 { }
6273 },
6274 .chained = true,
6275 .chain_id = ALC255_FIXUP_HEADSET_MODE
6276 },
Kailang Yang9a22a8f52013-11-08 15:54:49 +08006277 [ALC255_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6278 .type = HDA_FIXUP_PINS,
6279 .v.pins = (const struct hda_pintbl[]) {
6280 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6281 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6282 { }
6283 },
6284 .chained = true,
6285 .chain_id = ALC255_FIXUP_HEADSET_MODE
6286 },
Kailang Yang31278992014-03-03 15:27:22 +08006287 [ALC255_FIXUP_DELL2_MIC_NO_PRESENCE] = {
6288 .type = HDA_FIXUP_PINS,
6289 .v.pins = (const struct hda_pintbl[]) {
6290 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6291 { }
6292 },
6293 .chained = true,
6294 .chain_id = ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC
6295 },
Kailang Yang9a22a8f52013-11-08 15:54:49 +08006296 [ALC255_FIXUP_HEADSET_MODE] = {
6297 .type = HDA_FIXUP_FUNC,
6298 .v.func = alc_fixup_headset_mode_alc255,
Hui Wang4a83d422014-11-18 17:57:40 +08006299 .chained = true,
Takashi Iwaib3802782018-11-26 17:47:46 +01006300 .chain_id = ALC255_FIXUP_MIC_MUTE_LED
Kailang Yang9a22a8f52013-11-08 15:54:49 +08006301 },
Kailang Yang31278992014-03-03 15:27:22 +08006302 [ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC] = {
6303 .type = HDA_FIXUP_FUNC,
6304 .v.func = alc_fixup_headset_mode_alc255_no_hp_mic,
6305 },
Kailang Yanga22aa262014-04-23 17:34:28 +08006306 [ALC293_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6307 .type = HDA_FIXUP_PINS,
6308 .v.pins = (const struct hda_pintbl[]) {
6309 { 0x18, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6310 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6311 { }
6312 },
6313 .chained = true,
6314 .chain_id = ALC269_FIXUP_HEADSET_MODE
6315 },
Takashi Iwai1c37c222014-05-06 17:34:42 +02006316 [ALC292_FIXUP_TPT440_DOCK] = {
David Henningssonec56af62015-06-24 10:46:33 +02006317 .type = HDA_FIXUP_FUNC,
Takashi Iwai7f57d802015-09-24 17:36:51 +02006318 .v.func = alc_fixup_tpt440_dock,
Takashi Iwai1c37c222014-05-06 17:34:42 +02006319 .chained = true,
6320 .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST
6321 },
Takashi Iwai9a811232015-12-09 15:17:43 +01006322 [ALC292_FIXUP_TPT440] = {
6323 .type = HDA_FIXUP_FUNC,
Takashi Iwai157f0b72015-12-10 23:30:43 +01006324 .v.func = alc_fixup_disable_aamix,
Takashi Iwai9a811232015-12-09 15:17:43 +01006325 .chained = true,
6326 .chain_id = ALC292_FIXUP_TPT440_DOCK,
6327 },
Anisse Astierabaa22742016-08-24 09:14:13 +02006328 [ALC283_FIXUP_HEADSET_MIC] = {
Daniel Drake9dc12862014-07-22 10:58:29 +01006329 .type = HDA_FIXUP_PINS,
6330 .v.pins = (const struct hda_pintbl[]) {
6331 { 0x19, 0x04a110f0 },
6332 { },
6333 },
6334 },
Takashi Iwaib3802782018-11-26 17:47:46 +01006335 [ALC255_FIXUP_MIC_MUTE_LED] = {
Hui Wang00ef9942014-07-31 11:52:38 +08006336 .type = HDA_FIXUP_FUNC,
Takashi Iwaib3802782018-11-26 17:47:46 +01006337 .v.func = snd_hda_gen_fixup_micmute_led,
Hui Wang00ef9942014-07-31 11:52:38 +08006338 },
Takashi Iwai1a22e772014-08-27 08:19:05 +02006339 [ALC282_FIXUP_ASPIRE_V5_PINS] = {
6340 .type = HDA_FIXUP_PINS,
6341 .v.pins = (const struct hda_pintbl[]) {
6342 { 0x12, 0x90a60130 },
6343 { 0x14, 0x90170110 },
6344 { 0x17, 0x40000008 },
6345 { 0x18, 0x411111f0 },
Mateusz Sylwestrzak04206942015-07-19 17:38:56 +02006346 { 0x19, 0x01a1913c },
Takashi Iwai1a22e772014-08-27 08:19:05 +02006347 { 0x1a, 0x411111f0 },
6348 { 0x1b, 0x411111f0 },
6349 { 0x1d, 0x40f89b2d },
6350 { 0x1e, 0x411111f0 },
6351 { 0x21, 0x0321101f },
6352 { },
6353 },
6354 },
David Henningsson7a5255f2014-10-30 08:26:01 +01006355 [ALC280_FIXUP_HP_GPIO4] = {
6356 .type = HDA_FIXUP_FUNC,
6357 .v.func = alc280_fixup_hp_gpio4,
6358 },
Kailang Yangeaa8e5e2014-11-21 15:49:11 +08006359 [ALC286_FIXUP_HP_GPIO_LED] = {
6360 .type = HDA_FIXUP_FUNC,
6361 .v.func = alc286_fixup_hp_gpio_led,
6362 },
David Henningsson33f4acd2015-01-07 15:50:13 +01006363 [ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY] = {
6364 .type = HDA_FIXUP_FUNC,
6365 .v.func = alc280_fixup_hp_gpio2_mic_hotkey,
6366 },
TienFu Chenb4b33f92015-01-20 15:06:21 +01006367 [ALC280_FIXUP_HP_DOCK_PINS] = {
6368 .type = HDA_FIXUP_PINS,
6369 .v.pins = (const struct hda_pintbl[]) {
6370 { 0x1b, 0x21011020 }, /* line-out */
6371 { 0x1a, 0x01a1903c }, /* headset mic */
6372 { 0x18, 0x2181103f }, /* line-in */
6373 { },
6374 },
6375 .chained = true,
6376 .chain_id = ALC280_FIXUP_HP_GPIO4
6377 },
Jaroslav Kysela04d54662017-03-09 13:29:13 +01006378 [ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED] = {
6379 .type = HDA_FIXUP_PINS,
6380 .v.pins = (const struct hda_pintbl[]) {
6381 { 0x1b, 0x21011020 }, /* line-out */
6382 { 0x18, 0x2181103f }, /* line-in */
6383 { },
6384 },
6385 .chained = true,
6386 .chain_id = ALC269_FIXUP_HP_GPIO_MIC1_LED
6387 },
Keith Packard98973f22015-07-15 12:14:39 -07006388 [ALC280_FIXUP_HP_9480M] = {
6389 .type = HDA_FIXUP_FUNC,
6390 .v.func = alc280_fixup_hp_9480m,
6391 },
Kailang Yange1e62b92015-04-08 16:01:22 +08006392 [ALC288_FIXUP_DELL_HEADSET_MODE] = {
6393 .type = HDA_FIXUP_FUNC,
6394 .v.func = alc_fixup_headset_mode_dell_alc288,
6395 .chained = true,
Takashi Iwaib3802782018-11-26 17:47:46 +01006396 .chain_id = ALC255_FIXUP_MIC_MUTE_LED
Kailang Yange1e62b92015-04-08 16:01:22 +08006397 },
6398 [ALC288_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6399 .type = HDA_FIXUP_PINS,
6400 .v.pins = (const struct hda_pintbl[]) {
6401 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6402 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6403 { }
6404 },
6405 .chained = true,
6406 .chain_id = ALC288_FIXUP_DELL_HEADSET_MODE
6407 },
Hui Wang831bfdf92015-06-26 12:35:17 +08006408 [ALC288_FIXUP_DISABLE_AAMIX] = {
6409 .type = HDA_FIXUP_FUNC,
6410 .v.func = alc_fixup_disable_aamix,
6411 .chained = true,
Takashi Iwaid44a6862018-06-19 23:04:03 +02006412 .chain_id = ALC288_FIXUP_DELL1_MIC_NO_PRESENCE
Hui Wang831bfdf92015-06-26 12:35:17 +08006413 },
6414 [ALC288_FIXUP_DELL_XPS_13] = {
6415 .type = HDA_FIXUP_FUNC,
6416 .v.func = alc_fixup_dell_xps13,
6417 .chained = true,
6418 .chain_id = ALC288_FIXUP_DISABLE_AAMIX
6419 },
Takashi Iwai8b99aba2015-06-15 11:59:32 +02006420 [ALC292_FIXUP_DISABLE_AAMIX] = {
6421 .type = HDA_FIXUP_FUNC,
6422 .v.func = alc_fixup_disable_aamix,
Hui Wang831bfdf92015-06-26 12:35:17 +08006423 .chained = true,
6424 .chain_id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE
Takashi Iwai8b99aba2015-06-15 11:59:32 +02006425 },
David Henningssonc04017e2015-12-15 14:44:03 +01006426 [ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK] = {
6427 .type = HDA_FIXUP_FUNC,
6428 .v.func = alc_fixup_disable_aamix,
6429 .chained = true,
6430 .chain_id = ALC293_FIXUP_DELL1_MIC_NO_PRESENCE
6431 },
Takashi Iwai8b99aba2015-06-15 11:59:32 +02006432 [ALC292_FIXUP_DELL_E7X] = {
6433 .type = HDA_FIXUP_FUNC,
6434 .v.func = alc_fixup_dell_xps13,
6435 .chained = true,
6436 .chain_id = ALC292_FIXUP_DISABLE_AAMIX
6437 },
Kailang Yang977e6272015-05-18 15:31:20 +08006438 [ALC298_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6439 .type = HDA_FIXUP_PINS,
6440 .v.pins = (const struct hda_pintbl[]) {
6441 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6442 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6443 { }
6444 },
6445 .chained = true,
6446 .chain_id = ALC269_FIXUP_HEADSET_MODE
6447 },
Hui Wang2f726ae2017-03-31 10:31:40 +08006448 [ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE] = {
6449 .type = HDA_FIXUP_PINS,
6450 .v.pins = (const struct hda_pintbl[]) {
6451 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6452 { }
6453 },
6454 .chained = true,
6455 .chain_id = ALC269_FIXUP_HEADSET_MODE
6456 },
Kailang Yang6ed11312015-10-26 15:37:39 +08006457 [ALC275_FIXUP_DELL_XPS] = {
6458 .type = HDA_FIXUP_VERBS,
6459 .v.verbs = (const struct hda_verb[]) {
6460 /* Enables internal speaker */
6461 {0x20, AC_VERB_SET_COEF_INDEX, 0x1f},
6462 {0x20, AC_VERB_SET_PROC_COEF, 0x00c0},
6463 {0x20, AC_VERB_SET_COEF_INDEX, 0x30},
6464 {0x20, AC_VERB_SET_PROC_COEF, 0x00b1},
6465 {}
6466 }
6467 },
Hui Wang8c697292015-11-24 11:08:18 +08006468 [ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE] = {
6469 .type = HDA_FIXUP_VERBS,
6470 .v.verbs = (const struct hda_verb[]) {
6471 /* Disable pass-through path for FRONT 14h */
6472 {0x20, AC_VERB_SET_COEF_INDEX, 0x36},
6473 {0x20, AC_VERB_SET_PROC_COEF, 0x1737},
6474 {}
6475 },
6476 .chained = true,
6477 .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
6478 },
Hui Wang23adc192015-12-08 12:27:18 +08006479 [ALC293_FIXUP_LENOVO_SPK_NOISE] = {
6480 .type = HDA_FIXUP_FUNC,
6481 .v.func = alc_fixup_disable_aamix,
6482 .chained = true,
6483 .chain_id = ALC269_FIXUP_THINKPAD_ACPI
6484 },
Kailang3694cb22015-12-28 11:35:24 +08006485 [ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY] = {
6486 .type = HDA_FIXUP_FUNC,
6487 .v.func = alc233_fixup_lenovo_line2_mic_hotkey,
6488 },
Kai-Heng Feng3b43b712016-02-25 15:19:38 +08006489 [ALC255_FIXUP_DELL_SPK_NOISE] = {
6490 .type = HDA_FIXUP_FUNC,
6491 .v.func = alc_fixup_disable_aamix,
6492 .chained = true,
6493 .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
6494 },
Kailang Yangd1dd4212019-01-09 17:05:24 +08006495 [ALC225_FIXUP_DISABLE_MIC_VREF] = {
6496 .type = HDA_FIXUP_FUNC,
6497 .v.func = alc_fixup_disable_mic_vref,
6498 .chained = true,
6499 .chain_id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE
6500 },
David Henningsson2ae95572016-02-25 09:37:05 +01006501 [ALC225_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6502 .type = HDA_FIXUP_VERBS,
6503 .v.verbs = (const struct hda_verb[]) {
6504 /* Disable pass-through path for FRONT 14h */
6505 { 0x20, AC_VERB_SET_COEF_INDEX, 0x36 },
6506 { 0x20, AC_VERB_SET_PROC_COEF, 0x57d7 },
6507 {}
6508 },
6509 .chained = true,
Kailang Yangd1dd4212019-01-09 17:05:24 +08006510 .chain_id = ALC225_FIXUP_DISABLE_MIC_VREF
David Henningsson2ae95572016-02-25 09:37:05 +01006511 },
Takashi Iwaif8839822016-02-25 14:31:59 +01006512 [ALC280_FIXUP_HP_HEADSET_MIC] = {
6513 .type = HDA_FIXUP_FUNC,
6514 .v.func = alc_fixup_disable_aamix,
6515 .chained = true,
6516 .chain_id = ALC269_FIXUP_HEADSET_MIC,
6517 },
Hui Wange549d192016-04-01 11:00:15 +08006518 [ALC221_FIXUP_HP_FRONT_MIC] = {
6519 .type = HDA_FIXUP_PINS,
6520 .v.pins = (const struct hda_pintbl[]) {
6521 { 0x19, 0x02a19020 }, /* Front Mic */
6522 { }
6523 },
6524 },
Sven Eckelmannc636b952016-04-11 16:55:26 +02006525 [ALC292_FIXUP_TPT460] = {
6526 .type = HDA_FIXUP_FUNC,
6527 .v.func = alc_fixup_tpt440_dock,
6528 .chained = true,
6529 .chain_id = ALC293_FIXUP_LENOVO_SPK_NOISE,
6530 },
Hui Wangdd9aa332016-08-01 10:20:32 +08006531 [ALC298_FIXUP_SPK_VOLUME] = {
6532 .type = HDA_FIXUP_FUNC,
6533 .v.func = alc298_fixup_speaker_volume,
Hui Wang59ec4b52016-08-04 15:28:04 +08006534 .chained = true,
Hui Wang2f726ae2017-03-31 10:31:40 +08006535 .chain_id = ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE,
Hui Wangdd9aa332016-08-01 10:20:32 +08006536 },
Takashi Iwaie312a862018-03-06 12:14:17 +01006537 [ALC295_FIXUP_DISABLE_DAC3] = {
6538 .type = HDA_FIXUP_FUNC,
6539 .v.func = alc295_fixup_disable_dac3,
6540 },
Kai-Heng Fengfd06c772016-08-30 15:36:34 +08006541 [ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER] = {
6542 .type = HDA_FIXUP_PINS,
6543 .v.pins = (const struct hda_pintbl[]) {
6544 { 0x1b, 0x90170151 },
6545 { }
6546 },
6547 .chained = true,
6548 .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
6549 },
Gabriele Mazzotta823ff162016-12-24 19:50:01 +01006550 [ALC269_FIXUP_ATIV_BOOK_8] = {
6551 .type = HDA_FIXUP_FUNC,
6552 .v.func = alc_fixup_auto_mute_via_amp,
6553 .chained = true,
6554 .chain_id = ALC269_FIXUP_NO_SHUTUP
6555 },
Kailang Yang9eb5d0e2017-01-17 15:40:25 +08006556 [ALC221_FIXUP_HP_MIC_NO_PRESENCE] = {
6557 .type = HDA_FIXUP_PINS,
6558 .v.pins = (const struct hda_pintbl[]) {
6559 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6560 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6561 { }
6562 },
6563 .chained = true,
6564 .chain_id = ALC269_FIXUP_HEADSET_MODE
6565 },
Chris Chiuc1732ed2017-02-28 14:17:13 -06006566 [ALC256_FIXUP_ASUS_HEADSET_MODE] = {
6567 .type = HDA_FIXUP_FUNC,
6568 .v.func = alc_fixup_headset_mode,
6569 },
6570 [ALC256_FIXUP_ASUS_MIC] = {
6571 .type = HDA_FIXUP_PINS,
6572 .v.pins = (const struct hda_pintbl[]) {
6573 { 0x13, 0x90a60160 }, /* use as internal mic */
6574 { 0x19, 0x04a11120 }, /* use as headset mic, without its own jack detect */
6575 { }
6576 },
6577 .chained = true,
6578 .chain_id = ALC256_FIXUP_ASUS_HEADSET_MODE
6579 },
Chris Chiueeed4cd2017-02-28 14:17:15 -06006580 [ALC256_FIXUP_ASUS_AIO_GPIO2] = {
Takashi Iwaiae065f12018-06-19 23:00:03 +02006581 .type = HDA_FIXUP_FUNC,
6582 /* Set up GPIO2 for the speaker amp */
6583 .v.func = alc_fixup_gpio4,
Chris Chiueeed4cd2017-02-28 14:17:15 -06006584 },
Chris Chiu216d7ae2017-02-28 14:17:14 -06006585 [ALC233_FIXUP_ASUS_MIC_NO_PRESENCE] = {
6586 .type = HDA_FIXUP_PINS,
6587 .v.pins = (const struct hda_pintbl[]) {
6588 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6589 { }
6590 },
6591 .chained = true,
6592 .chain_id = ALC269_FIXUP_HEADSET_MIC
6593 },
6594 [ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE] = {
6595 .type = HDA_FIXUP_VERBS,
6596 .v.verbs = (const struct hda_verb[]) {
6597 /* Enables internal speaker */
6598 {0x20, AC_VERB_SET_COEF_INDEX, 0x40},
6599 {0x20, AC_VERB_SET_PROC_COEF, 0x8800},
6600 {}
6601 },
6602 .chained = true,
6603 .chain_id = ALC233_FIXUP_ASUS_MIC_NO_PRESENCE
6604 },
Kailang Yangca169cc2017-04-25 16:17:40 +08006605 [ALC233_FIXUP_LENOVO_MULTI_CODECS] = {
6606 .type = HDA_FIXUP_FUNC,
6607 .v.func = alc233_alc662_fixup_lenovo_dual_codecs,
6608 },
Jian-Hong Panea5c7eb2019-04-01 11:25:05 +08006609 [ALC233_FIXUP_ACER_HEADSET_MIC] = {
6610 .type = HDA_FIXUP_VERBS,
6611 .v.verbs = (const struct hda_verb[]) {
6612 { 0x20, AC_VERB_SET_COEF_INDEX, 0x45 },
6613 { 0x20, AC_VERB_SET_PROC_COEF, 0x5089 },
6614 { }
6615 },
6616 .chained = true,
6617 .chain_id = ALC233_FIXUP_ASUS_MIC_NO_PRESENCE
6618 },
Hui Wangf33f79f2017-07-07 12:08:29 +08006619 [ALC294_FIXUP_LENOVO_MIC_LOCATION] = {
6620 .type = HDA_FIXUP_PINS,
6621 .v.pins = (const struct hda_pintbl[]) {
6622 /* Change the mic location from front to right, otherwise there are
6623 two front mics with the same name, pulseaudio can't handle them.
6624 This is just a temporary workaround, after applying this fixup,
6625 there will be one "Front Mic" and one "Mic" in this machine.
6626 */
6627 { 0x1a, 0x04a19040 },
6628 { }
6629 },
6630 },
Kailang Yang5f364132017-07-25 16:28:16 +08006631 [ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE] = {
6632 .type = HDA_FIXUP_PINS,
6633 .v.pins = (const struct hda_pintbl[]) {
6634 { 0x16, 0x0101102f }, /* Rear Headset HP */
6635 { 0x19, 0x02a1913c }, /* use as Front headset mic, without its own jack detect */
6636 { 0x1a, 0x01a19030 }, /* Rear Headset MIC */
6637 { 0x1b, 0x02011020 },
6638 { }
6639 },
6640 .chained = true,
6641 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
6642 },
PeiSen Houb84e8432017-09-01 15:11:56 +08006643 [ALC700_FIXUP_INTEL_REFERENCE] = {
6644 .type = HDA_FIXUP_VERBS,
6645 .v.verbs = (const struct hda_verb[]) {
6646 /* Enables internal speaker */
6647 {0x20, AC_VERB_SET_COEF_INDEX, 0x45},
6648 {0x20, AC_VERB_SET_PROC_COEF, 0x5289},
6649 {0x20, AC_VERB_SET_COEF_INDEX, 0x4A},
6650 {0x20, AC_VERB_SET_PROC_COEF, 0x001b},
6651 {0x58, AC_VERB_SET_COEF_INDEX, 0x00},
6652 {0x58, AC_VERB_SET_PROC_COEF, 0x3888},
6653 {0x20, AC_VERB_SET_COEF_INDEX, 0x6f},
6654 {0x20, AC_VERB_SET_PROC_COEF, 0x2c0b},
6655 {}
6656 }
6657 },
Kailang Yang92266652017-12-14 15:28:58 +08006658 [ALC274_FIXUP_DELL_BIND_DACS] = {
6659 .type = HDA_FIXUP_FUNC,
6660 .v.func = alc274_fixup_bind_dacs,
6661 .chained = true,
6662 .chain_id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE
6663 },
6664 [ALC274_FIXUP_DELL_AIO_LINEOUT_VERB] = {
6665 .type = HDA_FIXUP_PINS,
6666 .v.pins = (const struct hda_pintbl[]) {
6667 { 0x1b, 0x0401102f },
6668 { }
6669 },
6670 .chained = true,
6671 .chain_id = ALC274_FIXUP_DELL_BIND_DACS
6672 },
Kailang Yang61fcf8e2018-02-02 15:26:46 +08006673 [ALC298_FIXUP_TPT470_DOCK] = {
6674 .type = HDA_FIXUP_FUNC,
6675 .v.func = alc_fixup_tpt470_dock,
6676 .chained = true,
6677 .chain_id = ALC293_FIXUP_LENOVO_SPK_NOISE
6678 },
Kailang Yangae104a22018-02-05 16:07:20 +08006679 [ALC255_FIXUP_DUMMY_LINEOUT_VERB] = {
6680 .type = HDA_FIXUP_PINS,
6681 .v.pins = (const struct hda_pintbl[]) {
6682 { 0x14, 0x0201101f },
6683 { }
6684 },
6685 .chained = true,
6686 .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
6687 },
Kailang Yangf0ba9d62018-03-16 11:46:08 +08006688 [ALC255_FIXUP_DELL_HEADSET_MIC] = {
6689 .type = HDA_FIXUP_PINS,
6690 .v.pins = (const struct hda_pintbl[]) {
6691 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6692 { }
6693 },
Hui Wang3ce0d5a2018-04-19 13:29:04 +08006694 .chained = true,
6695 .chain_id = ALC269_FIXUP_HEADSET_MIC
Kailang Yangf0ba9d62018-03-16 11:46:08 +08006696 },
Tom Bridenbbf8ff62018-05-29 17:34:20 +01006697 [ALC295_FIXUP_HP_X360] = {
6698 .type = HDA_FIXUP_FUNC,
6699 .v.func = alc295_fixup_hp_top_speakers,
6700 .chained = true,
6701 .chain_id = ALC269_FIXUP_HP_MUTE_LED_MIC3
Kailang Yang8a328ac2018-08-21 16:54:41 +08006702 },
6703 [ALC221_FIXUP_HP_HEADSET_MIC] = {
6704 .type = HDA_FIXUP_PINS,
6705 .v.pins = (const struct hda_pintbl[]) {
6706 { 0x19, 0x0181313f},
6707 { }
6708 },
6709 .chained = true,
6710 .chain_id = ALC269_FIXUP_HEADSET_MIC
6711 },
Hui Wangc4cfcf62018-11-26 14:17:16 +08006712 [ALC285_FIXUP_LENOVO_HEADPHONE_NOISE] = {
6713 .type = HDA_FIXUP_FUNC,
6714 .v.func = alc285_fixup_invalidate_dacs,
Hui Wang6ba189c2018-12-09 09:16:43 +08006715 .chained = true,
6716 .chain_id = ALC269_FIXUP_THINKPAD_ACPI
Hui Wangc4cfcf62018-11-26 14:17:16 +08006717 },
Girija Kumar Kasinadhunie8ed64b2018-11-26 13:40:46 -05006718 [ALC295_FIXUP_HP_AUTO_MUTE] = {
6719 .type = HDA_FIXUP_FUNC,
6720 .v.func = alc_fixup_auto_mute_via_amp,
6721 },
Chris Chiu33aaebd2018-12-05 14:48:53 +08006722 [ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE] = {
6723 .type = HDA_FIXUP_PINS,
6724 .v.pins = (const struct hda_pintbl[]) {
6725 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6726 { }
6727 },
6728 .chained = true,
6729 .chain_id = ALC269_FIXUP_HEADSET_MIC
6730 },
Chris Chiud8ae4582018-12-07 17:17:11 +08006731 [ALC294_FIXUP_ASUS_MIC] = {
6732 .type = HDA_FIXUP_PINS,
6733 .v.pins = (const struct hda_pintbl[]) {
6734 { 0x13, 0x90a60160 }, /* use as internal mic */
6735 { 0x19, 0x04a11120 }, /* use as headset mic, without its own jack detect */
6736 { }
6737 },
6738 .chained = true,
6739 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
6740 },
Jian-Hong Pan4e051102018-12-07 17:17:12 +08006741 [ALC294_FIXUP_ASUS_HEADSET_MIC] = {
6742 .type = HDA_FIXUP_PINS,
6743 .v.pins = (const struct hda_pintbl[]) {
Jian-Hong Pan82b01142018-12-27 16:46:31 +08006744 { 0x19, 0x01a1103c }, /* use as headset mic */
Jian-Hong Pan4e051102018-12-07 17:17:12 +08006745 { }
6746 },
6747 .chained = true,
6748 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
6749 },
6750 [ALC294_FIXUP_ASUS_SPK] = {
6751 .type = HDA_FIXUP_VERBS,
6752 .v.verbs = (const struct hda_verb[]) {
6753 /* Set EAPD high */
6754 { 0x20, AC_VERB_SET_COEF_INDEX, 0x40 },
6755 { 0x20, AC_VERB_SET_PROC_COEF, 0x8800 },
6756 { }
6757 },
6758 .chained = true,
6759 .chain_id = ALC294_FIXUP_ASUS_HEADSET_MIC
6760 },
Jaroslav Kyselac8a9afa2019-03-14 09:21:08 +01006761 [ALC295_FIXUP_CHROME_BOOK] = {
Kailang Yange8547472018-11-28 15:32:45 +08006762 .type = HDA_FIXUP_FUNC,
Jaroslav Kyselac8a9afa2019-03-14 09:21:08 +01006763 .v.func = alc295_fixup_chromebook,
Kailang Yang8983eb62019-04-03 15:31:49 +08006764 .chained = true,
6765 .chain_id = ALC225_FIXUP_HEADSET_JACK
6766 },
6767 [ALC225_FIXUP_HEADSET_JACK] = {
6768 .type = HDA_FIXUP_FUNC,
6769 .v.func = alc_fixup_headset_jack,
Kailang Yange8547472018-11-28 15:32:45 +08006770 },
Jeremy Soller89e3a562019-01-30 16:12:31 -07006771 [ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE] = {
6772 .type = HDA_FIXUP_PINS,
6773 .v.pins = (const struct hda_pintbl[]) {
6774 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6775 { }
6776 },
6777 .chained = true,
6778 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
6779 },
Hui Wangc8c6ee62019-02-14 11:41:33 +08006780 [ALC285_FIXUP_LENOVO_PC_BEEP_IN_NOISE] = {
6781 .type = HDA_FIXUP_VERBS,
6782 .v.verbs = (const struct hda_verb[]) {
6783 /* Disable PCBEEP-IN passthrough */
6784 { 0x20, AC_VERB_SET_COEF_INDEX, 0x36 },
6785 { 0x20, AC_VERB_SET_PROC_COEF, 0x57d7 },
6786 { }
6787 },
6788 .chained = true,
6789 .chain_id = ALC285_FIXUP_LENOVO_HEADPHONE_NOISE
6790 },
Jian-Hong Pancbc05fd2019-03-13 17:33:24 +08006791 [ALC255_FIXUP_ACER_HEADSET_MIC] = {
6792 .type = HDA_FIXUP_PINS,
6793 .v.pins = (const struct hda_pintbl[]) {
6794 { 0x19, 0x03a11130 },
6795 { 0x1a, 0x90a60140 }, /* use as internal mic */
6796 { }
6797 },
6798 .chained = true,
6799 .chain_id = ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC
6800 },
Kailang Yang136824e2019-03-14 16:22:45 +08006801 [ALC225_FIXUP_DELL_WYSE_AIO_MIC_NO_PRESENCE] = {
6802 .type = HDA_FIXUP_PINS,
6803 .v.pins = (const struct hda_pintbl[]) {
6804 { 0x16, 0x01011020 }, /* Rear Line out */
6805 { 0x19, 0x01a1913c }, /* use as Front headset mic, without its own jack detect */
6806 { }
6807 },
6808 .chained = true,
6809 .chain_id = ALC225_FIXUP_WYSE_AUTO_MUTE
6810 },
6811 [ALC225_FIXUP_WYSE_AUTO_MUTE] = {
6812 .type = HDA_FIXUP_FUNC,
6813 .v.func = alc_fixup_auto_mute_via_amp,
6814 .chained = true,
6815 .chain_id = ALC225_FIXUP_WYSE_DISABLE_MIC_VREF
6816 },
6817 [ALC225_FIXUP_WYSE_DISABLE_MIC_VREF] = {
6818 .type = HDA_FIXUP_FUNC,
6819 .v.func = alc_fixup_disable_mic_vref,
6820 .chained = true,
6821 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
6822 },
Jian-Hong Pan667a8f72019-03-15 17:51:09 +08006823 [ALC286_FIXUP_ACER_AIO_HEADSET_MIC] = {
6824 .type = HDA_FIXUP_VERBS,
6825 .v.verbs = (const struct hda_verb[]) {
6826 { 0x20, AC_VERB_SET_COEF_INDEX, 0x4f },
6827 { 0x20, AC_VERB_SET_PROC_COEF, 0x5029 },
6828 { }
6829 },
6830 .chained = true,
6831 .chain_id = ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE
6832 },
Jian-Hong Pane1037352019-03-22 11:37:18 +08006833 [ALC256_FIXUP_ASUS_MIC_NO_PRESENCE] = {
6834 .type = HDA_FIXUP_PINS,
6835 .v.pins = (const struct hda_pintbl[]) {
6836 { 0x19, 0x04a11120 }, /* use as headset mic, without its own jack detect */
6837 { }
6838 },
6839 .chained = true,
6840 .chain_id = ALC256_FIXUP_ASUS_HEADSET_MODE
6841 },
Bernhard Rosenkraenzere2a829b2019-03-05 00:38:19 +01006842 [ALC299_FIXUP_PREDATOR_SPK] = {
6843 .type = HDA_FIXUP_PINS,
6844 .v.pins = (const struct hda_pintbl[]) {
6845 { 0x21, 0x90170150 }, /* use as headset mic, without its own jack detect */
6846 { }
6847 }
6848 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02006849};
6850
6851static const struct snd_pci_quirk alc269_fixup_tbl[] = {
Marius Knausta6b92b62014-03-03 01:48:58 +01006852 SND_PCI_QUIRK(0x1025, 0x0283, "Acer TravelMate 8371", ALC269_FIXUP_INV_DMIC),
David Henningsson693b6132012-06-22 19:12:10 +02006853 SND_PCI_QUIRK(0x1025, 0x029b, "Acer 1810TZ", ALC269_FIXUP_INV_DMIC),
6854 SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC),
David Henningssonaaedfb42013-08-16 14:09:02 +02006855 SND_PCI_QUIRK(0x1025, 0x047c, "Acer AC700", ALC269_FIXUP_ACER_AC700),
Takashi Iwai78197172015-06-27 10:21:13 +02006856 SND_PCI_QUIRK(0x1025, 0x072d, "Acer Aspire V5-571G", ALC269_FIXUP_ASPIRE_HEADSET_MIC),
6857 SND_PCI_QUIRK(0x1025, 0x080d, "Acer Aspire V5-122P", ALC269_FIXUP_ASPIRE_HEADSET_MIC),
David Henningssonaaedfb42013-08-16 14:09:02 +02006858 SND_PCI_QUIRK(0x1025, 0x0740, "Acer AO725", ALC271_FIXUP_HP_GATE_MIC_JACK),
6859 SND_PCI_QUIRK(0x1025, 0x0742, "Acer AO756", ALC271_FIXUP_HP_GATE_MIC_JACK),
Simon South02322ac2016-03-02 23:10:44 -05006860 SND_PCI_QUIRK(0x1025, 0x0762, "Acer Aspire E1-472", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572),
Oleksij Rempelb1e89722013-12-04 20:50:53 +01006861 SND_PCI_QUIRK(0x1025, 0x0775, "Acer Aspire E1-572", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572),
Takashi Iwai1a22e772014-08-27 08:19:05 +02006862 SND_PCI_QUIRK(0x1025, 0x079b, "Acer Aspire V5-573G", ALC282_FIXUP_ASPIRE_V5_PINS),
Chris Chiu705b65f2018-12-05 14:48:54 +08006863 SND_PCI_QUIRK(0x1025, 0x102b, "Acer Aspire C24-860", ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE),
Takashi Iwaib9c2fa52015-11-19 16:39:50 +01006864 SND_PCI_QUIRK(0x1025, 0x106d, "Acer Cloudbook 14", ALC283_FIXUP_CHROME_BOOK),
Chris Chiuc7531e32019-03-21 17:17:31 +08006865 SND_PCI_QUIRK(0x1025, 0x1099, "Acer Aspire E5-523G", ALC255_FIXUP_ACER_MIC_NO_PRESENCE),
6866 SND_PCI_QUIRK(0x1025, 0x110e, "Acer Aspire ES1-432", ALC255_FIXUP_ACER_MIC_NO_PRESENCE),
Bernhard Rosenkraenzere2a829b2019-03-05 00:38:19 +01006867 SND_PCI_QUIRK(0x1025, 0x1246, "Acer Predator Helios 500", ALC299_FIXUP_PREDATOR_SPK),
Jian-Hong Pan667a8f72019-03-15 17:51:09 +08006868 SND_PCI_QUIRK(0x1025, 0x128f, "Acer Veriton Z6860G", ALC286_FIXUP_ACER_AIO_HEADSET_MIC),
6869 SND_PCI_QUIRK(0x1025, 0x1290, "Acer Veriton Z4860G", ALC286_FIXUP_ACER_AIO_HEADSET_MIC),
6870 SND_PCI_QUIRK(0x1025, 0x1291, "Acer Veriton Z4660G", ALC286_FIXUP_ACER_AIO_HEADSET_MIC),
Jian-Hong Pan2733cce2019-03-21 16:39:04 +08006871 SND_PCI_QUIRK(0x1025, 0x1308, "Acer Aspire Z24-890", ALC286_FIXUP_ACER_AIO_HEADSET_MIC),
Jian-Hong Panea5c7eb2019-04-01 11:25:05 +08006872 SND_PCI_QUIRK(0x1025, 0x132a, "Acer TravelMate B114-21", ALC233_FIXUP_ACER_HEADSET_MIC),
Jian-Hong Pancbc05fd2019-03-13 17:33:24 +08006873 SND_PCI_QUIRK(0x1025, 0x1330, "Acer TravelMate X514-51T", ALC255_FIXUP_ACER_HEADSET_MIC),
David Henningssonaaedfb42013-08-16 14:09:02 +02006874 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
Kailang Yang6ed11312015-10-26 15:37:39 +08006875 SND_PCI_QUIRK(0x1028, 0x054b, "Dell XPS one 2710", ALC275_FIXUP_DELL_XPS),
Takashi Iwai86f799b2015-11-14 17:46:31 +01006876 SND_PCI_QUIRK(0x1028, 0x05bd, "Dell Latitude E6440", ALC292_FIXUP_DELL_E7X),
Takashi Iwaicf521032016-01-15 12:59:25 +01006877 SND_PCI_QUIRK(0x1028, 0x05be, "Dell Latitude E6540", ALC292_FIXUP_DELL_E7X),
Takashi Iwai8b99aba2015-06-15 11:59:32 +02006878 SND_PCI_QUIRK(0x1028, 0x05ca, "Dell Latitude E7240", ALC292_FIXUP_DELL_E7X),
6879 SND_PCI_QUIRK(0x1028, 0x05cb, "Dell Latitude E7440", ALC292_FIXUP_DELL_E7X),
David Henningsson0f4881d2013-12-20 16:08:13 +01006880 SND_PCI_QUIRK(0x1028, 0x05da, "Dell Vostro 5460", ALC290_FIXUP_SUBWOOFER),
David Henningsson73bdd592013-04-15 15:44:14 +02006881 SND_PCI_QUIRK(0x1028, 0x05f4, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
6882 SND_PCI_QUIRK(0x1028, 0x05f5, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
6883 SND_PCI_QUIRK(0x1028, 0x05f6, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
David Henningsson0f4881d2013-12-20 16:08:13 +01006884 SND_PCI_QUIRK(0x1028, 0x0615, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK),
6885 SND_PCI_QUIRK(0x1028, 0x0616, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK),
Takashi Iwai98070572016-01-12 21:06:39 +01006886 SND_PCI_QUIRK(0x1028, 0x062c, "Dell Latitude E5550", ALC292_FIXUP_DELL_E7X),
Takashi Iwai42755542015-06-29 10:56:53 +02006887 SND_PCI_QUIRK(0x1028, 0x062e, "Dell Latitude E7450", ALC292_FIXUP_DELL_E7X),
David Henningsson0f4881d2013-12-20 16:08:13 +01006888 SND_PCI_QUIRK(0x1028, 0x0638, "Dell Inspiron 5439", ALC290_FIXUP_MONO_SPEAKERS_HSJACK),
Kailang Yanga22aa262014-04-23 17:34:28 +08006889 SND_PCI_QUIRK(0x1028, 0x064a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
6890 SND_PCI_QUIRK(0x1028, 0x064b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
Hui Wang831bfdf92015-06-26 12:35:17 +08006891 SND_PCI_QUIRK(0x1028, 0x0665, "Dell XPS 13", ALC288_FIXUP_DELL_XPS_13),
Bastien Noceraafecb142016-04-18 11:10:42 +02006892 SND_PCI_QUIRK(0x1028, 0x0669, "Dell Optiplex 9020m", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
Takashi Iwai3a05d122015-07-29 09:04:52 +02006893 SND_PCI_QUIRK(0x1028, 0x069a, "Dell Vostro 5480", ALC290_FIXUP_SUBWOOFER_HSJACK),
Kailang Yang8b724152014-12-17 17:08:59 +08006894 SND_PCI_QUIRK(0x1028, 0x06c7, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
Kailang Yangb7343042014-12-02 14:50:45 +08006895 SND_PCI_QUIRK(0x1028, 0x06d9, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
6896 SND_PCI_QUIRK(0x1028, 0x06da, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
David Henningssonc04017e2015-12-15 14:44:03 +01006897 SND_PCI_QUIRK(0x1028, 0x06db, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
6898 SND_PCI_QUIRK(0x1028, 0x06dd, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
6899 SND_PCI_QUIRK(0x1028, 0x06de, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
6900 SND_PCI_QUIRK(0x1028, 0x06df, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
6901 SND_PCI_QUIRK(0x1028, 0x06e0, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
Kai-Heng Feng423cd782016-05-20 15:47:23 +08006902 SND_PCI_QUIRK(0x1028, 0x0704, "Dell XPS 13 9350", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE),
Kai-Heng Fengfd06c772016-08-30 15:36:34 +08006903 SND_PCI_QUIRK(0x1028, 0x0706, "Dell Inspiron 7559", ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER),
Kai-Heng Feng3b43b712016-02-25 15:19:38 +08006904 SND_PCI_QUIRK(0x1028, 0x0725, "Dell Inspiron 3162", ALC255_FIXUP_DELL_SPK_NOISE),
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01006905 SND_PCI_QUIRK(0x1028, 0x0738, "Dell Precision 5820", ALC269_FIXUP_NO_SHUTUP),
Kai-Heng Feng423cd782016-05-20 15:47:23 +08006906 SND_PCI_QUIRK(0x1028, 0x075b, "Dell XPS 13 9360", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE),
Kai-Heng Feng709ae622018-10-04 11:39:42 +08006907 SND_PCI_QUIRK(0x1028, 0x075c, "Dell XPS 27 7760", ALC298_FIXUP_SPK_VOLUME),
Hui Wangdd9aa332016-08-01 10:20:32 +08006908 SND_PCI_QUIRK(0x1028, 0x075d, "Dell AIO", ALC298_FIXUP_SPK_VOLUME),
Takashi Iwaie312a862018-03-06 12:14:17 +01006909 SND_PCI_QUIRK(0x1028, 0x07b0, "Dell Precision 7520", ALC295_FIXUP_DISABLE_DAC3),
Takashi Iwai493de342017-02-28 17:27:57 +01006910 SND_PCI_QUIRK(0x1028, 0x0798, "Dell Inspiron 17 7000 Gaming", ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER),
Kailang Yang5f364132017-07-25 16:28:16 +08006911 SND_PCI_QUIRK(0x1028, 0x080c, "Dell WYSE", ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE),
Takashi Iwaie4c9fd12018-01-10 08:34:28 +01006912 SND_PCI_QUIRK(0x1028, 0x082a, "Dell XPS 13 9360", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE),
Kailang Yang40e2c4e2018-02-02 15:13:09 +08006913 SND_PCI_QUIRK(0x1028, 0x084b, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB),
6914 SND_PCI_QUIRK(0x1028, 0x084e, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB),
Kailang Yangf0ba9d62018-03-16 11:46:08 +08006915 SND_PCI_QUIRK(0x1028, 0x0871, "Dell Precision 3630", ALC255_FIXUP_DELL_HEADSET_MIC),
6916 SND_PCI_QUIRK(0x1028, 0x0872, "Dell Precision 3630", ALC255_FIXUP_DELL_HEADSET_MIC),
Kailang Yangae104a22018-02-05 16:07:20 +08006917 SND_PCI_QUIRK(0x1028, 0x0873, "Dell Precision 3930", ALC255_FIXUP_DUMMY_LINEOUT_VERB),
Kailang Yang136824e2019-03-14 16:22:45 +08006918 SND_PCI_QUIRK(0x1028, 0x08ad, "Dell WYSE AIO", ALC225_FIXUP_DELL_WYSE_AIO_MIC_NO_PRESENCE),
Kailang Yangda484d02019-03-14 15:50:59 +08006919 SND_PCI_QUIRK(0x1028, 0x08ae, "Dell WYSE NB", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE),
Kailang Yangc2a7c55a2019-01-03 15:53:39 +08006920 SND_PCI_QUIRK(0x1028, 0x0935, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB),
Kailang Yanga22aa262014-04-23 17:34:28 +08006921 SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
6922 SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
Takashi Iwai08fb0d02013-01-10 17:33:58 +01006923 SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01006924 SND_PCI_QUIRK(0x103c, 0x18e6, "HP", ALC269_FIXUP_HP_GPIO_LED),
David Henningsson8e35cd42013-11-06 11:20:01 +01006925 SND_PCI_QUIRK(0x103c, 0x218b, "HP", ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED),
David Henningsson33f4acd2015-01-07 15:50:13 +01006926 SND_PCI_QUIRK(0x103c, 0x225f, "HP", ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY),
Kailang Yangc60666b2014-02-21 16:23:35 +08006927 /* ALC282 */
Hui Wang7976eb42015-02-13 11:14:41 +08006928 SND_PCI_QUIRK(0x103c, 0x21f9, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang8a02b162014-06-13 17:16:31 +08006929 SND_PCI_QUIRK(0x103c, 0x2210, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang8a02b162014-06-13 17:16:31 +08006930 SND_PCI_QUIRK(0x103c, 0x2214, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08006931 SND_PCI_QUIRK(0x103c, 0x2236, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
6932 SND_PCI_QUIRK(0x103c, 0x2237, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
6933 SND_PCI_QUIRK(0x103c, 0x2238, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
6934 SND_PCI_QUIRK(0x103c, 0x2239, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08006935 SND_PCI_QUIRK(0x103c, 0x224b, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
Kailang Yangc60666b2014-02-21 16:23:35 +08006936 SND_PCI_QUIRK(0x103c, 0x2268, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08006937 SND_PCI_QUIRK(0x103c, 0x226a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
6938 SND_PCI_QUIRK(0x103c, 0x226b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang8a02b162014-06-13 17:16:31 +08006939 SND_PCI_QUIRK(0x103c, 0x226e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangeaa8e5e2014-11-21 15:49:11 +08006940 SND_PCI_QUIRK(0x103c, 0x2271, "HP", ALC286_FIXUP_HP_GPIO_LED),
TienFu Chenb4b33f92015-01-20 15:06:21 +01006941 SND_PCI_QUIRK(0x103c, 0x2272, "HP", ALC280_FIXUP_HP_DOCK_PINS),
TienFu Chen3271cb22015-02-10 09:09:41 +01006942 SND_PCI_QUIRK(0x103c, 0x2273, "HP", ALC280_FIXUP_HP_DOCK_PINS),
Kailang Yangc60666b2014-02-21 16:23:35 +08006943 SND_PCI_QUIRK(0x103c, 0x229e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08006944 SND_PCI_QUIRK(0x103c, 0x22b2, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
6945 SND_PCI_QUIRK(0x103c, 0x22b7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
6946 SND_PCI_QUIRK(0x103c, 0x22bf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08006947 SND_PCI_QUIRK(0x103c, 0x22cf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Keith Packard98973f22015-07-15 12:14:39 -07006948 SND_PCI_QUIRK(0x103c, 0x22db, "HP", ALC280_FIXUP_HP_9480M),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08006949 SND_PCI_QUIRK(0x103c, 0x22dc, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
6950 SND_PCI_QUIRK(0x103c, 0x22fb, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yangc60666b2014-02-21 16:23:35 +08006951 /* ALC290 */
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08006952 SND_PCI_QUIRK(0x103c, 0x221b, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08006953 SND_PCI_QUIRK(0x103c, 0x2221, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08006954 SND_PCI_QUIRK(0x103c, 0x2225, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08006955 SND_PCI_QUIRK(0x103c, 0x2253, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
6956 SND_PCI_QUIRK(0x103c, 0x2254, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
6957 SND_PCI_QUIRK(0x103c, 0x2255, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
6958 SND_PCI_QUIRK(0x103c, 0x2256, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
6959 SND_PCI_QUIRK(0x103c, 0x2257, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08006960 SND_PCI_QUIRK(0x103c, 0x2259, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Jaroslav Kysela04d54662017-03-09 13:29:13 +01006961 SND_PCI_QUIRK(0x103c, 0x225a, "HP", ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED),
Kailang Yangc60666b2014-02-21 16:23:35 +08006962 SND_PCI_QUIRK(0x103c, 0x2260, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08006963 SND_PCI_QUIRK(0x103c, 0x2263, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
6964 SND_PCI_QUIRK(0x103c, 0x2264, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
6965 SND_PCI_QUIRK(0x103c, 0x2265, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08006966 SND_PCI_QUIRK(0x103c, 0x2272, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
6967 SND_PCI_QUIRK(0x103c, 0x2273, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08006968 SND_PCI_QUIRK(0x103c, 0x2278, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yangc60666b2014-02-21 16:23:35 +08006969 SND_PCI_QUIRK(0x103c, 0x227f, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08006970 SND_PCI_QUIRK(0x103c, 0x2282, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08006971 SND_PCI_QUIRK(0x103c, 0x228b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08006972 SND_PCI_QUIRK(0x103c, 0x228e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
6973 SND_PCI_QUIRK(0x103c, 0x22c5, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08006974 SND_PCI_QUIRK(0x103c, 0x22c7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
6975 SND_PCI_QUIRK(0x103c, 0x22c8, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08006976 SND_PCI_QUIRK(0x103c, 0x22c4, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang8a02b162014-06-13 17:16:31 +08006977 SND_PCI_QUIRK(0x103c, 0x2334, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
6978 SND_PCI_QUIRK(0x103c, 0x2335, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
6979 SND_PCI_QUIRK(0x103c, 0x2336, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
6980 SND_PCI_QUIRK(0x103c, 0x2337, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Takashi Iwaif8839822016-02-25 14:31:59 +01006981 SND_PCI_QUIRK(0x103c, 0x221c, "HP EliteBook 755 G2", ALC280_FIXUP_HP_HEADSET_MIC),
Jaroslav Kysela167897f2019-03-13 13:40:15 +01006982 SND_PCI_QUIRK(0x103c, 0x802e, "HP Z240 SFF", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
6983 SND_PCI_QUIRK(0x103c, 0x802f, "HP Z240", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
Takashi Iwai563785e2018-11-12 09:43:12 +01006984 SND_PCI_QUIRK(0x103c, 0x820d, "HP Pavilion 15", ALC269_FIXUP_HP_MUTE_LED_MIC3),
Hui Wange549d192016-04-01 11:00:15 +08006985 SND_PCI_QUIRK(0x103c, 0x8256, "HP", ALC221_FIXUP_HP_FRONT_MIC),
Tom Bridenbbf8ff62018-05-29 17:34:20 +01006986 SND_PCI_QUIRK(0x103c, 0x827e, "HP x360", ALC295_FIXUP_HP_X360),
Jaroslav Kysela167897f2019-03-13 13:40:15 +01006987 SND_PCI_QUIRK(0x103c, 0x82bf, "HP G3 mini", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
6988 SND_PCI_QUIRK(0x103c, 0x82c0, "HP G3 mini premium", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
Alexandru Gagniuc56e40eb2018-08-04 11:44:44 -05006989 SND_PCI_QUIRK(0x103c, 0x83b9, "HP Spectre x360", ALC269_FIXUP_HP_MUTE_LED_MIC3),
Takashi Iwai190d0382019-08-13 17:39:56 +02006990 SND_PCI_QUIRK(0x103c, 0x8497, "HP Envy x360", ALC269_FIXUP_HP_MUTE_LED_MIC3),
Chris Chiuc1732ed2017-02-28 14:17:13 -06006991 SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC),
Takashi Iwai7bba2152013-09-06 15:45:38 +02006992 SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300),
David Henningsson3e0d6112013-04-22 14:30:14 +02006993 SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Wandrille RONCE9cf65332018-12-19 14:52:44 +01006994 SND_PCI_QUIRK(0x1043, 0x10a1, "ASUS UX391UA", ALC294_FIXUP_ASUS_SPK),
Chris Chiuc1732ed2017-02-28 14:17:13 -06006995 SND_PCI_QUIRK(0x1043, 0x10c0, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC),
Takashi Iwai4eab0ea2017-06-06 12:33:17 +02006996 SND_PCI_QUIRK(0x1043, 0x10d0, "ASUS X540LA/X540LJ", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
David Henningsson3e0d6112013-04-22 14:30:14 +02006997 SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Takashi Iwai4eab0ea2017-06-06 12:33:17 +02006998 SND_PCI_QUIRK(0x1043, 0x11c0, "ASUS X556UR", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
6999 SND_PCI_QUIRK(0x1043, 0x1290, "ASUS X441SA", ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE),
7000 SND_PCI_QUIRK(0x1043, 0x12a0, "ASUS X441UV", ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE),
Chris Chiuc1732ed2017-02-28 14:17:13 -06007001 SND_PCI_QUIRK(0x1043, 0x12f0, "ASUS X541UV", ALC256_FIXUP_ASUS_MIC),
7002 SND_PCI_QUIRK(0x1043, 0x12e0, "ASUS X541SA", ALC256_FIXUP_ASUS_MIC),
7003 SND_PCI_QUIRK(0x1043, 0x13b0, "ASUS Z550SA", ALC256_FIXUP_ASUS_MIC),
Oleksij Rempel2cede302013-11-27 17:12:03 +01007004 SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK),
Takashi Iwai23870832013-11-29 14:13:12 +01007005 SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A),
David Henningsson3e0d6112013-04-22 14:30:14 +02007006 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC),
Takashi Iwai017f2a12011-07-09 14:42:25 +02007007 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
Chris Chiu28e8af82017-06-05 15:05:30 -06007008 SND_PCI_QUIRK(0x1043, 0x1a30, "ASUS X705UD", ALC256_FIXUP_ASUS_MIC),
David Henningsson693b6132012-06-22 19:12:10 +02007009 SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC),
Chris Chiu615966a2017-02-28 14:17:12 -06007010 SND_PCI_QUIRK(0x1043, 0x1bbd, "ASUS Z550MA", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
Takashi Iwai4eab0ea2017-06-06 12:33:17 +02007011 SND_PCI_QUIRK(0x1043, 0x1c23, "Asus X55U", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Chris Chiuc1732ed2017-02-28 14:17:13 -06007012 SND_PCI_QUIRK(0x1043, 0x1ccd, "ASUS X555UB", ALC256_FIXUP_ASUS_MIC),
Chris Chiueeed4cd2017-02-28 14:17:15 -06007013 SND_PCI_QUIRK(0x1043, 0x3030, "ASUS ZN270IE", ALC256_FIXUP_ASUS_AIO_GPIO2),
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02007014 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC),
7015 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC),
7016 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
7017 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
David Henningssond240d1d2013-04-15 12:50:02 +02007018 SND_PCI_QUIRK(0x1043, 0x8516, "ASUS X101CH", ALC269_FIXUP_ASUS_X101),
Takashi Iwaif88abaa2014-02-07 12:07:59 +01007019 SND_PCI_QUIRK(0x104d, 0x90b5, "Sony VAIO Pro 11", ALC286_FIXUP_SONY_MIC_NO_PRESENCE),
David Henningsson88cfcf82013-10-11 10:18:45 +02007020 SND_PCI_QUIRK(0x104d, 0x90b6, "Sony VAIO Pro 13", ALC286_FIXUP_SONY_MIC_NO_PRESENCE),
Takashi Iwai1d045db2011-07-07 18:23:21 +02007021 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
7022 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
7023 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
Takashi Iwaie9bd7d52014-05-21 11:06:49 +02007024 SND_PCI_QUIRK(0x104d, 0x9099, "Sony VAIO S13", ALC275_FIXUP_SONY_DISABLE_AAMIX),
Takashi Iwai24519912011-08-16 15:08:49 +02007025 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook", ALC269_FIXUP_LIFEBOOK),
Takashi Iwai4df3fd12015-06-29 08:38:02 +02007026 SND_PCI_QUIRK(0x10cf, 0x159f, "Lifebook E780", ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT),
Takashi Iwaicc7016a2015-04-08 20:47:55 +02007027 SND_PCI_QUIRK(0x10cf, 0x15dc, "Lifebook T731", ALC269_FIXUP_LIFEBOOK_HP_PIN),
Takashi Iwai88776f32015-05-01 09:20:34 +02007028 SND_PCI_QUIRK(0x10cf, 0x1757, "Lifebook E752", ALC269_FIXUP_LIFEBOOK_HP_PIN),
Jan-Marek Glogowskifdcc9682018-02-14 11:29:15 +01007029 SND_PCI_QUIRK(0x10cf, 0x1629, "Lifebook U7x7", ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC),
David Henningsson2041d562014-06-13 11:15:44 +02007030 SND_PCI_QUIRK(0x10cf, 0x1845, "Lifebook U904", ALC269_FIXUP_LIFEBOOK_EXTMIC),
PeiSen Houb84e8432017-09-01 15:11:56 +08007031 SND_PCI_QUIRK(0x10ec, 0x10f2, "Intel Reference board", ALC700_FIXUP_INTEL_REFERENCE),
YOKOTA Hiroshi0fca97a2018-07-01 18:30:01 +09007032 SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-SZ6", ALC269_FIXUP_HEADSET_MODE),
David Henningssona33cc482014-10-07 10:18:41 +02007033 SND_PCI_QUIRK(0x144d, 0xc109, "Samsung Ativ book 9 (NP900X3G)", ALC269_FIXUP_INV_DMIC),
Gabriele Mazzotta823ff162016-12-24 19:50:01 +01007034 SND_PCI_QUIRK(0x144d, 0xc740, "Samsung Ativ book 8 (NP870Z5G)", ALC269_FIXUP_ATIV_BOOK_8),
Anisse Astierabaa22742016-08-24 09:14:13 +02007035 SND_PCI_QUIRK(0x1458, 0xfa53, "Gigabyte BXBT-2807", ALC283_FIXUP_HEADSET_MIC),
7036 SND_PCI_QUIRK(0x1462, 0xb120, "MSI Cubi MS-B120", ALC283_FIXUP_HEADSET_MIC),
Anisse Astier8cd65272018-11-23 17:59:11 +01007037 SND_PCI_QUIRK(0x1462, 0xb171, "Cubi N 8GL (MS-B171)", ALC283_FIXUP_HEADSET_MIC),
Jeremy Soller89e3a562019-01-30 16:12:31 -07007038 SND_PCI_QUIRK(0x1558, 0x1325, "System76 Darter Pro (darp5)", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
Jeremy Soller80a50522019-05-07 17:11:08 -04007039 SND_PCI_QUIRK(0x1558, 0x8550, "System76 Gazelle (gaze14)", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
Jeremy Soller891afcf2019-05-10 10:15:07 -04007040 SND_PCI_QUIRK(0x1558, 0x8551, "System76 Gazelle (gaze14)", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
7041 SND_PCI_QUIRK(0x1558, 0x8560, "System76 Gazelle (gaze14)", ALC269_FIXUP_HEADSET_MIC),
7042 SND_PCI_QUIRK(0x1558, 0x8561, "System76 Gazelle (gaze14)", ALC269_FIXUP_HEADSET_MIC),
Kailang Yangca169cc2017-04-25 16:17:40 +08007043 SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC233_FIXUP_LENOVO_MULTI_CODECS),
Takashi Iwai1d045db2011-07-07 18:23:21 +02007044 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
7045 SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
7046 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
7047 SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
7048 SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
Takashi Iwai707fba32012-08-02 09:04:39 +02007049 SND_PCI_QUIRK(0x17aa, 0x21f6, "Thinkpad T530", ALC269_FIXUP_LENOVO_DOCK),
Felix Kaechelec8415a42012-08-06 23:02:01 +02007050 SND_PCI_QUIRK(0x17aa, 0x21fa, "Thinkpad X230", ALC269_FIXUP_LENOVO_DOCK),
Stefán Freyr84f98fd2012-10-19 22:46:00 +02007051 SND_PCI_QUIRK(0x17aa, 0x21f3, "Thinkpad T430", ALC269_FIXUP_LENOVO_DOCK),
Philipp A. Mohrenweiser4407be62012-08-06 13:14:18 +02007052 SND_PCI_QUIRK(0x17aa, 0x21fb, "Thinkpad T430s", ALC269_FIXUP_LENOVO_DOCK),
David Henningsson108cc102012-07-20 10:37:25 +02007053 SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK),
David Henningssonaaedfb42013-08-16 14:09:02 +02007054 SND_PCI_QUIRK(0x17aa, 0x2208, "Thinkpad T431s", ALC269_FIXUP_LENOVO_DOCK),
Takashi Iwai9a811232015-12-09 15:17:43 +01007055 SND_PCI_QUIRK(0x17aa, 0x220c, "Thinkpad T440s", ALC292_FIXUP_TPT440),
Takashi Iwai1c37c222014-05-06 17:34:42 +02007056 SND_PCI_QUIRK(0x17aa, 0x220e, "Thinkpad T440p", ALC292_FIXUP_TPT440_DOCK),
Takashi Iwaia12137e2014-06-27 12:14:35 +02007057 SND_PCI_QUIRK(0x17aa, 0x2210, "Thinkpad T540p", ALC292_FIXUP_TPT440_DOCK),
Rick Sherman59a51a62015-08-18 21:04:30 -05007058 SND_PCI_QUIRK(0x17aa, 0x2211, "Thinkpad W541", ALC292_FIXUP_TPT440_DOCK),
Takashi Iwai6d169412014-10-07 17:27:02 +02007059 SND_PCI_QUIRK(0x17aa, 0x2212, "Thinkpad T440", ALC292_FIXUP_TPT440_DOCK),
Lukas Bossard7c215392014-10-29 18:31:07 +01007060 SND_PCI_QUIRK(0x17aa, 0x2214, "Thinkpad X240", ALC292_FIXUP_TPT440_DOCK),
David Henningssona4a9e082013-08-16 14:09:01 +02007061 SND_PCI_QUIRK(0x17aa, 0x2215, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Takashi Iwaib6903c02015-12-10 12:20:20 +01007062 SND_PCI_QUIRK(0x17aa, 0x2218, "Thinkpad X1 Carbon 2nd", ALC292_FIXUP_TPT440_DOCK),
Laura Abbottd05ea7d2015-10-02 11:09:54 -07007063 SND_PCI_QUIRK(0x17aa, 0x2223, "ThinkPad T550", ALC292_FIXUP_TPT440_DOCK),
Yves-Alexis Perezc0278662015-04-11 09:31:35 +02007064 SND_PCI_QUIRK(0x17aa, 0x2226, "ThinkPad X250", ALC292_FIXUP_TPT440_DOCK),
Kailang Yang61fcf8e2018-02-02 15:26:46 +08007065 SND_PCI_QUIRK(0x17aa, 0x222d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7066 SND_PCI_QUIRK(0x17aa, 0x222e, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
Torsten Hilbrichdab38e42016-06-07 13:14:21 +02007067 SND_PCI_QUIRK(0x17aa, 0x2231, "Thinkpad T560", ALC292_FIXUP_TPT460),
Sven Eckelmannc636b952016-04-11 16:55:26 +02007068 SND_PCI_QUIRK(0x17aa, 0x2233, "Thinkpad", ALC292_FIXUP_TPT460),
Kailang Yang61fcf8e2018-02-02 15:26:46 +08007069 SND_PCI_QUIRK(0x17aa, 0x2245, "Thinkpad T470", ALC298_FIXUP_TPT470_DOCK),
7070 SND_PCI_QUIRK(0x17aa, 0x2246, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7071 SND_PCI_QUIRK(0x17aa, 0x2247, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
Dennis Wassenberge4c07b32018-03-08 13:17:54 +01007072 SND_PCI_QUIRK(0x17aa, 0x2249, "Thinkpad", ALC292_FIXUP_TPT460),
Kailang Yang61fcf8e2018-02-02 15:26:46 +08007073 SND_PCI_QUIRK(0x17aa, 0x224b, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7074 SND_PCI_QUIRK(0x17aa, 0x224c, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7075 SND_PCI_QUIRK(0x17aa, 0x224d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
Benjamin Berg85981df2018-02-14 13:29:39 +01007076 SND_PCI_QUIRK(0x17aa, 0x225d, "Thinkpad T480", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Kailang3694cb22015-12-28 11:35:24 +08007077 SND_PCI_QUIRK(0x17aa, 0x30bb, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
Hui Wang6ef2f682016-03-11 12:04:02 +08007078 SND_PCI_QUIRK(0x17aa, 0x30e2, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
Hui Wangf33f79f2017-07-07 12:08:29 +08007079 SND_PCI_QUIRK(0x17aa, 0x310c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
Dennis Wassenbergbef33e12019-06-28 10:54:53 +02007080 SND_PCI_QUIRK(0x17aa, 0x3111, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
Hui Wange41fc8c2018-06-25 14:40:56 +08007081 SND_PCI_QUIRK(0x17aa, 0x312a, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
Kailang Yang65811832018-04-25 17:07:27 +08007082 SND_PCI_QUIRK(0x17aa, 0x312f, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
Hui Wang8da5bbf2017-12-22 11:17:46 +08007083 SND_PCI_QUIRK(0x17aa, 0x313c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
David Henningsson56f27012016-01-11 09:33:14 +01007084 SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
Takashi Iwaifedb2242014-11-13 07:11:38 +01007085 SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC),
Michał Wadowski56df90b2019-05-14 16:58:00 +02007086 SND_PCI_QUIRK(0x17aa, 0x3978, "Lenovo B50-70", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
David Henningssona4a9e082013-08-16 14:09:01 +02007087 SND_PCI_QUIRK(0x17aa, 0x5013, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Kailang Yang1bb3e062013-09-27 13:10:25 +02007088 SND_PCI_QUIRK(0x17aa, 0x501a, "Thinkpad", ALC283_FIXUP_INT_MIC),
Takashi Iwaic497d9f2014-10-08 12:14:40 +02007089 SND_PCI_QUIRK(0x17aa, 0x501e, "Thinkpad L440", ALC292_FIXUP_TPT440_DOCK),
David Henningssoncd5302c2013-08-19 12:22:33 +02007090 SND_PCI_QUIRK(0x17aa, 0x5026, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Jo-Philipp Wichf2aa1112015-04-13 12:47:26 +02007091 SND_PCI_QUIRK(0x17aa, 0x5034, "Thinkpad T450", ALC292_FIXUP_TPT440_DOCK),
Sebastian Wicki80b311d2015-03-23 17:23:11 +01007092 SND_PCI_QUIRK(0x17aa, 0x5036, "Thinkpad T450s", ALC292_FIXUP_TPT440_DOCK),
Ansgar Hegerfeld09ea9972015-05-14 12:31:32 +02007093 SND_PCI_QUIRK(0x17aa, 0x503c, "Thinkpad L450", ALC292_FIXUP_TPT440_DOCK),
Conrad Kostecki037e1192016-04-26 10:08:10 +02007094 SND_PCI_QUIRK(0x17aa, 0x504a, "ThinkPad X260", ALC292_FIXUP_TPT440_DOCK),
Hui Wang23adc192015-12-08 12:27:18 +08007095 SND_PCI_QUIRK(0x17aa, 0x504b, "Thinkpad", ALC293_FIXUP_LENOVO_SPK_NOISE),
Jaroslav Kysela0f087ee2016-06-24 15:13:16 +02007096 SND_PCI_QUIRK(0x17aa, 0x5050, "Thinkpad T560p", ALC292_FIXUP_TPT460),
Torsten Hilbrich9cd25742016-07-05 10:40:22 +02007097 SND_PCI_QUIRK(0x17aa, 0x5051, "Thinkpad L460", ALC292_FIXUP_TPT460),
Jaroslav Kysela0f087ee2016-06-24 15:13:16 +02007098 SND_PCI_QUIRK(0x17aa, 0x5053, "Thinkpad T460", ALC292_FIXUP_TPT460),
Kailang Yang61fcf8e2018-02-02 15:26:46 +08007099 SND_PCI_QUIRK(0x17aa, 0x505d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7100 SND_PCI_QUIRK(0x17aa, 0x505f, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7101 SND_PCI_QUIRK(0x17aa, 0x5062, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
David Henningssoncd5302c2013-08-19 12:22:33 +02007102 SND_PCI_QUIRK(0x17aa, 0x5109, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Kailang Yang61fcf8e2018-02-02 15:26:46 +08007103 SND_PCI_QUIRK(0x17aa, 0x511e, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7104 SND_PCI_QUIRK(0x17aa, 0x511f, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
David Henningsson012e7eb2012-08-08 08:43:37 +02007105 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K),
Takashi Iwai1d045db2011-07-07 18:23:21 +02007106 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
Ayman Bagabas0fbf21c2019-05-23 05:30:11 -04007107 SND_PCI_QUIRK(0x19e5, 0x3204, "Huawei MACH-WX9", ALC256_FIXUP_HUAWEI_MACH_WX9_PINS),
Anisse Astier02b504d2013-06-03 11:53:10 +02007108 SND_PCI_QUIRK(0x1b7d, 0xa831, "Ordissimo EVE2 ", ALC269VB_FIXUP_ORDISSIMO_EVE2), /* Also known as Malata PC-B1303 */
Takashi Iwaia4297b52011-08-23 18:40:12 +02007109
Takashi Iwaia7f3eed2012-02-16 13:03:18 +01007110#if 0
Takashi Iwaia4297b52011-08-23 18:40:12 +02007111 /* Below is a quirk table taken from the old code.
7112 * Basically the device should work as is without the fixup table.
7113 * If BIOS doesn't give a proper info, enable the corresponding
7114 * fixup entry.
Jesper Juhl7d7eb9e2012-04-12 22:11:25 +02007115 */
Takashi Iwaia4297b52011-08-23 18:40:12 +02007116 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
7117 ALC269_FIXUP_AMIC),
7118 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269_FIXUP_AMIC),
Takashi Iwaia4297b52011-08-23 18:40:12 +02007119 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269_FIXUP_AMIC),
7120 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_FIXUP_AMIC),
7121 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269_FIXUP_AMIC),
7122 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269_FIXUP_AMIC),
7123 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269_FIXUP_AMIC),
7124 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269_FIXUP_AMIC),
7125 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_FIXUP_AMIC),
7126 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269_FIXUP_AMIC),
7127 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_FIXUP_AMIC),
7128 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_FIXUP_AMIC),
7129 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_FIXUP_AMIC),
7130 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_FIXUP_AMIC),
7131 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_FIXUP_AMIC),
7132 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_FIXUP_AMIC),
7133 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_FIXUP_AMIC),
7134 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_FIXUP_AMIC),
7135 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_FIXUP_AMIC),
7136 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_FIXUP_AMIC),
7137 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_FIXUP_AMIC),
7138 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_FIXUP_AMIC),
7139 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_FIXUP_AMIC),
7140 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_FIXUP_AMIC),
7141 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_FIXUP_AMIC),
7142 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_FIXUP_AMIC),
7143 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_FIXUP_AMIC),
7144 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_FIXUP_AMIC),
7145 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_FIXUP_AMIC),
7146 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_FIXUP_AMIC),
7147 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_FIXUP_AMIC),
7148 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_FIXUP_AMIC),
7149 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_FIXUP_AMIC),
7150 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_FIXUP_AMIC),
7151 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_FIXUP_AMIC),
7152 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_FIXUP_DMIC),
7153 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_FIXUP_AMIC),
7154 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_AMIC),
7155 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_FIXUP_DMIC),
7156 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_FIXUP_DMIC),
7157#endif
7158 {}
7159};
7160
David Henningsson214eef72014-07-22 14:09:35 +02007161static const struct snd_pci_quirk alc269_fixup_vendor_tbl[] = {
7162 SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC),
7163 SND_PCI_QUIRK_VENDOR(0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED),
7164 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
7165 SND_PCI_QUIRK_VENDOR(0x17aa, "Thinkpad", ALC269_FIXUP_THINKPAD_ACPI),
Ayman Bagabas0fbf21c2019-05-23 05:30:11 -04007166 SND_PCI_QUIRK_VENDOR(0x19e5, "Huawei Matebook", ALC255_FIXUP_MIC_MUTE_LED),
David Henningsson214eef72014-07-22 14:09:35 +02007167 {}
7168};
7169
Takashi Iwai1727a772013-01-10 09:52:52 +01007170static const struct hda_model_fixup alc269_fixup_models[] = {
Takashi Iwaia4297b52011-08-23 18:40:12 +02007171 {.id = ALC269_FIXUP_AMIC, .name = "laptop-amic"},
7172 {.id = ALC269_FIXUP_DMIC, .name = "laptop-dmic"},
Takashi Iwai6e72aa52012-06-25 10:52:25 +02007173 {.id = ALC269_FIXUP_STEREO_DMIC, .name = "alc269-dmic"},
7174 {.id = ALC271_FIXUP_DMIC, .name = "alc271-dmic"},
7175 {.id = ALC269_FIXUP_INV_DMIC, .name = "inv-dmic"},
David Henningsson7c478f02013-10-11 10:18:46 +02007176 {.id = ALC269_FIXUP_HEADSET_MIC, .name = "headset-mic"},
Takashi Iwaib0169512015-05-19 10:20:13 +02007177 {.id = ALC269_FIXUP_HEADSET_MODE, .name = "headset-mode"},
7178 {.id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC, .name = "headset-mode-no-hp-mic"},
David Henningsson108cc102012-07-20 10:37:25 +02007179 {.id = ALC269_FIXUP_LENOVO_DOCK, .name = "lenovo-dock"},
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01007180 {.id = ALC269_FIXUP_HP_GPIO_LED, .name = "hp-gpio-led"},
Jaroslav Kysela04d54662017-03-09 13:29:13 +01007181 {.id = ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED, .name = "hp-dock-gpio-mic1-led"},
David Henningssone32aa852013-06-17 11:04:02 +02007182 {.id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "dell-headset-multi"},
7183 {.id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE, .name = "dell-headset-dock"},
Takashi Iwaia26d96c2018-06-26 15:09:25 +02007184 {.id = ALC269_FIXUP_DELL3_MIC_NO_PRESENCE, .name = "dell-headset3"},
7185 {.id = ALC269_FIXUP_DELL4_MIC_NO_PRESENCE, .name = "dell-headset4"},
Kailang Yangbe8ef162014-04-08 15:19:49 +08007186 {.id = ALC283_FIXUP_CHROME_BOOK, .name = "alc283-dac-wcaps"},
Kailang Yang0202e992013-12-02 15:20:15 +08007187 {.id = ALC283_FIXUP_SENSE_COMBO_JACK, .name = "alc283-sense-combo"},
Takashi Iwai1c37c222014-05-06 17:34:42 +02007188 {.id = ALC292_FIXUP_TPT440_DOCK, .name = "tpt440-dock"},
Takashi Iwai9a811232015-12-09 15:17:43 +01007189 {.id = ALC292_FIXUP_TPT440, .name = "tpt440"},
Sven Eckelmannc636b952016-04-11 16:55:26 +02007190 {.id = ALC292_FIXUP_TPT460, .name = "tpt460"},
Takashi Iwaia26d96c2018-06-26 15:09:25 +02007191 {.id = ALC298_FIXUP_TPT470_DOCK, .name = "tpt470-dock"},
Takashi Iwaiba90d6a2017-05-22 16:38:47 +02007192 {.id = ALC233_FIXUP_LENOVO_MULTI_CODECS, .name = "dual-codecs"},
Takashi Iwai28d1d6d2017-10-18 14:01:58 +02007193 {.id = ALC700_FIXUP_INTEL_REFERENCE, .name = "alc700-ref"},
Takashi Iwaia26d96c2018-06-26 15:09:25 +02007194 {.id = ALC269_FIXUP_SONY_VAIO, .name = "vaio"},
7195 {.id = ALC269_FIXUP_DELL_M101Z, .name = "dell-m101z"},
7196 {.id = ALC269_FIXUP_ASUS_G73JW, .name = "asus-g73jw"},
7197 {.id = ALC269_FIXUP_LENOVO_EAPD, .name = "lenovo-eapd"},
7198 {.id = ALC275_FIXUP_SONY_HWEQ, .name = "sony-hweq"},
7199 {.id = ALC269_FIXUP_PCM_44K, .name = "pcm44k"},
7200 {.id = ALC269_FIXUP_LIFEBOOK, .name = "lifebook"},
7201 {.id = ALC269_FIXUP_LIFEBOOK_EXTMIC, .name = "lifebook-extmic"},
7202 {.id = ALC269_FIXUP_LIFEBOOK_HP_PIN, .name = "lifebook-hp-pin"},
7203 {.id = ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC, .name = "lifebook-u7x7"},
7204 {.id = ALC269VB_FIXUP_AMIC, .name = "alc269vb-amic"},
7205 {.id = ALC269VB_FIXUP_DMIC, .name = "alc269vb-dmic"},
7206 {.id = ALC269_FIXUP_HP_MUTE_LED_MIC1, .name = "hp-mute-led-mic1"},
7207 {.id = ALC269_FIXUP_HP_MUTE_LED_MIC2, .name = "hp-mute-led-mic2"},
7208 {.id = ALC269_FIXUP_HP_MUTE_LED_MIC3, .name = "hp-mute-led-mic3"},
7209 {.id = ALC269_FIXUP_HP_GPIO_MIC1_LED, .name = "hp-gpio-mic1"},
7210 {.id = ALC269_FIXUP_HP_LINE1_MIC1_LED, .name = "hp-line1-mic1"},
7211 {.id = ALC269_FIXUP_NO_SHUTUP, .name = "noshutup"},
7212 {.id = ALC286_FIXUP_SONY_MIC_NO_PRESENCE, .name = "sony-nomic"},
7213 {.id = ALC269_FIXUP_ASPIRE_HEADSET_MIC, .name = "aspire-headset-mic"},
7214 {.id = ALC269_FIXUP_ASUS_X101, .name = "asus-x101"},
7215 {.id = ALC271_FIXUP_HP_GATE_MIC_JACK, .name = "acer-ao7xx"},
7216 {.id = ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572, .name = "acer-aspire-e1"},
7217 {.id = ALC269_FIXUP_ACER_AC700, .name = "acer-ac700"},
7218 {.id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST, .name = "limit-mic-boost"},
7219 {.id = ALC269VB_FIXUP_ASUS_ZENBOOK, .name = "asus-zenbook"},
7220 {.id = ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A, .name = "asus-zenbook-ux31a"},
7221 {.id = ALC269VB_FIXUP_ORDISSIMO_EVE2, .name = "ordissimo"},
7222 {.id = ALC282_FIXUP_ASUS_TX300, .name = "asus-tx300"},
7223 {.id = ALC283_FIXUP_INT_MIC, .name = "alc283-int-mic"},
7224 {.id = ALC290_FIXUP_MONO_SPEAKERS_HSJACK, .name = "mono-speakers"},
7225 {.id = ALC290_FIXUP_SUBWOOFER_HSJACK, .name = "alc290-subwoofer"},
7226 {.id = ALC269_FIXUP_THINKPAD_ACPI, .name = "thinkpad"},
7227 {.id = ALC269_FIXUP_DMIC_THINKPAD_ACPI, .name = "dmic-thinkpad"},
7228 {.id = ALC255_FIXUP_ACER_MIC_NO_PRESENCE, .name = "alc255-acer"},
7229 {.id = ALC255_FIXUP_ASUS_MIC_NO_PRESENCE, .name = "alc255-asus"},
7230 {.id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc255-dell1"},
7231 {.id = ALC255_FIXUP_DELL2_MIC_NO_PRESENCE, .name = "alc255-dell2"},
7232 {.id = ALC293_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc293-dell1"},
7233 {.id = ALC283_FIXUP_HEADSET_MIC, .name = "alc283-headset"},
Takashi Iwaib3802782018-11-26 17:47:46 +01007234 {.id = ALC255_FIXUP_MIC_MUTE_LED, .name = "alc255-dell-mute"},
Takashi Iwaia26d96c2018-06-26 15:09:25 +02007235 {.id = ALC282_FIXUP_ASPIRE_V5_PINS, .name = "aspire-v5"},
7236 {.id = ALC280_FIXUP_HP_GPIO4, .name = "hp-gpio4"},
7237 {.id = ALC286_FIXUP_HP_GPIO_LED, .name = "hp-gpio-led"},
7238 {.id = ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY, .name = "hp-gpio2-hotkey"},
7239 {.id = ALC280_FIXUP_HP_DOCK_PINS, .name = "hp-dock-pins"},
7240 {.id = ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED, .name = "hp-dock-gpio-mic"},
7241 {.id = ALC280_FIXUP_HP_9480M, .name = "hp-9480m"},
7242 {.id = ALC288_FIXUP_DELL_HEADSET_MODE, .name = "alc288-dell-headset"},
7243 {.id = ALC288_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc288-dell1"},
7244 {.id = ALC288_FIXUP_DELL_XPS_13, .name = "alc288-dell-xps13"},
7245 {.id = ALC292_FIXUP_DELL_E7X, .name = "dell-e7x"},
7246 {.id = ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK, .name = "alc293-dell"},
7247 {.id = ALC298_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc298-dell1"},
7248 {.id = ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE, .name = "alc298-dell-aio"},
7249 {.id = ALC275_FIXUP_DELL_XPS, .name = "alc275-dell-xps"},
7250 {.id = ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE, .name = "alc256-dell-xps13"},
7251 {.id = ALC293_FIXUP_LENOVO_SPK_NOISE, .name = "lenovo-spk-noise"},
7252 {.id = ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY, .name = "lenovo-hotkey"},
7253 {.id = ALC255_FIXUP_DELL_SPK_NOISE, .name = "dell-spk-noise"},
Kailang Yang82aa0d72019-01-11 17:15:53 +08007254 {.id = ALC225_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc225-dell1"},
Takashi Iwaia26d96c2018-06-26 15:09:25 +02007255 {.id = ALC295_FIXUP_DISABLE_DAC3, .name = "alc295-disable-dac3"},
7256 {.id = ALC280_FIXUP_HP_HEADSET_MIC, .name = "alc280-hp-headset"},
7257 {.id = ALC221_FIXUP_HP_FRONT_MIC, .name = "alc221-hp-mic"},
7258 {.id = ALC298_FIXUP_SPK_VOLUME, .name = "alc298-spk-volume"},
7259 {.id = ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER, .name = "dell-inspiron-7559"},
7260 {.id = ALC269_FIXUP_ATIV_BOOK_8, .name = "ativ-book"},
7261 {.id = ALC221_FIXUP_HP_MIC_NO_PRESENCE, .name = "alc221-hp-mic"},
7262 {.id = ALC256_FIXUP_ASUS_HEADSET_MODE, .name = "alc256-asus-headset"},
7263 {.id = ALC256_FIXUP_ASUS_MIC, .name = "alc256-asus-mic"},
7264 {.id = ALC256_FIXUP_ASUS_AIO_GPIO2, .name = "alc256-asus-aio"},
7265 {.id = ALC233_FIXUP_ASUS_MIC_NO_PRESENCE, .name = "alc233-asus"},
7266 {.id = ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE, .name = "alc233-eapd"},
7267 {.id = ALC294_FIXUP_LENOVO_MIC_LOCATION, .name = "alc294-lenovo-mic"},
7268 {.id = ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE, .name = "alc225-wyse"},
7269 {.id = ALC274_FIXUP_DELL_AIO_LINEOUT_VERB, .name = "alc274-dell-aio"},
7270 {.id = ALC255_FIXUP_DUMMY_LINEOUT_VERB, .name = "alc255-dummy-lineout"},
7271 {.id = ALC255_FIXUP_DELL_HEADSET_MIC, .name = "alc255-dell-headset"},
7272 {.id = ALC295_FIXUP_HP_X360, .name = "alc295-hp-x360"},
Kailang Yang8983eb62019-04-03 15:31:49 +08007273 {.id = ALC225_FIXUP_HEADSET_JACK, .name = "alc-headset-jack"},
7274 {.id = ALC295_FIXUP_CHROME_BOOK, .name = "alc-chrome-book"},
Bernhard Rosenkraenzere2a829b2019-03-05 00:38:19 +01007275 {.id = ALC299_FIXUP_PREDATOR_SPK, .name = "predator-spk"},
Takashi Iwai1d045db2011-07-07 18:23:21 +02007276 {}
7277};
Kailang Yangcfc5a842016-02-03 15:20:39 +08007278#define ALC225_STANDARD_PINS \
Kailang Yangcfc5a842016-02-03 15:20:39 +08007279 {0x21, 0x04211020}
Takashi Iwai1d045db2011-07-07 18:23:21 +02007280
Hui Wange8191a82015-04-24 13:39:59 +08007281#define ALC256_STANDARD_PINS \
7282 {0x12, 0x90a60140}, \
7283 {0x14, 0x90170110}, \
Hui Wange8191a82015-04-24 13:39:59 +08007284 {0x21, 0x02211020}
7285
David Henningssonfea185e2014-09-03 10:23:04 +02007286#define ALC282_STANDARD_PINS \
Hui Wang11580292015-08-03 11:03:49 +08007287 {0x14, 0x90170110}
Kailang Yange1e62b92015-04-08 16:01:22 +08007288
David Henningssonfea185e2014-09-03 10:23:04 +02007289#define ALC290_STANDARD_PINS \
Hui Wang11580292015-08-03 11:03:49 +08007290 {0x12, 0x99a30130}
David Henningssonfea185e2014-09-03 10:23:04 +02007291
7292#define ALC292_STANDARD_PINS \
7293 {0x14, 0x90170110}, \
Hui Wang11580292015-08-03 11:03:49 +08007294 {0x15, 0x0221401f}
Kailang Yang977e6272015-05-18 15:31:20 +08007295
Hui Wang3f6409702016-09-11 11:26:16 +08007296#define ALC295_STANDARD_PINS \
7297 {0x12, 0xb7a60130}, \
7298 {0x14, 0x90170110}, \
Hui Wang3f6409702016-09-11 11:26:16 +08007299 {0x21, 0x04211020}
7300
Woodrow Shen703867e2015-08-05 12:34:12 +08007301#define ALC298_STANDARD_PINS \
7302 {0x12, 0x90a60130}, \
7303 {0x21, 0x03211020}
7304
Hui Wange1918932014-05-26 16:22:44 +08007305static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
Kailang Yang8a328ac2018-08-21 16:54:41 +08007306 SND_HDA_PIN_QUIRK(0x10ec0221, 0x103c, "HP Workstation", ALC221_FIXUP_HP_HEADSET_MIC,
7307 {0x14, 0x01014020},
7308 {0x17, 0x90170110},
7309 {0x18, 0x02a11030},
7310 {0x19, 0x0181303F},
7311 {0x21, 0x0221102f}),
Chris Chiu5824ce82017-02-28 14:17:11 -06007312 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1025, "Acer", ALC255_FIXUP_ACER_MIC_NO_PRESENCE,
7313 {0x12, 0x90a601c0},
7314 {0x14, 0x90171120},
7315 {0x21, 0x02211030}),
Chris Chiu615966a2017-02-28 14:17:12 -06007316 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1043, "ASUS", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE,
7317 {0x14, 0x90170110},
7318 {0x1b, 0x90a70130},
7319 {0x21, 0x03211020}),
7320 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1043, "ASUS", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE,
7321 {0x1a, 0x90a70130},
7322 {0x1b, 0x90170110},
7323 {0x21, 0x03211020}),
David Henningsson2ae95572016-02-25 09:37:05 +01007324 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
Kailang Yangcfc5a842016-02-03 15:20:39 +08007325 ALC225_STANDARD_PINS,
Hui Wang8a132092016-07-08 14:26:57 +08007326 {0x12, 0xb7a60130},
Kailang Yangcfc5a842016-02-03 15:20:39 +08007327 {0x14, 0x901701a0}),
David Henningsson2ae95572016-02-25 09:37:05 +01007328 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
Kailang Yangcfc5a842016-02-03 15:20:39 +08007329 ALC225_STANDARD_PINS,
Hui Wang8a132092016-07-08 14:26:57 +08007330 {0x12, 0xb7a60130},
Kailang Yangcfc5a842016-02-03 15:20:39 +08007331 {0x14, 0x901701b0}),
Hui Wang8a132092016-07-08 14:26:57 +08007332 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
7333 ALC225_STANDARD_PINS,
7334 {0x12, 0xb7a60150},
7335 {0x14, 0x901701a0}),
7336 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
7337 ALC225_STANDARD_PINS,
7338 {0x12, 0xb7a60150},
7339 {0x14, 0x901701b0}),
7340 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
7341 ALC225_STANDARD_PINS,
7342 {0x12, 0xb7a60130},
7343 {0x1b, 0x90170110}),
Kai-Heng Feng0ce48e12017-11-20 02:29:13 -05007344 SND_HDA_PIN_QUIRK(0x10ec0233, 0x8086, "Intel NUC Skull Canyon", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
7345 {0x1b, 0x01111010},
7346 {0x1e, 0x01451130},
7347 {0x21, 0x02211020}),
Hui Wang986376b2018-05-30 12:33:07 +08007348 SND_HDA_PIN_QUIRK(0x10ec0235, 0x17aa, "Lenovo", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY,
7349 {0x12, 0x90a60140},
7350 {0x14, 0x90170110},
7351 {0x19, 0x02a11030},
7352 {0x21, 0x02211020}),
Hui Wange41fc8c2018-06-25 14:40:56 +08007353 SND_HDA_PIN_QUIRK(0x10ec0235, 0x17aa, "Lenovo", ALC294_FIXUP_LENOVO_MIC_LOCATION,
7354 {0x14, 0x90170110},
7355 {0x19, 0x02a11030},
7356 {0x1a, 0x02a11040},
7357 {0x1b, 0x01014020},
7358 {0x21, 0x0221101f}),
Hui Wangc6b17f12018-07-06 15:14:11 +08007359 SND_HDA_PIN_QUIRK(0x10ec0235, 0x17aa, "Lenovo", ALC294_FIXUP_LENOVO_MIC_LOCATION,
7360 {0x14, 0x90170110},
Hui Wangd06fb562018-10-10 11:57:25 +08007361 {0x19, 0x02a11030},
7362 {0x1a, 0x02a11040},
7363 {0x1b, 0x01011020},
7364 {0x21, 0x0221101f}),
7365 SND_HDA_PIN_QUIRK(0x10ec0235, 0x17aa, "Lenovo", ALC294_FIXUP_LENOVO_MIC_LOCATION,
7366 {0x14, 0x90170110},
Hui Wangc6b17f12018-07-06 15:14:11 +08007367 {0x19, 0x02a11020},
7368 {0x1a, 0x02a11030},
7369 {0x21, 0x0221101f}),
Hui Wangf2657882017-10-24 16:53:34 +08007370 SND_HDA_PIN_QUIRK(0x10ec0236, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7371 {0x12, 0x90a60140},
7372 {0x14, 0x90170110},
7373 {0x21, 0x02211020}),
7374 SND_HDA_PIN_QUIRK(0x10ec0236, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7375 {0x12, 0x90a60140},
7376 {0x14, 0x90170150},
7377 {0x21, 0x02211020}),
Hui Wangb26e36b2019-04-17 16:10:32 +08007378 SND_HDA_PIN_QUIRK(0x10ec0236, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7379 {0x21, 0x02211020}),
Kailang Yang0a29c572019-04-24 16:34:25 +08007380 SND_HDA_PIN_QUIRK(0x10ec0236, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7381 {0x12, 0x40000000},
7382 {0x14, 0x90170110},
7383 {0x21, 0x02211020}),
Hui Wangc77900e2014-09-03 11:31:07 +08007384 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE,
Hui Wangc77900e2014-09-03 11:31:07 +08007385 {0x14, 0x90170110},
Hui Wangc77900e2014-09-03 11:31:07 +08007386 {0x21, 0x02211020}),
David Henningsson76c21322014-06-24 14:46:54 +02007387 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang86c72d12016-05-25 12:12:32 +08007388 {0x14, 0x90170130},
7389 {0x21, 0x02211040}),
7390 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningsson76c21322014-06-24 14:46:54 +02007391 {0x12, 0x90a60140},
7392 {0x14, 0x90170110},
David Henningsson76c21322014-06-24 14:46:54 +02007393 {0x21, 0x02211020}),
7394 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7395 {0x12, 0x90a60160},
7396 {0x14, 0x90170120},
David Henningsson76c21322014-06-24 14:46:54 +02007397 {0x21, 0x02211030}),
7398 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang392c9da2016-09-26 10:59:38 +08007399 {0x14, 0x90170110},
7400 {0x1b, 0x02011020},
7401 {0x21, 0x0221101f}),
7402 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang6aecd872016-10-20 14:03:33 +08007403 {0x14, 0x90170110},
7404 {0x1b, 0x01011020},
7405 {0x21, 0x0221101f}),
7406 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssoncba59972015-07-22 10:00:25 +02007407 {0x14, 0x90170130},
David Henningssoncba59972015-07-22 10:00:25 +02007408 {0x1b, 0x01014020},
David Henningssoncba59972015-07-22 10:00:25 +02007409 {0x21, 0x0221103f}),
7410 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang59ec4b52016-08-04 15:28:04 +08007411 {0x14, 0x90170130},
Hui Wang6aecd872016-10-20 14:03:33 +08007412 {0x1b, 0x01011020},
7413 {0x21, 0x0221103f}),
7414 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7415 {0x14, 0x90170130},
Hui Wang59ec4b52016-08-04 15:28:04 +08007416 {0x1b, 0x02011020},
7417 {0x21, 0x0221103f}),
7418 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Woodrow Shene9c28e12015-07-25 10:36:16 +08007419 {0x14, 0x90170150},
Woodrow Shene9c28e12015-07-25 10:36:16 +08007420 {0x1b, 0x02011020},
Woodrow Shene9c28e12015-07-25 10:36:16 +08007421 {0x21, 0x0221105f}),
7422 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Woodrow Shene9c28e12015-07-25 10:36:16 +08007423 {0x14, 0x90170110},
Woodrow Shene9c28e12015-07-25 10:36:16 +08007424 {0x1b, 0x01014020},
Woodrow Shene9c28e12015-07-25 10:36:16 +08007425 {0x21, 0x0221101f}),
7426 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningsson76c21322014-06-24 14:46:54 +02007427 {0x12, 0x90a60160},
7428 {0x14, 0x90170120},
7429 {0x17, 0x90170140},
David Henningsson76c21322014-06-24 14:46:54 +02007430 {0x21, 0x0321102f}),
7431 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7432 {0x12, 0x90a60160},
7433 {0x14, 0x90170130},
David Henningsson76c21322014-06-24 14:46:54 +02007434 {0x21, 0x02211040}),
7435 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7436 {0x12, 0x90a60160},
7437 {0x14, 0x90170140},
David Henningsson76c21322014-06-24 14:46:54 +02007438 {0x21, 0x02211050}),
7439 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7440 {0x12, 0x90a60170},
7441 {0x14, 0x90170120},
David Henningsson76c21322014-06-24 14:46:54 +02007442 {0x21, 0x02211030}),
7443 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7444 {0x12, 0x90a60170},
7445 {0x14, 0x90170130},
David Henningsson76c21322014-06-24 14:46:54 +02007446 {0x21, 0x02211040}),
Hui Wang70658b92015-03-06 14:03:57 +08007447 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang70658b92015-03-06 14:03:57 +08007448 {0x12, 0x90a60170},
Hui Wang0a1f90a2016-01-13 11:51:38 +08007449 {0x14, 0x90171130},
7450 {0x21, 0x02211040}),
7451 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7452 {0x12, 0x90a60170},
Hui Wang70658b92015-03-06 14:03:57 +08007453 {0x14, 0x90170140},
Hui Wang70658b92015-03-06 14:03:57 +08007454 {0x21, 0x02211050}),
David Henningsson9b5a4e32015-05-11 14:04:14 +02007455 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell Inspiron 5548", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningsson9b5a4e32015-05-11 14:04:14 +02007456 {0x12, 0x90a60180},
7457 {0x14, 0x90170130},
David Henningsson9b5a4e32015-05-11 14:04:14 +02007458 {0x21, 0x02211040}),
AceLan Kaof90d83b2016-06-03 14:45:25 +08007459 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell Inspiron 5565", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7460 {0x12, 0x90a60180},
7461 {0x14, 0x90170120},
7462 {0x21, 0x02211030}),
Hui Wang989dbe42016-11-23 16:05:38 +08007463 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7464 {0x1b, 0x01011020},
7465 {0x21, 0x02211010}),
Kailang Yang7081adf2015-03-30 17:05:37 +08007466 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang285d5dd2017-12-22 11:17:45 +08007467 {0x12, 0x90a60130},
7468 {0x14, 0x90170110},
7469 {0x1b, 0x01011020},
7470 {0x21, 0x0221101f}),
7471 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Kailang Yang81a12312015-05-28 16:48:22 +08007472 {0x12, 0x90a60160},
7473 {0x14, 0x90170120},
Kailang Yang81a12312015-05-28 16:48:22 +08007474 {0x21, 0x02211030}),
7475 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Woodrow Shenf83c3292016-06-24 15:58:34 +08007476 {0x12, 0x90a60170},
7477 {0x14, 0x90170120},
7478 {0x21, 0x02211030}),
Shrirang Bagul311042d2016-08-29 15:19:27 +08007479 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell Inspiron 5468", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7480 {0x12, 0x90a60180},
7481 {0x14, 0x90170120},
7482 {0x21, 0x02211030}),
Woodrow Shenf83c3292016-06-24 15:58:34 +08007483 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang3f6409702016-09-11 11:26:16 +08007484 {0x12, 0xb7a60130},
7485 {0x14, 0x90170110},
7486 {0x21, 0x02211020}),
David Henningssoncf51eb92014-10-30 08:26:02 +01007487 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang3f2f7c52018-01-29 14:23:15 +08007488 {0x12, 0x90a60130},
7489 {0x14, 0x90170110},
7490 {0x14, 0x01011020},
7491 {0x21, 0x0221101f}),
7492 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssoncf51eb92014-10-30 08:26:02 +01007493 ALC256_STANDARD_PINS),
Hui Wangb26e36b2019-04-17 16:10:32 +08007494 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7495 {0x14, 0x90170110},
7496 {0x1b, 0x01011020},
7497 {0x21, 0x0221101f}),
Chris Chiuc1732ed2017-02-28 14:17:13 -06007498 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC,
7499 {0x14, 0x90170110},
7500 {0x1b, 0x90a70130},
7501 {0x21, 0x04211020}),
7502 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC,
7503 {0x14, 0x90170110},
7504 {0x1b, 0x90a70130},
7505 {0x21, 0x03211020}),
Jian-Hong Pane1037352019-03-22 11:37:18 +08007506 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE,
Chris Chiua806ef12019-03-22 11:37:20 +08007507 {0x12, 0x90a60130},
7508 {0x14, 0x90170110},
7509 {0x21, 0x03211020}),
7510 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE,
Jian-Hong Pan6ac371a2019-03-22 11:37:22 +08007511 {0x12, 0x90a60130},
7512 {0x14, 0x90170110},
7513 {0x21, 0x04211020}),
7514 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE,
Jian-Hong Pane1037352019-03-22 11:37:18 +08007515 {0x1a, 0x90a70130},
7516 {0x1b, 0x90170110},
7517 {0x21, 0x03211020}),
Kailang Yang92266652017-12-14 15:28:58 +08007518 SND_HDA_PIN_QUIRK(0x10ec0274, 0x1028, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB,
Hui Wang75ee94b2017-11-09 08:48:08 +08007519 {0x12, 0xb7a60130},
7520 {0x13, 0xb8a61140},
7521 {0x16, 0x90170110},
7522 {0x21, 0x04211020}),
David Henningssoncf51eb92014-10-30 08:26:02 +01007523 SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC280_FIXUP_HP_GPIO4,
7524 {0x12, 0x90a60130},
7525 {0x14, 0x90170110},
7526 {0x15, 0x0421101f},
Hui Wang11580292015-08-03 11:03:49 +08007527 {0x1a, 0x04a11020}),
Hui Wang02796612014-09-03 11:31:11 +08007528 SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED,
7529 {0x12, 0x90a60140},
Hui Wang02796612014-09-03 11:31:11 +08007530 {0x14, 0x90170110},
7531 {0x15, 0x0421101f},
Hui Wang02796612014-09-03 11:31:11 +08007532 {0x18, 0x02811030},
Hui Wang02796612014-09-03 11:31:11 +08007533 {0x1a, 0x04a1103f},
Hui Wang11580292015-08-03 11:03:49 +08007534 {0x1b, 0x02011020}),
David Henningsson42304472014-07-22 11:42:17 +02007535 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP 15 Touchsmart", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007536 ALC282_STANDARD_PINS,
David Henningsson42304472014-07-22 11:42:17 +02007537 {0x12, 0x99a30130},
David Henningsson42304472014-07-22 11:42:17 +02007538 {0x19, 0x03a11020},
David Henningsson42304472014-07-22 11:42:17 +02007539 {0x21, 0x0321101f}),
Hui Wang2c609992014-09-03 11:31:08 +08007540 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007541 ALC282_STANDARD_PINS,
Hui Wang2c609992014-09-03 11:31:08 +08007542 {0x12, 0x99a30130},
Hui Wang2c609992014-09-03 11:31:08 +08007543 {0x19, 0x03a11020},
Hui Wang2c609992014-09-03 11:31:08 +08007544 {0x21, 0x03211040}),
7545 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007546 ALC282_STANDARD_PINS,
Hui Wang2c609992014-09-03 11:31:08 +08007547 {0x12, 0x99a30130},
Hui Wang2c609992014-09-03 11:31:08 +08007548 {0x19, 0x03a11030},
Hui Wang2c609992014-09-03 11:31:08 +08007549 {0x21, 0x03211020}),
7550 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007551 ALC282_STANDARD_PINS,
Hui Wang2c609992014-09-03 11:31:08 +08007552 {0x12, 0x99a30130},
Hui Wang2c609992014-09-03 11:31:08 +08007553 {0x19, 0x04a11020},
Hui Wang2c609992014-09-03 11:31:08 +08007554 {0x21, 0x0421101f}),
Hui Wang200afc02014-09-03 11:31:10 +08007555 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED,
David Henningssonaec856d2014-09-03 10:23:05 +02007556 ALC282_STANDARD_PINS,
Hui Wang200afc02014-09-03 11:31:10 +08007557 {0x12, 0x90a60140},
Hui Wang200afc02014-09-03 11:31:10 +08007558 {0x19, 0x04a11030},
Hui Wang200afc02014-09-03 11:31:10 +08007559 {0x21, 0x04211020}),
David Henningsson76c21322014-06-24 14:46:54 +02007560 SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007561 ALC282_STANDARD_PINS,
David Henningsson76c21322014-06-24 14:46:54 +02007562 {0x12, 0x90a60130},
David Henningsson76c21322014-06-24 14:46:54 +02007563 {0x21, 0x0321101f}),
7564 SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
7565 {0x12, 0x90a60160},
7566 {0x14, 0x90170120},
David Henningsson76c21322014-06-24 14:46:54 +02007567 {0x21, 0x02211030}),
Hui Wangbc262172014-09-03 11:31:05 +08007568 SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007569 ALC282_STANDARD_PINS,
Hui Wangbc262172014-09-03 11:31:05 +08007570 {0x12, 0x90a60130},
Hui Wangbc262172014-09-03 11:31:05 +08007571 {0x19, 0x03a11020},
Hui Wangbc262172014-09-03 11:31:05 +08007572 {0x21, 0x0321101f}),
Hui Wangc8c6ee62019-02-14 11:41:33 +08007573 SND_HDA_PIN_QUIRK(0x10ec0285, 0x17aa, "Lenovo", ALC285_FIXUP_LENOVO_PC_BEEP_IN_NOISE,
Hui Wangc4cfcf62018-11-26 14:17:16 +08007574 {0x12, 0x90a60130},
7575 {0x14, 0x90170110},
7576 {0x19, 0x04a11040},
7577 {0x21, 0x04211020}),
Chris Chiu33aaebd2018-12-05 14:48:53 +08007578 SND_HDA_PIN_QUIRK(0x10ec0286, 0x1025, "Acer", ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE,
7579 {0x12, 0x90a60130},
7580 {0x17, 0x90170110},
7581 {0x21, 0x02211020}),
Takashi Iwaid44a6862018-06-19 23:04:03 +02007582 SND_HDA_PIN_QUIRK(0x10ec0288, 0x1028, "Dell", ALC288_FIXUP_DELL1_MIC_NO_PRESENCE,
Kailang Yange1e62b92015-04-08 16:01:22 +08007583 {0x12, 0x90a60120},
Kailang Yange1e62b92015-04-08 16:01:22 +08007584 {0x14, 0x90170110},
Kailang Yange1e62b92015-04-08 16:01:22 +08007585 {0x21, 0x0321101f}),
Hui Wangd5078192018-03-02 13:05:36 +08007586 SND_HDA_PIN_QUIRK(0x10ec0289, 0x1028, "Dell", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
Hui Wang3f2f7c52018-01-29 14:23:15 +08007587 {0x12, 0xb7a60130},
7588 {0x14, 0x90170110},
7589 {0x21, 0x04211020}),
Hui Wange4442bc2014-09-03 11:31:09 +08007590 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007591 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08007592 {0x15, 0x04211040},
Hui Wange4442bc2014-09-03 11:31:09 +08007593 {0x18, 0x90170112},
Hui Wang11580292015-08-03 11:03:49 +08007594 {0x1a, 0x04a11020}),
Hui Wange4442bc2014-09-03 11:31:09 +08007595 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007596 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08007597 {0x15, 0x04211040},
Hui Wange4442bc2014-09-03 11:31:09 +08007598 {0x18, 0x90170110},
Hui Wang11580292015-08-03 11:03:49 +08007599 {0x1a, 0x04a11020}),
Hui Wange4442bc2014-09-03 11:31:09 +08007600 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007601 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08007602 {0x15, 0x0421101f},
Hui Wang11580292015-08-03 11:03:49 +08007603 {0x1a, 0x04a11020}),
Hui Wange4442bc2014-09-03 11:31:09 +08007604 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007605 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08007606 {0x15, 0x04211020},
Hui Wang11580292015-08-03 11:03:49 +08007607 {0x1a, 0x04a11040}),
Hui Wange4442bc2014-09-03 11:31:09 +08007608 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007609 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08007610 {0x14, 0x90170110},
7611 {0x15, 0x04211020},
Hui Wang11580292015-08-03 11:03:49 +08007612 {0x1a, 0x04a11040}),
Hui Wange4442bc2014-09-03 11:31:09 +08007613 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007614 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08007615 {0x14, 0x90170110},
7616 {0x15, 0x04211020},
Hui Wang11580292015-08-03 11:03:49 +08007617 {0x1a, 0x04a11020}),
Hui Wange4442bc2014-09-03 11:31:09 +08007618 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007619 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08007620 {0x14, 0x90170110},
7621 {0x15, 0x0421101f},
Hui Wang11580292015-08-03 11:03:49 +08007622 {0x1a, 0x04a11020}),
Hui Wange8818fa2014-09-03 11:31:04 +08007623 SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007624 ALC292_STANDARD_PINS,
Hui Wange8818fa2014-09-03 11:31:04 +08007625 {0x12, 0x90a60140},
Hui Wange8818fa2014-09-03 11:31:04 +08007626 {0x16, 0x01014020},
Hui Wang11580292015-08-03 11:03:49 +08007627 {0x19, 0x01a19030}),
Hui Wange8818fa2014-09-03 11:31:04 +08007628 SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007629 ALC292_STANDARD_PINS,
Hui Wange8818fa2014-09-03 11:31:04 +08007630 {0x12, 0x90a60140},
Hui Wange8818fa2014-09-03 11:31:04 +08007631 {0x16, 0x01014020},
7632 {0x18, 0x02a19031},
Hui Wang11580292015-08-03 11:03:49 +08007633 {0x19, 0x01a1903e}),
David Henningsson76c21322014-06-24 14:46:54 +02007634 SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007635 ALC292_STANDARD_PINS,
Hui Wang11580292015-08-03 11:03:49 +08007636 {0x12, 0x90a60140}),
David Henningsson76c21322014-06-24 14:46:54 +02007637 SND_HDA_PIN_QUIRK(0x10ec0293, 0x1028, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007638 ALC292_STANDARD_PINS,
David Henningsson76c21322014-06-24 14:46:54 +02007639 {0x13, 0x90a60140},
David Henningsson76c21322014-06-24 14:46:54 +02007640 {0x16, 0x21014020},
Hui Wang11580292015-08-03 11:03:49 +08007641 {0x19, 0x21a19030}),
David Henningssone03fdbd2014-06-27 08:41:59 +02007642 SND_HDA_PIN_QUIRK(0x10ec0293, 0x1028, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007643 ALC292_STANDARD_PINS,
Hui Wang11580292015-08-03 11:03:49 +08007644 {0x13, 0x90a60140}),
Chris Chiud8ae4582018-12-07 17:17:11 +08007645 SND_HDA_PIN_QUIRK(0x10ec0294, 0x1043, "ASUS", ALC294_FIXUP_ASUS_MIC,
7646 {0x14, 0x90170110},
7647 {0x1b, 0x90a70130},
7648 {0x21, 0x04211020}),
Jian-Hong Pan0bea4cc2018-12-07 17:17:13 +08007649 SND_HDA_PIN_QUIRK(0x10ec0294, 0x1043, "ASUS", ALC294_FIXUP_ASUS_SPK,
7650 {0x12, 0x90a60130},
7651 {0x17, 0x90170110},
Jian-Hong Pan8bb37a22019-02-21 17:00:18 +08007652 {0x21, 0x03211020}),
7653 SND_HDA_PIN_QUIRK(0x10ec0294, 0x1043, "ASUS", ALC294_FIXUP_ASUS_SPK,
7654 {0x12, 0x90a60130},
7655 {0x17, 0x90170110},
Jian-Hong Pan0bea4cc2018-12-07 17:17:13 +08007656 {0x21, 0x04211020}),
Takashi Iwai3887c262019-04-30 15:10:01 +02007657 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1043, "ASUS", ALC294_FIXUP_ASUS_SPK,
7658 {0x12, 0x90a60130},
7659 {0x17, 0x90170110},
7660 {0x21, 0x03211020}),
Kailang Yangfbc57122019-07-15 10:41:50 +08007661 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
Kailang Yang0a29c572019-04-24 16:34:25 +08007662 {0x14, 0x90170110},
7663 {0x21, 0x04211020}),
Kailang Yangfbc57122019-07-15 10:41:50 +08007664 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
7665 {0x14, 0x90170110},
7666 {0x21, 0x04211030}),
Hui Wang3f6409702016-09-11 11:26:16 +08007667 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wangf771d5b2016-10-18 10:59:09 +08007668 ALC295_STANDARD_PINS,
7669 {0x17, 0x21014020},
7670 {0x18, 0x21a19030}),
7671 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
7672 ALC295_STANDARD_PINS,
7673 {0x17, 0x21014040},
7674 {0x18, 0x21a19050}),
Hui Wang3f307832017-03-23 10:00:25 +08007675 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
7676 ALC295_STANDARD_PINS),
Kailang Yang977e6272015-05-18 15:31:20 +08007677 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
Woodrow Shen703867e2015-08-05 12:34:12 +08007678 ALC298_STANDARD_PINS,
Takashi Iwai9f502ff2015-08-05 12:09:45 +02007679 {0x17, 0x90170110}),
7680 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
7681 ALC298_STANDARD_PINS,
Woodrow Shen703867e2015-08-05 12:34:12 +08007682 {0x17, 0x90170140}),
7683 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
7684 ALC298_STANDARD_PINS,
Takashi Iwai9f502ff2015-08-05 12:09:45 +02007685 {0x17, 0x90170150}),
Kai-Heng Feng9f1bc2c42017-02-16 15:26:54 +08007686 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_SPK_VOLUME,
7687 {0x12, 0xb7a60140},
7688 {0x13, 0xb7a60150},
7689 {0x17, 0x90170110},
7690 {0x1a, 0x03011020},
7691 {0x21, 0x03211030}),
Kailang Yangfcc6c872017-06-29 15:21:27 +08007692 SND_HDA_PIN_QUIRK(0x10ec0299, 0x1028, "Dell", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
7693 ALC225_STANDARD_PINS,
7694 {0x12, 0xb7a60130},
Kailang Yangfcc6c872017-06-29 15:21:27 +08007695 {0x17, 0x90170110}),
Hui Wange1918932014-05-26 16:22:44 +08007696 {}
7697};
Takashi Iwai1d045db2011-07-07 18:23:21 +02007698
Takashi Iwai546bb672012-03-07 08:37:19 +01007699static void alc269_fill_coef(struct hda_codec *codec)
Takashi Iwai1d045db2011-07-07 18:23:21 +02007700{
Kailang Yang526af6e2012-03-07 08:25:20 +01007701 struct alc_spec *spec = codec->spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02007702 int val;
7703
Kailang Yang526af6e2012-03-07 08:25:20 +01007704 if (spec->codec_variant != ALC269_TYPE_ALC269VB)
Takashi Iwai546bb672012-03-07 08:37:19 +01007705 return;
Kailang Yang526af6e2012-03-07 08:25:20 +01007706
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007707 if ((alc_get_coef0(codec) & 0x00ff) < 0x015) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02007708 alc_write_coef_idx(codec, 0xf, 0x960b);
7709 alc_write_coef_idx(codec, 0xe, 0x8817);
7710 }
7711
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007712 if ((alc_get_coef0(codec) & 0x00ff) == 0x016) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02007713 alc_write_coef_idx(codec, 0xf, 0x960b);
7714 alc_write_coef_idx(codec, 0xe, 0x8814);
7715 }
7716
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007717 if ((alc_get_coef0(codec) & 0x00ff) == 0x017) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02007718 /* Power up output pin */
Takashi Iwai98b24882014-08-18 13:47:50 +02007719 alc_update_coef_idx(codec, 0x04, 0, 1<<11);
Takashi Iwai1d045db2011-07-07 18:23:21 +02007720 }
7721
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007722 if ((alc_get_coef0(codec) & 0x00ff) == 0x018) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02007723 val = alc_read_coef_idx(codec, 0xd);
Takashi Iwaif3ee07d2014-08-15 17:35:00 +02007724 if (val != -1 && (val & 0x0c00) >> 10 != 0x1) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02007725 /* Capless ramp up clock control */
7726 alc_write_coef_idx(codec, 0xd, val | (1<<10));
7727 }
7728 val = alc_read_coef_idx(codec, 0x17);
Takashi Iwaif3ee07d2014-08-15 17:35:00 +02007729 if (val != -1 && (val & 0x01c0) >> 6 != 0x4) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02007730 /* Class D power on reset */
7731 alc_write_coef_idx(codec, 0x17, val | (1<<7));
7732 }
7733 }
7734
Takashi Iwai98b24882014-08-18 13:47:50 +02007735 /* HP */
7736 alc_update_coef_idx(codec, 0x4, 0, 1<<11);
Takashi Iwai1d045db2011-07-07 18:23:21 +02007737}
7738
7739/*
7740 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02007741static int patch_alc269(struct hda_codec *codec)
7742{
7743 struct alc_spec *spec;
Takashi Iwai3de95172012-05-07 18:03:15 +02007744 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02007745
Takashi Iwai3de95172012-05-07 18:03:15 +02007746 err = alc_alloc_spec(codec, 0x0b);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007747 if (err < 0)
Takashi Iwai3de95172012-05-07 18:03:15 +02007748 return err;
7749
7750 spec = codec->spec;
Takashi Iwai08c189f2012-12-19 15:22:24 +01007751 spec->gen.shared_mic_vref_pin = 0x18;
Kailang Yang317d9312019-05-23 14:43:04 +08007752 codec->power_save_node = 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007753
Takashi Iwai225068a2015-05-29 10:42:14 +02007754#ifdef CONFIG_PM
7755 codec->patch_ops.suspend = alc269_suspend;
7756 codec->patch_ops.resume = alc269_resume;
7757#endif
Kailang Yangc2d6af52017-06-21 14:50:54 +08007758 spec->shutup = alc_default_shutup;
7759 spec->init_hook = alc_default_init;
Takashi Iwai225068a2015-05-29 10:42:14 +02007760
Takashi Iwai7639a062015-03-03 10:07:24 +01007761 switch (codec->core.vendor_id) {
Kailang Yang065380f2013-01-10 10:25:48 +01007762 case 0x10ec0269:
Takashi Iwai1d045db2011-07-07 18:23:21 +02007763 spec->codec_variant = ALC269_TYPE_ALC269VA;
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007764 switch (alc_get_coef0(codec) & 0x00f0) {
7765 case 0x0010:
Takashi Iwai5100cd02014-02-15 10:03:19 +01007766 if (codec->bus->pci &&
7767 codec->bus->pci->subsystem_vendor == 0x1025 &&
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007768 spec->cdefine.platform_type == 1)
Takashi Iwai20ca0c32011-10-17 16:00:35 +02007769 err = alc_codec_rename(codec, "ALC271X");
Takashi Iwai1d045db2011-07-07 18:23:21 +02007770 spec->codec_variant = ALC269_TYPE_ALC269VB;
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007771 break;
7772 case 0x0020:
Takashi Iwai5100cd02014-02-15 10:03:19 +01007773 if (codec->bus->pci &&
7774 codec->bus->pci->subsystem_vendor == 0x17aa &&
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007775 codec->bus->pci->subsystem_device == 0x21f3)
Takashi Iwai20ca0c32011-10-17 16:00:35 +02007776 err = alc_codec_rename(codec, "ALC3202");
Takashi Iwai1d045db2011-07-07 18:23:21 +02007777 spec->codec_variant = ALC269_TYPE_ALC269VC;
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007778 break;
Kailang Yangadcc70b2012-05-25 08:08:38 +02007779 case 0x0030:
7780 spec->codec_variant = ALC269_TYPE_ALC269VD;
7781 break;
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007782 default:
Takashi Iwai1d045db2011-07-07 18:23:21 +02007783 alc_fix_pll_init(codec, 0x20, 0x04, 15);
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007784 }
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007785 if (err < 0)
7786 goto error;
Kailang Yangc2d6af52017-06-21 14:50:54 +08007787 spec->shutup = alc269_shutup;
Takashi Iwai546bb672012-03-07 08:37:19 +01007788 spec->init_hook = alc269_fill_coef;
Takashi Iwai1d045db2011-07-07 18:23:21 +02007789 alc269_fill_coef(codec);
Kailang Yang065380f2013-01-10 10:25:48 +01007790 break;
7791
7792 case 0x10ec0280:
7793 case 0x10ec0290:
7794 spec->codec_variant = ALC269_TYPE_ALC280;
7795 break;
7796 case 0x10ec0282:
Kailang Yang065380f2013-01-10 10:25:48 +01007797 spec->codec_variant = ALC269_TYPE_ALC282;
Kailang Yang7b5c7a02014-03-18 16:15:54 +08007798 spec->shutup = alc282_shutup;
7799 spec->init_hook = alc282_init;
Kailang Yang065380f2013-01-10 10:25:48 +01007800 break;
Kailang Yang2af02be2013-08-22 10:03:50 +02007801 case 0x10ec0233:
7802 case 0x10ec0283:
7803 spec->codec_variant = ALC269_TYPE_ALC283;
7804 spec->shutup = alc283_shutup;
7805 spec->init_hook = alc283_init;
7806 break;
Kailang Yang065380f2013-01-10 10:25:48 +01007807 case 0x10ec0284:
7808 case 0x10ec0292:
7809 spec->codec_variant = ALC269_TYPE_ALC284;
7810 break;
Kailang Yang161ebf22013-10-24 11:36:33 +02007811 case 0x10ec0293:
Kailang Yang4731d5d2017-06-30 15:22:57 +08007812 spec->codec_variant = ALC269_TYPE_ALC293;
Kailang Yang161ebf22013-10-24 11:36:33 +02007813 break;
Kailang Yang7fc7d042013-04-25 11:04:43 +02007814 case 0x10ec0286:
Kailang Yang7c665932014-04-14 15:09:44 +08007815 case 0x10ec0288:
Kailang Yang7fc7d042013-04-25 11:04:43 +02007816 spec->codec_variant = ALC269_TYPE_ALC286;
7817 break;
Kailang Yang506b62c2014-12-18 17:07:44 +08007818 case 0x10ec0298:
7819 spec->codec_variant = ALC269_TYPE_ALC298;
7820 break;
Kailang Yangea04a1d2018-04-25 15:31:52 +08007821 case 0x10ec0235:
Kailang Yang1d04c9d2013-10-24 11:35:18 +02007822 case 0x10ec0255:
7823 spec->codec_variant = ALC269_TYPE_ALC255;
Kailang Yangab3b8e52018-04-25 16:05:27 +08007824 spec->shutup = alc256_shutup;
7825 spec->init_hook = alc256_init;
Kailang Yang1d04c9d2013-10-24 11:35:18 +02007826 break;
Kailang Yang736f20a2017-10-20 15:06:34 +08007827 case 0x10ec0236:
Kailang Yang4344aec2014-12-17 17:39:05 +08007828 case 0x10ec0256:
7829 spec->codec_variant = ALC269_TYPE_ALC256;
Kailang Yang4a219ef2017-06-16 16:54:35 +08007830 spec->shutup = alc256_shutup;
7831 spec->init_hook = alc256_init;
David Henningsson7d1b6e22015-04-21 10:48:46 +02007832 spec->gen.mixer_nid = 0; /* ALC256 does not have any loopback mixer path */
Kailang Yang4344aec2014-12-17 17:39:05 +08007833 break;
Kailang Yangf429e7e2017-12-05 15:38:24 +08007834 case 0x10ec0257:
7835 spec->codec_variant = ALC269_TYPE_ALC257;
Kailang Yang88d42b22018-03-14 16:08:57 +08007836 spec->shutup = alc256_shutup;
7837 spec->init_hook = alc256_init;
Kailang Yangf429e7e2017-12-05 15:38:24 +08007838 spec->gen.mixer_nid = 0;
7839 break;
Kailang Yang0a6f0602017-06-30 16:00:48 +08007840 case 0x10ec0215:
7841 case 0x10ec0285:
7842 case 0x10ec0289:
7843 spec->codec_variant = ALC269_TYPE_ALC215;
Kailang Yang1b6832be2018-01-17 15:32:03 +08007844 spec->shutup = alc225_shutup;
7845 spec->init_hook = alc225_init;
Kailang Yang0a6f0602017-06-30 16:00:48 +08007846 spec->gen.mixer_nid = 0;
7847 break;
Kailang Yang42314302016-02-03 15:03:50 +08007848 case 0x10ec0225:
Kailang Yang7d727862016-05-24 16:46:07 +08007849 case 0x10ec0295:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08007850 case 0x10ec0299:
Kailang Yang42314302016-02-03 15:03:50 +08007851 spec->codec_variant = ALC269_TYPE_ALC225;
Kailang Yangda911b12018-01-05 16:50:08 +08007852 spec->shutup = alc225_shutup;
7853 spec->init_hook = alc225_init;
Takashi Iwaic1350bf2017-12-27 09:03:45 +01007854 spec->gen.mixer_nid = 0; /* no loopback on ALC225, ALC295 and ALC299 */
Kailang Yang42314302016-02-03 15:03:50 +08007855 break;
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08007856 case 0x10ec0234:
7857 case 0x10ec0274:
7858 case 0x10ec0294:
7859 spec->codec_variant = ALC269_TYPE_ALC294;
Hui Wang532a7782017-06-26 12:30:32 +08007860 spec->gen.mixer_nid = 0; /* ALC2x4 does not have any loopback mixer path */
Kailang Yang71683c32017-06-20 16:33:50 +08007861 alc_update_coef_idx(codec, 0x6b, 0x0018, (1<<4) | (1<<3)); /* UAJ MIC Vref control by verb */
Kailang Yang693abe12019-01-29 15:38:21 +08007862 spec->init_hook = alc294_init;
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08007863 break;
Kailang Yang1078bef2018-11-08 16:36:15 +08007864 case 0x10ec0300:
7865 spec->codec_variant = ALC269_TYPE_ALC300;
7866 spec->gen.mixer_nid = 0; /* no loopback on ALC300 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02007867 break;
Kailang Yang6fbae352016-05-30 16:44:20 +08007868 case 0x10ec0700:
7869 case 0x10ec0701:
7870 case 0x10ec0703:
7871 spec->codec_variant = ALC269_TYPE_ALC700;
7872 spec->gen.mixer_nid = 0; /* ALC700 does not have any loopback mixer path */
Kailang Yang2d7fe612017-11-22 15:21:32 +08007873 alc_update_coef_idx(codec, 0x4a, 1 << 15, 0); /* Combo jack auto trigger control */
Kailang Yang693abe12019-01-29 15:38:21 +08007874 spec->init_hook = alc294_init;
Kailang Yang6fbae352016-05-30 16:44:20 +08007875 break;
7876
Takashi Iwai1d045db2011-07-07 18:23:21 +02007877 }
7878
Kailang Yangad60d502013-06-28 12:03:01 +02007879 if (snd_hda_codec_read(codec, 0x51, 0, AC_VERB_PARAMETERS, 0) == 0x10ec5505) {
Kailang Yang97a26572013-11-29 00:35:26 -05007880 spec->has_alc5505_dsp = 1;
Kailang Yangad60d502013-06-28 12:03:01 +02007881 spec->init_hook = alc5505_dsp_init;
7882 }
7883
Takashi Iwaic9af7532019-05-10 11:01:43 +02007884 alc_pre_init(codec);
7885
Takashi Iwaiefe55732018-06-15 11:55:02 +02007886 snd_hda_pick_fixup(codec, alc269_fixup_models,
7887 alc269_fixup_tbl, alc269_fixups);
7888 snd_hda_pick_pin_fixup(codec, alc269_pin_fixup_tbl, alc269_fixups);
7889 snd_hda_pick_fixup(codec, NULL, alc269_fixup_vendor_tbl,
7890 alc269_fixups);
7891 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
7892
7893 alc_auto_parse_customize_define(codec);
7894
7895 if (has_cdefine_beep(codec))
7896 spec->gen.beep_nid = 0x01;
7897
Takashi Iwaia4297b52011-08-23 18:40:12 +02007898 /* automatic parse from the BIOS config */
7899 err = alc269_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007900 if (err < 0)
7901 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02007902
Takashi Iwaifea80fa2018-06-20 12:52:46 +02007903 if (!spec->gen.no_analog && spec->gen.beep_nid && spec->gen.mixer_nid) {
7904 err = set_beep_amp(spec, spec->gen.mixer_nid, 0x04, HDA_INPUT);
7905 if (err < 0)
7906 goto error;
7907 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02007908
Takashi Iwai1727a772013-01-10 09:52:52 +01007909 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01007910
Takashi Iwai1d045db2011-07-07 18:23:21 +02007911 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007912
7913 error:
7914 alc_free(codec);
7915 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02007916}
7917
7918/*
7919 * ALC861
7920 */
7921
Takashi Iwai1d045db2011-07-07 18:23:21 +02007922static int alc861_parse_auto_config(struct hda_codec *codec)
7923{
Takashi Iwai1d045db2011-07-07 18:23:21 +02007924 static const hda_nid_t alc861_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02007925 static const hda_nid_t alc861_ssids[] = { 0x0e, 0x0f, 0x0b, 0 };
7926 return alc_parse_auto_config(codec, alc861_ignore, alc861_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02007927}
7928
Takashi Iwai1d045db2011-07-07 18:23:21 +02007929/* Pin config fixes */
7930enum {
Takashi Iwaie652f4c2012-02-13 11:56:25 +01007931 ALC861_FIXUP_FSC_AMILO_PI1505,
7932 ALC861_FIXUP_AMP_VREF_0F,
7933 ALC861_FIXUP_NO_JACK_DETECT,
7934 ALC861_FIXUP_ASUS_A6RP,
Takashi Iwai6ddf0fd2013-11-29 12:47:34 +01007935 ALC660_FIXUP_ASUS_W7J,
Takashi Iwai1d045db2011-07-07 18:23:21 +02007936};
7937
Takashi Iwai31150f22012-01-30 10:54:08 +01007938/* On some laptops, VREF of pin 0x0f is abused for controlling the main amp */
7939static void alc861_fixup_asus_amp_vref_0f(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01007940 const struct hda_fixup *fix, int action)
Takashi Iwai31150f22012-01-30 10:54:08 +01007941{
7942 struct alc_spec *spec = codec->spec;
7943 unsigned int val;
7944
Takashi Iwai1727a772013-01-10 09:52:52 +01007945 if (action != HDA_FIXUP_ACT_INIT)
Takashi Iwai31150f22012-01-30 10:54:08 +01007946 return;
Takashi Iwaid3f02d62013-01-10 10:12:22 +01007947 val = snd_hda_codec_get_pin_target(codec, 0x0f);
Takashi Iwai31150f22012-01-30 10:54:08 +01007948 if (!(val & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN)))
7949 val |= AC_PINCTL_IN_EN;
7950 val |= AC_PINCTL_VREF_50;
Takashi Iwaicdd03ce2012-04-20 12:34:50 +02007951 snd_hda_set_pin_ctl(codec, 0x0f, val);
Takashi Iwai08c189f2012-12-19 15:22:24 +01007952 spec->gen.keep_vref_in_automute = 1;
Takashi Iwai31150f22012-01-30 10:54:08 +01007953}
7954
Takashi Iwaie652f4c2012-02-13 11:56:25 +01007955/* suppress the jack-detection */
7956static void alc_fixup_no_jack_detect(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01007957 const struct hda_fixup *fix, int action)
Takashi Iwaie652f4c2012-02-13 11:56:25 +01007958{
Takashi Iwai1727a772013-01-10 09:52:52 +01007959 if (action == HDA_FIXUP_ACT_PRE_PROBE)
Takashi Iwaie652f4c2012-02-13 11:56:25 +01007960 codec->no_jack_detect = 1;
Jesper Juhl7d7eb9e2012-04-12 22:11:25 +02007961}
Takashi Iwaie652f4c2012-02-13 11:56:25 +01007962
Takashi Iwai1727a772013-01-10 09:52:52 +01007963static const struct hda_fixup alc861_fixups[] = {
Takashi Iwaie652f4c2012-02-13 11:56:25 +01007964 [ALC861_FIXUP_FSC_AMILO_PI1505] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01007965 .type = HDA_FIXUP_PINS,
7966 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02007967 { 0x0b, 0x0221101f }, /* HP */
7968 { 0x0f, 0x90170310 }, /* speaker */
7969 { }
7970 }
7971 },
Takashi Iwaie652f4c2012-02-13 11:56:25 +01007972 [ALC861_FIXUP_AMP_VREF_0F] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01007973 .type = HDA_FIXUP_FUNC,
Takashi Iwai31150f22012-01-30 10:54:08 +01007974 .v.func = alc861_fixup_asus_amp_vref_0f,
Takashi Iwai3b25eb62012-01-25 09:55:46 +01007975 },
Takashi Iwaie652f4c2012-02-13 11:56:25 +01007976 [ALC861_FIXUP_NO_JACK_DETECT] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01007977 .type = HDA_FIXUP_FUNC,
Takashi Iwaie652f4c2012-02-13 11:56:25 +01007978 .v.func = alc_fixup_no_jack_detect,
7979 },
7980 [ALC861_FIXUP_ASUS_A6RP] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01007981 .type = HDA_FIXUP_FUNC,
Takashi Iwaie652f4c2012-02-13 11:56:25 +01007982 .v.func = alc861_fixup_asus_amp_vref_0f,
7983 .chained = true,
7984 .chain_id = ALC861_FIXUP_NO_JACK_DETECT,
Takashi Iwai6ddf0fd2013-11-29 12:47:34 +01007985 },
7986 [ALC660_FIXUP_ASUS_W7J] = {
7987 .type = HDA_FIXUP_VERBS,
7988 .v.verbs = (const struct hda_verb[]) {
7989 /* ASUS W7J needs a magic pin setup on unused NID 0x10
7990 * for enabling outputs
7991 */
7992 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
7993 { }
7994 },
Takashi Iwaie652f4c2012-02-13 11:56:25 +01007995 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02007996};
7997
7998static const struct snd_pci_quirk alc861_fixup_tbl[] = {
Takashi Iwai6ddf0fd2013-11-29 12:47:34 +01007999 SND_PCI_QUIRK(0x1043, 0x1253, "ASUS W7J", ALC660_FIXUP_ASUS_W7J),
Takashi Iwaie7ca2372013-12-02 15:27:19 +01008000 SND_PCI_QUIRK(0x1043, 0x1263, "ASUS Z35HL", ALC660_FIXUP_ASUS_W7J),
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008001 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS A6Rp", ALC861_FIXUP_ASUS_A6RP),
8002 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", ALC861_FIXUP_AMP_VREF_0F),
8003 SND_PCI_QUIRK(0x1462, 0x7254, "HP DX2200", ALC861_FIXUP_NO_JACK_DETECT),
8004 SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", ALC861_FIXUP_AMP_VREF_0F),
8005 SND_PCI_QUIRK(0x1584, 0x0000, "Uniwill ECS M31EI", ALC861_FIXUP_AMP_VREF_0F),
8006 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", ALC861_FIXUP_FSC_AMILO_PI1505),
Takashi Iwai1d045db2011-07-07 18:23:21 +02008007 {}
8008};
8009
8010/*
8011 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02008012static int patch_alc861(struct hda_codec *codec)
8013{
8014 struct alc_spec *spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008015 int err;
8016
Takashi Iwai3de95172012-05-07 18:03:15 +02008017 err = alc_alloc_spec(codec, 0x15);
8018 if (err < 0)
8019 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008020
Takashi Iwai3de95172012-05-07 18:03:15 +02008021 spec = codec->spec;
Takashi Iwai7504b6c2013-03-18 11:25:51 +01008022 spec->gen.beep_nid = 0x23;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008023
Takashi Iwai225068a2015-05-29 10:42:14 +02008024#ifdef CONFIG_PM
8025 spec->power_hook = alc_power_eapd;
8026#endif
8027
Takashi Iwaic9af7532019-05-10 11:01:43 +02008028 alc_pre_init(codec);
8029
Takashi Iwai1727a772013-01-10 09:52:52 +01008030 snd_hda_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
8031 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02008032
Takashi Iwaicb4e4822011-08-23 17:34:25 +02008033 /* automatic parse from the BIOS config */
8034 err = alc861_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008035 if (err < 0)
8036 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008037
Takashi Iwaifea80fa2018-06-20 12:52:46 +02008038 if (!spec->gen.no_analog) {
8039 err = set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
8040 if (err < 0)
8041 goto error;
8042 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02008043
Takashi Iwai1727a772013-01-10 09:52:52 +01008044 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01008045
Takashi Iwai1d045db2011-07-07 18:23:21 +02008046 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008047
8048 error:
8049 alc_free(codec);
8050 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008051}
8052
8053/*
8054 * ALC861-VD support
8055 *
8056 * Based on ALC882
8057 *
8058 * In addition, an independent DAC
8059 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02008060static int alc861vd_parse_auto_config(struct hda_codec *codec)
8061{
Takashi Iwai1d045db2011-07-07 18:23:21 +02008062 static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02008063 static const hda_nid_t alc861vd_ssids[] = { 0x15, 0x1b, 0x14, 0 };
8064 return alc_parse_auto_config(codec, alc861vd_ignore, alc861vd_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02008065}
8066
Takashi Iwai1d045db2011-07-07 18:23:21 +02008067enum {
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008068 ALC660VD_FIX_ASUS_GPIO1,
8069 ALC861VD_FIX_DALLAS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02008070};
8071
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008072/* exclude VREF80 */
8073static void alc861vd_fixup_dallas(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01008074 const struct hda_fixup *fix, int action)
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008075{
Takashi Iwai1727a772013-01-10 09:52:52 +01008076 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwaib78562b2012-12-17 20:06:49 +01008077 snd_hda_override_pin_caps(codec, 0x18, 0x00000734);
8078 snd_hda_override_pin_caps(codec, 0x19, 0x0000073c);
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008079 }
8080}
8081
Takashi Iwaidf73d832018-06-19 23:05:47 +02008082/* reset GPIO1 */
8083static void alc660vd_fixup_asus_gpio1(struct hda_codec *codec,
8084 const struct hda_fixup *fix, int action)
8085{
8086 struct alc_spec *spec = codec->spec;
8087
8088 if (action == HDA_FIXUP_ACT_PRE_PROBE)
8089 spec->gpio_mask |= 0x02;
8090 alc_fixup_gpio(codec, action, 0x01);
8091}
8092
Takashi Iwai1727a772013-01-10 09:52:52 +01008093static const struct hda_fixup alc861vd_fixups[] = {
Takashi Iwai1d045db2011-07-07 18:23:21 +02008094 [ALC660VD_FIX_ASUS_GPIO1] = {
Takashi Iwaidf73d832018-06-19 23:05:47 +02008095 .type = HDA_FIXUP_FUNC,
8096 .v.func = alc660vd_fixup_asus_gpio1,
Takashi Iwai1d045db2011-07-07 18:23:21 +02008097 },
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008098 [ALC861VD_FIX_DALLAS] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008099 .type = HDA_FIXUP_FUNC,
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008100 .v.func = alc861vd_fixup_dallas,
8101 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02008102};
8103
8104static const struct snd_pci_quirk alc861vd_fixup_tbl[] = {
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008105 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_FIX_DALLAS),
Takashi Iwai1d045db2011-07-07 18:23:21 +02008106 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008107 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_FIX_DALLAS),
Takashi Iwai1d045db2011-07-07 18:23:21 +02008108 {}
8109};
8110
Takashi Iwai1d045db2011-07-07 18:23:21 +02008111/*
8112 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02008113static int patch_alc861vd(struct hda_codec *codec)
8114{
8115 struct alc_spec *spec;
Takashi Iwaicb4e4822011-08-23 17:34:25 +02008116 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008117
Takashi Iwai3de95172012-05-07 18:03:15 +02008118 err = alc_alloc_spec(codec, 0x0b);
8119 if (err < 0)
8120 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008121
Takashi Iwai3de95172012-05-07 18:03:15 +02008122 spec = codec->spec;
Takashi Iwai7504b6c2013-03-18 11:25:51 +01008123 spec->gen.beep_nid = 0x23;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008124
Takashi Iwai225068a2015-05-29 10:42:14 +02008125 spec->shutup = alc_eapd_shutup;
8126
Takashi Iwaic9af7532019-05-10 11:01:43 +02008127 alc_pre_init(codec);
8128
Takashi Iwai1727a772013-01-10 09:52:52 +01008129 snd_hda_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
8130 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02008131
Takashi Iwaicb4e4822011-08-23 17:34:25 +02008132 /* automatic parse from the BIOS config */
8133 err = alc861vd_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008134 if (err < 0)
8135 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008136
Takashi Iwaifea80fa2018-06-20 12:52:46 +02008137 if (!spec->gen.no_analog) {
8138 err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
8139 if (err < 0)
8140 goto error;
8141 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02008142
Takashi Iwai1727a772013-01-10 09:52:52 +01008143 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01008144
Takashi Iwai1d045db2011-07-07 18:23:21 +02008145 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008146
8147 error:
8148 alc_free(codec);
8149 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008150}
8151
8152/*
8153 * ALC662 support
8154 *
8155 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
8156 * configuration. Each pin widget can choose any input DACs and a mixer.
8157 * Each ADC is connected from a mixer of all inputs. This makes possible
8158 * 6-channel independent captures.
8159 *
8160 * In addition, an independent DAC for the multi-playback (not used in this
8161 * driver yet).
8162 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02008163
8164/*
8165 * BIOS auto configuration
8166 */
8167
Kailang Yangbc9f98a2007-04-12 13:06:07 +02008168static int alc662_parse_auto_config(struct hda_codec *codec)
8169{
Takashi Iwai4c6d72d2011-05-02 11:30:18 +02008170 static const hda_nid_t alc662_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02008171 static const hda_nid_t alc663_ssids[] = { 0x15, 0x1b, 0x14, 0x21 };
8172 static const hda_nid_t alc662_ssids[] = { 0x15, 0x1b, 0x14, 0 };
8173 const hda_nid_t *ssids;
Takashi Iwaiee979a142008-09-02 15:42:20 +02008174
Takashi Iwai7639a062015-03-03 10:07:24 +01008175 if (codec->core.vendor_id == 0x10ec0272 || codec->core.vendor_id == 0x10ec0663 ||
8176 codec->core.vendor_id == 0x10ec0665 || codec->core.vendor_id == 0x10ec0670 ||
8177 codec->core.vendor_id == 0x10ec0671)
Takashi Iwai3e6179b2011-07-08 16:55:13 +02008178 ssids = alc663_ssids;
Kailang Yang6227cdc2010-02-25 08:36:52 +01008179 else
Takashi Iwai3e6179b2011-07-08 16:55:13 +02008180 ssids = alc662_ssids;
8181 return alc_parse_auto_config(codec, alc662_ignore, ssids);
Kailang Yangbc9f98a2007-04-12 13:06:07 +02008182}
8183
Todd Broch6be79482010-12-07 16:51:05 -08008184static void alc272_fixup_mario(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01008185 const struct hda_fixup *fix, int action)
Takashi Iwai6fc398c2011-01-13 14:36:37 +01008186{
Takashi Iwai9bb1f062013-01-10 17:14:29 +01008187 if (action != HDA_FIXUP_ACT_PRE_PROBE)
Takashi Iwai6fc398c2011-01-13 14:36:37 +01008188 return;
Todd Broch6be79482010-12-07 16:51:05 -08008189 if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT,
8190 (0x3b << AC_AMPCAP_OFFSET_SHIFT) |
8191 (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) |
8192 (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) |
8193 (0 << AC_AMPCAP_MUTE_SHIFT)))
Takashi Iwai4e76a882014-02-25 12:21:03 +01008194 codec_warn(codec, "failed to override amp caps for NID 0x2\n");
Todd Broch6be79482010-12-07 16:51:05 -08008195}
8196
Takashi Iwai8e383952013-10-30 17:41:12 +01008197static const struct snd_pcm_chmap_elem asus_pcm_2_1_chmaps[] = {
8198 { .channels = 2,
8199 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } },
8200 { .channels = 4,
8201 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR,
8202 SNDRV_CHMAP_NA, SNDRV_CHMAP_LFE } }, /* LFE only on right */
8203 { }
8204};
8205
8206/* override the 2.1 chmap */
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01008207static void alc_fixup_bass_chmap(struct hda_codec *codec,
Takashi Iwai8e383952013-10-30 17:41:12 +01008208 const struct hda_fixup *fix, int action)
8209{
8210 if (action == HDA_FIXUP_ACT_BUILD) {
8211 struct alc_spec *spec = codec->spec;
Takashi Iwaibbbc7e82015-02-27 17:43:19 +01008212 spec->gen.pcm_rec[0]->stream[0].chmap = asus_pcm_2_1_chmaps;
Takashi Iwai8e383952013-10-30 17:41:12 +01008213 }
8214}
8215
Takashi Iwaibf686652014-01-13 16:18:25 +01008216/* avoid D3 for keeping GPIO up */
8217static unsigned int gpio_led_power_filter(struct hda_codec *codec,
8218 hda_nid_t nid,
8219 unsigned int power_state)
8220{
8221 struct alc_spec *spec = codec->spec;
Takashi Iwaid261eec2018-06-19 22:32:29 +02008222 if (nid == codec->core.afg && power_state == AC_PWRST_D3 && spec->gpio_data)
Takashi Iwaibf686652014-01-13 16:18:25 +01008223 return AC_PWRST_D0;
8224 return power_state;
8225}
8226
Takashi Iwai3e887f32014-01-10 17:50:58 +01008227static void alc662_fixup_led_gpio1(struct hda_codec *codec,
8228 const struct hda_fixup *fix, int action)
8229{
8230 struct alc_spec *spec = codec->spec;
Takashi Iwai3e887f32014-01-10 17:50:58 +01008231
Takashi Iwai01e4a272018-06-19 22:47:30 +02008232 alc_fixup_hp_gpio_led(codec, action, 0x01, 0);
Takashi Iwai3e887f32014-01-10 17:50:58 +01008233 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai0f32fd192014-11-19 12:16:14 +01008234 spec->mute_led_polarity = 1;
Takashi Iwaibf686652014-01-13 16:18:25 +01008235 codec->power_filter = gpio_led_power_filter;
Takashi Iwai3e887f32014-01-10 17:50:58 +01008236 }
8237}
8238
Kailang Yangc6790c82016-11-25 16:15:17 +08008239static void alc662_usi_automute_hook(struct hda_codec *codec,
8240 struct hda_jack_callback *jack)
8241{
8242 struct alc_spec *spec = codec->spec;
8243 int vref;
8244 msleep(200);
8245 snd_hda_gen_hp_automute(codec, jack);
8246
8247 vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0;
8248 msleep(100);
8249 snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8250 vref);
8251}
8252
8253static void alc662_fixup_usi_headset_mic(struct hda_codec *codec,
8254 const struct hda_fixup *fix, int action)
8255{
8256 struct alc_spec *spec = codec->spec;
8257 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
8258 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
8259 spec->gen.hp_automute_hook = alc662_usi_automute_hook;
8260 }
8261}
8262
Kailang Yangf3f91852014-10-24 15:43:46 +08008263static struct coef_fw alc668_coefs[] = {
8264 WRITE_COEF(0x01, 0xbebe), WRITE_COEF(0x02, 0xaaaa), WRITE_COEF(0x03, 0x0),
8265 WRITE_COEF(0x04, 0x0180), WRITE_COEF(0x06, 0x0), WRITE_COEF(0x07, 0x0f80),
8266 WRITE_COEF(0x08, 0x0031), WRITE_COEF(0x0a, 0x0060), WRITE_COEF(0x0b, 0x0),
8267 WRITE_COEF(0x0c, 0x7cf7), WRITE_COEF(0x0d, 0x1080), WRITE_COEF(0x0e, 0x7f7f),
8268 WRITE_COEF(0x0f, 0xcccc), WRITE_COEF(0x10, 0xddcc), WRITE_COEF(0x11, 0x0001),
8269 WRITE_COEF(0x13, 0x0), WRITE_COEF(0x14, 0x2aa0), WRITE_COEF(0x17, 0xa940),
8270 WRITE_COEF(0x19, 0x0), WRITE_COEF(0x1a, 0x0), WRITE_COEF(0x1b, 0x0),
8271 WRITE_COEF(0x1c, 0x0), WRITE_COEF(0x1d, 0x0), WRITE_COEF(0x1e, 0x7418),
8272 WRITE_COEF(0x1f, 0x0804), WRITE_COEF(0x20, 0x4200), WRITE_COEF(0x21, 0x0468),
8273 WRITE_COEF(0x22, 0x8ccc), WRITE_COEF(0x23, 0x0250), WRITE_COEF(0x24, 0x7418),
8274 WRITE_COEF(0x27, 0x0), WRITE_COEF(0x28, 0x8ccc), WRITE_COEF(0x2a, 0xff00),
8275 WRITE_COEF(0x2b, 0x8000), WRITE_COEF(0xa7, 0xff00), WRITE_COEF(0xa8, 0x8000),
8276 WRITE_COEF(0xaa, 0x2e17), WRITE_COEF(0xab, 0xa0c0), WRITE_COEF(0xac, 0x0),
8277 WRITE_COEF(0xad, 0x0), WRITE_COEF(0xae, 0x2ac6), WRITE_COEF(0xaf, 0xa480),
8278 WRITE_COEF(0xb0, 0x0), WRITE_COEF(0xb1, 0x0), WRITE_COEF(0xb2, 0x0),
8279 WRITE_COEF(0xb3, 0x0), WRITE_COEF(0xb4, 0x0), WRITE_COEF(0xb5, 0x1040),
8280 WRITE_COEF(0xb6, 0xd697), WRITE_COEF(0xb7, 0x902b), WRITE_COEF(0xb8, 0xd697),
8281 WRITE_COEF(0xb9, 0x902b), WRITE_COEF(0xba, 0xb8ba), WRITE_COEF(0xbb, 0xaaab),
8282 WRITE_COEF(0xbc, 0xaaaf), WRITE_COEF(0xbd, 0x6aaa), WRITE_COEF(0xbe, 0x1c02),
8283 WRITE_COEF(0xc0, 0x00ff), WRITE_COEF(0xc1, 0x0fa6),
8284 {}
8285};
8286
8287static void alc668_restore_default_value(struct hda_codec *codec)
8288{
8289 alc_process_coef_fw(codec, alc668_coefs);
8290}
8291
David Henningsson6cb3b702010-09-09 08:51:44 +02008292enum {
Daniel T Chen2df03512010-10-10 22:39:28 -04008293 ALC662_FIXUP_ASPIRE,
Takashi Iwai3e887f32014-01-10 17:50:58 +01008294 ALC662_FIXUP_LED_GPIO1,
David Henningsson6cb3b702010-09-09 08:51:44 +02008295 ALC662_FIXUP_IDEAPAD,
Todd Broch6be79482010-12-07 16:51:05 -08008296 ALC272_FIXUP_MARIO,
Anisse Astierd2ebd472011-01-20 12:36:21 +01008297 ALC662_FIXUP_CZC_P10T,
David Henningsson94024cd2011-04-29 14:10:55 +02008298 ALC662_FIXUP_SKU_IGNORE,
Takashi Iwaie59ea3e2011-06-29 17:21:00 +02008299 ALC662_FIXUP_HP_RP5800,
Takashi Iwai53c334a2011-08-23 18:27:14 +02008300 ALC662_FIXUP_ASUS_MODE1,
8301 ALC662_FIXUP_ASUS_MODE2,
8302 ALC662_FIXUP_ASUS_MODE3,
8303 ALC662_FIXUP_ASUS_MODE4,
8304 ALC662_FIXUP_ASUS_MODE5,
8305 ALC662_FIXUP_ASUS_MODE6,
8306 ALC662_FIXUP_ASUS_MODE7,
8307 ALC662_FIXUP_ASUS_MODE8,
Takashi Iwai1565cc32012-02-13 12:03:25 +01008308 ALC662_FIXUP_NO_JACK_DETECT,
David Henningssonedfe3bf2012-06-12 13:15:12 +02008309 ALC662_FIXUP_ZOTAC_Z68,
Takashi Iwai125821a2012-06-22 14:30:29 +02008310 ALC662_FIXUP_INV_DMIC,
David Henningsson1f8b46c2015-05-12 14:38:15 +02008311 ALC662_FIXUP_DELL_MIC_NO_PRESENCE,
David Henningsson73bdd592013-04-15 15:44:14 +02008312 ALC668_FIXUP_DELL_MIC_NO_PRESENCE,
David Henningsson1f8b46c2015-05-12 14:38:15 +02008313 ALC662_FIXUP_HEADSET_MODE,
David Henningsson73bdd592013-04-15 15:44:14 +02008314 ALC668_FIXUP_HEADSET_MODE,
David Henningsson8e54b4a2014-02-07 09:31:07 +01008315 ALC662_FIXUP_BASS_MODE4_CHMAP,
David Henningsson61a75f12014-02-07 09:31:08 +01008316 ALC662_FIXUP_BASS_16,
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01008317 ALC662_FIXUP_BASS_1A,
David Henningsson8e54b4a2014-02-07 09:31:07 +01008318 ALC662_FIXUP_BASS_CHMAP,
Hui Wang493a52a2014-01-14 14:07:36 +08008319 ALC668_FIXUP_AUTO_MUTE,
Gabriele Mazzotta5e6db662014-05-20 18:58:26 +02008320 ALC668_FIXUP_DELL_DISABLE_AAMIX,
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02008321 ALC668_FIXUP_DELL_XPS13,
Bobi Mihalca9d4dc582016-03-23 13:26:11 +02008322 ALC662_FIXUP_ASUS_Nx50,
Mikhail Paulyshkafc7438b2017-04-21 08:52:42 +02008323 ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE,
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07008324 ALC668_FIXUP_ASUS_Nx51,
Takashi Iwai5b7c5e12018-10-09 14:20:17 +02008325 ALC668_FIXUP_MIC_COEF,
Takashi Iwai11ba6112018-10-07 09:44:17 +02008326 ALC668_FIXUP_ASUS_G751,
Kailang Yang78f4f7c2016-06-07 11:31:34 +08008327 ALC891_FIXUP_HEADSET_MODE,
8328 ALC891_FIXUP_DELL_MIC_NO_PRESENCE,
Shrirang Bagul9b51fe32016-08-01 13:16:17 +08008329 ALC662_FIXUP_ACER_VERITON,
Takashi Iwai1a3f0992016-10-20 12:14:51 +02008330 ALC892_FIXUP_ASROCK_MOBO,
Kailang Yangc6790c82016-11-25 16:15:17 +08008331 ALC662_FIXUP_USI_FUNC,
8332 ALC662_FIXUP_USI_HEADSET_MODE,
Kailang Yangca169cc2017-04-25 16:17:40 +08008333 ALC662_FIXUP_LENOVO_MULTI_CODECS,
David Henningsson6cb3b702010-09-09 08:51:44 +02008334};
8335
Takashi Iwai1727a772013-01-10 09:52:52 +01008336static const struct hda_fixup alc662_fixups[] = {
Daniel T Chen2df03512010-10-10 22:39:28 -04008337 [ALC662_FIXUP_ASPIRE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008338 .type = HDA_FIXUP_PINS,
8339 .v.pins = (const struct hda_pintbl[]) {
Daniel T Chen2df03512010-10-10 22:39:28 -04008340 { 0x15, 0x99130112 }, /* subwoofer */
8341 { }
8342 }
8343 },
Takashi Iwai3e887f32014-01-10 17:50:58 +01008344 [ALC662_FIXUP_LED_GPIO1] = {
8345 .type = HDA_FIXUP_FUNC,
8346 .v.func = alc662_fixup_led_gpio1,
8347 },
David Henningsson6cb3b702010-09-09 08:51:44 +02008348 [ALC662_FIXUP_IDEAPAD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008349 .type = HDA_FIXUP_PINS,
8350 .v.pins = (const struct hda_pintbl[]) {
David Henningsson6cb3b702010-09-09 08:51:44 +02008351 { 0x17, 0x99130112 }, /* subwoofer */
8352 { }
Takashi Iwai3e887f32014-01-10 17:50:58 +01008353 },
8354 .chained = true,
8355 .chain_id = ALC662_FIXUP_LED_GPIO1,
David Henningsson6cb3b702010-09-09 08:51:44 +02008356 },
Todd Broch6be79482010-12-07 16:51:05 -08008357 [ALC272_FIXUP_MARIO] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008358 .type = HDA_FIXUP_FUNC,
Takashi Iwaib5bfbc62011-01-13 14:22:32 +01008359 .v.func = alc272_fixup_mario,
Anisse Astierd2ebd472011-01-20 12:36:21 +01008360 },
8361 [ALC662_FIXUP_CZC_P10T] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008362 .type = HDA_FIXUP_VERBS,
Anisse Astierd2ebd472011-01-20 12:36:21 +01008363 .v.verbs = (const struct hda_verb[]) {
8364 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
8365 {}
8366 }
8367 },
David Henningsson94024cd2011-04-29 14:10:55 +02008368 [ALC662_FIXUP_SKU_IGNORE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008369 .type = HDA_FIXUP_FUNC,
Takashi Iwai23d30f22012-05-07 17:17:32 +02008370 .v.func = alc_fixup_sku_ignore,
Takashi Iwaic6b35872011-03-28 12:05:31 +02008371 },
Takashi Iwaie59ea3e2011-06-29 17:21:00 +02008372 [ALC662_FIXUP_HP_RP5800] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008373 .type = HDA_FIXUP_PINS,
8374 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaie59ea3e2011-06-29 17:21:00 +02008375 { 0x14, 0x0221201f }, /* HP out */
8376 { }
8377 },
8378 .chained = true,
8379 .chain_id = ALC662_FIXUP_SKU_IGNORE
8380 },
Takashi Iwai53c334a2011-08-23 18:27:14 +02008381 [ALC662_FIXUP_ASUS_MODE1] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008382 .type = HDA_FIXUP_PINS,
8383 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008384 { 0x14, 0x99130110 }, /* speaker */
8385 { 0x18, 0x01a19c20 }, /* mic */
8386 { 0x19, 0x99a3092f }, /* int-mic */
8387 { 0x21, 0x0121401f }, /* HP out */
8388 { }
8389 },
8390 .chained = true,
8391 .chain_id = ALC662_FIXUP_SKU_IGNORE
8392 },
8393 [ALC662_FIXUP_ASUS_MODE2] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008394 .type = HDA_FIXUP_PINS,
8395 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai2996bdb2011-08-18 16:02:24 +02008396 { 0x14, 0x99130110 }, /* speaker */
8397 { 0x18, 0x01a19820 }, /* mic */
8398 { 0x19, 0x99a3092f }, /* int-mic */
8399 { 0x1b, 0x0121401f }, /* HP out */
8400 { }
8401 },
Takashi Iwai53c334a2011-08-23 18:27:14 +02008402 .chained = true,
8403 .chain_id = ALC662_FIXUP_SKU_IGNORE
8404 },
8405 [ALC662_FIXUP_ASUS_MODE3] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008406 .type = HDA_FIXUP_PINS,
8407 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008408 { 0x14, 0x99130110 }, /* speaker */
8409 { 0x15, 0x0121441f }, /* HP */
8410 { 0x18, 0x01a19840 }, /* mic */
8411 { 0x19, 0x99a3094f }, /* int-mic */
8412 { 0x21, 0x01211420 }, /* HP2 */
8413 { }
8414 },
8415 .chained = true,
8416 .chain_id = ALC662_FIXUP_SKU_IGNORE
8417 },
8418 [ALC662_FIXUP_ASUS_MODE4] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008419 .type = HDA_FIXUP_PINS,
8420 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008421 { 0x14, 0x99130110 }, /* speaker */
8422 { 0x16, 0x99130111 }, /* speaker */
8423 { 0x18, 0x01a19840 }, /* mic */
8424 { 0x19, 0x99a3094f }, /* int-mic */
8425 { 0x21, 0x0121441f }, /* HP */
8426 { }
8427 },
8428 .chained = true,
8429 .chain_id = ALC662_FIXUP_SKU_IGNORE
8430 },
8431 [ALC662_FIXUP_ASUS_MODE5] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008432 .type = HDA_FIXUP_PINS,
8433 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008434 { 0x14, 0x99130110 }, /* speaker */
8435 { 0x15, 0x0121441f }, /* HP */
8436 { 0x16, 0x99130111 }, /* speaker */
8437 { 0x18, 0x01a19840 }, /* mic */
8438 { 0x19, 0x99a3094f }, /* int-mic */
8439 { }
8440 },
8441 .chained = true,
8442 .chain_id = ALC662_FIXUP_SKU_IGNORE
8443 },
8444 [ALC662_FIXUP_ASUS_MODE6] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008445 .type = HDA_FIXUP_PINS,
8446 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008447 { 0x14, 0x99130110 }, /* speaker */
8448 { 0x15, 0x01211420 }, /* HP2 */
8449 { 0x18, 0x01a19840 }, /* mic */
8450 { 0x19, 0x99a3094f }, /* int-mic */
8451 { 0x1b, 0x0121441f }, /* HP */
8452 { }
8453 },
8454 .chained = true,
8455 .chain_id = ALC662_FIXUP_SKU_IGNORE
8456 },
8457 [ALC662_FIXUP_ASUS_MODE7] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008458 .type = HDA_FIXUP_PINS,
8459 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008460 { 0x14, 0x99130110 }, /* speaker */
8461 { 0x17, 0x99130111 }, /* speaker */
8462 { 0x18, 0x01a19840 }, /* mic */
8463 { 0x19, 0x99a3094f }, /* int-mic */
8464 { 0x1b, 0x01214020 }, /* HP */
8465 { 0x21, 0x0121401f }, /* HP */
8466 { }
8467 },
8468 .chained = true,
8469 .chain_id = ALC662_FIXUP_SKU_IGNORE
8470 },
8471 [ALC662_FIXUP_ASUS_MODE8] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008472 .type = HDA_FIXUP_PINS,
8473 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008474 { 0x14, 0x99130110 }, /* speaker */
8475 { 0x12, 0x99a30970 }, /* int-mic */
8476 { 0x15, 0x01214020 }, /* HP */
8477 { 0x17, 0x99130111 }, /* speaker */
8478 { 0x18, 0x01a19840 }, /* mic */
8479 { 0x21, 0x0121401f }, /* HP */
8480 { }
8481 },
8482 .chained = true,
8483 .chain_id = ALC662_FIXUP_SKU_IGNORE
Takashi Iwai2996bdb2011-08-18 16:02:24 +02008484 },
Takashi Iwai1565cc32012-02-13 12:03:25 +01008485 [ALC662_FIXUP_NO_JACK_DETECT] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008486 .type = HDA_FIXUP_FUNC,
Takashi Iwai1565cc32012-02-13 12:03:25 +01008487 .v.func = alc_fixup_no_jack_detect,
8488 },
David Henningssonedfe3bf2012-06-12 13:15:12 +02008489 [ALC662_FIXUP_ZOTAC_Z68] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008490 .type = HDA_FIXUP_PINS,
8491 .v.pins = (const struct hda_pintbl[]) {
David Henningssonedfe3bf2012-06-12 13:15:12 +02008492 { 0x1b, 0x02214020 }, /* Front HP */
8493 { }
8494 }
8495 },
Takashi Iwai125821a2012-06-22 14:30:29 +02008496 [ALC662_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008497 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02008498 .v.func = alc_fixup_inv_dmic,
Takashi Iwai125821a2012-06-22 14:30:29 +02008499 },
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02008500 [ALC668_FIXUP_DELL_XPS13] = {
8501 .type = HDA_FIXUP_FUNC,
8502 .v.func = alc_fixup_dell_xps13,
8503 .chained = true,
8504 .chain_id = ALC668_FIXUP_DELL_DISABLE_AAMIX
8505 },
Gabriele Mazzotta5e6db662014-05-20 18:58:26 +02008506 [ALC668_FIXUP_DELL_DISABLE_AAMIX] = {
8507 .type = HDA_FIXUP_FUNC,
8508 .v.func = alc_fixup_disable_aamix,
8509 .chained = true,
8510 .chain_id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE
8511 },
Hui Wang493a52a2014-01-14 14:07:36 +08008512 [ALC668_FIXUP_AUTO_MUTE] = {
8513 .type = HDA_FIXUP_FUNC,
8514 .v.func = alc_fixup_auto_mute_via_amp,
8515 .chained = true,
8516 .chain_id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE
8517 },
David Henningsson1f8b46c2015-05-12 14:38:15 +02008518 [ALC662_FIXUP_DELL_MIC_NO_PRESENCE] = {
8519 .type = HDA_FIXUP_PINS,
8520 .v.pins = (const struct hda_pintbl[]) {
8521 { 0x19, 0x03a1113c }, /* use as headset mic, without its own jack detect */
8522 /* headphone mic by setting pin control of 0x1b (headphone out) to in + vref_50 */
8523 { }
8524 },
8525 .chained = true,
8526 .chain_id = ALC662_FIXUP_HEADSET_MODE
8527 },
8528 [ALC662_FIXUP_HEADSET_MODE] = {
8529 .type = HDA_FIXUP_FUNC,
8530 .v.func = alc_fixup_headset_mode_alc662,
8531 },
David Henningsson73bdd592013-04-15 15:44:14 +02008532 [ALC668_FIXUP_DELL_MIC_NO_PRESENCE] = {
8533 .type = HDA_FIXUP_PINS,
8534 .v.pins = (const struct hda_pintbl[]) {
8535 { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
8536 { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */
8537 { }
8538 },
8539 .chained = true,
8540 .chain_id = ALC668_FIXUP_HEADSET_MODE
8541 },
8542 [ALC668_FIXUP_HEADSET_MODE] = {
8543 .type = HDA_FIXUP_FUNC,
8544 .v.func = alc_fixup_headset_mode_alc668,
8545 },
David Henningsson8e54b4a2014-02-07 09:31:07 +01008546 [ALC662_FIXUP_BASS_MODE4_CHMAP] = {
Takashi Iwai8e383952013-10-30 17:41:12 +01008547 .type = HDA_FIXUP_FUNC,
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01008548 .v.func = alc_fixup_bass_chmap,
Takashi Iwai8e383952013-10-30 17:41:12 +01008549 .chained = true,
8550 .chain_id = ALC662_FIXUP_ASUS_MODE4
8551 },
David Henningsson61a75f12014-02-07 09:31:08 +01008552 [ALC662_FIXUP_BASS_16] = {
8553 .type = HDA_FIXUP_PINS,
8554 .v.pins = (const struct hda_pintbl[]) {
8555 {0x16, 0x80106111}, /* bass speaker */
8556 {}
8557 },
8558 .chained = true,
8559 .chain_id = ALC662_FIXUP_BASS_CHMAP,
8560 },
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01008561 [ALC662_FIXUP_BASS_1A] = {
8562 .type = HDA_FIXUP_PINS,
8563 .v.pins = (const struct hda_pintbl[]) {
8564 {0x1a, 0x80106111}, /* bass speaker */
8565 {}
8566 },
David Henningsson8e54b4a2014-02-07 09:31:07 +01008567 .chained = true,
8568 .chain_id = ALC662_FIXUP_BASS_CHMAP,
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01008569 },
David Henningsson8e54b4a2014-02-07 09:31:07 +01008570 [ALC662_FIXUP_BASS_CHMAP] = {
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01008571 .type = HDA_FIXUP_FUNC,
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01008572 .v.func = alc_fixup_bass_chmap,
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01008573 },
Bobi Mihalca9d4dc582016-03-23 13:26:11 +02008574 [ALC662_FIXUP_ASUS_Nx50] = {
8575 .type = HDA_FIXUP_FUNC,
8576 .v.func = alc_fixup_auto_mute_via_amp,
8577 .chained = true,
8578 .chain_id = ALC662_FIXUP_BASS_1A
8579 },
Mikhail Paulyshkafc7438b2017-04-21 08:52:42 +02008580 [ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE] = {
8581 .type = HDA_FIXUP_FUNC,
8582 .v.func = alc_fixup_headset_mode_alc668,
8583 .chain_id = ALC662_FIXUP_BASS_CHMAP
8584 },
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07008585 [ALC668_FIXUP_ASUS_Nx51] = {
8586 .type = HDA_FIXUP_PINS,
8587 .v.pins = (const struct hda_pintbl[]) {
Mikhail Paulyshkafc7438b2017-04-21 08:52:42 +02008588 { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
8589 { 0x1a, 0x90170151 }, /* bass speaker */
8590 { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07008591 {}
8592 },
8593 .chained = true,
Mikhail Paulyshkafc7438b2017-04-21 08:52:42 +02008594 .chain_id = ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE,
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07008595 },
Takashi Iwai5b7c5e12018-10-09 14:20:17 +02008596 [ALC668_FIXUP_MIC_COEF] = {
Takashi Iwai11ba6112018-10-07 09:44:17 +02008597 .type = HDA_FIXUP_VERBS,
8598 .v.verbs = (const struct hda_verb[]) {
8599 { 0x20, AC_VERB_SET_COEF_INDEX, 0xc3 },
8600 { 0x20, AC_VERB_SET_PROC_COEF, 0x4000 },
8601 {}
8602 },
8603 },
Takashi Iwai5b7c5e12018-10-09 14:20:17 +02008604 [ALC668_FIXUP_ASUS_G751] = {
8605 .type = HDA_FIXUP_PINS,
8606 .v.pins = (const struct hda_pintbl[]) {
8607 { 0x16, 0x0421101f }, /* HP */
8608 {}
8609 },
8610 .chained = true,
8611 .chain_id = ALC668_FIXUP_MIC_COEF
8612 },
Kailang Yang78f4f7c2016-06-07 11:31:34 +08008613 [ALC891_FIXUP_HEADSET_MODE] = {
8614 .type = HDA_FIXUP_FUNC,
8615 .v.func = alc_fixup_headset_mode,
8616 },
8617 [ALC891_FIXUP_DELL_MIC_NO_PRESENCE] = {
8618 .type = HDA_FIXUP_PINS,
8619 .v.pins = (const struct hda_pintbl[]) {
8620 { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
8621 { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */
8622 { }
8623 },
8624 .chained = true,
8625 .chain_id = ALC891_FIXUP_HEADSET_MODE
8626 },
Shrirang Bagul9b51fe32016-08-01 13:16:17 +08008627 [ALC662_FIXUP_ACER_VERITON] = {
8628 .type = HDA_FIXUP_PINS,
8629 .v.pins = (const struct hda_pintbl[]) {
8630 { 0x15, 0x50170120 }, /* no internal speaker */
8631 { }
8632 }
8633 },
Takashi Iwai1a3f0992016-10-20 12:14:51 +02008634 [ALC892_FIXUP_ASROCK_MOBO] = {
8635 .type = HDA_FIXUP_PINS,
8636 .v.pins = (const struct hda_pintbl[]) {
8637 { 0x15, 0x40f000f0 }, /* disabled */
8638 { 0x16, 0x40f000f0 }, /* disabled */
Takashi Iwai1a3f0992016-10-20 12:14:51 +02008639 { }
8640 }
8641 },
Kailang Yangc6790c82016-11-25 16:15:17 +08008642 [ALC662_FIXUP_USI_FUNC] = {
8643 .type = HDA_FIXUP_FUNC,
8644 .v.func = alc662_fixup_usi_headset_mic,
8645 },
8646 [ALC662_FIXUP_USI_HEADSET_MODE] = {
8647 .type = HDA_FIXUP_PINS,
8648 .v.pins = (const struct hda_pintbl[]) {
8649 { 0x19, 0x02a1913c }, /* use as headset mic, without its own jack detect */
8650 { 0x18, 0x01a1903d },
8651 { }
8652 },
8653 .chained = true,
8654 .chain_id = ALC662_FIXUP_USI_FUNC
8655 },
Kailang Yangca169cc2017-04-25 16:17:40 +08008656 [ALC662_FIXUP_LENOVO_MULTI_CODECS] = {
8657 .type = HDA_FIXUP_FUNC,
8658 .v.func = alc233_alc662_fixup_lenovo_dual_codecs,
8659 },
David Henningsson6cb3b702010-09-09 08:51:44 +02008660};
8661
Takashi Iwaia9111322011-05-02 11:30:18 +02008662static const struct snd_pci_quirk alc662_fixup_tbl[] = {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008663 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_FIXUP_ASUS_MODE2),
Takashi Iwaid3d38352013-08-19 20:05:50 +02008664 SND_PCI_QUIRK(0x1025, 0x022f, "Acer Aspire One", ALC662_FIXUP_INV_DMIC),
David Henningsson02f6ff92015-12-07 11:29:31 +01008665 SND_PCI_QUIRK(0x1025, 0x0241, "Packard Bell DOTS", ALC662_FIXUP_INV_DMIC),
David Henningssona6c47a82011-02-10 15:39:19 +01008666 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
David Henningsson94024cd2011-04-29 14:10:55 +02008667 SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
Takashi Iwai125821a2012-06-22 14:30:29 +02008668 SND_PCI_QUIRK(0x1025, 0x0349, "eMachines eM250", ALC662_FIXUP_INV_DMIC),
Takashi Iwai18019282013-08-16 08:17:05 +02008669 SND_PCI_QUIRK(0x1025, 0x034a, "Gateway LT27", ALC662_FIXUP_INV_DMIC),
Daniel T Chen2df03512010-10-10 22:39:28 -04008670 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
David Henningsson73bdd592013-04-15 15:44:14 +02008671 SND_PCI_QUIRK(0x1028, 0x05d8, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
8672 SND_PCI_QUIRK(0x1028, 0x05db, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
Takashi Iwaic5d019c2014-07-22 17:33:32 +02008673 SND_PCI_QUIRK(0x1028, 0x05fe, "Dell XPS 15", ALC668_FIXUP_DELL_XPS13),
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02008674 SND_PCI_QUIRK(0x1028, 0x060a, "Dell XPS 13", ALC668_FIXUP_DELL_XPS13),
Niranjan Sivakumar467e1432015-09-05 18:20:35 +02008675 SND_PCI_QUIRK(0x1028, 0x060d, "Dell M3800", ALC668_FIXUP_DELL_XPS13),
David Henningsson09d20142013-11-20 11:43:30 +01008676 SND_PCI_QUIRK(0x1028, 0x0625, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
David Henningssonad8ff992013-11-07 09:28:59 +01008677 SND_PCI_QUIRK(0x1028, 0x0626, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
Kailang Yang8dc9abb2014-04-16 15:53:12 +08008678 SND_PCI_QUIRK(0x1028, 0x0696, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
8679 SND_PCI_QUIRK(0x1028, 0x0698, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
Kailang Yang6a98e342014-10-27 16:20:30 +08008680 SND_PCI_QUIRK(0x1028, 0x069f, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
Takashi Iwaie59ea3e2011-06-29 17:21:00 +02008681 SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800),
Kaho Ng2da2dc92016-05-09 00:27:49 +08008682 SND_PCI_QUIRK(0x1043, 0x1080, "Asus UX501VW", ALC668_FIXUP_HEADSET_MODE),
Bobi Mihalca83a9efb2016-03-23 13:32:33 +02008683 SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_ASUS_Nx50),
Takashi Iwaidb8948e2016-01-18 09:17:30 +01008684 SND_PCI_QUIRK(0x1043, 0x13df, "Asus N550JX", ALC662_FIXUP_BASS_1A),
Bobi Mihalca9d4dc582016-03-23 13:26:11 +02008685 SND_PCI_QUIRK(0x1043, 0x129d, "Asus N750", ALC662_FIXUP_ASUS_Nx50),
Takashi Iwai11ba6112018-10-07 09:44:17 +02008686 SND_PCI_QUIRK(0x1043, 0x12ff, "ASUS G751", ALC668_FIXUP_ASUS_G751),
David Henningsson8e54b4a2014-02-07 09:31:07 +01008687 SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
David Henningsson61a75f12014-02-07 09:31:08 +01008688 SND_PCI_QUIRK(0x1043, 0x15a7, "ASUS UX51VZH", ALC662_FIXUP_BASS_16),
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07008689 SND_PCI_QUIRK(0x1043, 0x177d, "ASUS N551", ALC668_FIXUP_ASUS_Nx51),
8690 SND_PCI_QUIRK(0x1043, 0x17bd, "ASUS N751", ALC668_FIXUP_ASUS_Nx51),
Takashi Iwaic7efff92017-01-04 21:38:16 +01008691 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71SL", ALC662_FIXUP_ASUS_MODE8),
David Henningsson61a75f12014-02-07 09:31:08 +01008692 SND_PCI_QUIRK(0x1043, 0x1b73, "ASUS N55SF", ALC662_FIXUP_BASS_16),
David Henningsson8e54b4a2014-02-07 09:31:07 +01008693 SND_PCI_QUIRK(0x1043, 0x1bf3, "ASUS N76VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
Takashi Iwai1565cc32012-02-13 12:03:25 +01008694 SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT),
Takashi Iwai53c334a2011-08-23 18:27:14 +02008695 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2),
Daniel T Chena0e90ac2010-11-20 10:20:35 -05008696 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
Kailang Yangc6790c82016-11-25 16:15:17 +08008697 SND_PCI_QUIRK(0x14cd, 0x5003, "USI", ALC662_FIXUP_USI_HEADSET_MODE),
Kailang Yangca169cc2017-04-25 16:17:40 +08008698 SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC662_FIXUP_LENOVO_MULTI_CODECS),
Valentine Sinitsynd4118582010-10-01 22:24:08 +06008699 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
David Henningsson6cb3b702010-09-09 08:51:44 +02008700 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
Takashi Iwai1a3f0992016-10-20 12:14:51 +02008701 SND_PCI_QUIRK(0x1849, 0x5892, "ASRock B150M", ALC892_FIXUP_ASROCK_MOBO),
David Henningssonedfe3bf2012-06-12 13:15:12 +02008702 SND_PCI_QUIRK(0x19da, 0xa130, "Zotac Z68", ALC662_FIXUP_ZOTAC_Z68),
Shrirang Bagul9b51fe32016-08-01 13:16:17 +08008703 SND_PCI_QUIRK(0x1b0a, 0x01b8, "ACER Veriton", ALC662_FIXUP_ACER_VERITON),
Anisse Astierd2ebd472011-01-20 12:36:21 +01008704 SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
Takashi Iwai53c334a2011-08-23 18:27:14 +02008705
8706#if 0
8707 /* Below is a quirk table taken from the old code.
8708 * Basically the device should work as is without the fixup table.
8709 * If BIOS doesn't give a proper info, enable the corresponding
8710 * fixup entry.
Jesper Juhl7d7eb9e2012-04-12 22:11:25 +02008711 */
Takashi Iwai53c334a2011-08-23 18:27:14 +02008712 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC662_FIXUP_ASUS_MODE1),
8713 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC662_FIXUP_ASUS_MODE3),
8714 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC662_FIXUP_ASUS_MODE1),
8715 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC662_FIXUP_ASUS_MODE3),
8716 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
8717 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8718 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
8719 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC662_FIXUP_ASUS_MODE1),
8720 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC662_FIXUP_ASUS_MODE1),
8721 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8722 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC662_FIXUP_ASUS_MODE7),
8723 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC662_FIXUP_ASUS_MODE7),
8724 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC662_FIXUP_ASUS_MODE8),
8725 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC662_FIXUP_ASUS_MODE3),
8726 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC662_FIXUP_ASUS_MODE1),
8727 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8728 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_FIXUP_ASUS_MODE2),
8729 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC662_FIXUP_ASUS_MODE1),
8730 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8731 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
8732 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
8733 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8734 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC662_FIXUP_ASUS_MODE1),
8735 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC662_FIXUP_ASUS_MODE3),
8736 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_FIXUP_ASUS_MODE2),
8737 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8738 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC662_FIXUP_ASUS_MODE5),
8739 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
8740 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8741 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC662_FIXUP_ASUS_MODE1),
8742 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8743 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8744 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC662_FIXUP_ASUS_MODE3),
8745 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC662_FIXUP_ASUS_MODE3),
8746 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC662_FIXUP_ASUS_MODE1),
8747 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC662_FIXUP_ASUS_MODE1),
8748 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC662_FIXUP_ASUS_MODE1),
8749 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC662_FIXUP_ASUS_MODE1),
8750 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC662_FIXUP_ASUS_MODE1),
8751 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8752 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_FIXUP_ASUS_MODE2),
8753 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC662_FIXUP_ASUS_MODE1),
8754 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
8755 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC662_FIXUP_ASUS_MODE3),
8756 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC662_FIXUP_ASUS_MODE1),
8757 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC662_FIXUP_ASUS_MODE1),
8758 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC662_FIXUP_ASUS_MODE1),
8759 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_FIXUP_ASUS_MODE2),
8760 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
8761 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE4),
8762#endif
David Henningsson6cb3b702010-09-09 08:51:44 +02008763 {}
8764};
8765
Takashi Iwai1727a772013-01-10 09:52:52 +01008766static const struct hda_model_fixup alc662_fixup_models[] = {
Takashi Iwaiaa3841b2018-06-26 07:42:40 +02008767 {.id = ALC662_FIXUP_ASPIRE, .name = "aspire"},
8768 {.id = ALC662_FIXUP_IDEAPAD, .name = "ideapad"},
Todd Broch6be79482010-12-07 16:51:05 -08008769 {.id = ALC272_FIXUP_MARIO, .name = "mario"},
Takashi Iwaiaa3841b2018-06-26 07:42:40 +02008770 {.id = ALC662_FIXUP_HP_RP5800, .name = "hp-rp5800"},
Takashi Iwai53c334a2011-08-23 18:27:14 +02008771 {.id = ALC662_FIXUP_ASUS_MODE1, .name = "asus-mode1"},
8772 {.id = ALC662_FIXUP_ASUS_MODE2, .name = "asus-mode2"},
8773 {.id = ALC662_FIXUP_ASUS_MODE3, .name = "asus-mode3"},
8774 {.id = ALC662_FIXUP_ASUS_MODE4, .name = "asus-mode4"},
8775 {.id = ALC662_FIXUP_ASUS_MODE5, .name = "asus-mode5"},
8776 {.id = ALC662_FIXUP_ASUS_MODE6, .name = "asus-mode6"},
8777 {.id = ALC662_FIXUP_ASUS_MODE7, .name = "asus-mode7"},
8778 {.id = ALC662_FIXUP_ASUS_MODE8, .name = "asus-mode8"},
Takashi Iwaiaa3841b2018-06-26 07:42:40 +02008779 {.id = ALC662_FIXUP_ZOTAC_Z68, .name = "zotac-z68"},
Takashi Iwai6e72aa52012-06-25 10:52:25 +02008780 {.id = ALC662_FIXUP_INV_DMIC, .name = "inv-dmic"},
Takashi Iwaiaa3841b2018-06-26 07:42:40 +02008781 {.id = ALC662_FIXUP_DELL_MIC_NO_PRESENCE, .name = "alc662-headset-multi"},
David Henningssone32aa852013-06-17 11:04:02 +02008782 {.id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE, .name = "dell-headset-multi"},
Takashi Iwaiaa3841b2018-06-26 07:42:40 +02008783 {.id = ALC662_FIXUP_HEADSET_MODE, .name = "alc662-headset"},
8784 {.id = ALC668_FIXUP_HEADSET_MODE, .name = "alc668-headset"},
8785 {.id = ALC662_FIXUP_BASS_16, .name = "bass16"},
8786 {.id = ALC662_FIXUP_BASS_1A, .name = "bass1a"},
8787 {.id = ALC668_FIXUP_AUTO_MUTE, .name = "automute"},
8788 {.id = ALC668_FIXUP_DELL_XPS13, .name = "dell-xps13"},
8789 {.id = ALC662_FIXUP_ASUS_Nx50, .name = "asus-nx50"},
8790 {.id = ALC668_FIXUP_ASUS_Nx51, .name = "asus-nx51"},
Takashi Iwai40c51672018-10-07 09:47:39 +02008791 {.id = ALC668_FIXUP_ASUS_G751, .name = "asus-g751"},
Takashi Iwaiaa3841b2018-06-26 07:42:40 +02008792 {.id = ALC891_FIXUP_HEADSET_MODE, .name = "alc891-headset"},
8793 {.id = ALC891_FIXUP_DELL_MIC_NO_PRESENCE, .name = "alc891-headset-multi"},
8794 {.id = ALC662_FIXUP_ACER_VERITON, .name = "acer-veriton"},
8795 {.id = ALC892_FIXUP_ASROCK_MOBO, .name = "asrock-mobo"},
8796 {.id = ALC662_FIXUP_USI_HEADSET_MODE, .name = "usi-headset"},
Takashi Iwaiba90d6a2017-05-22 16:38:47 +02008797 {.id = ALC662_FIXUP_LENOVO_MULTI_CODECS, .name = "dual-codecs"},
Todd Broch6be79482010-12-07 16:51:05 -08008798 {}
8799};
David Henningsson6cb3b702010-09-09 08:51:44 +02008800
Hui Wang532895c2014-05-29 15:59:19 +08008801static const struct snd_hda_pin_quirk alc662_pin_fixup_tbl[] = {
Kailang Yang78f4f7c2016-06-07 11:31:34 +08008802 SND_HDA_PIN_QUIRK(0x10ec0867, 0x1028, "Dell", ALC891_FIXUP_DELL_MIC_NO_PRESENCE,
8803 {0x17, 0x02211010},
8804 {0x18, 0x01a19030},
8805 {0x1a, 0x01813040},
8806 {0x21, 0x01014020}),
Hui Wang4b4e0e32019-07-16 15:21:34 +08008807 SND_HDA_PIN_QUIRK(0x10ec0867, 0x1028, "Dell", ALC891_FIXUP_DELL_MIC_NO_PRESENCE,
8808 {0x16, 0x01813030},
8809 {0x17, 0x02211010},
8810 {0x18, 0x01a19040},
8811 {0x21, 0x01014020}),
David Henningsson1f8b46c2015-05-12 14:38:15 +02008812 SND_HDA_PIN_QUIRK(0x10ec0662, 0x1028, "Dell", ALC662_FIXUP_DELL_MIC_NO_PRESENCE,
David Henningsson1f8b46c2015-05-12 14:38:15 +02008813 {0x14, 0x01014010},
David Henningsson1f8b46c2015-05-12 14:38:15 +02008814 {0x18, 0x01a19020},
David Henningsson1f8b46c2015-05-12 14:38:15 +02008815 {0x1a, 0x0181302f},
Hui Wang11580292015-08-03 11:03:49 +08008816 {0x1b, 0x0221401f}),
David Henningsson76c21322014-06-24 14:46:54 +02008817 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
8818 {0x12, 0x99a30130},
8819 {0x14, 0x90170110},
8820 {0x15, 0x0321101f},
Hui Wang11580292015-08-03 11:03:49 +08008821 {0x16, 0x03011020}),
David Henningsson76c21322014-06-24 14:46:54 +02008822 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
8823 {0x12, 0x99a30140},
8824 {0x14, 0x90170110},
8825 {0x15, 0x0321101f},
Hui Wang11580292015-08-03 11:03:49 +08008826 {0x16, 0x03011020}),
David Henningsson76c21322014-06-24 14:46:54 +02008827 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
8828 {0x12, 0x99a30150},
8829 {0x14, 0x90170110},
8830 {0x15, 0x0321101f},
Hui Wang11580292015-08-03 11:03:49 +08008831 {0x16, 0x03011020}),
David Henningsson76c21322014-06-24 14:46:54 +02008832 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
David Henningsson76c21322014-06-24 14:46:54 +02008833 {0x14, 0x90170110},
8834 {0x15, 0x0321101f},
Hui Wang11580292015-08-03 11:03:49 +08008835 {0x16, 0x03011020}),
David Henningsson76c21322014-06-24 14:46:54 +02008836 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell XPS 15", ALC668_FIXUP_AUTO_MUTE,
8837 {0x12, 0x90a60130},
8838 {0x14, 0x90170110},
Hui Wang11580292015-08-03 11:03:49 +08008839 {0x15, 0x0321101f}),
Hui Wang532895c2014-05-29 15:59:19 +08008840 {}
8841};
8842
Takashi Iwai1d045db2011-07-07 18:23:21 +02008843/*
8844 */
Kailang Yangbc9f98a2007-04-12 13:06:07 +02008845static int patch_alc662(struct hda_codec *codec)
8846{
8847 struct alc_spec *spec;
Takashi Iwai3de95172012-05-07 18:03:15 +02008848 int err;
Kailang Yangbc9f98a2007-04-12 13:06:07 +02008849
Takashi Iwai3de95172012-05-07 18:03:15 +02008850 err = alc_alloc_spec(codec, 0x0b);
8851 if (err < 0)
8852 return err;
Kailang Yangbc9f98a2007-04-12 13:06:07 +02008853
Takashi Iwai3de95172012-05-07 18:03:15 +02008854 spec = codec->spec;
Takashi Iwai1f0f4b82011-06-27 10:52:59 +02008855
Takashi Iwai225068a2015-05-29 10:42:14 +02008856 spec->shutup = alc_eapd_shutup;
8857
Takashi Iwai53c334a2011-08-23 18:27:14 +02008858 /* handle multiple HPs as is */
8859 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
8860
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +02008861 alc_fix_pll_init(codec, 0x20, 0x04, 15);
8862
Takashi Iwai7639a062015-03-03 10:07:24 +01008863 switch (codec->core.vendor_id) {
Kailang Yangf3f91852014-10-24 15:43:46 +08008864 case 0x10ec0668:
8865 spec->init_hook = alc668_restore_default_value;
8866 break;
Kailang Yangf3f91852014-10-24 15:43:46 +08008867 }
Kailang Yang8663ff72012-06-29 09:35:52 +02008868
Takashi Iwaic9af7532019-05-10 11:01:43 +02008869 alc_pre_init(codec);
8870
Takashi Iwai1727a772013-01-10 09:52:52 +01008871 snd_hda_pick_fixup(codec, alc662_fixup_models,
Takashi Iwai8e5a0502012-06-21 15:49:33 +02008872 alc662_fixup_tbl, alc662_fixups);
Hui Wang532895c2014-05-29 15:59:19 +08008873 snd_hda_pick_pin_fixup(codec, alc662_pin_fixup_tbl, alc662_fixups);
Takashi Iwai1727a772013-01-10 09:52:52 +01008874 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai8e5a0502012-06-21 15:49:33 +02008875
8876 alc_auto_parse_customize_define(codec);
8877
Takashi Iwai7504b6c2013-03-18 11:25:51 +01008878 if (has_cdefine_beep(codec))
8879 spec->gen.beep_nid = 0x01;
8880
Takashi Iwai1bb7e432011-10-17 16:50:59 +02008881 if ((alc_get_coef0(codec) & (1 << 14)) &&
Takashi Iwai5100cd02014-02-15 10:03:19 +01008882 codec->bus->pci && codec->bus->pci->subsystem_vendor == 0x1025 &&
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008883 spec->cdefine.platform_type == 1) {
Wei Yongjun6134b1a2013-04-18 11:12:59 +08008884 err = alc_codec_rename(codec, "ALC272X");
8885 if (err < 0)
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008886 goto error;
Takashi Iwai20ca0c32011-10-17 16:00:35 +02008887 }
Kailang Yang274693f2009-12-03 10:07:50 +01008888
Takashi Iwaib9c51062011-08-24 18:08:07 +02008889 /* automatic parse from the BIOS config */
8890 err = alc662_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008891 if (err < 0)
8892 goto error;
Kailang Yangbc9f98a2007-04-12 13:06:07 +02008893
Takashi Iwai7504b6c2013-03-18 11:25:51 +01008894 if (!spec->gen.no_analog && spec->gen.beep_nid) {
Takashi Iwai7639a062015-03-03 10:07:24 +01008895 switch (codec->core.vendor_id) {
Kailang Yangda00c242010-03-19 11:23:45 +01008896 case 0x10ec0662:
Takashi Iwaifea80fa2018-06-20 12:52:46 +02008897 err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
Kailang Yangda00c242010-03-19 11:23:45 +01008898 break;
8899 case 0x10ec0272:
8900 case 0x10ec0663:
8901 case 0x10ec0665:
Kailang Yang9ad54542013-11-26 15:41:40 +08008902 case 0x10ec0668:
Takashi Iwaifea80fa2018-06-20 12:52:46 +02008903 err = set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
Kailang Yangda00c242010-03-19 11:23:45 +01008904 break;
8905 case 0x10ec0273:
Takashi Iwaifea80fa2018-06-20 12:52:46 +02008906 err = set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
Kailang Yangda00c242010-03-19 11:23:45 +01008907 break;
8908 }
Takashi Iwaifea80fa2018-06-20 12:52:46 +02008909 if (err < 0)
8910 goto error;
Kailang Yangcec27c82010-02-04 14:18:18 +01008911 }
Takashi Iwai2134ea42008-01-10 16:53:55 +01008912
Takashi Iwai1727a772013-01-10 09:52:52 +01008913 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01008914
Kailang Yangbc9f98a2007-04-12 13:06:07 +02008915 return 0;
Kailang Yangbc9f98a2007-04-12 13:06:07 +02008916
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008917 error:
8918 alc_free(codec);
8919 return err;
Kailang Yangb478b992011-05-18 11:51:15 +02008920}
8921
Kailang Yangbc9f98a2007-04-12 13:06:07 +02008922/*
Kailang Yangd1eb57f2010-06-23 16:25:26 +02008923 * ALC680 support
8924 */
Kailang Yangd1eb57f2010-06-23 16:25:26 +02008925
Kailang Yangd1eb57f2010-06-23 16:25:26 +02008926static int alc680_parse_auto_config(struct hda_codec *codec)
8927{
Takashi Iwai3e6179b2011-07-08 16:55:13 +02008928 return alc_parse_auto_config(codec, NULL, NULL);
Kailang Yangd1eb57f2010-06-23 16:25:26 +02008929}
8930
Kailang Yangd1eb57f2010-06-23 16:25:26 +02008931/*
Kailang Yangd1eb57f2010-06-23 16:25:26 +02008932 */
Kailang Yangd1eb57f2010-06-23 16:25:26 +02008933static int patch_alc680(struct hda_codec *codec)
8934{
Kailang Yangd1eb57f2010-06-23 16:25:26 +02008935 int err;
8936
Takashi Iwai1f0f4b82011-06-27 10:52:59 +02008937 /* ALC680 has no aa-loopback mixer */
Takashi Iwai3de95172012-05-07 18:03:15 +02008938 err = alc_alloc_spec(codec, 0);
8939 if (err < 0)
8940 return err;
Takashi Iwai1f0f4b82011-06-27 10:52:59 +02008941
Takashi Iwai1ebec5f2011-08-15 13:21:48 +02008942 /* automatic parse from the BIOS config */
8943 err = alc680_parse_auto_config(codec);
8944 if (err < 0) {
8945 alc_free(codec);
8946 return err;
Kailang Yangd1eb57f2010-06-23 16:25:26 +02008947 }
8948
Kailang Yangd1eb57f2010-06-23 16:25:26 +02008949 return 0;
8950}
8951
8952/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07008953 * patch entries
8954 */
Takashi Iwaib9a94a92015-10-01 16:20:04 +02008955static const struct hda_device_id snd_hda_id_realtek[] = {
Kailang Yang0a6f0602017-06-30 16:00:48 +08008956 HDA_CODEC_ENTRY(0x10ec0215, "ALC215", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02008957 HDA_CODEC_ENTRY(0x10ec0221, "ALC221", patch_alc269),
Kailang Yang42314302016-02-03 15:03:50 +08008958 HDA_CODEC_ENTRY(0x10ec0225, "ALC225", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02008959 HDA_CODEC_ENTRY(0x10ec0231, "ALC231", patch_alc269),
8960 HDA_CODEC_ENTRY(0x10ec0233, "ALC233", patch_alc269),
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08008961 HDA_CODEC_ENTRY(0x10ec0234, "ALC234", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02008962 HDA_CODEC_ENTRY(0x10ec0235, "ALC233", patch_alc269),
Kailang Yang736f20a2017-10-20 15:06:34 +08008963 HDA_CODEC_ENTRY(0x10ec0236, "ALC236", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02008964 HDA_CODEC_ENTRY(0x10ec0255, "ALC255", patch_alc269),
8965 HDA_CODEC_ENTRY(0x10ec0256, "ALC256", patch_alc269),
Kailang Yangf429e7e2017-12-05 15:38:24 +08008966 HDA_CODEC_ENTRY(0x10ec0257, "ALC257", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02008967 HDA_CODEC_ENTRY(0x10ec0260, "ALC260", patch_alc260),
8968 HDA_CODEC_ENTRY(0x10ec0262, "ALC262", patch_alc262),
8969 HDA_CODEC_ENTRY(0x10ec0267, "ALC267", patch_alc268),
8970 HDA_CODEC_ENTRY(0x10ec0268, "ALC268", patch_alc268),
8971 HDA_CODEC_ENTRY(0x10ec0269, "ALC269", patch_alc269),
8972 HDA_CODEC_ENTRY(0x10ec0270, "ALC270", patch_alc269),
8973 HDA_CODEC_ENTRY(0x10ec0272, "ALC272", patch_alc662),
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08008974 HDA_CODEC_ENTRY(0x10ec0274, "ALC274", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02008975 HDA_CODEC_ENTRY(0x10ec0275, "ALC275", patch_alc269),
8976 HDA_CODEC_ENTRY(0x10ec0276, "ALC276", patch_alc269),
8977 HDA_CODEC_ENTRY(0x10ec0280, "ALC280", patch_alc269),
8978 HDA_CODEC_ENTRY(0x10ec0282, "ALC282", patch_alc269),
8979 HDA_CODEC_ENTRY(0x10ec0283, "ALC283", patch_alc269),
8980 HDA_CODEC_ENTRY(0x10ec0284, "ALC284", patch_alc269),
Kailang Yang0a6f0602017-06-30 16:00:48 +08008981 HDA_CODEC_ENTRY(0x10ec0285, "ALC285", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02008982 HDA_CODEC_ENTRY(0x10ec0286, "ALC286", patch_alc269),
8983 HDA_CODEC_ENTRY(0x10ec0288, "ALC288", patch_alc269),
Kailang Yang0a6f0602017-06-30 16:00:48 +08008984 HDA_CODEC_ENTRY(0x10ec0289, "ALC289", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02008985 HDA_CODEC_ENTRY(0x10ec0290, "ALC290", patch_alc269),
8986 HDA_CODEC_ENTRY(0x10ec0292, "ALC292", patch_alc269),
8987 HDA_CODEC_ENTRY(0x10ec0293, "ALC293", patch_alc269),
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08008988 HDA_CODEC_ENTRY(0x10ec0294, "ALC294", patch_alc269),
Kailang Yang7d727862016-05-24 16:46:07 +08008989 HDA_CODEC_ENTRY(0x10ec0295, "ALC295", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02008990 HDA_CODEC_ENTRY(0x10ec0298, "ALC298", patch_alc269),
Kailang Yang28f1f9b2017-01-04 14:49:07 +08008991 HDA_CODEC_ENTRY(0x10ec0299, "ALC299", patch_alc269),
Kailang Yang1078bef2018-11-08 16:36:15 +08008992 HDA_CODEC_ENTRY(0x10ec0300, "ALC300", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02008993 HDA_CODEC_REV_ENTRY(0x10ec0861, 0x100340, "ALC660", patch_alc861),
8994 HDA_CODEC_ENTRY(0x10ec0660, "ALC660-VD", patch_alc861vd),
8995 HDA_CODEC_ENTRY(0x10ec0861, "ALC861", patch_alc861),
8996 HDA_CODEC_ENTRY(0x10ec0862, "ALC861-VD", patch_alc861vd),
8997 HDA_CODEC_REV_ENTRY(0x10ec0662, 0x100002, "ALC662 rev2", patch_alc882),
8998 HDA_CODEC_REV_ENTRY(0x10ec0662, 0x100101, "ALC662 rev1", patch_alc662),
8999 HDA_CODEC_REV_ENTRY(0x10ec0662, 0x100300, "ALC662 rev3", patch_alc662),
9000 HDA_CODEC_ENTRY(0x10ec0663, "ALC663", patch_alc662),
9001 HDA_CODEC_ENTRY(0x10ec0665, "ALC665", patch_alc662),
9002 HDA_CODEC_ENTRY(0x10ec0667, "ALC667", patch_alc662),
9003 HDA_CODEC_ENTRY(0x10ec0668, "ALC668", patch_alc662),
9004 HDA_CODEC_ENTRY(0x10ec0670, "ALC670", patch_alc662),
9005 HDA_CODEC_ENTRY(0x10ec0671, "ALC671", patch_alc662),
9006 HDA_CODEC_ENTRY(0x10ec0680, "ALC680", patch_alc680),
Kailang Yang6fbae352016-05-30 16:44:20 +08009007 HDA_CODEC_ENTRY(0x10ec0700, "ALC700", patch_alc269),
9008 HDA_CODEC_ENTRY(0x10ec0701, "ALC701", patch_alc269),
9009 HDA_CODEC_ENTRY(0x10ec0703, "ALC703", patch_alc269),
Kailang Yang78f4f7c2016-06-07 11:31:34 +08009010 HDA_CODEC_ENTRY(0x10ec0867, "ALC891", patch_alc662),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009011 HDA_CODEC_ENTRY(0x10ec0880, "ALC880", patch_alc880),
9012 HDA_CODEC_ENTRY(0x10ec0882, "ALC882", patch_alc882),
9013 HDA_CODEC_ENTRY(0x10ec0883, "ALC883", patch_alc882),
9014 HDA_CODEC_REV_ENTRY(0x10ec0885, 0x100101, "ALC889A", patch_alc882),
9015 HDA_CODEC_REV_ENTRY(0x10ec0885, 0x100103, "ALC889A", patch_alc882),
9016 HDA_CODEC_ENTRY(0x10ec0885, "ALC885", patch_alc882),
9017 HDA_CODEC_ENTRY(0x10ec0887, "ALC887", patch_alc882),
9018 HDA_CODEC_REV_ENTRY(0x10ec0888, 0x100101, "ALC1200", patch_alc882),
9019 HDA_CODEC_ENTRY(0x10ec0888, "ALC888", patch_alc882),
9020 HDA_CODEC_ENTRY(0x10ec0889, "ALC889", patch_alc882),
9021 HDA_CODEC_ENTRY(0x10ec0892, "ALC892", patch_alc662),
9022 HDA_CODEC_ENTRY(0x10ec0899, "ALC898", patch_alc882),
9023 HDA_CODEC_ENTRY(0x10ec0900, "ALC1150", patch_alc882),
Kailang Yang65553b12017-07-11 15:15:47 +08009024 HDA_CODEC_ENTRY(0x10ec1168, "ALC1220", patch_alc882),
Kailang Yanga535ad52017-01-16 16:59:26 +08009025 HDA_CODEC_ENTRY(0x10ec1220, "ALC1220", patch_alc882),
Linus Torvalds1da177e2005-04-16 15:20:36 -07009026 {} /* terminator */
9027};
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009028MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_realtek);
Takashi Iwai1289e9e2008-11-27 15:47:11 +01009029
9030MODULE_LICENSE("GPL");
9031MODULE_DESCRIPTION("Realtek HD-audio codec");
9032
Takashi Iwaid8a766a2015-02-17 15:25:37 +01009033static struct hda_codec_driver realtek_driver = {
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009034 .id = snd_hda_id_realtek,
Takashi Iwai1289e9e2008-11-27 15:47:11 +01009035};
9036
Takashi Iwaid8a766a2015-02-17 15:25:37 +01009037module_hda_codec_driver(realtek_driver);