blob: c521a1f170969aabea99b5c627486d0985c97de8 [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>
Kai-Heng Feng87dc3642020-04-30 21:52:07 +080020#include <linux/leds.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070021#include <sound/core.h>
Kailang Yang9ad0e492010-09-14 23:22:00 +020022#include <sound/jack.h>
Pierre-Louis Bossartbe57bff2018-08-22 15:24:57 -050023#include <sound/hda_codec.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070024#include "hda_local.h"
Takashi Iwai23d30f22012-05-07 17:17:32 +020025#include "hda_auto_parser.h"
Takashi Iwai1835a0f2011-10-27 22:12:46 +020026#include "hda_jack.h"
Takashi Iwai08c189f2012-12-19 15:22:24 +010027#include "hda_generic.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070028
Takashi Iwaicd63a5f2013-07-05 12:13:59 +020029/* keep halting ALC5505 DSP, for power saving */
30#define HALT_REALTEK_ALC5505
31
Takashi Iwai4a79ba32009-04-22 16:31:35 +020032/* extra amp-initialization sequence types */
33enum {
Takashi Iwai1c76aa52018-06-21 16:37:54 +020034 ALC_INIT_UNDEFINED,
Takashi Iwai4a79ba32009-04-22 16:31:35 +020035 ALC_INIT_NONE,
36 ALC_INIT_DEFAULT,
Takashi Iwai4a79ba32009-04-22 16:31:35 +020037};
38
David Henningsson73bdd592013-04-15 15:44:14 +020039enum {
40 ALC_HEADSET_MODE_UNKNOWN,
41 ALC_HEADSET_MODE_UNPLUGGED,
42 ALC_HEADSET_MODE_HEADSET,
43 ALC_HEADSET_MODE_MIC,
44 ALC_HEADSET_MODE_HEADPHONE,
45};
46
47enum {
48 ALC_HEADSET_TYPE_UNKNOWN,
49 ALC_HEADSET_TYPE_CTIA,
50 ALC_HEADSET_TYPE_OMTP,
51};
52
Hui Wangc7b60a82015-12-28 11:35:25 +080053enum {
54 ALC_KEY_MICMUTE_INDEX,
55};
56
Kailang Yangda00c242010-03-19 11:23:45 +010057struct alc_customize_define {
58 unsigned int sku_cfg;
59 unsigned char port_connectivity;
60 unsigned char check_sum;
61 unsigned char customization;
62 unsigned char external_amp;
63 unsigned int enable_pcbeep:1;
64 unsigned int platform_type:1;
65 unsigned int swap:1;
66 unsigned int override:1;
David Henningsson90622912010-10-14 14:50:18 +020067 unsigned int fixup:1; /* Means that this sku is set by driver, not read from hw */
Kailang Yangda00c242010-03-19 11:23:45 +010068};
69
Takashi Iwai766538a2020-06-18 13:08:41 +020070struct alc_coef_led {
71 unsigned int idx;
72 unsigned int mask;
73 unsigned int on;
74 unsigned int off;
75};
76
Linus Torvalds1da177e2005-04-16 15:20:36 -070077struct alc_spec {
Takashi Iwai08c189f2012-12-19 15:22:24 +010078 struct hda_gen_spec gen; /* must be at head */
Takashi Iwai23d30f22012-05-07 17:17:32 +020079
Linus Torvalds1da177e2005-04-16 15:20:36 -070080 /* codec parameterization */
Kailang Yangda00c242010-03-19 11:23:45 +010081 struct alc_customize_define cdefine;
Takashi Iwai08c189f2012-12-19 15:22:24 +010082 unsigned int parse_flags; /* flag for snd_hda_parse_pin_defcfg() */
83
Takashi Iwai5579cd62018-06-19 22:22:41 +020084 /* GPIO bits */
85 unsigned int gpio_mask;
86 unsigned int gpio_dir;
87 unsigned int gpio_data;
Takashi Iwai215c8502018-06-19 22:34:26 +020088 bool gpio_write_delay; /* add a delay before writing gpio_data */
Takashi Iwai5579cd62018-06-19 22:22:41 +020089
Takashi Iwai8d3d1ec2020-06-18 13:08:38 +020090 /* mute LED for HP laptops, see vref_mute_led_set() */
Takashi Iwai08fb0d02013-01-10 17:33:58 +010091 int mute_led_polarity;
Kai-Heng Fengdbd13172020-04-30 16:32:51 +080092 int micmute_led_polarity;
Takashi Iwai08fb0d02013-01-10 17:33:58 +010093 hda_nid_t mute_led_nid;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +080094 hda_nid_t cap_mute_led_nid;
Takashi Iwai08fb0d02013-01-10 17:33:58 +010095
Takashi Iwai0f32fd192014-11-19 12:16:14 +010096 unsigned int gpio_mute_led_mask;
97 unsigned int gpio_mic_led_mask;
Takashi Iwai766538a2020-06-18 13:08:41 +020098 struct alc_coef_led mute_led_coef;
99 struct alc_coef_led mic_led_coef;
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +0100100
David Henningsson73bdd592013-04-15 15:44:14 +0200101 hda_nid_t headset_mic_pin;
102 hda_nid_t headphone_mic_pin;
103 int current_headset_mode;
104 int current_headset_type;
105
Takashi Iwaiae6b8132006-03-03 16:47:17 +0100106 /* hooks */
107 void (*init_hook)(struct hda_codec *codec);
Takashi Iwai83012a72012-08-24 18:38:08 +0200108#ifdef CONFIG_PM
Daniel T Chenc97259d2009-12-27 18:52:08 -0500109 void (*power_hook)(struct hda_codec *codec);
Hector Martinf5de24b2009-12-20 22:51:31 +0100110#endif
Takashi Iwai1c7161532011-04-07 10:37:16 +0200111 void (*shutup)(struct hda_codec *codec);
Takashi Iwai70a09762015-12-15 14:59:58 +0100112 void (*reboot_notify)(struct hda_codec *codec);
Takashi Iwaid922b512011-04-28 12:18:53 +0200113
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200114 int init_amp;
Takashi Iwaid433a672010-09-20 15:11:54 +0200115 int codec_variant; /* flag for other variants */
Kailang Yang97a26572013-11-29 00:35:26 -0500116 unsigned int has_alc5505_dsp:1;
117 unsigned int no_depop_delay:1;
Kailang Yang693abe12019-01-29 15:38:21 +0800118 unsigned int done_hp_init:1;
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +0100119 unsigned int no_shutup_pins:1;
Kailang Yangd3ba58b2019-05-06 15:09:42 +0800120 unsigned int ultra_low_power:1;
Hui Wang476c02e2020-03-29 16:20:18 +0800121 unsigned int has_hs_key:1;
Takashi Iwaie64f14f2009-01-20 18:32:55 +0100122
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200123 /* for PLL fix */
124 hda_nid_t pll_nid;
125 unsigned int pll_coef_idx, pll_coef_bit;
Takashi Iwai1bb7e432011-10-17 16:50:59 +0200126 unsigned int coef0;
David Henningsson33f4acd2015-01-07 15:50:13 +0100127 struct input_dev *kb_dev;
Hui Wangc7b60a82015-12-28 11:35:25 +0800128 u8 alc_mute_keycode_map[1];
Kailang Yangdf694da2005-12-05 19:42:22 +0100129};
130
Takashi Iwai23f0c042009-02-26 13:03:58 +0100131/*
Takashi Iwaif2a227c2014-08-18 13:35:22 +0200132 * COEF access helper functions
133 */
134
135static int alc_read_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
136 unsigned int coef_idx)
137{
138 unsigned int val;
139
140 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, coef_idx);
141 val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PROC_COEF, 0);
142 return val;
143}
144
145#define alc_read_coef_idx(codec, coef_idx) \
146 alc_read_coefex_idx(codec, 0x20, coef_idx)
147
148static void alc_write_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
149 unsigned int coef_idx, unsigned int coef_val)
150{
151 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, coef_idx);
152 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PROC_COEF, coef_val);
153}
154
155#define alc_write_coef_idx(codec, coef_idx, coef_val) \
156 alc_write_coefex_idx(codec, 0x20, coef_idx, coef_val)
157
Takashi Iwai98b24882014-08-18 13:47:50 +0200158static void alc_update_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
159 unsigned int coef_idx, unsigned int mask,
160 unsigned int bits_set)
161{
162 unsigned int val = alc_read_coefex_idx(codec, nid, coef_idx);
163
164 if (val != -1)
165 alc_write_coefex_idx(codec, nid, coef_idx,
166 (val & ~mask) | bits_set);
167}
168
169#define alc_update_coef_idx(codec, coef_idx, mask, bits_set) \
170 alc_update_coefex_idx(codec, 0x20, coef_idx, mask, bits_set)
171
Takashi Iwaif2a227c2014-08-18 13:35:22 +0200172/* a special bypass for COEF 0; read the cached value at the second time */
173static unsigned int alc_get_coef0(struct hda_codec *codec)
174{
175 struct alc_spec *spec = codec->spec;
176
177 if (!spec->coef0)
178 spec->coef0 = alc_read_coef_idx(codec, 0);
179 return spec->coef0;
180}
181
Takashi Iwai54db6c32014-08-18 15:11:19 +0200182/* coef writes/updates batch */
183struct coef_fw {
184 unsigned char nid;
185 unsigned char idx;
186 unsigned short mask;
187 unsigned short val;
188};
189
190#define UPDATE_COEFEX(_nid, _idx, _mask, _val) \
191 { .nid = (_nid), .idx = (_idx), .mask = (_mask), .val = (_val) }
192#define WRITE_COEFEX(_nid, _idx, _val) UPDATE_COEFEX(_nid, _idx, -1, _val)
193#define WRITE_COEF(_idx, _val) WRITE_COEFEX(0x20, _idx, _val)
194#define UPDATE_COEF(_idx, _mask, _val) UPDATE_COEFEX(0x20, _idx, _mask, _val)
195
196static void alc_process_coef_fw(struct hda_codec *codec,
197 const struct coef_fw *fw)
198{
199 for (; fw->nid; fw++) {
200 if (fw->mask == (unsigned short)-1)
201 alc_write_coefex_idx(codec, fw->nid, fw->idx, fw->val);
202 else
203 alc_update_coefex_idx(codec, fw->nid, fw->idx,
204 fw->mask, fw->val);
205 }
206}
207
Takashi Iwaif2a227c2014-08-18 13:35:22 +0200208/*
Takashi Iwai1d045db2011-07-07 18:23:21 +0200209 * GPIO setup tables, used in initialization
Kailang Yangdf694da2005-12-05 19:42:22 +0100210 */
Takashi Iwai5579cd62018-06-19 22:22:41 +0200211
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200212/* Enable GPIO mask and set output */
Takashi Iwai5579cd62018-06-19 22:22:41 +0200213static void alc_setup_gpio(struct hda_codec *codec, unsigned int mask)
214{
215 struct alc_spec *spec = codec->spec;
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200216
Takashi Iwai5579cd62018-06-19 22:22:41 +0200217 spec->gpio_mask |= mask;
218 spec->gpio_dir |= mask;
219 spec->gpio_data |= mask;
220}
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200221
Takashi Iwai5579cd62018-06-19 22:22:41 +0200222static void alc_write_gpio_data(struct hda_codec *codec)
223{
224 struct alc_spec *spec = codec->spec;
225
226 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
227 spec->gpio_data);
228}
229
Takashi Iwaiaaf312d2018-06-19 22:28:22 +0200230static void alc_update_gpio_data(struct hda_codec *codec, unsigned int mask,
231 bool on)
232{
233 struct alc_spec *spec = codec->spec;
234 unsigned int oldval = spec->gpio_data;
235
236 if (on)
237 spec->gpio_data |= mask;
238 else
239 spec->gpio_data &= ~mask;
240 if (oldval != spec->gpio_data)
241 alc_write_gpio_data(codec);
242}
243
Takashi Iwai5579cd62018-06-19 22:22:41 +0200244static void alc_write_gpio(struct hda_codec *codec)
245{
246 struct alc_spec *spec = codec->spec;
247
248 if (!spec->gpio_mask)
249 return;
250
251 snd_hda_codec_write(codec, codec->core.afg, 0,
252 AC_VERB_SET_GPIO_MASK, spec->gpio_mask);
253 snd_hda_codec_write(codec, codec->core.afg, 0,
254 AC_VERB_SET_GPIO_DIRECTION, spec->gpio_dir);
Takashi Iwai215c8502018-06-19 22:34:26 +0200255 if (spec->gpio_write_delay)
256 msleep(1);
Takashi Iwai5579cd62018-06-19 22:22:41 +0200257 alc_write_gpio_data(codec);
258}
259
260static void alc_fixup_gpio(struct hda_codec *codec, int action,
261 unsigned int mask)
262{
263 if (action == HDA_FIXUP_ACT_PRE_PROBE)
264 alc_setup_gpio(codec, mask);
265}
266
267static void alc_fixup_gpio1(struct hda_codec *codec,
268 const struct hda_fixup *fix, int action)
269{
270 alc_fixup_gpio(codec, action, 0x01);
271}
272
273static void alc_fixup_gpio2(struct hda_codec *codec,
274 const struct hda_fixup *fix, int action)
275{
276 alc_fixup_gpio(codec, action, 0x02);
277}
278
279static void alc_fixup_gpio3(struct hda_codec *codec,
280 const struct hda_fixup *fix, int action)
281{
282 alc_fixup_gpio(codec, action, 0x03);
283}
Kailang Yangbdd148a2007-05-08 15:19:08 +0200284
Takashi Iwaiae065f12018-06-19 23:00:03 +0200285static void alc_fixup_gpio4(struct hda_codec *codec,
286 const struct hda_fixup *fix, int action)
287{
288 alc_fixup_gpio(codec, action, 0x04);
289}
290
Takashi Iwai8a503552020-06-18 13:08:32 +0200291static void alc_fixup_micmute_led(struct hda_codec *codec,
292 const struct hda_fixup *fix, int action)
293{
294 if (action == HDA_FIXUP_ACT_PROBE)
295 snd_hda_gen_add_micmute_led_cdev(codec, NULL);
296}
297
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200298/*
299 * Fix hardware PLL issue
300 * On some codecs, the analog PLL gating control must be off while
301 * the default value is 1.
302 */
303static void alc_fix_pll(struct hda_codec *codec)
304{
305 struct alc_spec *spec = codec->spec;
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200306
Takashi Iwai98b24882014-08-18 13:47:50 +0200307 if (spec->pll_nid)
308 alc_update_coefex_idx(codec, spec->pll_nid, spec->pll_coef_idx,
309 1 << spec->pll_coef_bit, 0);
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200310}
311
312static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
313 unsigned int coef_idx, unsigned int coef_bit)
314{
315 struct alc_spec *spec = codec->spec;
316 spec->pll_nid = nid;
317 spec->pll_coef_idx = coef_idx;
318 spec->pll_coef_bit = coef_bit;
319 alc_fix_pll(codec);
320}
321
Takashi Iwaicf5a2272012-02-20 16:31:07 +0100322/* update the master volume per volume-knob's unsol event */
Takashi Iwai1a4f69d2014-09-11 15:22:46 +0200323static void alc_update_knob_master(struct hda_codec *codec,
324 struct hda_jack_callback *jack)
Takashi Iwaicf5a2272012-02-20 16:31:07 +0100325{
326 unsigned int val;
327 struct snd_kcontrol *kctl;
328 struct snd_ctl_elem_value *uctl;
329
330 kctl = snd_hda_find_mixer_ctl(codec, "Master Playback Volume");
331 if (!kctl)
332 return;
333 uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
334 if (!uctl)
335 return;
Takashi Iwai2ebab402016-02-09 10:23:52 +0100336 val = snd_hda_codec_read(codec, jack->nid, 0,
Takashi Iwaicf5a2272012-02-20 16:31:07 +0100337 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
338 val &= HDA_AMP_VOLMASK;
339 uctl->value.integer.value[0] = val;
340 uctl->value.integer.value[1] = val;
341 kctl->put(kctl, uctl);
342 kfree(uctl);
343}
344
David Henningsson29adc4b2012-09-25 11:31:00 +0200345static void alc880_unsol_event(struct hda_codec *codec, unsigned int res)
Takashi Iwaif21d78e2012-01-19 12:10:29 +0100346{
David Henningsson29adc4b2012-09-25 11:31:00 +0200347 /* For some reason, the res given from ALC880 is broken.
348 Here we adjust it properly. */
349 snd_hda_jack_unsol_event(codec, res >> 2);
Takashi Iwaif21d78e2012-01-19 12:10:29 +0100350}
351
Kailang Yang394c97f2014-11-12 17:38:08 +0800352/* Change EAPD to verb control */
353static void alc_fill_eapd_coef(struct hda_codec *codec)
354{
355 int coef;
356
357 coef = alc_get_coef0(codec);
358
Takashi Iwai7639a062015-03-03 10:07:24 +0100359 switch (codec->core.vendor_id) {
Kailang Yang394c97f2014-11-12 17:38:08 +0800360 case 0x10ec0262:
361 alc_update_coef_idx(codec, 0x7, 0, 1<<5);
362 break;
363 case 0x10ec0267:
364 case 0x10ec0268:
365 alc_update_coef_idx(codec, 0x7, 0, 1<<13);
366 break;
367 case 0x10ec0269:
368 if ((coef & 0x00f0) == 0x0010)
369 alc_update_coef_idx(codec, 0xd, 0, 1<<14);
370 if ((coef & 0x00f0) == 0x0020)
371 alc_update_coef_idx(codec, 0x4, 1<<15, 0);
372 if ((coef & 0x00f0) == 0x0030)
373 alc_update_coef_idx(codec, 0x10, 1<<9, 0);
374 break;
375 case 0x10ec0280:
376 case 0x10ec0284:
377 case 0x10ec0290:
378 case 0x10ec0292:
379 alc_update_coef_idx(codec, 0x4, 1<<15, 0);
380 break;
Kailang Yang42314302016-02-03 15:03:50 +0800381 case 0x10ec0225:
Takashi Iwai44be77c2017-12-27 08:53:59 +0100382 case 0x10ec0295:
383 case 0x10ec0299:
384 alc_update_coef_idx(codec, 0x67, 0xf000, 0x3000);
Gustavo A. R. Silvac0dbbda2020-07-08 15:32:36 -0500385 fallthrough;
Takashi Iwai44be77c2017-12-27 08:53:59 +0100386 case 0x10ec0215:
Kailang Yang394c97f2014-11-12 17:38:08 +0800387 case 0x10ec0233:
Kailang Yangea04a1d2018-04-25 15:31:52 +0800388 case 0x10ec0235:
Thomas Hebbc4473742020-03-30 12:09:38 -0400389 case 0x10ec0236:
Kailang Yang7fbdcd82020-04-23 14:18:31 +0800390 case 0x10ec0245:
Kailang Yang394c97f2014-11-12 17:38:08 +0800391 case 0x10ec0255:
Thomas Hebbc4473742020-03-30 12:09:38 -0400392 case 0x10ec0256:
Kailang Yangf429e7e2017-12-05 15:38:24 +0800393 case 0x10ec0257:
Kailang Yang394c97f2014-11-12 17:38:08 +0800394 case 0x10ec0282:
395 case 0x10ec0283:
396 case 0x10ec0286:
Kailang Yang630e3612020-05-27 14:10:26 +0800397 case 0x10ec0287:
Kailang Yang394c97f2014-11-12 17:38:08 +0800398 case 0x10ec0288:
Kailang Yang0a6f0602017-06-30 16:00:48 +0800399 case 0x10ec0285:
Kailang Yang506b62c2014-12-18 17:07:44 +0800400 case 0x10ec0298:
Kailang Yang0a6f0602017-06-30 16:00:48 +0800401 case 0x10ec0289:
Kailang Yang1078bef2018-11-08 16:36:15 +0800402 case 0x10ec0300:
Kailang Yang394c97f2014-11-12 17:38:08 +0800403 alc_update_coef_idx(codec, 0x10, 1<<9, 0);
404 break;
Kailang Yang3aabf942017-11-08 15:28:33 +0800405 case 0x10ec0275:
406 alc_update_coef_idx(codec, 0xe, 0, 1<<0);
407 break;
Kailang Yang394c97f2014-11-12 17:38:08 +0800408 case 0x10ec0293:
409 alc_update_coef_idx(codec, 0xa, 1<<13, 0);
410 break;
Kailang Yangdcd4f0d2016-05-04 15:50:18 +0800411 case 0x10ec0234:
412 case 0x10ec0274:
413 case 0x10ec0294:
Kailang Yang6fbae352016-05-30 16:44:20 +0800414 case 0x10ec0700:
415 case 0x10ec0701:
416 case 0x10ec0703:
Kailang Yang83629532019-05-02 16:03:26 +0800417 case 0x10ec0711:
Kailang Yangdcd4f0d2016-05-04 15:50:18 +0800418 alc_update_coef_idx(codec, 0x10, 1<<15, 0);
419 break;
Kailang Yang394c97f2014-11-12 17:38:08 +0800420 case 0x10ec0662:
421 if ((coef & 0x00f0) == 0x0030)
422 alc_update_coef_idx(codec, 0x4, 1<<10, 0); /* EAPD Ctrl */
423 break;
424 case 0x10ec0272:
425 case 0x10ec0273:
426 case 0x10ec0663:
427 case 0x10ec0665:
428 case 0x10ec0670:
429 case 0x10ec0671:
430 case 0x10ec0672:
431 alc_update_coef_idx(codec, 0xd, 0, 1<<14); /* EAPD Ctrl */
432 break;
Kailang Yang9194a1e2020-01-07 17:22:19 +0800433 case 0x10ec0222:
Kailang Yangf0778872019-10-24 15:13:32 +0800434 case 0x10ec0623:
435 alc_update_coef_idx(codec, 0x19, 1<<13, 0);
436 break;
Kailang Yang394c97f2014-11-12 17:38:08 +0800437 case 0x10ec0668:
438 alc_update_coef_idx(codec, 0x7, 3<<13, 0);
439 break;
440 case 0x10ec0867:
441 alc_update_coef_idx(codec, 0x4, 1<<10, 0);
442 break;
443 case 0x10ec0888:
444 if ((coef & 0x00f0) == 0x0020 || (coef & 0x00f0) == 0x0030)
445 alc_update_coef_idx(codec, 0x7, 1<<5, 0);
446 break;
447 case 0x10ec0892:
448 alc_update_coef_idx(codec, 0x7, 1<<5, 0);
449 break;
450 case 0x10ec0899:
451 case 0x10ec0900:
Kailang Yang6d9ffcf2020-01-03 16:24:06 +0800452 case 0x10ec0b00:
Kailang Yang65553b12017-07-11 15:15:47 +0800453 case 0x10ec1168:
Kailang Yanga535ad52017-01-16 16:59:26 +0800454 case 0x10ec1220:
Kailang Yang394c97f2014-11-12 17:38:08 +0800455 alc_update_coef_idx(codec, 0x7, 1<<1, 0);
456 break;
457 }
458}
459
Kailang Yangf9423e72008-05-27 12:32:25 +0200460/* additional initialization for ALC888 variants */
461static void alc888_coef_init(struct hda_codec *codec)
462{
Kailang Yang1df88742014-10-29 16:10:13 +0800463 switch (alc_get_coef0(codec) & 0x00f0) {
464 /* alc888-VA */
465 case 0x00:
466 /* alc888-VB */
467 case 0x10:
468 alc_update_coef_idx(codec, 7, 0, 0x2030); /* Turn EAPD to High */
469 break;
470 }
Jaroslav Kysela87a8c372009-07-23 10:58:29 +0200471}
472
Takashi Iwai3fb4a502010-01-19 15:46:37 +0100473/* turn on/off EAPD control (only if available) */
474static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
475{
476 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
477 return;
478 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
479 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
480 on ? 2 : 0);
481}
482
Takashi Iwai691f1fc2011-04-07 10:31:43 +0200483/* turn on/off EAPD controls of the codec */
484static void alc_auto_setup_eapd(struct hda_codec *codec, bool on)
485{
486 /* We currently only handle front, HP */
Michał Mirosławcaf3c042020-01-03 10:23:48 +0100487 static const hda_nid_t pins[] = {
Hui Wangaf95b412015-03-26 17:14:55 +0800488 0x0f, 0x10, 0x14, 0x15, 0x17, 0
Takashi Iwai39fa84e2011-06-27 15:28:57 +0200489 };
Michał Mirosławcaf3c042020-01-03 10:23:48 +0100490 const hda_nid_t *p;
Takashi Iwai39fa84e2011-06-27 15:28:57 +0200491 for (p = pins; *p; p++)
492 set_eapd(codec, *p, on);
Takashi Iwai691f1fc2011-04-07 10:31:43 +0200493}
494
Kailang Yangdad31972019-05-10 16:28:57 +0800495static int find_ext_mic_pin(struct hda_codec *codec);
496
497static void alc_headset_mic_no_shutup(struct hda_codec *codec)
498{
499 const struct hda_pincfg *pin;
500 int mic_pin = find_ext_mic_pin(codec);
501 int i;
502
503 /* don't shut up pins when unloading the driver; otherwise it breaks
504 * the default pin setup at the next load of the driver
505 */
506 if (codec->bus->shutdown)
507 return;
508
509 snd_array_for_each(&codec->init_pins, i, pin) {
510 /* use read here for syncing after issuing each verb */
511 if (pin->nid != mic_pin)
512 snd_hda_codec_read(codec, pin->nid, 0,
513 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
514 }
515
516 codec->pins_shutup = 1;
517}
518
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +0100519static void alc_shutup_pins(struct hda_codec *codec)
520{
521 struct alc_spec *spec = codec->spec;
522
Kailang Yangdad31972019-05-10 16:28:57 +0800523 switch (codec->core.vendor_id) {
Kailang Yang66c5d712019-12-09 15:56:15 +0800524 case 0x10ec0283:
Kailang Yangdad31972019-05-10 16:28:57 +0800525 case 0x10ec0286:
526 case 0x10ec0288:
527 case 0x10ec0298:
528 alc_headset_mic_no_shutup(codec);
529 break;
530 default:
531 if (!spec->no_shutup_pins)
532 snd_hda_shutup_pins(codec);
533 break;
534 }
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +0100535}
536
Takashi Iwai1c7161532011-04-07 10:37:16 +0200537/* generic shutup callback;
Lars-Peter Clausen4ce8e6a2016-11-08 15:48:06 +0100538 * just turning off EAPD and a little pause for avoiding pop-noise
Takashi Iwai1c7161532011-04-07 10:37:16 +0200539 */
540static void alc_eapd_shutup(struct hda_codec *codec)
541{
Kailang Yang97a26572013-11-29 00:35:26 -0500542 struct alc_spec *spec = codec->spec;
543
Takashi Iwai1c7161532011-04-07 10:37:16 +0200544 alc_auto_setup_eapd(codec, false);
Kailang Yang97a26572013-11-29 00:35:26 -0500545 if (!spec->no_depop_delay)
546 msleep(200);
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +0100547 alc_shutup_pins(codec);
Takashi Iwai1c7161532011-04-07 10:37:16 +0200548}
549
Takashi Iwai1d045db2011-07-07 18:23:21 +0200550/* generic EAPD initialization */
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200551static void alc_auto_init_amp(struct hda_codec *codec, int type)
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200552{
Takashi Iwai39fa84e2011-06-27 15:28:57 +0200553 alc_auto_setup_eapd(codec, true);
Takashi Iwai5579cd62018-06-19 22:22:41 +0200554 alc_write_gpio(codec);
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200555 switch (type) {
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200556 case ALC_INIT_DEFAULT:
Takashi Iwai7639a062015-03-03 10:07:24 +0100557 switch (codec->core.vendor_id) {
Kailang Yangc9b58002007-10-16 14:30:01 +0200558 case 0x10ec0260:
Takashi Iwai98b24882014-08-18 13:47:50 +0200559 alc_update_coefex_idx(codec, 0x1a, 7, 0, 0x2010);
Kailang Yangc9b58002007-10-16 14:30:01 +0200560 break;
Kailang Yangc9b58002007-10-16 14:30:01 +0200561 case 0x10ec0880:
562 case 0x10ec0882:
563 case 0x10ec0883:
564 case 0x10ec0885:
Kailang Yang1df88742014-10-29 16:10:13 +0800565 alc_update_coef_idx(codec, 7, 0, 0x2030);
Kailang Yangc9b58002007-10-16 14:30:01 +0200566 break;
Kailang Yangf9423e72008-05-27 12:32:25 +0200567 case 0x10ec0888:
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200568 alc888_coef_init(codec);
Kailang Yangf9423e72008-05-27 12:32:25 +0200569 break;
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200570 }
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200571 break;
572 }
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200573}
Kailang Yangea1fb292008-08-26 12:58:38 +0200574
Takashi Iwai35a39f92019-02-01 11:19:50 +0100575/* get a primary headphone pin if available */
576static hda_nid_t alc_get_hp_pin(struct alc_spec *spec)
577{
578 if (spec->gen.autocfg.hp_pins[0])
579 return spec->gen.autocfg.hp_pins[0];
580 if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
581 return spec->gen.autocfg.line_out_pins[0];
582 return 0;
583}
Takashi Iwai1d045db2011-07-07 18:23:21 +0200584
585/*
586 * Realtek SSID verification
587 */
588
David Henningsson90622912010-10-14 14:50:18 +0200589/* Could be any non-zero and even value. When used as fixup, tells
590 * the driver to ignore any present sku defines.
591 */
592#define ALC_FIXUP_SKU_IGNORE (2)
593
Takashi Iwai23d30f22012-05-07 17:17:32 +0200594static void alc_fixup_sku_ignore(struct hda_codec *codec,
595 const struct hda_fixup *fix, int action)
596{
597 struct alc_spec *spec = codec->spec;
598 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
599 spec->cdefine.fixup = 1;
600 spec->cdefine.sku_cfg = ALC_FIXUP_SKU_IGNORE;
601 }
602}
603
Mengdong Linb5c66112013-11-29 00:35:35 -0500604static void alc_fixup_no_depop_delay(struct hda_codec *codec,
605 const struct hda_fixup *fix, int action)
606{
607 struct alc_spec *spec = codec->spec;
608
Mengdong Lin84d2dc32013-12-02 22:26:03 -0500609 if (action == HDA_FIXUP_ACT_PROBE) {
Mengdong Linb5c66112013-11-29 00:35:35 -0500610 spec->no_depop_delay = 1;
Mengdong Lin84d2dc32013-12-02 22:26:03 -0500611 codec->depop_delay = 0;
612 }
Mengdong Linb5c66112013-11-29 00:35:35 -0500613}
614
Kailang Yangda00c242010-03-19 11:23:45 +0100615static int alc_auto_parse_customize_define(struct hda_codec *codec)
616{
617 unsigned int ass, tmp, i;
Takashi Iwai7fb56222010-03-22 17:09:47 +0100618 unsigned nid = 0;
Kailang Yangda00c242010-03-19 11:23:45 +0100619 struct alc_spec *spec = codec->spec;
620
Takashi Iwaib6cbe512010-07-28 17:43:36 +0200621 spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
622
David Henningsson90622912010-10-14 14:50:18 +0200623 if (spec->cdefine.fixup) {
624 ass = spec->cdefine.sku_cfg;
625 if (ass == ALC_FIXUP_SKU_IGNORE)
626 return -1;
627 goto do_sku;
628 }
629
Takashi Iwai5100cd02014-02-15 10:03:19 +0100630 if (!codec->bus->pci)
631 return -1;
Takashi Iwai7639a062015-03-03 10:07:24 +0100632 ass = codec->core.subsystem_id & 0xffff;
Takashi Iwaib6cbe512010-07-28 17:43:36 +0200633 if (ass != codec->bus->pci->subsystem_device && (ass & 1))
Kailang Yangda00c242010-03-19 11:23:45 +0100634 goto do_sku;
635
636 nid = 0x1d;
Takashi Iwai7639a062015-03-03 10:07:24 +0100637 if (codec->core.vendor_id == 0x10ec0260)
Kailang Yangda00c242010-03-19 11:23:45 +0100638 nid = 0x17;
639 ass = snd_hda_codec_get_pincfg(codec, nid);
640
641 if (!(ass & 1)) {
Takashi Iwai4e76a882014-02-25 12:21:03 +0100642 codec_info(codec, "%s: SKU not ready 0x%08x\n",
Takashi Iwai7639a062015-03-03 10:07:24 +0100643 codec->core.chip_name, ass);
Kailang Yangda00c242010-03-19 11:23:45 +0100644 return -1;
645 }
646
647 /* check sum */
648 tmp = 0;
649 for (i = 1; i < 16; i++) {
650 if ((ass >> i) & 1)
651 tmp++;
652 }
653 if (((ass >> 16) & 0xf) != tmp)
654 return -1;
655
656 spec->cdefine.port_connectivity = ass >> 30;
657 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
658 spec->cdefine.check_sum = (ass >> 16) & 0xf;
659 spec->cdefine.customization = ass >> 8;
660do_sku:
661 spec->cdefine.sku_cfg = ass;
662 spec->cdefine.external_amp = (ass & 0x38) >> 3;
663 spec->cdefine.platform_type = (ass & 0x4) >> 2;
664 spec->cdefine.swap = (ass & 0x2) >> 1;
665 spec->cdefine.override = ass & 0x1;
666
Takashi Iwai4e76a882014-02-25 12:21:03 +0100667 codec_dbg(codec, "SKU: Nid=0x%x sku_cfg=0x%08x\n",
Kailang Yangda00c242010-03-19 11:23:45 +0100668 nid, spec->cdefine.sku_cfg);
Takashi Iwai4e76a882014-02-25 12:21:03 +0100669 codec_dbg(codec, "SKU: port_connectivity=0x%x\n",
Kailang Yangda00c242010-03-19 11:23:45 +0100670 spec->cdefine.port_connectivity);
Takashi Iwai4e76a882014-02-25 12:21:03 +0100671 codec_dbg(codec, "SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
672 codec_dbg(codec, "SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
673 codec_dbg(codec, "SKU: customization=0x%08x\n", spec->cdefine.customization);
674 codec_dbg(codec, "SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
675 codec_dbg(codec, "SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
676 codec_dbg(codec, "SKU: swap=0x%x\n", spec->cdefine.swap);
677 codec_dbg(codec, "SKU: override=0x%x\n", spec->cdefine.override);
Kailang Yangda00c242010-03-19 11:23:45 +0100678
679 return 0;
680}
681
Takashi Iwai08c189f2012-12-19 15:22:24 +0100682/* return the position of NID in the list, or -1 if not found */
683static int find_idx_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
684{
685 int i;
686 for (i = 0; i < nums; i++)
687 if (list[i] == nid)
688 return i;
689 return -1;
690}
Takashi Iwai1d045db2011-07-07 18:23:21 +0200691/* return true if the given NID is found in the list */
Takashi Iwai3af9ee62011-06-27 12:34:01 +0200692static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
693{
Takashi Iwai21268962011-07-07 15:01:13 +0200694 return find_idx_in_nid_list(nid, list, nums) >= 0;
Takashi Iwai3af9ee62011-06-27 12:34:01 +0200695}
696
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200697/* check subsystem ID and set up device-specific initialization;
698 * return 1 if initialized, 0 if invalid SSID
699 */
700/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
701 * 31 ~ 16 : Manufacture ID
702 * 15 ~ 8 : SKU ID
703 * 7 ~ 0 : Assembly ID
704 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
705 */
Takashi Iwai58c57cf2014-01-07 18:22:49 +0100706static int alc_subsystem_id(struct hda_codec *codec, const hda_nid_t *ports)
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200707{
708 unsigned int ass, tmp, i;
709 unsigned nid;
710 struct alc_spec *spec = codec->spec;
711
David Henningsson90622912010-10-14 14:50:18 +0200712 if (spec->cdefine.fixup) {
713 ass = spec->cdefine.sku_cfg;
714 if (ass == ALC_FIXUP_SKU_IGNORE)
715 return 0;
716 goto do_sku;
717 }
718
Takashi Iwai7639a062015-03-03 10:07:24 +0100719 ass = codec->core.subsystem_id & 0xffff;
Takashi Iwai5100cd02014-02-15 10:03:19 +0100720 if (codec->bus->pci &&
721 ass != codec->bus->pci->subsystem_device && (ass & 1))
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200722 goto do_sku;
723
724 /* invalid SSID, check the special NID pin defcfg instead */
725 /*
Sasha Alexandrdef319f2009-06-16 16:00:15 -0400726 * 31~30 : port connectivity
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200727 * 29~21 : reserve
728 * 20 : PCBEEP input
729 * 19~16 : Check sum (15:1)
730 * 15~1 : Custom
731 * 0 : override
732 */
733 nid = 0x1d;
Takashi Iwai7639a062015-03-03 10:07:24 +0100734 if (codec->core.vendor_id == 0x10ec0260)
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200735 nid = 0x17;
736 ass = snd_hda_codec_get_pincfg(codec, nid);
Takashi Iwai4e76a882014-02-25 12:21:03 +0100737 codec_dbg(codec,
738 "realtek: No valid SSID, checking pincfg 0x%08x for NID 0x%x\n",
Takashi Iwaicb6605c2009-04-28 13:03:19 +0200739 ass, nid);
Kailang Yang6227cdc2010-02-25 08:36:52 +0100740 if (!(ass & 1))
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200741 return 0;
742 if ((ass >> 30) != 1) /* no physical connection */
743 return 0;
744
745 /* check sum */
746 tmp = 0;
747 for (i = 1; i < 16; i++) {
748 if ((ass >> i) & 1)
749 tmp++;
750 }
751 if (((ass >> 16) & 0xf) != tmp)
752 return 0;
753do_sku:
Takashi Iwai4e76a882014-02-25 12:21:03 +0100754 codec_dbg(codec, "realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
Takashi Iwai7639a062015-03-03 10:07:24 +0100755 ass & 0xffff, codec->core.vendor_id);
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200756 /*
757 * 0 : override
758 * 1 : Swap Jack
759 * 2 : 0 --> Desktop, 1 --> Laptop
760 * 3~5 : External Amplifier control
761 * 7~6 : Reserved
762 */
763 tmp = (ass & 0x38) >> 3; /* external Amp control */
Takashi Iwai1c76aa52018-06-21 16:37:54 +0200764 if (spec->init_amp == ALC_INIT_UNDEFINED) {
765 switch (tmp) {
766 case 1:
Takashi Iwai5579cd62018-06-19 22:22:41 +0200767 alc_setup_gpio(codec, 0x01);
Takashi Iwai1c76aa52018-06-21 16:37:54 +0200768 break;
769 case 3:
Takashi Iwai5579cd62018-06-19 22:22:41 +0200770 alc_setup_gpio(codec, 0x02);
Takashi Iwai1c76aa52018-06-21 16:37:54 +0200771 break;
772 case 7:
Takashi Iwai5579cd62018-06-19 22:22:41 +0200773 alc_setup_gpio(codec, 0x03);
Takashi Iwai1c76aa52018-06-21 16:37:54 +0200774 break;
775 case 5:
776 default:
777 spec->init_amp = ALC_INIT_DEFAULT;
778 break;
779 }
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200780 }
781
782 /* is laptop or Desktop and enable the function "Mute internal speaker
783 * when the external headphone out jack is plugged"
784 */
785 if (!(ass & 0x8000))
786 return 1;
787 /*
788 * 10~8 : Jack location
789 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
790 * 14~13: Resvered
791 * 15 : 1 --> enable the function "Mute internal speaker
792 * when the external headphone out jack is plugged"
793 */
Takashi Iwai35a39f92019-02-01 11:19:50 +0100794 if (!alc_get_hp_pin(spec)) {
Takashi Iwai01d48252009-10-06 13:21:54 +0200795 hda_nid_t nid;
Kailang Yangc9b58002007-10-16 14:30:01 +0200796 tmp = (ass >> 11) & 0x3; /* HP to chassis */
Takashi Iwai58c57cf2014-01-07 18:22:49 +0100797 nid = ports[tmp];
Takashi Iwai08c189f2012-12-19 15:22:24 +0100798 if (found_in_nid_list(nid, spec->gen.autocfg.line_out_pins,
799 spec->gen.autocfg.line_outs))
Takashi Iwai3af9ee62011-06-27 12:34:01 +0200800 return 1;
Takashi Iwai08c189f2012-12-19 15:22:24 +0100801 spec->gen.autocfg.hp_pins[0] = nid;
Kailang Yangc9b58002007-10-16 14:30:01 +0200802 }
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200803 return 1;
804}
Kailang Yangea1fb292008-08-26 12:58:38 +0200805
Takashi Iwai3e6179b2011-07-08 16:55:13 +0200806/* Check the validity of ALC subsystem-id
807 * ports contains an array of 4 pin NIDs for port-A, E, D and I */
808static void alc_ssid_check(struct hda_codec *codec, const hda_nid_t *ports)
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200809{
Takashi Iwai58c57cf2014-01-07 18:22:49 +0100810 if (!alc_subsystem_id(codec, ports)) {
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200811 struct alc_spec *spec = codec->spec;
Takashi Iwai67791202020-04-18 21:06:39 +0200812 if (spec->init_amp == ALC_INIT_UNDEFINED) {
813 codec_dbg(codec,
814 "realtek: Enable default setup for auto mode as fallback\n");
815 spec->init_amp = ALC_INIT_DEFAULT;
816 }
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200817 }
Takashi Iwai21268962011-07-07 15:01:13 +0200818}
Takashi Iwai1a1455d2011-04-28 17:36:18 +0200819
Takashi Iwai41e41f12005-06-08 14:48:49 +0200820/*
Takashi Iwai1d045db2011-07-07 18:23:21 +0200821 */
822
David Henningsson9d36a7d2014-10-07 10:18:42 +0200823static void alc_fixup_inv_dmic(struct hda_codec *codec,
824 const struct hda_fixup *fix, int action)
Takashi Iwai125821a2012-06-22 14:30:29 +0200825{
826 struct alc_spec *spec = codec->spec;
Takashi Iwai668d1e92012-11-29 14:10:17 +0100827
David Henningsson9d36a7d2014-10-07 10:18:42 +0200828 spec->gen.inv_dmic_split = 1;
Takashi Iwai6e72aa52012-06-25 10:52:25 +0200829}
830
Takashi Iwai603c4012008-07-30 15:01:44 +0200831
Takashi Iwai2eab6942012-12-18 15:30:41 +0100832static int alc_build_controls(struct hda_codec *codec)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700833{
Takashi Iwaia5cb4632018-06-20 12:50:11 +0200834 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700835
Takashi Iwai08c189f2012-12-19 15:22:24 +0100836 err = snd_hda_gen_build_controls(codec);
837 if (err < 0)
838 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700839
Takashi Iwai1727a772013-01-10 09:52:52 +0100840 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_BUILD);
Takashi Iwai420b0fe2012-03-12 12:35:27 +0100841 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700842}
843
Takashi Iwaie9edcee2005-06-13 14:16:38 +0200844
Linus Torvalds1da177e2005-04-16 15:20:36 -0700845/*
Takashi Iwaiae6b8132006-03-03 16:47:17 +0100846 * Common callbacks
Takashi Iwaie9edcee2005-06-13 14:16:38 +0200847 */
Takashi Iwai16ded522005-06-10 19:58:24 +0200848
Takashi Iwaic9af7532019-05-10 11:01:43 +0200849static void alc_pre_init(struct hda_codec *codec)
850{
851 alc_fill_eapd_coef(codec);
852}
853
Kailang Yangaeac1a02019-05-16 16:10:44 +0800854#define is_s3_resume(codec) \
855 ((codec)->core.dev.power.power_state.event == PM_EVENT_RESUME)
Takashi Iwaic9af7532019-05-10 11:01:43 +0200856#define is_s4_resume(codec) \
857 ((codec)->core.dev.power.power_state.event == PM_EVENT_RESTORE)
858
Linus Torvalds1da177e2005-04-16 15:20:36 -0700859static int alc_init(struct hda_codec *codec)
860{
861 struct alc_spec *spec = codec->spec;
Takashi Iwaie9edcee2005-06-13 14:16:38 +0200862
Takashi Iwaic9af7532019-05-10 11:01:43 +0200863 /* hibernation resume needs the full chip initialization */
864 if (is_s4_resume(codec))
865 alc_pre_init(codec);
866
Takashi Iwai546bb672012-03-07 08:37:19 +0100867 if (spec->init_hook)
868 spec->init_hook(codec);
Kailang Yang526af6e2012-03-07 08:25:20 +0100869
Takashi Iwai89781d02019-08-30 12:03:38 +0200870 spec->gen.skip_verbs = 1; /* applied in below */
Kailang Yang607ca3b2019-04-26 16:35:41 +0800871 snd_hda_gen_init(codec);
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200872 alc_fix_pll(codec);
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200873 alc_auto_init_amp(codec, spec->init_amp);
Takashi Iwai89781d02019-08-30 12:03:38 +0200874 snd_hda_apply_verbs(codec); /* apply verbs here after own init */
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200875
Takashi Iwai1727a772013-01-10 09:52:52 +0100876 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_INIT);
Takashi Iwaie08a0072006-09-07 17:52:14 +0200877
Linus Torvalds1da177e2005-04-16 15:20:36 -0700878 return 0;
879}
880
Takashi Iwaia4e09aa2009-12-27 11:22:24 +0100881static inline void alc_shutup(struct hda_codec *codec)
882{
Takashi Iwai1c7161532011-04-07 10:37:16 +0200883 struct alc_spec *spec = codec->spec;
884
Takashi Iwaic7273bd2018-06-12 16:09:57 +0200885 if (!snd_hda_get_bool_hint(codec, "shutup"))
886 return; /* disabled explicitly by hints */
887
Takashi Iwai1c7161532011-04-07 10:37:16 +0200888 if (spec && spec->shutup)
889 spec->shutup(codec);
Takashi Iwai9bfb2842013-07-24 14:31:50 +0200890 else
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +0100891 alc_shutup_pins(codec);
Takashi Iwaia4e09aa2009-12-27 11:22:24 +0100892}
893
Takashi Iwai70a09762015-12-15 14:59:58 +0100894static void alc_reboot_notify(struct hda_codec *codec)
895{
896 struct alc_spec *spec = codec->spec;
897
898 if (spec && spec->reboot_notify)
899 spec->reboot_notify(codec);
900 else
901 alc_shutup(codec);
902}
903
Takashi Iwai8a02c0c2014-02-10 18:09:45 +0100904#define alc_free snd_hda_gen_free
Linus Torvalds1da177e2005-04-16 15:20:36 -0700905
Takashi Iwai83012a72012-08-24 18:38:08 +0200906#ifdef CONFIG_PM
Daniel T Chenc97259d2009-12-27 18:52:08 -0500907static void alc_power_eapd(struct hda_codec *codec)
908{
Takashi Iwai691f1fc2011-04-07 10:31:43 +0200909 alc_auto_setup_eapd(codec, false);
Daniel T Chenc97259d2009-12-27 18:52:08 -0500910}
911
Takashi Iwai68cb2b52012-07-02 15:20:37 +0200912static int alc_suspend(struct hda_codec *codec)
Hector Martinf5de24b2009-12-20 22:51:31 +0100913{
914 struct alc_spec *spec = codec->spec;
Takashi Iwaia4e09aa2009-12-27 11:22:24 +0100915 alc_shutup(codec);
Hector Martinf5de24b2009-12-20 22:51:31 +0100916 if (spec && spec->power_hook)
Daniel T Chenc97259d2009-12-27 18:52:08 -0500917 spec->power_hook(codec);
Hector Martinf5de24b2009-12-20 22:51:31 +0100918 return 0;
919}
920#endif
921
Takashi Iwai2a439522011-07-26 09:52:50 +0200922#ifdef CONFIG_PM
Takashi Iwaie044c392008-10-27 16:56:24 +0100923static int alc_resume(struct hda_codec *codec)
924{
Kailang Yang97a26572013-11-29 00:35:26 -0500925 struct alc_spec *spec = codec->spec;
926
927 if (!spec->no_depop_delay)
928 msleep(150); /* to avoid pop noise */
Takashi Iwaie044c392008-10-27 16:56:24 +0100929 codec->patch_ops.init(codec);
Takashi Iwai1a462be2020-01-09 10:01:04 +0100930 snd_hda_regmap_sync(codec);
Takashi Iwai9e5341b2010-09-21 09:57:06 +0200931 hda_call_check_power_status(codec, 0x01);
Takashi Iwaie044c392008-10-27 16:56:24 +0100932 return 0;
933}
Takashi Iwaie044c392008-10-27 16:56:24 +0100934#endif
935
Linus Torvalds1da177e2005-04-16 15:20:36 -0700936/*
937 */
Takashi Iwaia9111322011-05-02 11:30:18 +0200938static const struct hda_codec_ops alc_patch_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700939 .build_controls = alc_build_controls,
Takashi Iwai08c189f2012-12-19 15:22:24 +0100940 .build_pcms = snd_hda_gen_build_pcms,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700941 .init = alc_init,
942 .free = alc_free,
David Henningsson29adc4b2012-09-25 11:31:00 +0200943 .unsol_event = snd_hda_jack_unsol_event,
Takashi Iwai2a439522011-07-26 09:52:50 +0200944#ifdef CONFIG_PM
Takashi Iwaie044c392008-10-27 16:56:24 +0100945 .resume = alc_resume,
Hector Martinf5de24b2009-12-20 22:51:31 +0100946 .suspend = alc_suspend,
Takashi Iwaifce52a32013-01-07 12:42:48 +0100947 .check_power_status = snd_hda_gen_check_power_status,
Takashi Iwaicb53c622007-08-10 17:21:45 +0200948#endif
Takashi Iwai70a09762015-12-15 14:59:58 +0100949 .reboot_notify = alc_reboot_notify,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700950};
951
David Henningsson29adc4b2012-09-25 11:31:00 +0200952
Takashi Iwaided255b2015-10-01 17:59:43 +0200953#define alc_codec_rename(codec, name) snd_hda_codec_set_name(codec, name)
Kailang Yangc027ddc2010-03-19 11:33:06 +0100954
Takashi Iwai2fa522b2005-05-12 14:51:12 +0200955/*
Kailang Yang4b016932013-11-28 11:55:09 +0100956 * Rename codecs appropriately from COEF value or subvendor id
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200957 */
958struct alc_codec_rename_table {
959 unsigned int vendor_id;
960 unsigned short coef_mask;
961 unsigned short coef_bits;
962 const char *name;
963};
964
Kailang Yang4b016932013-11-28 11:55:09 +0100965struct alc_codec_rename_pci_table {
966 unsigned int codec_vendor_id;
967 unsigned short pci_subvendor;
968 unsigned short pci_subdevice;
969 const char *name;
970};
971
Takashi Iwai6b0f95c2020-01-05 15:47:18 +0100972static const struct alc_codec_rename_table rename_tbl[] = {
Kailang Yange6e5f7a2014-06-06 16:46:43 +0800973 { 0x10ec0221, 0xf00f, 0x1003, "ALC231" },
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200974 { 0x10ec0269, 0xfff0, 0x3010, "ALC277" },
975 { 0x10ec0269, 0xf0f0, 0x2010, "ALC259" },
976 { 0x10ec0269, 0xf0f0, 0x3010, "ALC258" },
977 { 0x10ec0269, 0x00f0, 0x0010, "ALC269VB" },
978 { 0x10ec0269, 0xffff, 0xa023, "ALC259" },
979 { 0x10ec0269, 0xffff, 0x6023, "ALC281X" },
980 { 0x10ec0269, 0x00f0, 0x0020, "ALC269VC" },
Kailang Yangadcc70b2012-05-25 08:08:38 +0200981 { 0x10ec0269, 0x00f0, 0x0030, "ALC269VD" },
Kailang Yange6e5f7a2014-06-06 16:46:43 +0800982 { 0x10ec0662, 0xffff, 0x4020, "ALC656" },
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200983 { 0x10ec0887, 0x00f0, 0x0030, "ALC887-VD" },
984 { 0x10ec0888, 0x00f0, 0x0030, "ALC888-VD" },
985 { 0x10ec0888, 0xf0f0, 0x3020, "ALC886" },
986 { 0x10ec0899, 0x2000, 0x2000, "ALC899" },
987 { 0x10ec0892, 0xffff, 0x8020, "ALC661" },
988 { 0x10ec0892, 0xffff, 0x8011, "ALC661" },
989 { 0x10ec0892, 0xffff, 0x4011, "ALC656" },
990 { } /* terminator */
991};
992
Takashi Iwai6b0f95c2020-01-05 15:47:18 +0100993static const struct alc_codec_rename_pci_table rename_pci_tbl[] = {
Kailang Yang4b016932013-11-28 11:55:09 +0100994 { 0x10ec0280, 0x1028, 0, "ALC3220" },
995 { 0x10ec0282, 0x1028, 0, "ALC3221" },
996 { 0x10ec0283, 0x1028, 0, "ALC3223" },
Kailang Yang193177d2014-04-23 16:06:13 +0800997 { 0x10ec0288, 0x1028, 0, "ALC3263" },
Kailang Yang4b016932013-11-28 11:55:09 +0100998 { 0x10ec0292, 0x1028, 0, "ALC3226" },
Kailang Yang193177d2014-04-23 16:06:13 +0800999 { 0x10ec0293, 0x1028, 0, "ALC3235" },
Kailang Yang4b016932013-11-28 11:55:09 +01001000 { 0x10ec0255, 0x1028, 0, "ALC3234" },
1001 { 0x10ec0668, 0x1028, 0, "ALC3661" },
Kailang Yange6e5f7a2014-06-06 16:46:43 +08001002 { 0x10ec0275, 0x1028, 0, "ALC3260" },
1003 { 0x10ec0899, 0x1028, 0, "ALC3861" },
Kailang Yang2c674fa2015-05-05 15:02:42 +08001004 { 0x10ec0298, 0x1028, 0, "ALC3266" },
Kailang Yang736f20a2017-10-20 15:06:34 +08001005 { 0x10ec0236, 0x1028, 0, "ALC3204" },
Kailang Yang82324502015-05-25 17:16:49 +08001006 { 0x10ec0256, 0x1028, 0, "ALC3246" },
Kailang Yang42314302016-02-03 15:03:50 +08001007 { 0x10ec0225, 0x1028, 0, "ALC3253" },
Kailang Yang7d727862016-05-24 16:46:07 +08001008 { 0x10ec0295, 0x1028, 0, "ALC3254" },
Kailang Yang28f1f9b2017-01-04 14:49:07 +08001009 { 0x10ec0299, 0x1028, 0, "ALC3271" },
Kailang Yange6e5f7a2014-06-06 16:46:43 +08001010 { 0x10ec0670, 0x1025, 0, "ALC669X" },
1011 { 0x10ec0676, 0x1025, 0, "ALC679X" },
1012 { 0x10ec0282, 0x1043, 0, "ALC3229" },
1013 { 0x10ec0233, 0x1043, 0, "ALC3236" },
1014 { 0x10ec0280, 0x103c, 0, "ALC3228" },
1015 { 0x10ec0282, 0x103c, 0, "ALC3227" },
1016 { 0x10ec0286, 0x103c, 0, "ALC3242" },
1017 { 0x10ec0290, 0x103c, 0, "ALC3241" },
1018 { 0x10ec0668, 0x103c, 0, "ALC3662" },
1019 { 0x10ec0283, 0x17aa, 0, "ALC3239" },
1020 { 0x10ec0292, 0x17aa, 0, "ALC3232" },
Kailang Yang4b016932013-11-28 11:55:09 +01001021 { } /* terminator */
1022};
1023
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02001024static int alc_codec_rename_from_preset(struct hda_codec *codec)
1025{
1026 const struct alc_codec_rename_table *p;
Kailang Yang4b016932013-11-28 11:55:09 +01001027 const struct alc_codec_rename_pci_table *q;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02001028
1029 for (p = rename_tbl; p->vendor_id; p++) {
Takashi Iwai7639a062015-03-03 10:07:24 +01001030 if (p->vendor_id != codec->core.vendor_id)
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02001031 continue;
Takashi Iwai1bb7e432011-10-17 16:50:59 +02001032 if ((alc_get_coef0(codec) & p->coef_mask) == p->coef_bits)
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02001033 return alc_codec_rename(codec, p->name);
1034 }
Kailang Yang4b016932013-11-28 11:55:09 +01001035
Takashi Iwai5100cd02014-02-15 10:03:19 +01001036 if (!codec->bus->pci)
1037 return 0;
Kailang Yang4b016932013-11-28 11:55:09 +01001038 for (q = rename_pci_tbl; q->codec_vendor_id; q++) {
Takashi Iwai7639a062015-03-03 10:07:24 +01001039 if (q->codec_vendor_id != codec->core.vendor_id)
Kailang Yang4b016932013-11-28 11:55:09 +01001040 continue;
1041 if (q->pci_subvendor != codec->bus->pci->subsystem_vendor)
1042 continue;
1043 if (!q->pci_subdevice ||
1044 q->pci_subdevice == codec->bus->pci->subsystem_device)
1045 return alc_codec_rename(codec, q->name);
1046 }
1047
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02001048 return 0;
1049}
1050
Takashi Iwaie4770622011-07-08 11:11:35 +02001051
1052/*
Takashi Iwai1d045db2011-07-07 18:23:21 +02001053 * Digital-beep handlers
1054 */
1055#ifdef CONFIG_SND_HDA_INPUT_BEEP
Takashi Iwaifea80fa2018-06-20 12:52:46 +02001056
1057/* additional beep mixers; private_value will be overwritten */
1058static const struct snd_kcontrol_new alc_beep_mixer[] = {
1059 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
1060 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
1061};
1062
1063/* set up and create beep controls */
1064static int set_beep_amp(struct alc_spec *spec, hda_nid_t nid,
1065 int idx, int dir)
1066{
1067 struct snd_kcontrol_new *knew;
1068 unsigned int beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir);
1069 int i;
1070
1071 for (i = 0; i < ARRAY_SIZE(alc_beep_mixer); i++) {
1072 knew = snd_hda_gen_add_kctl(&spec->gen, NULL,
1073 &alc_beep_mixer[i]);
1074 if (!knew)
1075 return -ENOMEM;
1076 knew->private_value = beep_amp;
1077 }
1078 return 0;
1079}
Takashi Iwai1d045db2011-07-07 18:23:21 +02001080
Takashi Iwai6317e5e2020-07-14 19:26:27 +02001081static const struct snd_pci_quirk beep_allow_list[] = {
Duncan Roe71100052012-10-10 14:19:50 +02001082 SND_PCI_QUIRK(0x1043, 0x103c, "ASUS", 1),
W. Trevor Kinga4b7f21d2014-03-29 17:47:24 -07001083 SND_PCI_QUIRK(0x1043, 0x115d, "ASUS", 1),
Takashi Iwai1d045db2011-07-07 18:23:21 +02001084 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
Takashi Iwai8554ee42013-02-25 09:54:43 +01001085 SND_PCI_QUIRK(0x1043, 0x8376, "EeePC", 1),
Takashi Iwai1d045db2011-07-07 18:23:21 +02001086 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
1087 SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1),
1088 SND_PCI_QUIRK(0x1043, 0x834a, "EeePC", 1),
Takashi Iwai78f8baf2012-03-06 14:02:32 +01001089 SND_PCI_QUIRK(0x1458, 0xa002, "GA-MA790X", 1),
Takashi Iwai1d045db2011-07-07 18:23:21 +02001090 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
Takashi Iwai6317e5e2020-07-14 19:26:27 +02001091 /* denylist -- no beep available */
Takashi Iwai051c78a2019-08-22 09:58:07 +02001092 SND_PCI_QUIRK(0x17aa, 0x309e, "Lenovo ThinkCentre M73", 0),
1093 SND_PCI_QUIRK(0x17aa, 0x30a3, "Lenovo ThinkCentre M93", 0),
Takashi Iwai1d045db2011-07-07 18:23:21 +02001094 {}
1095};
1096
1097static inline int has_cdefine_beep(struct hda_codec *codec)
1098{
1099 struct alc_spec *spec = codec->spec;
1100 const struct snd_pci_quirk *q;
Takashi Iwai6317e5e2020-07-14 19:26:27 +02001101 q = snd_pci_quirk_lookup(codec->bus->pci, beep_allow_list);
Takashi Iwai1d045db2011-07-07 18:23:21 +02001102 if (q)
1103 return q->value;
1104 return spec->cdefine.enable_pcbeep;
1105}
1106#else
Takashi Iwaifea80fa2018-06-20 12:52:46 +02001107#define set_beep_amp(spec, nid, idx, dir) 0
Takashi Iwai1d045db2011-07-07 18:23:21 +02001108#define has_cdefine_beep(codec) 0
1109#endif
1110
1111/* parse the BIOS configuration and set up the alc_spec */
1112/* return 1 if successful, 0 if the proper config is not found,
1113 * or a negative error code
1114 */
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001115static int alc_parse_auto_config(struct hda_codec *codec,
1116 const hda_nid_t *ignore_nids,
1117 const hda_nid_t *ssid_nids)
Takashi Iwai1d045db2011-07-07 18:23:21 +02001118{
1119 struct alc_spec *spec = codec->spec;
Takashi Iwai08c189f2012-12-19 15:22:24 +01001120 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001121 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001122
Takashi Iwai53c334a2011-08-23 18:27:14 +02001123 err = snd_hda_parse_pin_defcfg(codec, cfg, ignore_nids,
1124 spec->parse_flags);
Takashi Iwai1d045db2011-07-07 18:23:21 +02001125 if (err < 0)
1126 return err;
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001127
1128 if (ssid_nids)
1129 alc_ssid_check(codec, ssid_nids);
1130
Takashi Iwai08c189f2012-12-19 15:22:24 +01001131 err = snd_hda_gen_parse_auto_config(codec, cfg);
1132 if (err < 0)
1133 return err;
Takashi Iwai070cff42012-02-21 12:54:17 +01001134
Takashi Iwai1d045db2011-07-07 18:23:21 +02001135 return 1;
1136}
1137
Takashi Iwai3de95172012-05-07 18:03:15 +02001138/* common preparation job for alc_spec */
1139static int alc_alloc_spec(struct hda_codec *codec, hda_nid_t mixer_nid)
1140{
1141 struct alc_spec *spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1142 int err;
1143
1144 if (!spec)
1145 return -ENOMEM;
1146 codec->spec = spec;
Takashi Iwai08c189f2012-12-19 15:22:24 +01001147 snd_hda_gen_spec_init(&spec->gen);
1148 spec->gen.mixer_nid = mixer_nid;
1149 spec->gen.own_eapd_ctl = 1;
Takashi Iwai1098b7c2012-12-17 20:03:15 +01001150 codec->single_adc_amp = 1;
Takashi Iwai08c189f2012-12-19 15:22:24 +01001151 /* FIXME: do we need this for all Realtek codec models? */
1152 codec->spdif_status_reset = 1;
Takashi Iwai225068a2015-05-29 10:42:14 +02001153 codec->patch_ops = alc_patch_ops;
Takashi Iwai3de95172012-05-07 18:03:15 +02001154
1155 err = alc_codec_rename_from_preset(codec);
1156 if (err < 0) {
1157 kfree(spec);
1158 return err;
1159 }
1160 return 0;
1161}
1162
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001163static int alc880_parse_auto_config(struct hda_codec *codec)
1164{
1165 static const hda_nid_t alc880_ignore[] = { 0x1d, 0 };
Jesper Juhl7d7eb9e2012-04-12 22:11:25 +02001166 static const hda_nid_t alc880_ssids[] = { 0x15, 0x1b, 0x14, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001167 return alc_parse_auto_config(codec, alc880_ignore, alc880_ssids);
1168}
1169
Takashi Iwai1d045db2011-07-07 18:23:21 +02001170/*
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001171 * ALC880 fix-ups
1172 */
1173enum {
Takashi Iwai411225a2012-02-20 17:48:19 +01001174 ALC880_FIXUP_GPIO1,
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001175 ALC880_FIXUP_GPIO2,
1176 ALC880_FIXUP_MEDION_RIM,
Takashi Iwaidc6af522012-02-17 16:18:59 +01001177 ALC880_FIXUP_LG,
Takashi Iwaidb8a38e2013-08-09 12:34:42 +02001178 ALC880_FIXUP_LG_LW25,
Takashi Iwaif02aab52012-02-17 16:33:56 +01001179 ALC880_FIXUP_W810,
Takashi Iwai27e917f2012-02-17 17:49:54 +01001180 ALC880_FIXUP_EAPD_COEF,
Takashi Iwaib9368f52012-02-17 17:54:44 +01001181 ALC880_FIXUP_TCL_S700,
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001182 ALC880_FIXUP_VOL_KNOB,
1183 ALC880_FIXUP_FUJITSU,
Takashi Iwaiba533812012-02-20 16:36:52 +01001184 ALC880_FIXUP_F1734,
Takashi Iwai817de922012-02-20 17:20:48 +01001185 ALC880_FIXUP_UNIWILL,
Takashi Iwai967b88c2012-02-20 17:31:02 +01001186 ALC880_FIXUP_UNIWILL_DIG,
Takashi Iwai96e225f2012-02-20 17:41:51 +01001187 ALC880_FIXUP_Z71V,
Takashi Iwai487a5882013-11-07 07:29:30 +01001188 ALC880_FIXUP_ASUS_W5A,
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001189 ALC880_FIXUP_3ST_BASE,
1190 ALC880_FIXUP_3ST,
1191 ALC880_FIXUP_3ST_DIG,
1192 ALC880_FIXUP_5ST_BASE,
1193 ALC880_FIXUP_5ST,
1194 ALC880_FIXUP_5ST_DIG,
1195 ALC880_FIXUP_6ST_BASE,
1196 ALC880_FIXUP_6ST,
1197 ALC880_FIXUP_6ST_DIG,
Takashi Iwai53971452013-01-23 18:21:37 +01001198 ALC880_FIXUP_6ST_AUTOMUTE,
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001199};
1200
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001201/* enable the volume-knob widget support on NID 0x21 */
1202static void alc880_fixup_vol_knob(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001203 const struct hda_fixup *fix, int action)
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001204{
Takashi Iwai1727a772013-01-10 09:52:52 +01001205 if (action == HDA_FIXUP_ACT_PROBE)
Takashi Iwai62f949b2014-09-11 14:06:53 +02001206 snd_hda_jack_detect_enable_callback(codec, 0x21,
1207 alc_update_knob_master);
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001208}
1209
Takashi Iwai1727a772013-01-10 09:52:52 +01001210static const struct hda_fixup alc880_fixups[] = {
Takashi Iwai411225a2012-02-20 17:48:19 +01001211 [ALC880_FIXUP_GPIO1] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02001212 .type = HDA_FIXUP_FUNC,
1213 .v.func = alc_fixup_gpio1,
Takashi Iwai411225a2012-02-20 17:48:19 +01001214 },
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001215 [ALC880_FIXUP_GPIO2] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02001216 .type = HDA_FIXUP_FUNC,
1217 .v.func = alc_fixup_gpio2,
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001218 },
1219 [ALC880_FIXUP_MEDION_RIM] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001220 .type = HDA_FIXUP_VERBS,
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001221 .v.verbs = (const struct hda_verb[]) {
1222 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
1223 { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
1224 { }
1225 },
1226 .chained = true,
1227 .chain_id = ALC880_FIXUP_GPIO2,
1228 },
Takashi Iwaidc6af522012-02-17 16:18:59 +01001229 [ALC880_FIXUP_LG] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001230 .type = HDA_FIXUP_PINS,
1231 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaidc6af522012-02-17 16:18:59 +01001232 /* disable bogus unused pins */
1233 { 0x16, 0x411111f0 },
1234 { 0x18, 0x411111f0 },
1235 { 0x1a, 0x411111f0 },
1236 { }
1237 }
1238 },
Takashi Iwaidb8a38e2013-08-09 12:34:42 +02001239 [ALC880_FIXUP_LG_LW25] = {
1240 .type = HDA_FIXUP_PINS,
1241 .v.pins = (const struct hda_pintbl[]) {
1242 { 0x1a, 0x0181344f }, /* line-in */
1243 { 0x1b, 0x0321403f }, /* headphone */
1244 { }
1245 }
1246 },
Takashi Iwaif02aab52012-02-17 16:33:56 +01001247 [ALC880_FIXUP_W810] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001248 .type = HDA_FIXUP_PINS,
1249 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaif02aab52012-02-17 16:33:56 +01001250 /* disable bogus unused pins */
1251 { 0x17, 0x411111f0 },
1252 { }
1253 },
1254 .chained = true,
1255 .chain_id = ALC880_FIXUP_GPIO2,
1256 },
Takashi Iwai27e917f2012-02-17 17:49:54 +01001257 [ALC880_FIXUP_EAPD_COEF] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001258 .type = HDA_FIXUP_VERBS,
Takashi Iwai27e917f2012-02-17 17:49:54 +01001259 .v.verbs = (const struct hda_verb[]) {
1260 /* change to EAPD mode */
1261 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
1262 { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
1263 {}
1264 },
1265 },
Takashi Iwaib9368f52012-02-17 17:54:44 +01001266 [ALC880_FIXUP_TCL_S700] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001267 .type = HDA_FIXUP_VERBS,
Takashi Iwaib9368f52012-02-17 17:54:44 +01001268 .v.verbs = (const struct hda_verb[]) {
1269 /* change to EAPD mode */
1270 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
1271 { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
1272 {}
1273 },
1274 .chained = true,
1275 .chain_id = ALC880_FIXUP_GPIO2,
1276 },
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001277 [ALC880_FIXUP_VOL_KNOB] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001278 .type = HDA_FIXUP_FUNC,
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001279 .v.func = alc880_fixup_vol_knob,
1280 },
1281 [ALC880_FIXUP_FUJITSU] = {
1282 /* override all pins as BIOS on old Amilo is broken */
Takashi Iwai1727a772013-01-10 09:52:52 +01001283 .type = HDA_FIXUP_PINS,
1284 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaibb148bd2015-08-13 18:02:39 +02001285 { 0x14, 0x0121401f }, /* HP */
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001286 { 0x15, 0x99030120 }, /* speaker */
1287 { 0x16, 0x99030130 }, /* bass speaker */
1288 { 0x17, 0x411111f0 }, /* N/A */
1289 { 0x18, 0x411111f0 }, /* N/A */
1290 { 0x19, 0x01a19950 }, /* mic-in */
1291 { 0x1a, 0x411111f0 }, /* N/A */
1292 { 0x1b, 0x411111f0 }, /* N/A */
1293 { 0x1c, 0x411111f0 }, /* N/A */
1294 { 0x1d, 0x411111f0 }, /* N/A */
1295 { 0x1e, 0x01454140 }, /* SPDIF out */
1296 { }
1297 },
1298 .chained = true,
1299 .chain_id = ALC880_FIXUP_VOL_KNOB,
1300 },
Takashi Iwaiba533812012-02-20 16:36:52 +01001301 [ALC880_FIXUP_F1734] = {
1302 /* almost compatible with FUJITSU, but no bass and SPDIF */
Takashi Iwai1727a772013-01-10 09:52:52 +01001303 .type = HDA_FIXUP_PINS,
1304 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaibb148bd2015-08-13 18:02:39 +02001305 { 0x14, 0x0121401f }, /* HP */
Takashi Iwaiba533812012-02-20 16:36:52 +01001306 { 0x15, 0x99030120 }, /* speaker */
1307 { 0x16, 0x411111f0 }, /* N/A */
1308 { 0x17, 0x411111f0 }, /* N/A */
1309 { 0x18, 0x411111f0 }, /* N/A */
1310 { 0x19, 0x01a19950 }, /* mic-in */
1311 { 0x1a, 0x411111f0 }, /* N/A */
1312 { 0x1b, 0x411111f0 }, /* N/A */
1313 { 0x1c, 0x411111f0 }, /* N/A */
1314 { 0x1d, 0x411111f0 }, /* N/A */
1315 { 0x1e, 0x411111f0 }, /* N/A */
1316 { }
1317 },
1318 .chained = true,
1319 .chain_id = ALC880_FIXUP_VOL_KNOB,
1320 },
Takashi Iwai817de922012-02-20 17:20:48 +01001321 [ALC880_FIXUP_UNIWILL] = {
1322 /* need to fix HP and speaker pins to be parsed correctly */
Takashi Iwai1727a772013-01-10 09:52:52 +01001323 .type = HDA_FIXUP_PINS,
1324 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai817de922012-02-20 17:20:48 +01001325 { 0x14, 0x0121411f }, /* HP */
1326 { 0x15, 0x99030120 }, /* speaker */
1327 { 0x16, 0x99030130 }, /* bass speaker */
1328 { }
1329 },
1330 },
Takashi Iwai967b88c2012-02-20 17:31:02 +01001331 [ALC880_FIXUP_UNIWILL_DIG] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001332 .type = HDA_FIXUP_PINS,
1333 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai967b88c2012-02-20 17:31:02 +01001334 /* disable bogus unused pins */
1335 { 0x17, 0x411111f0 },
1336 { 0x19, 0x411111f0 },
1337 { 0x1b, 0x411111f0 },
1338 { 0x1f, 0x411111f0 },
1339 { }
1340 }
1341 },
Takashi Iwai96e225f2012-02-20 17:41:51 +01001342 [ALC880_FIXUP_Z71V] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001343 .type = HDA_FIXUP_PINS,
1344 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai96e225f2012-02-20 17:41:51 +01001345 /* set up the whole pins as BIOS is utterly broken */
1346 { 0x14, 0x99030120 }, /* speaker */
1347 { 0x15, 0x0121411f }, /* HP */
1348 { 0x16, 0x411111f0 }, /* N/A */
1349 { 0x17, 0x411111f0 }, /* N/A */
1350 { 0x18, 0x01a19950 }, /* mic-in */
1351 { 0x19, 0x411111f0 }, /* N/A */
1352 { 0x1a, 0x01813031 }, /* line-in */
1353 { 0x1b, 0x411111f0 }, /* N/A */
1354 { 0x1c, 0x411111f0 }, /* N/A */
1355 { 0x1d, 0x411111f0 }, /* N/A */
1356 { 0x1e, 0x0144111e }, /* SPDIF */
1357 { }
1358 }
1359 },
Takashi Iwai487a5882013-11-07 07:29:30 +01001360 [ALC880_FIXUP_ASUS_W5A] = {
1361 .type = HDA_FIXUP_PINS,
1362 .v.pins = (const struct hda_pintbl[]) {
1363 /* set up the whole pins as BIOS is utterly broken */
1364 { 0x14, 0x0121411f }, /* HP */
1365 { 0x15, 0x411111f0 }, /* N/A */
1366 { 0x16, 0x411111f0 }, /* N/A */
1367 { 0x17, 0x411111f0 }, /* N/A */
1368 { 0x18, 0x90a60160 }, /* mic */
1369 { 0x19, 0x411111f0 }, /* N/A */
1370 { 0x1a, 0x411111f0 }, /* N/A */
1371 { 0x1b, 0x411111f0 }, /* N/A */
1372 { 0x1c, 0x411111f0 }, /* N/A */
1373 { 0x1d, 0x411111f0 }, /* N/A */
1374 { 0x1e, 0xb743111e }, /* SPDIF out */
1375 { }
1376 },
1377 .chained = true,
1378 .chain_id = ALC880_FIXUP_GPIO1,
1379 },
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001380 [ALC880_FIXUP_3ST_BASE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001381 .type = HDA_FIXUP_PINS,
1382 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001383 { 0x14, 0x01014010 }, /* line-out */
1384 { 0x15, 0x411111f0 }, /* N/A */
1385 { 0x16, 0x411111f0 }, /* N/A */
1386 { 0x17, 0x411111f0 }, /* N/A */
1387 { 0x18, 0x01a19c30 }, /* mic-in */
1388 { 0x19, 0x0121411f }, /* HP */
1389 { 0x1a, 0x01813031 }, /* line-in */
1390 { 0x1b, 0x02a19c40 }, /* front-mic */
1391 { 0x1c, 0x411111f0 }, /* N/A */
1392 { 0x1d, 0x411111f0 }, /* N/A */
1393 /* 0x1e is filled in below */
1394 { 0x1f, 0x411111f0 }, /* N/A */
1395 { }
1396 }
1397 },
1398 [ALC880_FIXUP_3ST] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001399 .type = HDA_FIXUP_PINS,
1400 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001401 { 0x1e, 0x411111f0 }, /* N/A */
1402 { }
1403 },
1404 .chained = true,
1405 .chain_id = ALC880_FIXUP_3ST_BASE,
1406 },
1407 [ALC880_FIXUP_3ST_DIG] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001408 .type = HDA_FIXUP_PINS,
1409 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001410 { 0x1e, 0x0144111e }, /* SPDIF */
1411 { }
1412 },
1413 .chained = true,
1414 .chain_id = ALC880_FIXUP_3ST_BASE,
1415 },
1416 [ALC880_FIXUP_5ST_BASE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001417 .type = HDA_FIXUP_PINS,
1418 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001419 { 0x14, 0x01014010 }, /* front */
1420 { 0x15, 0x411111f0 }, /* N/A */
1421 { 0x16, 0x01011411 }, /* CLFE */
1422 { 0x17, 0x01016412 }, /* surr */
1423 { 0x18, 0x01a19c30 }, /* mic-in */
1424 { 0x19, 0x0121411f }, /* HP */
1425 { 0x1a, 0x01813031 }, /* line-in */
1426 { 0x1b, 0x02a19c40 }, /* front-mic */
1427 { 0x1c, 0x411111f0 }, /* N/A */
1428 { 0x1d, 0x411111f0 }, /* N/A */
1429 /* 0x1e is filled in below */
1430 { 0x1f, 0x411111f0 }, /* N/A */
1431 { }
1432 }
1433 },
1434 [ALC880_FIXUP_5ST] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001435 .type = HDA_FIXUP_PINS,
1436 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001437 { 0x1e, 0x411111f0 }, /* N/A */
1438 { }
1439 },
1440 .chained = true,
1441 .chain_id = ALC880_FIXUP_5ST_BASE,
1442 },
1443 [ALC880_FIXUP_5ST_DIG] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001444 .type = HDA_FIXUP_PINS,
1445 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001446 { 0x1e, 0x0144111e }, /* SPDIF */
1447 { }
1448 },
1449 .chained = true,
1450 .chain_id = ALC880_FIXUP_5ST_BASE,
1451 },
1452 [ALC880_FIXUP_6ST_BASE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001453 .type = HDA_FIXUP_PINS,
1454 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001455 { 0x14, 0x01014010 }, /* front */
1456 { 0x15, 0x01016412 }, /* surr */
1457 { 0x16, 0x01011411 }, /* CLFE */
1458 { 0x17, 0x01012414 }, /* side */
1459 { 0x18, 0x01a19c30 }, /* mic-in */
1460 { 0x19, 0x02a19c40 }, /* front-mic */
1461 { 0x1a, 0x01813031 }, /* line-in */
1462 { 0x1b, 0x0121411f }, /* HP */
1463 { 0x1c, 0x411111f0 }, /* N/A */
1464 { 0x1d, 0x411111f0 }, /* N/A */
1465 /* 0x1e is filled in below */
1466 { 0x1f, 0x411111f0 }, /* N/A */
1467 { }
1468 }
1469 },
1470 [ALC880_FIXUP_6ST] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001471 .type = HDA_FIXUP_PINS,
1472 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001473 { 0x1e, 0x411111f0 }, /* N/A */
1474 { }
1475 },
1476 .chained = true,
1477 .chain_id = ALC880_FIXUP_6ST_BASE,
1478 },
1479 [ALC880_FIXUP_6ST_DIG] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001480 .type = HDA_FIXUP_PINS,
1481 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001482 { 0x1e, 0x0144111e }, /* SPDIF */
1483 { }
1484 },
1485 .chained = true,
1486 .chain_id = ALC880_FIXUP_6ST_BASE,
1487 },
Takashi Iwai53971452013-01-23 18:21:37 +01001488 [ALC880_FIXUP_6ST_AUTOMUTE] = {
1489 .type = HDA_FIXUP_PINS,
1490 .v.pins = (const struct hda_pintbl[]) {
1491 { 0x1b, 0x0121401f }, /* HP with jack detect */
1492 { }
1493 },
1494 .chained_before = true,
1495 .chain_id = ALC880_FIXUP_6ST_BASE,
1496 },
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001497};
1498
1499static const struct snd_pci_quirk alc880_fixup_tbl[] = {
Takashi Iwaif02aab52012-02-17 16:33:56 +01001500 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_FIXUP_W810),
Takashi Iwai487a5882013-11-07 07:29:30 +01001501 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS W5A", ALC880_FIXUP_ASUS_W5A),
Takashi Iwai96e225f2012-02-20 17:41:51 +01001502 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_FIXUP_Z71V),
Takashi Iwai29e3fdc2012-02-20 17:56:57 +01001503 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_FIXUP_GPIO1),
David Henningsson6538de02014-06-10 10:52:50 +02001504 SND_PCI_QUIRK(0x147b, 0x1045, "ABit AA8XE", ALC880_FIXUP_6ST_AUTOMUTE),
Takashi Iwai29e3fdc2012-02-20 17:56:57 +01001505 SND_PCI_QUIRK(0x1558, 0x5401, "Clevo GPIO2", ALC880_FIXUP_GPIO2),
Takashi Iwai27e917f2012-02-17 17:49:54 +01001506 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo", ALC880_FIXUP_EAPD_COEF),
Takashi Iwai967b88c2012-02-20 17:31:02 +01001507 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_FIXUP_UNIWILL_DIG),
Takashi Iwaiba533812012-02-20 16:36:52 +01001508 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_FIXUP_F1734),
Takashi Iwai817de922012-02-20 17:20:48 +01001509 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_FIXUP_UNIWILL),
Takashi Iwai7833c7e2012-02-20 17:11:38 +01001510 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_FIXUP_VOL_KNOB),
Takashi Iwaif02aab52012-02-17 16:33:56 +01001511 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_FIXUP_W810),
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001512 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_FIXUP_MEDION_RIM),
Takashi Iwai53971452013-01-23 18:21:37 +01001513 SND_PCI_QUIRK(0x1631, 0xe011, "PB 13201056", ALC880_FIXUP_6ST_AUTOMUTE),
Takashi Iwaia1615742015-08-13 18:05:06 +02001514 SND_PCI_QUIRK(0x1734, 0x107c, "FSC Amilo M1437", ALC880_FIXUP_FUJITSU),
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001515 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FIXUP_FUJITSU),
Takashi Iwaiba533812012-02-20 16:36:52 +01001516 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_FIXUP_F1734),
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001517 SND_PCI_QUIRK(0x1734, 0x10b0, "FSC Amilo Pi1556", ALC880_FIXUP_FUJITSU),
Takashi Iwaidc6af522012-02-17 16:18:59 +01001518 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_FIXUP_LG),
1519 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_FIXUP_LG),
1520 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_FIXUP_LG),
Takashi Iwaidb8a38e2013-08-09 12:34:42 +02001521 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_FIXUP_LG_LW25),
Takashi Iwaib9368f52012-02-17 17:54:44 +01001522 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_FIXUP_TCL_S700),
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001523
1524 /* Below is the copied entries from alc880_quirks.c.
1525 * It's not quite sure whether BIOS sets the correct pin-config table
1526 * on these machines, thus they are kept to be compatible with
1527 * the old static quirks. Once when it's confirmed to work without
1528 * these overrides, it'd be better to remove.
1529 */
1530 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_FIXUP_5ST_DIG),
1531 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_FIXUP_6ST),
1532 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_FIXUP_3ST_DIG),
1533 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_FIXUP_6ST_DIG),
1534 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_FIXUP_6ST_DIG),
1535 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_FIXUP_6ST_DIG),
1536 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_FIXUP_3ST_DIG),
1537 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_FIXUP_3ST),
1538 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_FIXUP_6ST_DIG),
1539 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_FIXUP_3ST),
1540 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_FIXUP_3ST),
1541 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_FIXUP_5ST),
1542 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_FIXUP_5ST),
1543 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_FIXUP_5ST),
1544 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_FIXUP_6ST_DIG),
1545 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_FIXUP_6ST_DIG),
1546 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_FIXUP_6ST_DIG),
1547 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_FIXUP_6ST_DIG),
1548 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_FIXUP_5ST_DIG),
1549 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_FIXUP_5ST_DIG),
1550 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_FIXUP_5ST_DIG),
1551 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_FIXUP_6ST_DIG), /* broken BIOS */
1552 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_FIXUP_6ST_DIG),
1553 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1554 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1555 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1556 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_FIXUP_3ST_DIG),
1557 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1558 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_FIXUP_3ST_DIG),
1559 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_FIXUP_3ST_DIG),
1560 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1561 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1562 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1563 /* default Intel */
1564 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_FIXUP_3ST),
1565 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_FIXUP_5ST_DIG),
1566 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_FIXUP_6ST_DIG),
1567 {}
1568};
1569
Takashi Iwai1727a772013-01-10 09:52:52 +01001570static const struct hda_model_fixup alc880_fixup_models[] = {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001571 {.id = ALC880_FIXUP_3ST, .name = "3stack"},
1572 {.id = ALC880_FIXUP_3ST_DIG, .name = "3stack-digout"},
1573 {.id = ALC880_FIXUP_5ST, .name = "5stack"},
1574 {.id = ALC880_FIXUP_5ST_DIG, .name = "5stack-digout"},
1575 {.id = ALC880_FIXUP_6ST, .name = "6stack"},
1576 {.id = ALC880_FIXUP_6ST_DIG, .name = "6stack-digout"},
Takashi Iwai53971452013-01-23 18:21:37 +01001577 {.id = ALC880_FIXUP_6ST_AUTOMUTE, .name = "6stack-automute"},
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001578 {}
1579};
1580
1581
1582/*
Takashi Iwai1d045db2011-07-07 18:23:21 +02001583 * OK, here we have finally the patch for ALC880
1584 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02001585static int patch_alc880(struct hda_codec *codec)
1586{
1587 struct alc_spec *spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001588 int err;
1589
Takashi Iwai3de95172012-05-07 18:03:15 +02001590 err = alc_alloc_spec(codec, 0x0b);
1591 if (err < 0)
1592 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001593
Takashi Iwai3de95172012-05-07 18:03:15 +02001594 spec = codec->spec;
Takashi Iwai08c189f2012-12-19 15:22:24 +01001595 spec->gen.need_dac_fix = 1;
Takashi Iwai7504b6c2013-03-18 11:25:51 +01001596 spec->gen.beep_nid = 0x01;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001597
Takashi Iwai225068a2015-05-29 10:42:14 +02001598 codec->patch_ops.unsol_event = alc880_unsol_event;
1599
Takashi Iwaic9af7532019-05-10 11:01:43 +02001600 alc_pre_init(codec);
1601
Takashi Iwai1727a772013-01-10 09:52:52 +01001602 snd_hda_pick_fixup(codec, alc880_fixup_models, alc880_fixup_tbl,
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001603 alc880_fixups);
Takashi Iwai1727a772013-01-10 09:52:52 +01001604 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02001605
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001606 /* automatic parse from the BIOS config */
1607 err = alc880_parse_auto_config(codec);
1608 if (err < 0)
1609 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001610
Takashi Iwaifea80fa2018-06-20 12:52:46 +02001611 if (!spec->gen.no_analog) {
1612 err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
1613 if (err < 0)
1614 goto error;
1615 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02001616
Takashi Iwai1727a772013-01-10 09:52:52 +01001617 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01001618
Takashi Iwai1d045db2011-07-07 18:23:21 +02001619 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02001620
1621 error:
1622 alc_free(codec);
1623 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001624}
1625
1626
1627/*
1628 * ALC260 support
1629 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02001630static int alc260_parse_auto_config(struct hda_codec *codec)
1631{
Takashi Iwai1d045db2011-07-07 18:23:21 +02001632 static const hda_nid_t alc260_ignore[] = { 0x17, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001633 static const hda_nid_t alc260_ssids[] = { 0x10, 0x15, 0x0f, 0 };
1634 return alc_parse_auto_config(codec, alc260_ignore, alc260_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02001635}
1636
Takashi Iwai1d045db2011-07-07 18:23:21 +02001637/*
1638 * Pin config fixes
1639 */
1640enum {
Takashi Iwaica8f0422012-02-16 11:51:19 +01001641 ALC260_FIXUP_HP_DC5750,
1642 ALC260_FIXUP_HP_PIN_0F,
1643 ALC260_FIXUP_COEF,
Takashi Iwai15317ab2012-02-16 12:02:53 +01001644 ALC260_FIXUP_GPIO1,
Takashi Iwai20f7d922012-02-16 12:35:16 +01001645 ALC260_FIXUP_GPIO1_TOGGLE,
1646 ALC260_FIXUP_REPLACER,
Takashi Iwai0a1c4fa2012-02-16 12:42:30 +01001647 ALC260_FIXUP_HP_B1900,
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001648 ALC260_FIXUP_KN1,
Takashi Iwai39aedee2013-01-10 17:10:40 +01001649 ALC260_FIXUP_FSC_S7020,
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001650 ALC260_FIXUP_FSC_S7020_JWSE,
Takashi Iwaid08c5ef2013-11-22 08:06:36 +01001651 ALC260_FIXUP_VAIO_PINS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02001652};
1653
Takashi Iwai20f7d922012-02-16 12:35:16 +01001654static void alc260_gpio1_automute(struct hda_codec *codec)
1655{
1656 struct alc_spec *spec = codec->spec;
Takashi Iwaiaaf312d2018-06-19 22:28:22 +02001657
1658 alc_update_gpio_data(codec, 0x01, spec->gen.hp_jack_present);
Takashi Iwai20f7d922012-02-16 12:35:16 +01001659}
1660
1661static void alc260_fixup_gpio1_toggle(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001662 const struct hda_fixup *fix, int action)
Takashi Iwai20f7d922012-02-16 12:35:16 +01001663{
1664 struct alc_spec *spec = codec->spec;
Takashi Iwai1727a772013-01-10 09:52:52 +01001665 if (action == HDA_FIXUP_ACT_PROBE) {
Takashi Iwai20f7d922012-02-16 12:35:16 +01001666 /* although the machine has only one output pin, we need to
1667 * toggle GPIO1 according to the jack state
1668 */
Takashi Iwai08c189f2012-12-19 15:22:24 +01001669 spec->gen.automute_hook = alc260_gpio1_automute;
1670 spec->gen.detect_hp = 1;
1671 spec->gen.automute_speaker = 1;
1672 spec->gen.autocfg.hp_pins[0] = 0x0f; /* copy it for automute */
Takashi Iwai62f949b2014-09-11 14:06:53 +02001673 snd_hda_jack_detect_enable_callback(codec, 0x0f,
Takashi Iwai08c189f2012-12-19 15:22:24 +01001674 snd_hda_gen_hp_automute);
Takashi Iwai5579cd62018-06-19 22:22:41 +02001675 alc_setup_gpio(codec, 0x01);
Takashi Iwai20f7d922012-02-16 12:35:16 +01001676 }
1677}
1678
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001679static void alc260_fixup_kn1(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001680 const struct hda_fixup *fix, int action)
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001681{
1682 struct alc_spec *spec = codec->spec;
Takashi Iwai1727a772013-01-10 09:52:52 +01001683 static const struct hda_pintbl pincfgs[] = {
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001684 { 0x0f, 0x02214000 }, /* HP/speaker */
1685 { 0x12, 0x90a60160 }, /* int mic */
1686 { 0x13, 0x02a19000 }, /* ext mic */
1687 { 0x18, 0x01446000 }, /* SPDIF out */
1688 /* disable bogus I/O pins */
1689 { 0x10, 0x411111f0 },
1690 { 0x11, 0x411111f0 },
1691 { 0x14, 0x411111f0 },
1692 { 0x15, 0x411111f0 },
1693 { 0x16, 0x411111f0 },
1694 { 0x17, 0x411111f0 },
1695 { 0x19, 0x411111f0 },
1696 { }
1697 };
1698
1699 switch (action) {
Takashi Iwai1727a772013-01-10 09:52:52 +01001700 case HDA_FIXUP_ACT_PRE_PROBE:
1701 snd_hda_apply_pincfgs(codec, pincfgs);
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001702 spec->init_amp = ALC_INIT_NONE;
1703 break;
1704 }
1705}
1706
Takashi Iwai39aedee2013-01-10 17:10:40 +01001707static void alc260_fixup_fsc_s7020(struct hda_codec *codec,
1708 const struct hda_fixup *fix, int action)
1709{
1710 struct alc_spec *spec = codec->spec;
Takashi Iwai1c76aa52018-06-21 16:37:54 +02001711 if (action == HDA_FIXUP_ACT_PRE_PROBE)
Takashi Iwaie6e0ee52013-02-18 17:04:20 +01001712 spec->init_amp = ALC_INIT_NONE;
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001713}
1714
1715static void alc260_fixup_fsc_s7020_jwse(struct hda_codec *codec,
1716 const struct hda_fixup *fix, int action)
1717{
1718 struct alc_spec *spec = codec->spec;
1719 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwaif811c3c2013-03-07 18:32:59 +01001720 spec->gen.add_jack_modes = 1;
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001721 spec->gen.hp_mic = 1;
Takashi Iwaie6e0ee52013-02-18 17:04:20 +01001722 }
Takashi Iwai39aedee2013-01-10 17:10:40 +01001723}
1724
Takashi Iwai1727a772013-01-10 09:52:52 +01001725static const struct hda_fixup alc260_fixups[] = {
Takashi Iwaica8f0422012-02-16 11:51:19 +01001726 [ALC260_FIXUP_HP_DC5750] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001727 .type = HDA_FIXUP_PINS,
1728 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02001729 { 0x11, 0x90130110 }, /* speaker */
1730 { }
1731 }
1732 },
Takashi Iwaica8f0422012-02-16 11:51:19 +01001733 [ALC260_FIXUP_HP_PIN_0F] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001734 .type = HDA_FIXUP_PINS,
1735 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaica8f0422012-02-16 11:51:19 +01001736 { 0x0f, 0x01214000 }, /* HP */
1737 { }
1738 }
1739 },
1740 [ALC260_FIXUP_COEF] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001741 .type = HDA_FIXUP_VERBS,
Takashi Iwaica8f0422012-02-16 11:51:19 +01001742 .v.verbs = (const struct hda_verb[]) {
Ronan Marquete30cf2d2014-06-01 18:38:53 +02001743 { 0x1a, AC_VERB_SET_COEF_INDEX, 0x07 },
1744 { 0x1a, AC_VERB_SET_PROC_COEF, 0x3040 },
Takashi Iwaica8f0422012-02-16 11:51:19 +01001745 { }
1746 },
Takashi Iwaica8f0422012-02-16 11:51:19 +01001747 },
Takashi Iwai15317ab2012-02-16 12:02:53 +01001748 [ALC260_FIXUP_GPIO1] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02001749 .type = HDA_FIXUP_FUNC,
1750 .v.func = alc_fixup_gpio1,
Takashi Iwai15317ab2012-02-16 12:02:53 +01001751 },
Takashi Iwai20f7d922012-02-16 12:35:16 +01001752 [ALC260_FIXUP_GPIO1_TOGGLE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001753 .type = HDA_FIXUP_FUNC,
Takashi Iwai20f7d922012-02-16 12:35:16 +01001754 .v.func = alc260_fixup_gpio1_toggle,
1755 .chained = true,
1756 .chain_id = ALC260_FIXUP_HP_PIN_0F,
1757 },
1758 [ALC260_FIXUP_REPLACER] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001759 .type = HDA_FIXUP_VERBS,
Takashi Iwai20f7d922012-02-16 12:35:16 +01001760 .v.verbs = (const struct hda_verb[]) {
Takashi Iwai192a98e2014-06-02 15:16:07 +02001761 { 0x1a, AC_VERB_SET_COEF_INDEX, 0x07 },
1762 { 0x1a, AC_VERB_SET_PROC_COEF, 0x3050 },
Takashi Iwai20f7d922012-02-16 12:35:16 +01001763 { }
1764 },
1765 .chained = true,
1766 .chain_id = ALC260_FIXUP_GPIO1_TOGGLE,
1767 },
Takashi Iwai0a1c4fa2012-02-16 12:42:30 +01001768 [ALC260_FIXUP_HP_B1900] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001769 .type = HDA_FIXUP_FUNC,
Takashi Iwai0a1c4fa2012-02-16 12:42:30 +01001770 .v.func = alc260_fixup_gpio1_toggle,
1771 .chained = true,
1772 .chain_id = ALC260_FIXUP_COEF,
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001773 },
1774 [ALC260_FIXUP_KN1] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001775 .type = HDA_FIXUP_FUNC,
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001776 .v.func = alc260_fixup_kn1,
1777 },
Takashi Iwai39aedee2013-01-10 17:10:40 +01001778 [ALC260_FIXUP_FSC_S7020] = {
1779 .type = HDA_FIXUP_FUNC,
1780 .v.func = alc260_fixup_fsc_s7020,
1781 },
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001782 [ALC260_FIXUP_FSC_S7020_JWSE] = {
1783 .type = HDA_FIXUP_FUNC,
1784 .v.func = alc260_fixup_fsc_s7020_jwse,
1785 .chained = true,
1786 .chain_id = ALC260_FIXUP_FSC_S7020,
1787 },
Takashi Iwaid08c5ef2013-11-22 08:06:36 +01001788 [ALC260_FIXUP_VAIO_PINS] = {
1789 .type = HDA_FIXUP_PINS,
1790 .v.pins = (const struct hda_pintbl[]) {
1791 /* Pin configs are missing completely on some VAIOs */
1792 { 0x0f, 0x01211020 },
1793 { 0x10, 0x0001003f },
1794 { 0x11, 0x411111f0 },
1795 { 0x12, 0x01a15930 },
1796 { 0x13, 0x411111f0 },
1797 { 0x14, 0x411111f0 },
1798 { 0x15, 0x411111f0 },
1799 { 0x16, 0x411111f0 },
1800 { 0x17, 0x411111f0 },
1801 { 0x18, 0x411111f0 },
1802 { 0x19, 0x411111f0 },
1803 { }
1804 }
1805 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02001806};
1807
1808static const struct snd_pci_quirk alc260_fixup_tbl[] = {
Takashi Iwai15317ab2012-02-16 12:02:53 +01001809 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_FIXUP_GPIO1),
Takashi Iwaica8f0422012-02-16 11:51:19 +01001810 SND_PCI_QUIRK(0x1025, 0x007f, "Acer Aspire 9500", ALC260_FIXUP_COEF),
Takashi Iwai15317ab2012-02-16 12:02:53 +01001811 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_FIXUP_GPIO1),
Takashi Iwaica8f0422012-02-16 11:51:19 +01001812 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", ALC260_FIXUP_HP_DC5750),
Takashi Iwai0a1c4fa2012-02-16 12:42:30 +01001813 SND_PCI_QUIRK(0x103c, 0x30ba, "HP Presario B1900", ALC260_FIXUP_HP_B1900),
Takashi Iwaid08c5ef2013-11-22 08:06:36 +01001814 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_FIXUP_VAIO_PINS),
Takashi Iwai0f5a5b82013-11-21 09:12:52 +01001815 SND_PCI_QUIRK(0x104d, 0x81e2, "Sony VAIO TX", ALC260_FIXUP_HP_PIN_0F),
Takashi Iwai39aedee2013-01-10 17:10:40 +01001816 SND_PCI_QUIRK(0x10cf, 0x1326, "FSC LifeBook S7020", ALC260_FIXUP_FSC_S7020),
Takashi Iwaib1f58082012-02-16 12:45:03 +01001817 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FIXUP_GPIO1),
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001818 SND_PCI_QUIRK(0x152d, 0x0729, "Quanta KN1", ALC260_FIXUP_KN1),
Takashi Iwai20f7d922012-02-16 12:35:16 +01001819 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_FIXUP_REPLACER),
Takashi Iwaica8f0422012-02-16 11:51:19 +01001820 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_FIXUP_COEF),
Takashi Iwai1d045db2011-07-07 18:23:21 +02001821 {}
1822};
1823
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001824static const struct hda_model_fixup alc260_fixup_models[] = {
1825 {.id = ALC260_FIXUP_GPIO1, .name = "gpio1"},
1826 {.id = ALC260_FIXUP_COEF, .name = "coef"},
1827 {.id = ALC260_FIXUP_FSC_S7020, .name = "fujitsu"},
1828 {.id = ALC260_FIXUP_FSC_S7020_JWSE, .name = "fujitsu-jwse"},
1829 {}
1830};
1831
Takashi Iwai1d045db2011-07-07 18:23:21 +02001832/*
1833 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02001834static int patch_alc260(struct hda_codec *codec)
1835{
1836 struct alc_spec *spec;
Takashi Iwaic3c2c9e2012-02-16 12:59:55 +01001837 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001838
Takashi Iwai3de95172012-05-07 18:03:15 +02001839 err = alc_alloc_spec(codec, 0x07);
1840 if (err < 0)
1841 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001842
Takashi Iwai3de95172012-05-07 18:03:15 +02001843 spec = codec->spec;
Takashi Iwaiea46c3c2013-01-15 18:45:53 +01001844 /* as quite a few machines require HP amp for speaker outputs,
1845 * it's easier to enable it unconditionally; even if it's unneeded,
1846 * it's almost harmless.
1847 */
1848 spec->gen.prefer_hp_amp = 1;
Takashi Iwai7504b6c2013-03-18 11:25:51 +01001849 spec->gen.beep_nid = 0x01;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001850
Takashi Iwai225068a2015-05-29 10:42:14 +02001851 spec->shutup = alc_eapd_shutup;
1852
Takashi Iwaic9af7532019-05-10 11:01:43 +02001853 alc_pre_init(codec);
1854
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001855 snd_hda_pick_fixup(codec, alc260_fixup_models, alc260_fixup_tbl,
1856 alc260_fixups);
Takashi Iwai1727a772013-01-10 09:52:52 +01001857 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02001858
Takashi Iwaic3c2c9e2012-02-16 12:59:55 +01001859 /* automatic parse from the BIOS config */
1860 err = alc260_parse_auto_config(codec);
1861 if (err < 0)
1862 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001863
Takashi Iwaifea80fa2018-06-20 12:52:46 +02001864 if (!spec->gen.no_analog) {
1865 err = set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
1866 if (err < 0)
1867 goto error;
1868 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02001869
Takashi Iwai1727a772013-01-10 09:52:52 +01001870 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01001871
Takashi Iwai1d045db2011-07-07 18:23:21 +02001872 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02001873
1874 error:
1875 alc_free(codec);
1876 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001877}
1878
1879
1880/*
1881 * ALC882/883/885/888/889 support
1882 *
1883 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
1884 * configuration. Each pin widget can choose any input DACs and a mixer.
1885 * Each ADC is connected from a mixer of all inputs. This makes possible
1886 * 6-channel independent captures.
1887 *
1888 * In addition, an independent DAC for the multi-playback (not used in this
1889 * driver yet).
1890 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02001891
1892/*
1893 * Pin config fixes
1894 */
1895enum {
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01001896 ALC882_FIXUP_ABIT_AW9D_MAX,
1897 ALC882_FIXUP_LENOVO_Y530,
1898 ALC882_FIXUP_PB_M5210,
1899 ALC882_FIXUP_ACER_ASPIRE_7736,
1900 ALC882_FIXUP_ASUS_W90V,
Marton Balint8f239212012-03-05 21:33:23 +01001901 ALC889_FIXUP_CD,
David Henningssonb2c53e22014-01-01 14:01:34 +01001902 ALC889_FIXUP_FRONT_HP_NO_PRESENCE,
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01001903 ALC889_FIXUP_VAIO_TT,
Takashi Iwai0e7cc2e2011-11-09 12:42:48 +01001904 ALC888_FIXUP_EEE1601,
Takashi Iwai177943a32011-11-09 12:55:18 +01001905 ALC882_FIXUP_EAPD,
Takashi Iwai7a6069b2011-11-09 15:22:01 +01001906 ALC883_FIXUP_EAPD,
Takashi Iwai8812c4f2011-11-09 17:39:15 +01001907 ALC883_FIXUP_ACER_EAPD,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001908 ALC882_FIXUP_GPIO1,
1909 ALC882_FIXUP_GPIO2,
Takashi Iwaieb844d52011-11-09 18:03:07 +01001910 ALC882_FIXUP_GPIO3,
Takashi Iwai68ef0562011-11-09 18:24:44 +01001911 ALC889_FIXUP_COEF,
1912 ALC882_FIXUP_ASUS_W2JC,
Takashi Iwaic3e837b2011-11-10 16:01:47 +01001913 ALC882_FIXUP_ACER_ASPIRE_4930G,
1914 ALC882_FIXUP_ACER_ASPIRE_8930G,
1915 ALC882_FIXUP_ASPIRE_8930G_VERBS,
Takashi Iwai56710872011-11-14 17:42:11 +01001916 ALC885_FIXUP_MACPRO_GPIO,
Takashi Iwai02a237b2012-02-13 15:25:07 +01001917 ALC889_FIXUP_DAC_ROUTE,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001918 ALC889_FIXUP_MBP_VREF,
1919 ALC889_FIXUP_IMAC91_VREF,
Adrien Vergée7729a42014-01-24 14:56:14 -05001920 ALC889_FIXUP_MBA11_VREF,
Takashi Iwai0756f092013-12-04 13:59:45 +01001921 ALC889_FIXUP_MBA21_VREF,
Takashi Iwaic20f31e2014-02-03 11:02:10 +01001922 ALC889_FIXUP_MP11_VREF,
Mario Kleiner9f660a12015-12-22 00:45:43 +01001923 ALC889_FIXUP_MP41_VREF,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02001924 ALC882_FIXUP_INV_DMIC,
Takashi Iwaie427c232012-07-29 10:04:08 +02001925 ALC882_FIXUP_NO_PRIMARY_HP,
Takashi Iwai1f0bbf02013-11-28 15:21:21 +01001926 ALC887_FIXUP_ASUS_BASS,
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01001927 ALC887_FIXUP_BASS_CHMAP,
Takashi Iwai7beb3a62017-04-10 18:05:52 +02001928 ALC1220_FIXUP_GB_DUAL_CODECS,
Peisen0202f5c2017-10-26 10:35:36 +08001929 ALC1220_FIXUP_CLEVO_P950,
Richard Sailer80690a22019-04-02 15:52:04 +02001930 ALC1220_FIXUP_CLEVO_PB51ED,
1931 ALC1220_FIXUP_CLEVO_PB51ED_PINS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02001932};
1933
Takashi Iwai68ef0562011-11-09 18:24:44 +01001934static void alc889_fixup_coef(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001935 const struct hda_fixup *fix, int action)
Takashi Iwai68ef0562011-11-09 18:24:44 +01001936{
Takashi Iwai1727a772013-01-10 09:52:52 +01001937 if (action != HDA_FIXUP_ACT_INIT)
Takashi Iwai68ef0562011-11-09 18:24:44 +01001938 return;
Kailang Yang1df88742014-10-29 16:10:13 +08001939 alc_update_coef_idx(codec, 7, 0, 0x2030);
Takashi Iwai68ef0562011-11-09 18:24:44 +01001940}
1941
Takashi Iwai56710872011-11-14 17:42:11 +01001942/* set up GPIO at initialization */
1943static void alc885_fixup_macpro_gpio(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001944 const struct hda_fixup *fix, int action)
Takashi Iwai56710872011-11-14 17:42:11 +01001945{
Takashi Iwai215c8502018-06-19 22:34:26 +02001946 struct alc_spec *spec = codec->spec;
1947
1948 spec->gpio_write_delay = true;
1949 alc_fixup_gpio3(codec, fix, action);
Takashi Iwai56710872011-11-14 17:42:11 +01001950}
1951
Takashi Iwai02a237b2012-02-13 15:25:07 +01001952/* Fix the connection of some pins for ALC889:
1953 * At least, Acer Aspire 5935 shows the connections to DAC3/4 don't
1954 * work correctly (bko#42740)
1955 */
1956static void alc889_fixup_dac_route(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001957 const struct hda_fixup *fix, int action)
Takashi Iwai02a237b2012-02-13 15:25:07 +01001958{
Takashi Iwai1727a772013-01-10 09:52:52 +01001959 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwaief8d60f2012-02-17 10:12:38 +01001960 /* fake the connections during parsing the tree */
Michał Mirosławcaf3c042020-01-03 10:23:48 +01001961 static const hda_nid_t conn1[] = { 0x0c, 0x0d };
1962 static const hda_nid_t conn2[] = { 0x0e, 0x0f };
1963 snd_hda_override_conn_list(codec, 0x14, ARRAY_SIZE(conn1), conn1);
1964 snd_hda_override_conn_list(codec, 0x15, ARRAY_SIZE(conn1), conn1);
1965 snd_hda_override_conn_list(codec, 0x18, ARRAY_SIZE(conn2), conn2);
1966 snd_hda_override_conn_list(codec, 0x1a, ARRAY_SIZE(conn2), conn2);
Takashi Iwai1727a772013-01-10 09:52:52 +01001967 } else if (action == HDA_FIXUP_ACT_PROBE) {
Takashi Iwaief8d60f2012-02-17 10:12:38 +01001968 /* restore the connections */
Michał Mirosławcaf3c042020-01-03 10:23:48 +01001969 static const hda_nid_t conn[] = { 0x0c, 0x0d, 0x0e, 0x0f, 0x26 };
1970 snd_hda_override_conn_list(codec, 0x14, ARRAY_SIZE(conn), conn);
1971 snd_hda_override_conn_list(codec, 0x15, ARRAY_SIZE(conn), conn);
1972 snd_hda_override_conn_list(codec, 0x18, ARRAY_SIZE(conn), conn);
1973 snd_hda_override_conn_list(codec, 0x1a, ARRAY_SIZE(conn), conn);
Takashi Iwai02a237b2012-02-13 15:25:07 +01001974 }
1975}
1976
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001977/* Set VREF on HP pin */
1978static void alc889_fixup_mbp_vref(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001979 const struct hda_fixup *fix, int action)
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001980{
Michał Mirosławcaf3c042020-01-03 10:23:48 +01001981 static const hda_nid_t nids[] = { 0x14, 0x15, 0x19 };
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001982 struct alc_spec *spec = codec->spec;
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001983 int i;
1984
Takashi Iwai1727a772013-01-10 09:52:52 +01001985 if (action != HDA_FIXUP_ACT_INIT)
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001986 return;
1987 for (i = 0; i < ARRAY_SIZE(nids); i++) {
1988 unsigned int val = snd_hda_codec_get_pincfg(codec, nids[i]);
1989 if (get_defcfg_device(val) != AC_JACK_HP_OUT)
1990 continue;
Takashi Iwaid3f02d62013-01-10 10:12:22 +01001991 val = snd_hda_codec_get_pin_target(codec, nids[i]);
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001992 val |= AC_PINCTL_VREF_80;
Takashi Iwaicdd03ce2012-04-20 12:34:50 +02001993 snd_hda_set_pin_ctl(codec, nids[i], val);
Takashi Iwai08c189f2012-12-19 15:22:24 +01001994 spec->gen.keep_vref_in_automute = 1;
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001995 break;
1996 }
1997}
1998
Takashi Iwai0756f092013-12-04 13:59:45 +01001999static void alc889_fixup_mac_pins(struct hda_codec *codec,
2000 const hda_nid_t *nids, int num_nids)
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002001{
2002 struct alc_spec *spec = codec->spec;
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002003 int i;
2004
Takashi Iwai0756f092013-12-04 13:59:45 +01002005 for (i = 0; i < num_nids; i++) {
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002006 unsigned int val;
Takashi Iwaid3f02d62013-01-10 10:12:22 +01002007 val = snd_hda_codec_get_pin_target(codec, nids[i]);
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002008 val |= AC_PINCTL_VREF_50;
Takashi Iwaicdd03ce2012-04-20 12:34:50 +02002009 snd_hda_set_pin_ctl(codec, nids[i], val);
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002010 }
Takashi Iwai08c189f2012-12-19 15:22:24 +01002011 spec->gen.keep_vref_in_automute = 1;
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002012}
2013
Takashi Iwai0756f092013-12-04 13:59:45 +01002014/* Set VREF on speaker pins on imac91 */
2015static void alc889_fixup_imac91_vref(struct hda_codec *codec,
2016 const struct hda_fixup *fix, int action)
2017{
Michał Mirosławcaf3c042020-01-03 10:23:48 +01002018 static const hda_nid_t nids[] = { 0x18, 0x1a };
Takashi Iwai0756f092013-12-04 13:59:45 +01002019
2020 if (action == HDA_FIXUP_ACT_INIT)
2021 alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
2022}
2023
Adrien Vergée7729a42014-01-24 14:56:14 -05002024/* Set VREF on speaker pins on mba11 */
2025static void alc889_fixup_mba11_vref(struct hda_codec *codec,
2026 const struct hda_fixup *fix, int action)
2027{
Michał Mirosławcaf3c042020-01-03 10:23:48 +01002028 static const hda_nid_t nids[] = { 0x18 };
Adrien Vergée7729a42014-01-24 14:56:14 -05002029
2030 if (action == HDA_FIXUP_ACT_INIT)
2031 alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
2032}
2033
Takashi Iwai0756f092013-12-04 13:59:45 +01002034/* Set VREF on speaker pins on mba21 */
2035static void alc889_fixup_mba21_vref(struct hda_codec *codec,
2036 const struct hda_fixup *fix, int action)
2037{
Michał Mirosławcaf3c042020-01-03 10:23:48 +01002038 static const hda_nid_t nids[] = { 0x18, 0x19 };
Takashi Iwai0756f092013-12-04 13:59:45 +01002039
2040 if (action == HDA_FIXUP_ACT_INIT)
2041 alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
2042}
2043
Takashi Iwaie427c232012-07-29 10:04:08 +02002044/* Don't take HP output as primary
Fernando Luis Vázquez Caod9111492013-02-12 16:49:46 +09002045 * Strangely, the speaker output doesn't work on Vaio Z and some Vaio
2046 * all-in-one desktop PCs (for example VGC-LN51JGB) through DAC 0x05
Takashi Iwaie427c232012-07-29 10:04:08 +02002047 */
2048static void alc882_fixup_no_primary_hp(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01002049 const struct hda_fixup *fix, int action)
Takashi Iwaie427c232012-07-29 10:04:08 +02002050{
2051 struct alc_spec *spec = codec->spec;
Takashi Iwaida96fb52013-07-29 16:54:36 +02002052 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai08c189f2012-12-19 15:22:24 +01002053 spec->gen.no_primary_hp = 1;
Takashi Iwaida96fb52013-07-29 16:54:36 +02002054 spec->gen.no_multi_io = 1;
2055 }
Takashi Iwaie427c232012-07-29 10:04:08 +02002056}
2057
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01002058static void alc_fixup_bass_chmap(struct hda_codec *codec,
2059 const struct hda_fixup *fix, int action);
2060
Takashi Iwai7beb3a62017-04-10 18:05:52 +02002061/* For dual-codec configuration, we need to disable some features to avoid
2062 * conflicts of kctls and PCM streams
2063 */
2064static void alc_fixup_dual_codecs(struct hda_codec *codec,
2065 const struct hda_fixup *fix, int action)
2066{
2067 struct alc_spec *spec = codec->spec;
2068
2069 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2070 return;
2071 /* disable vmaster */
2072 spec->gen.suppress_vmaster = 1;
2073 /* auto-mute and auto-mic switch don't work with multiple codecs */
2074 spec->gen.suppress_auto_mute = 1;
2075 spec->gen.suppress_auto_mic = 1;
2076 /* disable aamix as well */
2077 spec->gen.mixer_nid = 0;
2078 /* add location prefix to avoid conflicts */
2079 codec->force_pin_prefix = 1;
2080}
2081
2082static void rename_ctl(struct hda_codec *codec, const char *oldname,
2083 const char *newname)
2084{
2085 struct snd_kcontrol *kctl;
2086
2087 kctl = snd_hda_find_mixer_ctl(codec, oldname);
2088 if (kctl)
2089 strcpy(kctl->id.name, newname);
2090}
2091
2092static void alc1220_fixup_gb_dual_codecs(struct hda_codec *codec,
2093 const struct hda_fixup *fix,
2094 int action)
2095{
2096 alc_fixup_dual_codecs(codec, fix, action);
2097 switch (action) {
2098 case HDA_FIXUP_ACT_PRE_PROBE:
2099 /* override card longname to provide a unique UCM profile */
2100 strcpy(codec->card->longname, "HDAudio-Gigabyte-ALC1220DualCodecs");
2101 break;
2102 case HDA_FIXUP_ACT_BUILD:
2103 /* rename Capture controls depending on the codec */
2104 rename_ctl(codec, "Capture Volume",
2105 codec->addr == 0 ?
2106 "Rear-Panel Capture Volume" :
2107 "Front-Panel Capture Volume");
2108 rename_ctl(codec, "Capture Switch",
2109 codec->addr == 0 ?
2110 "Rear-Panel Capture Switch" :
2111 "Front-Panel Capture Switch");
2112 break;
2113 }
2114}
2115
Peisen0202f5c2017-10-26 10:35:36 +08002116static void alc1220_fixup_clevo_p950(struct hda_codec *codec,
2117 const struct hda_fixup *fix,
2118 int action)
2119{
Michał Mirosławcaf3c042020-01-03 10:23:48 +01002120 static const hda_nid_t conn1[] = { 0x0c };
Peisen0202f5c2017-10-26 10:35:36 +08002121
2122 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2123 return;
2124
2125 alc_update_coef_idx(codec, 0x7, 0, 0x3c3);
2126 /* We therefore want to make sure 0x14 (front headphone) and
2127 * 0x1b (speakers) use the stereo DAC 0x02
2128 */
Michał Mirosławcaf3c042020-01-03 10:23:48 +01002129 snd_hda_override_conn_list(codec, 0x14, ARRAY_SIZE(conn1), conn1);
2130 snd_hda_override_conn_list(codec, 0x1b, ARRAY_SIZE(conn1), conn1);
Peisen0202f5c2017-10-26 10:35:36 +08002131}
2132
Jeremy Soller7f665b12019-02-13 10:56:19 -07002133static void alc_fixup_headset_mode_no_hp_mic(struct hda_codec *codec,
2134 const struct hda_fixup *fix, int action);
2135
Richard Sailer80690a22019-04-02 15:52:04 +02002136static void alc1220_fixup_clevo_pb51ed(struct hda_codec *codec,
Jeremy Soller7f665b12019-02-13 10:56:19 -07002137 const struct hda_fixup *fix,
2138 int action)
2139{
2140 alc1220_fixup_clevo_p950(codec, fix, action);
2141 alc_fixup_headset_mode_no_hp_mic(codec, fix, action);
2142}
2143
Takashi Iwai1727a772013-01-10 09:52:52 +01002144static const struct hda_fixup alc882_fixups[] = {
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002145 [ALC882_FIXUP_ABIT_AW9D_MAX] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002146 .type = HDA_FIXUP_PINS,
2147 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002148 { 0x15, 0x01080104 }, /* side */
2149 { 0x16, 0x01011012 }, /* rear */
2150 { 0x17, 0x01016011 }, /* clfe */
2151 { }
2152 }
2153 },
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002154 [ALC882_FIXUP_LENOVO_Y530] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002155 .type = HDA_FIXUP_PINS,
2156 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002157 { 0x15, 0x99130112 }, /* rear int speakers */
2158 { 0x16, 0x99130111 }, /* subwoofer */
2159 { }
2160 }
2161 },
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002162 [ALC882_FIXUP_PB_M5210] = {
Takashi Iwaifd108212013-01-10 10:18:14 +01002163 .type = HDA_FIXUP_PINCTLS,
2164 .v.pins = (const struct hda_pintbl[]) {
2165 { 0x19, PIN_VREF50 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02002166 {}
2167 }
2168 },
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002169 [ALC882_FIXUP_ACER_ASPIRE_7736] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002170 .type = HDA_FIXUP_FUNC,
Takashi Iwai23d30f22012-05-07 17:17:32 +02002171 .v.func = alc_fixup_sku_ignore,
Takashi Iwai1d045db2011-07-07 18:23:21 +02002172 },
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002173 [ALC882_FIXUP_ASUS_W90V] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002174 .type = HDA_FIXUP_PINS,
2175 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai5cdf7452011-10-26 23:04:08 +02002176 { 0x16, 0x99130110 }, /* fix sequence for CLFE */
2177 { }
2178 }
2179 },
Marton Balint8f239212012-03-05 21:33:23 +01002180 [ALC889_FIXUP_CD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002181 .type = HDA_FIXUP_PINS,
2182 .v.pins = (const struct hda_pintbl[]) {
Marton Balint8f239212012-03-05 21:33:23 +01002183 { 0x1c, 0x993301f0 }, /* CD */
2184 { }
2185 }
2186 },
David Henningssonb2c53e22014-01-01 14:01:34 +01002187 [ALC889_FIXUP_FRONT_HP_NO_PRESENCE] = {
2188 .type = HDA_FIXUP_PINS,
2189 .v.pins = (const struct hda_pintbl[]) {
2190 { 0x1b, 0x02214120 }, /* Front HP jack is flaky, disable jack detect */
2191 { }
2192 },
2193 .chained = true,
2194 .chain_id = ALC889_FIXUP_CD,
2195 },
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002196 [ALC889_FIXUP_VAIO_TT] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002197 .type = HDA_FIXUP_PINS,
2198 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002199 { 0x17, 0x90170111 }, /* hidden surround speaker */
2200 { }
2201 }
2202 },
Takashi Iwai0e7cc2e2011-11-09 12:42:48 +01002203 [ALC888_FIXUP_EEE1601] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002204 .type = HDA_FIXUP_VERBS,
Takashi Iwai0e7cc2e2011-11-09 12:42:48 +01002205 .v.verbs = (const struct hda_verb[]) {
2206 { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b },
2207 { 0x20, AC_VERB_SET_PROC_COEF, 0x0838 },
2208 { }
2209 }
Takashi Iwai177943a32011-11-09 12:55:18 +01002210 },
2211 [ALC882_FIXUP_EAPD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002212 .type = HDA_FIXUP_VERBS,
Takashi Iwai177943a32011-11-09 12:55:18 +01002213 .v.verbs = (const struct hda_verb[]) {
2214 /* change to EAPD mode */
2215 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2216 { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
2217 { }
2218 }
2219 },
Takashi Iwai7a6069b2011-11-09 15:22:01 +01002220 [ALC883_FIXUP_EAPD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002221 .type = HDA_FIXUP_VERBS,
Takashi Iwai7a6069b2011-11-09 15:22:01 +01002222 .v.verbs = (const struct hda_verb[]) {
2223 /* change to EAPD mode */
2224 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2225 { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
2226 { }
2227 }
2228 },
Takashi Iwai8812c4f2011-11-09 17:39:15 +01002229 [ALC883_FIXUP_ACER_EAPD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002230 .type = HDA_FIXUP_VERBS,
Takashi Iwai8812c4f2011-11-09 17:39:15 +01002231 .v.verbs = (const struct hda_verb[]) {
2232 /* eanable EAPD on Acer laptops */
2233 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2234 { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
2235 { }
2236 }
2237 },
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002238 [ALC882_FIXUP_GPIO1] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02002239 .type = HDA_FIXUP_FUNC,
2240 .v.func = alc_fixup_gpio1,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002241 },
2242 [ALC882_FIXUP_GPIO2] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02002243 .type = HDA_FIXUP_FUNC,
2244 .v.func = alc_fixup_gpio2,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002245 },
Takashi Iwaieb844d52011-11-09 18:03:07 +01002246 [ALC882_FIXUP_GPIO3] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02002247 .type = HDA_FIXUP_FUNC,
2248 .v.func = alc_fixup_gpio3,
Takashi Iwaieb844d52011-11-09 18:03:07 +01002249 },
Takashi Iwai68ef0562011-11-09 18:24:44 +01002250 [ALC882_FIXUP_ASUS_W2JC] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02002251 .type = HDA_FIXUP_FUNC,
2252 .v.func = alc_fixup_gpio1,
Takashi Iwai68ef0562011-11-09 18:24:44 +01002253 .chained = true,
2254 .chain_id = ALC882_FIXUP_EAPD,
2255 },
2256 [ALC889_FIXUP_COEF] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002257 .type = HDA_FIXUP_FUNC,
Takashi Iwai68ef0562011-11-09 18:24:44 +01002258 .v.func = alc889_fixup_coef,
2259 },
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002260 [ALC882_FIXUP_ACER_ASPIRE_4930G] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002261 .type = HDA_FIXUP_PINS,
2262 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002263 { 0x16, 0x99130111 }, /* CLFE speaker */
2264 { 0x17, 0x99130112 }, /* surround speaker */
2265 { }
Takashi Iwai038d4fe2012-04-11 17:18:12 +02002266 },
2267 .chained = true,
2268 .chain_id = ALC882_FIXUP_GPIO1,
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002269 },
2270 [ALC882_FIXUP_ACER_ASPIRE_8930G] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002271 .type = HDA_FIXUP_PINS,
2272 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002273 { 0x16, 0x99130111 }, /* CLFE speaker */
2274 { 0x1b, 0x99130112 }, /* surround speaker */
2275 { }
2276 },
2277 .chained = true,
2278 .chain_id = ALC882_FIXUP_ASPIRE_8930G_VERBS,
2279 },
2280 [ALC882_FIXUP_ASPIRE_8930G_VERBS] = {
2281 /* additional init verbs for Acer Aspire 8930G */
Takashi Iwai1727a772013-01-10 09:52:52 +01002282 .type = HDA_FIXUP_VERBS,
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002283 .v.verbs = (const struct hda_verb[]) {
2284 /* Enable all DACs */
2285 /* DAC DISABLE/MUTE 1? */
2286 /* setting bits 1-5 disables DAC nids 0x02-0x06
2287 * apparently. Init=0x38 */
2288 { 0x20, AC_VERB_SET_COEF_INDEX, 0x03 },
2289 { 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
2290 /* DAC DISABLE/MUTE 2? */
2291 /* some bit here disables the other DACs.
2292 * Init=0x4900 */
2293 { 0x20, AC_VERB_SET_COEF_INDEX, 0x08 },
2294 { 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
2295 /* DMIC fix
2296 * This laptop has a stereo digital microphone.
2297 * The mics are only 1cm apart which makes the stereo
2298 * useless. However, either the mic or the ALC889
2299 * makes the signal become a difference/sum signal
2300 * instead of standard stereo, which is annoying.
2301 * So instead we flip this bit which makes the
2302 * codec replicate the sum signal to both channels,
2303 * turning it into a normal mono mic.
2304 */
2305 /* DMIC_CONTROL? Init value = 0x0001 */
2306 { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b },
2307 { 0x20, AC_VERB_SET_PROC_COEF, 0x0003 },
2308 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2309 { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
2310 { }
Takashi Iwai038d4fe2012-04-11 17:18:12 +02002311 },
2312 .chained = true,
2313 .chain_id = ALC882_FIXUP_GPIO1,
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002314 },
Takashi Iwai56710872011-11-14 17:42:11 +01002315 [ALC885_FIXUP_MACPRO_GPIO] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002316 .type = HDA_FIXUP_FUNC,
Takashi Iwai56710872011-11-14 17:42:11 +01002317 .v.func = alc885_fixup_macpro_gpio,
2318 },
Takashi Iwai02a237b2012-02-13 15:25:07 +01002319 [ALC889_FIXUP_DAC_ROUTE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002320 .type = HDA_FIXUP_FUNC,
Takashi Iwai02a237b2012-02-13 15:25:07 +01002321 .v.func = alc889_fixup_dac_route,
2322 },
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002323 [ALC889_FIXUP_MBP_VREF] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002324 .type = HDA_FIXUP_FUNC,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002325 .v.func = alc889_fixup_mbp_vref,
2326 .chained = true,
2327 .chain_id = ALC882_FIXUP_GPIO1,
2328 },
2329 [ALC889_FIXUP_IMAC91_VREF] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002330 .type = HDA_FIXUP_FUNC,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002331 .v.func = alc889_fixup_imac91_vref,
2332 .chained = true,
2333 .chain_id = ALC882_FIXUP_GPIO1,
2334 },
Adrien Vergée7729a42014-01-24 14:56:14 -05002335 [ALC889_FIXUP_MBA11_VREF] = {
2336 .type = HDA_FIXUP_FUNC,
2337 .v.func = alc889_fixup_mba11_vref,
2338 .chained = true,
2339 .chain_id = ALC889_FIXUP_MBP_VREF,
2340 },
Takashi Iwai0756f092013-12-04 13:59:45 +01002341 [ALC889_FIXUP_MBA21_VREF] = {
2342 .type = HDA_FIXUP_FUNC,
2343 .v.func = alc889_fixup_mba21_vref,
2344 .chained = true,
2345 .chain_id = ALC889_FIXUP_MBP_VREF,
2346 },
Takashi Iwaic20f31e2014-02-03 11:02:10 +01002347 [ALC889_FIXUP_MP11_VREF] = {
2348 .type = HDA_FIXUP_FUNC,
2349 .v.func = alc889_fixup_mba11_vref,
2350 .chained = true,
2351 .chain_id = ALC885_FIXUP_MACPRO_GPIO,
2352 },
Mario Kleiner9f660a12015-12-22 00:45:43 +01002353 [ALC889_FIXUP_MP41_VREF] = {
2354 .type = HDA_FIXUP_FUNC,
2355 .v.func = alc889_fixup_mbp_vref,
2356 .chained = true,
2357 .chain_id = ALC885_FIXUP_MACPRO_GPIO,
2358 },
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002359 [ALC882_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002360 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02002361 .v.func = alc_fixup_inv_dmic,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002362 },
Takashi Iwaie427c232012-07-29 10:04:08 +02002363 [ALC882_FIXUP_NO_PRIMARY_HP] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002364 .type = HDA_FIXUP_FUNC,
Takashi Iwaie427c232012-07-29 10:04:08 +02002365 .v.func = alc882_fixup_no_primary_hp,
2366 },
Takashi Iwai1f0bbf02013-11-28 15:21:21 +01002367 [ALC887_FIXUP_ASUS_BASS] = {
2368 .type = HDA_FIXUP_PINS,
2369 .v.pins = (const struct hda_pintbl[]) {
2370 {0x16, 0x99130130}, /* bass speaker */
2371 {}
2372 },
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01002373 .chained = true,
2374 .chain_id = ALC887_FIXUP_BASS_CHMAP,
2375 },
2376 [ALC887_FIXUP_BASS_CHMAP] = {
2377 .type = HDA_FIXUP_FUNC,
2378 .v.func = alc_fixup_bass_chmap,
Takashi Iwai1f0bbf02013-11-28 15:21:21 +01002379 },
Takashi Iwai7beb3a62017-04-10 18:05:52 +02002380 [ALC1220_FIXUP_GB_DUAL_CODECS] = {
2381 .type = HDA_FIXUP_FUNC,
2382 .v.func = alc1220_fixup_gb_dual_codecs,
2383 },
Peisen0202f5c2017-10-26 10:35:36 +08002384 [ALC1220_FIXUP_CLEVO_P950] = {
2385 .type = HDA_FIXUP_FUNC,
2386 .v.func = alc1220_fixup_clevo_p950,
2387 },
Richard Sailer80690a22019-04-02 15:52:04 +02002388 [ALC1220_FIXUP_CLEVO_PB51ED] = {
Jeremy Soller7f665b12019-02-13 10:56:19 -07002389 .type = HDA_FIXUP_FUNC,
Richard Sailer80690a22019-04-02 15:52:04 +02002390 .v.func = alc1220_fixup_clevo_pb51ed,
Jeremy Soller7f665b12019-02-13 10:56:19 -07002391 },
Richard Sailer80690a22019-04-02 15:52:04 +02002392 [ALC1220_FIXUP_CLEVO_PB51ED_PINS] = {
Jeremy Soller7f665b12019-02-13 10:56:19 -07002393 .type = HDA_FIXUP_PINS,
2394 .v.pins = (const struct hda_pintbl[]) {
2395 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
2396 {}
2397 },
2398 .chained = true,
Richard Sailer80690a22019-04-02 15:52:04 +02002399 .chain_id = ALC1220_FIXUP_CLEVO_PB51ED,
Jeremy Soller7f665b12019-02-13 10:56:19 -07002400 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02002401};
2402
2403static const struct snd_pci_quirk alc882_fixup_tbl[] = {
Takashi Iwai8812c4f2011-11-09 17:39:15 +01002404 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_FIXUP_ACER_EAPD),
2405 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
Takashi Iwaib5d724b2015-06-02 19:57:08 +02002406 SND_PCI_QUIRK(0x1025, 0x0107, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
Takashi Iwai8812c4f2011-11-09 17:39:15 +01002407 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_FIXUP_ACER_EAPD),
2408 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
2409 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_FIXUP_ACER_EAPD),
2410 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_FIXUP_ACER_EAPD),
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002411 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
2412 ALC882_FIXUP_ACER_ASPIRE_4930G),
2413 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
2414 ALC882_FIXUP_ACER_ASPIRE_4930G),
2415 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
2416 ALC882_FIXUP_ACER_ASPIRE_8930G),
2417 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
2418 ALC882_FIXUP_ACER_ASPIRE_8930G),
2419 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
2420 ALC882_FIXUP_ACER_ASPIRE_4930G),
2421 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
2422 ALC882_FIXUP_ACER_ASPIRE_4930G),
2423 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
2424 ALC882_FIXUP_ACER_ASPIRE_4930G),
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002425 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", ALC882_FIXUP_PB_M5210),
Takashi Iwaif5c53d82012-05-07 10:07:33 +02002426 SND_PCI_QUIRK(0x1025, 0x021e, "Acer Aspire 5739G",
2427 ALC882_FIXUP_ACER_ASPIRE_4930G),
Takashi Iwai02a237b2012-02-13 15:25:07 +01002428 SND_PCI_QUIRK(0x1025, 0x0259, "Acer Aspire 5935", ALC889_FIXUP_DAC_ROUTE),
Takashi Iwaife97da12012-04-12 08:00:19 +02002429 SND_PCI_QUIRK(0x1025, 0x026b, "Acer Aspire 8940G", ALC882_FIXUP_ACER_ASPIRE_8930G),
Takashi Iwaiac9b1cd2011-11-09 17:45:55 +01002430 SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", ALC882_FIXUP_ACER_ASPIRE_7736),
Takashi Iwai177943a32011-11-09 12:55:18 +01002431 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_FIXUP_EAPD),
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002432 SND_PCI_QUIRK(0x1043, 0x1873, "ASUS W90V", ALC882_FIXUP_ASUS_W90V),
Takashi Iwai68ef0562011-11-09 18:24:44 +01002433 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_FIXUP_ASUS_W2JC),
Takashi Iwai0e7cc2e2011-11-09 12:42:48 +01002434 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_FIXUP_EEE1601),
Takashi Iwai1f0bbf02013-11-28 15:21:21 +01002435 SND_PCI_QUIRK(0x1043, 0x84bc, "ASUS ET2700", ALC887_FIXUP_ASUS_BASS),
Takashi Iwai85bcf962016-12-06 16:20:36 +01002436 SND_PCI_QUIRK(0x1043, 0x8691, "ASUS ROG Ranger VIII", ALC882_FIXUP_GPIO3),
Takashi Iwaiac9b1cd2011-11-09 17:45:55 +01002437 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT),
Takashi Iwaie427c232012-07-29 10:04:08 +02002438 SND_PCI_QUIRK(0x104d, 0x905a, "Sony Vaio Z", ALC882_FIXUP_NO_PRIMARY_HP),
Sergei A. Trusov3f3c3712017-08-02 20:23:48 +10002439 SND_PCI_QUIRK(0x104d, 0x9060, "Sony Vaio VPCL14M1R", ALC882_FIXUP_NO_PRIMARY_HP),
Fernando Luis Vázquez Cao12e31a72013-02-12 16:47:44 +09002440 SND_PCI_QUIRK(0x104d, 0x9043, "Sony Vaio VGC-LN51JGB", ALC882_FIXUP_NO_PRIMARY_HP),
Takashi Iwaic44d9b12016-02-07 09:38:26 +01002441 SND_PCI_QUIRK(0x104d, 0x9044, "Sony VAIO AiO", ALC882_FIXUP_NO_PRIMARY_HP),
Takashi Iwai56710872011-11-14 17:42:11 +01002442
2443 /* All Apple entries are in codec SSIDs */
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002444 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC889_FIXUP_MBP_VREF),
2445 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC889_FIXUP_MBP_VREF),
2446 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF),
Takashi Iwaic20f31e2014-02-03 11:02:10 +01002447 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC889_FIXUP_MP11_VREF),
Takashi Iwai56710872011-11-14 17:42:11 +01002448 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_FIXUP_MACPRO_GPIO),
2449 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_FIXUP_MACPRO_GPIO),
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002450 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC889_FIXUP_MBP_VREF),
2451 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889_FIXUP_MBP_VREF),
Takashi Iwai56710872011-11-14 17:42:11 +01002452 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_FIXUP_EAPD),
Adrien Vergée7729a42014-01-24 14:56:14 -05002453 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC889_FIXUP_MBA11_VREF),
Takashi Iwai0756f092013-12-04 13:59:45 +01002454 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC889_FIXUP_MBA21_VREF),
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002455 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889_FIXUP_MBP_VREF),
2456 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF),
Takashi Iwai56710872011-11-14 17:42:11 +01002457 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_FIXUP_MACPRO_GPIO),
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002458 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC889_FIXUP_IMAC91_VREF),
2459 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC889_FIXUP_IMAC91_VREF),
2460 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC889_FIXUP_IMAC91_VREF),
Mario Kleiner9f660a12015-12-22 00:45:43 +01002461 SND_PCI_QUIRK(0x106b, 0x4200, "Mac Pro 4,1/5,1", ALC889_FIXUP_MP41_VREF),
Takashi Iwai05193632012-11-12 10:07:36 +01002462 SND_PCI_QUIRK(0x106b, 0x4300, "iMac 9,1", ALC889_FIXUP_IMAC91_VREF),
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002463 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC889_FIXUP_IMAC91_VREF),
2464 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC889_FIXUP_IMAC91_VREF),
Takashi Iwai649ccd02015-07-30 22:30:29 +02002465 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC889_FIXUP_MBA11_VREF),
Takashi Iwai56710872011-11-14 17:42:11 +01002466
Takashi Iwai7a6069b2011-11-09 15:22:01 +01002467 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC882_FIXUP_EAPD),
David Henningssonb2c53e22014-01-01 14:01:34 +01002468 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3/Z87X-UD3H", ALC889_FIXUP_FRONT_HP_NO_PRESENCE),
Takashi Iwai7beb3a62017-04-10 18:05:52 +02002469 SND_PCI_QUIRK(0x1458, 0xa0b8, "Gigabyte AZ370-Gaming", ALC1220_FIXUP_GB_DUAL_CODECS),
Christian Lachner0d45e862020-02-23 10:24:16 +01002470 SND_PCI_QUIRK(0x1458, 0xa0cd, "Gigabyte X570 Aorus Master", ALC1220_FIXUP_CLEVO_P950),
Christian Lachnerd9e8fe02020-05-18 07:38:44 +02002471 SND_PCI_QUIRK(0x1458, 0xa0ce, "Gigabyte X570 Aorus Xtreme", ALC1220_FIXUP_CLEVO_P950),
Takashi Iwaia0b03952020-06-16 15:21:50 +02002472 SND_PCI_QUIRK(0x1462, 0x11f7, "MSI-GE63", ALC1220_FIXUP_CLEVO_P950),
Takashi Iwaia655e2b2020-02-17 16:19:47 +01002473 SND_PCI_QUIRK(0x1462, 0x1228, "MSI-GP63", ALC1220_FIXUP_CLEVO_P950),
Takashi Iwai1d3aa4a2020-04-08 15:56:45 +02002474 SND_PCI_QUIRK(0x1462, 0x1275, "MSI-GL63", ALC1220_FIXUP_CLEVO_P950),
Takashi Iwai7dafba32020-02-12 09:10:47 +01002475 SND_PCI_QUIRK(0x1462, 0x1276, "MSI-GL73", ALC1220_FIXUP_CLEVO_P950),
Takashi Iwaicc5049a2020-02-18 09:09:15 +01002476 SND_PCI_QUIRK(0x1462, 0x1293, "MSI-GP65", ALC1220_FIXUP_CLEVO_P950),
Takashi Iwaid2c3b142017-06-01 09:35:30 +02002477 SND_PCI_QUIRK(0x1462, 0x7350, "MSI-7350", ALC889_FIXUP_CD),
Dan Crawford15cbff32020-08-29 12:49:46 +10002478 SND_PCI_QUIRK(0x1462, 0x9c37, "MSI X570-A PRO", ALC1220_FIXUP_CLEVO_P950),
Takashi Iwai63691582017-05-22 16:32:46 +02002479 SND_PCI_QUIRK(0x1462, 0xda57, "MSI Z270-Gaming", ALC1220_FIXUP_GB_DUAL_CODECS),
Takashi Iwaid2c3b142017-06-01 09:35:30 +02002480 SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3),
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002481 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX),
Peisen0202f5c2017-10-26 10:35:36 +08002482 SND_PCI_QUIRK(0x1558, 0x9501, "Clevo P950HR", ALC1220_FIXUP_CLEVO_P950),
Takashi Iwaif3d737b2018-07-17 17:08:32 +02002483 SND_PCI_QUIRK(0x1558, 0x95e1, "Clevo P95xER", ALC1220_FIXUP_CLEVO_P950),
Jeremy Soller2f0d5202018-05-07 09:28:45 -06002484 SND_PCI_QUIRK(0x1558, 0x95e2, "Clevo P950ER", ALC1220_FIXUP_CLEVO_P950),
Richard Sailer503d90b2019-06-19 13:33:11 +02002485 SND_PCI_QUIRK(0x1558, 0x96e1, "Clevo P960[ER][CDFN]-K", ALC1220_FIXUP_CLEVO_P950),
2486 SND_PCI_QUIRK(0x1558, 0x97e1, "Clevo P970[ER][CDFN]", ALC1220_FIXUP_CLEVO_P950),
2487 SND_PCI_QUIRK(0x1558, 0x65d1, "Clevo PB51[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
2488 SND_PCI_QUIRK(0x1558, 0x67d1, "Clevo PB71[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
PeiSen Hou259eb822020-05-19 08:50:12 +02002489 SND_PCI_QUIRK(0x1558, 0x50d3, "Clevo PC50[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
2490 SND_PCI_QUIRK(0x1558, 0x70d1, "Clevo PC70[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
2491 SND_PCI_QUIRK(0x1558, 0x7714, "Clevo X170", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
Takashi Iwai7a6069b2011-11-09 15:22:01 +01002492 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD),
2493 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD),
Takashi Iwaiac9b1cd2011-11-09 17:45:55 +01002494 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", ALC882_FIXUP_LENOVO_Y530),
Takashi Iwai68ef0562011-11-09 18:24:44 +01002495 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_FIXUP_COEF),
Takashi Iwai1d045db2011-07-07 18:23:21 +02002496 {}
2497};
2498
Takashi Iwai1727a772013-01-10 09:52:52 +01002499static const struct hda_model_fixup alc882_fixup_models[] = {
Takashi Iwai772c2912018-06-26 17:17:53 +02002500 {.id = ALC882_FIXUP_ABIT_AW9D_MAX, .name = "abit-aw9d"},
2501 {.id = ALC882_FIXUP_LENOVO_Y530, .name = "lenovo-y530"},
2502 {.id = ALC882_FIXUP_ACER_ASPIRE_7736, .name = "acer-aspire-7736"},
2503 {.id = ALC882_FIXUP_ASUS_W90V, .name = "asus-w90v"},
2504 {.id = ALC889_FIXUP_CD, .name = "cd"},
2505 {.id = ALC889_FIXUP_FRONT_HP_NO_PRESENCE, .name = "no-front-hp"},
2506 {.id = ALC889_FIXUP_VAIO_TT, .name = "vaio-tt"},
2507 {.id = ALC888_FIXUP_EEE1601, .name = "eee1601"},
2508 {.id = ALC882_FIXUP_EAPD, .name = "alc882-eapd"},
2509 {.id = ALC883_FIXUP_EAPD, .name = "alc883-eapd"},
2510 {.id = ALC882_FIXUP_GPIO1, .name = "gpio1"},
2511 {.id = ALC882_FIXUP_GPIO2, .name = "gpio2"},
2512 {.id = ALC882_FIXUP_GPIO3, .name = "gpio3"},
2513 {.id = ALC889_FIXUP_COEF, .name = "alc889-coef"},
2514 {.id = ALC882_FIXUP_ASUS_W2JC, .name = "asus-w2jc"},
Takashi Iwai912093b2012-04-11 14:03:41 +02002515 {.id = ALC882_FIXUP_ACER_ASPIRE_4930G, .name = "acer-aspire-4930g"},
2516 {.id = ALC882_FIXUP_ACER_ASPIRE_8930G, .name = "acer-aspire-8930g"},
2517 {.id = ALC883_FIXUP_ACER_EAPD, .name = "acer-aspire"},
Takashi Iwai772c2912018-06-26 17:17:53 +02002518 {.id = ALC885_FIXUP_MACPRO_GPIO, .name = "macpro-gpio"},
2519 {.id = ALC889_FIXUP_DAC_ROUTE, .name = "dac-route"},
2520 {.id = ALC889_FIXUP_MBP_VREF, .name = "mbp-vref"},
2521 {.id = ALC889_FIXUP_IMAC91_VREF, .name = "imac91-vref"},
2522 {.id = ALC889_FIXUP_MBA11_VREF, .name = "mba11-vref"},
2523 {.id = ALC889_FIXUP_MBA21_VREF, .name = "mba21-vref"},
2524 {.id = ALC889_FIXUP_MP11_VREF, .name = "mp11-vref"},
2525 {.id = ALC889_FIXUP_MP41_VREF, .name = "mp41-vref"},
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002526 {.id = ALC882_FIXUP_INV_DMIC, .name = "inv-dmic"},
Takashi Iwaie427c232012-07-29 10:04:08 +02002527 {.id = ALC882_FIXUP_NO_PRIMARY_HP, .name = "no-primary-hp"},
Takashi Iwai772c2912018-06-26 17:17:53 +02002528 {.id = ALC887_FIXUP_ASUS_BASS, .name = "asus-bass"},
Takashi Iwaiba90d6a2017-05-22 16:38:47 +02002529 {.id = ALC1220_FIXUP_GB_DUAL_CODECS, .name = "dual-codecs"},
Takashi Iwai772c2912018-06-26 17:17:53 +02002530 {.id = ALC1220_FIXUP_CLEVO_P950, .name = "clevo-p950"},
Takashi Iwai912093b2012-04-11 14:03:41 +02002531 {}
2532};
2533
Takashi Iwai1d045db2011-07-07 18:23:21 +02002534/*
2535 * BIOS auto configuration
2536 */
2537/* almost identical with ALC880 parser... */
2538static int alc882_parse_auto_config(struct hda_codec *codec)
2539{
Takashi Iwai1d045db2011-07-07 18:23:21 +02002540 static const hda_nid_t alc882_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002541 static const hda_nid_t alc882_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2542 return alc_parse_auto_config(codec, alc882_ignore, alc882_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002543}
2544
Takashi Iwai1d045db2011-07-07 18:23:21 +02002545/*
2546 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002547static int patch_alc882(struct hda_codec *codec)
2548{
2549 struct alc_spec *spec;
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002550 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002551
Takashi Iwai3de95172012-05-07 18:03:15 +02002552 err = alc_alloc_spec(codec, 0x0b);
2553 if (err < 0)
2554 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002555
Takashi Iwai3de95172012-05-07 18:03:15 +02002556 spec = codec->spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002557
Takashi Iwai7639a062015-03-03 10:07:24 +01002558 switch (codec->core.vendor_id) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002559 case 0x10ec0882:
2560 case 0x10ec0885:
Takashi Iwaiacf08082014-09-02 07:21:56 +02002561 case 0x10ec0900:
Kailang Yang6d9ffcf2020-01-03 16:24:06 +08002562 case 0x10ec0b00:
Kailang Yanga535ad52017-01-16 16:59:26 +08002563 case 0x10ec1220:
Takashi Iwai1d045db2011-07-07 18:23:21 +02002564 break;
2565 default:
2566 /* ALC883 and variants */
2567 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
2568 break;
2569 }
2570
Takashi Iwaic9af7532019-05-10 11:01:43 +02002571 alc_pre_init(codec);
2572
Takashi Iwai1727a772013-01-10 09:52:52 +01002573 snd_hda_pick_fixup(codec, alc882_fixup_models, alc882_fixup_tbl,
Takashi Iwai912093b2012-04-11 14:03:41 +02002574 alc882_fixups);
Takashi Iwai1727a772013-01-10 09:52:52 +01002575 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002576
2577 alc_auto_parse_customize_define(codec);
2578
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002579 if (has_cdefine_beep(codec))
2580 spec->gen.beep_nid = 0x01;
2581
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002582 /* automatic parse from the BIOS config */
2583 err = alc882_parse_auto_config(codec);
2584 if (err < 0)
2585 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002586
Takashi Iwaifea80fa2018-06-20 12:52:46 +02002587 if (!spec->gen.no_analog && spec->gen.beep_nid) {
2588 err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
2589 if (err < 0)
2590 goto error;
2591 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02002592
Takashi Iwai1727a772013-01-10 09:52:52 +01002593 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01002594
Takashi Iwai1d045db2011-07-07 18:23:21 +02002595 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02002596
2597 error:
2598 alc_free(codec);
2599 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002600}
2601
2602
2603/*
2604 * ALC262 support
2605 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002606static int alc262_parse_auto_config(struct hda_codec *codec)
2607{
Takashi Iwai1d045db2011-07-07 18:23:21 +02002608 static const hda_nid_t alc262_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002609 static const hda_nid_t alc262_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2610 return alc_parse_auto_config(codec, alc262_ignore, alc262_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002611}
2612
2613/*
2614 * Pin config fixes
2615 */
2616enum {
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002617 ALC262_FIXUP_FSC_H270,
Takashi Iwai7513e6d2013-01-18 15:41:34 +01002618 ALC262_FIXUP_FSC_S7110,
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002619 ALC262_FIXUP_HP_Z200,
2620 ALC262_FIXUP_TYAN,
Takashi Iwaic4701502011-11-07 14:20:07 +01002621 ALC262_FIXUP_LENOVO_3000,
Takashi Iwaib42590b2011-11-07 14:41:01 +01002622 ALC262_FIXUP_BENQ,
2623 ALC262_FIXUP_BENQ_T31,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002624 ALC262_FIXUP_INV_DMIC,
Mengdong Linb5c66112013-11-29 00:35:35 -05002625 ALC262_FIXUP_INTEL_BAYLEYBAY,
Takashi Iwai1d045db2011-07-07 18:23:21 +02002626};
2627
Takashi Iwai1727a772013-01-10 09:52:52 +01002628static const struct hda_fixup alc262_fixups[] = {
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002629 [ALC262_FIXUP_FSC_H270] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002630 .type = HDA_FIXUP_PINS,
2631 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002632 { 0x14, 0x99130110 }, /* speaker */
2633 { 0x15, 0x0221142f }, /* front HP */
2634 { 0x1b, 0x0121141f }, /* rear HP */
2635 { }
2636 }
2637 },
Takashi Iwai7513e6d2013-01-18 15:41:34 +01002638 [ALC262_FIXUP_FSC_S7110] = {
2639 .type = HDA_FIXUP_PINS,
2640 .v.pins = (const struct hda_pintbl[]) {
2641 { 0x15, 0x90170110 }, /* speaker */
2642 { }
2643 },
2644 .chained = true,
2645 .chain_id = ALC262_FIXUP_BENQ,
2646 },
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002647 [ALC262_FIXUP_HP_Z200] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002648 .type = HDA_FIXUP_PINS,
2649 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002650 { 0x16, 0x99130120 }, /* internal speaker */
2651 { }
2652 }
2653 },
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002654 [ALC262_FIXUP_TYAN] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002655 .type = HDA_FIXUP_PINS,
2656 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002657 { 0x14, 0x1993e1f0 }, /* int AUX */
2658 { }
2659 }
2660 },
Takashi Iwaic4701502011-11-07 14:20:07 +01002661 [ALC262_FIXUP_LENOVO_3000] = {
Takashi Iwaifd108212013-01-10 10:18:14 +01002662 .type = HDA_FIXUP_PINCTLS,
2663 .v.pins = (const struct hda_pintbl[]) {
2664 { 0x19, PIN_VREF50 },
Takashi Iwaib42590b2011-11-07 14:41:01 +01002665 {}
2666 },
2667 .chained = true,
2668 .chain_id = ALC262_FIXUP_BENQ,
2669 },
2670 [ALC262_FIXUP_BENQ] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002671 .type = HDA_FIXUP_VERBS,
Takashi Iwaib42590b2011-11-07 14:41:01 +01002672 .v.verbs = (const struct hda_verb[]) {
Takashi Iwaic4701502011-11-07 14:20:07 +01002673 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2674 { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
2675 {}
2676 }
2677 },
Takashi Iwaib42590b2011-11-07 14:41:01 +01002678 [ALC262_FIXUP_BENQ_T31] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002679 .type = HDA_FIXUP_VERBS,
Takashi Iwaib42590b2011-11-07 14:41:01 +01002680 .v.verbs = (const struct hda_verb[]) {
2681 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2682 { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
2683 {}
2684 }
2685 },
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002686 [ALC262_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002687 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02002688 .v.func = alc_fixup_inv_dmic,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002689 },
Mengdong Linb5c66112013-11-29 00:35:35 -05002690 [ALC262_FIXUP_INTEL_BAYLEYBAY] = {
2691 .type = HDA_FIXUP_FUNC,
2692 .v.func = alc_fixup_no_depop_delay,
2693 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02002694};
2695
2696static const struct snd_pci_quirk alc262_fixup_tbl[] = {
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002697 SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", ALC262_FIXUP_HP_Z200),
Takashi Iwai7513e6d2013-01-18 15:41:34 +01002698 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu Lifebook S7110", ALC262_FIXUP_FSC_S7110),
Takashi Iwai3dcd3be2011-11-07 14:59:40 +01002699 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FIXUP_BENQ),
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002700 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_FIXUP_TYAN),
Takashi Iwai275ec0c2018-06-22 12:17:45 +02002701 SND_PCI_QUIRK(0x1734, 0x1141, "FSC ESPRIMO U9210", ALC262_FIXUP_FSC_H270),
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002702 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", ALC262_FIXUP_FSC_H270),
Takashi Iwaic4701502011-11-07 14:20:07 +01002703 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000", ALC262_FIXUP_LENOVO_3000),
Takashi Iwaib42590b2011-11-07 14:41:01 +01002704 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_FIXUP_BENQ),
2705 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_FIXUP_BENQ_T31),
Mengdong Linb5c66112013-11-29 00:35:35 -05002706 SND_PCI_QUIRK(0x8086, 0x7270, "BayleyBay", ALC262_FIXUP_INTEL_BAYLEYBAY),
Takashi Iwai1d045db2011-07-07 18:23:21 +02002707 {}
2708};
2709
Takashi Iwai1727a772013-01-10 09:52:52 +01002710static const struct hda_model_fixup alc262_fixup_models[] = {
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002711 {.id = ALC262_FIXUP_INV_DMIC, .name = "inv-dmic"},
Takashi Iwaie43c44d2018-06-26 17:02:08 +02002712 {.id = ALC262_FIXUP_FSC_H270, .name = "fsc-h270"},
2713 {.id = ALC262_FIXUP_FSC_S7110, .name = "fsc-s7110"},
2714 {.id = ALC262_FIXUP_HP_Z200, .name = "hp-z200"},
2715 {.id = ALC262_FIXUP_TYAN, .name = "tyan"},
2716 {.id = ALC262_FIXUP_LENOVO_3000, .name = "lenovo-3000"},
2717 {.id = ALC262_FIXUP_BENQ, .name = "benq"},
2718 {.id = ALC262_FIXUP_BENQ_T31, .name = "benq-t31"},
2719 {.id = ALC262_FIXUP_INTEL_BAYLEYBAY, .name = "bayleybay"},
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002720 {}
2721};
Takashi Iwai1d045db2011-07-07 18:23:21 +02002722
Takashi Iwai1d045db2011-07-07 18:23:21 +02002723/*
2724 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002725static int patch_alc262(struct hda_codec *codec)
2726{
2727 struct alc_spec *spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002728 int err;
2729
Takashi Iwai3de95172012-05-07 18:03:15 +02002730 err = alc_alloc_spec(codec, 0x0b);
2731 if (err < 0)
2732 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002733
Takashi Iwai3de95172012-05-07 18:03:15 +02002734 spec = codec->spec;
Takashi Iwai08c189f2012-12-19 15:22:24 +01002735 spec->gen.shared_mic_vref_pin = 0x18;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002736
Takashi Iwai225068a2015-05-29 10:42:14 +02002737 spec->shutup = alc_eapd_shutup;
2738
Takashi Iwai1d045db2011-07-07 18:23:21 +02002739#if 0
2740 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
2741 * under-run
2742 */
Takashi Iwai98b24882014-08-18 13:47:50 +02002743 alc_update_coefex_idx(codec, 0x1a, 7, 0, 0x80);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002744#endif
Takashi Iwai1d045db2011-07-07 18:23:21 +02002745 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
2746
Takashi Iwaic9af7532019-05-10 11:01:43 +02002747 alc_pre_init(codec);
2748
Takashi Iwai1727a772013-01-10 09:52:52 +01002749 snd_hda_pick_fixup(codec, alc262_fixup_models, alc262_fixup_tbl,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002750 alc262_fixups);
Takashi Iwai1727a772013-01-10 09:52:52 +01002751 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002752
Takashi Iwaiaf741c12012-05-07 18:09:48 +02002753 alc_auto_parse_customize_define(codec);
2754
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002755 if (has_cdefine_beep(codec))
2756 spec->gen.beep_nid = 0x01;
2757
Takashi Iwai42399f72011-11-07 17:18:44 +01002758 /* automatic parse from the BIOS config */
2759 err = alc262_parse_auto_config(codec);
2760 if (err < 0)
2761 goto error;
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002762
Takashi Iwaifea80fa2018-06-20 12:52:46 +02002763 if (!spec->gen.no_analog && spec->gen.beep_nid) {
2764 err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
2765 if (err < 0)
2766 goto error;
2767 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02002768
Takashi Iwai1727a772013-01-10 09:52:52 +01002769 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01002770
Takashi Iwai1d045db2011-07-07 18:23:21 +02002771 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02002772
2773 error:
2774 alc_free(codec);
2775 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002776}
2777
2778/*
2779 * ALC268
2780 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002781/* bind Beep switches of both NID 0x0f and 0x10 */
Takashi Iwaia7177772017-05-10 12:04:08 +02002782static int alc268_beep_switch_put(struct snd_kcontrol *kcontrol,
2783 struct snd_ctl_elem_value *ucontrol)
2784{
2785 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2786 unsigned long pval;
2787 int err;
2788
2789 mutex_lock(&codec->control_mutex);
2790 pval = kcontrol->private_value;
2791 kcontrol->private_value = (pval & ~0xff) | 0x0f;
2792 err = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
2793 if (err >= 0) {
2794 kcontrol->private_value = (pval & ~0xff) | 0x10;
2795 err = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
2796 }
2797 kcontrol->private_value = pval;
2798 mutex_unlock(&codec->control_mutex);
2799 return err;
2800}
Takashi Iwai1d045db2011-07-07 18:23:21 +02002801
2802static const struct snd_kcontrol_new alc268_beep_mixer[] = {
2803 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
Takashi Iwaia7177772017-05-10 12:04:08 +02002804 {
2805 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2806 .name = "Beep Playback Switch",
2807 .subdevice = HDA_SUBDEV_AMP_FLAG,
2808 .info = snd_hda_mixer_amp_switch_info,
2809 .get = snd_hda_mixer_amp_switch_get,
2810 .put = alc268_beep_switch_put,
2811 .private_value = HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT)
2812 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02002813};
2814
2815/* set PCBEEP vol = 0, mute connections */
2816static const struct hda_verb alc268_beep_init_verbs[] = {
2817 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2818 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2819 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2820 { }
2821};
2822
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002823enum {
2824 ALC268_FIXUP_INV_DMIC,
Takashi Iwaicb766402012-10-20 10:55:21 +02002825 ALC268_FIXUP_HP_EAPD,
Takashi Iwai24eff322013-11-04 18:21:08 +01002826 ALC268_FIXUP_SPDIF,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002827};
2828
Takashi Iwai1727a772013-01-10 09:52:52 +01002829static const struct hda_fixup alc268_fixups[] = {
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002830 [ALC268_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002831 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02002832 .v.func = alc_fixup_inv_dmic,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002833 },
Takashi Iwaicb766402012-10-20 10:55:21 +02002834 [ALC268_FIXUP_HP_EAPD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002835 .type = HDA_FIXUP_VERBS,
Takashi Iwaicb766402012-10-20 10:55:21 +02002836 .v.verbs = (const struct hda_verb[]) {
2837 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 0},
2838 {}
2839 }
2840 },
Takashi Iwai24eff322013-11-04 18:21:08 +01002841 [ALC268_FIXUP_SPDIF] = {
2842 .type = HDA_FIXUP_PINS,
2843 .v.pins = (const struct hda_pintbl[]) {
2844 { 0x1e, 0x014b1180 }, /* enable SPDIF out */
2845 {}
2846 }
2847 },
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002848};
2849
Takashi Iwai1727a772013-01-10 09:52:52 +01002850static const struct hda_model_fixup alc268_fixup_models[] = {
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002851 {.id = ALC268_FIXUP_INV_DMIC, .name = "inv-dmic"},
Takashi Iwaicb766402012-10-20 10:55:21 +02002852 {.id = ALC268_FIXUP_HP_EAPD, .name = "hp-eapd"},
Takashi Iwai03bf11c2018-06-26 16:56:41 +02002853 {.id = ALC268_FIXUP_SPDIF, .name = "spdif"},
Takashi Iwaicb766402012-10-20 10:55:21 +02002854 {}
2855};
2856
2857static const struct snd_pci_quirk alc268_fixup_tbl[] = {
Takashi Iwai24eff322013-11-04 18:21:08 +01002858 SND_PCI_QUIRK(0x1025, 0x0139, "Acer TravelMate 6293", ALC268_FIXUP_SPDIF),
David Henningssonfcd8f3b2013-01-28 05:45:47 +01002859 SND_PCI_QUIRK(0x1025, 0x015b, "Acer AOA 150 (ZG5)", ALC268_FIXUP_INV_DMIC),
Takashi Iwaicb766402012-10-20 10:55:21 +02002860 /* below is codec SSID since multiple Toshiba laptops have the
2861 * same PCI SSID 1179:ff00
2862 */
2863 SND_PCI_QUIRK(0x1179, 0xff06, "Toshiba P200", ALC268_FIXUP_HP_EAPD),
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002864 {}
2865};
2866
Takashi Iwai1d045db2011-07-07 18:23:21 +02002867/*
2868 * BIOS auto configuration
2869 */
2870static int alc268_parse_auto_config(struct hda_codec *codec)
2871{
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002872 static const hda_nid_t alc268_ssids[] = { 0x15, 0x1b, 0x14, 0 };
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002873 return alc_parse_auto_config(codec, NULL, alc268_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002874}
2875
Takashi Iwai1d045db2011-07-07 18:23:21 +02002876/*
2877 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002878static int patch_alc268(struct hda_codec *codec)
2879{
2880 struct alc_spec *spec;
Takashi Iwaia5cb4632018-06-20 12:50:11 +02002881 int i, err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002882
Takashi Iwai1d045db2011-07-07 18:23:21 +02002883 /* ALC268 has no aa-loopback mixer */
Takashi Iwai3de95172012-05-07 18:03:15 +02002884 err = alc_alloc_spec(codec, 0);
2885 if (err < 0)
2886 return err;
2887
2888 spec = codec->spec;
Takashi Iwai2722b532019-08-22 09:55:37 +02002889 if (has_cdefine_beep(codec))
2890 spec->gen.beep_nid = 0x01;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002891
Takashi Iwai225068a2015-05-29 10:42:14 +02002892 spec->shutup = alc_eapd_shutup;
2893
Takashi Iwaic9af7532019-05-10 11:01:43 +02002894 alc_pre_init(codec);
2895
Takashi Iwai1727a772013-01-10 09:52:52 +01002896 snd_hda_pick_fixup(codec, alc268_fixup_models, alc268_fixup_tbl, alc268_fixups);
2897 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002898
Takashi Iwai6ebb8052011-08-16 15:15:40 +02002899 /* automatic parse from the BIOS config */
2900 err = alc268_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02002901 if (err < 0)
2902 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002903
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002904 if (err > 0 && !spec->gen.no_analog &&
2905 spec->gen.autocfg.speaker_pins[0] != 0x1d) {
Takashi Iwaia5cb4632018-06-20 12:50:11 +02002906 for (i = 0; i < ARRAY_SIZE(alc268_beep_mixer); i++) {
2907 if (!snd_hda_gen_add_kctl(&spec->gen, NULL,
2908 &alc268_beep_mixer[i])) {
2909 err = -ENOMEM;
2910 goto error;
2911 }
2912 }
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002913 snd_hda_add_verbs(codec, alc268_beep_init_verbs);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002914 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
2915 /* override the amp caps for beep generator */
2916 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
2917 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
2918 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
2919 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
2920 (0 << AC_AMPCAP_MUTE_SHIFT));
2921 }
2922
Takashi Iwai1727a772013-01-10 09:52:52 +01002923 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002924
Takashi Iwai1d045db2011-07-07 18:23:21 +02002925 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02002926
2927 error:
2928 alc_free(codec);
2929 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002930}
2931
2932/*
2933 * ALC269
2934 */
Takashi Iwai08c189f2012-12-19 15:22:24 +01002935
Takashi Iwai1d045db2011-07-07 18:23:21 +02002936static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002937 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002938};
2939
2940static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002941 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002942};
2943
Takashi Iwai1d045db2011-07-07 18:23:21 +02002944/* different alc269-variants */
2945enum {
2946 ALC269_TYPE_ALC269VA,
2947 ALC269_TYPE_ALC269VB,
2948 ALC269_TYPE_ALC269VC,
Kailang Yangadcc70b2012-05-25 08:08:38 +02002949 ALC269_TYPE_ALC269VD,
Kailang Yang065380f2013-01-10 10:25:48 +01002950 ALC269_TYPE_ALC280,
2951 ALC269_TYPE_ALC282,
Kailang Yang2af02be2013-08-22 10:03:50 +02002952 ALC269_TYPE_ALC283,
Kailang Yang065380f2013-01-10 10:25:48 +01002953 ALC269_TYPE_ALC284,
Kailang Yang4731d5d2017-06-30 15:22:57 +08002954 ALC269_TYPE_ALC293,
Kailang Yang7fc7d042013-04-25 11:04:43 +02002955 ALC269_TYPE_ALC286,
Kailang Yang506b62c2014-12-18 17:07:44 +08002956 ALC269_TYPE_ALC298,
Kailang Yang1d04c9d2013-10-24 11:35:18 +02002957 ALC269_TYPE_ALC255,
Kailang Yang4344aec2014-12-17 17:39:05 +08002958 ALC269_TYPE_ALC256,
Kailang Yangf429e7e2017-12-05 15:38:24 +08002959 ALC269_TYPE_ALC257,
Kailang Yang0a6f0602017-06-30 16:00:48 +08002960 ALC269_TYPE_ALC215,
Kailang Yang42314302016-02-03 15:03:50 +08002961 ALC269_TYPE_ALC225,
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08002962 ALC269_TYPE_ALC294,
Kailang Yang1078bef2018-11-08 16:36:15 +08002963 ALC269_TYPE_ALC300,
Kailang Yangf0778872019-10-24 15:13:32 +08002964 ALC269_TYPE_ALC623,
Kailang Yang6fbae352016-05-30 16:44:20 +08002965 ALC269_TYPE_ALC700,
Takashi Iwai1d045db2011-07-07 18:23:21 +02002966};
2967
2968/*
2969 * BIOS auto configuration
2970 */
2971static int alc269_parse_auto_config(struct hda_codec *codec)
2972{
Takashi Iwai1d045db2011-07-07 18:23:21 +02002973 static const hda_nid_t alc269_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002974 static const hda_nid_t alc269_ssids[] = { 0, 0x1b, 0x14, 0x21 };
2975 static const hda_nid_t alc269va_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2976 struct alc_spec *spec = codec->spec;
Kailang Yangadcc70b2012-05-25 08:08:38 +02002977 const hda_nid_t *ssids;
2978
2979 switch (spec->codec_variant) {
2980 case ALC269_TYPE_ALC269VA:
2981 case ALC269_TYPE_ALC269VC:
Kailang Yang065380f2013-01-10 10:25:48 +01002982 case ALC269_TYPE_ALC280:
2983 case ALC269_TYPE_ALC284:
Kailang Yang4731d5d2017-06-30 15:22:57 +08002984 case ALC269_TYPE_ALC293:
Kailang Yangadcc70b2012-05-25 08:08:38 +02002985 ssids = alc269va_ssids;
2986 break;
2987 case ALC269_TYPE_ALC269VB:
2988 case ALC269_TYPE_ALC269VD:
Kailang Yang065380f2013-01-10 10:25:48 +01002989 case ALC269_TYPE_ALC282:
Kailang Yang2af02be2013-08-22 10:03:50 +02002990 case ALC269_TYPE_ALC283:
Kailang Yang7fc7d042013-04-25 11:04:43 +02002991 case ALC269_TYPE_ALC286:
Kailang Yang506b62c2014-12-18 17:07:44 +08002992 case ALC269_TYPE_ALC298:
Kailang Yang1d04c9d2013-10-24 11:35:18 +02002993 case ALC269_TYPE_ALC255:
Kailang Yang4344aec2014-12-17 17:39:05 +08002994 case ALC269_TYPE_ALC256:
Kailang Yangf429e7e2017-12-05 15:38:24 +08002995 case ALC269_TYPE_ALC257:
Kailang Yang0a6f0602017-06-30 16:00:48 +08002996 case ALC269_TYPE_ALC215:
Kailang Yang42314302016-02-03 15:03:50 +08002997 case ALC269_TYPE_ALC225:
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08002998 case ALC269_TYPE_ALC294:
Kailang Yang1078bef2018-11-08 16:36:15 +08002999 case ALC269_TYPE_ALC300:
Kailang Yangf0778872019-10-24 15:13:32 +08003000 case ALC269_TYPE_ALC623:
Kailang Yang6fbae352016-05-30 16:44:20 +08003001 case ALC269_TYPE_ALC700:
Kailang Yangadcc70b2012-05-25 08:08:38 +02003002 ssids = alc269_ssids;
3003 break;
3004 default:
3005 ssids = alc269_ssids;
3006 break;
3007 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02003008
Takashi Iwai3e6179b2011-07-08 16:55:13 +02003009 return alc_parse_auto_config(codec, alc269_ignore, ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02003010}
3011
Hui Wang476c02e2020-03-29 16:20:18 +08003012static const struct hda_jack_keymap alc_headset_btn_keymap[] = {
3013 { SND_JACK_BTN_0, KEY_PLAYPAUSE },
3014 { SND_JACK_BTN_1, KEY_VOICECOMMAND },
3015 { SND_JACK_BTN_2, KEY_VOLUMEUP },
3016 { SND_JACK_BTN_3, KEY_VOLUMEDOWN },
3017 {}
3018};
3019
3020static void alc_headset_btn_callback(struct hda_codec *codec,
3021 struct hda_jack_callback *jack)
3022{
3023 int report = 0;
3024
3025 if (jack->unsol_res & (7 << 13))
3026 report |= SND_JACK_BTN_0;
3027
3028 if (jack->unsol_res & (1 << 16 | 3 << 8))
3029 report |= SND_JACK_BTN_1;
3030
3031 /* Volume up key */
3032 if (jack->unsol_res & (7 << 23))
3033 report |= SND_JACK_BTN_2;
3034
3035 /* Volume down key */
3036 if (jack->unsol_res & (7 << 10))
3037 report |= SND_JACK_BTN_3;
3038
3039 jack->jack->button_state = report;
3040}
3041
3042static void alc_disable_headset_jack_key(struct hda_codec *codec)
3043{
3044 struct alc_spec *spec = codec->spec;
3045
3046 if (!spec->has_hs_key)
3047 return;
3048
3049 switch (codec->core.vendor_id) {
3050 case 0x10ec0215:
3051 case 0x10ec0225:
3052 case 0x10ec0285:
3053 case 0x10ec0295:
3054 case 0x10ec0289:
3055 case 0x10ec0299:
3056 alc_write_coef_idx(codec, 0x48, 0x0);
3057 alc_update_coef_idx(codec, 0x49, 0x0045, 0x0);
3058 alc_update_coef_idx(codec, 0x44, 0x0045 << 8, 0x0);
3059 break;
3060 case 0x10ec0236:
3061 case 0x10ec0256:
3062 alc_write_coef_idx(codec, 0x48, 0x0);
3063 alc_update_coef_idx(codec, 0x49, 0x0045, 0x0);
3064 break;
3065 }
3066}
3067
3068static void alc_enable_headset_jack_key(struct hda_codec *codec)
3069{
3070 struct alc_spec *spec = codec->spec;
3071
3072 if (!spec->has_hs_key)
3073 return;
3074
3075 switch (codec->core.vendor_id) {
3076 case 0x10ec0215:
3077 case 0x10ec0225:
3078 case 0x10ec0285:
3079 case 0x10ec0295:
3080 case 0x10ec0289:
3081 case 0x10ec0299:
3082 alc_write_coef_idx(codec, 0x48, 0xd011);
3083 alc_update_coef_idx(codec, 0x49, 0x007f, 0x0045);
3084 alc_update_coef_idx(codec, 0x44, 0x007f << 8, 0x0045 << 8);
3085 break;
3086 case 0x10ec0236:
3087 case 0x10ec0256:
3088 alc_write_coef_idx(codec, 0x48, 0xd011);
3089 alc_update_coef_idx(codec, 0x49, 0x007f, 0x0045);
3090 break;
3091 }
3092}
3093
3094static void alc_fixup_headset_jack(struct hda_codec *codec,
3095 const struct hda_fixup *fix, int action)
3096{
3097 struct alc_spec *spec = codec->spec;
3098
3099 switch (action) {
3100 case HDA_FIXUP_ACT_PRE_PROBE:
3101 spec->has_hs_key = 1;
3102 snd_hda_jack_detect_enable_callback(codec, 0x55,
3103 alc_headset_btn_callback);
3104 snd_hda_jack_add_kctl(codec, 0x55, "Headset Jack", false,
3105 SND_JACK_HEADSET, alc_headset_btn_keymap);
3106 break;
3107 case HDA_FIXUP_ACT_INIT:
3108 alc_enable_headset_jack_key(codec);
3109 break;
3110 }
3111}
3112
Kailang Yang1387e2d2012-11-08 10:23:18 +01003113static void alc269vb_toggle_power_output(struct hda_codec *codec, int power_up)
Takashi Iwai1d045db2011-07-07 18:23:21 +02003114{
Takashi Iwai98b24882014-08-18 13:47:50 +02003115 alc_update_coef_idx(codec, 0x04, 1 << 11, power_up ? (1 << 11) : 0);
Takashi Iwai1d045db2011-07-07 18:23:21 +02003116}
3117
3118static void alc269_shutup(struct hda_codec *codec)
3119{
Kailang Yangadcc70b2012-05-25 08:08:38 +02003120 struct alc_spec *spec = codec->spec;
3121
Kailang Yang1387e2d2012-11-08 10:23:18 +01003122 if (spec->codec_variant == ALC269_TYPE_ALC269VB)
3123 alc269vb_toggle_power_output(codec, 0);
3124 if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
3125 (alc_get_coef0(codec) & 0x00ff) == 0x018) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02003126 msleep(150);
3127 }
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003128 alc_shutup_pins(codec);
Takashi Iwai1d045db2011-07-07 18:23:21 +02003129}
3130
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01003131static const struct coef_fw alc282_coefs[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02003132 WRITE_COEF(0x03, 0x0002), /* Power Down Control */
Kailang Yang32fa7e42014-10-24 16:26:01 +08003133 UPDATE_COEF(0x05, 0xff3f, 0x0700), /* FIFO and filter clock */
Takashi Iwai54db6c32014-08-18 15:11:19 +02003134 WRITE_COEF(0x07, 0x0200), /* DMIC control */
3135 UPDATE_COEF(0x06, 0x00f0, 0), /* Analog clock */
3136 UPDATE_COEF(0x08, 0xfffc, 0x0c2c), /* JD */
3137 WRITE_COEF(0x0a, 0xcccc), /* JD offset1 */
3138 WRITE_COEF(0x0b, 0xcccc), /* JD offset2 */
3139 WRITE_COEF(0x0e, 0x6e00), /* LDO1/2/3, DAC/ADC */
3140 UPDATE_COEF(0x0f, 0xf800, 0x1000), /* JD */
3141 UPDATE_COEF(0x10, 0xfc00, 0x0c00), /* Capless */
3142 WRITE_COEF(0x6f, 0x0), /* Class D test 4 */
3143 UPDATE_COEF(0x0c, 0xfe00, 0), /* IO power down directly */
3144 WRITE_COEF(0x34, 0xa0c0), /* ANC */
3145 UPDATE_COEF(0x16, 0x0008, 0), /* AGC MUX */
3146 UPDATE_COEF(0x1d, 0x00e0, 0), /* DAC simple content protection */
3147 UPDATE_COEF(0x1f, 0x00e0, 0), /* ADC simple content protection */
3148 WRITE_COEF(0x21, 0x8804), /* DAC ADC Zero Detection */
3149 WRITE_COEF(0x63, 0x2902), /* PLL */
3150 WRITE_COEF(0x68, 0xa080), /* capless control 2 */
3151 WRITE_COEF(0x69, 0x3400), /* capless control 3 */
3152 WRITE_COEF(0x6a, 0x2f3e), /* capless control 4 */
3153 WRITE_COEF(0x6b, 0x0), /* capless control 5 */
3154 UPDATE_COEF(0x6d, 0x0fff, 0x0900), /* class D test 2 */
3155 WRITE_COEF(0x6e, 0x110a), /* class D test 3 */
3156 UPDATE_COEF(0x70, 0x00f8, 0x00d8), /* class D test 5 */
3157 WRITE_COEF(0x71, 0x0014), /* class D test 6 */
3158 WRITE_COEF(0x72, 0xc2ba), /* classD OCP */
3159 UPDATE_COEF(0x77, 0x0f80, 0), /* classD pure DC test */
3160 WRITE_COEF(0x6c, 0xfc06), /* Class D amp control */
3161 {}
3162};
3163
Kailang Yangcb149cb2014-03-18 16:45:32 +08003164static void alc282_restore_default_value(struct hda_codec *codec)
3165{
Takashi Iwai54db6c32014-08-18 15:11:19 +02003166 alc_process_coef_fw(codec, alc282_coefs);
Kailang Yangcb149cb2014-03-18 16:45:32 +08003167}
3168
Kailang Yang7b5c7a02014-03-18 16:15:54 +08003169static void alc282_init(struct hda_codec *codec)
3170{
3171 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003172 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang7b5c7a02014-03-18 16:15:54 +08003173 bool hp_pin_sense;
3174 int coef78;
3175
Kailang Yangcb149cb2014-03-18 16:45:32 +08003176 alc282_restore_default_value(codec);
3177
Kailang Yang7b5c7a02014-03-18 16:15:54 +08003178 if (!hp_pin)
3179 return;
3180 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3181 coef78 = alc_read_coef_idx(codec, 0x78);
3182
3183 /* Index 0x78 Direct Drive HP AMP LPM Control 1 */
3184 /* Headphone capless set to high power mode */
3185 alc_write_coef_idx(codec, 0x78, 0x9004);
3186
3187 if (hp_pin_sense)
3188 msleep(2);
3189
3190 snd_hda_codec_write(codec, hp_pin, 0,
3191 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3192
3193 if (hp_pin_sense)
3194 msleep(85);
3195
3196 snd_hda_codec_write(codec, hp_pin, 0,
3197 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3198
3199 if (hp_pin_sense)
3200 msleep(100);
3201
3202 /* Headphone capless set to normal mode */
3203 alc_write_coef_idx(codec, 0x78, coef78);
3204}
3205
3206static void alc282_shutup(struct hda_codec *codec)
3207{
3208 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003209 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang7b5c7a02014-03-18 16:15:54 +08003210 bool hp_pin_sense;
3211 int coef78;
3212
3213 if (!hp_pin) {
3214 alc269_shutup(codec);
3215 return;
3216 }
3217
3218 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3219 coef78 = alc_read_coef_idx(codec, 0x78);
3220 alc_write_coef_idx(codec, 0x78, 0x9004);
3221
3222 if (hp_pin_sense)
3223 msleep(2);
3224
3225 snd_hda_codec_write(codec, hp_pin, 0,
3226 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3227
3228 if (hp_pin_sense)
3229 msleep(85);
3230
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003231 if (!spec->no_shutup_pins)
3232 snd_hda_codec_write(codec, hp_pin, 0,
3233 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
Kailang Yang7b5c7a02014-03-18 16:15:54 +08003234
3235 if (hp_pin_sense)
3236 msleep(100);
3237
3238 alc_auto_setup_eapd(codec, false);
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003239 alc_shutup_pins(codec);
Kailang Yang7b5c7a02014-03-18 16:15:54 +08003240 alc_write_coef_idx(codec, 0x78, coef78);
3241}
3242
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01003243static const struct coef_fw alc283_coefs[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02003244 WRITE_COEF(0x03, 0x0002), /* Power Down Control */
Kailang Yang56779862014-10-24 16:17:51 +08003245 UPDATE_COEF(0x05, 0xff3f, 0x0700), /* FIFO and filter clock */
Takashi Iwai54db6c32014-08-18 15:11:19 +02003246 WRITE_COEF(0x07, 0x0200), /* DMIC control */
3247 UPDATE_COEF(0x06, 0x00f0, 0), /* Analog clock */
3248 UPDATE_COEF(0x08, 0xfffc, 0x0c2c), /* JD */
3249 WRITE_COEF(0x0a, 0xcccc), /* JD offset1 */
3250 WRITE_COEF(0x0b, 0xcccc), /* JD offset2 */
3251 WRITE_COEF(0x0e, 0x6fc0), /* LDO1/2/3, DAC/ADC */
3252 UPDATE_COEF(0x0f, 0xf800, 0x1000), /* JD */
3253 UPDATE_COEF(0x10, 0xfc00, 0x0c00), /* Capless */
3254 WRITE_COEF(0x3a, 0x0), /* Class D test 4 */
3255 UPDATE_COEF(0x0c, 0xfe00, 0x0), /* IO power down directly */
3256 WRITE_COEF(0x22, 0xa0c0), /* ANC */
3257 UPDATE_COEFEX(0x53, 0x01, 0x000f, 0x0008), /* AGC MUX */
3258 UPDATE_COEF(0x1d, 0x00e0, 0), /* DAC simple content protection */
3259 UPDATE_COEF(0x1f, 0x00e0, 0), /* ADC simple content protection */
3260 WRITE_COEF(0x21, 0x8804), /* DAC ADC Zero Detection */
3261 WRITE_COEF(0x2e, 0x2902), /* PLL */
3262 WRITE_COEF(0x33, 0xa080), /* capless control 2 */
3263 WRITE_COEF(0x34, 0x3400), /* capless control 3 */
3264 WRITE_COEF(0x35, 0x2f3e), /* capless control 4 */
3265 WRITE_COEF(0x36, 0x0), /* capless control 5 */
3266 UPDATE_COEF(0x38, 0x0fff, 0x0900), /* class D test 2 */
3267 WRITE_COEF(0x39, 0x110a), /* class D test 3 */
3268 UPDATE_COEF(0x3b, 0x00f8, 0x00d8), /* class D test 5 */
3269 WRITE_COEF(0x3c, 0x0014), /* class D test 6 */
3270 WRITE_COEF(0x3d, 0xc2ba), /* classD OCP */
3271 UPDATE_COEF(0x42, 0x0f80, 0x0), /* classD pure DC test */
3272 WRITE_COEF(0x49, 0x0), /* test mode */
3273 UPDATE_COEF(0x40, 0xf800, 0x9800), /* Class D DC enable */
3274 UPDATE_COEF(0x42, 0xf000, 0x2000), /* DC offset */
3275 WRITE_COEF(0x37, 0xfc06), /* Class D amp control */
Kailang Yang56779862014-10-24 16:17:51 +08003276 UPDATE_COEF(0x1b, 0x8000, 0), /* HP JD control */
Takashi Iwai54db6c32014-08-18 15:11:19 +02003277 {}
3278};
3279
Kailang Yang6bd55b02014-03-17 13:51:27 +08003280static void alc283_restore_default_value(struct hda_codec *codec)
3281{
Takashi Iwai54db6c32014-08-18 15:11:19 +02003282 alc_process_coef_fw(codec, alc283_coefs);
Kailang Yang6bd55b02014-03-17 13:51:27 +08003283}
3284
Kailang Yang2af02be2013-08-22 10:03:50 +02003285static void alc283_init(struct hda_codec *codec)
3286{
3287 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003288 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang2af02be2013-08-22 10:03:50 +02003289 bool hp_pin_sense;
Kailang Yang2af02be2013-08-22 10:03:50 +02003290
Kailang Yang6bd55b02014-03-17 13:51:27 +08003291 alc283_restore_default_value(codec);
3292
Kailang Yang2af02be2013-08-22 10:03:50 +02003293 if (!hp_pin)
3294 return;
Kailang Yanga59d7192015-04-08 16:34:00 +08003295
3296 msleep(30);
Kailang Yang2af02be2013-08-22 10:03:50 +02003297 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3298
3299 /* Index 0x43 Direct Drive HP AMP LPM Control 1 */
3300 /* Headphone capless set to high power mode */
3301 alc_write_coef_idx(codec, 0x43, 0x9004);
3302
3303 snd_hda_codec_write(codec, hp_pin, 0,
3304 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3305
3306 if (hp_pin_sense)
3307 msleep(85);
3308
3309 snd_hda_codec_write(codec, hp_pin, 0,
3310 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3311
3312 if (hp_pin_sense)
3313 msleep(85);
3314 /* Index 0x46 Combo jack auto switch control 2 */
3315 /* 3k pull low control for Headset jack. */
Takashi Iwai98b24882014-08-18 13:47:50 +02003316 alc_update_coef_idx(codec, 0x46, 3 << 12, 0);
Kailang Yang2af02be2013-08-22 10:03:50 +02003317 /* Headphone capless set to normal mode */
3318 alc_write_coef_idx(codec, 0x43, 0x9614);
3319}
3320
3321static void alc283_shutup(struct hda_codec *codec)
3322{
3323 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003324 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang2af02be2013-08-22 10:03:50 +02003325 bool hp_pin_sense;
Kailang Yang2af02be2013-08-22 10:03:50 +02003326
3327 if (!hp_pin) {
3328 alc269_shutup(codec);
3329 return;
3330 }
3331
3332 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3333
3334 alc_write_coef_idx(codec, 0x43, 0x9004);
3335
Harsha Priyab450b172014-10-09 11:04:56 +00003336 /*depop hp during suspend*/
3337 alc_write_coef_idx(codec, 0x06, 0x2100);
3338
Kailang Yang2af02be2013-08-22 10:03:50 +02003339 snd_hda_codec_write(codec, hp_pin, 0,
3340 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3341
3342 if (hp_pin_sense)
Kailang Yang88011c092013-10-24 15:45:24 +02003343 msleep(100);
Kailang Yang2af02be2013-08-22 10:03:50 +02003344
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003345 if (!spec->no_shutup_pins)
3346 snd_hda_codec_write(codec, hp_pin, 0,
3347 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
Kailang Yang2af02be2013-08-22 10:03:50 +02003348
Takashi Iwai98b24882014-08-18 13:47:50 +02003349 alc_update_coef_idx(codec, 0x46, 0, 3 << 12);
Kailang Yang2af02be2013-08-22 10:03:50 +02003350
3351 if (hp_pin_sense)
Kailang Yang88011c092013-10-24 15:45:24 +02003352 msleep(100);
Kailang Yang0435b3f2014-04-08 17:14:14 +08003353 alc_auto_setup_eapd(codec, false);
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003354 alc_shutup_pins(codec);
Kailang Yang2af02be2013-08-22 10:03:50 +02003355 alc_write_coef_idx(codec, 0x43, 0x9614);
3356}
3357
Kailang Yang4a219ef2017-06-16 16:54:35 +08003358static void alc256_init(struct hda_codec *codec)
3359{
3360 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003361 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang4a219ef2017-06-16 16:54:35 +08003362 bool hp_pin_sense;
3363
3364 if (!hp_pin)
Kailang Yang6447c962019-05-08 16:27:03 +08003365 hp_pin = 0x21;
Kailang Yang4a219ef2017-06-16 16:54:35 +08003366
3367 msleep(30);
3368
3369 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3370
3371 if (hp_pin_sense)
3372 msleep(2);
3373
3374 alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */
Kailang Yang6447c962019-05-08 16:27:03 +08003375 if (spec->ultra_low_power) {
3376 alc_update_coef_idx(codec, 0x03, 1<<1, 1<<1);
3377 alc_update_coef_idx(codec, 0x08, 3<<2, 3<<2);
3378 alc_update_coef_idx(codec, 0x08, 7<<4, 0);
3379 alc_update_coef_idx(codec, 0x3b, 1<<15, 0);
3380 alc_update_coef_idx(codec, 0x0e, 7<<6, 7<<6);
3381 msleep(30);
3382 }
Kailang Yang4a219ef2017-06-16 16:54:35 +08003383
3384 snd_hda_codec_write(codec, hp_pin, 0,
3385 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3386
Kailang Yang6447c962019-05-08 16:27:03 +08003387 if (hp_pin_sense || spec->ultra_low_power)
Kailang Yang4a219ef2017-06-16 16:54:35 +08003388 msleep(85);
3389
3390 snd_hda_codec_write(codec, hp_pin, 0,
3391 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3392
Kailang Yang6447c962019-05-08 16:27:03 +08003393 if (hp_pin_sense || spec->ultra_low_power)
Kailang Yang4a219ef2017-06-16 16:54:35 +08003394 msleep(100);
3395
3396 alc_update_coef_idx(codec, 0x46, 3 << 12, 0);
3397 alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x4); /* Hight power */
Kailang Yang88d42b22018-03-14 16:08:57 +08003398 alc_update_coefex_idx(codec, 0x53, 0x02, 0x8000, 1 << 15); /* Clear bit */
3399 alc_update_coefex_idx(codec, 0x53, 0x02, 0x8000, 0 << 15);
Thomas Hebbc4473742020-03-30 12:09:38 -04003400 /*
3401 * Expose headphone mic (or possibly Line In on some machines) instead
3402 * of PC Beep on 1Ah, and disable 1Ah loopback for all outputs. See
3403 * Documentation/sound/hd-audio/realtek-pc-beep.rst for details of
3404 * this register.
3405 */
3406 alc_write_coef_idx(codec, 0x36, 0x5757);
Kailang Yang4a219ef2017-06-16 16:54:35 +08003407}
3408
3409static void alc256_shutup(struct hda_codec *codec)
3410{
3411 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003412 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang4a219ef2017-06-16 16:54:35 +08003413 bool hp_pin_sense;
3414
Kailang Yang6447c962019-05-08 16:27:03 +08003415 if (!hp_pin)
3416 hp_pin = 0x21;
Kailang Yang4a219ef2017-06-16 16:54:35 +08003417
3418 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3419
3420 if (hp_pin_sense)
3421 msleep(2);
3422
3423 snd_hda_codec_write(codec, hp_pin, 0,
3424 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3425
Kailang Yang6447c962019-05-08 16:27:03 +08003426 if (hp_pin_sense || spec->ultra_low_power)
Kailang Yang4a219ef2017-06-16 16:54:35 +08003427 msleep(85);
3428
Takashi Iwai1c9609e2018-01-19 14:18:34 +01003429 /* 3k pull low control for Headset jack. */
3430 /* NOTE: call this before clearing the pin, otherwise codec stalls */
3431 alc_update_coef_idx(codec, 0x46, 0, 3 << 12);
3432
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003433 if (!spec->no_shutup_pins)
3434 snd_hda_codec_write(codec, hp_pin, 0,
3435 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
Kailang Yang4a219ef2017-06-16 16:54:35 +08003436
Kailang Yang6447c962019-05-08 16:27:03 +08003437 if (hp_pin_sense || spec->ultra_low_power)
Kailang Yang4a219ef2017-06-16 16:54:35 +08003438 msleep(100);
3439
3440 alc_auto_setup_eapd(codec, false);
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003441 alc_shutup_pins(codec);
Kailang Yang6447c962019-05-08 16:27:03 +08003442 if (spec->ultra_low_power) {
3443 msleep(50);
3444 alc_update_coef_idx(codec, 0x03, 1<<1, 0);
3445 alc_update_coef_idx(codec, 0x08, 7<<4, 7<<4);
3446 alc_update_coef_idx(codec, 0x08, 3<<2, 0);
3447 alc_update_coef_idx(codec, 0x3b, 1<<15, 1<<15);
3448 alc_update_coef_idx(codec, 0x0e, 7<<6, 0);
3449 msleep(30);
3450 }
Kailang Yang4a219ef2017-06-16 16:54:35 +08003451}
3452
Kailang Yangda911b12018-01-05 16:50:08 +08003453static void alc225_init(struct hda_codec *codec)
3454{
3455 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003456 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yangda911b12018-01-05 16:50:08 +08003457 bool hp1_pin_sense, hp2_pin_sense;
3458
3459 if (!hp_pin)
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003460 hp_pin = 0x21;
Kailang Yangda911b12018-01-05 16:50:08 +08003461 msleep(30);
3462
3463 hp1_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3464 hp2_pin_sense = snd_hda_jack_detect(codec, 0x16);
3465
3466 if (hp1_pin_sense || hp2_pin_sense)
3467 msleep(2);
3468
3469 alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003470 if (spec->ultra_low_power) {
3471 alc_update_coef_idx(codec, 0x08, 0x0f << 2, 3<<2);
3472 alc_update_coef_idx(codec, 0x0e, 7<<6, 7<<6);
3473 alc_update_coef_idx(codec, 0x33, 1<<11, 0);
3474 msleep(30);
3475 }
Kailang Yangda911b12018-01-05 16:50:08 +08003476
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003477 if (hp1_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003478 snd_hda_codec_write(codec, hp_pin, 0,
3479 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3480 if (hp2_pin_sense)
3481 snd_hda_codec_write(codec, 0x16, 0,
3482 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3483
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003484 if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003485 msleep(85);
3486
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003487 if (hp1_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003488 snd_hda_codec_write(codec, hp_pin, 0,
3489 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3490 if (hp2_pin_sense)
3491 snd_hda_codec_write(codec, 0x16, 0,
3492 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3493
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003494 if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003495 msleep(100);
3496
3497 alc_update_coef_idx(codec, 0x4a, 3 << 10, 0);
3498 alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x4); /* Hight power */
3499}
3500
3501static void alc225_shutup(struct hda_codec *codec)
3502{
3503 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003504 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yangda911b12018-01-05 16:50:08 +08003505 bool hp1_pin_sense, hp2_pin_sense;
3506
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003507 if (!hp_pin)
3508 hp_pin = 0x21;
Hui Wang476c02e2020-03-29 16:20:18 +08003509
3510 alc_disable_headset_jack_key(codec);
Kailang Yangda911b12018-01-05 16:50:08 +08003511 /* 3k pull low control for Headset jack. */
3512 alc_update_coef_idx(codec, 0x4a, 0, 3 << 10);
3513
3514 hp1_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3515 hp2_pin_sense = snd_hda_jack_detect(codec, 0x16);
3516
3517 if (hp1_pin_sense || hp2_pin_sense)
3518 msleep(2);
3519
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003520 if (hp1_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003521 snd_hda_codec_write(codec, hp_pin, 0,
3522 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3523 if (hp2_pin_sense)
3524 snd_hda_codec_write(codec, 0x16, 0,
3525 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3526
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003527 if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003528 msleep(85);
3529
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003530 if (hp1_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003531 snd_hda_codec_write(codec, hp_pin, 0,
3532 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
3533 if (hp2_pin_sense)
3534 snd_hda_codec_write(codec, 0x16, 0,
3535 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
3536
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003537 if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003538 msleep(100);
3539
3540 alc_auto_setup_eapd(codec, false);
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003541 alc_shutup_pins(codec);
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003542 if (spec->ultra_low_power) {
3543 msleep(50);
3544 alc_update_coef_idx(codec, 0x08, 0x0f << 2, 0x0c << 2);
3545 alc_update_coef_idx(codec, 0x0e, 7<<6, 0);
3546 alc_update_coef_idx(codec, 0x33, 1<<11, 1<<11);
3547 alc_update_coef_idx(codec, 0x4a, 3<<4, 2<<4);
3548 msleep(30);
3549 }
Hui Wang476c02e2020-03-29 16:20:18 +08003550
3551 alc_update_coef_idx(codec, 0x4a, 3 << 10, 0);
3552 alc_enable_headset_jack_key(codec);
Kailang Yangda911b12018-01-05 16:50:08 +08003553}
3554
Kailang Yangc2d6af52017-06-21 14:50:54 +08003555static void alc_default_init(struct hda_codec *codec)
3556{
3557 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003558 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yangc2d6af52017-06-21 14:50:54 +08003559 bool hp_pin_sense;
3560
3561 if (!hp_pin)
3562 return;
3563
3564 msleep(30);
3565
3566 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3567
3568 if (hp_pin_sense)
3569 msleep(2);
3570
3571 snd_hda_codec_write(codec, hp_pin, 0,
3572 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3573
3574 if (hp_pin_sense)
3575 msleep(85);
3576
3577 snd_hda_codec_write(codec, hp_pin, 0,
3578 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3579
3580 if (hp_pin_sense)
3581 msleep(100);
3582}
3583
3584static void alc_default_shutup(struct hda_codec *codec)
3585{
3586 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003587 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yangc2d6af52017-06-21 14:50:54 +08003588 bool hp_pin_sense;
3589
3590 if (!hp_pin) {
3591 alc269_shutup(codec);
3592 return;
3593 }
3594
3595 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3596
3597 if (hp_pin_sense)
3598 msleep(2);
3599
3600 snd_hda_codec_write(codec, hp_pin, 0,
3601 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3602
3603 if (hp_pin_sense)
3604 msleep(85);
3605
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003606 if (!spec->no_shutup_pins)
3607 snd_hda_codec_write(codec, hp_pin, 0,
3608 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
Kailang Yangc2d6af52017-06-21 14:50:54 +08003609
3610 if (hp_pin_sense)
3611 msleep(100);
3612
3613 alc_auto_setup_eapd(codec, false);
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003614 alc_shutup_pins(codec);
Kailang Yangc2d6af52017-06-21 14:50:54 +08003615}
3616
Kailang Yang693abe12019-01-29 15:38:21 +08003617static void alc294_hp_init(struct hda_codec *codec)
3618{
3619 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003620 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang693abe12019-01-29 15:38:21 +08003621 int i, val;
3622
3623 if (!hp_pin)
3624 return;
3625
3626 snd_hda_codec_write(codec, hp_pin, 0,
3627 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3628
3629 msleep(100);
3630
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003631 if (!spec->no_shutup_pins)
3632 snd_hda_codec_write(codec, hp_pin, 0,
3633 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
Kailang Yang693abe12019-01-29 15:38:21 +08003634
3635 alc_update_coef_idx(codec, 0x6f, 0x000f, 0);/* Set HP depop to manual mode */
3636 alc_update_coefex_idx(codec, 0x58, 0x00, 0x8000, 0x8000); /* HP depop procedure start */
3637
3638 /* Wait for depop procedure finish */
3639 val = alc_read_coefex_idx(codec, 0x58, 0x01);
3640 for (i = 0; i < 20 && val & 0x0080; i++) {
3641 msleep(50);
3642 val = alc_read_coefex_idx(codec, 0x58, 0x01);
3643 }
3644 /* Set HP depop to auto mode */
3645 alc_update_coef_idx(codec, 0x6f, 0x000f, 0x000b);
3646 msleep(50);
3647}
3648
3649static void alc294_init(struct hda_codec *codec)
3650{
3651 struct alc_spec *spec = codec->spec;
3652
Takashi Iwaif6ef4e02019-01-29 14:14:51 +01003653 /* required only at boot or S4 resume time */
3654 if (!spec->done_hp_init ||
3655 codec->core.dev.power.power_state.event == PM_EVENT_RESTORE) {
Kailang Yang693abe12019-01-29 15:38:21 +08003656 alc294_hp_init(codec);
3657 spec->done_hp_init = true;
3658 }
3659 alc_default_init(codec);
3660}
3661
Kailang Yangad60d502013-06-28 12:03:01 +02003662static void alc5505_coef_set(struct hda_codec *codec, unsigned int index_reg,
3663 unsigned int val)
3664{
3665 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_COEF_INDEX, index_reg >> 1);
3666 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_PROC_COEF, val & 0xffff); /* LSB */
3667 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_PROC_COEF, val >> 16); /* MSB */
3668}
3669
3670static int alc5505_coef_get(struct hda_codec *codec, unsigned int index_reg)
3671{
3672 unsigned int val;
3673
3674 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_COEF_INDEX, index_reg >> 1);
3675 val = snd_hda_codec_read(codec, 0x51, 0, AC_VERB_GET_PROC_COEF, 0)
3676 & 0xffff;
3677 val |= snd_hda_codec_read(codec, 0x51, 0, AC_VERB_GET_PROC_COEF, 0)
3678 << 16;
3679 return val;
3680}
3681
3682static void alc5505_dsp_halt(struct hda_codec *codec)
3683{
3684 unsigned int val;
3685
3686 alc5505_coef_set(codec, 0x3000, 0x000c); /* DSP CPU stop */
3687 alc5505_coef_set(codec, 0x880c, 0x0008); /* DDR enter self refresh */
3688 alc5505_coef_set(codec, 0x61c0, 0x11110080); /* Clock control for PLL and CPU */
3689 alc5505_coef_set(codec, 0x6230, 0xfc0d4011); /* Disable Input OP */
3690 alc5505_coef_set(codec, 0x61b4, 0x040a2b03); /* Stop PLL2 */
3691 alc5505_coef_set(codec, 0x61b0, 0x00005b17); /* Stop PLL1 */
3692 alc5505_coef_set(codec, 0x61b8, 0x04133303); /* Stop PLL3 */
3693 val = alc5505_coef_get(codec, 0x6220);
3694 alc5505_coef_set(codec, 0x6220, (val | 0x3000)); /* switch Ringbuffer clock to DBUS clock */
3695}
3696
3697static void alc5505_dsp_back_from_halt(struct hda_codec *codec)
3698{
3699 alc5505_coef_set(codec, 0x61b8, 0x04133302);
3700 alc5505_coef_set(codec, 0x61b0, 0x00005b16);
3701 alc5505_coef_set(codec, 0x61b4, 0x040a2b02);
3702 alc5505_coef_set(codec, 0x6230, 0xf80d4011);
3703 alc5505_coef_set(codec, 0x6220, 0x2002010f);
3704 alc5505_coef_set(codec, 0x880c, 0x00000004);
3705}
3706
3707static void alc5505_dsp_init(struct hda_codec *codec)
3708{
3709 unsigned int val;
3710
3711 alc5505_dsp_halt(codec);
3712 alc5505_dsp_back_from_halt(codec);
3713 alc5505_coef_set(codec, 0x61b0, 0x5b14); /* PLL1 control */
3714 alc5505_coef_set(codec, 0x61b0, 0x5b16);
3715 alc5505_coef_set(codec, 0x61b4, 0x04132b00); /* PLL2 control */
3716 alc5505_coef_set(codec, 0x61b4, 0x04132b02);
3717 alc5505_coef_set(codec, 0x61b8, 0x041f3300); /* PLL3 control*/
3718 alc5505_coef_set(codec, 0x61b8, 0x041f3302);
3719 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_CODEC_RESET, 0); /* Function reset */
3720 alc5505_coef_set(codec, 0x61b8, 0x041b3302);
3721 alc5505_coef_set(codec, 0x61b8, 0x04173302);
3722 alc5505_coef_set(codec, 0x61b8, 0x04163302);
3723 alc5505_coef_set(codec, 0x8800, 0x348b328b); /* DRAM control */
3724 alc5505_coef_set(codec, 0x8808, 0x00020022); /* DRAM control */
3725 alc5505_coef_set(codec, 0x8818, 0x00000400); /* DRAM control */
3726
3727 val = alc5505_coef_get(codec, 0x6200) >> 16; /* Read revision ID */
3728 if (val <= 3)
3729 alc5505_coef_set(codec, 0x6220, 0x2002010f); /* I/O PAD Configuration */
3730 else
3731 alc5505_coef_set(codec, 0x6220, 0x6002018f);
3732
3733 alc5505_coef_set(codec, 0x61ac, 0x055525f0); /**/
3734 alc5505_coef_set(codec, 0x61c0, 0x12230080); /* Clock control */
3735 alc5505_coef_set(codec, 0x61b4, 0x040e2b02); /* PLL2 control */
3736 alc5505_coef_set(codec, 0x61bc, 0x010234f8); /* OSC Control */
3737 alc5505_coef_set(codec, 0x880c, 0x00000004); /* DRAM Function control */
3738 alc5505_coef_set(codec, 0x880c, 0x00000003);
3739 alc5505_coef_set(codec, 0x880c, 0x00000010);
Takashi Iwaicd63a5f2013-07-05 12:13:59 +02003740
3741#ifdef HALT_REALTEK_ALC5505
3742 alc5505_dsp_halt(codec);
3743#endif
Kailang Yangad60d502013-06-28 12:03:01 +02003744}
3745
Takashi Iwaicd63a5f2013-07-05 12:13:59 +02003746#ifdef HALT_REALTEK_ALC5505
Pierre-Louis Bossart8a718212020-01-11 15:47:35 -06003747#define alc5505_dsp_suspend(codec) do { } while (0) /* NOP */
3748#define alc5505_dsp_resume(codec) do { } while (0) /* NOP */
Takashi Iwaicd63a5f2013-07-05 12:13:59 +02003749#else
3750#define alc5505_dsp_suspend(codec) alc5505_dsp_halt(codec)
3751#define alc5505_dsp_resume(codec) alc5505_dsp_back_from_halt(codec)
3752#endif
3753
Takashi Iwai2a439522011-07-26 09:52:50 +02003754#ifdef CONFIG_PM
Kailang Yangad60d502013-06-28 12:03:01 +02003755static int alc269_suspend(struct hda_codec *codec)
3756{
3757 struct alc_spec *spec = codec->spec;
3758
3759 if (spec->has_alc5505_dsp)
Takashi Iwaicd63a5f2013-07-05 12:13:59 +02003760 alc5505_dsp_suspend(codec);
Kailang Yangad60d502013-06-28 12:03:01 +02003761 return alc_suspend(codec);
3762}
3763
Takashi Iwai1d045db2011-07-07 18:23:21 +02003764static int alc269_resume(struct hda_codec *codec)
3765{
Kailang Yangadcc70b2012-05-25 08:08:38 +02003766 struct alc_spec *spec = codec->spec;
3767
Kailang Yang1387e2d2012-11-08 10:23:18 +01003768 if (spec->codec_variant == ALC269_TYPE_ALC269VB)
3769 alc269vb_toggle_power_output(codec, 0);
3770 if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
Kailang Yangadcc70b2012-05-25 08:08:38 +02003771 (alc_get_coef0(codec) & 0x00ff) == 0x018) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02003772 msleep(150);
3773 }
3774
3775 codec->patch_ops.init(codec);
3776
Kailang Yang1387e2d2012-11-08 10:23:18 +01003777 if (spec->codec_variant == ALC269_TYPE_ALC269VB)
3778 alc269vb_toggle_power_output(codec, 1);
3779 if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
Kailang Yangadcc70b2012-05-25 08:08:38 +02003780 (alc_get_coef0(codec) & 0x00ff) == 0x017) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02003781 msleep(200);
3782 }
3783
Takashi Iwai1a462be2020-01-09 10:01:04 +01003784 snd_hda_regmap_sync(codec);
Takashi Iwai1d045db2011-07-07 18:23:21 +02003785 hda_call_check_power_status(codec, 0x01);
Hui Wangf4753712014-08-19 12:07:03 +08003786
3787 /* on some machine, the BIOS will clear the codec gpio data when enter
3788 * suspend, and won't restore the data after resume, so we restore it
3789 * in the driver.
3790 */
Takashi Iwaid261eec2018-06-19 22:32:29 +02003791 if (spec->gpio_data)
3792 alc_write_gpio_data(codec);
Hui Wangf4753712014-08-19 12:07:03 +08003793
Kailang Yangad60d502013-06-28 12:03:01 +02003794 if (spec->has_alc5505_dsp)
Takashi Iwaicd63a5f2013-07-05 12:13:59 +02003795 alc5505_dsp_resume(codec);
Kailang Yangc5177c82013-07-24 14:39:49 +02003796
Takashi Iwai1d045db2011-07-07 18:23:21 +02003797 return 0;
3798}
Takashi Iwai2a439522011-07-26 09:52:50 +02003799#endif /* CONFIG_PM */
Takashi Iwai1d045db2011-07-07 18:23:21 +02003800
David Henningsson108cc102012-07-20 10:37:25 +02003801static void alc269_fixup_pincfg_no_hp_to_lineout(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003802 const struct hda_fixup *fix, int action)
David Henningsson108cc102012-07-20 10:37:25 +02003803{
3804 struct alc_spec *spec = codec->spec;
3805
Takashi Iwai1727a772013-01-10 09:52:52 +01003806 if (action == HDA_FIXUP_ACT_PRE_PROBE)
David Henningsson108cc102012-07-20 10:37:25 +02003807 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
3808}
3809
Jan-Marek Glogowskifdcc9682018-02-14 11:29:15 +01003810static void alc269_fixup_pincfg_U7x7_headset_mic(struct hda_codec *codec,
3811 const struct hda_fixup *fix,
3812 int action)
3813{
3814 unsigned int cfg_headphone = snd_hda_codec_get_pincfg(codec, 0x21);
3815 unsigned int cfg_headset_mic = snd_hda_codec_get_pincfg(codec, 0x19);
3816
3817 if (cfg_headphone && cfg_headset_mic == 0x411111f0)
3818 snd_hda_codec_set_pincfg(codec, 0x19,
3819 (cfg_headphone & ~AC_DEFCFG_DEVICE) |
3820 (AC_JACK_MIC_IN << AC_DEFCFG_DEVICE_SHIFT));
3821}
3822
Takashi Iwai1d045db2011-07-07 18:23:21 +02003823static void alc269_fixup_hweq(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003824 const struct hda_fixup *fix, int action)
Takashi Iwai1d045db2011-07-07 18:23:21 +02003825{
Takashi Iwai98b24882014-08-18 13:47:50 +02003826 if (action == HDA_FIXUP_ACT_INIT)
3827 alc_update_coef_idx(codec, 0x1e, 0, 0x80);
Takashi Iwai1d045db2011-07-07 18:23:21 +02003828}
3829
David Henningsson7c478f02013-10-11 10:18:46 +02003830static void alc269_fixup_headset_mic(struct hda_codec *codec,
3831 const struct hda_fixup *fix, int action)
3832{
3833 struct alc_spec *spec = codec->spec;
3834
3835 if (action == HDA_FIXUP_ACT_PRE_PROBE)
3836 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
3837}
3838
Takashi Iwai1d045db2011-07-07 18:23:21 +02003839static void alc271_fixup_dmic(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003840 const struct hda_fixup *fix, int action)
Takashi Iwai1d045db2011-07-07 18:23:21 +02003841{
3842 static const struct hda_verb verbs[] = {
3843 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
3844 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
3845 {}
3846 };
3847 unsigned int cfg;
3848
Takashi Iwai7639a062015-03-03 10:07:24 +01003849 if (strcmp(codec->core.chip_name, "ALC271X") &&
3850 strcmp(codec->core.chip_name, "ALC269VB"))
Takashi Iwai1d045db2011-07-07 18:23:21 +02003851 return;
3852 cfg = snd_hda_codec_get_pincfg(codec, 0x12);
3853 if (get_defcfg_connect(cfg) == AC_JACK_PORT_FIXED)
3854 snd_hda_sequence_write(codec, verbs);
3855}
3856
Takashi Iwai017f2a12011-07-09 14:42:25 +02003857static void alc269_fixup_pcm_44k(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003858 const struct hda_fixup *fix, int action)
Takashi Iwai017f2a12011-07-09 14:42:25 +02003859{
3860 struct alc_spec *spec = codec->spec;
3861
Takashi Iwai1727a772013-01-10 09:52:52 +01003862 if (action != HDA_FIXUP_ACT_PROBE)
Takashi Iwai017f2a12011-07-09 14:42:25 +02003863 return;
3864
3865 /* Due to a hardware problem on Lenovo Ideadpad, we need to
3866 * fix the sample rate of analog I/O to 44.1kHz
3867 */
Takashi Iwai08c189f2012-12-19 15:22:24 +01003868 spec->gen.stream_analog_playback = &alc269_44k_pcm_analog_playback;
3869 spec->gen.stream_analog_capture = &alc269_44k_pcm_analog_capture;
Takashi Iwai017f2a12011-07-09 14:42:25 +02003870}
3871
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02003872static void alc269_fixup_stereo_dmic(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003873 const struct hda_fixup *fix, int action)
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02003874{
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02003875 /* The digital-mic unit sends PDM (differential signal) instead of
3876 * the standard PCM, thus you can't record a valid mono stream as is.
3877 * Below is a workaround specific to ALC269 to control the dmic
3878 * signal source as mono.
3879 */
Takashi Iwai98b24882014-08-18 13:47:50 +02003880 if (action == HDA_FIXUP_ACT_INIT)
3881 alc_update_coef_idx(codec, 0x07, 0, 0x80);
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02003882}
3883
Takashi Iwai24519912011-08-16 15:08:49 +02003884static void alc269_quanta_automute(struct hda_codec *codec)
3885{
Takashi Iwai08c189f2012-12-19 15:22:24 +01003886 snd_hda_gen_update_outputs(codec);
Takashi Iwai24519912011-08-16 15:08:49 +02003887
Takashi Iwai1687ccc2014-08-18 13:49:35 +02003888 alc_write_coef_idx(codec, 0x0c, 0x680);
3889 alc_write_coef_idx(codec, 0x0c, 0x480);
Takashi Iwai24519912011-08-16 15:08:49 +02003890}
3891
3892static void alc269_fixup_quanta_mute(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003893 const struct hda_fixup *fix, int action)
Takashi Iwai24519912011-08-16 15:08:49 +02003894{
3895 struct alc_spec *spec = codec->spec;
Takashi Iwai1727a772013-01-10 09:52:52 +01003896 if (action != HDA_FIXUP_ACT_PROBE)
Takashi Iwai24519912011-08-16 15:08:49 +02003897 return;
Takashi Iwai08c189f2012-12-19 15:22:24 +01003898 spec->gen.automute_hook = alc269_quanta_automute;
Takashi Iwai24519912011-08-16 15:08:49 +02003899}
3900
David Henningssond240d1d2013-04-15 12:50:02 +02003901static void alc269_x101_hp_automute_hook(struct hda_codec *codec,
Takashi Iwai1a4f69d2014-09-11 15:22:46 +02003902 struct hda_jack_callback *jack)
David Henningssond240d1d2013-04-15 12:50:02 +02003903{
3904 struct alc_spec *spec = codec->spec;
3905 int vref;
3906 msleep(200);
3907 snd_hda_gen_hp_automute(codec, jack);
3908
3909 vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0;
3910 msleep(100);
3911 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3912 vref);
3913 msleep(500);
3914 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3915 vref);
3916}
3917
Tomas Espeletaa2ef03f2019-08-09 16:37:54 +02003918/*
3919 * Magic sequence to make Huawei Matebook X right speaker working (bko#197801)
3920 */
3921struct hda_alc298_mbxinit {
3922 unsigned char value_0x23;
3923 unsigned char value_0x25;
3924};
3925
3926static void alc298_huawei_mbx_stereo_seq(struct hda_codec *codec,
3927 const struct hda_alc298_mbxinit *initval,
3928 bool first)
3929{
3930 snd_hda_codec_write(codec, 0x06, 0, AC_VERB_SET_DIGI_CONVERT_3, 0x0);
3931 alc_write_coef_idx(codec, 0x26, 0xb000);
3932
3933 if (first)
3934 snd_hda_codec_write(codec, 0x21, 0, AC_VERB_GET_PIN_SENSE, 0x0);
3935
3936 snd_hda_codec_write(codec, 0x6, 0, AC_VERB_SET_DIGI_CONVERT_3, 0x80);
3937 alc_write_coef_idx(codec, 0x26, 0xf000);
3938 alc_write_coef_idx(codec, 0x23, initval->value_0x23);
3939
3940 if (initval->value_0x23 != 0x1e)
3941 alc_write_coef_idx(codec, 0x25, initval->value_0x25);
3942
3943 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0x26);
3944 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, 0xb010);
3945}
3946
3947static void alc298_fixup_huawei_mbx_stereo(struct hda_codec *codec,
3948 const struct hda_fixup *fix,
3949 int action)
3950{
3951 /* Initialization magic */
3952 static const struct hda_alc298_mbxinit dac_init[] = {
3953 {0x0c, 0x00}, {0x0d, 0x00}, {0x0e, 0x00}, {0x0f, 0x00},
3954 {0x10, 0x00}, {0x1a, 0x40}, {0x1b, 0x82}, {0x1c, 0x00},
3955 {0x1d, 0x00}, {0x1e, 0x00}, {0x1f, 0x00},
3956 {0x20, 0xc2}, {0x21, 0xc8}, {0x22, 0x26}, {0x23, 0x24},
3957 {0x27, 0xff}, {0x28, 0xff}, {0x29, 0xff}, {0x2a, 0x8f},
3958 {0x2b, 0x02}, {0x2c, 0x48}, {0x2d, 0x34}, {0x2e, 0x00},
3959 {0x2f, 0x00},
3960 {0x30, 0x00}, {0x31, 0x00}, {0x32, 0x00}, {0x33, 0x00},
3961 {0x34, 0x00}, {0x35, 0x01}, {0x36, 0x93}, {0x37, 0x0c},
3962 {0x38, 0x00}, {0x39, 0x00}, {0x3a, 0xf8}, {0x38, 0x80},
3963 {}
3964 };
3965 const struct hda_alc298_mbxinit *seq;
3966
3967 if (action != HDA_FIXUP_ACT_INIT)
3968 return;
3969
3970 /* Start */
3971 snd_hda_codec_write(codec, 0x06, 0, AC_VERB_SET_DIGI_CONVERT_3, 0x00);
3972 snd_hda_codec_write(codec, 0x06, 0, AC_VERB_SET_DIGI_CONVERT_3, 0x80);
3973 alc_write_coef_idx(codec, 0x26, 0xf000);
3974 alc_write_coef_idx(codec, 0x22, 0x31);
3975 alc_write_coef_idx(codec, 0x23, 0x0b);
3976 alc_write_coef_idx(codec, 0x25, 0x00);
3977 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0x26);
3978 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, 0xb010);
3979
3980 for (seq = dac_init; seq->value_0x23; seq++)
3981 alc298_huawei_mbx_stereo_seq(codec, seq, seq == dac_init);
3982}
3983
David Henningssond240d1d2013-04-15 12:50:02 +02003984static void alc269_fixup_x101_headset_mic(struct hda_codec *codec,
3985 const struct hda_fixup *fix, int action)
3986{
3987 struct alc_spec *spec = codec->spec;
3988 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3989 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
3990 spec->gen.hp_automute_hook = alc269_x101_hp_automute_hook;
3991 }
3992}
3993
Takashi Iwai766538a2020-06-18 13:08:41 +02003994static void alc_update_vref_led(struct hda_codec *codec, hda_nid_t pin,
3995 bool polarity, bool on)
David Henningsson6d3cd5d2013-01-07 12:03:47 +01003996{
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003997 unsigned int pinval;
3998
Takashi Iwai766538a2020-06-18 13:08:41 +02003999 if (!pin)
4000 return;
4001 if (polarity)
4002 on = !on;
4003 pinval = snd_hda_codec_get_pin_target(codec, pin);
Takashi Iwai415d5552014-04-03 11:51:21 +02004004 pinval &= ~AC_PINCTL_VREFEN;
Takashi Iwai766538a2020-06-18 13:08:41 +02004005 pinval |= on ? AC_PINCTL_VREF_80 : AC_PINCTL_VREF_HIZ;
4006 /* temporarily power up/down for setting VREF */
4007 snd_hda_power_up_pm(codec);
4008 snd_hda_set_pin_ctl_cache(codec, pin, pinval);
4009 snd_hda_power_down_pm(codec);
4010}
Takashi Iwai1d045db2011-07-07 18:23:21 +02004011
David Henningsson6d3cd5d2013-01-07 12:03:47 +01004012/* update mute-LED according to the speaker mute state via mic VREF pin */
Takashi Iwai8d3d1ec2020-06-18 13:08:38 +02004013static int vref_mute_led_set(struct led_classdev *led_cdev,
4014 enum led_brightness brightness)
David Henningsson6d3cd5d2013-01-07 12:03:47 +01004015{
Takashi Iwai8d3d1ec2020-06-18 13:08:38 +02004016 struct hda_codec *codec = dev_to_hda_codec(led_cdev->dev->parent);
Takashi Iwai08fb0d02013-01-10 17:33:58 +01004017 struct alc_spec *spec = codec->spec;
Takashi Iwai08fb0d02013-01-10 17:33:58 +01004018
Takashi Iwai766538a2020-06-18 13:08:41 +02004019 alc_update_vref_led(codec, spec->mute_led_nid,
4020 spec->mute_led_polarity, brightness);
Takashi Iwai8d3d1ec2020-06-18 13:08:38 +02004021 return 0;
David Henningsson6d3cd5d2013-01-07 12:03:47 +01004022}
4023
David Henningssond5b6b652013-11-06 10:50:44 +01004024/* Make sure the led works even in runtime suspend */
4025static unsigned int led_power_filter(struct hda_codec *codec,
4026 hda_nid_t nid,
4027 unsigned int power_state)
4028{
4029 struct alc_spec *spec = codec->spec;
4030
Hui Wang50dd9052014-07-08 17:56:15 +08004031 if (power_state != AC_PWRST_D3 || nid == 0 ||
4032 (nid != spec->mute_led_nid && nid != spec->cap_mute_led_nid))
David Henningssond5b6b652013-11-06 10:50:44 +01004033 return power_state;
4034
4035 /* Set pin ctl again, it might have just been set to 0 */
4036 snd_hda_set_pin_ctl(codec, nid,
4037 snd_hda_codec_get_pin_target(codec, nid));
4038
Takashi Iwaicffd3962015-04-09 10:30:25 +02004039 return snd_hda_gen_path_power_filter(codec, nid, power_state);
David Henningssond5b6b652013-11-06 10:50:44 +01004040}
4041
Takashi Iwai08fb0d02013-01-10 17:33:58 +01004042static void alc269_fixup_hp_mute_led(struct hda_codec *codec,
4043 const struct hda_fixup *fix, int action)
David Henningsson6d3cd5d2013-01-07 12:03:47 +01004044{
4045 struct alc_spec *spec = codec->spec;
Takashi Iwai08fb0d02013-01-10 17:33:58 +01004046 const struct dmi_device *dev = NULL;
4047
4048 if (action != HDA_FIXUP_ACT_PRE_PROBE)
4049 return;
4050
4051 while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) {
4052 int pol, pin;
4053 if (sscanf(dev->name, "HP_Mute_LED_%d_%x", &pol, &pin) != 2)
4054 continue;
4055 if (pin < 0x0a || pin >= 0x10)
4056 break;
4057 spec->mute_led_polarity = pol;
4058 spec->mute_led_nid = pin - 0x0a + 0x18;
Takashi Iwai8d3d1ec2020-06-18 13:08:38 +02004059 snd_hda_gen_add_mute_led_cdev(codec, vref_mute_led_set);
David Henningssond5b6b652013-11-06 10:50:44 +01004060 codec->power_filter = led_power_filter;
Takashi Iwai4e76a882014-02-25 12:21:03 +01004061 codec_dbg(codec,
4062 "Detected mute LED for %x:%d\n", spec->mute_led_nid,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01004063 spec->mute_led_polarity);
David Henningsson6d3cd5d2013-01-07 12:03:47 +01004064 break;
4065 }
4066}
4067
Takashi Iwai85c467d2018-05-29 11:38:38 +02004068static void alc269_fixup_hp_mute_led_micx(struct hda_codec *codec,
4069 const struct hda_fixup *fix,
4070 int action, hda_nid_t pin)
David Henningssond06ac142013-02-18 11:41:55 +01004071{
4072 struct alc_spec *spec = codec->spec;
Takashi Iwai85c467d2018-05-29 11:38:38 +02004073
David Henningssond06ac142013-02-18 11:41:55 +01004074 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4075 spec->mute_led_polarity = 0;
Takashi Iwai85c467d2018-05-29 11:38:38 +02004076 spec->mute_led_nid = pin;
Takashi Iwai8d3d1ec2020-06-18 13:08:38 +02004077 snd_hda_gen_add_mute_led_cdev(codec, vref_mute_led_set);
David Henningssond5b6b652013-11-06 10:50:44 +01004078 codec->power_filter = led_power_filter;
David Henningssond06ac142013-02-18 11:41:55 +01004079 }
4080}
4081
Takashi Iwai85c467d2018-05-29 11:38:38 +02004082static void alc269_fixup_hp_mute_led_mic1(struct hda_codec *codec,
4083 const struct hda_fixup *fix, int action)
4084{
4085 alc269_fixup_hp_mute_led_micx(codec, fix, action, 0x18);
4086}
4087
Takashi Iwai08fb0d02013-01-10 17:33:58 +01004088static void alc269_fixup_hp_mute_led_mic2(struct hda_codec *codec,
4089 const struct hda_fixup *fix, int action)
Takashi Iwai420b0fe2012-03-12 12:35:27 +01004090{
Takashi Iwai85c467d2018-05-29 11:38:38 +02004091 alc269_fixup_hp_mute_led_micx(codec, fix, action, 0x19);
Takashi Iwai420b0fe2012-03-12 12:35:27 +01004092}
4093
Tom Briden7f783bd2017-03-25 10:12:01 +00004094static void alc269_fixup_hp_mute_led_mic3(struct hda_codec *codec,
4095 const struct hda_fixup *fix, int action)
4096{
Takashi Iwai85c467d2018-05-29 11:38:38 +02004097 alc269_fixup_hp_mute_led_micx(codec, fix, action, 0x1b);
Tom Briden7f783bd2017-03-25 10:12:01 +00004098}
4099
Takashi Iwai0f32fd192014-11-19 12:16:14 +01004100/* update LED status via GPIO */
4101static void alc_update_gpio_led(struct hda_codec *codec, unsigned int mask,
Kai-Heng Fengdbd13172020-04-30 16:32:51 +08004102 int polarity, bool enabled)
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01004103{
Kai-Heng Fengdbd13172020-04-30 16:32:51 +08004104 if (polarity)
Takashi Iwai0f32fd192014-11-19 12:16:14 +01004105 enabled = !enabled;
Takashi Iwaid261eec2018-06-19 22:32:29 +02004106 alc_update_gpio_data(codec, mask, !enabled); /* muted -> LED on */
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01004107}
4108
Takashi Iwai0f32fd192014-11-19 12:16:14 +01004109/* turn on/off mute LED via GPIO per vmaster hook */
Takashi Iwai8d3d1ec2020-06-18 13:08:38 +02004110static int gpio_mute_led_set(struct led_classdev *led_cdev,
4111 enum led_brightness brightness)
Takashi Iwai0f32fd192014-11-19 12:16:14 +01004112{
Takashi Iwai8d3d1ec2020-06-18 13:08:38 +02004113 struct hda_codec *codec = dev_to_hda_codec(led_cdev->dev->parent);
Takashi Iwai0f32fd192014-11-19 12:16:14 +01004114 struct alc_spec *spec = codec->spec;
4115
Kai-Heng Fengdbd13172020-04-30 16:32:51 +08004116 alc_update_gpio_led(codec, spec->gpio_mute_led_mask,
Takashi Iwai8d3d1ec2020-06-18 13:08:38 +02004117 spec->mute_led_polarity, !brightness);
4118 return 0;
Takashi Iwai0f32fd192014-11-19 12:16:14 +01004119}
4120
4121/* turn on/off mic-mute LED via GPIO per capture hook */
Kai-Heng Feng87dc3642020-04-30 21:52:07 +08004122static int micmute_led_set(struct led_classdev *led_cdev,
4123 enum led_brightness brightness)
4124{
4125 struct hda_codec *codec = dev_to_hda_codec(led_cdev->dev->parent);
4126 struct alc_spec *spec = codec->spec;
4127
4128 alc_update_gpio_led(codec, spec->gpio_mic_led_mask,
Hui Wang40469062020-08-11 20:24:30 +08004129 spec->micmute_led_polarity, !brightness);
Kai-Heng Feng87dc3642020-04-30 21:52:07 +08004130 return 0;
4131}
4132
Takashi Iwai01e4a272018-06-19 22:47:30 +02004133/* setup mute and mic-mute GPIO bits, add hooks appropriately */
4134static void alc_fixup_hp_gpio_led(struct hda_codec *codec,
4135 int action,
4136 unsigned int mute_mask,
4137 unsigned int micmute_mask)
4138{
4139 struct alc_spec *spec = codec->spec;
4140
4141 alc_fixup_gpio(codec, action, mute_mask | micmute_mask);
4142
4143 if (action != HDA_FIXUP_ACT_PRE_PROBE)
4144 return;
4145 if (mute_mask) {
4146 spec->gpio_mute_led_mask = mute_mask;
Takashi Iwai8d3d1ec2020-06-18 13:08:38 +02004147 snd_hda_gen_add_mute_led_cdev(codec, gpio_mute_led_set);
Takashi Iwai01e4a272018-06-19 22:47:30 +02004148 }
4149 if (micmute_mask) {
4150 spec->gpio_mic_led_mask = micmute_mask;
Takashi Iwai7cdf8c42020-06-18 13:08:31 +02004151 snd_hda_gen_add_micmute_led_cdev(codec, micmute_led_set);
Takashi Iwai01e4a272018-06-19 22:47:30 +02004152 }
4153}
4154
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01004155static void alc269_fixup_hp_gpio_led(struct hda_codec *codec,
4156 const struct hda_fixup *fix, int action)
4157{
Takashi Iwai01e4a272018-06-19 22:47:30 +02004158 alc_fixup_hp_gpio_led(codec, action, 0x08, 0x10);
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01004159}
4160
Kai-Heng Fengf5a88b02020-03-27 12:46:25 +08004161static void alc285_fixup_hp_gpio_led(struct hda_codec *codec,
4162 const struct hda_fixup *fix, int action)
4163{
Kai-Heng Feng3e0650a2020-04-30 16:32:52 +08004164 alc_fixup_hp_gpio_led(codec, action, 0x04, 0x01);
Kai-Heng Fengf5a88b02020-03-27 12:46:25 +08004165}
4166
Kailang Yangeaa8e5e2014-11-21 15:49:11 +08004167static void alc286_fixup_hp_gpio_led(struct hda_codec *codec,
4168 const struct hda_fixup *fix, int action)
4169{
Takashi Iwai01e4a272018-06-19 22:47:30 +02004170 alc_fixup_hp_gpio_led(codec, action, 0x02, 0x20);
Takashi Iwai1d045db2011-07-07 18:23:21 +02004171}
4172
Takashi Iwai8a503552020-06-18 13:08:32 +02004173/* turn on/off mic-mute LED per capture hook via VREF change */
4174static int vref_micmute_led_set(struct led_classdev *led_cdev,
4175 enum led_brightness brightness)
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004176{
Takashi Iwai8a503552020-06-18 13:08:32 +02004177 struct hda_codec *codec = dev_to_hda_codec(led_cdev->dev->parent);
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004178 struct alc_spec *spec = codec->spec;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004179
Takashi Iwai766538a2020-06-18 13:08:41 +02004180 alc_update_vref_led(codec, spec->cap_mute_led_nid,
4181 spec->micmute_led_polarity, brightness);
Takashi Iwai8a503552020-06-18 13:08:32 +02004182 return 0;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004183}
4184
4185static void alc269_fixup_hp_gpio_mic1_led(struct hda_codec *codec,
4186 const struct hda_fixup *fix, int action)
4187{
4188 struct alc_spec *spec = codec->spec;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004189
Takashi Iwai01e4a272018-06-19 22:47:30 +02004190 alc_fixup_hp_gpio_led(codec, action, 0x08, 0);
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004191 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai01e4a272018-06-19 22:47:30 +02004192 /* Like hp_gpio_mic1_led, but also needs GPIO4 low to
4193 * enable headphone amp
4194 */
4195 spec->gpio_mask |= 0x10;
4196 spec->gpio_dir |= 0x10;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004197 spec->cap_mute_led_nid = 0x18;
Takashi Iwai8a503552020-06-18 13:08:32 +02004198 snd_hda_gen_add_micmute_led_cdev(codec, vref_micmute_led_set);
Hui Wang50dd9052014-07-08 17:56:15 +08004199 codec->power_filter = led_power_filter;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004200 }
4201}
4202
David Henningsson7a5255f2014-10-30 08:26:01 +01004203static void alc280_fixup_hp_gpio4(struct hda_codec *codec,
4204 const struct hda_fixup *fix, int action)
4205{
David Henningsson7a5255f2014-10-30 08:26:01 +01004206 struct alc_spec *spec = codec->spec;
David Henningsson7a5255f2014-10-30 08:26:01 +01004207
Takashi Iwai01e4a272018-06-19 22:47:30 +02004208 alc_fixup_hp_gpio_led(codec, action, 0x08, 0);
David Henningsson7a5255f2014-10-30 08:26:01 +01004209 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
David Henningsson7a5255f2014-10-30 08:26:01 +01004210 spec->cap_mute_led_nid = 0x18;
Takashi Iwai8a503552020-06-18 13:08:32 +02004211 snd_hda_gen_add_micmute_led_cdev(codec, vref_micmute_led_set);
David Henningsson7a5255f2014-10-30 08:26:01 +01004212 codec->power_filter = led_power_filter;
4213 }
4214}
4215
Takashi Iwai766538a2020-06-18 13:08:41 +02004216static void alc_update_coef_led(struct hda_codec *codec,
4217 struct alc_coef_led *led,
4218 bool polarity, bool on)
Kailang Yang431e76c2020-04-07 14:40:20 +08004219{
Takashi Iwai766538a2020-06-18 13:08:41 +02004220 if (polarity)
4221 on = !on;
4222 /* temporarily power up/down for setting COEF bit */
4223 alc_update_coef_idx(codec, led->idx, led->mask,
4224 on ? led->on : led->off);
4225}
4226
Kailang Yang431e76c2020-04-07 14:40:20 +08004227/* update mute-LED according to the speaker mute state via COEF bit */
Takashi Iwai8d3d1ec2020-06-18 13:08:38 +02004228static int coef_mute_led_set(struct led_classdev *led_cdev,
4229 enum led_brightness brightness)
Kailang Yang431e76c2020-04-07 14:40:20 +08004230{
Takashi Iwai8d3d1ec2020-06-18 13:08:38 +02004231 struct hda_codec *codec = dev_to_hda_codec(led_cdev->dev->parent);
Kailang Yang431e76c2020-04-07 14:40:20 +08004232 struct alc_spec *spec = codec->spec;
4233
Takashi Iwai766538a2020-06-18 13:08:41 +02004234 alc_update_coef_led(codec, &spec->mute_led_coef,
4235 spec->mute_led_polarity, brightness);
Takashi Iwai8d3d1ec2020-06-18 13:08:38 +02004236 return 0;
Kailang Yang431e76c2020-04-07 14:40:20 +08004237}
4238
4239static void alc285_fixup_hp_mute_led_coefbit(struct hda_codec *codec,
4240 const struct hda_fixup *fix,
4241 int action)
4242{
4243 struct alc_spec *spec = codec->spec;
4244
4245 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4246 spec->mute_led_polarity = 0;
Takashi Iwai766538a2020-06-18 13:08:41 +02004247 spec->mute_led_coef.idx = 0x0b;
4248 spec->mute_led_coef.mask = 1 << 3;
4249 spec->mute_led_coef.on = 1 << 3;
4250 spec->mute_led_coef.off = 0;
Takashi Iwai8d3d1ec2020-06-18 13:08:38 +02004251 snd_hda_gen_add_mute_led_cdev(codec, coef_mute_led_set);
Kailang Yang431e76c2020-04-07 14:40:20 +08004252 }
4253}
4254
Kailang Yang24164f42020-04-07 14:52:42 +08004255static void alc236_fixup_hp_mute_led_coefbit(struct hda_codec *codec,
4256 const struct hda_fixup *fix,
4257 int action)
4258{
4259 struct alc_spec *spec = codec->spec;
4260
4261 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4262 spec->mute_led_polarity = 0;
Takashi Iwai766538a2020-06-18 13:08:41 +02004263 spec->mute_led_coef.idx = 0x34;
4264 spec->mute_led_coef.mask = 1 << 5;
4265 spec->mute_led_coef.on = 0;
4266 spec->mute_led_coef.off = 1 << 5;
Takashi Iwai8d3d1ec2020-06-18 13:08:38 +02004267 snd_hda_gen_add_mute_led_cdev(codec, coef_mute_led_set);
Kailang Yang24164f42020-04-07 14:52:42 +08004268 }
4269}
4270
Kailang Yang431e76c2020-04-07 14:40:20 +08004271/* turn on/off mic-mute LED per capture hook by coef bit */
Takashi Iwai8a503552020-06-18 13:08:32 +02004272static int coef_micmute_led_set(struct led_classdev *led_cdev,
4273 enum led_brightness brightness)
Kailang Yang431e76c2020-04-07 14:40:20 +08004274{
Takashi Iwai8a503552020-06-18 13:08:32 +02004275 struct hda_codec *codec = dev_to_hda_codec(led_cdev->dev->parent);
Kailang Yang431e76c2020-04-07 14:40:20 +08004276 struct alc_spec *spec = codec->spec;
4277
Takashi Iwai766538a2020-06-18 13:08:41 +02004278 alc_update_coef_led(codec, &spec->mic_led_coef,
4279 spec->micmute_led_polarity, brightness);
Takashi Iwai8a503552020-06-18 13:08:32 +02004280 return 0;
Kailang Yang431e76c2020-04-07 14:40:20 +08004281}
4282
4283static void alc285_fixup_hp_coef_micmute_led(struct hda_codec *codec,
4284 const struct hda_fixup *fix, int action)
4285{
4286 struct alc_spec *spec = codec->spec;
4287
4288 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai766538a2020-06-18 13:08:41 +02004289 spec->mic_led_coef.idx = 0x19;
4290 spec->mic_led_coef.mask = 1 << 13;
4291 spec->mic_led_coef.on = 1 << 13;
4292 spec->mic_led_coef.off = 0;
Takashi Iwai8a503552020-06-18 13:08:32 +02004293 snd_hda_gen_add_micmute_led_cdev(codec, coef_micmute_led_set);
Kailang Yang431e76c2020-04-07 14:40:20 +08004294 }
4295}
4296
Kailang Yang24164f42020-04-07 14:52:42 +08004297static void alc236_fixup_hp_coef_micmute_led(struct hda_codec *codec,
4298 const struct hda_fixup *fix, int action)
4299{
4300 struct alc_spec *spec = codec->spec;
4301
4302 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai766538a2020-06-18 13:08:41 +02004303 spec->mic_led_coef.idx = 0x35;
4304 spec->mic_led_coef.mask = 3 << 2;
4305 spec->mic_led_coef.on = 2 << 2;
4306 spec->mic_led_coef.off = 1 << 2;
Takashi Iwai8a503552020-06-18 13:08:32 +02004307 snd_hda_gen_add_micmute_led_cdev(codec, coef_micmute_led_set);
Kailang Yang24164f42020-04-07 14:52:42 +08004308 }
4309}
4310
Kailang Yang431e76c2020-04-07 14:40:20 +08004311static void alc285_fixup_hp_mute_led(struct hda_codec *codec,
4312 const struct hda_fixup *fix, int action)
4313{
4314 alc285_fixup_hp_mute_led_coefbit(codec, fix, action);
4315 alc285_fixup_hp_coef_micmute_led(codec, fix, action);
4316}
4317
Kailang Yang24164f42020-04-07 14:52:42 +08004318static void alc236_fixup_hp_mute_led(struct hda_codec *codec,
4319 const struct hda_fixup *fix, int action)
4320{
4321 alc236_fixup_hp_mute_led_coefbit(codec, fix, action);
4322 alc236_fixup_hp_coef_micmute_led(codec, fix, action);
4323}
4324
Takashi Iwai6a30aba2018-04-27 17:17:35 +02004325#if IS_REACHABLE(CONFIG_INPUT)
David Henningsson33f4acd2015-01-07 15:50:13 +01004326static void gpio2_mic_hotkey_event(struct hda_codec *codec,
4327 struct hda_jack_callback *event)
4328{
4329 struct alc_spec *spec = codec->spec;
4330
4331 /* GPIO2 just toggles on a keypress/keyrelease cycle. Therefore
4332 send both key on and key off event for every interrupt. */
Hui Wangc7b60a82015-12-28 11:35:25 +08004333 input_report_key(spec->kb_dev, spec->alc_mute_keycode_map[ALC_KEY_MICMUTE_INDEX], 1);
David Henningsson33f4acd2015-01-07 15:50:13 +01004334 input_sync(spec->kb_dev);
Hui Wangc7b60a82015-12-28 11:35:25 +08004335 input_report_key(spec->kb_dev, spec->alc_mute_keycode_map[ALC_KEY_MICMUTE_INDEX], 0);
David Henningsson33f4acd2015-01-07 15:50:13 +01004336 input_sync(spec->kb_dev);
4337}
David Henningsson33f4acd2015-01-07 15:50:13 +01004338
Kailang3694cb22015-12-28 11:35:24 +08004339static int alc_register_micmute_input_device(struct hda_codec *codec)
4340{
4341 struct alc_spec *spec = codec->spec;
Hui Wangc7b60a82015-12-28 11:35:25 +08004342 int i;
Kailang3694cb22015-12-28 11:35:24 +08004343
4344 spec->kb_dev = input_allocate_device();
4345 if (!spec->kb_dev) {
4346 codec_err(codec, "Out of memory (input_allocate_device)\n");
4347 return -ENOMEM;
4348 }
Hui Wangc7b60a82015-12-28 11:35:25 +08004349
4350 spec->alc_mute_keycode_map[ALC_KEY_MICMUTE_INDEX] = KEY_MICMUTE;
4351
Kailang3694cb22015-12-28 11:35:24 +08004352 spec->kb_dev->name = "Microphone Mute Button";
4353 spec->kb_dev->evbit[0] = BIT_MASK(EV_KEY);
Hui Wangc7b60a82015-12-28 11:35:25 +08004354 spec->kb_dev->keycodesize = sizeof(spec->alc_mute_keycode_map[0]);
4355 spec->kb_dev->keycodemax = ARRAY_SIZE(spec->alc_mute_keycode_map);
4356 spec->kb_dev->keycode = spec->alc_mute_keycode_map;
4357 for (i = 0; i < ARRAY_SIZE(spec->alc_mute_keycode_map); i++)
4358 set_bit(spec->alc_mute_keycode_map[i], spec->kb_dev->keybit);
Kailang3694cb22015-12-28 11:35:24 +08004359
4360 if (input_register_device(spec->kb_dev)) {
4361 codec_err(codec, "input_register_device failed\n");
4362 input_free_device(spec->kb_dev);
4363 spec->kb_dev = NULL;
4364 return -ENOMEM;
4365 }
4366
4367 return 0;
4368}
4369
Takashi Iwai01e4a272018-06-19 22:47:30 +02004370/* GPIO1 = set according to SKU external amp
4371 * GPIO2 = mic mute hotkey
4372 * GPIO3 = mute LED
4373 * GPIO4 = mic mute LED
4374 */
David Henningsson33f4acd2015-01-07 15:50:13 +01004375static void alc280_fixup_hp_gpio2_mic_hotkey(struct hda_codec *codec,
4376 const struct hda_fixup *fix, int action)
4377{
David Henningsson33f4acd2015-01-07 15:50:13 +01004378 struct alc_spec *spec = codec->spec;
4379
Takashi Iwai01e4a272018-06-19 22:47:30 +02004380 alc_fixup_hp_gpio_led(codec, action, 0x08, 0x10);
David Henningsson33f4acd2015-01-07 15:50:13 +01004381 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai1c76aa52018-06-21 16:37:54 +02004382 spec->init_amp = ALC_INIT_DEFAULT;
Kailang3694cb22015-12-28 11:35:24 +08004383 if (alc_register_micmute_input_device(codec) != 0)
David Henningsson33f4acd2015-01-07 15:50:13 +01004384 return;
David Henningsson33f4acd2015-01-07 15:50:13 +01004385
Takashi Iwai01e4a272018-06-19 22:47:30 +02004386 spec->gpio_mask |= 0x06;
4387 spec->gpio_dir |= 0x02;
4388 spec->gpio_data |= 0x02;
Takashi Iwai7639a062015-03-03 10:07:24 +01004389 snd_hda_codec_write_cache(codec, codec->core.afg, 0,
David Henningsson33f4acd2015-01-07 15:50:13 +01004390 AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x04);
Takashi Iwai7639a062015-03-03 10:07:24 +01004391 snd_hda_jack_detect_enable_callback(codec, codec->core.afg,
David Henningsson33f4acd2015-01-07 15:50:13 +01004392 gpio2_mic_hotkey_event);
David Henningsson33f4acd2015-01-07 15:50:13 +01004393 return;
4394 }
4395
4396 if (!spec->kb_dev)
4397 return;
4398
4399 switch (action) {
David Henningsson33f4acd2015-01-07 15:50:13 +01004400 case HDA_FIXUP_ACT_FREE:
4401 input_unregister_device(spec->kb_dev);
David Henningsson33f4acd2015-01-07 15:50:13 +01004402 spec->kb_dev = NULL;
4403 }
David Henningsson33f4acd2015-01-07 15:50:13 +01004404}
4405
Takashi Iwai01e4a272018-06-19 22:47:30 +02004406/* Line2 = mic mute hotkey
4407 * GPIO2 = mic mute LED
4408 */
Kailang3694cb22015-12-28 11:35:24 +08004409static void alc233_fixup_lenovo_line2_mic_hotkey(struct hda_codec *codec,
4410 const struct hda_fixup *fix, int action)
4411{
Kailang3694cb22015-12-28 11:35:24 +08004412 struct alc_spec *spec = codec->spec;
4413
Takashi Iwai01e4a272018-06-19 22:47:30 +02004414 alc_fixup_hp_gpio_led(codec, action, 0, 0x04);
Kailang3694cb22015-12-28 11:35:24 +08004415 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai1c76aa52018-06-21 16:37:54 +02004416 spec->init_amp = ALC_INIT_DEFAULT;
Kailang3694cb22015-12-28 11:35:24 +08004417 if (alc_register_micmute_input_device(codec) != 0)
4418 return;
4419
Kailang3694cb22015-12-28 11:35:24 +08004420 snd_hda_jack_detect_enable_callback(codec, 0x1b,
4421 gpio2_mic_hotkey_event);
Kailang3694cb22015-12-28 11:35:24 +08004422 return;
4423 }
4424
4425 if (!spec->kb_dev)
4426 return;
4427
4428 switch (action) {
Kailang3694cb22015-12-28 11:35:24 +08004429 case HDA_FIXUP_ACT_FREE:
4430 input_unregister_device(spec->kb_dev);
4431 spec->kb_dev = NULL;
4432 }
4433}
Takashi Iwaic4696522018-01-15 10:44:35 +01004434#else /* INPUT */
4435#define alc280_fixup_hp_gpio2_mic_hotkey NULL
4436#define alc233_fixup_lenovo_line2_mic_hotkey NULL
4437#endif /* INPUT */
Kailang3694cb22015-12-28 11:35:24 +08004438
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004439static void alc269_fixup_hp_line1_mic1_led(struct hda_codec *codec,
4440 const struct hda_fixup *fix, int action)
4441{
4442 struct alc_spec *spec = codec->spec;
4443
Takashi Iwai1bce62a2018-06-19 23:15:59 +02004444 alc269_fixup_hp_mute_led_micx(codec, fix, action, 0x1a);
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004445 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004446 spec->cap_mute_led_nid = 0x18;
Takashi Iwai8a503552020-06-18 13:08:32 +02004447 snd_hda_gen_add_micmute_led_cdev(codec, vref_micmute_led_set);
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004448 }
4449}
4450
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004451static const struct coef_fw alc225_pre_hsmode[] = {
Kailang Yang5a367672017-07-21 15:23:53 +08004452 UPDATE_COEF(0x4a, 1<<8, 0),
4453 UPDATE_COEFEX(0x57, 0x05, 1<<14, 0),
4454 UPDATE_COEF(0x63, 3<<14, 3<<14),
4455 UPDATE_COEF(0x4a, 3<<4, 2<<4),
4456 UPDATE_COEF(0x4a, 3<<10, 3<<10),
4457 UPDATE_COEF(0x45, 0x3f<<10, 0x34<<10),
4458 UPDATE_COEF(0x4a, 3<<10, 0),
4459 {}
4460};
4461
David Henningsson73bdd592013-04-15 15:44:14 +02004462static void alc_headset_mode_unplugged(struct hda_codec *codec)
4463{
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004464 static const struct coef_fw coef0255[] = {
Kailang Yang717f43d2019-05-31 17:16:53 +08004465 WRITE_COEF(0x1b, 0x0c0b), /* LDO and MISC control */
Takashi Iwai54db6c32014-08-18 15:11:19 +02004466 WRITE_COEF(0x45, 0xd089), /* UAJ function set to menual mode */
4467 UPDATE_COEFEX(0x57, 0x05, 1<<14, 0), /* Direct Drive HP Amp control(Set to verb control)*/
4468 WRITE_COEF(0x06, 0x6104), /* Set MIC2 Vref gate with HP */
4469 WRITE_COEFEX(0x57, 0x03, 0x8aa6), /* Direct Drive HP Amp control */
4470 {}
4471 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004472 static const struct coef_fw coef0256[] = {
Kailang Yange69e7e02016-05-30 15:58:28 +08004473 WRITE_COEF(0x1b, 0x0c4b), /* LDO and MISC control */
Kailang Yang717f43d2019-05-31 17:16:53 +08004474 WRITE_COEF(0x45, 0xd089), /* UAJ function set to menual mode */
4475 WRITE_COEF(0x06, 0x6104), /* Set MIC2 Vref gate with HP */
4476 WRITE_COEFEX(0x57, 0x03, 0x09a3), /* Direct Drive HP Amp control */
4477 UPDATE_COEFEX(0x57, 0x05, 1<<14, 0), /* Direct Drive HP Amp control(Set to verb control)*/
Kailang Yange69e7e02016-05-30 15:58:28 +08004478 {}
4479 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004480 static const struct coef_fw coef0233[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004481 WRITE_COEF(0x1b, 0x0c0b),
4482 WRITE_COEF(0x45, 0xc429),
4483 UPDATE_COEF(0x35, 0x4000, 0),
4484 WRITE_COEF(0x06, 0x2104),
4485 WRITE_COEF(0x1a, 0x0001),
4486 WRITE_COEF(0x26, 0x0004),
4487 WRITE_COEF(0x32, 0x42a3),
4488 {}
4489 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004490 static const struct coef_fw coef0288[] = {
Kailang Yangf3b70332015-04-08 15:01:17 +08004491 UPDATE_COEF(0x4f, 0xfcc0, 0xc400),
4492 UPDATE_COEF(0x50, 0x2000, 0x2000),
4493 UPDATE_COEF(0x56, 0x0006, 0x0006),
4494 UPDATE_COEF(0x66, 0x0008, 0),
4495 UPDATE_COEF(0x67, 0x2000, 0),
4496 {}
4497 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004498 static const struct coef_fw coef0298[] = {
Kailang Yang89542932017-07-17 15:03:43 +08004499 UPDATE_COEF(0x19, 0x1300, 0x0300),
4500 {}
4501 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004502 static const struct coef_fw coef0292[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004503 WRITE_COEF(0x76, 0x000e),
4504 WRITE_COEF(0x6c, 0x2400),
4505 WRITE_COEF(0x18, 0x7308),
4506 WRITE_COEF(0x6b, 0xc429),
4507 {}
4508 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004509 static const struct coef_fw coef0293[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004510 UPDATE_COEF(0x10, 7<<8, 6<<8), /* SET Line1 JD to 0 */
4511 UPDATE_COEFEX(0x57, 0x05, 1<<15|1<<13, 0x0), /* SET charge pump by verb */
4512 UPDATE_COEFEX(0x57, 0x03, 1<<10, 1<<10), /* SET EN_OSW to 1 */
4513 UPDATE_COEF(0x1a, 1<<3, 1<<3), /* Combo JD gating with LINE1-VREFO */
4514 WRITE_COEF(0x45, 0xc429), /* Set to TRS type */
4515 UPDATE_COEF(0x4a, 0x000f, 0x000e), /* Combo Jack auto detect */
4516 {}
4517 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004518 static const struct coef_fw coef0668[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004519 WRITE_COEF(0x15, 0x0d40),
4520 WRITE_COEF(0xb7, 0x802b),
4521 {}
4522 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004523 static const struct coef_fw coef0225[] = {
Kailang Yang5a367672017-07-21 15:23:53 +08004524 UPDATE_COEF(0x63, 3<<14, 0),
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004525 {}
4526 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004527 static const struct coef_fw coef0274[] = {
Kailang Yang71683c32017-06-20 16:33:50 +08004528 UPDATE_COEF(0x4a, 0x0100, 0),
4529 UPDATE_COEFEX(0x57, 0x05, 0x4000, 0),
4530 UPDATE_COEF(0x6b, 0xf000, 0x5000),
4531 UPDATE_COEF(0x4a, 0x0010, 0),
4532 UPDATE_COEF(0x4a, 0x0c00, 0x0c00),
4533 WRITE_COEF(0x45, 0x5289),
4534 UPDATE_COEF(0x4a, 0x0c00, 0),
4535 {}
4536 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004537
Takashi Iwai7639a062015-03-03 10:07:24 +01004538 switch (codec->core.vendor_id) {
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004539 case 0x10ec0255:
Kailang Yange69e7e02016-05-30 15:58:28 +08004540 alc_process_coef_fw(codec, coef0255);
4541 break;
Kailang Yang736f20a2017-10-20 15:06:34 +08004542 case 0x10ec0236:
Kailang Yang7081adf2015-03-30 17:05:37 +08004543 case 0x10ec0256:
Kailang Yange69e7e02016-05-30 15:58:28 +08004544 alc_process_coef_fw(codec, coef0256);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004545 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004546 case 0x10ec0234:
4547 case 0x10ec0274:
4548 case 0x10ec0294:
4549 alc_process_coef_fw(codec, coef0274);
4550 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004551 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004552 case 0x10ec0283:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004553 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02004554 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004555 case 0x10ec0286:
4556 case 0x10ec0288:
Kailang Yang89542932017-07-17 15:03:43 +08004557 alc_process_coef_fw(codec, coef0288);
4558 break;
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004559 case 0x10ec0298:
Kailang Yang89542932017-07-17 15:03:43 +08004560 alc_process_coef_fw(codec, coef0298);
Kailang Yangf3b70332015-04-08 15:01:17 +08004561 alc_process_coef_fw(codec, coef0288);
4562 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004563 case 0x10ec0292:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004564 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02004565 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004566 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004567 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004568 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004569 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004570 alc_process_coef_fw(codec, coef0668);
David Henningsson73bdd592013-04-15 15:44:14 +02004571 break;
Kailang Yangc2b691e2018-01-17 15:22:55 +08004572 case 0x10ec0215:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004573 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004574 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08004575 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004576 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08004577 case 0x10ec0299:
Kailang Yang4d4b0c52019-01-09 16:23:37 +08004578 alc_process_coef_fw(codec, alc225_pre_hsmode);
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004579 alc_process_coef_fw(codec, coef0225);
4580 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08004581 case 0x10ec0867:
4582 alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
4583 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004584 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01004585 codec_dbg(codec, "Headset jack set to unplugged mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02004586}
4587
4588
4589static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin,
4590 hda_nid_t mic_pin)
4591{
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004592 static const struct coef_fw coef0255[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004593 WRITE_COEFEX(0x57, 0x03, 0x8aa6),
4594 WRITE_COEF(0x06, 0x6100), /* Set MIC2 Vref gate to normal */
4595 {}
4596 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004597 static const struct coef_fw coef0256[] = {
Kailang Yang717f43d2019-05-31 17:16:53 +08004598 UPDATE_COEFEX(0x57, 0x05, 1<<14, 1<<14), /* Direct Drive HP Amp control(Set to verb control)*/
4599 WRITE_COEFEX(0x57, 0x03, 0x09a3),
4600 WRITE_COEF(0x06, 0x6100), /* Set MIC2 Vref gate to normal */
4601 {}
4602 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004603 static const struct coef_fw coef0233[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004604 UPDATE_COEF(0x35, 0, 1<<14),
4605 WRITE_COEF(0x06, 0x2100),
4606 WRITE_COEF(0x1a, 0x0021),
4607 WRITE_COEF(0x26, 0x008c),
4608 {}
4609 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004610 static const struct coef_fw coef0288[] = {
Kailang Yang89542932017-07-17 15:03:43 +08004611 UPDATE_COEF(0x4f, 0x00c0, 0),
Kailang Yangf3b70332015-04-08 15:01:17 +08004612 UPDATE_COEF(0x50, 0x2000, 0),
4613 UPDATE_COEF(0x56, 0x0006, 0),
4614 UPDATE_COEF(0x4f, 0xfcc0, 0xc400),
4615 UPDATE_COEF(0x66, 0x0008, 0x0008),
4616 UPDATE_COEF(0x67, 0x2000, 0x2000),
4617 {}
4618 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004619 static const struct coef_fw coef0292[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004620 WRITE_COEF(0x19, 0xa208),
4621 WRITE_COEF(0x2e, 0xacf0),
4622 {}
4623 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004624 static const struct coef_fw coef0293[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004625 UPDATE_COEFEX(0x57, 0x05, 0, 1<<15|1<<13), /* SET charge pump by verb */
4626 UPDATE_COEFEX(0x57, 0x03, 1<<10, 0), /* SET EN_OSW to 0 */
4627 UPDATE_COEF(0x1a, 1<<3, 0), /* Combo JD gating without LINE1-VREFO */
4628 {}
4629 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004630 static const struct coef_fw coef0688[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004631 WRITE_COEF(0xb7, 0x802b),
4632 WRITE_COEF(0xb5, 0x1040),
4633 UPDATE_COEF(0xc3, 0, 1<<12),
4634 {}
4635 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004636 static const struct coef_fw coef0225[] = {
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004637 UPDATE_COEFEX(0x57, 0x05, 1<<14, 1<<14),
4638 UPDATE_COEF(0x4a, 3<<4, 2<<4),
4639 UPDATE_COEF(0x63, 3<<14, 0),
4640 {}
4641 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004642 static const struct coef_fw coef0274[] = {
Kailang Yang71683c32017-06-20 16:33:50 +08004643 UPDATE_COEFEX(0x57, 0x05, 0x4000, 0x4000),
4644 UPDATE_COEF(0x4a, 0x0010, 0),
4645 UPDATE_COEF(0x6b, 0xf000, 0),
4646 {}
4647 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004648
Takashi Iwai7639a062015-03-03 10:07:24 +01004649 switch (codec->core.vendor_id) {
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004650 case 0x10ec0255:
4651 alc_write_coef_idx(codec, 0x45, 0xc489);
4652 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02004653 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004654 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4655 break;
Kailang Yang717f43d2019-05-31 17:16:53 +08004656 case 0x10ec0236:
4657 case 0x10ec0256:
4658 alc_write_coef_idx(codec, 0x45, 0xc489);
4659 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4660 alc_process_coef_fw(codec, coef0256);
4661 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4662 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004663 case 0x10ec0234:
4664 case 0x10ec0274:
4665 case 0x10ec0294:
4666 alc_write_coef_idx(codec, 0x45, 0x4689);
4667 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4668 alc_process_coef_fw(codec, coef0274);
4669 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4670 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004671 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004672 case 0x10ec0283:
4673 alc_write_coef_idx(codec, 0x45, 0xc429);
4674 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02004675 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02004676 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4677 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004678 case 0x10ec0286:
4679 case 0x10ec0288:
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004680 case 0x10ec0298:
Kailang Yangf3b70332015-04-08 15:01:17 +08004681 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4682 alc_process_coef_fw(codec, coef0288);
4683 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4684 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004685 case 0x10ec0292:
4686 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02004687 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02004688 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004689 case 0x10ec0293:
4690 /* Set to TRS mode */
4691 alc_write_coef_idx(codec, 0x45, 0xc429);
4692 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02004693 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004694 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4695 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08004696 case 0x10ec0867:
4697 alc_update_coefex_idx(codec, 0x57, 0x5, 0, 1<<14);
Gustavo A. R. Silvac0dbbda2020-07-08 15:32:36 -05004698 fallthrough;
Kailang Yang9eb5d0e2017-01-17 15:40:25 +08004699 case 0x10ec0221:
David Henningsson1f8b46c2015-05-12 14:38:15 +02004700 case 0x10ec0662:
4701 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4702 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4703 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004704 case 0x10ec0668:
4705 alc_write_coef_idx(codec, 0x11, 0x0001);
4706 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02004707 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02004708 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4709 break;
Kailang Yangc2b691e2018-01-17 15:22:55 +08004710 case 0x10ec0215:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004711 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004712 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08004713 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004714 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08004715 case 0x10ec0299:
Kailang Yang5a367672017-07-21 15:23:53 +08004716 alc_process_coef_fw(codec, alc225_pre_hsmode);
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004717 alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x31<<10);
4718 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4719 alc_process_coef_fw(codec, coef0225);
4720 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4721 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004722 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01004723 codec_dbg(codec, "Headset jack set to mic-in mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02004724}
4725
4726static void alc_headset_mode_default(struct hda_codec *codec)
4727{
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004728 static const struct coef_fw coef0225[] = {
Kailang Yang5a367672017-07-21 15:23:53 +08004729 UPDATE_COEF(0x45, 0x3f<<10, 0x30<<10),
4730 UPDATE_COEF(0x45, 0x3f<<10, 0x31<<10),
4731 UPDATE_COEF(0x49, 3<<8, 0<<8),
4732 UPDATE_COEF(0x4a, 3<<4, 3<<4),
4733 UPDATE_COEF(0x63, 3<<14, 0),
4734 UPDATE_COEF(0x67, 0xf000, 0x3000),
David Henningsson2ae95572016-02-25 09:37:05 +01004735 {}
4736 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004737 static const struct coef_fw coef0255[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004738 WRITE_COEF(0x45, 0xc089),
4739 WRITE_COEF(0x45, 0xc489),
4740 WRITE_COEFEX(0x57, 0x03, 0x8ea6),
4741 WRITE_COEF(0x49, 0x0049),
4742 {}
4743 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004744 static const struct coef_fw coef0256[] = {
Kailang Yang717f43d2019-05-31 17:16:53 +08004745 WRITE_COEF(0x45, 0xc489),
4746 WRITE_COEFEX(0x57, 0x03, 0x0da3),
4747 WRITE_COEF(0x49, 0x0049),
4748 UPDATE_COEFEX(0x57, 0x05, 1<<14, 0), /* Direct Drive HP Amp control(Set to verb control)*/
4749 WRITE_COEF(0x06, 0x6100),
4750 {}
4751 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004752 static const struct coef_fw coef0233[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004753 WRITE_COEF(0x06, 0x2100),
4754 WRITE_COEF(0x32, 0x4ea3),
4755 {}
4756 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004757 static const struct coef_fw coef0288[] = {
Kailang Yangf3b70332015-04-08 15:01:17 +08004758 UPDATE_COEF(0x4f, 0xfcc0, 0xc400), /* Set to TRS type */
4759 UPDATE_COEF(0x50, 0x2000, 0x2000),
4760 UPDATE_COEF(0x56, 0x0006, 0x0006),
4761 UPDATE_COEF(0x66, 0x0008, 0),
4762 UPDATE_COEF(0x67, 0x2000, 0),
4763 {}
4764 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004765 static const struct coef_fw coef0292[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004766 WRITE_COEF(0x76, 0x000e),
4767 WRITE_COEF(0x6c, 0x2400),
4768 WRITE_COEF(0x6b, 0xc429),
4769 WRITE_COEF(0x18, 0x7308),
4770 {}
4771 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004772 static const struct coef_fw coef0293[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004773 UPDATE_COEF(0x4a, 0x000f, 0x000e), /* Combo Jack auto detect */
4774 WRITE_COEF(0x45, 0xC429), /* Set to TRS type */
4775 UPDATE_COEF(0x1a, 1<<3, 0), /* Combo JD gating without LINE1-VREFO */
4776 {}
4777 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004778 static const struct coef_fw coef0688[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004779 WRITE_COEF(0x11, 0x0041),
4780 WRITE_COEF(0x15, 0x0d40),
4781 WRITE_COEF(0xb7, 0x802b),
4782 {}
4783 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004784 static const struct coef_fw coef0274[] = {
Kailang Yang71683c32017-06-20 16:33:50 +08004785 WRITE_COEF(0x45, 0x4289),
4786 UPDATE_COEF(0x4a, 0x0010, 0x0010),
4787 UPDATE_COEF(0x6b, 0x0f00, 0),
4788 UPDATE_COEF(0x49, 0x0300, 0x0300),
4789 {}
4790 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004791
Takashi Iwai7639a062015-03-03 10:07:24 +01004792 switch (codec->core.vendor_id) {
Kailang Yangc2b691e2018-01-17 15:22:55 +08004793 case 0x10ec0215:
David Henningsson2ae95572016-02-25 09:37:05 +01004794 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004795 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08004796 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004797 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08004798 case 0x10ec0299:
Kailang Yang5a367672017-07-21 15:23:53 +08004799 alc_process_coef_fw(codec, alc225_pre_hsmode);
David Henningsson2ae95572016-02-25 09:37:05 +01004800 alc_process_coef_fw(codec, coef0225);
4801 break;
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004802 case 0x10ec0255:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004803 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004804 break;
Kailang Yang717f43d2019-05-31 17:16:53 +08004805 case 0x10ec0236:
4806 case 0x10ec0256:
4807 alc_write_coef_idx(codec, 0x1b, 0x0e4b);
4808 alc_write_coef_idx(codec, 0x45, 0xc089);
4809 msleep(50);
4810 alc_process_coef_fw(codec, coef0256);
4811 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004812 case 0x10ec0234:
4813 case 0x10ec0274:
4814 case 0x10ec0294:
4815 alc_process_coef_fw(codec, coef0274);
4816 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004817 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004818 case 0x10ec0283:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004819 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02004820 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004821 case 0x10ec0286:
4822 case 0x10ec0288:
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004823 case 0x10ec0298:
Kailang Yangf3b70332015-04-08 15:01:17 +08004824 alc_process_coef_fw(codec, coef0288);
4825 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004826 case 0x10ec0292:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004827 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02004828 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004829 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004830 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004831 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004832 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004833 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02004834 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08004835 case 0x10ec0867:
4836 alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
4837 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004838 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01004839 codec_dbg(codec, "Headset jack set to headphone (default) mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02004840}
4841
4842/* Iphone type */
4843static void alc_headset_mode_ctia(struct hda_codec *codec)
4844{
Kailang Yang89542932017-07-17 15:03:43 +08004845 int val;
4846
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004847 static const struct coef_fw coef0255[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004848 WRITE_COEF(0x45, 0xd489), /* Set to CTIA type */
4849 WRITE_COEF(0x1b, 0x0c2b),
4850 WRITE_COEFEX(0x57, 0x03, 0x8ea6),
4851 {}
4852 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004853 static const struct coef_fw coef0256[] = {
Kailang Yange69e7e02016-05-30 15:58:28 +08004854 WRITE_COEF(0x45, 0xd489), /* Set to CTIA type */
Kailang Yang717f43d2019-05-31 17:16:53 +08004855 WRITE_COEF(0x1b, 0x0e6b),
Kailang Yange69e7e02016-05-30 15:58:28 +08004856 {}
4857 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004858 static const struct coef_fw coef0233[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004859 WRITE_COEF(0x45, 0xd429),
4860 WRITE_COEF(0x1b, 0x0c2b),
4861 WRITE_COEF(0x32, 0x4ea3),
4862 {}
4863 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004864 static const struct coef_fw coef0288[] = {
Kailang Yangf3b70332015-04-08 15:01:17 +08004865 UPDATE_COEF(0x50, 0x2000, 0x2000),
4866 UPDATE_COEF(0x56, 0x0006, 0x0006),
4867 UPDATE_COEF(0x66, 0x0008, 0),
4868 UPDATE_COEF(0x67, 0x2000, 0),
4869 {}
4870 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004871 static const struct coef_fw coef0292[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004872 WRITE_COEF(0x6b, 0xd429),
4873 WRITE_COEF(0x76, 0x0008),
4874 WRITE_COEF(0x18, 0x7388),
4875 {}
4876 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004877 static const struct coef_fw coef0293[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004878 WRITE_COEF(0x45, 0xd429), /* Set to ctia type */
4879 UPDATE_COEF(0x10, 7<<8, 7<<8), /* SET Line1 JD to 1 */
4880 {}
4881 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004882 static const struct coef_fw coef0688[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004883 WRITE_COEF(0x11, 0x0001),
4884 WRITE_COEF(0x15, 0x0d60),
4885 WRITE_COEF(0xc3, 0x0000),
4886 {}
4887 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004888 static const struct coef_fw coef0225_1[] = {
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004889 UPDATE_COEF(0x45, 0x3f<<10, 0x35<<10),
Kailang Yang5a367672017-07-21 15:23:53 +08004890 UPDATE_COEF(0x63, 3<<14, 2<<14),
4891 {}
4892 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004893 static const struct coef_fw coef0225_2[] = {
Kailang Yang5a367672017-07-21 15:23:53 +08004894 UPDATE_COEF(0x45, 0x3f<<10, 0x35<<10),
4895 UPDATE_COEF(0x63, 3<<14, 1<<14),
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004896 {}
4897 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004898
Takashi Iwai7639a062015-03-03 10:07:24 +01004899 switch (codec->core.vendor_id) {
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004900 case 0x10ec0255:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004901 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004902 break;
Kailang Yang736f20a2017-10-20 15:06:34 +08004903 case 0x10ec0236:
Kailang Yange69e7e02016-05-30 15:58:28 +08004904 case 0x10ec0256:
4905 alc_process_coef_fw(codec, coef0256);
4906 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004907 case 0x10ec0234:
4908 case 0x10ec0274:
4909 case 0x10ec0294:
4910 alc_write_coef_idx(codec, 0x45, 0xd689);
4911 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004912 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004913 case 0x10ec0283:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004914 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02004915 break;
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004916 case 0x10ec0298:
Kailang Yang89542932017-07-17 15:03:43 +08004917 val = alc_read_coef_idx(codec, 0x50);
4918 if (val & (1 << 12)) {
4919 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0020);
4920 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400);
4921 msleep(300);
4922 } else {
4923 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0010);
4924 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400);
4925 msleep(300);
4926 }
4927 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004928 case 0x10ec0286:
4929 case 0x10ec0288:
4930 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400);
4931 msleep(300);
4932 alc_process_coef_fw(codec, coef0288);
4933 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004934 case 0x10ec0292:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004935 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02004936 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004937 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004938 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004939 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004940 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004941 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02004942 break;
Kailang Yangc2b691e2018-01-17 15:22:55 +08004943 case 0x10ec0215:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004944 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004945 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08004946 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004947 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08004948 case 0x10ec0299:
Kailang Yang5a367672017-07-21 15:23:53 +08004949 val = alc_read_coef_idx(codec, 0x45);
4950 if (val & (1 << 9))
4951 alc_process_coef_fw(codec, coef0225_2);
4952 else
4953 alc_process_coef_fw(codec, coef0225_1);
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004954 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08004955 case 0x10ec0867:
4956 alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
4957 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004958 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01004959 codec_dbg(codec, "Headset jack set to iPhone-style headset mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02004960}
4961
4962/* Nokia type */
4963static void alc_headset_mode_omtp(struct hda_codec *codec)
4964{
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004965 static const struct coef_fw coef0255[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004966 WRITE_COEF(0x45, 0xe489), /* Set to OMTP Type */
4967 WRITE_COEF(0x1b, 0x0c2b),
4968 WRITE_COEFEX(0x57, 0x03, 0x8ea6),
4969 {}
4970 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004971 static const struct coef_fw coef0256[] = {
Kailang Yange69e7e02016-05-30 15:58:28 +08004972 WRITE_COEF(0x45, 0xe489), /* Set to OMTP Type */
Kailang Yang717f43d2019-05-31 17:16:53 +08004973 WRITE_COEF(0x1b, 0x0e6b),
Kailang Yange69e7e02016-05-30 15:58:28 +08004974 {}
4975 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004976 static const struct coef_fw coef0233[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004977 WRITE_COEF(0x45, 0xe429),
4978 WRITE_COEF(0x1b, 0x0c2b),
4979 WRITE_COEF(0x32, 0x4ea3),
4980 {}
4981 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004982 static const struct coef_fw coef0288[] = {
Kailang Yangf3b70332015-04-08 15:01:17 +08004983 UPDATE_COEF(0x50, 0x2000, 0x2000),
4984 UPDATE_COEF(0x56, 0x0006, 0x0006),
4985 UPDATE_COEF(0x66, 0x0008, 0),
4986 UPDATE_COEF(0x67, 0x2000, 0),
4987 {}
4988 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004989 static const struct coef_fw coef0292[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004990 WRITE_COEF(0x6b, 0xe429),
4991 WRITE_COEF(0x76, 0x0008),
4992 WRITE_COEF(0x18, 0x7388),
4993 {}
4994 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004995 static const struct coef_fw coef0293[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004996 WRITE_COEF(0x45, 0xe429), /* Set to omtp type */
4997 UPDATE_COEF(0x10, 7<<8, 7<<8), /* SET Line1 JD to 1 */
4998 {}
4999 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01005000 static const struct coef_fw coef0688[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02005001 WRITE_COEF(0x11, 0x0001),
5002 WRITE_COEF(0x15, 0x0d50),
5003 WRITE_COEF(0xc3, 0x0000),
5004 {}
5005 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01005006 static const struct coef_fw coef0225[] = {
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08005007 UPDATE_COEF(0x45, 0x3f<<10, 0x39<<10),
Kailang Yang5a367672017-07-21 15:23:53 +08005008 UPDATE_COEF(0x63, 3<<14, 2<<14),
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08005009 {}
5010 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02005011
Takashi Iwai7639a062015-03-03 10:07:24 +01005012 switch (codec->core.vendor_id) {
Kailang Yang9a22a8f52013-11-08 15:54:49 +08005013 case 0x10ec0255:
Takashi Iwai54db6c32014-08-18 15:11:19 +02005014 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08005015 break;
Kailang Yang736f20a2017-10-20 15:06:34 +08005016 case 0x10ec0236:
Kailang Yange69e7e02016-05-30 15:58:28 +08005017 case 0x10ec0256:
5018 alc_process_coef_fw(codec, coef0256);
5019 break;
Kailang Yang71683c32017-06-20 16:33:50 +08005020 case 0x10ec0234:
5021 case 0x10ec0274:
5022 case 0x10ec0294:
5023 alc_write_coef_idx(codec, 0x45, 0xe689);
5024 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08005025 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02005026 case 0x10ec0283:
Takashi Iwai54db6c32014-08-18 15:11:19 +02005027 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02005028 break;
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08005029 case 0x10ec0298:
5030 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0010);/* Headset output enable */
Kailang Yang89542932017-07-17 15:03:43 +08005031 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xe400);
5032 msleep(300);
5033 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08005034 case 0x10ec0286:
5035 case 0x10ec0288:
5036 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xe400);
5037 msleep(300);
5038 alc_process_coef_fw(codec, coef0288);
5039 break;
David Henningsson73bdd592013-04-15 15:44:14 +02005040 case 0x10ec0292:
Takashi Iwai54db6c32014-08-18 15:11:19 +02005041 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02005042 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08005043 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02005044 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08005045 break;
David Henningsson73bdd592013-04-15 15:44:14 +02005046 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02005047 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02005048 break;
Kailang Yangc2b691e2018-01-17 15:22:55 +08005049 case 0x10ec0215:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08005050 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08005051 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08005052 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08005053 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08005054 case 0x10ec0299:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08005055 alc_process_coef_fw(codec, coef0225);
5056 break;
David Henningsson73bdd592013-04-15 15:44:14 +02005057 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01005058 codec_dbg(codec, "Headset jack set to Nokia-style headset mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02005059}
5060
5061static void alc_determine_headset_type(struct hda_codec *codec)
5062{
5063 int val;
5064 bool is_ctia = false;
5065 struct alc_spec *spec = codec->spec;
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01005066 static const struct coef_fw coef0255[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02005067 WRITE_COEF(0x45, 0xd089), /* combo jack auto switch control(Check type)*/
5068 WRITE_COEF(0x49, 0x0149), /* combo jack auto switch control(Vref
5069 conteol) */
5070 {}
5071 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01005072 static const struct coef_fw coef0288[] = {
Kailang Yangf3b70332015-04-08 15:01:17 +08005073 UPDATE_COEF(0x4f, 0xfcc0, 0xd400), /* Check Type */
5074 {}
5075 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01005076 static const struct coef_fw coef0298[] = {
Kailang Yang89542932017-07-17 15:03:43 +08005077 UPDATE_COEF(0x50, 0x2000, 0x2000),
5078 UPDATE_COEF(0x56, 0x0006, 0x0006),
5079 UPDATE_COEF(0x66, 0x0008, 0),
5080 UPDATE_COEF(0x67, 0x2000, 0),
5081 UPDATE_COEF(0x19, 0x1300, 0x1300),
5082 {}
5083 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01005084 static const struct coef_fw coef0293[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02005085 UPDATE_COEF(0x4a, 0x000f, 0x0008), /* Combo Jack auto detect */
5086 WRITE_COEF(0x45, 0xD429), /* Set to ctia type */
5087 {}
5088 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01005089 static const struct coef_fw coef0688[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02005090 WRITE_COEF(0x11, 0x0001),
5091 WRITE_COEF(0xb7, 0x802b),
5092 WRITE_COEF(0x15, 0x0d60),
5093 WRITE_COEF(0xc3, 0x0c00),
5094 {}
5095 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01005096 static const struct coef_fw coef0274[] = {
Kailang Yang71683c32017-06-20 16:33:50 +08005097 UPDATE_COEF(0x4a, 0x0010, 0),
5098 UPDATE_COEF(0x4a, 0x8000, 0),
5099 WRITE_COEF(0x45, 0xd289),
5100 UPDATE_COEF(0x49, 0x0300, 0x0300),
5101 {}
5102 };
David Henningsson73bdd592013-04-15 15:44:14 +02005103
Takashi Iwai7639a062015-03-03 10:07:24 +01005104 switch (codec->core.vendor_id) {
Kailang Yang9a22a8f52013-11-08 15:54:49 +08005105 case 0x10ec0255:
Takashi Iwai54db6c32014-08-18 15:11:19 +02005106 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08005107 msleep(300);
5108 val = alc_read_coef_idx(codec, 0x46);
5109 is_ctia = (val & 0x0070) == 0x0070;
5110 break;
Kailang Yang717f43d2019-05-31 17:16:53 +08005111 case 0x10ec0236:
5112 case 0x10ec0256:
5113 alc_write_coef_idx(codec, 0x1b, 0x0e4b);
5114 alc_write_coef_idx(codec, 0x06, 0x6104);
5115 alc_write_coefex_idx(codec, 0x57, 0x3, 0x09a3);
5116
5117 snd_hda_codec_write(codec, 0x21, 0,
5118 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
5119 msleep(80);
5120 snd_hda_codec_write(codec, 0x21, 0,
5121 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
5122
5123 alc_process_coef_fw(codec, coef0255);
5124 msleep(300);
5125 val = alc_read_coef_idx(codec, 0x46);
5126 is_ctia = (val & 0x0070) == 0x0070;
5127
5128 alc_write_coefex_idx(codec, 0x57, 0x3, 0x0da3);
5129 alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
5130
5131 snd_hda_codec_write(codec, 0x21, 0,
5132 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
5133 msleep(80);
5134 snd_hda_codec_write(codec, 0x21, 0,
5135 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
5136 break;
Kailang Yang71683c32017-06-20 16:33:50 +08005137 case 0x10ec0234:
5138 case 0x10ec0274:
5139 case 0x10ec0294:
5140 alc_process_coef_fw(codec, coef0274);
5141 msleep(80);
5142 val = alc_read_coef_idx(codec, 0x46);
5143 is_ctia = (val & 0x00f0) == 0x00f0;
5144 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08005145 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02005146 case 0x10ec0283:
5147 alc_write_coef_idx(codec, 0x45, 0xd029);
5148 msleep(300);
5149 val = alc_read_coef_idx(codec, 0x46);
5150 is_ctia = (val & 0x0070) == 0x0070;
5151 break;
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08005152 case 0x10ec0298:
Kailang Yang89542932017-07-17 15:03:43 +08005153 snd_hda_codec_write(codec, 0x21, 0,
5154 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
5155 msleep(100);
5156 snd_hda_codec_write(codec, 0x21, 0,
5157 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
5158 msleep(200);
5159
5160 val = alc_read_coef_idx(codec, 0x50);
5161 if (val & (1 << 12)) {
5162 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0020);
5163 alc_process_coef_fw(codec, coef0288);
5164 msleep(350);
5165 val = alc_read_coef_idx(codec, 0x50);
5166 is_ctia = (val & 0x0070) == 0x0070;
5167 } else {
5168 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0010);
5169 alc_process_coef_fw(codec, coef0288);
5170 msleep(350);
5171 val = alc_read_coef_idx(codec, 0x50);
5172 is_ctia = (val & 0x0070) == 0x0070;
5173 }
5174 alc_process_coef_fw(codec, coef0298);
5175 snd_hda_codec_write(codec, 0x21, 0,
5176 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP);
5177 msleep(75);
5178 snd_hda_codec_write(codec, 0x21, 0,
5179 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
5180 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08005181 case 0x10ec0286:
5182 case 0x10ec0288:
5183 alc_process_coef_fw(codec, coef0288);
5184 msleep(350);
5185 val = alc_read_coef_idx(codec, 0x50);
5186 is_ctia = (val & 0x0070) == 0x0070;
5187 break;
David Henningsson73bdd592013-04-15 15:44:14 +02005188 case 0x10ec0292:
5189 alc_write_coef_idx(codec, 0x6b, 0xd429);
5190 msleep(300);
5191 val = alc_read_coef_idx(codec, 0x6c);
5192 is_ctia = (val & 0x001c) == 0x001c;
5193 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08005194 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02005195 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08005196 msleep(300);
5197 val = alc_read_coef_idx(codec, 0x46);
5198 is_ctia = (val & 0x0070) == 0x0070;
5199 break;
David Henningsson73bdd592013-04-15 15:44:14 +02005200 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02005201 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02005202 msleep(300);
5203 val = alc_read_coef_idx(codec, 0xbe);
5204 is_ctia = (val & 0x1c02) == 0x1c02;
5205 break;
Kailang Yangc2b691e2018-01-17 15:22:55 +08005206 case 0x10ec0215:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08005207 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08005208 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08005209 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08005210 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08005211 case 0x10ec0299:
Kailang Yangda911b12018-01-05 16:50:08 +08005212 snd_hda_codec_write(codec, 0x21, 0,
5213 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
5214 msleep(80);
5215 snd_hda_codec_write(codec, 0x21, 0,
5216 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
5217
Kailang Yang5a367672017-07-21 15:23:53 +08005218 alc_process_coef_fw(codec, alc225_pre_hsmode);
5219 alc_update_coef_idx(codec, 0x67, 0xf000, 0x1000);
5220 val = alc_read_coef_idx(codec, 0x45);
5221 if (val & (1 << 9)) {
5222 alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x34<<10);
5223 alc_update_coef_idx(codec, 0x49, 3<<8, 2<<8);
5224 msleep(800);
5225 val = alc_read_coef_idx(codec, 0x46);
5226 is_ctia = (val & 0x00f0) == 0x00f0;
5227 } else {
5228 alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x34<<10);
5229 alc_update_coef_idx(codec, 0x49, 3<<8, 1<<8);
5230 msleep(800);
5231 val = alc_read_coef_idx(codec, 0x46);
5232 is_ctia = (val & 0x00f0) == 0x00f0;
5233 }
5234 alc_update_coef_idx(codec, 0x4a, 7<<6, 7<<6);
5235 alc_update_coef_idx(codec, 0x4a, 3<<4, 3<<4);
5236 alc_update_coef_idx(codec, 0x67, 0xf000, 0x3000);
Kailang Yangda911b12018-01-05 16:50:08 +08005237
5238 snd_hda_codec_write(codec, 0x21, 0,
5239 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
5240 msleep(80);
5241 snd_hda_codec_write(codec, 0x21, 0,
5242 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08005243 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08005244 case 0x10ec0867:
5245 is_ctia = true;
5246 break;
David Henningsson73bdd592013-04-15 15:44:14 +02005247 }
5248
Takashi Iwai4e76a882014-02-25 12:21:03 +01005249 codec_dbg(codec, "Headset jack detected iPhone-style headset: %s\n",
David Henningsson73bdd592013-04-15 15:44:14 +02005250 is_ctia ? "yes" : "no");
5251 spec->current_headset_type = is_ctia ? ALC_HEADSET_TYPE_CTIA : ALC_HEADSET_TYPE_OMTP;
5252}
5253
5254static void alc_update_headset_mode(struct hda_codec *codec)
5255{
5256 struct alc_spec *spec = codec->spec;
5257
5258 hda_nid_t mux_pin = spec->gen.imux_pins[spec->gen.cur_mux[0]];
Takashi Iwai35a39f92019-02-01 11:19:50 +01005259 hda_nid_t hp_pin = alc_get_hp_pin(spec);
David Henningsson73bdd592013-04-15 15:44:14 +02005260
5261 int new_headset_mode;
5262
5263 if (!snd_hda_jack_detect(codec, hp_pin))
5264 new_headset_mode = ALC_HEADSET_MODE_UNPLUGGED;
5265 else if (mux_pin == spec->headset_mic_pin)
5266 new_headset_mode = ALC_HEADSET_MODE_HEADSET;
5267 else if (mux_pin == spec->headphone_mic_pin)
5268 new_headset_mode = ALC_HEADSET_MODE_MIC;
5269 else
5270 new_headset_mode = ALC_HEADSET_MODE_HEADPHONE;
5271
David Henningsson5959a6b2013-11-12 11:10:57 +01005272 if (new_headset_mode == spec->current_headset_mode) {
5273 snd_hda_gen_update_outputs(codec);
David Henningsson73bdd592013-04-15 15:44:14 +02005274 return;
David Henningsson5959a6b2013-11-12 11:10:57 +01005275 }
David Henningsson73bdd592013-04-15 15:44:14 +02005276
5277 switch (new_headset_mode) {
5278 case ALC_HEADSET_MODE_UNPLUGGED:
5279 alc_headset_mode_unplugged(codec);
Kailang Yangaeac1a02019-05-16 16:10:44 +08005280 spec->current_headset_mode = ALC_HEADSET_MODE_UNKNOWN;
5281 spec->current_headset_type = ALC_HEADSET_TYPE_UNKNOWN;
David Henningsson73bdd592013-04-15 15:44:14 +02005282 spec->gen.hp_jack_present = false;
5283 break;
5284 case ALC_HEADSET_MODE_HEADSET:
5285 if (spec->current_headset_type == ALC_HEADSET_TYPE_UNKNOWN)
5286 alc_determine_headset_type(codec);
5287 if (spec->current_headset_type == ALC_HEADSET_TYPE_CTIA)
5288 alc_headset_mode_ctia(codec);
5289 else if (spec->current_headset_type == ALC_HEADSET_TYPE_OMTP)
5290 alc_headset_mode_omtp(codec);
5291 spec->gen.hp_jack_present = true;
5292 break;
5293 case ALC_HEADSET_MODE_MIC:
5294 alc_headset_mode_mic_in(codec, hp_pin, spec->headphone_mic_pin);
5295 spec->gen.hp_jack_present = false;
5296 break;
5297 case ALC_HEADSET_MODE_HEADPHONE:
5298 alc_headset_mode_default(codec);
5299 spec->gen.hp_jack_present = true;
5300 break;
5301 }
5302 if (new_headset_mode != ALC_HEADSET_MODE_MIC) {
5303 snd_hda_set_pin_ctl_cache(codec, hp_pin,
5304 AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN);
David Henningsson1f8b46c2015-05-12 14:38:15 +02005305 if (spec->headphone_mic_pin && spec->headphone_mic_pin != hp_pin)
David Henningsson73bdd592013-04-15 15:44:14 +02005306 snd_hda_set_pin_ctl_cache(codec, spec->headphone_mic_pin,
5307 PIN_VREFHIZ);
5308 }
5309 spec->current_headset_mode = new_headset_mode;
5310
5311 snd_hda_gen_update_outputs(codec);
5312}
5313
5314static void alc_update_headset_mode_hook(struct hda_codec *codec,
Takashi Iwai7fe30712014-01-30 17:59:02 +01005315 struct snd_kcontrol *kcontrol,
5316 struct snd_ctl_elem_value *ucontrol)
David Henningsson73bdd592013-04-15 15:44:14 +02005317{
5318 alc_update_headset_mode(codec);
5319}
5320
Takashi Iwai1a4f69d2014-09-11 15:22:46 +02005321static void alc_update_headset_jack_cb(struct hda_codec *codec,
5322 struct hda_jack_callback *jack)
David Henningsson73bdd592013-04-15 15:44:14 +02005323{
David Henningsson73bdd592013-04-15 15:44:14 +02005324 snd_hda_gen_hp_automute(codec, jack);
5325}
5326
5327static void alc_probe_headset_mode(struct hda_codec *codec)
5328{
5329 int i;
5330 struct alc_spec *spec = codec->spec;
5331 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
5332
5333 /* Find mic pins */
5334 for (i = 0; i < cfg->num_inputs; i++) {
5335 if (cfg->inputs[i].is_headset_mic && !spec->headset_mic_pin)
5336 spec->headset_mic_pin = cfg->inputs[i].pin;
5337 if (cfg->inputs[i].is_headphone_mic && !spec->headphone_mic_pin)
5338 spec->headphone_mic_pin = cfg->inputs[i].pin;
5339 }
5340
Takashi Iwai0bed2aa2018-06-19 12:45:53 +02005341 WARN_ON(spec->gen.cap_sync_hook);
David Henningsson73bdd592013-04-15 15:44:14 +02005342 spec->gen.cap_sync_hook = alc_update_headset_mode_hook;
5343 spec->gen.automute_hook = alc_update_headset_mode;
5344 spec->gen.hp_automute_hook = alc_update_headset_jack_cb;
5345}
5346
5347static void alc_fixup_headset_mode(struct hda_codec *codec,
5348 const struct hda_fixup *fix, int action)
5349{
5350 struct alc_spec *spec = codec->spec;
5351
5352 switch (action) {
5353 case HDA_FIXUP_ACT_PRE_PROBE:
5354 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC | HDA_PINCFG_HEADPHONE_MIC;
5355 break;
5356 case HDA_FIXUP_ACT_PROBE:
5357 alc_probe_headset_mode(codec);
5358 break;
5359 case HDA_FIXUP_ACT_INIT:
Kailang Yangaeac1a02019-05-16 16:10:44 +08005360 if (is_s3_resume(codec) || is_s4_resume(codec)) {
5361 spec->current_headset_mode = ALC_HEADSET_MODE_UNKNOWN;
5362 spec->current_headset_type = ALC_HEADSET_TYPE_UNKNOWN;
5363 }
David Henningsson73bdd592013-04-15 15:44:14 +02005364 alc_update_headset_mode(codec);
5365 break;
5366 }
5367}
5368
5369static void alc_fixup_headset_mode_no_hp_mic(struct hda_codec *codec,
5370 const struct hda_fixup *fix, int action)
5371{
5372 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5373 struct alc_spec *spec = codec->spec;
5374 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
5375 }
5376 else
5377 alc_fixup_headset_mode(codec, fix, action);
5378}
5379
Kailang Yang31278992014-03-03 15:27:22 +08005380static void alc255_set_default_jack_type(struct hda_codec *codec)
5381{
5382 /* Set to iphone type */
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01005383 static const struct coef_fw alc255fw[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02005384 WRITE_COEF(0x1b, 0x880b),
5385 WRITE_COEF(0x45, 0xd089),
5386 WRITE_COEF(0x1b, 0x080b),
5387 WRITE_COEF(0x46, 0x0004),
5388 WRITE_COEF(0x1b, 0x0c0b),
5389 {}
5390 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01005391 static const struct coef_fw alc256fw[] = {
Kailang Yange69e7e02016-05-30 15:58:28 +08005392 WRITE_COEF(0x1b, 0x884b),
5393 WRITE_COEF(0x45, 0xd089),
5394 WRITE_COEF(0x1b, 0x084b),
5395 WRITE_COEF(0x46, 0x0004),
5396 WRITE_COEF(0x1b, 0x0c4b),
5397 {}
5398 };
5399 switch (codec->core.vendor_id) {
5400 case 0x10ec0255:
5401 alc_process_coef_fw(codec, alc255fw);
5402 break;
Kailang Yang736f20a2017-10-20 15:06:34 +08005403 case 0x10ec0236:
Kailang Yange69e7e02016-05-30 15:58:28 +08005404 case 0x10ec0256:
5405 alc_process_coef_fw(codec, alc256fw);
5406 break;
5407 }
Kailang Yang31278992014-03-03 15:27:22 +08005408 msleep(30);
5409}
5410
Kailang Yang9a22a8f52013-11-08 15:54:49 +08005411static void alc_fixup_headset_mode_alc255(struct hda_codec *codec,
5412 const struct hda_fixup *fix, int action)
5413{
5414 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Kailang Yang31278992014-03-03 15:27:22 +08005415 alc255_set_default_jack_type(codec);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08005416 }
5417 alc_fixup_headset_mode(codec, fix, action);
5418}
5419
Kailang Yang31278992014-03-03 15:27:22 +08005420static void alc_fixup_headset_mode_alc255_no_hp_mic(struct hda_codec *codec,
5421 const struct hda_fixup *fix, int action)
5422{
5423 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5424 struct alc_spec *spec = codec->spec;
5425 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
5426 alc255_set_default_jack_type(codec);
5427 }
5428 else
5429 alc_fixup_headset_mode(codec, fix, action);
5430}
5431
Kailang Yange1e62b92015-04-08 16:01:22 +08005432static void alc288_update_headset_jack_cb(struct hda_codec *codec,
5433 struct hda_jack_callback *jack)
5434{
5435 struct alc_spec *spec = codec->spec;
Kailang Yange1e62b92015-04-08 16:01:22 +08005436
5437 alc_update_headset_jack_cb(codec, jack);
5438 /* Headset Mic enable or disable, only for Dell Dino */
Takashi Iwaid44a6862018-06-19 23:04:03 +02005439 alc_update_gpio_data(codec, 0x40, spec->gen.hp_jack_present);
Kailang Yange1e62b92015-04-08 16:01:22 +08005440}
5441
5442static void alc_fixup_headset_mode_dell_alc288(struct hda_codec *codec,
5443 const struct hda_fixup *fix, int action)
5444{
5445 alc_fixup_headset_mode(codec, fix, action);
5446 if (action == HDA_FIXUP_ACT_PROBE) {
5447 struct alc_spec *spec = codec->spec;
Takashi Iwaid44a6862018-06-19 23:04:03 +02005448 /* toggled via hp_automute_hook */
5449 spec->gpio_mask |= 0x40;
5450 spec->gpio_dir |= 0x40;
Kailang Yange1e62b92015-04-08 16:01:22 +08005451 spec->gen.hp_automute_hook = alc288_update_headset_jack_cb;
5452 }
5453}
5454
Hui Wang493a52a2014-01-14 14:07:36 +08005455static void alc_fixup_auto_mute_via_amp(struct hda_codec *codec,
5456 const struct hda_fixup *fix, int action)
5457{
5458 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5459 struct alc_spec *spec = codec->spec;
5460 spec->gen.auto_mute_via_amp = 1;
5461 }
5462}
5463
Takashi Iwai9b745ab2014-03-07 08:37:19 +01005464static void alc_fixup_no_shutup(struct hda_codec *codec,
5465 const struct hda_fixup *fix, int action)
5466{
Takashi Iwaiefe55732018-06-15 11:55:02 +02005467 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai9b745ab2014-03-07 08:37:19 +01005468 struct alc_spec *spec = codec->spec;
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01005469 spec->no_shutup_pins = 1;
Takashi Iwai9b745ab2014-03-07 08:37:19 +01005470 }
5471}
5472
Gabriele Mazzotta5e6db662014-05-20 18:58:26 +02005473static void alc_fixup_disable_aamix(struct hda_codec *codec,
5474 const struct hda_fixup *fix, int action)
5475{
5476 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5477 struct alc_spec *spec = codec->spec;
5478 /* Disable AA-loopback as it causes white noise */
5479 spec->gen.mixer_nid = 0;
5480 }
5481}
5482
Takashi Iwai7f57d802015-09-24 17:36:51 +02005483/* fixup for Thinkpad docks: add dock pins, avoid HP parser fixup */
5484static void alc_fixup_tpt440_dock(struct hda_codec *codec,
5485 const struct hda_fixup *fix, int action)
5486{
5487 static const struct hda_pintbl pincfgs[] = {
5488 { 0x16, 0x21211010 }, /* dock headphone */
5489 { 0x19, 0x21a11010 }, /* dock mic */
5490 { }
5491 };
5492 struct alc_spec *spec = codec->spec;
5493
5494 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Hui Wang871b9062019-08-14 12:09:08 +08005495 spec->reboot_notify = snd_hda_gen_reboot_notify; /* reduce noise */
Takashi Iwai7f57d802015-09-24 17:36:51 +02005496 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
5497 codec->power_save_node = 0; /* avoid click noises */
5498 snd_hda_apply_pincfgs(codec, pincfgs);
5499 }
5500}
5501
Kailang Yang61fcf8e2018-02-02 15:26:46 +08005502static void alc_fixup_tpt470_dock(struct hda_codec *codec,
5503 const struct hda_fixup *fix, int action)
5504{
5505 static const struct hda_pintbl pincfgs[] = {
5506 { 0x17, 0x21211010 }, /* dock headphone */
5507 { 0x19, 0x21a11010 }, /* dock mic */
5508 { }
5509 };
5510 struct alc_spec *spec = codec->spec;
5511
5512 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5513 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
Takashi Iwai71db96d2018-02-26 15:36:38 +01005514 snd_hda_apply_pincfgs(codec, pincfgs);
5515 } else if (action == HDA_FIXUP_ACT_INIT) {
Kailang Yang61fcf8e2018-02-02 15:26:46 +08005516 /* Enable DOCK device */
5517 snd_hda_codec_write(codec, 0x17, 0,
5518 AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0);
5519 /* Enable DOCK device */
5520 snd_hda_codec_write(codec, 0x19, 0,
5521 AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0);
Kailang Yang61fcf8e2018-02-02 15:26:46 +08005522 }
5523}
5524
Takashi Iwai399c01a2020-05-26 08:24:06 +02005525static void alc_fixup_tpt470_dacs(struct hda_codec *codec,
5526 const struct hda_fixup *fix, int action)
5527{
5528 /* Assure the speaker pin to be coupled with DAC NID 0x03; otherwise
5529 * the speaker output becomes too low by some reason on Thinkpads with
5530 * ALC298 codec
5531 */
5532 static const hda_nid_t preferred_pairs[] = {
5533 0x14, 0x03, 0x17, 0x02, 0x21, 0x02,
5534 0
5535 };
5536 struct alc_spec *spec = codec->spec;
5537
5538 if (action == HDA_FIXUP_ACT_PRE_PROBE)
5539 spec->gen.preferred_dacs = preferred_pairs;
5540}
5541
Gabriele Mazzotta9476d3692015-04-19 19:00:40 +02005542static void alc_shutup_dell_xps13(struct hda_codec *codec)
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02005543{
5544 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01005545 int hp_pin = alc_get_hp_pin(spec);
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02005546
Gabriele Mazzotta9476d3692015-04-19 19:00:40 +02005547 /* Prevent pop noises when headphones are plugged in */
5548 snd_hda_codec_write(codec, hp_pin, 0,
5549 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
5550 msleep(20);
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02005551}
5552
5553static void alc_fixup_dell_xps13(struct hda_codec *codec,
5554 const struct hda_fixup *fix, int action)
5555{
Takashi Iwai3e1b0c42015-04-27 10:43:22 +02005556 struct alc_spec *spec = codec->spec;
5557 struct hda_input_mux *imux = &spec->gen.input_mux;
5558 int i;
Gabriele Mazzottaf38663a2014-08-08 19:34:40 +02005559
Takashi Iwai3e1b0c42015-04-27 10:43:22 +02005560 switch (action) {
5561 case HDA_FIXUP_ACT_PRE_PROBE:
5562 /* mic pin 0x19 must be initialized with Vref Hi-Z, otherwise
5563 * it causes a click noise at start up
5564 */
5565 snd_hda_codec_set_pin_target(codec, 0x19, PIN_VREFHIZ);
Takashi Iwaiefe55732018-06-15 11:55:02 +02005566 spec->shutup = alc_shutup_dell_xps13;
Takashi Iwai3e1b0c42015-04-27 10:43:22 +02005567 break;
5568 case HDA_FIXUP_ACT_PROBE:
Gabriele Mazzottaf38663a2014-08-08 19:34:40 +02005569 /* Make the internal mic the default input source. */
5570 for (i = 0; i < imux->num_items; i++) {
5571 if (spec->gen.imux_pins[i] == 0x12) {
5572 spec->gen.cur_mux[0] = i;
5573 break;
5574 }
5575 }
Takashi Iwai3e1b0c42015-04-27 10:43:22 +02005576 break;
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02005577 }
5578}
5579
David Henningsson1f8b46c2015-05-12 14:38:15 +02005580static void alc_fixup_headset_mode_alc662(struct hda_codec *codec,
5581 const struct hda_fixup *fix, int action)
5582{
5583 struct alc_spec *spec = codec->spec;
5584
5585 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5586 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
5587 spec->gen.hp_mic = 1; /* Mic-in is same pin as headphone */
David Henningssonb40eda62015-05-28 09:40:23 +02005588
5589 /* Disable boost for mic-in permanently. (This code is only called
5590 from quirks that guarantee that the headphone is at NID 0x1b.) */
5591 snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000);
5592 snd_hda_override_wcaps(codec, 0x1b, get_wcaps(codec, 0x1b) & ~AC_WCAP_IN_AMP);
David Henningsson1f8b46c2015-05-12 14:38:15 +02005593 } else
5594 alc_fixup_headset_mode(codec, fix, action);
5595}
5596
David Henningsson73bdd592013-04-15 15:44:14 +02005597static void alc_fixup_headset_mode_alc668(struct hda_codec *codec,
5598 const struct hda_fixup *fix, int action)
5599{
5600 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
David Henningsson73bdd592013-04-15 15:44:14 +02005601 alc_write_coef_idx(codec, 0xc4, 0x8000);
Takashi Iwai98b24882014-08-18 13:47:50 +02005602 alc_update_coef_idx(codec, 0xc2, ~0xfe, 0);
David Henningsson73bdd592013-04-15 15:44:14 +02005603 snd_hda_set_pin_ctl_cache(codec, 0x18, 0);
5604 }
5605 alc_fixup_headset_mode(codec, fix, action);
5606}
5607
Chih-Chung Changbde7bc62013-08-05 16:38:42 +08005608/* Returns the nid of the external mic input pin, or 0 if it cannot be found. */
5609static int find_ext_mic_pin(struct hda_codec *codec)
5610{
5611 struct alc_spec *spec = codec->spec;
5612 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
5613 hda_nid_t nid;
5614 unsigned int defcfg;
5615 int i;
5616
5617 for (i = 0; i < cfg->num_inputs; i++) {
5618 if (cfg->inputs[i].type != AUTO_PIN_MIC)
5619 continue;
5620 nid = cfg->inputs[i].pin;
5621 defcfg = snd_hda_codec_get_pincfg(codec, nid);
5622 if (snd_hda_get_input_pin_attr(defcfg) == INPUT_PIN_ATTR_INT)
5623 continue;
5624 return nid;
5625 }
5626
5627 return 0;
5628}
5629
Dylan Reid08a978d2012-11-18 22:56:40 -08005630static void alc271_hp_gate_mic_jack(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01005631 const struct hda_fixup *fix,
Dylan Reid08a978d2012-11-18 22:56:40 -08005632 int action)
5633{
5634 struct alc_spec *spec = codec->spec;
5635
Takashi Iwai0db75792013-01-23 13:57:20 +01005636 if (action == HDA_FIXUP_ACT_PROBE) {
Chih-Chung Changbde7bc62013-08-05 16:38:42 +08005637 int mic_pin = find_ext_mic_pin(codec);
Takashi Iwai35a39f92019-02-01 11:19:50 +01005638 int hp_pin = alc_get_hp_pin(spec);
Chih-Chung Changbde7bc62013-08-05 16:38:42 +08005639
5640 if (snd_BUG_ON(!mic_pin || !hp_pin))
Takashi Iwai0db75792013-01-23 13:57:20 +01005641 return;
Chih-Chung Changbde7bc62013-08-05 16:38:42 +08005642 snd_hda_jack_set_gating_jack(codec, mic_pin, hp_pin);
Takashi Iwai0db75792013-01-23 13:57:20 +01005643 }
Dylan Reid08a978d2012-11-18 22:56:40 -08005644}
David Henningsson693b6132012-06-22 19:12:10 +02005645
David Henningsson3e0d6112013-04-22 14:30:14 +02005646static void alc269_fixup_limit_int_mic_boost(struct hda_codec *codec,
5647 const struct hda_fixup *fix,
5648 int action)
5649{
5650 struct alc_spec *spec = codec->spec;
5651 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
5652 int i;
5653
5654 /* The mic boosts on level 2 and 3 are too noisy
5655 on the internal mic input.
5656 Therefore limit the boost to 0 or 1. */
5657
5658 if (action != HDA_FIXUP_ACT_PROBE)
5659 return;
5660
5661 for (i = 0; i < cfg->num_inputs; i++) {
5662 hda_nid_t nid = cfg->inputs[i].pin;
5663 unsigned int defcfg;
5664 if (cfg->inputs[i].type != AUTO_PIN_MIC)
5665 continue;
5666 defcfg = snd_hda_codec_get_pincfg(codec, nid);
5667 if (snd_hda_get_input_pin_attr(defcfg) != INPUT_PIN_ATTR_INT)
5668 continue;
5669
5670 snd_hda_override_amp_caps(codec, nid, HDA_INPUT,
5671 (0x00 << AC_AMPCAP_OFFSET_SHIFT) |
5672 (0x01 << AC_AMPCAP_NUM_STEPS_SHIFT) |
5673 (0x2f << AC_AMPCAP_STEP_SIZE_SHIFT) |
5674 (0 << AC_AMPCAP_MUTE_SHIFT));
5675 }
5676}
5677
Kailang Yangcd217a62013-08-22 10:15:24 +02005678static void alc283_hp_automute_hook(struct hda_codec *codec,
Takashi Iwai1a4f69d2014-09-11 15:22:46 +02005679 struct hda_jack_callback *jack)
Kailang Yangcd217a62013-08-22 10:15:24 +02005680{
5681 struct alc_spec *spec = codec->spec;
5682 int vref;
5683
5684 msleep(200);
5685 snd_hda_gen_hp_automute(codec, jack);
5686
5687 vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0;
5688
5689 msleep(600);
5690 snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5691 vref);
5692}
5693
Kailang Yangcd217a62013-08-22 10:15:24 +02005694static void alc283_fixup_chromebook(struct hda_codec *codec,
5695 const struct hda_fixup *fix, int action)
5696{
5697 struct alc_spec *spec = codec->spec;
Kailang Yangcd217a62013-08-22 10:15:24 +02005698
5699 switch (action) {
5700 case HDA_FIXUP_ACT_PRE_PROBE:
Kailang Yang0202e992013-12-02 15:20:15 +08005701 snd_hda_override_wcaps(codec, 0x03, 0);
Takashi Iwaid2e92702013-10-30 07:50:53 +01005702 /* Disable AA-loopback as it causes white noise */
5703 spec->gen.mixer_nid = 0;
Kailang Yang38070212013-11-01 15:57:35 +08005704 break;
5705 case HDA_FIXUP_ACT_INIT:
Kailang Yangde9481c2014-04-07 16:41:52 +08005706 /* MIC2-VREF control */
5707 /* Set to manual mode */
Takashi Iwai98b24882014-08-18 13:47:50 +02005708 alc_update_coef_idx(codec, 0x06, 0x000c, 0);
Kailang Yang0202e992013-12-02 15:20:15 +08005709 /* Enable Line1 input control by verb */
Takashi Iwai98b24882014-08-18 13:47:50 +02005710 alc_update_coef_idx(codec, 0x1a, 0, 1 << 4);
Kailang Yang0202e992013-12-02 15:20:15 +08005711 break;
5712 }
5713}
5714
5715static void alc283_fixup_sense_combo_jack(struct hda_codec *codec,
5716 const struct hda_fixup *fix, int action)
5717{
5718 struct alc_spec *spec = codec->spec;
Kailang Yang0202e992013-12-02 15:20:15 +08005719
5720 switch (action) {
5721 case HDA_FIXUP_ACT_PRE_PROBE:
Kailang Yangcd217a62013-08-22 10:15:24 +02005722 spec->gen.hp_automute_hook = alc283_hp_automute_hook;
5723 break;
5724 case HDA_FIXUP_ACT_INIT:
5725 /* MIC2-VREF control */
5726 /* Set to manual mode */
Takashi Iwai98b24882014-08-18 13:47:50 +02005727 alc_update_coef_idx(codec, 0x06, 0x000c, 0);
Kailang Yangcd217a62013-08-22 10:15:24 +02005728 break;
5729 }
5730}
5731
Takashi Iwai7bba2152013-09-06 15:45:38 +02005732/* mute tablet speaker pin (0x14) via dock plugging in addition */
5733static void asus_tx300_automute(struct hda_codec *codec)
5734{
5735 struct alc_spec *spec = codec->spec;
5736 snd_hda_gen_update_outputs(codec);
5737 if (snd_hda_jack_detect(codec, 0x1b))
5738 spec->gen.mute_bits |= (1ULL << 0x14);
5739}
5740
5741static void alc282_fixup_asus_tx300(struct hda_codec *codec,
5742 const struct hda_fixup *fix, int action)
5743{
5744 struct alc_spec *spec = codec->spec;
Takashi Iwai7bba2152013-09-06 15:45:38 +02005745 static const struct hda_pintbl dock_pins[] = {
5746 { 0x1b, 0x21114000 }, /* dock speaker pin */
5747 {}
5748 };
Takashi Iwai7bba2152013-09-06 15:45:38 +02005749
5750 switch (action) {
5751 case HDA_FIXUP_ACT_PRE_PROBE:
Takashi Iwai1c76aa52018-06-21 16:37:54 +02005752 spec->init_amp = ALC_INIT_DEFAULT;
Takashi Iwaiae065f12018-06-19 23:00:03 +02005753 /* TX300 needs to set up GPIO2 for the speaker amp */
5754 alc_setup_gpio(codec, 0x04);
Takashi Iwai7bba2152013-09-06 15:45:38 +02005755 snd_hda_apply_pincfgs(codec, dock_pins);
5756 spec->gen.auto_mute_via_amp = 1;
5757 spec->gen.automute_hook = asus_tx300_automute;
5758 snd_hda_jack_detect_enable_callback(codec, 0x1b,
Takashi Iwai7bba2152013-09-06 15:45:38 +02005759 snd_hda_gen_hp_automute);
5760 break;
Takashi Iwai5579cd62018-06-19 22:22:41 +02005761 case HDA_FIXUP_ACT_PROBE:
5762 spec->init_amp = ALC_INIT_DEFAULT;
5763 break;
Takashi Iwai7bba2152013-09-06 15:45:38 +02005764 case HDA_FIXUP_ACT_BUILD:
5765 /* this is a bit tricky; give more sane names for the main
5766 * (tablet) speaker and the dock speaker, respectively
5767 */
Takashi Iwai56798e62017-04-11 08:10:52 +02005768 rename_ctl(codec, "Speaker Playback Switch",
5769 "Dock Speaker Playback Switch");
5770 rename_ctl(codec, "Bass Speaker Playback Switch",
5771 "Speaker Playback Switch");
Takashi Iwai7bba2152013-09-06 15:45:38 +02005772 break;
5773 }
5774}
5775
David Henningsson338cae52013-10-07 10:39:59 +02005776static void alc290_fixup_mono_speakers(struct hda_codec *codec,
5777 const struct hda_fixup *fix, int action)
5778{
David Henningsson0f4881d2013-12-20 16:08:13 +01005779 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5780 /* DAC node 0x03 is giving mono output. We therefore want to
5781 make sure 0x14 (front speaker) and 0x15 (headphones) use the
5782 stereo DAC, while leaving 0x17 (bass speaker) for node 0x03. */
Michał Mirosławcaf3c042020-01-03 10:23:48 +01005783 static const hda_nid_t conn1[] = { 0x0c };
5784 snd_hda_override_conn_list(codec, 0x14, ARRAY_SIZE(conn1), conn1);
5785 snd_hda_override_conn_list(codec, 0x15, ARRAY_SIZE(conn1), conn1);
David Henningsson0f4881d2013-12-20 16:08:13 +01005786 }
David Henningsson338cae52013-10-07 10:39:59 +02005787}
5788
Hui Wangdd9aa332016-08-01 10:20:32 +08005789static void alc298_fixup_speaker_volume(struct hda_codec *codec,
5790 const struct hda_fixup *fix, int action)
5791{
5792 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5793 /* The speaker is routed to the Node 0x06 by a mistake, as a result
5794 we can't adjust the speaker's volume since this node does not has
5795 Amp-out capability. we change the speaker's route to:
5796 Node 0x02 (Audio Output) -> Node 0x0c (Audio Mixer) -> Node 0x17 (
5797 Pin Complex), since Node 0x02 has Amp-out caps, we can adjust
5798 speaker's volume now. */
5799
Michał Mirosławcaf3c042020-01-03 10:23:48 +01005800 static const hda_nid_t conn1[] = { 0x0c };
5801 snd_hda_override_conn_list(codec, 0x17, ARRAY_SIZE(conn1), conn1);
Hui Wangdd9aa332016-08-01 10:20:32 +08005802 }
5803}
5804
Takashi Iwaie312a862018-03-06 12:14:17 +01005805/* disable DAC3 (0x06) selection on NID 0x17 as it has no volume amp control */
5806static void alc295_fixup_disable_dac3(struct hda_codec *codec,
5807 const struct hda_fixup *fix, int action)
5808{
5809 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Michał Mirosławcaf3c042020-01-03 10:23:48 +01005810 static const hda_nid_t conn[] = { 0x02, 0x03 };
5811 snd_hda_override_conn_list(codec, 0x17, ARRAY_SIZE(conn), conn);
Takashi Iwaie312a862018-03-06 12:14:17 +01005812 }
5813}
5814
Jaroslav Kyselad2cd7952019-11-29 15:40:27 +01005815/* force NID 0x17 (Bass Speaker) to DAC1 to share it with the main speaker */
5816static void alc285_fixup_speaker2_to_dac1(struct hda_codec *codec,
5817 const struct hda_fixup *fix, int action)
5818{
5819 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Michał Mirosławcaf3c042020-01-03 10:23:48 +01005820 static const hda_nid_t conn[] = { 0x02 };
5821 snd_hda_override_conn_list(codec, 0x17, ARRAY_SIZE(conn), conn);
Jaroslav Kyselad2cd7952019-11-29 15:40:27 +01005822 }
5823}
5824
Keith Packard98973f22015-07-15 12:14:39 -07005825/* Hook to update amp GPIO4 for automute */
5826static void alc280_hp_gpio4_automute_hook(struct hda_codec *codec,
5827 struct hda_jack_callback *jack)
5828{
5829 struct alc_spec *spec = codec->spec;
5830
5831 snd_hda_gen_hp_automute(codec, jack);
5832 /* mute_led_polarity is set to 0, so we pass inverted value here */
Kai-Heng Fengdbd13172020-04-30 16:32:51 +08005833 alc_update_gpio_led(codec, 0x10, spec->mute_led_polarity,
5834 !spec->gen.hp_jack_present);
Keith Packard98973f22015-07-15 12:14:39 -07005835}
5836
5837/* Manage GPIOs for HP EliteBook Folio 9480m.
5838 *
5839 * GPIO4 is the headphone amplifier power control
5840 * GPIO3 is the audio output mute indicator LED
5841 */
5842
5843static void alc280_fixup_hp_9480m(struct hda_codec *codec,
5844 const struct hda_fixup *fix,
5845 int action)
5846{
5847 struct alc_spec *spec = codec->spec;
Keith Packard98973f22015-07-15 12:14:39 -07005848
Takashi Iwai01e4a272018-06-19 22:47:30 +02005849 alc_fixup_hp_gpio_led(codec, action, 0x08, 0);
Keith Packard98973f22015-07-15 12:14:39 -07005850 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai01e4a272018-06-19 22:47:30 +02005851 /* amp at GPIO4; toggled via alc280_hp_gpio4_automute_hook() */
5852 spec->gpio_mask |= 0x10;
5853 spec->gpio_dir |= 0x10;
Keith Packard98973f22015-07-15 12:14:39 -07005854 spec->gen.hp_automute_hook = alc280_hp_gpio4_automute_hook;
Keith Packard98973f22015-07-15 12:14:39 -07005855 }
5856}
5857
Takashi Iwaiae065f12018-06-19 23:00:03 +02005858static void alc275_fixup_gpio4_off(struct hda_codec *codec,
5859 const struct hda_fixup *fix,
5860 int action)
5861{
5862 struct alc_spec *spec = codec->spec;
5863
5864 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5865 spec->gpio_mask |= 0x04;
5866 spec->gpio_dir |= 0x04;
5867 /* set data bit low */
5868 }
5869}
5870
Takashi Iwai6a6660d2020-09-03 10:33:00 +02005871/* Quirk for Thinkpad X1 7th and 8th Gen
5872 * The following fixed routing needed
5873 * DAC1 (NID 0x02) -> Speaker (NID 0x14); some eq applied secretly
5874 * DAC2 (NID 0x03) -> Bass (NID 0x17) & Headphone (NID 0x21); sharing a DAC
5875 * DAC3 (NID 0x06) -> Unused, due to the lack of volume amp
5876 */
5877static void alc285_fixup_thinkpad_x1_gen7(struct hda_codec *codec,
5878 const struct hda_fixup *fix, int action)
5879{
5880 static const hda_nid_t conn[] = { 0x02, 0x03 }; /* exclude 0x06 */
5881 static const hda_nid_t preferred_pairs[] = {
5882 0x14, 0x02, 0x17, 0x03, 0x21, 0x03, 0
5883 };
5884 struct alc_spec *spec = codec->spec;
5885
5886 switch (action) {
5887 case HDA_FIXUP_ACT_PRE_PROBE:
5888 snd_hda_override_conn_list(codec, 0x17, ARRAY_SIZE(conn), conn);
5889 spec->gen.preferred_dacs = preferred_pairs;
5890 break;
5891 case HDA_FIXUP_ACT_BUILD:
5892 /* The generic parser creates somewhat unintuitive volume ctls
5893 * with the fixed routing above, and the shared DAC2 may be
5894 * confusing for PA.
5895 * Rename those to unique names so that PA doesn't touch them
5896 * and use only Master volume.
5897 */
5898 rename_ctl(codec, "Front Playback Volume", "DAC1 Playback Volume");
5899 rename_ctl(codec, "Bass Speaker Playback Volume", "DAC2 Playback Volume");
5900 break;
5901 }
5902}
5903
Kailang Yangca169cc2017-04-25 16:17:40 +08005904static void alc233_alc662_fixup_lenovo_dual_codecs(struct hda_codec *codec,
5905 const struct hda_fixup *fix,
5906 int action)
5907{
5908 alc_fixup_dual_codecs(codec, fix, action);
5909 switch (action) {
5910 case HDA_FIXUP_ACT_PRE_PROBE:
5911 /* override card longname to provide a unique UCM profile */
5912 strcpy(codec->card->longname, "HDAudio-Lenovo-DualCodecs");
5913 break;
5914 case HDA_FIXUP_ACT_BUILD:
5915 /* rename Capture controls depending on the codec */
5916 rename_ctl(codec, "Capture Volume",
5917 codec->addr == 0 ?
5918 "Rear-Panel Capture Volume" :
5919 "Front-Panel Capture Volume");
5920 rename_ctl(codec, "Capture Switch",
5921 codec->addr == 0 ?
5922 "Rear-Panel Capture Switch" :
5923 "Front-Panel Capture Switch");
5924 break;
5925 }
5926}
5927
Kai-Heng Feng52e4e362020-05-03 23:24:47 +08005928static void alc225_fixup_s3_pop_noise(struct hda_codec *codec,
5929 const struct hda_fixup *fix, int action)
5930{
5931 if (action != HDA_FIXUP_ACT_PRE_PROBE)
5932 return;
5933
5934 codec->power_save_node = 1;
5935}
5936
Kailang Yang92266652017-12-14 15:28:58 +08005937/* Forcibly assign NID 0x03 to HP/LO while NID 0x02 to SPK for EQ */
5938static void alc274_fixup_bind_dacs(struct hda_codec *codec,
5939 const struct hda_fixup *fix, int action)
5940{
5941 struct alc_spec *spec = codec->spec;
Michał Mirosławcaf3c042020-01-03 10:23:48 +01005942 static const hda_nid_t preferred_pairs[] = {
Kailang Yang92266652017-12-14 15:28:58 +08005943 0x21, 0x03, 0x1b, 0x03, 0x16, 0x02,
5944 0
5945 };
5946
5947 if (action != HDA_FIXUP_ACT_PRE_PROBE)
5948 return;
5949
5950 spec->gen.preferred_dacs = preferred_pairs;
Kailang Yang0700d3d2019-04-26 16:13:54 +08005951 spec->gen.auto_mute_via_amp = 1;
5952 codec->power_save_node = 0;
Kailang Yang92266652017-12-14 15:28:58 +08005953}
5954
Hui Wangc4cfcf62018-11-26 14:17:16 +08005955/* The DAC of NID 0x3 will introduce click/pop noise on headphones, so invalidate it */
5956static void alc285_fixup_invalidate_dacs(struct hda_codec *codec,
5957 const struct hda_fixup *fix, int action)
5958{
5959 if (action != HDA_FIXUP_ACT_PRE_PROBE)
5960 return;
5961
5962 snd_hda_override_wcaps(codec, 0x03, 0);
5963}
5964
Kailang Yang8983eb62019-04-03 15:31:49 +08005965static void alc295_fixup_chromebook(struct hda_codec *codec,
5966 const struct hda_fixup *fix, int action)
5967{
Kailang Yangd3ba58b2019-05-06 15:09:42 +08005968 struct alc_spec *spec = codec->spec;
5969
Kailang Yang8983eb62019-04-03 15:31:49 +08005970 switch (action) {
Kailang Yangd3ba58b2019-05-06 15:09:42 +08005971 case HDA_FIXUP_ACT_PRE_PROBE:
5972 spec->ultra_low_power = true;
5973 break;
Kailang Yang8983eb62019-04-03 15:31:49 +08005974 case HDA_FIXUP_ACT_INIT:
5975 switch (codec->core.vendor_id) {
5976 case 0x10ec0295:
5977 alc_update_coef_idx(codec, 0x4a, 0x8000, 1 << 15); /* Reset HP JD */
5978 alc_update_coef_idx(codec, 0x4a, 0x8000, 0 << 15);
5979 break;
5980 case 0x10ec0236:
5981 alc_update_coef_idx(codec, 0x1b, 0x8000, 1 << 15); /* Reset HP JD */
5982 alc_update_coef_idx(codec, 0x1b, 0x8000, 0 << 15);
5983 break;
5984 }
5985 break;
5986 }
5987}
5988
Kailang Yangd1dd4212019-01-09 17:05:24 +08005989static void alc_fixup_disable_mic_vref(struct hda_codec *codec,
5990 const struct hda_fixup *fix, int action)
5991{
5992 if (action == HDA_FIXUP_ACT_PRE_PROBE)
5993 snd_hda_codec_set_pin_target(codec, 0x19, PIN_VREFHIZ);
5994}
5995
Kailang Yang56496252020-07-29 15:09:27 +08005996static void alc285_fixup_hp_gpio_amp_init(struct hda_codec *codec,
5997 const struct hda_fixup *fix, int action)
5998{
5999 if (action != HDA_FIXUP_ACT_INIT)
6000 return;
6001
6002 msleep(100);
6003 alc_write_coef_idx(codec, 0x65, 0x0);
6004}
6005
Takashi Iwaib317b032014-01-08 11:44:21 +01006006/* for hda_fixup_thinkpad_acpi() */
6007#include "thinkpad_helper.c"
David Henningssonb67ae3f2013-11-05 13:11:37 +01006008
Takashi Iwaid5a6cab2018-06-13 12:43:10 +02006009static void alc_fixup_thinkpad_acpi(struct hda_codec *codec,
6010 const struct hda_fixup *fix, int action)
6011{
6012 alc_fixup_no_shutup(codec, fix, action); /* reduce click noise */
6013 hda_fixup_thinkpad_acpi(codec, fix, action);
6014}
6015
Tom Bridenbbf8ff62018-05-29 17:34:20 +01006016/* for alc295_fixup_hp_top_speakers */
6017#include "hp_x360_helper.c"
6018
Takashi Iwai1d045db2011-07-07 18:23:21 +02006019enum {
6020 ALC269_FIXUP_SONY_VAIO,
6021 ALC275_FIXUP_SONY_VAIO_GPIO2,
6022 ALC269_FIXUP_DELL_M101Z,
6023 ALC269_FIXUP_SKU_IGNORE,
6024 ALC269_FIXUP_ASUS_G73JW,
6025 ALC269_FIXUP_LENOVO_EAPD,
6026 ALC275_FIXUP_SONY_HWEQ,
Takashi Iwaie9bd7d52014-05-21 11:06:49 +02006027 ALC275_FIXUP_SONY_DISABLE_AAMIX,
Takashi Iwai1d045db2011-07-07 18:23:21 +02006028 ALC271_FIXUP_DMIC,
Takashi Iwai017f2a12011-07-09 14:42:25 +02006029 ALC269_FIXUP_PCM_44K,
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02006030 ALC269_FIXUP_STEREO_DMIC,
David Henningsson7c478f02013-10-11 10:18:46 +02006031 ALC269_FIXUP_HEADSET_MIC,
Takashi Iwai24519912011-08-16 15:08:49 +02006032 ALC269_FIXUP_QUANTA_MUTE,
6033 ALC269_FIXUP_LIFEBOOK,
David Henningsson2041d562014-06-13 11:15:44 +02006034 ALC269_FIXUP_LIFEBOOK_EXTMIC,
Takashi Iwaicc7016a2015-04-08 20:47:55 +02006035 ALC269_FIXUP_LIFEBOOK_HP_PIN,
Takashi Iwai4df3fd12015-06-29 08:38:02 +02006036 ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT,
Jan-Marek Glogowskifdcc9682018-02-14 11:29:15 +01006037 ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC,
Takashi Iwaia4297b52011-08-23 18:40:12 +02006038 ALC269_FIXUP_AMIC,
6039 ALC269_FIXUP_DMIC,
6040 ALC269VB_FIXUP_AMIC,
6041 ALC269VB_FIXUP_DMIC,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01006042 ALC269_FIXUP_HP_MUTE_LED,
David Henningssond06ac142013-02-18 11:41:55 +01006043 ALC269_FIXUP_HP_MUTE_LED_MIC1,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01006044 ALC269_FIXUP_HP_MUTE_LED_MIC2,
Tom Briden7f783bd2017-03-25 10:12:01 +00006045 ALC269_FIXUP_HP_MUTE_LED_MIC3,
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01006046 ALC269_FIXUP_HP_GPIO_LED,
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08006047 ALC269_FIXUP_HP_GPIO_MIC1_LED,
6048 ALC269_FIXUP_HP_LINE1_MIC1_LED,
David Henningsson693b6132012-06-22 19:12:10 +02006049 ALC269_FIXUP_INV_DMIC,
David Henningsson108cc102012-07-20 10:37:25 +02006050 ALC269_FIXUP_LENOVO_DOCK,
Takashi Iwaib590b382020-05-14 18:05:33 +02006051 ALC269_FIXUP_LENOVO_DOCK_LIMIT_BOOST,
Takashi Iwai9b745ab2014-03-07 08:37:19 +01006052 ALC269_FIXUP_NO_SHUTUP,
David Henningsson88cfcf82013-10-11 10:18:45 +02006053 ALC286_FIXUP_SONY_MIC_NO_PRESENCE,
David Henningsson108cc102012-07-20 10:37:25 +02006054 ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT,
David Henningsson73bdd592013-04-15 15:44:14 +02006055 ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
6056 ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
David Henningsson338cae52013-10-07 10:39:59 +02006057 ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
Kailang Yangfcc6c872017-06-29 15:21:27 +08006058 ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
David Henningsson73bdd592013-04-15 15:44:14 +02006059 ALC269_FIXUP_HEADSET_MODE,
6060 ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC,
Takashi Iwai78197172015-06-27 10:21:13 +02006061 ALC269_FIXUP_ASPIRE_HEADSET_MIC,
David Henningssond240d1d2013-04-15 12:50:02 +02006062 ALC269_FIXUP_ASUS_X101_FUNC,
6063 ALC269_FIXUP_ASUS_X101_VERB,
6064 ALC269_FIXUP_ASUS_X101,
Dylan Reid08a978d2012-11-18 22:56:40 -08006065 ALC271_FIXUP_AMIC_MIC2,
6066 ALC271_FIXUP_HP_GATE_MIC_JACK,
Oleksij Rempelb1e89722013-12-04 20:50:53 +01006067 ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572,
Dylan Reid42397002013-04-05 14:58:22 -07006068 ALC269_FIXUP_ACER_AC700,
David Henningsson3e0d6112013-04-22 14:30:14 +02006069 ALC269_FIXUP_LIMIT_INT_MIC_BOOST,
Oleksij Rempel2cede302013-11-27 17:12:03 +01006070 ALC269VB_FIXUP_ASUS_ZENBOOK,
Takashi Iwai23870832013-11-29 14:13:12 +01006071 ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A,
David Henningsson8e35cd42013-11-06 11:20:01 +01006072 ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED,
Anisse Astier02b504d2013-06-03 11:53:10 +02006073 ALC269VB_FIXUP_ORDISSIMO_EVE2,
Kailang Yangcd217a62013-08-22 10:15:24 +02006074 ALC283_FIXUP_CHROME_BOOK,
Kailang Yang0202e992013-12-02 15:20:15 +08006075 ALC283_FIXUP_SENSE_COMBO_JACK,
Takashi Iwai7bba2152013-09-06 15:45:38 +02006076 ALC282_FIXUP_ASUS_TX300,
Kailang Yang1bb3e062013-09-27 13:10:25 +02006077 ALC283_FIXUP_INT_MIC,
David Henningsson338cae52013-10-07 10:39:59 +02006078 ALC290_FIXUP_MONO_SPEAKERS,
David Henningsson0f4881d2013-12-20 16:08:13 +01006079 ALC290_FIXUP_MONO_SPEAKERS_HSJACK,
6080 ALC290_FIXUP_SUBWOOFER,
6081 ALC290_FIXUP_SUBWOOFER_HSJACK,
David Henningssonb67ae3f2013-11-05 13:11:37 +01006082 ALC269_FIXUP_THINKPAD_ACPI,
David Henningsson56f27012016-01-11 09:33:14 +01006083 ALC269_FIXUP_DMIC_THINKPAD_ACPI,
Chris Chiu5824ce82017-02-28 14:17:11 -06006084 ALC255_FIXUP_ACER_MIC_NO_PRESENCE,
Chris Chiu615966a2017-02-28 14:17:12 -06006085 ALC255_FIXUP_ASUS_MIC_NO_PRESENCE,
Kailang Yang9a22a8f52013-11-08 15:54:49 +08006086 ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Kailang Yang31278992014-03-03 15:27:22 +08006087 ALC255_FIXUP_DELL2_MIC_NO_PRESENCE,
Kailang Yang9a22a8f52013-11-08 15:54:49 +08006088 ALC255_FIXUP_HEADSET_MODE,
Kailang Yang31278992014-03-03 15:27:22 +08006089 ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC,
Kailang Yanga22aa262014-04-23 17:34:28 +08006090 ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
Takashi Iwai1c37c222014-05-06 17:34:42 +02006091 ALC292_FIXUP_TPT440_DOCK,
Takashi Iwai9a811232015-12-09 15:17:43 +01006092 ALC292_FIXUP_TPT440,
Anisse Astierabaa22742016-08-24 09:14:13 +02006093 ALC283_FIXUP_HEADSET_MIC,
Takashi Iwaib3802782018-11-26 17:47:46 +01006094 ALC255_FIXUP_MIC_MUTE_LED,
Takashi Iwai1a22e772014-08-27 08:19:05 +02006095 ALC282_FIXUP_ASPIRE_V5_PINS,
David Henningsson7a5255f2014-10-30 08:26:01 +01006096 ALC280_FIXUP_HP_GPIO4,
Kailang Yangeaa8e5e2014-11-21 15:49:11 +08006097 ALC286_FIXUP_HP_GPIO_LED,
David Henningsson33f4acd2015-01-07 15:50:13 +01006098 ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY,
TienFu Chenb4b33f92015-01-20 15:06:21 +01006099 ALC280_FIXUP_HP_DOCK_PINS,
Jaroslav Kysela04d54662017-03-09 13:29:13 +01006100 ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED,
Keith Packard98973f22015-07-15 12:14:39 -07006101 ALC280_FIXUP_HP_9480M,
Kailang Yange1e62b92015-04-08 16:01:22 +08006102 ALC288_FIXUP_DELL_HEADSET_MODE,
6103 ALC288_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang831bfdf92015-06-26 12:35:17 +08006104 ALC288_FIXUP_DELL_XPS_13,
6105 ALC288_FIXUP_DISABLE_AAMIX,
Takashi Iwai5fab5822020-01-05 09:11:19 +01006106 ALC292_FIXUP_DELL_E7X_AAMIX,
Takashi Iwai8b99aba2015-06-15 11:59:32 +02006107 ALC292_FIXUP_DELL_E7X,
6108 ALC292_FIXUP_DISABLE_AAMIX,
David Henningssonc04017e2015-12-15 14:44:03 +01006109 ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK,
James McDonnell54324222019-09-16 14:53:38 +00006110 ALC298_FIXUP_ALIENWARE_MIC_NO_PRESENCE,
Kailang Yang977e6272015-05-18 15:31:20 +08006111 ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang2f726ae2017-03-31 10:31:40 +08006112 ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE,
Kailang Yang6ed11312015-10-26 15:37:39 +08006113 ALC275_FIXUP_DELL_XPS,
Hui Wang23adc192015-12-08 12:27:18 +08006114 ALC293_FIXUP_LENOVO_SPK_NOISE,
Kailang3694cb22015-12-28 11:35:24 +08006115 ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY,
Kai-Heng Feng3b43b712016-02-25 15:19:38 +08006116 ALC255_FIXUP_DELL_SPK_NOISE,
Kailang Yangd1dd4212019-01-09 17:05:24 +08006117 ALC225_FIXUP_DISABLE_MIC_VREF,
David Henningsson2ae95572016-02-25 09:37:05 +01006118 ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
Takashi Iwaie312a862018-03-06 12:14:17 +01006119 ALC295_FIXUP_DISABLE_DAC3,
Jaroslav Kyselad2cd7952019-11-29 15:40:27 +01006120 ALC285_FIXUP_SPEAKER2_TO_DAC1,
Takashi Iwaif8839822016-02-25 14:31:59 +01006121 ALC280_FIXUP_HP_HEADSET_MIC,
Hui Wange549d192016-04-01 11:00:15 +08006122 ALC221_FIXUP_HP_FRONT_MIC,
Sven Eckelmannc636b952016-04-11 16:55:26 +02006123 ALC292_FIXUP_TPT460,
Hui Wangdd9aa332016-08-01 10:20:32 +08006124 ALC298_FIXUP_SPK_VOLUME,
Kai-Heng Fengfd06c772016-08-30 15:36:34 +08006125 ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER,
Gabriele Mazzotta823ff162016-12-24 19:50:01 +01006126 ALC269_FIXUP_ATIV_BOOK_8,
Kailang Yang9eb5d0e2017-01-17 15:40:25 +08006127 ALC221_FIXUP_HP_MIC_NO_PRESENCE,
Chris Chiuc1732ed2017-02-28 14:17:13 -06006128 ALC256_FIXUP_ASUS_HEADSET_MODE,
6129 ALC256_FIXUP_ASUS_MIC,
Chris Chiueeed4cd2017-02-28 14:17:15 -06006130 ALC256_FIXUP_ASUS_AIO_GPIO2,
Chris Chiu216d7ae2017-02-28 14:17:14 -06006131 ALC233_FIXUP_ASUS_MIC_NO_PRESENCE,
6132 ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE,
Kailang Yangca169cc2017-04-25 16:17:40 +08006133 ALC233_FIXUP_LENOVO_MULTI_CODECS,
Jian-Hong Panea5c7eb2019-04-01 11:25:05 +08006134 ALC233_FIXUP_ACER_HEADSET_MIC,
Hui Wangf33f79f2017-07-07 12:08:29 +08006135 ALC294_FIXUP_LENOVO_MIC_LOCATION,
Kailang Yang5f364132017-07-25 16:28:16 +08006136 ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE,
Kai-Heng Feng52e4e362020-05-03 23:24:47 +08006137 ALC225_FIXUP_S3_POP_NOISE,
PeiSen Houb84e8432017-09-01 15:11:56 +08006138 ALC700_FIXUP_INTEL_REFERENCE,
Kailang Yang92266652017-12-14 15:28:58 +08006139 ALC274_FIXUP_DELL_BIND_DACS,
6140 ALC274_FIXUP_DELL_AIO_LINEOUT_VERB,
Takashi Iwai399c01a2020-05-26 08:24:06 +02006141 ALC298_FIXUP_TPT470_DOCK_FIX,
Kailang Yang61fcf8e2018-02-02 15:26:46 +08006142 ALC298_FIXUP_TPT470_DOCK,
Kailang Yangae104a22018-02-05 16:07:20 +08006143 ALC255_FIXUP_DUMMY_LINEOUT_VERB,
Kailang Yangf0ba9d62018-03-16 11:46:08 +08006144 ALC255_FIXUP_DELL_HEADSET_MIC,
Ayman Bagabas0fbf21c2019-05-23 05:30:11 -04006145 ALC256_FIXUP_HUAWEI_MACH_WX9_PINS,
Tomas Espeletaa2ef03f2019-08-09 16:37:54 +02006146 ALC298_FIXUP_HUAWEI_MBX_STEREO,
Tom Bridenbbf8ff62018-05-29 17:34:20 +01006147 ALC295_FIXUP_HP_X360,
Kailang Yang8a328ac2018-08-21 16:54:41 +08006148 ALC221_FIXUP_HP_HEADSET_MIC,
Hui Wangc4cfcf62018-11-26 14:17:16 +08006149 ALC285_FIXUP_LENOVO_HEADPHONE_NOISE,
Girija Kumar Kasinadhunie8ed64b2018-11-26 13:40:46 -05006150 ALC295_FIXUP_HP_AUTO_MUTE,
Chris Chiu33aaebd2018-12-05 14:48:53 +08006151 ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE,
Chris Chiud8ae4582018-12-07 17:17:11 +08006152 ALC294_FIXUP_ASUS_MIC,
Jian-Hong Pan4e051102018-12-07 17:17:12 +08006153 ALC294_FIXUP_ASUS_HEADSET_MIC,
6154 ALC294_FIXUP_ASUS_SPK,
Jeremy Soller89e3a562019-01-30 16:12:31 -07006155 ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE,
Hui Wangc8c6ee62019-02-14 11:41:33 +08006156 ALC285_FIXUP_LENOVO_PC_BEEP_IN_NOISE,
Jian-Hong Pancbc05fd2019-03-13 17:33:24 +08006157 ALC255_FIXUP_ACER_HEADSET_MIC,
Kailang Yang10f5b1b2019-02-21 16:10:22 +08006158 ALC295_FIXUP_CHROME_BOOK,
Kailang Yang8983eb62019-04-03 15:31:49 +08006159 ALC225_FIXUP_HEADSET_JACK,
Kailang Yang136824e2019-03-14 16:22:45 +08006160 ALC225_FIXUP_DELL_WYSE_AIO_MIC_NO_PRESENCE,
6161 ALC225_FIXUP_WYSE_AUTO_MUTE,
6162 ALC225_FIXUP_WYSE_DISABLE_MIC_VREF,
Jian-Hong Pan667a8f72019-03-15 17:51:09 +08006163 ALC286_FIXUP_ACER_AIO_HEADSET_MIC,
Daniel Drake8c8967a2019-10-17 16:15:01 +08006164 ALC256_FIXUP_ASUS_HEADSET_MIC,
Jian-Hong Pane1037352019-03-22 11:37:18 +08006165 ALC256_FIXUP_ASUS_MIC_NO_PRESENCE,
Bernhard Rosenkraenzere2a829b2019-03-05 00:38:19 +01006166 ALC299_FIXUP_PREDATOR_SPK,
Jan-Marek Glogowskibd9c10b2019-09-15 16:57:28 +02006167 ALC256_FIXUP_MEDION_HEADSET_NO_PRESENCE,
Kailang Yange79c2262019-12-19 14:12:15 +08006168 ALC289_FIXUP_DELL_SPK2,
6169 ALC289_FIXUP_DUAL_SPK,
Chris Chiu48e01502019-12-30 11:11:18 +08006170 ALC294_FIXUP_SPK2_TO_DAC1,
6171 ALC294_FIXUP_ASUS_DUAL_SPK,
Takashi Iwai6a6660d2020-09-03 10:33:00 +02006172 ALC285_FIXUP_THINKPAD_X1_GEN7,
Kailang Yang76f7dec2020-02-10 16:30:26 +08006173 ALC285_FIXUP_THINKPAD_HEADSET_JACK,
Jian-Hong Pan8b33a132020-02-25 15:29:21 +08006174 ALC294_FIXUP_ASUS_HPE,
Takashi Iwai1b94e592020-05-12 09:32:03 +02006175 ALC294_FIXUP_ASUS_COEF_1B,
Kai-Heng Fengf5a88b02020-03-27 12:46:25 +08006176 ALC285_FIXUP_HP_GPIO_LED,
Kailang Yang431e76c2020-04-07 14:40:20 +08006177 ALC285_FIXUP_HP_MUTE_LED,
Kailang Yang24164f42020-04-07 14:52:42 +08006178 ALC236_FIXUP_HP_MUTE_LED,
Mike Pozulp14425f12020-05-09 20:28:37 -07006179 ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET,
Chris Chiu9e433422020-05-12 14:15:24 +08006180 ALC295_FIXUP_ASUS_MIC_NO_PRESENCE,
Jian-Hong Pan8eae7e92020-07-06 15:18:25 +08006181 ALC269VC_FIXUP_ACER_VCOPPERBOX_PINS,
Jian-Hong Pan6e15d122020-07-06 15:18:27 +08006182 ALC269VC_FIXUP_ACER_HEADSET_MIC,
Jian-Hong Pan781c90c2020-07-06 15:18:29 +08006183 ALC269VC_FIXUP_ACER_MIC_NO_PRESENCE,
Armas Spann293a92c2020-07-24 16:08:37 +02006184 ALC289_FIXUP_ASUS_GA401,
Armas Spann4b43d052020-07-24 16:06:16 +02006185 ALC289_FIXUP_ASUS_GA502,
Jian-Hong Panf50a1212020-07-13 14:04:22 +08006186 ALC256_FIXUP_ACER_MIC_NO_PRESENCE,
Kailang Yang56496252020-07-29 15:09:27 +08006187 ALC285_FIXUP_HP_GPIO_AMP_INIT,
Huacai Chenf1ec5be2020-08-02 17:26:40 +08006188 ALC269_FIXUP_CZC_B20,
6189 ALC269_FIXUP_CZC_TMI,
6190 ALC269_FIXUP_CZC_L101,
6191 ALC269_FIXUP_LEMOTE_A1802,
6192 ALC269_FIXUP_LEMOTE_A190X,
Kai-Heng Fenge2d2fde2020-08-07 16:05:12 +08006193 ALC256_FIXUP_INTEL_NUC8_RUGGED,
Takashi Iwai1d045db2011-07-07 18:23:21 +02006194};
6195
Takashi Iwai1727a772013-01-10 09:52:52 +01006196static const struct hda_fixup alc269_fixups[] = {
Takashi Iwai1d045db2011-07-07 18:23:21 +02006197 [ALC269_FIXUP_SONY_VAIO] = {
Takashi Iwaifd108212013-01-10 10:18:14 +01006198 .type = HDA_FIXUP_PINCTLS,
6199 .v.pins = (const struct hda_pintbl[]) {
6200 {0x19, PIN_VREFGRD},
Takashi Iwai1d045db2011-07-07 18:23:21 +02006201 {}
6202 }
6203 },
6204 [ALC275_FIXUP_SONY_VAIO_GPIO2] = {
Takashi Iwaiae065f12018-06-19 23:00:03 +02006205 .type = HDA_FIXUP_FUNC,
6206 .v.func = alc275_fixup_gpio4_off,
Takashi Iwai1d045db2011-07-07 18:23:21 +02006207 .chained = true,
6208 .chain_id = ALC269_FIXUP_SONY_VAIO
6209 },
6210 [ALC269_FIXUP_DELL_M101Z] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006211 .type = HDA_FIXUP_VERBS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02006212 .v.verbs = (const struct hda_verb[]) {
6213 /* Enables internal speaker */
6214 {0x20, AC_VERB_SET_COEF_INDEX, 13},
6215 {0x20, AC_VERB_SET_PROC_COEF, 0x4040},
6216 {}
6217 }
6218 },
6219 [ALC269_FIXUP_SKU_IGNORE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006220 .type = HDA_FIXUP_FUNC,
Takashi Iwai23d30f22012-05-07 17:17:32 +02006221 .v.func = alc_fixup_sku_ignore,
Takashi Iwai1d045db2011-07-07 18:23:21 +02006222 },
6223 [ALC269_FIXUP_ASUS_G73JW] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006224 .type = HDA_FIXUP_PINS,
6225 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02006226 { 0x17, 0x99130111 }, /* subwoofer */
6227 { }
6228 }
6229 },
6230 [ALC269_FIXUP_LENOVO_EAPD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006231 .type = HDA_FIXUP_VERBS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02006232 .v.verbs = (const struct hda_verb[]) {
6233 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
6234 {}
6235 }
6236 },
6237 [ALC275_FIXUP_SONY_HWEQ] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006238 .type = HDA_FIXUP_FUNC,
Takashi Iwai1d045db2011-07-07 18:23:21 +02006239 .v.func = alc269_fixup_hweq,
6240 .chained = true,
6241 .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2
6242 },
Takashi Iwaie9bd7d52014-05-21 11:06:49 +02006243 [ALC275_FIXUP_SONY_DISABLE_AAMIX] = {
6244 .type = HDA_FIXUP_FUNC,
6245 .v.func = alc_fixup_disable_aamix,
6246 .chained = true,
6247 .chain_id = ALC269_FIXUP_SONY_VAIO
6248 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02006249 [ALC271_FIXUP_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006250 .type = HDA_FIXUP_FUNC,
Takashi Iwai1d045db2011-07-07 18:23:21 +02006251 .v.func = alc271_fixup_dmic,
6252 },
Takashi Iwai017f2a12011-07-09 14:42:25 +02006253 [ALC269_FIXUP_PCM_44K] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006254 .type = HDA_FIXUP_FUNC,
Takashi Iwai017f2a12011-07-09 14:42:25 +02006255 .v.func = alc269_fixup_pcm_44k,
David Henningsson012e7eb2012-08-08 08:43:37 +02006256 .chained = true,
6257 .chain_id = ALC269_FIXUP_QUANTA_MUTE
Takashi Iwai017f2a12011-07-09 14:42:25 +02006258 },
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02006259 [ALC269_FIXUP_STEREO_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006260 .type = HDA_FIXUP_FUNC,
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02006261 .v.func = alc269_fixup_stereo_dmic,
6262 },
David Henningsson7c478f02013-10-11 10:18:46 +02006263 [ALC269_FIXUP_HEADSET_MIC] = {
6264 .type = HDA_FIXUP_FUNC,
6265 .v.func = alc269_fixup_headset_mic,
6266 },
Takashi Iwai24519912011-08-16 15:08:49 +02006267 [ALC269_FIXUP_QUANTA_MUTE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006268 .type = HDA_FIXUP_FUNC,
Takashi Iwai24519912011-08-16 15:08:49 +02006269 .v.func = alc269_fixup_quanta_mute,
6270 },
6271 [ALC269_FIXUP_LIFEBOOK] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006272 .type = HDA_FIXUP_PINS,
6273 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai24519912011-08-16 15:08:49 +02006274 { 0x1a, 0x2101103f }, /* dock line-out */
6275 { 0x1b, 0x23a11040 }, /* dock mic-in */
6276 { }
6277 },
6278 .chained = true,
6279 .chain_id = ALC269_FIXUP_QUANTA_MUTE
6280 },
David Henningsson2041d562014-06-13 11:15:44 +02006281 [ALC269_FIXUP_LIFEBOOK_EXTMIC] = {
6282 .type = HDA_FIXUP_PINS,
6283 .v.pins = (const struct hda_pintbl[]) {
6284 { 0x19, 0x01a1903c }, /* headset mic, with jack detect */
6285 { }
6286 },
6287 },
Takashi Iwaicc7016a2015-04-08 20:47:55 +02006288 [ALC269_FIXUP_LIFEBOOK_HP_PIN] = {
6289 .type = HDA_FIXUP_PINS,
6290 .v.pins = (const struct hda_pintbl[]) {
6291 { 0x21, 0x0221102f }, /* HP out */
6292 { }
6293 },
6294 },
Takashi Iwai4df3fd12015-06-29 08:38:02 +02006295 [ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT] = {
6296 .type = HDA_FIXUP_FUNC,
6297 .v.func = alc269_fixup_pincfg_no_hp_to_lineout,
6298 },
Jan-Marek Glogowskifdcc9682018-02-14 11:29:15 +01006299 [ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC] = {
6300 .type = HDA_FIXUP_FUNC,
6301 .v.func = alc269_fixup_pincfg_U7x7_headset_mic,
6302 },
Takashi Iwaia4297b52011-08-23 18:40:12 +02006303 [ALC269_FIXUP_AMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006304 .type = HDA_FIXUP_PINS,
6305 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaia4297b52011-08-23 18:40:12 +02006306 { 0x14, 0x99130110 }, /* speaker */
6307 { 0x15, 0x0121401f }, /* HP out */
6308 { 0x18, 0x01a19c20 }, /* mic */
6309 { 0x19, 0x99a3092f }, /* int-mic */
6310 { }
6311 },
6312 },
6313 [ALC269_FIXUP_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006314 .type = HDA_FIXUP_PINS,
6315 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaia4297b52011-08-23 18:40:12 +02006316 { 0x12, 0x99a3092f }, /* int-mic */
6317 { 0x14, 0x99130110 }, /* speaker */
6318 { 0x15, 0x0121401f }, /* HP out */
6319 { 0x18, 0x01a19c20 }, /* mic */
6320 { }
6321 },
6322 },
6323 [ALC269VB_FIXUP_AMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006324 .type = HDA_FIXUP_PINS,
6325 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaia4297b52011-08-23 18:40:12 +02006326 { 0x14, 0x99130110 }, /* speaker */
6327 { 0x18, 0x01a19c20 }, /* mic */
6328 { 0x19, 0x99a3092f }, /* int-mic */
6329 { 0x21, 0x0121401f }, /* HP out */
6330 { }
6331 },
6332 },
David Henningsson2267ea92012-01-03 08:45:56 +01006333 [ALC269VB_FIXUP_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006334 .type = HDA_FIXUP_PINS,
6335 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaia4297b52011-08-23 18:40:12 +02006336 { 0x12, 0x99a3092f }, /* int-mic */
6337 { 0x14, 0x99130110 }, /* speaker */
6338 { 0x18, 0x01a19c20 }, /* mic */
6339 { 0x21, 0x0121401f }, /* HP out */
6340 { }
6341 },
6342 },
Takashi Iwai08fb0d02013-01-10 17:33:58 +01006343 [ALC269_FIXUP_HP_MUTE_LED] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006344 .type = HDA_FIXUP_FUNC,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01006345 .v.func = alc269_fixup_hp_mute_led,
David Henningsson6d3cd5d2013-01-07 12:03:47 +01006346 },
David Henningssond06ac142013-02-18 11:41:55 +01006347 [ALC269_FIXUP_HP_MUTE_LED_MIC1] = {
6348 .type = HDA_FIXUP_FUNC,
6349 .v.func = alc269_fixup_hp_mute_led_mic1,
6350 },
Takashi Iwai08fb0d02013-01-10 17:33:58 +01006351 [ALC269_FIXUP_HP_MUTE_LED_MIC2] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006352 .type = HDA_FIXUP_FUNC,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01006353 .v.func = alc269_fixup_hp_mute_led_mic2,
Takashi Iwai420b0fe2012-03-12 12:35:27 +01006354 },
Tom Briden7f783bd2017-03-25 10:12:01 +00006355 [ALC269_FIXUP_HP_MUTE_LED_MIC3] = {
6356 .type = HDA_FIXUP_FUNC,
6357 .v.func = alc269_fixup_hp_mute_led_mic3,
Girija Kumar Kasinadhunie8ed64b2018-11-26 13:40:46 -05006358 .chained = true,
6359 .chain_id = ALC295_FIXUP_HP_AUTO_MUTE
Tom Briden7f783bd2017-03-25 10:12:01 +00006360 },
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01006361 [ALC269_FIXUP_HP_GPIO_LED] = {
6362 .type = HDA_FIXUP_FUNC,
6363 .v.func = alc269_fixup_hp_gpio_led,
6364 },
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08006365 [ALC269_FIXUP_HP_GPIO_MIC1_LED] = {
6366 .type = HDA_FIXUP_FUNC,
6367 .v.func = alc269_fixup_hp_gpio_mic1_led,
6368 },
6369 [ALC269_FIXUP_HP_LINE1_MIC1_LED] = {
6370 .type = HDA_FIXUP_FUNC,
6371 .v.func = alc269_fixup_hp_line1_mic1_led,
6372 },
David Henningsson693b6132012-06-22 19:12:10 +02006373 [ALC269_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006374 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02006375 .v.func = alc_fixup_inv_dmic,
David Henningsson693b6132012-06-22 19:12:10 +02006376 },
Takashi Iwai9b745ab2014-03-07 08:37:19 +01006377 [ALC269_FIXUP_NO_SHUTUP] = {
6378 .type = HDA_FIXUP_FUNC,
6379 .v.func = alc_fixup_no_shutup,
6380 },
David Henningsson108cc102012-07-20 10:37:25 +02006381 [ALC269_FIXUP_LENOVO_DOCK] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006382 .type = HDA_FIXUP_PINS,
6383 .v.pins = (const struct hda_pintbl[]) {
David Henningsson108cc102012-07-20 10:37:25 +02006384 { 0x19, 0x23a11040 }, /* dock mic */
6385 { 0x1b, 0x2121103f }, /* dock headphone */
6386 { }
6387 },
6388 .chained = true,
6389 .chain_id = ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT
6390 },
Takashi Iwaib590b382020-05-14 18:05:33 +02006391 [ALC269_FIXUP_LENOVO_DOCK_LIMIT_BOOST] = {
6392 .type = HDA_FIXUP_FUNC,
6393 .v.func = alc269_fixup_limit_int_mic_boost,
6394 .chained = true,
6395 .chain_id = ALC269_FIXUP_LENOVO_DOCK,
6396 },
David Henningsson108cc102012-07-20 10:37:25 +02006397 [ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006398 .type = HDA_FIXUP_FUNC,
David Henningsson108cc102012-07-20 10:37:25 +02006399 .v.func = alc269_fixup_pincfg_no_hp_to_lineout,
David Henningsson52129002013-11-19 10:25:53 +01006400 .chained = true,
6401 .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
David Henningsson108cc102012-07-20 10:37:25 +02006402 },
David Henningsson73bdd592013-04-15 15:44:14 +02006403 [ALC269_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6404 .type = HDA_FIXUP_PINS,
6405 .v.pins = (const struct hda_pintbl[]) {
6406 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6407 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6408 { }
6409 },
6410 .chained = true,
6411 .chain_id = ALC269_FIXUP_HEADSET_MODE
6412 },
6413 [ALC269_FIXUP_DELL2_MIC_NO_PRESENCE] = {
6414 .type = HDA_FIXUP_PINS,
6415 .v.pins = (const struct hda_pintbl[]) {
6416 { 0x16, 0x21014020 }, /* dock line out */
6417 { 0x19, 0x21a19030 }, /* dock mic */
6418 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6419 { }
6420 },
6421 .chained = true,
6422 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
6423 },
David Henningsson338cae52013-10-07 10:39:59 +02006424 [ALC269_FIXUP_DELL3_MIC_NO_PRESENCE] = {
6425 .type = HDA_FIXUP_PINS,
6426 .v.pins = (const struct hda_pintbl[]) {
6427 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6428 { }
6429 },
6430 .chained = true,
6431 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
6432 },
Kailang Yangfcc6c872017-06-29 15:21:27 +08006433 [ALC269_FIXUP_DELL4_MIC_NO_PRESENCE] = {
6434 .type = HDA_FIXUP_PINS,
6435 .v.pins = (const struct hda_pintbl[]) {
6436 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6437 { 0x1b, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6438 { }
6439 },
6440 .chained = true,
6441 .chain_id = ALC269_FIXUP_HEADSET_MODE
6442 },
David Henningsson73bdd592013-04-15 15:44:14 +02006443 [ALC269_FIXUP_HEADSET_MODE] = {
6444 .type = HDA_FIXUP_FUNC,
6445 .v.func = alc_fixup_headset_mode,
Hui Wang6676f302014-11-18 17:57:41 +08006446 .chained = true,
Takashi Iwaib3802782018-11-26 17:47:46 +01006447 .chain_id = ALC255_FIXUP_MIC_MUTE_LED
David Henningsson73bdd592013-04-15 15:44:14 +02006448 },
6449 [ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC] = {
6450 .type = HDA_FIXUP_FUNC,
6451 .v.func = alc_fixup_headset_mode_no_hp_mic,
6452 },
Takashi Iwai78197172015-06-27 10:21:13 +02006453 [ALC269_FIXUP_ASPIRE_HEADSET_MIC] = {
6454 .type = HDA_FIXUP_PINS,
6455 .v.pins = (const struct hda_pintbl[]) {
6456 { 0x19, 0x01a1913c }, /* headset mic w/o jack detect */
6457 { }
6458 },
6459 .chained = true,
6460 .chain_id = ALC269_FIXUP_HEADSET_MODE,
6461 },
David Henningsson88cfcf82013-10-11 10:18:45 +02006462 [ALC286_FIXUP_SONY_MIC_NO_PRESENCE] = {
6463 .type = HDA_FIXUP_PINS,
6464 .v.pins = (const struct hda_pintbl[]) {
6465 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6466 { }
6467 },
David Henningssonfbc78ad2013-10-11 13:46:04 +02006468 .chained = true,
6469 .chain_id = ALC269_FIXUP_HEADSET_MIC
David Henningsson88cfcf82013-10-11 10:18:45 +02006470 },
Ayman Bagabas0fbf21c2019-05-23 05:30:11 -04006471 [ALC256_FIXUP_HUAWEI_MACH_WX9_PINS] = {
Ayman Bagabas8ac51bb2018-12-12 18:07:57 -05006472 .type = HDA_FIXUP_PINS,
6473 .v.pins = (const struct hda_pintbl[]) {
6474 {0x12, 0x90a60130},
6475 {0x13, 0x40000000},
6476 {0x14, 0x90170110},
6477 {0x18, 0x411111f0},
6478 {0x19, 0x04a11040},
6479 {0x1a, 0x411111f0},
6480 {0x1b, 0x90170112},
6481 {0x1d, 0x40759a05},
6482 {0x1e, 0x411111f0},
6483 {0x21, 0x04211020},
6484 { }
6485 },
Ayman Bagabase2744fd2018-12-12 18:07:59 -05006486 .chained = true,
6487 .chain_id = ALC255_FIXUP_MIC_MUTE_LED
Ayman Bagabas8ac51bb2018-12-12 18:07:57 -05006488 },
Tomas Espeletaa2ef03f2019-08-09 16:37:54 +02006489 [ALC298_FIXUP_HUAWEI_MBX_STEREO] = {
6490 .type = HDA_FIXUP_FUNC,
6491 .v.func = alc298_fixup_huawei_mbx_stereo,
6492 .chained = true,
6493 .chain_id = ALC255_FIXUP_MIC_MUTE_LED
6494 },
David Henningssond240d1d2013-04-15 12:50:02 +02006495 [ALC269_FIXUP_ASUS_X101_FUNC] = {
6496 .type = HDA_FIXUP_FUNC,
6497 .v.func = alc269_fixup_x101_headset_mic,
6498 },
6499 [ALC269_FIXUP_ASUS_X101_VERB] = {
6500 .type = HDA_FIXUP_VERBS,
6501 .v.verbs = (const struct hda_verb[]) {
6502 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6503 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
6504 {0x20, AC_VERB_SET_PROC_COEF, 0x0310},
6505 { }
6506 },
6507 .chained = true,
6508 .chain_id = ALC269_FIXUP_ASUS_X101_FUNC
6509 },
6510 [ALC269_FIXUP_ASUS_X101] = {
6511 .type = HDA_FIXUP_PINS,
6512 .v.pins = (const struct hda_pintbl[]) {
6513 { 0x18, 0x04a1182c }, /* Headset mic */
6514 { }
6515 },
6516 .chained = true,
6517 .chain_id = ALC269_FIXUP_ASUS_X101_VERB
6518 },
Dylan Reid08a978d2012-11-18 22:56:40 -08006519 [ALC271_FIXUP_AMIC_MIC2] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006520 .type = HDA_FIXUP_PINS,
6521 .v.pins = (const struct hda_pintbl[]) {
Dylan Reid08a978d2012-11-18 22:56:40 -08006522 { 0x14, 0x99130110 }, /* speaker */
6523 { 0x19, 0x01a19c20 }, /* mic */
6524 { 0x1b, 0x99a7012f }, /* int-mic */
6525 { 0x21, 0x0121401f }, /* HP out */
6526 { }
6527 },
6528 },
6529 [ALC271_FIXUP_HP_GATE_MIC_JACK] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006530 .type = HDA_FIXUP_FUNC,
Dylan Reid08a978d2012-11-18 22:56:40 -08006531 .v.func = alc271_hp_gate_mic_jack,
6532 .chained = true,
6533 .chain_id = ALC271_FIXUP_AMIC_MIC2,
6534 },
Oleksij Rempelb1e89722013-12-04 20:50:53 +01006535 [ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572] = {
6536 .type = HDA_FIXUP_FUNC,
6537 .v.func = alc269_fixup_limit_int_mic_boost,
6538 .chained = true,
6539 .chain_id = ALC271_FIXUP_HP_GATE_MIC_JACK,
6540 },
Dylan Reid42397002013-04-05 14:58:22 -07006541 [ALC269_FIXUP_ACER_AC700] = {
6542 .type = HDA_FIXUP_PINS,
6543 .v.pins = (const struct hda_pintbl[]) {
6544 { 0x12, 0x99a3092f }, /* int-mic */
6545 { 0x14, 0x99130110 }, /* speaker */
6546 { 0x18, 0x03a11c20 }, /* mic */
6547 { 0x1e, 0x0346101e }, /* SPDIF1 */
6548 { 0x21, 0x0321101f }, /* HP out */
6549 { }
6550 },
6551 .chained = true,
6552 .chain_id = ALC271_FIXUP_DMIC,
6553 },
David Henningsson3e0d6112013-04-22 14:30:14 +02006554 [ALC269_FIXUP_LIMIT_INT_MIC_BOOST] = {
6555 .type = HDA_FIXUP_FUNC,
6556 .v.func = alc269_fixup_limit_int_mic_boost,
David Henningsson27937692013-11-18 11:51:47 +01006557 .chained = true,
6558 .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
David Henningsson3e0d6112013-04-22 14:30:14 +02006559 },
Oleksij Rempel2cede302013-11-27 17:12:03 +01006560 [ALC269VB_FIXUP_ASUS_ZENBOOK] = {
6561 .type = HDA_FIXUP_FUNC,
6562 .v.func = alc269_fixup_limit_int_mic_boost,
6563 .chained = true,
6564 .chain_id = ALC269VB_FIXUP_DMIC,
6565 },
Takashi Iwai23870832013-11-29 14:13:12 +01006566 [ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A] = {
6567 .type = HDA_FIXUP_VERBS,
6568 .v.verbs = (const struct hda_verb[]) {
6569 /* class-D output amp +5dB */
6570 { 0x20, AC_VERB_SET_COEF_INDEX, 0x12 },
6571 { 0x20, AC_VERB_SET_PROC_COEF, 0x2800 },
6572 {}
6573 },
6574 .chained = true,
6575 .chain_id = ALC269VB_FIXUP_ASUS_ZENBOOK,
6576 },
David Henningsson8e35cd42013-11-06 11:20:01 +01006577 [ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED] = {
6578 .type = HDA_FIXUP_FUNC,
6579 .v.func = alc269_fixup_limit_int_mic_boost,
6580 .chained = true,
6581 .chain_id = ALC269_FIXUP_HP_MUTE_LED_MIC1,
6582 },
Anisse Astier02b504d2013-06-03 11:53:10 +02006583 [ALC269VB_FIXUP_ORDISSIMO_EVE2] = {
6584 .type = HDA_FIXUP_PINS,
6585 .v.pins = (const struct hda_pintbl[]) {
6586 { 0x12, 0x99a3092f }, /* int-mic */
6587 { 0x18, 0x03a11d20 }, /* mic */
6588 { 0x19, 0x411111f0 }, /* Unused bogus pin */
6589 { }
6590 },
6591 },
Kailang Yangcd217a62013-08-22 10:15:24 +02006592 [ALC283_FIXUP_CHROME_BOOK] = {
6593 .type = HDA_FIXUP_FUNC,
6594 .v.func = alc283_fixup_chromebook,
6595 },
Kailang Yang0202e992013-12-02 15:20:15 +08006596 [ALC283_FIXUP_SENSE_COMBO_JACK] = {
6597 .type = HDA_FIXUP_FUNC,
6598 .v.func = alc283_fixup_sense_combo_jack,
6599 .chained = true,
6600 .chain_id = ALC283_FIXUP_CHROME_BOOK,
6601 },
Takashi Iwai7bba2152013-09-06 15:45:38 +02006602 [ALC282_FIXUP_ASUS_TX300] = {
6603 .type = HDA_FIXUP_FUNC,
6604 .v.func = alc282_fixup_asus_tx300,
6605 },
Kailang Yang1bb3e062013-09-27 13:10:25 +02006606 [ALC283_FIXUP_INT_MIC] = {
6607 .type = HDA_FIXUP_VERBS,
6608 .v.verbs = (const struct hda_verb[]) {
6609 {0x20, AC_VERB_SET_COEF_INDEX, 0x1a},
6610 {0x20, AC_VERB_SET_PROC_COEF, 0x0011},
6611 { }
6612 },
6613 .chained = true,
6614 .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST
6615 },
David Henningsson0f4881d2013-12-20 16:08:13 +01006616 [ALC290_FIXUP_SUBWOOFER_HSJACK] = {
6617 .type = HDA_FIXUP_PINS,
6618 .v.pins = (const struct hda_pintbl[]) {
6619 { 0x17, 0x90170112 }, /* subwoofer */
6620 { }
6621 },
6622 .chained = true,
6623 .chain_id = ALC290_FIXUP_MONO_SPEAKERS_HSJACK,
6624 },
6625 [ALC290_FIXUP_SUBWOOFER] = {
6626 .type = HDA_FIXUP_PINS,
6627 .v.pins = (const struct hda_pintbl[]) {
6628 { 0x17, 0x90170112 }, /* subwoofer */
6629 { }
6630 },
6631 .chained = true,
6632 .chain_id = ALC290_FIXUP_MONO_SPEAKERS,
6633 },
David Henningsson338cae52013-10-07 10:39:59 +02006634 [ALC290_FIXUP_MONO_SPEAKERS] = {
6635 .type = HDA_FIXUP_FUNC,
6636 .v.func = alc290_fixup_mono_speakers,
David Henningsson0f4881d2013-12-20 16:08:13 +01006637 },
6638 [ALC290_FIXUP_MONO_SPEAKERS_HSJACK] = {
6639 .type = HDA_FIXUP_FUNC,
6640 .v.func = alc290_fixup_mono_speakers,
David Henningsson338cae52013-10-07 10:39:59 +02006641 .chained = true,
6642 .chain_id = ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
6643 },
David Henningssonb67ae3f2013-11-05 13:11:37 +01006644 [ALC269_FIXUP_THINKPAD_ACPI] = {
6645 .type = HDA_FIXUP_FUNC,
Takashi Iwaid5a6cab2018-06-13 12:43:10 +02006646 .v.func = alc_fixup_thinkpad_acpi,
Takashi Iwai09da1112016-09-08 12:15:02 +02006647 .chained = true,
6648 .chain_id = ALC269_FIXUP_SKU_IGNORE,
David Henningssonb67ae3f2013-11-05 13:11:37 +01006649 },
David Henningsson56f27012016-01-11 09:33:14 +01006650 [ALC269_FIXUP_DMIC_THINKPAD_ACPI] = {
6651 .type = HDA_FIXUP_FUNC,
6652 .v.func = alc_fixup_inv_dmic,
6653 .chained = true,
6654 .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
6655 },
Chris Chiu5824ce82017-02-28 14:17:11 -06006656 [ALC255_FIXUP_ACER_MIC_NO_PRESENCE] = {
Hui Wang17d30462019-06-14 16:44:12 +08006657 .type = HDA_FIXUP_PINS,
6658 .v.pins = (const struct hda_pintbl[]) {
6659 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6660 { }
Chris Chiu5824ce82017-02-28 14:17:11 -06006661 },
6662 .chained = true,
Hui Wang17d30462019-06-14 16:44:12 +08006663 .chain_id = ALC255_FIXUP_HEADSET_MODE
Chris Chiu5824ce82017-02-28 14:17:11 -06006664 },
Chris Chiu615966a2017-02-28 14:17:12 -06006665 [ALC255_FIXUP_ASUS_MIC_NO_PRESENCE] = {
6666 .type = HDA_FIXUP_PINS,
6667 .v.pins = (const struct hda_pintbl[]) {
6668 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6669 { }
6670 },
6671 .chained = true,
6672 .chain_id = ALC255_FIXUP_HEADSET_MODE
6673 },
Kailang Yang9a22a8f52013-11-08 15:54:49 +08006674 [ALC255_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6675 .type = HDA_FIXUP_PINS,
6676 .v.pins = (const struct hda_pintbl[]) {
6677 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6678 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6679 { }
6680 },
6681 .chained = true,
6682 .chain_id = ALC255_FIXUP_HEADSET_MODE
6683 },
Kailang Yang31278992014-03-03 15:27:22 +08006684 [ALC255_FIXUP_DELL2_MIC_NO_PRESENCE] = {
6685 .type = HDA_FIXUP_PINS,
6686 .v.pins = (const struct hda_pintbl[]) {
6687 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6688 { }
6689 },
6690 .chained = true,
6691 .chain_id = ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC
6692 },
Kailang Yang9a22a8f52013-11-08 15:54:49 +08006693 [ALC255_FIXUP_HEADSET_MODE] = {
6694 .type = HDA_FIXUP_FUNC,
6695 .v.func = alc_fixup_headset_mode_alc255,
Hui Wang4a83d422014-11-18 17:57:40 +08006696 .chained = true,
Takashi Iwaib3802782018-11-26 17:47:46 +01006697 .chain_id = ALC255_FIXUP_MIC_MUTE_LED
Kailang Yang9a22a8f52013-11-08 15:54:49 +08006698 },
Kailang Yang31278992014-03-03 15:27:22 +08006699 [ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC] = {
6700 .type = HDA_FIXUP_FUNC,
6701 .v.func = alc_fixup_headset_mode_alc255_no_hp_mic,
6702 },
Kailang Yanga22aa262014-04-23 17:34:28 +08006703 [ALC293_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6704 .type = HDA_FIXUP_PINS,
6705 .v.pins = (const struct hda_pintbl[]) {
6706 { 0x18, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6707 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6708 { }
6709 },
6710 .chained = true,
6711 .chain_id = ALC269_FIXUP_HEADSET_MODE
6712 },
Takashi Iwai1c37c222014-05-06 17:34:42 +02006713 [ALC292_FIXUP_TPT440_DOCK] = {
David Henningssonec56af62015-06-24 10:46:33 +02006714 .type = HDA_FIXUP_FUNC,
Takashi Iwai7f57d802015-09-24 17:36:51 +02006715 .v.func = alc_fixup_tpt440_dock,
Takashi Iwai1c37c222014-05-06 17:34:42 +02006716 .chained = true,
6717 .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST
6718 },
Takashi Iwai9a811232015-12-09 15:17:43 +01006719 [ALC292_FIXUP_TPT440] = {
6720 .type = HDA_FIXUP_FUNC,
Takashi Iwai157f0b72015-12-10 23:30:43 +01006721 .v.func = alc_fixup_disable_aamix,
Takashi Iwai9a811232015-12-09 15:17:43 +01006722 .chained = true,
6723 .chain_id = ALC292_FIXUP_TPT440_DOCK,
6724 },
Anisse Astierabaa22742016-08-24 09:14:13 +02006725 [ALC283_FIXUP_HEADSET_MIC] = {
Daniel Drake9dc12862014-07-22 10:58:29 +01006726 .type = HDA_FIXUP_PINS,
6727 .v.pins = (const struct hda_pintbl[]) {
6728 { 0x19, 0x04a110f0 },
6729 { },
6730 },
6731 },
Takashi Iwaib3802782018-11-26 17:47:46 +01006732 [ALC255_FIXUP_MIC_MUTE_LED] = {
Hui Wang00ef9942014-07-31 11:52:38 +08006733 .type = HDA_FIXUP_FUNC,
Takashi Iwai8a503552020-06-18 13:08:32 +02006734 .v.func = alc_fixup_micmute_led,
Hui Wang00ef9942014-07-31 11:52:38 +08006735 },
Takashi Iwai1a22e772014-08-27 08:19:05 +02006736 [ALC282_FIXUP_ASPIRE_V5_PINS] = {
6737 .type = HDA_FIXUP_PINS,
6738 .v.pins = (const struct hda_pintbl[]) {
6739 { 0x12, 0x90a60130 },
6740 { 0x14, 0x90170110 },
6741 { 0x17, 0x40000008 },
6742 { 0x18, 0x411111f0 },
Mateusz Sylwestrzak04206942015-07-19 17:38:56 +02006743 { 0x19, 0x01a1913c },
Takashi Iwai1a22e772014-08-27 08:19:05 +02006744 { 0x1a, 0x411111f0 },
6745 { 0x1b, 0x411111f0 },
6746 { 0x1d, 0x40f89b2d },
6747 { 0x1e, 0x411111f0 },
6748 { 0x21, 0x0321101f },
6749 { },
6750 },
6751 },
David Henningsson7a5255f2014-10-30 08:26:01 +01006752 [ALC280_FIXUP_HP_GPIO4] = {
6753 .type = HDA_FIXUP_FUNC,
6754 .v.func = alc280_fixup_hp_gpio4,
6755 },
Kailang Yangeaa8e5e2014-11-21 15:49:11 +08006756 [ALC286_FIXUP_HP_GPIO_LED] = {
6757 .type = HDA_FIXUP_FUNC,
6758 .v.func = alc286_fixup_hp_gpio_led,
6759 },
David Henningsson33f4acd2015-01-07 15:50:13 +01006760 [ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY] = {
6761 .type = HDA_FIXUP_FUNC,
6762 .v.func = alc280_fixup_hp_gpio2_mic_hotkey,
6763 },
TienFu Chenb4b33f92015-01-20 15:06:21 +01006764 [ALC280_FIXUP_HP_DOCK_PINS] = {
6765 .type = HDA_FIXUP_PINS,
6766 .v.pins = (const struct hda_pintbl[]) {
6767 { 0x1b, 0x21011020 }, /* line-out */
6768 { 0x1a, 0x01a1903c }, /* headset mic */
6769 { 0x18, 0x2181103f }, /* line-in */
6770 { },
6771 },
6772 .chained = true,
6773 .chain_id = ALC280_FIXUP_HP_GPIO4
6774 },
Jaroslav Kysela04d54662017-03-09 13:29:13 +01006775 [ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED] = {
6776 .type = HDA_FIXUP_PINS,
6777 .v.pins = (const struct hda_pintbl[]) {
6778 { 0x1b, 0x21011020 }, /* line-out */
6779 { 0x18, 0x2181103f }, /* line-in */
6780 { },
6781 },
6782 .chained = true,
6783 .chain_id = ALC269_FIXUP_HP_GPIO_MIC1_LED
6784 },
Keith Packard98973f22015-07-15 12:14:39 -07006785 [ALC280_FIXUP_HP_9480M] = {
6786 .type = HDA_FIXUP_FUNC,
6787 .v.func = alc280_fixup_hp_9480m,
6788 },
Kailang Yange1e62b92015-04-08 16:01:22 +08006789 [ALC288_FIXUP_DELL_HEADSET_MODE] = {
6790 .type = HDA_FIXUP_FUNC,
6791 .v.func = alc_fixup_headset_mode_dell_alc288,
6792 .chained = true,
Takashi Iwaib3802782018-11-26 17:47:46 +01006793 .chain_id = ALC255_FIXUP_MIC_MUTE_LED
Kailang Yange1e62b92015-04-08 16:01:22 +08006794 },
6795 [ALC288_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6796 .type = HDA_FIXUP_PINS,
6797 .v.pins = (const struct hda_pintbl[]) {
6798 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6799 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6800 { }
6801 },
6802 .chained = true,
6803 .chain_id = ALC288_FIXUP_DELL_HEADSET_MODE
6804 },
Hui Wang831bfdf92015-06-26 12:35:17 +08006805 [ALC288_FIXUP_DISABLE_AAMIX] = {
6806 .type = HDA_FIXUP_FUNC,
6807 .v.func = alc_fixup_disable_aamix,
6808 .chained = true,
Takashi Iwaid44a6862018-06-19 23:04:03 +02006809 .chain_id = ALC288_FIXUP_DELL1_MIC_NO_PRESENCE
Hui Wang831bfdf92015-06-26 12:35:17 +08006810 },
6811 [ALC288_FIXUP_DELL_XPS_13] = {
6812 .type = HDA_FIXUP_FUNC,
6813 .v.func = alc_fixup_dell_xps13,
6814 .chained = true,
6815 .chain_id = ALC288_FIXUP_DISABLE_AAMIX
6816 },
Takashi Iwai8b99aba2015-06-15 11:59:32 +02006817 [ALC292_FIXUP_DISABLE_AAMIX] = {
6818 .type = HDA_FIXUP_FUNC,
6819 .v.func = alc_fixup_disable_aamix,
Hui Wang831bfdf92015-06-26 12:35:17 +08006820 .chained = true,
6821 .chain_id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE
Takashi Iwai8b99aba2015-06-15 11:59:32 +02006822 },
David Henningssonc04017e2015-12-15 14:44:03 +01006823 [ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK] = {
6824 .type = HDA_FIXUP_FUNC,
6825 .v.func = alc_fixup_disable_aamix,
6826 .chained = true,
6827 .chain_id = ALC293_FIXUP_DELL1_MIC_NO_PRESENCE
6828 },
Takashi Iwai5fab5822020-01-05 09:11:19 +01006829 [ALC292_FIXUP_DELL_E7X_AAMIX] = {
Takashi Iwai8b99aba2015-06-15 11:59:32 +02006830 .type = HDA_FIXUP_FUNC,
6831 .v.func = alc_fixup_dell_xps13,
6832 .chained = true,
6833 .chain_id = ALC292_FIXUP_DISABLE_AAMIX
6834 },
Takashi Iwai5fab5822020-01-05 09:11:19 +01006835 [ALC292_FIXUP_DELL_E7X] = {
6836 .type = HDA_FIXUP_FUNC,
Takashi Iwai8a503552020-06-18 13:08:32 +02006837 .v.func = alc_fixup_micmute_led,
Takashi Iwai5fab5822020-01-05 09:11:19 +01006838 /* micmute fixup must be applied at last */
6839 .chained_before = true,
6840 .chain_id = ALC292_FIXUP_DELL_E7X_AAMIX,
6841 },
James McDonnell54324222019-09-16 14:53:38 +00006842 [ALC298_FIXUP_ALIENWARE_MIC_NO_PRESENCE] = {
6843 .type = HDA_FIXUP_PINS,
6844 .v.pins = (const struct hda_pintbl[]) {
6845 { 0x18, 0x01a1913c }, /* headset mic w/o jack detect */
6846 { }
6847 },
6848 .chained_before = true,
6849 .chain_id = ALC269_FIXUP_HEADSET_MODE,
6850 },
Kailang Yang977e6272015-05-18 15:31:20 +08006851 [ALC298_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6852 .type = HDA_FIXUP_PINS,
6853 .v.pins = (const struct hda_pintbl[]) {
6854 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6855 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6856 { }
6857 },
6858 .chained = true,
6859 .chain_id = ALC269_FIXUP_HEADSET_MODE
6860 },
Hui Wang2f726ae2017-03-31 10:31:40 +08006861 [ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE] = {
6862 .type = HDA_FIXUP_PINS,
6863 .v.pins = (const struct hda_pintbl[]) {
6864 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6865 { }
6866 },
6867 .chained = true,
6868 .chain_id = ALC269_FIXUP_HEADSET_MODE
6869 },
Kailang Yang6ed11312015-10-26 15:37:39 +08006870 [ALC275_FIXUP_DELL_XPS] = {
6871 .type = HDA_FIXUP_VERBS,
6872 .v.verbs = (const struct hda_verb[]) {
6873 /* Enables internal speaker */
6874 {0x20, AC_VERB_SET_COEF_INDEX, 0x1f},
6875 {0x20, AC_VERB_SET_PROC_COEF, 0x00c0},
6876 {0x20, AC_VERB_SET_COEF_INDEX, 0x30},
6877 {0x20, AC_VERB_SET_PROC_COEF, 0x00b1},
6878 {}
6879 }
6880 },
Hui Wang23adc192015-12-08 12:27:18 +08006881 [ALC293_FIXUP_LENOVO_SPK_NOISE] = {
6882 .type = HDA_FIXUP_FUNC,
6883 .v.func = alc_fixup_disable_aamix,
6884 .chained = true,
6885 .chain_id = ALC269_FIXUP_THINKPAD_ACPI
6886 },
Kailang3694cb22015-12-28 11:35:24 +08006887 [ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY] = {
6888 .type = HDA_FIXUP_FUNC,
6889 .v.func = alc233_fixup_lenovo_line2_mic_hotkey,
6890 },
Kai-Heng Feng3b43b712016-02-25 15:19:38 +08006891 [ALC255_FIXUP_DELL_SPK_NOISE] = {
6892 .type = HDA_FIXUP_FUNC,
6893 .v.func = alc_fixup_disable_aamix,
6894 .chained = true,
6895 .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
6896 },
Kailang Yangd1dd4212019-01-09 17:05:24 +08006897 [ALC225_FIXUP_DISABLE_MIC_VREF] = {
6898 .type = HDA_FIXUP_FUNC,
6899 .v.func = alc_fixup_disable_mic_vref,
6900 .chained = true,
6901 .chain_id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE
6902 },
David Henningsson2ae95572016-02-25 09:37:05 +01006903 [ALC225_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6904 .type = HDA_FIXUP_VERBS,
6905 .v.verbs = (const struct hda_verb[]) {
6906 /* Disable pass-through path for FRONT 14h */
6907 { 0x20, AC_VERB_SET_COEF_INDEX, 0x36 },
6908 { 0x20, AC_VERB_SET_PROC_COEF, 0x57d7 },
6909 {}
6910 },
6911 .chained = true,
Kailang Yangd1dd4212019-01-09 17:05:24 +08006912 .chain_id = ALC225_FIXUP_DISABLE_MIC_VREF
David Henningsson2ae95572016-02-25 09:37:05 +01006913 },
Takashi Iwaif8839822016-02-25 14:31:59 +01006914 [ALC280_FIXUP_HP_HEADSET_MIC] = {
6915 .type = HDA_FIXUP_FUNC,
6916 .v.func = alc_fixup_disable_aamix,
6917 .chained = true,
6918 .chain_id = ALC269_FIXUP_HEADSET_MIC,
6919 },
Hui Wange549d192016-04-01 11:00:15 +08006920 [ALC221_FIXUP_HP_FRONT_MIC] = {
6921 .type = HDA_FIXUP_PINS,
6922 .v.pins = (const struct hda_pintbl[]) {
6923 { 0x19, 0x02a19020 }, /* Front Mic */
6924 { }
6925 },
6926 },
Sven Eckelmannc636b952016-04-11 16:55:26 +02006927 [ALC292_FIXUP_TPT460] = {
6928 .type = HDA_FIXUP_FUNC,
6929 .v.func = alc_fixup_tpt440_dock,
6930 .chained = true,
6931 .chain_id = ALC293_FIXUP_LENOVO_SPK_NOISE,
6932 },
Hui Wangdd9aa332016-08-01 10:20:32 +08006933 [ALC298_FIXUP_SPK_VOLUME] = {
6934 .type = HDA_FIXUP_FUNC,
6935 .v.func = alc298_fixup_speaker_volume,
Hui Wang59ec4b52016-08-04 15:28:04 +08006936 .chained = true,
Hui Wang2f726ae2017-03-31 10:31:40 +08006937 .chain_id = ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE,
Hui Wangdd9aa332016-08-01 10:20:32 +08006938 },
Takashi Iwaie312a862018-03-06 12:14:17 +01006939 [ALC295_FIXUP_DISABLE_DAC3] = {
6940 .type = HDA_FIXUP_FUNC,
6941 .v.func = alc295_fixup_disable_dac3,
6942 },
Jaroslav Kyselad2cd7952019-11-29 15:40:27 +01006943 [ALC285_FIXUP_SPEAKER2_TO_DAC1] = {
6944 .type = HDA_FIXUP_FUNC,
6945 .v.func = alc285_fixup_speaker2_to_dac1,
Hui Wangc37c0ab2020-02-19 13:23:06 +08006946 .chained = true,
6947 .chain_id = ALC269_FIXUP_THINKPAD_ACPI
Jaroslav Kyselad2cd7952019-11-29 15:40:27 +01006948 },
Kai-Heng Fengfd06c772016-08-30 15:36:34 +08006949 [ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER] = {
6950 .type = HDA_FIXUP_PINS,
6951 .v.pins = (const struct hda_pintbl[]) {
6952 { 0x1b, 0x90170151 },
6953 { }
6954 },
6955 .chained = true,
6956 .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
6957 },
Gabriele Mazzotta823ff162016-12-24 19:50:01 +01006958 [ALC269_FIXUP_ATIV_BOOK_8] = {
6959 .type = HDA_FIXUP_FUNC,
6960 .v.func = alc_fixup_auto_mute_via_amp,
6961 .chained = true,
6962 .chain_id = ALC269_FIXUP_NO_SHUTUP
6963 },
Kailang Yang9eb5d0e2017-01-17 15:40:25 +08006964 [ALC221_FIXUP_HP_MIC_NO_PRESENCE] = {
6965 .type = HDA_FIXUP_PINS,
6966 .v.pins = (const struct hda_pintbl[]) {
6967 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6968 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6969 { }
6970 },
6971 .chained = true,
6972 .chain_id = ALC269_FIXUP_HEADSET_MODE
6973 },
Chris Chiuc1732ed2017-02-28 14:17:13 -06006974 [ALC256_FIXUP_ASUS_HEADSET_MODE] = {
6975 .type = HDA_FIXUP_FUNC,
6976 .v.func = alc_fixup_headset_mode,
6977 },
6978 [ALC256_FIXUP_ASUS_MIC] = {
6979 .type = HDA_FIXUP_PINS,
6980 .v.pins = (const struct hda_pintbl[]) {
6981 { 0x13, 0x90a60160 }, /* use as internal mic */
6982 { 0x19, 0x04a11120 }, /* use as headset mic, without its own jack detect */
6983 { }
6984 },
6985 .chained = true,
6986 .chain_id = ALC256_FIXUP_ASUS_HEADSET_MODE
6987 },
Chris Chiueeed4cd2017-02-28 14:17:15 -06006988 [ALC256_FIXUP_ASUS_AIO_GPIO2] = {
Takashi Iwaiae065f12018-06-19 23:00:03 +02006989 .type = HDA_FIXUP_FUNC,
6990 /* Set up GPIO2 for the speaker amp */
6991 .v.func = alc_fixup_gpio4,
Chris Chiueeed4cd2017-02-28 14:17:15 -06006992 },
Chris Chiu216d7ae2017-02-28 14:17:14 -06006993 [ALC233_FIXUP_ASUS_MIC_NO_PRESENCE] = {
6994 .type = HDA_FIXUP_PINS,
6995 .v.pins = (const struct hda_pintbl[]) {
6996 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6997 { }
6998 },
6999 .chained = true,
7000 .chain_id = ALC269_FIXUP_HEADSET_MIC
7001 },
7002 [ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE] = {
7003 .type = HDA_FIXUP_VERBS,
7004 .v.verbs = (const struct hda_verb[]) {
7005 /* Enables internal speaker */
7006 {0x20, AC_VERB_SET_COEF_INDEX, 0x40},
7007 {0x20, AC_VERB_SET_PROC_COEF, 0x8800},
7008 {}
7009 },
7010 .chained = true,
7011 .chain_id = ALC233_FIXUP_ASUS_MIC_NO_PRESENCE
7012 },
Kailang Yangca169cc2017-04-25 16:17:40 +08007013 [ALC233_FIXUP_LENOVO_MULTI_CODECS] = {
7014 .type = HDA_FIXUP_FUNC,
7015 .v.func = alc233_alc662_fixup_lenovo_dual_codecs,
7016 },
Jian-Hong Panea5c7eb2019-04-01 11:25:05 +08007017 [ALC233_FIXUP_ACER_HEADSET_MIC] = {
7018 .type = HDA_FIXUP_VERBS,
7019 .v.verbs = (const struct hda_verb[]) {
7020 { 0x20, AC_VERB_SET_COEF_INDEX, 0x45 },
7021 { 0x20, AC_VERB_SET_PROC_COEF, 0x5089 },
7022 { }
7023 },
7024 .chained = true,
7025 .chain_id = ALC233_FIXUP_ASUS_MIC_NO_PRESENCE
7026 },
Hui Wangf33f79f2017-07-07 12:08:29 +08007027 [ALC294_FIXUP_LENOVO_MIC_LOCATION] = {
7028 .type = HDA_FIXUP_PINS,
7029 .v.pins = (const struct hda_pintbl[]) {
7030 /* Change the mic location from front to right, otherwise there are
7031 two front mics with the same name, pulseaudio can't handle them.
7032 This is just a temporary workaround, after applying this fixup,
7033 there will be one "Front Mic" and one "Mic" in this machine.
7034 */
7035 { 0x1a, 0x04a19040 },
7036 { }
7037 },
7038 },
Kailang Yang5f364132017-07-25 16:28:16 +08007039 [ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE] = {
7040 .type = HDA_FIXUP_PINS,
7041 .v.pins = (const struct hda_pintbl[]) {
7042 { 0x16, 0x0101102f }, /* Rear Headset HP */
7043 { 0x19, 0x02a1913c }, /* use as Front headset mic, without its own jack detect */
7044 { 0x1a, 0x01a19030 }, /* Rear Headset MIC */
7045 { 0x1b, 0x02011020 },
7046 { }
7047 },
7048 .chained = true,
Kai-Heng Feng52e4e362020-05-03 23:24:47 +08007049 .chain_id = ALC225_FIXUP_S3_POP_NOISE
7050 },
7051 [ALC225_FIXUP_S3_POP_NOISE] = {
7052 .type = HDA_FIXUP_FUNC,
7053 .v.func = alc225_fixup_s3_pop_noise,
7054 .chained = true,
Kailang Yang5f364132017-07-25 16:28:16 +08007055 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
7056 },
PeiSen Houb84e8432017-09-01 15:11:56 +08007057 [ALC700_FIXUP_INTEL_REFERENCE] = {
7058 .type = HDA_FIXUP_VERBS,
7059 .v.verbs = (const struct hda_verb[]) {
7060 /* Enables internal speaker */
7061 {0x20, AC_VERB_SET_COEF_INDEX, 0x45},
7062 {0x20, AC_VERB_SET_PROC_COEF, 0x5289},
7063 {0x20, AC_VERB_SET_COEF_INDEX, 0x4A},
7064 {0x20, AC_VERB_SET_PROC_COEF, 0x001b},
7065 {0x58, AC_VERB_SET_COEF_INDEX, 0x00},
7066 {0x58, AC_VERB_SET_PROC_COEF, 0x3888},
7067 {0x20, AC_VERB_SET_COEF_INDEX, 0x6f},
7068 {0x20, AC_VERB_SET_PROC_COEF, 0x2c0b},
7069 {}
7070 }
7071 },
Kailang Yang92266652017-12-14 15:28:58 +08007072 [ALC274_FIXUP_DELL_BIND_DACS] = {
7073 .type = HDA_FIXUP_FUNC,
7074 .v.func = alc274_fixup_bind_dacs,
7075 .chained = true,
7076 .chain_id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE
7077 },
7078 [ALC274_FIXUP_DELL_AIO_LINEOUT_VERB] = {
7079 .type = HDA_FIXUP_PINS,
7080 .v.pins = (const struct hda_pintbl[]) {
7081 { 0x1b, 0x0401102f },
7082 { }
7083 },
7084 .chained = true,
7085 .chain_id = ALC274_FIXUP_DELL_BIND_DACS
7086 },
Takashi Iwai399c01a2020-05-26 08:24:06 +02007087 [ALC298_FIXUP_TPT470_DOCK_FIX] = {
Kailang Yang61fcf8e2018-02-02 15:26:46 +08007088 .type = HDA_FIXUP_FUNC,
7089 .v.func = alc_fixup_tpt470_dock,
7090 .chained = true,
7091 .chain_id = ALC293_FIXUP_LENOVO_SPK_NOISE
7092 },
Takashi Iwai399c01a2020-05-26 08:24:06 +02007093 [ALC298_FIXUP_TPT470_DOCK] = {
7094 .type = HDA_FIXUP_FUNC,
7095 .v.func = alc_fixup_tpt470_dacs,
7096 .chained = true,
7097 .chain_id = ALC298_FIXUP_TPT470_DOCK_FIX
7098 },
Kailang Yangae104a22018-02-05 16:07:20 +08007099 [ALC255_FIXUP_DUMMY_LINEOUT_VERB] = {
7100 .type = HDA_FIXUP_PINS,
7101 .v.pins = (const struct hda_pintbl[]) {
7102 { 0x14, 0x0201101f },
7103 { }
7104 },
7105 .chained = true,
7106 .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
7107 },
Kailang Yangf0ba9d62018-03-16 11:46:08 +08007108 [ALC255_FIXUP_DELL_HEADSET_MIC] = {
7109 .type = HDA_FIXUP_PINS,
7110 .v.pins = (const struct hda_pintbl[]) {
7111 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
7112 { }
7113 },
Hui Wang3ce0d5a2018-04-19 13:29:04 +08007114 .chained = true,
7115 .chain_id = ALC269_FIXUP_HEADSET_MIC
Kailang Yangf0ba9d62018-03-16 11:46:08 +08007116 },
Tom Bridenbbf8ff62018-05-29 17:34:20 +01007117 [ALC295_FIXUP_HP_X360] = {
7118 .type = HDA_FIXUP_FUNC,
7119 .v.func = alc295_fixup_hp_top_speakers,
7120 .chained = true,
7121 .chain_id = ALC269_FIXUP_HP_MUTE_LED_MIC3
Kailang Yang8a328ac2018-08-21 16:54:41 +08007122 },
7123 [ALC221_FIXUP_HP_HEADSET_MIC] = {
7124 .type = HDA_FIXUP_PINS,
7125 .v.pins = (const struct hda_pintbl[]) {
7126 { 0x19, 0x0181313f},
7127 { }
7128 },
7129 .chained = true,
7130 .chain_id = ALC269_FIXUP_HEADSET_MIC
7131 },
Hui Wangc4cfcf62018-11-26 14:17:16 +08007132 [ALC285_FIXUP_LENOVO_HEADPHONE_NOISE] = {
7133 .type = HDA_FIXUP_FUNC,
7134 .v.func = alc285_fixup_invalidate_dacs,
Hui Wang6ba189c2018-12-09 09:16:43 +08007135 .chained = true,
7136 .chain_id = ALC269_FIXUP_THINKPAD_ACPI
Hui Wangc4cfcf62018-11-26 14:17:16 +08007137 },
Girija Kumar Kasinadhunie8ed64b2018-11-26 13:40:46 -05007138 [ALC295_FIXUP_HP_AUTO_MUTE] = {
7139 .type = HDA_FIXUP_FUNC,
7140 .v.func = alc_fixup_auto_mute_via_amp,
7141 },
Chris Chiu33aaebd2018-12-05 14:48:53 +08007142 [ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE] = {
7143 .type = HDA_FIXUP_PINS,
7144 .v.pins = (const struct hda_pintbl[]) {
7145 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
7146 { }
7147 },
7148 .chained = true,
7149 .chain_id = ALC269_FIXUP_HEADSET_MIC
7150 },
Chris Chiud8ae4582018-12-07 17:17:11 +08007151 [ALC294_FIXUP_ASUS_MIC] = {
7152 .type = HDA_FIXUP_PINS,
7153 .v.pins = (const struct hda_pintbl[]) {
7154 { 0x13, 0x90a60160 }, /* use as internal mic */
7155 { 0x19, 0x04a11120 }, /* use as headset mic, without its own jack detect */
7156 { }
7157 },
7158 .chained = true,
Kailang Yangef9ddb92020-07-10 15:31:11 +08007159 .chain_id = ALC269_FIXUP_HEADSET_MIC
Chris Chiud8ae4582018-12-07 17:17:11 +08007160 },
Jian-Hong Pan4e051102018-12-07 17:17:12 +08007161 [ALC294_FIXUP_ASUS_HEADSET_MIC] = {
7162 .type = HDA_FIXUP_PINS,
7163 .v.pins = (const struct hda_pintbl[]) {
Jian-Hong Pan82b01142018-12-27 16:46:31 +08007164 { 0x19, 0x01a1103c }, /* use as headset mic */
Jian-Hong Pan4e051102018-12-07 17:17:12 +08007165 { }
7166 },
7167 .chained = true,
Kailang Yangef9ddb92020-07-10 15:31:11 +08007168 .chain_id = ALC269_FIXUP_HEADSET_MIC
Jian-Hong Pan4e051102018-12-07 17:17:12 +08007169 },
7170 [ALC294_FIXUP_ASUS_SPK] = {
7171 .type = HDA_FIXUP_VERBS,
7172 .v.verbs = (const struct hda_verb[]) {
7173 /* Set EAPD high */
7174 { 0x20, AC_VERB_SET_COEF_INDEX, 0x40 },
7175 { 0x20, AC_VERB_SET_PROC_COEF, 0x8800 },
Kailang Yang473fbe132020-07-16 14:42:33 +08007176 { 0x20, AC_VERB_SET_COEF_INDEX, 0x0f },
7177 { 0x20, AC_VERB_SET_PROC_COEF, 0x7774 },
Jian-Hong Pan4e051102018-12-07 17:17:12 +08007178 { }
7179 },
7180 .chained = true,
7181 .chain_id = ALC294_FIXUP_ASUS_HEADSET_MIC
7182 },
Jaroslav Kyselac8a9afa2019-03-14 09:21:08 +01007183 [ALC295_FIXUP_CHROME_BOOK] = {
Kailang Yange8547472018-11-28 15:32:45 +08007184 .type = HDA_FIXUP_FUNC,
Jaroslav Kyselac8a9afa2019-03-14 09:21:08 +01007185 .v.func = alc295_fixup_chromebook,
Kailang Yang8983eb62019-04-03 15:31:49 +08007186 .chained = true,
7187 .chain_id = ALC225_FIXUP_HEADSET_JACK
7188 },
7189 [ALC225_FIXUP_HEADSET_JACK] = {
7190 .type = HDA_FIXUP_FUNC,
7191 .v.func = alc_fixup_headset_jack,
Kailang Yange8547472018-11-28 15:32:45 +08007192 },
Jeremy Soller89e3a562019-01-30 16:12:31 -07007193 [ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE] = {
7194 .type = HDA_FIXUP_PINS,
7195 .v.pins = (const struct hda_pintbl[]) {
7196 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
7197 { }
7198 },
7199 .chained = true,
7200 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
7201 },
Hui Wangc8c6ee62019-02-14 11:41:33 +08007202 [ALC285_FIXUP_LENOVO_PC_BEEP_IN_NOISE] = {
7203 .type = HDA_FIXUP_VERBS,
7204 .v.verbs = (const struct hda_verb[]) {
7205 /* Disable PCBEEP-IN passthrough */
7206 { 0x20, AC_VERB_SET_COEF_INDEX, 0x36 },
7207 { 0x20, AC_VERB_SET_PROC_COEF, 0x57d7 },
7208 { }
7209 },
7210 .chained = true,
7211 .chain_id = ALC285_FIXUP_LENOVO_HEADPHONE_NOISE
7212 },
Jian-Hong Pancbc05fd2019-03-13 17:33:24 +08007213 [ALC255_FIXUP_ACER_HEADSET_MIC] = {
7214 .type = HDA_FIXUP_PINS,
7215 .v.pins = (const struct hda_pintbl[]) {
7216 { 0x19, 0x03a11130 },
7217 { 0x1a, 0x90a60140 }, /* use as internal mic */
7218 { }
7219 },
7220 .chained = true,
7221 .chain_id = ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC
7222 },
Kailang Yang136824e2019-03-14 16:22:45 +08007223 [ALC225_FIXUP_DELL_WYSE_AIO_MIC_NO_PRESENCE] = {
7224 .type = HDA_FIXUP_PINS,
7225 .v.pins = (const struct hda_pintbl[]) {
7226 { 0x16, 0x01011020 }, /* Rear Line out */
7227 { 0x19, 0x01a1913c }, /* use as Front headset mic, without its own jack detect */
7228 { }
7229 },
7230 .chained = true,
7231 .chain_id = ALC225_FIXUP_WYSE_AUTO_MUTE
7232 },
7233 [ALC225_FIXUP_WYSE_AUTO_MUTE] = {
7234 .type = HDA_FIXUP_FUNC,
7235 .v.func = alc_fixup_auto_mute_via_amp,
7236 .chained = true,
7237 .chain_id = ALC225_FIXUP_WYSE_DISABLE_MIC_VREF
7238 },
7239 [ALC225_FIXUP_WYSE_DISABLE_MIC_VREF] = {
7240 .type = HDA_FIXUP_FUNC,
7241 .v.func = alc_fixup_disable_mic_vref,
7242 .chained = true,
7243 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
7244 },
Jian-Hong Pan667a8f72019-03-15 17:51:09 +08007245 [ALC286_FIXUP_ACER_AIO_HEADSET_MIC] = {
7246 .type = HDA_FIXUP_VERBS,
7247 .v.verbs = (const struct hda_verb[]) {
7248 { 0x20, AC_VERB_SET_COEF_INDEX, 0x4f },
7249 { 0x20, AC_VERB_SET_PROC_COEF, 0x5029 },
7250 { }
7251 },
7252 .chained = true,
7253 .chain_id = ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE
7254 },
Daniel Drake8c8967a2019-10-17 16:15:01 +08007255 [ALC256_FIXUP_ASUS_HEADSET_MIC] = {
7256 .type = HDA_FIXUP_PINS,
7257 .v.pins = (const struct hda_pintbl[]) {
7258 { 0x19, 0x03a11020 }, /* headset mic with jack detect */
7259 { }
7260 },
7261 .chained = true,
7262 .chain_id = ALC256_FIXUP_ASUS_HEADSET_MODE
7263 },
Jian-Hong Pane1037352019-03-22 11:37:18 +08007264 [ALC256_FIXUP_ASUS_MIC_NO_PRESENCE] = {
7265 .type = HDA_FIXUP_PINS,
7266 .v.pins = (const struct hda_pintbl[]) {
7267 { 0x19, 0x04a11120 }, /* use as headset mic, without its own jack detect */
7268 { }
7269 },
7270 .chained = true,
7271 .chain_id = ALC256_FIXUP_ASUS_HEADSET_MODE
7272 },
Bernhard Rosenkraenzere2a829b2019-03-05 00:38:19 +01007273 [ALC299_FIXUP_PREDATOR_SPK] = {
7274 .type = HDA_FIXUP_PINS,
7275 .v.pins = (const struct hda_pintbl[]) {
7276 { 0x21, 0x90170150 }, /* use as headset mic, without its own jack detect */
7277 { }
7278 }
7279 },
Jan-Marek Glogowskibd9c10b2019-09-15 16:57:28 +02007280 [ALC256_FIXUP_MEDION_HEADSET_NO_PRESENCE] = {
7281 .type = HDA_FIXUP_PINS,
7282 .v.pins = (const struct hda_pintbl[]) {
7283 { 0x19, 0x04a11040 },
7284 { 0x21, 0x04211020 },
7285 { }
7286 },
7287 .chained = true,
7288 .chain_id = ALC256_FIXUP_ASUS_HEADSET_MODE
7289 },
Kailang Yange79c2262019-12-19 14:12:15 +08007290 [ALC289_FIXUP_DELL_SPK2] = {
7291 .type = HDA_FIXUP_PINS,
7292 .v.pins = (const struct hda_pintbl[]) {
7293 { 0x17, 0x90170130 }, /* bass spk */
7294 { }
7295 },
7296 .chained = true,
7297 .chain_id = ALC269_FIXUP_DELL4_MIC_NO_PRESENCE
7298 },
7299 [ALC289_FIXUP_DUAL_SPK] = {
7300 .type = HDA_FIXUP_FUNC,
7301 .v.func = alc285_fixup_speaker2_to_dac1,
7302 .chained = true,
7303 .chain_id = ALC289_FIXUP_DELL_SPK2
7304 },
Chris Chiu48e01502019-12-30 11:11:18 +08007305 [ALC294_FIXUP_SPK2_TO_DAC1] = {
7306 .type = HDA_FIXUP_FUNC,
7307 .v.func = alc285_fixup_speaker2_to_dac1,
7308 .chained = true,
7309 .chain_id = ALC294_FIXUP_ASUS_HEADSET_MIC
7310 },
7311 [ALC294_FIXUP_ASUS_DUAL_SPK] = {
Jian-Hong Pan436e2552019-11-25 17:34:06 +08007312 .type = HDA_FIXUP_FUNC,
7313 /* The GPIO must be pulled to initialize the AMP */
7314 .v.func = alc_fixup_gpio4,
7315 .chained = true,
Chris Chiu48e01502019-12-30 11:11:18 +08007316 .chain_id = ALC294_FIXUP_SPK2_TO_DAC1
Jian-Hong Pan436e2552019-11-25 17:34:06 +08007317 },
Takashi Iwai6a6660d2020-09-03 10:33:00 +02007318 [ALC285_FIXUP_THINKPAD_X1_GEN7] = {
7319 .type = HDA_FIXUP_FUNC,
7320 .v.func = alc285_fixup_thinkpad_x1_gen7,
7321 .chained = true,
7322 .chain_id = ALC269_FIXUP_THINKPAD_ACPI
7323 },
Kailang Yang76f7dec2020-02-10 16:30:26 +08007324 [ALC285_FIXUP_THINKPAD_HEADSET_JACK] = {
7325 .type = HDA_FIXUP_FUNC,
7326 .v.func = alc_fixup_headset_jack,
7327 .chained = true,
Takashi Iwai6a6660d2020-09-03 10:33:00 +02007328 .chain_id = ALC285_FIXUP_THINKPAD_X1_GEN7
Kailang Yang76f7dec2020-02-10 16:30:26 +08007329 },
Jian-Hong Pan8b33a132020-02-25 15:29:21 +08007330 [ALC294_FIXUP_ASUS_HPE] = {
7331 .type = HDA_FIXUP_VERBS,
7332 .v.verbs = (const struct hda_verb[]) {
7333 /* Set EAPD high */
7334 { 0x20, AC_VERB_SET_COEF_INDEX, 0x0f },
7335 { 0x20, AC_VERB_SET_PROC_COEF, 0x7774 },
7336 { }
7337 },
7338 .chained = true,
7339 .chain_id = ALC294_FIXUP_ASUS_HEADSET_MIC
7340 },
Takashi Iwai1b94e592020-05-12 09:32:03 +02007341 [ALC294_FIXUP_ASUS_COEF_1B] = {
7342 .type = HDA_FIXUP_VERBS,
7343 .v.verbs = (const struct hda_verb[]) {
7344 /* Set bit 10 to correct noisy output after reboot from
7345 * Windows 10 (due to pop noise reduction?)
7346 */
7347 { 0x20, AC_VERB_SET_COEF_INDEX, 0x1b },
7348 { 0x20, AC_VERB_SET_PROC_COEF, 0x4e4b },
7349 { }
7350 },
7351 },
Kai-Heng Fengf5a88b02020-03-27 12:46:25 +08007352 [ALC285_FIXUP_HP_GPIO_LED] = {
7353 .type = HDA_FIXUP_FUNC,
7354 .v.func = alc285_fixup_hp_gpio_led,
7355 },
Kailang Yang431e76c2020-04-07 14:40:20 +08007356 [ALC285_FIXUP_HP_MUTE_LED] = {
7357 .type = HDA_FIXUP_FUNC,
7358 .v.func = alc285_fixup_hp_mute_led,
7359 },
Kailang Yang24164f42020-04-07 14:52:42 +08007360 [ALC236_FIXUP_HP_MUTE_LED] = {
7361 .type = HDA_FIXUP_FUNC,
7362 .v.func = alc236_fixup_hp_mute_led,
7363 },
Mike Pozulp14425f12020-05-09 20:28:37 -07007364 [ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET] = {
7365 .type = HDA_FIXUP_VERBS,
7366 .v.verbs = (const struct hda_verb[]) {
7367 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc5 },
7368 { }
7369 },
7370 },
Chris Chiu9e433422020-05-12 14:15:24 +08007371 [ALC295_FIXUP_ASUS_MIC_NO_PRESENCE] = {
7372 .type = HDA_FIXUP_PINS,
7373 .v.pins = (const struct hda_pintbl[]) {
7374 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
7375 { }
7376 },
7377 .chained = true,
7378 .chain_id = ALC269_FIXUP_HEADSET_MODE
7379 },
Jian-Hong Pan8eae7e92020-07-06 15:18:25 +08007380 [ALC269VC_FIXUP_ACER_VCOPPERBOX_PINS] = {
7381 .type = HDA_FIXUP_PINS,
7382 .v.pins = (const struct hda_pintbl[]) {
7383 { 0x14, 0x90100120 }, /* use as internal speaker */
7384 { 0x18, 0x02a111f0 }, /* use as headset mic, without its own jack detect */
7385 { 0x1a, 0x01011020 }, /* use as line out */
7386 { },
7387 },
7388 .chained = true,
7389 .chain_id = ALC269_FIXUP_HEADSET_MIC
7390 },
Jian-Hong Pan6e15d122020-07-06 15:18:27 +08007391 [ALC269VC_FIXUP_ACER_HEADSET_MIC] = {
7392 .type = HDA_FIXUP_PINS,
7393 .v.pins = (const struct hda_pintbl[]) {
7394 { 0x18, 0x02a11030 }, /* use as headset mic */
7395 { }
7396 },
7397 .chained = true,
7398 .chain_id = ALC269_FIXUP_HEADSET_MIC
7399 },
Jian-Hong Pan781c90c2020-07-06 15:18:29 +08007400 [ALC269VC_FIXUP_ACER_MIC_NO_PRESENCE] = {
7401 .type = HDA_FIXUP_PINS,
7402 .v.pins = (const struct hda_pintbl[]) {
7403 { 0x18, 0x01a11130 }, /* use as headset mic, without its own jack detect */
7404 { }
7405 },
7406 .chained = true,
7407 .chain_id = ALC269_FIXUP_HEADSET_MIC
7408 },
Armas Spann293a92c2020-07-24 16:08:37 +02007409 [ALC289_FIXUP_ASUS_GA401] = {
Armas Spannff536642020-07-11 13:05:57 +02007410 .type = HDA_FIXUP_PINS,
7411 .v.pins = (const struct hda_pintbl[]) {
7412 { 0x19, 0x03a11020 }, /* headset mic with jack detect */
7413 { }
7414 },
7415 },
Armas Spann4b43d052020-07-24 16:06:16 +02007416 [ALC289_FIXUP_ASUS_GA502] = {
7417 .type = HDA_FIXUP_PINS,
7418 .v.pins = (const struct hda_pintbl[]) {
7419 { 0x19, 0x03a11020 }, /* headset mic with jack detect */
7420 { }
7421 },
7422 },
Jian-Hong Panf50a1212020-07-13 14:04:22 +08007423 [ALC256_FIXUP_ACER_MIC_NO_PRESENCE] = {
7424 .type = HDA_FIXUP_PINS,
7425 .v.pins = (const struct hda_pintbl[]) {
7426 { 0x19, 0x02a11120 }, /* use as headset mic, without its own jack detect */
7427 { }
7428 },
7429 .chained = true,
7430 .chain_id = ALC256_FIXUP_ASUS_HEADSET_MODE
7431 },
Kailang Yang56496252020-07-29 15:09:27 +08007432 [ALC285_FIXUP_HP_GPIO_AMP_INIT] = {
7433 .type = HDA_FIXUP_FUNC,
7434 .v.func = alc285_fixup_hp_gpio_amp_init,
7435 .chained = true,
7436 .chain_id = ALC285_FIXUP_HP_GPIO_LED
7437 },
Huacai Chenf1ec5be2020-08-02 17:26:40 +08007438 [ALC269_FIXUP_CZC_B20] = {
7439 .type = HDA_FIXUP_PINS,
7440 .v.pins = (const struct hda_pintbl[]) {
7441 { 0x12, 0x411111f0 },
7442 { 0x14, 0x90170110 }, /* speaker */
7443 { 0x15, 0x032f1020 }, /* HP out */
7444 { 0x17, 0x411111f0 },
7445 { 0x18, 0x03ab1040 }, /* mic */
7446 { 0x19, 0xb7a7013f },
7447 { 0x1a, 0x0181305f },
7448 { 0x1b, 0x411111f0 },
7449 { 0x1d, 0x411111f0 },
7450 { 0x1e, 0x411111f0 },
7451 { }
7452 },
7453 .chain_id = ALC269_FIXUP_DMIC,
7454 },
7455 [ALC269_FIXUP_CZC_TMI] = {
7456 .type = HDA_FIXUP_PINS,
7457 .v.pins = (const struct hda_pintbl[]) {
7458 { 0x12, 0x4000c000 },
7459 { 0x14, 0x90170110 }, /* speaker */
7460 { 0x15, 0x0421401f }, /* HP out */
7461 { 0x17, 0x411111f0 },
7462 { 0x18, 0x04a19020 }, /* mic */
7463 { 0x19, 0x411111f0 },
7464 { 0x1a, 0x411111f0 },
7465 { 0x1b, 0x411111f0 },
7466 { 0x1d, 0x40448505 },
7467 { 0x1e, 0x411111f0 },
7468 { 0x20, 0x8000ffff },
7469 { }
7470 },
7471 .chain_id = ALC269_FIXUP_DMIC,
7472 },
7473 [ALC269_FIXUP_CZC_L101] = {
7474 .type = HDA_FIXUP_PINS,
7475 .v.pins = (const struct hda_pintbl[]) {
7476 { 0x12, 0x40000000 },
7477 { 0x14, 0x01014010 }, /* speaker */
7478 { 0x15, 0x411111f0 }, /* HP out */
7479 { 0x16, 0x411111f0 },
7480 { 0x18, 0x01a19020 }, /* mic */
7481 { 0x19, 0x02a19021 },
7482 { 0x1a, 0x0181302f },
7483 { 0x1b, 0x0221401f },
7484 { 0x1c, 0x411111f0 },
7485 { 0x1d, 0x4044c601 },
7486 { 0x1e, 0x411111f0 },
7487 { }
7488 },
7489 .chain_id = ALC269_FIXUP_DMIC,
7490 },
7491 [ALC269_FIXUP_LEMOTE_A1802] = {
7492 .type = HDA_FIXUP_PINS,
7493 .v.pins = (const struct hda_pintbl[]) {
7494 { 0x12, 0x40000000 },
7495 { 0x14, 0x90170110 }, /* speaker */
7496 { 0x17, 0x411111f0 },
7497 { 0x18, 0x03a19040 }, /* mic1 */
7498 { 0x19, 0x90a70130 }, /* mic2 */
7499 { 0x1a, 0x411111f0 },
7500 { 0x1b, 0x411111f0 },
7501 { 0x1d, 0x40489d2d },
7502 { 0x1e, 0x411111f0 },
7503 { 0x20, 0x0003ffff },
7504 { 0x21, 0x03214020 },
7505 { }
7506 },
7507 .chain_id = ALC269_FIXUP_DMIC,
7508 },
7509 [ALC269_FIXUP_LEMOTE_A190X] = {
7510 .type = HDA_FIXUP_PINS,
7511 .v.pins = (const struct hda_pintbl[]) {
7512 { 0x14, 0x99130110 }, /* speaker */
7513 { 0x15, 0x0121401f }, /* HP out */
7514 { 0x18, 0x01a19c20 }, /* rear mic */
7515 { 0x19, 0x99a3092f }, /* front mic */
7516 { 0x1b, 0x0201401f }, /* front lineout */
7517 { }
7518 },
7519 .chain_id = ALC269_FIXUP_DMIC,
7520 },
Kai-Heng Fenge2d2fde2020-08-07 16:05:12 +08007521 [ALC256_FIXUP_INTEL_NUC8_RUGGED] = {
7522 .type = HDA_FIXUP_PINS,
7523 .v.pins = (const struct hda_pintbl[]) {
7524 { 0x1b, 0x01a1913c }, /* use as headset mic, without its own jack detect */
7525 { }
7526 },
7527 .chained = true,
7528 .chain_id = ALC269_FIXUP_HEADSET_MODE
7529 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02007530};
7531
7532static const struct snd_pci_quirk alc269_fixup_tbl[] = {
Marius Knausta6b92b62014-03-03 01:48:58 +01007533 SND_PCI_QUIRK(0x1025, 0x0283, "Acer TravelMate 8371", ALC269_FIXUP_INV_DMIC),
David Henningsson693b6132012-06-22 19:12:10 +02007534 SND_PCI_QUIRK(0x1025, 0x029b, "Acer 1810TZ", ALC269_FIXUP_INV_DMIC),
7535 SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC),
David Henningssonaaedfb42013-08-16 14:09:02 +02007536 SND_PCI_QUIRK(0x1025, 0x047c, "Acer AC700", ALC269_FIXUP_ACER_AC700),
Takashi Iwai78197172015-06-27 10:21:13 +02007537 SND_PCI_QUIRK(0x1025, 0x072d, "Acer Aspire V5-571G", ALC269_FIXUP_ASPIRE_HEADSET_MIC),
7538 SND_PCI_QUIRK(0x1025, 0x080d, "Acer Aspire V5-122P", ALC269_FIXUP_ASPIRE_HEADSET_MIC),
David Henningssonaaedfb42013-08-16 14:09:02 +02007539 SND_PCI_QUIRK(0x1025, 0x0740, "Acer AO725", ALC271_FIXUP_HP_GATE_MIC_JACK),
7540 SND_PCI_QUIRK(0x1025, 0x0742, "Acer AO756", ALC271_FIXUP_HP_GATE_MIC_JACK),
Simon South02322ac2016-03-02 23:10:44 -05007541 SND_PCI_QUIRK(0x1025, 0x0762, "Acer Aspire E1-472", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572),
Oleksij Rempelb1e89722013-12-04 20:50:53 +01007542 SND_PCI_QUIRK(0x1025, 0x0775, "Acer Aspire E1-572", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572),
Takashi Iwai1a22e772014-08-27 08:19:05 +02007543 SND_PCI_QUIRK(0x1025, 0x079b, "Acer Aspire V5-573G", ALC282_FIXUP_ASPIRE_V5_PINS),
Chris Chiu705b65f2018-12-05 14:48:54 +08007544 SND_PCI_QUIRK(0x1025, 0x102b, "Acer Aspire C24-860", ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE),
Jian-Hong Pan6e15d122020-07-06 15:18:27 +08007545 SND_PCI_QUIRK(0x1025, 0x1065, "Acer Aspire C20-820", ALC269VC_FIXUP_ACER_HEADSET_MIC),
Takashi Iwaib9c2fa52015-11-19 16:39:50 +01007546 SND_PCI_QUIRK(0x1025, 0x106d, "Acer Cloudbook 14", ALC283_FIXUP_CHROME_BOOK),
Chris Chiuc7531e32019-03-21 17:17:31 +08007547 SND_PCI_QUIRK(0x1025, 0x1099, "Acer Aspire E5-523G", ALC255_FIXUP_ACER_MIC_NO_PRESENCE),
7548 SND_PCI_QUIRK(0x1025, 0x110e, "Acer Aspire ES1-432", ALC255_FIXUP_ACER_MIC_NO_PRESENCE),
Bernhard Rosenkraenzere2a829b2019-03-05 00:38:19 +01007549 SND_PCI_QUIRK(0x1025, 0x1246, "Acer Predator Helios 500", ALC299_FIXUP_PREDATOR_SPK),
Jian-Hong Pan8eae7e92020-07-06 15:18:25 +08007550 SND_PCI_QUIRK(0x1025, 0x1247, "Acer vCopperbox", ALC269VC_FIXUP_ACER_VCOPPERBOX_PINS),
Jian-Hong Pan781c90c2020-07-06 15:18:29 +08007551 SND_PCI_QUIRK(0x1025, 0x1248, "Acer Veriton N4660G", ALC269VC_FIXUP_ACER_MIC_NO_PRESENCE),
Jian-Hong Pan667a8f72019-03-15 17:51:09 +08007552 SND_PCI_QUIRK(0x1025, 0x128f, "Acer Veriton Z6860G", ALC286_FIXUP_ACER_AIO_HEADSET_MIC),
7553 SND_PCI_QUIRK(0x1025, 0x1290, "Acer Veriton Z4860G", ALC286_FIXUP_ACER_AIO_HEADSET_MIC),
7554 SND_PCI_QUIRK(0x1025, 0x1291, "Acer Veriton Z4660G", ALC286_FIXUP_ACER_AIO_HEADSET_MIC),
Jian-Hong Pan2733cce2019-03-21 16:39:04 +08007555 SND_PCI_QUIRK(0x1025, 0x1308, "Acer Aspire Z24-890", ALC286_FIXUP_ACER_AIO_HEADSET_MIC),
Jian-Hong Panea5c7eb2019-04-01 11:25:05 +08007556 SND_PCI_QUIRK(0x1025, 0x132a, "Acer TravelMate B114-21", ALC233_FIXUP_ACER_HEADSET_MIC),
Jian-Hong Pancbc05fd2019-03-13 17:33:24 +08007557 SND_PCI_QUIRK(0x1025, 0x1330, "Acer TravelMate X514-51T", ALC255_FIXUP_ACER_HEADSET_MIC),
Jian-Hong Panf50a1212020-07-13 14:04:22 +08007558 SND_PCI_QUIRK(0x1025, 0x1430, "Acer TravelMate B311R-31", ALC256_FIXUP_ACER_MIC_NO_PRESENCE),
David Henningssonaaedfb42013-08-16 14:09:02 +02007559 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
Kailang Yang6ed11312015-10-26 15:37:39 +08007560 SND_PCI_QUIRK(0x1028, 0x054b, "Dell XPS one 2710", ALC275_FIXUP_DELL_XPS),
Takashi Iwai86f799b2015-11-14 17:46:31 +01007561 SND_PCI_QUIRK(0x1028, 0x05bd, "Dell Latitude E6440", ALC292_FIXUP_DELL_E7X),
Takashi Iwaicf521032016-01-15 12:59:25 +01007562 SND_PCI_QUIRK(0x1028, 0x05be, "Dell Latitude E6540", ALC292_FIXUP_DELL_E7X),
Takashi Iwai8b99aba2015-06-15 11:59:32 +02007563 SND_PCI_QUIRK(0x1028, 0x05ca, "Dell Latitude E7240", ALC292_FIXUP_DELL_E7X),
7564 SND_PCI_QUIRK(0x1028, 0x05cb, "Dell Latitude E7440", ALC292_FIXUP_DELL_E7X),
David Henningsson0f4881d2013-12-20 16:08:13 +01007565 SND_PCI_QUIRK(0x1028, 0x05da, "Dell Vostro 5460", ALC290_FIXUP_SUBWOOFER),
David Henningsson73bdd592013-04-15 15:44:14 +02007566 SND_PCI_QUIRK(0x1028, 0x05f4, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
7567 SND_PCI_QUIRK(0x1028, 0x05f5, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
7568 SND_PCI_QUIRK(0x1028, 0x05f6, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
David Henningsson0f4881d2013-12-20 16:08:13 +01007569 SND_PCI_QUIRK(0x1028, 0x0615, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK),
7570 SND_PCI_QUIRK(0x1028, 0x0616, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK),
Takashi Iwai98070572016-01-12 21:06:39 +01007571 SND_PCI_QUIRK(0x1028, 0x062c, "Dell Latitude E5550", ALC292_FIXUP_DELL_E7X),
Takashi Iwai42755542015-06-29 10:56:53 +02007572 SND_PCI_QUIRK(0x1028, 0x062e, "Dell Latitude E7450", ALC292_FIXUP_DELL_E7X),
David Henningsson0f4881d2013-12-20 16:08:13 +01007573 SND_PCI_QUIRK(0x1028, 0x0638, "Dell Inspiron 5439", ALC290_FIXUP_MONO_SPEAKERS_HSJACK),
Kailang Yanga22aa262014-04-23 17:34:28 +08007574 SND_PCI_QUIRK(0x1028, 0x064a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
7575 SND_PCI_QUIRK(0x1028, 0x064b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
Hui Wang831bfdf92015-06-26 12:35:17 +08007576 SND_PCI_QUIRK(0x1028, 0x0665, "Dell XPS 13", ALC288_FIXUP_DELL_XPS_13),
Bastien Noceraafecb142016-04-18 11:10:42 +02007577 SND_PCI_QUIRK(0x1028, 0x0669, "Dell Optiplex 9020m", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
Takashi Iwai3a05d122015-07-29 09:04:52 +02007578 SND_PCI_QUIRK(0x1028, 0x069a, "Dell Vostro 5480", ALC290_FIXUP_SUBWOOFER_HSJACK),
Kailang Yang8b724152014-12-17 17:08:59 +08007579 SND_PCI_QUIRK(0x1028, 0x06c7, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
Kailang Yangb7343042014-12-02 14:50:45 +08007580 SND_PCI_QUIRK(0x1028, 0x06d9, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
7581 SND_PCI_QUIRK(0x1028, 0x06da, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
David Henningssonc04017e2015-12-15 14:44:03 +01007582 SND_PCI_QUIRK(0x1028, 0x06db, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
7583 SND_PCI_QUIRK(0x1028, 0x06dd, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
7584 SND_PCI_QUIRK(0x1028, 0x06de, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
7585 SND_PCI_QUIRK(0x1028, 0x06df, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
7586 SND_PCI_QUIRK(0x1028, 0x06e0, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
Kai-Heng Fengfd06c772016-08-30 15:36:34 +08007587 SND_PCI_QUIRK(0x1028, 0x0706, "Dell Inspiron 7559", ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER),
Kai-Heng Feng3b43b712016-02-25 15:19:38 +08007588 SND_PCI_QUIRK(0x1028, 0x0725, "Dell Inspiron 3162", ALC255_FIXUP_DELL_SPK_NOISE),
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01007589 SND_PCI_QUIRK(0x1028, 0x0738, "Dell Precision 5820", ALC269_FIXUP_NO_SHUTUP),
Kai-Heng Feng709ae622018-10-04 11:39:42 +08007590 SND_PCI_QUIRK(0x1028, 0x075c, "Dell XPS 27 7760", ALC298_FIXUP_SPK_VOLUME),
Hui Wangdd9aa332016-08-01 10:20:32 +08007591 SND_PCI_QUIRK(0x1028, 0x075d, "Dell AIO", ALC298_FIXUP_SPK_VOLUME),
Takashi Iwaie312a862018-03-06 12:14:17 +01007592 SND_PCI_QUIRK(0x1028, 0x07b0, "Dell Precision 7520", ALC295_FIXUP_DISABLE_DAC3),
Takashi Iwai493de342017-02-28 17:27:57 +01007593 SND_PCI_QUIRK(0x1028, 0x0798, "Dell Inspiron 17 7000 Gaming", ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER),
Kailang Yang5f364132017-07-25 16:28:16 +08007594 SND_PCI_QUIRK(0x1028, 0x080c, "Dell WYSE", ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE),
Kailang Yang40e2c4e2018-02-02 15:13:09 +08007595 SND_PCI_QUIRK(0x1028, 0x084b, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB),
7596 SND_PCI_QUIRK(0x1028, 0x084e, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB),
Kailang Yangf0ba9d62018-03-16 11:46:08 +08007597 SND_PCI_QUIRK(0x1028, 0x0871, "Dell Precision 3630", ALC255_FIXUP_DELL_HEADSET_MIC),
7598 SND_PCI_QUIRK(0x1028, 0x0872, "Dell Precision 3630", ALC255_FIXUP_DELL_HEADSET_MIC),
Kailang Yangae104a22018-02-05 16:07:20 +08007599 SND_PCI_QUIRK(0x1028, 0x0873, "Dell Precision 3930", ALC255_FIXUP_DUMMY_LINEOUT_VERB),
Kailang Yang136824e2019-03-14 16:22:45 +08007600 SND_PCI_QUIRK(0x1028, 0x08ad, "Dell WYSE AIO", ALC225_FIXUP_DELL_WYSE_AIO_MIC_NO_PRESENCE),
Kailang Yangda484d02019-03-14 15:50:59 +08007601 SND_PCI_QUIRK(0x1028, 0x08ae, "Dell WYSE NB", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE),
Kailang Yangc2a7c55a2019-01-03 15:53:39 +08007602 SND_PCI_QUIRK(0x1028, 0x0935, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB),
Kailang Yange79c2262019-12-19 14:12:15 +08007603 SND_PCI_QUIRK(0x1028, 0x097e, "Dell Precision", ALC289_FIXUP_DUAL_SPK),
7604 SND_PCI_QUIRK(0x1028, 0x097d, "Dell Precision", ALC289_FIXUP_DUAL_SPK),
Kailang Yang78def222020-02-20 15:21:54 +08007605 SND_PCI_QUIRK(0x1028, 0x098d, "Dell Precision", ALC233_FIXUP_ASUS_MIC_NO_PRESENCE),
7606 SND_PCI_QUIRK(0x1028, 0x09bf, "Dell Precision", ALC233_FIXUP_ASUS_MIC_NO_PRESENCE),
Kailang Yanga22aa262014-04-23 17:34:28 +08007607 SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
7608 SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
Takashi Iwai08fb0d02013-01-10 17:33:58 +01007609 SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01007610 SND_PCI_QUIRK(0x103c, 0x18e6, "HP", ALC269_FIXUP_HP_GPIO_LED),
David Henningsson8e35cd42013-11-06 11:20:01 +01007611 SND_PCI_QUIRK(0x103c, 0x218b, "HP", ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED),
David Henningsson33f4acd2015-01-07 15:50:13 +01007612 SND_PCI_QUIRK(0x103c, 0x225f, "HP", ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY),
Kailang Yangc60666b2014-02-21 16:23:35 +08007613 /* ALC282 */
Hui Wang7976eb42015-02-13 11:14:41 +08007614 SND_PCI_QUIRK(0x103c, 0x21f9, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang8a02b162014-06-13 17:16:31 +08007615 SND_PCI_QUIRK(0x103c, 0x2210, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang8a02b162014-06-13 17:16:31 +08007616 SND_PCI_QUIRK(0x103c, 0x2214, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007617 SND_PCI_QUIRK(0x103c, 0x2236, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
7618 SND_PCI_QUIRK(0x103c, 0x2237, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
7619 SND_PCI_QUIRK(0x103c, 0x2238, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
7620 SND_PCI_QUIRK(0x103c, 0x2239, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007621 SND_PCI_QUIRK(0x103c, 0x224b, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
Kailang Yangc60666b2014-02-21 16:23:35 +08007622 SND_PCI_QUIRK(0x103c, 0x2268, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08007623 SND_PCI_QUIRK(0x103c, 0x226a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7624 SND_PCI_QUIRK(0x103c, 0x226b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang8a02b162014-06-13 17:16:31 +08007625 SND_PCI_QUIRK(0x103c, 0x226e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangeaa8e5e2014-11-21 15:49:11 +08007626 SND_PCI_QUIRK(0x103c, 0x2271, "HP", ALC286_FIXUP_HP_GPIO_LED),
TienFu Chenb4b33f92015-01-20 15:06:21 +01007627 SND_PCI_QUIRK(0x103c, 0x2272, "HP", ALC280_FIXUP_HP_DOCK_PINS),
TienFu Chen3271cb22015-02-10 09:09:41 +01007628 SND_PCI_QUIRK(0x103c, 0x2273, "HP", ALC280_FIXUP_HP_DOCK_PINS),
Kailang Yangc60666b2014-02-21 16:23:35 +08007629 SND_PCI_QUIRK(0x103c, 0x229e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08007630 SND_PCI_QUIRK(0x103c, 0x22b2, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7631 SND_PCI_QUIRK(0x103c, 0x22b7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7632 SND_PCI_QUIRK(0x103c, 0x22bf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08007633 SND_PCI_QUIRK(0x103c, 0x22cf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Keith Packard98973f22015-07-15 12:14:39 -07007634 SND_PCI_QUIRK(0x103c, 0x22db, "HP", ALC280_FIXUP_HP_9480M),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007635 SND_PCI_QUIRK(0x103c, 0x22dc, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
7636 SND_PCI_QUIRK(0x103c, 0x22fb, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yangc60666b2014-02-21 16:23:35 +08007637 /* ALC290 */
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007638 SND_PCI_QUIRK(0x103c, 0x221b, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007639 SND_PCI_QUIRK(0x103c, 0x2221, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007640 SND_PCI_QUIRK(0x103c, 0x2225, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007641 SND_PCI_QUIRK(0x103c, 0x2253, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
7642 SND_PCI_QUIRK(0x103c, 0x2254, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
7643 SND_PCI_QUIRK(0x103c, 0x2255, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
7644 SND_PCI_QUIRK(0x103c, 0x2256, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
7645 SND_PCI_QUIRK(0x103c, 0x2257, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007646 SND_PCI_QUIRK(0x103c, 0x2259, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Jaroslav Kysela04d54662017-03-09 13:29:13 +01007647 SND_PCI_QUIRK(0x103c, 0x225a, "HP", ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED),
Kailang Yangc60666b2014-02-21 16:23:35 +08007648 SND_PCI_QUIRK(0x103c, 0x2260, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08007649 SND_PCI_QUIRK(0x103c, 0x2263, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7650 SND_PCI_QUIRK(0x103c, 0x2264, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7651 SND_PCI_QUIRK(0x103c, 0x2265, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007652 SND_PCI_QUIRK(0x103c, 0x2272, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
7653 SND_PCI_QUIRK(0x103c, 0x2273, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007654 SND_PCI_QUIRK(0x103c, 0x2278, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yangc60666b2014-02-21 16:23:35 +08007655 SND_PCI_QUIRK(0x103c, 0x227f, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08007656 SND_PCI_QUIRK(0x103c, 0x2282, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08007657 SND_PCI_QUIRK(0x103c, 0x228b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08007658 SND_PCI_QUIRK(0x103c, 0x228e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7659 SND_PCI_QUIRK(0x103c, 0x22c5, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08007660 SND_PCI_QUIRK(0x103c, 0x22c7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7661 SND_PCI_QUIRK(0x103c, 0x22c8, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08007662 SND_PCI_QUIRK(0x103c, 0x22c4, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang8a02b162014-06-13 17:16:31 +08007663 SND_PCI_QUIRK(0x103c, 0x2334, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7664 SND_PCI_QUIRK(0x103c, 0x2335, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7665 SND_PCI_QUIRK(0x103c, 0x2336, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7666 SND_PCI_QUIRK(0x103c, 0x2337, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Takashi Iwaif8839822016-02-25 14:31:59 +01007667 SND_PCI_QUIRK(0x103c, 0x221c, "HP EliteBook 755 G2", ALC280_FIXUP_HP_HEADSET_MIC),
Jaroslav Kysela167897f2019-03-13 13:40:15 +01007668 SND_PCI_QUIRK(0x103c, 0x802e, "HP Z240 SFF", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
7669 SND_PCI_QUIRK(0x103c, 0x802f, "HP Z240", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
Takashi Iwai563785e2018-11-12 09:43:12 +01007670 SND_PCI_QUIRK(0x103c, 0x820d, "HP Pavilion 15", ALC269_FIXUP_HP_MUTE_LED_MIC3),
Hui Wange549d192016-04-01 11:00:15 +08007671 SND_PCI_QUIRK(0x103c, 0x8256, "HP", ALC221_FIXUP_HP_FRONT_MIC),
Tom Bridenbbf8ff62018-05-29 17:34:20 +01007672 SND_PCI_QUIRK(0x103c, 0x827e, "HP x360", ALC295_FIXUP_HP_X360),
Jaroslav Kysela167897f2019-03-13 13:40:15 +01007673 SND_PCI_QUIRK(0x103c, 0x82bf, "HP G3 mini", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
7674 SND_PCI_QUIRK(0x103c, 0x82c0, "HP G3 mini premium", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
Alexandru Gagniuc56e40eb2018-08-04 11:44:44 -05007675 SND_PCI_QUIRK(0x103c, 0x83b9, "HP Spectre x360", ALC269_FIXUP_HP_MUTE_LED_MIC3),
Takashi Iwai190d0382019-08-13 17:39:56 +02007676 SND_PCI_QUIRK(0x103c, 0x8497, "HP Envy x360", ALC269_FIXUP_HP_MUTE_LED_MIC3),
Sam Bazleyd33cd422019-09-01 03:31:30 +01007677 SND_PCI_QUIRK(0x103c, 0x84e7, "HP Pavilion 15", ALC269_FIXUP_HP_MUTE_LED_MIC3),
Kai-Heng Fengb2c22912020-06-17 18:29:02 +08007678 SND_PCI_QUIRK(0x103c, 0x869d, "HP", ALC236_FIXUP_HP_MUTE_LED),
7679 SND_PCI_QUIRK(0x103c, 0x8729, "HP", ALC285_FIXUP_HP_GPIO_LED),
Kailang Yang56496252020-07-29 15:09:27 +08007680 SND_PCI_QUIRK(0x103c, 0x8736, "HP", ALC285_FIXUP_HP_GPIO_AMP_INIT),
Kailang Yang431e76c2020-04-07 14:40:20 +08007681 SND_PCI_QUIRK(0x103c, 0x877a, "HP", ALC285_FIXUP_HP_MUTE_LED),
Kailang Yang24164f42020-04-07 14:52:42 +08007682 SND_PCI_QUIRK(0x103c, 0x877d, "HP", ALC236_FIXUP_HP_MUTE_LED),
Chris Chiuc1732ed2017-02-28 14:17:13 -06007683 SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC),
Takashi Iwai7bba2152013-09-06 15:45:38 +02007684 SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300),
David Henningsson3e0d6112013-04-22 14:30:14 +02007685 SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Wandrille RONCE9cf65332018-12-19 14:52:44 +01007686 SND_PCI_QUIRK(0x1043, 0x10a1, "ASUS UX391UA", ALC294_FIXUP_ASUS_SPK),
Chris Chiuc1732ed2017-02-28 14:17:13 -06007687 SND_PCI_QUIRK(0x1043, 0x10c0, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC),
Takashi Iwai4eab0ea2017-06-06 12:33:17 +02007688 SND_PCI_QUIRK(0x1043, 0x10d0, "ASUS X540LA/X540LJ", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
David Henningsson3e0d6112013-04-22 14:30:14 +02007689 SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Takashi Iwai4eab0ea2017-06-06 12:33:17 +02007690 SND_PCI_QUIRK(0x1043, 0x11c0, "ASUS X556UR", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
7691 SND_PCI_QUIRK(0x1043, 0x1290, "ASUS X441SA", ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE),
7692 SND_PCI_QUIRK(0x1043, 0x12a0, "ASUS X441UV", ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE),
Chris Chiuc1732ed2017-02-28 14:17:13 -06007693 SND_PCI_QUIRK(0x1043, 0x12f0, "ASUS X541UV", ALC256_FIXUP_ASUS_MIC),
7694 SND_PCI_QUIRK(0x1043, 0x12e0, "ASUS X541SA", ALC256_FIXUP_ASUS_MIC),
7695 SND_PCI_QUIRK(0x1043, 0x13b0, "ASUS Z550SA", ALC256_FIXUP_ASUS_MIC),
Oleksij Rempel2cede302013-11-27 17:12:03 +01007696 SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK),
Takashi Iwai23870832013-11-29 14:13:12 +01007697 SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A),
David Henningsson3e0d6112013-04-22 14:30:14 +02007698 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC),
Chris Chiu48e01502019-12-30 11:11:18 +08007699 SND_PCI_QUIRK(0x1043, 0x17d1, "ASUS UX431FL", ALC294_FIXUP_ASUS_DUAL_SPK),
Daniel Drake8c8967a2019-10-17 16:15:01 +08007700 SND_PCI_QUIRK(0x1043, 0x18b1, "Asus MJ401TA", ALC256_FIXUP_ASUS_HEADSET_MIC),
Adam Barber4963d662020-04-10 17:00:32 +08007701 SND_PCI_QUIRK(0x1043, 0x18f1, "Asus FX505DT", ALC256_FIXUP_ASUS_HEADSET_MIC),
Kailang Yang158ae2f2020-07-16 15:21:59 +08007702 SND_PCI_QUIRK(0x1043, 0x194e, "ASUS UX563FD", ALC294_FIXUP_ASUS_HPE),
Jian-Hong Pan8b33a132020-02-25 15:29:21 +08007703 SND_PCI_QUIRK(0x1043, 0x19ce, "ASUS B9450FA", ALC294_FIXUP_ASUS_HPE),
Jian-Hong Pan7900e812020-05-12 14:15:28 +08007704 SND_PCI_QUIRK(0x1043, 0x19e1, "ASUS UX581LV", ALC295_FIXUP_ASUS_MIC_NO_PRESENCE),
Takashi Iwai017f2a12011-07-09 14:42:25 +02007705 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
Chris Chiu28e8af82017-06-05 15:05:30 -06007706 SND_PCI_QUIRK(0x1043, 0x1a30, "ASUS X705UD", ALC256_FIXUP_ASUS_MIC),
Takashi Iwai1b94e592020-05-12 09:32:03 +02007707 SND_PCI_QUIRK(0x1043, 0x1b11, "ASUS UX431DA", ALC294_FIXUP_ASUS_COEF_1B),
David Henningsson693b6132012-06-22 19:12:10 +02007708 SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC),
Chris Chiu615966a2017-02-28 14:17:12 -06007709 SND_PCI_QUIRK(0x1043, 0x1bbd, "ASUS Z550MA", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
Takashi Iwai4eab0ea2017-06-06 12:33:17 +02007710 SND_PCI_QUIRK(0x1043, 0x1c23, "Asus X55U", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Chris Chiuc1732ed2017-02-28 14:17:13 -06007711 SND_PCI_QUIRK(0x1043, 0x1ccd, "ASUS X555UB", ALC256_FIXUP_ASUS_MIC),
Armas Spann4b43d052020-07-24 16:06:16 +02007712 SND_PCI_QUIRK(0x1043, 0x1e11, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA502),
Armas Spann293a92c2020-07-24 16:08:37 +02007713 SND_PCI_QUIRK(0x1043, 0x1f11, "ASUS Zephyrus G14", ALC289_FIXUP_ASUS_GA401),
Chris Chiueeed4cd2017-02-28 14:17:15 -06007714 SND_PCI_QUIRK(0x1043, 0x3030, "ASUS ZN270IE", ALC256_FIXUP_ASUS_AIO_GPIO2),
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02007715 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC),
7716 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC),
7717 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
7718 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
David Henningssond240d1d2013-04-15 12:50:02 +02007719 SND_PCI_QUIRK(0x1043, 0x8516, "ASUS X101CH", ALC269_FIXUP_ASUS_X101),
Takashi Iwaif88abaa2014-02-07 12:07:59 +01007720 SND_PCI_QUIRK(0x104d, 0x90b5, "Sony VAIO Pro 11", ALC286_FIXUP_SONY_MIC_NO_PRESENCE),
David Henningsson88cfcf82013-10-11 10:18:45 +02007721 SND_PCI_QUIRK(0x104d, 0x90b6, "Sony VAIO Pro 13", ALC286_FIXUP_SONY_MIC_NO_PRESENCE),
Takashi Iwai1d045db2011-07-07 18:23:21 +02007722 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
7723 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
7724 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
Takashi Iwaie9bd7d52014-05-21 11:06:49 +02007725 SND_PCI_QUIRK(0x104d, 0x9099, "Sony VAIO S13", ALC275_FIXUP_SONY_DISABLE_AAMIX),
Takashi Iwai24519912011-08-16 15:08:49 +02007726 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook", ALC269_FIXUP_LIFEBOOK),
Takashi Iwai4df3fd12015-06-29 08:38:02 +02007727 SND_PCI_QUIRK(0x10cf, 0x159f, "Lifebook E780", ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT),
Takashi Iwaicc7016a2015-04-08 20:47:55 +02007728 SND_PCI_QUIRK(0x10cf, 0x15dc, "Lifebook T731", ALC269_FIXUP_LIFEBOOK_HP_PIN),
Takashi Iwai88776f32015-05-01 09:20:34 +02007729 SND_PCI_QUIRK(0x10cf, 0x1757, "Lifebook E752", ALC269_FIXUP_LIFEBOOK_HP_PIN),
Jan-Marek Glogowskifdcc9682018-02-14 11:29:15 +01007730 SND_PCI_QUIRK(0x10cf, 0x1629, "Lifebook U7x7", ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC),
David Henningsson2041d562014-06-13 11:15:44 +02007731 SND_PCI_QUIRK(0x10cf, 0x1845, "Lifebook U904", ALC269_FIXUP_LIFEBOOK_EXTMIC),
PeiSen Houb84e8432017-09-01 15:11:56 +08007732 SND_PCI_QUIRK(0x10ec, 0x10f2, "Intel Reference board", ALC700_FIXUP_INTEL_REFERENCE),
PeiSen Hou6fa38ef2020-07-27 13:56:47 +02007733 SND_PCI_QUIRK(0x10ec, 0x1230, "Intel Reference board", ALC295_FIXUP_CHROME_BOOK),
YOKOTA Hiroshi0fca97a2018-07-01 18:30:01 +09007734 SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-SZ6", ALC269_FIXUP_HEADSET_MODE),
David Henningssona33cc482014-10-07 10:18:41 +02007735 SND_PCI_QUIRK(0x144d, 0xc109, "Samsung Ativ book 9 (NP900X3G)", ALC269_FIXUP_INV_DMIC),
Mike Pozulp14425f12020-05-09 20:28:37 -07007736 SND_PCI_QUIRK(0x144d, 0xc169, "Samsung Notebook 9 Pen (NP930SBE-K01US)", ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET),
7737 SND_PCI_QUIRK(0x144d, 0xc176, "Samsung Notebook 9 Pro (NP930MBE-K04US)", ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET),
Mike Pozulpf70fff82020-08-13 21:53:44 -07007738 SND_PCI_QUIRK(0x144d, 0xc189, "Samsung Galaxy Flex Book (NT950QCG-X716)", ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET),
Adrien Crivelli8bcea6c2020-08-26 17:40:14 +09007739 SND_PCI_QUIRK(0x144d, 0xc18a, "Samsung Galaxy Book Ion (NP930XCJ-K01US)", ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET),
7740 SND_PCI_QUIRK(0x144d, 0xc830, "Samsung Galaxy Book Ion (NT950XCJ-X716A)", ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET),
Gabriele Mazzotta823ff162016-12-24 19:50:01 +01007741 SND_PCI_QUIRK(0x144d, 0xc740, "Samsung Ativ book 8 (NP870Z5G)", ALC269_FIXUP_ATIV_BOOK_8),
Joonho Wohn568e4e82020-07-18 17:23:15 +09007742 SND_PCI_QUIRK(0x144d, 0xc812, "Samsung Notebook Pen S (NT950SBE-X58)", ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET),
Anisse Astierabaa22742016-08-24 09:14:13 +02007743 SND_PCI_QUIRK(0x1458, 0xfa53, "Gigabyte BXBT-2807", ALC283_FIXUP_HEADSET_MIC),
7744 SND_PCI_QUIRK(0x1462, 0xb120, "MSI Cubi MS-B120", ALC283_FIXUP_HEADSET_MIC),
Anisse Astier8cd65272018-11-23 17:59:11 +01007745 SND_PCI_QUIRK(0x1462, 0xb171, "Cubi N 8GL (MS-B171)", ALC283_FIXUP_HEADSET_MIC),
Jeremy Soller89e3a562019-01-30 16:12:31 -07007746 SND_PCI_QUIRK(0x1558, 0x1325, "System76 Darter Pro (darp5)", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
Jeremy Soller80a50522019-05-07 17:11:08 -04007747 SND_PCI_QUIRK(0x1558, 0x8550, "System76 Gazelle (gaze14)", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
Jeremy Soller891afcf2019-05-10 10:15:07 -04007748 SND_PCI_QUIRK(0x1558, 0x8551, "System76 Gazelle (gaze14)", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
7749 SND_PCI_QUIRK(0x1558, 0x8560, "System76 Gazelle (gaze14)", ALC269_FIXUP_HEADSET_MIC),
7750 SND_PCI_QUIRK(0x1558, 0x8561, "System76 Gazelle (gaze14)", ALC269_FIXUP_HEADSET_MIC),
Kailang Yangca169cc2017-04-25 16:17:40 +08007751 SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC233_FIXUP_LENOVO_MULTI_CODECS),
Hui Wangef0b3202020-04-27 11:00:39 +08007752 SND_PCI_QUIRK(0x17aa, 0x1048, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC),
Takashi Iwai1d045db2011-07-07 18:23:21 +02007753 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
7754 SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
7755 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
7756 SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
7757 SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
Takashi Iwaib590b382020-05-14 18:05:33 +02007758 SND_PCI_QUIRK(0x17aa, 0x21f6, "Thinkpad T530", ALC269_FIXUP_LENOVO_DOCK_LIMIT_BOOST),
Felix Kaechelec8415a42012-08-06 23:02:01 +02007759 SND_PCI_QUIRK(0x17aa, 0x21fa, "Thinkpad X230", ALC269_FIXUP_LENOVO_DOCK),
Stefán Freyr84f98fd2012-10-19 22:46:00 +02007760 SND_PCI_QUIRK(0x17aa, 0x21f3, "Thinkpad T430", ALC269_FIXUP_LENOVO_DOCK),
Philipp A. Mohrenweiser4407be62012-08-06 13:14:18 +02007761 SND_PCI_QUIRK(0x17aa, 0x21fb, "Thinkpad T430s", ALC269_FIXUP_LENOVO_DOCK),
David Henningsson108cc102012-07-20 10:37:25 +02007762 SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK),
David Henningssonaaedfb42013-08-16 14:09:02 +02007763 SND_PCI_QUIRK(0x17aa, 0x2208, "Thinkpad T431s", ALC269_FIXUP_LENOVO_DOCK),
Takashi Iwai9a811232015-12-09 15:17:43 +01007764 SND_PCI_QUIRK(0x17aa, 0x220c, "Thinkpad T440s", ALC292_FIXUP_TPT440),
Takashi Iwai1c37c222014-05-06 17:34:42 +02007765 SND_PCI_QUIRK(0x17aa, 0x220e, "Thinkpad T440p", ALC292_FIXUP_TPT440_DOCK),
Takashi Iwaia12137e2014-06-27 12:14:35 +02007766 SND_PCI_QUIRK(0x17aa, 0x2210, "Thinkpad T540p", ALC292_FIXUP_TPT440_DOCK),
Rick Sherman59a51a62015-08-18 21:04:30 -05007767 SND_PCI_QUIRK(0x17aa, 0x2211, "Thinkpad W541", ALC292_FIXUP_TPT440_DOCK),
Takashi Iwai6d169412014-10-07 17:27:02 +02007768 SND_PCI_QUIRK(0x17aa, 0x2212, "Thinkpad T440", ALC292_FIXUP_TPT440_DOCK),
Lukas Bossard7c215392014-10-29 18:31:07 +01007769 SND_PCI_QUIRK(0x17aa, 0x2214, "Thinkpad X240", ALC292_FIXUP_TPT440_DOCK),
David Henningssona4a9e082013-08-16 14:09:01 +02007770 SND_PCI_QUIRK(0x17aa, 0x2215, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Takashi Iwaib6903c02015-12-10 12:20:20 +01007771 SND_PCI_QUIRK(0x17aa, 0x2218, "Thinkpad X1 Carbon 2nd", ALC292_FIXUP_TPT440_DOCK),
Laura Abbottd05ea7d2015-10-02 11:09:54 -07007772 SND_PCI_QUIRK(0x17aa, 0x2223, "ThinkPad T550", ALC292_FIXUP_TPT440_DOCK),
Yves-Alexis Perezc0278662015-04-11 09:31:35 +02007773 SND_PCI_QUIRK(0x17aa, 0x2226, "ThinkPad X250", ALC292_FIXUP_TPT440_DOCK),
Kailang Yang61fcf8e2018-02-02 15:26:46 +08007774 SND_PCI_QUIRK(0x17aa, 0x222d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7775 SND_PCI_QUIRK(0x17aa, 0x222e, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
Torsten Hilbrichdab38e42016-06-07 13:14:21 +02007776 SND_PCI_QUIRK(0x17aa, 0x2231, "Thinkpad T560", ALC292_FIXUP_TPT460),
Sven Eckelmannc636b952016-04-11 16:55:26 +02007777 SND_PCI_QUIRK(0x17aa, 0x2233, "Thinkpad", ALC292_FIXUP_TPT460),
Kailang Yang61fcf8e2018-02-02 15:26:46 +08007778 SND_PCI_QUIRK(0x17aa, 0x2245, "Thinkpad T470", ALC298_FIXUP_TPT470_DOCK),
7779 SND_PCI_QUIRK(0x17aa, 0x2246, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7780 SND_PCI_QUIRK(0x17aa, 0x2247, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
Dennis Wassenberge4c07b32018-03-08 13:17:54 +01007781 SND_PCI_QUIRK(0x17aa, 0x2249, "Thinkpad", ALC292_FIXUP_TPT460),
Kailang Yang61fcf8e2018-02-02 15:26:46 +08007782 SND_PCI_QUIRK(0x17aa, 0x224b, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7783 SND_PCI_QUIRK(0x17aa, 0x224c, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7784 SND_PCI_QUIRK(0x17aa, 0x224d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
Benjamin Berg85981df2018-02-14 13:29:39 +01007785 SND_PCI_QUIRK(0x17aa, 0x225d, "Thinkpad T480", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Benjamin Poirier9774dc22020-07-03 17:00:04 +09007786 SND_PCI_QUIRK(0x17aa, 0x2292, "Thinkpad X1 Carbon 7th", ALC285_FIXUP_THINKPAD_HEADSET_JACK),
Hans de Goedeca707b32020-04-02 19:43:11 +02007787 SND_PCI_QUIRK(0x17aa, 0x22be, "Thinkpad X1 Carbon 8th", ALC285_FIXUP_THINKPAD_HEADSET_JACK),
Kailang3694cb22015-12-28 11:35:24 +08007788 SND_PCI_QUIRK(0x17aa, 0x30bb, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
Hui Wang6ef2f682016-03-11 12:04:02 +08007789 SND_PCI_QUIRK(0x17aa, 0x30e2, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
Hui Wangf33f79f2017-07-07 12:08:29 +08007790 SND_PCI_QUIRK(0x17aa, 0x310c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
Dennis Wassenbergbef33e12019-06-28 10:54:53 +02007791 SND_PCI_QUIRK(0x17aa, 0x3111, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
Hui Wange41fc8c2018-06-25 14:40:56 +08007792 SND_PCI_QUIRK(0x17aa, 0x312a, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
Kailang Yang65811832018-04-25 17:07:27 +08007793 SND_PCI_QUIRK(0x17aa, 0x312f, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
Hui Wang8da5bbf2017-12-22 11:17:46 +08007794 SND_PCI_QUIRK(0x17aa, 0x313c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
Hui Wang2a36c162019-09-04 13:53:27 +08007795 SND_PCI_QUIRK(0x17aa, 0x3151, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC),
Aaron Ma8a6c55d2019-10-24 19:44:39 +08007796 SND_PCI_QUIRK(0x17aa, 0x3176, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC),
7797 SND_PCI_QUIRK(0x17aa, 0x3178, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC),
David Henningsson56f27012016-01-11 09:33:14 +01007798 SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
Takashi Iwaifedb2242014-11-13 07:11:38 +01007799 SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC),
Michał Wadowski56df90b2019-05-14 16:58:00 +02007800 SND_PCI_QUIRK(0x17aa, 0x3978, "Lenovo B50-70", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
David Henningssona4a9e082013-08-16 14:09:01 +02007801 SND_PCI_QUIRK(0x17aa, 0x5013, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Kailang Yang1bb3e062013-09-27 13:10:25 +02007802 SND_PCI_QUIRK(0x17aa, 0x501a, "Thinkpad", ALC283_FIXUP_INT_MIC),
Takashi Iwaic497d9f2014-10-08 12:14:40 +02007803 SND_PCI_QUIRK(0x17aa, 0x501e, "Thinkpad L440", ALC292_FIXUP_TPT440_DOCK),
David Henningssoncd5302c2013-08-19 12:22:33 +02007804 SND_PCI_QUIRK(0x17aa, 0x5026, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Jo-Philipp Wichf2aa1112015-04-13 12:47:26 +02007805 SND_PCI_QUIRK(0x17aa, 0x5034, "Thinkpad T450", ALC292_FIXUP_TPT440_DOCK),
Sebastian Wicki80b311d2015-03-23 17:23:11 +01007806 SND_PCI_QUIRK(0x17aa, 0x5036, "Thinkpad T450s", ALC292_FIXUP_TPT440_DOCK),
Ansgar Hegerfeld09ea9972015-05-14 12:31:32 +02007807 SND_PCI_QUIRK(0x17aa, 0x503c, "Thinkpad L450", ALC292_FIXUP_TPT440_DOCK),
Conrad Kostecki037e1192016-04-26 10:08:10 +02007808 SND_PCI_QUIRK(0x17aa, 0x504a, "ThinkPad X260", ALC292_FIXUP_TPT440_DOCK),
Hui Wang23adc192015-12-08 12:27:18 +08007809 SND_PCI_QUIRK(0x17aa, 0x504b, "Thinkpad", ALC293_FIXUP_LENOVO_SPK_NOISE),
Jaroslav Kysela0f087ee2016-06-24 15:13:16 +02007810 SND_PCI_QUIRK(0x17aa, 0x5050, "Thinkpad T560p", ALC292_FIXUP_TPT460),
Torsten Hilbrich9cd25742016-07-05 10:40:22 +02007811 SND_PCI_QUIRK(0x17aa, 0x5051, "Thinkpad L460", ALC292_FIXUP_TPT460),
Jaroslav Kysela0f087ee2016-06-24 15:13:16 +02007812 SND_PCI_QUIRK(0x17aa, 0x5053, "Thinkpad T460", ALC292_FIXUP_TPT460),
Kailang Yang61fcf8e2018-02-02 15:26:46 +08007813 SND_PCI_QUIRK(0x17aa, 0x505d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7814 SND_PCI_QUIRK(0x17aa, 0x505f, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7815 SND_PCI_QUIRK(0x17aa, 0x5062, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
David Henningssoncd5302c2013-08-19 12:22:33 +02007816 SND_PCI_QUIRK(0x17aa, 0x5109, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Kailang Yang61fcf8e2018-02-02 15:26:46 +08007817 SND_PCI_QUIRK(0x17aa, 0x511e, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7818 SND_PCI_QUIRK(0x17aa, 0x511f, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
David Henningsson012e7eb2012-08-08 08:43:37 +02007819 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K),
Takashi Iwai1d045db2011-07-07 18:23:21 +02007820 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
Ayman Bagabas0fbf21c2019-05-23 05:30:11 -04007821 SND_PCI_QUIRK(0x19e5, 0x3204, "Huawei MACH-WX9", ALC256_FIXUP_HUAWEI_MACH_WX9_PINS),
Huacai Chenf1ec5be2020-08-02 17:26:40 +08007822 SND_PCI_QUIRK(0x1b35, 0x1235, "CZC B20", ALC269_FIXUP_CZC_B20),
7823 SND_PCI_QUIRK(0x1b35, 0x1236, "CZC TMI", ALC269_FIXUP_CZC_TMI),
7824 SND_PCI_QUIRK(0x1b35, 0x1237, "CZC L101", ALC269_FIXUP_CZC_L101),
Anisse Astier02b504d2013-06-03 11:53:10 +02007825 SND_PCI_QUIRK(0x1b7d, 0xa831, "Ordissimo EVE2 ", ALC269VB_FIXUP_ORDISSIMO_EVE2), /* Also known as Malata PC-B1303 */
Hui Wang695d1ec2019-11-21 10:54:27 +08007826 SND_PCI_QUIRK(0x1d72, 0x1901, "RedmiBook 14", ALC256_FIXUP_ASUS_HEADSET_MIC),
Jan-Marek Glogowskibd9c10b2019-09-15 16:57:28 +02007827 SND_PCI_QUIRK(0x10ec, 0x118c, "Medion EE4254 MD62100", ALC256_FIXUP_MEDION_HEADSET_NO_PRESENCE),
Huacai Chenf1ec5be2020-08-02 17:26:40 +08007828 SND_PCI_QUIRK(0x1c06, 0x2013, "Lemote A1802", ALC269_FIXUP_LEMOTE_A1802),
7829 SND_PCI_QUIRK(0x1c06, 0x2015, "Lemote A190X", ALC269_FIXUP_LEMOTE_A190X),
Kai-Heng Fenge2d2fde2020-08-07 16:05:12 +08007830 SND_PCI_QUIRK(0x8086, 0x2080, "Intel NUC 8 Rugged", ALC256_FIXUP_INTEL_NUC8_RUGGED),
Takashi Iwaia4297b52011-08-23 18:40:12 +02007831
Takashi Iwaia7f3eed2012-02-16 13:03:18 +01007832#if 0
Takashi Iwaia4297b52011-08-23 18:40:12 +02007833 /* Below is a quirk table taken from the old code.
7834 * Basically the device should work as is without the fixup table.
7835 * If BIOS doesn't give a proper info, enable the corresponding
7836 * fixup entry.
Jesper Juhl7d7eb9e2012-04-12 22:11:25 +02007837 */
Takashi Iwaia4297b52011-08-23 18:40:12 +02007838 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
7839 ALC269_FIXUP_AMIC),
7840 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269_FIXUP_AMIC),
Takashi Iwaia4297b52011-08-23 18:40:12 +02007841 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269_FIXUP_AMIC),
7842 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_FIXUP_AMIC),
7843 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269_FIXUP_AMIC),
7844 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269_FIXUP_AMIC),
7845 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269_FIXUP_AMIC),
7846 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269_FIXUP_AMIC),
7847 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_FIXUP_AMIC),
7848 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269_FIXUP_AMIC),
7849 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_FIXUP_AMIC),
7850 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_FIXUP_AMIC),
7851 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_FIXUP_AMIC),
7852 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_FIXUP_AMIC),
7853 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_FIXUP_AMIC),
7854 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_FIXUP_AMIC),
7855 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_FIXUP_AMIC),
7856 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_FIXUP_AMIC),
7857 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_FIXUP_AMIC),
7858 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_FIXUP_AMIC),
7859 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_FIXUP_AMIC),
7860 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_FIXUP_AMIC),
7861 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_FIXUP_AMIC),
7862 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_FIXUP_AMIC),
7863 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_FIXUP_AMIC),
7864 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_FIXUP_AMIC),
7865 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_FIXUP_AMIC),
7866 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_FIXUP_AMIC),
7867 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_FIXUP_AMIC),
7868 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_FIXUP_AMIC),
7869 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_FIXUP_AMIC),
7870 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_FIXUP_AMIC),
7871 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_FIXUP_AMIC),
7872 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_FIXUP_AMIC),
7873 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_FIXUP_AMIC),
7874 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_FIXUP_DMIC),
7875 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_FIXUP_AMIC),
7876 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_AMIC),
7877 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_FIXUP_DMIC),
7878 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_FIXUP_DMIC),
7879#endif
7880 {}
7881};
7882
David Henningsson214eef72014-07-22 14:09:35 +02007883static const struct snd_pci_quirk alc269_fixup_vendor_tbl[] = {
7884 SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC),
7885 SND_PCI_QUIRK_VENDOR(0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED),
7886 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
7887 SND_PCI_QUIRK_VENDOR(0x17aa, "Thinkpad", ALC269_FIXUP_THINKPAD_ACPI),
Ayman Bagabas0fbf21c2019-05-23 05:30:11 -04007888 SND_PCI_QUIRK_VENDOR(0x19e5, "Huawei Matebook", ALC255_FIXUP_MIC_MUTE_LED),
David Henningsson214eef72014-07-22 14:09:35 +02007889 {}
7890};
7891
Takashi Iwai1727a772013-01-10 09:52:52 +01007892static const struct hda_model_fixup alc269_fixup_models[] = {
Takashi Iwaia4297b52011-08-23 18:40:12 +02007893 {.id = ALC269_FIXUP_AMIC, .name = "laptop-amic"},
7894 {.id = ALC269_FIXUP_DMIC, .name = "laptop-dmic"},
Takashi Iwai6e72aa52012-06-25 10:52:25 +02007895 {.id = ALC269_FIXUP_STEREO_DMIC, .name = "alc269-dmic"},
7896 {.id = ALC271_FIXUP_DMIC, .name = "alc271-dmic"},
7897 {.id = ALC269_FIXUP_INV_DMIC, .name = "inv-dmic"},
David Henningsson7c478f02013-10-11 10:18:46 +02007898 {.id = ALC269_FIXUP_HEADSET_MIC, .name = "headset-mic"},
Takashi Iwaib0169512015-05-19 10:20:13 +02007899 {.id = ALC269_FIXUP_HEADSET_MODE, .name = "headset-mode"},
7900 {.id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC, .name = "headset-mode-no-hp-mic"},
David Henningsson108cc102012-07-20 10:37:25 +02007901 {.id = ALC269_FIXUP_LENOVO_DOCK, .name = "lenovo-dock"},
Takashi Iwaib590b382020-05-14 18:05:33 +02007902 {.id = ALC269_FIXUP_LENOVO_DOCK_LIMIT_BOOST, .name = "lenovo-dock-limit-boost"},
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01007903 {.id = ALC269_FIXUP_HP_GPIO_LED, .name = "hp-gpio-led"},
Jaroslav Kysela04d54662017-03-09 13:29:13 +01007904 {.id = ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED, .name = "hp-dock-gpio-mic1-led"},
David Henningssone32aa852013-06-17 11:04:02 +02007905 {.id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "dell-headset-multi"},
7906 {.id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE, .name = "dell-headset-dock"},
Takashi Iwaia26d96c2018-06-26 15:09:25 +02007907 {.id = ALC269_FIXUP_DELL3_MIC_NO_PRESENCE, .name = "dell-headset3"},
7908 {.id = ALC269_FIXUP_DELL4_MIC_NO_PRESENCE, .name = "dell-headset4"},
Kailang Yangbe8ef162014-04-08 15:19:49 +08007909 {.id = ALC283_FIXUP_CHROME_BOOK, .name = "alc283-dac-wcaps"},
Kailang Yang0202e992013-12-02 15:20:15 +08007910 {.id = ALC283_FIXUP_SENSE_COMBO_JACK, .name = "alc283-sense-combo"},
Takashi Iwai1c37c222014-05-06 17:34:42 +02007911 {.id = ALC292_FIXUP_TPT440_DOCK, .name = "tpt440-dock"},
Takashi Iwai9a811232015-12-09 15:17:43 +01007912 {.id = ALC292_FIXUP_TPT440, .name = "tpt440"},
Sven Eckelmannc636b952016-04-11 16:55:26 +02007913 {.id = ALC292_FIXUP_TPT460, .name = "tpt460"},
Takashi Iwai399c01a2020-05-26 08:24:06 +02007914 {.id = ALC298_FIXUP_TPT470_DOCK_FIX, .name = "tpt470-dock-fix"},
Takashi Iwaia26d96c2018-06-26 15:09:25 +02007915 {.id = ALC298_FIXUP_TPT470_DOCK, .name = "tpt470-dock"},
Takashi Iwaiba90d6a2017-05-22 16:38:47 +02007916 {.id = ALC233_FIXUP_LENOVO_MULTI_CODECS, .name = "dual-codecs"},
Takashi Iwai28d1d6d2017-10-18 14:01:58 +02007917 {.id = ALC700_FIXUP_INTEL_REFERENCE, .name = "alc700-ref"},
Takashi Iwaia26d96c2018-06-26 15:09:25 +02007918 {.id = ALC269_FIXUP_SONY_VAIO, .name = "vaio"},
7919 {.id = ALC269_FIXUP_DELL_M101Z, .name = "dell-m101z"},
7920 {.id = ALC269_FIXUP_ASUS_G73JW, .name = "asus-g73jw"},
7921 {.id = ALC269_FIXUP_LENOVO_EAPD, .name = "lenovo-eapd"},
7922 {.id = ALC275_FIXUP_SONY_HWEQ, .name = "sony-hweq"},
7923 {.id = ALC269_FIXUP_PCM_44K, .name = "pcm44k"},
7924 {.id = ALC269_FIXUP_LIFEBOOK, .name = "lifebook"},
7925 {.id = ALC269_FIXUP_LIFEBOOK_EXTMIC, .name = "lifebook-extmic"},
7926 {.id = ALC269_FIXUP_LIFEBOOK_HP_PIN, .name = "lifebook-hp-pin"},
7927 {.id = ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC, .name = "lifebook-u7x7"},
7928 {.id = ALC269VB_FIXUP_AMIC, .name = "alc269vb-amic"},
7929 {.id = ALC269VB_FIXUP_DMIC, .name = "alc269vb-dmic"},
7930 {.id = ALC269_FIXUP_HP_MUTE_LED_MIC1, .name = "hp-mute-led-mic1"},
7931 {.id = ALC269_FIXUP_HP_MUTE_LED_MIC2, .name = "hp-mute-led-mic2"},
7932 {.id = ALC269_FIXUP_HP_MUTE_LED_MIC3, .name = "hp-mute-led-mic3"},
7933 {.id = ALC269_FIXUP_HP_GPIO_MIC1_LED, .name = "hp-gpio-mic1"},
7934 {.id = ALC269_FIXUP_HP_LINE1_MIC1_LED, .name = "hp-line1-mic1"},
7935 {.id = ALC269_FIXUP_NO_SHUTUP, .name = "noshutup"},
7936 {.id = ALC286_FIXUP_SONY_MIC_NO_PRESENCE, .name = "sony-nomic"},
7937 {.id = ALC269_FIXUP_ASPIRE_HEADSET_MIC, .name = "aspire-headset-mic"},
7938 {.id = ALC269_FIXUP_ASUS_X101, .name = "asus-x101"},
7939 {.id = ALC271_FIXUP_HP_GATE_MIC_JACK, .name = "acer-ao7xx"},
7940 {.id = ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572, .name = "acer-aspire-e1"},
7941 {.id = ALC269_FIXUP_ACER_AC700, .name = "acer-ac700"},
7942 {.id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST, .name = "limit-mic-boost"},
7943 {.id = ALC269VB_FIXUP_ASUS_ZENBOOK, .name = "asus-zenbook"},
7944 {.id = ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A, .name = "asus-zenbook-ux31a"},
7945 {.id = ALC269VB_FIXUP_ORDISSIMO_EVE2, .name = "ordissimo"},
7946 {.id = ALC282_FIXUP_ASUS_TX300, .name = "asus-tx300"},
7947 {.id = ALC283_FIXUP_INT_MIC, .name = "alc283-int-mic"},
7948 {.id = ALC290_FIXUP_MONO_SPEAKERS_HSJACK, .name = "mono-speakers"},
7949 {.id = ALC290_FIXUP_SUBWOOFER_HSJACK, .name = "alc290-subwoofer"},
7950 {.id = ALC269_FIXUP_THINKPAD_ACPI, .name = "thinkpad"},
7951 {.id = ALC269_FIXUP_DMIC_THINKPAD_ACPI, .name = "dmic-thinkpad"},
7952 {.id = ALC255_FIXUP_ACER_MIC_NO_PRESENCE, .name = "alc255-acer"},
7953 {.id = ALC255_FIXUP_ASUS_MIC_NO_PRESENCE, .name = "alc255-asus"},
7954 {.id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc255-dell1"},
7955 {.id = ALC255_FIXUP_DELL2_MIC_NO_PRESENCE, .name = "alc255-dell2"},
7956 {.id = ALC293_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc293-dell1"},
7957 {.id = ALC283_FIXUP_HEADSET_MIC, .name = "alc283-headset"},
Takashi Iwaib3802782018-11-26 17:47:46 +01007958 {.id = ALC255_FIXUP_MIC_MUTE_LED, .name = "alc255-dell-mute"},
Takashi Iwaia26d96c2018-06-26 15:09:25 +02007959 {.id = ALC282_FIXUP_ASPIRE_V5_PINS, .name = "aspire-v5"},
7960 {.id = ALC280_FIXUP_HP_GPIO4, .name = "hp-gpio4"},
7961 {.id = ALC286_FIXUP_HP_GPIO_LED, .name = "hp-gpio-led"},
7962 {.id = ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY, .name = "hp-gpio2-hotkey"},
7963 {.id = ALC280_FIXUP_HP_DOCK_PINS, .name = "hp-dock-pins"},
7964 {.id = ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED, .name = "hp-dock-gpio-mic"},
7965 {.id = ALC280_FIXUP_HP_9480M, .name = "hp-9480m"},
7966 {.id = ALC288_FIXUP_DELL_HEADSET_MODE, .name = "alc288-dell-headset"},
7967 {.id = ALC288_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc288-dell1"},
7968 {.id = ALC288_FIXUP_DELL_XPS_13, .name = "alc288-dell-xps13"},
7969 {.id = ALC292_FIXUP_DELL_E7X, .name = "dell-e7x"},
7970 {.id = ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK, .name = "alc293-dell"},
7971 {.id = ALC298_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc298-dell1"},
7972 {.id = ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE, .name = "alc298-dell-aio"},
7973 {.id = ALC275_FIXUP_DELL_XPS, .name = "alc275-dell-xps"},
Takashi Iwaia26d96c2018-06-26 15:09:25 +02007974 {.id = ALC293_FIXUP_LENOVO_SPK_NOISE, .name = "lenovo-spk-noise"},
7975 {.id = ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY, .name = "lenovo-hotkey"},
7976 {.id = ALC255_FIXUP_DELL_SPK_NOISE, .name = "dell-spk-noise"},
Kailang Yang82aa0d72019-01-11 17:15:53 +08007977 {.id = ALC225_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc225-dell1"},
Takashi Iwaia26d96c2018-06-26 15:09:25 +02007978 {.id = ALC295_FIXUP_DISABLE_DAC3, .name = "alc295-disable-dac3"},
Jaroslav Kyselad2cd7952019-11-29 15:40:27 +01007979 {.id = ALC285_FIXUP_SPEAKER2_TO_DAC1, .name = "alc285-speaker2-to-dac1"},
Takashi Iwaia26d96c2018-06-26 15:09:25 +02007980 {.id = ALC280_FIXUP_HP_HEADSET_MIC, .name = "alc280-hp-headset"},
7981 {.id = ALC221_FIXUP_HP_FRONT_MIC, .name = "alc221-hp-mic"},
7982 {.id = ALC298_FIXUP_SPK_VOLUME, .name = "alc298-spk-volume"},
7983 {.id = ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER, .name = "dell-inspiron-7559"},
7984 {.id = ALC269_FIXUP_ATIV_BOOK_8, .name = "ativ-book"},
7985 {.id = ALC221_FIXUP_HP_MIC_NO_PRESENCE, .name = "alc221-hp-mic"},
7986 {.id = ALC256_FIXUP_ASUS_HEADSET_MODE, .name = "alc256-asus-headset"},
7987 {.id = ALC256_FIXUP_ASUS_MIC, .name = "alc256-asus-mic"},
7988 {.id = ALC256_FIXUP_ASUS_AIO_GPIO2, .name = "alc256-asus-aio"},
7989 {.id = ALC233_FIXUP_ASUS_MIC_NO_PRESENCE, .name = "alc233-asus"},
7990 {.id = ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE, .name = "alc233-eapd"},
7991 {.id = ALC294_FIXUP_LENOVO_MIC_LOCATION, .name = "alc294-lenovo-mic"},
7992 {.id = ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE, .name = "alc225-wyse"},
7993 {.id = ALC274_FIXUP_DELL_AIO_LINEOUT_VERB, .name = "alc274-dell-aio"},
7994 {.id = ALC255_FIXUP_DUMMY_LINEOUT_VERB, .name = "alc255-dummy-lineout"},
7995 {.id = ALC255_FIXUP_DELL_HEADSET_MIC, .name = "alc255-dell-headset"},
7996 {.id = ALC295_FIXUP_HP_X360, .name = "alc295-hp-x360"},
Kailang Yang8983eb62019-04-03 15:31:49 +08007997 {.id = ALC225_FIXUP_HEADSET_JACK, .name = "alc-headset-jack"},
7998 {.id = ALC295_FIXUP_CHROME_BOOK, .name = "alc-chrome-book"},
Bernhard Rosenkraenzere2a829b2019-03-05 00:38:19 +01007999 {.id = ALC299_FIXUP_PREDATOR_SPK, .name = "predator-spk"},
Tomas Espeletaa2ef03f2019-08-09 16:37:54 +02008000 {.id = ALC298_FIXUP_HUAWEI_MBX_STEREO, .name = "huawei-mbx-stereo"},
Jan-Marek Glogowskibd9c10b2019-09-15 16:57:28 +02008001 {.id = ALC256_FIXUP_MEDION_HEADSET_NO_PRESENCE, .name = "alc256-medion-headset"},
Mike Pozulp23dc9582020-08-16 21:32:17 -07008002 {.id = ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET, .name = "alc298-samsung-headphone"},
Takashi Iwai1d045db2011-07-07 18:23:21 +02008003 {}
8004};
Kailang Yangcfc5a842016-02-03 15:20:39 +08008005#define ALC225_STANDARD_PINS \
Kailang Yangcfc5a842016-02-03 15:20:39 +08008006 {0x21, 0x04211020}
Takashi Iwai1d045db2011-07-07 18:23:21 +02008007
Hui Wange8191a82015-04-24 13:39:59 +08008008#define ALC256_STANDARD_PINS \
8009 {0x12, 0x90a60140}, \
8010 {0x14, 0x90170110}, \
Hui Wange8191a82015-04-24 13:39:59 +08008011 {0x21, 0x02211020}
8012
David Henningssonfea185e2014-09-03 10:23:04 +02008013#define ALC282_STANDARD_PINS \
Hui Wang11580292015-08-03 11:03:49 +08008014 {0x14, 0x90170110}
Kailang Yange1e62b92015-04-08 16:01:22 +08008015
David Henningssonfea185e2014-09-03 10:23:04 +02008016#define ALC290_STANDARD_PINS \
Hui Wang11580292015-08-03 11:03:49 +08008017 {0x12, 0x99a30130}
David Henningssonfea185e2014-09-03 10:23:04 +02008018
8019#define ALC292_STANDARD_PINS \
8020 {0x14, 0x90170110}, \
Hui Wang11580292015-08-03 11:03:49 +08008021 {0x15, 0x0221401f}
Kailang Yang977e6272015-05-18 15:31:20 +08008022
Hui Wang3f6409702016-09-11 11:26:16 +08008023#define ALC295_STANDARD_PINS \
8024 {0x12, 0xb7a60130}, \
8025 {0x14, 0x90170110}, \
Hui Wang3f6409702016-09-11 11:26:16 +08008026 {0x21, 0x04211020}
8027
Woodrow Shen703867e2015-08-05 12:34:12 +08008028#define ALC298_STANDARD_PINS \
8029 {0x12, 0x90a60130}, \
8030 {0x21, 0x03211020}
8031
Hui Wange1918932014-05-26 16:22:44 +08008032static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
Kailang Yang8a328ac2018-08-21 16:54:41 +08008033 SND_HDA_PIN_QUIRK(0x10ec0221, 0x103c, "HP Workstation", ALC221_FIXUP_HP_HEADSET_MIC,
8034 {0x14, 0x01014020},
8035 {0x17, 0x90170110},
8036 {0x18, 0x02a11030},
8037 {0x19, 0x0181303F},
8038 {0x21, 0x0221102f}),
Chris Chiu5824ce82017-02-28 14:17:11 -06008039 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1025, "Acer", ALC255_FIXUP_ACER_MIC_NO_PRESENCE,
8040 {0x12, 0x90a601c0},
8041 {0x14, 0x90171120},
8042 {0x21, 0x02211030}),
Chris Chiu615966a2017-02-28 14:17:12 -06008043 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1043, "ASUS", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE,
8044 {0x14, 0x90170110},
8045 {0x1b, 0x90a70130},
8046 {0x21, 0x03211020}),
8047 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1043, "ASUS", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE,
8048 {0x1a, 0x90a70130},
8049 {0x1b, 0x90170110},
8050 {0x21, 0x03211020}),
David Henningsson2ae95572016-02-25 09:37:05 +01008051 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
Kailang Yangcfc5a842016-02-03 15:20:39 +08008052 ALC225_STANDARD_PINS,
Hui Wang8a132092016-07-08 14:26:57 +08008053 {0x12, 0xb7a60130},
Kailang Yangcfc5a842016-02-03 15:20:39 +08008054 {0x14, 0x901701a0}),
David Henningsson2ae95572016-02-25 09:37:05 +01008055 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
Kailang Yangcfc5a842016-02-03 15:20:39 +08008056 ALC225_STANDARD_PINS,
Hui Wang8a132092016-07-08 14:26:57 +08008057 {0x12, 0xb7a60130},
Kailang Yangcfc5a842016-02-03 15:20:39 +08008058 {0x14, 0x901701b0}),
Hui Wang8a132092016-07-08 14:26:57 +08008059 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
8060 ALC225_STANDARD_PINS,
8061 {0x12, 0xb7a60150},
8062 {0x14, 0x901701a0}),
8063 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
8064 ALC225_STANDARD_PINS,
8065 {0x12, 0xb7a60150},
8066 {0x14, 0x901701b0}),
8067 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
8068 ALC225_STANDARD_PINS,
8069 {0x12, 0xb7a60130},
8070 {0x1b, 0x90170110}),
Kai-Heng Feng0ce48e12017-11-20 02:29:13 -05008071 SND_HDA_PIN_QUIRK(0x10ec0233, 0x8086, "Intel NUC Skull Canyon", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
8072 {0x1b, 0x01111010},
8073 {0x1e, 0x01451130},
8074 {0x21, 0x02211020}),
Hui Wang986376b2018-05-30 12:33:07 +08008075 SND_HDA_PIN_QUIRK(0x10ec0235, 0x17aa, "Lenovo", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY,
8076 {0x12, 0x90a60140},
8077 {0x14, 0x90170110},
8078 {0x19, 0x02a11030},
8079 {0x21, 0x02211020}),
Hui Wange41fc8c2018-06-25 14:40:56 +08008080 SND_HDA_PIN_QUIRK(0x10ec0235, 0x17aa, "Lenovo", ALC294_FIXUP_LENOVO_MIC_LOCATION,
8081 {0x14, 0x90170110},
8082 {0x19, 0x02a11030},
8083 {0x1a, 0x02a11040},
8084 {0x1b, 0x01014020},
8085 {0x21, 0x0221101f}),
Hui Wangc6b17f12018-07-06 15:14:11 +08008086 SND_HDA_PIN_QUIRK(0x10ec0235, 0x17aa, "Lenovo", ALC294_FIXUP_LENOVO_MIC_LOCATION,
8087 {0x14, 0x90170110},
Hui Wangd06fb562018-10-10 11:57:25 +08008088 {0x19, 0x02a11030},
8089 {0x1a, 0x02a11040},
8090 {0x1b, 0x01011020},
8091 {0x21, 0x0221101f}),
8092 SND_HDA_PIN_QUIRK(0x10ec0235, 0x17aa, "Lenovo", ALC294_FIXUP_LENOVO_MIC_LOCATION,
8093 {0x14, 0x90170110},
Hui Wangc6b17f12018-07-06 15:14:11 +08008094 {0x19, 0x02a11020},
8095 {0x1a, 0x02a11030},
8096 {0x21, 0x0221101f}),
Hui Wangc77900e2014-09-03 11:31:07 +08008097 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE,
Hui Wangc77900e2014-09-03 11:31:07 +08008098 {0x14, 0x90170110},
Hui Wangc77900e2014-09-03 11:31:07 +08008099 {0x21, 0x02211020}),
David Henningsson76c21322014-06-24 14:46:54 +02008100 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang86c72d12016-05-25 12:12:32 +08008101 {0x14, 0x90170130},
8102 {0x21, 0x02211040}),
8103 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningsson76c21322014-06-24 14:46:54 +02008104 {0x12, 0x90a60140},
8105 {0x14, 0x90170110},
David Henningsson76c21322014-06-24 14:46:54 +02008106 {0x21, 0x02211020}),
8107 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
8108 {0x12, 0x90a60160},
8109 {0x14, 0x90170120},
David Henningsson76c21322014-06-24 14:46:54 +02008110 {0x21, 0x02211030}),
8111 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang392c9da2016-09-26 10:59:38 +08008112 {0x14, 0x90170110},
8113 {0x1b, 0x02011020},
8114 {0x21, 0x0221101f}),
8115 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang6aecd872016-10-20 14:03:33 +08008116 {0x14, 0x90170110},
8117 {0x1b, 0x01011020},
8118 {0x21, 0x0221101f}),
8119 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssoncba59972015-07-22 10:00:25 +02008120 {0x14, 0x90170130},
David Henningssoncba59972015-07-22 10:00:25 +02008121 {0x1b, 0x01014020},
David Henningssoncba59972015-07-22 10:00:25 +02008122 {0x21, 0x0221103f}),
8123 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang59ec4b52016-08-04 15:28:04 +08008124 {0x14, 0x90170130},
Hui Wang6aecd872016-10-20 14:03:33 +08008125 {0x1b, 0x01011020},
8126 {0x21, 0x0221103f}),
8127 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
8128 {0x14, 0x90170130},
Hui Wang59ec4b52016-08-04 15:28:04 +08008129 {0x1b, 0x02011020},
8130 {0x21, 0x0221103f}),
8131 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Woodrow Shene9c28e12015-07-25 10:36:16 +08008132 {0x14, 0x90170150},
Woodrow Shene9c28e12015-07-25 10:36:16 +08008133 {0x1b, 0x02011020},
Woodrow Shene9c28e12015-07-25 10:36:16 +08008134 {0x21, 0x0221105f}),
8135 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Woodrow Shene9c28e12015-07-25 10:36:16 +08008136 {0x14, 0x90170110},
Woodrow Shene9c28e12015-07-25 10:36:16 +08008137 {0x1b, 0x01014020},
Woodrow Shene9c28e12015-07-25 10:36:16 +08008138 {0x21, 0x0221101f}),
8139 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningsson76c21322014-06-24 14:46:54 +02008140 {0x12, 0x90a60160},
8141 {0x14, 0x90170120},
8142 {0x17, 0x90170140},
David Henningsson76c21322014-06-24 14:46:54 +02008143 {0x21, 0x0321102f}),
8144 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
8145 {0x12, 0x90a60160},
8146 {0x14, 0x90170130},
David Henningsson76c21322014-06-24 14:46:54 +02008147 {0x21, 0x02211040}),
8148 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
8149 {0x12, 0x90a60160},
8150 {0x14, 0x90170140},
David Henningsson76c21322014-06-24 14:46:54 +02008151 {0x21, 0x02211050}),
8152 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
8153 {0x12, 0x90a60170},
8154 {0x14, 0x90170120},
David Henningsson76c21322014-06-24 14:46:54 +02008155 {0x21, 0x02211030}),
8156 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
8157 {0x12, 0x90a60170},
8158 {0x14, 0x90170130},
David Henningsson76c21322014-06-24 14:46:54 +02008159 {0x21, 0x02211040}),
Hui Wang70658b92015-03-06 14:03:57 +08008160 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang70658b92015-03-06 14:03:57 +08008161 {0x12, 0x90a60170},
Hui Wang0a1f90a2016-01-13 11:51:38 +08008162 {0x14, 0x90171130},
8163 {0x21, 0x02211040}),
8164 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
8165 {0x12, 0x90a60170},
Hui Wang70658b92015-03-06 14:03:57 +08008166 {0x14, 0x90170140},
Hui Wang70658b92015-03-06 14:03:57 +08008167 {0x21, 0x02211050}),
David Henningsson9b5a4e32015-05-11 14:04:14 +02008168 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell Inspiron 5548", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningsson9b5a4e32015-05-11 14:04:14 +02008169 {0x12, 0x90a60180},
8170 {0x14, 0x90170130},
David Henningsson9b5a4e32015-05-11 14:04:14 +02008171 {0x21, 0x02211040}),
AceLan Kaof90d83b2016-06-03 14:45:25 +08008172 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell Inspiron 5565", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
8173 {0x12, 0x90a60180},
8174 {0x14, 0x90170120},
8175 {0x21, 0x02211030}),
Hui Wang989dbe42016-11-23 16:05:38 +08008176 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
8177 {0x1b, 0x01011020},
8178 {0x21, 0x02211010}),
Chris Chiuc1732ed2017-02-28 14:17:13 -06008179 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC,
8180 {0x14, 0x90170110},
8181 {0x1b, 0x90a70130},
8182 {0x21, 0x04211020}),
8183 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC,
8184 {0x14, 0x90170110},
8185 {0x1b, 0x90a70130},
8186 {0x21, 0x03211020}),
Jian-Hong Pane1037352019-03-22 11:37:18 +08008187 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE,
Chris Chiua806ef12019-03-22 11:37:20 +08008188 {0x12, 0x90a60130},
8189 {0x14, 0x90170110},
8190 {0x21, 0x03211020}),
8191 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE,
Jian-Hong Pan6ac371a2019-03-22 11:37:22 +08008192 {0x12, 0x90a60130},
8193 {0x14, 0x90170110},
8194 {0x21, 0x04211020}),
8195 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE,
Jian-Hong Pane1037352019-03-22 11:37:18 +08008196 {0x1a, 0x90a70130},
8197 {0x1b, 0x90170110},
8198 {0x21, 0x03211020}),
David Henningssoncf51eb92014-10-30 08:26:02 +01008199 SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC280_FIXUP_HP_GPIO4,
8200 {0x12, 0x90a60130},
David Henningssoncf51eb92014-10-30 08:26:02 +01008201 {0x14, 0x90170110},
8202 {0x15, 0x0421101f},
Hui Wang11580292015-08-03 11:03:49 +08008203 {0x1a, 0x04a11020}),
Hui Wang02796612014-09-03 11:31:11 +08008204 SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED,
8205 {0x12, 0x90a60140},
Hui Wang02796612014-09-03 11:31:11 +08008206 {0x14, 0x90170110},
8207 {0x15, 0x0421101f},
Hui Wang02796612014-09-03 11:31:11 +08008208 {0x18, 0x02811030},
Hui Wang02796612014-09-03 11:31:11 +08008209 {0x1a, 0x04a1103f},
Hui Wang11580292015-08-03 11:03:49 +08008210 {0x1b, 0x02011020}),
David Henningsson42304472014-07-22 11:42:17 +02008211 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP 15 Touchsmart", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02008212 ALC282_STANDARD_PINS,
David Henningsson42304472014-07-22 11:42:17 +02008213 {0x12, 0x99a30130},
David Henningsson42304472014-07-22 11:42:17 +02008214 {0x19, 0x03a11020},
David Henningsson42304472014-07-22 11:42:17 +02008215 {0x21, 0x0321101f}),
Hui Wang2c609992014-09-03 11:31:08 +08008216 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02008217 ALC282_STANDARD_PINS,
Hui Wang2c609992014-09-03 11:31:08 +08008218 {0x12, 0x99a30130},
Hui Wang2c609992014-09-03 11:31:08 +08008219 {0x19, 0x03a11020},
Hui Wang2c609992014-09-03 11:31:08 +08008220 {0x21, 0x03211040}),
8221 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02008222 ALC282_STANDARD_PINS,
Hui Wang2c609992014-09-03 11:31:08 +08008223 {0x12, 0x99a30130},
Hui Wang2c609992014-09-03 11:31:08 +08008224 {0x19, 0x03a11030},
Hui Wang2c609992014-09-03 11:31:08 +08008225 {0x21, 0x03211020}),
8226 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02008227 ALC282_STANDARD_PINS,
Hui Wang2c609992014-09-03 11:31:08 +08008228 {0x12, 0x99a30130},
Hui Wang2c609992014-09-03 11:31:08 +08008229 {0x19, 0x04a11020},
Hui Wang2c609992014-09-03 11:31:08 +08008230 {0x21, 0x0421101f}),
Hui Wang200afc02014-09-03 11:31:10 +08008231 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED,
David Henningssonaec856d2014-09-03 10:23:05 +02008232 ALC282_STANDARD_PINS,
Hui Wang200afc02014-09-03 11:31:10 +08008233 {0x12, 0x90a60140},
Hui Wang200afc02014-09-03 11:31:10 +08008234 {0x19, 0x04a11030},
Hui Wang200afc02014-09-03 11:31:10 +08008235 {0x21, 0x04211020}),
David Henningsson76c21322014-06-24 14:46:54 +02008236 SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02008237 ALC282_STANDARD_PINS,
David Henningsson76c21322014-06-24 14:46:54 +02008238 {0x12, 0x90a60130},
David Henningsson76c21322014-06-24 14:46:54 +02008239 {0x21, 0x0321101f}),
8240 SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
8241 {0x12, 0x90a60160},
8242 {0x14, 0x90170120},
David Henningsson76c21322014-06-24 14:46:54 +02008243 {0x21, 0x02211030}),
Hui Wangbc262172014-09-03 11:31:05 +08008244 SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02008245 ALC282_STANDARD_PINS,
Hui Wangbc262172014-09-03 11:31:05 +08008246 {0x12, 0x90a60130},
Hui Wangbc262172014-09-03 11:31:05 +08008247 {0x19, 0x03a11020},
Hui Wangbc262172014-09-03 11:31:05 +08008248 {0x21, 0x0321101f}),
Hui Wangc8c6ee62019-02-14 11:41:33 +08008249 SND_HDA_PIN_QUIRK(0x10ec0285, 0x17aa, "Lenovo", ALC285_FIXUP_LENOVO_PC_BEEP_IN_NOISE,
Hui Wangc4cfcf62018-11-26 14:17:16 +08008250 {0x12, 0x90a60130},
8251 {0x14, 0x90170110},
8252 {0x19, 0x04a11040},
8253 {0x21, 0x04211020}),
Chris Chiu33aaebd2018-12-05 14:48:53 +08008254 SND_HDA_PIN_QUIRK(0x10ec0286, 0x1025, "Acer", ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE,
8255 {0x12, 0x90a60130},
8256 {0x17, 0x90170110},
8257 {0x21, 0x02211020}),
Takashi Iwaid44a6862018-06-19 23:04:03 +02008258 SND_HDA_PIN_QUIRK(0x10ec0288, 0x1028, "Dell", ALC288_FIXUP_DELL1_MIC_NO_PRESENCE,
Kailang Yange1e62b92015-04-08 16:01:22 +08008259 {0x12, 0x90a60120},
Kailang Yange1e62b92015-04-08 16:01:22 +08008260 {0x14, 0x90170110},
Kailang Yange1e62b92015-04-08 16:01:22 +08008261 {0x21, 0x0321101f}),
Hui Wange4442bc2014-09-03 11:31:09 +08008262 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02008263 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08008264 {0x15, 0x04211040},
Hui Wange4442bc2014-09-03 11:31:09 +08008265 {0x18, 0x90170112},
Hui Wang11580292015-08-03 11:03:49 +08008266 {0x1a, 0x04a11020}),
Hui Wange4442bc2014-09-03 11:31:09 +08008267 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02008268 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08008269 {0x15, 0x04211040},
Hui Wange4442bc2014-09-03 11:31:09 +08008270 {0x18, 0x90170110},
Hui Wang11580292015-08-03 11:03:49 +08008271 {0x1a, 0x04a11020}),
Hui Wange4442bc2014-09-03 11:31:09 +08008272 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02008273 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08008274 {0x15, 0x0421101f},
Hui Wang11580292015-08-03 11:03:49 +08008275 {0x1a, 0x04a11020}),
Hui Wange4442bc2014-09-03 11:31:09 +08008276 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02008277 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08008278 {0x15, 0x04211020},
Hui Wang11580292015-08-03 11:03:49 +08008279 {0x1a, 0x04a11040}),
Hui Wange4442bc2014-09-03 11:31:09 +08008280 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02008281 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08008282 {0x14, 0x90170110},
8283 {0x15, 0x04211020},
Hui Wang11580292015-08-03 11:03:49 +08008284 {0x1a, 0x04a11040}),
Hui Wange4442bc2014-09-03 11:31:09 +08008285 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02008286 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08008287 {0x14, 0x90170110},
8288 {0x15, 0x04211020},
Hui Wang11580292015-08-03 11:03:49 +08008289 {0x1a, 0x04a11020}),
Hui Wange4442bc2014-09-03 11:31:09 +08008290 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02008291 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08008292 {0x14, 0x90170110},
8293 {0x15, 0x0421101f},
Hui Wang11580292015-08-03 11:03:49 +08008294 {0x1a, 0x04a11020}),
Hui Wange8818fa2014-09-03 11:31:04 +08008295 SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02008296 ALC292_STANDARD_PINS,
Hui Wange8818fa2014-09-03 11:31:04 +08008297 {0x12, 0x90a60140},
Hui Wange8818fa2014-09-03 11:31:04 +08008298 {0x16, 0x01014020},
Hui Wang11580292015-08-03 11:03:49 +08008299 {0x19, 0x01a19030}),
Hui Wange8818fa2014-09-03 11:31:04 +08008300 SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02008301 ALC292_STANDARD_PINS,
Hui Wange8818fa2014-09-03 11:31:04 +08008302 {0x12, 0x90a60140},
Hui Wange8818fa2014-09-03 11:31:04 +08008303 {0x16, 0x01014020},
8304 {0x18, 0x02a19031},
Hui Wang11580292015-08-03 11:03:49 +08008305 {0x19, 0x01a1903e}),
David Henningsson76c21322014-06-24 14:46:54 +02008306 SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02008307 ALC292_STANDARD_PINS,
Hui Wang11580292015-08-03 11:03:49 +08008308 {0x12, 0x90a60140}),
David Henningsson76c21322014-06-24 14:46:54 +02008309 SND_HDA_PIN_QUIRK(0x10ec0293, 0x1028, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02008310 ALC292_STANDARD_PINS,
David Henningsson76c21322014-06-24 14:46:54 +02008311 {0x13, 0x90a60140},
David Henningsson76c21322014-06-24 14:46:54 +02008312 {0x16, 0x21014020},
Hui Wang11580292015-08-03 11:03:49 +08008313 {0x19, 0x21a19030}),
David Henningssone03fdbd2014-06-27 08:41:59 +02008314 SND_HDA_PIN_QUIRK(0x10ec0293, 0x1028, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02008315 ALC292_STANDARD_PINS,
Hui Wang11580292015-08-03 11:03:49 +08008316 {0x13, 0x90a60140}),
Chris Chiud8ae4582018-12-07 17:17:11 +08008317 SND_HDA_PIN_QUIRK(0x10ec0294, 0x1043, "ASUS", ALC294_FIXUP_ASUS_MIC,
8318 {0x14, 0x90170110},
8319 {0x1b, 0x90a70130},
8320 {0x21, 0x04211020}),
Jian-Hong Pan0bea4cc2018-12-07 17:17:13 +08008321 SND_HDA_PIN_QUIRK(0x10ec0294, 0x1043, "ASUS", ALC294_FIXUP_ASUS_SPK,
8322 {0x12, 0x90a60130},
8323 {0x17, 0x90170110},
Jian-Hong Pan8bb37a22019-02-21 17:00:18 +08008324 {0x21, 0x03211020}),
8325 SND_HDA_PIN_QUIRK(0x10ec0294, 0x1043, "ASUS", ALC294_FIXUP_ASUS_SPK,
8326 {0x12, 0x90a60130},
8327 {0x17, 0x90170110},
Jian-Hong Pan0bea4cc2018-12-07 17:17:13 +08008328 {0x21, 0x04211020}),
Takashi Iwai3887c262019-04-30 15:10:01 +02008329 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1043, "ASUS", ALC294_FIXUP_ASUS_SPK,
8330 {0x12, 0x90a60130},
8331 {0x17, 0x90170110},
8332 {0x21, 0x03211020}),
Chris Chiu9e433422020-05-12 14:15:24 +08008333 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1043, "ASUS", ALC295_FIXUP_ASUS_MIC_NO_PRESENCE,
Jian-Hong Panad97d662020-05-12 14:15:26 +08008334 {0x12, 0x90a60120},
8335 {0x17, 0x90170110},
8336 {0x21, 0x04211030}),
8337 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1043, "ASUS", ALC295_FIXUP_ASUS_MIC_NO_PRESENCE,
Chris Chiu9e433422020-05-12 14:15:24 +08008338 {0x12, 0x90a60130},
8339 {0x17, 0x90170110},
8340 {0x21, 0x03211020}),
8341 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1043, "ASUS", ALC295_FIXUP_ASUS_MIC_NO_PRESENCE,
8342 {0x12, 0x90a60130},
8343 {0x17, 0x90170110},
8344 {0x21, 0x03211020}),
Kailang Yangfbc57122019-07-15 10:41:50 +08008345 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
Kailang Yang0a29c572019-04-24 16:34:25 +08008346 {0x14, 0x90170110},
8347 {0x21, 0x04211020}),
Kailang Yangfbc57122019-07-15 10:41:50 +08008348 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
8349 {0x14, 0x90170110},
8350 {0x21, 0x04211030}),
Hui Wang3f6409702016-09-11 11:26:16 +08008351 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wangf771d5b2016-10-18 10:59:09 +08008352 ALC295_STANDARD_PINS,
8353 {0x17, 0x21014020},
8354 {0x18, 0x21a19030}),
8355 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
8356 ALC295_STANDARD_PINS,
8357 {0x17, 0x21014040},
8358 {0x18, 0x21a19050}),
Hui Wang3f307832017-03-23 10:00:25 +08008359 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
8360 ALC295_STANDARD_PINS),
Kailang Yang977e6272015-05-18 15:31:20 +08008361 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
Woodrow Shen703867e2015-08-05 12:34:12 +08008362 ALC298_STANDARD_PINS,
Takashi Iwai9f502ff2015-08-05 12:09:45 +02008363 {0x17, 0x90170110}),
8364 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
8365 ALC298_STANDARD_PINS,
Woodrow Shen703867e2015-08-05 12:34:12 +08008366 {0x17, 0x90170140}),
8367 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
8368 ALC298_STANDARD_PINS,
Takashi Iwai9f502ff2015-08-05 12:09:45 +02008369 {0x17, 0x90170150}),
Kai-Heng Feng9f1bc2c42017-02-16 15:26:54 +08008370 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_SPK_VOLUME,
8371 {0x12, 0xb7a60140},
8372 {0x13, 0xb7a60150},
8373 {0x17, 0x90170110},
8374 {0x1a, 0x03011020},
8375 {0x21, 0x03211030}),
James McDonnell54324222019-09-16 14:53:38 +00008376 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_ALIENWARE_MIC_NO_PRESENCE,
8377 {0x12, 0xb7a60140},
8378 {0x17, 0x90170110},
8379 {0x1a, 0x03a11030},
8380 {0x21, 0x03211020}),
Kailang Yangfcc6c872017-06-29 15:21:27 +08008381 SND_HDA_PIN_QUIRK(0x10ec0299, 0x1028, "Dell", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
8382 ALC225_STANDARD_PINS,
8383 {0x12, 0xb7a60130},
Kailang Yangfcc6c872017-06-29 15:21:27 +08008384 {0x17, 0x90170110}),
Hui Wang573fcbf2020-06-08 19:55:41 +08008385 SND_HDA_PIN_QUIRK(0x10ec0623, 0x17aa, "Lenovo", ALC283_FIXUP_HEADSET_MIC,
8386 {0x14, 0x01014010},
8387 {0x17, 0x90170120},
8388 {0x18, 0x02a11030},
8389 {0x19, 0x02a1103f},
8390 {0x21, 0x0221101f}),
Hui Wange1918932014-05-26 16:22:44 +08008391 {}
8392};
Takashi Iwai1d045db2011-07-07 18:23:21 +02008393
Hui Wang7c0a6932019-08-16 14:27:40 +08008394/* This is the fallback pin_fixup_tbl for alc269 family, to make the tbl match
8395 * more machines, don't need to match all valid pins, just need to match
8396 * all the pins defined in the tbl. Just because of this reason, it is possible
8397 * that a single machine matches multiple tbls, so there is one limitation:
8398 * at most one tbl is allowed to define for the same vendor and same codec
8399 */
8400static const struct snd_hda_pin_quirk alc269_fallback_pin_fixup_tbl[] = {
8401 SND_HDA_PIN_QUIRK(0x10ec0289, 0x1028, "Dell", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
8402 {0x19, 0x40000000},
8403 {0x1b, 0x40000000}),
Hui Wangaed8c7f2019-11-21 10:26:43 +08008404 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
8405 {0x19, 0x40000000},
8406 {0x1a, 0x40000000}),
Hui Wangd64ebdb2019-11-21 10:26:44 +08008407 SND_HDA_PIN_QUIRK(0x10ec0236, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
8408 {0x19, 0x40000000},
8409 {0x1a, 0x40000000}),
Hui Wang5815bdf2019-12-11 13:13:21 +08008410 SND_HDA_PIN_QUIRK(0x10ec0274, 0x1028, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB,
8411 {0x19, 0x40000000},
8412 {0x1a, 0x40000000}),
Hui Wang7c0a6932019-08-16 14:27:40 +08008413 {}
8414};
8415
Takashi Iwai546bb672012-03-07 08:37:19 +01008416static void alc269_fill_coef(struct hda_codec *codec)
Takashi Iwai1d045db2011-07-07 18:23:21 +02008417{
Kailang Yang526af6e2012-03-07 08:25:20 +01008418 struct alc_spec *spec = codec->spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008419 int val;
8420
Kailang Yang526af6e2012-03-07 08:25:20 +01008421 if (spec->codec_variant != ALC269_TYPE_ALC269VB)
Takashi Iwai546bb672012-03-07 08:37:19 +01008422 return;
Kailang Yang526af6e2012-03-07 08:25:20 +01008423
Takashi Iwai1bb7e432011-10-17 16:50:59 +02008424 if ((alc_get_coef0(codec) & 0x00ff) < 0x015) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02008425 alc_write_coef_idx(codec, 0xf, 0x960b);
8426 alc_write_coef_idx(codec, 0xe, 0x8817);
8427 }
8428
Takashi Iwai1bb7e432011-10-17 16:50:59 +02008429 if ((alc_get_coef0(codec) & 0x00ff) == 0x016) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02008430 alc_write_coef_idx(codec, 0xf, 0x960b);
8431 alc_write_coef_idx(codec, 0xe, 0x8814);
8432 }
8433
Takashi Iwai1bb7e432011-10-17 16:50:59 +02008434 if ((alc_get_coef0(codec) & 0x00ff) == 0x017) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02008435 /* Power up output pin */
Takashi Iwai98b24882014-08-18 13:47:50 +02008436 alc_update_coef_idx(codec, 0x04, 0, 1<<11);
Takashi Iwai1d045db2011-07-07 18:23:21 +02008437 }
8438
Takashi Iwai1bb7e432011-10-17 16:50:59 +02008439 if ((alc_get_coef0(codec) & 0x00ff) == 0x018) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02008440 val = alc_read_coef_idx(codec, 0xd);
Takashi Iwaif3ee07d2014-08-15 17:35:00 +02008441 if (val != -1 && (val & 0x0c00) >> 10 != 0x1) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02008442 /* Capless ramp up clock control */
8443 alc_write_coef_idx(codec, 0xd, val | (1<<10));
8444 }
8445 val = alc_read_coef_idx(codec, 0x17);
Takashi Iwaif3ee07d2014-08-15 17:35:00 +02008446 if (val != -1 && (val & 0x01c0) >> 6 != 0x4) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02008447 /* Class D power on reset */
8448 alc_write_coef_idx(codec, 0x17, val | (1<<7));
8449 }
8450 }
8451
Takashi Iwai98b24882014-08-18 13:47:50 +02008452 /* HP */
8453 alc_update_coef_idx(codec, 0x4, 0, 1<<11);
Takashi Iwai1d045db2011-07-07 18:23:21 +02008454}
8455
8456/*
8457 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02008458static int patch_alc269(struct hda_codec *codec)
8459{
8460 struct alc_spec *spec;
Takashi Iwai3de95172012-05-07 18:03:15 +02008461 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008462
Takashi Iwai3de95172012-05-07 18:03:15 +02008463 err = alc_alloc_spec(codec, 0x0b);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008464 if (err < 0)
Takashi Iwai3de95172012-05-07 18:03:15 +02008465 return err;
8466
8467 spec = codec->spec;
Takashi Iwai08c189f2012-12-19 15:22:24 +01008468 spec->gen.shared_mic_vref_pin = 0x18;
Kailang Yang317d9312019-05-23 14:43:04 +08008469 codec->power_save_node = 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008470
Takashi Iwai225068a2015-05-29 10:42:14 +02008471#ifdef CONFIG_PM
8472 codec->patch_ops.suspend = alc269_suspend;
8473 codec->patch_ops.resume = alc269_resume;
8474#endif
Kailang Yangc2d6af52017-06-21 14:50:54 +08008475 spec->shutup = alc_default_shutup;
8476 spec->init_hook = alc_default_init;
Takashi Iwai225068a2015-05-29 10:42:14 +02008477
Takashi Iwai7639a062015-03-03 10:07:24 +01008478 switch (codec->core.vendor_id) {
Kailang Yang065380f2013-01-10 10:25:48 +01008479 case 0x10ec0269:
Takashi Iwai1d045db2011-07-07 18:23:21 +02008480 spec->codec_variant = ALC269_TYPE_ALC269VA;
Takashi Iwai1bb7e432011-10-17 16:50:59 +02008481 switch (alc_get_coef0(codec) & 0x00f0) {
8482 case 0x0010:
Takashi Iwai5100cd02014-02-15 10:03:19 +01008483 if (codec->bus->pci &&
8484 codec->bus->pci->subsystem_vendor == 0x1025 &&
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008485 spec->cdefine.platform_type == 1)
Takashi Iwai20ca0c32011-10-17 16:00:35 +02008486 err = alc_codec_rename(codec, "ALC271X");
Takashi Iwai1d045db2011-07-07 18:23:21 +02008487 spec->codec_variant = ALC269_TYPE_ALC269VB;
Takashi Iwai1bb7e432011-10-17 16:50:59 +02008488 break;
8489 case 0x0020:
Takashi Iwai5100cd02014-02-15 10:03:19 +01008490 if (codec->bus->pci &&
8491 codec->bus->pci->subsystem_vendor == 0x17aa &&
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008492 codec->bus->pci->subsystem_device == 0x21f3)
Takashi Iwai20ca0c32011-10-17 16:00:35 +02008493 err = alc_codec_rename(codec, "ALC3202");
Takashi Iwai1d045db2011-07-07 18:23:21 +02008494 spec->codec_variant = ALC269_TYPE_ALC269VC;
Takashi Iwai1bb7e432011-10-17 16:50:59 +02008495 break;
Kailang Yangadcc70b2012-05-25 08:08:38 +02008496 case 0x0030:
8497 spec->codec_variant = ALC269_TYPE_ALC269VD;
8498 break;
Takashi Iwai1bb7e432011-10-17 16:50:59 +02008499 default:
Takashi Iwai1d045db2011-07-07 18:23:21 +02008500 alc_fix_pll_init(codec, 0x20, 0x04, 15);
Takashi Iwai1bb7e432011-10-17 16:50:59 +02008501 }
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008502 if (err < 0)
8503 goto error;
Kailang Yangc2d6af52017-06-21 14:50:54 +08008504 spec->shutup = alc269_shutup;
Takashi Iwai546bb672012-03-07 08:37:19 +01008505 spec->init_hook = alc269_fill_coef;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008506 alc269_fill_coef(codec);
Kailang Yang065380f2013-01-10 10:25:48 +01008507 break;
8508
8509 case 0x10ec0280:
8510 case 0x10ec0290:
8511 spec->codec_variant = ALC269_TYPE_ALC280;
8512 break;
8513 case 0x10ec0282:
Kailang Yang065380f2013-01-10 10:25:48 +01008514 spec->codec_variant = ALC269_TYPE_ALC282;
Kailang Yang7b5c7a02014-03-18 16:15:54 +08008515 spec->shutup = alc282_shutup;
8516 spec->init_hook = alc282_init;
Kailang Yang065380f2013-01-10 10:25:48 +01008517 break;
Kailang Yang2af02be2013-08-22 10:03:50 +02008518 case 0x10ec0233:
8519 case 0x10ec0283:
8520 spec->codec_variant = ALC269_TYPE_ALC283;
8521 spec->shutup = alc283_shutup;
8522 spec->init_hook = alc283_init;
8523 break;
Kailang Yang065380f2013-01-10 10:25:48 +01008524 case 0x10ec0284:
8525 case 0x10ec0292:
8526 spec->codec_variant = ALC269_TYPE_ALC284;
8527 break;
Kailang Yang161ebf22013-10-24 11:36:33 +02008528 case 0x10ec0293:
Kailang Yang4731d5d2017-06-30 15:22:57 +08008529 spec->codec_variant = ALC269_TYPE_ALC293;
Kailang Yang161ebf22013-10-24 11:36:33 +02008530 break;
Kailang Yang7fc7d042013-04-25 11:04:43 +02008531 case 0x10ec0286:
Kailang Yang7c665932014-04-14 15:09:44 +08008532 case 0x10ec0288:
Kailang Yang7fc7d042013-04-25 11:04:43 +02008533 spec->codec_variant = ALC269_TYPE_ALC286;
8534 break;
Kailang Yang506b62c2014-12-18 17:07:44 +08008535 case 0x10ec0298:
8536 spec->codec_variant = ALC269_TYPE_ALC298;
8537 break;
Kailang Yangea04a1d2018-04-25 15:31:52 +08008538 case 0x10ec0235:
Kailang Yang1d04c9d2013-10-24 11:35:18 +02008539 case 0x10ec0255:
8540 spec->codec_variant = ALC269_TYPE_ALC255;
Kailang Yangab3b8e52018-04-25 16:05:27 +08008541 spec->shutup = alc256_shutup;
8542 spec->init_hook = alc256_init;
Kailang Yang1d04c9d2013-10-24 11:35:18 +02008543 break;
Kailang Yang736f20a2017-10-20 15:06:34 +08008544 case 0x10ec0236:
Kailang Yang4344aec2014-12-17 17:39:05 +08008545 case 0x10ec0256:
8546 spec->codec_variant = ALC269_TYPE_ALC256;
Kailang Yang4a219ef2017-06-16 16:54:35 +08008547 spec->shutup = alc256_shutup;
8548 spec->init_hook = alc256_init;
David Henningsson7d1b6e22015-04-21 10:48:46 +02008549 spec->gen.mixer_nid = 0; /* ALC256 does not have any loopback mixer path */
Kailang Yang4344aec2014-12-17 17:39:05 +08008550 break;
Kailang Yangf429e7e2017-12-05 15:38:24 +08008551 case 0x10ec0257:
8552 spec->codec_variant = ALC269_TYPE_ALC257;
Kailang Yang88d42b22018-03-14 16:08:57 +08008553 spec->shutup = alc256_shutup;
8554 spec->init_hook = alc256_init;
Kailang Yangf429e7e2017-12-05 15:38:24 +08008555 spec->gen.mixer_nid = 0;
8556 break;
Kailang Yang0a6f0602017-06-30 16:00:48 +08008557 case 0x10ec0215:
Kailang Yang7fbdcd82020-04-23 14:18:31 +08008558 case 0x10ec0245:
Kailang Yang0a6f0602017-06-30 16:00:48 +08008559 case 0x10ec0285:
Kailang Yang630e3612020-05-27 14:10:26 +08008560 case 0x10ec0287:
Kailang Yang0a6f0602017-06-30 16:00:48 +08008561 case 0x10ec0289:
8562 spec->codec_variant = ALC269_TYPE_ALC215;
Kailang Yang1b6832be2018-01-17 15:32:03 +08008563 spec->shutup = alc225_shutup;
8564 spec->init_hook = alc225_init;
Kailang Yang0a6f0602017-06-30 16:00:48 +08008565 spec->gen.mixer_nid = 0;
8566 break;
Kailang Yang42314302016-02-03 15:03:50 +08008567 case 0x10ec0225:
Kailang Yang7d727862016-05-24 16:46:07 +08008568 case 0x10ec0295:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08008569 case 0x10ec0299:
Kailang Yang42314302016-02-03 15:03:50 +08008570 spec->codec_variant = ALC269_TYPE_ALC225;
Kailang Yangda911b12018-01-05 16:50:08 +08008571 spec->shutup = alc225_shutup;
8572 spec->init_hook = alc225_init;
Takashi Iwaic1350bf2017-12-27 09:03:45 +01008573 spec->gen.mixer_nid = 0; /* no loopback on ALC225, ALC295 and ALC299 */
Kailang Yang42314302016-02-03 15:03:50 +08008574 break;
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08008575 case 0x10ec0234:
8576 case 0x10ec0274:
8577 case 0x10ec0294:
8578 spec->codec_variant = ALC269_TYPE_ALC294;
Hui Wang532a7782017-06-26 12:30:32 +08008579 spec->gen.mixer_nid = 0; /* ALC2x4 does not have any loopback mixer path */
Kailang Yang71683c32017-06-20 16:33:50 +08008580 alc_update_coef_idx(codec, 0x6b, 0x0018, (1<<4) | (1<<3)); /* UAJ MIC Vref control by verb */
Kailang Yang693abe12019-01-29 15:38:21 +08008581 spec->init_hook = alc294_init;
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08008582 break;
Kailang Yang1078bef2018-11-08 16:36:15 +08008583 case 0x10ec0300:
8584 spec->codec_variant = ALC269_TYPE_ALC300;
8585 spec->gen.mixer_nid = 0; /* no loopback on ALC300 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02008586 break;
Kailang Yangf0778872019-10-24 15:13:32 +08008587 case 0x10ec0623:
8588 spec->codec_variant = ALC269_TYPE_ALC623;
8589 break;
Kailang Yang6fbae352016-05-30 16:44:20 +08008590 case 0x10ec0700:
8591 case 0x10ec0701:
8592 case 0x10ec0703:
Kailang Yang83629532019-05-02 16:03:26 +08008593 case 0x10ec0711:
Kailang Yang6fbae352016-05-30 16:44:20 +08008594 spec->codec_variant = ALC269_TYPE_ALC700;
8595 spec->gen.mixer_nid = 0; /* ALC700 does not have any loopback mixer path */
Kailang Yang2d7fe612017-11-22 15:21:32 +08008596 alc_update_coef_idx(codec, 0x4a, 1 << 15, 0); /* Combo jack auto trigger control */
Kailang Yang693abe12019-01-29 15:38:21 +08008597 spec->init_hook = alc294_init;
Kailang Yang6fbae352016-05-30 16:44:20 +08008598 break;
8599
Takashi Iwai1d045db2011-07-07 18:23:21 +02008600 }
8601
Kailang Yangad60d502013-06-28 12:03:01 +02008602 if (snd_hda_codec_read(codec, 0x51, 0, AC_VERB_PARAMETERS, 0) == 0x10ec5505) {
Kailang Yang97a26572013-11-29 00:35:26 -05008603 spec->has_alc5505_dsp = 1;
Kailang Yangad60d502013-06-28 12:03:01 +02008604 spec->init_hook = alc5505_dsp_init;
8605 }
8606
Takashi Iwaic9af7532019-05-10 11:01:43 +02008607 alc_pre_init(codec);
8608
Takashi Iwaiefe55732018-06-15 11:55:02 +02008609 snd_hda_pick_fixup(codec, alc269_fixup_models,
8610 alc269_fixup_tbl, alc269_fixups);
Hui Wang0fc1e442019-08-16 14:27:39 +08008611 snd_hda_pick_pin_fixup(codec, alc269_pin_fixup_tbl, alc269_fixups, true);
Hui Wang7c0a6932019-08-16 14:27:40 +08008612 snd_hda_pick_pin_fixup(codec, alc269_fallback_pin_fixup_tbl, alc269_fixups, false);
Takashi Iwaiefe55732018-06-15 11:55:02 +02008613 snd_hda_pick_fixup(codec, NULL, alc269_fixup_vendor_tbl,
8614 alc269_fixups);
8615 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
8616
8617 alc_auto_parse_customize_define(codec);
8618
8619 if (has_cdefine_beep(codec))
8620 spec->gen.beep_nid = 0x01;
8621
Takashi Iwaia4297b52011-08-23 18:40:12 +02008622 /* automatic parse from the BIOS config */
8623 err = alc269_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008624 if (err < 0)
8625 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008626
Takashi Iwaifea80fa2018-06-20 12:52:46 +02008627 if (!spec->gen.no_analog && spec->gen.beep_nid && spec->gen.mixer_nid) {
8628 err = set_beep_amp(spec, spec->gen.mixer_nid, 0x04, HDA_INPUT);
8629 if (err < 0)
8630 goto error;
8631 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02008632
Takashi Iwai1727a772013-01-10 09:52:52 +01008633 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01008634
Takashi Iwai1d045db2011-07-07 18:23:21 +02008635 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008636
8637 error:
8638 alc_free(codec);
8639 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008640}
8641
8642/*
8643 * ALC861
8644 */
8645
Takashi Iwai1d045db2011-07-07 18:23:21 +02008646static int alc861_parse_auto_config(struct hda_codec *codec)
8647{
Takashi Iwai1d045db2011-07-07 18:23:21 +02008648 static const hda_nid_t alc861_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02008649 static const hda_nid_t alc861_ssids[] = { 0x0e, 0x0f, 0x0b, 0 };
8650 return alc_parse_auto_config(codec, alc861_ignore, alc861_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02008651}
8652
Takashi Iwai1d045db2011-07-07 18:23:21 +02008653/* Pin config fixes */
8654enum {
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008655 ALC861_FIXUP_FSC_AMILO_PI1505,
8656 ALC861_FIXUP_AMP_VREF_0F,
8657 ALC861_FIXUP_NO_JACK_DETECT,
8658 ALC861_FIXUP_ASUS_A6RP,
Takashi Iwai6ddf0fd2013-11-29 12:47:34 +01008659 ALC660_FIXUP_ASUS_W7J,
Takashi Iwai1d045db2011-07-07 18:23:21 +02008660};
8661
Takashi Iwai31150f22012-01-30 10:54:08 +01008662/* On some laptops, VREF of pin 0x0f is abused for controlling the main amp */
8663static void alc861_fixup_asus_amp_vref_0f(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01008664 const struct hda_fixup *fix, int action)
Takashi Iwai31150f22012-01-30 10:54:08 +01008665{
8666 struct alc_spec *spec = codec->spec;
8667 unsigned int val;
8668
Takashi Iwai1727a772013-01-10 09:52:52 +01008669 if (action != HDA_FIXUP_ACT_INIT)
Takashi Iwai31150f22012-01-30 10:54:08 +01008670 return;
Takashi Iwaid3f02d62013-01-10 10:12:22 +01008671 val = snd_hda_codec_get_pin_target(codec, 0x0f);
Takashi Iwai31150f22012-01-30 10:54:08 +01008672 if (!(val & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN)))
8673 val |= AC_PINCTL_IN_EN;
8674 val |= AC_PINCTL_VREF_50;
Takashi Iwaicdd03ce2012-04-20 12:34:50 +02008675 snd_hda_set_pin_ctl(codec, 0x0f, val);
Takashi Iwai08c189f2012-12-19 15:22:24 +01008676 spec->gen.keep_vref_in_automute = 1;
Takashi Iwai31150f22012-01-30 10:54:08 +01008677}
8678
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008679/* suppress the jack-detection */
8680static void alc_fixup_no_jack_detect(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01008681 const struct hda_fixup *fix, int action)
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008682{
Takashi Iwai1727a772013-01-10 09:52:52 +01008683 if (action == HDA_FIXUP_ACT_PRE_PROBE)
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008684 codec->no_jack_detect = 1;
Jesper Juhl7d7eb9e2012-04-12 22:11:25 +02008685}
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008686
Takashi Iwai1727a772013-01-10 09:52:52 +01008687static const struct hda_fixup alc861_fixups[] = {
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008688 [ALC861_FIXUP_FSC_AMILO_PI1505] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008689 .type = HDA_FIXUP_PINS,
8690 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02008691 { 0x0b, 0x0221101f }, /* HP */
8692 { 0x0f, 0x90170310 }, /* speaker */
8693 { }
8694 }
8695 },
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008696 [ALC861_FIXUP_AMP_VREF_0F] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008697 .type = HDA_FIXUP_FUNC,
Takashi Iwai31150f22012-01-30 10:54:08 +01008698 .v.func = alc861_fixup_asus_amp_vref_0f,
Takashi Iwai3b25eb62012-01-25 09:55:46 +01008699 },
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008700 [ALC861_FIXUP_NO_JACK_DETECT] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008701 .type = HDA_FIXUP_FUNC,
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008702 .v.func = alc_fixup_no_jack_detect,
8703 },
8704 [ALC861_FIXUP_ASUS_A6RP] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008705 .type = HDA_FIXUP_FUNC,
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008706 .v.func = alc861_fixup_asus_amp_vref_0f,
8707 .chained = true,
8708 .chain_id = ALC861_FIXUP_NO_JACK_DETECT,
Takashi Iwai6ddf0fd2013-11-29 12:47:34 +01008709 },
8710 [ALC660_FIXUP_ASUS_W7J] = {
8711 .type = HDA_FIXUP_VERBS,
8712 .v.verbs = (const struct hda_verb[]) {
8713 /* ASUS W7J needs a magic pin setup on unused NID 0x10
8714 * for enabling outputs
8715 */
8716 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8717 { }
8718 },
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008719 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02008720};
8721
8722static const struct snd_pci_quirk alc861_fixup_tbl[] = {
Takashi Iwai6ddf0fd2013-11-29 12:47:34 +01008723 SND_PCI_QUIRK(0x1043, 0x1253, "ASUS W7J", ALC660_FIXUP_ASUS_W7J),
Takashi Iwaie7ca2372013-12-02 15:27:19 +01008724 SND_PCI_QUIRK(0x1043, 0x1263, "ASUS Z35HL", ALC660_FIXUP_ASUS_W7J),
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008725 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS A6Rp", ALC861_FIXUP_ASUS_A6RP),
8726 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", ALC861_FIXUP_AMP_VREF_0F),
8727 SND_PCI_QUIRK(0x1462, 0x7254, "HP DX2200", ALC861_FIXUP_NO_JACK_DETECT),
8728 SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", ALC861_FIXUP_AMP_VREF_0F),
8729 SND_PCI_QUIRK(0x1584, 0x0000, "Uniwill ECS M31EI", ALC861_FIXUP_AMP_VREF_0F),
8730 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", ALC861_FIXUP_FSC_AMILO_PI1505),
Takashi Iwai1d045db2011-07-07 18:23:21 +02008731 {}
8732};
8733
8734/*
8735 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02008736static int patch_alc861(struct hda_codec *codec)
8737{
8738 struct alc_spec *spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008739 int err;
8740
Takashi Iwai3de95172012-05-07 18:03:15 +02008741 err = alc_alloc_spec(codec, 0x15);
8742 if (err < 0)
8743 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008744
Takashi Iwai3de95172012-05-07 18:03:15 +02008745 spec = codec->spec;
Takashi Iwai2722b532019-08-22 09:55:37 +02008746 if (has_cdefine_beep(codec))
8747 spec->gen.beep_nid = 0x23;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008748
Takashi Iwai225068a2015-05-29 10:42:14 +02008749#ifdef CONFIG_PM
8750 spec->power_hook = alc_power_eapd;
8751#endif
8752
Takashi Iwaic9af7532019-05-10 11:01:43 +02008753 alc_pre_init(codec);
8754
Takashi Iwai1727a772013-01-10 09:52:52 +01008755 snd_hda_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
8756 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02008757
Takashi Iwaicb4e4822011-08-23 17:34:25 +02008758 /* automatic parse from the BIOS config */
8759 err = alc861_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008760 if (err < 0)
8761 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008762
Takashi Iwaifea80fa2018-06-20 12:52:46 +02008763 if (!spec->gen.no_analog) {
8764 err = set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
8765 if (err < 0)
8766 goto error;
8767 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02008768
Takashi Iwai1727a772013-01-10 09:52:52 +01008769 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01008770
Takashi Iwai1d045db2011-07-07 18:23:21 +02008771 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008772
8773 error:
8774 alc_free(codec);
8775 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008776}
8777
8778/*
8779 * ALC861-VD support
8780 *
8781 * Based on ALC882
8782 *
8783 * In addition, an independent DAC
8784 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02008785static int alc861vd_parse_auto_config(struct hda_codec *codec)
8786{
Takashi Iwai1d045db2011-07-07 18:23:21 +02008787 static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02008788 static const hda_nid_t alc861vd_ssids[] = { 0x15, 0x1b, 0x14, 0 };
8789 return alc_parse_auto_config(codec, alc861vd_ignore, alc861vd_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02008790}
8791
Takashi Iwai1d045db2011-07-07 18:23:21 +02008792enum {
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008793 ALC660VD_FIX_ASUS_GPIO1,
8794 ALC861VD_FIX_DALLAS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02008795};
8796
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008797/* exclude VREF80 */
8798static void alc861vd_fixup_dallas(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01008799 const struct hda_fixup *fix, int action)
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008800{
Takashi Iwai1727a772013-01-10 09:52:52 +01008801 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwaib78562b2012-12-17 20:06:49 +01008802 snd_hda_override_pin_caps(codec, 0x18, 0x00000734);
8803 snd_hda_override_pin_caps(codec, 0x19, 0x0000073c);
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008804 }
8805}
8806
Takashi Iwaidf73d832018-06-19 23:05:47 +02008807/* reset GPIO1 */
8808static void alc660vd_fixup_asus_gpio1(struct hda_codec *codec,
8809 const struct hda_fixup *fix, int action)
8810{
8811 struct alc_spec *spec = codec->spec;
8812
8813 if (action == HDA_FIXUP_ACT_PRE_PROBE)
8814 spec->gpio_mask |= 0x02;
8815 alc_fixup_gpio(codec, action, 0x01);
8816}
8817
Takashi Iwai1727a772013-01-10 09:52:52 +01008818static const struct hda_fixup alc861vd_fixups[] = {
Takashi Iwai1d045db2011-07-07 18:23:21 +02008819 [ALC660VD_FIX_ASUS_GPIO1] = {
Takashi Iwaidf73d832018-06-19 23:05:47 +02008820 .type = HDA_FIXUP_FUNC,
8821 .v.func = alc660vd_fixup_asus_gpio1,
Takashi Iwai1d045db2011-07-07 18:23:21 +02008822 },
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008823 [ALC861VD_FIX_DALLAS] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008824 .type = HDA_FIXUP_FUNC,
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008825 .v.func = alc861vd_fixup_dallas,
8826 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02008827};
8828
8829static const struct snd_pci_quirk alc861vd_fixup_tbl[] = {
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008830 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_FIX_DALLAS),
Takashi Iwai1d045db2011-07-07 18:23:21 +02008831 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008832 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_FIX_DALLAS),
Takashi Iwai1d045db2011-07-07 18:23:21 +02008833 {}
8834};
8835
Takashi Iwai1d045db2011-07-07 18:23:21 +02008836/*
8837 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02008838static int patch_alc861vd(struct hda_codec *codec)
8839{
8840 struct alc_spec *spec;
Takashi Iwaicb4e4822011-08-23 17:34:25 +02008841 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008842
Takashi Iwai3de95172012-05-07 18:03:15 +02008843 err = alc_alloc_spec(codec, 0x0b);
8844 if (err < 0)
8845 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008846
Takashi Iwai3de95172012-05-07 18:03:15 +02008847 spec = codec->spec;
Takashi Iwai2722b532019-08-22 09:55:37 +02008848 if (has_cdefine_beep(codec))
8849 spec->gen.beep_nid = 0x23;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008850
Takashi Iwai225068a2015-05-29 10:42:14 +02008851 spec->shutup = alc_eapd_shutup;
8852
Takashi Iwaic9af7532019-05-10 11:01:43 +02008853 alc_pre_init(codec);
8854
Takashi Iwai1727a772013-01-10 09:52:52 +01008855 snd_hda_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
8856 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02008857
Takashi Iwaicb4e4822011-08-23 17:34:25 +02008858 /* automatic parse from the BIOS config */
8859 err = alc861vd_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008860 if (err < 0)
8861 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008862
Takashi Iwaifea80fa2018-06-20 12:52:46 +02008863 if (!spec->gen.no_analog) {
8864 err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
8865 if (err < 0)
8866 goto error;
8867 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02008868
Takashi Iwai1727a772013-01-10 09:52:52 +01008869 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01008870
Takashi Iwai1d045db2011-07-07 18:23:21 +02008871 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008872
8873 error:
8874 alc_free(codec);
8875 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008876}
8877
8878/*
8879 * ALC662 support
8880 *
8881 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
8882 * configuration. Each pin widget can choose any input DACs and a mixer.
8883 * Each ADC is connected from a mixer of all inputs. This makes possible
8884 * 6-channel independent captures.
8885 *
8886 * In addition, an independent DAC for the multi-playback (not used in this
8887 * driver yet).
8888 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02008889
8890/*
8891 * BIOS auto configuration
8892 */
8893
Kailang Yangbc9f98a2007-04-12 13:06:07 +02008894static int alc662_parse_auto_config(struct hda_codec *codec)
8895{
Takashi Iwai4c6d72d2011-05-02 11:30:18 +02008896 static const hda_nid_t alc662_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02008897 static const hda_nid_t alc663_ssids[] = { 0x15, 0x1b, 0x14, 0x21 };
8898 static const hda_nid_t alc662_ssids[] = { 0x15, 0x1b, 0x14, 0 };
8899 const hda_nid_t *ssids;
Takashi Iwaiee979a142008-09-02 15:42:20 +02008900
Takashi Iwai7639a062015-03-03 10:07:24 +01008901 if (codec->core.vendor_id == 0x10ec0272 || codec->core.vendor_id == 0x10ec0663 ||
8902 codec->core.vendor_id == 0x10ec0665 || codec->core.vendor_id == 0x10ec0670 ||
8903 codec->core.vendor_id == 0x10ec0671)
Takashi Iwai3e6179b2011-07-08 16:55:13 +02008904 ssids = alc663_ssids;
Kailang Yang6227cdc2010-02-25 08:36:52 +01008905 else
Takashi Iwai3e6179b2011-07-08 16:55:13 +02008906 ssids = alc662_ssids;
8907 return alc_parse_auto_config(codec, alc662_ignore, ssids);
Kailang Yangbc9f98a2007-04-12 13:06:07 +02008908}
8909
Todd Broch6be79482010-12-07 16:51:05 -08008910static void alc272_fixup_mario(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01008911 const struct hda_fixup *fix, int action)
Takashi Iwai6fc398c2011-01-13 14:36:37 +01008912{
Takashi Iwai9bb1f062013-01-10 17:14:29 +01008913 if (action != HDA_FIXUP_ACT_PRE_PROBE)
Takashi Iwai6fc398c2011-01-13 14:36:37 +01008914 return;
Todd Broch6be79482010-12-07 16:51:05 -08008915 if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT,
8916 (0x3b << AC_AMPCAP_OFFSET_SHIFT) |
8917 (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) |
8918 (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) |
8919 (0 << AC_AMPCAP_MUTE_SHIFT)))
Takashi Iwai4e76a882014-02-25 12:21:03 +01008920 codec_warn(codec, "failed to override amp caps for NID 0x2\n");
Todd Broch6be79482010-12-07 16:51:05 -08008921}
8922
Takashi Iwai8e383952013-10-30 17:41:12 +01008923static const struct snd_pcm_chmap_elem asus_pcm_2_1_chmaps[] = {
8924 { .channels = 2,
8925 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } },
8926 { .channels = 4,
8927 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR,
8928 SNDRV_CHMAP_NA, SNDRV_CHMAP_LFE } }, /* LFE only on right */
8929 { }
8930};
8931
8932/* override the 2.1 chmap */
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01008933static void alc_fixup_bass_chmap(struct hda_codec *codec,
Takashi Iwai8e383952013-10-30 17:41:12 +01008934 const struct hda_fixup *fix, int action)
8935{
8936 if (action == HDA_FIXUP_ACT_BUILD) {
8937 struct alc_spec *spec = codec->spec;
Takashi Iwaibbbc7e82015-02-27 17:43:19 +01008938 spec->gen.pcm_rec[0]->stream[0].chmap = asus_pcm_2_1_chmaps;
Takashi Iwai8e383952013-10-30 17:41:12 +01008939 }
8940}
8941
Takashi Iwaibf686652014-01-13 16:18:25 +01008942/* avoid D3 for keeping GPIO up */
8943static unsigned int gpio_led_power_filter(struct hda_codec *codec,
8944 hda_nid_t nid,
8945 unsigned int power_state)
8946{
8947 struct alc_spec *spec = codec->spec;
Takashi Iwaid261eec2018-06-19 22:32:29 +02008948 if (nid == codec->core.afg && power_state == AC_PWRST_D3 && spec->gpio_data)
Takashi Iwaibf686652014-01-13 16:18:25 +01008949 return AC_PWRST_D0;
8950 return power_state;
8951}
8952
Takashi Iwai3e887f32014-01-10 17:50:58 +01008953static void alc662_fixup_led_gpio1(struct hda_codec *codec,
8954 const struct hda_fixup *fix, int action)
8955{
8956 struct alc_spec *spec = codec->spec;
Takashi Iwai3e887f32014-01-10 17:50:58 +01008957
Takashi Iwai01e4a272018-06-19 22:47:30 +02008958 alc_fixup_hp_gpio_led(codec, action, 0x01, 0);
Takashi Iwai3e887f32014-01-10 17:50:58 +01008959 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai0f32fd192014-11-19 12:16:14 +01008960 spec->mute_led_polarity = 1;
Takashi Iwaibf686652014-01-13 16:18:25 +01008961 codec->power_filter = gpio_led_power_filter;
Takashi Iwai3e887f32014-01-10 17:50:58 +01008962 }
8963}
8964
Kailang Yangc6790c82016-11-25 16:15:17 +08008965static void alc662_usi_automute_hook(struct hda_codec *codec,
8966 struct hda_jack_callback *jack)
8967{
8968 struct alc_spec *spec = codec->spec;
8969 int vref;
8970 msleep(200);
8971 snd_hda_gen_hp_automute(codec, jack);
8972
8973 vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0;
8974 msleep(100);
8975 snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8976 vref);
8977}
8978
8979static void alc662_fixup_usi_headset_mic(struct hda_codec *codec,
8980 const struct hda_fixup *fix, int action)
8981{
8982 struct alc_spec *spec = codec->spec;
8983 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
8984 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
8985 spec->gen.hp_automute_hook = alc662_usi_automute_hook;
8986 }
8987}
8988
Sergey Bostandzhyan00066e92019-09-06 11:33:43 +02008989static void alc662_aspire_ethos_mute_speakers(struct hda_codec *codec,
8990 struct hda_jack_callback *cb)
8991{
8992 /* surround speakers at 0x1b already get muted automatically when
8993 * headphones are plugged in, but we have to mute/unmute the remaining
8994 * channels manually:
8995 * 0x15 - front left/front right
8996 * 0x18 - front center/ LFE
8997 */
8998 if (snd_hda_jack_detect_state(codec, 0x1b) == HDA_JACK_PRESENT) {
8999 snd_hda_set_pin_ctl_cache(codec, 0x15, 0);
9000 snd_hda_set_pin_ctl_cache(codec, 0x18, 0);
9001 } else {
9002 snd_hda_set_pin_ctl_cache(codec, 0x15, PIN_OUT);
9003 snd_hda_set_pin_ctl_cache(codec, 0x18, PIN_OUT);
9004 }
9005}
9006
9007static void alc662_fixup_aspire_ethos_hp(struct hda_codec *codec,
9008 const struct hda_fixup *fix, int action)
9009{
9010 /* Pin 0x1b: shared headphones jack and surround speakers */
9011 if (!is_jack_detectable(codec, 0x1b))
9012 return;
9013
9014 switch (action) {
9015 case HDA_FIXUP_ACT_PRE_PROBE:
9016 snd_hda_jack_detect_enable_callback(codec, 0x1b,
9017 alc662_aspire_ethos_mute_speakers);
Takashi Iwai336820c2019-11-28 21:26:30 +01009018 /* subwoofer needs an extra GPIO setting to become audible */
9019 alc_setup_gpio(codec, 0x02);
Sergey Bostandzhyan00066e92019-09-06 11:33:43 +02009020 break;
9021 case HDA_FIXUP_ACT_INIT:
9022 /* Make sure to start in a correct state, i.e. if
9023 * headphones have been plugged in before powering up the system
9024 */
9025 alc662_aspire_ethos_mute_speakers(codec, NULL);
9026 break;
9027 }
9028}
9029
Kailang Yang5af290282020-01-17 14:04:01 +08009030static void alc671_fixup_hp_headset_mic2(struct hda_codec *codec,
9031 const struct hda_fixup *fix, int action)
9032{
9033 struct alc_spec *spec = codec->spec;
9034
9035 static const struct hda_pintbl pincfgs[] = {
9036 { 0x19, 0x02a11040 }, /* use as headset mic, with its own jack detect */
9037 { 0x1b, 0x0181304f },
9038 { }
9039 };
9040
9041 switch (action) {
9042 case HDA_FIXUP_ACT_PRE_PROBE:
9043 spec->gen.mixer_nid = 0;
9044 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
9045 snd_hda_apply_pincfgs(codec, pincfgs);
9046 break;
9047 case HDA_FIXUP_ACT_INIT:
9048 alc_write_coef_idx(codec, 0x19, 0xa054);
9049 break;
9050 }
9051}
9052
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01009053static const struct coef_fw alc668_coefs[] = {
Kailang Yangf3f91852014-10-24 15:43:46 +08009054 WRITE_COEF(0x01, 0xbebe), WRITE_COEF(0x02, 0xaaaa), WRITE_COEF(0x03, 0x0),
9055 WRITE_COEF(0x04, 0x0180), WRITE_COEF(0x06, 0x0), WRITE_COEF(0x07, 0x0f80),
9056 WRITE_COEF(0x08, 0x0031), WRITE_COEF(0x0a, 0x0060), WRITE_COEF(0x0b, 0x0),
9057 WRITE_COEF(0x0c, 0x7cf7), WRITE_COEF(0x0d, 0x1080), WRITE_COEF(0x0e, 0x7f7f),
9058 WRITE_COEF(0x0f, 0xcccc), WRITE_COEF(0x10, 0xddcc), WRITE_COEF(0x11, 0x0001),
9059 WRITE_COEF(0x13, 0x0), WRITE_COEF(0x14, 0x2aa0), WRITE_COEF(0x17, 0xa940),
9060 WRITE_COEF(0x19, 0x0), WRITE_COEF(0x1a, 0x0), WRITE_COEF(0x1b, 0x0),
9061 WRITE_COEF(0x1c, 0x0), WRITE_COEF(0x1d, 0x0), WRITE_COEF(0x1e, 0x7418),
9062 WRITE_COEF(0x1f, 0x0804), WRITE_COEF(0x20, 0x4200), WRITE_COEF(0x21, 0x0468),
9063 WRITE_COEF(0x22, 0x8ccc), WRITE_COEF(0x23, 0x0250), WRITE_COEF(0x24, 0x7418),
9064 WRITE_COEF(0x27, 0x0), WRITE_COEF(0x28, 0x8ccc), WRITE_COEF(0x2a, 0xff00),
9065 WRITE_COEF(0x2b, 0x8000), WRITE_COEF(0xa7, 0xff00), WRITE_COEF(0xa8, 0x8000),
9066 WRITE_COEF(0xaa, 0x2e17), WRITE_COEF(0xab, 0xa0c0), WRITE_COEF(0xac, 0x0),
9067 WRITE_COEF(0xad, 0x0), WRITE_COEF(0xae, 0x2ac6), WRITE_COEF(0xaf, 0xa480),
9068 WRITE_COEF(0xb0, 0x0), WRITE_COEF(0xb1, 0x0), WRITE_COEF(0xb2, 0x0),
9069 WRITE_COEF(0xb3, 0x0), WRITE_COEF(0xb4, 0x0), WRITE_COEF(0xb5, 0x1040),
9070 WRITE_COEF(0xb6, 0xd697), WRITE_COEF(0xb7, 0x902b), WRITE_COEF(0xb8, 0xd697),
9071 WRITE_COEF(0xb9, 0x902b), WRITE_COEF(0xba, 0xb8ba), WRITE_COEF(0xbb, 0xaaab),
9072 WRITE_COEF(0xbc, 0xaaaf), WRITE_COEF(0xbd, 0x6aaa), WRITE_COEF(0xbe, 0x1c02),
9073 WRITE_COEF(0xc0, 0x00ff), WRITE_COEF(0xc1, 0x0fa6),
9074 {}
9075};
9076
9077static void alc668_restore_default_value(struct hda_codec *codec)
9078{
9079 alc_process_coef_fw(codec, alc668_coefs);
9080}
9081
David Henningsson6cb3b702010-09-09 08:51:44 +02009082enum {
Daniel T Chen2df03512010-10-10 22:39:28 -04009083 ALC662_FIXUP_ASPIRE,
Takashi Iwai3e887f32014-01-10 17:50:58 +01009084 ALC662_FIXUP_LED_GPIO1,
David Henningsson6cb3b702010-09-09 08:51:44 +02009085 ALC662_FIXUP_IDEAPAD,
Todd Broch6be79482010-12-07 16:51:05 -08009086 ALC272_FIXUP_MARIO,
Huacai Chenf1ec5be2020-08-02 17:26:40 +08009087 ALC662_FIXUP_CZC_ET26,
Anisse Astierd2ebd472011-01-20 12:36:21 +01009088 ALC662_FIXUP_CZC_P10T,
David Henningsson94024cd2011-04-29 14:10:55 +02009089 ALC662_FIXUP_SKU_IGNORE,
Takashi Iwaie59ea3e2011-06-29 17:21:00 +02009090 ALC662_FIXUP_HP_RP5800,
Takashi Iwai53c334a2011-08-23 18:27:14 +02009091 ALC662_FIXUP_ASUS_MODE1,
9092 ALC662_FIXUP_ASUS_MODE2,
9093 ALC662_FIXUP_ASUS_MODE3,
9094 ALC662_FIXUP_ASUS_MODE4,
9095 ALC662_FIXUP_ASUS_MODE5,
9096 ALC662_FIXUP_ASUS_MODE6,
9097 ALC662_FIXUP_ASUS_MODE7,
9098 ALC662_FIXUP_ASUS_MODE8,
Takashi Iwai1565cc32012-02-13 12:03:25 +01009099 ALC662_FIXUP_NO_JACK_DETECT,
David Henningssonedfe3bf2012-06-12 13:15:12 +02009100 ALC662_FIXUP_ZOTAC_Z68,
Takashi Iwai125821a2012-06-22 14:30:29 +02009101 ALC662_FIXUP_INV_DMIC,
David Henningsson1f8b46c2015-05-12 14:38:15 +02009102 ALC662_FIXUP_DELL_MIC_NO_PRESENCE,
David Henningsson73bdd592013-04-15 15:44:14 +02009103 ALC668_FIXUP_DELL_MIC_NO_PRESENCE,
David Henningsson1f8b46c2015-05-12 14:38:15 +02009104 ALC662_FIXUP_HEADSET_MODE,
David Henningsson73bdd592013-04-15 15:44:14 +02009105 ALC668_FIXUP_HEADSET_MODE,
David Henningsson8e54b4a2014-02-07 09:31:07 +01009106 ALC662_FIXUP_BASS_MODE4_CHMAP,
David Henningsson61a75f12014-02-07 09:31:08 +01009107 ALC662_FIXUP_BASS_16,
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01009108 ALC662_FIXUP_BASS_1A,
David Henningsson8e54b4a2014-02-07 09:31:07 +01009109 ALC662_FIXUP_BASS_CHMAP,
Hui Wang493a52a2014-01-14 14:07:36 +08009110 ALC668_FIXUP_AUTO_MUTE,
Gabriele Mazzotta5e6db662014-05-20 18:58:26 +02009111 ALC668_FIXUP_DELL_DISABLE_AAMIX,
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02009112 ALC668_FIXUP_DELL_XPS13,
Bobi Mihalca9d4dc582016-03-23 13:26:11 +02009113 ALC662_FIXUP_ASUS_Nx50,
Mikhail Paulyshkafc7438b2017-04-21 08:52:42 +02009114 ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE,
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07009115 ALC668_FIXUP_ASUS_Nx51,
Takashi Iwai5b7c5e12018-10-09 14:20:17 +02009116 ALC668_FIXUP_MIC_COEF,
Takashi Iwai11ba6112018-10-07 09:44:17 +02009117 ALC668_FIXUP_ASUS_G751,
Kailang Yang78f4f7c2016-06-07 11:31:34 +08009118 ALC891_FIXUP_HEADSET_MODE,
9119 ALC891_FIXUP_DELL_MIC_NO_PRESENCE,
Shrirang Bagul9b51fe32016-08-01 13:16:17 +08009120 ALC662_FIXUP_ACER_VERITON,
Takashi Iwai1a3f0992016-10-20 12:14:51 +02009121 ALC892_FIXUP_ASROCK_MOBO,
Kailang Yangc6790c82016-11-25 16:15:17 +08009122 ALC662_FIXUP_USI_FUNC,
9123 ALC662_FIXUP_USI_HEADSET_MODE,
Kailang Yangca169cc2017-04-25 16:17:40 +08009124 ALC662_FIXUP_LENOVO_MULTI_CODECS,
Sergey Bostandzhyan00066e92019-09-06 11:33:43 +02009125 ALC669_FIXUP_ACER_ASPIRE_ETHOS,
Sergey Bostandzhyan00066e92019-09-06 11:33:43 +02009126 ALC669_FIXUP_ACER_ASPIRE_ETHOS_HEADSET,
Kailang Yang5af290282020-01-17 14:04:01 +08009127 ALC671_FIXUP_HP_HEADSET_MIC2,
Jian-Hong Pand858c702020-03-17 16:28:07 +08009128 ALC662_FIXUP_ACER_X2660G_HEADSET_MODE,
Jian-Hong Pana1244582020-03-17 16:28:09 +08009129 ALC662_FIXUP_ACER_NITRO_HEADSET_MODE,
David Henningsson6cb3b702010-09-09 08:51:44 +02009130};
9131
Takashi Iwai1727a772013-01-10 09:52:52 +01009132static const struct hda_fixup alc662_fixups[] = {
Daniel T Chen2df03512010-10-10 22:39:28 -04009133 [ALC662_FIXUP_ASPIRE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01009134 .type = HDA_FIXUP_PINS,
9135 .v.pins = (const struct hda_pintbl[]) {
Daniel T Chen2df03512010-10-10 22:39:28 -04009136 { 0x15, 0x99130112 }, /* subwoofer */
9137 { }
9138 }
9139 },
Takashi Iwai3e887f32014-01-10 17:50:58 +01009140 [ALC662_FIXUP_LED_GPIO1] = {
9141 .type = HDA_FIXUP_FUNC,
9142 .v.func = alc662_fixup_led_gpio1,
9143 },
David Henningsson6cb3b702010-09-09 08:51:44 +02009144 [ALC662_FIXUP_IDEAPAD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01009145 .type = HDA_FIXUP_PINS,
9146 .v.pins = (const struct hda_pintbl[]) {
David Henningsson6cb3b702010-09-09 08:51:44 +02009147 { 0x17, 0x99130112 }, /* subwoofer */
9148 { }
Takashi Iwai3e887f32014-01-10 17:50:58 +01009149 },
9150 .chained = true,
9151 .chain_id = ALC662_FIXUP_LED_GPIO1,
David Henningsson6cb3b702010-09-09 08:51:44 +02009152 },
Todd Broch6be79482010-12-07 16:51:05 -08009153 [ALC272_FIXUP_MARIO] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01009154 .type = HDA_FIXUP_FUNC,
Takashi Iwaib5bfbc62011-01-13 14:22:32 +01009155 .v.func = alc272_fixup_mario,
Anisse Astierd2ebd472011-01-20 12:36:21 +01009156 },
Huacai Chenf1ec5be2020-08-02 17:26:40 +08009157 [ALC662_FIXUP_CZC_ET26] = {
9158 .type = HDA_FIXUP_PINS,
9159 .v.pins = (const struct hda_pintbl[]) {
9160 {0x12, 0x403cc000},
9161 {0x14, 0x90170110}, /* speaker */
9162 {0x15, 0x411111f0},
9163 {0x16, 0x411111f0},
9164 {0x18, 0x01a19030}, /* mic */
9165 {0x19, 0x90a7013f}, /* int-mic */
9166 {0x1a, 0x01014020},
9167 {0x1b, 0x0121401f},
9168 {0x1c, 0x411111f0},
9169 {0x1d, 0x411111f0},
9170 {0x1e, 0x40478e35},
9171 {}
9172 },
9173 .chained = true,
9174 .chain_id = ALC662_FIXUP_SKU_IGNORE
9175 },
Anisse Astierd2ebd472011-01-20 12:36:21 +01009176 [ALC662_FIXUP_CZC_P10T] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01009177 .type = HDA_FIXUP_VERBS,
Anisse Astierd2ebd472011-01-20 12:36:21 +01009178 .v.verbs = (const struct hda_verb[]) {
9179 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
9180 {}
9181 }
9182 },
David Henningsson94024cd2011-04-29 14:10:55 +02009183 [ALC662_FIXUP_SKU_IGNORE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01009184 .type = HDA_FIXUP_FUNC,
Takashi Iwai23d30f22012-05-07 17:17:32 +02009185 .v.func = alc_fixup_sku_ignore,
Takashi Iwaic6b35872011-03-28 12:05:31 +02009186 },
Takashi Iwaie59ea3e2011-06-29 17:21:00 +02009187 [ALC662_FIXUP_HP_RP5800] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01009188 .type = HDA_FIXUP_PINS,
9189 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaie59ea3e2011-06-29 17:21:00 +02009190 { 0x14, 0x0221201f }, /* HP out */
9191 { }
9192 },
9193 .chained = true,
9194 .chain_id = ALC662_FIXUP_SKU_IGNORE
9195 },
Takashi Iwai53c334a2011-08-23 18:27:14 +02009196 [ALC662_FIXUP_ASUS_MODE1] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01009197 .type = HDA_FIXUP_PINS,
9198 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02009199 { 0x14, 0x99130110 }, /* speaker */
9200 { 0x18, 0x01a19c20 }, /* mic */
9201 { 0x19, 0x99a3092f }, /* int-mic */
9202 { 0x21, 0x0121401f }, /* HP out */
9203 { }
9204 },
9205 .chained = true,
9206 .chain_id = ALC662_FIXUP_SKU_IGNORE
9207 },
9208 [ALC662_FIXUP_ASUS_MODE2] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01009209 .type = HDA_FIXUP_PINS,
9210 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai2996bdb2011-08-18 16:02:24 +02009211 { 0x14, 0x99130110 }, /* speaker */
9212 { 0x18, 0x01a19820 }, /* mic */
9213 { 0x19, 0x99a3092f }, /* int-mic */
9214 { 0x1b, 0x0121401f }, /* HP out */
9215 { }
9216 },
Takashi Iwai53c334a2011-08-23 18:27:14 +02009217 .chained = true,
9218 .chain_id = ALC662_FIXUP_SKU_IGNORE
9219 },
9220 [ALC662_FIXUP_ASUS_MODE3] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01009221 .type = HDA_FIXUP_PINS,
9222 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02009223 { 0x14, 0x99130110 }, /* speaker */
9224 { 0x15, 0x0121441f }, /* HP */
9225 { 0x18, 0x01a19840 }, /* mic */
9226 { 0x19, 0x99a3094f }, /* int-mic */
9227 { 0x21, 0x01211420 }, /* HP2 */
9228 { }
9229 },
9230 .chained = true,
9231 .chain_id = ALC662_FIXUP_SKU_IGNORE
9232 },
9233 [ALC662_FIXUP_ASUS_MODE4] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01009234 .type = HDA_FIXUP_PINS,
9235 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02009236 { 0x14, 0x99130110 }, /* speaker */
9237 { 0x16, 0x99130111 }, /* speaker */
9238 { 0x18, 0x01a19840 }, /* mic */
9239 { 0x19, 0x99a3094f }, /* int-mic */
9240 { 0x21, 0x0121441f }, /* HP */
9241 { }
9242 },
9243 .chained = true,
9244 .chain_id = ALC662_FIXUP_SKU_IGNORE
9245 },
9246 [ALC662_FIXUP_ASUS_MODE5] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01009247 .type = HDA_FIXUP_PINS,
9248 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02009249 { 0x14, 0x99130110 }, /* speaker */
9250 { 0x15, 0x0121441f }, /* HP */
9251 { 0x16, 0x99130111 }, /* speaker */
9252 { 0x18, 0x01a19840 }, /* mic */
9253 { 0x19, 0x99a3094f }, /* int-mic */
9254 { }
9255 },
9256 .chained = true,
9257 .chain_id = ALC662_FIXUP_SKU_IGNORE
9258 },
9259 [ALC662_FIXUP_ASUS_MODE6] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01009260 .type = HDA_FIXUP_PINS,
9261 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02009262 { 0x14, 0x99130110 }, /* speaker */
9263 { 0x15, 0x01211420 }, /* HP2 */
9264 { 0x18, 0x01a19840 }, /* mic */
9265 { 0x19, 0x99a3094f }, /* int-mic */
9266 { 0x1b, 0x0121441f }, /* HP */
9267 { }
9268 },
9269 .chained = true,
9270 .chain_id = ALC662_FIXUP_SKU_IGNORE
9271 },
9272 [ALC662_FIXUP_ASUS_MODE7] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01009273 .type = HDA_FIXUP_PINS,
9274 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02009275 { 0x14, 0x99130110 }, /* speaker */
9276 { 0x17, 0x99130111 }, /* speaker */
9277 { 0x18, 0x01a19840 }, /* mic */
9278 { 0x19, 0x99a3094f }, /* int-mic */
9279 { 0x1b, 0x01214020 }, /* HP */
9280 { 0x21, 0x0121401f }, /* HP */
9281 { }
9282 },
9283 .chained = true,
9284 .chain_id = ALC662_FIXUP_SKU_IGNORE
9285 },
9286 [ALC662_FIXUP_ASUS_MODE8] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01009287 .type = HDA_FIXUP_PINS,
9288 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02009289 { 0x14, 0x99130110 }, /* speaker */
9290 { 0x12, 0x99a30970 }, /* int-mic */
9291 { 0x15, 0x01214020 }, /* HP */
9292 { 0x17, 0x99130111 }, /* speaker */
9293 { 0x18, 0x01a19840 }, /* mic */
9294 { 0x21, 0x0121401f }, /* HP */
9295 { }
9296 },
9297 .chained = true,
9298 .chain_id = ALC662_FIXUP_SKU_IGNORE
Takashi Iwai2996bdb2011-08-18 16:02:24 +02009299 },
Takashi Iwai1565cc32012-02-13 12:03:25 +01009300 [ALC662_FIXUP_NO_JACK_DETECT] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01009301 .type = HDA_FIXUP_FUNC,
Takashi Iwai1565cc32012-02-13 12:03:25 +01009302 .v.func = alc_fixup_no_jack_detect,
9303 },
David Henningssonedfe3bf2012-06-12 13:15:12 +02009304 [ALC662_FIXUP_ZOTAC_Z68] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01009305 .type = HDA_FIXUP_PINS,
9306 .v.pins = (const struct hda_pintbl[]) {
David Henningssonedfe3bf2012-06-12 13:15:12 +02009307 { 0x1b, 0x02214020 }, /* Front HP */
9308 { }
9309 }
9310 },
Takashi Iwai125821a2012-06-22 14:30:29 +02009311 [ALC662_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01009312 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02009313 .v.func = alc_fixup_inv_dmic,
Takashi Iwai125821a2012-06-22 14:30:29 +02009314 },
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02009315 [ALC668_FIXUP_DELL_XPS13] = {
9316 .type = HDA_FIXUP_FUNC,
9317 .v.func = alc_fixup_dell_xps13,
9318 .chained = true,
9319 .chain_id = ALC668_FIXUP_DELL_DISABLE_AAMIX
9320 },
Gabriele Mazzotta5e6db662014-05-20 18:58:26 +02009321 [ALC668_FIXUP_DELL_DISABLE_AAMIX] = {
9322 .type = HDA_FIXUP_FUNC,
9323 .v.func = alc_fixup_disable_aamix,
9324 .chained = true,
9325 .chain_id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE
9326 },
Hui Wang493a52a2014-01-14 14:07:36 +08009327 [ALC668_FIXUP_AUTO_MUTE] = {
9328 .type = HDA_FIXUP_FUNC,
9329 .v.func = alc_fixup_auto_mute_via_amp,
9330 .chained = true,
9331 .chain_id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE
9332 },
David Henningsson1f8b46c2015-05-12 14:38:15 +02009333 [ALC662_FIXUP_DELL_MIC_NO_PRESENCE] = {
9334 .type = HDA_FIXUP_PINS,
9335 .v.pins = (const struct hda_pintbl[]) {
9336 { 0x19, 0x03a1113c }, /* use as headset mic, without its own jack detect */
9337 /* headphone mic by setting pin control of 0x1b (headphone out) to in + vref_50 */
9338 { }
9339 },
9340 .chained = true,
9341 .chain_id = ALC662_FIXUP_HEADSET_MODE
9342 },
9343 [ALC662_FIXUP_HEADSET_MODE] = {
9344 .type = HDA_FIXUP_FUNC,
9345 .v.func = alc_fixup_headset_mode_alc662,
9346 },
David Henningsson73bdd592013-04-15 15:44:14 +02009347 [ALC668_FIXUP_DELL_MIC_NO_PRESENCE] = {
9348 .type = HDA_FIXUP_PINS,
9349 .v.pins = (const struct hda_pintbl[]) {
9350 { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
9351 { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */
9352 { }
9353 },
9354 .chained = true,
9355 .chain_id = ALC668_FIXUP_HEADSET_MODE
9356 },
9357 [ALC668_FIXUP_HEADSET_MODE] = {
9358 .type = HDA_FIXUP_FUNC,
9359 .v.func = alc_fixup_headset_mode_alc668,
9360 },
David Henningsson8e54b4a2014-02-07 09:31:07 +01009361 [ALC662_FIXUP_BASS_MODE4_CHMAP] = {
Takashi Iwai8e383952013-10-30 17:41:12 +01009362 .type = HDA_FIXUP_FUNC,
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01009363 .v.func = alc_fixup_bass_chmap,
Takashi Iwai8e383952013-10-30 17:41:12 +01009364 .chained = true,
9365 .chain_id = ALC662_FIXUP_ASUS_MODE4
9366 },
David Henningsson61a75f12014-02-07 09:31:08 +01009367 [ALC662_FIXUP_BASS_16] = {
9368 .type = HDA_FIXUP_PINS,
9369 .v.pins = (const struct hda_pintbl[]) {
9370 {0x16, 0x80106111}, /* bass speaker */
9371 {}
9372 },
9373 .chained = true,
9374 .chain_id = ALC662_FIXUP_BASS_CHMAP,
9375 },
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01009376 [ALC662_FIXUP_BASS_1A] = {
9377 .type = HDA_FIXUP_PINS,
9378 .v.pins = (const struct hda_pintbl[]) {
9379 {0x1a, 0x80106111}, /* bass speaker */
9380 {}
9381 },
David Henningsson8e54b4a2014-02-07 09:31:07 +01009382 .chained = true,
9383 .chain_id = ALC662_FIXUP_BASS_CHMAP,
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01009384 },
David Henningsson8e54b4a2014-02-07 09:31:07 +01009385 [ALC662_FIXUP_BASS_CHMAP] = {
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01009386 .type = HDA_FIXUP_FUNC,
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01009387 .v.func = alc_fixup_bass_chmap,
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01009388 },
Bobi Mihalca9d4dc582016-03-23 13:26:11 +02009389 [ALC662_FIXUP_ASUS_Nx50] = {
9390 .type = HDA_FIXUP_FUNC,
9391 .v.func = alc_fixup_auto_mute_via_amp,
9392 .chained = true,
9393 .chain_id = ALC662_FIXUP_BASS_1A
9394 },
Mikhail Paulyshkafc7438b2017-04-21 08:52:42 +02009395 [ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE] = {
9396 .type = HDA_FIXUP_FUNC,
9397 .v.func = alc_fixup_headset_mode_alc668,
9398 .chain_id = ALC662_FIXUP_BASS_CHMAP
9399 },
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07009400 [ALC668_FIXUP_ASUS_Nx51] = {
9401 .type = HDA_FIXUP_PINS,
9402 .v.pins = (const struct hda_pintbl[]) {
Mikhail Paulyshkafc7438b2017-04-21 08:52:42 +02009403 { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
9404 { 0x1a, 0x90170151 }, /* bass speaker */
9405 { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07009406 {}
9407 },
9408 .chained = true,
Mikhail Paulyshkafc7438b2017-04-21 08:52:42 +02009409 .chain_id = ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE,
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07009410 },
Takashi Iwai5b7c5e12018-10-09 14:20:17 +02009411 [ALC668_FIXUP_MIC_COEF] = {
Takashi Iwai11ba6112018-10-07 09:44:17 +02009412 .type = HDA_FIXUP_VERBS,
9413 .v.verbs = (const struct hda_verb[]) {
9414 { 0x20, AC_VERB_SET_COEF_INDEX, 0xc3 },
9415 { 0x20, AC_VERB_SET_PROC_COEF, 0x4000 },
9416 {}
9417 },
9418 },
Takashi Iwai5b7c5e12018-10-09 14:20:17 +02009419 [ALC668_FIXUP_ASUS_G751] = {
9420 .type = HDA_FIXUP_PINS,
9421 .v.pins = (const struct hda_pintbl[]) {
9422 { 0x16, 0x0421101f }, /* HP */
9423 {}
9424 },
9425 .chained = true,
9426 .chain_id = ALC668_FIXUP_MIC_COEF
9427 },
Kailang Yang78f4f7c2016-06-07 11:31:34 +08009428 [ALC891_FIXUP_HEADSET_MODE] = {
9429 .type = HDA_FIXUP_FUNC,
9430 .v.func = alc_fixup_headset_mode,
9431 },
9432 [ALC891_FIXUP_DELL_MIC_NO_PRESENCE] = {
9433 .type = HDA_FIXUP_PINS,
9434 .v.pins = (const struct hda_pintbl[]) {
9435 { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
9436 { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */
9437 { }
9438 },
9439 .chained = true,
9440 .chain_id = ALC891_FIXUP_HEADSET_MODE
9441 },
Shrirang Bagul9b51fe32016-08-01 13:16:17 +08009442 [ALC662_FIXUP_ACER_VERITON] = {
9443 .type = HDA_FIXUP_PINS,
9444 .v.pins = (const struct hda_pintbl[]) {
9445 { 0x15, 0x50170120 }, /* no internal speaker */
9446 { }
9447 }
9448 },
Takashi Iwai1a3f0992016-10-20 12:14:51 +02009449 [ALC892_FIXUP_ASROCK_MOBO] = {
9450 .type = HDA_FIXUP_PINS,
9451 .v.pins = (const struct hda_pintbl[]) {
9452 { 0x15, 0x40f000f0 }, /* disabled */
9453 { 0x16, 0x40f000f0 }, /* disabled */
Takashi Iwai1a3f0992016-10-20 12:14:51 +02009454 { }
9455 }
9456 },
Kailang Yangc6790c82016-11-25 16:15:17 +08009457 [ALC662_FIXUP_USI_FUNC] = {
9458 .type = HDA_FIXUP_FUNC,
9459 .v.func = alc662_fixup_usi_headset_mic,
9460 },
9461 [ALC662_FIXUP_USI_HEADSET_MODE] = {
9462 .type = HDA_FIXUP_PINS,
9463 .v.pins = (const struct hda_pintbl[]) {
9464 { 0x19, 0x02a1913c }, /* use as headset mic, without its own jack detect */
9465 { 0x18, 0x01a1903d },
9466 { }
9467 },
9468 .chained = true,
9469 .chain_id = ALC662_FIXUP_USI_FUNC
9470 },
Kailang Yangca169cc2017-04-25 16:17:40 +08009471 [ALC662_FIXUP_LENOVO_MULTI_CODECS] = {
9472 .type = HDA_FIXUP_FUNC,
9473 .v.func = alc233_alc662_fixup_lenovo_dual_codecs,
9474 },
Sergey Bostandzhyan00066e92019-09-06 11:33:43 +02009475 [ALC669_FIXUP_ACER_ASPIRE_ETHOS_HEADSET] = {
9476 .type = HDA_FIXUP_FUNC,
9477 .v.func = alc662_fixup_aspire_ethos_hp,
9478 },
Sergey Bostandzhyan00066e92019-09-06 11:33:43 +02009479 [ALC669_FIXUP_ACER_ASPIRE_ETHOS] = {
9480 .type = HDA_FIXUP_PINS,
9481 .v.pins = (const struct hda_pintbl[]) {
9482 { 0x15, 0x92130110 }, /* front speakers */
9483 { 0x18, 0x99130111 }, /* center/subwoofer */
9484 { 0x1b, 0x11130012 }, /* surround plus jack for HP */
9485 { }
9486 },
9487 .chained = true,
Takashi Iwai336820c2019-11-28 21:26:30 +01009488 .chain_id = ALC669_FIXUP_ACER_ASPIRE_ETHOS_HEADSET
Sergey Bostandzhyan00066e92019-09-06 11:33:43 +02009489 },
Kailang Yang5af290282020-01-17 14:04:01 +08009490 [ALC671_FIXUP_HP_HEADSET_MIC2] = {
9491 .type = HDA_FIXUP_FUNC,
9492 .v.func = alc671_fixup_hp_headset_mic2,
9493 },
Jian-Hong Pand858c702020-03-17 16:28:07 +08009494 [ALC662_FIXUP_ACER_X2660G_HEADSET_MODE] = {
9495 .type = HDA_FIXUP_PINS,
9496 .v.pins = (const struct hda_pintbl[]) {
9497 { 0x1a, 0x02a1113c }, /* use as headset mic, without its own jack detect */
9498 { }
9499 },
9500 .chained = true,
9501 .chain_id = ALC662_FIXUP_USI_FUNC
9502 },
Jian-Hong Pana1244582020-03-17 16:28:09 +08009503 [ALC662_FIXUP_ACER_NITRO_HEADSET_MODE] = {
9504 .type = HDA_FIXUP_PINS,
9505 .v.pins = (const struct hda_pintbl[]) {
9506 { 0x1a, 0x01a11140 }, /* use as headset mic, without its own jack detect */
9507 { 0x1b, 0x0221144f },
9508 { }
9509 },
9510 .chained = true,
9511 .chain_id = ALC662_FIXUP_USI_FUNC
9512 },
David Henningsson6cb3b702010-09-09 08:51:44 +02009513};
9514
Takashi Iwaia9111322011-05-02 11:30:18 +02009515static const struct snd_pci_quirk alc662_fixup_tbl[] = {
Takashi Iwai53c334a2011-08-23 18:27:14 +02009516 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_FIXUP_ASUS_MODE2),
Takashi Iwaid3d38352013-08-19 20:05:50 +02009517 SND_PCI_QUIRK(0x1025, 0x022f, "Acer Aspire One", ALC662_FIXUP_INV_DMIC),
David Henningsson02f6ff92015-12-07 11:29:31 +01009518 SND_PCI_QUIRK(0x1025, 0x0241, "Packard Bell DOTS", ALC662_FIXUP_INV_DMIC),
David Henningssona6c47a82011-02-10 15:39:19 +01009519 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
David Henningsson94024cd2011-04-29 14:10:55 +02009520 SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
Takashi Iwai125821a2012-06-22 14:30:29 +02009521 SND_PCI_QUIRK(0x1025, 0x0349, "eMachines eM250", ALC662_FIXUP_INV_DMIC),
Takashi Iwai18019282013-08-16 08:17:05 +02009522 SND_PCI_QUIRK(0x1025, 0x034a, "Gateway LT27", ALC662_FIXUP_INV_DMIC),
Daniel T Chen2df03512010-10-10 22:39:28 -04009523 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
Jian-Hong Pana1244582020-03-17 16:28:09 +08009524 SND_PCI_QUIRK(0x1025, 0x123c, "Acer Nitro N50-600", ALC662_FIXUP_ACER_NITRO_HEADSET_MODE),
Jian-Hong Pand858c702020-03-17 16:28:07 +08009525 SND_PCI_QUIRK(0x1025, 0x124e, "Acer 2660G", ALC662_FIXUP_ACER_X2660G_HEADSET_MODE),
David Henningsson73bdd592013-04-15 15:44:14 +02009526 SND_PCI_QUIRK(0x1028, 0x05d8, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
9527 SND_PCI_QUIRK(0x1028, 0x05db, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
Takashi Iwaic5d019c2014-07-22 17:33:32 +02009528 SND_PCI_QUIRK(0x1028, 0x05fe, "Dell XPS 15", ALC668_FIXUP_DELL_XPS13),
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02009529 SND_PCI_QUIRK(0x1028, 0x060a, "Dell XPS 13", ALC668_FIXUP_DELL_XPS13),
Niranjan Sivakumar467e1432015-09-05 18:20:35 +02009530 SND_PCI_QUIRK(0x1028, 0x060d, "Dell M3800", ALC668_FIXUP_DELL_XPS13),
David Henningsson09d20142013-11-20 11:43:30 +01009531 SND_PCI_QUIRK(0x1028, 0x0625, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
David Henningssonad8ff99e2013-11-07 09:28:59 +01009532 SND_PCI_QUIRK(0x1028, 0x0626, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
Kailang Yang8dc9abb2014-04-16 15:53:12 +08009533 SND_PCI_QUIRK(0x1028, 0x0696, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
9534 SND_PCI_QUIRK(0x1028, 0x0698, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
Kailang Yang6a98e342014-10-27 16:20:30 +08009535 SND_PCI_QUIRK(0x1028, 0x069f, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
Takashi Iwaie59ea3e2011-06-29 17:21:00 +02009536 SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800),
Kaho Ng2da2dc92016-05-09 00:27:49 +08009537 SND_PCI_QUIRK(0x1043, 0x1080, "Asus UX501VW", ALC668_FIXUP_HEADSET_MODE),
Bobi Mihalca83a9efb2016-03-23 13:32:33 +02009538 SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_ASUS_Nx50),
Takashi Iwaidb8948e2016-01-18 09:17:30 +01009539 SND_PCI_QUIRK(0x1043, 0x13df, "Asus N550JX", ALC662_FIXUP_BASS_1A),
Bobi Mihalca9d4dc582016-03-23 13:26:11 +02009540 SND_PCI_QUIRK(0x1043, 0x129d, "Asus N750", ALC662_FIXUP_ASUS_Nx50),
Takashi Iwai11ba6112018-10-07 09:44:17 +02009541 SND_PCI_QUIRK(0x1043, 0x12ff, "ASUS G751", ALC668_FIXUP_ASUS_G751),
David Henningsson8e54b4a2014-02-07 09:31:07 +01009542 SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
David Henningsson61a75f12014-02-07 09:31:08 +01009543 SND_PCI_QUIRK(0x1043, 0x15a7, "ASUS UX51VZH", ALC662_FIXUP_BASS_16),
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07009544 SND_PCI_QUIRK(0x1043, 0x177d, "ASUS N551", ALC668_FIXUP_ASUS_Nx51),
9545 SND_PCI_QUIRK(0x1043, 0x17bd, "ASUS N751", ALC668_FIXUP_ASUS_Nx51),
Takashi Iwaic7efff92017-01-04 21:38:16 +01009546 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71SL", ALC662_FIXUP_ASUS_MODE8),
David Henningsson61a75f12014-02-07 09:31:08 +01009547 SND_PCI_QUIRK(0x1043, 0x1b73, "ASUS N55SF", ALC662_FIXUP_BASS_16),
David Henningsson8e54b4a2014-02-07 09:31:07 +01009548 SND_PCI_QUIRK(0x1043, 0x1bf3, "ASUS N76VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
Takashi Iwai1565cc32012-02-13 12:03:25 +01009549 SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT),
Takashi Iwai53c334a2011-08-23 18:27:14 +02009550 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2),
Daniel T Chena0e90ac2010-11-20 10:20:35 -05009551 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
Kailang Yangc6790c82016-11-25 16:15:17 +08009552 SND_PCI_QUIRK(0x14cd, 0x5003, "USI", ALC662_FIXUP_USI_HEADSET_MODE),
Kailang Yangca169cc2017-04-25 16:17:40 +08009553 SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC662_FIXUP_LENOVO_MULTI_CODECS),
Valentine Sinitsynd4118582010-10-01 22:24:08 +06009554 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
David Henningsson6cb3b702010-09-09 08:51:44 +02009555 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
Takashi Iwai1a3f0992016-10-20 12:14:51 +02009556 SND_PCI_QUIRK(0x1849, 0x5892, "ASRock B150M", ALC892_FIXUP_ASROCK_MOBO),
David Henningssonedfe3bf2012-06-12 13:15:12 +02009557 SND_PCI_QUIRK(0x19da, 0xa130, "Zotac Z68", ALC662_FIXUP_ZOTAC_Z68),
Shrirang Bagul9b51fe32016-08-01 13:16:17 +08009558 SND_PCI_QUIRK(0x1b0a, 0x01b8, "ACER Veriton", ALC662_FIXUP_ACER_VERITON),
Huacai Chenf1ec5be2020-08-02 17:26:40 +08009559 SND_PCI_QUIRK(0x1b35, 0x1234, "CZC ET26", ALC662_FIXUP_CZC_ET26),
Anisse Astierd2ebd472011-01-20 12:36:21 +01009560 SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
Sergey Bostandzhyan00066e92019-09-06 11:33:43 +02009561 SND_PCI_QUIRK(0x1025, 0x0566, "Acer Aspire Ethos 8951G", ALC669_FIXUP_ACER_ASPIRE_ETHOS),
Takashi Iwai53c334a2011-08-23 18:27:14 +02009562
9563#if 0
9564 /* Below is a quirk table taken from the old code.
9565 * Basically the device should work as is without the fixup table.
9566 * If BIOS doesn't give a proper info, enable the corresponding
9567 * fixup entry.
Jesper Juhl7d7eb9e2012-04-12 22:11:25 +02009568 */
Takashi Iwai53c334a2011-08-23 18:27:14 +02009569 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC662_FIXUP_ASUS_MODE1),
9570 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC662_FIXUP_ASUS_MODE3),
9571 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC662_FIXUP_ASUS_MODE1),
9572 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC662_FIXUP_ASUS_MODE3),
9573 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
9574 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
9575 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
9576 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC662_FIXUP_ASUS_MODE1),
9577 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC662_FIXUP_ASUS_MODE1),
9578 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
9579 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC662_FIXUP_ASUS_MODE7),
9580 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC662_FIXUP_ASUS_MODE7),
9581 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC662_FIXUP_ASUS_MODE8),
9582 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC662_FIXUP_ASUS_MODE3),
9583 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC662_FIXUP_ASUS_MODE1),
9584 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
9585 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_FIXUP_ASUS_MODE2),
9586 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC662_FIXUP_ASUS_MODE1),
9587 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
9588 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
9589 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
9590 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
9591 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC662_FIXUP_ASUS_MODE1),
9592 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC662_FIXUP_ASUS_MODE3),
9593 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_FIXUP_ASUS_MODE2),
9594 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
9595 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC662_FIXUP_ASUS_MODE5),
9596 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
9597 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
9598 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC662_FIXUP_ASUS_MODE1),
9599 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
9600 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
9601 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC662_FIXUP_ASUS_MODE3),
9602 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC662_FIXUP_ASUS_MODE3),
9603 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC662_FIXUP_ASUS_MODE1),
9604 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC662_FIXUP_ASUS_MODE1),
9605 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC662_FIXUP_ASUS_MODE1),
9606 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC662_FIXUP_ASUS_MODE1),
9607 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC662_FIXUP_ASUS_MODE1),
9608 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
9609 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_FIXUP_ASUS_MODE2),
9610 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC662_FIXUP_ASUS_MODE1),
9611 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
9612 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC662_FIXUP_ASUS_MODE3),
9613 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC662_FIXUP_ASUS_MODE1),
9614 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC662_FIXUP_ASUS_MODE1),
9615 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC662_FIXUP_ASUS_MODE1),
9616 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_FIXUP_ASUS_MODE2),
9617 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
9618 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE4),
9619#endif
David Henningsson6cb3b702010-09-09 08:51:44 +02009620 {}
9621};
9622
Takashi Iwai1727a772013-01-10 09:52:52 +01009623static const struct hda_model_fixup alc662_fixup_models[] = {
Takashi Iwaiaa3841b2018-06-26 07:42:40 +02009624 {.id = ALC662_FIXUP_ASPIRE, .name = "aspire"},
9625 {.id = ALC662_FIXUP_IDEAPAD, .name = "ideapad"},
Todd Broch6be79482010-12-07 16:51:05 -08009626 {.id = ALC272_FIXUP_MARIO, .name = "mario"},
Takashi Iwaiaa3841b2018-06-26 07:42:40 +02009627 {.id = ALC662_FIXUP_HP_RP5800, .name = "hp-rp5800"},
Takashi Iwai53c334a2011-08-23 18:27:14 +02009628 {.id = ALC662_FIXUP_ASUS_MODE1, .name = "asus-mode1"},
9629 {.id = ALC662_FIXUP_ASUS_MODE2, .name = "asus-mode2"},
9630 {.id = ALC662_FIXUP_ASUS_MODE3, .name = "asus-mode3"},
9631 {.id = ALC662_FIXUP_ASUS_MODE4, .name = "asus-mode4"},
9632 {.id = ALC662_FIXUP_ASUS_MODE5, .name = "asus-mode5"},
9633 {.id = ALC662_FIXUP_ASUS_MODE6, .name = "asus-mode6"},
9634 {.id = ALC662_FIXUP_ASUS_MODE7, .name = "asus-mode7"},
9635 {.id = ALC662_FIXUP_ASUS_MODE8, .name = "asus-mode8"},
Takashi Iwaiaa3841b2018-06-26 07:42:40 +02009636 {.id = ALC662_FIXUP_ZOTAC_Z68, .name = "zotac-z68"},
Takashi Iwai6e72aa52012-06-25 10:52:25 +02009637 {.id = ALC662_FIXUP_INV_DMIC, .name = "inv-dmic"},
Takashi Iwaiaa3841b2018-06-26 07:42:40 +02009638 {.id = ALC662_FIXUP_DELL_MIC_NO_PRESENCE, .name = "alc662-headset-multi"},
David Henningssone32aa852013-06-17 11:04:02 +02009639 {.id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE, .name = "dell-headset-multi"},
Takashi Iwaiaa3841b2018-06-26 07:42:40 +02009640 {.id = ALC662_FIXUP_HEADSET_MODE, .name = "alc662-headset"},
9641 {.id = ALC668_FIXUP_HEADSET_MODE, .name = "alc668-headset"},
9642 {.id = ALC662_FIXUP_BASS_16, .name = "bass16"},
9643 {.id = ALC662_FIXUP_BASS_1A, .name = "bass1a"},
9644 {.id = ALC668_FIXUP_AUTO_MUTE, .name = "automute"},
9645 {.id = ALC668_FIXUP_DELL_XPS13, .name = "dell-xps13"},
9646 {.id = ALC662_FIXUP_ASUS_Nx50, .name = "asus-nx50"},
9647 {.id = ALC668_FIXUP_ASUS_Nx51, .name = "asus-nx51"},
Takashi Iwai40c51672018-10-07 09:47:39 +02009648 {.id = ALC668_FIXUP_ASUS_G751, .name = "asus-g751"},
Takashi Iwaiaa3841b2018-06-26 07:42:40 +02009649 {.id = ALC891_FIXUP_HEADSET_MODE, .name = "alc891-headset"},
9650 {.id = ALC891_FIXUP_DELL_MIC_NO_PRESENCE, .name = "alc891-headset-multi"},
9651 {.id = ALC662_FIXUP_ACER_VERITON, .name = "acer-veriton"},
9652 {.id = ALC892_FIXUP_ASROCK_MOBO, .name = "asrock-mobo"},
9653 {.id = ALC662_FIXUP_USI_HEADSET_MODE, .name = "usi-headset"},
Takashi Iwaiba90d6a2017-05-22 16:38:47 +02009654 {.id = ALC662_FIXUP_LENOVO_MULTI_CODECS, .name = "dual-codecs"},
Sergey Bostandzhyan00066e92019-09-06 11:33:43 +02009655 {.id = ALC669_FIXUP_ACER_ASPIRE_ETHOS, .name = "aspire-ethos"},
Todd Broch6be79482010-12-07 16:51:05 -08009656 {}
9657};
David Henningsson6cb3b702010-09-09 08:51:44 +02009658
Hui Wang532895c2014-05-29 15:59:19 +08009659static const struct snd_hda_pin_quirk alc662_pin_fixup_tbl[] = {
Kailang Yang78f4f7c2016-06-07 11:31:34 +08009660 SND_HDA_PIN_QUIRK(0x10ec0867, 0x1028, "Dell", ALC891_FIXUP_DELL_MIC_NO_PRESENCE,
9661 {0x17, 0x02211010},
9662 {0x18, 0x01a19030},
9663 {0x1a, 0x01813040},
9664 {0x21, 0x01014020}),
Hui Wang4b4e0e32019-07-16 15:21:34 +08009665 SND_HDA_PIN_QUIRK(0x10ec0867, 0x1028, "Dell", ALC891_FIXUP_DELL_MIC_NO_PRESENCE,
9666 {0x16, 0x01813030},
9667 {0x17, 0x02211010},
9668 {0x18, 0x01a19040},
9669 {0x21, 0x01014020}),
David Henningsson1f8b46c2015-05-12 14:38:15 +02009670 SND_HDA_PIN_QUIRK(0x10ec0662, 0x1028, "Dell", ALC662_FIXUP_DELL_MIC_NO_PRESENCE,
David Henningsson1f8b46c2015-05-12 14:38:15 +02009671 {0x14, 0x01014010},
David Henningsson1f8b46c2015-05-12 14:38:15 +02009672 {0x18, 0x01a19020},
David Henningsson1f8b46c2015-05-12 14:38:15 +02009673 {0x1a, 0x0181302f},
Hui Wang11580292015-08-03 11:03:49 +08009674 {0x1b, 0x0221401f}),
David Henningsson76c21322014-06-24 14:46:54 +02009675 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
9676 {0x12, 0x99a30130},
9677 {0x14, 0x90170110},
9678 {0x15, 0x0321101f},
Hui Wang11580292015-08-03 11:03:49 +08009679 {0x16, 0x03011020}),
David Henningsson76c21322014-06-24 14:46:54 +02009680 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
9681 {0x12, 0x99a30140},
9682 {0x14, 0x90170110},
9683 {0x15, 0x0321101f},
Hui Wang11580292015-08-03 11:03:49 +08009684 {0x16, 0x03011020}),
David Henningsson76c21322014-06-24 14:46:54 +02009685 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
9686 {0x12, 0x99a30150},
9687 {0x14, 0x90170110},
9688 {0x15, 0x0321101f},
Hui Wang11580292015-08-03 11:03:49 +08009689 {0x16, 0x03011020}),
David Henningsson76c21322014-06-24 14:46:54 +02009690 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
David Henningsson76c21322014-06-24 14:46:54 +02009691 {0x14, 0x90170110},
9692 {0x15, 0x0321101f},
Hui Wang11580292015-08-03 11:03:49 +08009693 {0x16, 0x03011020}),
David Henningsson76c21322014-06-24 14:46:54 +02009694 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell XPS 15", ALC668_FIXUP_AUTO_MUTE,
9695 {0x12, 0x90a60130},
9696 {0x14, 0x90170110},
Hui Wang11580292015-08-03 11:03:49 +08009697 {0x15, 0x0321101f}),
Kailang Yang5af290282020-01-17 14:04:01 +08009698 SND_HDA_PIN_QUIRK(0x10ec0671, 0x103c, "HP cPC", ALC671_FIXUP_HP_HEADSET_MIC2,
9699 {0x14, 0x01014010},
9700 {0x17, 0x90170150},
Kailang Yangf2adbae2020-02-05 15:40:01 +08009701 {0x19, 0x02a11060},
Kailang Yang5af290282020-01-17 14:04:01 +08009702 {0x1b, 0x01813030},
9703 {0x21, 0x02211020}),
9704 SND_HDA_PIN_QUIRK(0x10ec0671, 0x103c, "HP cPC", ALC671_FIXUP_HP_HEADSET_MIC2,
9705 {0x14, 0x01014010},
9706 {0x18, 0x01a19040},
9707 {0x1b, 0x01813030},
9708 {0x21, 0x02211020}),
9709 SND_HDA_PIN_QUIRK(0x10ec0671, 0x103c, "HP cPC", ALC671_FIXUP_HP_HEADSET_MIC2,
9710 {0x14, 0x01014020},
9711 {0x17, 0x90170110},
9712 {0x18, 0x01a19050},
9713 {0x1b, 0x01813040},
9714 {0x21, 0x02211030}),
Hui Wang532895c2014-05-29 15:59:19 +08009715 {}
9716};
9717
Takashi Iwai1d045db2011-07-07 18:23:21 +02009718/*
9719 */
Kailang Yangbc9f98a2007-04-12 13:06:07 +02009720static int patch_alc662(struct hda_codec *codec)
9721{
9722 struct alc_spec *spec;
Takashi Iwai3de95172012-05-07 18:03:15 +02009723 int err;
Kailang Yangbc9f98a2007-04-12 13:06:07 +02009724
Takashi Iwai3de95172012-05-07 18:03:15 +02009725 err = alc_alloc_spec(codec, 0x0b);
9726 if (err < 0)
9727 return err;
Kailang Yangbc9f98a2007-04-12 13:06:07 +02009728
Takashi Iwai3de95172012-05-07 18:03:15 +02009729 spec = codec->spec;
Takashi Iwai1f0f4b82011-06-27 10:52:59 +02009730
Takashi Iwai225068a2015-05-29 10:42:14 +02009731 spec->shutup = alc_eapd_shutup;
9732
Takashi Iwai53c334a2011-08-23 18:27:14 +02009733 /* handle multiple HPs as is */
9734 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
9735
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +02009736 alc_fix_pll_init(codec, 0x20, 0x04, 15);
9737
Takashi Iwai7639a062015-03-03 10:07:24 +01009738 switch (codec->core.vendor_id) {
Kailang Yangf3f91852014-10-24 15:43:46 +08009739 case 0x10ec0668:
9740 spec->init_hook = alc668_restore_default_value;
9741 break;
Kailang Yangf3f91852014-10-24 15:43:46 +08009742 }
Kailang Yang8663ff72012-06-29 09:35:52 +02009743
Takashi Iwaic9af7532019-05-10 11:01:43 +02009744 alc_pre_init(codec);
9745
Takashi Iwai1727a772013-01-10 09:52:52 +01009746 snd_hda_pick_fixup(codec, alc662_fixup_models,
Takashi Iwai8e5a0502012-06-21 15:49:33 +02009747 alc662_fixup_tbl, alc662_fixups);
Hui Wang0fc1e442019-08-16 14:27:39 +08009748 snd_hda_pick_pin_fixup(codec, alc662_pin_fixup_tbl, alc662_fixups, true);
Takashi Iwai1727a772013-01-10 09:52:52 +01009749 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai8e5a0502012-06-21 15:49:33 +02009750
9751 alc_auto_parse_customize_define(codec);
9752
Takashi Iwai7504b6c2013-03-18 11:25:51 +01009753 if (has_cdefine_beep(codec))
9754 spec->gen.beep_nid = 0x01;
9755
Takashi Iwai1bb7e432011-10-17 16:50:59 +02009756 if ((alc_get_coef0(codec) & (1 << 14)) &&
Takashi Iwai5100cd02014-02-15 10:03:19 +01009757 codec->bus->pci && codec->bus->pci->subsystem_vendor == 0x1025 &&
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02009758 spec->cdefine.platform_type == 1) {
Wei Yongjun6134b1a2013-04-18 11:12:59 +08009759 err = alc_codec_rename(codec, "ALC272X");
9760 if (err < 0)
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02009761 goto error;
Takashi Iwai20ca0c32011-10-17 16:00:35 +02009762 }
Kailang Yang274693f2009-12-03 10:07:50 +01009763
Takashi Iwaib9c51062011-08-24 18:08:07 +02009764 /* automatic parse from the BIOS config */
9765 err = alc662_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02009766 if (err < 0)
9767 goto error;
Kailang Yangbc9f98a2007-04-12 13:06:07 +02009768
Takashi Iwai7504b6c2013-03-18 11:25:51 +01009769 if (!spec->gen.no_analog && spec->gen.beep_nid) {
Takashi Iwai7639a062015-03-03 10:07:24 +01009770 switch (codec->core.vendor_id) {
Kailang Yangda00c242010-03-19 11:23:45 +01009771 case 0x10ec0662:
Takashi Iwaifea80fa2018-06-20 12:52:46 +02009772 err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
Kailang Yangda00c242010-03-19 11:23:45 +01009773 break;
9774 case 0x10ec0272:
9775 case 0x10ec0663:
9776 case 0x10ec0665:
Kailang Yang9ad54542013-11-26 15:41:40 +08009777 case 0x10ec0668:
Takashi Iwaifea80fa2018-06-20 12:52:46 +02009778 err = set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
Kailang Yangda00c242010-03-19 11:23:45 +01009779 break;
9780 case 0x10ec0273:
Takashi Iwaifea80fa2018-06-20 12:52:46 +02009781 err = set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
Kailang Yangda00c242010-03-19 11:23:45 +01009782 break;
9783 }
Takashi Iwaifea80fa2018-06-20 12:52:46 +02009784 if (err < 0)
9785 goto error;
Kailang Yangcec27c82010-02-04 14:18:18 +01009786 }
Takashi Iwai2134ea42008-01-10 16:53:55 +01009787
Takashi Iwai1727a772013-01-10 09:52:52 +01009788 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01009789
Kailang Yangbc9f98a2007-04-12 13:06:07 +02009790 return 0;
Kailang Yangbc9f98a2007-04-12 13:06:07 +02009791
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02009792 error:
9793 alc_free(codec);
9794 return err;
Kailang Yangb478b992011-05-18 11:51:15 +02009795}
9796
Kailang Yangbc9f98a2007-04-12 13:06:07 +02009797/*
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009798 * ALC680 support
9799 */
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009800
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009801static int alc680_parse_auto_config(struct hda_codec *codec)
9802{
Takashi Iwai3e6179b2011-07-08 16:55:13 +02009803 return alc_parse_auto_config(codec, NULL, NULL);
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009804}
9805
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009806/*
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009807 */
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009808static int patch_alc680(struct hda_codec *codec)
9809{
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009810 int err;
9811
Takashi Iwai1f0f4b82011-06-27 10:52:59 +02009812 /* ALC680 has no aa-loopback mixer */
Takashi Iwai3de95172012-05-07 18:03:15 +02009813 err = alc_alloc_spec(codec, 0);
9814 if (err < 0)
9815 return err;
Takashi Iwai1f0f4b82011-06-27 10:52:59 +02009816
Takashi Iwai1ebec5f2011-08-15 13:21:48 +02009817 /* automatic parse from the BIOS config */
9818 err = alc680_parse_auto_config(codec);
9819 if (err < 0) {
9820 alc_free(codec);
9821 return err;
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009822 }
9823
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009824 return 0;
9825}
9826
9827/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07009828 * patch entries
9829 */
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009830static const struct hda_device_id snd_hda_id_realtek[] = {
Kailang Yang0a6f0602017-06-30 16:00:48 +08009831 HDA_CODEC_ENTRY(0x10ec0215, "ALC215", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009832 HDA_CODEC_ENTRY(0x10ec0221, "ALC221", patch_alc269),
Hui Wang2a36c162019-09-04 13:53:27 +08009833 HDA_CODEC_ENTRY(0x10ec0222, "ALC222", patch_alc269),
Kailang Yang42314302016-02-03 15:03:50 +08009834 HDA_CODEC_ENTRY(0x10ec0225, "ALC225", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009835 HDA_CODEC_ENTRY(0x10ec0231, "ALC231", patch_alc269),
9836 HDA_CODEC_ENTRY(0x10ec0233, "ALC233", patch_alc269),
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08009837 HDA_CODEC_ENTRY(0x10ec0234, "ALC234", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009838 HDA_CODEC_ENTRY(0x10ec0235, "ALC233", patch_alc269),
Kailang Yang736f20a2017-10-20 15:06:34 +08009839 HDA_CODEC_ENTRY(0x10ec0236, "ALC236", patch_alc269),
Kailang Yang7fbdcd82020-04-23 14:18:31 +08009840 HDA_CODEC_ENTRY(0x10ec0245, "ALC245", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009841 HDA_CODEC_ENTRY(0x10ec0255, "ALC255", patch_alc269),
9842 HDA_CODEC_ENTRY(0x10ec0256, "ALC256", patch_alc269),
Kailang Yangf429e7e2017-12-05 15:38:24 +08009843 HDA_CODEC_ENTRY(0x10ec0257, "ALC257", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009844 HDA_CODEC_ENTRY(0x10ec0260, "ALC260", patch_alc260),
9845 HDA_CODEC_ENTRY(0x10ec0262, "ALC262", patch_alc262),
9846 HDA_CODEC_ENTRY(0x10ec0267, "ALC267", patch_alc268),
9847 HDA_CODEC_ENTRY(0x10ec0268, "ALC268", patch_alc268),
9848 HDA_CODEC_ENTRY(0x10ec0269, "ALC269", patch_alc269),
9849 HDA_CODEC_ENTRY(0x10ec0270, "ALC270", patch_alc269),
9850 HDA_CODEC_ENTRY(0x10ec0272, "ALC272", patch_alc662),
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08009851 HDA_CODEC_ENTRY(0x10ec0274, "ALC274", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009852 HDA_CODEC_ENTRY(0x10ec0275, "ALC275", patch_alc269),
9853 HDA_CODEC_ENTRY(0x10ec0276, "ALC276", patch_alc269),
9854 HDA_CODEC_ENTRY(0x10ec0280, "ALC280", patch_alc269),
9855 HDA_CODEC_ENTRY(0x10ec0282, "ALC282", patch_alc269),
9856 HDA_CODEC_ENTRY(0x10ec0283, "ALC283", patch_alc269),
9857 HDA_CODEC_ENTRY(0x10ec0284, "ALC284", patch_alc269),
Kailang Yang0a6f0602017-06-30 16:00:48 +08009858 HDA_CODEC_ENTRY(0x10ec0285, "ALC285", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009859 HDA_CODEC_ENTRY(0x10ec0286, "ALC286", patch_alc269),
Kailang Yang630e3612020-05-27 14:10:26 +08009860 HDA_CODEC_ENTRY(0x10ec0287, "ALC287", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009861 HDA_CODEC_ENTRY(0x10ec0288, "ALC288", patch_alc269),
Kailang Yang0a6f0602017-06-30 16:00:48 +08009862 HDA_CODEC_ENTRY(0x10ec0289, "ALC289", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009863 HDA_CODEC_ENTRY(0x10ec0290, "ALC290", patch_alc269),
9864 HDA_CODEC_ENTRY(0x10ec0292, "ALC292", patch_alc269),
9865 HDA_CODEC_ENTRY(0x10ec0293, "ALC293", patch_alc269),
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08009866 HDA_CODEC_ENTRY(0x10ec0294, "ALC294", patch_alc269),
Kailang Yang7d727862016-05-24 16:46:07 +08009867 HDA_CODEC_ENTRY(0x10ec0295, "ALC295", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009868 HDA_CODEC_ENTRY(0x10ec0298, "ALC298", patch_alc269),
Kailang Yang28f1f9b2017-01-04 14:49:07 +08009869 HDA_CODEC_ENTRY(0x10ec0299, "ALC299", patch_alc269),
Kailang Yang1078bef2018-11-08 16:36:15 +08009870 HDA_CODEC_ENTRY(0x10ec0300, "ALC300", patch_alc269),
Kailang Yangf0778872019-10-24 15:13:32 +08009871 HDA_CODEC_ENTRY(0x10ec0623, "ALC623", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009872 HDA_CODEC_REV_ENTRY(0x10ec0861, 0x100340, "ALC660", patch_alc861),
9873 HDA_CODEC_ENTRY(0x10ec0660, "ALC660-VD", patch_alc861vd),
9874 HDA_CODEC_ENTRY(0x10ec0861, "ALC861", patch_alc861),
9875 HDA_CODEC_ENTRY(0x10ec0862, "ALC861-VD", patch_alc861vd),
9876 HDA_CODEC_REV_ENTRY(0x10ec0662, 0x100002, "ALC662 rev2", patch_alc882),
9877 HDA_CODEC_REV_ENTRY(0x10ec0662, 0x100101, "ALC662 rev1", patch_alc662),
9878 HDA_CODEC_REV_ENTRY(0x10ec0662, 0x100300, "ALC662 rev3", patch_alc662),
9879 HDA_CODEC_ENTRY(0x10ec0663, "ALC663", patch_alc662),
9880 HDA_CODEC_ENTRY(0x10ec0665, "ALC665", patch_alc662),
9881 HDA_CODEC_ENTRY(0x10ec0667, "ALC667", patch_alc662),
9882 HDA_CODEC_ENTRY(0x10ec0668, "ALC668", patch_alc662),
9883 HDA_CODEC_ENTRY(0x10ec0670, "ALC670", patch_alc662),
9884 HDA_CODEC_ENTRY(0x10ec0671, "ALC671", patch_alc662),
9885 HDA_CODEC_ENTRY(0x10ec0680, "ALC680", patch_alc680),
Kailang Yang6fbae352016-05-30 16:44:20 +08009886 HDA_CODEC_ENTRY(0x10ec0700, "ALC700", patch_alc269),
9887 HDA_CODEC_ENTRY(0x10ec0701, "ALC701", patch_alc269),
9888 HDA_CODEC_ENTRY(0x10ec0703, "ALC703", patch_alc269),
Kailang Yang83629532019-05-02 16:03:26 +08009889 HDA_CODEC_ENTRY(0x10ec0711, "ALC711", patch_alc269),
Kailang Yang78f4f7c2016-06-07 11:31:34 +08009890 HDA_CODEC_ENTRY(0x10ec0867, "ALC891", patch_alc662),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009891 HDA_CODEC_ENTRY(0x10ec0880, "ALC880", patch_alc880),
9892 HDA_CODEC_ENTRY(0x10ec0882, "ALC882", patch_alc882),
9893 HDA_CODEC_ENTRY(0x10ec0883, "ALC883", patch_alc882),
9894 HDA_CODEC_REV_ENTRY(0x10ec0885, 0x100101, "ALC889A", patch_alc882),
9895 HDA_CODEC_REV_ENTRY(0x10ec0885, 0x100103, "ALC889A", patch_alc882),
9896 HDA_CODEC_ENTRY(0x10ec0885, "ALC885", patch_alc882),
9897 HDA_CODEC_ENTRY(0x10ec0887, "ALC887", patch_alc882),
9898 HDA_CODEC_REV_ENTRY(0x10ec0888, 0x100101, "ALC1200", patch_alc882),
9899 HDA_CODEC_ENTRY(0x10ec0888, "ALC888", patch_alc882),
9900 HDA_CODEC_ENTRY(0x10ec0889, "ALC889", patch_alc882),
9901 HDA_CODEC_ENTRY(0x10ec0892, "ALC892", patch_alc662),
9902 HDA_CODEC_ENTRY(0x10ec0899, "ALC898", patch_alc882),
9903 HDA_CODEC_ENTRY(0x10ec0900, "ALC1150", patch_alc882),
Kailang Yang6d9ffcf2020-01-03 16:24:06 +08009904 HDA_CODEC_ENTRY(0x10ec0b00, "ALCS1200A", patch_alc882),
Kailang Yang65553b12017-07-11 15:15:47 +08009905 HDA_CODEC_ENTRY(0x10ec1168, "ALC1220", patch_alc882),
Kailang Yanga535ad52017-01-16 16:59:26 +08009906 HDA_CODEC_ENTRY(0x10ec1220, "ALC1220", patch_alc882),
Linus Torvalds1da177e2005-04-16 15:20:36 -07009907 {} /* terminator */
9908};
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009909MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_realtek);
Takashi Iwai1289e9e2008-11-27 15:47:11 +01009910
9911MODULE_LICENSE("GPL");
9912MODULE_DESCRIPTION("Realtek HD-audio codec");
9913
Takashi Iwaid8a766a2015-02-17 15:25:37 +01009914static struct hda_codec_driver realtek_driver = {
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009915 .id = snd_hda_id_realtek,
Takashi Iwai1289e9e2008-11-27 15:47:11 +01009916};
9917
Takashi Iwaid8a766a2015-02-17 15:25:37 +01009918module_hda_codec_driver(realtek_driver);