blob: 019239190f6d0ba79dd1d77cd34bdbd335eb86ee [file] [log] [blame]
Thomas Gleixnerd0fa1172019-05-20 19:07:57 +02001// SPDX-License-Identifier: GPL-2.0-or-later
Linus Torvalds1da177e2005-04-16 15:20:36 -07002/*
3 * Universal Interface for Intel High Definition Audio Codec
4 *
Takashi Iwai1d045db2011-07-07 18:23:21 +02005 * HD audio interface patch for Realtek ALC codecs
Linus Torvalds1da177e2005-04-16 15:20:36 -07006 *
Kailang Yangdf694da2005-12-05 19:42:22 +01007 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
8 * PeiSen Hou <pshou@realtek.com.tw>
Linus Torvalds1da177e2005-04-16 15:20:36 -07009 * Takashi Iwai <tiwai@suse.de>
Jonathan Woithe409a3e92012-03-27 13:01:01 +103010 * Jonathan Woithe <jwoithe@just42.net>
Linus Torvalds1da177e2005-04-16 15:20:36 -070011 */
12
Linus Torvalds1da177e2005-04-16 15:20:36 -070013#include <linux/init.h>
14#include <linux/delay.h>
15#include <linux/slab.h>
16#include <linux/pci.h>
Takashi Iwai08fb0d02013-01-10 17:33:58 +010017#include <linux/dmi.h>
Paul Gortmakerda155d52011-07-15 12:38:28 -040018#include <linux/module.h>
David Henningsson33f4acd2015-01-07 15:50:13 +010019#include <linux/input.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070020#include <sound/core.h>
Kailang Yang9ad0e492010-09-14 23:22:00 +020021#include <sound/jack.h>
Pierre-Louis Bossartbe57bff2018-08-22 15:24:57 -050022#include <sound/hda_codec.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070023#include "hda_local.h"
Takashi Iwai23d30f22012-05-07 17:17:32 +020024#include "hda_auto_parser.h"
Takashi Iwai1835a0f2011-10-27 22:12:46 +020025#include "hda_jack.h"
Takashi Iwai08c189f2012-12-19 15:22:24 +010026#include "hda_generic.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070027
Takashi Iwaicd63a5f2013-07-05 12:13:59 +020028/* keep halting ALC5505 DSP, for power saving */
29#define HALT_REALTEK_ALC5505
30
Takashi Iwai4a79ba32009-04-22 16:31:35 +020031/* extra amp-initialization sequence types */
32enum {
Takashi Iwai1c76aa52018-06-21 16:37:54 +020033 ALC_INIT_UNDEFINED,
Takashi Iwai4a79ba32009-04-22 16:31:35 +020034 ALC_INIT_NONE,
35 ALC_INIT_DEFAULT,
Takashi Iwai4a79ba32009-04-22 16:31:35 +020036};
37
David Henningsson73bdd592013-04-15 15:44:14 +020038enum {
39 ALC_HEADSET_MODE_UNKNOWN,
40 ALC_HEADSET_MODE_UNPLUGGED,
41 ALC_HEADSET_MODE_HEADSET,
42 ALC_HEADSET_MODE_MIC,
43 ALC_HEADSET_MODE_HEADPHONE,
44};
45
46enum {
47 ALC_HEADSET_TYPE_UNKNOWN,
48 ALC_HEADSET_TYPE_CTIA,
49 ALC_HEADSET_TYPE_OMTP,
50};
51
Hui Wangc7b60a82015-12-28 11:35:25 +080052enum {
53 ALC_KEY_MICMUTE_INDEX,
54};
55
Kailang Yangda00c242010-03-19 11:23:45 +010056struct alc_customize_define {
57 unsigned int sku_cfg;
58 unsigned char port_connectivity;
59 unsigned char check_sum;
60 unsigned char customization;
61 unsigned char external_amp;
62 unsigned int enable_pcbeep:1;
63 unsigned int platform_type:1;
64 unsigned int swap:1;
65 unsigned int override:1;
David Henningsson90622912010-10-14 14:50:18 +020066 unsigned int fixup:1; /* Means that this sku is set by driver, not read from hw */
Kailang Yangda00c242010-03-19 11:23:45 +010067};
68
Linus Torvalds1da177e2005-04-16 15:20:36 -070069struct alc_spec {
Takashi Iwai08c189f2012-12-19 15:22:24 +010070 struct hda_gen_spec gen; /* must be at head */
Takashi Iwai23d30f22012-05-07 17:17:32 +020071
Linus Torvalds1da177e2005-04-16 15:20:36 -070072 /* codec parameterization */
Kailang Yangda00c242010-03-19 11:23:45 +010073 struct alc_customize_define cdefine;
Takashi Iwai08c189f2012-12-19 15:22:24 +010074 unsigned int parse_flags; /* flag for snd_hda_parse_pin_defcfg() */
75
Takashi Iwai5579cd62018-06-19 22:22:41 +020076 /* GPIO bits */
77 unsigned int gpio_mask;
78 unsigned int gpio_dir;
79 unsigned int gpio_data;
Takashi Iwai215c8502018-06-19 22:34:26 +020080 bool gpio_write_delay; /* add a delay before writing gpio_data */
Takashi Iwai5579cd62018-06-19 22:22:41 +020081
Takashi Iwai08fb0d02013-01-10 17:33:58 +010082 /* mute LED for HP laptops, see alc269_fixup_mic_mute_hook() */
83 int mute_led_polarity;
84 hda_nid_t mute_led_nid;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +080085 hda_nid_t cap_mute_led_nid;
Takashi Iwai08fb0d02013-01-10 17:33:58 +010086
Takashi Iwai0f32fd192014-11-19 12:16:14 +010087 unsigned int gpio_mute_led_mask;
88 unsigned int gpio_mic_led_mask;
Kailang Yang431e76c2020-04-07 14:40:20 +080089 unsigned int mute_led_coef_idx;
90 unsigned int mute_led_coefbit_mask;
91 unsigned int mute_led_coefbit_on;
92 unsigned int mute_led_coefbit_off;
93 unsigned int mic_led_coef_idx;
94 unsigned int mic_led_coefbit_mask;
95 unsigned int mic_led_coefbit_on;
96 unsigned int mic_led_coefbit_off;
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +010097
David Henningsson73bdd592013-04-15 15:44:14 +020098 hda_nid_t headset_mic_pin;
99 hda_nid_t headphone_mic_pin;
100 int current_headset_mode;
101 int current_headset_type;
102
Takashi Iwaiae6b8132006-03-03 16:47:17 +0100103 /* hooks */
104 void (*init_hook)(struct hda_codec *codec);
Takashi Iwai83012a72012-08-24 18:38:08 +0200105#ifdef CONFIG_PM
Daniel T Chenc97259d2009-12-27 18:52:08 -0500106 void (*power_hook)(struct hda_codec *codec);
Hector Martinf5de24b2009-12-20 22:51:31 +0100107#endif
Takashi Iwai1c7161532011-04-07 10:37:16 +0200108 void (*shutup)(struct hda_codec *codec);
Takashi Iwai70a09762015-12-15 14:59:58 +0100109 void (*reboot_notify)(struct hda_codec *codec);
Takashi Iwaid922b512011-04-28 12:18:53 +0200110
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200111 int init_amp;
Takashi Iwaid433a672010-09-20 15:11:54 +0200112 int codec_variant; /* flag for other variants */
Kailang Yang97a26572013-11-29 00:35:26 -0500113 unsigned int has_alc5505_dsp:1;
114 unsigned int no_depop_delay:1;
Kailang Yang693abe12019-01-29 15:38:21 +0800115 unsigned int done_hp_init:1;
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +0100116 unsigned int no_shutup_pins:1;
Kailang Yangd3ba58b2019-05-06 15:09:42 +0800117 unsigned int ultra_low_power:1;
Hui Wang476c02e2020-03-29 16:20:18 +0800118 unsigned int has_hs_key:1;
Takashi Iwaie64f14f2009-01-20 18:32:55 +0100119
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200120 /* for PLL fix */
121 hda_nid_t pll_nid;
122 unsigned int pll_coef_idx, pll_coef_bit;
Takashi Iwai1bb7e432011-10-17 16:50:59 +0200123 unsigned int coef0;
David Henningsson33f4acd2015-01-07 15:50:13 +0100124 struct input_dev *kb_dev;
Hui Wangc7b60a82015-12-28 11:35:25 +0800125 u8 alc_mute_keycode_map[1];
Kailang Yangdf694da2005-12-05 19:42:22 +0100126};
127
Takashi Iwai23f0c042009-02-26 13:03:58 +0100128/*
Takashi Iwaif2a227c2014-08-18 13:35:22 +0200129 * COEF access helper functions
130 */
131
132static int alc_read_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
133 unsigned int coef_idx)
134{
135 unsigned int val;
136
137 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, coef_idx);
138 val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PROC_COEF, 0);
139 return val;
140}
141
142#define alc_read_coef_idx(codec, coef_idx) \
143 alc_read_coefex_idx(codec, 0x20, coef_idx)
144
145static void alc_write_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
146 unsigned int coef_idx, unsigned int coef_val)
147{
148 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, coef_idx);
149 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PROC_COEF, coef_val);
150}
151
152#define alc_write_coef_idx(codec, coef_idx, coef_val) \
153 alc_write_coefex_idx(codec, 0x20, coef_idx, coef_val)
154
Takashi Iwai98b24882014-08-18 13:47:50 +0200155static void alc_update_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
156 unsigned int coef_idx, unsigned int mask,
157 unsigned int bits_set)
158{
159 unsigned int val = alc_read_coefex_idx(codec, nid, coef_idx);
160
161 if (val != -1)
162 alc_write_coefex_idx(codec, nid, coef_idx,
163 (val & ~mask) | bits_set);
164}
165
166#define alc_update_coef_idx(codec, coef_idx, mask, bits_set) \
167 alc_update_coefex_idx(codec, 0x20, coef_idx, mask, bits_set)
168
Takashi Iwaif2a227c2014-08-18 13:35:22 +0200169/* a special bypass for COEF 0; read the cached value at the second time */
170static unsigned int alc_get_coef0(struct hda_codec *codec)
171{
172 struct alc_spec *spec = codec->spec;
173
174 if (!spec->coef0)
175 spec->coef0 = alc_read_coef_idx(codec, 0);
176 return spec->coef0;
177}
178
Takashi Iwai54db6c32014-08-18 15:11:19 +0200179/* coef writes/updates batch */
180struct coef_fw {
181 unsigned char nid;
182 unsigned char idx;
183 unsigned short mask;
184 unsigned short val;
185};
186
187#define UPDATE_COEFEX(_nid, _idx, _mask, _val) \
188 { .nid = (_nid), .idx = (_idx), .mask = (_mask), .val = (_val) }
189#define WRITE_COEFEX(_nid, _idx, _val) UPDATE_COEFEX(_nid, _idx, -1, _val)
190#define WRITE_COEF(_idx, _val) WRITE_COEFEX(0x20, _idx, _val)
191#define UPDATE_COEF(_idx, _mask, _val) UPDATE_COEFEX(0x20, _idx, _mask, _val)
192
193static void alc_process_coef_fw(struct hda_codec *codec,
194 const struct coef_fw *fw)
195{
196 for (; fw->nid; fw++) {
197 if (fw->mask == (unsigned short)-1)
198 alc_write_coefex_idx(codec, fw->nid, fw->idx, fw->val);
199 else
200 alc_update_coefex_idx(codec, fw->nid, fw->idx,
201 fw->mask, fw->val);
202 }
203}
204
Takashi Iwaif2a227c2014-08-18 13:35:22 +0200205/*
Takashi Iwai1d045db2011-07-07 18:23:21 +0200206 * GPIO setup tables, used in initialization
Kailang Yangdf694da2005-12-05 19:42:22 +0100207 */
Takashi Iwai5579cd62018-06-19 22:22:41 +0200208
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200209/* Enable GPIO mask and set output */
Takashi Iwai5579cd62018-06-19 22:22:41 +0200210static void alc_setup_gpio(struct hda_codec *codec, unsigned int mask)
211{
212 struct alc_spec *spec = codec->spec;
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200213
Takashi Iwai5579cd62018-06-19 22:22:41 +0200214 spec->gpio_mask |= mask;
215 spec->gpio_dir |= mask;
216 spec->gpio_data |= mask;
217}
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200218
Takashi Iwai5579cd62018-06-19 22:22:41 +0200219static void alc_write_gpio_data(struct hda_codec *codec)
220{
221 struct alc_spec *spec = codec->spec;
222
223 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
224 spec->gpio_data);
225}
226
Takashi Iwaiaaf312d2018-06-19 22:28:22 +0200227static void alc_update_gpio_data(struct hda_codec *codec, unsigned int mask,
228 bool on)
229{
230 struct alc_spec *spec = codec->spec;
231 unsigned int oldval = spec->gpio_data;
232
233 if (on)
234 spec->gpio_data |= mask;
235 else
236 spec->gpio_data &= ~mask;
237 if (oldval != spec->gpio_data)
238 alc_write_gpio_data(codec);
239}
240
Takashi Iwai5579cd62018-06-19 22:22:41 +0200241static void alc_write_gpio(struct hda_codec *codec)
242{
243 struct alc_spec *spec = codec->spec;
244
245 if (!spec->gpio_mask)
246 return;
247
248 snd_hda_codec_write(codec, codec->core.afg, 0,
249 AC_VERB_SET_GPIO_MASK, spec->gpio_mask);
250 snd_hda_codec_write(codec, codec->core.afg, 0,
251 AC_VERB_SET_GPIO_DIRECTION, spec->gpio_dir);
Takashi Iwai215c8502018-06-19 22:34:26 +0200252 if (spec->gpio_write_delay)
253 msleep(1);
Takashi Iwai5579cd62018-06-19 22:22:41 +0200254 alc_write_gpio_data(codec);
255}
256
257static void alc_fixup_gpio(struct hda_codec *codec, int action,
258 unsigned int mask)
259{
260 if (action == HDA_FIXUP_ACT_PRE_PROBE)
261 alc_setup_gpio(codec, mask);
262}
263
264static void alc_fixup_gpio1(struct hda_codec *codec,
265 const struct hda_fixup *fix, int action)
266{
267 alc_fixup_gpio(codec, action, 0x01);
268}
269
270static void alc_fixup_gpio2(struct hda_codec *codec,
271 const struct hda_fixup *fix, int action)
272{
273 alc_fixup_gpio(codec, action, 0x02);
274}
275
276static void alc_fixup_gpio3(struct hda_codec *codec,
277 const struct hda_fixup *fix, int action)
278{
279 alc_fixup_gpio(codec, action, 0x03);
280}
Kailang Yangbdd148a2007-05-08 15:19:08 +0200281
Takashi Iwaiae065f12018-06-19 23:00:03 +0200282static void alc_fixup_gpio4(struct hda_codec *codec,
283 const struct hda_fixup *fix, int action)
284{
285 alc_fixup_gpio(codec, action, 0x04);
286}
287
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200288/*
289 * Fix hardware PLL issue
290 * On some codecs, the analog PLL gating control must be off while
291 * the default value is 1.
292 */
293static void alc_fix_pll(struct hda_codec *codec)
294{
295 struct alc_spec *spec = codec->spec;
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200296
Takashi Iwai98b24882014-08-18 13:47:50 +0200297 if (spec->pll_nid)
298 alc_update_coefex_idx(codec, spec->pll_nid, spec->pll_coef_idx,
299 1 << spec->pll_coef_bit, 0);
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200300}
301
302static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
303 unsigned int coef_idx, unsigned int coef_bit)
304{
305 struct alc_spec *spec = codec->spec;
306 spec->pll_nid = nid;
307 spec->pll_coef_idx = coef_idx;
308 spec->pll_coef_bit = coef_bit;
309 alc_fix_pll(codec);
310}
311
Takashi Iwaicf5a2272012-02-20 16:31:07 +0100312/* update the master volume per volume-knob's unsol event */
Takashi Iwai1a4f69d2014-09-11 15:22:46 +0200313static void alc_update_knob_master(struct hda_codec *codec,
314 struct hda_jack_callback *jack)
Takashi Iwaicf5a2272012-02-20 16:31:07 +0100315{
316 unsigned int val;
317 struct snd_kcontrol *kctl;
318 struct snd_ctl_elem_value *uctl;
319
320 kctl = snd_hda_find_mixer_ctl(codec, "Master Playback Volume");
321 if (!kctl)
322 return;
323 uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
324 if (!uctl)
325 return;
Takashi Iwai2ebab402016-02-09 10:23:52 +0100326 val = snd_hda_codec_read(codec, jack->nid, 0,
Takashi Iwaicf5a2272012-02-20 16:31:07 +0100327 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
328 val &= HDA_AMP_VOLMASK;
329 uctl->value.integer.value[0] = val;
330 uctl->value.integer.value[1] = val;
331 kctl->put(kctl, uctl);
332 kfree(uctl);
333}
334
David Henningsson29adc4b2012-09-25 11:31:00 +0200335static void alc880_unsol_event(struct hda_codec *codec, unsigned int res)
Takashi Iwaif21d78e2012-01-19 12:10:29 +0100336{
David Henningsson29adc4b2012-09-25 11:31:00 +0200337 /* For some reason, the res given from ALC880 is broken.
338 Here we adjust it properly. */
339 snd_hda_jack_unsol_event(codec, res >> 2);
Takashi Iwaif21d78e2012-01-19 12:10:29 +0100340}
341
Kailang Yang394c97f2014-11-12 17:38:08 +0800342/* Change EAPD to verb control */
343static void alc_fill_eapd_coef(struct hda_codec *codec)
344{
345 int coef;
346
347 coef = alc_get_coef0(codec);
348
Takashi Iwai7639a062015-03-03 10:07:24 +0100349 switch (codec->core.vendor_id) {
Kailang Yang394c97f2014-11-12 17:38:08 +0800350 case 0x10ec0262:
351 alc_update_coef_idx(codec, 0x7, 0, 1<<5);
352 break;
353 case 0x10ec0267:
354 case 0x10ec0268:
355 alc_update_coef_idx(codec, 0x7, 0, 1<<13);
356 break;
357 case 0x10ec0269:
358 if ((coef & 0x00f0) == 0x0010)
359 alc_update_coef_idx(codec, 0xd, 0, 1<<14);
360 if ((coef & 0x00f0) == 0x0020)
361 alc_update_coef_idx(codec, 0x4, 1<<15, 0);
362 if ((coef & 0x00f0) == 0x0030)
363 alc_update_coef_idx(codec, 0x10, 1<<9, 0);
364 break;
365 case 0x10ec0280:
366 case 0x10ec0284:
367 case 0x10ec0290:
368 case 0x10ec0292:
369 alc_update_coef_idx(codec, 0x4, 1<<15, 0);
370 break;
Kailang Yang42314302016-02-03 15:03:50 +0800371 case 0x10ec0225:
Takashi Iwai44be77c2017-12-27 08:53:59 +0100372 case 0x10ec0295:
373 case 0x10ec0299:
374 alc_update_coef_idx(codec, 0x67, 0xf000, 0x3000);
375 /* fallthrough */
376 case 0x10ec0215:
Kailang Yang394c97f2014-11-12 17:38:08 +0800377 case 0x10ec0233:
Kailang Yangea04a1d2018-04-25 15:31:52 +0800378 case 0x10ec0235:
Thomas Hebbc4473742020-03-30 12:09:38 -0400379 case 0x10ec0236:
Kailang Yang394c97f2014-11-12 17:38:08 +0800380 case 0x10ec0255:
Thomas Hebbc4473742020-03-30 12:09:38 -0400381 case 0x10ec0256:
Kailang Yangf429e7e2017-12-05 15:38:24 +0800382 case 0x10ec0257:
Kailang Yang394c97f2014-11-12 17:38:08 +0800383 case 0x10ec0282:
384 case 0x10ec0283:
385 case 0x10ec0286:
386 case 0x10ec0288:
Kailang Yang0a6f0602017-06-30 16:00:48 +0800387 case 0x10ec0285:
Kailang Yang506b62c2014-12-18 17:07:44 +0800388 case 0x10ec0298:
Kailang Yang0a6f0602017-06-30 16:00:48 +0800389 case 0x10ec0289:
Kailang Yang1078bef2018-11-08 16:36:15 +0800390 case 0x10ec0300:
Kailang Yang394c97f2014-11-12 17:38:08 +0800391 alc_update_coef_idx(codec, 0x10, 1<<9, 0);
392 break;
Kailang Yang3aabf942017-11-08 15:28:33 +0800393 case 0x10ec0275:
394 alc_update_coef_idx(codec, 0xe, 0, 1<<0);
395 break;
Kailang Yang394c97f2014-11-12 17:38:08 +0800396 case 0x10ec0293:
397 alc_update_coef_idx(codec, 0xa, 1<<13, 0);
398 break;
Kailang Yangdcd4f0d2016-05-04 15:50:18 +0800399 case 0x10ec0234:
400 case 0x10ec0274:
401 case 0x10ec0294:
Kailang Yang6fbae352016-05-30 16:44:20 +0800402 case 0x10ec0700:
403 case 0x10ec0701:
404 case 0x10ec0703:
Kailang Yang83629532019-05-02 16:03:26 +0800405 case 0x10ec0711:
Kailang Yangdcd4f0d2016-05-04 15:50:18 +0800406 alc_update_coef_idx(codec, 0x10, 1<<15, 0);
407 break;
Kailang Yang394c97f2014-11-12 17:38:08 +0800408 case 0x10ec0662:
409 if ((coef & 0x00f0) == 0x0030)
410 alc_update_coef_idx(codec, 0x4, 1<<10, 0); /* EAPD Ctrl */
411 break;
412 case 0x10ec0272:
413 case 0x10ec0273:
414 case 0x10ec0663:
415 case 0x10ec0665:
416 case 0x10ec0670:
417 case 0x10ec0671:
418 case 0x10ec0672:
419 alc_update_coef_idx(codec, 0xd, 0, 1<<14); /* EAPD Ctrl */
420 break;
Kailang Yang9194a1e2020-01-07 17:22:19 +0800421 case 0x10ec0222:
Kailang Yangf0778872019-10-24 15:13:32 +0800422 case 0x10ec0623:
423 alc_update_coef_idx(codec, 0x19, 1<<13, 0);
424 break;
Kailang Yang394c97f2014-11-12 17:38:08 +0800425 case 0x10ec0668:
426 alc_update_coef_idx(codec, 0x7, 3<<13, 0);
427 break;
428 case 0x10ec0867:
429 alc_update_coef_idx(codec, 0x4, 1<<10, 0);
430 break;
431 case 0x10ec0888:
432 if ((coef & 0x00f0) == 0x0020 || (coef & 0x00f0) == 0x0030)
433 alc_update_coef_idx(codec, 0x7, 1<<5, 0);
434 break;
435 case 0x10ec0892:
436 alc_update_coef_idx(codec, 0x7, 1<<5, 0);
437 break;
438 case 0x10ec0899:
439 case 0x10ec0900:
Kailang Yang6d9ffcf2020-01-03 16:24:06 +0800440 case 0x10ec0b00:
Kailang Yang65553b12017-07-11 15:15:47 +0800441 case 0x10ec1168:
Kailang Yanga535ad52017-01-16 16:59:26 +0800442 case 0x10ec1220:
Kailang Yang394c97f2014-11-12 17:38:08 +0800443 alc_update_coef_idx(codec, 0x7, 1<<1, 0);
444 break;
445 }
446}
447
Kailang Yangf9423e72008-05-27 12:32:25 +0200448/* additional initialization for ALC888 variants */
449static void alc888_coef_init(struct hda_codec *codec)
450{
Kailang Yang1df88742014-10-29 16:10:13 +0800451 switch (alc_get_coef0(codec) & 0x00f0) {
452 /* alc888-VA */
453 case 0x00:
454 /* alc888-VB */
455 case 0x10:
456 alc_update_coef_idx(codec, 7, 0, 0x2030); /* Turn EAPD to High */
457 break;
458 }
Jaroslav Kysela87a8c372009-07-23 10:58:29 +0200459}
460
Takashi Iwai3fb4a502010-01-19 15:46:37 +0100461/* turn on/off EAPD control (only if available) */
462static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
463{
464 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
465 return;
466 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
467 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
468 on ? 2 : 0);
469}
470
Takashi Iwai691f1fc2011-04-07 10:31:43 +0200471/* turn on/off EAPD controls of the codec */
472static void alc_auto_setup_eapd(struct hda_codec *codec, bool on)
473{
474 /* We currently only handle front, HP */
Michał Mirosławcaf3c042020-01-03 10:23:48 +0100475 static const hda_nid_t pins[] = {
Hui Wangaf95b412015-03-26 17:14:55 +0800476 0x0f, 0x10, 0x14, 0x15, 0x17, 0
Takashi Iwai39fa84e2011-06-27 15:28:57 +0200477 };
Michał Mirosławcaf3c042020-01-03 10:23:48 +0100478 const hda_nid_t *p;
Takashi Iwai39fa84e2011-06-27 15:28:57 +0200479 for (p = pins; *p; p++)
480 set_eapd(codec, *p, on);
Takashi Iwai691f1fc2011-04-07 10:31:43 +0200481}
482
Kailang Yangdad31972019-05-10 16:28:57 +0800483static int find_ext_mic_pin(struct hda_codec *codec);
484
485static void alc_headset_mic_no_shutup(struct hda_codec *codec)
486{
487 const struct hda_pincfg *pin;
488 int mic_pin = find_ext_mic_pin(codec);
489 int i;
490
491 /* don't shut up pins when unloading the driver; otherwise it breaks
492 * the default pin setup at the next load of the driver
493 */
494 if (codec->bus->shutdown)
495 return;
496
497 snd_array_for_each(&codec->init_pins, i, pin) {
498 /* use read here for syncing after issuing each verb */
499 if (pin->nid != mic_pin)
500 snd_hda_codec_read(codec, pin->nid, 0,
501 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
502 }
503
504 codec->pins_shutup = 1;
505}
506
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +0100507static void alc_shutup_pins(struct hda_codec *codec)
508{
509 struct alc_spec *spec = codec->spec;
510
Kailang Yangdad31972019-05-10 16:28:57 +0800511 switch (codec->core.vendor_id) {
Kailang Yang66c5d712019-12-09 15:56:15 +0800512 case 0x10ec0283:
Kailang Yangdad31972019-05-10 16:28:57 +0800513 case 0x10ec0286:
514 case 0x10ec0288:
515 case 0x10ec0298:
516 alc_headset_mic_no_shutup(codec);
517 break;
518 default:
519 if (!spec->no_shutup_pins)
520 snd_hda_shutup_pins(codec);
521 break;
522 }
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +0100523}
524
Takashi Iwai1c7161532011-04-07 10:37:16 +0200525/* generic shutup callback;
Lars-Peter Clausen4ce8e6a2016-11-08 15:48:06 +0100526 * just turning off EAPD and a little pause for avoiding pop-noise
Takashi Iwai1c7161532011-04-07 10:37:16 +0200527 */
528static void alc_eapd_shutup(struct hda_codec *codec)
529{
Kailang Yang97a26572013-11-29 00:35:26 -0500530 struct alc_spec *spec = codec->spec;
531
Takashi Iwai1c7161532011-04-07 10:37:16 +0200532 alc_auto_setup_eapd(codec, false);
Kailang Yang97a26572013-11-29 00:35:26 -0500533 if (!spec->no_depop_delay)
534 msleep(200);
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +0100535 alc_shutup_pins(codec);
Takashi Iwai1c7161532011-04-07 10:37:16 +0200536}
537
Takashi Iwai1d045db2011-07-07 18:23:21 +0200538/* generic EAPD initialization */
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200539static void alc_auto_init_amp(struct hda_codec *codec, int type)
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200540{
Takashi Iwai39fa84e2011-06-27 15:28:57 +0200541 alc_auto_setup_eapd(codec, true);
Takashi Iwai5579cd62018-06-19 22:22:41 +0200542 alc_write_gpio(codec);
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200543 switch (type) {
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200544 case ALC_INIT_DEFAULT:
Takashi Iwai7639a062015-03-03 10:07:24 +0100545 switch (codec->core.vendor_id) {
Kailang Yangc9b58002007-10-16 14:30:01 +0200546 case 0x10ec0260:
Takashi Iwai98b24882014-08-18 13:47:50 +0200547 alc_update_coefex_idx(codec, 0x1a, 7, 0, 0x2010);
Kailang Yangc9b58002007-10-16 14:30:01 +0200548 break;
Kailang Yangc9b58002007-10-16 14:30:01 +0200549 case 0x10ec0880:
550 case 0x10ec0882:
551 case 0x10ec0883:
552 case 0x10ec0885:
Kailang Yang1df88742014-10-29 16:10:13 +0800553 alc_update_coef_idx(codec, 7, 0, 0x2030);
Kailang Yangc9b58002007-10-16 14:30:01 +0200554 break;
Kailang Yangf9423e72008-05-27 12:32:25 +0200555 case 0x10ec0888:
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200556 alc888_coef_init(codec);
Kailang Yangf9423e72008-05-27 12:32:25 +0200557 break;
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200558 }
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200559 break;
560 }
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200561}
Kailang Yangea1fb292008-08-26 12:58:38 +0200562
Takashi Iwai35a39f92019-02-01 11:19:50 +0100563/* get a primary headphone pin if available */
564static hda_nid_t alc_get_hp_pin(struct alc_spec *spec)
565{
566 if (spec->gen.autocfg.hp_pins[0])
567 return spec->gen.autocfg.hp_pins[0];
568 if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
569 return spec->gen.autocfg.line_out_pins[0];
570 return 0;
571}
Takashi Iwai1d045db2011-07-07 18:23:21 +0200572
573/*
574 * Realtek SSID verification
575 */
576
David Henningsson90622912010-10-14 14:50:18 +0200577/* Could be any non-zero and even value. When used as fixup, tells
578 * the driver to ignore any present sku defines.
579 */
580#define ALC_FIXUP_SKU_IGNORE (2)
581
Takashi Iwai23d30f22012-05-07 17:17:32 +0200582static void alc_fixup_sku_ignore(struct hda_codec *codec,
583 const struct hda_fixup *fix, int action)
584{
585 struct alc_spec *spec = codec->spec;
586 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
587 spec->cdefine.fixup = 1;
588 spec->cdefine.sku_cfg = ALC_FIXUP_SKU_IGNORE;
589 }
590}
591
Mengdong Linb5c66112013-11-29 00:35:35 -0500592static void alc_fixup_no_depop_delay(struct hda_codec *codec,
593 const struct hda_fixup *fix, int action)
594{
595 struct alc_spec *spec = codec->spec;
596
Mengdong Lin84d2dc32013-12-02 22:26:03 -0500597 if (action == HDA_FIXUP_ACT_PROBE) {
Mengdong Linb5c66112013-11-29 00:35:35 -0500598 spec->no_depop_delay = 1;
Mengdong Lin84d2dc32013-12-02 22:26:03 -0500599 codec->depop_delay = 0;
600 }
Mengdong Linb5c66112013-11-29 00:35:35 -0500601}
602
Kailang Yangda00c242010-03-19 11:23:45 +0100603static int alc_auto_parse_customize_define(struct hda_codec *codec)
604{
605 unsigned int ass, tmp, i;
Takashi Iwai7fb56222010-03-22 17:09:47 +0100606 unsigned nid = 0;
Kailang Yangda00c242010-03-19 11:23:45 +0100607 struct alc_spec *spec = codec->spec;
608
Takashi Iwaib6cbe512010-07-28 17:43:36 +0200609 spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
610
David Henningsson90622912010-10-14 14:50:18 +0200611 if (spec->cdefine.fixup) {
612 ass = spec->cdefine.sku_cfg;
613 if (ass == ALC_FIXUP_SKU_IGNORE)
614 return -1;
615 goto do_sku;
616 }
617
Takashi Iwai5100cd02014-02-15 10:03:19 +0100618 if (!codec->bus->pci)
619 return -1;
Takashi Iwai7639a062015-03-03 10:07:24 +0100620 ass = codec->core.subsystem_id & 0xffff;
Takashi Iwaib6cbe512010-07-28 17:43:36 +0200621 if (ass != codec->bus->pci->subsystem_device && (ass & 1))
Kailang Yangda00c242010-03-19 11:23:45 +0100622 goto do_sku;
623
624 nid = 0x1d;
Takashi Iwai7639a062015-03-03 10:07:24 +0100625 if (codec->core.vendor_id == 0x10ec0260)
Kailang Yangda00c242010-03-19 11:23:45 +0100626 nid = 0x17;
627 ass = snd_hda_codec_get_pincfg(codec, nid);
628
629 if (!(ass & 1)) {
Takashi Iwai4e76a882014-02-25 12:21:03 +0100630 codec_info(codec, "%s: SKU not ready 0x%08x\n",
Takashi Iwai7639a062015-03-03 10:07:24 +0100631 codec->core.chip_name, ass);
Kailang Yangda00c242010-03-19 11:23:45 +0100632 return -1;
633 }
634
635 /* check sum */
636 tmp = 0;
637 for (i = 1; i < 16; i++) {
638 if ((ass >> i) & 1)
639 tmp++;
640 }
641 if (((ass >> 16) & 0xf) != tmp)
642 return -1;
643
644 spec->cdefine.port_connectivity = ass >> 30;
645 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
646 spec->cdefine.check_sum = (ass >> 16) & 0xf;
647 spec->cdefine.customization = ass >> 8;
648do_sku:
649 spec->cdefine.sku_cfg = ass;
650 spec->cdefine.external_amp = (ass & 0x38) >> 3;
651 spec->cdefine.platform_type = (ass & 0x4) >> 2;
652 spec->cdefine.swap = (ass & 0x2) >> 1;
653 spec->cdefine.override = ass & 0x1;
654
Takashi Iwai4e76a882014-02-25 12:21:03 +0100655 codec_dbg(codec, "SKU: Nid=0x%x sku_cfg=0x%08x\n",
Kailang Yangda00c242010-03-19 11:23:45 +0100656 nid, spec->cdefine.sku_cfg);
Takashi Iwai4e76a882014-02-25 12:21:03 +0100657 codec_dbg(codec, "SKU: port_connectivity=0x%x\n",
Kailang Yangda00c242010-03-19 11:23:45 +0100658 spec->cdefine.port_connectivity);
Takashi Iwai4e76a882014-02-25 12:21:03 +0100659 codec_dbg(codec, "SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
660 codec_dbg(codec, "SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
661 codec_dbg(codec, "SKU: customization=0x%08x\n", spec->cdefine.customization);
662 codec_dbg(codec, "SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
663 codec_dbg(codec, "SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
664 codec_dbg(codec, "SKU: swap=0x%x\n", spec->cdefine.swap);
665 codec_dbg(codec, "SKU: override=0x%x\n", spec->cdefine.override);
Kailang Yangda00c242010-03-19 11:23:45 +0100666
667 return 0;
668}
669
Takashi Iwai08c189f2012-12-19 15:22:24 +0100670/* return the position of NID in the list, or -1 if not found */
671static int find_idx_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
672{
673 int i;
674 for (i = 0; i < nums; i++)
675 if (list[i] == nid)
676 return i;
677 return -1;
678}
Takashi Iwai1d045db2011-07-07 18:23:21 +0200679/* return true if the given NID is found in the list */
Takashi Iwai3af9ee62011-06-27 12:34:01 +0200680static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
681{
Takashi Iwai21268962011-07-07 15:01:13 +0200682 return find_idx_in_nid_list(nid, list, nums) >= 0;
Takashi Iwai3af9ee62011-06-27 12:34:01 +0200683}
684
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200685/* check subsystem ID and set up device-specific initialization;
686 * return 1 if initialized, 0 if invalid SSID
687 */
688/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
689 * 31 ~ 16 : Manufacture ID
690 * 15 ~ 8 : SKU ID
691 * 7 ~ 0 : Assembly ID
692 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
693 */
Takashi Iwai58c57cf2014-01-07 18:22:49 +0100694static int alc_subsystem_id(struct hda_codec *codec, const hda_nid_t *ports)
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200695{
696 unsigned int ass, tmp, i;
697 unsigned nid;
698 struct alc_spec *spec = codec->spec;
699
David Henningsson90622912010-10-14 14:50:18 +0200700 if (spec->cdefine.fixup) {
701 ass = spec->cdefine.sku_cfg;
702 if (ass == ALC_FIXUP_SKU_IGNORE)
703 return 0;
704 goto do_sku;
705 }
706
Takashi Iwai7639a062015-03-03 10:07:24 +0100707 ass = codec->core.subsystem_id & 0xffff;
Takashi Iwai5100cd02014-02-15 10:03:19 +0100708 if (codec->bus->pci &&
709 ass != codec->bus->pci->subsystem_device && (ass & 1))
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200710 goto do_sku;
711
712 /* invalid SSID, check the special NID pin defcfg instead */
713 /*
Sasha Alexandrdef319f2009-06-16 16:00:15 -0400714 * 31~30 : port connectivity
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200715 * 29~21 : reserve
716 * 20 : PCBEEP input
717 * 19~16 : Check sum (15:1)
718 * 15~1 : Custom
719 * 0 : override
720 */
721 nid = 0x1d;
Takashi Iwai7639a062015-03-03 10:07:24 +0100722 if (codec->core.vendor_id == 0x10ec0260)
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200723 nid = 0x17;
724 ass = snd_hda_codec_get_pincfg(codec, nid);
Takashi Iwai4e76a882014-02-25 12:21:03 +0100725 codec_dbg(codec,
726 "realtek: No valid SSID, checking pincfg 0x%08x for NID 0x%x\n",
Takashi Iwaicb6605c2009-04-28 13:03:19 +0200727 ass, nid);
Kailang Yang6227cdc2010-02-25 08:36:52 +0100728 if (!(ass & 1))
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200729 return 0;
730 if ((ass >> 30) != 1) /* no physical connection */
731 return 0;
732
733 /* check sum */
734 tmp = 0;
735 for (i = 1; i < 16; i++) {
736 if ((ass >> i) & 1)
737 tmp++;
738 }
739 if (((ass >> 16) & 0xf) != tmp)
740 return 0;
741do_sku:
Takashi Iwai4e76a882014-02-25 12:21:03 +0100742 codec_dbg(codec, "realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
Takashi Iwai7639a062015-03-03 10:07:24 +0100743 ass & 0xffff, codec->core.vendor_id);
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200744 /*
745 * 0 : override
746 * 1 : Swap Jack
747 * 2 : 0 --> Desktop, 1 --> Laptop
748 * 3~5 : External Amplifier control
749 * 7~6 : Reserved
750 */
751 tmp = (ass & 0x38) >> 3; /* external Amp control */
Takashi Iwai1c76aa52018-06-21 16:37:54 +0200752 if (spec->init_amp == ALC_INIT_UNDEFINED) {
753 switch (tmp) {
754 case 1:
Takashi Iwai5579cd62018-06-19 22:22:41 +0200755 alc_setup_gpio(codec, 0x01);
Takashi Iwai1c76aa52018-06-21 16:37:54 +0200756 break;
757 case 3:
Takashi Iwai5579cd62018-06-19 22:22:41 +0200758 alc_setup_gpio(codec, 0x02);
Takashi Iwai1c76aa52018-06-21 16:37:54 +0200759 break;
760 case 7:
Takashi Iwai5579cd62018-06-19 22:22:41 +0200761 alc_setup_gpio(codec, 0x03);
Takashi Iwai1c76aa52018-06-21 16:37:54 +0200762 break;
763 case 5:
764 default:
765 spec->init_amp = ALC_INIT_DEFAULT;
766 break;
767 }
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200768 }
769
770 /* is laptop or Desktop and enable the function "Mute internal speaker
771 * when the external headphone out jack is plugged"
772 */
773 if (!(ass & 0x8000))
774 return 1;
775 /*
776 * 10~8 : Jack location
777 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
778 * 14~13: Resvered
779 * 15 : 1 --> enable the function "Mute internal speaker
780 * when the external headphone out jack is plugged"
781 */
Takashi Iwai35a39f92019-02-01 11:19:50 +0100782 if (!alc_get_hp_pin(spec)) {
Takashi Iwai01d48252009-10-06 13:21:54 +0200783 hda_nid_t nid;
Kailang Yangc9b58002007-10-16 14:30:01 +0200784 tmp = (ass >> 11) & 0x3; /* HP to chassis */
Takashi Iwai58c57cf2014-01-07 18:22:49 +0100785 nid = ports[tmp];
Takashi Iwai08c189f2012-12-19 15:22:24 +0100786 if (found_in_nid_list(nid, spec->gen.autocfg.line_out_pins,
787 spec->gen.autocfg.line_outs))
Takashi Iwai3af9ee62011-06-27 12:34:01 +0200788 return 1;
Takashi Iwai08c189f2012-12-19 15:22:24 +0100789 spec->gen.autocfg.hp_pins[0] = nid;
Kailang Yangc9b58002007-10-16 14:30:01 +0200790 }
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200791 return 1;
792}
Kailang Yangea1fb292008-08-26 12:58:38 +0200793
Takashi Iwai3e6179b2011-07-08 16:55:13 +0200794/* Check the validity of ALC subsystem-id
795 * ports contains an array of 4 pin NIDs for port-A, E, D and I */
796static void alc_ssid_check(struct hda_codec *codec, const hda_nid_t *ports)
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200797{
Takashi Iwai58c57cf2014-01-07 18:22:49 +0100798 if (!alc_subsystem_id(codec, ports)) {
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200799 struct alc_spec *spec = codec->spec;
Takashi Iwai4e76a882014-02-25 12:21:03 +0100800 codec_dbg(codec,
801 "realtek: Enable default setup for auto mode as fallback\n");
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200802 spec->init_amp = ALC_INIT_DEFAULT;
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200803 }
Takashi Iwai21268962011-07-07 15:01:13 +0200804}
Takashi Iwai1a1455d2011-04-28 17:36:18 +0200805
Takashi Iwai41e41f12005-06-08 14:48:49 +0200806/*
Takashi Iwai1d045db2011-07-07 18:23:21 +0200807 */
808
David Henningsson9d36a7d2014-10-07 10:18:42 +0200809static void alc_fixup_inv_dmic(struct hda_codec *codec,
810 const struct hda_fixup *fix, int action)
Takashi Iwai125821a2012-06-22 14:30:29 +0200811{
812 struct alc_spec *spec = codec->spec;
Takashi Iwai668d1e92012-11-29 14:10:17 +0100813
David Henningsson9d36a7d2014-10-07 10:18:42 +0200814 spec->gen.inv_dmic_split = 1;
Takashi Iwai6e72aa52012-06-25 10:52:25 +0200815}
816
Takashi Iwai603c4012008-07-30 15:01:44 +0200817
Takashi Iwai2eab6942012-12-18 15:30:41 +0100818static int alc_build_controls(struct hda_codec *codec)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700819{
Takashi Iwaia5cb4632018-06-20 12:50:11 +0200820 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700821
Takashi Iwai08c189f2012-12-19 15:22:24 +0100822 err = snd_hda_gen_build_controls(codec);
823 if (err < 0)
824 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700825
Takashi Iwai1727a772013-01-10 09:52:52 +0100826 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_BUILD);
Takashi Iwai420b0fe2012-03-12 12:35:27 +0100827 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700828}
829
Takashi Iwaie9edcee2005-06-13 14:16:38 +0200830
Linus Torvalds1da177e2005-04-16 15:20:36 -0700831/*
Takashi Iwaiae6b8132006-03-03 16:47:17 +0100832 * Common callbacks
Takashi Iwaie9edcee2005-06-13 14:16:38 +0200833 */
Takashi Iwai16ded522005-06-10 19:58:24 +0200834
Takashi Iwaic9af7532019-05-10 11:01:43 +0200835static void alc_pre_init(struct hda_codec *codec)
836{
837 alc_fill_eapd_coef(codec);
838}
839
Kailang Yangaeac1a02019-05-16 16:10:44 +0800840#define is_s3_resume(codec) \
841 ((codec)->core.dev.power.power_state.event == PM_EVENT_RESUME)
Takashi Iwaic9af7532019-05-10 11:01:43 +0200842#define is_s4_resume(codec) \
843 ((codec)->core.dev.power.power_state.event == PM_EVENT_RESTORE)
844
Linus Torvalds1da177e2005-04-16 15:20:36 -0700845static int alc_init(struct hda_codec *codec)
846{
847 struct alc_spec *spec = codec->spec;
Takashi Iwaie9edcee2005-06-13 14:16:38 +0200848
Takashi Iwaic9af7532019-05-10 11:01:43 +0200849 /* hibernation resume needs the full chip initialization */
850 if (is_s4_resume(codec))
851 alc_pre_init(codec);
852
Takashi Iwai546bb672012-03-07 08:37:19 +0100853 if (spec->init_hook)
854 spec->init_hook(codec);
Kailang Yang526af6e2012-03-07 08:25:20 +0100855
Takashi Iwai89781d02019-08-30 12:03:38 +0200856 spec->gen.skip_verbs = 1; /* applied in below */
Kailang Yang607ca3b2019-04-26 16:35:41 +0800857 snd_hda_gen_init(codec);
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200858 alc_fix_pll(codec);
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200859 alc_auto_init_amp(codec, spec->init_amp);
Takashi Iwai89781d02019-08-30 12:03:38 +0200860 snd_hda_apply_verbs(codec); /* apply verbs here after own init */
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200861
Takashi Iwai1727a772013-01-10 09:52:52 +0100862 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_INIT);
Takashi Iwaie08a0072006-09-07 17:52:14 +0200863
Linus Torvalds1da177e2005-04-16 15:20:36 -0700864 return 0;
865}
866
Takashi Iwaia4e09aa2009-12-27 11:22:24 +0100867static inline void alc_shutup(struct hda_codec *codec)
868{
Takashi Iwai1c7161532011-04-07 10:37:16 +0200869 struct alc_spec *spec = codec->spec;
870
Takashi Iwaic7273bd2018-06-12 16:09:57 +0200871 if (!snd_hda_get_bool_hint(codec, "shutup"))
872 return; /* disabled explicitly by hints */
873
Takashi Iwai1c7161532011-04-07 10:37:16 +0200874 if (spec && spec->shutup)
875 spec->shutup(codec);
Takashi Iwai9bfb2842013-07-24 14:31:50 +0200876 else
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +0100877 alc_shutup_pins(codec);
Takashi Iwaia4e09aa2009-12-27 11:22:24 +0100878}
879
Takashi Iwai70a09762015-12-15 14:59:58 +0100880static void alc_reboot_notify(struct hda_codec *codec)
881{
882 struct alc_spec *spec = codec->spec;
883
884 if (spec && spec->reboot_notify)
885 spec->reboot_notify(codec);
886 else
887 alc_shutup(codec);
888}
889
Takashi Iwai8a02c0c2014-02-10 18:09:45 +0100890#define alc_free snd_hda_gen_free
Linus Torvalds1da177e2005-04-16 15:20:36 -0700891
Takashi Iwai83012a72012-08-24 18:38:08 +0200892#ifdef CONFIG_PM
Daniel T Chenc97259d2009-12-27 18:52:08 -0500893static void alc_power_eapd(struct hda_codec *codec)
894{
Takashi Iwai691f1fc2011-04-07 10:31:43 +0200895 alc_auto_setup_eapd(codec, false);
Daniel T Chenc97259d2009-12-27 18:52:08 -0500896}
897
Takashi Iwai68cb2b52012-07-02 15:20:37 +0200898static int alc_suspend(struct hda_codec *codec)
Hector Martinf5de24b2009-12-20 22:51:31 +0100899{
900 struct alc_spec *spec = codec->spec;
Takashi Iwaia4e09aa2009-12-27 11:22:24 +0100901 alc_shutup(codec);
Hector Martinf5de24b2009-12-20 22:51:31 +0100902 if (spec && spec->power_hook)
Daniel T Chenc97259d2009-12-27 18:52:08 -0500903 spec->power_hook(codec);
Hector Martinf5de24b2009-12-20 22:51:31 +0100904 return 0;
905}
906#endif
907
Takashi Iwai2a439522011-07-26 09:52:50 +0200908#ifdef CONFIG_PM
Takashi Iwaie044c392008-10-27 16:56:24 +0100909static int alc_resume(struct hda_codec *codec)
910{
Kailang Yang97a26572013-11-29 00:35:26 -0500911 struct alc_spec *spec = codec->spec;
912
913 if (!spec->no_depop_delay)
914 msleep(150); /* to avoid pop noise */
Takashi Iwaie044c392008-10-27 16:56:24 +0100915 codec->patch_ops.init(codec);
Takashi Iwai1a462be2020-01-09 10:01:04 +0100916 snd_hda_regmap_sync(codec);
Takashi Iwai9e5341b2010-09-21 09:57:06 +0200917 hda_call_check_power_status(codec, 0x01);
Takashi Iwaie044c392008-10-27 16:56:24 +0100918 return 0;
919}
Takashi Iwaie044c392008-10-27 16:56:24 +0100920#endif
921
Linus Torvalds1da177e2005-04-16 15:20:36 -0700922/*
923 */
Takashi Iwaia9111322011-05-02 11:30:18 +0200924static const struct hda_codec_ops alc_patch_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700925 .build_controls = alc_build_controls,
Takashi Iwai08c189f2012-12-19 15:22:24 +0100926 .build_pcms = snd_hda_gen_build_pcms,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700927 .init = alc_init,
928 .free = alc_free,
David Henningsson29adc4b2012-09-25 11:31:00 +0200929 .unsol_event = snd_hda_jack_unsol_event,
Takashi Iwai2a439522011-07-26 09:52:50 +0200930#ifdef CONFIG_PM
Takashi Iwaie044c392008-10-27 16:56:24 +0100931 .resume = alc_resume,
Hector Martinf5de24b2009-12-20 22:51:31 +0100932 .suspend = alc_suspend,
Takashi Iwaifce52a32013-01-07 12:42:48 +0100933 .check_power_status = snd_hda_gen_check_power_status,
Takashi Iwaicb53c622007-08-10 17:21:45 +0200934#endif
Takashi Iwai70a09762015-12-15 14:59:58 +0100935 .reboot_notify = alc_reboot_notify,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700936};
937
David Henningsson29adc4b2012-09-25 11:31:00 +0200938
Takashi Iwaided255b2015-10-01 17:59:43 +0200939#define alc_codec_rename(codec, name) snd_hda_codec_set_name(codec, name)
Kailang Yangc027ddc2010-03-19 11:33:06 +0100940
Takashi Iwai2fa522b2005-05-12 14:51:12 +0200941/*
Kailang Yang4b016932013-11-28 11:55:09 +0100942 * Rename codecs appropriately from COEF value or subvendor id
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200943 */
944struct alc_codec_rename_table {
945 unsigned int vendor_id;
946 unsigned short coef_mask;
947 unsigned short coef_bits;
948 const char *name;
949};
950
Kailang Yang4b016932013-11-28 11:55:09 +0100951struct alc_codec_rename_pci_table {
952 unsigned int codec_vendor_id;
953 unsigned short pci_subvendor;
954 unsigned short pci_subdevice;
955 const char *name;
956};
957
Takashi Iwai6b0f95c2020-01-05 15:47:18 +0100958static const struct alc_codec_rename_table rename_tbl[] = {
Kailang Yange6e5f7a2014-06-06 16:46:43 +0800959 { 0x10ec0221, 0xf00f, 0x1003, "ALC231" },
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200960 { 0x10ec0269, 0xfff0, 0x3010, "ALC277" },
961 { 0x10ec0269, 0xf0f0, 0x2010, "ALC259" },
962 { 0x10ec0269, 0xf0f0, 0x3010, "ALC258" },
963 { 0x10ec0269, 0x00f0, 0x0010, "ALC269VB" },
964 { 0x10ec0269, 0xffff, 0xa023, "ALC259" },
965 { 0x10ec0269, 0xffff, 0x6023, "ALC281X" },
966 { 0x10ec0269, 0x00f0, 0x0020, "ALC269VC" },
Kailang Yangadcc70b2012-05-25 08:08:38 +0200967 { 0x10ec0269, 0x00f0, 0x0030, "ALC269VD" },
Kailang Yange6e5f7a2014-06-06 16:46:43 +0800968 { 0x10ec0662, 0xffff, 0x4020, "ALC656" },
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200969 { 0x10ec0887, 0x00f0, 0x0030, "ALC887-VD" },
970 { 0x10ec0888, 0x00f0, 0x0030, "ALC888-VD" },
971 { 0x10ec0888, 0xf0f0, 0x3020, "ALC886" },
972 { 0x10ec0899, 0x2000, 0x2000, "ALC899" },
973 { 0x10ec0892, 0xffff, 0x8020, "ALC661" },
974 { 0x10ec0892, 0xffff, 0x8011, "ALC661" },
975 { 0x10ec0892, 0xffff, 0x4011, "ALC656" },
976 { } /* terminator */
977};
978
Takashi Iwai6b0f95c2020-01-05 15:47:18 +0100979static const struct alc_codec_rename_pci_table rename_pci_tbl[] = {
Kailang Yang4b016932013-11-28 11:55:09 +0100980 { 0x10ec0280, 0x1028, 0, "ALC3220" },
981 { 0x10ec0282, 0x1028, 0, "ALC3221" },
982 { 0x10ec0283, 0x1028, 0, "ALC3223" },
Kailang Yang193177d2014-04-23 16:06:13 +0800983 { 0x10ec0288, 0x1028, 0, "ALC3263" },
Kailang Yang4b016932013-11-28 11:55:09 +0100984 { 0x10ec0292, 0x1028, 0, "ALC3226" },
Kailang Yang193177d2014-04-23 16:06:13 +0800985 { 0x10ec0293, 0x1028, 0, "ALC3235" },
Kailang Yang4b016932013-11-28 11:55:09 +0100986 { 0x10ec0255, 0x1028, 0, "ALC3234" },
987 { 0x10ec0668, 0x1028, 0, "ALC3661" },
Kailang Yange6e5f7a2014-06-06 16:46:43 +0800988 { 0x10ec0275, 0x1028, 0, "ALC3260" },
989 { 0x10ec0899, 0x1028, 0, "ALC3861" },
Kailang Yang2c674fa2015-05-05 15:02:42 +0800990 { 0x10ec0298, 0x1028, 0, "ALC3266" },
Kailang Yang736f20a2017-10-20 15:06:34 +0800991 { 0x10ec0236, 0x1028, 0, "ALC3204" },
Kailang Yang82324502015-05-25 17:16:49 +0800992 { 0x10ec0256, 0x1028, 0, "ALC3246" },
Kailang Yang42314302016-02-03 15:03:50 +0800993 { 0x10ec0225, 0x1028, 0, "ALC3253" },
Kailang Yang7d727862016-05-24 16:46:07 +0800994 { 0x10ec0295, 0x1028, 0, "ALC3254" },
Kailang Yang28f1f9b2017-01-04 14:49:07 +0800995 { 0x10ec0299, 0x1028, 0, "ALC3271" },
Kailang Yange6e5f7a2014-06-06 16:46:43 +0800996 { 0x10ec0670, 0x1025, 0, "ALC669X" },
997 { 0x10ec0676, 0x1025, 0, "ALC679X" },
998 { 0x10ec0282, 0x1043, 0, "ALC3229" },
999 { 0x10ec0233, 0x1043, 0, "ALC3236" },
1000 { 0x10ec0280, 0x103c, 0, "ALC3228" },
1001 { 0x10ec0282, 0x103c, 0, "ALC3227" },
1002 { 0x10ec0286, 0x103c, 0, "ALC3242" },
1003 { 0x10ec0290, 0x103c, 0, "ALC3241" },
1004 { 0x10ec0668, 0x103c, 0, "ALC3662" },
1005 { 0x10ec0283, 0x17aa, 0, "ALC3239" },
1006 { 0x10ec0292, 0x17aa, 0, "ALC3232" },
Kailang Yang4b016932013-11-28 11:55:09 +01001007 { } /* terminator */
1008};
1009
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02001010static int alc_codec_rename_from_preset(struct hda_codec *codec)
1011{
1012 const struct alc_codec_rename_table *p;
Kailang Yang4b016932013-11-28 11:55:09 +01001013 const struct alc_codec_rename_pci_table *q;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02001014
1015 for (p = rename_tbl; p->vendor_id; p++) {
Takashi Iwai7639a062015-03-03 10:07:24 +01001016 if (p->vendor_id != codec->core.vendor_id)
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02001017 continue;
Takashi Iwai1bb7e432011-10-17 16:50:59 +02001018 if ((alc_get_coef0(codec) & p->coef_mask) == p->coef_bits)
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02001019 return alc_codec_rename(codec, p->name);
1020 }
Kailang Yang4b016932013-11-28 11:55:09 +01001021
Takashi Iwai5100cd02014-02-15 10:03:19 +01001022 if (!codec->bus->pci)
1023 return 0;
Kailang Yang4b016932013-11-28 11:55:09 +01001024 for (q = rename_pci_tbl; q->codec_vendor_id; q++) {
Takashi Iwai7639a062015-03-03 10:07:24 +01001025 if (q->codec_vendor_id != codec->core.vendor_id)
Kailang Yang4b016932013-11-28 11:55:09 +01001026 continue;
1027 if (q->pci_subvendor != codec->bus->pci->subsystem_vendor)
1028 continue;
1029 if (!q->pci_subdevice ||
1030 q->pci_subdevice == codec->bus->pci->subsystem_device)
1031 return alc_codec_rename(codec, q->name);
1032 }
1033
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02001034 return 0;
1035}
1036
Takashi Iwaie4770622011-07-08 11:11:35 +02001037
1038/*
Takashi Iwai1d045db2011-07-07 18:23:21 +02001039 * Digital-beep handlers
1040 */
1041#ifdef CONFIG_SND_HDA_INPUT_BEEP
Takashi Iwaifea80fa2018-06-20 12:52:46 +02001042
1043/* additional beep mixers; private_value will be overwritten */
1044static const struct snd_kcontrol_new alc_beep_mixer[] = {
1045 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
1046 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
1047};
1048
1049/* set up and create beep controls */
1050static int set_beep_amp(struct alc_spec *spec, hda_nid_t nid,
1051 int idx, int dir)
1052{
1053 struct snd_kcontrol_new *knew;
1054 unsigned int beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir);
1055 int i;
1056
1057 for (i = 0; i < ARRAY_SIZE(alc_beep_mixer); i++) {
1058 knew = snd_hda_gen_add_kctl(&spec->gen, NULL,
1059 &alc_beep_mixer[i]);
1060 if (!knew)
1061 return -ENOMEM;
1062 knew->private_value = beep_amp;
1063 }
1064 return 0;
1065}
Takashi Iwai1d045db2011-07-07 18:23:21 +02001066
1067static const struct snd_pci_quirk beep_white_list[] = {
Duncan Roe71100052012-10-10 14:19:50 +02001068 SND_PCI_QUIRK(0x1043, 0x103c, "ASUS", 1),
W. Trevor Kinga4b7f21d2014-03-29 17:47:24 -07001069 SND_PCI_QUIRK(0x1043, 0x115d, "ASUS", 1),
Takashi Iwai1d045db2011-07-07 18:23:21 +02001070 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
Takashi Iwai8554ee42013-02-25 09:54:43 +01001071 SND_PCI_QUIRK(0x1043, 0x8376, "EeePC", 1),
Takashi Iwai1d045db2011-07-07 18:23:21 +02001072 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
1073 SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1),
1074 SND_PCI_QUIRK(0x1043, 0x834a, "EeePC", 1),
Takashi Iwai78f8baf2012-03-06 14:02:32 +01001075 SND_PCI_QUIRK(0x1458, 0xa002, "GA-MA790X", 1),
Takashi Iwai1d045db2011-07-07 18:23:21 +02001076 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
Takashi Iwai051c78a2019-08-22 09:58:07 +02001077 /* blacklist -- no beep available */
1078 SND_PCI_QUIRK(0x17aa, 0x309e, "Lenovo ThinkCentre M73", 0),
1079 SND_PCI_QUIRK(0x17aa, 0x30a3, "Lenovo ThinkCentre M93", 0),
Takashi Iwai1d045db2011-07-07 18:23:21 +02001080 {}
1081};
1082
1083static inline int has_cdefine_beep(struct hda_codec *codec)
1084{
1085 struct alc_spec *spec = codec->spec;
1086 const struct snd_pci_quirk *q;
1087 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
1088 if (q)
1089 return q->value;
1090 return spec->cdefine.enable_pcbeep;
1091}
1092#else
Takashi Iwaifea80fa2018-06-20 12:52:46 +02001093#define set_beep_amp(spec, nid, idx, dir) 0
Takashi Iwai1d045db2011-07-07 18:23:21 +02001094#define has_cdefine_beep(codec) 0
1095#endif
1096
1097/* parse the BIOS configuration and set up the alc_spec */
1098/* return 1 if successful, 0 if the proper config is not found,
1099 * or a negative error code
1100 */
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001101static int alc_parse_auto_config(struct hda_codec *codec,
1102 const hda_nid_t *ignore_nids,
1103 const hda_nid_t *ssid_nids)
Takashi Iwai1d045db2011-07-07 18:23:21 +02001104{
1105 struct alc_spec *spec = codec->spec;
Takashi Iwai08c189f2012-12-19 15:22:24 +01001106 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001107 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001108
Takashi Iwai53c334a2011-08-23 18:27:14 +02001109 err = snd_hda_parse_pin_defcfg(codec, cfg, ignore_nids,
1110 spec->parse_flags);
Takashi Iwai1d045db2011-07-07 18:23:21 +02001111 if (err < 0)
1112 return err;
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001113
1114 if (ssid_nids)
1115 alc_ssid_check(codec, ssid_nids);
1116
Takashi Iwai08c189f2012-12-19 15:22:24 +01001117 err = snd_hda_gen_parse_auto_config(codec, cfg);
1118 if (err < 0)
1119 return err;
Takashi Iwai070cff42012-02-21 12:54:17 +01001120
Takashi Iwai1d045db2011-07-07 18:23:21 +02001121 return 1;
1122}
1123
Takashi Iwai3de95172012-05-07 18:03:15 +02001124/* common preparation job for alc_spec */
1125static int alc_alloc_spec(struct hda_codec *codec, hda_nid_t mixer_nid)
1126{
1127 struct alc_spec *spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1128 int err;
1129
1130 if (!spec)
1131 return -ENOMEM;
1132 codec->spec = spec;
Takashi Iwai08c189f2012-12-19 15:22:24 +01001133 snd_hda_gen_spec_init(&spec->gen);
1134 spec->gen.mixer_nid = mixer_nid;
1135 spec->gen.own_eapd_ctl = 1;
Takashi Iwai1098b7c2012-12-17 20:03:15 +01001136 codec->single_adc_amp = 1;
Takashi Iwai08c189f2012-12-19 15:22:24 +01001137 /* FIXME: do we need this for all Realtek codec models? */
1138 codec->spdif_status_reset = 1;
Takashi Iwai225068a2015-05-29 10:42:14 +02001139 codec->patch_ops = alc_patch_ops;
Takashi Iwai3de95172012-05-07 18:03:15 +02001140
1141 err = alc_codec_rename_from_preset(codec);
1142 if (err < 0) {
1143 kfree(spec);
1144 return err;
1145 }
1146 return 0;
1147}
1148
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001149static int alc880_parse_auto_config(struct hda_codec *codec)
1150{
1151 static const hda_nid_t alc880_ignore[] = { 0x1d, 0 };
Jesper Juhl7d7eb9e2012-04-12 22:11:25 +02001152 static const hda_nid_t alc880_ssids[] = { 0x15, 0x1b, 0x14, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001153 return alc_parse_auto_config(codec, alc880_ignore, alc880_ssids);
1154}
1155
Takashi Iwai1d045db2011-07-07 18:23:21 +02001156/*
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001157 * ALC880 fix-ups
1158 */
1159enum {
Takashi Iwai411225a2012-02-20 17:48:19 +01001160 ALC880_FIXUP_GPIO1,
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001161 ALC880_FIXUP_GPIO2,
1162 ALC880_FIXUP_MEDION_RIM,
Takashi Iwaidc6af522012-02-17 16:18:59 +01001163 ALC880_FIXUP_LG,
Takashi Iwaidb8a38e2013-08-09 12:34:42 +02001164 ALC880_FIXUP_LG_LW25,
Takashi Iwaif02aab52012-02-17 16:33:56 +01001165 ALC880_FIXUP_W810,
Takashi Iwai27e917f2012-02-17 17:49:54 +01001166 ALC880_FIXUP_EAPD_COEF,
Takashi Iwaib9368f52012-02-17 17:54:44 +01001167 ALC880_FIXUP_TCL_S700,
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001168 ALC880_FIXUP_VOL_KNOB,
1169 ALC880_FIXUP_FUJITSU,
Takashi Iwaiba533812012-02-20 16:36:52 +01001170 ALC880_FIXUP_F1734,
Takashi Iwai817de922012-02-20 17:20:48 +01001171 ALC880_FIXUP_UNIWILL,
Takashi Iwai967b88c2012-02-20 17:31:02 +01001172 ALC880_FIXUP_UNIWILL_DIG,
Takashi Iwai96e225f2012-02-20 17:41:51 +01001173 ALC880_FIXUP_Z71V,
Takashi Iwai487a5882013-11-07 07:29:30 +01001174 ALC880_FIXUP_ASUS_W5A,
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001175 ALC880_FIXUP_3ST_BASE,
1176 ALC880_FIXUP_3ST,
1177 ALC880_FIXUP_3ST_DIG,
1178 ALC880_FIXUP_5ST_BASE,
1179 ALC880_FIXUP_5ST,
1180 ALC880_FIXUP_5ST_DIG,
1181 ALC880_FIXUP_6ST_BASE,
1182 ALC880_FIXUP_6ST,
1183 ALC880_FIXUP_6ST_DIG,
Takashi Iwai53971452013-01-23 18:21:37 +01001184 ALC880_FIXUP_6ST_AUTOMUTE,
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001185};
1186
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001187/* enable the volume-knob widget support on NID 0x21 */
1188static void alc880_fixup_vol_knob(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001189 const struct hda_fixup *fix, int action)
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001190{
Takashi Iwai1727a772013-01-10 09:52:52 +01001191 if (action == HDA_FIXUP_ACT_PROBE)
Takashi Iwai62f949b2014-09-11 14:06:53 +02001192 snd_hda_jack_detect_enable_callback(codec, 0x21,
1193 alc_update_knob_master);
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001194}
1195
Takashi Iwai1727a772013-01-10 09:52:52 +01001196static const struct hda_fixup alc880_fixups[] = {
Takashi Iwai411225a2012-02-20 17:48:19 +01001197 [ALC880_FIXUP_GPIO1] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02001198 .type = HDA_FIXUP_FUNC,
1199 .v.func = alc_fixup_gpio1,
Takashi Iwai411225a2012-02-20 17:48:19 +01001200 },
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001201 [ALC880_FIXUP_GPIO2] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02001202 .type = HDA_FIXUP_FUNC,
1203 .v.func = alc_fixup_gpio2,
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001204 },
1205 [ALC880_FIXUP_MEDION_RIM] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001206 .type = HDA_FIXUP_VERBS,
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001207 .v.verbs = (const struct hda_verb[]) {
1208 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
1209 { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
1210 { }
1211 },
1212 .chained = true,
1213 .chain_id = ALC880_FIXUP_GPIO2,
1214 },
Takashi Iwaidc6af522012-02-17 16:18:59 +01001215 [ALC880_FIXUP_LG] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001216 .type = HDA_FIXUP_PINS,
1217 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaidc6af522012-02-17 16:18:59 +01001218 /* disable bogus unused pins */
1219 { 0x16, 0x411111f0 },
1220 { 0x18, 0x411111f0 },
1221 { 0x1a, 0x411111f0 },
1222 { }
1223 }
1224 },
Takashi Iwaidb8a38e2013-08-09 12:34:42 +02001225 [ALC880_FIXUP_LG_LW25] = {
1226 .type = HDA_FIXUP_PINS,
1227 .v.pins = (const struct hda_pintbl[]) {
1228 { 0x1a, 0x0181344f }, /* line-in */
1229 { 0x1b, 0x0321403f }, /* headphone */
1230 { }
1231 }
1232 },
Takashi Iwaif02aab52012-02-17 16:33:56 +01001233 [ALC880_FIXUP_W810] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001234 .type = HDA_FIXUP_PINS,
1235 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaif02aab52012-02-17 16:33:56 +01001236 /* disable bogus unused pins */
1237 { 0x17, 0x411111f0 },
1238 { }
1239 },
1240 .chained = true,
1241 .chain_id = ALC880_FIXUP_GPIO2,
1242 },
Takashi Iwai27e917f2012-02-17 17:49:54 +01001243 [ALC880_FIXUP_EAPD_COEF] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001244 .type = HDA_FIXUP_VERBS,
Takashi Iwai27e917f2012-02-17 17:49:54 +01001245 .v.verbs = (const struct hda_verb[]) {
1246 /* change to EAPD mode */
1247 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
1248 { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
1249 {}
1250 },
1251 },
Takashi Iwaib9368f52012-02-17 17:54:44 +01001252 [ALC880_FIXUP_TCL_S700] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001253 .type = HDA_FIXUP_VERBS,
Takashi Iwaib9368f52012-02-17 17:54:44 +01001254 .v.verbs = (const struct hda_verb[]) {
1255 /* change to EAPD mode */
1256 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
1257 { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
1258 {}
1259 },
1260 .chained = true,
1261 .chain_id = ALC880_FIXUP_GPIO2,
1262 },
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001263 [ALC880_FIXUP_VOL_KNOB] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001264 .type = HDA_FIXUP_FUNC,
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001265 .v.func = alc880_fixup_vol_knob,
1266 },
1267 [ALC880_FIXUP_FUJITSU] = {
1268 /* override all pins as BIOS on old Amilo is broken */
Takashi Iwai1727a772013-01-10 09:52:52 +01001269 .type = HDA_FIXUP_PINS,
1270 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaibb148bd2015-08-13 18:02:39 +02001271 { 0x14, 0x0121401f }, /* HP */
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001272 { 0x15, 0x99030120 }, /* speaker */
1273 { 0x16, 0x99030130 }, /* bass speaker */
1274 { 0x17, 0x411111f0 }, /* N/A */
1275 { 0x18, 0x411111f0 }, /* N/A */
1276 { 0x19, 0x01a19950 }, /* mic-in */
1277 { 0x1a, 0x411111f0 }, /* N/A */
1278 { 0x1b, 0x411111f0 }, /* N/A */
1279 { 0x1c, 0x411111f0 }, /* N/A */
1280 { 0x1d, 0x411111f0 }, /* N/A */
1281 { 0x1e, 0x01454140 }, /* SPDIF out */
1282 { }
1283 },
1284 .chained = true,
1285 .chain_id = ALC880_FIXUP_VOL_KNOB,
1286 },
Takashi Iwaiba533812012-02-20 16:36:52 +01001287 [ALC880_FIXUP_F1734] = {
1288 /* almost compatible with FUJITSU, but no bass and SPDIF */
Takashi Iwai1727a772013-01-10 09:52:52 +01001289 .type = HDA_FIXUP_PINS,
1290 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaibb148bd2015-08-13 18:02:39 +02001291 { 0x14, 0x0121401f }, /* HP */
Takashi Iwaiba533812012-02-20 16:36:52 +01001292 { 0x15, 0x99030120 }, /* speaker */
1293 { 0x16, 0x411111f0 }, /* N/A */
1294 { 0x17, 0x411111f0 }, /* N/A */
1295 { 0x18, 0x411111f0 }, /* N/A */
1296 { 0x19, 0x01a19950 }, /* mic-in */
1297 { 0x1a, 0x411111f0 }, /* N/A */
1298 { 0x1b, 0x411111f0 }, /* N/A */
1299 { 0x1c, 0x411111f0 }, /* N/A */
1300 { 0x1d, 0x411111f0 }, /* N/A */
1301 { 0x1e, 0x411111f0 }, /* N/A */
1302 { }
1303 },
1304 .chained = true,
1305 .chain_id = ALC880_FIXUP_VOL_KNOB,
1306 },
Takashi Iwai817de922012-02-20 17:20:48 +01001307 [ALC880_FIXUP_UNIWILL] = {
1308 /* need to fix HP and speaker pins to be parsed correctly */
Takashi Iwai1727a772013-01-10 09:52:52 +01001309 .type = HDA_FIXUP_PINS,
1310 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai817de922012-02-20 17:20:48 +01001311 { 0x14, 0x0121411f }, /* HP */
1312 { 0x15, 0x99030120 }, /* speaker */
1313 { 0x16, 0x99030130 }, /* bass speaker */
1314 { }
1315 },
1316 },
Takashi Iwai967b88c2012-02-20 17:31:02 +01001317 [ALC880_FIXUP_UNIWILL_DIG] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001318 .type = HDA_FIXUP_PINS,
1319 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai967b88c2012-02-20 17:31:02 +01001320 /* disable bogus unused pins */
1321 { 0x17, 0x411111f0 },
1322 { 0x19, 0x411111f0 },
1323 { 0x1b, 0x411111f0 },
1324 { 0x1f, 0x411111f0 },
1325 { }
1326 }
1327 },
Takashi Iwai96e225f2012-02-20 17:41:51 +01001328 [ALC880_FIXUP_Z71V] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001329 .type = HDA_FIXUP_PINS,
1330 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai96e225f2012-02-20 17:41:51 +01001331 /* set up the whole pins as BIOS is utterly broken */
1332 { 0x14, 0x99030120 }, /* speaker */
1333 { 0x15, 0x0121411f }, /* HP */
1334 { 0x16, 0x411111f0 }, /* N/A */
1335 { 0x17, 0x411111f0 }, /* N/A */
1336 { 0x18, 0x01a19950 }, /* mic-in */
1337 { 0x19, 0x411111f0 }, /* N/A */
1338 { 0x1a, 0x01813031 }, /* line-in */
1339 { 0x1b, 0x411111f0 }, /* N/A */
1340 { 0x1c, 0x411111f0 }, /* N/A */
1341 { 0x1d, 0x411111f0 }, /* N/A */
1342 { 0x1e, 0x0144111e }, /* SPDIF */
1343 { }
1344 }
1345 },
Takashi Iwai487a5882013-11-07 07:29:30 +01001346 [ALC880_FIXUP_ASUS_W5A] = {
1347 .type = HDA_FIXUP_PINS,
1348 .v.pins = (const struct hda_pintbl[]) {
1349 /* set up the whole pins as BIOS is utterly broken */
1350 { 0x14, 0x0121411f }, /* HP */
1351 { 0x15, 0x411111f0 }, /* N/A */
1352 { 0x16, 0x411111f0 }, /* N/A */
1353 { 0x17, 0x411111f0 }, /* N/A */
1354 { 0x18, 0x90a60160 }, /* mic */
1355 { 0x19, 0x411111f0 }, /* N/A */
1356 { 0x1a, 0x411111f0 }, /* N/A */
1357 { 0x1b, 0x411111f0 }, /* N/A */
1358 { 0x1c, 0x411111f0 }, /* N/A */
1359 { 0x1d, 0x411111f0 }, /* N/A */
1360 { 0x1e, 0xb743111e }, /* SPDIF out */
1361 { }
1362 },
1363 .chained = true,
1364 .chain_id = ALC880_FIXUP_GPIO1,
1365 },
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001366 [ALC880_FIXUP_3ST_BASE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001367 .type = HDA_FIXUP_PINS,
1368 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001369 { 0x14, 0x01014010 }, /* line-out */
1370 { 0x15, 0x411111f0 }, /* N/A */
1371 { 0x16, 0x411111f0 }, /* N/A */
1372 { 0x17, 0x411111f0 }, /* N/A */
1373 { 0x18, 0x01a19c30 }, /* mic-in */
1374 { 0x19, 0x0121411f }, /* HP */
1375 { 0x1a, 0x01813031 }, /* line-in */
1376 { 0x1b, 0x02a19c40 }, /* front-mic */
1377 { 0x1c, 0x411111f0 }, /* N/A */
1378 { 0x1d, 0x411111f0 }, /* N/A */
1379 /* 0x1e is filled in below */
1380 { 0x1f, 0x411111f0 }, /* N/A */
1381 { }
1382 }
1383 },
1384 [ALC880_FIXUP_3ST] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001385 .type = HDA_FIXUP_PINS,
1386 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001387 { 0x1e, 0x411111f0 }, /* N/A */
1388 { }
1389 },
1390 .chained = true,
1391 .chain_id = ALC880_FIXUP_3ST_BASE,
1392 },
1393 [ALC880_FIXUP_3ST_DIG] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001394 .type = HDA_FIXUP_PINS,
1395 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001396 { 0x1e, 0x0144111e }, /* SPDIF */
1397 { }
1398 },
1399 .chained = true,
1400 .chain_id = ALC880_FIXUP_3ST_BASE,
1401 },
1402 [ALC880_FIXUP_5ST_BASE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001403 .type = HDA_FIXUP_PINS,
1404 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001405 { 0x14, 0x01014010 }, /* front */
1406 { 0x15, 0x411111f0 }, /* N/A */
1407 { 0x16, 0x01011411 }, /* CLFE */
1408 { 0x17, 0x01016412 }, /* surr */
1409 { 0x18, 0x01a19c30 }, /* mic-in */
1410 { 0x19, 0x0121411f }, /* HP */
1411 { 0x1a, 0x01813031 }, /* line-in */
1412 { 0x1b, 0x02a19c40 }, /* front-mic */
1413 { 0x1c, 0x411111f0 }, /* N/A */
1414 { 0x1d, 0x411111f0 }, /* N/A */
1415 /* 0x1e is filled in below */
1416 { 0x1f, 0x411111f0 }, /* N/A */
1417 { }
1418 }
1419 },
1420 [ALC880_FIXUP_5ST] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001421 .type = HDA_FIXUP_PINS,
1422 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001423 { 0x1e, 0x411111f0 }, /* N/A */
1424 { }
1425 },
1426 .chained = true,
1427 .chain_id = ALC880_FIXUP_5ST_BASE,
1428 },
1429 [ALC880_FIXUP_5ST_DIG] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001430 .type = HDA_FIXUP_PINS,
1431 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001432 { 0x1e, 0x0144111e }, /* SPDIF */
1433 { }
1434 },
1435 .chained = true,
1436 .chain_id = ALC880_FIXUP_5ST_BASE,
1437 },
1438 [ALC880_FIXUP_6ST_BASE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001439 .type = HDA_FIXUP_PINS,
1440 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001441 { 0x14, 0x01014010 }, /* front */
1442 { 0x15, 0x01016412 }, /* surr */
1443 { 0x16, 0x01011411 }, /* CLFE */
1444 { 0x17, 0x01012414 }, /* side */
1445 { 0x18, 0x01a19c30 }, /* mic-in */
1446 { 0x19, 0x02a19c40 }, /* front-mic */
1447 { 0x1a, 0x01813031 }, /* line-in */
1448 { 0x1b, 0x0121411f }, /* HP */
1449 { 0x1c, 0x411111f0 }, /* N/A */
1450 { 0x1d, 0x411111f0 }, /* N/A */
1451 /* 0x1e is filled in below */
1452 { 0x1f, 0x411111f0 }, /* N/A */
1453 { }
1454 }
1455 },
1456 [ALC880_FIXUP_6ST] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001457 .type = HDA_FIXUP_PINS,
1458 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001459 { 0x1e, 0x411111f0 }, /* N/A */
1460 { }
1461 },
1462 .chained = true,
1463 .chain_id = ALC880_FIXUP_6ST_BASE,
1464 },
1465 [ALC880_FIXUP_6ST_DIG] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001466 .type = HDA_FIXUP_PINS,
1467 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001468 { 0x1e, 0x0144111e }, /* SPDIF */
1469 { }
1470 },
1471 .chained = true,
1472 .chain_id = ALC880_FIXUP_6ST_BASE,
1473 },
Takashi Iwai53971452013-01-23 18:21:37 +01001474 [ALC880_FIXUP_6ST_AUTOMUTE] = {
1475 .type = HDA_FIXUP_PINS,
1476 .v.pins = (const struct hda_pintbl[]) {
1477 { 0x1b, 0x0121401f }, /* HP with jack detect */
1478 { }
1479 },
1480 .chained_before = true,
1481 .chain_id = ALC880_FIXUP_6ST_BASE,
1482 },
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001483};
1484
1485static const struct snd_pci_quirk alc880_fixup_tbl[] = {
Takashi Iwaif02aab52012-02-17 16:33:56 +01001486 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_FIXUP_W810),
Takashi Iwai487a5882013-11-07 07:29:30 +01001487 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS W5A", ALC880_FIXUP_ASUS_W5A),
Takashi Iwai96e225f2012-02-20 17:41:51 +01001488 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_FIXUP_Z71V),
Takashi Iwai29e3fdc2012-02-20 17:56:57 +01001489 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_FIXUP_GPIO1),
David Henningsson6538de02014-06-10 10:52:50 +02001490 SND_PCI_QUIRK(0x147b, 0x1045, "ABit AA8XE", ALC880_FIXUP_6ST_AUTOMUTE),
Takashi Iwai29e3fdc2012-02-20 17:56:57 +01001491 SND_PCI_QUIRK(0x1558, 0x5401, "Clevo GPIO2", ALC880_FIXUP_GPIO2),
Takashi Iwai27e917f2012-02-17 17:49:54 +01001492 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo", ALC880_FIXUP_EAPD_COEF),
Takashi Iwai967b88c2012-02-20 17:31:02 +01001493 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_FIXUP_UNIWILL_DIG),
Takashi Iwaiba533812012-02-20 16:36:52 +01001494 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_FIXUP_F1734),
Takashi Iwai817de922012-02-20 17:20:48 +01001495 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_FIXUP_UNIWILL),
Takashi Iwai7833c7e2012-02-20 17:11:38 +01001496 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_FIXUP_VOL_KNOB),
Takashi Iwaif02aab52012-02-17 16:33:56 +01001497 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_FIXUP_W810),
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001498 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_FIXUP_MEDION_RIM),
Takashi Iwai53971452013-01-23 18:21:37 +01001499 SND_PCI_QUIRK(0x1631, 0xe011, "PB 13201056", ALC880_FIXUP_6ST_AUTOMUTE),
Takashi Iwaia1615742015-08-13 18:05:06 +02001500 SND_PCI_QUIRK(0x1734, 0x107c, "FSC Amilo M1437", ALC880_FIXUP_FUJITSU),
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001501 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FIXUP_FUJITSU),
Takashi Iwaiba533812012-02-20 16:36:52 +01001502 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_FIXUP_F1734),
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001503 SND_PCI_QUIRK(0x1734, 0x10b0, "FSC Amilo Pi1556", ALC880_FIXUP_FUJITSU),
Takashi Iwaidc6af522012-02-17 16:18:59 +01001504 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_FIXUP_LG),
1505 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_FIXUP_LG),
1506 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_FIXUP_LG),
Takashi Iwaidb8a38e2013-08-09 12:34:42 +02001507 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_FIXUP_LG_LW25),
Takashi Iwaib9368f52012-02-17 17:54:44 +01001508 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_FIXUP_TCL_S700),
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001509
1510 /* Below is the copied entries from alc880_quirks.c.
1511 * It's not quite sure whether BIOS sets the correct pin-config table
1512 * on these machines, thus they are kept to be compatible with
1513 * the old static quirks. Once when it's confirmed to work without
1514 * these overrides, it'd be better to remove.
1515 */
1516 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_FIXUP_5ST_DIG),
1517 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_FIXUP_6ST),
1518 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_FIXUP_3ST_DIG),
1519 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_FIXUP_6ST_DIG),
1520 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_FIXUP_6ST_DIG),
1521 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_FIXUP_6ST_DIG),
1522 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_FIXUP_3ST_DIG),
1523 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_FIXUP_3ST),
1524 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_FIXUP_6ST_DIG),
1525 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_FIXUP_3ST),
1526 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_FIXUP_3ST),
1527 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_FIXUP_5ST),
1528 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_FIXUP_5ST),
1529 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_FIXUP_5ST),
1530 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_FIXUP_6ST_DIG),
1531 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_FIXUP_6ST_DIG),
1532 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_FIXUP_6ST_DIG),
1533 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_FIXUP_6ST_DIG),
1534 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_FIXUP_5ST_DIG),
1535 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_FIXUP_5ST_DIG),
1536 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_FIXUP_5ST_DIG),
1537 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_FIXUP_6ST_DIG), /* broken BIOS */
1538 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_FIXUP_6ST_DIG),
1539 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1540 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1541 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1542 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_FIXUP_3ST_DIG),
1543 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1544 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_FIXUP_3ST_DIG),
1545 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_FIXUP_3ST_DIG),
1546 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1547 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1548 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1549 /* default Intel */
1550 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_FIXUP_3ST),
1551 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_FIXUP_5ST_DIG),
1552 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_FIXUP_6ST_DIG),
1553 {}
1554};
1555
Takashi Iwai1727a772013-01-10 09:52:52 +01001556static const struct hda_model_fixup alc880_fixup_models[] = {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001557 {.id = ALC880_FIXUP_3ST, .name = "3stack"},
1558 {.id = ALC880_FIXUP_3ST_DIG, .name = "3stack-digout"},
1559 {.id = ALC880_FIXUP_5ST, .name = "5stack"},
1560 {.id = ALC880_FIXUP_5ST_DIG, .name = "5stack-digout"},
1561 {.id = ALC880_FIXUP_6ST, .name = "6stack"},
1562 {.id = ALC880_FIXUP_6ST_DIG, .name = "6stack-digout"},
Takashi Iwai53971452013-01-23 18:21:37 +01001563 {.id = ALC880_FIXUP_6ST_AUTOMUTE, .name = "6stack-automute"},
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001564 {}
1565};
1566
1567
1568/*
Takashi Iwai1d045db2011-07-07 18:23:21 +02001569 * OK, here we have finally the patch for ALC880
1570 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02001571static int patch_alc880(struct hda_codec *codec)
1572{
1573 struct alc_spec *spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001574 int err;
1575
Takashi Iwai3de95172012-05-07 18:03:15 +02001576 err = alc_alloc_spec(codec, 0x0b);
1577 if (err < 0)
1578 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001579
Takashi Iwai3de95172012-05-07 18:03:15 +02001580 spec = codec->spec;
Takashi Iwai08c189f2012-12-19 15:22:24 +01001581 spec->gen.need_dac_fix = 1;
Takashi Iwai7504b6c2013-03-18 11:25:51 +01001582 spec->gen.beep_nid = 0x01;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001583
Takashi Iwai225068a2015-05-29 10:42:14 +02001584 codec->patch_ops.unsol_event = alc880_unsol_event;
1585
Takashi Iwaic9af7532019-05-10 11:01:43 +02001586 alc_pre_init(codec);
1587
Takashi Iwai1727a772013-01-10 09:52:52 +01001588 snd_hda_pick_fixup(codec, alc880_fixup_models, alc880_fixup_tbl,
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001589 alc880_fixups);
Takashi Iwai1727a772013-01-10 09:52:52 +01001590 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02001591
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001592 /* automatic parse from the BIOS config */
1593 err = alc880_parse_auto_config(codec);
1594 if (err < 0)
1595 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001596
Takashi Iwaifea80fa2018-06-20 12:52:46 +02001597 if (!spec->gen.no_analog) {
1598 err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
1599 if (err < 0)
1600 goto error;
1601 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02001602
Takashi Iwai1727a772013-01-10 09:52:52 +01001603 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01001604
Takashi Iwai1d045db2011-07-07 18:23:21 +02001605 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02001606
1607 error:
1608 alc_free(codec);
1609 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001610}
1611
1612
1613/*
1614 * ALC260 support
1615 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02001616static int alc260_parse_auto_config(struct hda_codec *codec)
1617{
Takashi Iwai1d045db2011-07-07 18:23:21 +02001618 static const hda_nid_t alc260_ignore[] = { 0x17, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001619 static const hda_nid_t alc260_ssids[] = { 0x10, 0x15, 0x0f, 0 };
1620 return alc_parse_auto_config(codec, alc260_ignore, alc260_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02001621}
1622
Takashi Iwai1d045db2011-07-07 18:23:21 +02001623/*
1624 * Pin config fixes
1625 */
1626enum {
Takashi Iwaica8f0422012-02-16 11:51:19 +01001627 ALC260_FIXUP_HP_DC5750,
1628 ALC260_FIXUP_HP_PIN_0F,
1629 ALC260_FIXUP_COEF,
Takashi Iwai15317ab2012-02-16 12:02:53 +01001630 ALC260_FIXUP_GPIO1,
Takashi Iwai20f7d922012-02-16 12:35:16 +01001631 ALC260_FIXUP_GPIO1_TOGGLE,
1632 ALC260_FIXUP_REPLACER,
Takashi Iwai0a1c4fa2012-02-16 12:42:30 +01001633 ALC260_FIXUP_HP_B1900,
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001634 ALC260_FIXUP_KN1,
Takashi Iwai39aedee2013-01-10 17:10:40 +01001635 ALC260_FIXUP_FSC_S7020,
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001636 ALC260_FIXUP_FSC_S7020_JWSE,
Takashi Iwaid08c5ef2013-11-22 08:06:36 +01001637 ALC260_FIXUP_VAIO_PINS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02001638};
1639
Takashi Iwai20f7d922012-02-16 12:35:16 +01001640static void alc260_gpio1_automute(struct hda_codec *codec)
1641{
1642 struct alc_spec *spec = codec->spec;
Takashi Iwaiaaf312d2018-06-19 22:28:22 +02001643
1644 alc_update_gpio_data(codec, 0x01, spec->gen.hp_jack_present);
Takashi Iwai20f7d922012-02-16 12:35:16 +01001645}
1646
1647static void alc260_fixup_gpio1_toggle(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001648 const struct hda_fixup *fix, int action)
Takashi Iwai20f7d922012-02-16 12:35:16 +01001649{
1650 struct alc_spec *spec = codec->spec;
Takashi Iwai1727a772013-01-10 09:52:52 +01001651 if (action == HDA_FIXUP_ACT_PROBE) {
Takashi Iwai20f7d922012-02-16 12:35:16 +01001652 /* although the machine has only one output pin, we need to
1653 * toggle GPIO1 according to the jack state
1654 */
Takashi Iwai08c189f2012-12-19 15:22:24 +01001655 spec->gen.automute_hook = alc260_gpio1_automute;
1656 spec->gen.detect_hp = 1;
1657 spec->gen.automute_speaker = 1;
1658 spec->gen.autocfg.hp_pins[0] = 0x0f; /* copy it for automute */
Takashi Iwai62f949b2014-09-11 14:06:53 +02001659 snd_hda_jack_detect_enable_callback(codec, 0x0f,
Takashi Iwai08c189f2012-12-19 15:22:24 +01001660 snd_hda_gen_hp_automute);
Takashi Iwai5579cd62018-06-19 22:22:41 +02001661 alc_setup_gpio(codec, 0x01);
Takashi Iwai20f7d922012-02-16 12:35:16 +01001662 }
1663}
1664
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001665static void alc260_fixup_kn1(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001666 const struct hda_fixup *fix, int action)
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001667{
1668 struct alc_spec *spec = codec->spec;
Takashi Iwai1727a772013-01-10 09:52:52 +01001669 static const struct hda_pintbl pincfgs[] = {
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001670 { 0x0f, 0x02214000 }, /* HP/speaker */
1671 { 0x12, 0x90a60160 }, /* int mic */
1672 { 0x13, 0x02a19000 }, /* ext mic */
1673 { 0x18, 0x01446000 }, /* SPDIF out */
1674 /* disable bogus I/O pins */
1675 { 0x10, 0x411111f0 },
1676 { 0x11, 0x411111f0 },
1677 { 0x14, 0x411111f0 },
1678 { 0x15, 0x411111f0 },
1679 { 0x16, 0x411111f0 },
1680 { 0x17, 0x411111f0 },
1681 { 0x19, 0x411111f0 },
1682 { }
1683 };
1684
1685 switch (action) {
Takashi Iwai1727a772013-01-10 09:52:52 +01001686 case HDA_FIXUP_ACT_PRE_PROBE:
1687 snd_hda_apply_pincfgs(codec, pincfgs);
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001688 spec->init_amp = ALC_INIT_NONE;
1689 break;
1690 }
1691}
1692
Takashi Iwai39aedee2013-01-10 17:10:40 +01001693static void alc260_fixup_fsc_s7020(struct hda_codec *codec,
1694 const struct hda_fixup *fix, int action)
1695{
1696 struct alc_spec *spec = codec->spec;
Takashi Iwai1c76aa52018-06-21 16:37:54 +02001697 if (action == HDA_FIXUP_ACT_PRE_PROBE)
Takashi Iwaie6e0ee52013-02-18 17:04:20 +01001698 spec->init_amp = ALC_INIT_NONE;
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001699}
1700
1701static void alc260_fixup_fsc_s7020_jwse(struct hda_codec *codec,
1702 const struct hda_fixup *fix, int action)
1703{
1704 struct alc_spec *spec = codec->spec;
1705 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwaif811c3c2013-03-07 18:32:59 +01001706 spec->gen.add_jack_modes = 1;
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001707 spec->gen.hp_mic = 1;
Takashi Iwaie6e0ee52013-02-18 17:04:20 +01001708 }
Takashi Iwai39aedee2013-01-10 17:10:40 +01001709}
1710
Takashi Iwai1727a772013-01-10 09:52:52 +01001711static const struct hda_fixup alc260_fixups[] = {
Takashi Iwaica8f0422012-02-16 11:51:19 +01001712 [ALC260_FIXUP_HP_DC5750] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001713 .type = HDA_FIXUP_PINS,
1714 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02001715 { 0x11, 0x90130110 }, /* speaker */
1716 { }
1717 }
1718 },
Takashi Iwaica8f0422012-02-16 11:51:19 +01001719 [ALC260_FIXUP_HP_PIN_0F] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001720 .type = HDA_FIXUP_PINS,
1721 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaica8f0422012-02-16 11:51:19 +01001722 { 0x0f, 0x01214000 }, /* HP */
1723 { }
1724 }
1725 },
1726 [ALC260_FIXUP_COEF] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001727 .type = HDA_FIXUP_VERBS,
Takashi Iwaica8f0422012-02-16 11:51:19 +01001728 .v.verbs = (const struct hda_verb[]) {
Ronan Marquete30cf2d2014-06-01 18:38:53 +02001729 { 0x1a, AC_VERB_SET_COEF_INDEX, 0x07 },
1730 { 0x1a, AC_VERB_SET_PROC_COEF, 0x3040 },
Takashi Iwaica8f0422012-02-16 11:51:19 +01001731 { }
1732 },
Takashi Iwaica8f0422012-02-16 11:51:19 +01001733 },
Takashi Iwai15317ab2012-02-16 12:02:53 +01001734 [ALC260_FIXUP_GPIO1] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02001735 .type = HDA_FIXUP_FUNC,
1736 .v.func = alc_fixup_gpio1,
Takashi Iwai15317ab2012-02-16 12:02:53 +01001737 },
Takashi Iwai20f7d922012-02-16 12:35:16 +01001738 [ALC260_FIXUP_GPIO1_TOGGLE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001739 .type = HDA_FIXUP_FUNC,
Takashi Iwai20f7d922012-02-16 12:35:16 +01001740 .v.func = alc260_fixup_gpio1_toggle,
1741 .chained = true,
1742 .chain_id = ALC260_FIXUP_HP_PIN_0F,
1743 },
1744 [ALC260_FIXUP_REPLACER] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001745 .type = HDA_FIXUP_VERBS,
Takashi Iwai20f7d922012-02-16 12:35:16 +01001746 .v.verbs = (const struct hda_verb[]) {
Takashi Iwai192a98e2014-06-02 15:16:07 +02001747 { 0x1a, AC_VERB_SET_COEF_INDEX, 0x07 },
1748 { 0x1a, AC_VERB_SET_PROC_COEF, 0x3050 },
Takashi Iwai20f7d922012-02-16 12:35:16 +01001749 { }
1750 },
1751 .chained = true,
1752 .chain_id = ALC260_FIXUP_GPIO1_TOGGLE,
1753 },
Takashi Iwai0a1c4fa2012-02-16 12:42:30 +01001754 [ALC260_FIXUP_HP_B1900] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001755 .type = HDA_FIXUP_FUNC,
Takashi Iwai0a1c4fa2012-02-16 12:42:30 +01001756 .v.func = alc260_fixup_gpio1_toggle,
1757 .chained = true,
1758 .chain_id = ALC260_FIXUP_COEF,
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001759 },
1760 [ALC260_FIXUP_KN1] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001761 .type = HDA_FIXUP_FUNC,
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001762 .v.func = alc260_fixup_kn1,
1763 },
Takashi Iwai39aedee2013-01-10 17:10:40 +01001764 [ALC260_FIXUP_FSC_S7020] = {
1765 .type = HDA_FIXUP_FUNC,
1766 .v.func = alc260_fixup_fsc_s7020,
1767 },
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001768 [ALC260_FIXUP_FSC_S7020_JWSE] = {
1769 .type = HDA_FIXUP_FUNC,
1770 .v.func = alc260_fixup_fsc_s7020_jwse,
1771 .chained = true,
1772 .chain_id = ALC260_FIXUP_FSC_S7020,
1773 },
Takashi Iwaid08c5ef2013-11-22 08:06:36 +01001774 [ALC260_FIXUP_VAIO_PINS] = {
1775 .type = HDA_FIXUP_PINS,
1776 .v.pins = (const struct hda_pintbl[]) {
1777 /* Pin configs are missing completely on some VAIOs */
1778 { 0x0f, 0x01211020 },
1779 { 0x10, 0x0001003f },
1780 { 0x11, 0x411111f0 },
1781 { 0x12, 0x01a15930 },
1782 { 0x13, 0x411111f0 },
1783 { 0x14, 0x411111f0 },
1784 { 0x15, 0x411111f0 },
1785 { 0x16, 0x411111f0 },
1786 { 0x17, 0x411111f0 },
1787 { 0x18, 0x411111f0 },
1788 { 0x19, 0x411111f0 },
1789 { }
1790 }
1791 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02001792};
1793
1794static const struct snd_pci_quirk alc260_fixup_tbl[] = {
Takashi Iwai15317ab2012-02-16 12:02:53 +01001795 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_FIXUP_GPIO1),
Takashi Iwaica8f0422012-02-16 11:51:19 +01001796 SND_PCI_QUIRK(0x1025, 0x007f, "Acer Aspire 9500", ALC260_FIXUP_COEF),
Takashi Iwai15317ab2012-02-16 12:02:53 +01001797 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_FIXUP_GPIO1),
Takashi Iwaica8f0422012-02-16 11:51:19 +01001798 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", ALC260_FIXUP_HP_DC5750),
Takashi Iwai0a1c4fa2012-02-16 12:42:30 +01001799 SND_PCI_QUIRK(0x103c, 0x30ba, "HP Presario B1900", ALC260_FIXUP_HP_B1900),
Takashi Iwaid08c5ef2013-11-22 08:06:36 +01001800 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_FIXUP_VAIO_PINS),
Takashi Iwai0f5a5b82013-11-21 09:12:52 +01001801 SND_PCI_QUIRK(0x104d, 0x81e2, "Sony VAIO TX", ALC260_FIXUP_HP_PIN_0F),
Takashi Iwai39aedee2013-01-10 17:10:40 +01001802 SND_PCI_QUIRK(0x10cf, 0x1326, "FSC LifeBook S7020", ALC260_FIXUP_FSC_S7020),
Takashi Iwaib1f58082012-02-16 12:45:03 +01001803 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FIXUP_GPIO1),
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001804 SND_PCI_QUIRK(0x152d, 0x0729, "Quanta KN1", ALC260_FIXUP_KN1),
Takashi Iwai20f7d922012-02-16 12:35:16 +01001805 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_FIXUP_REPLACER),
Takashi Iwaica8f0422012-02-16 11:51:19 +01001806 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_FIXUP_COEF),
Takashi Iwai1d045db2011-07-07 18:23:21 +02001807 {}
1808};
1809
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001810static const struct hda_model_fixup alc260_fixup_models[] = {
1811 {.id = ALC260_FIXUP_GPIO1, .name = "gpio1"},
1812 {.id = ALC260_FIXUP_COEF, .name = "coef"},
1813 {.id = ALC260_FIXUP_FSC_S7020, .name = "fujitsu"},
1814 {.id = ALC260_FIXUP_FSC_S7020_JWSE, .name = "fujitsu-jwse"},
1815 {}
1816};
1817
Takashi Iwai1d045db2011-07-07 18:23:21 +02001818/*
1819 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02001820static int patch_alc260(struct hda_codec *codec)
1821{
1822 struct alc_spec *spec;
Takashi Iwaic3c2c9e2012-02-16 12:59:55 +01001823 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001824
Takashi Iwai3de95172012-05-07 18:03:15 +02001825 err = alc_alloc_spec(codec, 0x07);
1826 if (err < 0)
1827 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001828
Takashi Iwai3de95172012-05-07 18:03:15 +02001829 spec = codec->spec;
Takashi Iwaiea46c3c2013-01-15 18:45:53 +01001830 /* as quite a few machines require HP amp for speaker outputs,
1831 * it's easier to enable it unconditionally; even if it's unneeded,
1832 * it's almost harmless.
1833 */
1834 spec->gen.prefer_hp_amp = 1;
Takashi Iwai7504b6c2013-03-18 11:25:51 +01001835 spec->gen.beep_nid = 0x01;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001836
Takashi Iwai225068a2015-05-29 10:42:14 +02001837 spec->shutup = alc_eapd_shutup;
1838
Takashi Iwaic9af7532019-05-10 11:01:43 +02001839 alc_pre_init(codec);
1840
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001841 snd_hda_pick_fixup(codec, alc260_fixup_models, alc260_fixup_tbl,
1842 alc260_fixups);
Takashi Iwai1727a772013-01-10 09:52:52 +01001843 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02001844
Takashi Iwaic3c2c9e2012-02-16 12:59:55 +01001845 /* automatic parse from the BIOS config */
1846 err = alc260_parse_auto_config(codec);
1847 if (err < 0)
1848 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001849
Takashi Iwaifea80fa2018-06-20 12:52:46 +02001850 if (!spec->gen.no_analog) {
1851 err = set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
1852 if (err < 0)
1853 goto error;
1854 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02001855
Takashi Iwai1727a772013-01-10 09:52:52 +01001856 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01001857
Takashi Iwai1d045db2011-07-07 18:23:21 +02001858 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02001859
1860 error:
1861 alc_free(codec);
1862 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001863}
1864
1865
1866/*
1867 * ALC882/883/885/888/889 support
1868 *
1869 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
1870 * configuration. Each pin widget can choose any input DACs and a mixer.
1871 * Each ADC is connected from a mixer of all inputs. This makes possible
1872 * 6-channel independent captures.
1873 *
1874 * In addition, an independent DAC for the multi-playback (not used in this
1875 * driver yet).
1876 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02001877
1878/*
1879 * Pin config fixes
1880 */
1881enum {
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01001882 ALC882_FIXUP_ABIT_AW9D_MAX,
1883 ALC882_FIXUP_LENOVO_Y530,
1884 ALC882_FIXUP_PB_M5210,
1885 ALC882_FIXUP_ACER_ASPIRE_7736,
1886 ALC882_FIXUP_ASUS_W90V,
Marton Balint8f239212012-03-05 21:33:23 +01001887 ALC889_FIXUP_CD,
David Henningssonb2c53e22014-01-01 14:01:34 +01001888 ALC889_FIXUP_FRONT_HP_NO_PRESENCE,
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01001889 ALC889_FIXUP_VAIO_TT,
Takashi Iwai0e7cc2e2011-11-09 12:42:48 +01001890 ALC888_FIXUP_EEE1601,
Takashi Iwai177943a32011-11-09 12:55:18 +01001891 ALC882_FIXUP_EAPD,
Takashi Iwai7a6069b2011-11-09 15:22:01 +01001892 ALC883_FIXUP_EAPD,
Takashi Iwai8812c4f2011-11-09 17:39:15 +01001893 ALC883_FIXUP_ACER_EAPD,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001894 ALC882_FIXUP_GPIO1,
1895 ALC882_FIXUP_GPIO2,
Takashi Iwaieb844d52011-11-09 18:03:07 +01001896 ALC882_FIXUP_GPIO3,
Takashi Iwai68ef0562011-11-09 18:24:44 +01001897 ALC889_FIXUP_COEF,
1898 ALC882_FIXUP_ASUS_W2JC,
Takashi Iwaic3e837b2011-11-10 16:01:47 +01001899 ALC882_FIXUP_ACER_ASPIRE_4930G,
1900 ALC882_FIXUP_ACER_ASPIRE_8930G,
1901 ALC882_FIXUP_ASPIRE_8930G_VERBS,
Takashi Iwai56710872011-11-14 17:42:11 +01001902 ALC885_FIXUP_MACPRO_GPIO,
Takashi Iwai02a237b2012-02-13 15:25:07 +01001903 ALC889_FIXUP_DAC_ROUTE,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001904 ALC889_FIXUP_MBP_VREF,
1905 ALC889_FIXUP_IMAC91_VREF,
Adrien Vergée7729a42014-01-24 14:56:14 -05001906 ALC889_FIXUP_MBA11_VREF,
Takashi Iwai0756f092013-12-04 13:59:45 +01001907 ALC889_FIXUP_MBA21_VREF,
Takashi Iwaic20f31e2014-02-03 11:02:10 +01001908 ALC889_FIXUP_MP11_VREF,
Mario Kleiner9f660a12015-12-22 00:45:43 +01001909 ALC889_FIXUP_MP41_VREF,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02001910 ALC882_FIXUP_INV_DMIC,
Takashi Iwaie427c232012-07-29 10:04:08 +02001911 ALC882_FIXUP_NO_PRIMARY_HP,
Takashi Iwai1f0bbf02013-11-28 15:21:21 +01001912 ALC887_FIXUP_ASUS_BASS,
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01001913 ALC887_FIXUP_BASS_CHMAP,
Takashi Iwai7beb3a62017-04-10 18:05:52 +02001914 ALC1220_FIXUP_GB_DUAL_CODECS,
Peisen0202f5c2017-10-26 10:35:36 +08001915 ALC1220_FIXUP_CLEVO_P950,
Richard Sailer80690a22019-04-02 15:52:04 +02001916 ALC1220_FIXUP_CLEVO_PB51ED,
1917 ALC1220_FIXUP_CLEVO_PB51ED_PINS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02001918};
1919
Takashi Iwai68ef0562011-11-09 18:24:44 +01001920static void alc889_fixup_coef(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001921 const struct hda_fixup *fix, int action)
Takashi Iwai68ef0562011-11-09 18:24:44 +01001922{
Takashi Iwai1727a772013-01-10 09:52:52 +01001923 if (action != HDA_FIXUP_ACT_INIT)
Takashi Iwai68ef0562011-11-09 18:24:44 +01001924 return;
Kailang Yang1df88742014-10-29 16:10:13 +08001925 alc_update_coef_idx(codec, 7, 0, 0x2030);
Takashi Iwai68ef0562011-11-09 18:24:44 +01001926}
1927
Takashi Iwai56710872011-11-14 17:42:11 +01001928/* set up GPIO at initialization */
1929static void alc885_fixup_macpro_gpio(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001930 const struct hda_fixup *fix, int action)
Takashi Iwai56710872011-11-14 17:42:11 +01001931{
Takashi Iwai215c8502018-06-19 22:34:26 +02001932 struct alc_spec *spec = codec->spec;
1933
1934 spec->gpio_write_delay = true;
1935 alc_fixup_gpio3(codec, fix, action);
Takashi Iwai56710872011-11-14 17:42:11 +01001936}
1937
Takashi Iwai02a237b2012-02-13 15:25:07 +01001938/* Fix the connection of some pins for ALC889:
1939 * At least, Acer Aspire 5935 shows the connections to DAC3/4 don't
1940 * work correctly (bko#42740)
1941 */
1942static void alc889_fixup_dac_route(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001943 const struct hda_fixup *fix, int action)
Takashi Iwai02a237b2012-02-13 15:25:07 +01001944{
Takashi Iwai1727a772013-01-10 09:52:52 +01001945 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwaief8d60f2012-02-17 10:12:38 +01001946 /* fake the connections during parsing the tree */
Michał Mirosławcaf3c042020-01-03 10:23:48 +01001947 static const hda_nid_t conn1[] = { 0x0c, 0x0d };
1948 static const hda_nid_t conn2[] = { 0x0e, 0x0f };
1949 snd_hda_override_conn_list(codec, 0x14, ARRAY_SIZE(conn1), conn1);
1950 snd_hda_override_conn_list(codec, 0x15, ARRAY_SIZE(conn1), conn1);
1951 snd_hda_override_conn_list(codec, 0x18, ARRAY_SIZE(conn2), conn2);
1952 snd_hda_override_conn_list(codec, 0x1a, ARRAY_SIZE(conn2), conn2);
Takashi Iwai1727a772013-01-10 09:52:52 +01001953 } else if (action == HDA_FIXUP_ACT_PROBE) {
Takashi Iwaief8d60f2012-02-17 10:12:38 +01001954 /* restore the connections */
Michał Mirosławcaf3c042020-01-03 10:23:48 +01001955 static const hda_nid_t conn[] = { 0x0c, 0x0d, 0x0e, 0x0f, 0x26 };
1956 snd_hda_override_conn_list(codec, 0x14, ARRAY_SIZE(conn), conn);
1957 snd_hda_override_conn_list(codec, 0x15, ARRAY_SIZE(conn), conn);
1958 snd_hda_override_conn_list(codec, 0x18, ARRAY_SIZE(conn), conn);
1959 snd_hda_override_conn_list(codec, 0x1a, ARRAY_SIZE(conn), conn);
Takashi Iwai02a237b2012-02-13 15:25:07 +01001960 }
1961}
1962
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001963/* Set VREF on HP pin */
1964static void alc889_fixup_mbp_vref(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001965 const struct hda_fixup *fix, int action)
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001966{
Michał Mirosławcaf3c042020-01-03 10:23:48 +01001967 static const hda_nid_t nids[] = { 0x14, 0x15, 0x19 };
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001968 struct alc_spec *spec = codec->spec;
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001969 int i;
1970
Takashi Iwai1727a772013-01-10 09:52:52 +01001971 if (action != HDA_FIXUP_ACT_INIT)
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001972 return;
1973 for (i = 0; i < ARRAY_SIZE(nids); i++) {
1974 unsigned int val = snd_hda_codec_get_pincfg(codec, nids[i]);
1975 if (get_defcfg_device(val) != AC_JACK_HP_OUT)
1976 continue;
Takashi Iwaid3f02d62013-01-10 10:12:22 +01001977 val = snd_hda_codec_get_pin_target(codec, nids[i]);
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001978 val |= AC_PINCTL_VREF_80;
Takashi Iwaicdd03ce2012-04-20 12:34:50 +02001979 snd_hda_set_pin_ctl(codec, nids[i], val);
Takashi Iwai08c189f2012-12-19 15:22:24 +01001980 spec->gen.keep_vref_in_automute = 1;
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001981 break;
1982 }
1983}
1984
Takashi Iwai0756f092013-12-04 13:59:45 +01001985static void alc889_fixup_mac_pins(struct hda_codec *codec,
1986 const hda_nid_t *nids, int num_nids)
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001987{
1988 struct alc_spec *spec = codec->spec;
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001989 int i;
1990
Takashi Iwai0756f092013-12-04 13:59:45 +01001991 for (i = 0; i < num_nids; i++) {
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001992 unsigned int val;
Takashi Iwaid3f02d62013-01-10 10:12:22 +01001993 val = snd_hda_codec_get_pin_target(codec, nids[i]);
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001994 val |= AC_PINCTL_VREF_50;
Takashi Iwaicdd03ce2012-04-20 12:34:50 +02001995 snd_hda_set_pin_ctl(codec, nids[i], val);
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001996 }
Takashi Iwai08c189f2012-12-19 15:22:24 +01001997 spec->gen.keep_vref_in_automute = 1;
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001998}
1999
Takashi Iwai0756f092013-12-04 13:59:45 +01002000/* Set VREF on speaker pins on imac91 */
2001static void alc889_fixup_imac91_vref(struct hda_codec *codec,
2002 const struct hda_fixup *fix, int action)
2003{
Michał Mirosławcaf3c042020-01-03 10:23:48 +01002004 static const hda_nid_t nids[] = { 0x18, 0x1a };
Takashi Iwai0756f092013-12-04 13:59:45 +01002005
2006 if (action == HDA_FIXUP_ACT_INIT)
2007 alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
2008}
2009
Adrien Vergée7729a42014-01-24 14:56:14 -05002010/* Set VREF on speaker pins on mba11 */
2011static void alc889_fixup_mba11_vref(struct hda_codec *codec,
2012 const struct hda_fixup *fix, int action)
2013{
Michał Mirosławcaf3c042020-01-03 10:23:48 +01002014 static const hda_nid_t nids[] = { 0x18 };
Adrien Vergée7729a42014-01-24 14:56:14 -05002015
2016 if (action == HDA_FIXUP_ACT_INIT)
2017 alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
2018}
2019
Takashi Iwai0756f092013-12-04 13:59:45 +01002020/* Set VREF on speaker pins on mba21 */
2021static void alc889_fixup_mba21_vref(struct hda_codec *codec,
2022 const struct hda_fixup *fix, int action)
2023{
Michał Mirosławcaf3c042020-01-03 10:23:48 +01002024 static const hda_nid_t nids[] = { 0x18, 0x19 };
Takashi Iwai0756f092013-12-04 13:59:45 +01002025
2026 if (action == HDA_FIXUP_ACT_INIT)
2027 alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
2028}
2029
Takashi Iwaie427c232012-07-29 10:04:08 +02002030/* Don't take HP output as primary
Fernando Luis Vázquez Caod9111492013-02-12 16:49:46 +09002031 * Strangely, the speaker output doesn't work on Vaio Z and some Vaio
2032 * all-in-one desktop PCs (for example VGC-LN51JGB) through DAC 0x05
Takashi Iwaie427c232012-07-29 10:04:08 +02002033 */
2034static void alc882_fixup_no_primary_hp(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01002035 const struct hda_fixup *fix, int action)
Takashi Iwaie427c232012-07-29 10:04:08 +02002036{
2037 struct alc_spec *spec = codec->spec;
Takashi Iwaida96fb52013-07-29 16:54:36 +02002038 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai08c189f2012-12-19 15:22:24 +01002039 spec->gen.no_primary_hp = 1;
Takashi Iwaida96fb52013-07-29 16:54:36 +02002040 spec->gen.no_multi_io = 1;
2041 }
Takashi Iwaie427c232012-07-29 10:04:08 +02002042}
2043
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01002044static void alc_fixup_bass_chmap(struct hda_codec *codec,
2045 const struct hda_fixup *fix, int action);
2046
Takashi Iwai7beb3a62017-04-10 18:05:52 +02002047/* For dual-codec configuration, we need to disable some features to avoid
2048 * conflicts of kctls and PCM streams
2049 */
2050static void alc_fixup_dual_codecs(struct hda_codec *codec,
2051 const struct hda_fixup *fix, int action)
2052{
2053 struct alc_spec *spec = codec->spec;
2054
2055 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2056 return;
2057 /* disable vmaster */
2058 spec->gen.suppress_vmaster = 1;
2059 /* auto-mute and auto-mic switch don't work with multiple codecs */
2060 spec->gen.suppress_auto_mute = 1;
2061 spec->gen.suppress_auto_mic = 1;
2062 /* disable aamix as well */
2063 spec->gen.mixer_nid = 0;
2064 /* add location prefix to avoid conflicts */
2065 codec->force_pin_prefix = 1;
2066}
2067
2068static void rename_ctl(struct hda_codec *codec, const char *oldname,
2069 const char *newname)
2070{
2071 struct snd_kcontrol *kctl;
2072
2073 kctl = snd_hda_find_mixer_ctl(codec, oldname);
2074 if (kctl)
2075 strcpy(kctl->id.name, newname);
2076}
2077
2078static void alc1220_fixup_gb_dual_codecs(struct hda_codec *codec,
2079 const struct hda_fixup *fix,
2080 int action)
2081{
2082 alc_fixup_dual_codecs(codec, fix, action);
2083 switch (action) {
2084 case HDA_FIXUP_ACT_PRE_PROBE:
2085 /* override card longname to provide a unique UCM profile */
2086 strcpy(codec->card->longname, "HDAudio-Gigabyte-ALC1220DualCodecs");
2087 break;
2088 case HDA_FIXUP_ACT_BUILD:
2089 /* rename Capture controls depending on the codec */
2090 rename_ctl(codec, "Capture Volume",
2091 codec->addr == 0 ?
2092 "Rear-Panel Capture Volume" :
2093 "Front-Panel Capture Volume");
2094 rename_ctl(codec, "Capture Switch",
2095 codec->addr == 0 ?
2096 "Rear-Panel Capture Switch" :
2097 "Front-Panel Capture Switch");
2098 break;
2099 }
2100}
2101
Peisen0202f5c2017-10-26 10:35:36 +08002102static void alc1220_fixup_clevo_p950(struct hda_codec *codec,
2103 const struct hda_fixup *fix,
2104 int action)
2105{
Michał Mirosławcaf3c042020-01-03 10:23:48 +01002106 static const hda_nid_t conn1[] = { 0x0c };
Peisen0202f5c2017-10-26 10:35:36 +08002107
2108 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2109 return;
2110
2111 alc_update_coef_idx(codec, 0x7, 0, 0x3c3);
2112 /* We therefore want to make sure 0x14 (front headphone) and
2113 * 0x1b (speakers) use the stereo DAC 0x02
2114 */
Michał Mirosławcaf3c042020-01-03 10:23:48 +01002115 snd_hda_override_conn_list(codec, 0x14, ARRAY_SIZE(conn1), conn1);
2116 snd_hda_override_conn_list(codec, 0x1b, ARRAY_SIZE(conn1), conn1);
Peisen0202f5c2017-10-26 10:35:36 +08002117}
2118
Jeremy Soller7f665b12019-02-13 10:56:19 -07002119static void alc_fixup_headset_mode_no_hp_mic(struct hda_codec *codec,
2120 const struct hda_fixup *fix, int action);
2121
Richard Sailer80690a22019-04-02 15:52:04 +02002122static void alc1220_fixup_clevo_pb51ed(struct hda_codec *codec,
Jeremy Soller7f665b12019-02-13 10:56:19 -07002123 const struct hda_fixup *fix,
2124 int action)
2125{
2126 alc1220_fixup_clevo_p950(codec, fix, action);
2127 alc_fixup_headset_mode_no_hp_mic(codec, fix, action);
2128}
2129
Takashi Iwai1727a772013-01-10 09:52:52 +01002130static const struct hda_fixup alc882_fixups[] = {
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002131 [ALC882_FIXUP_ABIT_AW9D_MAX] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002132 .type = HDA_FIXUP_PINS,
2133 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002134 { 0x15, 0x01080104 }, /* side */
2135 { 0x16, 0x01011012 }, /* rear */
2136 { 0x17, 0x01016011 }, /* clfe */
2137 { }
2138 }
2139 },
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002140 [ALC882_FIXUP_LENOVO_Y530] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002141 .type = HDA_FIXUP_PINS,
2142 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002143 { 0x15, 0x99130112 }, /* rear int speakers */
2144 { 0x16, 0x99130111 }, /* subwoofer */
2145 { }
2146 }
2147 },
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002148 [ALC882_FIXUP_PB_M5210] = {
Takashi Iwaifd108212013-01-10 10:18:14 +01002149 .type = HDA_FIXUP_PINCTLS,
2150 .v.pins = (const struct hda_pintbl[]) {
2151 { 0x19, PIN_VREF50 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02002152 {}
2153 }
2154 },
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002155 [ALC882_FIXUP_ACER_ASPIRE_7736] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002156 .type = HDA_FIXUP_FUNC,
Takashi Iwai23d30f22012-05-07 17:17:32 +02002157 .v.func = alc_fixup_sku_ignore,
Takashi Iwai1d045db2011-07-07 18:23:21 +02002158 },
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002159 [ALC882_FIXUP_ASUS_W90V] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002160 .type = HDA_FIXUP_PINS,
2161 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai5cdf7452011-10-26 23:04:08 +02002162 { 0x16, 0x99130110 }, /* fix sequence for CLFE */
2163 { }
2164 }
2165 },
Marton Balint8f239212012-03-05 21:33:23 +01002166 [ALC889_FIXUP_CD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002167 .type = HDA_FIXUP_PINS,
2168 .v.pins = (const struct hda_pintbl[]) {
Marton Balint8f239212012-03-05 21:33:23 +01002169 { 0x1c, 0x993301f0 }, /* CD */
2170 { }
2171 }
2172 },
David Henningssonb2c53e22014-01-01 14:01:34 +01002173 [ALC889_FIXUP_FRONT_HP_NO_PRESENCE] = {
2174 .type = HDA_FIXUP_PINS,
2175 .v.pins = (const struct hda_pintbl[]) {
2176 { 0x1b, 0x02214120 }, /* Front HP jack is flaky, disable jack detect */
2177 { }
2178 },
2179 .chained = true,
2180 .chain_id = ALC889_FIXUP_CD,
2181 },
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002182 [ALC889_FIXUP_VAIO_TT] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002183 .type = HDA_FIXUP_PINS,
2184 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002185 { 0x17, 0x90170111 }, /* hidden surround speaker */
2186 { }
2187 }
2188 },
Takashi Iwai0e7cc2e2011-11-09 12:42:48 +01002189 [ALC888_FIXUP_EEE1601] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002190 .type = HDA_FIXUP_VERBS,
Takashi Iwai0e7cc2e2011-11-09 12:42:48 +01002191 .v.verbs = (const struct hda_verb[]) {
2192 { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b },
2193 { 0x20, AC_VERB_SET_PROC_COEF, 0x0838 },
2194 { }
2195 }
Takashi Iwai177943a32011-11-09 12:55:18 +01002196 },
2197 [ALC882_FIXUP_EAPD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002198 .type = HDA_FIXUP_VERBS,
Takashi Iwai177943a32011-11-09 12:55:18 +01002199 .v.verbs = (const struct hda_verb[]) {
2200 /* change to EAPD mode */
2201 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2202 { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
2203 { }
2204 }
2205 },
Takashi Iwai7a6069b2011-11-09 15:22:01 +01002206 [ALC883_FIXUP_EAPD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002207 .type = HDA_FIXUP_VERBS,
Takashi Iwai7a6069b2011-11-09 15:22:01 +01002208 .v.verbs = (const struct hda_verb[]) {
2209 /* change to EAPD mode */
2210 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2211 { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
2212 { }
2213 }
2214 },
Takashi Iwai8812c4f2011-11-09 17:39:15 +01002215 [ALC883_FIXUP_ACER_EAPD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002216 .type = HDA_FIXUP_VERBS,
Takashi Iwai8812c4f2011-11-09 17:39:15 +01002217 .v.verbs = (const struct hda_verb[]) {
2218 /* eanable EAPD on Acer laptops */
2219 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2220 { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
2221 { }
2222 }
2223 },
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002224 [ALC882_FIXUP_GPIO1] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02002225 .type = HDA_FIXUP_FUNC,
2226 .v.func = alc_fixup_gpio1,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002227 },
2228 [ALC882_FIXUP_GPIO2] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02002229 .type = HDA_FIXUP_FUNC,
2230 .v.func = alc_fixup_gpio2,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002231 },
Takashi Iwaieb844d52011-11-09 18:03:07 +01002232 [ALC882_FIXUP_GPIO3] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02002233 .type = HDA_FIXUP_FUNC,
2234 .v.func = alc_fixup_gpio3,
Takashi Iwaieb844d52011-11-09 18:03:07 +01002235 },
Takashi Iwai68ef0562011-11-09 18:24:44 +01002236 [ALC882_FIXUP_ASUS_W2JC] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02002237 .type = HDA_FIXUP_FUNC,
2238 .v.func = alc_fixup_gpio1,
Takashi Iwai68ef0562011-11-09 18:24:44 +01002239 .chained = true,
2240 .chain_id = ALC882_FIXUP_EAPD,
2241 },
2242 [ALC889_FIXUP_COEF] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002243 .type = HDA_FIXUP_FUNC,
Takashi Iwai68ef0562011-11-09 18:24:44 +01002244 .v.func = alc889_fixup_coef,
2245 },
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002246 [ALC882_FIXUP_ACER_ASPIRE_4930G] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002247 .type = HDA_FIXUP_PINS,
2248 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002249 { 0x16, 0x99130111 }, /* CLFE speaker */
2250 { 0x17, 0x99130112 }, /* surround speaker */
2251 { }
Takashi Iwai038d4fe2012-04-11 17:18:12 +02002252 },
2253 .chained = true,
2254 .chain_id = ALC882_FIXUP_GPIO1,
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002255 },
2256 [ALC882_FIXUP_ACER_ASPIRE_8930G] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002257 .type = HDA_FIXUP_PINS,
2258 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002259 { 0x16, 0x99130111 }, /* CLFE speaker */
2260 { 0x1b, 0x99130112 }, /* surround speaker */
2261 { }
2262 },
2263 .chained = true,
2264 .chain_id = ALC882_FIXUP_ASPIRE_8930G_VERBS,
2265 },
2266 [ALC882_FIXUP_ASPIRE_8930G_VERBS] = {
2267 /* additional init verbs for Acer Aspire 8930G */
Takashi Iwai1727a772013-01-10 09:52:52 +01002268 .type = HDA_FIXUP_VERBS,
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002269 .v.verbs = (const struct hda_verb[]) {
2270 /* Enable all DACs */
2271 /* DAC DISABLE/MUTE 1? */
2272 /* setting bits 1-5 disables DAC nids 0x02-0x06
2273 * apparently. Init=0x38 */
2274 { 0x20, AC_VERB_SET_COEF_INDEX, 0x03 },
2275 { 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
2276 /* DAC DISABLE/MUTE 2? */
2277 /* some bit here disables the other DACs.
2278 * Init=0x4900 */
2279 { 0x20, AC_VERB_SET_COEF_INDEX, 0x08 },
2280 { 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
2281 /* DMIC fix
2282 * This laptop has a stereo digital microphone.
2283 * The mics are only 1cm apart which makes the stereo
2284 * useless. However, either the mic or the ALC889
2285 * makes the signal become a difference/sum signal
2286 * instead of standard stereo, which is annoying.
2287 * So instead we flip this bit which makes the
2288 * codec replicate the sum signal to both channels,
2289 * turning it into a normal mono mic.
2290 */
2291 /* DMIC_CONTROL? Init value = 0x0001 */
2292 { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b },
2293 { 0x20, AC_VERB_SET_PROC_COEF, 0x0003 },
2294 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2295 { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
2296 { }
Takashi Iwai038d4fe2012-04-11 17:18:12 +02002297 },
2298 .chained = true,
2299 .chain_id = ALC882_FIXUP_GPIO1,
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002300 },
Takashi Iwai56710872011-11-14 17:42:11 +01002301 [ALC885_FIXUP_MACPRO_GPIO] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002302 .type = HDA_FIXUP_FUNC,
Takashi Iwai56710872011-11-14 17:42:11 +01002303 .v.func = alc885_fixup_macpro_gpio,
2304 },
Takashi Iwai02a237b2012-02-13 15:25:07 +01002305 [ALC889_FIXUP_DAC_ROUTE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002306 .type = HDA_FIXUP_FUNC,
Takashi Iwai02a237b2012-02-13 15:25:07 +01002307 .v.func = alc889_fixup_dac_route,
2308 },
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002309 [ALC889_FIXUP_MBP_VREF] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002310 .type = HDA_FIXUP_FUNC,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002311 .v.func = alc889_fixup_mbp_vref,
2312 .chained = true,
2313 .chain_id = ALC882_FIXUP_GPIO1,
2314 },
2315 [ALC889_FIXUP_IMAC91_VREF] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002316 .type = HDA_FIXUP_FUNC,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002317 .v.func = alc889_fixup_imac91_vref,
2318 .chained = true,
2319 .chain_id = ALC882_FIXUP_GPIO1,
2320 },
Adrien Vergée7729a42014-01-24 14:56:14 -05002321 [ALC889_FIXUP_MBA11_VREF] = {
2322 .type = HDA_FIXUP_FUNC,
2323 .v.func = alc889_fixup_mba11_vref,
2324 .chained = true,
2325 .chain_id = ALC889_FIXUP_MBP_VREF,
2326 },
Takashi Iwai0756f092013-12-04 13:59:45 +01002327 [ALC889_FIXUP_MBA21_VREF] = {
2328 .type = HDA_FIXUP_FUNC,
2329 .v.func = alc889_fixup_mba21_vref,
2330 .chained = true,
2331 .chain_id = ALC889_FIXUP_MBP_VREF,
2332 },
Takashi Iwaic20f31e2014-02-03 11:02:10 +01002333 [ALC889_FIXUP_MP11_VREF] = {
2334 .type = HDA_FIXUP_FUNC,
2335 .v.func = alc889_fixup_mba11_vref,
2336 .chained = true,
2337 .chain_id = ALC885_FIXUP_MACPRO_GPIO,
2338 },
Mario Kleiner9f660a12015-12-22 00:45:43 +01002339 [ALC889_FIXUP_MP41_VREF] = {
2340 .type = HDA_FIXUP_FUNC,
2341 .v.func = alc889_fixup_mbp_vref,
2342 .chained = true,
2343 .chain_id = ALC885_FIXUP_MACPRO_GPIO,
2344 },
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002345 [ALC882_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002346 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02002347 .v.func = alc_fixup_inv_dmic,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002348 },
Takashi Iwaie427c232012-07-29 10:04:08 +02002349 [ALC882_FIXUP_NO_PRIMARY_HP] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002350 .type = HDA_FIXUP_FUNC,
Takashi Iwaie427c232012-07-29 10:04:08 +02002351 .v.func = alc882_fixup_no_primary_hp,
2352 },
Takashi Iwai1f0bbf02013-11-28 15:21:21 +01002353 [ALC887_FIXUP_ASUS_BASS] = {
2354 .type = HDA_FIXUP_PINS,
2355 .v.pins = (const struct hda_pintbl[]) {
2356 {0x16, 0x99130130}, /* bass speaker */
2357 {}
2358 },
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01002359 .chained = true,
2360 .chain_id = ALC887_FIXUP_BASS_CHMAP,
2361 },
2362 [ALC887_FIXUP_BASS_CHMAP] = {
2363 .type = HDA_FIXUP_FUNC,
2364 .v.func = alc_fixup_bass_chmap,
Takashi Iwai1f0bbf02013-11-28 15:21:21 +01002365 },
Takashi Iwai7beb3a62017-04-10 18:05:52 +02002366 [ALC1220_FIXUP_GB_DUAL_CODECS] = {
2367 .type = HDA_FIXUP_FUNC,
2368 .v.func = alc1220_fixup_gb_dual_codecs,
2369 },
Peisen0202f5c2017-10-26 10:35:36 +08002370 [ALC1220_FIXUP_CLEVO_P950] = {
2371 .type = HDA_FIXUP_FUNC,
2372 .v.func = alc1220_fixup_clevo_p950,
2373 },
Richard Sailer80690a22019-04-02 15:52:04 +02002374 [ALC1220_FIXUP_CLEVO_PB51ED] = {
Jeremy Soller7f665b12019-02-13 10:56:19 -07002375 .type = HDA_FIXUP_FUNC,
Richard Sailer80690a22019-04-02 15:52:04 +02002376 .v.func = alc1220_fixup_clevo_pb51ed,
Jeremy Soller7f665b12019-02-13 10:56:19 -07002377 },
Richard Sailer80690a22019-04-02 15:52:04 +02002378 [ALC1220_FIXUP_CLEVO_PB51ED_PINS] = {
Jeremy Soller7f665b12019-02-13 10:56:19 -07002379 .type = HDA_FIXUP_PINS,
2380 .v.pins = (const struct hda_pintbl[]) {
2381 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
2382 {}
2383 },
2384 .chained = true,
Richard Sailer80690a22019-04-02 15:52:04 +02002385 .chain_id = ALC1220_FIXUP_CLEVO_PB51ED,
Jeremy Soller7f665b12019-02-13 10:56:19 -07002386 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02002387};
2388
2389static const struct snd_pci_quirk alc882_fixup_tbl[] = {
Takashi Iwai8812c4f2011-11-09 17:39:15 +01002390 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_FIXUP_ACER_EAPD),
2391 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
Takashi Iwaib5d724b2015-06-02 19:57:08 +02002392 SND_PCI_QUIRK(0x1025, 0x0107, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
Takashi Iwai8812c4f2011-11-09 17:39:15 +01002393 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_FIXUP_ACER_EAPD),
2394 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
2395 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_FIXUP_ACER_EAPD),
2396 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_FIXUP_ACER_EAPD),
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002397 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
2398 ALC882_FIXUP_ACER_ASPIRE_4930G),
2399 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
2400 ALC882_FIXUP_ACER_ASPIRE_4930G),
2401 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
2402 ALC882_FIXUP_ACER_ASPIRE_8930G),
2403 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
2404 ALC882_FIXUP_ACER_ASPIRE_8930G),
2405 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
2406 ALC882_FIXUP_ACER_ASPIRE_4930G),
2407 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
2408 ALC882_FIXUP_ACER_ASPIRE_4930G),
2409 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
2410 ALC882_FIXUP_ACER_ASPIRE_4930G),
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002411 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", ALC882_FIXUP_PB_M5210),
Takashi Iwaif5c53d82012-05-07 10:07:33 +02002412 SND_PCI_QUIRK(0x1025, 0x021e, "Acer Aspire 5739G",
2413 ALC882_FIXUP_ACER_ASPIRE_4930G),
Takashi Iwai02a237b2012-02-13 15:25:07 +01002414 SND_PCI_QUIRK(0x1025, 0x0259, "Acer Aspire 5935", ALC889_FIXUP_DAC_ROUTE),
Takashi Iwaife97da12012-04-12 08:00:19 +02002415 SND_PCI_QUIRK(0x1025, 0x026b, "Acer Aspire 8940G", ALC882_FIXUP_ACER_ASPIRE_8930G),
Takashi Iwaiac9b1cd2011-11-09 17:45:55 +01002416 SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", ALC882_FIXUP_ACER_ASPIRE_7736),
Takashi Iwai177943a32011-11-09 12:55:18 +01002417 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_FIXUP_EAPD),
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002418 SND_PCI_QUIRK(0x1043, 0x1873, "ASUS W90V", ALC882_FIXUP_ASUS_W90V),
Takashi Iwai68ef0562011-11-09 18:24:44 +01002419 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_FIXUP_ASUS_W2JC),
Takashi Iwai0e7cc2e2011-11-09 12:42:48 +01002420 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_FIXUP_EEE1601),
Takashi Iwai1f0bbf02013-11-28 15:21:21 +01002421 SND_PCI_QUIRK(0x1043, 0x84bc, "ASUS ET2700", ALC887_FIXUP_ASUS_BASS),
Takashi Iwai85bcf962016-12-06 16:20:36 +01002422 SND_PCI_QUIRK(0x1043, 0x8691, "ASUS ROG Ranger VIII", ALC882_FIXUP_GPIO3),
Takashi Iwaiac9b1cd2011-11-09 17:45:55 +01002423 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT),
Takashi Iwaie427c232012-07-29 10:04:08 +02002424 SND_PCI_QUIRK(0x104d, 0x905a, "Sony Vaio Z", ALC882_FIXUP_NO_PRIMARY_HP),
Sergei A. Trusov3f3c3712017-08-02 20:23:48 +10002425 SND_PCI_QUIRK(0x104d, 0x9060, "Sony Vaio VPCL14M1R", ALC882_FIXUP_NO_PRIMARY_HP),
Fernando Luis Vázquez Cao12e31a72013-02-12 16:47:44 +09002426 SND_PCI_QUIRK(0x104d, 0x9043, "Sony Vaio VGC-LN51JGB", ALC882_FIXUP_NO_PRIMARY_HP),
Takashi Iwaic44d9b12016-02-07 09:38:26 +01002427 SND_PCI_QUIRK(0x104d, 0x9044, "Sony VAIO AiO", ALC882_FIXUP_NO_PRIMARY_HP),
Takashi Iwai56710872011-11-14 17:42:11 +01002428
2429 /* All Apple entries are in codec SSIDs */
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002430 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC889_FIXUP_MBP_VREF),
2431 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC889_FIXUP_MBP_VREF),
2432 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF),
Takashi Iwaic20f31e2014-02-03 11:02:10 +01002433 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC889_FIXUP_MP11_VREF),
Takashi Iwai56710872011-11-14 17:42:11 +01002434 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_FIXUP_MACPRO_GPIO),
2435 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_FIXUP_MACPRO_GPIO),
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002436 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC889_FIXUP_MBP_VREF),
2437 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889_FIXUP_MBP_VREF),
Takashi Iwai56710872011-11-14 17:42:11 +01002438 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_FIXUP_EAPD),
Adrien Vergée7729a42014-01-24 14:56:14 -05002439 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC889_FIXUP_MBA11_VREF),
Takashi Iwai0756f092013-12-04 13:59:45 +01002440 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC889_FIXUP_MBA21_VREF),
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002441 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889_FIXUP_MBP_VREF),
2442 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF),
Takashi Iwai56710872011-11-14 17:42:11 +01002443 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_FIXUP_MACPRO_GPIO),
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002444 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC889_FIXUP_IMAC91_VREF),
2445 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC889_FIXUP_IMAC91_VREF),
2446 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC889_FIXUP_IMAC91_VREF),
Mario Kleiner9f660a12015-12-22 00:45:43 +01002447 SND_PCI_QUIRK(0x106b, 0x4200, "Mac Pro 4,1/5,1", ALC889_FIXUP_MP41_VREF),
Takashi Iwai05193632012-11-12 10:07:36 +01002448 SND_PCI_QUIRK(0x106b, 0x4300, "iMac 9,1", ALC889_FIXUP_IMAC91_VREF),
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002449 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC889_FIXUP_IMAC91_VREF),
2450 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC889_FIXUP_IMAC91_VREF),
Takashi Iwai649ccd02015-07-30 22:30:29 +02002451 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC889_FIXUP_MBA11_VREF),
Takashi Iwai56710872011-11-14 17:42:11 +01002452
Takashi Iwai7a6069b2011-11-09 15:22:01 +01002453 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC882_FIXUP_EAPD),
David Henningssonb2c53e22014-01-01 14:01:34 +01002454 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3/Z87X-UD3H", ALC889_FIXUP_FRONT_HP_NO_PRESENCE),
Takashi Iwai7beb3a62017-04-10 18:05:52 +02002455 SND_PCI_QUIRK(0x1458, 0xa0b8, "Gigabyte AZ370-Gaming", ALC1220_FIXUP_GB_DUAL_CODECS),
Christian Lachner0d45e862020-02-23 10:24:16 +01002456 SND_PCI_QUIRK(0x1458, 0xa0cd, "Gigabyte X570 Aorus Master", ALC1220_FIXUP_CLEVO_P950),
Takashi Iwaia655e2b2020-02-17 16:19:47 +01002457 SND_PCI_QUIRK(0x1462, 0x1228, "MSI-GP63", ALC1220_FIXUP_CLEVO_P950),
Takashi Iwai7dafba32020-02-12 09:10:47 +01002458 SND_PCI_QUIRK(0x1462, 0x1276, "MSI-GL73", ALC1220_FIXUP_CLEVO_P950),
Takashi Iwaicc5049a2020-02-18 09:09:15 +01002459 SND_PCI_QUIRK(0x1462, 0x1293, "MSI-GP65", ALC1220_FIXUP_CLEVO_P950),
Takashi Iwaid2c3b142017-06-01 09:35:30 +02002460 SND_PCI_QUIRK(0x1462, 0x7350, "MSI-7350", ALC889_FIXUP_CD),
Takashi Iwai63691582017-05-22 16:32:46 +02002461 SND_PCI_QUIRK(0x1462, 0xda57, "MSI Z270-Gaming", ALC1220_FIXUP_GB_DUAL_CODECS),
Takashi Iwaid2c3b142017-06-01 09:35:30 +02002462 SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3),
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002463 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX),
Peisen0202f5c2017-10-26 10:35:36 +08002464 SND_PCI_QUIRK(0x1558, 0x9501, "Clevo P950HR", ALC1220_FIXUP_CLEVO_P950),
Takashi Iwaif3d737b2018-07-17 17:08:32 +02002465 SND_PCI_QUIRK(0x1558, 0x95e1, "Clevo P95xER", ALC1220_FIXUP_CLEVO_P950),
Jeremy Soller2f0d5202018-05-07 09:28:45 -06002466 SND_PCI_QUIRK(0x1558, 0x95e2, "Clevo P950ER", ALC1220_FIXUP_CLEVO_P950),
Richard Sailer503d90b2019-06-19 13:33:11 +02002467 SND_PCI_QUIRK(0x1558, 0x96e1, "Clevo P960[ER][CDFN]-K", ALC1220_FIXUP_CLEVO_P950),
2468 SND_PCI_QUIRK(0x1558, 0x97e1, "Clevo P970[ER][CDFN]", ALC1220_FIXUP_CLEVO_P950),
2469 SND_PCI_QUIRK(0x1558, 0x65d1, "Clevo PB51[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
2470 SND_PCI_QUIRK(0x1558, 0x67d1, "Clevo PB71[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
Takashi Iwai7a6069b2011-11-09 15:22:01 +01002471 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD),
2472 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD),
Takashi Iwaiac9b1cd2011-11-09 17:45:55 +01002473 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", ALC882_FIXUP_LENOVO_Y530),
Takashi Iwai68ef0562011-11-09 18:24:44 +01002474 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_FIXUP_COEF),
Takashi Iwai1d045db2011-07-07 18:23:21 +02002475 {}
2476};
2477
Takashi Iwai1727a772013-01-10 09:52:52 +01002478static const struct hda_model_fixup alc882_fixup_models[] = {
Takashi Iwai772c2912018-06-26 17:17:53 +02002479 {.id = ALC882_FIXUP_ABIT_AW9D_MAX, .name = "abit-aw9d"},
2480 {.id = ALC882_FIXUP_LENOVO_Y530, .name = "lenovo-y530"},
2481 {.id = ALC882_FIXUP_ACER_ASPIRE_7736, .name = "acer-aspire-7736"},
2482 {.id = ALC882_FIXUP_ASUS_W90V, .name = "asus-w90v"},
2483 {.id = ALC889_FIXUP_CD, .name = "cd"},
2484 {.id = ALC889_FIXUP_FRONT_HP_NO_PRESENCE, .name = "no-front-hp"},
2485 {.id = ALC889_FIXUP_VAIO_TT, .name = "vaio-tt"},
2486 {.id = ALC888_FIXUP_EEE1601, .name = "eee1601"},
2487 {.id = ALC882_FIXUP_EAPD, .name = "alc882-eapd"},
2488 {.id = ALC883_FIXUP_EAPD, .name = "alc883-eapd"},
2489 {.id = ALC882_FIXUP_GPIO1, .name = "gpio1"},
2490 {.id = ALC882_FIXUP_GPIO2, .name = "gpio2"},
2491 {.id = ALC882_FIXUP_GPIO3, .name = "gpio3"},
2492 {.id = ALC889_FIXUP_COEF, .name = "alc889-coef"},
2493 {.id = ALC882_FIXUP_ASUS_W2JC, .name = "asus-w2jc"},
Takashi Iwai912093b2012-04-11 14:03:41 +02002494 {.id = ALC882_FIXUP_ACER_ASPIRE_4930G, .name = "acer-aspire-4930g"},
2495 {.id = ALC882_FIXUP_ACER_ASPIRE_8930G, .name = "acer-aspire-8930g"},
2496 {.id = ALC883_FIXUP_ACER_EAPD, .name = "acer-aspire"},
Takashi Iwai772c2912018-06-26 17:17:53 +02002497 {.id = ALC885_FIXUP_MACPRO_GPIO, .name = "macpro-gpio"},
2498 {.id = ALC889_FIXUP_DAC_ROUTE, .name = "dac-route"},
2499 {.id = ALC889_FIXUP_MBP_VREF, .name = "mbp-vref"},
2500 {.id = ALC889_FIXUP_IMAC91_VREF, .name = "imac91-vref"},
2501 {.id = ALC889_FIXUP_MBA11_VREF, .name = "mba11-vref"},
2502 {.id = ALC889_FIXUP_MBA21_VREF, .name = "mba21-vref"},
2503 {.id = ALC889_FIXUP_MP11_VREF, .name = "mp11-vref"},
2504 {.id = ALC889_FIXUP_MP41_VREF, .name = "mp41-vref"},
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002505 {.id = ALC882_FIXUP_INV_DMIC, .name = "inv-dmic"},
Takashi Iwaie427c232012-07-29 10:04:08 +02002506 {.id = ALC882_FIXUP_NO_PRIMARY_HP, .name = "no-primary-hp"},
Takashi Iwai772c2912018-06-26 17:17:53 +02002507 {.id = ALC887_FIXUP_ASUS_BASS, .name = "asus-bass"},
Takashi Iwaiba90d6a2017-05-22 16:38:47 +02002508 {.id = ALC1220_FIXUP_GB_DUAL_CODECS, .name = "dual-codecs"},
Takashi Iwai772c2912018-06-26 17:17:53 +02002509 {.id = ALC1220_FIXUP_CLEVO_P950, .name = "clevo-p950"},
Takashi Iwai912093b2012-04-11 14:03:41 +02002510 {}
2511};
2512
Takashi Iwai1d045db2011-07-07 18:23:21 +02002513/*
2514 * BIOS auto configuration
2515 */
2516/* almost identical with ALC880 parser... */
2517static int alc882_parse_auto_config(struct hda_codec *codec)
2518{
Takashi Iwai1d045db2011-07-07 18:23:21 +02002519 static const hda_nid_t alc882_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002520 static const hda_nid_t alc882_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2521 return alc_parse_auto_config(codec, alc882_ignore, alc882_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002522}
2523
Takashi Iwai1d045db2011-07-07 18:23:21 +02002524/*
2525 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002526static int patch_alc882(struct hda_codec *codec)
2527{
2528 struct alc_spec *spec;
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002529 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002530
Takashi Iwai3de95172012-05-07 18:03:15 +02002531 err = alc_alloc_spec(codec, 0x0b);
2532 if (err < 0)
2533 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002534
Takashi Iwai3de95172012-05-07 18:03:15 +02002535 spec = codec->spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002536
Takashi Iwai7639a062015-03-03 10:07:24 +01002537 switch (codec->core.vendor_id) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002538 case 0x10ec0882:
2539 case 0x10ec0885:
Takashi Iwaiacf08082014-09-02 07:21:56 +02002540 case 0x10ec0900:
Kailang Yang6d9ffcf2020-01-03 16:24:06 +08002541 case 0x10ec0b00:
Kailang Yanga535ad52017-01-16 16:59:26 +08002542 case 0x10ec1220:
Takashi Iwai1d045db2011-07-07 18:23:21 +02002543 break;
2544 default:
2545 /* ALC883 and variants */
2546 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
2547 break;
2548 }
2549
Takashi Iwaic9af7532019-05-10 11:01:43 +02002550 alc_pre_init(codec);
2551
Takashi Iwai1727a772013-01-10 09:52:52 +01002552 snd_hda_pick_fixup(codec, alc882_fixup_models, alc882_fixup_tbl,
Takashi Iwai912093b2012-04-11 14:03:41 +02002553 alc882_fixups);
Takashi Iwai1727a772013-01-10 09:52:52 +01002554 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002555
2556 alc_auto_parse_customize_define(codec);
2557
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002558 if (has_cdefine_beep(codec))
2559 spec->gen.beep_nid = 0x01;
2560
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002561 /* automatic parse from the BIOS config */
2562 err = alc882_parse_auto_config(codec);
2563 if (err < 0)
2564 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002565
Takashi Iwaifea80fa2018-06-20 12:52:46 +02002566 if (!spec->gen.no_analog && spec->gen.beep_nid) {
2567 err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
2568 if (err < 0)
2569 goto error;
2570 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02002571
Takashi Iwai1727a772013-01-10 09:52:52 +01002572 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01002573
Takashi Iwai1d045db2011-07-07 18:23:21 +02002574 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02002575
2576 error:
2577 alc_free(codec);
2578 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002579}
2580
2581
2582/*
2583 * ALC262 support
2584 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002585static int alc262_parse_auto_config(struct hda_codec *codec)
2586{
Takashi Iwai1d045db2011-07-07 18:23:21 +02002587 static const hda_nid_t alc262_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002588 static const hda_nid_t alc262_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2589 return alc_parse_auto_config(codec, alc262_ignore, alc262_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002590}
2591
2592/*
2593 * Pin config fixes
2594 */
2595enum {
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002596 ALC262_FIXUP_FSC_H270,
Takashi Iwai7513e6d2013-01-18 15:41:34 +01002597 ALC262_FIXUP_FSC_S7110,
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002598 ALC262_FIXUP_HP_Z200,
2599 ALC262_FIXUP_TYAN,
Takashi Iwaic4701502011-11-07 14:20:07 +01002600 ALC262_FIXUP_LENOVO_3000,
Takashi Iwaib42590b2011-11-07 14:41:01 +01002601 ALC262_FIXUP_BENQ,
2602 ALC262_FIXUP_BENQ_T31,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002603 ALC262_FIXUP_INV_DMIC,
Mengdong Linb5c66112013-11-29 00:35:35 -05002604 ALC262_FIXUP_INTEL_BAYLEYBAY,
Takashi Iwai1d045db2011-07-07 18:23:21 +02002605};
2606
Takashi Iwai1727a772013-01-10 09:52:52 +01002607static const struct hda_fixup alc262_fixups[] = {
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002608 [ALC262_FIXUP_FSC_H270] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002609 .type = HDA_FIXUP_PINS,
2610 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002611 { 0x14, 0x99130110 }, /* speaker */
2612 { 0x15, 0x0221142f }, /* front HP */
2613 { 0x1b, 0x0121141f }, /* rear HP */
2614 { }
2615 }
2616 },
Takashi Iwai7513e6d2013-01-18 15:41:34 +01002617 [ALC262_FIXUP_FSC_S7110] = {
2618 .type = HDA_FIXUP_PINS,
2619 .v.pins = (const struct hda_pintbl[]) {
2620 { 0x15, 0x90170110 }, /* speaker */
2621 { }
2622 },
2623 .chained = true,
2624 .chain_id = ALC262_FIXUP_BENQ,
2625 },
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002626 [ALC262_FIXUP_HP_Z200] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002627 .type = HDA_FIXUP_PINS,
2628 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002629 { 0x16, 0x99130120 }, /* internal speaker */
2630 { }
2631 }
2632 },
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002633 [ALC262_FIXUP_TYAN] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002634 .type = HDA_FIXUP_PINS,
2635 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002636 { 0x14, 0x1993e1f0 }, /* int AUX */
2637 { }
2638 }
2639 },
Takashi Iwaic4701502011-11-07 14:20:07 +01002640 [ALC262_FIXUP_LENOVO_3000] = {
Takashi Iwaifd108212013-01-10 10:18:14 +01002641 .type = HDA_FIXUP_PINCTLS,
2642 .v.pins = (const struct hda_pintbl[]) {
2643 { 0x19, PIN_VREF50 },
Takashi Iwaib42590b2011-11-07 14:41:01 +01002644 {}
2645 },
2646 .chained = true,
2647 .chain_id = ALC262_FIXUP_BENQ,
2648 },
2649 [ALC262_FIXUP_BENQ] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002650 .type = HDA_FIXUP_VERBS,
Takashi Iwaib42590b2011-11-07 14:41:01 +01002651 .v.verbs = (const struct hda_verb[]) {
Takashi Iwaic4701502011-11-07 14:20:07 +01002652 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2653 { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
2654 {}
2655 }
2656 },
Takashi Iwaib42590b2011-11-07 14:41:01 +01002657 [ALC262_FIXUP_BENQ_T31] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002658 .type = HDA_FIXUP_VERBS,
Takashi Iwaib42590b2011-11-07 14:41:01 +01002659 .v.verbs = (const struct hda_verb[]) {
2660 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2661 { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
2662 {}
2663 }
2664 },
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002665 [ALC262_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002666 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02002667 .v.func = alc_fixup_inv_dmic,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002668 },
Mengdong Linb5c66112013-11-29 00:35:35 -05002669 [ALC262_FIXUP_INTEL_BAYLEYBAY] = {
2670 .type = HDA_FIXUP_FUNC,
2671 .v.func = alc_fixup_no_depop_delay,
2672 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02002673};
2674
2675static const struct snd_pci_quirk alc262_fixup_tbl[] = {
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002676 SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", ALC262_FIXUP_HP_Z200),
Takashi Iwai7513e6d2013-01-18 15:41:34 +01002677 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu Lifebook S7110", ALC262_FIXUP_FSC_S7110),
Takashi Iwai3dcd3be2011-11-07 14:59:40 +01002678 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FIXUP_BENQ),
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002679 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_FIXUP_TYAN),
Takashi Iwai275ec0c2018-06-22 12:17:45 +02002680 SND_PCI_QUIRK(0x1734, 0x1141, "FSC ESPRIMO U9210", ALC262_FIXUP_FSC_H270),
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002681 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", ALC262_FIXUP_FSC_H270),
Takashi Iwaic4701502011-11-07 14:20:07 +01002682 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000", ALC262_FIXUP_LENOVO_3000),
Takashi Iwaib42590b2011-11-07 14:41:01 +01002683 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_FIXUP_BENQ),
2684 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_FIXUP_BENQ_T31),
Mengdong Linb5c66112013-11-29 00:35:35 -05002685 SND_PCI_QUIRK(0x8086, 0x7270, "BayleyBay", ALC262_FIXUP_INTEL_BAYLEYBAY),
Takashi Iwai1d045db2011-07-07 18:23:21 +02002686 {}
2687};
2688
Takashi Iwai1727a772013-01-10 09:52:52 +01002689static const struct hda_model_fixup alc262_fixup_models[] = {
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002690 {.id = ALC262_FIXUP_INV_DMIC, .name = "inv-dmic"},
Takashi Iwaie43c44d2018-06-26 17:02:08 +02002691 {.id = ALC262_FIXUP_FSC_H270, .name = "fsc-h270"},
2692 {.id = ALC262_FIXUP_FSC_S7110, .name = "fsc-s7110"},
2693 {.id = ALC262_FIXUP_HP_Z200, .name = "hp-z200"},
2694 {.id = ALC262_FIXUP_TYAN, .name = "tyan"},
2695 {.id = ALC262_FIXUP_LENOVO_3000, .name = "lenovo-3000"},
2696 {.id = ALC262_FIXUP_BENQ, .name = "benq"},
2697 {.id = ALC262_FIXUP_BENQ_T31, .name = "benq-t31"},
2698 {.id = ALC262_FIXUP_INTEL_BAYLEYBAY, .name = "bayleybay"},
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002699 {}
2700};
Takashi Iwai1d045db2011-07-07 18:23:21 +02002701
Takashi Iwai1d045db2011-07-07 18:23:21 +02002702/*
2703 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002704static int patch_alc262(struct hda_codec *codec)
2705{
2706 struct alc_spec *spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002707 int err;
2708
Takashi Iwai3de95172012-05-07 18:03:15 +02002709 err = alc_alloc_spec(codec, 0x0b);
2710 if (err < 0)
2711 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002712
Takashi Iwai3de95172012-05-07 18:03:15 +02002713 spec = codec->spec;
Takashi Iwai08c189f2012-12-19 15:22:24 +01002714 spec->gen.shared_mic_vref_pin = 0x18;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002715
Takashi Iwai225068a2015-05-29 10:42:14 +02002716 spec->shutup = alc_eapd_shutup;
2717
Takashi Iwai1d045db2011-07-07 18:23:21 +02002718#if 0
2719 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
2720 * under-run
2721 */
Takashi Iwai98b24882014-08-18 13:47:50 +02002722 alc_update_coefex_idx(codec, 0x1a, 7, 0, 0x80);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002723#endif
Takashi Iwai1d045db2011-07-07 18:23:21 +02002724 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
2725
Takashi Iwaic9af7532019-05-10 11:01:43 +02002726 alc_pre_init(codec);
2727
Takashi Iwai1727a772013-01-10 09:52:52 +01002728 snd_hda_pick_fixup(codec, alc262_fixup_models, alc262_fixup_tbl,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002729 alc262_fixups);
Takashi Iwai1727a772013-01-10 09:52:52 +01002730 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002731
Takashi Iwaiaf741c12012-05-07 18:09:48 +02002732 alc_auto_parse_customize_define(codec);
2733
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002734 if (has_cdefine_beep(codec))
2735 spec->gen.beep_nid = 0x01;
2736
Takashi Iwai42399f72011-11-07 17:18:44 +01002737 /* automatic parse from the BIOS config */
2738 err = alc262_parse_auto_config(codec);
2739 if (err < 0)
2740 goto error;
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002741
Takashi Iwaifea80fa2018-06-20 12:52:46 +02002742 if (!spec->gen.no_analog && spec->gen.beep_nid) {
2743 err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
2744 if (err < 0)
2745 goto error;
2746 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02002747
Takashi Iwai1727a772013-01-10 09:52:52 +01002748 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01002749
Takashi Iwai1d045db2011-07-07 18:23:21 +02002750 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02002751
2752 error:
2753 alc_free(codec);
2754 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002755}
2756
2757/*
2758 * ALC268
2759 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002760/* bind Beep switches of both NID 0x0f and 0x10 */
Takashi Iwaia7177772017-05-10 12:04:08 +02002761static int alc268_beep_switch_put(struct snd_kcontrol *kcontrol,
2762 struct snd_ctl_elem_value *ucontrol)
2763{
2764 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2765 unsigned long pval;
2766 int err;
2767
2768 mutex_lock(&codec->control_mutex);
2769 pval = kcontrol->private_value;
2770 kcontrol->private_value = (pval & ~0xff) | 0x0f;
2771 err = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
2772 if (err >= 0) {
2773 kcontrol->private_value = (pval & ~0xff) | 0x10;
2774 err = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
2775 }
2776 kcontrol->private_value = pval;
2777 mutex_unlock(&codec->control_mutex);
2778 return err;
2779}
Takashi Iwai1d045db2011-07-07 18:23:21 +02002780
2781static const struct snd_kcontrol_new alc268_beep_mixer[] = {
2782 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
Takashi Iwaia7177772017-05-10 12:04:08 +02002783 {
2784 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2785 .name = "Beep Playback Switch",
2786 .subdevice = HDA_SUBDEV_AMP_FLAG,
2787 .info = snd_hda_mixer_amp_switch_info,
2788 .get = snd_hda_mixer_amp_switch_get,
2789 .put = alc268_beep_switch_put,
2790 .private_value = HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT)
2791 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02002792};
2793
2794/* set PCBEEP vol = 0, mute connections */
2795static const struct hda_verb alc268_beep_init_verbs[] = {
2796 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2797 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2798 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2799 { }
2800};
2801
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002802enum {
2803 ALC268_FIXUP_INV_DMIC,
Takashi Iwaicb766402012-10-20 10:55:21 +02002804 ALC268_FIXUP_HP_EAPD,
Takashi Iwai24eff322013-11-04 18:21:08 +01002805 ALC268_FIXUP_SPDIF,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002806};
2807
Takashi Iwai1727a772013-01-10 09:52:52 +01002808static const struct hda_fixup alc268_fixups[] = {
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002809 [ALC268_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002810 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02002811 .v.func = alc_fixup_inv_dmic,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002812 },
Takashi Iwaicb766402012-10-20 10:55:21 +02002813 [ALC268_FIXUP_HP_EAPD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002814 .type = HDA_FIXUP_VERBS,
Takashi Iwaicb766402012-10-20 10:55:21 +02002815 .v.verbs = (const struct hda_verb[]) {
2816 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 0},
2817 {}
2818 }
2819 },
Takashi Iwai24eff322013-11-04 18:21:08 +01002820 [ALC268_FIXUP_SPDIF] = {
2821 .type = HDA_FIXUP_PINS,
2822 .v.pins = (const struct hda_pintbl[]) {
2823 { 0x1e, 0x014b1180 }, /* enable SPDIF out */
2824 {}
2825 }
2826 },
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002827};
2828
Takashi Iwai1727a772013-01-10 09:52:52 +01002829static const struct hda_model_fixup alc268_fixup_models[] = {
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002830 {.id = ALC268_FIXUP_INV_DMIC, .name = "inv-dmic"},
Takashi Iwaicb766402012-10-20 10:55:21 +02002831 {.id = ALC268_FIXUP_HP_EAPD, .name = "hp-eapd"},
Takashi Iwai03bf11c2018-06-26 16:56:41 +02002832 {.id = ALC268_FIXUP_SPDIF, .name = "spdif"},
Takashi Iwaicb766402012-10-20 10:55:21 +02002833 {}
2834};
2835
2836static const struct snd_pci_quirk alc268_fixup_tbl[] = {
Takashi Iwai24eff322013-11-04 18:21:08 +01002837 SND_PCI_QUIRK(0x1025, 0x0139, "Acer TravelMate 6293", ALC268_FIXUP_SPDIF),
David Henningssonfcd8f3b2013-01-28 05:45:47 +01002838 SND_PCI_QUIRK(0x1025, 0x015b, "Acer AOA 150 (ZG5)", ALC268_FIXUP_INV_DMIC),
Takashi Iwaicb766402012-10-20 10:55:21 +02002839 /* below is codec SSID since multiple Toshiba laptops have the
2840 * same PCI SSID 1179:ff00
2841 */
2842 SND_PCI_QUIRK(0x1179, 0xff06, "Toshiba P200", ALC268_FIXUP_HP_EAPD),
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002843 {}
2844};
2845
Takashi Iwai1d045db2011-07-07 18:23:21 +02002846/*
2847 * BIOS auto configuration
2848 */
2849static int alc268_parse_auto_config(struct hda_codec *codec)
2850{
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002851 static const hda_nid_t alc268_ssids[] = { 0x15, 0x1b, 0x14, 0 };
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002852 return alc_parse_auto_config(codec, NULL, alc268_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002853}
2854
Takashi Iwai1d045db2011-07-07 18:23:21 +02002855/*
2856 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002857static int patch_alc268(struct hda_codec *codec)
2858{
2859 struct alc_spec *spec;
Takashi Iwaia5cb4632018-06-20 12:50:11 +02002860 int i, err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002861
Takashi Iwai1d045db2011-07-07 18:23:21 +02002862 /* ALC268 has no aa-loopback mixer */
Takashi Iwai3de95172012-05-07 18:03:15 +02002863 err = alc_alloc_spec(codec, 0);
2864 if (err < 0)
2865 return err;
2866
2867 spec = codec->spec;
Takashi Iwai2722b532019-08-22 09:55:37 +02002868 if (has_cdefine_beep(codec))
2869 spec->gen.beep_nid = 0x01;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002870
Takashi Iwai225068a2015-05-29 10:42:14 +02002871 spec->shutup = alc_eapd_shutup;
2872
Takashi Iwaic9af7532019-05-10 11:01:43 +02002873 alc_pre_init(codec);
2874
Takashi Iwai1727a772013-01-10 09:52:52 +01002875 snd_hda_pick_fixup(codec, alc268_fixup_models, alc268_fixup_tbl, alc268_fixups);
2876 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002877
Takashi Iwai6ebb8052011-08-16 15:15:40 +02002878 /* automatic parse from the BIOS config */
2879 err = alc268_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02002880 if (err < 0)
2881 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002882
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002883 if (err > 0 && !spec->gen.no_analog &&
2884 spec->gen.autocfg.speaker_pins[0] != 0x1d) {
Takashi Iwaia5cb4632018-06-20 12:50:11 +02002885 for (i = 0; i < ARRAY_SIZE(alc268_beep_mixer); i++) {
2886 if (!snd_hda_gen_add_kctl(&spec->gen, NULL,
2887 &alc268_beep_mixer[i])) {
2888 err = -ENOMEM;
2889 goto error;
2890 }
2891 }
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002892 snd_hda_add_verbs(codec, alc268_beep_init_verbs);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002893 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
2894 /* override the amp caps for beep generator */
2895 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
2896 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
2897 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
2898 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
2899 (0 << AC_AMPCAP_MUTE_SHIFT));
2900 }
2901
Takashi Iwai1727a772013-01-10 09:52:52 +01002902 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002903
Takashi Iwai1d045db2011-07-07 18:23:21 +02002904 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02002905
2906 error:
2907 alc_free(codec);
2908 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002909}
2910
2911/*
2912 * ALC269
2913 */
Takashi Iwai08c189f2012-12-19 15:22:24 +01002914
Takashi Iwai1d045db2011-07-07 18:23:21 +02002915static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002916 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002917};
2918
2919static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002920 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002921};
2922
Takashi Iwai1d045db2011-07-07 18:23:21 +02002923/* different alc269-variants */
2924enum {
2925 ALC269_TYPE_ALC269VA,
2926 ALC269_TYPE_ALC269VB,
2927 ALC269_TYPE_ALC269VC,
Kailang Yangadcc70b2012-05-25 08:08:38 +02002928 ALC269_TYPE_ALC269VD,
Kailang Yang065380f2013-01-10 10:25:48 +01002929 ALC269_TYPE_ALC280,
2930 ALC269_TYPE_ALC282,
Kailang Yang2af02be2013-08-22 10:03:50 +02002931 ALC269_TYPE_ALC283,
Kailang Yang065380f2013-01-10 10:25:48 +01002932 ALC269_TYPE_ALC284,
Kailang Yang4731d5d2017-06-30 15:22:57 +08002933 ALC269_TYPE_ALC293,
Kailang Yang7fc7d042013-04-25 11:04:43 +02002934 ALC269_TYPE_ALC286,
Kailang Yang506b62c2014-12-18 17:07:44 +08002935 ALC269_TYPE_ALC298,
Kailang Yang1d04c9d2013-10-24 11:35:18 +02002936 ALC269_TYPE_ALC255,
Kailang Yang4344aec2014-12-17 17:39:05 +08002937 ALC269_TYPE_ALC256,
Kailang Yangf429e7e2017-12-05 15:38:24 +08002938 ALC269_TYPE_ALC257,
Kailang Yang0a6f0602017-06-30 16:00:48 +08002939 ALC269_TYPE_ALC215,
Kailang Yang42314302016-02-03 15:03:50 +08002940 ALC269_TYPE_ALC225,
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08002941 ALC269_TYPE_ALC294,
Kailang Yang1078bef2018-11-08 16:36:15 +08002942 ALC269_TYPE_ALC300,
Kailang Yangf0778872019-10-24 15:13:32 +08002943 ALC269_TYPE_ALC623,
Kailang Yang6fbae352016-05-30 16:44:20 +08002944 ALC269_TYPE_ALC700,
Takashi Iwai1d045db2011-07-07 18:23:21 +02002945};
2946
2947/*
2948 * BIOS auto configuration
2949 */
2950static int alc269_parse_auto_config(struct hda_codec *codec)
2951{
Takashi Iwai1d045db2011-07-07 18:23:21 +02002952 static const hda_nid_t alc269_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002953 static const hda_nid_t alc269_ssids[] = { 0, 0x1b, 0x14, 0x21 };
2954 static const hda_nid_t alc269va_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2955 struct alc_spec *spec = codec->spec;
Kailang Yangadcc70b2012-05-25 08:08:38 +02002956 const hda_nid_t *ssids;
2957
2958 switch (spec->codec_variant) {
2959 case ALC269_TYPE_ALC269VA:
2960 case ALC269_TYPE_ALC269VC:
Kailang Yang065380f2013-01-10 10:25:48 +01002961 case ALC269_TYPE_ALC280:
2962 case ALC269_TYPE_ALC284:
Kailang Yang4731d5d2017-06-30 15:22:57 +08002963 case ALC269_TYPE_ALC293:
Kailang Yangadcc70b2012-05-25 08:08:38 +02002964 ssids = alc269va_ssids;
2965 break;
2966 case ALC269_TYPE_ALC269VB:
2967 case ALC269_TYPE_ALC269VD:
Kailang Yang065380f2013-01-10 10:25:48 +01002968 case ALC269_TYPE_ALC282:
Kailang Yang2af02be2013-08-22 10:03:50 +02002969 case ALC269_TYPE_ALC283:
Kailang Yang7fc7d042013-04-25 11:04:43 +02002970 case ALC269_TYPE_ALC286:
Kailang Yang506b62c2014-12-18 17:07:44 +08002971 case ALC269_TYPE_ALC298:
Kailang Yang1d04c9d2013-10-24 11:35:18 +02002972 case ALC269_TYPE_ALC255:
Kailang Yang4344aec2014-12-17 17:39:05 +08002973 case ALC269_TYPE_ALC256:
Kailang Yangf429e7e2017-12-05 15:38:24 +08002974 case ALC269_TYPE_ALC257:
Kailang Yang0a6f0602017-06-30 16:00:48 +08002975 case ALC269_TYPE_ALC215:
Kailang Yang42314302016-02-03 15:03:50 +08002976 case ALC269_TYPE_ALC225:
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08002977 case ALC269_TYPE_ALC294:
Kailang Yang1078bef2018-11-08 16:36:15 +08002978 case ALC269_TYPE_ALC300:
Kailang Yangf0778872019-10-24 15:13:32 +08002979 case ALC269_TYPE_ALC623:
Kailang Yang6fbae352016-05-30 16:44:20 +08002980 case ALC269_TYPE_ALC700:
Kailang Yangadcc70b2012-05-25 08:08:38 +02002981 ssids = alc269_ssids;
2982 break;
2983 default:
2984 ssids = alc269_ssids;
2985 break;
2986 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02002987
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002988 return alc_parse_auto_config(codec, alc269_ignore, ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002989}
2990
Hui Wang476c02e2020-03-29 16:20:18 +08002991static const struct hda_jack_keymap alc_headset_btn_keymap[] = {
2992 { SND_JACK_BTN_0, KEY_PLAYPAUSE },
2993 { SND_JACK_BTN_1, KEY_VOICECOMMAND },
2994 { SND_JACK_BTN_2, KEY_VOLUMEUP },
2995 { SND_JACK_BTN_3, KEY_VOLUMEDOWN },
2996 {}
2997};
2998
2999static void alc_headset_btn_callback(struct hda_codec *codec,
3000 struct hda_jack_callback *jack)
3001{
3002 int report = 0;
3003
3004 if (jack->unsol_res & (7 << 13))
3005 report |= SND_JACK_BTN_0;
3006
3007 if (jack->unsol_res & (1 << 16 | 3 << 8))
3008 report |= SND_JACK_BTN_1;
3009
3010 /* Volume up key */
3011 if (jack->unsol_res & (7 << 23))
3012 report |= SND_JACK_BTN_2;
3013
3014 /* Volume down key */
3015 if (jack->unsol_res & (7 << 10))
3016 report |= SND_JACK_BTN_3;
3017
3018 jack->jack->button_state = report;
3019}
3020
3021static void alc_disable_headset_jack_key(struct hda_codec *codec)
3022{
3023 struct alc_spec *spec = codec->spec;
3024
3025 if (!spec->has_hs_key)
3026 return;
3027
3028 switch (codec->core.vendor_id) {
3029 case 0x10ec0215:
3030 case 0x10ec0225:
3031 case 0x10ec0285:
3032 case 0x10ec0295:
3033 case 0x10ec0289:
3034 case 0x10ec0299:
3035 alc_write_coef_idx(codec, 0x48, 0x0);
3036 alc_update_coef_idx(codec, 0x49, 0x0045, 0x0);
3037 alc_update_coef_idx(codec, 0x44, 0x0045 << 8, 0x0);
3038 break;
3039 case 0x10ec0236:
3040 case 0x10ec0256:
3041 alc_write_coef_idx(codec, 0x48, 0x0);
3042 alc_update_coef_idx(codec, 0x49, 0x0045, 0x0);
3043 break;
3044 }
3045}
3046
3047static void alc_enable_headset_jack_key(struct hda_codec *codec)
3048{
3049 struct alc_spec *spec = codec->spec;
3050
3051 if (!spec->has_hs_key)
3052 return;
3053
3054 switch (codec->core.vendor_id) {
3055 case 0x10ec0215:
3056 case 0x10ec0225:
3057 case 0x10ec0285:
3058 case 0x10ec0295:
3059 case 0x10ec0289:
3060 case 0x10ec0299:
3061 alc_write_coef_idx(codec, 0x48, 0xd011);
3062 alc_update_coef_idx(codec, 0x49, 0x007f, 0x0045);
3063 alc_update_coef_idx(codec, 0x44, 0x007f << 8, 0x0045 << 8);
3064 break;
3065 case 0x10ec0236:
3066 case 0x10ec0256:
3067 alc_write_coef_idx(codec, 0x48, 0xd011);
3068 alc_update_coef_idx(codec, 0x49, 0x007f, 0x0045);
3069 break;
3070 }
3071}
3072
3073static void alc_fixup_headset_jack(struct hda_codec *codec,
3074 const struct hda_fixup *fix, int action)
3075{
3076 struct alc_spec *spec = codec->spec;
3077
3078 switch (action) {
3079 case HDA_FIXUP_ACT_PRE_PROBE:
3080 spec->has_hs_key = 1;
3081 snd_hda_jack_detect_enable_callback(codec, 0x55,
3082 alc_headset_btn_callback);
3083 snd_hda_jack_add_kctl(codec, 0x55, "Headset Jack", false,
3084 SND_JACK_HEADSET, alc_headset_btn_keymap);
3085 break;
3086 case HDA_FIXUP_ACT_INIT:
3087 alc_enable_headset_jack_key(codec);
3088 break;
3089 }
3090}
3091
Kailang Yang1387e2d2012-11-08 10:23:18 +01003092static void alc269vb_toggle_power_output(struct hda_codec *codec, int power_up)
Takashi Iwai1d045db2011-07-07 18:23:21 +02003093{
Takashi Iwai98b24882014-08-18 13:47:50 +02003094 alc_update_coef_idx(codec, 0x04, 1 << 11, power_up ? (1 << 11) : 0);
Takashi Iwai1d045db2011-07-07 18:23:21 +02003095}
3096
3097static void alc269_shutup(struct hda_codec *codec)
3098{
Kailang Yangadcc70b2012-05-25 08:08:38 +02003099 struct alc_spec *spec = codec->spec;
3100
Kailang Yang1387e2d2012-11-08 10:23:18 +01003101 if (spec->codec_variant == ALC269_TYPE_ALC269VB)
3102 alc269vb_toggle_power_output(codec, 0);
3103 if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
3104 (alc_get_coef0(codec) & 0x00ff) == 0x018) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02003105 msleep(150);
3106 }
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003107 alc_shutup_pins(codec);
Takashi Iwai1d045db2011-07-07 18:23:21 +02003108}
3109
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01003110static const struct coef_fw alc282_coefs[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02003111 WRITE_COEF(0x03, 0x0002), /* Power Down Control */
Kailang Yang32fa7e42014-10-24 16:26:01 +08003112 UPDATE_COEF(0x05, 0xff3f, 0x0700), /* FIFO and filter clock */
Takashi Iwai54db6c32014-08-18 15:11:19 +02003113 WRITE_COEF(0x07, 0x0200), /* DMIC control */
3114 UPDATE_COEF(0x06, 0x00f0, 0), /* Analog clock */
3115 UPDATE_COEF(0x08, 0xfffc, 0x0c2c), /* JD */
3116 WRITE_COEF(0x0a, 0xcccc), /* JD offset1 */
3117 WRITE_COEF(0x0b, 0xcccc), /* JD offset2 */
3118 WRITE_COEF(0x0e, 0x6e00), /* LDO1/2/3, DAC/ADC */
3119 UPDATE_COEF(0x0f, 0xf800, 0x1000), /* JD */
3120 UPDATE_COEF(0x10, 0xfc00, 0x0c00), /* Capless */
3121 WRITE_COEF(0x6f, 0x0), /* Class D test 4 */
3122 UPDATE_COEF(0x0c, 0xfe00, 0), /* IO power down directly */
3123 WRITE_COEF(0x34, 0xa0c0), /* ANC */
3124 UPDATE_COEF(0x16, 0x0008, 0), /* AGC MUX */
3125 UPDATE_COEF(0x1d, 0x00e0, 0), /* DAC simple content protection */
3126 UPDATE_COEF(0x1f, 0x00e0, 0), /* ADC simple content protection */
3127 WRITE_COEF(0x21, 0x8804), /* DAC ADC Zero Detection */
3128 WRITE_COEF(0x63, 0x2902), /* PLL */
3129 WRITE_COEF(0x68, 0xa080), /* capless control 2 */
3130 WRITE_COEF(0x69, 0x3400), /* capless control 3 */
3131 WRITE_COEF(0x6a, 0x2f3e), /* capless control 4 */
3132 WRITE_COEF(0x6b, 0x0), /* capless control 5 */
3133 UPDATE_COEF(0x6d, 0x0fff, 0x0900), /* class D test 2 */
3134 WRITE_COEF(0x6e, 0x110a), /* class D test 3 */
3135 UPDATE_COEF(0x70, 0x00f8, 0x00d8), /* class D test 5 */
3136 WRITE_COEF(0x71, 0x0014), /* class D test 6 */
3137 WRITE_COEF(0x72, 0xc2ba), /* classD OCP */
3138 UPDATE_COEF(0x77, 0x0f80, 0), /* classD pure DC test */
3139 WRITE_COEF(0x6c, 0xfc06), /* Class D amp control */
3140 {}
3141};
3142
Kailang Yangcb149cb2014-03-18 16:45:32 +08003143static void alc282_restore_default_value(struct hda_codec *codec)
3144{
Takashi Iwai54db6c32014-08-18 15:11:19 +02003145 alc_process_coef_fw(codec, alc282_coefs);
Kailang Yangcb149cb2014-03-18 16:45:32 +08003146}
3147
Kailang Yang7b5c7a02014-03-18 16:15:54 +08003148static void alc282_init(struct hda_codec *codec)
3149{
3150 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003151 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang7b5c7a02014-03-18 16:15:54 +08003152 bool hp_pin_sense;
3153 int coef78;
3154
Kailang Yangcb149cb2014-03-18 16:45:32 +08003155 alc282_restore_default_value(codec);
3156
Kailang Yang7b5c7a02014-03-18 16:15:54 +08003157 if (!hp_pin)
3158 return;
3159 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3160 coef78 = alc_read_coef_idx(codec, 0x78);
3161
3162 /* Index 0x78 Direct Drive HP AMP LPM Control 1 */
3163 /* Headphone capless set to high power mode */
3164 alc_write_coef_idx(codec, 0x78, 0x9004);
3165
3166 if (hp_pin_sense)
3167 msleep(2);
3168
3169 snd_hda_codec_write(codec, hp_pin, 0,
3170 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3171
3172 if (hp_pin_sense)
3173 msleep(85);
3174
3175 snd_hda_codec_write(codec, hp_pin, 0,
3176 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3177
3178 if (hp_pin_sense)
3179 msleep(100);
3180
3181 /* Headphone capless set to normal mode */
3182 alc_write_coef_idx(codec, 0x78, coef78);
3183}
3184
3185static void alc282_shutup(struct hda_codec *codec)
3186{
3187 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003188 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang7b5c7a02014-03-18 16:15:54 +08003189 bool hp_pin_sense;
3190 int coef78;
3191
3192 if (!hp_pin) {
3193 alc269_shutup(codec);
3194 return;
3195 }
3196
3197 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3198 coef78 = alc_read_coef_idx(codec, 0x78);
3199 alc_write_coef_idx(codec, 0x78, 0x9004);
3200
3201 if (hp_pin_sense)
3202 msleep(2);
3203
3204 snd_hda_codec_write(codec, hp_pin, 0,
3205 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3206
3207 if (hp_pin_sense)
3208 msleep(85);
3209
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003210 if (!spec->no_shutup_pins)
3211 snd_hda_codec_write(codec, hp_pin, 0,
3212 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
Kailang Yang7b5c7a02014-03-18 16:15:54 +08003213
3214 if (hp_pin_sense)
3215 msleep(100);
3216
3217 alc_auto_setup_eapd(codec, false);
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003218 alc_shutup_pins(codec);
Kailang Yang7b5c7a02014-03-18 16:15:54 +08003219 alc_write_coef_idx(codec, 0x78, coef78);
3220}
3221
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01003222static const struct coef_fw alc283_coefs[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02003223 WRITE_COEF(0x03, 0x0002), /* Power Down Control */
Kailang Yang56779862014-10-24 16:17:51 +08003224 UPDATE_COEF(0x05, 0xff3f, 0x0700), /* FIFO and filter clock */
Takashi Iwai54db6c32014-08-18 15:11:19 +02003225 WRITE_COEF(0x07, 0x0200), /* DMIC control */
3226 UPDATE_COEF(0x06, 0x00f0, 0), /* Analog clock */
3227 UPDATE_COEF(0x08, 0xfffc, 0x0c2c), /* JD */
3228 WRITE_COEF(0x0a, 0xcccc), /* JD offset1 */
3229 WRITE_COEF(0x0b, 0xcccc), /* JD offset2 */
3230 WRITE_COEF(0x0e, 0x6fc0), /* LDO1/2/3, DAC/ADC */
3231 UPDATE_COEF(0x0f, 0xf800, 0x1000), /* JD */
3232 UPDATE_COEF(0x10, 0xfc00, 0x0c00), /* Capless */
3233 WRITE_COEF(0x3a, 0x0), /* Class D test 4 */
3234 UPDATE_COEF(0x0c, 0xfe00, 0x0), /* IO power down directly */
3235 WRITE_COEF(0x22, 0xa0c0), /* ANC */
3236 UPDATE_COEFEX(0x53, 0x01, 0x000f, 0x0008), /* AGC MUX */
3237 UPDATE_COEF(0x1d, 0x00e0, 0), /* DAC simple content protection */
3238 UPDATE_COEF(0x1f, 0x00e0, 0), /* ADC simple content protection */
3239 WRITE_COEF(0x21, 0x8804), /* DAC ADC Zero Detection */
3240 WRITE_COEF(0x2e, 0x2902), /* PLL */
3241 WRITE_COEF(0x33, 0xa080), /* capless control 2 */
3242 WRITE_COEF(0x34, 0x3400), /* capless control 3 */
3243 WRITE_COEF(0x35, 0x2f3e), /* capless control 4 */
3244 WRITE_COEF(0x36, 0x0), /* capless control 5 */
3245 UPDATE_COEF(0x38, 0x0fff, 0x0900), /* class D test 2 */
3246 WRITE_COEF(0x39, 0x110a), /* class D test 3 */
3247 UPDATE_COEF(0x3b, 0x00f8, 0x00d8), /* class D test 5 */
3248 WRITE_COEF(0x3c, 0x0014), /* class D test 6 */
3249 WRITE_COEF(0x3d, 0xc2ba), /* classD OCP */
3250 UPDATE_COEF(0x42, 0x0f80, 0x0), /* classD pure DC test */
3251 WRITE_COEF(0x49, 0x0), /* test mode */
3252 UPDATE_COEF(0x40, 0xf800, 0x9800), /* Class D DC enable */
3253 UPDATE_COEF(0x42, 0xf000, 0x2000), /* DC offset */
3254 WRITE_COEF(0x37, 0xfc06), /* Class D amp control */
Kailang Yang56779862014-10-24 16:17:51 +08003255 UPDATE_COEF(0x1b, 0x8000, 0), /* HP JD control */
Takashi Iwai54db6c32014-08-18 15:11:19 +02003256 {}
3257};
3258
Kailang Yang6bd55b02014-03-17 13:51:27 +08003259static void alc283_restore_default_value(struct hda_codec *codec)
3260{
Takashi Iwai54db6c32014-08-18 15:11:19 +02003261 alc_process_coef_fw(codec, alc283_coefs);
Kailang Yang6bd55b02014-03-17 13:51:27 +08003262}
3263
Kailang Yang2af02be2013-08-22 10:03:50 +02003264static void alc283_init(struct hda_codec *codec)
3265{
3266 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003267 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang2af02be2013-08-22 10:03:50 +02003268 bool hp_pin_sense;
Kailang Yang2af02be2013-08-22 10:03:50 +02003269
Kailang Yang6bd55b02014-03-17 13:51:27 +08003270 alc283_restore_default_value(codec);
3271
Kailang Yang2af02be2013-08-22 10:03:50 +02003272 if (!hp_pin)
3273 return;
Kailang Yanga59d7192015-04-08 16:34:00 +08003274
3275 msleep(30);
Kailang Yang2af02be2013-08-22 10:03:50 +02003276 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3277
3278 /* Index 0x43 Direct Drive HP AMP LPM Control 1 */
3279 /* Headphone capless set to high power mode */
3280 alc_write_coef_idx(codec, 0x43, 0x9004);
3281
3282 snd_hda_codec_write(codec, hp_pin, 0,
3283 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3284
3285 if (hp_pin_sense)
3286 msleep(85);
3287
3288 snd_hda_codec_write(codec, hp_pin, 0,
3289 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3290
3291 if (hp_pin_sense)
3292 msleep(85);
3293 /* Index 0x46 Combo jack auto switch control 2 */
3294 /* 3k pull low control for Headset jack. */
Takashi Iwai98b24882014-08-18 13:47:50 +02003295 alc_update_coef_idx(codec, 0x46, 3 << 12, 0);
Kailang Yang2af02be2013-08-22 10:03:50 +02003296 /* Headphone capless set to normal mode */
3297 alc_write_coef_idx(codec, 0x43, 0x9614);
3298}
3299
3300static void alc283_shutup(struct hda_codec *codec)
3301{
3302 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003303 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang2af02be2013-08-22 10:03:50 +02003304 bool hp_pin_sense;
Kailang Yang2af02be2013-08-22 10:03:50 +02003305
3306 if (!hp_pin) {
3307 alc269_shutup(codec);
3308 return;
3309 }
3310
3311 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3312
3313 alc_write_coef_idx(codec, 0x43, 0x9004);
3314
Harsha Priyab450b172014-10-09 11:04:56 +00003315 /*depop hp during suspend*/
3316 alc_write_coef_idx(codec, 0x06, 0x2100);
3317
Kailang Yang2af02be2013-08-22 10:03:50 +02003318 snd_hda_codec_write(codec, hp_pin, 0,
3319 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3320
3321 if (hp_pin_sense)
Kailang Yang88011c092013-10-24 15:45:24 +02003322 msleep(100);
Kailang Yang2af02be2013-08-22 10:03:50 +02003323
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003324 if (!spec->no_shutup_pins)
3325 snd_hda_codec_write(codec, hp_pin, 0,
3326 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
Kailang Yang2af02be2013-08-22 10:03:50 +02003327
Takashi Iwai98b24882014-08-18 13:47:50 +02003328 alc_update_coef_idx(codec, 0x46, 0, 3 << 12);
Kailang Yang2af02be2013-08-22 10:03:50 +02003329
3330 if (hp_pin_sense)
Kailang Yang88011c092013-10-24 15:45:24 +02003331 msleep(100);
Kailang Yang0435b3f2014-04-08 17:14:14 +08003332 alc_auto_setup_eapd(codec, false);
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003333 alc_shutup_pins(codec);
Kailang Yang2af02be2013-08-22 10:03:50 +02003334 alc_write_coef_idx(codec, 0x43, 0x9614);
3335}
3336
Kailang Yang4a219ef2017-06-16 16:54:35 +08003337static void alc256_init(struct hda_codec *codec)
3338{
3339 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003340 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang4a219ef2017-06-16 16:54:35 +08003341 bool hp_pin_sense;
3342
3343 if (!hp_pin)
Kailang Yang6447c962019-05-08 16:27:03 +08003344 hp_pin = 0x21;
Kailang Yang4a219ef2017-06-16 16:54:35 +08003345
3346 msleep(30);
3347
3348 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3349
3350 if (hp_pin_sense)
3351 msleep(2);
3352
3353 alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */
Kailang Yang6447c962019-05-08 16:27:03 +08003354 if (spec->ultra_low_power) {
3355 alc_update_coef_idx(codec, 0x03, 1<<1, 1<<1);
3356 alc_update_coef_idx(codec, 0x08, 3<<2, 3<<2);
3357 alc_update_coef_idx(codec, 0x08, 7<<4, 0);
3358 alc_update_coef_idx(codec, 0x3b, 1<<15, 0);
3359 alc_update_coef_idx(codec, 0x0e, 7<<6, 7<<6);
3360 msleep(30);
3361 }
Kailang Yang4a219ef2017-06-16 16:54:35 +08003362
3363 snd_hda_codec_write(codec, hp_pin, 0,
3364 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3365
Kailang Yang6447c962019-05-08 16:27:03 +08003366 if (hp_pin_sense || spec->ultra_low_power)
Kailang Yang4a219ef2017-06-16 16:54:35 +08003367 msleep(85);
3368
3369 snd_hda_codec_write(codec, hp_pin, 0,
3370 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3371
Kailang Yang6447c962019-05-08 16:27:03 +08003372 if (hp_pin_sense || spec->ultra_low_power)
Kailang Yang4a219ef2017-06-16 16:54:35 +08003373 msleep(100);
3374
3375 alc_update_coef_idx(codec, 0x46, 3 << 12, 0);
3376 alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x4); /* Hight power */
Kailang Yang88d42b22018-03-14 16:08:57 +08003377 alc_update_coefex_idx(codec, 0x53, 0x02, 0x8000, 1 << 15); /* Clear bit */
3378 alc_update_coefex_idx(codec, 0x53, 0x02, 0x8000, 0 << 15);
Thomas Hebbc4473742020-03-30 12:09:38 -04003379 /*
3380 * Expose headphone mic (or possibly Line In on some machines) instead
3381 * of PC Beep on 1Ah, and disable 1Ah loopback for all outputs. See
3382 * Documentation/sound/hd-audio/realtek-pc-beep.rst for details of
3383 * this register.
3384 */
3385 alc_write_coef_idx(codec, 0x36, 0x5757);
Kailang Yang4a219ef2017-06-16 16:54:35 +08003386}
3387
3388static void alc256_shutup(struct hda_codec *codec)
3389{
3390 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003391 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang4a219ef2017-06-16 16:54:35 +08003392 bool hp_pin_sense;
3393
Kailang Yang6447c962019-05-08 16:27:03 +08003394 if (!hp_pin)
3395 hp_pin = 0x21;
Kailang Yang4a219ef2017-06-16 16:54:35 +08003396
3397 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3398
3399 if (hp_pin_sense)
3400 msleep(2);
3401
3402 snd_hda_codec_write(codec, hp_pin, 0,
3403 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3404
Kailang Yang6447c962019-05-08 16:27:03 +08003405 if (hp_pin_sense || spec->ultra_low_power)
Kailang Yang4a219ef2017-06-16 16:54:35 +08003406 msleep(85);
3407
Takashi Iwai1c9609e2018-01-19 14:18:34 +01003408 /* 3k pull low control for Headset jack. */
3409 /* NOTE: call this before clearing the pin, otherwise codec stalls */
3410 alc_update_coef_idx(codec, 0x46, 0, 3 << 12);
3411
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003412 if (!spec->no_shutup_pins)
3413 snd_hda_codec_write(codec, hp_pin, 0,
3414 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
Kailang Yang4a219ef2017-06-16 16:54:35 +08003415
Kailang Yang6447c962019-05-08 16:27:03 +08003416 if (hp_pin_sense || spec->ultra_low_power)
Kailang Yang4a219ef2017-06-16 16:54:35 +08003417 msleep(100);
3418
3419 alc_auto_setup_eapd(codec, false);
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003420 alc_shutup_pins(codec);
Kailang Yang6447c962019-05-08 16:27:03 +08003421 if (spec->ultra_low_power) {
3422 msleep(50);
3423 alc_update_coef_idx(codec, 0x03, 1<<1, 0);
3424 alc_update_coef_idx(codec, 0x08, 7<<4, 7<<4);
3425 alc_update_coef_idx(codec, 0x08, 3<<2, 0);
3426 alc_update_coef_idx(codec, 0x3b, 1<<15, 1<<15);
3427 alc_update_coef_idx(codec, 0x0e, 7<<6, 0);
3428 msleep(30);
3429 }
Kailang Yang4a219ef2017-06-16 16:54:35 +08003430}
3431
Kailang Yangda911b12018-01-05 16:50:08 +08003432static void alc225_init(struct hda_codec *codec)
3433{
3434 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003435 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yangda911b12018-01-05 16:50:08 +08003436 bool hp1_pin_sense, hp2_pin_sense;
3437
3438 if (!hp_pin)
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003439 hp_pin = 0x21;
Kailang Yangda911b12018-01-05 16:50:08 +08003440 msleep(30);
3441
3442 hp1_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3443 hp2_pin_sense = snd_hda_jack_detect(codec, 0x16);
3444
3445 if (hp1_pin_sense || hp2_pin_sense)
3446 msleep(2);
3447
3448 alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003449 if (spec->ultra_low_power) {
3450 alc_update_coef_idx(codec, 0x08, 0x0f << 2, 3<<2);
3451 alc_update_coef_idx(codec, 0x0e, 7<<6, 7<<6);
3452 alc_update_coef_idx(codec, 0x33, 1<<11, 0);
3453 msleep(30);
3454 }
Kailang Yangda911b12018-01-05 16:50:08 +08003455
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003456 if (hp1_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003457 snd_hda_codec_write(codec, hp_pin, 0,
3458 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3459 if (hp2_pin_sense)
3460 snd_hda_codec_write(codec, 0x16, 0,
3461 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3462
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003463 if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003464 msleep(85);
3465
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003466 if (hp1_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003467 snd_hda_codec_write(codec, hp_pin, 0,
3468 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3469 if (hp2_pin_sense)
3470 snd_hda_codec_write(codec, 0x16, 0,
3471 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3472
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003473 if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003474 msleep(100);
3475
3476 alc_update_coef_idx(codec, 0x4a, 3 << 10, 0);
3477 alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x4); /* Hight power */
3478}
3479
3480static void alc225_shutup(struct hda_codec *codec)
3481{
3482 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003483 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yangda911b12018-01-05 16:50:08 +08003484 bool hp1_pin_sense, hp2_pin_sense;
3485
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003486 if (!hp_pin)
3487 hp_pin = 0x21;
Hui Wang476c02e2020-03-29 16:20:18 +08003488
3489 alc_disable_headset_jack_key(codec);
Kailang Yangda911b12018-01-05 16:50:08 +08003490 /* 3k pull low control for Headset jack. */
3491 alc_update_coef_idx(codec, 0x4a, 0, 3 << 10);
3492
3493 hp1_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3494 hp2_pin_sense = snd_hda_jack_detect(codec, 0x16);
3495
3496 if (hp1_pin_sense || hp2_pin_sense)
3497 msleep(2);
3498
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003499 if (hp1_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003500 snd_hda_codec_write(codec, hp_pin, 0,
3501 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3502 if (hp2_pin_sense)
3503 snd_hda_codec_write(codec, 0x16, 0,
3504 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3505
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003506 if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003507 msleep(85);
3508
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003509 if (hp1_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003510 snd_hda_codec_write(codec, hp_pin, 0,
3511 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
3512 if (hp2_pin_sense)
3513 snd_hda_codec_write(codec, 0x16, 0,
3514 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
3515
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003516 if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003517 msleep(100);
3518
3519 alc_auto_setup_eapd(codec, false);
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003520 alc_shutup_pins(codec);
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003521 if (spec->ultra_low_power) {
3522 msleep(50);
3523 alc_update_coef_idx(codec, 0x08, 0x0f << 2, 0x0c << 2);
3524 alc_update_coef_idx(codec, 0x0e, 7<<6, 0);
3525 alc_update_coef_idx(codec, 0x33, 1<<11, 1<<11);
3526 alc_update_coef_idx(codec, 0x4a, 3<<4, 2<<4);
3527 msleep(30);
3528 }
Hui Wang476c02e2020-03-29 16:20:18 +08003529
3530 alc_update_coef_idx(codec, 0x4a, 3 << 10, 0);
3531 alc_enable_headset_jack_key(codec);
Kailang Yangda911b12018-01-05 16:50:08 +08003532}
3533
Kailang Yangc2d6af52017-06-21 14:50:54 +08003534static void alc_default_init(struct hda_codec *codec)
3535{
3536 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003537 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yangc2d6af52017-06-21 14:50:54 +08003538 bool hp_pin_sense;
3539
3540 if (!hp_pin)
3541 return;
3542
3543 msleep(30);
3544
3545 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3546
3547 if (hp_pin_sense)
3548 msleep(2);
3549
3550 snd_hda_codec_write(codec, hp_pin, 0,
3551 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3552
3553 if (hp_pin_sense)
3554 msleep(85);
3555
3556 snd_hda_codec_write(codec, hp_pin, 0,
3557 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3558
3559 if (hp_pin_sense)
3560 msleep(100);
3561}
3562
3563static void alc_default_shutup(struct hda_codec *codec)
3564{
3565 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003566 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yangc2d6af52017-06-21 14:50:54 +08003567 bool hp_pin_sense;
3568
3569 if (!hp_pin) {
3570 alc269_shutup(codec);
3571 return;
3572 }
3573
3574 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3575
3576 if (hp_pin_sense)
3577 msleep(2);
3578
3579 snd_hda_codec_write(codec, hp_pin, 0,
3580 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3581
3582 if (hp_pin_sense)
3583 msleep(85);
3584
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003585 if (!spec->no_shutup_pins)
3586 snd_hda_codec_write(codec, hp_pin, 0,
3587 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
Kailang Yangc2d6af52017-06-21 14:50:54 +08003588
3589 if (hp_pin_sense)
3590 msleep(100);
3591
3592 alc_auto_setup_eapd(codec, false);
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003593 alc_shutup_pins(codec);
Kailang Yangc2d6af52017-06-21 14:50:54 +08003594}
3595
Kailang Yang693abe12019-01-29 15:38:21 +08003596static void alc294_hp_init(struct hda_codec *codec)
3597{
3598 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003599 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang693abe12019-01-29 15:38:21 +08003600 int i, val;
3601
3602 if (!hp_pin)
3603 return;
3604
3605 snd_hda_codec_write(codec, hp_pin, 0,
3606 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3607
3608 msleep(100);
3609
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003610 if (!spec->no_shutup_pins)
3611 snd_hda_codec_write(codec, hp_pin, 0,
3612 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
Kailang Yang693abe12019-01-29 15:38:21 +08003613
3614 alc_update_coef_idx(codec, 0x6f, 0x000f, 0);/* Set HP depop to manual mode */
3615 alc_update_coefex_idx(codec, 0x58, 0x00, 0x8000, 0x8000); /* HP depop procedure start */
3616
3617 /* Wait for depop procedure finish */
3618 val = alc_read_coefex_idx(codec, 0x58, 0x01);
3619 for (i = 0; i < 20 && val & 0x0080; i++) {
3620 msleep(50);
3621 val = alc_read_coefex_idx(codec, 0x58, 0x01);
3622 }
3623 /* Set HP depop to auto mode */
3624 alc_update_coef_idx(codec, 0x6f, 0x000f, 0x000b);
3625 msleep(50);
3626}
3627
3628static void alc294_init(struct hda_codec *codec)
3629{
3630 struct alc_spec *spec = codec->spec;
3631
Takashi Iwaif6ef4e02019-01-29 14:14:51 +01003632 /* required only at boot or S4 resume time */
3633 if (!spec->done_hp_init ||
3634 codec->core.dev.power.power_state.event == PM_EVENT_RESTORE) {
Kailang Yang693abe12019-01-29 15:38:21 +08003635 alc294_hp_init(codec);
3636 spec->done_hp_init = true;
3637 }
3638 alc_default_init(codec);
3639}
3640
Kailang Yangad60d502013-06-28 12:03:01 +02003641static void alc5505_coef_set(struct hda_codec *codec, unsigned int index_reg,
3642 unsigned int val)
3643{
3644 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_COEF_INDEX, index_reg >> 1);
3645 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_PROC_COEF, val & 0xffff); /* LSB */
3646 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_PROC_COEF, val >> 16); /* MSB */
3647}
3648
3649static int alc5505_coef_get(struct hda_codec *codec, unsigned int index_reg)
3650{
3651 unsigned int val;
3652
3653 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_COEF_INDEX, index_reg >> 1);
3654 val = snd_hda_codec_read(codec, 0x51, 0, AC_VERB_GET_PROC_COEF, 0)
3655 & 0xffff;
3656 val |= snd_hda_codec_read(codec, 0x51, 0, AC_VERB_GET_PROC_COEF, 0)
3657 << 16;
3658 return val;
3659}
3660
3661static void alc5505_dsp_halt(struct hda_codec *codec)
3662{
3663 unsigned int val;
3664
3665 alc5505_coef_set(codec, 0x3000, 0x000c); /* DSP CPU stop */
3666 alc5505_coef_set(codec, 0x880c, 0x0008); /* DDR enter self refresh */
3667 alc5505_coef_set(codec, 0x61c0, 0x11110080); /* Clock control for PLL and CPU */
3668 alc5505_coef_set(codec, 0x6230, 0xfc0d4011); /* Disable Input OP */
3669 alc5505_coef_set(codec, 0x61b4, 0x040a2b03); /* Stop PLL2 */
3670 alc5505_coef_set(codec, 0x61b0, 0x00005b17); /* Stop PLL1 */
3671 alc5505_coef_set(codec, 0x61b8, 0x04133303); /* Stop PLL3 */
3672 val = alc5505_coef_get(codec, 0x6220);
3673 alc5505_coef_set(codec, 0x6220, (val | 0x3000)); /* switch Ringbuffer clock to DBUS clock */
3674}
3675
3676static void alc5505_dsp_back_from_halt(struct hda_codec *codec)
3677{
3678 alc5505_coef_set(codec, 0x61b8, 0x04133302);
3679 alc5505_coef_set(codec, 0x61b0, 0x00005b16);
3680 alc5505_coef_set(codec, 0x61b4, 0x040a2b02);
3681 alc5505_coef_set(codec, 0x6230, 0xf80d4011);
3682 alc5505_coef_set(codec, 0x6220, 0x2002010f);
3683 alc5505_coef_set(codec, 0x880c, 0x00000004);
3684}
3685
3686static void alc5505_dsp_init(struct hda_codec *codec)
3687{
3688 unsigned int val;
3689
3690 alc5505_dsp_halt(codec);
3691 alc5505_dsp_back_from_halt(codec);
3692 alc5505_coef_set(codec, 0x61b0, 0x5b14); /* PLL1 control */
3693 alc5505_coef_set(codec, 0x61b0, 0x5b16);
3694 alc5505_coef_set(codec, 0x61b4, 0x04132b00); /* PLL2 control */
3695 alc5505_coef_set(codec, 0x61b4, 0x04132b02);
3696 alc5505_coef_set(codec, 0x61b8, 0x041f3300); /* PLL3 control*/
3697 alc5505_coef_set(codec, 0x61b8, 0x041f3302);
3698 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_CODEC_RESET, 0); /* Function reset */
3699 alc5505_coef_set(codec, 0x61b8, 0x041b3302);
3700 alc5505_coef_set(codec, 0x61b8, 0x04173302);
3701 alc5505_coef_set(codec, 0x61b8, 0x04163302);
3702 alc5505_coef_set(codec, 0x8800, 0x348b328b); /* DRAM control */
3703 alc5505_coef_set(codec, 0x8808, 0x00020022); /* DRAM control */
3704 alc5505_coef_set(codec, 0x8818, 0x00000400); /* DRAM control */
3705
3706 val = alc5505_coef_get(codec, 0x6200) >> 16; /* Read revision ID */
3707 if (val <= 3)
3708 alc5505_coef_set(codec, 0x6220, 0x2002010f); /* I/O PAD Configuration */
3709 else
3710 alc5505_coef_set(codec, 0x6220, 0x6002018f);
3711
3712 alc5505_coef_set(codec, 0x61ac, 0x055525f0); /**/
3713 alc5505_coef_set(codec, 0x61c0, 0x12230080); /* Clock control */
3714 alc5505_coef_set(codec, 0x61b4, 0x040e2b02); /* PLL2 control */
3715 alc5505_coef_set(codec, 0x61bc, 0x010234f8); /* OSC Control */
3716 alc5505_coef_set(codec, 0x880c, 0x00000004); /* DRAM Function control */
3717 alc5505_coef_set(codec, 0x880c, 0x00000003);
3718 alc5505_coef_set(codec, 0x880c, 0x00000010);
Takashi Iwaicd63a5f2013-07-05 12:13:59 +02003719
3720#ifdef HALT_REALTEK_ALC5505
3721 alc5505_dsp_halt(codec);
3722#endif
Kailang Yangad60d502013-06-28 12:03:01 +02003723}
3724
Takashi Iwaicd63a5f2013-07-05 12:13:59 +02003725#ifdef HALT_REALTEK_ALC5505
Pierre-Louis Bossart8a718212020-01-11 15:47:35 -06003726#define alc5505_dsp_suspend(codec) do { } while (0) /* NOP */
3727#define alc5505_dsp_resume(codec) do { } while (0) /* NOP */
Takashi Iwaicd63a5f2013-07-05 12:13:59 +02003728#else
3729#define alc5505_dsp_suspend(codec) alc5505_dsp_halt(codec)
3730#define alc5505_dsp_resume(codec) alc5505_dsp_back_from_halt(codec)
3731#endif
3732
Takashi Iwai2a439522011-07-26 09:52:50 +02003733#ifdef CONFIG_PM
Kailang Yangad60d502013-06-28 12:03:01 +02003734static int alc269_suspend(struct hda_codec *codec)
3735{
3736 struct alc_spec *spec = codec->spec;
3737
3738 if (spec->has_alc5505_dsp)
Takashi Iwaicd63a5f2013-07-05 12:13:59 +02003739 alc5505_dsp_suspend(codec);
Kailang Yangad60d502013-06-28 12:03:01 +02003740 return alc_suspend(codec);
3741}
3742
Takashi Iwai1d045db2011-07-07 18:23:21 +02003743static int alc269_resume(struct hda_codec *codec)
3744{
Kailang Yangadcc70b2012-05-25 08:08:38 +02003745 struct alc_spec *spec = codec->spec;
3746
Kailang Yang1387e2d2012-11-08 10:23:18 +01003747 if (spec->codec_variant == ALC269_TYPE_ALC269VB)
3748 alc269vb_toggle_power_output(codec, 0);
3749 if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
Kailang Yangadcc70b2012-05-25 08:08:38 +02003750 (alc_get_coef0(codec) & 0x00ff) == 0x018) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02003751 msleep(150);
3752 }
3753
3754 codec->patch_ops.init(codec);
3755
Kailang Yang1387e2d2012-11-08 10:23:18 +01003756 if (spec->codec_variant == ALC269_TYPE_ALC269VB)
3757 alc269vb_toggle_power_output(codec, 1);
3758 if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
Kailang Yangadcc70b2012-05-25 08:08:38 +02003759 (alc_get_coef0(codec) & 0x00ff) == 0x017) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02003760 msleep(200);
3761 }
3762
Takashi Iwai1a462be2020-01-09 10:01:04 +01003763 snd_hda_regmap_sync(codec);
Takashi Iwai1d045db2011-07-07 18:23:21 +02003764 hda_call_check_power_status(codec, 0x01);
Hui Wangf4753712014-08-19 12:07:03 +08003765
3766 /* on some machine, the BIOS will clear the codec gpio data when enter
3767 * suspend, and won't restore the data after resume, so we restore it
3768 * in the driver.
3769 */
Takashi Iwaid261eec2018-06-19 22:32:29 +02003770 if (spec->gpio_data)
3771 alc_write_gpio_data(codec);
Hui Wangf4753712014-08-19 12:07:03 +08003772
Kailang Yangad60d502013-06-28 12:03:01 +02003773 if (spec->has_alc5505_dsp)
Takashi Iwaicd63a5f2013-07-05 12:13:59 +02003774 alc5505_dsp_resume(codec);
Kailang Yangc5177c82013-07-24 14:39:49 +02003775
Takashi Iwai1d045db2011-07-07 18:23:21 +02003776 return 0;
3777}
Takashi Iwai2a439522011-07-26 09:52:50 +02003778#endif /* CONFIG_PM */
Takashi Iwai1d045db2011-07-07 18:23:21 +02003779
David Henningsson108cc102012-07-20 10:37:25 +02003780static void alc269_fixup_pincfg_no_hp_to_lineout(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003781 const struct hda_fixup *fix, int action)
David Henningsson108cc102012-07-20 10:37:25 +02003782{
3783 struct alc_spec *spec = codec->spec;
3784
Takashi Iwai1727a772013-01-10 09:52:52 +01003785 if (action == HDA_FIXUP_ACT_PRE_PROBE)
David Henningsson108cc102012-07-20 10:37:25 +02003786 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
3787}
3788
Jan-Marek Glogowskifdcc9682018-02-14 11:29:15 +01003789static void alc269_fixup_pincfg_U7x7_headset_mic(struct hda_codec *codec,
3790 const struct hda_fixup *fix,
3791 int action)
3792{
3793 unsigned int cfg_headphone = snd_hda_codec_get_pincfg(codec, 0x21);
3794 unsigned int cfg_headset_mic = snd_hda_codec_get_pincfg(codec, 0x19);
3795
3796 if (cfg_headphone && cfg_headset_mic == 0x411111f0)
3797 snd_hda_codec_set_pincfg(codec, 0x19,
3798 (cfg_headphone & ~AC_DEFCFG_DEVICE) |
3799 (AC_JACK_MIC_IN << AC_DEFCFG_DEVICE_SHIFT));
3800}
3801
Takashi Iwai1d045db2011-07-07 18:23:21 +02003802static void alc269_fixup_hweq(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003803 const struct hda_fixup *fix, int action)
Takashi Iwai1d045db2011-07-07 18:23:21 +02003804{
Takashi Iwai98b24882014-08-18 13:47:50 +02003805 if (action == HDA_FIXUP_ACT_INIT)
3806 alc_update_coef_idx(codec, 0x1e, 0, 0x80);
Takashi Iwai1d045db2011-07-07 18:23:21 +02003807}
3808
David Henningsson7c478f02013-10-11 10:18:46 +02003809static void alc269_fixup_headset_mic(struct hda_codec *codec,
3810 const struct hda_fixup *fix, int action)
3811{
3812 struct alc_spec *spec = codec->spec;
3813
3814 if (action == HDA_FIXUP_ACT_PRE_PROBE)
3815 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
3816}
3817
Takashi Iwai1d045db2011-07-07 18:23:21 +02003818static void alc271_fixup_dmic(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003819 const struct hda_fixup *fix, int action)
Takashi Iwai1d045db2011-07-07 18:23:21 +02003820{
3821 static const struct hda_verb verbs[] = {
3822 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
3823 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
3824 {}
3825 };
3826 unsigned int cfg;
3827
Takashi Iwai7639a062015-03-03 10:07:24 +01003828 if (strcmp(codec->core.chip_name, "ALC271X") &&
3829 strcmp(codec->core.chip_name, "ALC269VB"))
Takashi Iwai1d045db2011-07-07 18:23:21 +02003830 return;
3831 cfg = snd_hda_codec_get_pincfg(codec, 0x12);
3832 if (get_defcfg_connect(cfg) == AC_JACK_PORT_FIXED)
3833 snd_hda_sequence_write(codec, verbs);
3834}
3835
Takashi Iwai017f2a12011-07-09 14:42:25 +02003836static void alc269_fixup_pcm_44k(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003837 const struct hda_fixup *fix, int action)
Takashi Iwai017f2a12011-07-09 14:42:25 +02003838{
3839 struct alc_spec *spec = codec->spec;
3840
Takashi Iwai1727a772013-01-10 09:52:52 +01003841 if (action != HDA_FIXUP_ACT_PROBE)
Takashi Iwai017f2a12011-07-09 14:42:25 +02003842 return;
3843
3844 /* Due to a hardware problem on Lenovo Ideadpad, we need to
3845 * fix the sample rate of analog I/O to 44.1kHz
3846 */
Takashi Iwai08c189f2012-12-19 15:22:24 +01003847 spec->gen.stream_analog_playback = &alc269_44k_pcm_analog_playback;
3848 spec->gen.stream_analog_capture = &alc269_44k_pcm_analog_capture;
Takashi Iwai017f2a12011-07-09 14:42:25 +02003849}
3850
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02003851static void alc269_fixup_stereo_dmic(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003852 const struct hda_fixup *fix, int action)
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02003853{
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02003854 /* The digital-mic unit sends PDM (differential signal) instead of
3855 * the standard PCM, thus you can't record a valid mono stream as is.
3856 * Below is a workaround specific to ALC269 to control the dmic
3857 * signal source as mono.
3858 */
Takashi Iwai98b24882014-08-18 13:47:50 +02003859 if (action == HDA_FIXUP_ACT_INIT)
3860 alc_update_coef_idx(codec, 0x07, 0, 0x80);
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02003861}
3862
Takashi Iwai24519912011-08-16 15:08:49 +02003863static void alc269_quanta_automute(struct hda_codec *codec)
3864{
Takashi Iwai08c189f2012-12-19 15:22:24 +01003865 snd_hda_gen_update_outputs(codec);
Takashi Iwai24519912011-08-16 15:08:49 +02003866
Takashi Iwai1687ccc2014-08-18 13:49:35 +02003867 alc_write_coef_idx(codec, 0x0c, 0x680);
3868 alc_write_coef_idx(codec, 0x0c, 0x480);
Takashi Iwai24519912011-08-16 15:08:49 +02003869}
3870
3871static void alc269_fixup_quanta_mute(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003872 const struct hda_fixup *fix, int action)
Takashi Iwai24519912011-08-16 15:08:49 +02003873{
3874 struct alc_spec *spec = codec->spec;
Takashi Iwai1727a772013-01-10 09:52:52 +01003875 if (action != HDA_FIXUP_ACT_PROBE)
Takashi Iwai24519912011-08-16 15:08:49 +02003876 return;
Takashi Iwai08c189f2012-12-19 15:22:24 +01003877 spec->gen.automute_hook = alc269_quanta_automute;
Takashi Iwai24519912011-08-16 15:08:49 +02003878}
3879
David Henningssond240d1d2013-04-15 12:50:02 +02003880static void alc269_x101_hp_automute_hook(struct hda_codec *codec,
Takashi Iwai1a4f69d2014-09-11 15:22:46 +02003881 struct hda_jack_callback *jack)
David Henningssond240d1d2013-04-15 12:50:02 +02003882{
3883 struct alc_spec *spec = codec->spec;
3884 int vref;
3885 msleep(200);
3886 snd_hda_gen_hp_automute(codec, jack);
3887
3888 vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0;
3889 msleep(100);
3890 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3891 vref);
3892 msleep(500);
3893 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3894 vref);
3895}
3896
Tomas Espeletaa2ef03f2019-08-09 16:37:54 +02003897/*
3898 * Magic sequence to make Huawei Matebook X right speaker working (bko#197801)
3899 */
3900struct hda_alc298_mbxinit {
3901 unsigned char value_0x23;
3902 unsigned char value_0x25;
3903};
3904
3905static void alc298_huawei_mbx_stereo_seq(struct hda_codec *codec,
3906 const struct hda_alc298_mbxinit *initval,
3907 bool first)
3908{
3909 snd_hda_codec_write(codec, 0x06, 0, AC_VERB_SET_DIGI_CONVERT_3, 0x0);
3910 alc_write_coef_idx(codec, 0x26, 0xb000);
3911
3912 if (first)
3913 snd_hda_codec_write(codec, 0x21, 0, AC_VERB_GET_PIN_SENSE, 0x0);
3914
3915 snd_hda_codec_write(codec, 0x6, 0, AC_VERB_SET_DIGI_CONVERT_3, 0x80);
3916 alc_write_coef_idx(codec, 0x26, 0xf000);
3917 alc_write_coef_idx(codec, 0x23, initval->value_0x23);
3918
3919 if (initval->value_0x23 != 0x1e)
3920 alc_write_coef_idx(codec, 0x25, initval->value_0x25);
3921
3922 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0x26);
3923 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, 0xb010);
3924}
3925
3926static void alc298_fixup_huawei_mbx_stereo(struct hda_codec *codec,
3927 const struct hda_fixup *fix,
3928 int action)
3929{
3930 /* Initialization magic */
3931 static const struct hda_alc298_mbxinit dac_init[] = {
3932 {0x0c, 0x00}, {0x0d, 0x00}, {0x0e, 0x00}, {0x0f, 0x00},
3933 {0x10, 0x00}, {0x1a, 0x40}, {0x1b, 0x82}, {0x1c, 0x00},
3934 {0x1d, 0x00}, {0x1e, 0x00}, {0x1f, 0x00},
3935 {0x20, 0xc2}, {0x21, 0xc8}, {0x22, 0x26}, {0x23, 0x24},
3936 {0x27, 0xff}, {0x28, 0xff}, {0x29, 0xff}, {0x2a, 0x8f},
3937 {0x2b, 0x02}, {0x2c, 0x48}, {0x2d, 0x34}, {0x2e, 0x00},
3938 {0x2f, 0x00},
3939 {0x30, 0x00}, {0x31, 0x00}, {0x32, 0x00}, {0x33, 0x00},
3940 {0x34, 0x00}, {0x35, 0x01}, {0x36, 0x93}, {0x37, 0x0c},
3941 {0x38, 0x00}, {0x39, 0x00}, {0x3a, 0xf8}, {0x38, 0x80},
3942 {}
3943 };
3944 const struct hda_alc298_mbxinit *seq;
3945
3946 if (action != HDA_FIXUP_ACT_INIT)
3947 return;
3948
3949 /* Start */
3950 snd_hda_codec_write(codec, 0x06, 0, AC_VERB_SET_DIGI_CONVERT_3, 0x00);
3951 snd_hda_codec_write(codec, 0x06, 0, AC_VERB_SET_DIGI_CONVERT_3, 0x80);
3952 alc_write_coef_idx(codec, 0x26, 0xf000);
3953 alc_write_coef_idx(codec, 0x22, 0x31);
3954 alc_write_coef_idx(codec, 0x23, 0x0b);
3955 alc_write_coef_idx(codec, 0x25, 0x00);
3956 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0x26);
3957 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, 0xb010);
3958
3959 for (seq = dac_init; seq->value_0x23; seq++)
3960 alc298_huawei_mbx_stereo_seq(codec, seq, seq == dac_init);
3961}
3962
David Henningssond240d1d2013-04-15 12:50:02 +02003963static void alc269_fixup_x101_headset_mic(struct hda_codec *codec,
3964 const struct hda_fixup *fix, int action)
3965{
3966 struct alc_spec *spec = codec->spec;
3967 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3968 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
3969 spec->gen.hp_automute_hook = alc269_x101_hp_automute_hook;
3970 }
3971}
3972
3973
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003974/* update mute-LED according to the speaker mute state via mic VREF pin */
3975static void alc269_fixup_mic_mute_hook(void *private_data, int enabled)
David Henningsson6d3cd5d2013-01-07 12:03:47 +01003976{
3977 struct hda_codec *codec = private_data;
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003978 struct alc_spec *spec = codec->spec;
3979 unsigned int pinval;
3980
3981 if (spec->mute_led_polarity)
3982 enabled = !enabled;
Takashi Iwai415d5552014-04-03 11:51:21 +02003983 pinval = snd_hda_codec_get_pin_target(codec, spec->mute_led_nid);
3984 pinval &= ~AC_PINCTL_VREFEN;
3985 pinval |= enabled ? AC_PINCTL_VREF_HIZ : AC_PINCTL_VREF_80;
Takashi Iwaie40bdb02018-03-17 22:40:18 +01003986 if (spec->mute_led_nid) {
3987 /* temporarily power up/down for setting VREF */
3988 snd_hda_power_up_pm(codec);
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003989 snd_hda_set_pin_ctl_cache(codec, spec->mute_led_nid, pinval);
Takashi Iwaie40bdb02018-03-17 22:40:18 +01003990 snd_hda_power_down_pm(codec);
3991 }
David Henningsson6d3cd5d2013-01-07 12:03:47 +01003992}
3993
David Henningssond5b6b652013-11-06 10:50:44 +01003994/* Make sure the led works even in runtime suspend */
3995static unsigned int led_power_filter(struct hda_codec *codec,
3996 hda_nid_t nid,
3997 unsigned int power_state)
3998{
3999 struct alc_spec *spec = codec->spec;
4000
Hui Wang50dd9052014-07-08 17:56:15 +08004001 if (power_state != AC_PWRST_D3 || nid == 0 ||
4002 (nid != spec->mute_led_nid && nid != spec->cap_mute_led_nid))
David Henningssond5b6b652013-11-06 10:50:44 +01004003 return power_state;
4004
4005 /* Set pin ctl again, it might have just been set to 0 */
4006 snd_hda_set_pin_ctl(codec, nid,
4007 snd_hda_codec_get_pin_target(codec, nid));
4008
Takashi Iwaicffd3962015-04-09 10:30:25 +02004009 return snd_hda_gen_path_power_filter(codec, nid, power_state);
David Henningssond5b6b652013-11-06 10:50:44 +01004010}
4011
Takashi Iwai08fb0d02013-01-10 17:33:58 +01004012static void alc269_fixup_hp_mute_led(struct hda_codec *codec,
4013 const struct hda_fixup *fix, int action)
David Henningsson6d3cd5d2013-01-07 12:03:47 +01004014{
4015 struct alc_spec *spec = codec->spec;
Takashi Iwai08fb0d02013-01-10 17:33:58 +01004016 const struct dmi_device *dev = NULL;
4017
4018 if (action != HDA_FIXUP_ACT_PRE_PROBE)
4019 return;
4020
4021 while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) {
4022 int pol, pin;
4023 if (sscanf(dev->name, "HP_Mute_LED_%d_%x", &pol, &pin) != 2)
4024 continue;
4025 if (pin < 0x0a || pin >= 0x10)
4026 break;
4027 spec->mute_led_polarity = pol;
4028 spec->mute_led_nid = pin - 0x0a + 0x18;
4029 spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook;
Takashi Iwaifd25a972012-12-20 14:57:18 +01004030 spec->gen.vmaster_mute_enum = 1;
David Henningssond5b6b652013-11-06 10:50:44 +01004031 codec->power_filter = led_power_filter;
Takashi Iwai4e76a882014-02-25 12:21:03 +01004032 codec_dbg(codec,
4033 "Detected mute LED for %x:%d\n", spec->mute_led_nid,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01004034 spec->mute_led_polarity);
David Henningsson6d3cd5d2013-01-07 12:03:47 +01004035 break;
4036 }
4037}
4038
Takashi Iwai85c467d2018-05-29 11:38:38 +02004039static void alc269_fixup_hp_mute_led_micx(struct hda_codec *codec,
4040 const struct hda_fixup *fix,
4041 int action, hda_nid_t pin)
David Henningssond06ac142013-02-18 11:41:55 +01004042{
4043 struct alc_spec *spec = codec->spec;
Takashi Iwai85c467d2018-05-29 11:38:38 +02004044
David Henningssond06ac142013-02-18 11:41:55 +01004045 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4046 spec->mute_led_polarity = 0;
Takashi Iwai85c467d2018-05-29 11:38:38 +02004047 spec->mute_led_nid = pin;
David Henningssond06ac142013-02-18 11:41:55 +01004048 spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook;
4049 spec->gen.vmaster_mute_enum = 1;
David Henningssond5b6b652013-11-06 10:50:44 +01004050 codec->power_filter = led_power_filter;
David Henningssond06ac142013-02-18 11:41:55 +01004051 }
4052}
4053
Takashi Iwai85c467d2018-05-29 11:38:38 +02004054static void alc269_fixup_hp_mute_led_mic1(struct hda_codec *codec,
4055 const struct hda_fixup *fix, int action)
4056{
4057 alc269_fixup_hp_mute_led_micx(codec, fix, action, 0x18);
4058}
4059
Takashi Iwai08fb0d02013-01-10 17:33:58 +01004060static void alc269_fixup_hp_mute_led_mic2(struct hda_codec *codec,
4061 const struct hda_fixup *fix, int action)
Takashi Iwai420b0fe2012-03-12 12:35:27 +01004062{
Takashi Iwai85c467d2018-05-29 11:38:38 +02004063 alc269_fixup_hp_mute_led_micx(codec, fix, action, 0x19);
Takashi Iwai420b0fe2012-03-12 12:35:27 +01004064}
4065
Tom Briden7f783bd2017-03-25 10:12:01 +00004066static void alc269_fixup_hp_mute_led_mic3(struct hda_codec *codec,
4067 const struct hda_fixup *fix, int action)
4068{
Takashi Iwai85c467d2018-05-29 11:38:38 +02004069 alc269_fixup_hp_mute_led_micx(codec, fix, action, 0x1b);
Tom Briden7f783bd2017-03-25 10:12:01 +00004070}
4071
Takashi Iwai0f32fd192014-11-19 12:16:14 +01004072/* update LED status via GPIO */
4073static void alc_update_gpio_led(struct hda_codec *codec, unsigned int mask,
4074 bool enabled)
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01004075{
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01004076 struct alc_spec *spec = codec->spec;
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01004077
Takashi Iwai0f32fd192014-11-19 12:16:14 +01004078 if (spec->mute_led_polarity)
4079 enabled = !enabled;
Takashi Iwaid261eec2018-06-19 22:32:29 +02004080 alc_update_gpio_data(codec, mask, !enabled); /* muted -> LED on */
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01004081}
4082
Takashi Iwai0f32fd192014-11-19 12:16:14 +01004083/* turn on/off mute LED via GPIO per vmaster hook */
4084static void alc_fixup_gpio_mute_hook(void *private_data, int enabled)
4085{
4086 struct hda_codec *codec = private_data;
4087 struct alc_spec *spec = codec->spec;
4088
4089 alc_update_gpio_led(codec, spec->gpio_mute_led_mask, enabled);
4090}
4091
4092/* turn on/off mic-mute LED via GPIO per capture hook */
Takashi Iwaid03abec2018-06-19 12:29:13 +02004093static void alc_gpio_micmute_update(struct hda_codec *codec)
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01004094{
4095 struct alc_spec *spec = codec->spec;
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01004096
Takashi Iwaid03abec2018-06-19 12:29:13 +02004097 alc_update_gpio_led(codec, spec->gpio_mic_led_mask,
4098 spec->gen.micmute_led.led_value);
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01004099}
4100
Takashi Iwai01e4a272018-06-19 22:47:30 +02004101/* setup mute and mic-mute GPIO bits, add hooks appropriately */
4102static void alc_fixup_hp_gpio_led(struct hda_codec *codec,
4103 int action,
4104 unsigned int mute_mask,
4105 unsigned int micmute_mask)
4106{
4107 struct alc_spec *spec = codec->spec;
4108
4109 alc_fixup_gpio(codec, action, mute_mask | micmute_mask);
4110
4111 if (action != HDA_FIXUP_ACT_PRE_PROBE)
4112 return;
4113 if (mute_mask) {
4114 spec->gpio_mute_led_mask = mute_mask;
4115 spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook;
4116 }
4117 if (micmute_mask) {
4118 spec->gpio_mic_led_mask = micmute_mask;
4119 snd_hda_gen_add_micmute_led(codec, alc_gpio_micmute_update);
4120 }
4121}
4122
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01004123static void alc269_fixup_hp_gpio_led(struct hda_codec *codec,
4124 const struct hda_fixup *fix, int action)
4125{
Takashi Iwai01e4a272018-06-19 22:47:30 +02004126 alc_fixup_hp_gpio_led(codec, action, 0x08, 0x10);
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01004127}
4128
Kai-Heng Fengf5a88b02020-03-27 12:46:25 +08004129static void alc285_fixup_hp_gpio_led(struct hda_codec *codec,
4130 const struct hda_fixup *fix, int action)
4131{
4132 alc_fixup_hp_gpio_led(codec, action, 0x04, 0x00);
4133}
4134
Kailang Yangeaa8e5e2014-11-21 15:49:11 +08004135static void alc286_fixup_hp_gpio_led(struct hda_codec *codec,
4136 const struct hda_fixup *fix, int action)
4137{
Takashi Iwai01e4a272018-06-19 22:47:30 +02004138 alc_fixup_hp_gpio_led(codec, action, 0x02, 0x20);
Takashi Iwai1d045db2011-07-07 18:23:21 +02004139}
4140
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004141/* turn on/off mic-mute LED per capture hook */
Takashi Iwaid03abec2018-06-19 12:29:13 +02004142static void alc_cap_micmute_update(struct hda_codec *codec)
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004143{
4144 struct alc_spec *spec = codec->spec;
Takashi Iwaid03abec2018-06-19 12:29:13 +02004145 unsigned int pinval;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004146
Takashi Iwaid03abec2018-06-19 12:29:13 +02004147 if (!spec->cap_mute_led_nid)
4148 return;
Hui Wangfc1fad92014-07-08 17:56:14 +08004149 pinval = snd_hda_codec_get_pin_target(codec, spec->cap_mute_led_nid);
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004150 pinval &= ~AC_PINCTL_VREFEN;
Takashi Iwaid03abec2018-06-19 12:29:13 +02004151 if (spec->gen.micmute_led.led_value)
4152 pinval |= AC_PINCTL_VREF_80;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004153 else
Takashi Iwaid03abec2018-06-19 12:29:13 +02004154 pinval |= AC_PINCTL_VREF_HIZ;
4155 snd_hda_set_pin_ctl_cache(codec, spec->cap_mute_led_nid, pinval);
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004156}
4157
4158static void alc269_fixup_hp_gpio_mic1_led(struct hda_codec *codec,
4159 const struct hda_fixup *fix, int action)
4160{
4161 struct alc_spec *spec = codec->spec;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004162
Takashi Iwai01e4a272018-06-19 22:47:30 +02004163 alc_fixup_hp_gpio_led(codec, action, 0x08, 0);
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004164 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai01e4a272018-06-19 22:47:30 +02004165 /* Like hp_gpio_mic1_led, but also needs GPIO4 low to
4166 * enable headphone amp
4167 */
4168 spec->gpio_mask |= 0x10;
4169 spec->gpio_dir |= 0x10;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004170 spec->cap_mute_led_nid = 0x18;
Takashi Iwaid03abec2018-06-19 12:29:13 +02004171 snd_hda_gen_add_micmute_led(codec, alc_cap_micmute_update);
Hui Wang50dd9052014-07-08 17:56:15 +08004172 codec->power_filter = led_power_filter;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004173 }
4174}
4175
David Henningsson7a5255f2014-10-30 08:26:01 +01004176static void alc280_fixup_hp_gpio4(struct hda_codec *codec,
4177 const struct hda_fixup *fix, int action)
4178{
David Henningsson7a5255f2014-10-30 08:26:01 +01004179 struct alc_spec *spec = codec->spec;
David Henningsson7a5255f2014-10-30 08:26:01 +01004180
Takashi Iwai01e4a272018-06-19 22:47:30 +02004181 alc_fixup_hp_gpio_led(codec, action, 0x08, 0);
David Henningsson7a5255f2014-10-30 08:26:01 +01004182 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
David Henningsson7a5255f2014-10-30 08:26:01 +01004183 spec->cap_mute_led_nid = 0x18;
Takashi Iwaid03abec2018-06-19 12:29:13 +02004184 snd_hda_gen_add_micmute_led(codec, alc_cap_micmute_update);
David Henningsson7a5255f2014-10-30 08:26:01 +01004185 codec->power_filter = led_power_filter;
4186 }
4187}
4188
Kailang Yang431e76c2020-04-07 14:40:20 +08004189/* update mute-LED according to the speaker mute state via COEF bit */
4190static void alc_fixup_mute_led_coefbit_hook(void *private_data, int enabled)
4191{
4192 struct hda_codec *codec = private_data;
4193 struct alc_spec *spec = codec->spec;
4194
4195 if (spec->mute_led_polarity)
4196 enabled = !enabled;
4197
4198 /* temporarily power up/down for setting COEF bit */
4199 enabled ? alc_update_coef_idx(codec, spec->mute_led_coef_idx,
4200 spec->mute_led_coefbit_mask, spec->mute_led_coefbit_off) :
4201 alc_update_coef_idx(codec, spec->mute_led_coef_idx,
4202 spec->mute_led_coefbit_mask, spec->mute_led_coefbit_on);
4203}
4204
4205static void alc285_fixup_hp_mute_led_coefbit(struct hda_codec *codec,
4206 const struct hda_fixup *fix,
4207 int action)
4208{
4209 struct alc_spec *spec = codec->spec;
4210
4211 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4212 spec->mute_led_polarity = 0;
4213 spec->mute_led_coef_idx = 0x0b;
4214 spec->mute_led_coefbit_mask = 1<<3;
4215 spec->mute_led_coefbit_on = 1<<3;
4216 spec->mute_led_coefbit_off = 0;
4217 spec->gen.vmaster_mute.hook = alc_fixup_mute_led_coefbit_hook;
4218 spec->gen.vmaster_mute_enum = 1;
4219 }
4220}
4221
Kailang Yang24164f42020-04-07 14:52:42 +08004222static void alc236_fixup_hp_mute_led_coefbit(struct hda_codec *codec,
4223 const struct hda_fixup *fix,
4224 int action)
4225{
4226 struct alc_spec *spec = codec->spec;
4227
4228 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4229 spec->mute_led_polarity = 0;
4230 spec->mute_led_coef_idx = 0x34;
4231 spec->mute_led_coefbit_mask = 1<<5;
4232 spec->mute_led_coefbit_on = 0;
4233 spec->mute_led_coefbit_off = 1<<5;
4234 spec->gen.vmaster_mute.hook = alc_fixup_mute_led_coefbit_hook;
4235 spec->gen.vmaster_mute_enum = 1;
4236 }
4237}
4238
Kailang Yang431e76c2020-04-07 14:40:20 +08004239/* turn on/off mic-mute LED per capture hook by coef bit */
4240static void alc_hp_cap_micmute_update(struct hda_codec *codec)
4241{
4242 struct alc_spec *spec = codec->spec;
4243
4244 if (spec->gen.micmute_led.led_value)
4245 alc_update_coef_idx(codec, spec->mic_led_coef_idx,
4246 spec->mic_led_coefbit_mask, spec->mic_led_coefbit_on);
4247 else
4248 alc_update_coef_idx(codec, spec->mic_led_coef_idx,
4249 spec->mic_led_coefbit_mask, spec->mic_led_coefbit_off);
4250}
4251
4252static void alc285_fixup_hp_coef_micmute_led(struct hda_codec *codec,
4253 const struct hda_fixup *fix, int action)
4254{
4255 struct alc_spec *spec = codec->spec;
4256
4257 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4258 spec->mic_led_coef_idx = 0x19;
4259 spec->mic_led_coefbit_mask = 1<<13;
4260 spec->mic_led_coefbit_on = 1<<13;
4261 spec->mic_led_coefbit_off = 0;
4262 snd_hda_gen_add_micmute_led(codec, alc_hp_cap_micmute_update);
4263 }
4264}
4265
Kailang Yang24164f42020-04-07 14:52:42 +08004266static void alc236_fixup_hp_coef_micmute_led(struct hda_codec *codec,
4267 const struct hda_fixup *fix, int action)
4268{
4269 struct alc_spec *spec = codec->spec;
4270
4271 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4272 spec->mic_led_coef_idx = 0x35;
4273 spec->mic_led_coefbit_mask = 3<<2;
4274 spec->mic_led_coefbit_on = 2<<2;
4275 spec->mic_led_coefbit_off = 1<<2;
4276 snd_hda_gen_add_micmute_led(codec, alc_hp_cap_micmute_update);
4277 }
4278}
4279
Kailang Yang431e76c2020-04-07 14:40:20 +08004280static void alc285_fixup_hp_mute_led(struct hda_codec *codec,
4281 const struct hda_fixup *fix, int action)
4282{
4283 alc285_fixup_hp_mute_led_coefbit(codec, fix, action);
4284 alc285_fixup_hp_coef_micmute_led(codec, fix, action);
4285}
4286
Kailang Yang24164f42020-04-07 14:52:42 +08004287static void alc236_fixup_hp_mute_led(struct hda_codec *codec,
4288 const struct hda_fixup *fix, int action)
4289{
4290 alc236_fixup_hp_mute_led_coefbit(codec, fix, action);
4291 alc236_fixup_hp_coef_micmute_led(codec, fix, action);
4292}
4293
Takashi Iwai6a30aba2018-04-27 17:17:35 +02004294#if IS_REACHABLE(CONFIG_INPUT)
David Henningsson33f4acd2015-01-07 15:50:13 +01004295static void gpio2_mic_hotkey_event(struct hda_codec *codec,
4296 struct hda_jack_callback *event)
4297{
4298 struct alc_spec *spec = codec->spec;
4299
4300 /* GPIO2 just toggles on a keypress/keyrelease cycle. Therefore
4301 send both key on and key off event for every interrupt. */
Hui Wangc7b60a82015-12-28 11:35:25 +08004302 input_report_key(spec->kb_dev, spec->alc_mute_keycode_map[ALC_KEY_MICMUTE_INDEX], 1);
David Henningsson33f4acd2015-01-07 15:50:13 +01004303 input_sync(spec->kb_dev);
Hui Wangc7b60a82015-12-28 11:35:25 +08004304 input_report_key(spec->kb_dev, spec->alc_mute_keycode_map[ALC_KEY_MICMUTE_INDEX], 0);
David Henningsson33f4acd2015-01-07 15:50:13 +01004305 input_sync(spec->kb_dev);
4306}
David Henningsson33f4acd2015-01-07 15:50:13 +01004307
Kailang3694cb22015-12-28 11:35:24 +08004308static int alc_register_micmute_input_device(struct hda_codec *codec)
4309{
4310 struct alc_spec *spec = codec->spec;
Hui Wangc7b60a82015-12-28 11:35:25 +08004311 int i;
Kailang3694cb22015-12-28 11:35:24 +08004312
4313 spec->kb_dev = input_allocate_device();
4314 if (!spec->kb_dev) {
4315 codec_err(codec, "Out of memory (input_allocate_device)\n");
4316 return -ENOMEM;
4317 }
Hui Wangc7b60a82015-12-28 11:35:25 +08004318
4319 spec->alc_mute_keycode_map[ALC_KEY_MICMUTE_INDEX] = KEY_MICMUTE;
4320
Kailang3694cb22015-12-28 11:35:24 +08004321 spec->kb_dev->name = "Microphone Mute Button";
4322 spec->kb_dev->evbit[0] = BIT_MASK(EV_KEY);
Hui Wangc7b60a82015-12-28 11:35:25 +08004323 spec->kb_dev->keycodesize = sizeof(spec->alc_mute_keycode_map[0]);
4324 spec->kb_dev->keycodemax = ARRAY_SIZE(spec->alc_mute_keycode_map);
4325 spec->kb_dev->keycode = spec->alc_mute_keycode_map;
4326 for (i = 0; i < ARRAY_SIZE(spec->alc_mute_keycode_map); i++)
4327 set_bit(spec->alc_mute_keycode_map[i], spec->kb_dev->keybit);
Kailang3694cb22015-12-28 11:35:24 +08004328
4329 if (input_register_device(spec->kb_dev)) {
4330 codec_err(codec, "input_register_device failed\n");
4331 input_free_device(spec->kb_dev);
4332 spec->kb_dev = NULL;
4333 return -ENOMEM;
4334 }
4335
4336 return 0;
4337}
4338
Takashi Iwai01e4a272018-06-19 22:47:30 +02004339/* GPIO1 = set according to SKU external amp
4340 * GPIO2 = mic mute hotkey
4341 * GPIO3 = mute LED
4342 * GPIO4 = mic mute LED
4343 */
David Henningsson33f4acd2015-01-07 15:50:13 +01004344static void alc280_fixup_hp_gpio2_mic_hotkey(struct hda_codec *codec,
4345 const struct hda_fixup *fix, int action)
4346{
David Henningsson33f4acd2015-01-07 15:50:13 +01004347 struct alc_spec *spec = codec->spec;
4348
Takashi Iwai01e4a272018-06-19 22:47:30 +02004349 alc_fixup_hp_gpio_led(codec, action, 0x08, 0x10);
David Henningsson33f4acd2015-01-07 15:50:13 +01004350 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai1c76aa52018-06-21 16:37:54 +02004351 spec->init_amp = ALC_INIT_DEFAULT;
Kailang3694cb22015-12-28 11:35:24 +08004352 if (alc_register_micmute_input_device(codec) != 0)
David Henningsson33f4acd2015-01-07 15:50:13 +01004353 return;
David Henningsson33f4acd2015-01-07 15:50:13 +01004354
Takashi Iwai01e4a272018-06-19 22:47:30 +02004355 spec->gpio_mask |= 0x06;
4356 spec->gpio_dir |= 0x02;
4357 spec->gpio_data |= 0x02;
Takashi Iwai7639a062015-03-03 10:07:24 +01004358 snd_hda_codec_write_cache(codec, codec->core.afg, 0,
David Henningsson33f4acd2015-01-07 15:50:13 +01004359 AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x04);
Takashi Iwai7639a062015-03-03 10:07:24 +01004360 snd_hda_jack_detect_enable_callback(codec, codec->core.afg,
David Henningsson33f4acd2015-01-07 15:50:13 +01004361 gpio2_mic_hotkey_event);
David Henningsson33f4acd2015-01-07 15:50:13 +01004362 return;
4363 }
4364
4365 if (!spec->kb_dev)
4366 return;
4367
4368 switch (action) {
David Henningsson33f4acd2015-01-07 15:50:13 +01004369 case HDA_FIXUP_ACT_FREE:
4370 input_unregister_device(spec->kb_dev);
David Henningsson33f4acd2015-01-07 15:50:13 +01004371 spec->kb_dev = NULL;
4372 }
David Henningsson33f4acd2015-01-07 15:50:13 +01004373}
4374
Takashi Iwai01e4a272018-06-19 22:47:30 +02004375/* Line2 = mic mute hotkey
4376 * GPIO2 = mic mute LED
4377 */
Kailang3694cb22015-12-28 11:35:24 +08004378static void alc233_fixup_lenovo_line2_mic_hotkey(struct hda_codec *codec,
4379 const struct hda_fixup *fix, int action)
4380{
Kailang3694cb22015-12-28 11:35:24 +08004381 struct alc_spec *spec = codec->spec;
4382
Takashi Iwai01e4a272018-06-19 22:47:30 +02004383 alc_fixup_hp_gpio_led(codec, action, 0, 0x04);
Kailang3694cb22015-12-28 11:35:24 +08004384 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai1c76aa52018-06-21 16:37:54 +02004385 spec->init_amp = ALC_INIT_DEFAULT;
Kailang3694cb22015-12-28 11:35:24 +08004386 if (alc_register_micmute_input_device(codec) != 0)
4387 return;
4388
Kailang3694cb22015-12-28 11:35:24 +08004389 snd_hda_jack_detect_enable_callback(codec, 0x1b,
4390 gpio2_mic_hotkey_event);
Kailang3694cb22015-12-28 11:35:24 +08004391 return;
4392 }
4393
4394 if (!spec->kb_dev)
4395 return;
4396
4397 switch (action) {
Kailang3694cb22015-12-28 11:35:24 +08004398 case HDA_FIXUP_ACT_FREE:
4399 input_unregister_device(spec->kb_dev);
4400 spec->kb_dev = NULL;
4401 }
4402}
Takashi Iwaic4696522018-01-15 10:44:35 +01004403#else /* INPUT */
4404#define alc280_fixup_hp_gpio2_mic_hotkey NULL
4405#define alc233_fixup_lenovo_line2_mic_hotkey NULL
4406#endif /* INPUT */
Kailang3694cb22015-12-28 11:35:24 +08004407
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004408static void alc269_fixup_hp_line1_mic1_led(struct hda_codec *codec,
4409 const struct hda_fixup *fix, int action)
4410{
4411 struct alc_spec *spec = codec->spec;
4412
Takashi Iwai1bce62a2018-06-19 23:15:59 +02004413 alc269_fixup_hp_mute_led_micx(codec, fix, action, 0x1a);
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004414 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004415 spec->cap_mute_led_nid = 0x18;
Takashi Iwaid03abec2018-06-19 12:29:13 +02004416 snd_hda_gen_add_micmute_led(codec, alc_cap_micmute_update);
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004417 }
4418}
4419
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004420static const struct coef_fw alc225_pre_hsmode[] = {
Kailang Yang5a367672017-07-21 15:23:53 +08004421 UPDATE_COEF(0x4a, 1<<8, 0),
4422 UPDATE_COEFEX(0x57, 0x05, 1<<14, 0),
4423 UPDATE_COEF(0x63, 3<<14, 3<<14),
4424 UPDATE_COEF(0x4a, 3<<4, 2<<4),
4425 UPDATE_COEF(0x4a, 3<<10, 3<<10),
4426 UPDATE_COEF(0x45, 0x3f<<10, 0x34<<10),
4427 UPDATE_COEF(0x4a, 3<<10, 0),
4428 {}
4429};
4430
David Henningsson73bdd592013-04-15 15:44:14 +02004431static void alc_headset_mode_unplugged(struct hda_codec *codec)
4432{
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004433 static const struct coef_fw coef0255[] = {
Kailang Yang717f43d2019-05-31 17:16:53 +08004434 WRITE_COEF(0x1b, 0x0c0b), /* LDO and MISC control */
Takashi Iwai54db6c32014-08-18 15:11:19 +02004435 WRITE_COEF(0x45, 0xd089), /* UAJ function set to menual mode */
4436 UPDATE_COEFEX(0x57, 0x05, 1<<14, 0), /* Direct Drive HP Amp control(Set to verb control)*/
4437 WRITE_COEF(0x06, 0x6104), /* Set MIC2 Vref gate with HP */
4438 WRITE_COEFEX(0x57, 0x03, 0x8aa6), /* Direct Drive HP Amp control */
4439 {}
4440 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004441 static const struct coef_fw coef0256[] = {
Kailang Yange69e7e02016-05-30 15:58:28 +08004442 WRITE_COEF(0x1b, 0x0c4b), /* LDO and MISC control */
Kailang Yang717f43d2019-05-31 17:16:53 +08004443 WRITE_COEF(0x45, 0xd089), /* UAJ function set to menual mode */
4444 WRITE_COEF(0x06, 0x6104), /* Set MIC2 Vref gate with HP */
4445 WRITE_COEFEX(0x57, 0x03, 0x09a3), /* Direct Drive HP Amp control */
4446 UPDATE_COEFEX(0x57, 0x05, 1<<14, 0), /* Direct Drive HP Amp control(Set to verb control)*/
Kailang Yange69e7e02016-05-30 15:58:28 +08004447 {}
4448 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004449 static const struct coef_fw coef0233[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004450 WRITE_COEF(0x1b, 0x0c0b),
4451 WRITE_COEF(0x45, 0xc429),
4452 UPDATE_COEF(0x35, 0x4000, 0),
4453 WRITE_COEF(0x06, 0x2104),
4454 WRITE_COEF(0x1a, 0x0001),
4455 WRITE_COEF(0x26, 0x0004),
4456 WRITE_COEF(0x32, 0x42a3),
4457 {}
4458 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004459 static const struct coef_fw coef0288[] = {
Kailang Yangf3b70332015-04-08 15:01:17 +08004460 UPDATE_COEF(0x4f, 0xfcc0, 0xc400),
4461 UPDATE_COEF(0x50, 0x2000, 0x2000),
4462 UPDATE_COEF(0x56, 0x0006, 0x0006),
4463 UPDATE_COEF(0x66, 0x0008, 0),
4464 UPDATE_COEF(0x67, 0x2000, 0),
4465 {}
4466 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004467 static const struct coef_fw coef0298[] = {
Kailang Yang89542932017-07-17 15:03:43 +08004468 UPDATE_COEF(0x19, 0x1300, 0x0300),
4469 {}
4470 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004471 static const struct coef_fw coef0292[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004472 WRITE_COEF(0x76, 0x000e),
4473 WRITE_COEF(0x6c, 0x2400),
4474 WRITE_COEF(0x18, 0x7308),
4475 WRITE_COEF(0x6b, 0xc429),
4476 {}
4477 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004478 static const struct coef_fw coef0293[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004479 UPDATE_COEF(0x10, 7<<8, 6<<8), /* SET Line1 JD to 0 */
4480 UPDATE_COEFEX(0x57, 0x05, 1<<15|1<<13, 0x0), /* SET charge pump by verb */
4481 UPDATE_COEFEX(0x57, 0x03, 1<<10, 1<<10), /* SET EN_OSW to 1 */
4482 UPDATE_COEF(0x1a, 1<<3, 1<<3), /* Combo JD gating with LINE1-VREFO */
4483 WRITE_COEF(0x45, 0xc429), /* Set to TRS type */
4484 UPDATE_COEF(0x4a, 0x000f, 0x000e), /* Combo Jack auto detect */
4485 {}
4486 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004487 static const struct coef_fw coef0668[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004488 WRITE_COEF(0x15, 0x0d40),
4489 WRITE_COEF(0xb7, 0x802b),
4490 {}
4491 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004492 static const struct coef_fw coef0225[] = {
Kailang Yang5a367672017-07-21 15:23:53 +08004493 UPDATE_COEF(0x63, 3<<14, 0),
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004494 {}
4495 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004496 static const struct coef_fw coef0274[] = {
Kailang Yang71683c32017-06-20 16:33:50 +08004497 UPDATE_COEF(0x4a, 0x0100, 0),
4498 UPDATE_COEFEX(0x57, 0x05, 0x4000, 0),
4499 UPDATE_COEF(0x6b, 0xf000, 0x5000),
4500 UPDATE_COEF(0x4a, 0x0010, 0),
4501 UPDATE_COEF(0x4a, 0x0c00, 0x0c00),
4502 WRITE_COEF(0x45, 0x5289),
4503 UPDATE_COEF(0x4a, 0x0c00, 0),
4504 {}
4505 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004506
Takashi Iwai7639a062015-03-03 10:07:24 +01004507 switch (codec->core.vendor_id) {
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004508 case 0x10ec0255:
Kailang Yange69e7e02016-05-30 15:58:28 +08004509 alc_process_coef_fw(codec, coef0255);
4510 break;
Kailang Yang736f20a2017-10-20 15:06:34 +08004511 case 0x10ec0236:
Kailang Yang7081adf2015-03-30 17:05:37 +08004512 case 0x10ec0256:
Kailang Yange69e7e02016-05-30 15:58:28 +08004513 alc_process_coef_fw(codec, coef0256);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004514 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004515 case 0x10ec0234:
4516 case 0x10ec0274:
4517 case 0x10ec0294:
4518 alc_process_coef_fw(codec, coef0274);
4519 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004520 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004521 case 0x10ec0283:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004522 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02004523 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004524 case 0x10ec0286:
4525 case 0x10ec0288:
Kailang Yang89542932017-07-17 15:03:43 +08004526 alc_process_coef_fw(codec, coef0288);
4527 break;
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004528 case 0x10ec0298:
Kailang Yang89542932017-07-17 15:03:43 +08004529 alc_process_coef_fw(codec, coef0298);
Kailang Yangf3b70332015-04-08 15:01:17 +08004530 alc_process_coef_fw(codec, coef0288);
4531 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004532 case 0x10ec0292:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004533 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02004534 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004535 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004536 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004537 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004538 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004539 alc_process_coef_fw(codec, coef0668);
David Henningsson73bdd592013-04-15 15:44:14 +02004540 break;
Kailang Yangc2b691e2018-01-17 15:22:55 +08004541 case 0x10ec0215:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004542 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004543 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08004544 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004545 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08004546 case 0x10ec0299:
Kailang Yang4d4b0c52019-01-09 16:23:37 +08004547 alc_process_coef_fw(codec, alc225_pre_hsmode);
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004548 alc_process_coef_fw(codec, coef0225);
4549 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08004550 case 0x10ec0867:
4551 alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
4552 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004553 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01004554 codec_dbg(codec, "Headset jack set to unplugged mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02004555}
4556
4557
4558static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin,
4559 hda_nid_t mic_pin)
4560{
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004561 static const struct coef_fw coef0255[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004562 WRITE_COEFEX(0x57, 0x03, 0x8aa6),
4563 WRITE_COEF(0x06, 0x6100), /* Set MIC2 Vref gate to normal */
4564 {}
4565 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004566 static const struct coef_fw coef0256[] = {
Kailang Yang717f43d2019-05-31 17:16:53 +08004567 UPDATE_COEFEX(0x57, 0x05, 1<<14, 1<<14), /* Direct Drive HP Amp control(Set to verb control)*/
4568 WRITE_COEFEX(0x57, 0x03, 0x09a3),
4569 WRITE_COEF(0x06, 0x6100), /* Set MIC2 Vref gate to normal */
4570 {}
4571 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004572 static const struct coef_fw coef0233[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004573 UPDATE_COEF(0x35, 0, 1<<14),
4574 WRITE_COEF(0x06, 0x2100),
4575 WRITE_COEF(0x1a, 0x0021),
4576 WRITE_COEF(0x26, 0x008c),
4577 {}
4578 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004579 static const struct coef_fw coef0288[] = {
Kailang Yang89542932017-07-17 15:03:43 +08004580 UPDATE_COEF(0x4f, 0x00c0, 0),
Kailang Yangf3b70332015-04-08 15:01:17 +08004581 UPDATE_COEF(0x50, 0x2000, 0),
4582 UPDATE_COEF(0x56, 0x0006, 0),
4583 UPDATE_COEF(0x4f, 0xfcc0, 0xc400),
4584 UPDATE_COEF(0x66, 0x0008, 0x0008),
4585 UPDATE_COEF(0x67, 0x2000, 0x2000),
4586 {}
4587 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004588 static const struct coef_fw coef0292[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004589 WRITE_COEF(0x19, 0xa208),
4590 WRITE_COEF(0x2e, 0xacf0),
4591 {}
4592 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004593 static const struct coef_fw coef0293[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004594 UPDATE_COEFEX(0x57, 0x05, 0, 1<<15|1<<13), /* SET charge pump by verb */
4595 UPDATE_COEFEX(0x57, 0x03, 1<<10, 0), /* SET EN_OSW to 0 */
4596 UPDATE_COEF(0x1a, 1<<3, 0), /* Combo JD gating without LINE1-VREFO */
4597 {}
4598 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004599 static const struct coef_fw coef0688[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004600 WRITE_COEF(0xb7, 0x802b),
4601 WRITE_COEF(0xb5, 0x1040),
4602 UPDATE_COEF(0xc3, 0, 1<<12),
4603 {}
4604 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004605 static const struct coef_fw coef0225[] = {
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004606 UPDATE_COEFEX(0x57, 0x05, 1<<14, 1<<14),
4607 UPDATE_COEF(0x4a, 3<<4, 2<<4),
4608 UPDATE_COEF(0x63, 3<<14, 0),
4609 {}
4610 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004611 static const struct coef_fw coef0274[] = {
Kailang Yang71683c32017-06-20 16:33:50 +08004612 UPDATE_COEFEX(0x57, 0x05, 0x4000, 0x4000),
4613 UPDATE_COEF(0x4a, 0x0010, 0),
4614 UPDATE_COEF(0x6b, 0xf000, 0),
4615 {}
4616 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004617
Takashi Iwai7639a062015-03-03 10:07:24 +01004618 switch (codec->core.vendor_id) {
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004619 case 0x10ec0255:
4620 alc_write_coef_idx(codec, 0x45, 0xc489);
4621 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02004622 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004623 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4624 break;
Kailang Yang717f43d2019-05-31 17:16:53 +08004625 case 0x10ec0236:
4626 case 0x10ec0256:
4627 alc_write_coef_idx(codec, 0x45, 0xc489);
4628 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4629 alc_process_coef_fw(codec, coef0256);
4630 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4631 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004632 case 0x10ec0234:
4633 case 0x10ec0274:
4634 case 0x10ec0294:
4635 alc_write_coef_idx(codec, 0x45, 0x4689);
4636 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4637 alc_process_coef_fw(codec, coef0274);
4638 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4639 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004640 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004641 case 0x10ec0283:
4642 alc_write_coef_idx(codec, 0x45, 0xc429);
4643 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02004644 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02004645 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4646 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004647 case 0x10ec0286:
4648 case 0x10ec0288:
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004649 case 0x10ec0298:
Kailang Yangf3b70332015-04-08 15:01:17 +08004650 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4651 alc_process_coef_fw(codec, coef0288);
4652 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4653 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004654 case 0x10ec0292:
4655 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02004656 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02004657 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004658 case 0x10ec0293:
4659 /* Set to TRS mode */
4660 alc_write_coef_idx(codec, 0x45, 0xc429);
4661 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02004662 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004663 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4664 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08004665 case 0x10ec0867:
4666 alc_update_coefex_idx(codec, 0x57, 0x5, 0, 1<<14);
4667 /* fallthru */
Kailang Yang9eb5d0e2017-01-17 15:40:25 +08004668 case 0x10ec0221:
David Henningsson1f8b46c2015-05-12 14:38:15 +02004669 case 0x10ec0662:
4670 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4671 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4672 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004673 case 0x10ec0668:
4674 alc_write_coef_idx(codec, 0x11, 0x0001);
4675 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02004676 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02004677 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4678 break;
Kailang Yangc2b691e2018-01-17 15:22:55 +08004679 case 0x10ec0215:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004680 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004681 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08004682 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004683 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08004684 case 0x10ec0299:
Kailang Yang5a367672017-07-21 15:23:53 +08004685 alc_process_coef_fw(codec, alc225_pre_hsmode);
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004686 alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x31<<10);
4687 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4688 alc_process_coef_fw(codec, coef0225);
4689 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4690 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004691 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01004692 codec_dbg(codec, "Headset jack set to mic-in mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02004693}
4694
4695static void alc_headset_mode_default(struct hda_codec *codec)
4696{
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004697 static const struct coef_fw coef0225[] = {
Kailang Yang5a367672017-07-21 15:23:53 +08004698 UPDATE_COEF(0x45, 0x3f<<10, 0x30<<10),
4699 UPDATE_COEF(0x45, 0x3f<<10, 0x31<<10),
4700 UPDATE_COEF(0x49, 3<<8, 0<<8),
4701 UPDATE_COEF(0x4a, 3<<4, 3<<4),
4702 UPDATE_COEF(0x63, 3<<14, 0),
4703 UPDATE_COEF(0x67, 0xf000, 0x3000),
David Henningsson2ae95572016-02-25 09:37:05 +01004704 {}
4705 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004706 static const struct coef_fw coef0255[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004707 WRITE_COEF(0x45, 0xc089),
4708 WRITE_COEF(0x45, 0xc489),
4709 WRITE_COEFEX(0x57, 0x03, 0x8ea6),
4710 WRITE_COEF(0x49, 0x0049),
4711 {}
4712 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004713 static const struct coef_fw coef0256[] = {
Kailang Yang717f43d2019-05-31 17:16:53 +08004714 WRITE_COEF(0x45, 0xc489),
4715 WRITE_COEFEX(0x57, 0x03, 0x0da3),
4716 WRITE_COEF(0x49, 0x0049),
4717 UPDATE_COEFEX(0x57, 0x05, 1<<14, 0), /* Direct Drive HP Amp control(Set to verb control)*/
4718 WRITE_COEF(0x06, 0x6100),
4719 {}
4720 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004721 static const struct coef_fw coef0233[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004722 WRITE_COEF(0x06, 0x2100),
4723 WRITE_COEF(0x32, 0x4ea3),
4724 {}
4725 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004726 static const struct coef_fw coef0288[] = {
Kailang Yangf3b70332015-04-08 15:01:17 +08004727 UPDATE_COEF(0x4f, 0xfcc0, 0xc400), /* Set to TRS type */
4728 UPDATE_COEF(0x50, 0x2000, 0x2000),
4729 UPDATE_COEF(0x56, 0x0006, 0x0006),
4730 UPDATE_COEF(0x66, 0x0008, 0),
4731 UPDATE_COEF(0x67, 0x2000, 0),
4732 {}
4733 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004734 static const struct coef_fw coef0292[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004735 WRITE_COEF(0x76, 0x000e),
4736 WRITE_COEF(0x6c, 0x2400),
4737 WRITE_COEF(0x6b, 0xc429),
4738 WRITE_COEF(0x18, 0x7308),
4739 {}
4740 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004741 static const struct coef_fw coef0293[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004742 UPDATE_COEF(0x4a, 0x000f, 0x000e), /* Combo Jack auto detect */
4743 WRITE_COEF(0x45, 0xC429), /* Set to TRS type */
4744 UPDATE_COEF(0x1a, 1<<3, 0), /* Combo JD gating without LINE1-VREFO */
4745 {}
4746 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004747 static const struct coef_fw coef0688[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004748 WRITE_COEF(0x11, 0x0041),
4749 WRITE_COEF(0x15, 0x0d40),
4750 WRITE_COEF(0xb7, 0x802b),
4751 {}
4752 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004753 static const struct coef_fw coef0274[] = {
Kailang Yang71683c32017-06-20 16:33:50 +08004754 WRITE_COEF(0x45, 0x4289),
4755 UPDATE_COEF(0x4a, 0x0010, 0x0010),
4756 UPDATE_COEF(0x6b, 0x0f00, 0),
4757 UPDATE_COEF(0x49, 0x0300, 0x0300),
4758 {}
4759 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004760
Takashi Iwai7639a062015-03-03 10:07:24 +01004761 switch (codec->core.vendor_id) {
Kailang Yangc2b691e2018-01-17 15:22:55 +08004762 case 0x10ec0215:
David Henningsson2ae95572016-02-25 09:37:05 +01004763 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004764 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08004765 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004766 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08004767 case 0x10ec0299:
Kailang Yang5a367672017-07-21 15:23:53 +08004768 alc_process_coef_fw(codec, alc225_pre_hsmode);
David Henningsson2ae95572016-02-25 09:37:05 +01004769 alc_process_coef_fw(codec, coef0225);
4770 break;
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004771 case 0x10ec0255:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004772 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004773 break;
Kailang Yang717f43d2019-05-31 17:16:53 +08004774 case 0x10ec0236:
4775 case 0x10ec0256:
4776 alc_write_coef_idx(codec, 0x1b, 0x0e4b);
4777 alc_write_coef_idx(codec, 0x45, 0xc089);
4778 msleep(50);
4779 alc_process_coef_fw(codec, coef0256);
4780 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004781 case 0x10ec0234:
4782 case 0x10ec0274:
4783 case 0x10ec0294:
4784 alc_process_coef_fw(codec, coef0274);
4785 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004786 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004787 case 0x10ec0283:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004788 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02004789 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004790 case 0x10ec0286:
4791 case 0x10ec0288:
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004792 case 0x10ec0298:
Kailang Yangf3b70332015-04-08 15:01:17 +08004793 alc_process_coef_fw(codec, coef0288);
4794 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004795 case 0x10ec0292:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004796 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02004797 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004798 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004799 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004800 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004801 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004802 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02004803 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08004804 case 0x10ec0867:
4805 alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
4806 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004807 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01004808 codec_dbg(codec, "Headset jack set to headphone (default) mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02004809}
4810
4811/* Iphone type */
4812static void alc_headset_mode_ctia(struct hda_codec *codec)
4813{
Kailang Yang89542932017-07-17 15:03:43 +08004814 int val;
4815
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004816 static const struct coef_fw coef0255[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004817 WRITE_COEF(0x45, 0xd489), /* Set to CTIA type */
4818 WRITE_COEF(0x1b, 0x0c2b),
4819 WRITE_COEFEX(0x57, 0x03, 0x8ea6),
4820 {}
4821 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004822 static const struct coef_fw coef0256[] = {
Kailang Yange69e7e02016-05-30 15:58:28 +08004823 WRITE_COEF(0x45, 0xd489), /* Set to CTIA type */
Kailang Yang717f43d2019-05-31 17:16:53 +08004824 WRITE_COEF(0x1b, 0x0e6b),
Kailang Yange69e7e02016-05-30 15:58:28 +08004825 {}
4826 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004827 static const struct coef_fw coef0233[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004828 WRITE_COEF(0x45, 0xd429),
4829 WRITE_COEF(0x1b, 0x0c2b),
4830 WRITE_COEF(0x32, 0x4ea3),
4831 {}
4832 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004833 static const struct coef_fw coef0288[] = {
Kailang Yangf3b70332015-04-08 15:01:17 +08004834 UPDATE_COEF(0x50, 0x2000, 0x2000),
4835 UPDATE_COEF(0x56, 0x0006, 0x0006),
4836 UPDATE_COEF(0x66, 0x0008, 0),
4837 UPDATE_COEF(0x67, 0x2000, 0),
4838 {}
4839 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004840 static const struct coef_fw coef0292[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004841 WRITE_COEF(0x6b, 0xd429),
4842 WRITE_COEF(0x76, 0x0008),
4843 WRITE_COEF(0x18, 0x7388),
4844 {}
4845 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004846 static const struct coef_fw coef0293[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004847 WRITE_COEF(0x45, 0xd429), /* Set to ctia type */
4848 UPDATE_COEF(0x10, 7<<8, 7<<8), /* SET Line1 JD to 1 */
4849 {}
4850 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004851 static const struct coef_fw coef0688[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004852 WRITE_COEF(0x11, 0x0001),
4853 WRITE_COEF(0x15, 0x0d60),
4854 WRITE_COEF(0xc3, 0x0000),
4855 {}
4856 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004857 static const struct coef_fw coef0225_1[] = {
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004858 UPDATE_COEF(0x45, 0x3f<<10, 0x35<<10),
Kailang Yang5a367672017-07-21 15:23:53 +08004859 UPDATE_COEF(0x63, 3<<14, 2<<14),
4860 {}
4861 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004862 static const struct coef_fw coef0225_2[] = {
Kailang Yang5a367672017-07-21 15:23:53 +08004863 UPDATE_COEF(0x45, 0x3f<<10, 0x35<<10),
4864 UPDATE_COEF(0x63, 3<<14, 1<<14),
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004865 {}
4866 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004867
Takashi Iwai7639a062015-03-03 10:07:24 +01004868 switch (codec->core.vendor_id) {
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004869 case 0x10ec0255:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004870 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004871 break;
Kailang Yang736f20a2017-10-20 15:06:34 +08004872 case 0x10ec0236:
Kailang Yange69e7e02016-05-30 15:58:28 +08004873 case 0x10ec0256:
4874 alc_process_coef_fw(codec, coef0256);
4875 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004876 case 0x10ec0234:
4877 case 0x10ec0274:
4878 case 0x10ec0294:
4879 alc_write_coef_idx(codec, 0x45, 0xd689);
4880 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004881 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004882 case 0x10ec0283:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004883 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02004884 break;
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004885 case 0x10ec0298:
Kailang Yang89542932017-07-17 15:03:43 +08004886 val = alc_read_coef_idx(codec, 0x50);
4887 if (val & (1 << 12)) {
4888 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0020);
4889 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400);
4890 msleep(300);
4891 } else {
4892 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0010);
4893 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400);
4894 msleep(300);
4895 }
4896 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004897 case 0x10ec0286:
4898 case 0x10ec0288:
4899 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400);
4900 msleep(300);
4901 alc_process_coef_fw(codec, coef0288);
4902 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004903 case 0x10ec0292:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004904 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02004905 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004906 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004907 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004908 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004909 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004910 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02004911 break;
Kailang Yangc2b691e2018-01-17 15:22:55 +08004912 case 0x10ec0215:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004913 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004914 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08004915 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004916 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08004917 case 0x10ec0299:
Kailang Yang5a367672017-07-21 15:23:53 +08004918 val = alc_read_coef_idx(codec, 0x45);
4919 if (val & (1 << 9))
4920 alc_process_coef_fw(codec, coef0225_2);
4921 else
4922 alc_process_coef_fw(codec, coef0225_1);
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004923 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08004924 case 0x10ec0867:
4925 alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
4926 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004927 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01004928 codec_dbg(codec, "Headset jack set to iPhone-style headset mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02004929}
4930
4931/* Nokia type */
4932static void alc_headset_mode_omtp(struct hda_codec *codec)
4933{
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004934 static const struct coef_fw coef0255[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004935 WRITE_COEF(0x45, 0xe489), /* Set to OMTP Type */
4936 WRITE_COEF(0x1b, 0x0c2b),
4937 WRITE_COEFEX(0x57, 0x03, 0x8ea6),
4938 {}
4939 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004940 static const struct coef_fw coef0256[] = {
Kailang Yange69e7e02016-05-30 15:58:28 +08004941 WRITE_COEF(0x45, 0xe489), /* Set to OMTP Type */
Kailang Yang717f43d2019-05-31 17:16:53 +08004942 WRITE_COEF(0x1b, 0x0e6b),
Kailang Yange69e7e02016-05-30 15:58:28 +08004943 {}
4944 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004945 static const struct coef_fw coef0233[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004946 WRITE_COEF(0x45, 0xe429),
4947 WRITE_COEF(0x1b, 0x0c2b),
4948 WRITE_COEF(0x32, 0x4ea3),
4949 {}
4950 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004951 static const struct coef_fw coef0288[] = {
Kailang Yangf3b70332015-04-08 15:01:17 +08004952 UPDATE_COEF(0x50, 0x2000, 0x2000),
4953 UPDATE_COEF(0x56, 0x0006, 0x0006),
4954 UPDATE_COEF(0x66, 0x0008, 0),
4955 UPDATE_COEF(0x67, 0x2000, 0),
4956 {}
4957 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004958 static const struct coef_fw coef0292[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004959 WRITE_COEF(0x6b, 0xe429),
4960 WRITE_COEF(0x76, 0x0008),
4961 WRITE_COEF(0x18, 0x7388),
4962 {}
4963 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004964 static const struct coef_fw coef0293[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004965 WRITE_COEF(0x45, 0xe429), /* Set to omtp type */
4966 UPDATE_COEF(0x10, 7<<8, 7<<8), /* SET Line1 JD to 1 */
4967 {}
4968 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004969 static const struct coef_fw coef0688[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004970 WRITE_COEF(0x11, 0x0001),
4971 WRITE_COEF(0x15, 0x0d50),
4972 WRITE_COEF(0xc3, 0x0000),
4973 {}
4974 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004975 static const struct coef_fw coef0225[] = {
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004976 UPDATE_COEF(0x45, 0x3f<<10, 0x39<<10),
Kailang Yang5a367672017-07-21 15:23:53 +08004977 UPDATE_COEF(0x63, 3<<14, 2<<14),
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004978 {}
4979 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004980
Takashi Iwai7639a062015-03-03 10:07:24 +01004981 switch (codec->core.vendor_id) {
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004982 case 0x10ec0255:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004983 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004984 break;
Kailang Yang736f20a2017-10-20 15:06:34 +08004985 case 0x10ec0236:
Kailang Yange69e7e02016-05-30 15:58:28 +08004986 case 0x10ec0256:
4987 alc_process_coef_fw(codec, coef0256);
4988 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004989 case 0x10ec0234:
4990 case 0x10ec0274:
4991 case 0x10ec0294:
4992 alc_write_coef_idx(codec, 0x45, 0xe689);
4993 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004994 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004995 case 0x10ec0283:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004996 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02004997 break;
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004998 case 0x10ec0298:
4999 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0010);/* Headset output enable */
Kailang Yang89542932017-07-17 15:03:43 +08005000 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xe400);
5001 msleep(300);
5002 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08005003 case 0x10ec0286:
5004 case 0x10ec0288:
5005 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xe400);
5006 msleep(300);
5007 alc_process_coef_fw(codec, coef0288);
5008 break;
David Henningsson73bdd592013-04-15 15:44:14 +02005009 case 0x10ec0292:
Takashi Iwai54db6c32014-08-18 15:11:19 +02005010 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02005011 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08005012 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02005013 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08005014 break;
David Henningsson73bdd592013-04-15 15:44:14 +02005015 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02005016 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02005017 break;
Kailang Yangc2b691e2018-01-17 15:22:55 +08005018 case 0x10ec0215:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08005019 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08005020 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08005021 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08005022 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08005023 case 0x10ec0299:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08005024 alc_process_coef_fw(codec, coef0225);
5025 break;
David Henningsson73bdd592013-04-15 15:44:14 +02005026 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01005027 codec_dbg(codec, "Headset jack set to Nokia-style headset mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02005028}
5029
5030static void alc_determine_headset_type(struct hda_codec *codec)
5031{
5032 int val;
5033 bool is_ctia = false;
5034 struct alc_spec *spec = codec->spec;
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01005035 static const struct coef_fw coef0255[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02005036 WRITE_COEF(0x45, 0xd089), /* combo jack auto switch control(Check type)*/
5037 WRITE_COEF(0x49, 0x0149), /* combo jack auto switch control(Vref
5038 conteol) */
5039 {}
5040 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01005041 static const struct coef_fw coef0288[] = {
Kailang Yangf3b70332015-04-08 15:01:17 +08005042 UPDATE_COEF(0x4f, 0xfcc0, 0xd400), /* Check Type */
5043 {}
5044 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01005045 static const struct coef_fw coef0298[] = {
Kailang Yang89542932017-07-17 15:03:43 +08005046 UPDATE_COEF(0x50, 0x2000, 0x2000),
5047 UPDATE_COEF(0x56, 0x0006, 0x0006),
5048 UPDATE_COEF(0x66, 0x0008, 0),
5049 UPDATE_COEF(0x67, 0x2000, 0),
5050 UPDATE_COEF(0x19, 0x1300, 0x1300),
5051 {}
5052 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01005053 static const struct coef_fw coef0293[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02005054 UPDATE_COEF(0x4a, 0x000f, 0x0008), /* Combo Jack auto detect */
5055 WRITE_COEF(0x45, 0xD429), /* Set to ctia type */
5056 {}
5057 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01005058 static const struct coef_fw coef0688[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02005059 WRITE_COEF(0x11, 0x0001),
5060 WRITE_COEF(0xb7, 0x802b),
5061 WRITE_COEF(0x15, 0x0d60),
5062 WRITE_COEF(0xc3, 0x0c00),
5063 {}
5064 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01005065 static const struct coef_fw coef0274[] = {
Kailang Yang71683c32017-06-20 16:33:50 +08005066 UPDATE_COEF(0x4a, 0x0010, 0),
5067 UPDATE_COEF(0x4a, 0x8000, 0),
5068 WRITE_COEF(0x45, 0xd289),
5069 UPDATE_COEF(0x49, 0x0300, 0x0300),
5070 {}
5071 };
David Henningsson73bdd592013-04-15 15:44:14 +02005072
Takashi Iwai7639a062015-03-03 10:07:24 +01005073 switch (codec->core.vendor_id) {
Kailang Yang9a22a8f52013-11-08 15:54:49 +08005074 case 0x10ec0255:
Takashi Iwai54db6c32014-08-18 15:11:19 +02005075 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08005076 msleep(300);
5077 val = alc_read_coef_idx(codec, 0x46);
5078 is_ctia = (val & 0x0070) == 0x0070;
5079 break;
Kailang Yang717f43d2019-05-31 17:16:53 +08005080 case 0x10ec0236:
5081 case 0x10ec0256:
5082 alc_write_coef_idx(codec, 0x1b, 0x0e4b);
5083 alc_write_coef_idx(codec, 0x06, 0x6104);
5084 alc_write_coefex_idx(codec, 0x57, 0x3, 0x09a3);
5085
5086 snd_hda_codec_write(codec, 0x21, 0,
5087 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
5088 msleep(80);
5089 snd_hda_codec_write(codec, 0x21, 0,
5090 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
5091
5092 alc_process_coef_fw(codec, coef0255);
5093 msleep(300);
5094 val = alc_read_coef_idx(codec, 0x46);
5095 is_ctia = (val & 0x0070) == 0x0070;
5096
5097 alc_write_coefex_idx(codec, 0x57, 0x3, 0x0da3);
5098 alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
5099
5100 snd_hda_codec_write(codec, 0x21, 0,
5101 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
5102 msleep(80);
5103 snd_hda_codec_write(codec, 0x21, 0,
5104 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
5105 break;
Kailang Yang71683c32017-06-20 16:33:50 +08005106 case 0x10ec0234:
5107 case 0x10ec0274:
5108 case 0x10ec0294:
5109 alc_process_coef_fw(codec, coef0274);
5110 msleep(80);
5111 val = alc_read_coef_idx(codec, 0x46);
5112 is_ctia = (val & 0x00f0) == 0x00f0;
5113 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08005114 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02005115 case 0x10ec0283:
5116 alc_write_coef_idx(codec, 0x45, 0xd029);
5117 msleep(300);
5118 val = alc_read_coef_idx(codec, 0x46);
5119 is_ctia = (val & 0x0070) == 0x0070;
5120 break;
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08005121 case 0x10ec0298:
Kailang Yang89542932017-07-17 15:03:43 +08005122 snd_hda_codec_write(codec, 0x21, 0,
5123 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
5124 msleep(100);
5125 snd_hda_codec_write(codec, 0x21, 0,
5126 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
5127 msleep(200);
5128
5129 val = alc_read_coef_idx(codec, 0x50);
5130 if (val & (1 << 12)) {
5131 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0020);
5132 alc_process_coef_fw(codec, coef0288);
5133 msleep(350);
5134 val = alc_read_coef_idx(codec, 0x50);
5135 is_ctia = (val & 0x0070) == 0x0070;
5136 } else {
5137 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0010);
5138 alc_process_coef_fw(codec, coef0288);
5139 msleep(350);
5140 val = alc_read_coef_idx(codec, 0x50);
5141 is_ctia = (val & 0x0070) == 0x0070;
5142 }
5143 alc_process_coef_fw(codec, coef0298);
5144 snd_hda_codec_write(codec, 0x21, 0,
5145 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP);
5146 msleep(75);
5147 snd_hda_codec_write(codec, 0x21, 0,
5148 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
5149 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08005150 case 0x10ec0286:
5151 case 0x10ec0288:
5152 alc_process_coef_fw(codec, coef0288);
5153 msleep(350);
5154 val = alc_read_coef_idx(codec, 0x50);
5155 is_ctia = (val & 0x0070) == 0x0070;
5156 break;
David Henningsson73bdd592013-04-15 15:44:14 +02005157 case 0x10ec0292:
5158 alc_write_coef_idx(codec, 0x6b, 0xd429);
5159 msleep(300);
5160 val = alc_read_coef_idx(codec, 0x6c);
5161 is_ctia = (val & 0x001c) == 0x001c;
5162 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08005163 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02005164 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08005165 msleep(300);
5166 val = alc_read_coef_idx(codec, 0x46);
5167 is_ctia = (val & 0x0070) == 0x0070;
5168 break;
David Henningsson73bdd592013-04-15 15:44:14 +02005169 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02005170 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02005171 msleep(300);
5172 val = alc_read_coef_idx(codec, 0xbe);
5173 is_ctia = (val & 0x1c02) == 0x1c02;
5174 break;
Kailang Yangc2b691e2018-01-17 15:22:55 +08005175 case 0x10ec0215:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08005176 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08005177 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08005178 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08005179 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08005180 case 0x10ec0299:
Kailang Yangda911b12018-01-05 16:50:08 +08005181 snd_hda_codec_write(codec, 0x21, 0,
5182 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
5183 msleep(80);
5184 snd_hda_codec_write(codec, 0x21, 0,
5185 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
5186
Kailang Yang5a367672017-07-21 15:23:53 +08005187 alc_process_coef_fw(codec, alc225_pre_hsmode);
5188 alc_update_coef_idx(codec, 0x67, 0xf000, 0x1000);
5189 val = alc_read_coef_idx(codec, 0x45);
5190 if (val & (1 << 9)) {
5191 alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x34<<10);
5192 alc_update_coef_idx(codec, 0x49, 3<<8, 2<<8);
5193 msleep(800);
5194 val = alc_read_coef_idx(codec, 0x46);
5195 is_ctia = (val & 0x00f0) == 0x00f0;
5196 } else {
5197 alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x34<<10);
5198 alc_update_coef_idx(codec, 0x49, 3<<8, 1<<8);
5199 msleep(800);
5200 val = alc_read_coef_idx(codec, 0x46);
5201 is_ctia = (val & 0x00f0) == 0x00f0;
5202 }
5203 alc_update_coef_idx(codec, 0x4a, 7<<6, 7<<6);
5204 alc_update_coef_idx(codec, 0x4a, 3<<4, 3<<4);
5205 alc_update_coef_idx(codec, 0x67, 0xf000, 0x3000);
Kailang Yangda911b12018-01-05 16:50:08 +08005206
5207 snd_hda_codec_write(codec, 0x21, 0,
5208 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
5209 msleep(80);
5210 snd_hda_codec_write(codec, 0x21, 0,
5211 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08005212 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08005213 case 0x10ec0867:
5214 is_ctia = true;
5215 break;
David Henningsson73bdd592013-04-15 15:44:14 +02005216 }
5217
Takashi Iwai4e76a882014-02-25 12:21:03 +01005218 codec_dbg(codec, "Headset jack detected iPhone-style headset: %s\n",
David Henningsson73bdd592013-04-15 15:44:14 +02005219 is_ctia ? "yes" : "no");
5220 spec->current_headset_type = is_ctia ? ALC_HEADSET_TYPE_CTIA : ALC_HEADSET_TYPE_OMTP;
5221}
5222
5223static void alc_update_headset_mode(struct hda_codec *codec)
5224{
5225 struct alc_spec *spec = codec->spec;
5226
5227 hda_nid_t mux_pin = spec->gen.imux_pins[spec->gen.cur_mux[0]];
Takashi Iwai35a39f92019-02-01 11:19:50 +01005228 hda_nid_t hp_pin = alc_get_hp_pin(spec);
David Henningsson73bdd592013-04-15 15:44:14 +02005229
5230 int new_headset_mode;
5231
5232 if (!snd_hda_jack_detect(codec, hp_pin))
5233 new_headset_mode = ALC_HEADSET_MODE_UNPLUGGED;
5234 else if (mux_pin == spec->headset_mic_pin)
5235 new_headset_mode = ALC_HEADSET_MODE_HEADSET;
5236 else if (mux_pin == spec->headphone_mic_pin)
5237 new_headset_mode = ALC_HEADSET_MODE_MIC;
5238 else
5239 new_headset_mode = ALC_HEADSET_MODE_HEADPHONE;
5240
David Henningsson5959a6b2013-11-12 11:10:57 +01005241 if (new_headset_mode == spec->current_headset_mode) {
5242 snd_hda_gen_update_outputs(codec);
David Henningsson73bdd592013-04-15 15:44:14 +02005243 return;
David Henningsson5959a6b2013-11-12 11:10:57 +01005244 }
David Henningsson73bdd592013-04-15 15:44:14 +02005245
5246 switch (new_headset_mode) {
5247 case ALC_HEADSET_MODE_UNPLUGGED:
5248 alc_headset_mode_unplugged(codec);
Kailang Yangaeac1a02019-05-16 16:10:44 +08005249 spec->current_headset_mode = ALC_HEADSET_MODE_UNKNOWN;
5250 spec->current_headset_type = ALC_HEADSET_TYPE_UNKNOWN;
David Henningsson73bdd592013-04-15 15:44:14 +02005251 spec->gen.hp_jack_present = false;
5252 break;
5253 case ALC_HEADSET_MODE_HEADSET:
5254 if (spec->current_headset_type == ALC_HEADSET_TYPE_UNKNOWN)
5255 alc_determine_headset_type(codec);
5256 if (spec->current_headset_type == ALC_HEADSET_TYPE_CTIA)
5257 alc_headset_mode_ctia(codec);
5258 else if (spec->current_headset_type == ALC_HEADSET_TYPE_OMTP)
5259 alc_headset_mode_omtp(codec);
5260 spec->gen.hp_jack_present = true;
5261 break;
5262 case ALC_HEADSET_MODE_MIC:
5263 alc_headset_mode_mic_in(codec, hp_pin, spec->headphone_mic_pin);
5264 spec->gen.hp_jack_present = false;
5265 break;
5266 case ALC_HEADSET_MODE_HEADPHONE:
5267 alc_headset_mode_default(codec);
5268 spec->gen.hp_jack_present = true;
5269 break;
5270 }
5271 if (new_headset_mode != ALC_HEADSET_MODE_MIC) {
5272 snd_hda_set_pin_ctl_cache(codec, hp_pin,
5273 AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN);
David Henningsson1f8b46c2015-05-12 14:38:15 +02005274 if (spec->headphone_mic_pin && spec->headphone_mic_pin != hp_pin)
David Henningsson73bdd592013-04-15 15:44:14 +02005275 snd_hda_set_pin_ctl_cache(codec, spec->headphone_mic_pin,
5276 PIN_VREFHIZ);
5277 }
5278 spec->current_headset_mode = new_headset_mode;
5279
5280 snd_hda_gen_update_outputs(codec);
5281}
5282
5283static void alc_update_headset_mode_hook(struct hda_codec *codec,
Takashi Iwai7fe30712014-01-30 17:59:02 +01005284 struct snd_kcontrol *kcontrol,
5285 struct snd_ctl_elem_value *ucontrol)
David Henningsson73bdd592013-04-15 15:44:14 +02005286{
5287 alc_update_headset_mode(codec);
5288}
5289
Takashi Iwai1a4f69d2014-09-11 15:22:46 +02005290static void alc_update_headset_jack_cb(struct hda_codec *codec,
5291 struct hda_jack_callback *jack)
David Henningsson73bdd592013-04-15 15:44:14 +02005292{
David Henningsson73bdd592013-04-15 15:44:14 +02005293 snd_hda_gen_hp_automute(codec, jack);
5294}
5295
5296static void alc_probe_headset_mode(struct hda_codec *codec)
5297{
5298 int i;
5299 struct alc_spec *spec = codec->spec;
5300 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
5301
5302 /* Find mic pins */
5303 for (i = 0; i < cfg->num_inputs; i++) {
5304 if (cfg->inputs[i].is_headset_mic && !spec->headset_mic_pin)
5305 spec->headset_mic_pin = cfg->inputs[i].pin;
5306 if (cfg->inputs[i].is_headphone_mic && !spec->headphone_mic_pin)
5307 spec->headphone_mic_pin = cfg->inputs[i].pin;
5308 }
5309
Takashi Iwai0bed2aa2018-06-19 12:45:53 +02005310 WARN_ON(spec->gen.cap_sync_hook);
David Henningsson73bdd592013-04-15 15:44:14 +02005311 spec->gen.cap_sync_hook = alc_update_headset_mode_hook;
5312 spec->gen.automute_hook = alc_update_headset_mode;
5313 spec->gen.hp_automute_hook = alc_update_headset_jack_cb;
5314}
5315
5316static void alc_fixup_headset_mode(struct hda_codec *codec,
5317 const struct hda_fixup *fix, int action)
5318{
5319 struct alc_spec *spec = codec->spec;
5320
5321 switch (action) {
5322 case HDA_FIXUP_ACT_PRE_PROBE:
5323 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC | HDA_PINCFG_HEADPHONE_MIC;
5324 break;
5325 case HDA_FIXUP_ACT_PROBE:
5326 alc_probe_headset_mode(codec);
5327 break;
5328 case HDA_FIXUP_ACT_INIT:
Kailang Yangaeac1a02019-05-16 16:10:44 +08005329 if (is_s3_resume(codec) || is_s4_resume(codec)) {
5330 spec->current_headset_mode = ALC_HEADSET_MODE_UNKNOWN;
5331 spec->current_headset_type = ALC_HEADSET_TYPE_UNKNOWN;
5332 }
David Henningsson73bdd592013-04-15 15:44:14 +02005333 alc_update_headset_mode(codec);
5334 break;
5335 }
5336}
5337
5338static void alc_fixup_headset_mode_no_hp_mic(struct hda_codec *codec,
5339 const struct hda_fixup *fix, int action)
5340{
5341 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5342 struct alc_spec *spec = codec->spec;
5343 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
5344 }
5345 else
5346 alc_fixup_headset_mode(codec, fix, action);
5347}
5348
Kailang Yang31278992014-03-03 15:27:22 +08005349static void alc255_set_default_jack_type(struct hda_codec *codec)
5350{
5351 /* Set to iphone type */
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01005352 static const struct coef_fw alc255fw[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02005353 WRITE_COEF(0x1b, 0x880b),
5354 WRITE_COEF(0x45, 0xd089),
5355 WRITE_COEF(0x1b, 0x080b),
5356 WRITE_COEF(0x46, 0x0004),
5357 WRITE_COEF(0x1b, 0x0c0b),
5358 {}
5359 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01005360 static const struct coef_fw alc256fw[] = {
Kailang Yange69e7e02016-05-30 15:58:28 +08005361 WRITE_COEF(0x1b, 0x884b),
5362 WRITE_COEF(0x45, 0xd089),
5363 WRITE_COEF(0x1b, 0x084b),
5364 WRITE_COEF(0x46, 0x0004),
5365 WRITE_COEF(0x1b, 0x0c4b),
5366 {}
5367 };
5368 switch (codec->core.vendor_id) {
5369 case 0x10ec0255:
5370 alc_process_coef_fw(codec, alc255fw);
5371 break;
Kailang Yang736f20a2017-10-20 15:06:34 +08005372 case 0x10ec0236:
Kailang Yange69e7e02016-05-30 15:58:28 +08005373 case 0x10ec0256:
5374 alc_process_coef_fw(codec, alc256fw);
5375 break;
5376 }
Kailang Yang31278992014-03-03 15:27:22 +08005377 msleep(30);
5378}
5379
Kailang Yang9a22a8f52013-11-08 15:54:49 +08005380static void alc_fixup_headset_mode_alc255(struct hda_codec *codec,
5381 const struct hda_fixup *fix, int action)
5382{
5383 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Kailang Yang31278992014-03-03 15:27:22 +08005384 alc255_set_default_jack_type(codec);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08005385 }
5386 alc_fixup_headset_mode(codec, fix, action);
5387}
5388
Kailang Yang31278992014-03-03 15:27:22 +08005389static void alc_fixup_headset_mode_alc255_no_hp_mic(struct hda_codec *codec,
5390 const struct hda_fixup *fix, int action)
5391{
5392 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5393 struct alc_spec *spec = codec->spec;
5394 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
5395 alc255_set_default_jack_type(codec);
5396 }
5397 else
5398 alc_fixup_headset_mode(codec, fix, action);
5399}
5400
Kailang Yange1e62b92015-04-08 16:01:22 +08005401static void alc288_update_headset_jack_cb(struct hda_codec *codec,
5402 struct hda_jack_callback *jack)
5403{
5404 struct alc_spec *spec = codec->spec;
Kailang Yange1e62b92015-04-08 16:01:22 +08005405
5406 alc_update_headset_jack_cb(codec, jack);
5407 /* Headset Mic enable or disable, only for Dell Dino */
Takashi Iwaid44a6862018-06-19 23:04:03 +02005408 alc_update_gpio_data(codec, 0x40, spec->gen.hp_jack_present);
Kailang Yange1e62b92015-04-08 16:01:22 +08005409}
5410
5411static void alc_fixup_headset_mode_dell_alc288(struct hda_codec *codec,
5412 const struct hda_fixup *fix, int action)
5413{
5414 alc_fixup_headset_mode(codec, fix, action);
5415 if (action == HDA_FIXUP_ACT_PROBE) {
5416 struct alc_spec *spec = codec->spec;
Takashi Iwaid44a6862018-06-19 23:04:03 +02005417 /* toggled via hp_automute_hook */
5418 spec->gpio_mask |= 0x40;
5419 spec->gpio_dir |= 0x40;
Kailang Yange1e62b92015-04-08 16:01:22 +08005420 spec->gen.hp_automute_hook = alc288_update_headset_jack_cb;
5421 }
5422}
5423
Hui Wang493a52a2014-01-14 14:07:36 +08005424static void alc_fixup_auto_mute_via_amp(struct hda_codec *codec,
5425 const struct hda_fixup *fix, int action)
5426{
5427 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5428 struct alc_spec *spec = codec->spec;
5429 spec->gen.auto_mute_via_amp = 1;
5430 }
5431}
5432
Takashi Iwai9b745ab2014-03-07 08:37:19 +01005433static void alc_fixup_no_shutup(struct hda_codec *codec,
5434 const struct hda_fixup *fix, int action)
5435{
Takashi Iwaiefe55732018-06-15 11:55:02 +02005436 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai9b745ab2014-03-07 08:37:19 +01005437 struct alc_spec *spec = codec->spec;
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01005438 spec->no_shutup_pins = 1;
Takashi Iwai9b745ab2014-03-07 08:37:19 +01005439 }
5440}
5441
Gabriele Mazzotta5e6db662014-05-20 18:58:26 +02005442static void alc_fixup_disable_aamix(struct hda_codec *codec,
5443 const struct hda_fixup *fix, int action)
5444{
5445 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5446 struct alc_spec *spec = codec->spec;
5447 /* Disable AA-loopback as it causes white noise */
5448 spec->gen.mixer_nid = 0;
5449 }
5450}
5451
Takashi Iwai7f57d802015-09-24 17:36:51 +02005452/* fixup for Thinkpad docks: add dock pins, avoid HP parser fixup */
5453static void alc_fixup_tpt440_dock(struct hda_codec *codec,
5454 const struct hda_fixup *fix, int action)
5455{
5456 static const struct hda_pintbl pincfgs[] = {
5457 { 0x16, 0x21211010 }, /* dock headphone */
5458 { 0x19, 0x21a11010 }, /* dock mic */
5459 { }
5460 };
5461 struct alc_spec *spec = codec->spec;
5462
5463 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Hui Wang871b9062019-08-14 12:09:08 +08005464 spec->reboot_notify = snd_hda_gen_reboot_notify; /* reduce noise */
Takashi Iwai7f57d802015-09-24 17:36:51 +02005465 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
5466 codec->power_save_node = 0; /* avoid click noises */
5467 snd_hda_apply_pincfgs(codec, pincfgs);
5468 }
5469}
5470
Kailang Yang61fcf8e2018-02-02 15:26:46 +08005471static void alc_fixup_tpt470_dock(struct hda_codec *codec,
5472 const struct hda_fixup *fix, int action)
5473{
5474 static const struct hda_pintbl pincfgs[] = {
5475 { 0x17, 0x21211010 }, /* dock headphone */
5476 { 0x19, 0x21a11010 }, /* dock mic */
5477 { }
5478 };
Takashi Iwai54947cd2018-12-03 10:44:15 +01005479 /* Assure the speaker pin to be coupled with DAC NID 0x03; otherwise
5480 * the speaker output becomes too low by some reason on Thinkpads with
5481 * ALC298 codec
5482 */
Michał Mirosławcaf3c042020-01-03 10:23:48 +01005483 static const hda_nid_t preferred_pairs[] = {
Takashi Iwai54947cd2018-12-03 10:44:15 +01005484 0x14, 0x03, 0x17, 0x02, 0x21, 0x02,
5485 0
5486 };
Kailang Yang61fcf8e2018-02-02 15:26:46 +08005487 struct alc_spec *spec = codec->spec;
5488
5489 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai54947cd2018-12-03 10:44:15 +01005490 spec->gen.preferred_dacs = preferred_pairs;
Kailang Yang61fcf8e2018-02-02 15:26:46 +08005491 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
Takashi Iwai71db96d2018-02-26 15:36:38 +01005492 snd_hda_apply_pincfgs(codec, pincfgs);
5493 } else if (action == HDA_FIXUP_ACT_INIT) {
Kailang Yang61fcf8e2018-02-02 15:26:46 +08005494 /* Enable DOCK device */
5495 snd_hda_codec_write(codec, 0x17, 0,
5496 AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0);
5497 /* Enable DOCK device */
5498 snd_hda_codec_write(codec, 0x19, 0,
5499 AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0);
Kailang Yang61fcf8e2018-02-02 15:26:46 +08005500 }
5501}
5502
Gabriele Mazzotta9476d3692015-04-19 19:00:40 +02005503static void alc_shutup_dell_xps13(struct hda_codec *codec)
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02005504{
5505 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01005506 int hp_pin = alc_get_hp_pin(spec);
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02005507
Gabriele Mazzotta9476d3692015-04-19 19:00:40 +02005508 /* Prevent pop noises when headphones are plugged in */
5509 snd_hda_codec_write(codec, hp_pin, 0,
5510 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
5511 msleep(20);
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02005512}
5513
5514static void alc_fixup_dell_xps13(struct hda_codec *codec,
5515 const struct hda_fixup *fix, int action)
5516{
Takashi Iwai3e1b0c42015-04-27 10:43:22 +02005517 struct alc_spec *spec = codec->spec;
5518 struct hda_input_mux *imux = &spec->gen.input_mux;
5519 int i;
Gabriele Mazzottaf38663a2014-08-08 19:34:40 +02005520
Takashi Iwai3e1b0c42015-04-27 10:43:22 +02005521 switch (action) {
5522 case HDA_FIXUP_ACT_PRE_PROBE:
5523 /* mic pin 0x19 must be initialized with Vref Hi-Z, otherwise
5524 * it causes a click noise at start up
5525 */
5526 snd_hda_codec_set_pin_target(codec, 0x19, PIN_VREFHIZ);
Takashi Iwaiefe55732018-06-15 11:55:02 +02005527 spec->shutup = alc_shutup_dell_xps13;
Takashi Iwai3e1b0c42015-04-27 10:43:22 +02005528 break;
5529 case HDA_FIXUP_ACT_PROBE:
Gabriele Mazzottaf38663a2014-08-08 19:34:40 +02005530 /* Make the internal mic the default input source. */
5531 for (i = 0; i < imux->num_items; i++) {
5532 if (spec->gen.imux_pins[i] == 0x12) {
5533 spec->gen.cur_mux[0] = i;
5534 break;
5535 }
5536 }
Takashi Iwai3e1b0c42015-04-27 10:43:22 +02005537 break;
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02005538 }
5539}
5540
David Henningsson1f8b46c2015-05-12 14:38:15 +02005541static void alc_fixup_headset_mode_alc662(struct hda_codec *codec,
5542 const struct hda_fixup *fix, int action)
5543{
5544 struct alc_spec *spec = codec->spec;
5545
5546 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5547 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
5548 spec->gen.hp_mic = 1; /* Mic-in is same pin as headphone */
David Henningssonb40eda62015-05-28 09:40:23 +02005549
5550 /* Disable boost for mic-in permanently. (This code is only called
5551 from quirks that guarantee that the headphone is at NID 0x1b.) */
5552 snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000);
5553 snd_hda_override_wcaps(codec, 0x1b, get_wcaps(codec, 0x1b) & ~AC_WCAP_IN_AMP);
David Henningsson1f8b46c2015-05-12 14:38:15 +02005554 } else
5555 alc_fixup_headset_mode(codec, fix, action);
5556}
5557
David Henningsson73bdd592013-04-15 15:44:14 +02005558static void alc_fixup_headset_mode_alc668(struct hda_codec *codec,
5559 const struct hda_fixup *fix, int action)
5560{
5561 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
David Henningsson73bdd592013-04-15 15:44:14 +02005562 alc_write_coef_idx(codec, 0xc4, 0x8000);
Takashi Iwai98b24882014-08-18 13:47:50 +02005563 alc_update_coef_idx(codec, 0xc2, ~0xfe, 0);
David Henningsson73bdd592013-04-15 15:44:14 +02005564 snd_hda_set_pin_ctl_cache(codec, 0x18, 0);
5565 }
5566 alc_fixup_headset_mode(codec, fix, action);
5567}
5568
Chih-Chung Changbde7bc62013-08-05 16:38:42 +08005569/* Returns the nid of the external mic input pin, or 0 if it cannot be found. */
5570static int find_ext_mic_pin(struct hda_codec *codec)
5571{
5572 struct alc_spec *spec = codec->spec;
5573 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
5574 hda_nid_t nid;
5575 unsigned int defcfg;
5576 int i;
5577
5578 for (i = 0; i < cfg->num_inputs; i++) {
5579 if (cfg->inputs[i].type != AUTO_PIN_MIC)
5580 continue;
5581 nid = cfg->inputs[i].pin;
5582 defcfg = snd_hda_codec_get_pincfg(codec, nid);
5583 if (snd_hda_get_input_pin_attr(defcfg) == INPUT_PIN_ATTR_INT)
5584 continue;
5585 return nid;
5586 }
5587
5588 return 0;
5589}
5590
Dylan Reid08a978d2012-11-18 22:56:40 -08005591static void alc271_hp_gate_mic_jack(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01005592 const struct hda_fixup *fix,
Dylan Reid08a978d2012-11-18 22:56:40 -08005593 int action)
5594{
5595 struct alc_spec *spec = codec->spec;
5596
Takashi Iwai0db75792013-01-23 13:57:20 +01005597 if (action == HDA_FIXUP_ACT_PROBE) {
Chih-Chung Changbde7bc62013-08-05 16:38:42 +08005598 int mic_pin = find_ext_mic_pin(codec);
Takashi Iwai35a39f92019-02-01 11:19:50 +01005599 int hp_pin = alc_get_hp_pin(spec);
Chih-Chung Changbde7bc62013-08-05 16:38:42 +08005600
5601 if (snd_BUG_ON(!mic_pin || !hp_pin))
Takashi Iwai0db75792013-01-23 13:57:20 +01005602 return;
Chih-Chung Changbde7bc62013-08-05 16:38:42 +08005603 snd_hda_jack_set_gating_jack(codec, mic_pin, hp_pin);
Takashi Iwai0db75792013-01-23 13:57:20 +01005604 }
Dylan Reid08a978d2012-11-18 22:56:40 -08005605}
David Henningsson693b6132012-06-22 19:12:10 +02005606
David Henningsson3e0d6112013-04-22 14:30:14 +02005607static void alc269_fixup_limit_int_mic_boost(struct hda_codec *codec,
5608 const struct hda_fixup *fix,
5609 int action)
5610{
5611 struct alc_spec *spec = codec->spec;
5612 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
5613 int i;
5614
5615 /* The mic boosts on level 2 and 3 are too noisy
5616 on the internal mic input.
5617 Therefore limit the boost to 0 or 1. */
5618
5619 if (action != HDA_FIXUP_ACT_PROBE)
5620 return;
5621
5622 for (i = 0; i < cfg->num_inputs; i++) {
5623 hda_nid_t nid = cfg->inputs[i].pin;
5624 unsigned int defcfg;
5625 if (cfg->inputs[i].type != AUTO_PIN_MIC)
5626 continue;
5627 defcfg = snd_hda_codec_get_pincfg(codec, nid);
5628 if (snd_hda_get_input_pin_attr(defcfg) != INPUT_PIN_ATTR_INT)
5629 continue;
5630
5631 snd_hda_override_amp_caps(codec, nid, HDA_INPUT,
5632 (0x00 << AC_AMPCAP_OFFSET_SHIFT) |
5633 (0x01 << AC_AMPCAP_NUM_STEPS_SHIFT) |
5634 (0x2f << AC_AMPCAP_STEP_SIZE_SHIFT) |
5635 (0 << AC_AMPCAP_MUTE_SHIFT));
5636 }
5637}
5638
Kailang Yangcd217a62013-08-22 10:15:24 +02005639static void alc283_hp_automute_hook(struct hda_codec *codec,
Takashi Iwai1a4f69d2014-09-11 15:22:46 +02005640 struct hda_jack_callback *jack)
Kailang Yangcd217a62013-08-22 10:15:24 +02005641{
5642 struct alc_spec *spec = codec->spec;
5643 int vref;
5644
5645 msleep(200);
5646 snd_hda_gen_hp_automute(codec, jack);
5647
5648 vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0;
5649
5650 msleep(600);
5651 snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5652 vref);
5653}
5654
Kailang Yangcd217a62013-08-22 10:15:24 +02005655static void alc283_fixup_chromebook(struct hda_codec *codec,
5656 const struct hda_fixup *fix, int action)
5657{
5658 struct alc_spec *spec = codec->spec;
Kailang Yangcd217a62013-08-22 10:15:24 +02005659
5660 switch (action) {
5661 case HDA_FIXUP_ACT_PRE_PROBE:
Kailang Yang0202e992013-12-02 15:20:15 +08005662 snd_hda_override_wcaps(codec, 0x03, 0);
Takashi Iwaid2e92702013-10-30 07:50:53 +01005663 /* Disable AA-loopback as it causes white noise */
5664 spec->gen.mixer_nid = 0;
Kailang Yang38070212013-11-01 15:57:35 +08005665 break;
5666 case HDA_FIXUP_ACT_INIT:
Kailang Yangde9481c2014-04-07 16:41:52 +08005667 /* MIC2-VREF control */
5668 /* Set to manual mode */
Takashi Iwai98b24882014-08-18 13:47:50 +02005669 alc_update_coef_idx(codec, 0x06, 0x000c, 0);
Kailang Yang0202e992013-12-02 15:20:15 +08005670 /* Enable Line1 input control by verb */
Takashi Iwai98b24882014-08-18 13:47:50 +02005671 alc_update_coef_idx(codec, 0x1a, 0, 1 << 4);
Kailang Yang0202e992013-12-02 15:20:15 +08005672 break;
5673 }
5674}
5675
5676static void alc283_fixup_sense_combo_jack(struct hda_codec *codec,
5677 const struct hda_fixup *fix, int action)
5678{
5679 struct alc_spec *spec = codec->spec;
Kailang Yang0202e992013-12-02 15:20:15 +08005680
5681 switch (action) {
5682 case HDA_FIXUP_ACT_PRE_PROBE:
Kailang Yangcd217a62013-08-22 10:15:24 +02005683 spec->gen.hp_automute_hook = alc283_hp_automute_hook;
5684 break;
5685 case HDA_FIXUP_ACT_INIT:
5686 /* MIC2-VREF control */
5687 /* Set to manual mode */
Takashi Iwai98b24882014-08-18 13:47:50 +02005688 alc_update_coef_idx(codec, 0x06, 0x000c, 0);
Kailang Yangcd217a62013-08-22 10:15:24 +02005689 break;
5690 }
5691}
5692
Takashi Iwai7bba2152013-09-06 15:45:38 +02005693/* mute tablet speaker pin (0x14) via dock plugging in addition */
5694static void asus_tx300_automute(struct hda_codec *codec)
5695{
5696 struct alc_spec *spec = codec->spec;
5697 snd_hda_gen_update_outputs(codec);
5698 if (snd_hda_jack_detect(codec, 0x1b))
5699 spec->gen.mute_bits |= (1ULL << 0x14);
5700}
5701
5702static void alc282_fixup_asus_tx300(struct hda_codec *codec,
5703 const struct hda_fixup *fix, int action)
5704{
5705 struct alc_spec *spec = codec->spec;
Takashi Iwai7bba2152013-09-06 15:45:38 +02005706 static const struct hda_pintbl dock_pins[] = {
5707 { 0x1b, 0x21114000 }, /* dock speaker pin */
5708 {}
5709 };
Takashi Iwai7bba2152013-09-06 15:45:38 +02005710
5711 switch (action) {
5712 case HDA_FIXUP_ACT_PRE_PROBE:
Takashi Iwai1c76aa52018-06-21 16:37:54 +02005713 spec->init_amp = ALC_INIT_DEFAULT;
Takashi Iwaiae065f12018-06-19 23:00:03 +02005714 /* TX300 needs to set up GPIO2 for the speaker amp */
5715 alc_setup_gpio(codec, 0x04);
Takashi Iwai7bba2152013-09-06 15:45:38 +02005716 snd_hda_apply_pincfgs(codec, dock_pins);
5717 spec->gen.auto_mute_via_amp = 1;
5718 spec->gen.automute_hook = asus_tx300_automute;
5719 snd_hda_jack_detect_enable_callback(codec, 0x1b,
Takashi Iwai7bba2152013-09-06 15:45:38 +02005720 snd_hda_gen_hp_automute);
5721 break;
Takashi Iwai5579cd62018-06-19 22:22:41 +02005722 case HDA_FIXUP_ACT_PROBE:
5723 spec->init_amp = ALC_INIT_DEFAULT;
5724 break;
Takashi Iwai7bba2152013-09-06 15:45:38 +02005725 case HDA_FIXUP_ACT_BUILD:
5726 /* this is a bit tricky; give more sane names for the main
5727 * (tablet) speaker and the dock speaker, respectively
5728 */
Takashi Iwai56798e62017-04-11 08:10:52 +02005729 rename_ctl(codec, "Speaker Playback Switch",
5730 "Dock Speaker Playback Switch");
5731 rename_ctl(codec, "Bass Speaker Playback Switch",
5732 "Speaker Playback Switch");
Takashi Iwai7bba2152013-09-06 15:45:38 +02005733 break;
5734 }
5735}
5736
David Henningsson338cae52013-10-07 10:39:59 +02005737static void alc290_fixup_mono_speakers(struct hda_codec *codec,
5738 const struct hda_fixup *fix, int action)
5739{
David Henningsson0f4881d2013-12-20 16:08:13 +01005740 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5741 /* DAC node 0x03 is giving mono output. We therefore want to
5742 make sure 0x14 (front speaker) and 0x15 (headphones) use the
5743 stereo DAC, while leaving 0x17 (bass speaker) for node 0x03. */
Michał Mirosławcaf3c042020-01-03 10:23:48 +01005744 static const hda_nid_t conn1[] = { 0x0c };
5745 snd_hda_override_conn_list(codec, 0x14, ARRAY_SIZE(conn1), conn1);
5746 snd_hda_override_conn_list(codec, 0x15, ARRAY_SIZE(conn1), conn1);
David Henningsson0f4881d2013-12-20 16:08:13 +01005747 }
David Henningsson338cae52013-10-07 10:39:59 +02005748}
5749
Hui Wangdd9aa332016-08-01 10:20:32 +08005750static void alc298_fixup_speaker_volume(struct hda_codec *codec,
5751 const struct hda_fixup *fix, int action)
5752{
5753 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5754 /* The speaker is routed to the Node 0x06 by a mistake, as a result
5755 we can't adjust the speaker's volume since this node does not has
5756 Amp-out capability. we change the speaker's route to:
5757 Node 0x02 (Audio Output) -> Node 0x0c (Audio Mixer) -> Node 0x17 (
5758 Pin Complex), since Node 0x02 has Amp-out caps, we can adjust
5759 speaker's volume now. */
5760
Michał Mirosławcaf3c042020-01-03 10:23:48 +01005761 static const hda_nid_t conn1[] = { 0x0c };
5762 snd_hda_override_conn_list(codec, 0x17, ARRAY_SIZE(conn1), conn1);
Hui Wangdd9aa332016-08-01 10:20:32 +08005763 }
5764}
5765
Takashi Iwaie312a862018-03-06 12:14:17 +01005766/* disable DAC3 (0x06) selection on NID 0x17 as it has no volume amp control */
5767static void alc295_fixup_disable_dac3(struct hda_codec *codec,
5768 const struct hda_fixup *fix, int action)
5769{
5770 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Michał Mirosławcaf3c042020-01-03 10:23:48 +01005771 static const hda_nid_t conn[] = { 0x02, 0x03 };
5772 snd_hda_override_conn_list(codec, 0x17, ARRAY_SIZE(conn), conn);
Takashi Iwaie312a862018-03-06 12:14:17 +01005773 }
5774}
5775
Jaroslav Kyselad2cd7952019-11-29 15:40:27 +01005776/* force NID 0x17 (Bass Speaker) to DAC1 to share it with the main speaker */
5777static void alc285_fixup_speaker2_to_dac1(struct hda_codec *codec,
5778 const struct hda_fixup *fix, int action)
5779{
5780 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Michał Mirosławcaf3c042020-01-03 10:23:48 +01005781 static const hda_nid_t conn[] = { 0x02 };
5782 snd_hda_override_conn_list(codec, 0x17, ARRAY_SIZE(conn), conn);
Jaroslav Kyselad2cd7952019-11-29 15:40:27 +01005783 }
5784}
5785
Keith Packard98973f22015-07-15 12:14:39 -07005786/* Hook to update amp GPIO4 for automute */
5787static void alc280_hp_gpio4_automute_hook(struct hda_codec *codec,
5788 struct hda_jack_callback *jack)
5789{
5790 struct alc_spec *spec = codec->spec;
5791
5792 snd_hda_gen_hp_automute(codec, jack);
5793 /* mute_led_polarity is set to 0, so we pass inverted value here */
5794 alc_update_gpio_led(codec, 0x10, !spec->gen.hp_jack_present);
5795}
5796
5797/* Manage GPIOs for HP EliteBook Folio 9480m.
5798 *
5799 * GPIO4 is the headphone amplifier power control
5800 * GPIO3 is the audio output mute indicator LED
5801 */
5802
5803static void alc280_fixup_hp_9480m(struct hda_codec *codec,
5804 const struct hda_fixup *fix,
5805 int action)
5806{
5807 struct alc_spec *spec = codec->spec;
Keith Packard98973f22015-07-15 12:14:39 -07005808
Takashi Iwai01e4a272018-06-19 22:47:30 +02005809 alc_fixup_hp_gpio_led(codec, action, 0x08, 0);
Keith Packard98973f22015-07-15 12:14:39 -07005810 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai01e4a272018-06-19 22:47:30 +02005811 /* amp at GPIO4; toggled via alc280_hp_gpio4_automute_hook() */
5812 spec->gpio_mask |= 0x10;
5813 spec->gpio_dir |= 0x10;
Keith Packard98973f22015-07-15 12:14:39 -07005814 spec->gen.hp_automute_hook = alc280_hp_gpio4_automute_hook;
Keith Packard98973f22015-07-15 12:14:39 -07005815 }
5816}
5817
Takashi Iwaiae065f12018-06-19 23:00:03 +02005818static void alc275_fixup_gpio4_off(struct hda_codec *codec,
5819 const struct hda_fixup *fix,
5820 int action)
5821{
5822 struct alc_spec *spec = codec->spec;
5823
5824 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5825 spec->gpio_mask |= 0x04;
5826 spec->gpio_dir |= 0x04;
5827 /* set data bit low */
5828 }
5829}
5830
Kailang Yangca169cc2017-04-25 16:17:40 +08005831static void alc233_alc662_fixup_lenovo_dual_codecs(struct hda_codec *codec,
5832 const struct hda_fixup *fix,
5833 int action)
5834{
5835 alc_fixup_dual_codecs(codec, fix, action);
5836 switch (action) {
5837 case HDA_FIXUP_ACT_PRE_PROBE:
5838 /* override card longname to provide a unique UCM profile */
5839 strcpy(codec->card->longname, "HDAudio-Lenovo-DualCodecs");
5840 break;
5841 case HDA_FIXUP_ACT_BUILD:
5842 /* rename Capture controls depending on the codec */
5843 rename_ctl(codec, "Capture Volume",
5844 codec->addr == 0 ?
5845 "Rear-Panel Capture Volume" :
5846 "Front-Panel Capture Volume");
5847 rename_ctl(codec, "Capture Switch",
5848 codec->addr == 0 ?
5849 "Rear-Panel Capture Switch" :
5850 "Front-Panel Capture Switch");
5851 break;
5852 }
5853}
5854
Kailang Yang92266652017-12-14 15:28:58 +08005855/* Forcibly assign NID 0x03 to HP/LO while NID 0x02 to SPK for EQ */
5856static void alc274_fixup_bind_dacs(struct hda_codec *codec,
5857 const struct hda_fixup *fix, int action)
5858{
5859 struct alc_spec *spec = codec->spec;
Michał Mirosławcaf3c042020-01-03 10:23:48 +01005860 static const hda_nid_t preferred_pairs[] = {
Kailang Yang92266652017-12-14 15:28:58 +08005861 0x21, 0x03, 0x1b, 0x03, 0x16, 0x02,
5862 0
5863 };
5864
5865 if (action != HDA_FIXUP_ACT_PRE_PROBE)
5866 return;
5867
5868 spec->gen.preferred_dacs = preferred_pairs;
Kailang Yang0700d3d2019-04-26 16:13:54 +08005869 spec->gen.auto_mute_via_amp = 1;
5870 codec->power_save_node = 0;
Kailang Yang92266652017-12-14 15:28:58 +08005871}
5872
Hui Wangc4cfcf62018-11-26 14:17:16 +08005873/* The DAC of NID 0x3 will introduce click/pop noise on headphones, so invalidate it */
5874static void alc285_fixup_invalidate_dacs(struct hda_codec *codec,
5875 const struct hda_fixup *fix, int action)
5876{
5877 if (action != HDA_FIXUP_ACT_PRE_PROBE)
5878 return;
5879
5880 snd_hda_override_wcaps(codec, 0x03, 0);
5881}
5882
Kailang Yang8983eb62019-04-03 15:31:49 +08005883static void alc295_fixup_chromebook(struct hda_codec *codec,
5884 const struct hda_fixup *fix, int action)
5885{
Kailang Yangd3ba58b2019-05-06 15:09:42 +08005886 struct alc_spec *spec = codec->spec;
5887
Kailang Yang8983eb62019-04-03 15:31:49 +08005888 switch (action) {
Kailang Yangd3ba58b2019-05-06 15:09:42 +08005889 case HDA_FIXUP_ACT_PRE_PROBE:
5890 spec->ultra_low_power = true;
5891 break;
Kailang Yang8983eb62019-04-03 15:31:49 +08005892 case HDA_FIXUP_ACT_INIT:
5893 switch (codec->core.vendor_id) {
5894 case 0x10ec0295:
5895 alc_update_coef_idx(codec, 0x4a, 0x8000, 1 << 15); /* Reset HP JD */
5896 alc_update_coef_idx(codec, 0x4a, 0x8000, 0 << 15);
5897 break;
5898 case 0x10ec0236:
5899 alc_update_coef_idx(codec, 0x1b, 0x8000, 1 << 15); /* Reset HP JD */
5900 alc_update_coef_idx(codec, 0x1b, 0x8000, 0 << 15);
5901 break;
5902 }
5903 break;
5904 }
5905}
5906
Kailang Yangd1dd4212019-01-09 17:05:24 +08005907static void alc_fixup_disable_mic_vref(struct hda_codec *codec,
5908 const struct hda_fixup *fix, int action)
5909{
5910 if (action == HDA_FIXUP_ACT_PRE_PROBE)
5911 snd_hda_codec_set_pin_target(codec, 0x19, PIN_VREFHIZ);
5912}
5913
Takashi Iwaib317b032014-01-08 11:44:21 +01005914/* for hda_fixup_thinkpad_acpi() */
5915#include "thinkpad_helper.c"
David Henningssonb67ae3f2013-11-05 13:11:37 +01005916
Takashi Iwaid5a6cab2018-06-13 12:43:10 +02005917static void alc_fixup_thinkpad_acpi(struct hda_codec *codec,
5918 const struct hda_fixup *fix, int action)
5919{
5920 alc_fixup_no_shutup(codec, fix, action); /* reduce click noise */
5921 hda_fixup_thinkpad_acpi(codec, fix, action);
5922}
5923
Tom Bridenbbf8ff62018-05-29 17:34:20 +01005924/* for alc295_fixup_hp_top_speakers */
5925#include "hp_x360_helper.c"
5926
Takashi Iwai1d045db2011-07-07 18:23:21 +02005927enum {
5928 ALC269_FIXUP_SONY_VAIO,
5929 ALC275_FIXUP_SONY_VAIO_GPIO2,
5930 ALC269_FIXUP_DELL_M101Z,
5931 ALC269_FIXUP_SKU_IGNORE,
5932 ALC269_FIXUP_ASUS_G73JW,
5933 ALC269_FIXUP_LENOVO_EAPD,
5934 ALC275_FIXUP_SONY_HWEQ,
Takashi Iwaie9bd7d52014-05-21 11:06:49 +02005935 ALC275_FIXUP_SONY_DISABLE_AAMIX,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005936 ALC271_FIXUP_DMIC,
Takashi Iwai017f2a12011-07-09 14:42:25 +02005937 ALC269_FIXUP_PCM_44K,
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02005938 ALC269_FIXUP_STEREO_DMIC,
David Henningsson7c478f02013-10-11 10:18:46 +02005939 ALC269_FIXUP_HEADSET_MIC,
Takashi Iwai24519912011-08-16 15:08:49 +02005940 ALC269_FIXUP_QUANTA_MUTE,
5941 ALC269_FIXUP_LIFEBOOK,
David Henningsson2041d562014-06-13 11:15:44 +02005942 ALC269_FIXUP_LIFEBOOK_EXTMIC,
Takashi Iwaicc7016a2015-04-08 20:47:55 +02005943 ALC269_FIXUP_LIFEBOOK_HP_PIN,
Takashi Iwai4df3fd12015-06-29 08:38:02 +02005944 ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT,
Jan-Marek Glogowskifdcc9682018-02-14 11:29:15 +01005945 ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC,
Takashi Iwaia4297b52011-08-23 18:40:12 +02005946 ALC269_FIXUP_AMIC,
5947 ALC269_FIXUP_DMIC,
5948 ALC269VB_FIXUP_AMIC,
5949 ALC269VB_FIXUP_DMIC,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01005950 ALC269_FIXUP_HP_MUTE_LED,
David Henningssond06ac142013-02-18 11:41:55 +01005951 ALC269_FIXUP_HP_MUTE_LED_MIC1,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01005952 ALC269_FIXUP_HP_MUTE_LED_MIC2,
Tom Briden7f783bd2017-03-25 10:12:01 +00005953 ALC269_FIXUP_HP_MUTE_LED_MIC3,
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01005954 ALC269_FIXUP_HP_GPIO_LED,
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08005955 ALC269_FIXUP_HP_GPIO_MIC1_LED,
5956 ALC269_FIXUP_HP_LINE1_MIC1_LED,
David Henningsson693b6132012-06-22 19:12:10 +02005957 ALC269_FIXUP_INV_DMIC,
David Henningsson108cc102012-07-20 10:37:25 +02005958 ALC269_FIXUP_LENOVO_DOCK,
Takashi Iwai9b745ab2014-03-07 08:37:19 +01005959 ALC269_FIXUP_NO_SHUTUP,
David Henningsson88cfcf82013-10-11 10:18:45 +02005960 ALC286_FIXUP_SONY_MIC_NO_PRESENCE,
David Henningsson108cc102012-07-20 10:37:25 +02005961 ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT,
David Henningsson73bdd592013-04-15 15:44:14 +02005962 ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
5963 ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
David Henningsson338cae52013-10-07 10:39:59 +02005964 ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
Kailang Yangfcc6c872017-06-29 15:21:27 +08005965 ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
David Henningsson73bdd592013-04-15 15:44:14 +02005966 ALC269_FIXUP_HEADSET_MODE,
5967 ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC,
Takashi Iwai78197172015-06-27 10:21:13 +02005968 ALC269_FIXUP_ASPIRE_HEADSET_MIC,
David Henningssond240d1d2013-04-15 12:50:02 +02005969 ALC269_FIXUP_ASUS_X101_FUNC,
5970 ALC269_FIXUP_ASUS_X101_VERB,
5971 ALC269_FIXUP_ASUS_X101,
Dylan Reid08a978d2012-11-18 22:56:40 -08005972 ALC271_FIXUP_AMIC_MIC2,
5973 ALC271_FIXUP_HP_GATE_MIC_JACK,
Oleksij Rempelb1e89722013-12-04 20:50:53 +01005974 ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572,
Dylan Reid42397002013-04-05 14:58:22 -07005975 ALC269_FIXUP_ACER_AC700,
David Henningsson3e0d6112013-04-22 14:30:14 +02005976 ALC269_FIXUP_LIMIT_INT_MIC_BOOST,
Oleksij Rempel2cede302013-11-27 17:12:03 +01005977 ALC269VB_FIXUP_ASUS_ZENBOOK,
Takashi Iwai23870832013-11-29 14:13:12 +01005978 ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A,
David Henningsson8e35cd42013-11-06 11:20:01 +01005979 ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED,
Anisse Astier02b504d2013-06-03 11:53:10 +02005980 ALC269VB_FIXUP_ORDISSIMO_EVE2,
Kailang Yangcd217a62013-08-22 10:15:24 +02005981 ALC283_FIXUP_CHROME_BOOK,
Kailang Yang0202e992013-12-02 15:20:15 +08005982 ALC283_FIXUP_SENSE_COMBO_JACK,
Takashi Iwai7bba2152013-09-06 15:45:38 +02005983 ALC282_FIXUP_ASUS_TX300,
Kailang Yang1bb3e062013-09-27 13:10:25 +02005984 ALC283_FIXUP_INT_MIC,
David Henningsson338cae52013-10-07 10:39:59 +02005985 ALC290_FIXUP_MONO_SPEAKERS,
David Henningsson0f4881d2013-12-20 16:08:13 +01005986 ALC290_FIXUP_MONO_SPEAKERS_HSJACK,
5987 ALC290_FIXUP_SUBWOOFER,
5988 ALC290_FIXUP_SUBWOOFER_HSJACK,
David Henningssonb67ae3f2013-11-05 13:11:37 +01005989 ALC269_FIXUP_THINKPAD_ACPI,
David Henningsson56f27012016-01-11 09:33:14 +01005990 ALC269_FIXUP_DMIC_THINKPAD_ACPI,
Chris Chiu5824ce82017-02-28 14:17:11 -06005991 ALC255_FIXUP_ACER_MIC_NO_PRESENCE,
Chris Chiu615966a2017-02-28 14:17:12 -06005992 ALC255_FIXUP_ASUS_MIC_NO_PRESENCE,
Kailang Yang9a22a8f52013-11-08 15:54:49 +08005993 ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Kailang Yang31278992014-03-03 15:27:22 +08005994 ALC255_FIXUP_DELL2_MIC_NO_PRESENCE,
Kailang Yang9a22a8f52013-11-08 15:54:49 +08005995 ALC255_FIXUP_HEADSET_MODE,
Kailang Yang31278992014-03-03 15:27:22 +08005996 ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC,
Kailang Yanga22aa262014-04-23 17:34:28 +08005997 ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
Takashi Iwai1c37c222014-05-06 17:34:42 +02005998 ALC292_FIXUP_TPT440_DOCK,
Takashi Iwai9a811232015-12-09 15:17:43 +01005999 ALC292_FIXUP_TPT440,
Anisse Astierabaa22742016-08-24 09:14:13 +02006000 ALC283_FIXUP_HEADSET_MIC,
Takashi Iwaib3802782018-11-26 17:47:46 +01006001 ALC255_FIXUP_MIC_MUTE_LED,
Takashi Iwai1a22e772014-08-27 08:19:05 +02006002 ALC282_FIXUP_ASPIRE_V5_PINS,
David Henningsson7a5255f2014-10-30 08:26:01 +01006003 ALC280_FIXUP_HP_GPIO4,
Kailang Yangeaa8e5e2014-11-21 15:49:11 +08006004 ALC286_FIXUP_HP_GPIO_LED,
David Henningsson33f4acd2015-01-07 15:50:13 +01006005 ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY,
TienFu Chenb4b33f92015-01-20 15:06:21 +01006006 ALC280_FIXUP_HP_DOCK_PINS,
Jaroslav Kysela04d54662017-03-09 13:29:13 +01006007 ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED,
Keith Packard98973f22015-07-15 12:14:39 -07006008 ALC280_FIXUP_HP_9480M,
Kailang Yange1e62b92015-04-08 16:01:22 +08006009 ALC288_FIXUP_DELL_HEADSET_MODE,
6010 ALC288_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang831bfdf92015-06-26 12:35:17 +08006011 ALC288_FIXUP_DELL_XPS_13,
6012 ALC288_FIXUP_DISABLE_AAMIX,
Takashi Iwai5fab5822020-01-05 09:11:19 +01006013 ALC292_FIXUP_DELL_E7X_AAMIX,
Takashi Iwai8b99aba2015-06-15 11:59:32 +02006014 ALC292_FIXUP_DELL_E7X,
6015 ALC292_FIXUP_DISABLE_AAMIX,
David Henningssonc04017e2015-12-15 14:44:03 +01006016 ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK,
James McDonnell54324222019-09-16 14:53:38 +00006017 ALC298_FIXUP_ALIENWARE_MIC_NO_PRESENCE,
Kailang Yang977e6272015-05-18 15:31:20 +08006018 ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang2f726ae2017-03-31 10:31:40 +08006019 ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE,
Kailang Yang6ed11312015-10-26 15:37:39 +08006020 ALC275_FIXUP_DELL_XPS,
Hui Wang23adc192015-12-08 12:27:18 +08006021 ALC293_FIXUP_LENOVO_SPK_NOISE,
Kailang3694cb22015-12-28 11:35:24 +08006022 ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY,
Kai-Heng Feng3b43b712016-02-25 15:19:38 +08006023 ALC255_FIXUP_DELL_SPK_NOISE,
Kailang Yangd1dd4212019-01-09 17:05:24 +08006024 ALC225_FIXUP_DISABLE_MIC_VREF,
David Henningsson2ae95572016-02-25 09:37:05 +01006025 ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
Takashi Iwaie312a862018-03-06 12:14:17 +01006026 ALC295_FIXUP_DISABLE_DAC3,
Jaroslav Kyselad2cd7952019-11-29 15:40:27 +01006027 ALC285_FIXUP_SPEAKER2_TO_DAC1,
Takashi Iwaif8839822016-02-25 14:31:59 +01006028 ALC280_FIXUP_HP_HEADSET_MIC,
Hui Wange549d192016-04-01 11:00:15 +08006029 ALC221_FIXUP_HP_FRONT_MIC,
Sven Eckelmannc636b952016-04-11 16:55:26 +02006030 ALC292_FIXUP_TPT460,
Hui Wangdd9aa332016-08-01 10:20:32 +08006031 ALC298_FIXUP_SPK_VOLUME,
Kai-Heng Fengfd06c772016-08-30 15:36:34 +08006032 ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER,
Gabriele Mazzotta823ff162016-12-24 19:50:01 +01006033 ALC269_FIXUP_ATIV_BOOK_8,
Kailang Yang9eb5d0e2017-01-17 15:40:25 +08006034 ALC221_FIXUP_HP_MIC_NO_PRESENCE,
Chris Chiuc1732ed2017-02-28 14:17:13 -06006035 ALC256_FIXUP_ASUS_HEADSET_MODE,
6036 ALC256_FIXUP_ASUS_MIC,
Chris Chiueeed4cd2017-02-28 14:17:15 -06006037 ALC256_FIXUP_ASUS_AIO_GPIO2,
Chris Chiu216d7ae2017-02-28 14:17:14 -06006038 ALC233_FIXUP_ASUS_MIC_NO_PRESENCE,
6039 ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE,
Kailang Yangca169cc2017-04-25 16:17:40 +08006040 ALC233_FIXUP_LENOVO_MULTI_CODECS,
Jian-Hong Panea5c7eb2019-04-01 11:25:05 +08006041 ALC233_FIXUP_ACER_HEADSET_MIC,
Hui Wangf33f79f2017-07-07 12:08:29 +08006042 ALC294_FIXUP_LENOVO_MIC_LOCATION,
Kailang Yang5f364132017-07-25 16:28:16 +08006043 ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE,
PeiSen Houb84e8432017-09-01 15:11:56 +08006044 ALC700_FIXUP_INTEL_REFERENCE,
Kailang Yang92266652017-12-14 15:28:58 +08006045 ALC274_FIXUP_DELL_BIND_DACS,
6046 ALC274_FIXUP_DELL_AIO_LINEOUT_VERB,
Kailang Yang61fcf8e2018-02-02 15:26:46 +08006047 ALC298_FIXUP_TPT470_DOCK,
Kailang Yangae104a22018-02-05 16:07:20 +08006048 ALC255_FIXUP_DUMMY_LINEOUT_VERB,
Kailang Yangf0ba9d62018-03-16 11:46:08 +08006049 ALC255_FIXUP_DELL_HEADSET_MIC,
Ayman Bagabas0fbf21c2019-05-23 05:30:11 -04006050 ALC256_FIXUP_HUAWEI_MACH_WX9_PINS,
Tomas Espeletaa2ef03f2019-08-09 16:37:54 +02006051 ALC298_FIXUP_HUAWEI_MBX_STEREO,
Tom Bridenbbf8ff62018-05-29 17:34:20 +01006052 ALC295_FIXUP_HP_X360,
Kailang Yang8a328ac2018-08-21 16:54:41 +08006053 ALC221_FIXUP_HP_HEADSET_MIC,
Hui Wangc4cfcf62018-11-26 14:17:16 +08006054 ALC285_FIXUP_LENOVO_HEADPHONE_NOISE,
Girija Kumar Kasinadhunie8ed64b2018-11-26 13:40:46 -05006055 ALC295_FIXUP_HP_AUTO_MUTE,
Chris Chiu33aaebd2018-12-05 14:48:53 +08006056 ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE,
Chris Chiud8ae4582018-12-07 17:17:11 +08006057 ALC294_FIXUP_ASUS_MIC,
Jian-Hong Pan4e051102018-12-07 17:17:12 +08006058 ALC294_FIXUP_ASUS_HEADSET_MIC,
6059 ALC294_FIXUP_ASUS_SPK,
Jeremy Soller89e3a562019-01-30 16:12:31 -07006060 ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE,
Hui Wangc8c6ee62019-02-14 11:41:33 +08006061 ALC285_FIXUP_LENOVO_PC_BEEP_IN_NOISE,
Jian-Hong Pancbc05fd2019-03-13 17:33:24 +08006062 ALC255_FIXUP_ACER_HEADSET_MIC,
Kailang Yang10f5b1b2019-02-21 16:10:22 +08006063 ALC295_FIXUP_CHROME_BOOK,
Kailang Yang8983eb62019-04-03 15:31:49 +08006064 ALC225_FIXUP_HEADSET_JACK,
Kailang Yang136824e2019-03-14 16:22:45 +08006065 ALC225_FIXUP_DELL_WYSE_AIO_MIC_NO_PRESENCE,
6066 ALC225_FIXUP_WYSE_AUTO_MUTE,
6067 ALC225_FIXUP_WYSE_DISABLE_MIC_VREF,
Jian-Hong Pan667a8f72019-03-15 17:51:09 +08006068 ALC286_FIXUP_ACER_AIO_HEADSET_MIC,
Daniel Drake8c8967a2019-10-17 16:15:01 +08006069 ALC256_FIXUP_ASUS_HEADSET_MIC,
Jian-Hong Pane1037352019-03-22 11:37:18 +08006070 ALC256_FIXUP_ASUS_MIC_NO_PRESENCE,
Bernhard Rosenkraenzere2a829b2019-03-05 00:38:19 +01006071 ALC299_FIXUP_PREDATOR_SPK,
Jan-Marek Glogowskibd9c10b2019-09-15 16:57:28 +02006072 ALC256_FIXUP_MEDION_HEADSET_NO_PRESENCE,
Kailang Yange79c2262019-12-19 14:12:15 +08006073 ALC289_FIXUP_DELL_SPK2,
6074 ALC289_FIXUP_DUAL_SPK,
Chris Chiu48e01502019-12-30 11:11:18 +08006075 ALC294_FIXUP_SPK2_TO_DAC1,
6076 ALC294_FIXUP_ASUS_DUAL_SPK,
Kailang Yang76f7dec2020-02-10 16:30:26 +08006077 ALC285_FIXUP_THINKPAD_HEADSET_JACK,
Jian-Hong Pan8b33a132020-02-25 15:29:21 +08006078 ALC294_FIXUP_ASUS_HPE,
Kai-Heng Fengf5a88b02020-03-27 12:46:25 +08006079 ALC285_FIXUP_HP_GPIO_LED,
Kailang Yang431e76c2020-04-07 14:40:20 +08006080 ALC285_FIXUP_HP_MUTE_LED,
Kailang Yang24164f42020-04-07 14:52:42 +08006081 ALC236_FIXUP_HP_MUTE_LED,
Takashi Iwai1d045db2011-07-07 18:23:21 +02006082};
6083
Takashi Iwai1727a772013-01-10 09:52:52 +01006084static const struct hda_fixup alc269_fixups[] = {
Takashi Iwai1d045db2011-07-07 18:23:21 +02006085 [ALC269_FIXUP_SONY_VAIO] = {
Takashi Iwaifd108212013-01-10 10:18:14 +01006086 .type = HDA_FIXUP_PINCTLS,
6087 .v.pins = (const struct hda_pintbl[]) {
6088 {0x19, PIN_VREFGRD},
Takashi Iwai1d045db2011-07-07 18:23:21 +02006089 {}
6090 }
6091 },
6092 [ALC275_FIXUP_SONY_VAIO_GPIO2] = {
Takashi Iwaiae065f12018-06-19 23:00:03 +02006093 .type = HDA_FIXUP_FUNC,
6094 .v.func = alc275_fixup_gpio4_off,
Takashi Iwai1d045db2011-07-07 18:23:21 +02006095 .chained = true,
6096 .chain_id = ALC269_FIXUP_SONY_VAIO
6097 },
6098 [ALC269_FIXUP_DELL_M101Z] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006099 .type = HDA_FIXUP_VERBS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02006100 .v.verbs = (const struct hda_verb[]) {
6101 /* Enables internal speaker */
6102 {0x20, AC_VERB_SET_COEF_INDEX, 13},
6103 {0x20, AC_VERB_SET_PROC_COEF, 0x4040},
6104 {}
6105 }
6106 },
6107 [ALC269_FIXUP_SKU_IGNORE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006108 .type = HDA_FIXUP_FUNC,
Takashi Iwai23d30f22012-05-07 17:17:32 +02006109 .v.func = alc_fixup_sku_ignore,
Takashi Iwai1d045db2011-07-07 18:23:21 +02006110 },
6111 [ALC269_FIXUP_ASUS_G73JW] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006112 .type = HDA_FIXUP_PINS,
6113 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02006114 { 0x17, 0x99130111 }, /* subwoofer */
6115 { }
6116 }
6117 },
6118 [ALC269_FIXUP_LENOVO_EAPD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006119 .type = HDA_FIXUP_VERBS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02006120 .v.verbs = (const struct hda_verb[]) {
6121 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
6122 {}
6123 }
6124 },
6125 [ALC275_FIXUP_SONY_HWEQ] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006126 .type = HDA_FIXUP_FUNC,
Takashi Iwai1d045db2011-07-07 18:23:21 +02006127 .v.func = alc269_fixup_hweq,
6128 .chained = true,
6129 .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2
6130 },
Takashi Iwaie9bd7d52014-05-21 11:06:49 +02006131 [ALC275_FIXUP_SONY_DISABLE_AAMIX] = {
6132 .type = HDA_FIXUP_FUNC,
6133 .v.func = alc_fixup_disable_aamix,
6134 .chained = true,
6135 .chain_id = ALC269_FIXUP_SONY_VAIO
6136 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02006137 [ALC271_FIXUP_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006138 .type = HDA_FIXUP_FUNC,
Takashi Iwai1d045db2011-07-07 18:23:21 +02006139 .v.func = alc271_fixup_dmic,
6140 },
Takashi Iwai017f2a12011-07-09 14:42:25 +02006141 [ALC269_FIXUP_PCM_44K] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006142 .type = HDA_FIXUP_FUNC,
Takashi Iwai017f2a12011-07-09 14:42:25 +02006143 .v.func = alc269_fixup_pcm_44k,
David Henningsson012e7eb2012-08-08 08:43:37 +02006144 .chained = true,
6145 .chain_id = ALC269_FIXUP_QUANTA_MUTE
Takashi Iwai017f2a12011-07-09 14:42:25 +02006146 },
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02006147 [ALC269_FIXUP_STEREO_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006148 .type = HDA_FIXUP_FUNC,
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02006149 .v.func = alc269_fixup_stereo_dmic,
6150 },
David Henningsson7c478f02013-10-11 10:18:46 +02006151 [ALC269_FIXUP_HEADSET_MIC] = {
6152 .type = HDA_FIXUP_FUNC,
6153 .v.func = alc269_fixup_headset_mic,
6154 },
Takashi Iwai24519912011-08-16 15:08:49 +02006155 [ALC269_FIXUP_QUANTA_MUTE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006156 .type = HDA_FIXUP_FUNC,
Takashi Iwai24519912011-08-16 15:08:49 +02006157 .v.func = alc269_fixup_quanta_mute,
6158 },
6159 [ALC269_FIXUP_LIFEBOOK] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006160 .type = HDA_FIXUP_PINS,
6161 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai24519912011-08-16 15:08:49 +02006162 { 0x1a, 0x2101103f }, /* dock line-out */
6163 { 0x1b, 0x23a11040 }, /* dock mic-in */
6164 { }
6165 },
6166 .chained = true,
6167 .chain_id = ALC269_FIXUP_QUANTA_MUTE
6168 },
David Henningsson2041d562014-06-13 11:15:44 +02006169 [ALC269_FIXUP_LIFEBOOK_EXTMIC] = {
6170 .type = HDA_FIXUP_PINS,
6171 .v.pins = (const struct hda_pintbl[]) {
6172 { 0x19, 0x01a1903c }, /* headset mic, with jack detect */
6173 { }
6174 },
6175 },
Takashi Iwaicc7016a2015-04-08 20:47:55 +02006176 [ALC269_FIXUP_LIFEBOOK_HP_PIN] = {
6177 .type = HDA_FIXUP_PINS,
6178 .v.pins = (const struct hda_pintbl[]) {
6179 { 0x21, 0x0221102f }, /* HP out */
6180 { }
6181 },
6182 },
Takashi Iwai4df3fd12015-06-29 08:38:02 +02006183 [ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT] = {
6184 .type = HDA_FIXUP_FUNC,
6185 .v.func = alc269_fixup_pincfg_no_hp_to_lineout,
6186 },
Jan-Marek Glogowskifdcc9682018-02-14 11:29:15 +01006187 [ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC] = {
6188 .type = HDA_FIXUP_FUNC,
6189 .v.func = alc269_fixup_pincfg_U7x7_headset_mic,
6190 },
Takashi Iwaia4297b52011-08-23 18:40:12 +02006191 [ALC269_FIXUP_AMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006192 .type = HDA_FIXUP_PINS,
6193 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaia4297b52011-08-23 18:40:12 +02006194 { 0x14, 0x99130110 }, /* speaker */
6195 { 0x15, 0x0121401f }, /* HP out */
6196 { 0x18, 0x01a19c20 }, /* mic */
6197 { 0x19, 0x99a3092f }, /* int-mic */
6198 { }
6199 },
6200 },
6201 [ALC269_FIXUP_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006202 .type = HDA_FIXUP_PINS,
6203 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaia4297b52011-08-23 18:40:12 +02006204 { 0x12, 0x99a3092f }, /* int-mic */
6205 { 0x14, 0x99130110 }, /* speaker */
6206 { 0x15, 0x0121401f }, /* HP out */
6207 { 0x18, 0x01a19c20 }, /* mic */
6208 { }
6209 },
6210 },
6211 [ALC269VB_FIXUP_AMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006212 .type = HDA_FIXUP_PINS,
6213 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaia4297b52011-08-23 18:40:12 +02006214 { 0x14, 0x99130110 }, /* speaker */
6215 { 0x18, 0x01a19c20 }, /* mic */
6216 { 0x19, 0x99a3092f }, /* int-mic */
6217 { 0x21, 0x0121401f }, /* HP out */
6218 { }
6219 },
6220 },
David Henningsson2267ea92012-01-03 08:45:56 +01006221 [ALC269VB_FIXUP_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006222 .type = HDA_FIXUP_PINS,
6223 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaia4297b52011-08-23 18:40:12 +02006224 { 0x12, 0x99a3092f }, /* int-mic */
6225 { 0x14, 0x99130110 }, /* speaker */
6226 { 0x18, 0x01a19c20 }, /* mic */
6227 { 0x21, 0x0121401f }, /* HP out */
6228 { }
6229 },
6230 },
Takashi Iwai08fb0d02013-01-10 17:33:58 +01006231 [ALC269_FIXUP_HP_MUTE_LED] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006232 .type = HDA_FIXUP_FUNC,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01006233 .v.func = alc269_fixup_hp_mute_led,
David Henningsson6d3cd5d2013-01-07 12:03:47 +01006234 },
David Henningssond06ac142013-02-18 11:41:55 +01006235 [ALC269_FIXUP_HP_MUTE_LED_MIC1] = {
6236 .type = HDA_FIXUP_FUNC,
6237 .v.func = alc269_fixup_hp_mute_led_mic1,
6238 },
Takashi Iwai08fb0d02013-01-10 17:33:58 +01006239 [ALC269_FIXUP_HP_MUTE_LED_MIC2] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006240 .type = HDA_FIXUP_FUNC,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01006241 .v.func = alc269_fixup_hp_mute_led_mic2,
Takashi Iwai420b0fe2012-03-12 12:35:27 +01006242 },
Tom Briden7f783bd2017-03-25 10:12:01 +00006243 [ALC269_FIXUP_HP_MUTE_LED_MIC3] = {
6244 .type = HDA_FIXUP_FUNC,
6245 .v.func = alc269_fixup_hp_mute_led_mic3,
Girija Kumar Kasinadhunie8ed64b2018-11-26 13:40:46 -05006246 .chained = true,
6247 .chain_id = ALC295_FIXUP_HP_AUTO_MUTE
Tom Briden7f783bd2017-03-25 10:12:01 +00006248 },
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01006249 [ALC269_FIXUP_HP_GPIO_LED] = {
6250 .type = HDA_FIXUP_FUNC,
6251 .v.func = alc269_fixup_hp_gpio_led,
6252 },
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08006253 [ALC269_FIXUP_HP_GPIO_MIC1_LED] = {
6254 .type = HDA_FIXUP_FUNC,
6255 .v.func = alc269_fixup_hp_gpio_mic1_led,
6256 },
6257 [ALC269_FIXUP_HP_LINE1_MIC1_LED] = {
6258 .type = HDA_FIXUP_FUNC,
6259 .v.func = alc269_fixup_hp_line1_mic1_led,
6260 },
David Henningsson693b6132012-06-22 19:12:10 +02006261 [ALC269_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006262 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02006263 .v.func = alc_fixup_inv_dmic,
David Henningsson693b6132012-06-22 19:12:10 +02006264 },
Takashi Iwai9b745ab2014-03-07 08:37:19 +01006265 [ALC269_FIXUP_NO_SHUTUP] = {
6266 .type = HDA_FIXUP_FUNC,
6267 .v.func = alc_fixup_no_shutup,
6268 },
David Henningsson108cc102012-07-20 10:37:25 +02006269 [ALC269_FIXUP_LENOVO_DOCK] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006270 .type = HDA_FIXUP_PINS,
6271 .v.pins = (const struct hda_pintbl[]) {
David Henningsson108cc102012-07-20 10:37:25 +02006272 { 0x19, 0x23a11040 }, /* dock mic */
6273 { 0x1b, 0x2121103f }, /* dock headphone */
6274 { }
6275 },
6276 .chained = true,
6277 .chain_id = ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT
6278 },
6279 [ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006280 .type = HDA_FIXUP_FUNC,
David Henningsson108cc102012-07-20 10:37:25 +02006281 .v.func = alc269_fixup_pincfg_no_hp_to_lineout,
David Henningsson52129002013-11-19 10:25:53 +01006282 .chained = true,
6283 .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
David Henningsson108cc102012-07-20 10:37:25 +02006284 },
David Henningsson73bdd592013-04-15 15:44:14 +02006285 [ALC269_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6286 .type = HDA_FIXUP_PINS,
6287 .v.pins = (const struct hda_pintbl[]) {
6288 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6289 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6290 { }
6291 },
6292 .chained = true,
6293 .chain_id = ALC269_FIXUP_HEADSET_MODE
6294 },
6295 [ALC269_FIXUP_DELL2_MIC_NO_PRESENCE] = {
6296 .type = HDA_FIXUP_PINS,
6297 .v.pins = (const struct hda_pintbl[]) {
6298 { 0x16, 0x21014020 }, /* dock line out */
6299 { 0x19, 0x21a19030 }, /* dock mic */
6300 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6301 { }
6302 },
6303 .chained = true,
6304 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
6305 },
David Henningsson338cae52013-10-07 10:39:59 +02006306 [ALC269_FIXUP_DELL3_MIC_NO_PRESENCE] = {
6307 .type = HDA_FIXUP_PINS,
6308 .v.pins = (const struct hda_pintbl[]) {
6309 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6310 { }
6311 },
6312 .chained = true,
6313 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
6314 },
Kailang Yangfcc6c872017-06-29 15:21:27 +08006315 [ALC269_FIXUP_DELL4_MIC_NO_PRESENCE] = {
6316 .type = HDA_FIXUP_PINS,
6317 .v.pins = (const struct hda_pintbl[]) {
6318 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6319 { 0x1b, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6320 { }
6321 },
6322 .chained = true,
6323 .chain_id = ALC269_FIXUP_HEADSET_MODE
6324 },
David Henningsson73bdd592013-04-15 15:44:14 +02006325 [ALC269_FIXUP_HEADSET_MODE] = {
6326 .type = HDA_FIXUP_FUNC,
6327 .v.func = alc_fixup_headset_mode,
Hui Wang6676f302014-11-18 17:57:41 +08006328 .chained = true,
Takashi Iwaib3802782018-11-26 17:47:46 +01006329 .chain_id = ALC255_FIXUP_MIC_MUTE_LED
David Henningsson73bdd592013-04-15 15:44:14 +02006330 },
6331 [ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC] = {
6332 .type = HDA_FIXUP_FUNC,
6333 .v.func = alc_fixup_headset_mode_no_hp_mic,
6334 },
Takashi Iwai78197172015-06-27 10:21:13 +02006335 [ALC269_FIXUP_ASPIRE_HEADSET_MIC] = {
6336 .type = HDA_FIXUP_PINS,
6337 .v.pins = (const struct hda_pintbl[]) {
6338 { 0x19, 0x01a1913c }, /* headset mic w/o jack detect */
6339 { }
6340 },
6341 .chained = true,
6342 .chain_id = ALC269_FIXUP_HEADSET_MODE,
6343 },
David Henningsson88cfcf82013-10-11 10:18:45 +02006344 [ALC286_FIXUP_SONY_MIC_NO_PRESENCE] = {
6345 .type = HDA_FIXUP_PINS,
6346 .v.pins = (const struct hda_pintbl[]) {
6347 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6348 { }
6349 },
David Henningssonfbc78ad2013-10-11 13:46:04 +02006350 .chained = true,
6351 .chain_id = ALC269_FIXUP_HEADSET_MIC
David Henningsson88cfcf82013-10-11 10:18:45 +02006352 },
Ayman Bagabas0fbf21c2019-05-23 05:30:11 -04006353 [ALC256_FIXUP_HUAWEI_MACH_WX9_PINS] = {
Ayman Bagabas8ac51bb2018-12-12 18:07:57 -05006354 .type = HDA_FIXUP_PINS,
6355 .v.pins = (const struct hda_pintbl[]) {
6356 {0x12, 0x90a60130},
6357 {0x13, 0x40000000},
6358 {0x14, 0x90170110},
6359 {0x18, 0x411111f0},
6360 {0x19, 0x04a11040},
6361 {0x1a, 0x411111f0},
6362 {0x1b, 0x90170112},
6363 {0x1d, 0x40759a05},
6364 {0x1e, 0x411111f0},
6365 {0x21, 0x04211020},
6366 { }
6367 },
Ayman Bagabase2744fd2018-12-12 18:07:59 -05006368 .chained = true,
6369 .chain_id = ALC255_FIXUP_MIC_MUTE_LED
Ayman Bagabas8ac51bb2018-12-12 18:07:57 -05006370 },
Tomas Espeletaa2ef03f2019-08-09 16:37:54 +02006371 [ALC298_FIXUP_HUAWEI_MBX_STEREO] = {
6372 .type = HDA_FIXUP_FUNC,
6373 .v.func = alc298_fixup_huawei_mbx_stereo,
6374 .chained = true,
6375 .chain_id = ALC255_FIXUP_MIC_MUTE_LED
6376 },
David Henningssond240d1d2013-04-15 12:50:02 +02006377 [ALC269_FIXUP_ASUS_X101_FUNC] = {
6378 .type = HDA_FIXUP_FUNC,
6379 .v.func = alc269_fixup_x101_headset_mic,
6380 },
6381 [ALC269_FIXUP_ASUS_X101_VERB] = {
6382 .type = HDA_FIXUP_VERBS,
6383 .v.verbs = (const struct hda_verb[]) {
6384 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6385 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
6386 {0x20, AC_VERB_SET_PROC_COEF, 0x0310},
6387 { }
6388 },
6389 .chained = true,
6390 .chain_id = ALC269_FIXUP_ASUS_X101_FUNC
6391 },
6392 [ALC269_FIXUP_ASUS_X101] = {
6393 .type = HDA_FIXUP_PINS,
6394 .v.pins = (const struct hda_pintbl[]) {
6395 { 0x18, 0x04a1182c }, /* Headset mic */
6396 { }
6397 },
6398 .chained = true,
6399 .chain_id = ALC269_FIXUP_ASUS_X101_VERB
6400 },
Dylan Reid08a978d2012-11-18 22:56:40 -08006401 [ALC271_FIXUP_AMIC_MIC2] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006402 .type = HDA_FIXUP_PINS,
6403 .v.pins = (const struct hda_pintbl[]) {
Dylan Reid08a978d2012-11-18 22:56:40 -08006404 { 0x14, 0x99130110 }, /* speaker */
6405 { 0x19, 0x01a19c20 }, /* mic */
6406 { 0x1b, 0x99a7012f }, /* int-mic */
6407 { 0x21, 0x0121401f }, /* HP out */
6408 { }
6409 },
6410 },
6411 [ALC271_FIXUP_HP_GATE_MIC_JACK] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006412 .type = HDA_FIXUP_FUNC,
Dylan Reid08a978d2012-11-18 22:56:40 -08006413 .v.func = alc271_hp_gate_mic_jack,
6414 .chained = true,
6415 .chain_id = ALC271_FIXUP_AMIC_MIC2,
6416 },
Oleksij Rempelb1e89722013-12-04 20:50:53 +01006417 [ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572] = {
6418 .type = HDA_FIXUP_FUNC,
6419 .v.func = alc269_fixup_limit_int_mic_boost,
6420 .chained = true,
6421 .chain_id = ALC271_FIXUP_HP_GATE_MIC_JACK,
6422 },
Dylan Reid42397002013-04-05 14:58:22 -07006423 [ALC269_FIXUP_ACER_AC700] = {
6424 .type = HDA_FIXUP_PINS,
6425 .v.pins = (const struct hda_pintbl[]) {
6426 { 0x12, 0x99a3092f }, /* int-mic */
6427 { 0x14, 0x99130110 }, /* speaker */
6428 { 0x18, 0x03a11c20 }, /* mic */
6429 { 0x1e, 0x0346101e }, /* SPDIF1 */
6430 { 0x21, 0x0321101f }, /* HP out */
6431 { }
6432 },
6433 .chained = true,
6434 .chain_id = ALC271_FIXUP_DMIC,
6435 },
David Henningsson3e0d6112013-04-22 14:30:14 +02006436 [ALC269_FIXUP_LIMIT_INT_MIC_BOOST] = {
6437 .type = HDA_FIXUP_FUNC,
6438 .v.func = alc269_fixup_limit_int_mic_boost,
David Henningsson27937692013-11-18 11:51:47 +01006439 .chained = true,
6440 .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
David Henningsson3e0d6112013-04-22 14:30:14 +02006441 },
Oleksij Rempel2cede302013-11-27 17:12:03 +01006442 [ALC269VB_FIXUP_ASUS_ZENBOOK] = {
6443 .type = HDA_FIXUP_FUNC,
6444 .v.func = alc269_fixup_limit_int_mic_boost,
6445 .chained = true,
6446 .chain_id = ALC269VB_FIXUP_DMIC,
6447 },
Takashi Iwai23870832013-11-29 14:13:12 +01006448 [ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A] = {
6449 .type = HDA_FIXUP_VERBS,
6450 .v.verbs = (const struct hda_verb[]) {
6451 /* class-D output amp +5dB */
6452 { 0x20, AC_VERB_SET_COEF_INDEX, 0x12 },
6453 { 0x20, AC_VERB_SET_PROC_COEF, 0x2800 },
6454 {}
6455 },
6456 .chained = true,
6457 .chain_id = ALC269VB_FIXUP_ASUS_ZENBOOK,
6458 },
David Henningsson8e35cd42013-11-06 11:20:01 +01006459 [ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED] = {
6460 .type = HDA_FIXUP_FUNC,
6461 .v.func = alc269_fixup_limit_int_mic_boost,
6462 .chained = true,
6463 .chain_id = ALC269_FIXUP_HP_MUTE_LED_MIC1,
6464 },
Anisse Astier02b504d2013-06-03 11:53:10 +02006465 [ALC269VB_FIXUP_ORDISSIMO_EVE2] = {
6466 .type = HDA_FIXUP_PINS,
6467 .v.pins = (const struct hda_pintbl[]) {
6468 { 0x12, 0x99a3092f }, /* int-mic */
6469 { 0x18, 0x03a11d20 }, /* mic */
6470 { 0x19, 0x411111f0 }, /* Unused bogus pin */
6471 { }
6472 },
6473 },
Kailang Yangcd217a62013-08-22 10:15:24 +02006474 [ALC283_FIXUP_CHROME_BOOK] = {
6475 .type = HDA_FIXUP_FUNC,
6476 .v.func = alc283_fixup_chromebook,
6477 },
Kailang Yang0202e992013-12-02 15:20:15 +08006478 [ALC283_FIXUP_SENSE_COMBO_JACK] = {
6479 .type = HDA_FIXUP_FUNC,
6480 .v.func = alc283_fixup_sense_combo_jack,
6481 .chained = true,
6482 .chain_id = ALC283_FIXUP_CHROME_BOOK,
6483 },
Takashi Iwai7bba2152013-09-06 15:45:38 +02006484 [ALC282_FIXUP_ASUS_TX300] = {
6485 .type = HDA_FIXUP_FUNC,
6486 .v.func = alc282_fixup_asus_tx300,
6487 },
Kailang Yang1bb3e062013-09-27 13:10:25 +02006488 [ALC283_FIXUP_INT_MIC] = {
6489 .type = HDA_FIXUP_VERBS,
6490 .v.verbs = (const struct hda_verb[]) {
6491 {0x20, AC_VERB_SET_COEF_INDEX, 0x1a},
6492 {0x20, AC_VERB_SET_PROC_COEF, 0x0011},
6493 { }
6494 },
6495 .chained = true,
6496 .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST
6497 },
David Henningsson0f4881d2013-12-20 16:08:13 +01006498 [ALC290_FIXUP_SUBWOOFER_HSJACK] = {
6499 .type = HDA_FIXUP_PINS,
6500 .v.pins = (const struct hda_pintbl[]) {
6501 { 0x17, 0x90170112 }, /* subwoofer */
6502 { }
6503 },
6504 .chained = true,
6505 .chain_id = ALC290_FIXUP_MONO_SPEAKERS_HSJACK,
6506 },
6507 [ALC290_FIXUP_SUBWOOFER] = {
6508 .type = HDA_FIXUP_PINS,
6509 .v.pins = (const struct hda_pintbl[]) {
6510 { 0x17, 0x90170112 }, /* subwoofer */
6511 { }
6512 },
6513 .chained = true,
6514 .chain_id = ALC290_FIXUP_MONO_SPEAKERS,
6515 },
David Henningsson338cae52013-10-07 10:39:59 +02006516 [ALC290_FIXUP_MONO_SPEAKERS] = {
6517 .type = HDA_FIXUP_FUNC,
6518 .v.func = alc290_fixup_mono_speakers,
David Henningsson0f4881d2013-12-20 16:08:13 +01006519 },
6520 [ALC290_FIXUP_MONO_SPEAKERS_HSJACK] = {
6521 .type = HDA_FIXUP_FUNC,
6522 .v.func = alc290_fixup_mono_speakers,
David Henningsson338cae52013-10-07 10:39:59 +02006523 .chained = true,
6524 .chain_id = ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
6525 },
David Henningssonb67ae3f2013-11-05 13:11:37 +01006526 [ALC269_FIXUP_THINKPAD_ACPI] = {
6527 .type = HDA_FIXUP_FUNC,
Takashi Iwaid5a6cab2018-06-13 12:43:10 +02006528 .v.func = alc_fixup_thinkpad_acpi,
Takashi Iwai09da1112016-09-08 12:15:02 +02006529 .chained = true,
6530 .chain_id = ALC269_FIXUP_SKU_IGNORE,
David Henningssonb67ae3f2013-11-05 13:11:37 +01006531 },
David Henningsson56f27012016-01-11 09:33:14 +01006532 [ALC269_FIXUP_DMIC_THINKPAD_ACPI] = {
6533 .type = HDA_FIXUP_FUNC,
6534 .v.func = alc_fixup_inv_dmic,
6535 .chained = true,
6536 .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
6537 },
Chris Chiu5824ce82017-02-28 14:17:11 -06006538 [ALC255_FIXUP_ACER_MIC_NO_PRESENCE] = {
Hui Wang17d30462019-06-14 16:44:12 +08006539 .type = HDA_FIXUP_PINS,
6540 .v.pins = (const struct hda_pintbl[]) {
6541 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6542 { }
Chris Chiu5824ce82017-02-28 14:17:11 -06006543 },
6544 .chained = true,
Hui Wang17d30462019-06-14 16:44:12 +08006545 .chain_id = ALC255_FIXUP_HEADSET_MODE
Chris Chiu5824ce82017-02-28 14:17:11 -06006546 },
Chris Chiu615966a2017-02-28 14:17:12 -06006547 [ALC255_FIXUP_ASUS_MIC_NO_PRESENCE] = {
6548 .type = HDA_FIXUP_PINS,
6549 .v.pins = (const struct hda_pintbl[]) {
6550 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6551 { }
6552 },
6553 .chained = true,
6554 .chain_id = ALC255_FIXUP_HEADSET_MODE
6555 },
Kailang Yang9a22a8f52013-11-08 15:54:49 +08006556 [ALC255_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6557 .type = HDA_FIXUP_PINS,
6558 .v.pins = (const struct hda_pintbl[]) {
6559 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6560 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6561 { }
6562 },
6563 .chained = true,
6564 .chain_id = ALC255_FIXUP_HEADSET_MODE
6565 },
Kailang Yang31278992014-03-03 15:27:22 +08006566 [ALC255_FIXUP_DELL2_MIC_NO_PRESENCE] = {
6567 .type = HDA_FIXUP_PINS,
6568 .v.pins = (const struct hda_pintbl[]) {
6569 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6570 { }
6571 },
6572 .chained = true,
6573 .chain_id = ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC
6574 },
Kailang Yang9a22a8f52013-11-08 15:54:49 +08006575 [ALC255_FIXUP_HEADSET_MODE] = {
6576 .type = HDA_FIXUP_FUNC,
6577 .v.func = alc_fixup_headset_mode_alc255,
Hui Wang4a83d422014-11-18 17:57:40 +08006578 .chained = true,
Takashi Iwaib3802782018-11-26 17:47:46 +01006579 .chain_id = ALC255_FIXUP_MIC_MUTE_LED
Kailang Yang9a22a8f52013-11-08 15:54:49 +08006580 },
Kailang Yang31278992014-03-03 15:27:22 +08006581 [ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC] = {
6582 .type = HDA_FIXUP_FUNC,
6583 .v.func = alc_fixup_headset_mode_alc255_no_hp_mic,
6584 },
Kailang Yanga22aa262014-04-23 17:34:28 +08006585 [ALC293_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6586 .type = HDA_FIXUP_PINS,
6587 .v.pins = (const struct hda_pintbl[]) {
6588 { 0x18, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6589 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6590 { }
6591 },
6592 .chained = true,
6593 .chain_id = ALC269_FIXUP_HEADSET_MODE
6594 },
Takashi Iwai1c37c222014-05-06 17:34:42 +02006595 [ALC292_FIXUP_TPT440_DOCK] = {
David Henningssonec56af62015-06-24 10:46:33 +02006596 .type = HDA_FIXUP_FUNC,
Takashi Iwai7f57d802015-09-24 17:36:51 +02006597 .v.func = alc_fixup_tpt440_dock,
Takashi Iwai1c37c222014-05-06 17:34:42 +02006598 .chained = true,
6599 .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST
6600 },
Takashi Iwai9a811232015-12-09 15:17:43 +01006601 [ALC292_FIXUP_TPT440] = {
6602 .type = HDA_FIXUP_FUNC,
Takashi Iwai157f0b72015-12-10 23:30:43 +01006603 .v.func = alc_fixup_disable_aamix,
Takashi Iwai9a811232015-12-09 15:17:43 +01006604 .chained = true,
6605 .chain_id = ALC292_FIXUP_TPT440_DOCK,
6606 },
Anisse Astierabaa22742016-08-24 09:14:13 +02006607 [ALC283_FIXUP_HEADSET_MIC] = {
Daniel Drake9dc12862014-07-22 10:58:29 +01006608 .type = HDA_FIXUP_PINS,
6609 .v.pins = (const struct hda_pintbl[]) {
6610 { 0x19, 0x04a110f0 },
6611 { },
6612 },
6613 },
Takashi Iwaib3802782018-11-26 17:47:46 +01006614 [ALC255_FIXUP_MIC_MUTE_LED] = {
Hui Wang00ef9942014-07-31 11:52:38 +08006615 .type = HDA_FIXUP_FUNC,
Takashi Iwaib3802782018-11-26 17:47:46 +01006616 .v.func = snd_hda_gen_fixup_micmute_led,
Hui Wang00ef9942014-07-31 11:52:38 +08006617 },
Takashi Iwai1a22e772014-08-27 08:19:05 +02006618 [ALC282_FIXUP_ASPIRE_V5_PINS] = {
6619 .type = HDA_FIXUP_PINS,
6620 .v.pins = (const struct hda_pintbl[]) {
6621 { 0x12, 0x90a60130 },
6622 { 0x14, 0x90170110 },
6623 { 0x17, 0x40000008 },
6624 { 0x18, 0x411111f0 },
Mateusz Sylwestrzak04206942015-07-19 17:38:56 +02006625 { 0x19, 0x01a1913c },
Takashi Iwai1a22e772014-08-27 08:19:05 +02006626 { 0x1a, 0x411111f0 },
6627 { 0x1b, 0x411111f0 },
6628 { 0x1d, 0x40f89b2d },
6629 { 0x1e, 0x411111f0 },
6630 { 0x21, 0x0321101f },
6631 { },
6632 },
6633 },
David Henningsson7a5255f2014-10-30 08:26:01 +01006634 [ALC280_FIXUP_HP_GPIO4] = {
6635 .type = HDA_FIXUP_FUNC,
6636 .v.func = alc280_fixup_hp_gpio4,
6637 },
Kailang Yangeaa8e5e2014-11-21 15:49:11 +08006638 [ALC286_FIXUP_HP_GPIO_LED] = {
6639 .type = HDA_FIXUP_FUNC,
6640 .v.func = alc286_fixup_hp_gpio_led,
6641 },
David Henningsson33f4acd2015-01-07 15:50:13 +01006642 [ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY] = {
6643 .type = HDA_FIXUP_FUNC,
6644 .v.func = alc280_fixup_hp_gpio2_mic_hotkey,
6645 },
TienFu Chenb4b33f92015-01-20 15:06:21 +01006646 [ALC280_FIXUP_HP_DOCK_PINS] = {
6647 .type = HDA_FIXUP_PINS,
6648 .v.pins = (const struct hda_pintbl[]) {
6649 { 0x1b, 0x21011020 }, /* line-out */
6650 { 0x1a, 0x01a1903c }, /* headset mic */
6651 { 0x18, 0x2181103f }, /* line-in */
6652 { },
6653 },
6654 .chained = true,
6655 .chain_id = ALC280_FIXUP_HP_GPIO4
6656 },
Jaroslav Kysela04d54662017-03-09 13:29:13 +01006657 [ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED] = {
6658 .type = HDA_FIXUP_PINS,
6659 .v.pins = (const struct hda_pintbl[]) {
6660 { 0x1b, 0x21011020 }, /* line-out */
6661 { 0x18, 0x2181103f }, /* line-in */
6662 { },
6663 },
6664 .chained = true,
6665 .chain_id = ALC269_FIXUP_HP_GPIO_MIC1_LED
6666 },
Keith Packard98973f22015-07-15 12:14:39 -07006667 [ALC280_FIXUP_HP_9480M] = {
6668 .type = HDA_FIXUP_FUNC,
6669 .v.func = alc280_fixup_hp_9480m,
6670 },
Kailang Yange1e62b92015-04-08 16:01:22 +08006671 [ALC288_FIXUP_DELL_HEADSET_MODE] = {
6672 .type = HDA_FIXUP_FUNC,
6673 .v.func = alc_fixup_headset_mode_dell_alc288,
6674 .chained = true,
Takashi Iwaib3802782018-11-26 17:47:46 +01006675 .chain_id = ALC255_FIXUP_MIC_MUTE_LED
Kailang Yange1e62b92015-04-08 16:01:22 +08006676 },
6677 [ALC288_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6678 .type = HDA_FIXUP_PINS,
6679 .v.pins = (const struct hda_pintbl[]) {
6680 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6681 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6682 { }
6683 },
6684 .chained = true,
6685 .chain_id = ALC288_FIXUP_DELL_HEADSET_MODE
6686 },
Hui Wang831bfdf92015-06-26 12:35:17 +08006687 [ALC288_FIXUP_DISABLE_AAMIX] = {
6688 .type = HDA_FIXUP_FUNC,
6689 .v.func = alc_fixup_disable_aamix,
6690 .chained = true,
Takashi Iwaid44a6862018-06-19 23:04:03 +02006691 .chain_id = ALC288_FIXUP_DELL1_MIC_NO_PRESENCE
Hui Wang831bfdf92015-06-26 12:35:17 +08006692 },
6693 [ALC288_FIXUP_DELL_XPS_13] = {
6694 .type = HDA_FIXUP_FUNC,
6695 .v.func = alc_fixup_dell_xps13,
6696 .chained = true,
6697 .chain_id = ALC288_FIXUP_DISABLE_AAMIX
6698 },
Takashi Iwai8b99aba2015-06-15 11:59:32 +02006699 [ALC292_FIXUP_DISABLE_AAMIX] = {
6700 .type = HDA_FIXUP_FUNC,
6701 .v.func = alc_fixup_disable_aamix,
Hui Wang831bfdf92015-06-26 12:35:17 +08006702 .chained = true,
6703 .chain_id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE
Takashi Iwai8b99aba2015-06-15 11:59:32 +02006704 },
David Henningssonc04017e2015-12-15 14:44:03 +01006705 [ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK] = {
6706 .type = HDA_FIXUP_FUNC,
6707 .v.func = alc_fixup_disable_aamix,
6708 .chained = true,
6709 .chain_id = ALC293_FIXUP_DELL1_MIC_NO_PRESENCE
6710 },
Takashi Iwai5fab5822020-01-05 09:11:19 +01006711 [ALC292_FIXUP_DELL_E7X_AAMIX] = {
Takashi Iwai8b99aba2015-06-15 11:59:32 +02006712 .type = HDA_FIXUP_FUNC,
6713 .v.func = alc_fixup_dell_xps13,
6714 .chained = true,
6715 .chain_id = ALC292_FIXUP_DISABLE_AAMIX
6716 },
Takashi Iwai5fab5822020-01-05 09:11:19 +01006717 [ALC292_FIXUP_DELL_E7X] = {
6718 .type = HDA_FIXUP_FUNC,
6719 .v.func = snd_hda_gen_fixup_micmute_led,
6720 /* micmute fixup must be applied at last */
6721 .chained_before = true,
6722 .chain_id = ALC292_FIXUP_DELL_E7X_AAMIX,
6723 },
James McDonnell54324222019-09-16 14:53:38 +00006724 [ALC298_FIXUP_ALIENWARE_MIC_NO_PRESENCE] = {
6725 .type = HDA_FIXUP_PINS,
6726 .v.pins = (const struct hda_pintbl[]) {
6727 { 0x18, 0x01a1913c }, /* headset mic w/o jack detect */
6728 { }
6729 },
6730 .chained_before = true,
6731 .chain_id = ALC269_FIXUP_HEADSET_MODE,
6732 },
Kailang Yang977e6272015-05-18 15:31:20 +08006733 [ALC298_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6734 .type = HDA_FIXUP_PINS,
6735 .v.pins = (const struct hda_pintbl[]) {
6736 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6737 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6738 { }
6739 },
6740 .chained = true,
6741 .chain_id = ALC269_FIXUP_HEADSET_MODE
6742 },
Hui Wang2f726ae2017-03-31 10:31:40 +08006743 [ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE] = {
6744 .type = HDA_FIXUP_PINS,
6745 .v.pins = (const struct hda_pintbl[]) {
6746 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6747 { }
6748 },
6749 .chained = true,
6750 .chain_id = ALC269_FIXUP_HEADSET_MODE
6751 },
Kailang Yang6ed11312015-10-26 15:37:39 +08006752 [ALC275_FIXUP_DELL_XPS] = {
6753 .type = HDA_FIXUP_VERBS,
6754 .v.verbs = (const struct hda_verb[]) {
6755 /* Enables internal speaker */
6756 {0x20, AC_VERB_SET_COEF_INDEX, 0x1f},
6757 {0x20, AC_VERB_SET_PROC_COEF, 0x00c0},
6758 {0x20, AC_VERB_SET_COEF_INDEX, 0x30},
6759 {0x20, AC_VERB_SET_PROC_COEF, 0x00b1},
6760 {}
6761 }
6762 },
Hui Wang23adc192015-12-08 12:27:18 +08006763 [ALC293_FIXUP_LENOVO_SPK_NOISE] = {
6764 .type = HDA_FIXUP_FUNC,
6765 .v.func = alc_fixup_disable_aamix,
6766 .chained = true,
6767 .chain_id = ALC269_FIXUP_THINKPAD_ACPI
6768 },
Kailang3694cb22015-12-28 11:35:24 +08006769 [ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY] = {
6770 .type = HDA_FIXUP_FUNC,
6771 .v.func = alc233_fixup_lenovo_line2_mic_hotkey,
6772 },
Kai-Heng Feng3b43b712016-02-25 15:19:38 +08006773 [ALC255_FIXUP_DELL_SPK_NOISE] = {
6774 .type = HDA_FIXUP_FUNC,
6775 .v.func = alc_fixup_disable_aamix,
6776 .chained = true,
6777 .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
6778 },
Kailang Yangd1dd4212019-01-09 17:05:24 +08006779 [ALC225_FIXUP_DISABLE_MIC_VREF] = {
6780 .type = HDA_FIXUP_FUNC,
6781 .v.func = alc_fixup_disable_mic_vref,
6782 .chained = true,
6783 .chain_id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE
6784 },
David Henningsson2ae95572016-02-25 09:37:05 +01006785 [ALC225_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6786 .type = HDA_FIXUP_VERBS,
6787 .v.verbs = (const struct hda_verb[]) {
6788 /* Disable pass-through path for FRONT 14h */
6789 { 0x20, AC_VERB_SET_COEF_INDEX, 0x36 },
6790 { 0x20, AC_VERB_SET_PROC_COEF, 0x57d7 },
6791 {}
6792 },
6793 .chained = true,
Kailang Yangd1dd4212019-01-09 17:05:24 +08006794 .chain_id = ALC225_FIXUP_DISABLE_MIC_VREF
David Henningsson2ae95572016-02-25 09:37:05 +01006795 },
Takashi Iwaif8839822016-02-25 14:31:59 +01006796 [ALC280_FIXUP_HP_HEADSET_MIC] = {
6797 .type = HDA_FIXUP_FUNC,
6798 .v.func = alc_fixup_disable_aamix,
6799 .chained = true,
6800 .chain_id = ALC269_FIXUP_HEADSET_MIC,
6801 },
Hui Wange549d192016-04-01 11:00:15 +08006802 [ALC221_FIXUP_HP_FRONT_MIC] = {
6803 .type = HDA_FIXUP_PINS,
6804 .v.pins = (const struct hda_pintbl[]) {
6805 { 0x19, 0x02a19020 }, /* Front Mic */
6806 { }
6807 },
6808 },
Sven Eckelmannc636b952016-04-11 16:55:26 +02006809 [ALC292_FIXUP_TPT460] = {
6810 .type = HDA_FIXUP_FUNC,
6811 .v.func = alc_fixup_tpt440_dock,
6812 .chained = true,
6813 .chain_id = ALC293_FIXUP_LENOVO_SPK_NOISE,
6814 },
Hui Wangdd9aa332016-08-01 10:20:32 +08006815 [ALC298_FIXUP_SPK_VOLUME] = {
6816 .type = HDA_FIXUP_FUNC,
6817 .v.func = alc298_fixup_speaker_volume,
Hui Wang59ec4b52016-08-04 15:28:04 +08006818 .chained = true,
Hui Wang2f726ae2017-03-31 10:31:40 +08006819 .chain_id = ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE,
Hui Wangdd9aa332016-08-01 10:20:32 +08006820 },
Takashi Iwaie312a862018-03-06 12:14:17 +01006821 [ALC295_FIXUP_DISABLE_DAC3] = {
6822 .type = HDA_FIXUP_FUNC,
6823 .v.func = alc295_fixup_disable_dac3,
6824 },
Jaroslav Kyselad2cd7952019-11-29 15:40:27 +01006825 [ALC285_FIXUP_SPEAKER2_TO_DAC1] = {
6826 .type = HDA_FIXUP_FUNC,
6827 .v.func = alc285_fixup_speaker2_to_dac1,
Hui Wangc37c0ab2020-02-19 13:23:06 +08006828 .chained = true,
6829 .chain_id = ALC269_FIXUP_THINKPAD_ACPI
Jaroslav Kyselad2cd7952019-11-29 15:40:27 +01006830 },
Kai-Heng Fengfd06c772016-08-30 15:36:34 +08006831 [ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER] = {
6832 .type = HDA_FIXUP_PINS,
6833 .v.pins = (const struct hda_pintbl[]) {
6834 { 0x1b, 0x90170151 },
6835 { }
6836 },
6837 .chained = true,
6838 .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
6839 },
Gabriele Mazzotta823ff162016-12-24 19:50:01 +01006840 [ALC269_FIXUP_ATIV_BOOK_8] = {
6841 .type = HDA_FIXUP_FUNC,
6842 .v.func = alc_fixup_auto_mute_via_amp,
6843 .chained = true,
6844 .chain_id = ALC269_FIXUP_NO_SHUTUP
6845 },
Kailang Yang9eb5d0e2017-01-17 15:40:25 +08006846 [ALC221_FIXUP_HP_MIC_NO_PRESENCE] = {
6847 .type = HDA_FIXUP_PINS,
6848 .v.pins = (const struct hda_pintbl[]) {
6849 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6850 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6851 { }
6852 },
6853 .chained = true,
6854 .chain_id = ALC269_FIXUP_HEADSET_MODE
6855 },
Chris Chiuc1732ed2017-02-28 14:17:13 -06006856 [ALC256_FIXUP_ASUS_HEADSET_MODE] = {
6857 .type = HDA_FIXUP_FUNC,
6858 .v.func = alc_fixup_headset_mode,
6859 },
6860 [ALC256_FIXUP_ASUS_MIC] = {
6861 .type = HDA_FIXUP_PINS,
6862 .v.pins = (const struct hda_pintbl[]) {
6863 { 0x13, 0x90a60160 }, /* use as internal mic */
6864 { 0x19, 0x04a11120 }, /* use as headset mic, without its own jack detect */
6865 { }
6866 },
6867 .chained = true,
6868 .chain_id = ALC256_FIXUP_ASUS_HEADSET_MODE
6869 },
Chris Chiueeed4cd2017-02-28 14:17:15 -06006870 [ALC256_FIXUP_ASUS_AIO_GPIO2] = {
Takashi Iwaiae065f12018-06-19 23:00:03 +02006871 .type = HDA_FIXUP_FUNC,
6872 /* Set up GPIO2 for the speaker amp */
6873 .v.func = alc_fixup_gpio4,
Chris Chiueeed4cd2017-02-28 14:17:15 -06006874 },
Chris Chiu216d7ae2017-02-28 14:17:14 -06006875 [ALC233_FIXUP_ASUS_MIC_NO_PRESENCE] = {
6876 .type = HDA_FIXUP_PINS,
6877 .v.pins = (const struct hda_pintbl[]) {
6878 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6879 { }
6880 },
6881 .chained = true,
6882 .chain_id = ALC269_FIXUP_HEADSET_MIC
6883 },
6884 [ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE] = {
6885 .type = HDA_FIXUP_VERBS,
6886 .v.verbs = (const struct hda_verb[]) {
6887 /* Enables internal speaker */
6888 {0x20, AC_VERB_SET_COEF_INDEX, 0x40},
6889 {0x20, AC_VERB_SET_PROC_COEF, 0x8800},
6890 {}
6891 },
6892 .chained = true,
6893 .chain_id = ALC233_FIXUP_ASUS_MIC_NO_PRESENCE
6894 },
Kailang Yangca169cc2017-04-25 16:17:40 +08006895 [ALC233_FIXUP_LENOVO_MULTI_CODECS] = {
6896 .type = HDA_FIXUP_FUNC,
6897 .v.func = alc233_alc662_fixup_lenovo_dual_codecs,
6898 },
Jian-Hong Panea5c7eb2019-04-01 11:25:05 +08006899 [ALC233_FIXUP_ACER_HEADSET_MIC] = {
6900 .type = HDA_FIXUP_VERBS,
6901 .v.verbs = (const struct hda_verb[]) {
6902 { 0x20, AC_VERB_SET_COEF_INDEX, 0x45 },
6903 { 0x20, AC_VERB_SET_PROC_COEF, 0x5089 },
6904 { }
6905 },
6906 .chained = true,
6907 .chain_id = ALC233_FIXUP_ASUS_MIC_NO_PRESENCE
6908 },
Hui Wangf33f79f2017-07-07 12:08:29 +08006909 [ALC294_FIXUP_LENOVO_MIC_LOCATION] = {
6910 .type = HDA_FIXUP_PINS,
6911 .v.pins = (const struct hda_pintbl[]) {
6912 /* Change the mic location from front to right, otherwise there are
6913 two front mics with the same name, pulseaudio can't handle them.
6914 This is just a temporary workaround, after applying this fixup,
6915 there will be one "Front Mic" and one "Mic" in this machine.
6916 */
6917 { 0x1a, 0x04a19040 },
6918 { }
6919 },
6920 },
Kailang Yang5f364132017-07-25 16:28:16 +08006921 [ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE] = {
6922 .type = HDA_FIXUP_PINS,
6923 .v.pins = (const struct hda_pintbl[]) {
6924 { 0x16, 0x0101102f }, /* Rear Headset HP */
6925 { 0x19, 0x02a1913c }, /* use as Front headset mic, without its own jack detect */
6926 { 0x1a, 0x01a19030 }, /* Rear Headset MIC */
6927 { 0x1b, 0x02011020 },
6928 { }
6929 },
6930 .chained = true,
6931 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
6932 },
PeiSen Houb84e8432017-09-01 15:11:56 +08006933 [ALC700_FIXUP_INTEL_REFERENCE] = {
6934 .type = HDA_FIXUP_VERBS,
6935 .v.verbs = (const struct hda_verb[]) {
6936 /* Enables internal speaker */
6937 {0x20, AC_VERB_SET_COEF_INDEX, 0x45},
6938 {0x20, AC_VERB_SET_PROC_COEF, 0x5289},
6939 {0x20, AC_VERB_SET_COEF_INDEX, 0x4A},
6940 {0x20, AC_VERB_SET_PROC_COEF, 0x001b},
6941 {0x58, AC_VERB_SET_COEF_INDEX, 0x00},
6942 {0x58, AC_VERB_SET_PROC_COEF, 0x3888},
6943 {0x20, AC_VERB_SET_COEF_INDEX, 0x6f},
6944 {0x20, AC_VERB_SET_PROC_COEF, 0x2c0b},
6945 {}
6946 }
6947 },
Kailang Yang92266652017-12-14 15:28:58 +08006948 [ALC274_FIXUP_DELL_BIND_DACS] = {
6949 .type = HDA_FIXUP_FUNC,
6950 .v.func = alc274_fixup_bind_dacs,
6951 .chained = true,
6952 .chain_id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE
6953 },
6954 [ALC274_FIXUP_DELL_AIO_LINEOUT_VERB] = {
6955 .type = HDA_FIXUP_PINS,
6956 .v.pins = (const struct hda_pintbl[]) {
6957 { 0x1b, 0x0401102f },
6958 { }
6959 },
6960 .chained = true,
6961 .chain_id = ALC274_FIXUP_DELL_BIND_DACS
6962 },
Kailang Yang61fcf8e2018-02-02 15:26:46 +08006963 [ALC298_FIXUP_TPT470_DOCK] = {
6964 .type = HDA_FIXUP_FUNC,
6965 .v.func = alc_fixup_tpt470_dock,
6966 .chained = true,
6967 .chain_id = ALC293_FIXUP_LENOVO_SPK_NOISE
6968 },
Kailang Yangae104a22018-02-05 16:07:20 +08006969 [ALC255_FIXUP_DUMMY_LINEOUT_VERB] = {
6970 .type = HDA_FIXUP_PINS,
6971 .v.pins = (const struct hda_pintbl[]) {
6972 { 0x14, 0x0201101f },
6973 { }
6974 },
6975 .chained = true,
6976 .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
6977 },
Kailang Yangf0ba9d62018-03-16 11:46:08 +08006978 [ALC255_FIXUP_DELL_HEADSET_MIC] = {
6979 .type = HDA_FIXUP_PINS,
6980 .v.pins = (const struct hda_pintbl[]) {
6981 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6982 { }
6983 },
Hui Wang3ce0d5a2018-04-19 13:29:04 +08006984 .chained = true,
6985 .chain_id = ALC269_FIXUP_HEADSET_MIC
Kailang Yangf0ba9d62018-03-16 11:46:08 +08006986 },
Tom Bridenbbf8ff62018-05-29 17:34:20 +01006987 [ALC295_FIXUP_HP_X360] = {
6988 .type = HDA_FIXUP_FUNC,
6989 .v.func = alc295_fixup_hp_top_speakers,
6990 .chained = true,
6991 .chain_id = ALC269_FIXUP_HP_MUTE_LED_MIC3
Kailang Yang8a328ac2018-08-21 16:54:41 +08006992 },
6993 [ALC221_FIXUP_HP_HEADSET_MIC] = {
6994 .type = HDA_FIXUP_PINS,
6995 .v.pins = (const struct hda_pintbl[]) {
6996 { 0x19, 0x0181313f},
6997 { }
6998 },
6999 .chained = true,
7000 .chain_id = ALC269_FIXUP_HEADSET_MIC
7001 },
Hui Wangc4cfcf62018-11-26 14:17:16 +08007002 [ALC285_FIXUP_LENOVO_HEADPHONE_NOISE] = {
7003 .type = HDA_FIXUP_FUNC,
7004 .v.func = alc285_fixup_invalidate_dacs,
Hui Wang6ba189c2018-12-09 09:16:43 +08007005 .chained = true,
7006 .chain_id = ALC269_FIXUP_THINKPAD_ACPI
Hui Wangc4cfcf62018-11-26 14:17:16 +08007007 },
Girija Kumar Kasinadhunie8ed64b2018-11-26 13:40:46 -05007008 [ALC295_FIXUP_HP_AUTO_MUTE] = {
7009 .type = HDA_FIXUP_FUNC,
7010 .v.func = alc_fixup_auto_mute_via_amp,
7011 },
Chris Chiu33aaebd2018-12-05 14:48:53 +08007012 [ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE] = {
7013 .type = HDA_FIXUP_PINS,
7014 .v.pins = (const struct hda_pintbl[]) {
7015 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
7016 { }
7017 },
7018 .chained = true,
7019 .chain_id = ALC269_FIXUP_HEADSET_MIC
7020 },
Chris Chiud8ae4582018-12-07 17:17:11 +08007021 [ALC294_FIXUP_ASUS_MIC] = {
7022 .type = HDA_FIXUP_PINS,
7023 .v.pins = (const struct hda_pintbl[]) {
7024 { 0x13, 0x90a60160 }, /* use as internal mic */
7025 { 0x19, 0x04a11120 }, /* use as headset mic, without its own jack detect */
7026 { }
7027 },
7028 .chained = true,
7029 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
7030 },
Jian-Hong Pan4e051102018-12-07 17:17:12 +08007031 [ALC294_FIXUP_ASUS_HEADSET_MIC] = {
7032 .type = HDA_FIXUP_PINS,
7033 .v.pins = (const struct hda_pintbl[]) {
Jian-Hong Pan82b01142018-12-27 16:46:31 +08007034 { 0x19, 0x01a1103c }, /* use as headset mic */
Jian-Hong Pan4e051102018-12-07 17:17:12 +08007035 { }
7036 },
7037 .chained = true,
7038 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
7039 },
7040 [ALC294_FIXUP_ASUS_SPK] = {
7041 .type = HDA_FIXUP_VERBS,
7042 .v.verbs = (const struct hda_verb[]) {
7043 /* Set EAPD high */
7044 { 0x20, AC_VERB_SET_COEF_INDEX, 0x40 },
7045 { 0x20, AC_VERB_SET_PROC_COEF, 0x8800 },
7046 { }
7047 },
7048 .chained = true,
7049 .chain_id = ALC294_FIXUP_ASUS_HEADSET_MIC
7050 },
Jaroslav Kyselac8a9afa2019-03-14 09:21:08 +01007051 [ALC295_FIXUP_CHROME_BOOK] = {
Kailang Yange8547472018-11-28 15:32:45 +08007052 .type = HDA_FIXUP_FUNC,
Jaroslav Kyselac8a9afa2019-03-14 09:21:08 +01007053 .v.func = alc295_fixup_chromebook,
Kailang Yang8983eb62019-04-03 15:31:49 +08007054 .chained = true,
7055 .chain_id = ALC225_FIXUP_HEADSET_JACK
7056 },
7057 [ALC225_FIXUP_HEADSET_JACK] = {
7058 .type = HDA_FIXUP_FUNC,
7059 .v.func = alc_fixup_headset_jack,
Kailang Yange8547472018-11-28 15:32:45 +08007060 },
Jeremy Soller89e3a562019-01-30 16:12:31 -07007061 [ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE] = {
7062 .type = HDA_FIXUP_PINS,
7063 .v.pins = (const struct hda_pintbl[]) {
7064 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
7065 { }
7066 },
7067 .chained = true,
7068 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
7069 },
Hui Wangc8c6ee62019-02-14 11:41:33 +08007070 [ALC285_FIXUP_LENOVO_PC_BEEP_IN_NOISE] = {
7071 .type = HDA_FIXUP_VERBS,
7072 .v.verbs = (const struct hda_verb[]) {
7073 /* Disable PCBEEP-IN passthrough */
7074 { 0x20, AC_VERB_SET_COEF_INDEX, 0x36 },
7075 { 0x20, AC_VERB_SET_PROC_COEF, 0x57d7 },
7076 { }
7077 },
7078 .chained = true,
7079 .chain_id = ALC285_FIXUP_LENOVO_HEADPHONE_NOISE
7080 },
Jian-Hong Pancbc05fd2019-03-13 17:33:24 +08007081 [ALC255_FIXUP_ACER_HEADSET_MIC] = {
7082 .type = HDA_FIXUP_PINS,
7083 .v.pins = (const struct hda_pintbl[]) {
7084 { 0x19, 0x03a11130 },
7085 { 0x1a, 0x90a60140 }, /* use as internal mic */
7086 { }
7087 },
7088 .chained = true,
7089 .chain_id = ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC
7090 },
Kailang Yang136824e2019-03-14 16:22:45 +08007091 [ALC225_FIXUP_DELL_WYSE_AIO_MIC_NO_PRESENCE] = {
7092 .type = HDA_FIXUP_PINS,
7093 .v.pins = (const struct hda_pintbl[]) {
7094 { 0x16, 0x01011020 }, /* Rear Line out */
7095 { 0x19, 0x01a1913c }, /* use as Front headset mic, without its own jack detect */
7096 { }
7097 },
7098 .chained = true,
7099 .chain_id = ALC225_FIXUP_WYSE_AUTO_MUTE
7100 },
7101 [ALC225_FIXUP_WYSE_AUTO_MUTE] = {
7102 .type = HDA_FIXUP_FUNC,
7103 .v.func = alc_fixup_auto_mute_via_amp,
7104 .chained = true,
7105 .chain_id = ALC225_FIXUP_WYSE_DISABLE_MIC_VREF
7106 },
7107 [ALC225_FIXUP_WYSE_DISABLE_MIC_VREF] = {
7108 .type = HDA_FIXUP_FUNC,
7109 .v.func = alc_fixup_disable_mic_vref,
7110 .chained = true,
7111 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
7112 },
Jian-Hong Pan667a8f72019-03-15 17:51:09 +08007113 [ALC286_FIXUP_ACER_AIO_HEADSET_MIC] = {
7114 .type = HDA_FIXUP_VERBS,
7115 .v.verbs = (const struct hda_verb[]) {
7116 { 0x20, AC_VERB_SET_COEF_INDEX, 0x4f },
7117 { 0x20, AC_VERB_SET_PROC_COEF, 0x5029 },
7118 { }
7119 },
7120 .chained = true,
7121 .chain_id = ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE
7122 },
Daniel Drake8c8967a2019-10-17 16:15:01 +08007123 [ALC256_FIXUP_ASUS_HEADSET_MIC] = {
7124 .type = HDA_FIXUP_PINS,
7125 .v.pins = (const struct hda_pintbl[]) {
7126 { 0x19, 0x03a11020 }, /* headset mic with jack detect */
7127 { }
7128 },
7129 .chained = true,
7130 .chain_id = ALC256_FIXUP_ASUS_HEADSET_MODE
7131 },
Jian-Hong Pane1037352019-03-22 11:37:18 +08007132 [ALC256_FIXUP_ASUS_MIC_NO_PRESENCE] = {
7133 .type = HDA_FIXUP_PINS,
7134 .v.pins = (const struct hda_pintbl[]) {
7135 { 0x19, 0x04a11120 }, /* use as headset mic, without its own jack detect */
7136 { }
7137 },
7138 .chained = true,
7139 .chain_id = ALC256_FIXUP_ASUS_HEADSET_MODE
7140 },
Bernhard Rosenkraenzere2a829b2019-03-05 00:38:19 +01007141 [ALC299_FIXUP_PREDATOR_SPK] = {
7142 .type = HDA_FIXUP_PINS,
7143 .v.pins = (const struct hda_pintbl[]) {
7144 { 0x21, 0x90170150 }, /* use as headset mic, without its own jack detect */
7145 { }
7146 }
7147 },
Jan-Marek Glogowskibd9c10b2019-09-15 16:57:28 +02007148 [ALC256_FIXUP_MEDION_HEADSET_NO_PRESENCE] = {
7149 .type = HDA_FIXUP_PINS,
7150 .v.pins = (const struct hda_pintbl[]) {
7151 { 0x19, 0x04a11040 },
7152 { 0x21, 0x04211020 },
7153 { }
7154 },
7155 .chained = true,
7156 .chain_id = ALC256_FIXUP_ASUS_HEADSET_MODE
7157 },
Kailang Yange79c2262019-12-19 14:12:15 +08007158 [ALC289_FIXUP_DELL_SPK2] = {
7159 .type = HDA_FIXUP_PINS,
7160 .v.pins = (const struct hda_pintbl[]) {
7161 { 0x17, 0x90170130 }, /* bass spk */
7162 { }
7163 },
7164 .chained = true,
7165 .chain_id = ALC269_FIXUP_DELL4_MIC_NO_PRESENCE
7166 },
7167 [ALC289_FIXUP_DUAL_SPK] = {
7168 .type = HDA_FIXUP_FUNC,
7169 .v.func = alc285_fixup_speaker2_to_dac1,
7170 .chained = true,
7171 .chain_id = ALC289_FIXUP_DELL_SPK2
7172 },
Chris Chiu48e01502019-12-30 11:11:18 +08007173 [ALC294_FIXUP_SPK2_TO_DAC1] = {
7174 .type = HDA_FIXUP_FUNC,
7175 .v.func = alc285_fixup_speaker2_to_dac1,
7176 .chained = true,
7177 .chain_id = ALC294_FIXUP_ASUS_HEADSET_MIC
7178 },
7179 [ALC294_FIXUP_ASUS_DUAL_SPK] = {
Jian-Hong Pan436e2552019-11-25 17:34:06 +08007180 .type = HDA_FIXUP_FUNC,
7181 /* The GPIO must be pulled to initialize the AMP */
7182 .v.func = alc_fixup_gpio4,
7183 .chained = true,
Chris Chiu48e01502019-12-30 11:11:18 +08007184 .chain_id = ALC294_FIXUP_SPK2_TO_DAC1
Jian-Hong Pan436e2552019-11-25 17:34:06 +08007185 },
Kailang Yang76f7dec2020-02-10 16:30:26 +08007186 [ALC285_FIXUP_THINKPAD_HEADSET_JACK] = {
7187 .type = HDA_FIXUP_FUNC,
7188 .v.func = alc_fixup_headset_jack,
7189 .chained = true,
7190 .chain_id = ALC285_FIXUP_SPEAKER2_TO_DAC1
7191 },
Jian-Hong Pan8b33a132020-02-25 15:29:21 +08007192 [ALC294_FIXUP_ASUS_HPE] = {
7193 .type = HDA_FIXUP_VERBS,
7194 .v.verbs = (const struct hda_verb[]) {
7195 /* Set EAPD high */
7196 { 0x20, AC_VERB_SET_COEF_INDEX, 0x0f },
7197 { 0x20, AC_VERB_SET_PROC_COEF, 0x7774 },
7198 { }
7199 },
7200 .chained = true,
7201 .chain_id = ALC294_FIXUP_ASUS_HEADSET_MIC
7202 },
Kai-Heng Fengf5a88b02020-03-27 12:46:25 +08007203 [ALC285_FIXUP_HP_GPIO_LED] = {
7204 .type = HDA_FIXUP_FUNC,
7205 .v.func = alc285_fixup_hp_gpio_led,
7206 },
Kailang Yang431e76c2020-04-07 14:40:20 +08007207 [ALC285_FIXUP_HP_MUTE_LED] = {
7208 .type = HDA_FIXUP_FUNC,
7209 .v.func = alc285_fixup_hp_mute_led,
7210 },
Kailang Yang24164f42020-04-07 14:52:42 +08007211 [ALC236_FIXUP_HP_MUTE_LED] = {
7212 .type = HDA_FIXUP_FUNC,
7213 .v.func = alc236_fixup_hp_mute_led,
7214 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02007215};
7216
7217static const struct snd_pci_quirk alc269_fixup_tbl[] = {
Marius Knausta6b92b62014-03-03 01:48:58 +01007218 SND_PCI_QUIRK(0x1025, 0x0283, "Acer TravelMate 8371", ALC269_FIXUP_INV_DMIC),
David Henningsson693b6132012-06-22 19:12:10 +02007219 SND_PCI_QUIRK(0x1025, 0x029b, "Acer 1810TZ", ALC269_FIXUP_INV_DMIC),
7220 SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC),
David Henningssonaaedfb42013-08-16 14:09:02 +02007221 SND_PCI_QUIRK(0x1025, 0x047c, "Acer AC700", ALC269_FIXUP_ACER_AC700),
Takashi Iwai78197172015-06-27 10:21:13 +02007222 SND_PCI_QUIRK(0x1025, 0x072d, "Acer Aspire V5-571G", ALC269_FIXUP_ASPIRE_HEADSET_MIC),
7223 SND_PCI_QUIRK(0x1025, 0x080d, "Acer Aspire V5-122P", ALC269_FIXUP_ASPIRE_HEADSET_MIC),
David Henningssonaaedfb42013-08-16 14:09:02 +02007224 SND_PCI_QUIRK(0x1025, 0x0740, "Acer AO725", ALC271_FIXUP_HP_GATE_MIC_JACK),
7225 SND_PCI_QUIRK(0x1025, 0x0742, "Acer AO756", ALC271_FIXUP_HP_GATE_MIC_JACK),
Simon South02322ac2016-03-02 23:10:44 -05007226 SND_PCI_QUIRK(0x1025, 0x0762, "Acer Aspire E1-472", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572),
Oleksij Rempelb1e89722013-12-04 20:50:53 +01007227 SND_PCI_QUIRK(0x1025, 0x0775, "Acer Aspire E1-572", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572),
Takashi Iwai1a22e772014-08-27 08:19:05 +02007228 SND_PCI_QUIRK(0x1025, 0x079b, "Acer Aspire V5-573G", ALC282_FIXUP_ASPIRE_V5_PINS),
Chris Chiu705b65f2018-12-05 14:48:54 +08007229 SND_PCI_QUIRK(0x1025, 0x102b, "Acer Aspire C24-860", ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE),
Takashi Iwaib9c2fa52015-11-19 16:39:50 +01007230 SND_PCI_QUIRK(0x1025, 0x106d, "Acer Cloudbook 14", ALC283_FIXUP_CHROME_BOOK),
Chris Chiuc7531e32019-03-21 17:17:31 +08007231 SND_PCI_QUIRK(0x1025, 0x1099, "Acer Aspire E5-523G", ALC255_FIXUP_ACER_MIC_NO_PRESENCE),
7232 SND_PCI_QUIRK(0x1025, 0x110e, "Acer Aspire ES1-432", ALC255_FIXUP_ACER_MIC_NO_PRESENCE),
Bernhard Rosenkraenzere2a829b2019-03-05 00:38:19 +01007233 SND_PCI_QUIRK(0x1025, 0x1246, "Acer Predator Helios 500", ALC299_FIXUP_PREDATOR_SPK),
Jian-Hong Pan667a8f72019-03-15 17:51:09 +08007234 SND_PCI_QUIRK(0x1025, 0x128f, "Acer Veriton Z6860G", ALC286_FIXUP_ACER_AIO_HEADSET_MIC),
7235 SND_PCI_QUIRK(0x1025, 0x1290, "Acer Veriton Z4860G", ALC286_FIXUP_ACER_AIO_HEADSET_MIC),
7236 SND_PCI_QUIRK(0x1025, 0x1291, "Acer Veriton Z4660G", ALC286_FIXUP_ACER_AIO_HEADSET_MIC),
Jian-Hong Pan2733cce2019-03-21 16:39:04 +08007237 SND_PCI_QUIRK(0x1025, 0x1308, "Acer Aspire Z24-890", ALC286_FIXUP_ACER_AIO_HEADSET_MIC),
Jian-Hong Panea5c7eb2019-04-01 11:25:05 +08007238 SND_PCI_QUIRK(0x1025, 0x132a, "Acer TravelMate B114-21", ALC233_FIXUP_ACER_HEADSET_MIC),
Jian-Hong Pancbc05fd2019-03-13 17:33:24 +08007239 SND_PCI_QUIRK(0x1025, 0x1330, "Acer TravelMate X514-51T", ALC255_FIXUP_ACER_HEADSET_MIC),
David Henningssonaaedfb42013-08-16 14:09:02 +02007240 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
Kailang Yang6ed11312015-10-26 15:37:39 +08007241 SND_PCI_QUIRK(0x1028, 0x054b, "Dell XPS one 2710", ALC275_FIXUP_DELL_XPS),
Takashi Iwai86f799b2015-11-14 17:46:31 +01007242 SND_PCI_QUIRK(0x1028, 0x05bd, "Dell Latitude E6440", ALC292_FIXUP_DELL_E7X),
Takashi Iwaicf521032016-01-15 12:59:25 +01007243 SND_PCI_QUIRK(0x1028, 0x05be, "Dell Latitude E6540", ALC292_FIXUP_DELL_E7X),
Takashi Iwai8b99aba2015-06-15 11:59:32 +02007244 SND_PCI_QUIRK(0x1028, 0x05ca, "Dell Latitude E7240", ALC292_FIXUP_DELL_E7X),
7245 SND_PCI_QUIRK(0x1028, 0x05cb, "Dell Latitude E7440", ALC292_FIXUP_DELL_E7X),
David Henningsson0f4881d2013-12-20 16:08:13 +01007246 SND_PCI_QUIRK(0x1028, 0x05da, "Dell Vostro 5460", ALC290_FIXUP_SUBWOOFER),
David Henningsson73bdd592013-04-15 15:44:14 +02007247 SND_PCI_QUIRK(0x1028, 0x05f4, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
7248 SND_PCI_QUIRK(0x1028, 0x05f5, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
7249 SND_PCI_QUIRK(0x1028, 0x05f6, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
David Henningsson0f4881d2013-12-20 16:08:13 +01007250 SND_PCI_QUIRK(0x1028, 0x0615, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK),
7251 SND_PCI_QUIRK(0x1028, 0x0616, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK),
Takashi Iwai98070572016-01-12 21:06:39 +01007252 SND_PCI_QUIRK(0x1028, 0x062c, "Dell Latitude E5550", ALC292_FIXUP_DELL_E7X),
Takashi Iwai42755542015-06-29 10:56:53 +02007253 SND_PCI_QUIRK(0x1028, 0x062e, "Dell Latitude E7450", ALC292_FIXUP_DELL_E7X),
David Henningsson0f4881d2013-12-20 16:08:13 +01007254 SND_PCI_QUIRK(0x1028, 0x0638, "Dell Inspiron 5439", ALC290_FIXUP_MONO_SPEAKERS_HSJACK),
Kailang Yanga22aa262014-04-23 17:34:28 +08007255 SND_PCI_QUIRK(0x1028, 0x064a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
7256 SND_PCI_QUIRK(0x1028, 0x064b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
Hui Wang831bfdf92015-06-26 12:35:17 +08007257 SND_PCI_QUIRK(0x1028, 0x0665, "Dell XPS 13", ALC288_FIXUP_DELL_XPS_13),
Bastien Noceraafecb142016-04-18 11:10:42 +02007258 SND_PCI_QUIRK(0x1028, 0x0669, "Dell Optiplex 9020m", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
Takashi Iwai3a05d122015-07-29 09:04:52 +02007259 SND_PCI_QUIRK(0x1028, 0x069a, "Dell Vostro 5480", ALC290_FIXUP_SUBWOOFER_HSJACK),
Kailang Yang8b724152014-12-17 17:08:59 +08007260 SND_PCI_QUIRK(0x1028, 0x06c7, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
Kailang Yangb7343042014-12-02 14:50:45 +08007261 SND_PCI_QUIRK(0x1028, 0x06d9, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
7262 SND_PCI_QUIRK(0x1028, 0x06da, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
David Henningssonc04017e2015-12-15 14:44:03 +01007263 SND_PCI_QUIRK(0x1028, 0x06db, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
7264 SND_PCI_QUIRK(0x1028, 0x06dd, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
7265 SND_PCI_QUIRK(0x1028, 0x06de, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
7266 SND_PCI_QUIRK(0x1028, 0x06df, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
7267 SND_PCI_QUIRK(0x1028, 0x06e0, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
Kai-Heng Fengfd06c772016-08-30 15:36:34 +08007268 SND_PCI_QUIRK(0x1028, 0x0706, "Dell Inspiron 7559", ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER),
Kai-Heng Feng3b43b712016-02-25 15:19:38 +08007269 SND_PCI_QUIRK(0x1028, 0x0725, "Dell Inspiron 3162", ALC255_FIXUP_DELL_SPK_NOISE),
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01007270 SND_PCI_QUIRK(0x1028, 0x0738, "Dell Precision 5820", ALC269_FIXUP_NO_SHUTUP),
Kai-Heng Feng709ae622018-10-04 11:39:42 +08007271 SND_PCI_QUIRK(0x1028, 0x075c, "Dell XPS 27 7760", ALC298_FIXUP_SPK_VOLUME),
Hui Wangdd9aa332016-08-01 10:20:32 +08007272 SND_PCI_QUIRK(0x1028, 0x075d, "Dell AIO", ALC298_FIXUP_SPK_VOLUME),
Takashi Iwaie312a862018-03-06 12:14:17 +01007273 SND_PCI_QUIRK(0x1028, 0x07b0, "Dell Precision 7520", ALC295_FIXUP_DISABLE_DAC3),
Takashi Iwai493de342017-02-28 17:27:57 +01007274 SND_PCI_QUIRK(0x1028, 0x0798, "Dell Inspiron 17 7000 Gaming", ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER),
Kailang Yang5f364132017-07-25 16:28:16 +08007275 SND_PCI_QUIRK(0x1028, 0x080c, "Dell WYSE", ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE),
Kailang Yang40e2c4e2018-02-02 15:13:09 +08007276 SND_PCI_QUIRK(0x1028, 0x084b, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB),
7277 SND_PCI_QUIRK(0x1028, 0x084e, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB),
Kailang Yangf0ba9d62018-03-16 11:46:08 +08007278 SND_PCI_QUIRK(0x1028, 0x0871, "Dell Precision 3630", ALC255_FIXUP_DELL_HEADSET_MIC),
7279 SND_PCI_QUIRK(0x1028, 0x0872, "Dell Precision 3630", ALC255_FIXUP_DELL_HEADSET_MIC),
Kailang Yangae104a22018-02-05 16:07:20 +08007280 SND_PCI_QUIRK(0x1028, 0x0873, "Dell Precision 3930", ALC255_FIXUP_DUMMY_LINEOUT_VERB),
Kailang Yang136824e2019-03-14 16:22:45 +08007281 SND_PCI_QUIRK(0x1028, 0x08ad, "Dell WYSE AIO", ALC225_FIXUP_DELL_WYSE_AIO_MIC_NO_PRESENCE),
Kailang Yangda484d02019-03-14 15:50:59 +08007282 SND_PCI_QUIRK(0x1028, 0x08ae, "Dell WYSE NB", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE),
Kailang Yangc2a7c55a2019-01-03 15:53:39 +08007283 SND_PCI_QUIRK(0x1028, 0x0935, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB),
Kailang Yange79c2262019-12-19 14:12:15 +08007284 SND_PCI_QUIRK(0x1028, 0x097e, "Dell Precision", ALC289_FIXUP_DUAL_SPK),
7285 SND_PCI_QUIRK(0x1028, 0x097d, "Dell Precision", ALC289_FIXUP_DUAL_SPK),
Kailang Yang78def222020-02-20 15:21:54 +08007286 SND_PCI_QUIRK(0x1028, 0x098d, "Dell Precision", ALC233_FIXUP_ASUS_MIC_NO_PRESENCE),
7287 SND_PCI_QUIRK(0x1028, 0x09bf, "Dell Precision", ALC233_FIXUP_ASUS_MIC_NO_PRESENCE),
Kailang Yanga22aa262014-04-23 17:34:28 +08007288 SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
7289 SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
Takashi Iwai08fb0d02013-01-10 17:33:58 +01007290 SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01007291 SND_PCI_QUIRK(0x103c, 0x18e6, "HP", ALC269_FIXUP_HP_GPIO_LED),
David Henningsson8e35cd42013-11-06 11:20:01 +01007292 SND_PCI_QUIRK(0x103c, 0x218b, "HP", ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED),
David Henningsson33f4acd2015-01-07 15:50:13 +01007293 SND_PCI_QUIRK(0x103c, 0x225f, "HP", ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY),
Kailang Yangc60666b2014-02-21 16:23:35 +08007294 /* ALC282 */
Hui Wang7976eb42015-02-13 11:14:41 +08007295 SND_PCI_QUIRK(0x103c, 0x21f9, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang8a02b162014-06-13 17:16:31 +08007296 SND_PCI_QUIRK(0x103c, 0x2210, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang8a02b162014-06-13 17:16:31 +08007297 SND_PCI_QUIRK(0x103c, 0x2214, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007298 SND_PCI_QUIRK(0x103c, 0x2236, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
7299 SND_PCI_QUIRK(0x103c, 0x2237, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
7300 SND_PCI_QUIRK(0x103c, 0x2238, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
7301 SND_PCI_QUIRK(0x103c, 0x2239, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007302 SND_PCI_QUIRK(0x103c, 0x224b, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
Kailang Yangc60666b2014-02-21 16:23:35 +08007303 SND_PCI_QUIRK(0x103c, 0x2268, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08007304 SND_PCI_QUIRK(0x103c, 0x226a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7305 SND_PCI_QUIRK(0x103c, 0x226b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang8a02b162014-06-13 17:16:31 +08007306 SND_PCI_QUIRK(0x103c, 0x226e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangeaa8e5e2014-11-21 15:49:11 +08007307 SND_PCI_QUIRK(0x103c, 0x2271, "HP", ALC286_FIXUP_HP_GPIO_LED),
TienFu Chenb4b33f92015-01-20 15:06:21 +01007308 SND_PCI_QUIRK(0x103c, 0x2272, "HP", ALC280_FIXUP_HP_DOCK_PINS),
TienFu Chen3271cb22015-02-10 09:09:41 +01007309 SND_PCI_QUIRK(0x103c, 0x2273, "HP", ALC280_FIXUP_HP_DOCK_PINS),
Kailang Yangc60666b2014-02-21 16:23:35 +08007310 SND_PCI_QUIRK(0x103c, 0x229e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08007311 SND_PCI_QUIRK(0x103c, 0x22b2, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7312 SND_PCI_QUIRK(0x103c, 0x22b7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7313 SND_PCI_QUIRK(0x103c, 0x22bf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08007314 SND_PCI_QUIRK(0x103c, 0x22cf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Keith Packard98973f22015-07-15 12:14:39 -07007315 SND_PCI_QUIRK(0x103c, 0x22db, "HP", ALC280_FIXUP_HP_9480M),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007316 SND_PCI_QUIRK(0x103c, 0x22dc, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
7317 SND_PCI_QUIRK(0x103c, 0x22fb, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yangc60666b2014-02-21 16:23:35 +08007318 /* ALC290 */
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007319 SND_PCI_QUIRK(0x103c, 0x221b, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007320 SND_PCI_QUIRK(0x103c, 0x2221, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007321 SND_PCI_QUIRK(0x103c, 0x2225, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007322 SND_PCI_QUIRK(0x103c, 0x2253, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
7323 SND_PCI_QUIRK(0x103c, 0x2254, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
7324 SND_PCI_QUIRK(0x103c, 0x2255, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
7325 SND_PCI_QUIRK(0x103c, 0x2256, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
7326 SND_PCI_QUIRK(0x103c, 0x2257, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007327 SND_PCI_QUIRK(0x103c, 0x2259, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Jaroslav Kysela04d54662017-03-09 13:29:13 +01007328 SND_PCI_QUIRK(0x103c, 0x225a, "HP", ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED),
Kailang Yangc60666b2014-02-21 16:23:35 +08007329 SND_PCI_QUIRK(0x103c, 0x2260, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08007330 SND_PCI_QUIRK(0x103c, 0x2263, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7331 SND_PCI_QUIRK(0x103c, 0x2264, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7332 SND_PCI_QUIRK(0x103c, 0x2265, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007333 SND_PCI_QUIRK(0x103c, 0x2272, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
7334 SND_PCI_QUIRK(0x103c, 0x2273, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007335 SND_PCI_QUIRK(0x103c, 0x2278, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yangc60666b2014-02-21 16:23:35 +08007336 SND_PCI_QUIRK(0x103c, 0x227f, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08007337 SND_PCI_QUIRK(0x103c, 0x2282, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08007338 SND_PCI_QUIRK(0x103c, 0x228b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08007339 SND_PCI_QUIRK(0x103c, 0x228e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7340 SND_PCI_QUIRK(0x103c, 0x22c5, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08007341 SND_PCI_QUIRK(0x103c, 0x22c7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7342 SND_PCI_QUIRK(0x103c, 0x22c8, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08007343 SND_PCI_QUIRK(0x103c, 0x22c4, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang8a02b162014-06-13 17:16:31 +08007344 SND_PCI_QUIRK(0x103c, 0x2334, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7345 SND_PCI_QUIRK(0x103c, 0x2335, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7346 SND_PCI_QUIRK(0x103c, 0x2336, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7347 SND_PCI_QUIRK(0x103c, 0x2337, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Takashi Iwaif8839822016-02-25 14:31:59 +01007348 SND_PCI_QUIRK(0x103c, 0x221c, "HP EliteBook 755 G2", ALC280_FIXUP_HP_HEADSET_MIC),
Jaroslav Kysela167897f2019-03-13 13:40:15 +01007349 SND_PCI_QUIRK(0x103c, 0x802e, "HP Z240 SFF", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
7350 SND_PCI_QUIRK(0x103c, 0x802f, "HP Z240", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
Takashi Iwai563785e2018-11-12 09:43:12 +01007351 SND_PCI_QUIRK(0x103c, 0x820d, "HP Pavilion 15", ALC269_FIXUP_HP_MUTE_LED_MIC3),
Hui Wange549d192016-04-01 11:00:15 +08007352 SND_PCI_QUIRK(0x103c, 0x8256, "HP", ALC221_FIXUP_HP_FRONT_MIC),
Tom Bridenbbf8ff62018-05-29 17:34:20 +01007353 SND_PCI_QUIRK(0x103c, 0x827e, "HP x360", ALC295_FIXUP_HP_X360),
Jaroslav Kysela167897f2019-03-13 13:40:15 +01007354 SND_PCI_QUIRK(0x103c, 0x82bf, "HP G3 mini", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
7355 SND_PCI_QUIRK(0x103c, 0x82c0, "HP G3 mini premium", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
Alexandru Gagniuc56e40eb2018-08-04 11:44:44 -05007356 SND_PCI_QUIRK(0x103c, 0x83b9, "HP Spectre x360", ALC269_FIXUP_HP_MUTE_LED_MIC3),
Takashi Iwai190d0382019-08-13 17:39:56 +02007357 SND_PCI_QUIRK(0x103c, 0x8497, "HP Envy x360", ALC269_FIXUP_HP_MUTE_LED_MIC3),
Sam Bazleyd33cd422019-09-01 03:31:30 +01007358 SND_PCI_QUIRK(0x103c, 0x84e7, "HP Pavilion 15", ALC269_FIXUP_HP_MUTE_LED_MIC3),
Kai-Heng Fengf5a88b02020-03-27 12:46:25 +08007359 SND_PCI_QUIRK(0x103c, 0x8736, "HP", ALC285_FIXUP_HP_GPIO_LED),
Kailang Yang431e76c2020-04-07 14:40:20 +08007360 SND_PCI_QUIRK(0x103c, 0x877a, "HP", ALC285_FIXUP_HP_MUTE_LED),
Kailang Yang24164f42020-04-07 14:52:42 +08007361 SND_PCI_QUIRK(0x103c, 0x877d, "HP", ALC236_FIXUP_HP_MUTE_LED),
Chris Chiuc1732ed2017-02-28 14:17:13 -06007362 SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC),
Takashi Iwai7bba2152013-09-06 15:45:38 +02007363 SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300),
David Henningsson3e0d6112013-04-22 14:30:14 +02007364 SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Wandrille RONCE9cf65332018-12-19 14:52:44 +01007365 SND_PCI_QUIRK(0x1043, 0x10a1, "ASUS UX391UA", ALC294_FIXUP_ASUS_SPK),
Chris Chiuc1732ed2017-02-28 14:17:13 -06007366 SND_PCI_QUIRK(0x1043, 0x10c0, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC),
Takashi Iwai4eab0ea2017-06-06 12:33:17 +02007367 SND_PCI_QUIRK(0x1043, 0x10d0, "ASUS X540LA/X540LJ", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
David Henningsson3e0d6112013-04-22 14:30:14 +02007368 SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Takashi Iwai4eab0ea2017-06-06 12:33:17 +02007369 SND_PCI_QUIRK(0x1043, 0x11c0, "ASUS X556UR", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
7370 SND_PCI_QUIRK(0x1043, 0x1290, "ASUS X441SA", ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE),
7371 SND_PCI_QUIRK(0x1043, 0x12a0, "ASUS X441UV", ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE),
Chris Chiuc1732ed2017-02-28 14:17:13 -06007372 SND_PCI_QUIRK(0x1043, 0x12f0, "ASUS X541UV", ALC256_FIXUP_ASUS_MIC),
7373 SND_PCI_QUIRK(0x1043, 0x12e0, "ASUS X541SA", ALC256_FIXUP_ASUS_MIC),
7374 SND_PCI_QUIRK(0x1043, 0x13b0, "ASUS Z550SA", ALC256_FIXUP_ASUS_MIC),
Oleksij Rempel2cede302013-11-27 17:12:03 +01007375 SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK),
Takashi Iwai23870832013-11-29 14:13:12 +01007376 SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A),
David Henningsson3e0d6112013-04-22 14:30:14 +02007377 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC),
Chris Chiu48e01502019-12-30 11:11:18 +08007378 SND_PCI_QUIRK(0x1043, 0x17d1, "ASUS UX431FL", ALC294_FIXUP_ASUS_DUAL_SPK),
Daniel Drake8c8967a2019-10-17 16:15:01 +08007379 SND_PCI_QUIRK(0x1043, 0x18b1, "Asus MJ401TA", ALC256_FIXUP_ASUS_HEADSET_MIC),
Jian-Hong Pan8b33a132020-02-25 15:29:21 +08007380 SND_PCI_QUIRK(0x1043, 0x19ce, "ASUS B9450FA", ALC294_FIXUP_ASUS_HPE),
Takashi Iwai017f2a12011-07-09 14:42:25 +02007381 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
Chris Chiu28e8af82017-06-05 15:05:30 -06007382 SND_PCI_QUIRK(0x1043, 0x1a30, "ASUS X705UD", ALC256_FIXUP_ASUS_MIC),
David Henningsson693b6132012-06-22 19:12:10 +02007383 SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC),
Chris Chiu615966a2017-02-28 14:17:12 -06007384 SND_PCI_QUIRK(0x1043, 0x1bbd, "ASUS Z550MA", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
Takashi Iwai4eab0ea2017-06-06 12:33:17 +02007385 SND_PCI_QUIRK(0x1043, 0x1c23, "Asus X55U", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Chris Chiuc1732ed2017-02-28 14:17:13 -06007386 SND_PCI_QUIRK(0x1043, 0x1ccd, "ASUS X555UB", ALC256_FIXUP_ASUS_MIC),
Chris Chiueeed4cd2017-02-28 14:17:15 -06007387 SND_PCI_QUIRK(0x1043, 0x3030, "ASUS ZN270IE", ALC256_FIXUP_ASUS_AIO_GPIO2),
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02007388 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC),
7389 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC),
7390 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
7391 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
David Henningssond240d1d2013-04-15 12:50:02 +02007392 SND_PCI_QUIRK(0x1043, 0x8516, "ASUS X101CH", ALC269_FIXUP_ASUS_X101),
Takashi Iwaif88abaa2014-02-07 12:07:59 +01007393 SND_PCI_QUIRK(0x104d, 0x90b5, "Sony VAIO Pro 11", ALC286_FIXUP_SONY_MIC_NO_PRESENCE),
David Henningsson88cfcf82013-10-11 10:18:45 +02007394 SND_PCI_QUIRK(0x104d, 0x90b6, "Sony VAIO Pro 13", ALC286_FIXUP_SONY_MIC_NO_PRESENCE),
Takashi Iwai1d045db2011-07-07 18:23:21 +02007395 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
7396 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
7397 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
Takashi Iwaie9bd7d52014-05-21 11:06:49 +02007398 SND_PCI_QUIRK(0x104d, 0x9099, "Sony VAIO S13", ALC275_FIXUP_SONY_DISABLE_AAMIX),
Takashi Iwai24519912011-08-16 15:08:49 +02007399 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook", ALC269_FIXUP_LIFEBOOK),
Takashi Iwai4df3fd12015-06-29 08:38:02 +02007400 SND_PCI_QUIRK(0x10cf, 0x159f, "Lifebook E780", ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT),
Takashi Iwaicc7016a2015-04-08 20:47:55 +02007401 SND_PCI_QUIRK(0x10cf, 0x15dc, "Lifebook T731", ALC269_FIXUP_LIFEBOOK_HP_PIN),
Takashi Iwai88776f32015-05-01 09:20:34 +02007402 SND_PCI_QUIRK(0x10cf, 0x1757, "Lifebook E752", ALC269_FIXUP_LIFEBOOK_HP_PIN),
Jan-Marek Glogowskifdcc9682018-02-14 11:29:15 +01007403 SND_PCI_QUIRK(0x10cf, 0x1629, "Lifebook U7x7", ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC),
David Henningsson2041d562014-06-13 11:15:44 +02007404 SND_PCI_QUIRK(0x10cf, 0x1845, "Lifebook U904", ALC269_FIXUP_LIFEBOOK_EXTMIC),
PeiSen Houb84e8432017-09-01 15:11:56 +08007405 SND_PCI_QUIRK(0x10ec, 0x10f2, "Intel Reference board", ALC700_FIXUP_INTEL_REFERENCE),
YOKOTA Hiroshi0fca97a2018-07-01 18:30:01 +09007406 SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-SZ6", ALC269_FIXUP_HEADSET_MODE),
David Henningssona33cc482014-10-07 10:18:41 +02007407 SND_PCI_QUIRK(0x144d, 0xc109, "Samsung Ativ book 9 (NP900X3G)", ALC269_FIXUP_INV_DMIC),
Gabriele Mazzotta823ff162016-12-24 19:50:01 +01007408 SND_PCI_QUIRK(0x144d, 0xc740, "Samsung Ativ book 8 (NP870Z5G)", ALC269_FIXUP_ATIV_BOOK_8),
Anisse Astierabaa22742016-08-24 09:14:13 +02007409 SND_PCI_QUIRK(0x1458, 0xfa53, "Gigabyte BXBT-2807", ALC283_FIXUP_HEADSET_MIC),
7410 SND_PCI_QUIRK(0x1462, 0xb120, "MSI Cubi MS-B120", ALC283_FIXUP_HEADSET_MIC),
Anisse Astier8cd65272018-11-23 17:59:11 +01007411 SND_PCI_QUIRK(0x1462, 0xb171, "Cubi N 8GL (MS-B171)", ALC283_FIXUP_HEADSET_MIC),
Jeremy Soller89e3a562019-01-30 16:12:31 -07007412 SND_PCI_QUIRK(0x1558, 0x1325, "System76 Darter Pro (darp5)", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
Jeremy Soller80a50522019-05-07 17:11:08 -04007413 SND_PCI_QUIRK(0x1558, 0x8550, "System76 Gazelle (gaze14)", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
Jeremy Soller891afcf2019-05-10 10:15:07 -04007414 SND_PCI_QUIRK(0x1558, 0x8551, "System76 Gazelle (gaze14)", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
7415 SND_PCI_QUIRK(0x1558, 0x8560, "System76 Gazelle (gaze14)", ALC269_FIXUP_HEADSET_MIC),
7416 SND_PCI_QUIRK(0x1558, 0x8561, "System76 Gazelle (gaze14)", ALC269_FIXUP_HEADSET_MIC),
Kailang Yangca169cc2017-04-25 16:17:40 +08007417 SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC233_FIXUP_LENOVO_MULTI_CODECS),
Takashi Iwai1d045db2011-07-07 18:23:21 +02007418 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
7419 SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
7420 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
7421 SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
7422 SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
Takashi Iwai707fba32012-08-02 09:04:39 +02007423 SND_PCI_QUIRK(0x17aa, 0x21f6, "Thinkpad T530", ALC269_FIXUP_LENOVO_DOCK),
Felix Kaechelec8415a42012-08-06 23:02:01 +02007424 SND_PCI_QUIRK(0x17aa, 0x21fa, "Thinkpad X230", ALC269_FIXUP_LENOVO_DOCK),
Stefán Freyr84f98fd2012-10-19 22:46:00 +02007425 SND_PCI_QUIRK(0x17aa, 0x21f3, "Thinkpad T430", ALC269_FIXUP_LENOVO_DOCK),
Philipp A. Mohrenweiser4407be62012-08-06 13:14:18 +02007426 SND_PCI_QUIRK(0x17aa, 0x21fb, "Thinkpad T430s", ALC269_FIXUP_LENOVO_DOCK),
David Henningsson108cc102012-07-20 10:37:25 +02007427 SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK),
David Henningssonaaedfb42013-08-16 14:09:02 +02007428 SND_PCI_QUIRK(0x17aa, 0x2208, "Thinkpad T431s", ALC269_FIXUP_LENOVO_DOCK),
Takashi Iwai9a811232015-12-09 15:17:43 +01007429 SND_PCI_QUIRK(0x17aa, 0x220c, "Thinkpad T440s", ALC292_FIXUP_TPT440),
Takashi Iwai1c37c222014-05-06 17:34:42 +02007430 SND_PCI_QUIRK(0x17aa, 0x220e, "Thinkpad T440p", ALC292_FIXUP_TPT440_DOCK),
Takashi Iwaia12137e2014-06-27 12:14:35 +02007431 SND_PCI_QUIRK(0x17aa, 0x2210, "Thinkpad T540p", ALC292_FIXUP_TPT440_DOCK),
Rick Sherman59a51a62015-08-18 21:04:30 -05007432 SND_PCI_QUIRK(0x17aa, 0x2211, "Thinkpad W541", ALC292_FIXUP_TPT440_DOCK),
Takashi Iwai6d169412014-10-07 17:27:02 +02007433 SND_PCI_QUIRK(0x17aa, 0x2212, "Thinkpad T440", ALC292_FIXUP_TPT440_DOCK),
Lukas Bossard7c215392014-10-29 18:31:07 +01007434 SND_PCI_QUIRK(0x17aa, 0x2214, "Thinkpad X240", ALC292_FIXUP_TPT440_DOCK),
David Henningssona4a9e082013-08-16 14:09:01 +02007435 SND_PCI_QUIRK(0x17aa, 0x2215, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Takashi Iwaib6903c02015-12-10 12:20:20 +01007436 SND_PCI_QUIRK(0x17aa, 0x2218, "Thinkpad X1 Carbon 2nd", ALC292_FIXUP_TPT440_DOCK),
Laura Abbottd05ea7d2015-10-02 11:09:54 -07007437 SND_PCI_QUIRK(0x17aa, 0x2223, "ThinkPad T550", ALC292_FIXUP_TPT440_DOCK),
Yves-Alexis Perezc0278662015-04-11 09:31:35 +02007438 SND_PCI_QUIRK(0x17aa, 0x2226, "ThinkPad X250", ALC292_FIXUP_TPT440_DOCK),
Kailang Yang61fcf8e2018-02-02 15:26:46 +08007439 SND_PCI_QUIRK(0x17aa, 0x222d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7440 SND_PCI_QUIRK(0x17aa, 0x222e, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
Torsten Hilbrichdab38e42016-06-07 13:14:21 +02007441 SND_PCI_QUIRK(0x17aa, 0x2231, "Thinkpad T560", ALC292_FIXUP_TPT460),
Sven Eckelmannc636b952016-04-11 16:55:26 +02007442 SND_PCI_QUIRK(0x17aa, 0x2233, "Thinkpad", ALC292_FIXUP_TPT460),
Kailang Yang61fcf8e2018-02-02 15:26:46 +08007443 SND_PCI_QUIRK(0x17aa, 0x2245, "Thinkpad T470", ALC298_FIXUP_TPT470_DOCK),
7444 SND_PCI_QUIRK(0x17aa, 0x2246, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7445 SND_PCI_QUIRK(0x17aa, 0x2247, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
Dennis Wassenberge4c07b32018-03-08 13:17:54 +01007446 SND_PCI_QUIRK(0x17aa, 0x2249, "Thinkpad", ALC292_FIXUP_TPT460),
Kailang Yang61fcf8e2018-02-02 15:26:46 +08007447 SND_PCI_QUIRK(0x17aa, 0x224b, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7448 SND_PCI_QUIRK(0x17aa, 0x224c, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7449 SND_PCI_QUIRK(0x17aa, 0x224d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
Benjamin Berg85981df2018-02-14 13:29:39 +01007450 SND_PCI_QUIRK(0x17aa, 0x225d, "Thinkpad T480", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Kailang Yang76f7dec2020-02-10 16:30:26 +08007451 SND_PCI_QUIRK(0x17aa, 0x2292, "Thinkpad X1 Yoga 7th", ALC285_FIXUP_THINKPAD_HEADSET_JACK),
7452 SND_PCI_QUIRK(0x17aa, 0x2293, "Thinkpad X1 Carbon 7th", ALC285_FIXUP_THINKPAD_HEADSET_JACK),
Hans de Goedeca707b32020-04-02 19:43:11 +02007453 SND_PCI_QUIRK(0x17aa, 0x22be, "Thinkpad X1 Carbon 8th", ALC285_FIXUP_THINKPAD_HEADSET_JACK),
Kailang3694cb22015-12-28 11:35:24 +08007454 SND_PCI_QUIRK(0x17aa, 0x30bb, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
Hui Wang6ef2f682016-03-11 12:04:02 +08007455 SND_PCI_QUIRK(0x17aa, 0x30e2, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
Hui Wangf33f79f2017-07-07 12:08:29 +08007456 SND_PCI_QUIRK(0x17aa, 0x310c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
Dennis Wassenbergbef33e12019-06-28 10:54:53 +02007457 SND_PCI_QUIRK(0x17aa, 0x3111, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
Hui Wange41fc8c2018-06-25 14:40:56 +08007458 SND_PCI_QUIRK(0x17aa, 0x312a, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
Kailang Yang65811832018-04-25 17:07:27 +08007459 SND_PCI_QUIRK(0x17aa, 0x312f, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
Hui Wang8da5bbf2017-12-22 11:17:46 +08007460 SND_PCI_QUIRK(0x17aa, 0x313c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
Hui Wang2a36c162019-09-04 13:53:27 +08007461 SND_PCI_QUIRK(0x17aa, 0x3151, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC),
Aaron Ma8a6c55d2019-10-24 19:44:39 +08007462 SND_PCI_QUIRK(0x17aa, 0x3176, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC),
7463 SND_PCI_QUIRK(0x17aa, 0x3178, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC),
David Henningsson56f27012016-01-11 09:33:14 +01007464 SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
Takashi Iwaifedb2242014-11-13 07:11:38 +01007465 SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC),
Michał Wadowski56df90b2019-05-14 16:58:00 +02007466 SND_PCI_QUIRK(0x17aa, 0x3978, "Lenovo B50-70", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
David Henningssona4a9e082013-08-16 14:09:01 +02007467 SND_PCI_QUIRK(0x17aa, 0x5013, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Kailang Yang1bb3e062013-09-27 13:10:25 +02007468 SND_PCI_QUIRK(0x17aa, 0x501a, "Thinkpad", ALC283_FIXUP_INT_MIC),
Takashi Iwaic497d9f2014-10-08 12:14:40 +02007469 SND_PCI_QUIRK(0x17aa, 0x501e, "Thinkpad L440", ALC292_FIXUP_TPT440_DOCK),
David Henningssoncd5302c2013-08-19 12:22:33 +02007470 SND_PCI_QUIRK(0x17aa, 0x5026, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Jo-Philipp Wichf2aa1112015-04-13 12:47:26 +02007471 SND_PCI_QUIRK(0x17aa, 0x5034, "Thinkpad T450", ALC292_FIXUP_TPT440_DOCK),
Sebastian Wicki80b311d2015-03-23 17:23:11 +01007472 SND_PCI_QUIRK(0x17aa, 0x5036, "Thinkpad T450s", ALC292_FIXUP_TPT440_DOCK),
Ansgar Hegerfeld09ea9972015-05-14 12:31:32 +02007473 SND_PCI_QUIRK(0x17aa, 0x503c, "Thinkpad L450", ALC292_FIXUP_TPT440_DOCK),
Conrad Kostecki037e1192016-04-26 10:08:10 +02007474 SND_PCI_QUIRK(0x17aa, 0x504a, "ThinkPad X260", ALC292_FIXUP_TPT440_DOCK),
Hui Wang23adc192015-12-08 12:27:18 +08007475 SND_PCI_QUIRK(0x17aa, 0x504b, "Thinkpad", ALC293_FIXUP_LENOVO_SPK_NOISE),
Jaroslav Kysela0f087ee2016-06-24 15:13:16 +02007476 SND_PCI_QUIRK(0x17aa, 0x5050, "Thinkpad T560p", ALC292_FIXUP_TPT460),
Torsten Hilbrich9cd25742016-07-05 10:40:22 +02007477 SND_PCI_QUIRK(0x17aa, 0x5051, "Thinkpad L460", ALC292_FIXUP_TPT460),
Jaroslav Kysela0f087ee2016-06-24 15:13:16 +02007478 SND_PCI_QUIRK(0x17aa, 0x5053, "Thinkpad T460", ALC292_FIXUP_TPT460),
Kailang Yang61fcf8e2018-02-02 15:26:46 +08007479 SND_PCI_QUIRK(0x17aa, 0x505d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7480 SND_PCI_QUIRK(0x17aa, 0x505f, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7481 SND_PCI_QUIRK(0x17aa, 0x5062, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
David Henningssoncd5302c2013-08-19 12:22:33 +02007482 SND_PCI_QUIRK(0x17aa, 0x5109, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Kailang Yang61fcf8e2018-02-02 15:26:46 +08007483 SND_PCI_QUIRK(0x17aa, 0x511e, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7484 SND_PCI_QUIRK(0x17aa, 0x511f, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
David Henningsson012e7eb2012-08-08 08:43:37 +02007485 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K),
Takashi Iwai1d045db2011-07-07 18:23:21 +02007486 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
Ayman Bagabas0fbf21c2019-05-23 05:30:11 -04007487 SND_PCI_QUIRK(0x19e5, 0x3204, "Huawei MACH-WX9", ALC256_FIXUP_HUAWEI_MACH_WX9_PINS),
Anisse Astier02b504d2013-06-03 11:53:10 +02007488 SND_PCI_QUIRK(0x1b7d, 0xa831, "Ordissimo EVE2 ", ALC269VB_FIXUP_ORDISSIMO_EVE2), /* Also known as Malata PC-B1303 */
Hui Wang695d1ec2019-11-21 10:54:27 +08007489 SND_PCI_QUIRK(0x1d72, 0x1901, "RedmiBook 14", ALC256_FIXUP_ASUS_HEADSET_MIC),
Jan-Marek Glogowskibd9c10b2019-09-15 16:57:28 +02007490 SND_PCI_QUIRK(0x10ec, 0x118c, "Medion EE4254 MD62100", ALC256_FIXUP_MEDION_HEADSET_NO_PRESENCE),
Takashi Iwaia4297b52011-08-23 18:40:12 +02007491
Takashi Iwaia7f3eed2012-02-16 13:03:18 +01007492#if 0
Takashi Iwaia4297b52011-08-23 18:40:12 +02007493 /* Below is a quirk table taken from the old code.
7494 * Basically the device should work as is without the fixup table.
7495 * If BIOS doesn't give a proper info, enable the corresponding
7496 * fixup entry.
Jesper Juhl7d7eb9e2012-04-12 22:11:25 +02007497 */
Takashi Iwaia4297b52011-08-23 18:40:12 +02007498 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
7499 ALC269_FIXUP_AMIC),
7500 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269_FIXUP_AMIC),
Takashi Iwaia4297b52011-08-23 18:40:12 +02007501 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269_FIXUP_AMIC),
7502 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_FIXUP_AMIC),
7503 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269_FIXUP_AMIC),
7504 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269_FIXUP_AMIC),
7505 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269_FIXUP_AMIC),
7506 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269_FIXUP_AMIC),
7507 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_FIXUP_AMIC),
7508 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269_FIXUP_AMIC),
7509 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_FIXUP_AMIC),
7510 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_FIXUP_AMIC),
7511 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_FIXUP_AMIC),
7512 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_FIXUP_AMIC),
7513 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_FIXUP_AMIC),
7514 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_FIXUP_AMIC),
7515 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_FIXUP_AMIC),
7516 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_FIXUP_AMIC),
7517 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_FIXUP_AMIC),
7518 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_FIXUP_AMIC),
7519 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_FIXUP_AMIC),
7520 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_FIXUP_AMIC),
7521 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_FIXUP_AMIC),
7522 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_FIXUP_AMIC),
7523 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_FIXUP_AMIC),
7524 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_FIXUP_AMIC),
7525 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_FIXUP_AMIC),
7526 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_FIXUP_AMIC),
7527 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_FIXUP_AMIC),
7528 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_FIXUP_AMIC),
7529 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_FIXUP_AMIC),
7530 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_FIXUP_AMIC),
7531 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_FIXUP_AMIC),
7532 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_FIXUP_AMIC),
7533 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_FIXUP_AMIC),
7534 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_FIXUP_DMIC),
7535 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_FIXUP_AMIC),
7536 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_AMIC),
7537 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_FIXUP_DMIC),
7538 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_FIXUP_DMIC),
7539#endif
7540 {}
7541};
7542
David Henningsson214eef72014-07-22 14:09:35 +02007543static const struct snd_pci_quirk alc269_fixup_vendor_tbl[] = {
7544 SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC),
7545 SND_PCI_QUIRK_VENDOR(0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED),
7546 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
7547 SND_PCI_QUIRK_VENDOR(0x17aa, "Thinkpad", ALC269_FIXUP_THINKPAD_ACPI),
Ayman Bagabas0fbf21c2019-05-23 05:30:11 -04007548 SND_PCI_QUIRK_VENDOR(0x19e5, "Huawei Matebook", ALC255_FIXUP_MIC_MUTE_LED),
David Henningsson214eef72014-07-22 14:09:35 +02007549 {}
7550};
7551
Takashi Iwai1727a772013-01-10 09:52:52 +01007552static const struct hda_model_fixup alc269_fixup_models[] = {
Takashi Iwaia4297b52011-08-23 18:40:12 +02007553 {.id = ALC269_FIXUP_AMIC, .name = "laptop-amic"},
7554 {.id = ALC269_FIXUP_DMIC, .name = "laptop-dmic"},
Takashi Iwai6e72aa52012-06-25 10:52:25 +02007555 {.id = ALC269_FIXUP_STEREO_DMIC, .name = "alc269-dmic"},
7556 {.id = ALC271_FIXUP_DMIC, .name = "alc271-dmic"},
7557 {.id = ALC269_FIXUP_INV_DMIC, .name = "inv-dmic"},
David Henningsson7c478f02013-10-11 10:18:46 +02007558 {.id = ALC269_FIXUP_HEADSET_MIC, .name = "headset-mic"},
Takashi Iwaib0169512015-05-19 10:20:13 +02007559 {.id = ALC269_FIXUP_HEADSET_MODE, .name = "headset-mode"},
7560 {.id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC, .name = "headset-mode-no-hp-mic"},
David Henningsson108cc102012-07-20 10:37:25 +02007561 {.id = ALC269_FIXUP_LENOVO_DOCK, .name = "lenovo-dock"},
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01007562 {.id = ALC269_FIXUP_HP_GPIO_LED, .name = "hp-gpio-led"},
Jaroslav Kysela04d54662017-03-09 13:29:13 +01007563 {.id = ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED, .name = "hp-dock-gpio-mic1-led"},
David Henningssone32aa852013-06-17 11:04:02 +02007564 {.id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "dell-headset-multi"},
7565 {.id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE, .name = "dell-headset-dock"},
Takashi Iwaia26d96c2018-06-26 15:09:25 +02007566 {.id = ALC269_FIXUP_DELL3_MIC_NO_PRESENCE, .name = "dell-headset3"},
7567 {.id = ALC269_FIXUP_DELL4_MIC_NO_PRESENCE, .name = "dell-headset4"},
Kailang Yangbe8ef162014-04-08 15:19:49 +08007568 {.id = ALC283_FIXUP_CHROME_BOOK, .name = "alc283-dac-wcaps"},
Kailang Yang0202e992013-12-02 15:20:15 +08007569 {.id = ALC283_FIXUP_SENSE_COMBO_JACK, .name = "alc283-sense-combo"},
Takashi Iwai1c37c222014-05-06 17:34:42 +02007570 {.id = ALC292_FIXUP_TPT440_DOCK, .name = "tpt440-dock"},
Takashi Iwai9a811232015-12-09 15:17:43 +01007571 {.id = ALC292_FIXUP_TPT440, .name = "tpt440"},
Sven Eckelmannc636b952016-04-11 16:55:26 +02007572 {.id = ALC292_FIXUP_TPT460, .name = "tpt460"},
Takashi Iwaia26d96c2018-06-26 15:09:25 +02007573 {.id = ALC298_FIXUP_TPT470_DOCK, .name = "tpt470-dock"},
Takashi Iwaiba90d6a2017-05-22 16:38:47 +02007574 {.id = ALC233_FIXUP_LENOVO_MULTI_CODECS, .name = "dual-codecs"},
Takashi Iwai28d1d6d2017-10-18 14:01:58 +02007575 {.id = ALC700_FIXUP_INTEL_REFERENCE, .name = "alc700-ref"},
Takashi Iwaia26d96c2018-06-26 15:09:25 +02007576 {.id = ALC269_FIXUP_SONY_VAIO, .name = "vaio"},
7577 {.id = ALC269_FIXUP_DELL_M101Z, .name = "dell-m101z"},
7578 {.id = ALC269_FIXUP_ASUS_G73JW, .name = "asus-g73jw"},
7579 {.id = ALC269_FIXUP_LENOVO_EAPD, .name = "lenovo-eapd"},
7580 {.id = ALC275_FIXUP_SONY_HWEQ, .name = "sony-hweq"},
7581 {.id = ALC269_FIXUP_PCM_44K, .name = "pcm44k"},
7582 {.id = ALC269_FIXUP_LIFEBOOK, .name = "lifebook"},
7583 {.id = ALC269_FIXUP_LIFEBOOK_EXTMIC, .name = "lifebook-extmic"},
7584 {.id = ALC269_FIXUP_LIFEBOOK_HP_PIN, .name = "lifebook-hp-pin"},
7585 {.id = ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC, .name = "lifebook-u7x7"},
7586 {.id = ALC269VB_FIXUP_AMIC, .name = "alc269vb-amic"},
7587 {.id = ALC269VB_FIXUP_DMIC, .name = "alc269vb-dmic"},
7588 {.id = ALC269_FIXUP_HP_MUTE_LED_MIC1, .name = "hp-mute-led-mic1"},
7589 {.id = ALC269_FIXUP_HP_MUTE_LED_MIC2, .name = "hp-mute-led-mic2"},
7590 {.id = ALC269_FIXUP_HP_MUTE_LED_MIC3, .name = "hp-mute-led-mic3"},
7591 {.id = ALC269_FIXUP_HP_GPIO_MIC1_LED, .name = "hp-gpio-mic1"},
7592 {.id = ALC269_FIXUP_HP_LINE1_MIC1_LED, .name = "hp-line1-mic1"},
7593 {.id = ALC269_FIXUP_NO_SHUTUP, .name = "noshutup"},
7594 {.id = ALC286_FIXUP_SONY_MIC_NO_PRESENCE, .name = "sony-nomic"},
7595 {.id = ALC269_FIXUP_ASPIRE_HEADSET_MIC, .name = "aspire-headset-mic"},
7596 {.id = ALC269_FIXUP_ASUS_X101, .name = "asus-x101"},
7597 {.id = ALC271_FIXUP_HP_GATE_MIC_JACK, .name = "acer-ao7xx"},
7598 {.id = ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572, .name = "acer-aspire-e1"},
7599 {.id = ALC269_FIXUP_ACER_AC700, .name = "acer-ac700"},
7600 {.id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST, .name = "limit-mic-boost"},
7601 {.id = ALC269VB_FIXUP_ASUS_ZENBOOK, .name = "asus-zenbook"},
7602 {.id = ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A, .name = "asus-zenbook-ux31a"},
7603 {.id = ALC269VB_FIXUP_ORDISSIMO_EVE2, .name = "ordissimo"},
7604 {.id = ALC282_FIXUP_ASUS_TX300, .name = "asus-tx300"},
7605 {.id = ALC283_FIXUP_INT_MIC, .name = "alc283-int-mic"},
7606 {.id = ALC290_FIXUP_MONO_SPEAKERS_HSJACK, .name = "mono-speakers"},
7607 {.id = ALC290_FIXUP_SUBWOOFER_HSJACK, .name = "alc290-subwoofer"},
7608 {.id = ALC269_FIXUP_THINKPAD_ACPI, .name = "thinkpad"},
7609 {.id = ALC269_FIXUP_DMIC_THINKPAD_ACPI, .name = "dmic-thinkpad"},
7610 {.id = ALC255_FIXUP_ACER_MIC_NO_PRESENCE, .name = "alc255-acer"},
7611 {.id = ALC255_FIXUP_ASUS_MIC_NO_PRESENCE, .name = "alc255-asus"},
7612 {.id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc255-dell1"},
7613 {.id = ALC255_FIXUP_DELL2_MIC_NO_PRESENCE, .name = "alc255-dell2"},
7614 {.id = ALC293_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc293-dell1"},
7615 {.id = ALC283_FIXUP_HEADSET_MIC, .name = "alc283-headset"},
Takashi Iwaib3802782018-11-26 17:47:46 +01007616 {.id = ALC255_FIXUP_MIC_MUTE_LED, .name = "alc255-dell-mute"},
Takashi Iwaia26d96c2018-06-26 15:09:25 +02007617 {.id = ALC282_FIXUP_ASPIRE_V5_PINS, .name = "aspire-v5"},
7618 {.id = ALC280_FIXUP_HP_GPIO4, .name = "hp-gpio4"},
7619 {.id = ALC286_FIXUP_HP_GPIO_LED, .name = "hp-gpio-led"},
7620 {.id = ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY, .name = "hp-gpio2-hotkey"},
7621 {.id = ALC280_FIXUP_HP_DOCK_PINS, .name = "hp-dock-pins"},
7622 {.id = ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED, .name = "hp-dock-gpio-mic"},
7623 {.id = ALC280_FIXUP_HP_9480M, .name = "hp-9480m"},
7624 {.id = ALC288_FIXUP_DELL_HEADSET_MODE, .name = "alc288-dell-headset"},
7625 {.id = ALC288_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc288-dell1"},
7626 {.id = ALC288_FIXUP_DELL_XPS_13, .name = "alc288-dell-xps13"},
7627 {.id = ALC292_FIXUP_DELL_E7X, .name = "dell-e7x"},
7628 {.id = ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK, .name = "alc293-dell"},
7629 {.id = ALC298_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc298-dell1"},
7630 {.id = ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE, .name = "alc298-dell-aio"},
7631 {.id = ALC275_FIXUP_DELL_XPS, .name = "alc275-dell-xps"},
Takashi Iwaia26d96c2018-06-26 15:09:25 +02007632 {.id = ALC293_FIXUP_LENOVO_SPK_NOISE, .name = "lenovo-spk-noise"},
7633 {.id = ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY, .name = "lenovo-hotkey"},
7634 {.id = ALC255_FIXUP_DELL_SPK_NOISE, .name = "dell-spk-noise"},
Kailang Yang82aa0d72019-01-11 17:15:53 +08007635 {.id = ALC225_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc225-dell1"},
Takashi Iwaia26d96c2018-06-26 15:09:25 +02007636 {.id = ALC295_FIXUP_DISABLE_DAC3, .name = "alc295-disable-dac3"},
Jaroslav Kyselad2cd7952019-11-29 15:40:27 +01007637 {.id = ALC285_FIXUP_SPEAKER2_TO_DAC1, .name = "alc285-speaker2-to-dac1"},
Takashi Iwaia26d96c2018-06-26 15:09:25 +02007638 {.id = ALC280_FIXUP_HP_HEADSET_MIC, .name = "alc280-hp-headset"},
7639 {.id = ALC221_FIXUP_HP_FRONT_MIC, .name = "alc221-hp-mic"},
7640 {.id = ALC298_FIXUP_SPK_VOLUME, .name = "alc298-spk-volume"},
7641 {.id = ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER, .name = "dell-inspiron-7559"},
7642 {.id = ALC269_FIXUP_ATIV_BOOK_8, .name = "ativ-book"},
7643 {.id = ALC221_FIXUP_HP_MIC_NO_PRESENCE, .name = "alc221-hp-mic"},
7644 {.id = ALC256_FIXUP_ASUS_HEADSET_MODE, .name = "alc256-asus-headset"},
7645 {.id = ALC256_FIXUP_ASUS_MIC, .name = "alc256-asus-mic"},
7646 {.id = ALC256_FIXUP_ASUS_AIO_GPIO2, .name = "alc256-asus-aio"},
7647 {.id = ALC233_FIXUP_ASUS_MIC_NO_PRESENCE, .name = "alc233-asus"},
7648 {.id = ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE, .name = "alc233-eapd"},
7649 {.id = ALC294_FIXUP_LENOVO_MIC_LOCATION, .name = "alc294-lenovo-mic"},
7650 {.id = ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE, .name = "alc225-wyse"},
7651 {.id = ALC274_FIXUP_DELL_AIO_LINEOUT_VERB, .name = "alc274-dell-aio"},
7652 {.id = ALC255_FIXUP_DUMMY_LINEOUT_VERB, .name = "alc255-dummy-lineout"},
7653 {.id = ALC255_FIXUP_DELL_HEADSET_MIC, .name = "alc255-dell-headset"},
7654 {.id = ALC295_FIXUP_HP_X360, .name = "alc295-hp-x360"},
Kailang Yang8983eb62019-04-03 15:31:49 +08007655 {.id = ALC225_FIXUP_HEADSET_JACK, .name = "alc-headset-jack"},
7656 {.id = ALC295_FIXUP_CHROME_BOOK, .name = "alc-chrome-book"},
Bernhard Rosenkraenzere2a829b2019-03-05 00:38:19 +01007657 {.id = ALC299_FIXUP_PREDATOR_SPK, .name = "predator-spk"},
Tomas Espeletaa2ef03f2019-08-09 16:37:54 +02007658 {.id = ALC298_FIXUP_HUAWEI_MBX_STEREO, .name = "huawei-mbx-stereo"},
Jan-Marek Glogowskibd9c10b2019-09-15 16:57:28 +02007659 {.id = ALC256_FIXUP_MEDION_HEADSET_NO_PRESENCE, .name = "alc256-medion-headset"},
Takashi Iwai1d045db2011-07-07 18:23:21 +02007660 {}
7661};
Kailang Yangcfc5a842016-02-03 15:20:39 +08007662#define ALC225_STANDARD_PINS \
Kailang Yangcfc5a842016-02-03 15:20:39 +08007663 {0x21, 0x04211020}
Takashi Iwai1d045db2011-07-07 18:23:21 +02007664
Hui Wange8191a82015-04-24 13:39:59 +08007665#define ALC256_STANDARD_PINS \
7666 {0x12, 0x90a60140}, \
7667 {0x14, 0x90170110}, \
Hui Wange8191a82015-04-24 13:39:59 +08007668 {0x21, 0x02211020}
7669
David Henningssonfea185e2014-09-03 10:23:04 +02007670#define ALC282_STANDARD_PINS \
Hui Wang11580292015-08-03 11:03:49 +08007671 {0x14, 0x90170110}
Kailang Yange1e62b92015-04-08 16:01:22 +08007672
David Henningssonfea185e2014-09-03 10:23:04 +02007673#define ALC290_STANDARD_PINS \
Hui Wang11580292015-08-03 11:03:49 +08007674 {0x12, 0x99a30130}
David Henningssonfea185e2014-09-03 10:23:04 +02007675
7676#define ALC292_STANDARD_PINS \
7677 {0x14, 0x90170110}, \
Hui Wang11580292015-08-03 11:03:49 +08007678 {0x15, 0x0221401f}
Kailang Yang977e6272015-05-18 15:31:20 +08007679
Hui Wang3f6409702016-09-11 11:26:16 +08007680#define ALC295_STANDARD_PINS \
7681 {0x12, 0xb7a60130}, \
7682 {0x14, 0x90170110}, \
Hui Wang3f6409702016-09-11 11:26:16 +08007683 {0x21, 0x04211020}
7684
Woodrow Shen703867e2015-08-05 12:34:12 +08007685#define ALC298_STANDARD_PINS \
7686 {0x12, 0x90a60130}, \
7687 {0x21, 0x03211020}
7688
Hui Wange1918932014-05-26 16:22:44 +08007689static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
Kailang Yang8a328ac2018-08-21 16:54:41 +08007690 SND_HDA_PIN_QUIRK(0x10ec0221, 0x103c, "HP Workstation", ALC221_FIXUP_HP_HEADSET_MIC,
7691 {0x14, 0x01014020},
7692 {0x17, 0x90170110},
7693 {0x18, 0x02a11030},
7694 {0x19, 0x0181303F},
7695 {0x21, 0x0221102f}),
Chris Chiu5824ce82017-02-28 14:17:11 -06007696 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1025, "Acer", ALC255_FIXUP_ACER_MIC_NO_PRESENCE,
7697 {0x12, 0x90a601c0},
7698 {0x14, 0x90171120},
7699 {0x21, 0x02211030}),
Chris Chiu615966a2017-02-28 14:17:12 -06007700 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1043, "ASUS", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE,
7701 {0x14, 0x90170110},
7702 {0x1b, 0x90a70130},
7703 {0x21, 0x03211020}),
7704 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1043, "ASUS", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE,
7705 {0x1a, 0x90a70130},
7706 {0x1b, 0x90170110},
7707 {0x21, 0x03211020}),
David Henningsson2ae95572016-02-25 09:37:05 +01007708 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
Kailang Yangcfc5a842016-02-03 15:20:39 +08007709 ALC225_STANDARD_PINS,
Hui Wang8a132092016-07-08 14:26:57 +08007710 {0x12, 0xb7a60130},
Kailang Yangcfc5a842016-02-03 15:20:39 +08007711 {0x14, 0x901701a0}),
David Henningsson2ae95572016-02-25 09:37:05 +01007712 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
Kailang Yangcfc5a842016-02-03 15:20:39 +08007713 ALC225_STANDARD_PINS,
Hui Wang8a132092016-07-08 14:26:57 +08007714 {0x12, 0xb7a60130},
Kailang Yangcfc5a842016-02-03 15:20:39 +08007715 {0x14, 0x901701b0}),
Hui Wang8a132092016-07-08 14:26:57 +08007716 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
7717 ALC225_STANDARD_PINS,
7718 {0x12, 0xb7a60150},
7719 {0x14, 0x901701a0}),
7720 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
7721 ALC225_STANDARD_PINS,
7722 {0x12, 0xb7a60150},
7723 {0x14, 0x901701b0}),
7724 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
7725 ALC225_STANDARD_PINS,
7726 {0x12, 0xb7a60130},
7727 {0x1b, 0x90170110}),
Kai-Heng Feng0ce48e12017-11-20 02:29:13 -05007728 SND_HDA_PIN_QUIRK(0x10ec0233, 0x8086, "Intel NUC Skull Canyon", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
7729 {0x1b, 0x01111010},
7730 {0x1e, 0x01451130},
7731 {0x21, 0x02211020}),
Hui Wang986376b2018-05-30 12:33:07 +08007732 SND_HDA_PIN_QUIRK(0x10ec0235, 0x17aa, "Lenovo", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY,
7733 {0x12, 0x90a60140},
7734 {0x14, 0x90170110},
7735 {0x19, 0x02a11030},
7736 {0x21, 0x02211020}),
Hui Wange41fc8c2018-06-25 14:40:56 +08007737 SND_HDA_PIN_QUIRK(0x10ec0235, 0x17aa, "Lenovo", ALC294_FIXUP_LENOVO_MIC_LOCATION,
7738 {0x14, 0x90170110},
7739 {0x19, 0x02a11030},
7740 {0x1a, 0x02a11040},
7741 {0x1b, 0x01014020},
7742 {0x21, 0x0221101f}),
Hui Wangc6b17f12018-07-06 15:14:11 +08007743 SND_HDA_PIN_QUIRK(0x10ec0235, 0x17aa, "Lenovo", ALC294_FIXUP_LENOVO_MIC_LOCATION,
7744 {0x14, 0x90170110},
Hui Wangd06fb562018-10-10 11:57:25 +08007745 {0x19, 0x02a11030},
7746 {0x1a, 0x02a11040},
7747 {0x1b, 0x01011020},
7748 {0x21, 0x0221101f}),
7749 SND_HDA_PIN_QUIRK(0x10ec0235, 0x17aa, "Lenovo", ALC294_FIXUP_LENOVO_MIC_LOCATION,
7750 {0x14, 0x90170110},
Hui Wangc6b17f12018-07-06 15:14:11 +08007751 {0x19, 0x02a11020},
7752 {0x1a, 0x02a11030},
7753 {0x21, 0x0221101f}),
Hui Wangc77900e2014-09-03 11:31:07 +08007754 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE,
Hui Wangc77900e2014-09-03 11:31:07 +08007755 {0x14, 0x90170110},
Hui Wangc77900e2014-09-03 11:31:07 +08007756 {0x21, 0x02211020}),
David Henningsson76c21322014-06-24 14:46:54 +02007757 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang86c72d12016-05-25 12:12:32 +08007758 {0x14, 0x90170130},
7759 {0x21, 0x02211040}),
7760 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningsson76c21322014-06-24 14:46:54 +02007761 {0x12, 0x90a60140},
7762 {0x14, 0x90170110},
David Henningsson76c21322014-06-24 14:46:54 +02007763 {0x21, 0x02211020}),
7764 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7765 {0x12, 0x90a60160},
7766 {0x14, 0x90170120},
David Henningsson76c21322014-06-24 14:46:54 +02007767 {0x21, 0x02211030}),
7768 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang392c9da2016-09-26 10:59:38 +08007769 {0x14, 0x90170110},
7770 {0x1b, 0x02011020},
7771 {0x21, 0x0221101f}),
7772 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang6aecd872016-10-20 14:03:33 +08007773 {0x14, 0x90170110},
7774 {0x1b, 0x01011020},
7775 {0x21, 0x0221101f}),
7776 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssoncba59972015-07-22 10:00:25 +02007777 {0x14, 0x90170130},
David Henningssoncba59972015-07-22 10:00:25 +02007778 {0x1b, 0x01014020},
David Henningssoncba59972015-07-22 10:00:25 +02007779 {0x21, 0x0221103f}),
7780 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang59ec4b52016-08-04 15:28:04 +08007781 {0x14, 0x90170130},
Hui Wang6aecd872016-10-20 14:03:33 +08007782 {0x1b, 0x01011020},
7783 {0x21, 0x0221103f}),
7784 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7785 {0x14, 0x90170130},
Hui Wang59ec4b52016-08-04 15:28:04 +08007786 {0x1b, 0x02011020},
7787 {0x21, 0x0221103f}),
7788 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Woodrow Shene9c28e12015-07-25 10:36:16 +08007789 {0x14, 0x90170150},
Woodrow Shene9c28e12015-07-25 10:36:16 +08007790 {0x1b, 0x02011020},
Woodrow Shene9c28e12015-07-25 10:36:16 +08007791 {0x21, 0x0221105f}),
7792 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Woodrow Shene9c28e12015-07-25 10:36:16 +08007793 {0x14, 0x90170110},
Woodrow Shene9c28e12015-07-25 10:36:16 +08007794 {0x1b, 0x01014020},
Woodrow Shene9c28e12015-07-25 10:36:16 +08007795 {0x21, 0x0221101f}),
7796 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningsson76c21322014-06-24 14:46:54 +02007797 {0x12, 0x90a60160},
7798 {0x14, 0x90170120},
7799 {0x17, 0x90170140},
David Henningsson76c21322014-06-24 14:46:54 +02007800 {0x21, 0x0321102f}),
7801 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7802 {0x12, 0x90a60160},
7803 {0x14, 0x90170130},
David Henningsson76c21322014-06-24 14:46:54 +02007804 {0x21, 0x02211040}),
7805 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7806 {0x12, 0x90a60160},
7807 {0x14, 0x90170140},
David Henningsson76c21322014-06-24 14:46:54 +02007808 {0x21, 0x02211050}),
7809 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7810 {0x12, 0x90a60170},
7811 {0x14, 0x90170120},
David Henningsson76c21322014-06-24 14:46:54 +02007812 {0x21, 0x02211030}),
7813 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7814 {0x12, 0x90a60170},
7815 {0x14, 0x90170130},
David Henningsson76c21322014-06-24 14:46:54 +02007816 {0x21, 0x02211040}),
Hui Wang70658b92015-03-06 14:03:57 +08007817 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang70658b92015-03-06 14:03:57 +08007818 {0x12, 0x90a60170},
Hui Wang0a1f90a2016-01-13 11:51:38 +08007819 {0x14, 0x90171130},
7820 {0x21, 0x02211040}),
7821 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7822 {0x12, 0x90a60170},
Hui Wang70658b92015-03-06 14:03:57 +08007823 {0x14, 0x90170140},
Hui Wang70658b92015-03-06 14:03:57 +08007824 {0x21, 0x02211050}),
David Henningsson9b5a4e32015-05-11 14:04:14 +02007825 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell Inspiron 5548", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningsson9b5a4e32015-05-11 14:04:14 +02007826 {0x12, 0x90a60180},
7827 {0x14, 0x90170130},
David Henningsson9b5a4e32015-05-11 14:04:14 +02007828 {0x21, 0x02211040}),
AceLan Kaof90d83b2016-06-03 14:45:25 +08007829 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell Inspiron 5565", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7830 {0x12, 0x90a60180},
7831 {0x14, 0x90170120},
7832 {0x21, 0x02211030}),
Hui Wang989dbe42016-11-23 16:05:38 +08007833 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7834 {0x1b, 0x01011020},
7835 {0x21, 0x02211010}),
Chris Chiuc1732ed2017-02-28 14:17:13 -06007836 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC,
7837 {0x14, 0x90170110},
7838 {0x1b, 0x90a70130},
7839 {0x21, 0x04211020}),
7840 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC,
7841 {0x14, 0x90170110},
7842 {0x1b, 0x90a70130},
7843 {0x21, 0x03211020}),
Jian-Hong Pane1037352019-03-22 11:37:18 +08007844 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE,
Chris Chiua806ef12019-03-22 11:37:20 +08007845 {0x12, 0x90a60130},
7846 {0x14, 0x90170110},
7847 {0x21, 0x03211020}),
7848 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE,
Jian-Hong Pan6ac371a2019-03-22 11:37:22 +08007849 {0x12, 0x90a60130},
7850 {0x14, 0x90170110},
7851 {0x21, 0x04211020}),
7852 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE,
Jian-Hong Pane1037352019-03-22 11:37:18 +08007853 {0x1a, 0x90a70130},
7854 {0x1b, 0x90170110},
7855 {0x21, 0x03211020}),
David Henningssoncf51eb92014-10-30 08:26:02 +01007856 SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC280_FIXUP_HP_GPIO4,
7857 {0x12, 0x90a60130},
David Henningssoncf51eb92014-10-30 08:26:02 +01007858 {0x14, 0x90170110},
7859 {0x15, 0x0421101f},
Hui Wang11580292015-08-03 11:03:49 +08007860 {0x1a, 0x04a11020}),
Hui Wang02796612014-09-03 11:31:11 +08007861 SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED,
7862 {0x12, 0x90a60140},
Hui Wang02796612014-09-03 11:31:11 +08007863 {0x14, 0x90170110},
7864 {0x15, 0x0421101f},
Hui Wang02796612014-09-03 11:31:11 +08007865 {0x18, 0x02811030},
Hui Wang02796612014-09-03 11:31:11 +08007866 {0x1a, 0x04a1103f},
Hui Wang11580292015-08-03 11:03:49 +08007867 {0x1b, 0x02011020}),
David Henningsson42304472014-07-22 11:42:17 +02007868 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP 15 Touchsmart", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007869 ALC282_STANDARD_PINS,
David Henningsson42304472014-07-22 11:42:17 +02007870 {0x12, 0x99a30130},
David Henningsson42304472014-07-22 11:42:17 +02007871 {0x19, 0x03a11020},
David Henningsson42304472014-07-22 11:42:17 +02007872 {0x21, 0x0321101f}),
Hui Wang2c609992014-09-03 11:31:08 +08007873 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007874 ALC282_STANDARD_PINS,
Hui Wang2c609992014-09-03 11:31:08 +08007875 {0x12, 0x99a30130},
Hui Wang2c609992014-09-03 11:31:08 +08007876 {0x19, 0x03a11020},
Hui Wang2c609992014-09-03 11:31:08 +08007877 {0x21, 0x03211040}),
7878 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007879 ALC282_STANDARD_PINS,
Hui Wang2c609992014-09-03 11:31:08 +08007880 {0x12, 0x99a30130},
Hui Wang2c609992014-09-03 11:31:08 +08007881 {0x19, 0x03a11030},
Hui Wang2c609992014-09-03 11:31:08 +08007882 {0x21, 0x03211020}),
7883 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007884 ALC282_STANDARD_PINS,
Hui Wang2c609992014-09-03 11:31:08 +08007885 {0x12, 0x99a30130},
Hui Wang2c609992014-09-03 11:31:08 +08007886 {0x19, 0x04a11020},
Hui Wang2c609992014-09-03 11:31:08 +08007887 {0x21, 0x0421101f}),
Hui Wang200afc02014-09-03 11:31:10 +08007888 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED,
David Henningssonaec856d2014-09-03 10:23:05 +02007889 ALC282_STANDARD_PINS,
Hui Wang200afc02014-09-03 11:31:10 +08007890 {0x12, 0x90a60140},
Hui Wang200afc02014-09-03 11:31:10 +08007891 {0x19, 0x04a11030},
Hui Wang200afc02014-09-03 11:31:10 +08007892 {0x21, 0x04211020}),
David Henningsson76c21322014-06-24 14:46:54 +02007893 SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007894 ALC282_STANDARD_PINS,
David Henningsson76c21322014-06-24 14:46:54 +02007895 {0x12, 0x90a60130},
David Henningsson76c21322014-06-24 14:46:54 +02007896 {0x21, 0x0321101f}),
7897 SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
7898 {0x12, 0x90a60160},
7899 {0x14, 0x90170120},
David Henningsson76c21322014-06-24 14:46:54 +02007900 {0x21, 0x02211030}),
Hui Wangbc262172014-09-03 11:31:05 +08007901 SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007902 ALC282_STANDARD_PINS,
Hui Wangbc262172014-09-03 11:31:05 +08007903 {0x12, 0x90a60130},
Hui Wangbc262172014-09-03 11:31:05 +08007904 {0x19, 0x03a11020},
Hui Wangbc262172014-09-03 11:31:05 +08007905 {0x21, 0x0321101f}),
Hui Wangc8c6ee62019-02-14 11:41:33 +08007906 SND_HDA_PIN_QUIRK(0x10ec0285, 0x17aa, "Lenovo", ALC285_FIXUP_LENOVO_PC_BEEP_IN_NOISE,
Hui Wangc4cfcf62018-11-26 14:17:16 +08007907 {0x12, 0x90a60130},
7908 {0x14, 0x90170110},
7909 {0x19, 0x04a11040},
7910 {0x21, 0x04211020}),
Chris Chiu33aaebd2018-12-05 14:48:53 +08007911 SND_HDA_PIN_QUIRK(0x10ec0286, 0x1025, "Acer", ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE,
7912 {0x12, 0x90a60130},
7913 {0x17, 0x90170110},
7914 {0x21, 0x02211020}),
Takashi Iwaid44a6862018-06-19 23:04:03 +02007915 SND_HDA_PIN_QUIRK(0x10ec0288, 0x1028, "Dell", ALC288_FIXUP_DELL1_MIC_NO_PRESENCE,
Kailang Yange1e62b92015-04-08 16:01:22 +08007916 {0x12, 0x90a60120},
Kailang Yange1e62b92015-04-08 16:01:22 +08007917 {0x14, 0x90170110},
Kailang Yange1e62b92015-04-08 16:01:22 +08007918 {0x21, 0x0321101f}),
Hui Wange4442bc2014-09-03 11:31:09 +08007919 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007920 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08007921 {0x15, 0x04211040},
Hui Wange4442bc2014-09-03 11:31:09 +08007922 {0x18, 0x90170112},
Hui Wang11580292015-08-03 11:03:49 +08007923 {0x1a, 0x04a11020}),
Hui Wange4442bc2014-09-03 11:31:09 +08007924 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007925 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08007926 {0x15, 0x04211040},
Hui Wange4442bc2014-09-03 11:31:09 +08007927 {0x18, 0x90170110},
Hui Wang11580292015-08-03 11:03:49 +08007928 {0x1a, 0x04a11020}),
Hui Wange4442bc2014-09-03 11:31:09 +08007929 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007930 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08007931 {0x15, 0x0421101f},
Hui Wang11580292015-08-03 11:03:49 +08007932 {0x1a, 0x04a11020}),
Hui Wange4442bc2014-09-03 11:31:09 +08007933 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007934 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08007935 {0x15, 0x04211020},
Hui Wang11580292015-08-03 11:03:49 +08007936 {0x1a, 0x04a11040}),
Hui Wange4442bc2014-09-03 11:31:09 +08007937 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007938 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08007939 {0x14, 0x90170110},
7940 {0x15, 0x04211020},
Hui Wang11580292015-08-03 11:03:49 +08007941 {0x1a, 0x04a11040}),
Hui Wange4442bc2014-09-03 11:31:09 +08007942 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007943 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08007944 {0x14, 0x90170110},
7945 {0x15, 0x04211020},
Hui Wang11580292015-08-03 11:03:49 +08007946 {0x1a, 0x04a11020}),
Hui Wange4442bc2014-09-03 11:31:09 +08007947 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007948 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08007949 {0x14, 0x90170110},
7950 {0x15, 0x0421101f},
Hui Wang11580292015-08-03 11:03:49 +08007951 {0x1a, 0x04a11020}),
Hui Wange8818fa2014-09-03 11:31:04 +08007952 SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007953 ALC292_STANDARD_PINS,
Hui Wange8818fa2014-09-03 11:31:04 +08007954 {0x12, 0x90a60140},
Hui Wange8818fa2014-09-03 11:31:04 +08007955 {0x16, 0x01014020},
Hui Wang11580292015-08-03 11:03:49 +08007956 {0x19, 0x01a19030}),
Hui Wange8818fa2014-09-03 11:31:04 +08007957 SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007958 ALC292_STANDARD_PINS,
Hui Wange8818fa2014-09-03 11:31:04 +08007959 {0x12, 0x90a60140},
Hui Wange8818fa2014-09-03 11:31:04 +08007960 {0x16, 0x01014020},
7961 {0x18, 0x02a19031},
Hui Wang11580292015-08-03 11:03:49 +08007962 {0x19, 0x01a1903e}),
David Henningsson76c21322014-06-24 14:46:54 +02007963 SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007964 ALC292_STANDARD_PINS,
Hui Wang11580292015-08-03 11:03:49 +08007965 {0x12, 0x90a60140}),
David Henningsson76c21322014-06-24 14:46:54 +02007966 SND_HDA_PIN_QUIRK(0x10ec0293, 0x1028, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007967 ALC292_STANDARD_PINS,
David Henningsson76c21322014-06-24 14:46:54 +02007968 {0x13, 0x90a60140},
David Henningsson76c21322014-06-24 14:46:54 +02007969 {0x16, 0x21014020},
Hui Wang11580292015-08-03 11:03:49 +08007970 {0x19, 0x21a19030}),
David Henningssone03fdbd2014-06-27 08:41:59 +02007971 SND_HDA_PIN_QUIRK(0x10ec0293, 0x1028, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007972 ALC292_STANDARD_PINS,
Hui Wang11580292015-08-03 11:03:49 +08007973 {0x13, 0x90a60140}),
Chris Chiud8ae4582018-12-07 17:17:11 +08007974 SND_HDA_PIN_QUIRK(0x10ec0294, 0x1043, "ASUS", ALC294_FIXUP_ASUS_MIC,
7975 {0x14, 0x90170110},
7976 {0x1b, 0x90a70130},
7977 {0x21, 0x04211020}),
Jian-Hong Pan0bea4cc2018-12-07 17:17:13 +08007978 SND_HDA_PIN_QUIRK(0x10ec0294, 0x1043, "ASUS", ALC294_FIXUP_ASUS_SPK,
7979 {0x12, 0x90a60130},
7980 {0x17, 0x90170110},
Jian-Hong Pan8bb37a22019-02-21 17:00:18 +08007981 {0x21, 0x03211020}),
7982 SND_HDA_PIN_QUIRK(0x10ec0294, 0x1043, "ASUS", ALC294_FIXUP_ASUS_SPK,
7983 {0x12, 0x90a60130},
7984 {0x17, 0x90170110},
Jian-Hong Pan0bea4cc2018-12-07 17:17:13 +08007985 {0x21, 0x04211020}),
Takashi Iwai3887c262019-04-30 15:10:01 +02007986 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1043, "ASUS", ALC294_FIXUP_ASUS_SPK,
7987 {0x12, 0x90a60130},
7988 {0x17, 0x90170110},
7989 {0x21, 0x03211020}),
Kailang Yangfbc57122019-07-15 10:41:50 +08007990 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
Kailang Yang0a29c572019-04-24 16:34:25 +08007991 {0x14, 0x90170110},
7992 {0x21, 0x04211020}),
Kailang Yangfbc57122019-07-15 10:41:50 +08007993 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
7994 {0x14, 0x90170110},
7995 {0x21, 0x04211030}),
Hui Wang3f6409702016-09-11 11:26:16 +08007996 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wangf771d5b2016-10-18 10:59:09 +08007997 ALC295_STANDARD_PINS,
7998 {0x17, 0x21014020},
7999 {0x18, 0x21a19030}),
8000 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
8001 ALC295_STANDARD_PINS,
8002 {0x17, 0x21014040},
8003 {0x18, 0x21a19050}),
Hui Wang3f307832017-03-23 10:00:25 +08008004 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
8005 ALC295_STANDARD_PINS),
Kailang Yang977e6272015-05-18 15:31:20 +08008006 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
Woodrow Shen703867e2015-08-05 12:34:12 +08008007 ALC298_STANDARD_PINS,
Takashi Iwai9f502ff2015-08-05 12:09:45 +02008008 {0x17, 0x90170110}),
8009 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
8010 ALC298_STANDARD_PINS,
Woodrow Shen703867e2015-08-05 12:34:12 +08008011 {0x17, 0x90170140}),
8012 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
8013 ALC298_STANDARD_PINS,
Takashi Iwai9f502ff2015-08-05 12:09:45 +02008014 {0x17, 0x90170150}),
Kai-Heng Feng9f1bc2c42017-02-16 15:26:54 +08008015 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_SPK_VOLUME,
8016 {0x12, 0xb7a60140},
8017 {0x13, 0xb7a60150},
8018 {0x17, 0x90170110},
8019 {0x1a, 0x03011020},
8020 {0x21, 0x03211030}),
James McDonnell54324222019-09-16 14:53:38 +00008021 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_ALIENWARE_MIC_NO_PRESENCE,
8022 {0x12, 0xb7a60140},
8023 {0x17, 0x90170110},
8024 {0x1a, 0x03a11030},
8025 {0x21, 0x03211020}),
Kailang Yangfcc6c872017-06-29 15:21:27 +08008026 SND_HDA_PIN_QUIRK(0x10ec0299, 0x1028, "Dell", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
8027 ALC225_STANDARD_PINS,
8028 {0x12, 0xb7a60130},
Kailang Yangfcc6c872017-06-29 15:21:27 +08008029 {0x17, 0x90170110}),
Hui Wange1918932014-05-26 16:22:44 +08008030 {}
8031};
Takashi Iwai1d045db2011-07-07 18:23:21 +02008032
Hui Wang7c0a6932019-08-16 14:27:40 +08008033/* This is the fallback pin_fixup_tbl for alc269 family, to make the tbl match
8034 * more machines, don't need to match all valid pins, just need to match
8035 * all the pins defined in the tbl. Just because of this reason, it is possible
8036 * that a single machine matches multiple tbls, so there is one limitation:
8037 * at most one tbl is allowed to define for the same vendor and same codec
8038 */
8039static const struct snd_hda_pin_quirk alc269_fallback_pin_fixup_tbl[] = {
8040 SND_HDA_PIN_QUIRK(0x10ec0289, 0x1028, "Dell", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
8041 {0x19, 0x40000000},
8042 {0x1b, 0x40000000}),
Hui Wangaed8c7f2019-11-21 10:26:43 +08008043 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
8044 {0x19, 0x40000000},
8045 {0x1a, 0x40000000}),
Hui Wangd64ebdb2019-11-21 10:26:44 +08008046 SND_HDA_PIN_QUIRK(0x10ec0236, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
8047 {0x19, 0x40000000},
8048 {0x1a, 0x40000000}),
Hui Wang5815bdf2019-12-11 13:13:21 +08008049 SND_HDA_PIN_QUIRK(0x10ec0274, 0x1028, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB,
8050 {0x19, 0x40000000},
8051 {0x1a, 0x40000000}),
Hui Wang7c0a6932019-08-16 14:27:40 +08008052 {}
8053};
8054
Takashi Iwai546bb672012-03-07 08:37:19 +01008055static void alc269_fill_coef(struct hda_codec *codec)
Takashi Iwai1d045db2011-07-07 18:23:21 +02008056{
Kailang Yang526af6e2012-03-07 08:25:20 +01008057 struct alc_spec *spec = codec->spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008058 int val;
8059
Kailang Yang526af6e2012-03-07 08:25:20 +01008060 if (spec->codec_variant != ALC269_TYPE_ALC269VB)
Takashi Iwai546bb672012-03-07 08:37:19 +01008061 return;
Kailang Yang526af6e2012-03-07 08:25:20 +01008062
Takashi Iwai1bb7e432011-10-17 16:50:59 +02008063 if ((alc_get_coef0(codec) & 0x00ff) < 0x015) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02008064 alc_write_coef_idx(codec, 0xf, 0x960b);
8065 alc_write_coef_idx(codec, 0xe, 0x8817);
8066 }
8067
Takashi Iwai1bb7e432011-10-17 16:50:59 +02008068 if ((alc_get_coef0(codec) & 0x00ff) == 0x016) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02008069 alc_write_coef_idx(codec, 0xf, 0x960b);
8070 alc_write_coef_idx(codec, 0xe, 0x8814);
8071 }
8072
Takashi Iwai1bb7e432011-10-17 16:50:59 +02008073 if ((alc_get_coef0(codec) & 0x00ff) == 0x017) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02008074 /* Power up output pin */
Takashi Iwai98b24882014-08-18 13:47:50 +02008075 alc_update_coef_idx(codec, 0x04, 0, 1<<11);
Takashi Iwai1d045db2011-07-07 18:23:21 +02008076 }
8077
Takashi Iwai1bb7e432011-10-17 16:50:59 +02008078 if ((alc_get_coef0(codec) & 0x00ff) == 0x018) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02008079 val = alc_read_coef_idx(codec, 0xd);
Takashi Iwaif3ee07d2014-08-15 17:35:00 +02008080 if (val != -1 && (val & 0x0c00) >> 10 != 0x1) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02008081 /* Capless ramp up clock control */
8082 alc_write_coef_idx(codec, 0xd, val | (1<<10));
8083 }
8084 val = alc_read_coef_idx(codec, 0x17);
Takashi Iwaif3ee07d2014-08-15 17:35:00 +02008085 if (val != -1 && (val & 0x01c0) >> 6 != 0x4) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02008086 /* Class D power on reset */
8087 alc_write_coef_idx(codec, 0x17, val | (1<<7));
8088 }
8089 }
8090
Takashi Iwai98b24882014-08-18 13:47:50 +02008091 /* HP */
8092 alc_update_coef_idx(codec, 0x4, 0, 1<<11);
Takashi Iwai1d045db2011-07-07 18:23:21 +02008093}
8094
8095/*
8096 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02008097static int patch_alc269(struct hda_codec *codec)
8098{
8099 struct alc_spec *spec;
Takashi Iwai3de95172012-05-07 18:03:15 +02008100 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008101
Takashi Iwai3de95172012-05-07 18:03:15 +02008102 err = alc_alloc_spec(codec, 0x0b);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008103 if (err < 0)
Takashi Iwai3de95172012-05-07 18:03:15 +02008104 return err;
8105
8106 spec = codec->spec;
Takashi Iwai08c189f2012-12-19 15:22:24 +01008107 spec->gen.shared_mic_vref_pin = 0x18;
Kailang Yang317d9312019-05-23 14:43:04 +08008108 codec->power_save_node = 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008109
Takashi Iwai225068a2015-05-29 10:42:14 +02008110#ifdef CONFIG_PM
8111 codec->patch_ops.suspend = alc269_suspend;
8112 codec->patch_ops.resume = alc269_resume;
8113#endif
Kailang Yangc2d6af52017-06-21 14:50:54 +08008114 spec->shutup = alc_default_shutup;
8115 spec->init_hook = alc_default_init;
Takashi Iwai225068a2015-05-29 10:42:14 +02008116
Takashi Iwai7639a062015-03-03 10:07:24 +01008117 switch (codec->core.vendor_id) {
Kailang Yang065380f2013-01-10 10:25:48 +01008118 case 0x10ec0269:
Takashi Iwai1d045db2011-07-07 18:23:21 +02008119 spec->codec_variant = ALC269_TYPE_ALC269VA;
Takashi Iwai1bb7e432011-10-17 16:50:59 +02008120 switch (alc_get_coef0(codec) & 0x00f0) {
8121 case 0x0010:
Takashi Iwai5100cd02014-02-15 10:03:19 +01008122 if (codec->bus->pci &&
8123 codec->bus->pci->subsystem_vendor == 0x1025 &&
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008124 spec->cdefine.platform_type == 1)
Takashi Iwai20ca0c32011-10-17 16:00:35 +02008125 err = alc_codec_rename(codec, "ALC271X");
Takashi Iwai1d045db2011-07-07 18:23:21 +02008126 spec->codec_variant = ALC269_TYPE_ALC269VB;
Takashi Iwai1bb7e432011-10-17 16:50:59 +02008127 break;
8128 case 0x0020:
Takashi Iwai5100cd02014-02-15 10:03:19 +01008129 if (codec->bus->pci &&
8130 codec->bus->pci->subsystem_vendor == 0x17aa &&
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008131 codec->bus->pci->subsystem_device == 0x21f3)
Takashi Iwai20ca0c32011-10-17 16:00:35 +02008132 err = alc_codec_rename(codec, "ALC3202");
Takashi Iwai1d045db2011-07-07 18:23:21 +02008133 spec->codec_variant = ALC269_TYPE_ALC269VC;
Takashi Iwai1bb7e432011-10-17 16:50:59 +02008134 break;
Kailang Yangadcc70b2012-05-25 08:08:38 +02008135 case 0x0030:
8136 spec->codec_variant = ALC269_TYPE_ALC269VD;
8137 break;
Takashi Iwai1bb7e432011-10-17 16:50:59 +02008138 default:
Takashi Iwai1d045db2011-07-07 18:23:21 +02008139 alc_fix_pll_init(codec, 0x20, 0x04, 15);
Takashi Iwai1bb7e432011-10-17 16:50:59 +02008140 }
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008141 if (err < 0)
8142 goto error;
Kailang Yangc2d6af52017-06-21 14:50:54 +08008143 spec->shutup = alc269_shutup;
Takashi Iwai546bb672012-03-07 08:37:19 +01008144 spec->init_hook = alc269_fill_coef;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008145 alc269_fill_coef(codec);
Kailang Yang065380f2013-01-10 10:25:48 +01008146 break;
8147
8148 case 0x10ec0280:
8149 case 0x10ec0290:
8150 spec->codec_variant = ALC269_TYPE_ALC280;
8151 break;
8152 case 0x10ec0282:
Kailang Yang065380f2013-01-10 10:25:48 +01008153 spec->codec_variant = ALC269_TYPE_ALC282;
Kailang Yang7b5c7a02014-03-18 16:15:54 +08008154 spec->shutup = alc282_shutup;
8155 spec->init_hook = alc282_init;
Kailang Yang065380f2013-01-10 10:25:48 +01008156 break;
Kailang Yang2af02be2013-08-22 10:03:50 +02008157 case 0x10ec0233:
8158 case 0x10ec0283:
8159 spec->codec_variant = ALC269_TYPE_ALC283;
8160 spec->shutup = alc283_shutup;
8161 spec->init_hook = alc283_init;
8162 break;
Kailang Yang065380f2013-01-10 10:25:48 +01008163 case 0x10ec0284:
8164 case 0x10ec0292:
8165 spec->codec_variant = ALC269_TYPE_ALC284;
8166 break;
Kailang Yang161ebf22013-10-24 11:36:33 +02008167 case 0x10ec0293:
Kailang Yang4731d5d2017-06-30 15:22:57 +08008168 spec->codec_variant = ALC269_TYPE_ALC293;
Kailang Yang161ebf22013-10-24 11:36:33 +02008169 break;
Kailang Yang7fc7d042013-04-25 11:04:43 +02008170 case 0x10ec0286:
Kailang Yang7c665932014-04-14 15:09:44 +08008171 case 0x10ec0288:
Kailang Yang7fc7d042013-04-25 11:04:43 +02008172 spec->codec_variant = ALC269_TYPE_ALC286;
8173 break;
Kailang Yang506b62c2014-12-18 17:07:44 +08008174 case 0x10ec0298:
8175 spec->codec_variant = ALC269_TYPE_ALC298;
8176 break;
Kailang Yangea04a1d2018-04-25 15:31:52 +08008177 case 0x10ec0235:
Kailang Yang1d04c9d2013-10-24 11:35:18 +02008178 case 0x10ec0255:
8179 spec->codec_variant = ALC269_TYPE_ALC255;
Kailang Yangab3b8e52018-04-25 16:05:27 +08008180 spec->shutup = alc256_shutup;
8181 spec->init_hook = alc256_init;
Kailang Yang1d04c9d2013-10-24 11:35:18 +02008182 break;
Kailang Yang736f20a2017-10-20 15:06:34 +08008183 case 0x10ec0236:
Kailang Yang4344aec2014-12-17 17:39:05 +08008184 case 0x10ec0256:
8185 spec->codec_variant = ALC269_TYPE_ALC256;
Kailang Yang4a219ef2017-06-16 16:54:35 +08008186 spec->shutup = alc256_shutup;
8187 spec->init_hook = alc256_init;
David Henningsson7d1b6e22015-04-21 10:48:46 +02008188 spec->gen.mixer_nid = 0; /* ALC256 does not have any loopback mixer path */
Kailang Yang4344aec2014-12-17 17:39:05 +08008189 break;
Kailang Yangf429e7e2017-12-05 15:38:24 +08008190 case 0x10ec0257:
8191 spec->codec_variant = ALC269_TYPE_ALC257;
Kailang Yang88d42b22018-03-14 16:08:57 +08008192 spec->shutup = alc256_shutup;
8193 spec->init_hook = alc256_init;
Kailang Yangf429e7e2017-12-05 15:38:24 +08008194 spec->gen.mixer_nid = 0;
8195 break;
Kailang Yang0a6f0602017-06-30 16:00:48 +08008196 case 0x10ec0215:
8197 case 0x10ec0285:
8198 case 0x10ec0289:
8199 spec->codec_variant = ALC269_TYPE_ALC215;
Kailang Yang1b6832be2018-01-17 15:32:03 +08008200 spec->shutup = alc225_shutup;
8201 spec->init_hook = alc225_init;
Kailang Yang0a6f0602017-06-30 16:00:48 +08008202 spec->gen.mixer_nid = 0;
8203 break;
Kailang Yang42314302016-02-03 15:03:50 +08008204 case 0x10ec0225:
Kai-Heng Feng3b36b132020-03-11 14:13:28 +08008205 codec->power_save_node = 1;
8206 /* fall through */
Kailang Yang7d727862016-05-24 16:46:07 +08008207 case 0x10ec0295:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08008208 case 0x10ec0299:
Kailang Yang42314302016-02-03 15:03:50 +08008209 spec->codec_variant = ALC269_TYPE_ALC225;
Kailang Yangda911b12018-01-05 16:50:08 +08008210 spec->shutup = alc225_shutup;
8211 spec->init_hook = alc225_init;
Takashi Iwaic1350bf2017-12-27 09:03:45 +01008212 spec->gen.mixer_nid = 0; /* no loopback on ALC225, ALC295 and ALC299 */
Kailang Yang42314302016-02-03 15:03:50 +08008213 break;
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08008214 case 0x10ec0234:
8215 case 0x10ec0274:
8216 case 0x10ec0294:
8217 spec->codec_variant = ALC269_TYPE_ALC294;
Hui Wang532a7782017-06-26 12:30:32 +08008218 spec->gen.mixer_nid = 0; /* ALC2x4 does not have any loopback mixer path */
Kailang Yang71683c32017-06-20 16:33:50 +08008219 alc_update_coef_idx(codec, 0x6b, 0x0018, (1<<4) | (1<<3)); /* UAJ MIC Vref control by verb */
Kailang Yang693abe12019-01-29 15:38:21 +08008220 spec->init_hook = alc294_init;
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08008221 break;
Kailang Yang1078bef2018-11-08 16:36:15 +08008222 case 0x10ec0300:
8223 spec->codec_variant = ALC269_TYPE_ALC300;
8224 spec->gen.mixer_nid = 0; /* no loopback on ALC300 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02008225 break;
Kailang Yangf0778872019-10-24 15:13:32 +08008226 case 0x10ec0623:
8227 spec->codec_variant = ALC269_TYPE_ALC623;
8228 break;
Kailang Yang6fbae352016-05-30 16:44:20 +08008229 case 0x10ec0700:
8230 case 0x10ec0701:
8231 case 0x10ec0703:
Kailang Yang83629532019-05-02 16:03:26 +08008232 case 0x10ec0711:
Kailang Yang6fbae352016-05-30 16:44:20 +08008233 spec->codec_variant = ALC269_TYPE_ALC700;
8234 spec->gen.mixer_nid = 0; /* ALC700 does not have any loopback mixer path */
Kailang Yang2d7fe612017-11-22 15:21:32 +08008235 alc_update_coef_idx(codec, 0x4a, 1 << 15, 0); /* Combo jack auto trigger control */
Kailang Yang693abe12019-01-29 15:38:21 +08008236 spec->init_hook = alc294_init;
Kailang Yang6fbae352016-05-30 16:44:20 +08008237 break;
8238
Takashi Iwai1d045db2011-07-07 18:23:21 +02008239 }
8240
Kailang Yangad60d502013-06-28 12:03:01 +02008241 if (snd_hda_codec_read(codec, 0x51, 0, AC_VERB_PARAMETERS, 0) == 0x10ec5505) {
Kailang Yang97a26572013-11-29 00:35:26 -05008242 spec->has_alc5505_dsp = 1;
Kailang Yangad60d502013-06-28 12:03:01 +02008243 spec->init_hook = alc5505_dsp_init;
8244 }
8245
Takashi Iwaic9af7532019-05-10 11:01:43 +02008246 alc_pre_init(codec);
8247
Takashi Iwaiefe55732018-06-15 11:55:02 +02008248 snd_hda_pick_fixup(codec, alc269_fixup_models,
8249 alc269_fixup_tbl, alc269_fixups);
Hui Wang0fc1e442019-08-16 14:27:39 +08008250 snd_hda_pick_pin_fixup(codec, alc269_pin_fixup_tbl, alc269_fixups, true);
Hui Wang7c0a6932019-08-16 14:27:40 +08008251 snd_hda_pick_pin_fixup(codec, alc269_fallback_pin_fixup_tbl, alc269_fixups, false);
Takashi Iwaiefe55732018-06-15 11:55:02 +02008252 snd_hda_pick_fixup(codec, NULL, alc269_fixup_vendor_tbl,
8253 alc269_fixups);
8254 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
8255
8256 alc_auto_parse_customize_define(codec);
8257
8258 if (has_cdefine_beep(codec))
8259 spec->gen.beep_nid = 0x01;
8260
Takashi Iwaia4297b52011-08-23 18:40:12 +02008261 /* automatic parse from the BIOS config */
8262 err = alc269_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008263 if (err < 0)
8264 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008265
Takashi Iwaifea80fa2018-06-20 12:52:46 +02008266 if (!spec->gen.no_analog && spec->gen.beep_nid && spec->gen.mixer_nid) {
8267 err = set_beep_amp(spec, spec->gen.mixer_nid, 0x04, HDA_INPUT);
8268 if (err < 0)
8269 goto error;
8270 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02008271
Takashi Iwai1727a772013-01-10 09:52:52 +01008272 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01008273
Takashi Iwai1d045db2011-07-07 18:23:21 +02008274 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008275
8276 error:
8277 alc_free(codec);
8278 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008279}
8280
8281/*
8282 * ALC861
8283 */
8284
Takashi Iwai1d045db2011-07-07 18:23:21 +02008285static int alc861_parse_auto_config(struct hda_codec *codec)
8286{
Takashi Iwai1d045db2011-07-07 18:23:21 +02008287 static const hda_nid_t alc861_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02008288 static const hda_nid_t alc861_ssids[] = { 0x0e, 0x0f, 0x0b, 0 };
8289 return alc_parse_auto_config(codec, alc861_ignore, alc861_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02008290}
8291
Takashi Iwai1d045db2011-07-07 18:23:21 +02008292/* Pin config fixes */
8293enum {
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008294 ALC861_FIXUP_FSC_AMILO_PI1505,
8295 ALC861_FIXUP_AMP_VREF_0F,
8296 ALC861_FIXUP_NO_JACK_DETECT,
8297 ALC861_FIXUP_ASUS_A6RP,
Takashi Iwai6ddf0fd2013-11-29 12:47:34 +01008298 ALC660_FIXUP_ASUS_W7J,
Takashi Iwai1d045db2011-07-07 18:23:21 +02008299};
8300
Takashi Iwai31150f22012-01-30 10:54:08 +01008301/* On some laptops, VREF of pin 0x0f is abused for controlling the main amp */
8302static void alc861_fixup_asus_amp_vref_0f(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01008303 const struct hda_fixup *fix, int action)
Takashi Iwai31150f22012-01-30 10:54:08 +01008304{
8305 struct alc_spec *spec = codec->spec;
8306 unsigned int val;
8307
Takashi Iwai1727a772013-01-10 09:52:52 +01008308 if (action != HDA_FIXUP_ACT_INIT)
Takashi Iwai31150f22012-01-30 10:54:08 +01008309 return;
Takashi Iwaid3f02d62013-01-10 10:12:22 +01008310 val = snd_hda_codec_get_pin_target(codec, 0x0f);
Takashi Iwai31150f22012-01-30 10:54:08 +01008311 if (!(val & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN)))
8312 val |= AC_PINCTL_IN_EN;
8313 val |= AC_PINCTL_VREF_50;
Takashi Iwaicdd03ce2012-04-20 12:34:50 +02008314 snd_hda_set_pin_ctl(codec, 0x0f, val);
Takashi Iwai08c189f2012-12-19 15:22:24 +01008315 spec->gen.keep_vref_in_automute = 1;
Takashi Iwai31150f22012-01-30 10:54:08 +01008316}
8317
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008318/* suppress the jack-detection */
8319static void alc_fixup_no_jack_detect(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01008320 const struct hda_fixup *fix, int action)
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008321{
Takashi Iwai1727a772013-01-10 09:52:52 +01008322 if (action == HDA_FIXUP_ACT_PRE_PROBE)
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008323 codec->no_jack_detect = 1;
Jesper Juhl7d7eb9e2012-04-12 22:11:25 +02008324}
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008325
Takashi Iwai1727a772013-01-10 09:52:52 +01008326static const struct hda_fixup alc861_fixups[] = {
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008327 [ALC861_FIXUP_FSC_AMILO_PI1505] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008328 .type = HDA_FIXUP_PINS,
8329 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02008330 { 0x0b, 0x0221101f }, /* HP */
8331 { 0x0f, 0x90170310 }, /* speaker */
8332 { }
8333 }
8334 },
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008335 [ALC861_FIXUP_AMP_VREF_0F] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008336 .type = HDA_FIXUP_FUNC,
Takashi Iwai31150f22012-01-30 10:54:08 +01008337 .v.func = alc861_fixup_asus_amp_vref_0f,
Takashi Iwai3b25eb62012-01-25 09:55:46 +01008338 },
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008339 [ALC861_FIXUP_NO_JACK_DETECT] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008340 .type = HDA_FIXUP_FUNC,
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008341 .v.func = alc_fixup_no_jack_detect,
8342 },
8343 [ALC861_FIXUP_ASUS_A6RP] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008344 .type = HDA_FIXUP_FUNC,
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008345 .v.func = alc861_fixup_asus_amp_vref_0f,
8346 .chained = true,
8347 .chain_id = ALC861_FIXUP_NO_JACK_DETECT,
Takashi Iwai6ddf0fd2013-11-29 12:47:34 +01008348 },
8349 [ALC660_FIXUP_ASUS_W7J] = {
8350 .type = HDA_FIXUP_VERBS,
8351 .v.verbs = (const struct hda_verb[]) {
8352 /* ASUS W7J needs a magic pin setup on unused NID 0x10
8353 * for enabling outputs
8354 */
8355 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8356 { }
8357 },
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008358 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02008359};
8360
8361static const struct snd_pci_quirk alc861_fixup_tbl[] = {
Takashi Iwai6ddf0fd2013-11-29 12:47:34 +01008362 SND_PCI_QUIRK(0x1043, 0x1253, "ASUS W7J", ALC660_FIXUP_ASUS_W7J),
Takashi Iwaie7ca2372013-12-02 15:27:19 +01008363 SND_PCI_QUIRK(0x1043, 0x1263, "ASUS Z35HL", ALC660_FIXUP_ASUS_W7J),
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008364 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS A6Rp", ALC861_FIXUP_ASUS_A6RP),
8365 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", ALC861_FIXUP_AMP_VREF_0F),
8366 SND_PCI_QUIRK(0x1462, 0x7254, "HP DX2200", ALC861_FIXUP_NO_JACK_DETECT),
8367 SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", ALC861_FIXUP_AMP_VREF_0F),
8368 SND_PCI_QUIRK(0x1584, 0x0000, "Uniwill ECS M31EI", ALC861_FIXUP_AMP_VREF_0F),
8369 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", ALC861_FIXUP_FSC_AMILO_PI1505),
Takashi Iwai1d045db2011-07-07 18:23:21 +02008370 {}
8371};
8372
8373/*
8374 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02008375static int patch_alc861(struct hda_codec *codec)
8376{
8377 struct alc_spec *spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008378 int err;
8379
Takashi Iwai3de95172012-05-07 18:03:15 +02008380 err = alc_alloc_spec(codec, 0x15);
8381 if (err < 0)
8382 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008383
Takashi Iwai3de95172012-05-07 18:03:15 +02008384 spec = codec->spec;
Takashi Iwai2722b532019-08-22 09:55:37 +02008385 if (has_cdefine_beep(codec))
8386 spec->gen.beep_nid = 0x23;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008387
Takashi Iwai225068a2015-05-29 10:42:14 +02008388#ifdef CONFIG_PM
8389 spec->power_hook = alc_power_eapd;
8390#endif
8391
Takashi Iwaic9af7532019-05-10 11:01:43 +02008392 alc_pre_init(codec);
8393
Takashi Iwai1727a772013-01-10 09:52:52 +01008394 snd_hda_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
8395 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02008396
Takashi Iwaicb4e4822011-08-23 17:34:25 +02008397 /* automatic parse from the BIOS config */
8398 err = alc861_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008399 if (err < 0)
8400 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008401
Takashi Iwaifea80fa2018-06-20 12:52:46 +02008402 if (!spec->gen.no_analog) {
8403 err = set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
8404 if (err < 0)
8405 goto error;
8406 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02008407
Takashi Iwai1727a772013-01-10 09:52:52 +01008408 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01008409
Takashi Iwai1d045db2011-07-07 18:23:21 +02008410 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008411
8412 error:
8413 alc_free(codec);
8414 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008415}
8416
8417/*
8418 * ALC861-VD support
8419 *
8420 * Based on ALC882
8421 *
8422 * In addition, an independent DAC
8423 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02008424static int alc861vd_parse_auto_config(struct hda_codec *codec)
8425{
Takashi Iwai1d045db2011-07-07 18:23:21 +02008426 static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02008427 static const hda_nid_t alc861vd_ssids[] = { 0x15, 0x1b, 0x14, 0 };
8428 return alc_parse_auto_config(codec, alc861vd_ignore, alc861vd_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02008429}
8430
Takashi Iwai1d045db2011-07-07 18:23:21 +02008431enum {
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008432 ALC660VD_FIX_ASUS_GPIO1,
8433 ALC861VD_FIX_DALLAS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02008434};
8435
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008436/* exclude VREF80 */
8437static void alc861vd_fixup_dallas(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01008438 const struct hda_fixup *fix, int action)
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008439{
Takashi Iwai1727a772013-01-10 09:52:52 +01008440 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwaib78562b2012-12-17 20:06:49 +01008441 snd_hda_override_pin_caps(codec, 0x18, 0x00000734);
8442 snd_hda_override_pin_caps(codec, 0x19, 0x0000073c);
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008443 }
8444}
8445
Takashi Iwaidf73d832018-06-19 23:05:47 +02008446/* reset GPIO1 */
8447static void alc660vd_fixup_asus_gpio1(struct hda_codec *codec,
8448 const struct hda_fixup *fix, int action)
8449{
8450 struct alc_spec *spec = codec->spec;
8451
8452 if (action == HDA_FIXUP_ACT_PRE_PROBE)
8453 spec->gpio_mask |= 0x02;
8454 alc_fixup_gpio(codec, action, 0x01);
8455}
8456
Takashi Iwai1727a772013-01-10 09:52:52 +01008457static const struct hda_fixup alc861vd_fixups[] = {
Takashi Iwai1d045db2011-07-07 18:23:21 +02008458 [ALC660VD_FIX_ASUS_GPIO1] = {
Takashi Iwaidf73d832018-06-19 23:05:47 +02008459 .type = HDA_FIXUP_FUNC,
8460 .v.func = alc660vd_fixup_asus_gpio1,
Takashi Iwai1d045db2011-07-07 18:23:21 +02008461 },
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008462 [ALC861VD_FIX_DALLAS] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008463 .type = HDA_FIXUP_FUNC,
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008464 .v.func = alc861vd_fixup_dallas,
8465 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02008466};
8467
8468static const struct snd_pci_quirk alc861vd_fixup_tbl[] = {
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008469 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_FIX_DALLAS),
Takashi Iwai1d045db2011-07-07 18:23:21 +02008470 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008471 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_FIX_DALLAS),
Takashi Iwai1d045db2011-07-07 18:23:21 +02008472 {}
8473};
8474
Takashi Iwai1d045db2011-07-07 18:23:21 +02008475/*
8476 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02008477static int patch_alc861vd(struct hda_codec *codec)
8478{
8479 struct alc_spec *spec;
Takashi Iwaicb4e4822011-08-23 17:34:25 +02008480 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008481
Takashi Iwai3de95172012-05-07 18:03:15 +02008482 err = alc_alloc_spec(codec, 0x0b);
8483 if (err < 0)
8484 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008485
Takashi Iwai3de95172012-05-07 18:03:15 +02008486 spec = codec->spec;
Takashi Iwai2722b532019-08-22 09:55:37 +02008487 if (has_cdefine_beep(codec))
8488 spec->gen.beep_nid = 0x23;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008489
Takashi Iwai225068a2015-05-29 10:42:14 +02008490 spec->shutup = alc_eapd_shutup;
8491
Takashi Iwaic9af7532019-05-10 11:01:43 +02008492 alc_pre_init(codec);
8493
Takashi Iwai1727a772013-01-10 09:52:52 +01008494 snd_hda_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
8495 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02008496
Takashi Iwaicb4e4822011-08-23 17:34:25 +02008497 /* automatic parse from the BIOS config */
8498 err = alc861vd_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008499 if (err < 0)
8500 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008501
Takashi Iwaifea80fa2018-06-20 12:52:46 +02008502 if (!spec->gen.no_analog) {
8503 err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
8504 if (err < 0)
8505 goto error;
8506 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02008507
Takashi Iwai1727a772013-01-10 09:52:52 +01008508 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01008509
Takashi Iwai1d045db2011-07-07 18:23:21 +02008510 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008511
8512 error:
8513 alc_free(codec);
8514 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008515}
8516
8517/*
8518 * ALC662 support
8519 *
8520 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
8521 * configuration. Each pin widget can choose any input DACs and a mixer.
8522 * Each ADC is connected from a mixer of all inputs. This makes possible
8523 * 6-channel independent captures.
8524 *
8525 * In addition, an independent DAC for the multi-playback (not used in this
8526 * driver yet).
8527 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02008528
8529/*
8530 * BIOS auto configuration
8531 */
8532
Kailang Yangbc9f98a2007-04-12 13:06:07 +02008533static int alc662_parse_auto_config(struct hda_codec *codec)
8534{
Takashi Iwai4c6d72d2011-05-02 11:30:18 +02008535 static const hda_nid_t alc662_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02008536 static const hda_nid_t alc663_ssids[] = { 0x15, 0x1b, 0x14, 0x21 };
8537 static const hda_nid_t alc662_ssids[] = { 0x15, 0x1b, 0x14, 0 };
8538 const hda_nid_t *ssids;
Takashi Iwaiee979a142008-09-02 15:42:20 +02008539
Takashi Iwai7639a062015-03-03 10:07:24 +01008540 if (codec->core.vendor_id == 0x10ec0272 || codec->core.vendor_id == 0x10ec0663 ||
8541 codec->core.vendor_id == 0x10ec0665 || codec->core.vendor_id == 0x10ec0670 ||
8542 codec->core.vendor_id == 0x10ec0671)
Takashi Iwai3e6179b2011-07-08 16:55:13 +02008543 ssids = alc663_ssids;
Kailang Yang6227cdc2010-02-25 08:36:52 +01008544 else
Takashi Iwai3e6179b2011-07-08 16:55:13 +02008545 ssids = alc662_ssids;
8546 return alc_parse_auto_config(codec, alc662_ignore, ssids);
Kailang Yangbc9f98a2007-04-12 13:06:07 +02008547}
8548
Todd Broch6be79482010-12-07 16:51:05 -08008549static void alc272_fixup_mario(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01008550 const struct hda_fixup *fix, int action)
Takashi Iwai6fc398c2011-01-13 14:36:37 +01008551{
Takashi Iwai9bb1f062013-01-10 17:14:29 +01008552 if (action != HDA_FIXUP_ACT_PRE_PROBE)
Takashi Iwai6fc398c2011-01-13 14:36:37 +01008553 return;
Todd Broch6be79482010-12-07 16:51:05 -08008554 if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT,
8555 (0x3b << AC_AMPCAP_OFFSET_SHIFT) |
8556 (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) |
8557 (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) |
8558 (0 << AC_AMPCAP_MUTE_SHIFT)))
Takashi Iwai4e76a882014-02-25 12:21:03 +01008559 codec_warn(codec, "failed to override amp caps for NID 0x2\n");
Todd Broch6be79482010-12-07 16:51:05 -08008560}
8561
Takashi Iwai8e383952013-10-30 17:41:12 +01008562static const struct snd_pcm_chmap_elem asus_pcm_2_1_chmaps[] = {
8563 { .channels = 2,
8564 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } },
8565 { .channels = 4,
8566 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR,
8567 SNDRV_CHMAP_NA, SNDRV_CHMAP_LFE } }, /* LFE only on right */
8568 { }
8569};
8570
8571/* override the 2.1 chmap */
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01008572static void alc_fixup_bass_chmap(struct hda_codec *codec,
Takashi Iwai8e383952013-10-30 17:41:12 +01008573 const struct hda_fixup *fix, int action)
8574{
8575 if (action == HDA_FIXUP_ACT_BUILD) {
8576 struct alc_spec *spec = codec->spec;
Takashi Iwaibbbc7e82015-02-27 17:43:19 +01008577 spec->gen.pcm_rec[0]->stream[0].chmap = asus_pcm_2_1_chmaps;
Takashi Iwai8e383952013-10-30 17:41:12 +01008578 }
8579}
8580
Takashi Iwaibf686652014-01-13 16:18:25 +01008581/* avoid D3 for keeping GPIO up */
8582static unsigned int gpio_led_power_filter(struct hda_codec *codec,
8583 hda_nid_t nid,
8584 unsigned int power_state)
8585{
8586 struct alc_spec *spec = codec->spec;
Takashi Iwaid261eec2018-06-19 22:32:29 +02008587 if (nid == codec->core.afg && power_state == AC_PWRST_D3 && spec->gpio_data)
Takashi Iwaibf686652014-01-13 16:18:25 +01008588 return AC_PWRST_D0;
8589 return power_state;
8590}
8591
Takashi Iwai3e887f32014-01-10 17:50:58 +01008592static void alc662_fixup_led_gpio1(struct hda_codec *codec,
8593 const struct hda_fixup *fix, int action)
8594{
8595 struct alc_spec *spec = codec->spec;
Takashi Iwai3e887f32014-01-10 17:50:58 +01008596
Takashi Iwai01e4a272018-06-19 22:47:30 +02008597 alc_fixup_hp_gpio_led(codec, action, 0x01, 0);
Takashi Iwai3e887f32014-01-10 17:50:58 +01008598 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai0f32fd192014-11-19 12:16:14 +01008599 spec->mute_led_polarity = 1;
Takashi Iwaibf686652014-01-13 16:18:25 +01008600 codec->power_filter = gpio_led_power_filter;
Takashi Iwai3e887f32014-01-10 17:50:58 +01008601 }
8602}
8603
Kailang Yangc6790c82016-11-25 16:15:17 +08008604static void alc662_usi_automute_hook(struct hda_codec *codec,
8605 struct hda_jack_callback *jack)
8606{
8607 struct alc_spec *spec = codec->spec;
8608 int vref;
8609 msleep(200);
8610 snd_hda_gen_hp_automute(codec, jack);
8611
8612 vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0;
8613 msleep(100);
8614 snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8615 vref);
8616}
8617
8618static void alc662_fixup_usi_headset_mic(struct hda_codec *codec,
8619 const struct hda_fixup *fix, int action)
8620{
8621 struct alc_spec *spec = codec->spec;
8622 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
8623 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
8624 spec->gen.hp_automute_hook = alc662_usi_automute_hook;
8625 }
8626}
8627
Sergey Bostandzhyan00066e92019-09-06 11:33:43 +02008628static void alc662_aspire_ethos_mute_speakers(struct hda_codec *codec,
8629 struct hda_jack_callback *cb)
8630{
8631 /* surround speakers at 0x1b already get muted automatically when
8632 * headphones are plugged in, but we have to mute/unmute the remaining
8633 * channels manually:
8634 * 0x15 - front left/front right
8635 * 0x18 - front center/ LFE
8636 */
8637 if (snd_hda_jack_detect_state(codec, 0x1b) == HDA_JACK_PRESENT) {
8638 snd_hda_set_pin_ctl_cache(codec, 0x15, 0);
8639 snd_hda_set_pin_ctl_cache(codec, 0x18, 0);
8640 } else {
8641 snd_hda_set_pin_ctl_cache(codec, 0x15, PIN_OUT);
8642 snd_hda_set_pin_ctl_cache(codec, 0x18, PIN_OUT);
8643 }
8644}
8645
8646static void alc662_fixup_aspire_ethos_hp(struct hda_codec *codec,
8647 const struct hda_fixup *fix, int action)
8648{
8649 /* Pin 0x1b: shared headphones jack and surround speakers */
8650 if (!is_jack_detectable(codec, 0x1b))
8651 return;
8652
8653 switch (action) {
8654 case HDA_FIXUP_ACT_PRE_PROBE:
8655 snd_hda_jack_detect_enable_callback(codec, 0x1b,
8656 alc662_aspire_ethos_mute_speakers);
Takashi Iwai336820c2019-11-28 21:26:30 +01008657 /* subwoofer needs an extra GPIO setting to become audible */
8658 alc_setup_gpio(codec, 0x02);
Sergey Bostandzhyan00066e92019-09-06 11:33:43 +02008659 break;
8660 case HDA_FIXUP_ACT_INIT:
8661 /* Make sure to start in a correct state, i.e. if
8662 * headphones have been plugged in before powering up the system
8663 */
8664 alc662_aspire_ethos_mute_speakers(codec, NULL);
8665 break;
8666 }
8667}
8668
Kailang Yang5af290282020-01-17 14:04:01 +08008669static void alc671_fixup_hp_headset_mic2(struct hda_codec *codec,
8670 const struct hda_fixup *fix, int action)
8671{
8672 struct alc_spec *spec = codec->spec;
8673
8674 static const struct hda_pintbl pincfgs[] = {
8675 { 0x19, 0x02a11040 }, /* use as headset mic, with its own jack detect */
8676 { 0x1b, 0x0181304f },
8677 { }
8678 };
8679
8680 switch (action) {
8681 case HDA_FIXUP_ACT_PRE_PROBE:
8682 spec->gen.mixer_nid = 0;
8683 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
8684 snd_hda_apply_pincfgs(codec, pincfgs);
8685 break;
8686 case HDA_FIXUP_ACT_INIT:
8687 alc_write_coef_idx(codec, 0x19, 0xa054);
8688 break;
8689 }
8690}
8691
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01008692static const struct coef_fw alc668_coefs[] = {
Kailang Yangf3f91852014-10-24 15:43:46 +08008693 WRITE_COEF(0x01, 0xbebe), WRITE_COEF(0x02, 0xaaaa), WRITE_COEF(0x03, 0x0),
8694 WRITE_COEF(0x04, 0x0180), WRITE_COEF(0x06, 0x0), WRITE_COEF(0x07, 0x0f80),
8695 WRITE_COEF(0x08, 0x0031), WRITE_COEF(0x0a, 0x0060), WRITE_COEF(0x0b, 0x0),
8696 WRITE_COEF(0x0c, 0x7cf7), WRITE_COEF(0x0d, 0x1080), WRITE_COEF(0x0e, 0x7f7f),
8697 WRITE_COEF(0x0f, 0xcccc), WRITE_COEF(0x10, 0xddcc), WRITE_COEF(0x11, 0x0001),
8698 WRITE_COEF(0x13, 0x0), WRITE_COEF(0x14, 0x2aa0), WRITE_COEF(0x17, 0xa940),
8699 WRITE_COEF(0x19, 0x0), WRITE_COEF(0x1a, 0x0), WRITE_COEF(0x1b, 0x0),
8700 WRITE_COEF(0x1c, 0x0), WRITE_COEF(0x1d, 0x0), WRITE_COEF(0x1e, 0x7418),
8701 WRITE_COEF(0x1f, 0x0804), WRITE_COEF(0x20, 0x4200), WRITE_COEF(0x21, 0x0468),
8702 WRITE_COEF(0x22, 0x8ccc), WRITE_COEF(0x23, 0x0250), WRITE_COEF(0x24, 0x7418),
8703 WRITE_COEF(0x27, 0x0), WRITE_COEF(0x28, 0x8ccc), WRITE_COEF(0x2a, 0xff00),
8704 WRITE_COEF(0x2b, 0x8000), WRITE_COEF(0xa7, 0xff00), WRITE_COEF(0xa8, 0x8000),
8705 WRITE_COEF(0xaa, 0x2e17), WRITE_COEF(0xab, 0xa0c0), WRITE_COEF(0xac, 0x0),
8706 WRITE_COEF(0xad, 0x0), WRITE_COEF(0xae, 0x2ac6), WRITE_COEF(0xaf, 0xa480),
8707 WRITE_COEF(0xb0, 0x0), WRITE_COEF(0xb1, 0x0), WRITE_COEF(0xb2, 0x0),
8708 WRITE_COEF(0xb3, 0x0), WRITE_COEF(0xb4, 0x0), WRITE_COEF(0xb5, 0x1040),
8709 WRITE_COEF(0xb6, 0xd697), WRITE_COEF(0xb7, 0x902b), WRITE_COEF(0xb8, 0xd697),
8710 WRITE_COEF(0xb9, 0x902b), WRITE_COEF(0xba, 0xb8ba), WRITE_COEF(0xbb, 0xaaab),
8711 WRITE_COEF(0xbc, 0xaaaf), WRITE_COEF(0xbd, 0x6aaa), WRITE_COEF(0xbe, 0x1c02),
8712 WRITE_COEF(0xc0, 0x00ff), WRITE_COEF(0xc1, 0x0fa6),
8713 {}
8714};
8715
8716static void alc668_restore_default_value(struct hda_codec *codec)
8717{
8718 alc_process_coef_fw(codec, alc668_coefs);
8719}
8720
David Henningsson6cb3b702010-09-09 08:51:44 +02008721enum {
Daniel T Chen2df03512010-10-10 22:39:28 -04008722 ALC662_FIXUP_ASPIRE,
Takashi Iwai3e887f32014-01-10 17:50:58 +01008723 ALC662_FIXUP_LED_GPIO1,
David Henningsson6cb3b702010-09-09 08:51:44 +02008724 ALC662_FIXUP_IDEAPAD,
Todd Broch6be79482010-12-07 16:51:05 -08008725 ALC272_FIXUP_MARIO,
Anisse Astierd2ebd472011-01-20 12:36:21 +01008726 ALC662_FIXUP_CZC_P10T,
David Henningsson94024cd2011-04-29 14:10:55 +02008727 ALC662_FIXUP_SKU_IGNORE,
Takashi Iwaie59ea3e2011-06-29 17:21:00 +02008728 ALC662_FIXUP_HP_RP5800,
Takashi Iwai53c334a2011-08-23 18:27:14 +02008729 ALC662_FIXUP_ASUS_MODE1,
8730 ALC662_FIXUP_ASUS_MODE2,
8731 ALC662_FIXUP_ASUS_MODE3,
8732 ALC662_FIXUP_ASUS_MODE4,
8733 ALC662_FIXUP_ASUS_MODE5,
8734 ALC662_FIXUP_ASUS_MODE6,
8735 ALC662_FIXUP_ASUS_MODE7,
8736 ALC662_FIXUP_ASUS_MODE8,
Takashi Iwai1565cc32012-02-13 12:03:25 +01008737 ALC662_FIXUP_NO_JACK_DETECT,
David Henningssonedfe3bf2012-06-12 13:15:12 +02008738 ALC662_FIXUP_ZOTAC_Z68,
Takashi Iwai125821a2012-06-22 14:30:29 +02008739 ALC662_FIXUP_INV_DMIC,
David Henningsson1f8b46c2015-05-12 14:38:15 +02008740 ALC662_FIXUP_DELL_MIC_NO_PRESENCE,
David Henningsson73bdd592013-04-15 15:44:14 +02008741 ALC668_FIXUP_DELL_MIC_NO_PRESENCE,
David Henningsson1f8b46c2015-05-12 14:38:15 +02008742 ALC662_FIXUP_HEADSET_MODE,
David Henningsson73bdd592013-04-15 15:44:14 +02008743 ALC668_FIXUP_HEADSET_MODE,
David Henningsson8e54b4a2014-02-07 09:31:07 +01008744 ALC662_FIXUP_BASS_MODE4_CHMAP,
David Henningsson61a75f12014-02-07 09:31:08 +01008745 ALC662_FIXUP_BASS_16,
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01008746 ALC662_FIXUP_BASS_1A,
David Henningsson8e54b4a2014-02-07 09:31:07 +01008747 ALC662_FIXUP_BASS_CHMAP,
Hui Wang493a52a2014-01-14 14:07:36 +08008748 ALC668_FIXUP_AUTO_MUTE,
Gabriele Mazzotta5e6db662014-05-20 18:58:26 +02008749 ALC668_FIXUP_DELL_DISABLE_AAMIX,
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02008750 ALC668_FIXUP_DELL_XPS13,
Bobi Mihalca9d4dc582016-03-23 13:26:11 +02008751 ALC662_FIXUP_ASUS_Nx50,
Mikhail Paulyshkafc7438b2017-04-21 08:52:42 +02008752 ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE,
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07008753 ALC668_FIXUP_ASUS_Nx51,
Takashi Iwai5b7c5e12018-10-09 14:20:17 +02008754 ALC668_FIXUP_MIC_COEF,
Takashi Iwai11ba6112018-10-07 09:44:17 +02008755 ALC668_FIXUP_ASUS_G751,
Kailang Yang78f4f7c2016-06-07 11:31:34 +08008756 ALC891_FIXUP_HEADSET_MODE,
8757 ALC891_FIXUP_DELL_MIC_NO_PRESENCE,
Shrirang Bagul9b51fe32016-08-01 13:16:17 +08008758 ALC662_FIXUP_ACER_VERITON,
Takashi Iwai1a3f0992016-10-20 12:14:51 +02008759 ALC892_FIXUP_ASROCK_MOBO,
Kailang Yangc6790c82016-11-25 16:15:17 +08008760 ALC662_FIXUP_USI_FUNC,
8761 ALC662_FIXUP_USI_HEADSET_MODE,
Kailang Yangca169cc2017-04-25 16:17:40 +08008762 ALC662_FIXUP_LENOVO_MULTI_CODECS,
Sergey Bostandzhyan00066e92019-09-06 11:33:43 +02008763 ALC669_FIXUP_ACER_ASPIRE_ETHOS,
Sergey Bostandzhyan00066e92019-09-06 11:33:43 +02008764 ALC669_FIXUP_ACER_ASPIRE_ETHOS_HEADSET,
Kailang Yang5af290282020-01-17 14:04:01 +08008765 ALC671_FIXUP_HP_HEADSET_MIC2,
Jian-Hong Pand858c702020-03-17 16:28:07 +08008766 ALC662_FIXUP_ACER_X2660G_HEADSET_MODE,
Jian-Hong Pana1244582020-03-17 16:28:09 +08008767 ALC662_FIXUP_ACER_NITRO_HEADSET_MODE,
David Henningsson6cb3b702010-09-09 08:51:44 +02008768};
8769
Takashi Iwai1727a772013-01-10 09:52:52 +01008770static const struct hda_fixup alc662_fixups[] = {
Daniel T Chen2df03512010-10-10 22:39:28 -04008771 [ALC662_FIXUP_ASPIRE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008772 .type = HDA_FIXUP_PINS,
8773 .v.pins = (const struct hda_pintbl[]) {
Daniel T Chen2df03512010-10-10 22:39:28 -04008774 { 0x15, 0x99130112 }, /* subwoofer */
8775 { }
8776 }
8777 },
Takashi Iwai3e887f32014-01-10 17:50:58 +01008778 [ALC662_FIXUP_LED_GPIO1] = {
8779 .type = HDA_FIXUP_FUNC,
8780 .v.func = alc662_fixup_led_gpio1,
8781 },
David Henningsson6cb3b702010-09-09 08:51:44 +02008782 [ALC662_FIXUP_IDEAPAD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008783 .type = HDA_FIXUP_PINS,
8784 .v.pins = (const struct hda_pintbl[]) {
David Henningsson6cb3b702010-09-09 08:51:44 +02008785 { 0x17, 0x99130112 }, /* subwoofer */
8786 { }
Takashi Iwai3e887f32014-01-10 17:50:58 +01008787 },
8788 .chained = true,
8789 .chain_id = ALC662_FIXUP_LED_GPIO1,
David Henningsson6cb3b702010-09-09 08:51:44 +02008790 },
Todd Broch6be79482010-12-07 16:51:05 -08008791 [ALC272_FIXUP_MARIO] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008792 .type = HDA_FIXUP_FUNC,
Takashi Iwaib5bfbc62011-01-13 14:22:32 +01008793 .v.func = alc272_fixup_mario,
Anisse Astierd2ebd472011-01-20 12:36:21 +01008794 },
8795 [ALC662_FIXUP_CZC_P10T] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008796 .type = HDA_FIXUP_VERBS,
Anisse Astierd2ebd472011-01-20 12:36:21 +01008797 .v.verbs = (const struct hda_verb[]) {
8798 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
8799 {}
8800 }
8801 },
David Henningsson94024cd2011-04-29 14:10:55 +02008802 [ALC662_FIXUP_SKU_IGNORE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008803 .type = HDA_FIXUP_FUNC,
Takashi Iwai23d30f22012-05-07 17:17:32 +02008804 .v.func = alc_fixup_sku_ignore,
Takashi Iwaic6b35872011-03-28 12:05:31 +02008805 },
Takashi Iwaie59ea3e2011-06-29 17:21:00 +02008806 [ALC662_FIXUP_HP_RP5800] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008807 .type = HDA_FIXUP_PINS,
8808 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaie59ea3e2011-06-29 17:21:00 +02008809 { 0x14, 0x0221201f }, /* HP out */
8810 { }
8811 },
8812 .chained = true,
8813 .chain_id = ALC662_FIXUP_SKU_IGNORE
8814 },
Takashi Iwai53c334a2011-08-23 18:27:14 +02008815 [ALC662_FIXUP_ASUS_MODE1] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008816 .type = HDA_FIXUP_PINS,
8817 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008818 { 0x14, 0x99130110 }, /* speaker */
8819 { 0x18, 0x01a19c20 }, /* mic */
8820 { 0x19, 0x99a3092f }, /* int-mic */
8821 { 0x21, 0x0121401f }, /* HP out */
8822 { }
8823 },
8824 .chained = true,
8825 .chain_id = ALC662_FIXUP_SKU_IGNORE
8826 },
8827 [ALC662_FIXUP_ASUS_MODE2] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008828 .type = HDA_FIXUP_PINS,
8829 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai2996bdb2011-08-18 16:02:24 +02008830 { 0x14, 0x99130110 }, /* speaker */
8831 { 0x18, 0x01a19820 }, /* mic */
8832 { 0x19, 0x99a3092f }, /* int-mic */
8833 { 0x1b, 0x0121401f }, /* HP out */
8834 { }
8835 },
Takashi Iwai53c334a2011-08-23 18:27:14 +02008836 .chained = true,
8837 .chain_id = ALC662_FIXUP_SKU_IGNORE
8838 },
8839 [ALC662_FIXUP_ASUS_MODE3] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008840 .type = HDA_FIXUP_PINS,
8841 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008842 { 0x14, 0x99130110 }, /* speaker */
8843 { 0x15, 0x0121441f }, /* HP */
8844 { 0x18, 0x01a19840 }, /* mic */
8845 { 0x19, 0x99a3094f }, /* int-mic */
8846 { 0x21, 0x01211420 }, /* HP2 */
8847 { }
8848 },
8849 .chained = true,
8850 .chain_id = ALC662_FIXUP_SKU_IGNORE
8851 },
8852 [ALC662_FIXUP_ASUS_MODE4] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008853 .type = HDA_FIXUP_PINS,
8854 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008855 { 0x14, 0x99130110 }, /* speaker */
8856 { 0x16, 0x99130111 }, /* speaker */
8857 { 0x18, 0x01a19840 }, /* mic */
8858 { 0x19, 0x99a3094f }, /* int-mic */
8859 { 0x21, 0x0121441f }, /* HP */
8860 { }
8861 },
8862 .chained = true,
8863 .chain_id = ALC662_FIXUP_SKU_IGNORE
8864 },
8865 [ALC662_FIXUP_ASUS_MODE5] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008866 .type = HDA_FIXUP_PINS,
8867 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008868 { 0x14, 0x99130110 }, /* speaker */
8869 { 0x15, 0x0121441f }, /* HP */
8870 { 0x16, 0x99130111 }, /* speaker */
8871 { 0x18, 0x01a19840 }, /* mic */
8872 { 0x19, 0x99a3094f }, /* int-mic */
8873 { }
8874 },
8875 .chained = true,
8876 .chain_id = ALC662_FIXUP_SKU_IGNORE
8877 },
8878 [ALC662_FIXUP_ASUS_MODE6] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008879 .type = HDA_FIXUP_PINS,
8880 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008881 { 0x14, 0x99130110 }, /* speaker */
8882 { 0x15, 0x01211420 }, /* HP2 */
8883 { 0x18, 0x01a19840 }, /* mic */
8884 { 0x19, 0x99a3094f }, /* int-mic */
8885 { 0x1b, 0x0121441f }, /* HP */
8886 { }
8887 },
8888 .chained = true,
8889 .chain_id = ALC662_FIXUP_SKU_IGNORE
8890 },
8891 [ALC662_FIXUP_ASUS_MODE7] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008892 .type = HDA_FIXUP_PINS,
8893 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008894 { 0x14, 0x99130110 }, /* speaker */
8895 { 0x17, 0x99130111 }, /* speaker */
8896 { 0x18, 0x01a19840 }, /* mic */
8897 { 0x19, 0x99a3094f }, /* int-mic */
8898 { 0x1b, 0x01214020 }, /* HP */
8899 { 0x21, 0x0121401f }, /* HP */
8900 { }
8901 },
8902 .chained = true,
8903 .chain_id = ALC662_FIXUP_SKU_IGNORE
8904 },
8905 [ALC662_FIXUP_ASUS_MODE8] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008906 .type = HDA_FIXUP_PINS,
8907 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008908 { 0x14, 0x99130110 }, /* speaker */
8909 { 0x12, 0x99a30970 }, /* int-mic */
8910 { 0x15, 0x01214020 }, /* HP */
8911 { 0x17, 0x99130111 }, /* speaker */
8912 { 0x18, 0x01a19840 }, /* mic */
8913 { 0x21, 0x0121401f }, /* HP */
8914 { }
8915 },
8916 .chained = true,
8917 .chain_id = ALC662_FIXUP_SKU_IGNORE
Takashi Iwai2996bdb2011-08-18 16:02:24 +02008918 },
Takashi Iwai1565cc32012-02-13 12:03:25 +01008919 [ALC662_FIXUP_NO_JACK_DETECT] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008920 .type = HDA_FIXUP_FUNC,
Takashi Iwai1565cc32012-02-13 12:03:25 +01008921 .v.func = alc_fixup_no_jack_detect,
8922 },
David Henningssonedfe3bf2012-06-12 13:15:12 +02008923 [ALC662_FIXUP_ZOTAC_Z68] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008924 .type = HDA_FIXUP_PINS,
8925 .v.pins = (const struct hda_pintbl[]) {
David Henningssonedfe3bf2012-06-12 13:15:12 +02008926 { 0x1b, 0x02214020 }, /* Front HP */
8927 { }
8928 }
8929 },
Takashi Iwai125821a2012-06-22 14:30:29 +02008930 [ALC662_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008931 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02008932 .v.func = alc_fixup_inv_dmic,
Takashi Iwai125821a2012-06-22 14:30:29 +02008933 },
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02008934 [ALC668_FIXUP_DELL_XPS13] = {
8935 .type = HDA_FIXUP_FUNC,
8936 .v.func = alc_fixup_dell_xps13,
8937 .chained = true,
8938 .chain_id = ALC668_FIXUP_DELL_DISABLE_AAMIX
8939 },
Gabriele Mazzotta5e6db662014-05-20 18:58:26 +02008940 [ALC668_FIXUP_DELL_DISABLE_AAMIX] = {
8941 .type = HDA_FIXUP_FUNC,
8942 .v.func = alc_fixup_disable_aamix,
8943 .chained = true,
8944 .chain_id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE
8945 },
Hui Wang493a52a2014-01-14 14:07:36 +08008946 [ALC668_FIXUP_AUTO_MUTE] = {
8947 .type = HDA_FIXUP_FUNC,
8948 .v.func = alc_fixup_auto_mute_via_amp,
8949 .chained = true,
8950 .chain_id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE
8951 },
David Henningsson1f8b46c2015-05-12 14:38:15 +02008952 [ALC662_FIXUP_DELL_MIC_NO_PRESENCE] = {
8953 .type = HDA_FIXUP_PINS,
8954 .v.pins = (const struct hda_pintbl[]) {
8955 { 0x19, 0x03a1113c }, /* use as headset mic, without its own jack detect */
8956 /* headphone mic by setting pin control of 0x1b (headphone out) to in + vref_50 */
8957 { }
8958 },
8959 .chained = true,
8960 .chain_id = ALC662_FIXUP_HEADSET_MODE
8961 },
8962 [ALC662_FIXUP_HEADSET_MODE] = {
8963 .type = HDA_FIXUP_FUNC,
8964 .v.func = alc_fixup_headset_mode_alc662,
8965 },
David Henningsson73bdd592013-04-15 15:44:14 +02008966 [ALC668_FIXUP_DELL_MIC_NO_PRESENCE] = {
8967 .type = HDA_FIXUP_PINS,
8968 .v.pins = (const struct hda_pintbl[]) {
8969 { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
8970 { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */
8971 { }
8972 },
8973 .chained = true,
8974 .chain_id = ALC668_FIXUP_HEADSET_MODE
8975 },
8976 [ALC668_FIXUP_HEADSET_MODE] = {
8977 .type = HDA_FIXUP_FUNC,
8978 .v.func = alc_fixup_headset_mode_alc668,
8979 },
David Henningsson8e54b4a2014-02-07 09:31:07 +01008980 [ALC662_FIXUP_BASS_MODE4_CHMAP] = {
Takashi Iwai8e383952013-10-30 17:41:12 +01008981 .type = HDA_FIXUP_FUNC,
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01008982 .v.func = alc_fixup_bass_chmap,
Takashi Iwai8e383952013-10-30 17:41:12 +01008983 .chained = true,
8984 .chain_id = ALC662_FIXUP_ASUS_MODE4
8985 },
David Henningsson61a75f12014-02-07 09:31:08 +01008986 [ALC662_FIXUP_BASS_16] = {
8987 .type = HDA_FIXUP_PINS,
8988 .v.pins = (const struct hda_pintbl[]) {
8989 {0x16, 0x80106111}, /* bass speaker */
8990 {}
8991 },
8992 .chained = true,
8993 .chain_id = ALC662_FIXUP_BASS_CHMAP,
8994 },
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01008995 [ALC662_FIXUP_BASS_1A] = {
8996 .type = HDA_FIXUP_PINS,
8997 .v.pins = (const struct hda_pintbl[]) {
8998 {0x1a, 0x80106111}, /* bass speaker */
8999 {}
9000 },
David Henningsson8e54b4a2014-02-07 09:31:07 +01009001 .chained = true,
9002 .chain_id = ALC662_FIXUP_BASS_CHMAP,
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01009003 },
David Henningsson8e54b4a2014-02-07 09:31:07 +01009004 [ALC662_FIXUP_BASS_CHMAP] = {
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01009005 .type = HDA_FIXUP_FUNC,
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01009006 .v.func = alc_fixup_bass_chmap,
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01009007 },
Bobi Mihalca9d4dc582016-03-23 13:26:11 +02009008 [ALC662_FIXUP_ASUS_Nx50] = {
9009 .type = HDA_FIXUP_FUNC,
9010 .v.func = alc_fixup_auto_mute_via_amp,
9011 .chained = true,
9012 .chain_id = ALC662_FIXUP_BASS_1A
9013 },
Mikhail Paulyshkafc7438b2017-04-21 08:52:42 +02009014 [ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE] = {
9015 .type = HDA_FIXUP_FUNC,
9016 .v.func = alc_fixup_headset_mode_alc668,
9017 .chain_id = ALC662_FIXUP_BASS_CHMAP
9018 },
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07009019 [ALC668_FIXUP_ASUS_Nx51] = {
9020 .type = HDA_FIXUP_PINS,
9021 .v.pins = (const struct hda_pintbl[]) {
Mikhail Paulyshkafc7438b2017-04-21 08:52:42 +02009022 { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
9023 { 0x1a, 0x90170151 }, /* bass speaker */
9024 { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07009025 {}
9026 },
9027 .chained = true,
Mikhail Paulyshkafc7438b2017-04-21 08:52:42 +02009028 .chain_id = ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE,
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07009029 },
Takashi Iwai5b7c5e12018-10-09 14:20:17 +02009030 [ALC668_FIXUP_MIC_COEF] = {
Takashi Iwai11ba6112018-10-07 09:44:17 +02009031 .type = HDA_FIXUP_VERBS,
9032 .v.verbs = (const struct hda_verb[]) {
9033 { 0x20, AC_VERB_SET_COEF_INDEX, 0xc3 },
9034 { 0x20, AC_VERB_SET_PROC_COEF, 0x4000 },
9035 {}
9036 },
9037 },
Takashi Iwai5b7c5e12018-10-09 14:20:17 +02009038 [ALC668_FIXUP_ASUS_G751] = {
9039 .type = HDA_FIXUP_PINS,
9040 .v.pins = (const struct hda_pintbl[]) {
9041 { 0x16, 0x0421101f }, /* HP */
9042 {}
9043 },
9044 .chained = true,
9045 .chain_id = ALC668_FIXUP_MIC_COEF
9046 },
Kailang Yang78f4f7c2016-06-07 11:31:34 +08009047 [ALC891_FIXUP_HEADSET_MODE] = {
9048 .type = HDA_FIXUP_FUNC,
9049 .v.func = alc_fixup_headset_mode,
9050 },
9051 [ALC891_FIXUP_DELL_MIC_NO_PRESENCE] = {
9052 .type = HDA_FIXUP_PINS,
9053 .v.pins = (const struct hda_pintbl[]) {
9054 { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
9055 { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */
9056 { }
9057 },
9058 .chained = true,
9059 .chain_id = ALC891_FIXUP_HEADSET_MODE
9060 },
Shrirang Bagul9b51fe32016-08-01 13:16:17 +08009061 [ALC662_FIXUP_ACER_VERITON] = {
9062 .type = HDA_FIXUP_PINS,
9063 .v.pins = (const struct hda_pintbl[]) {
9064 { 0x15, 0x50170120 }, /* no internal speaker */
9065 { }
9066 }
9067 },
Takashi Iwai1a3f0992016-10-20 12:14:51 +02009068 [ALC892_FIXUP_ASROCK_MOBO] = {
9069 .type = HDA_FIXUP_PINS,
9070 .v.pins = (const struct hda_pintbl[]) {
9071 { 0x15, 0x40f000f0 }, /* disabled */
9072 { 0x16, 0x40f000f0 }, /* disabled */
Takashi Iwai1a3f0992016-10-20 12:14:51 +02009073 { }
9074 }
9075 },
Kailang Yangc6790c82016-11-25 16:15:17 +08009076 [ALC662_FIXUP_USI_FUNC] = {
9077 .type = HDA_FIXUP_FUNC,
9078 .v.func = alc662_fixup_usi_headset_mic,
9079 },
9080 [ALC662_FIXUP_USI_HEADSET_MODE] = {
9081 .type = HDA_FIXUP_PINS,
9082 .v.pins = (const struct hda_pintbl[]) {
9083 { 0x19, 0x02a1913c }, /* use as headset mic, without its own jack detect */
9084 { 0x18, 0x01a1903d },
9085 { }
9086 },
9087 .chained = true,
9088 .chain_id = ALC662_FIXUP_USI_FUNC
9089 },
Kailang Yangca169cc2017-04-25 16:17:40 +08009090 [ALC662_FIXUP_LENOVO_MULTI_CODECS] = {
9091 .type = HDA_FIXUP_FUNC,
9092 .v.func = alc233_alc662_fixup_lenovo_dual_codecs,
9093 },
Sergey Bostandzhyan00066e92019-09-06 11:33:43 +02009094 [ALC669_FIXUP_ACER_ASPIRE_ETHOS_HEADSET] = {
9095 .type = HDA_FIXUP_FUNC,
9096 .v.func = alc662_fixup_aspire_ethos_hp,
9097 },
Sergey Bostandzhyan00066e92019-09-06 11:33:43 +02009098 [ALC669_FIXUP_ACER_ASPIRE_ETHOS] = {
9099 .type = HDA_FIXUP_PINS,
9100 .v.pins = (const struct hda_pintbl[]) {
9101 { 0x15, 0x92130110 }, /* front speakers */
9102 { 0x18, 0x99130111 }, /* center/subwoofer */
9103 { 0x1b, 0x11130012 }, /* surround plus jack for HP */
9104 { }
9105 },
9106 .chained = true,
Takashi Iwai336820c2019-11-28 21:26:30 +01009107 .chain_id = ALC669_FIXUP_ACER_ASPIRE_ETHOS_HEADSET
Sergey Bostandzhyan00066e92019-09-06 11:33:43 +02009108 },
Kailang Yang5af290282020-01-17 14:04:01 +08009109 [ALC671_FIXUP_HP_HEADSET_MIC2] = {
9110 .type = HDA_FIXUP_FUNC,
9111 .v.func = alc671_fixup_hp_headset_mic2,
9112 },
Jian-Hong Pand858c702020-03-17 16:28:07 +08009113 [ALC662_FIXUP_ACER_X2660G_HEADSET_MODE] = {
9114 .type = HDA_FIXUP_PINS,
9115 .v.pins = (const struct hda_pintbl[]) {
9116 { 0x1a, 0x02a1113c }, /* use as headset mic, without its own jack detect */
9117 { }
9118 },
9119 .chained = true,
9120 .chain_id = ALC662_FIXUP_USI_FUNC
9121 },
Jian-Hong Pana1244582020-03-17 16:28:09 +08009122 [ALC662_FIXUP_ACER_NITRO_HEADSET_MODE] = {
9123 .type = HDA_FIXUP_PINS,
9124 .v.pins = (const struct hda_pintbl[]) {
9125 { 0x1a, 0x01a11140 }, /* use as headset mic, without its own jack detect */
9126 { 0x1b, 0x0221144f },
9127 { }
9128 },
9129 .chained = true,
9130 .chain_id = ALC662_FIXUP_USI_FUNC
9131 },
David Henningsson6cb3b702010-09-09 08:51:44 +02009132};
9133
Takashi Iwaia9111322011-05-02 11:30:18 +02009134static const struct snd_pci_quirk alc662_fixup_tbl[] = {
Takashi Iwai53c334a2011-08-23 18:27:14 +02009135 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_FIXUP_ASUS_MODE2),
Takashi Iwaid3d38352013-08-19 20:05:50 +02009136 SND_PCI_QUIRK(0x1025, 0x022f, "Acer Aspire One", ALC662_FIXUP_INV_DMIC),
David Henningsson02f6ff92015-12-07 11:29:31 +01009137 SND_PCI_QUIRK(0x1025, 0x0241, "Packard Bell DOTS", ALC662_FIXUP_INV_DMIC),
David Henningssona6c47a82011-02-10 15:39:19 +01009138 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
David Henningsson94024cd2011-04-29 14:10:55 +02009139 SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
Takashi Iwai125821a2012-06-22 14:30:29 +02009140 SND_PCI_QUIRK(0x1025, 0x0349, "eMachines eM250", ALC662_FIXUP_INV_DMIC),
Takashi Iwai18019282013-08-16 08:17:05 +02009141 SND_PCI_QUIRK(0x1025, 0x034a, "Gateway LT27", ALC662_FIXUP_INV_DMIC),
Daniel T Chen2df03512010-10-10 22:39:28 -04009142 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
Jian-Hong Pana1244582020-03-17 16:28:09 +08009143 SND_PCI_QUIRK(0x1025, 0x123c, "Acer Nitro N50-600", ALC662_FIXUP_ACER_NITRO_HEADSET_MODE),
Jian-Hong Pand858c702020-03-17 16:28:07 +08009144 SND_PCI_QUIRK(0x1025, 0x124e, "Acer 2660G", ALC662_FIXUP_ACER_X2660G_HEADSET_MODE),
David Henningsson73bdd592013-04-15 15:44:14 +02009145 SND_PCI_QUIRK(0x1028, 0x05d8, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
9146 SND_PCI_QUIRK(0x1028, 0x05db, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
Takashi Iwaic5d019c2014-07-22 17:33:32 +02009147 SND_PCI_QUIRK(0x1028, 0x05fe, "Dell XPS 15", ALC668_FIXUP_DELL_XPS13),
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02009148 SND_PCI_QUIRK(0x1028, 0x060a, "Dell XPS 13", ALC668_FIXUP_DELL_XPS13),
Niranjan Sivakumar467e1432015-09-05 18:20:35 +02009149 SND_PCI_QUIRK(0x1028, 0x060d, "Dell M3800", ALC668_FIXUP_DELL_XPS13),
David Henningsson09d20142013-11-20 11:43:30 +01009150 SND_PCI_QUIRK(0x1028, 0x0625, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
David Henningssonad8ff99e2013-11-07 09:28:59 +01009151 SND_PCI_QUIRK(0x1028, 0x0626, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
Kailang Yang8dc9abb2014-04-16 15:53:12 +08009152 SND_PCI_QUIRK(0x1028, 0x0696, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
9153 SND_PCI_QUIRK(0x1028, 0x0698, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
Kailang Yang6a98e342014-10-27 16:20:30 +08009154 SND_PCI_QUIRK(0x1028, 0x069f, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
Takashi Iwaie59ea3e2011-06-29 17:21:00 +02009155 SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800),
Kaho Ng2da2dc92016-05-09 00:27:49 +08009156 SND_PCI_QUIRK(0x1043, 0x1080, "Asus UX501VW", ALC668_FIXUP_HEADSET_MODE),
Bobi Mihalca83a9efb2016-03-23 13:32:33 +02009157 SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_ASUS_Nx50),
Takashi Iwaidb8948e2016-01-18 09:17:30 +01009158 SND_PCI_QUIRK(0x1043, 0x13df, "Asus N550JX", ALC662_FIXUP_BASS_1A),
Bobi Mihalca9d4dc582016-03-23 13:26:11 +02009159 SND_PCI_QUIRK(0x1043, 0x129d, "Asus N750", ALC662_FIXUP_ASUS_Nx50),
Takashi Iwai11ba6112018-10-07 09:44:17 +02009160 SND_PCI_QUIRK(0x1043, 0x12ff, "ASUS G751", ALC668_FIXUP_ASUS_G751),
David Henningsson8e54b4a2014-02-07 09:31:07 +01009161 SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
David Henningsson61a75f12014-02-07 09:31:08 +01009162 SND_PCI_QUIRK(0x1043, 0x15a7, "ASUS UX51VZH", ALC662_FIXUP_BASS_16),
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07009163 SND_PCI_QUIRK(0x1043, 0x177d, "ASUS N551", ALC668_FIXUP_ASUS_Nx51),
9164 SND_PCI_QUIRK(0x1043, 0x17bd, "ASUS N751", ALC668_FIXUP_ASUS_Nx51),
Takashi Iwaic7efff92017-01-04 21:38:16 +01009165 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71SL", ALC662_FIXUP_ASUS_MODE8),
David Henningsson61a75f12014-02-07 09:31:08 +01009166 SND_PCI_QUIRK(0x1043, 0x1b73, "ASUS N55SF", ALC662_FIXUP_BASS_16),
David Henningsson8e54b4a2014-02-07 09:31:07 +01009167 SND_PCI_QUIRK(0x1043, 0x1bf3, "ASUS N76VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
Takashi Iwai1565cc32012-02-13 12:03:25 +01009168 SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT),
Takashi Iwai53c334a2011-08-23 18:27:14 +02009169 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2),
Daniel T Chena0e90ac2010-11-20 10:20:35 -05009170 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
Kailang Yangc6790c82016-11-25 16:15:17 +08009171 SND_PCI_QUIRK(0x14cd, 0x5003, "USI", ALC662_FIXUP_USI_HEADSET_MODE),
Kailang Yangca169cc2017-04-25 16:17:40 +08009172 SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC662_FIXUP_LENOVO_MULTI_CODECS),
Valentine Sinitsynd4118582010-10-01 22:24:08 +06009173 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
David Henningsson6cb3b702010-09-09 08:51:44 +02009174 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
Takashi Iwai1a3f0992016-10-20 12:14:51 +02009175 SND_PCI_QUIRK(0x1849, 0x5892, "ASRock B150M", ALC892_FIXUP_ASROCK_MOBO),
David Henningssonedfe3bf2012-06-12 13:15:12 +02009176 SND_PCI_QUIRK(0x19da, 0xa130, "Zotac Z68", ALC662_FIXUP_ZOTAC_Z68),
Shrirang Bagul9b51fe32016-08-01 13:16:17 +08009177 SND_PCI_QUIRK(0x1b0a, 0x01b8, "ACER Veriton", ALC662_FIXUP_ACER_VERITON),
Anisse Astierd2ebd472011-01-20 12:36:21 +01009178 SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
Sergey Bostandzhyan00066e92019-09-06 11:33:43 +02009179 SND_PCI_QUIRK(0x1025, 0x0566, "Acer Aspire Ethos 8951G", ALC669_FIXUP_ACER_ASPIRE_ETHOS),
Takashi Iwai53c334a2011-08-23 18:27:14 +02009180
9181#if 0
9182 /* Below is a quirk table taken from the old code.
9183 * Basically the device should work as is without the fixup table.
9184 * If BIOS doesn't give a proper info, enable the corresponding
9185 * fixup entry.
Jesper Juhl7d7eb9e2012-04-12 22:11:25 +02009186 */
Takashi Iwai53c334a2011-08-23 18:27:14 +02009187 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC662_FIXUP_ASUS_MODE1),
9188 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC662_FIXUP_ASUS_MODE3),
9189 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC662_FIXUP_ASUS_MODE1),
9190 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC662_FIXUP_ASUS_MODE3),
9191 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
9192 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
9193 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
9194 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC662_FIXUP_ASUS_MODE1),
9195 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC662_FIXUP_ASUS_MODE1),
9196 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
9197 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC662_FIXUP_ASUS_MODE7),
9198 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC662_FIXUP_ASUS_MODE7),
9199 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC662_FIXUP_ASUS_MODE8),
9200 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC662_FIXUP_ASUS_MODE3),
9201 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC662_FIXUP_ASUS_MODE1),
9202 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
9203 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_FIXUP_ASUS_MODE2),
9204 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC662_FIXUP_ASUS_MODE1),
9205 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
9206 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
9207 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
9208 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
9209 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC662_FIXUP_ASUS_MODE1),
9210 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC662_FIXUP_ASUS_MODE3),
9211 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_FIXUP_ASUS_MODE2),
9212 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
9213 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC662_FIXUP_ASUS_MODE5),
9214 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
9215 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
9216 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC662_FIXUP_ASUS_MODE1),
9217 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
9218 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
9219 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC662_FIXUP_ASUS_MODE3),
9220 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC662_FIXUP_ASUS_MODE3),
9221 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC662_FIXUP_ASUS_MODE1),
9222 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC662_FIXUP_ASUS_MODE1),
9223 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC662_FIXUP_ASUS_MODE1),
9224 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC662_FIXUP_ASUS_MODE1),
9225 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC662_FIXUP_ASUS_MODE1),
9226 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
9227 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_FIXUP_ASUS_MODE2),
9228 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC662_FIXUP_ASUS_MODE1),
9229 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
9230 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC662_FIXUP_ASUS_MODE3),
9231 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC662_FIXUP_ASUS_MODE1),
9232 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC662_FIXUP_ASUS_MODE1),
9233 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC662_FIXUP_ASUS_MODE1),
9234 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_FIXUP_ASUS_MODE2),
9235 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
9236 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE4),
9237#endif
David Henningsson6cb3b702010-09-09 08:51:44 +02009238 {}
9239};
9240
Takashi Iwai1727a772013-01-10 09:52:52 +01009241static const struct hda_model_fixup alc662_fixup_models[] = {
Takashi Iwaiaa3841b2018-06-26 07:42:40 +02009242 {.id = ALC662_FIXUP_ASPIRE, .name = "aspire"},
9243 {.id = ALC662_FIXUP_IDEAPAD, .name = "ideapad"},
Todd Broch6be79482010-12-07 16:51:05 -08009244 {.id = ALC272_FIXUP_MARIO, .name = "mario"},
Takashi Iwaiaa3841b2018-06-26 07:42:40 +02009245 {.id = ALC662_FIXUP_HP_RP5800, .name = "hp-rp5800"},
Takashi Iwai53c334a2011-08-23 18:27:14 +02009246 {.id = ALC662_FIXUP_ASUS_MODE1, .name = "asus-mode1"},
9247 {.id = ALC662_FIXUP_ASUS_MODE2, .name = "asus-mode2"},
9248 {.id = ALC662_FIXUP_ASUS_MODE3, .name = "asus-mode3"},
9249 {.id = ALC662_FIXUP_ASUS_MODE4, .name = "asus-mode4"},
9250 {.id = ALC662_FIXUP_ASUS_MODE5, .name = "asus-mode5"},
9251 {.id = ALC662_FIXUP_ASUS_MODE6, .name = "asus-mode6"},
9252 {.id = ALC662_FIXUP_ASUS_MODE7, .name = "asus-mode7"},
9253 {.id = ALC662_FIXUP_ASUS_MODE8, .name = "asus-mode8"},
Takashi Iwaiaa3841b2018-06-26 07:42:40 +02009254 {.id = ALC662_FIXUP_ZOTAC_Z68, .name = "zotac-z68"},
Takashi Iwai6e72aa52012-06-25 10:52:25 +02009255 {.id = ALC662_FIXUP_INV_DMIC, .name = "inv-dmic"},
Takashi Iwaiaa3841b2018-06-26 07:42:40 +02009256 {.id = ALC662_FIXUP_DELL_MIC_NO_PRESENCE, .name = "alc662-headset-multi"},
David Henningssone32aa852013-06-17 11:04:02 +02009257 {.id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE, .name = "dell-headset-multi"},
Takashi Iwaiaa3841b2018-06-26 07:42:40 +02009258 {.id = ALC662_FIXUP_HEADSET_MODE, .name = "alc662-headset"},
9259 {.id = ALC668_FIXUP_HEADSET_MODE, .name = "alc668-headset"},
9260 {.id = ALC662_FIXUP_BASS_16, .name = "bass16"},
9261 {.id = ALC662_FIXUP_BASS_1A, .name = "bass1a"},
9262 {.id = ALC668_FIXUP_AUTO_MUTE, .name = "automute"},
9263 {.id = ALC668_FIXUP_DELL_XPS13, .name = "dell-xps13"},
9264 {.id = ALC662_FIXUP_ASUS_Nx50, .name = "asus-nx50"},
9265 {.id = ALC668_FIXUP_ASUS_Nx51, .name = "asus-nx51"},
Takashi Iwai40c51672018-10-07 09:47:39 +02009266 {.id = ALC668_FIXUP_ASUS_G751, .name = "asus-g751"},
Takashi Iwaiaa3841b2018-06-26 07:42:40 +02009267 {.id = ALC891_FIXUP_HEADSET_MODE, .name = "alc891-headset"},
9268 {.id = ALC891_FIXUP_DELL_MIC_NO_PRESENCE, .name = "alc891-headset-multi"},
9269 {.id = ALC662_FIXUP_ACER_VERITON, .name = "acer-veriton"},
9270 {.id = ALC892_FIXUP_ASROCK_MOBO, .name = "asrock-mobo"},
9271 {.id = ALC662_FIXUP_USI_HEADSET_MODE, .name = "usi-headset"},
Takashi Iwaiba90d6a2017-05-22 16:38:47 +02009272 {.id = ALC662_FIXUP_LENOVO_MULTI_CODECS, .name = "dual-codecs"},
Sergey Bostandzhyan00066e92019-09-06 11:33:43 +02009273 {.id = ALC669_FIXUP_ACER_ASPIRE_ETHOS, .name = "aspire-ethos"},
Todd Broch6be79482010-12-07 16:51:05 -08009274 {}
9275};
David Henningsson6cb3b702010-09-09 08:51:44 +02009276
Hui Wang532895c2014-05-29 15:59:19 +08009277static const struct snd_hda_pin_quirk alc662_pin_fixup_tbl[] = {
Kailang Yang78f4f7c2016-06-07 11:31:34 +08009278 SND_HDA_PIN_QUIRK(0x10ec0867, 0x1028, "Dell", ALC891_FIXUP_DELL_MIC_NO_PRESENCE,
9279 {0x17, 0x02211010},
9280 {0x18, 0x01a19030},
9281 {0x1a, 0x01813040},
9282 {0x21, 0x01014020}),
Hui Wang4b4e0e32019-07-16 15:21:34 +08009283 SND_HDA_PIN_QUIRK(0x10ec0867, 0x1028, "Dell", ALC891_FIXUP_DELL_MIC_NO_PRESENCE,
9284 {0x16, 0x01813030},
9285 {0x17, 0x02211010},
9286 {0x18, 0x01a19040},
9287 {0x21, 0x01014020}),
David Henningsson1f8b46c2015-05-12 14:38:15 +02009288 SND_HDA_PIN_QUIRK(0x10ec0662, 0x1028, "Dell", ALC662_FIXUP_DELL_MIC_NO_PRESENCE,
David Henningsson1f8b46c2015-05-12 14:38:15 +02009289 {0x14, 0x01014010},
David Henningsson1f8b46c2015-05-12 14:38:15 +02009290 {0x18, 0x01a19020},
David Henningsson1f8b46c2015-05-12 14:38:15 +02009291 {0x1a, 0x0181302f},
Hui Wang11580292015-08-03 11:03:49 +08009292 {0x1b, 0x0221401f}),
David Henningsson76c21322014-06-24 14:46:54 +02009293 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
9294 {0x12, 0x99a30130},
9295 {0x14, 0x90170110},
9296 {0x15, 0x0321101f},
Hui Wang11580292015-08-03 11:03:49 +08009297 {0x16, 0x03011020}),
David Henningsson76c21322014-06-24 14:46:54 +02009298 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
9299 {0x12, 0x99a30140},
9300 {0x14, 0x90170110},
9301 {0x15, 0x0321101f},
Hui Wang11580292015-08-03 11:03:49 +08009302 {0x16, 0x03011020}),
David Henningsson76c21322014-06-24 14:46:54 +02009303 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
9304 {0x12, 0x99a30150},
9305 {0x14, 0x90170110},
9306 {0x15, 0x0321101f},
Hui Wang11580292015-08-03 11:03:49 +08009307 {0x16, 0x03011020}),
David Henningsson76c21322014-06-24 14:46:54 +02009308 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
David Henningsson76c21322014-06-24 14:46:54 +02009309 {0x14, 0x90170110},
9310 {0x15, 0x0321101f},
Hui Wang11580292015-08-03 11:03:49 +08009311 {0x16, 0x03011020}),
David Henningsson76c21322014-06-24 14:46:54 +02009312 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell XPS 15", ALC668_FIXUP_AUTO_MUTE,
9313 {0x12, 0x90a60130},
9314 {0x14, 0x90170110},
Hui Wang11580292015-08-03 11:03:49 +08009315 {0x15, 0x0321101f}),
Kailang Yang5af290282020-01-17 14:04:01 +08009316 SND_HDA_PIN_QUIRK(0x10ec0671, 0x103c, "HP cPC", ALC671_FIXUP_HP_HEADSET_MIC2,
9317 {0x14, 0x01014010},
9318 {0x17, 0x90170150},
Kailang Yangf2adbae2020-02-05 15:40:01 +08009319 {0x19, 0x02a11060},
Kailang Yang5af290282020-01-17 14:04:01 +08009320 {0x1b, 0x01813030},
9321 {0x21, 0x02211020}),
9322 SND_HDA_PIN_QUIRK(0x10ec0671, 0x103c, "HP cPC", ALC671_FIXUP_HP_HEADSET_MIC2,
9323 {0x14, 0x01014010},
9324 {0x18, 0x01a19040},
9325 {0x1b, 0x01813030},
9326 {0x21, 0x02211020}),
9327 SND_HDA_PIN_QUIRK(0x10ec0671, 0x103c, "HP cPC", ALC671_FIXUP_HP_HEADSET_MIC2,
9328 {0x14, 0x01014020},
9329 {0x17, 0x90170110},
9330 {0x18, 0x01a19050},
9331 {0x1b, 0x01813040},
9332 {0x21, 0x02211030}),
Hui Wang532895c2014-05-29 15:59:19 +08009333 {}
9334};
9335
Takashi Iwai1d045db2011-07-07 18:23:21 +02009336/*
9337 */
Kailang Yangbc9f98a2007-04-12 13:06:07 +02009338static int patch_alc662(struct hda_codec *codec)
9339{
9340 struct alc_spec *spec;
Takashi Iwai3de95172012-05-07 18:03:15 +02009341 int err;
Kailang Yangbc9f98a2007-04-12 13:06:07 +02009342
Takashi Iwai3de95172012-05-07 18:03:15 +02009343 err = alc_alloc_spec(codec, 0x0b);
9344 if (err < 0)
9345 return err;
Kailang Yangbc9f98a2007-04-12 13:06:07 +02009346
Takashi Iwai3de95172012-05-07 18:03:15 +02009347 spec = codec->spec;
Takashi Iwai1f0f4b82011-06-27 10:52:59 +02009348
Takashi Iwai225068a2015-05-29 10:42:14 +02009349 spec->shutup = alc_eapd_shutup;
9350
Takashi Iwai53c334a2011-08-23 18:27:14 +02009351 /* handle multiple HPs as is */
9352 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
9353
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +02009354 alc_fix_pll_init(codec, 0x20, 0x04, 15);
9355
Takashi Iwai7639a062015-03-03 10:07:24 +01009356 switch (codec->core.vendor_id) {
Kailang Yangf3f91852014-10-24 15:43:46 +08009357 case 0x10ec0668:
9358 spec->init_hook = alc668_restore_default_value;
9359 break;
Kailang Yangf3f91852014-10-24 15:43:46 +08009360 }
Kailang Yang8663ff72012-06-29 09:35:52 +02009361
Takashi Iwaic9af7532019-05-10 11:01:43 +02009362 alc_pre_init(codec);
9363
Takashi Iwai1727a772013-01-10 09:52:52 +01009364 snd_hda_pick_fixup(codec, alc662_fixup_models,
Takashi Iwai8e5a0502012-06-21 15:49:33 +02009365 alc662_fixup_tbl, alc662_fixups);
Hui Wang0fc1e442019-08-16 14:27:39 +08009366 snd_hda_pick_pin_fixup(codec, alc662_pin_fixup_tbl, alc662_fixups, true);
Takashi Iwai1727a772013-01-10 09:52:52 +01009367 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai8e5a0502012-06-21 15:49:33 +02009368
9369 alc_auto_parse_customize_define(codec);
9370
Takashi Iwai7504b6c2013-03-18 11:25:51 +01009371 if (has_cdefine_beep(codec))
9372 spec->gen.beep_nid = 0x01;
9373
Takashi Iwai1bb7e432011-10-17 16:50:59 +02009374 if ((alc_get_coef0(codec) & (1 << 14)) &&
Takashi Iwai5100cd02014-02-15 10:03:19 +01009375 codec->bus->pci && codec->bus->pci->subsystem_vendor == 0x1025 &&
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02009376 spec->cdefine.platform_type == 1) {
Wei Yongjun6134b1a2013-04-18 11:12:59 +08009377 err = alc_codec_rename(codec, "ALC272X");
9378 if (err < 0)
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02009379 goto error;
Takashi Iwai20ca0c32011-10-17 16:00:35 +02009380 }
Kailang Yang274693f2009-12-03 10:07:50 +01009381
Takashi Iwaib9c51062011-08-24 18:08:07 +02009382 /* automatic parse from the BIOS config */
9383 err = alc662_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02009384 if (err < 0)
9385 goto error;
Kailang Yangbc9f98a2007-04-12 13:06:07 +02009386
Takashi Iwai7504b6c2013-03-18 11:25:51 +01009387 if (!spec->gen.no_analog && spec->gen.beep_nid) {
Takashi Iwai7639a062015-03-03 10:07:24 +01009388 switch (codec->core.vendor_id) {
Kailang Yangda00c242010-03-19 11:23:45 +01009389 case 0x10ec0662:
Takashi Iwaifea80fa2018-06-20 12:52:46 +02009390 err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
Kailang Yangda00c242010-03-19 11:23:45 +01009391 break;
9392 case 0x10ec0272:
9393 case 0x10ec0663:
9394 case 0x10ec0665:
Kailang Yang9ad54542013-11-26 15:41:40 +08009395 case 0x10ec0668:
Takashi Iwaifea80fa2018-06-20 12:52:46 +02009396 err = set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
Kailang Yangda00c242010-03-19 11:23:45 +01009397 break;
9398 case 0x10ec0273:
Takashi Iwaifea80fa2018-06-20 12:52:46 +02009399 err = set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
Kailang Yangda00c242010-03-19 11:23:45 +01009400 break;
9401 }
Takashi Iwaifea80fa2018-06-20 12:52:46 +02009402 if (err < 0)
9403 goto error;
Kailang Yangcec27c82010-02-04 14:18:18 +01009404 }
Takashi Iwai2134ea42008-01-10 16:53:55 +01009405
Takashi Iwai1727a772013-01-10 09:52:52 +01009406 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01009407
Kailang Yangbc9f98a2007-04-12 13:06:07 +02009408 return 0;
Kailang Yangbc9f98a2007-04-12 13:06:07 +02009409
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02009410 error:
9411 alc_free(codec);
9412 return err;
Kailang Yangb478b992011-05-18 11:51:15 +02009413}
9414
Kailang Yangbc9f98a2007-04-12 13:06:07 +02009415/*
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009416 * ALC680 support
9417 */
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009418
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009419static int alc680_parse_auto_config(struct hda_codec *codec)
9420{
Takashi Iwai3e6179b2011-07-08 16:55:13 +02009421 return alc_parse_auto_config(codec, NULL, NULL);
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009422}
9423
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009424/*
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009425 */
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009426static int patch_alc680(struct hda_codec *codec)
9427{
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009428 int err;
9429
Takashi Iwai1f0f4b82011-06-27 10:52:59 +02009430 /* ALC680 has no aa-loopback mixer */
Takashi Iwai3de95172012-05-07 18:03:15 +02009431 err = alc_alloc_spec(codec, 0);
9432 if (err < 0)
9433 return err;
Takashi Iwai1f0f4b82011-06-27 10:52:59 +02009434
Takashi Iwai1ebec5f2011-08-15 13:21:48 +02009435 /* automatic parse from the BIOS config */
9436 err = alc680_parse_auto_config(codec);
9437 if (err < 0) {
9438 alc_free(codec);
9439 return err;
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009440 }
9441
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009442 return 0;
9443}
9444
9445/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07009446 * patch entries
9447 */
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009448static const struct hda_device_id snd_hda_id_realtek[] = {
Kailang Yang0a6f0602017-06-30 16:00:48 +08009449 HDA_CODEC_ENTRY(0x10ec0215, "ALC215", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009450 HDA_CODEC_ENTRY(0x10ec0221, "ALC221", patch_alc269),
Hui Wang2a36c162019-09-04 13:53:27 +08009451 HDA_CODEC_ENTRY(0x10ec0222, "ALC222", patch_alc269),
Kailang Yang42314302016-02-03 15:03:50 +08009452 HDA_CODEC_ENTRY(0x10ec0225, "ALC225", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009453 HDA_CODEC_ENTRY(0x10ec0231, "ALC231", patch_alc269),
9454 HDA_CODEC_ENTRY(0x10ec0233, "ALC233", patch_alc269),
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08009455 HDA_CODEC_ENTRY(0x10ec0234, "ALC234", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009456 HDA_CODEC_ENTRY(0x10ec0235, "ALC233", patch_alc269),
Kailang Yang736f20a2017-10-20 15:06:34 +08009457 HDA_CODEC_ENTRY(0x10ec0236, "ALC236", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009458 HDA_CODEC_ENTRY(0x10ec0255, "ALC255", patch_alc269),
9459 HDA_CODEC_ENTRY(0x10ec0256, "ALC256", patch_alc269),
Kailang Yangf429e7e2017-12-05 15:38:24 +08009460 HDA_CODEC_ENTRY(0x10ec0257, "ALC257", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009461 HDA_CODEC_ENTRY(0x10ec0260, "ALC260", patch_alc260),
9462 HDA_CODEC_ENTRY(0x10ec0262, "ALC262", patch_alc262),
9463 HDA_CODEC_ENTRY(0x10ec0267, "ALC267", patch_alc268),
9464 HDA_CODEC_ENTRY(0x10ec0268, "ALC268", patch_alc268),
9465 HDA_CODEC_ENTRY(0x10ec0269, "ALC269", patch_alc269),
9466 HDA_CODEC_ENTRY(0x10ec0270, "ALC270", patch_alc269),
9467 HDA_CODEC_ENTRY(0x10ec0272, "ALC272", patch_alc662),
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08009468 HDA_CODEC_ENTRY(0x10ec0274, "ALC274", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009469 HDA_CODEC_ENTRY(0x10ec0275, "ALC275", patch_alc269),
9470 HDA_CODEC_ENTRY(0x10ec0276, "ALC276", patch_alc269),
9471 HDA_CODEC_ENTRY(0x10ec0280, "ALC280", patch_alc269),
9472 HDA_CODEC_ENTRY(0x10ec0282, "ALC282", patch_alc269),
9473 HDA_CODEC_ENTRY(0x10ec0283, "ALC283", patch_alc269),
9474 HDA_CODEC_ENTRY(0x10ec0284, "ALC284", patch_alc269),
Kailang Yang0a6f0602017-06-30 16:00:48 +08009475 HDA_CODEC_ENTRY(0x10ec0285, "ALC285", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009476 HDA_CODEC_ENTRY(0x10ec0286, "ALC286", patch_alc269),
9477 HDA_CODEC_ENTRY(0x10ec0288, "ALC288", patch_alc269),
Kailang Yang0a6f0602017-06-30 16:00:48 +08009478 HDA_CODEC_ENTRY(0x10ec0289, "ALC289", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009479 HDA_CODEC_ENTRY(0x10ec0290, "ALC290", patch_alc269),
9480 HDA_CODEC_ENTRY(0x10ec0292, "ALC292", patch_alc269),
9481 HDA_CODEC_ENTRY(0x10ec0293, "ALC293", patch_alc269),
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08009482 HDA_CODEC_ENTRY(0x10ec0294, "ALC294", patch_alc269),
Kailang Yang7d727862016-05-24 16:46:07 +08009483 HDA_CODEC_ENTRY(0x10ec0295, "ALC295", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009484 HDA_CODEC_ENTRY(0x10ec0298, "ALC298", patch_alc269),
Kailang Yang28f1f9b2017-01-04 14:49:07 +08009485 HDA_CODEC_ENTRY(0x10ec0299, "ALC299", patch_alc269),
Kailang Yang1078bef2018-11-08 16:36:15 +08009486 HDA_CODEC_ENTRY(0x10ec0300, "ALC300", patch_alc269),
Kailang Yangf0778872019-10-24 15:13:32 +08009487 HDA_CODEC_ENTRY(0x10ec0623, "ALC623", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009488 HDA_CODEC_REV_ENTRY(0x10ec0861, 0x100340, "ALC660", patch_alc861),
9489 HDA_CODEC_ENTRY(0x10ec0660, "ALC660-VD", patch_alc861vd),
9490 HDA_CODEC_ENTRY(0x10ec0861, "ALC861", patch_alc861),
9491 HDA_CODEC_ENTRY(0x10ec0862, "ALC861-VD", patch_alc861vd),
9492 HDA_CODEC_REV_ENTRY(0x10ec0662, 0x100002, "ALC662 rev2", patch_alc882),
9493 HDA_CODEC_REV_ENTRY(0x10ec0662, 0x100101, "ALC662 rev1", patch_alc662),
9494 HDA_CODEC_REV_ENTRY(0x10ec0662, 0x100300, "ALC662 rev3", patch_alc662),
9495 HDA_CODEC_ENTRY(0x10ec0663, "ALC663", patch_alc662),
9496 HDA_CODEC_ENTRY(0x10ec0665, "ALC665", patch_alc662),
9497 HDA_CODEC_ENTRY(0x10ec0667, "ALC667", patch_alc662),
9498 HDA_CODEC_ENTRY(0x10ec0668, "ALC668", patch_alc662),
9499 HDA_CODEC_ENTRY(0x10ec0670, "ALC670", patch_alc662),
9500 HDA_CODEC_ENTRY(0x10ec0671, "ALC671", patch_alc662),
9501 HDA_CODEC_ENTRY(0x10ec0680, "ALC680", patch_alc680),
Kailang Yang6fbae352016-05-30 16:44:20 +08009502 HDA_CODEC_ENTRY(0x10ec0700, "ALC700", patch_alc269),
9503 HDA_CODEC_ENTRY(0x10ec0701, "ALC701", patch_alc269),
9504 HDA_CODEC_ENTRY(0x10ec0703, "ALC703", patch_alc269),
Kailang Yang83629532019-05-02 16:03:26 +08009505 HDA_CODEC_ENTRY(0x10ec0711, "ALC711", patch_alc269),
Kailang Yang78f4f7c2016-06-07 11:31:34 +08009506 HDA_CODEC_ENTRY(0x10ec0867, "ALC891", patch_alc662),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009507 HDA_CODEC_ENTRY(0x10ec0880, "ALC880", patch_alc880),
9508 HDA_CODEC_ENTRY(0x10ec0882, "ALC882", patch_alc882),
9509 HDA_CODEC_ENTRY(0x10ec0883, "ALC883", patch_alc882),
9510 HDA_CODEC_REV_ENTRY(0x10ec0885, 0x100101, "ALC889A", patch_alc882),
9511 HDA_CODEC_REV_ENTRY(0x10ec0885, 0x100103, "ALC889A", patch_alc882),
9512 HDA_CODEC_ENTRY(0x10ec0885, "ALC885", patch_alc882),
9513 HDA_CODEC_ENTRY(0x10ec0887, "ALC887", patch_alc882),
9514 HDA_CODEC_REV_ENTRY(0x10ec0888, 0x100101, "ALC1200", patch_alc882),
9515 HDA_CODEC_ENTRY(0x10ec0888, "ALC888", patch_alc882),
9516 HDA_CODEC_ENTRY(0x10ec0889, "ALC889", patch_alc882),
9517 HDA_CODEC_ENTRY(0x10ec0892, "ALC892", patch_alc662),
9518 HDA_CODEC_ENTRY(0x10ec0899, "ALC898", patch_alc882),
9519 HDA_CODEC_ENTRY(0x10ec0900, "ALC1150", patch_alc882),
Kailang Yang6d9ffcf2020-01-03 16:24:06 +08009520 HDA_CODEC_ENTRY(0x10ec0b00, "ALCS1200A", patch_alc882),
Kailang Yang65553b12017-07-11 15:15:47 +08009521 HDA_CODEC_ENTRY(0x10ec1168, "ALC1220", patch_alc882),
Kailang Yanga535ad52017-01-16 16:59:26 +08009522 HDA_CODEC_ENTRY(0x10ec1220, "ALC1220", patch_alc882),
Linus Torvalds1da177e2005-04-16 15:20:36 -07009523 {} /* terminator */
9524};
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009525MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_realtek);
Takashi Iwai1289e9e2008-11-27 15:47:11 +01009526
9527MODULE_LICENSE("GPL");
9528MODULE_DESCRIPTION("Realtek HD-audio codec");
9529
Takashi Iwaid8a766a2015-02-17 15:25:37 +01009530static struct hda_codec_driver realtek_driver = {
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009531 .id = snd_hda_id_realtek,
Takashi Iwai1289e9e2008-11-27 15:47:11 +01009532};
9533
Takashi Iwaid8a766a2015-02-17 15:25:37 +01009534module_hda_codec_driver(realtek_driver);