blob: dc5557d79c43e079dbeb42b90ca8a96882f1d79e [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 Iwai177943a2011-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 Iwai177943a2011-11-09 12:55:18 +01002196 },
2197 [ALC882_FIXUP_EAPD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002198 .type = HDA_FIXUP_VERBS,
Takashi Iwai177943a2011-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 Iwai177943a2011-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 Iwai1d3aa4a2020-04-08 15:56:45 +02002458 SND_PCI_QUIRK(0x1462, 0x1275, "MSI-GL63", ALC1220_FIXUP_CLEVO_P950),
Takashi Iwai7dafba32020-02-12 09:10:47 +01002459 SND_PCI_QUIRK(0x1462, 0x1276, "MSI-GL73", ALC1220_FIXUP_CLEVO_P950),
Takashi Iwaicc5049a2020-02-18 09:09:15 +01002460 SND_PCI_QUIRK(0x1462, 0x1293, "MSI-GP65", ALC1220_FIXUP_CLEVO_P950),
Takashi Iwaid2c3b142017-06-01 09:35:30 +02002461 SND_PCI_QUIRK(0x1462, 0x7350, "MSI-7350", ALC889_FIXUP_CD),
Takashi Iwai63691582017-05-22 16:32:46 +02002462 SND_PCI_QUIRK(0x1462, 0xda57, "MSI Z270-Gaming", ALC1220_FIXUP_GB_DUAL_CODECS),
Takashi Iwaid2c3b142017-06-01 09:35:30 +02002463 SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3),
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002464 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX),
Peisen0202f5c2017-10-26 10:35:36 +08002465 SND_PCI_QUIRK(0x1558, 0x9501, "Clevo P950HR", ALC1220_FIXUP_CLEVO_P950),
Takashi Iwaif3d737b2018-07-17 17:08:32 +02002466 SND_PCI_QUIRK(0x1558, 0x95e1, "Clevo P95xER", ALC1220_FIXUP_CLEVO_P950),
Jeremy Soller2f0d5202018-05-07 09:28:45 -06002467 SND_PCI_QUIRK(0x1558, 0x95e2, "Clevo P950ER", ALC1220_FIXUP_CLEVO_P950),
Richard Sailer503d90b2019-06-19 13:33:11 +02002468 SND_PCI_QUIRK(0x1558, 0x96e1, "Clevo P960[ER][CDFN]-K", ALC1220_FIXUP_CLEVO_P950),
2469 SND_PCI_QUIRK(0x1558, 0x97e1, "Clevo P970[ER][CDFN]", ALC1220_FIXUP_CLEVO_P950),
2470 SND_PCI_QUIRK(0x1558, 0x65d1, "Clevo PB51[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
2471 SND_PCI_QUIRK(0x1558, 0x67d1, "Clevo PB71[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
Takashi Iwai7a6069b2011-11-09 15:22:01 +01002472 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD),
2473 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD),
Takashi Iwaiac9b1cd2011-11-09 17:45:55 +01002474 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", ALC882_FIXUP_LENOVO_Y530),
Takashi Iwai68ef0562011-11-09 18:24:44 +01002475 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_FIXUP_COEF),
Takashi Iwai1d045db2011-07-07 18:23:21 +02002476 {}
2477};
2478
Takashi Iwai1727a772013-01-10 09:52:52 +01002479static const struct hda_model_fixup alc882_fixup_models[] = {
Takashi Iwai772c2912018-06-26 17:17:53 +02002480 {.id = ALC882_FIXUP_ABIT_AW9D_MAX, .name = "abit-aw9d"},
2481 {.id = ALC882_FIXUP_LENOVO_Y530, .name = "lenovo-y530"},
2482 {.id = ALC882_FIXUP_ACER_ASPIRE_7736, .name = "acer-aspire-7736"},
2483 {.id = ALC882_FIXUP_ASUS_W90V, .name = "asus-w90v"},
2484 {.id = ALC889_FIXUP_CD, .name = "cd"},
2485 {.id = ALC889_FIXUP_FRONT_HP_NO_PRESENCE, .name = "no-front-hp"},
2486 {.id = ALC889_FIXUP_VAIO_TT, .name = "vaio-tt"},
2487 {.id = ALC888_FIXUP_EEE1601, .name = "eee1601"},
2488 {.id = ALC882_FIXUP_EAPD, .name = "alc882-eapd"},
2489 {.id = ALC883_FIXUP_EAPD, .name = "alc883-eapd"},
2490 {.id = ALC882_FIXUP_GPIO1, .name = "gpio1"},
2491 {.id = ALC882_FIXUP_GPIO2, .name = "gpio2"},
2492 {.id = ALC882_FIXUP_GPIO3, .name = "gpio3"},
2493 {.id = ALC889_FIXUP_COEF, .name = "alc889-coef"},
2494 {.id = ALC882_FIXUP_ASUS_W2JC, .name = "asus-w2jc"},
Takashi Iwai912093b2012-04-11 14:03:41 +02002495 {.id = ALC882_FIXUP_ACER_ASPIRE_4930G, .name = "acer-aspire-4930g"},
2496 {.id = ALC882_FIXUP_ACER_ASPIRE_8930G, .name = "acer-aspire-8930g"},
2497 {.id = ALC883_FIXUP_ACER_EAPD, .name = "acer-aspire"},
Takashi Iwai772c2912018-06-26 17:17:53 +02002498 {.id = ALC885_FIXUP_MACPRO_GPIO, .name = "macpro-gpio"},
2499 {.id = ALC889_FIXUP_DAC_ROUTE, .name = "dac-route"},
2500 {.id = ALC889_FIXUP_MBP_VREF, .name = "mbp-vref"},
2501 {.id = ALC889_FIXUP_IMAC91_VREF, .name = "imac91-vref"},
2502 {.id = ALC889_FIXUP_MBA11_VREF, .name = "mba11-vref"},
2503 {.id = ALC889_FIXUP_MBA21_VREF, .name = "mba21-vref"},
2504 {.id = ALC889_FIXUP_MP11_VREF, .name = "mp11-vref"},
2505 {.id = ALC889_FIXUP_MP41_VREF, .name = "mp41-vref"},
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002506 {.id = ALC882_FIXUP_INV_DMIC, .name = "inv-dmic"},
Takashi Iwaie427c232012-07-29 10:04:08 +02002507 {.id = ALC882_FIXUP_NO_PRIMARY_HP, .name = "no-primary-hp"},
Takashi Iwai772c2912018-06-26 17:17:53 +02002508 {.id = ALC887_FIXUP_ASUS_BASS, .name = "asus-bass"},
Takashi Iwaiba90d6a2017-05-22 16:38:47 +02002509 {.id = ALC1220_FIXUP_GB_DUAL_CODECS, .name = "dual-codecs"},
Takashi Iwai772c2912018-06-26 17:17:53 +02002510 {.id = ALC1220_FIXUP_CLEVO_P950, .name = "clevo-p950"},
Takashi Iwai912093b2012-04-11 14:03:41 +02002511 {}
2512};
2513
Takashi Iwai1d045db2011-07-07 18:23:21 +02002514/*
2515 * BIOS auto configuration
2516 */
2517/* almost identical with ALC880 parser... */
2518static int alc882_parse_auto_config(struct hda_codec *codec)
2519{
Takashi Iwai1d045db2011-07-07 18:23:21 +02002520 static const hda_nid_t alc882_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002521 static const hda_nid_t alc882_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2522 return alc_parse_auto_config(codec, alc882_ignore, alc882_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002523}
2524
Takashi Iwai1d045db2011-07-07 18:23:21 +02002525/*
2526 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002527static int patch_alc882(struct hda_codec *codec)
2528{
2529 struct alc_spec *spec;
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002530 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002531
Takashi Iwai3de95172012-05-07 18:03:15 +02002532 err = alc_alloc_spec(codec, 0x0b);
2533 if (err < 0)
2534 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002535
Takashi Iwai3de95172012-05-07 18:03:15 +02002536 spec = codec->spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002537
Takashi Iwai7639a062015-03-03 10:07:24 +01002538 switch (codec->core.vendor_id) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002539 case 0x10ec0882:
2540 case 0x10ec0885:
Takashi Iwaiacf08082014-09-02 07:21:56 +02002541 case 0x10ec0900:
Kailang Yang6d9ffcf2020-01-03 16:24:06 +08002542 case 0x10ec0b00:
Kailang Yanga535ad52017-01-16 16:59:26 +08002543 case 0x10ec1220:
Takashi Iwai1d045db2011-07-07 18:23:21 +02002544 break;
2545 default:
2546 /* ALC883 and variants */
2547 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
2548 break;
2549 }
2550
Takashi Iwaic9af7532019-05-10 11:01:43 +02002551 alc_pre_init(codec);
2552
Takashi Iwai1727a772013-01-10 09:52:52 +01002553 snd_hda_pick_fixup(codec, alc882_fixup_models, alc882_fixup_tbl,
Takashi Iwai912093b2012-04-11 14:03:41 +02002554 alc882_fixups);
Takashi Iwai1727a772013-01-10 09:52:52 +01002555 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002556
2557 alc_auto_parse_customize_define(codec);
2558
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002559 if (has_cdefine_beep(codec))
2560 spec->gen.beep_nid = 0x01;
2561
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002562 /* automatic parse from the BIOS config */
2563 err = alc882_parse_auto_config(codec);
2564 if (err < 0)
2565 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002566
Takashi Iwaifea80fa2018-06-20 12:52:46 +02002567 if (!spec->gen.no_analog && spec->gen.beep_nid) {
2568 err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
2569 if (err < 0)
2570 goto error;
2571 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02002572
Takashi Iwai1727a772013-01-10 09:52:52 +01002573 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01002574
Takashi Iwai1d045db2011-07-07 18:23:21 +02002575 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02002576
2577 error:
2578 alc_free(codec);
2579 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002580}
2581
2582
2583/*
2584 * ALC262 support
2585 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002586static int alc262_parse_auto_config(struct hda_codec *codec)
2587{
Takashi Iwai1d045db2011-07-07 18:23:21 +02002588 static const hda_nid_t alc262_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002589 static const hda_nid_t alc262_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2590 return alc_parse_auto_config(codec, alc262_ignore, alc262_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002591}
2592
2593/*
2594 * Pin config fixes
2595 */
2596enum {
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002597 ALC262_FIXUP_FSC_H270,
Takashi Iwai7513e6d2013-01-18 15:41:34 +01002598 ALC262_FIXUP_FSC_S7110,
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002599 ALC262_FIXUP_HP_Z200,
2600 ALC262_FIXUP_TYAN,
Takashi Iwaic4701502011-11-07 14:20:07 +01002601 ALC262_FIXUP_LENOVO_3000,
Takashi Iwaib42590b2011-11-07 14:41:01 +01002602 ALC262_FIXUP_BENQ,
2603 ALC262_FIXUP_BENQ_T31,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002604 ALC262_FIXUP_INV_DMIC,
Mengdong Linb5c66112013-11-29 00:35:35 -05002605 ALC262_FIXUP_INTEL_BAYLEYBAY,
Takashi Iwai1d045db2011-07-07 18:23:21 +02002606};
2607
Takashi Iwai1727a772013-01-10 09:52:52 +01002608static const struct hda_fixup alc262_fixups[] = {
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002609 [ALC262_FIXUP_FSC_H270] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002610 .type = HDA_FIXUP_PINS,
2611 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002612 { 0x14, 0x99130110 }, /* speaker */
2613 { 0x15, 0x0221142f }, /* front HP */
2614 { 0x1b, 0x0121141f }, /* rear HP */
2615 { }
2616 }
2617 },
Takashi Iwai7513e6d2013-01-18 15:41:34 +01002618 [ALC262_FIXUP_FSC_S7110] = {
2619 .type = HDA_FIXUP_PINS,
2620 .v.pins = (const struct hda_pintbl[]) {
2621 { 0x15, 0x90170110 }, /* speaker */
2622 { }
2623 },
2624 .chained = true,
2625 .chain_id = ALC262_FIXUP_BENQ,
2626 },
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002627 [ALC262_FIXUP_HP_Z200] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002628 .type = HDA_FIXUP_PINS,
2629 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002630 { 0x16, 0x99130120 }, /* internal speaker */
2631 { }
2632 }
2633 },
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002634 [ALC262_FIXUP_TYAN] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002635 .type = HDA_FIXUP_PINS,
2636 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002637 { 0x14, 0x1993e1f0 }, /* int AUX */
2638 { }
2639 }
2640 },
Takashi Iwaic4701502011-11-07 14:20:07 +01002641 [ALC262_FIXUP_LENOVO_3000] = {
Takashi Iwaifd108212013-01-10 10:18:14 +01002642 .type = HDA_FIXUP_PINCTLS,
2643 .v.pins = (const struct hda_pintbl[]) {
2644 { 0x19, PIN_VREF50 },
Takashi Iwaib42590b2011-11-07 14:41:01 +01002645 {}
2646 },
2647 .chained = true,
2648 .chain_id = ALC262_FIXUP_BENQ,
2649 },
2650 [ALC262_FIXUP_BENQ] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002651 .type = HDA_FIXUP_VERBS,
Takashi Iwaib42590b2011-11-07 14:41:01 +01002652 .v.verbs = (const struct hda_verb[]) {
Takashi Iwaic4701502011-11-07 14:20:07 +01002653 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2654 { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
2655 {}
2656 }
2657 },
Takashi Iwaib42590b2011-11-07 14:41:01 +01002658 [ALC262_FIXUP_BENQ_T31] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002659 .type = HDA_FIXUP_VERBS,
Takashi Iwaib42590b2011-11-07 14:41:01 +01002660 .v.verbs = (const struct hda_verb[]) {
2661 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2662 { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
2663 {}
2664 }
2665 },
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002666 [ALC262_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002667 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02002668 .v.func = alc_fixup_inv_dmic,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002669 },
Mengdong Linb5c66112013-11-29 00:35:35 -05002670 [ALC262_FIXUP_INTEL_BAYLEYBAY] = {
2671 .type = HDA_FIXUP_FUNC,
2672 .v.func = alc_fixup_no_depop_delay,
2673 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02002674};
2675
2676static const struct snd_pci_quirk alc262_fixup_tbl[] = {
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002677 SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", ALC262_FIXUP_HP_Z200),
Takashi Iwai7513e6d2013-01-18 15:41:34 +01002678 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu Lifebook S7110", ALC262_FIXUP_FSC_S7110),
Takashi Iwai3dcd3be2011-11-07 14:59:40 +01002679 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FIXUP_BENQ),
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002680 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_FIXUP_TYAN),
Takashi Iwai275ec0c2018-06-22 12:17:45 +02002681 SND_PCI_QUIRK(0x1734, 0x1141, "FSC ESPRIMO U9210", ALC262_FIXUP_FSC_H270),
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002682 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", ALC262_FIXUP_FSC_H270),
Takashi Iwaic4701502011-11-07 14:20:07 +01002683 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000", ALC262_FIXUP_LENOVO_3000),
Takashi Iwaib42590b2011-11-07 14:41:01 +01002684 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_FIXUP_BENQ),
2685 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_FIXUP_BENQ_T31),
Mengdong Linb5c66112013-11-29 00:35:35 -05002686 SND_PCI_QUIRK(0x8086, 0x7270, "BayleyBay", ALC262_FIXUP_INTEL_BAYLEYBAY),
Takashi Iwai1d045db2011-07-07 18:23:21 +02002687 {}
2688};
2689
Takashi Iwai1727a772013-01-10 09:52:52 +01002690static const struct hda_model_fixup alc262_fixup_models[] = {
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002691 {.id = ALC262_FIXUP_INV_DMIC, .name = "inv-dmic"},
Takashi Iwaie43c44d2018-06-26 17:02:08 +02002692 {.id = ALC262_FIXUP_FSC_H270, .name = "fsc-h270"},
2693 {.id = ALC262_FIXUP_FSC_S7110, .name = "fsc-s7110"},
2694 {.id = ALC262_FIXUP_HP_Z200, .name = "hp-z200"},
2695 {.id = ALC262_FIXUP_TYAN, .name = "tyan"},
2696 {.id = ALC262_FIXUP_LENOVO_3000, .name = "lenovo-3000"},
2697 {.id = ALC262_FIXUP_BENQ, .name = "benq"},
2698 {.id = ALC262_FIXUP_BENQ_T31, .name = "benq-t31"},
2699 {.id = ALC262_FIXUP_INTEL_BAYLEYBAY, .name = "bayleybay"},
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002700 {}
2701};
Takashi Iwai1d045db2011-07-07 18:23:21 +02002702
Takashi Iwai1d045db2011-07-07 18:23:21 +02002703/*
2704 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002705static int patch_alc262(struct hda_codec *codec)
2706{
2707 struct alc_spec *spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002708 int err;
2709
Takashi Iwai3de95172012-05-07 18:03:15 +02002710 err = alc_alloc_spec(codec, 0x0b);
2711 if (err < 0)
2712 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002713
Takashi Iwai3de95172012-05-07 18:03:15 +02002714 spec = codec->spec;
Takashi Iwai08c189f2012-12-19 15:22:24 +01002715 spec->gen.shared_mic_vref_pin = 0x18;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002716
Takashi Iwai225068a2015-05-29 10:42:14 +02002717 spec->shutup = alc_eapd_shutup;
2718
Takashi Iwai1d045db2011-07-07 18:23:21 +02002719#if 0
2720 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
2721 * under-run
2722 */
Takashi Iwai98b24882014-08-18 13:47:50 +02002723 alc_update_coefex_idx(codec, 0x1a, 7, 0, 0x80);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002724#endif
Takashi Iwai1d045db2011-07-07 18:23:21 +02002725 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
2726
Takashi Iwaic9af7532019-05-10 11:01:43 +02002727 alc_pre_init(codec);
2728
Takashi Iwai1727a772013-01-10 09:52:52 +01002729 snd_hda_pick_fixup(codec, alc262_fixup_models, alc262_fixup_tbl,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002730 alc262_fixups);
Takashi Iwai1727a772013-01-10 09:52:52 +01002731 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002732
Takashi Iwaiaf741c12012-05-07 18:09:48 +02002733 alc_auto_parse_customize_define(codec);
2734
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002735 if (has_cdefine_beep(codec))
2736 spec->gen.beep_nid = 0x01;
2737
Takashi Iwai42399f72011-11-07 17:18:44 +01002738 /* automatic parse from the BIOS config */
2739 err = alc262_parse_auto_config(codec);
2740 if (err < 0)
2741 goto error;
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002742
Takashi Iwaifea80fa2018-06-20 12:52:46 +02002743 if (!spec->gen.no_analog && spec->gen.beep_nid) {
2744 err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
2745 if (err < 0)
2746 goto error;
2747 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02002748
Takashi Iwai1727a772013-01-10 09:52:52 +01002749 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01002750
Takashi Iwai1d045db2011-07-07 18:23:21 +02002751 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02002752
2753 error:
2754 alc_free(codec);
2755 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002756}
2757
2758/*
2759 * ALC268
2760 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002761/* bind Beep switches of both NID 0x0f and 0x10 */
Takashi Iwaia7177772017-05-10 12:04:08 +02002762static int alc268_beep_switch_put(struct snd_kcontrol *kcontrol,
2763 struct snd_ctl_elem_value *ucontrol)
2764{
2765 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2766 unsigned long pval;
2767 int err;
2768
2769 mutex_lock(&codec->control_mutex);
2770 pval = kcontrol->private_value;
2771 kcontrol->private_value = (pval & ~0xff) | 0x0f;
2772 err = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
2773 if (err >= 0) {
2774 kcontrol->private_value = (pval & ~0xff) | 0x10;
2775 err = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
2776 }
2777 kcontrol->private_value = pval;
2778 mutex_unlock(&codec->control_mutex);
2779 return err;
2780}
Takashi Iwai1d045db2011-07-07 18:23:21 +02002781
2782static const struct snd_kcontrol_new alc268_beep_mixer[] = {
2783 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
Takashi Iwaia7177772017-05-10 12:04:08 +02002784 {
2785 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2786 .name = "Beep Playback Switch",
2787 .subdevice = HDA_SUBDEV_AMP_FLAG,
2788 .info = snd_hda_mixer_amp_switch_info,
2789 .get = snd_hda_mixer_amp_switch_get,
2790 .put = alc268_beep_switch_put,
2791 .private_value = HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT)
2792 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02002793};
2794
2795/* set PCBEEP vol = 0, mute connections */
2796static const struct hda_verb alc268_beep_init_verbs[] = {
2797 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2798 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2799 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2800 { }
2801};
2802
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002803enum {
2804 ALC268_FIXUP_INV_DMIC,
Takashi Iwaicb766402012-10-20 10:55:21 +02002805 ALC268_FIXUP_HP_EAPD,
Takashi Iwai24eff322013-11-04 18:21:08 +01002806 ALC268_FIXUP_SPDIF,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002807};
2808
Takashi Iwai1727a772013-01-10 09:52:52 +01002809static const struct hda_fixup alc268_fixups[] = {
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002810 [ALC268_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002811 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02002812 .v.func = alc_fixup_inv_dmic,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002813 },
Takashi Iwaicb766402012-10-20 10:55:21 +02002814 [ALC268_FIXUP_HP_EAPD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002815 .type = HDA_FIXUP_VERBS,
Takashi Iwaicb766402012-10-20 10:55:21 +02002816 .v.verbs = (const struct hda_verb[]) {
2817 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 0},
2818 {}
2819 }
2820 },
Takashi Iwai24eff322013-11-04 18:21:08 +01002821 [ALC268_FIXUP_SPDIF] = {
2822 .type = HDA_FIXUP_PINS,
2823 .v.pins = (const struct hda_pintbl[]) {
2824 { 0x1e, 0x014b1180 }, /* enable SPDIF out */
2825 {}
2826 }
2827 },
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002828};
2829
Takashi Iwai1727a772013-01-10 09:52:52 +01002830static const struct hda_model_fixup alc268_fixup_models[] = {
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002831 {.id = ALC268_FIXUP_INV_DMIC, .name = "inv-dmic"},
Takashi Iwaicb766402012-10-20 10:55:21 +02002832 {.id = ALC268_FIXUP_HP_EAPD, .name = "hp-eapd"},
Takashi Iwai03bf11c2018-06-26 16:56:41 +02002833 {.id = ALC268_FIXUP_SPDIF, .name = "spdif"},
Takashi Iwaicb766402012-10-20 10:55:21 +02002834 {}
2835};
2836
2837static const struct snd_pci_quirk alc268_fixup_tbl[] = {
Takashi Iwai24eff322013-11-04 18:21:08 +01002838 SND_PCI_QUIRK(0x1025, 0x0139, "Acer TravelMate 6293", ALC268_FIXUP_SPDIF),
David Henningssonfcd8f3b2013-01-28 05:45:47 +01002839 SND_PCI_QUIRK(0x1025, 0x015b, "Acer AOA 150 (ZG5)", ALC268_FIXUP_INV_DMIC),
Takashi Iwaicb766402012-10-20 10:55:21 +02002840 /* below is codec SSID since multiple Toshiba laptops have the
2841 * same PCI SSID 1179:ff00
2842 */
2843 SND_PCI_QUIRK(0x1179, 0xff06, "Toshiba P200", ALC268_FIXUP_HP_EAPD),
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002844 {}
2845};
2846
Takashi Iwai1d045db2011-07-07 18:23:21 +02002847/*
2848 * BIOS auto configuration
2849 */
2850static int alc268_parse_auto_config(struct hda_codec *codec)
2851{
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002852 static const hda_nid_t alc268_ssids[] = { 0x15, 0x1b, 0x14, 0 };
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002853 return alc_parse_auto_config(codec, NULL, alc268_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002854}
2855
Takashi Iwai1d045db2011-07-07 18:23:21 +02002856/*
2857 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002858static int patch_alc268(struct hda_codec *codec)
2859{
2860 struct alc_spec *spec;
Takashi Iwaia5cb4632018-06-20 12:50:11 +02002861 int i, err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002862
Takashi Iwai1d045db2011-07-07 18:23:21 +02002863 /* ALC268 has no aa-loopback mixer */
Takashi Iwai3de95172012-05-07 18:03:15 +02002864 err = alc_alloc_spec(codec, 0);
2865 if (err < 0)
2866 return err;
2867
2868 spec = codec->spec;
Takashi Iwai2722b532019-08-22 09:55:37 +02002869 if (has_cdefine_beep(codec))
2870 spec->gen.beep_nid = 0x01;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002871
Takashi Iwai225068a2015-05-29 10:42:14 +02002872 spec->shutup = alc_eapd_shutup;
2873
Takashi Iwaic9af7532019-05-10 11:01:43 +02002874 alc_pre_init(codec);
2875
Takashi Iwai1727a772013-01-10 09:52:52 +01002876 snd_hda_pick_fixup(codec, alc268_fixup_models, alc268_fixup_tbl, alc268_fixups);
2877 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002878
Takashi Iwai6ebb8052011-08-16 15:15:40 +02002879 /* automatic parse from the BIOS config */
2880 err = alc268_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02002881 if (err < 0)
2882 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002883
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002884 if (err > 0 && !spec->gen.no_analog &&
2885 spec->gen.autocfg.speaker_pins[0] != 0x1d) {
Takashi Iwaia5cb4632018-06-20 12:50:11 +02002886 for (i = 0; i < ARRAY_SIZE(alc268_beep_mixer); i++) {
2887 if (!snd_hda_gen_add_kctl(&spec->gen, NULL,
2888 &alc268_beep_mixer[i])) {
2889 err = -ENOMEM;
2890 goto error;
2891 }
2892 }
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002893 snd_hda_add_verbs(codec, alc268_beep_init_verbs);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002894 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
2895 /* override the amp caps for beep generator */
2896 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
2897 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
2898 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
2899 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
2900 (0 << AC_AMPCAP_MUTE_SHIFT));
2901 }
2902
Takashi Iwai1727a772013-01-10 09:52:52 +01002903 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002904
Takashi Iwai1d045db2011-07-07 18:23:21 +02002905 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02002906
2907 error:
2908 alc_free(codec);
2909 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002910}
2911
2912/*
2913 * ALC269
2914 */
Takashi Iwai08c189f2012-12-19 15:22:24 +01002915
Takashi Iwai1d045db2011-07-07 18:23:21 +02002916static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002917 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002918};
2919
2920static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002921 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002922};
2923
Takashi Iwai1d045db2011-07-07 18:23:21 +02002924/* different alc269-variants */
2925enum {
2926 ALC269_TYPE_ALC269VA,
2927 ALC269_TYPE_ALC269VB,
2928 ALC269_TYPE_ALC269VC,
Kailang Yangadcc70b2012-05-25 08:08:38 +02002929 ALC269_TYPE_ALC269VD,
Kailang Yang065380f2013-01-10 10:25:48 +01002930 ALC269_TYPE_ALC280,
2931 ALC269_TYPE_ALC282,
Kailang Yang2af02be2013-08-22 10:03:50 +02002932 ALC269_TYPE_ALC283,
Kailang Yang065380f2013-01-10 10:25:48 +01002933 ALC269_TYPE_ALC284,
Kailang Yang4731d5d2017-06-30 15:22:57 +08002934 ALC269_TYPE_ALC293,
Kailang Yang7fc7d042013-04-25 11:04:43 +02002935 ALC269_TYPE_ALC286,
Kailang Yang506b62c2014-12-18 17:07:44 +08002936 ALC269_TYPE_ALC298,
Kailang Yang1d04c9d2013-10-24 11:35:18 +02002937 ALC269_TYPE_ALC255,
Kailang Yang4344aec2014-12-17 17:39:05 +08002938 ALC269_TYPE_ALC256,
Kailang Yangf429e7e2017-12-05 15:38:24 +08002939 ALC269_TYPE_ALC257,
Kailang Yang0a6f0602017-06-30 16:00:48 +08002940 ALC269_TYPE_ALC215,
Kailang Yang42314302016-02-03 15:03:50 +08002941 ALC269_TYPE_ALC225,
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08002942 ALC269_TYPE_ALC294,
Kailang Yang1078bef2018-11-08 16:36:15 +08002943 ALC269_TYPE_ALC300,
Kailang Yangf0778872019-10-24 15:13:32 +08002944 ALC269_TYPE_ALC623,
Kailang Yang6fbae352016-05-30 16:44:20 +08002945 ALC269_TYPE_ALC700,
Takashi Iwai1d045db2011-07-07 18:23:21 +02002946};
2947
2948/*
2949 * BIOS auto configuration
2950 */
2951static int alc269_parse_auto_config(struct hda_codec *codec)
2952{
Takashi Iwai1d045db2011-07-07 18:23:21 +02002953 static const hda_nid_t alc269_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002954 static const hda_nid_t alc269_ssids[] = { 0, 0x1b, 0x14, 0x21 };
2955 static const hda_nid_t alc269va_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2956 struct alc_spec *spec = codec->spec;
Kailang Yangadcc70b2012-05-25 08:08:38 +02002957 const hda_nid_t *ssids;
2958
2959 switch (spec->codec_variant) {
2960 case ALC269_TYPE_ALC269VA:
2961 case ALC269_TYPE_ALC269VC:
Kailang Yang065380f2013-01-10 10:25:48 +01002962 case ALC269_TYPE_ALC280:
2963 case ALC269_TYPE_ALC284:
Kailang Yang4731d5d2017-06-30 15:22:57 +08002964 case ALC269_TYPE_ALC293:
Kailang Yangadcc70b2012-05-25 08:08:38 +02002965 ssids = alc269va_ssids;
2966 break;
2967 case ALC269_TYPE_ALC269VB:
2968 case ALC269_TYPE_ALC269VD:
Kailang Yang065380f2013-01-10 10:25:48 +01002969 case ALC269_TYPE_ALC282:
Kailang Yang2af02be2013-08-22 10:03:50 +02002970 case ALC269_TYPE_ALC283:
Kailang Yang7fc7d042013-04-25 11:04:43 +02002971 case ALC269_TYPE_ALC286:
Kailang Yang506b62c2014-12-18 17:07:44 +08002972 case ALC269_TYPE_ALC298:
Kailang Yang1d04c9d2013-10-24 11:35:18 +02002973 case ALC269_TYPE_ALC255:
Kailang Yang4344aec2014-12-17 17:39:05 +08002974 case ALC269_TYPE_ALC256:
Kailang Yangf429e7e2017-12-05 15:38:24 +08002975 case ALC269_TYPE_ALC257:
Kailang Yang0a6f0602017-06-30 16:00:48 +08002976 case ALC269_TYPE_ALC215:
Kailang Yang42314302016-02-03 15:03:50 +08002977 case ALC269_TYPE_ALC225:
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08002978 case ALC269_TYPE_ALC294:
Kailang Yang1078bef2018-11-08 16:36:15 +08002979 case ALC269_TYPE_ALC300:
Kailang Yangf0778872019-10-24 15:13:32 +08002980 case ALC269_TYPE_ALC623:
Kailang Yang6fbae352016-05-30 16:44:20 +08002981 case ALC269_TYPE_ALC700:
Kailang Yangadcc70b2012-05-25 08:08:38 +02002982 ssids = alc269_ssids;
2983 break;
2984 default:
2985 ssids = alc269_ssids;
2986 break;
2987 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02002988
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002989 return alc_parse_auto_config(codec, alc269_ignore, ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002990}
2991
Hui Wang476c02e2020-03-29 16:20:18 +08002992static const struct hda_jack_keymap alc_headset_btn_keymap[] = {
2993 { SND_JACK_BTN_0, KEY_PLAYPAUSE },
2994 { SND_JACK_BTN_1, KEY_VOICECOMMAND },
2995 { SND_JACK_BTN_2, KEY_VOLUMEUP },
2996 { SND_JACK_BTN_3, KEY_VOLUMEDOWN },
2997 {}
2998};
2999
3000static void alc_headset_btn_callback(struct hda_codec *codec,
3001 struct hda_jack_callback *jack)
3002{
3003 int report = 0;
3004
3005 if (jack->unsol_res & (7 << 13))
3006 report |= SND_JACK_BTN_0;
3007
3008 if (jack->unsol_res & (1 << 16 | 3 << 8))
3009 report |= SND_JACK_BTN_1;
3010
3011 /* Volume up key */
3012 if (jack->unsol_res & (7 << 23))
3013 report |= SND_JACK_BTN_2;
3014
3015 /* Volume down key */
3016 if (jack->unsol_res & (7 << 10))
3017 report |= SND_JACK_BTN_3;
3018
3019 jack->jack->button_state = report;
3020}
3021
3022static void alc_disable_headset_jack_key(struct hda_codec *codec)
3023{
3024 struct alc_spec *spec = codec->spec;
3025
3026 if (!spec->has_hs_key)
3027 return;
3028
3029 switch (codec->core.vendor_id) {
3030 case 0x10ec0215:
3031 case 0x10ec0225:
3032 case 0x10ec0285:
3033 case 0x10ec0295:
3034 case 0x10ec0289:
3035 case 0x10ec0299:
3036 alc_write_coef_idx(codec, 0x48, 0x0);
3037 alc_update_coef_idx(codec, 0x49, 0x0045, 0x0);
3038 alc_update_coef_idx(codec, 0x44, 0x0045 << 8, 0x0);
3039 break;
3040 case 0x10ec0236:
3041 case 0x10ec0256:
3042 alc_write_coef_idx(codec, 0x48, 0x0);
3043 alc_update_coef_idx(codec, 0x49, 0x0045, 0x0);
3044 break;
3045 }
3046}
3047
3048static void alc_enable_headset_jack_key(struct hda_codec *codec)
3049{
3050 struct alc_spec *spec = codec->spec;
3051
3052 if (!spec->has_hs_key)
3053 return;
3054
3055 switch (codec->core.vendor_id) {
3056 case 0x10ec0215:
3057 case 0x10ec0225:
3058 case 0x10ec0285:
3059 case 0x10ec0295:
3060 case 0x10ec0289:
3061 case 0x10ec0299:
3062 alc_write_coef_idx(codec, 0x48, 0xd011);
3063 alc_update_coef_idx(codec, 0x49, 0x007f, 0x0045);
3064 alc_update_coef_idx(codec, 0x44, 0x007f << 8, 0x0045 << 8);
3065 break;
3066 case 0x10ec0236:
3067 case 0x10ec0256:
3068 alc_write_coef_idx(codec, 0x48, 0xd011);
3069 alc_update_coef_idx(codec, 0x49, 0x007f, 0x0045);
3070 break;
3071 }
3072}
3073
3074static void alc_fixup_headset_jack(struct hda_codec *codec,
3075 const struct hda_fixup *fix, int action)
3076{
3077 struct alc_spec *spec = codec->spec;
3078
3079 switch (action) {
3080 case HDA_FIXUP_ACT_PRE_PROBE:
3081 spec->has_hs_key = 1;
3082 snd_hda_jack_detect_enable_callback(codec, 0x55,
3083 alc_headset_btn_callback);
3084 snd_hda_jack_add_kctl(codec, 0x55, "Headset Jack", false,
3085 SND_JACK_HEADSET, alc_headset_btn_keymap);
3086 break;
3087 case HDA_FIXUP_ACT_INIT:
3088 alc_enable_headset_jack_key(codec);
3089 break;
3090 }
3091}
3092
Kailang Yang1387e2d2012-11-08 10:23:18 +01003093static void alc269vb_toggle_power_output(struct hda_codec *codec, int power_up)
Takashi Iwai1d045db2011-07-07 18:23:21 +02003094{
Takashi Iwai98b24882014-08-18 13:47:50 +02003095 alc_update_coef_idx(codec, 0x04, 1 << 11, power_up ? (1 << 11) : 0);
Takashi Iwai1d045db2011-07-07 18:23:21 +02003096}
3097
3098static void alc269_shutup(struct hda_codec *codec)
3099{
Kailang Yangadcc70b2012-05-25 08:08:38 +02003100 struct alc_spec *spec = codec->spec;
3101
Kailang Yang1387e2d2012-11-08 10:23:18 +01003102 if (spec->codec_variant == ALC269_TYPE_ALC269VB)
3103 alc269vb_toggle_power_output(codec, 0);
3104 if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
3105 (alc_get_coef0(codec) & 0x00ff) == 0x018) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02003106 msleep(150);
3107 }
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003108 alc_shutup_pins(codec);
Takashi Iwai1d045db2011-07-07 18:23:21 +02003109}
3110
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01003111static const struct coef_fw alc282_coefs[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02003112 WRITE_COEF(0x03, 0x0002), /* Power Down Control */
Kailang Yang32fa7e42014-10-24 16:26:01 +08003113 UPDATE_COEF(0x05, 0xff3f, 0x0700), /* FIFO and filter clock */
Takashi Iwai54db6c32014-08-18 15:11:19 +02003114 WRITE_COEF(0x07, 0x0200), /* DMIC control */
3115 UPDATE_COEF(0x06, 0x00f0, 0), /* Analog clock */
3116 UPDATE_COEF(0x08, 0xfffc, 0x0c2c), /* JD */
3117 WRITE_COEF(0x0a, 0xcccc), /* JD offset1 */
3118 WRITE_COEF(0x0b, 0xcccc), /* JD offset2 */
3119 WRITE_COEF(0x0e, 0x6e00), /* LDO1/2/3, DAC/ADC */
3120 UPDATE_COEF(0x0f, 0xf800, 0x1000), /* JD */
3121 UPDATE_COEF(0x10, 0xfc00, 0x0c00), /* Capless */
3122 WRITE_COEF(0x6f, 0x0), /* Class D test 4 */
3123 UPDATE_COEF(0x0c, 0xfe00, 0), /* IO power down directly */
3124 WRITE_COEF(0x34, 0xa0c0), /* ANC */
3125 UPDATE_COEF(0x16, 0x0008, 0), /* AGC MUX */
3126 UPDATE_COEF(0x1d, 0x00e0, 0), /* DAC simple content protection */
3127 UPDATE_COEF(0x1f, 0x00e0, 0), /* ADC simple content protection */
3128 WRITE_COEF(0x21, 0x8804), /* DAC ADC Zero Detection */
3129 WRITE_COEF(0x63, 0x2902), /* PLL */
3130 WRITE_COEF(0x68, 0xa080), /* capless control 2 */
3131 WRITE_COEF(0x69, 0x3400), /* capless control 3 */
3132 WRITE_COEF(0x6a, 0x2f3e), /* capless control 4 */
3133 WRITE_COEF(0x6b, 0x0), /* capless control 5 */
3134 UPDATE_COEF(0x6d, 0x0fff, 0x0900), /* class D test 2 */
3135 WRITE_COEF(0x6e, 0x110a), /* class D test 3 */
3136 UPDATE_COEF(0x70, 0x00f8, 0x00d8), /* class D test 5 */
3137 WRITE_COEF(0x71, 0x0014), /* class D test 6 */
3138 WRITE_COEF(0x72, 0xc2ba), /* classD OCP */
3139 UPDATE_COEF(0x77, 0x0f80, 0), /* classD pure DC test */
3140 WRITE_COEF(0x6c, 0xfc06), /* Class D amp control */
3141 {}
3142};
3143
Kailang Yangcb149cb2014-03-18 16:45:32 +08003144static void alc282_restore_default_value(struct hda_codec *codec)
3145{
Takashi Iwai54db6c32014-08-18 15:11:19 +02003146 alc_process_coef_fw(codec, alc282_coefs);
Kailang Yangcb149cb2014-03-18 16:45:32 +08003147}
3148
Kailang Yang7b5c7a02014-03-18 16:15:54 +08003149static void alc282_init(struct hda_codec *codec)
3150{
3151 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003152 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang7b5c7a02014-03-18 16:15:54 +08003153 bool hp_pin_sense;
3154 int coef78;
3155
Kailang Yangcb149cb2014-03-18 16:45:32 +08003156 alc282_restore_default_value(codec);
3157
Kailang Yang7b5c7a02014-03-18 16:15:54 +08003158 if (!hp_pin)
3159 return;
3160 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3161 coef78 = alc_read_coef_idx(codec, 0x78);
3162
3163 /* Index 0x78 Direct Drive HP AMP LPM Control 1 */
3164 /* Headphone capless set to high power mode */
3165 alc_write_coef_idx(codec, 0x78, 0x9004);
3166
3167 if (hp_pin_sense)
3168 msleep(2);
3169
3170 snd_hda_codec_write(codec, hp_pin, 0,
3171 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3172
3173 if (hp_pin_sense)
3174 msleep(85);
3175
3176 snd_hda_codec_write(codec, hp_pin, 0,
3177 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3178
3179 if (hp_pin_sense)
3180 msleep(100);
3181
3182 /* Headphone capless set to normal mode */
3183 alc_write_coef_idx(codec, 0x78, coef78);
3184}
3185
3186static void alc282_shutup(struct hda_codec *codec)
3187{
3188 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003189 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang7b5c7a02014-03-18 16:15:54 +08003190 bool hp_pin_sense;
3191 int coef78;
3192
3193 if (!hp_pin) {
3194 alc269_shutup(codec);
3195 return;
3196 }
3197
3198 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3199 coef78 = alc_read_coef_idx(codec, 0x78);
3200 alc_write_coef_idx(codec, 0x78, 0x9004);
3201
3202 if (hp_pin_sense)
3203 msleep(2);
3204
3205 snd_hda_codec_write(codec, hp_pin, 0,
3206 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3207
3208 if (hp_pin_sense)
3209 msleep(85);
3210
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003211 if (!spec->no_shutup_pins)
3212 snd_hda_codec_write(codec, hp_pin, 0,
3213 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
Kailang Yang7b5c7a02014-03-18 16:15:54 +08003214
3215 if (hp_pin_sense)
3216 msleep(100);
3217
3218 alc_auto_setup_eapd(codec, false);
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003219 alc_shutup_pins(codec);
Kailang Yang7b5c7a02014-03-18 16:15:54 +08003220 alc_write_coef_idx(codec, 0x78, coef78);
3221}
3222
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01003223static const struct coef_fw alc283_coefs[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02003224 WRITE_COEF(0x03, 0x0002), /* Power Down Control */
Kailang Yang56779862014-10-24 16:17:51 +08003225 UPDATE_COEF(0x05, 0xff3f, 0x0700), /* FIFO and filter clock */
Takashi Iwai54db6c32014-08-18 15:11:19 +02003226 WRITE_COEF(0x07, 0x0200), /* DMIC control */
3227 UPDATE_COEF(0x06, 0x00f0, 0), /* Analog clock */
3228 UPDATE_COEF(0x08, 0xfffc, 0x0c2c), /* JD */
3229 WRITE_COEF(0x0a, 0xcccc), /* JD offset1 */
3230 WRITE_COEF(0x0b, 0xcccc), /* JD offset2 */
3231 WRITE_COEF(0x0e, 0x6fc0), /* LDO1/2/3, DAC/ADC */
3232 UPDATE_COEF(0x0f, 0xf800, 0x1000), /* JD */
3233 UPDATE_COEF(0x10, 0xfc00, 0x0c00), /* Capless */
3234 WRITE_COEF(0x3a, 0x0), /* Class D test 4 */
3235 UPDATE_COEF(0x0c, 0xfe00, 0x0), /* IO power down directly */
3236 WRITE_COEF(0x22, 0xa0c0), /* ANC */
3237 UPDATE_COEFEX(0x53, 0x01, 0x000f, 0x0008), /* AGC MUX */
3238 UPDATE_COEF(0x1d, 0x00e0, 0), /* DAC simple content protection */
3239 UPDATE_COEF(0x1f, 0x00e0, 0), /* ADC simple content protection */
3240 WRITE_COEF(0x21, 0x8804), /* DAC ADC Zero Detection */
3241 WRITE_COEF(0x2e, 0x2902), /* PLL */
3242 WRITE_COEF(0x33, 0xa080), /* capless control 2 */
3243 WRITE_COEF(0x34, 0x3400), /* capless control 3 */
3244 WRITE_COEF(0x35, 0x2f3e), /* capless control 4 */
3245 WRITE_COEF(0x36, 0x0), /* capless control 5 */
3246 UPDATE_COEF(0x38, 0x0fff, 0x0900), /* class D test 2 */
3247 WRITE_COEF(0x39, 0x110a), /* class D test 3 */
3248 UPDATE_COEF(0x3b, 0x00f8, 0x00d8), /* class D test 5 */
3249 WRITE_COEF(0x3c, 0x0014), /* class D test 6 */
3250 WRITE_COEF(0x3d, 0xc2ba), /* classD OCP */
3251 UPDATE_COEF(0x42, 0x0f80, 0x0), /* classD pure DC test */
3252 WRITE_COEF(0x49, 0x0), /* test mode */
3253 UPDATE_COEF(0x40, 0xf800, 0x9800), /* Class D DC enable */
3254 UPDATE_COEF(0x42, 0xf000, 0x2000), /* DC offset */
3255 WRITE_COEF(0x37, 0xfc06), /* Class D amp control */
Kailang Yang56779862014-10-24 16:17:51 +08003256 UPDATE_COEF(0x1b, 0x8000, 0), /* HP JD control */
Takashi Iwai54db6c32014-08-18 15:11:19 +02003257 {}
3258};
3259
Kailang Yang6bd55b02014-03-17 13:51:27 +08003260static void alc283_restore_default_value(struct hda_codec *codec)
3261{
Takashi Iwai54db6c32014-08-18 15:11:19 +02003262 alc_process_coef_fw(codec, alc283_coefs);
Kailang Yang6bd55b02014-03-17 13:51:27 +08003263}
3264
Kailang Yang2af02be2013-08-22 10:03:50 +02003265static void alc283_init(struct hda_codec *codec)
3266{
3267 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003268 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang2af02be2013-08-22 10:03:50 +02003269 bool hp_pin_sense;
Kailang Yang2af02be2013-08-22 10:03:50 +02003270
Kailang Yang6bd55b02014-03-17 13:51:27 +08003271 alc283_restore_default_value(codec);
3272
Kailang Yang2af02be2013-08-22 10:03:50 +02003273 if (!hp_pin)
3274 return;
Kailang Yanga59d7192015-04-08 16:34:00 +08003275
3276 msleep(30);
Kailang Yang2af02be2013-08-22 10:03:50 +02003277 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3278
3279 /* Index 0x43 Direct Drive HP AMP LPM Control 1 */
3280 /* Headphone capless set to high power mode */
3281 alc_write_coef_idx(codec, 0x43, 0x9004);
3282
3283 snd_hda_codec_write(codec, hp_pin, 0,
3284 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3285
3286 if (hp_pin_sense)
3287 msleep(85);
3288
3289 snd_hda_codec_write(codec, hp_pin, 0,
3290 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3291
3292 if (hp_pin_sense)
3293 msleep(85);
3294 /* Index 0x46 Combo jack auto switch control 2 */
3295 /* 3k pull low control for Headset jack. */
Takashi Iwai98b24882014-08-18 13:47:50 +02003296 alc_update_coef_idx(codec, 0x46, 3 << 12, 0);
Kailang Yang2af02be2013-08-22 10:03:50 +02003297 /* Headphone capless set to normal mode */
3298 alc_write_coef_idx(codec, 0x43, 0x9614);
3299}
3300
3301static void alc283_shutup(struct hda_codec *codec)
3302{
3303 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003304 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang2af02be2013-08-22 10:03:50 +02003305 bool hp_pin_sense;
Kailang Yang2af02be2013-08-22 10:03:50 +02003306
3307 if (!hp_pin) {
3308 alc269_shutup(codec);
3309 return;
3310 }
3311
3312 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3313
3314 alc_write_coef_idx(codec, 0x43, 0x9004);
3315
Harsha Priyab450b172014-10-09 11:04:56 +00003316 /*depop hp during suspend*/
3317 alc_write_coef_idx(codec, 0x06, 0x2100);
3318
Kailang Yang2af02be2013-08-22 10:03:50 +02003319 snd_hda_codec_write(codec, hp_pin, 0,
3320 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3321
3322 if (hp_pin_sense)
Kailang Yang88011c092013-10-24 15:45:24 +02003323 msleep(100);
Kailang Yang2af02be2013-08-22 10:03:50 +02003324
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003325 if (!spec->no_shutup_pins)
3326 snd_hda_codec_write(codec, hp_pin, 0,
3327 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
Kailang Yang2af02be2013-08-22 10:03:50 +02003328
Takashi Iwai98b24882014-08-18 13:47:50 +02003329 alc_update_coef_idx(codec, 0x46, 0, 3 << 12);
Kailang Yang2af02be2013-08-22 10:03:50 +02003330
3331 if (hp_pin_sense)
Kailang Yang88011c092013-10-24 15:45:24 +02003332 msleep(100);
Kailang Yang0435b3f2014-04-08 17:14:14 +08003333 alc_auto_setup_eapd(codec, false);
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003334 alc_shutup_pins(codec);
Kailang Yang2af02be2013-08-22 10:03:50 +02003335 alc_write_coef_idx(codec, 0x43, 0x9614);
3336}
3337
Kailang Yang4a219ef2017-06-16 16:54:35 +08003338static void alc256_init(struct hda_codec *codec)
3339{
3340 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003341 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang4a219ef2017-06-16 16:54:35 +08003342 bool hp_pin_sense;
3343
3344 if (!hp_pin)
Kailang Yang6447c962019-05-08 16:27:03 +08003345 hp_pin = 0x21;
Kailang Yang4a219ef2017-06-16 16:54:35 +08003346
3347 msleep(30);
3348
3349 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3350
3351 if (hp_pin_sense)
3352 msleep(2);
3353
3354 alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */
Kailang Yang6447c962019-05-08 16:27:03 +08003355 if (spec->ultra_low_power) {
3356 alc_update_coef_idx(codec, 0x03, 1<<1, 1<<1);
3357 alc_update_coef_idx(codec, 0x08, 3<<2, 3<<2);
3358 alc_update_coef_idx(codec, 0x08, 7<<4, 0);
3359 alc_update_coef_idx(codec, 0x3b, 1<<15, 0);
3360 alc_update_coef_idx(codec, 0x0e, 7<<6, 7<<6);
3361 msleep(30);
3362 }
Kailang Yang4a219ef2017-06-16 16:54:35 +08003363
3364 snd_hda_codec_write(codec, hp_pin, 0,
3365 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3366
Kailang Yang6447c962019-05-08 16:27:03 +08003367 if (hp_pin_sense || spec->ultra_low_power)
Kailang Yang4a219ef2017-06-16 16:54:35 +08003368 msleep(85);
3369
3370 snd_hda_codec_write(codec, hp_pin, 0,
3371 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3372
Kailang Yang6447c962019-05-08 16:27:03 +08003373 if (hp_pin_sense || spec->ultra_low_power)
Kailang Yang4a219ef2017-06-16 16:54:35 +08003374 msleep(100);
3375
3376 alc_update_coef_idx(codec, 0x46, 3 << 12, 0);
3377 alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x4); /* Hight power */
Kailang Yang88d42b22018-03-14 16:08:57 +08003378 alc_update_coefex_idx(codec, 0x53, 0x02, 0x8000, 1 << 15); /* Clear bit */
3379 alc_update_coefex_idx(codec, 0x53, 0x02, 0x8000, 0 << 15);
Thomas Hebbc4473742020-03-30 12:09:38 -04003380 /*
3381 * Expose headphone mic (or possibly Line In on some machines) instead
3382 * of PC Beep on 1Ah, and disable 1Ah loopback for all outputs. See
3383 * Documentation/sound/hd-audio/realtek-pc-beep.rst for details of
3384 * this register.
3385 */
3386 alc_write_coef_idx(codec, 0x36, 0x5757);
Kailang Yang4a219ef2017-06-16 16:54:35 +08003387}
3388
3389static void alc256_shutup(struct hda_codec *codec)
3390{
3391 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003392 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang4a219ef2017-06-16 16:54:35 +08003393 bool hp_pin_sense;
3394
Kailang Yang6447c962019-05-08 16:27:03 +08003395 if (!hp_pin)
3396 hp_pin = 0x21;
Kailang Yang4a219ef2017-06-16 16:54:35 +08003397
3398 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3399
3400 if (hp_pin_sense)
3401 msleep(2);
3402
3403 snd_hda_codec_write(codec, hp_pin, 0,
3404 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3405
Kailang Yang6447c962019-05-08 16:27:03 +08003406 if (hp_pin_sense || spec->ultra_low_power)
Kailang Yang4a219ef2017-06-16 16:54:35 +08003407 msleep(85);
3408
Takashi Iwai1c9609e2018-01-19 14:18:34 +01003409 /* 3k pull low control for Headset jack. */
3410 /* NOTE: call this before clearing the pin, otherwise codec stalls */
3411 alc_update_coef_idx(codec, 0x46, 0, 3 << 12);
3412
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003413 if (!spec->no_shutup_pins)
3414 snd_hda_codec_write(codec, hp_pin, 0,
3415 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
Kailang Yang4a219ef2017-06-16 16:54:35 +08003416
Kailang Yang6447c962019-05-08 16:27:03 +08003417 if (hp_pin_sense || spec->ultra_low_power)
Kailang Yang4a219ef2017-06-16 16:54:35 +08003418 msleep(100);
3419
3420 alc_auto_setup_eapd(codec, false);
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003421 alc_shutup_pins(codec);
Kailang Yang6447c962019-05-08 16:27:03 +08003422 if (spec->ultra_low_power) {
3423 msleep(50);
3424 alc_update_coef_idx(codec, 0x03, 1<<1, 0);
3425 alc_update_coef_idx(codec, 0x08, 7<<4, 7<<4);
3426 alc_update_coef_idx(codec, 0x08, 3<<2, 0);
3427 alc_update_coef_idx(codec, 0x3b, 1<<15, 1<<15);
3428 alc_update_coef_idx(codec, 0x0e, 7<<6, 0);
3429 msleep(30);
3430 }
Kailang Yang4a219ef2017-06-16 16:54:35 +08003431}
3432
Kailang Yangda911b12018-01-05 16:50:08 +08003433static void alc225_init(struct hda_codec *codec)
3434{
3435 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003436 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yangda911b12018-01-05 16:50:08 +08003437 bool hp1_pin_sense, hp2_pin_sense;
3438
3439 if (!hp_pin)
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003440 hp_pin = 0x21;
Kailang Yangda911b12018-01-05 16:50:08 +08003441 msleep(30);
3442
3443 hp1_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3444 hp2_pin_sense = snd_hda_jack_detect(codec, 0x16);
3445
3446 if (hp1_pin_sense || hp2_pin_sense)
3447 msleep(2);
3448
3449 alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003450 if (spec->ultra_low_power) {
3451 alc_update_coef_idx(codec, 0x08, 0x0f << 2, 3<<2);
3452 alc_update_coef_idx(codec, 0x0e, 7<<6, 7<<6);
3453 alc_update_coef_idx(codec, 0x33, 1<<11, 0);
3454 msleep(30);
3455 }
Kailang Yangda911b12018-01-05 16:50:08 +08003456
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003457 if (hp1_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003458 snd_hda_codec_write(codec, hp_pin, 0,
3459 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3460 if (hp2_pin_sense)
3461 snd_hda_codec_write(codec, 0x16, 0,
3462 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3463
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003464 if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003465 msleep(85);
3466
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003467 if (hp1_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003468 snd_hda_codec_write(codec, hp_pin, 0,
3469 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3470 if (hp2_pin_sense)
3471 snd_hda_codec_write(codec, 0x16, 0,
3472 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3473
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003474 if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003475 msleep(100);
3476
3477 alc_update_coef_idx(codec, 0x4a, 3 << 10, 0);
3478 alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x4); /* Hight power */
3479}
3480
3481static void alc225_shutup(struct hda_codec *codec)
3482{
3483 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003484 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yangda911b12018-01-05 16:50:08 +08003485 bool hp1_pin_sense, hp2_pin_sense;
3486
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003487 if (!hp_pin)
3488 hp_pin = 0x21;
Hui Wang476c02e2020-03-29 16:20:18 +08003489
3490 alc_disable_headset_jack_key(codec);
Kailang Yangda911b12018-01-05 16:50:08 +08003491 /* 3k pull low control for Headset jack. */
3492 alc_update_coef_idx(codec, 0x4a, 0, 3 << 10);
3493
3494 hp1_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3495 hp2_pin_sense = snd_hda_jack_detect(codec, 0x16);
3496
3497 if (hp1_pin_sense || hp2_pin_sense)
3498 msleep(2);
3499
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003500 if (hp1_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003501 snd_hda_codec_write(codec, hp_pin, 0,
3502 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3503 if (hp2_pin_sense)
3504 snd_hda_codec_write(codec, 0x16, 0,
3505 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3506
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003507 if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003508 msleep(85);
3509
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003510 if (hp1_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003511 snd_hda_codec_write(codec, hp_pin, 0,
3512 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
3513 if (hp2_pin_sense)
3514 snd_hda_codec_write(codec, 0x16, 0,
3515 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
3516
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003517 if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003518 msleep(100);
3519
3520 alc_auto_setup_eapd(codec, false);
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003521 alc_shutup_pins(codec);
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003522 if (spec->ultra_low_power) {
3523 msleep(50);
3524 alc_update_coef_idx(codec, 0x08, 0x0f << 2, 0x0c << 2);
3525 alc_update_coef_idx(codec, 0x0e, 7<<6, 0);
3526 alc_update_coef_idx(codec, 0x33, 1<<11, 1<<11);
3527 alc_update_coef_idx(codec, 0x4a, 3<<4, 2<<4);
3528 msleep(30);
3529 }
Hui Wang476c02e2020-03-29 16:20:18 +08003530
3531 alc_update_coef_idx(codec, 0x4a, 3 << 10, 0);
3532 alc_enable_headset_jack_key(codec);
Kailang Yangda911b12018-01-05 16:50:08 +08003533}
3534
Kailang Yangc2d6af52017-06-21 14:50:54 +08003535static void alc_default_init(struct hda_codec *codec)
3536{
3537 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003538 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yangc2d6af52017-06-21 14:50:54 +08003539 bool hp_pin_sense;
3540
3541 if (!hp_pin)
3542 return;
3543
3544 msleep(30);
3545
3546 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3547
3548 if (hp_pin_sense)
3549 msleep(2);
3550
3551 snd_hda_codec_write(codec, hp_pin, 0,
3552 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3553
3554 if (hp_pin_sense)
3555 msleep(85);
3556
3557 snd_hda_codec_write(codec, hp_pin, 0,
3558 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3559
3560 if (hp_pin_sense)
3561 msleep(100);
3562}
3563
3564static void alc_default_shutup(struct hda_codec *codec)
3565{
3566 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003567 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yangc2d6af52017-06-21 14:50:54 +08003568 bool hp_pin_sense;
3569
3570 if (!hp_pin) {
3571 alc269_shutup(codec);
3572 return;
3573 }
3574
3575 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3576
3577 if (hp_pin_sense)
3578 msleep(2);
3579
3580 snd_hda_codec_write(codec, hp_pin, 0,
3581 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3582
3583 if (hp_pin_sense)
3584 msleep(85);
3585
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003586 if (!spec->no_shutup_pins)
3587 snd_hda_codec_write(codec, hp_pin, 0,
3588 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
Kailang Yangc2d6af52017-06-21 14:50:54 +08003589
3590 if (hp_pin_sense)
3591 msleep(100);
3592
3593 alc_auto_setup_eapd(codec, false);
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003594 alc_shutup_pins(codec);
Kailang Yangc2d6af52017-06-21 14:50:54 +08003595}
3596
Kailang Yang693abe12019-01-29 15:38:21 +08003597static void alc294_hp_init(struct hda_codec *codec)
3598{
3599 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003600 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang693abe12019-01-29 15:38:21 +08003601 int i, val;
3602
3603 if (!hp_pin)
3604 return;
3605
3606 snd_hda_codec_write(codec, hp_pin, 0,
3607 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3608
3609 msleep(100);
3610
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003611 if (!spec->no_shutup_pins)
3612 snd_hda_codec_write(codec, hp_pin, 0,
3613 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
Kailang Yang693abe12019-01-29 15:38:21 +08003614
3615 alc_update_coef_idx(codec, 0x6f, 0x000f, 0);/* Set HP depop to manual mode */
3616 alc_update_coefex_idx(codec, 0x58, 0x00, 0x8000, 0x8000); /* HP depop procedure start */
3617
3618 /* Wait for depop procedure finish */
3619 val = alc_read_coefex_idx(codec, 0x58, 0x01);
3620 for (i = 0; i < 20 && val & 0x0080; i++) {
3621 msleep(50);
3622 val = alc_read_coefex_idx(codec, 0x58, 0x01);
3623 }
3624 /* Set HP depop to auto mode */
3625 alc_update_coef_idx(codec, 0x6f, 0x000f, 0x000b);
3626 msleep(50);
3627}
3628
3629static void alc294_init(struct hda_codec *codec)
3630{
3631 struct alc_spec *spec = codec->spec;
3632
Takashi Iwaif6ef4e02019-01-29 14:14:51 +01003633 /* required only at boot or S4 resume time */
3634 if (!spec->done_hp_init ||
3635 codec->core.dev.power.power_state.event == PM_EVENT_RESTORE) {
Kailang Yang693abe12019-01-29 15:38:21 +08003636 alc294_hp_init(codec);
3637 spec->done_hp_init = true;
3638 }
3639 alc_default_init(codec);
3640}
3641
Kailang Yangad60d502013-06-28 12:03:01 +02003642static void alc5505_coef_set(struct hda_codec *codec, unsigned int index_reg,
3643 unsigned int val)
3644{
3645 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_COEF_INDEX, index_reg >> 1);
3646 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_PROC_COEF, val & 0xffff); /* LSB */
3647 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_PROC_COEF, val >> 16); /* MSB */
3648}
3649
3650static int alc5505_coef_get(struct hda_codec *codec, unsigned int index_reg)
3651{
3652 unsigned int val;
3653
3654 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_COEF_INDEX, index_reg >> 1);
3655 val = snd_hda_codec_read(codec, 0x51, 0, AC_VERB_GET_PROC_COEF, 0)
3656 & 0xffff;
3657 val |= snd_hda_codec_read(codec, 0x51, 0, AC_VERB_GET_PROC_COEF, 0)
3658 << 16;
3659 return val;
3660}
3661
3662static void alc5505_dsp_halt(struct hda_codec *codec)
3663{
3664 unsigned int val;
3665
3666 alc5505_coef_set(codec, 0x3000, 0x000c); /* DSP CPU stop */
3667 alc5505_coef_set(codec, 0x880c, 0x0008); /* DDR enter self refresh */
3668 alc5505_coef_set(codec, 0x61c0, 0x11110080); /* Clock control for PLL and CPU */
3669 alc5505_coef_set(codec, 0x6230, 0xfc0d4011); /* Disable Input OP */
3670 alc5505_coef_set(codec, 0x61b4, 0x040a2b03); /* Stop PLL2 */
3671 alc5505_coef_set(codec, 0x61b0, 0x00005b17); /* Stop PLL1 */
3672 alc5505_coef_set(codec, 0x61b8, 0x04133303); /* Stop PLL3 */
3673 val = alc5505_coef_get(codec, 0x6220);
3674 alc5505_coef_set(codec, 0x6220, (val | 0x3000)); /* switch Ringbuffer clock to DBUS clock */
3675}
3676
3677static void alc5505_dsp_back_from_halt(struct hda_codec *codec)
3678{
3679 alc5505_coef_set(codec, 0x61b8, 0x04133302);
3680 alc5505_coef_set(codec, 0x61b0, 0x00005b16);
3681 alc5505_coef_set(codec, 0x61b4, 0x040a2b02);
3682 alc5505_coef_set(codec, 0x6230, 0xf80d4011);
3683 alc5505_coef_set(codec, 0x6220, 0x2002010f);
3684 alc5505_coef_set(codec, 0x880c, 0x00000004);
3685}
3686
3687static void alc5505_dsp_init(struct hda_codec *codec)
3688{
3689 unsigned int val;
3690
3691 alc5505_dsp_halt(codec);
3692 alc5505_dsp_back_from_halt(codec);
3693 alc5505_coef_set(codec, 0x61b0, 0x5b14); /* PLL1 control */
3694 alc5505_coef_set(codec, 0x61b0, 0x5b16);
3695 alc5505_coef_set(codec, 0x61b4, 0x04132b00); /* PLL2 control */
3696 alc5505_coef_set(codec, 0x61b4, 0x04132b02);
3697 alc5505_coef_set(codec, 0x61b8, 0x041f3300); /* PLL3 control*/
3698 alc5505_coef_set(codec, 0x61b8, 0x041f3302);
3699 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_CODEC_RESET, 0); /* Function reset */
3700 alc5505_coef_set(codec, 0x61b8, 0x041b3302);
3701 alc5505_coef_set(codec, 0x61b8, 0x04173302);
3702 alc5505_coef_set(codec, 0x61b8, 0x04163302);
3703 alc5505_coef_set(codec, 0x8800, 0x348b328b); /* DRAM control */
3704 alc5505_coef_set(codec, 0x8808, 0x00020022); /* DRAM control */
3705 alc5505_coef_set(codec, 0x8818, 0x00000400); /* DRAM control */
3706
3707 val = alc5505_coef_get(codec, 0x6200) >> 16; /* Read revision ID */
3708 if (val <= 3)
3709 alc5505_coef_set(codec, 0x6220, 0x2002010f); /* I/O PAD Configuration */
3710 else
3711 alc5505_coef_set(codec, 0x6220, 0x6002018f);
3712
3713 alc5505_coef_set(codec, 0x61ac, 0x055525f0); /**/
3714 alc5505_coef_set(codec, 0x61c0, 0x12230080); /* Clock control */
3715 alc5505_coef_set(codec, 0x61b4, 0x040e2b02); /* PLL2 control */
3716 alc5505_coef_set(codec, 0x61bc, 0x010234f8); /* OSC Control */
3717 alc5505_coef_set(codec, 0x880c, 0x00000004); /* DRAM Function control */
3718 alc5505_coef_set(codec, 0x880c, 0x00000003);
3719 alc5505_coef_set(codec, 0x880c, 0x00000010);
Takashi Iwaicd63a5f2013-07-05 12:13:59 +02003720
3721#ifdef HALT_REALTEK_ALC5505
3722 alc5505_dsp_halt(codec);
3723#endif
Kailang Yangad60d502013-06-28 12:03:01 +02003724}
3725
Takashi Iwaicd63a5f2013-07-05 12:13:59 +02003726#ifdef HALT_REALTEK_ALC5505
Pierre-Louis Bossart8a718212020-01-11 15:47:35 -06003727#define alc5505_dsp_suspend(codec) do { } while (0) /* NOP */
3728#define alc5505_dsp_resume(codec) do { } while (0) /* NOP */
Takashi Iwaicd63a5f2013-07-05 12:13:59 +02003729#else
3730#define alc5505_dsp_suspend(codec) alc5505_dsp_halt(codec)
3731#define alc5505_dsp_resume(codec) alc5505_dsp_back_from_halt(codec)
3732#endif
3733
Takashi Iwai2a439522011-07-26 09:52:50 +02003734#ifdef CONFIG_PM
Kailang Yangad60d502013-06-28 12:03:01 +02003735static int alc269_suspend(struct hda_codec *codec)
3736{
3737 struct alc_spec *spec = codec->spec;
3738
3739 if (spec->has_alc5505_dsp)
Takashi Iwaicd63a5f2013-07-05 12:13:59 +02003740 alc5505_dsp_suspend(codec);
Kailang Yangad60d502013-06-28 12:03:01 +02003741 return alc_suspend(codec);
3742}
3743
Takashi Iwai1d045db2011-07-07 18:23:21 +02003744static int alc269_resume(struct hda_codec *codec)
3745{
Kailang Yangadcc70b2012-05-25 08:08:38 +02003746 struct alc_spec *spec = codec->spec;
3747
Kailang Yang1387e2d2012-11-08 10:23:18 +01003748 if (spec->codec_variant == ALC269_TYPE_ALC269VB)
3749 alc269vb_toggle_power_output(codec, 0);
3750 if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
Kailang Yangadcc70b2012-05-25 08:08:38 +02003751 (alc_get_coef0(codec) & 0x00ff) == 0x018) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02003752 msleep(150);
3753 }
3754
3755 codec->patch_ops.init(codec);
3756
Kailang Yang1387e2d2012-11-08 10:23:18 +01003757 if (spec->codec_variant == ALC269_TYPE_ALC269VB)
3758 alc269vb_toggle_power_output(codec, 1);
3759 if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
Kailang Yangadcc70b2012-05-25 08:08:38 +02003760 (alc_get_coef0(codec) & 0x00ff) == 0x017) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02003761 msleep(200);
3762 }
3763
Takashi Iwai1a462be2020-01-09 10:01:04 +01003764 snd_hda_regmap_sync(codec);
Takashi Iwai1d045db2011-07-07 18:23:21 +02003765 hda_call_check_power_status(codec, 0x01);
Hui Wangf4753712014-08-19 12:07:03 +08003766
3767 /* on some machine, the BIOS will clear the codec gpio data when enter
3768 * suspend, and won't restore the data after resume, so we restore it
3769 * in the driver.
3770 */
Takashi Iwaid261eec2018-06-19 22:32:29 +02003771 if (spec->gpio_data)
3772 alc_write_gpio_data(codec);
Hui Wangf4753712014-08-19 12:07:03 +08003773
Kailang Yangad60d502013-06-28 12:03:01 +02003774 if (spec->has_alc5505_dsp)
Takashi Iwaicd63a5f2013-07-05 12:13:59 +02003775 alc5505_dsp_resume(codec);
Kailang Yangc5177c82013-07-24 14:39:49 +02003776
Takashi Iwai1d045db2011-07-07 18:23:21 +02003777 return 0;
3778}
Takashi Iwai2a439522011-07-26 09:52:50 +02003779#endif /* CONFIG_PM */
Takashi Iwai1d045db2011-07-07 18:23:21 +02003780
David Henningsson108cc102012-07-20 10:37:25 +02003781static void alc269_fixup_pincfg_no_hp_to_lineout(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003782 const struct hda_fixup *fix, int action)
David Henningsson108cc102012-07-20 10:37:25 +02003783{
3784 struct alc_spec *spec = codec->spec;
3785
Takashi Iwai1727a772013-01-10 09:52:52 +01003786 if (action == HDA_FIXUP_ACT_PRE_PROBE)
David Henningsson108cc102012-07-20 10:37:25 +02003787 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
3788}
3789
Jan-Marek Glogowskifdcc9682018-02-14 11:29:15 +01003790static void alc269_fixup_pincfg_U7x7_headset_mic(struct hda_codec *codec,
3791 const struct hda_fixup *fix,
3792 int action)
3793{
3794 unsigned int cfg_headphone = snd_hda_codec_get_pincfg(codec, 0x21);
3795 unsigned int cfg_headset_mic = snd_hda_codec_get_pincfg(codec, 0x19);
3796
3797 if (cfg_headphone && cfg_headset_mic == 0x411111f0)
3798 snd_hda_codec_set_pincfg(codec, 0x19,
3799 (cfg_headphone & ~AC_DEFCFG_DEVICE) |
3800 (AC_JACK_MIC_IN << AC_DEFCFG_DEVICE_SHIFT));
3801}
3802
Takashi Iwai1d045db2011-07-07 18:23:21 +02003803static void alc269_fixup_hweq(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003804 const struct hda_fixup *fix, int action)
Takashi Iwai1d045db2011-07-07 18:23:21 +02003805{
Takashi Iwai98b24882014-08-18 13:47:50 +02003806 if (action == HDA_FIXUP_ACT_INIT)
3807 alc_update_coef_idx(codec, 0x1e, 0, 0x80);
Takashi Iwai1d045db2011-07-07 18:23:21 +02003808}
3809
David Henningsson7c478f02013-10-11 10:18:46 +02003810static void alc269_fixup_headset_mic(struct hda_codec *codec,
3811 const struct hda_fixup *fix, int action)
3812{
3813 struct alc_spec *spec = codec->spec;
3814
3815 if (action == HDA_FIXUP_ACT_PRE_PROBE)
3816 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
3817}
3818
Takashi Iwai1d045db2011-07-07 18:23:21 +02003819static void alc271_fixup_dmic(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003820 const struct hda_fixup *fix, int action)
Takashi Iwai1d045db2011-07-07 18:23:21 +02003821{
3822 static const struct hda_verb verbs[] = {
3823 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
3824 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
3825 {}
3826 };
3827 unsigned int cfg;
3828
Takashi Iwai7639a062015-03-03 10:07:24 +01003829 if (strcmp(codec->core.chip_name, "ALC271X") &&
3830 strcmp(codec->core.chip_name, "ALC269VB"))
Takashi Iwai1d045db2011-07-07 18:23:21 +02003831 return;
3832 cfg = snd_hda_codec_get_pincfg(codec, 0x12);
3833 if (get_defcfg_connect(cfg) == AC_JACK_PORT_FIXED)
3834 snd_hda_sequence_write(codec, verbs);
3835}
3836
Takashi Iwai017f2a12011-07-09 14:42:25 +02003837static void alc269_fixup_pcm_44k(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003838 const struct hda_fixup *fix, int action)
Takashi Iwai017f2a12011-07-09 14:42:25 +02003839{
3840 struct alc_spec *spec = codec->spec;
3841
Takashi Iwai1727a772013-01-10 09:52:52 +01003842 if (action != HDA_FIXUP_ACT_PROBE)
Takashi Iwai017f2a12011-07-09 14:42:25 +02003843 return;
3844
3845 /* Due to a hardware problem on Lenovo Ideadpad, we need to
3846 * fix the sample rate of analog I/O to 44.1kHz
3847 */
Takashi Iwai08c189f2012-12-19 15:22:24 +01003848 spec->gen.stream_analog_playback = &alc269_44k_pcm_analog_playback;
3849 spec->gen.stream_analog_capture = &alc269_44k_pcm_analog_capture;
Takashi Iwai017f2a12011-07-09 14:42:25 +02003850}
3851
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02003852static void alc269_fixup_stereo_dmic(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003853 const struct hda_fixup *fix, int action)
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02003854{
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02003855 /* The digital-mic unit sends PDM (differential signal) instead of
3856 * the standard PCM, thus you can't record a valid mono stream as is.
3857 * Below is a workaround specific to ALC269 to control the dmic
3858 * signal source as mono.
3859 */
Takashi Iwai98b24882014-08-18 13:47:50 +02003860 if (action == HDA_FIXUP_ACT_INIT)
3861 alc_update_coef_idx(codec, 0x07, 0, 0x80);
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02003862}
3863
Takashi Iwai24519912011-08-16 15:08:49 +02003864static void alc269_quanta_automute(struct hda_codec *codec)
3865{
Takashi Iwai08c189f2012-12-19 15:22:24 +01003866 snd_hda_gen_update_outputs(codec);
Takashi Iwai24519912011-08-16 15:08:49 +02003867
Takashi Iwai1687ccc2014-08-18 13:49:35 +02003868 alc_write_coef_idx(codec, 0x0c, 0x680);
3869 alc_write_coef_idx(codec, 0x0c, 0x480);
Takashi Iwai24519912011-08-16 15:08:49 +02003870}
3871
3872static void alc269_fixup_quanta_mute(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003873 const struct hda_fixup *fix, int action)
Takashi Iwai24519912011-08-16 15:08:49 +02003874{
3875 struct alc_spec *spec = codec->spec;
Takashi Iwai1727a772013-01-10 09:52:52 +01003876 if (action != HDA_FIXUP_ACT_PROBE)
Takashi Iwai24519912011-08-16 15:08:49 +02003877 return;
Takashi Iwai08c189f2012-12-19 15:22:24 +01003878 spec->gen.automute_hook = alc269_quanta_automute;
Takashi Iwai24519912011-08-16 15:08:49 +02003879}
3880
David Henningssond240d1d2013-04-15 12:50:02 +02003881static void alc269_x101_hp_automute_hook(struct hda_codec *codec,
Takashi Iwai1a4f69d2014-09-11 15:22:46 +02003882 struct hda_jack_callback *jack)
David Henningssond240d1d2013-04-15 12:50:02 +02003883{
3884 struct alc_spec *spec = codec->spec;
3885 int vref;
3886 msleep(200);
3887 snd_hda_gen_hp_automute(codec, jack);
3888
3889 vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0;
3890 msleep(100);
3891 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3892 vref);
3893 msleep(500);
3894 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3895 vref);
3896}
3897
Tomas Espeletaa2ef03f2019-08-09 16:37:54 +02003898/*
3899 * Magic sequence to make Huawei Matebook X right speaker working (bko#197801)
3900 */
3901struct hda_alc298_mbxinit {
3902 unsigned char value_0x23;
3903 unsigned char value_0x25;
3904};
3905
3906static void alc298_huawei_mbx_stereo_seq(struct hda_codec *codec,
3907 const struct hda_alc298_mbxinit *initval,
3908 bool first)
3909{
3910 snd_hda_codec_write(codec, 0x06, 0, AC_VERB_SET_DIGI_CONVERT_3, 0x0);
3911 alc_write_coef_idx(codec, 0x26, 0xb000);
3912
3913 if (first)
3914 snd_hda_codec_write(codec, 0x21, 0, AC_VERB_GET_PIN_SENSE, 0x0);
3915
3916 snd_hda_codec_write(codec, 0x6, 0, AC_VERB_SET_DIGI_CONVERT_3, 0x80);
3917 alc_write_coef_idx(codec, 0x26, 0xf000);
3918 alc_write_coef_idx(codec, 0x23, initval->value_0x23);
3919
3920 if (initval->value_0x23 != 0x1e)
3921 alc_write_coef_idx(codec, 0x25, initval->value_0x25);
3922
3923 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0x26);
3924 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, 0xb010);
3925}
3926
3927static void alc298_fixup_huawei_mbx_stereo(struct hda_codec *codec,
3928 const struct hda_fixup *fix,
3929 int action)
3930{
3931 /* Initialization magic */
3932 static const struct hda_alc298_mbxinit dac_init[] = {
3933 {0x0c, 0x00}, {0x0d, 0x00}, {0x0e, 0x00}, {0x0f, 0x00},
3934 {0x10, 0x00}, {0x1a, 0x40}, {0x1b, 0x82}, {0x1c, 0x00},
3935 {0x1d, 0x00}, {0x1e, 0x00}, {0x1f, 0x00},
3936 {0x20, 0xc2}, {0x21, 0xc8}, {0x22, 0x26}, {0x23, 0x24},
3937 {0x27, 0xff}, {0x28, 0xff}, {0x29, 0xff}, {0x2a, 0x8f},
3938 {0x2b, 0x02}, {0x2c, 0x48}, {0x2d, 0x34}, {0x2e, 0x00},
3939 {0x2f, 0x00},
3940 {0x30, 0x00}, {0x31, 0x00}, {0x32, 0x00}, {0x33, 0x00},
3941 {0x34, 0x00}, {0x35, 0x01}, {0x36, 0x93}, {0x37, 0x0c},
3942 {0x38, 0x00}, {0x39, 0x00}, {0x3a, 0xf8}, {0x38, 0x80},
3943 {}
3944 };
3945 const struct hda_alc298_mbxinit *seq;
3946
3947 if (action != HDA_FIXUP_ACT_INIT)
3948 return;
3949
3950 /* Start */
3951 snd_hda_codec_write(codec, 0x06, 0, AC_VERB_SET_DIGI_CONVERT_3, 0x00);
3952 snd_hda_codec_write(codec, 0x06, 0, AC_VERB_SET_DIGI_CONVERT_3, 0x80);
3953 alc_write_coef_idx(codec, 0x26, 0xf000);
3954 alc_write_coef_idx(codec, 0x22, 0x31);
3955 alc_write_coef_idx(codec, 0x23, 0x0b);
3956 alc_write_coef_idx(codec, 0x25, 0x00);
3957 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0x26);
3958 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, 0xb010);
3959
3960 for (seq = dac_init; seq->value_0x23; seq++)
3961 alc298_huawei_mbx_stereo_seq(codec, seq, seq == dac_init);
3962}
3963
David Henningssond240d1d2013-04-15 12:50:02 +02003964static void alc269_fixup_x101_headset_mic(struct hda_codec *codec,
3965 const struct hda_fixup *fix, int action)
3966{
3967 struct alc_spec *spec = codec->spec;
3968 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3969 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
3970 spec->gen.hp_automute_hook = alc269_x101_hp_automute_hook;
3971 }
3972}
3973
3974
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003975/* update mute-LED according to the speaker mute state via mic VREF pin */
3976static void alc269_fixup_mic_mute_hook(void *private_data, int enabled)
David Henningsson6d3cd5d2013-01-07 12:03:47 +01003977{
3978 struct hda_codec *codec = private_data;
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003979 struct alc_spec *spec = codec->spec;
3980 unsigned int pinval;
3981
3982 if (spec->mute_led_polarity)
3983 enabled = !enabled;
Takashi Iwai415d5552014-04-03 11:51:21 +02003984 pinval = snd_hda_codec_get_pin_target(codec, spec->mute_led_nid);
3985 pinval &= ~AC_PINCTL_VREFEN;
3986 pinval |= enabled ? AC_PINCTL_VREF_HIZ : AC_PINCTL_VREF_80;
Takashi Iwaie40bdb02018-03-17 22:40:18 +01003987 if (spec->mute_led_nid) {
3988 /* temporarily power up/down for setting VREF */
3989 snd_hda_power_up_pm(codec);
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003990 snd_hda_set_pin_ctl_cache(codec, spec->mute_led_nid, pinval);
Takashi Iwaie40bdb02018-03-17 22:40:18 +01003991 snd_hda_power_down_pm(codec);
3992 }
David Henningsson6d3cd5d2013-01-07 12:03:47 +01003993}
3994
David Henningssond5b6b652013-11-06 10:50:44 +01003995/* Make sure the led works even in runtime suspend */
3996static unsigned int led_power_filter(struct hda_codec *codec,
3997 hda_nid_t nid,
3998 unsigned int power_state)
3999{
4000 struct alc_spec *spec = codec->spec;
4001
Hui Wang50dd9052014-07-08 17:56:15 +08004002 if (power_state != AC_PWRST_D3 || nid == 0 ||
4003 (nid != spec->mute_led_nid && nid != spec->cap_mute_led_nid))
David Henningssond5b6b652013-11-06 10:50:44 +01004004 return power_state;
4005
4006 /* Set pin ctl again, it might have just been set to 0 */
4007 snd_hda_set_pin_ctl(codec, nid,
4008 snd_hda_codec_get_pin_target(codec, nid));
4009
Takashi Iwaicffd3962015-04-09 10:30:25 +02004010 return snd_hda_gen_path_power_filter(codec, nid, power_state);
David Henningssond5b6b652013-11-06 10:50:44 +01004011}
4012
Takashi Iwai08fb0d02013-01-10 17:33:58 +01004013static void alc269_fixup_hp_mute_led(struct hda_codec *codec,
4014 const struct hda_fixup *fix, int action)
David Henningsson6d3cd5d2013-01-07 12:03:47 +01004015{
4016 struct alc_spec *spec = codec->spec;
Takashi Iwai08fb0d02013-01-10 17:33:58 +01004017 const struct dmi_device *dev = NULL;
4018
4019 if (action != HDA_FIXUP_ACT_PRE_PROBE)
4020 return;
4021
4022 while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) {
4023 int pol, pin;
4024 if (sscanf(dev->name, "HP_Mute_LED_%d_%x", &pol, &pin) != 2)
4025 continue;
4026 if (pin < 0x0a || pin >= 0x10)
4027 break;
4028 spec->mute_led_polarity = pol;
4029 spec->mute_led_nid = pin - 0x0a + 0x18;
4030 spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook;
Takashi Iwaifd25a972012-12-20 14:57:18 +01004031 spec->gen.vmaster_mute_enum = 1;
David Henningssond5b6b652013-11-06 10:50:44 +01004032 codec->power_filter = led_power_filter;
Takashi Iwai4e76a882014-02-25 12:21:03 +01004033 codec_dbg(codec,
4034 "Detected mute LED for %x:%d\n", spec->mute_led_nid,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01004035 spec->mute_led_polarity);
David Henningsson6d3cd5d2013-01-07 12:03:47 +01004036 break;
4037 }
4038}
4039
Takashi Iwai85c467d2018-05-29 11:38:38 +02004040static void alc269_fixup_hp_mute_led_micx(struct hda_codec *codec,
4041 const struct hda_fixup *fix,
4042 int action, hda_nid_t pin)
David Henningssond06ac142013-02-18 11:41:55 +01004043{
4044 struct alc_spec *spec = codec->spec;
Takashi Iwai85c467d2018-05-29 11:38:38 +02004045
David Henningssond06ac142013-02-18 11:41:55 +01004046 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4047 spec->mute_led_polarity = 0;
Takashi Iwai85c467d2018-05-29 11:38:38 +02004048 spec->mute_led_nid = pin;
David Henningssond06ac142013-02-18 11:41:55 +01004049 spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook;
4050 spec->gen.vmaster_mute_enum = 1;
David Henningssond5b6b652013-11-06 10:50:44 +01004051 codec->power_filter = led_power_filter;
David Henningssond06ac142013-02-18 11:41:55 +01004052 }
4053}
4054
Takashi Iwai85c467d2018-05-29 11:38:38 +02004055static void alc269_fixup_hp_mute_led_mic1(struct hda_codec *codec,
4056 const struct hda_fixup *fix, int action)
4057{
4058 alc269_fixup_hp_mute_led_micx(codec, fix, action, 0x18);
4059}
4060
Takashi Iwai08fb0d02013-01-10 17:33:58 +01004061static void alc269_fixup_hp_mute_led_mic2(struct hda_codec *codec,
4062 const struct hda_fixup *fix, int action)
Takashi Iwai420b0fe2012-03-12 12:35:27 +01004063{
Takashi Iwai85c467d2018-05-29 11:38:38 +02004064 alc269_fixup_hp_mute_led_micx(codec, fix, action, 0x19);
Takashi Iwai420b0fe2012-03-12 12:35:27 +01004065}
4066
Tom Briden7f783bd2017-03-25 10:12:01 +00004067static void alc269_fixup_hp_mute_led_mic3(struct hda_codec *codec,
4068 const struct hda_fixup *fix, int action)
4069{
Takashi Iwai85c467d2018-05-29 11:38:38 +02004070 alc269_fixup_hp_mute_led_micx(codec, fix, action, 0x1b);
Tom Briden7f783bd2017-03-25 10:12:01 +00004071}
4072
Takashi Iwai0f32fd192014-11-19 12:16:14 +01004073/* update LED status via GPIO */
4074static void alc_update_gpio_led(struct hda_codec *codec, unsigned int mask,
4075 bool enabled)
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01004076{
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01004077 struct alc_spec *spec = codec->spec;
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01004078
Takashi Iwai0f32fd192014-11-19 12:16:14 +01004079 if (spec->mute_led_polarity)
4080 enabled = !enabled;
Takashi Iwaid261eec2018-06-19 22:32:29 +02004081 alc_update_gpio_data(codec, mask, !enabled); /* muted -> LED on */
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01004082}
4083
Takashi Iwai0f32fd192014-11-19 12:16:14 +01004084/* turn on/off mute LED via GPIO per vmaster hook */
4085static void alc_fixup_gpio_mute_hook(void *private_data, int enabled)
4086{
4087 struct hda_codec *codec = private_data;
4088 struct alc_spec *spec = codec->spec;
4089
4090 alc_update_gpio_led(codec, spec->gpio_mute_led_mask, enabled);
4091}
4092
4093/* turn on/off mic-mute LED via GPIO per capture hook */
Takashi Iwaid03abec2018-06-19 12:29:13 +02004094static void alc_gpio_micmute_update(struct hda_codec *codec)
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01004095{
4096 struct alc_spec *spec = codec->spec;
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01004097
Takashi Iwaid03abec2018-06-19 12:29:13 +02004098 alc_update_gpio_led(codec, spec->gpio_mic_led_mask,
4099 spec->gen.micmute_led.led_value);
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01004100}
4101
Takashi Iwai01e4a272018-06-19 22:47:30 +02004102/* setup mute and mic-mute GPIO bits, add hooks appropriately */
4103static void alc_fixup_hp_gpio_led(struct hda_codec *codec,
4104 int action,
4105 unsigned int mute_mask,
4106 unsigned int micmute_mask)
4107{
4108 struct alc_spec *spec = codec->spec;
4109
4110 alc_fixup_gpio(codec, action, mute_mask | micmute_mask);
4111
4112 if (action != HDA_FIXUP_ACT_PRE_PROBE)
4113 return;
4114 if (mute_mask) {
4115 spec->gpio_mute_led_mask = mute_mask;
4116 spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook;
4117 }
4118 if (micmute_mask) {
4119 spec->gpio_mic_led_mask = micmute_mask;
4120 snd_hda_gen_add_micmute_led(codec, alc_gpio_micmute_update);
4121 }
4122}
4123
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01004124static void alc269_fixup_hp_gpio_led(struct hda_codec *codec,
4125 const struct hda_fixup *fix, int action)
4126{
Takashi Iwai01e4a272018-06-19 22:47:30 +02004127 alc_fixup_hp_gpio_led(codec, action, 0x08, 0x10);
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01004128}
4129
Kai-Heng Fengf5a88b02020-03-27 12:46:25 +08004130static void alc285_fixup_hp_gpio_led(struct hda_codec *codec,
4131 const struct hda_fixup *fix, int action)
4132{
4133 alc_fixup_hp_gpio_led(codec, action, 0x04, 0x00);
4134}
4135
Kailang Yangeaa8e5e2014-11-21 15:49:11 +08004136static void alc286_fixup_hp_gpio_led(struct hda_codec *codec,
4137 const struct hda_fixup *fix, int action)
4138{
Takashi Iwai01e4a272018-06-19 22:47:30 +02004139 alc_fixup_hp_gpio_led(codec, action, 0x02, 0x20);
Takashi Iwai1d045db2011-07-07 18:23:21 +02004140}
4141
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004142/* turn on/off mic-mute LED per capture hook */
Takashi Iwaid03abec2018-06-19 12:29:13 +02004143static void alc_cap_micmute_update(struct hda_codec *codec)
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004144{
4145 struct alc_spec *spec = codec->spec;
Takashi Iwaid03abec2018-06-19 12:29:13 +02004146 unsigned int pinval;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004147
Takashi Iwaid03abec2018-06-19 12:29:13 +02004148 if (!spec->cap_mute_led_nid)
4149 return;
Hui Wangfc1fad92014-07-08 17:56:14 +08004150 pinval = snd_hda_codec_get_pin_target(codec, spec->cap_mute_led_nid);
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004151 pinval &= ~AC_PINCTL_VREFEN;
Takashi Iwaid03abec2018-06-19 12:29:13 +02004152 if (spec->gen.micmute_led.led_value)
4153 pinval |= AC_PINCTL_VREF_80;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004154 else
Takashi Iwaid03abec2018-06-19 12:29:13 +02004155 pinval |= AC_PINCTL_VREF_HIZ;
4156 snd_hda_set_pin_ctl_cache(codec, spec->cap_mute_led_nid, pinval);
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004157}
4158
4159static void alc269_fixup_hp_gpio_mic1_led(struct hda_codec *codec,
4160 const struct hda_fixup *fix, int action)
4161{
4162 struct alc_spec *spec = codec->spec;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004163
Takashi Iwai01e4a272018-06-19 22:47:30 +02004164 alc_fixup_hp_gpio_led(codec, action, 0x08, 0);
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004165 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai01e4a272018-06-19 22:47:30 +02004166 /* Like hp_gpio_mic1_led, but also needs GPIO4 low to
4167 * enable headphone amp
4168 */
4169 spec->gpio_mask |= 0x10;
4170 spec->gpio_dir |= 0x10;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004171 spec->cap_mute_led_nid = 0x18;
Takashi Iwaid03abec2018-06-19 12:29:13 +02004172 snd_hda_gen_add_micmute_led(codec, alc_cap_micmute_update);
Hui Wang50dd9052014-07-08 17:56:15 +08004173 codec->power_filter = led_power_filter;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004174 }
4175}
4176
David Henningsson7a5255f2014-10-30 08:26:01 +01004177static void alc280_fixup_hp_gpio4(struct hda_codec *codec,
4178 const struct hda_fixup *fix, int action)
4179{
David Henningsson7a5255f2014-10-30 08:26:01 +01004180 struct alc_spec *spec = codec->spec;
David Henningsson7a5255f2014-10-30 08:26:01 +01004181
Takashi Iwai01e4a272018-06-19 22:47:30 +02004182 alc_fixup_hp_gpio_led(codec, action, 0x08, 0);
David Henningsson7a5255f2014-10-30 08:26:01 +01004183 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
David Henningsson7a5255f2014-10-30 08:26:01 +01004184 spec->cap_mute_led_nid = 0x18;
Takashi Iwaid03abec2018-06-19 12:29:13 +02004185 snd_hda_gen_add_micmute_led(codec, alc_cap_micmute_update);
David Henningsson7a5255f2014-10-30 08:26:01 +01004186 codec->power_filter = led_power_filter;
4187 }
4188}
4189
Kailang Yang431e76c2020-04-07 14:40:20 +08004190/* update mute-LED according to the speaker mute state via COEF bit */
4191static void alc_fixup_mute_led_coefbit_hook(void *private_data, int enabled)
4192{
4193 struct hda_codec *codec = private_data;
4194 struct alc_spec *spec = codec->spec;
4195
4196 if (spec->mute_led_polarity)
4197 enabled = !enabled;
4198
4199 /* temporarily power up/down for setting COEF bit */
4200 enabled ? alc_update_coef_idx(codec, spec->mute_led_coef_idx,
4201 spec->mute_led_coefbit_mask, spec->mute_led_coefbit_off) :
4202 alc_update_coef_idx(codec, spec->mute_led_coef_idx,
4203 spec->mute_led_coefbit_mask, spec->mute_led_coefbit_on);
4204}
4205
4206static void alc285_fixup_hp_mute_led_coefbit(struct hda_codec *codec,
4207 const struct hda_fixup *fix,
4208 int action)
4209{
4210 struct alc_spec *spec = codec->spec;
4211
4212 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4213 spec->mute_led_polarity = 0;
4214 spec->mute_led_coef_idx = 0x0b;
4215 spec->mute_led_coefbit_mask = 1<<3;
4216 spec->mute_led_coefbit_on = 1<<3;
4217 spec->mute_led_coefbit_off = 0;
4218 spec->gen.vmaster_mute.hook = alc_fixup_mute_led_coefbit_hook;
4219 spec->gen.vmaster_mute_enum = 1;
4220 }
4221}
4222
Kailang Yang24164f42020-04-07 14:52:42 +08004223static void alc236_fixup_hp_mute_led_coefbit(struct hda_codec *codec,
4224 const struct hda_fixup *fix,
4225 int action)
4226{
4227 struct alc_spec *spec = codec->spec;
4228
4229 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4230 spec->mute_led_polarity = 0;
4231 spec->mute_led_coef_idx = 0x34;
4232 spec->mute_led_coefbit_mask = 1<<5;
4233 spec->mute_led_coefbit_on = 0;
4234 spec->mute_led_coefbit_off = 1<<5;
4235 spec->gen.vmaster_mute.hook = alc_fixup_mute_led_coefbit_hook;
4236 spec->gen.vmaster_mute_enum = 1;
4237 }
4238}
4239
Kailang Yang431e76c2020-04-07 14:40:20 +08004240/* turn on/off mic-mute LED per capture hook by coef bit */
4241static void alc_hp_cap_micmute_update(struct hda_codec *codec)
4242{
4243 struct alc_spec *spec = codec->spec;
4244
4245 if (spec->gen.micmute_led.led_value)
4246 alc_update_coef_idx(codec, spec->mic_led_coef_idx,
4247 spec->mic_led_coefbit_mask, spec->mic_led_coefbit_on);
4248 else
4249 alc_update_coef_idx(codec, spec->mic_led_coef_idx,
4250 spec->mic_led_coefbit_mask, spec->mic_led_coefbit_off);
4251}
4252
4253static void alc285_fixup_hp_coef_micmute_led(struct hda_codec *codec,
4254 const struct hda_fixup *fix, int action)
4255{
4256 struct alc_spec *spec = codec->spec;
4257
4258 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4259 spec->mic_led_coef_idx = 0x19;
4260 spec->mic_led_coefbit_mask = 1<<13;
4261 spec->mic_led_coefbit_on = 1<<13;
4262 spec->mic_led_coefbit_off = 0;
4263 snd_hda_gen_add_micmute_led(codec, alc_hp_cap_micmute_update);
4264 }
4265}
4266
Kailang Yang24164f42020-04-07 14:52:42 +08004267static void alc236_fixup_hp_coef_micmute_led(struct hda_codec *codec,
4268 const struct hda_fixup *fix, int action)
4269{
4270 struct alc_spec *spec = codec->spec;
4271
4272 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4273 spec->mic_led_coef_idx = 0x35;
4274 spec->mic_led_coefbit_mask = 3<<2;
4275 spec->mic_led_coefbit_on = 2<<2;
4276 spec->mic_led_coefbit_off = 1<<2;
4277 snd_hda_gen_add_micmute_led(codec, alc_hp_cap_micmute_update);
4278 }
4279}
4280
Kailang Yang431e76c2020-04-07 14:40:20 +08004281static void alc285_fixup_hp_mute_led(struct hda_codec *codec,
4282 const struct hda_fixup *fix, int action)
4283{
4284 alc285_fixup_hp_mute_led_coefbit(codec, fix, action);
4285 alc285_fixup_hp_coef_micmute_led(codec, fix, action);
4286}
4287
Kailang Yang24164f42020-04-07 14:52:42 +08004288static void alc236_fixup_hp_mute_led(struct hda_codec *codec,
4289 const struct hda_fixup *fix, int action)
4290{
4291 alc236_fixup_hp_mute_led_coefbit(codec, fix, action);
4292 alc236_fixup_hp_coef_micmute_led(codec, fix, action);
4293}
4294
Takashi Iwai6a30aba2018-04-27 17:17:35 +02004295#if IS_REACHABLE(CONFIG_INPUT)
David Henningsson33f4acd2015-01-07 15:50:13 +01004296static void gpio2_mic_hotkey_event(struct hda_codec *codec,
4297 struct hda_jack_callback *event)
4298{
4299 struct alc_spec *spec = codec->spec;
4300
4301 /* GPIO2 just toggles on a keypress/keyrelease cycle. Therefore
4302 send both key on and key off event for every interrupt. */
Hui Wangc7b60a82015-12-28 11:35:25 +08004303 input_report_key(spec->kb_dev, spec->alc_mute_keycode_map[ALC_KEY_MICMUTE_INDEX], 1);
David Henningsson33f4acd2015-01-07 15:50:13 +01004304 input_sync(spec->kb_dev);
Hui Wangc7b60a82015-12-28 11:35:25 +08004305 input_report_key(spec->kb_dev, spec->alc_mute_keycode_map[ALC_KEY_MICMUTE_INDEX], 0);
David Henningsson33f4acd2015-01-07 15:50:13 +01004306 input_sync(spec->kb_dev);
4307}
David Henningsson33f4acd2015-01-07 15:50:13 +01004308
Kailang3694cb22015-12-28 11:35:24 +08004309static int alc_register_micmute_input_device(struct hda_codec *codec)
4310{
4311 struct alc_spec *spec = codec->spec;
Hui Wangc7b60a82015-12-28 11:35:25 +08004312 int i;
Kailang3694cb22015-12-28 11:35:24 +08004313
4314 spec->kb_dev = input_allocate_device();
4315 if (!spec->kb_dev) {
4316 codec_err(codec, "Out of memory (input_allocate_device)\n");
4317 return -ENOMEM;
4318 }
Hui Wangc7b60a82015-12-28 11:35:25 +08004319
4320 spec->alc_mute_keycode_map[ALC_KEY_MICMUTE_INDEX] = KEY_MICMUTE;
4321
Kailang3694cb22015-12-28 11:35:24 +08004322 spec->kb_dev->name = "Microphone Mute Button";
4323 spec->kb_dev->evbit[0] = BIT_MASK(EV_KEY);
Hui Wangc7b60a82015-12-28 11:35:25 +08004324 spec->kb_dev->keycodesize = sizeof(spec->alc_mute_keycode_map[0]);
4325 spec->kb_dev->keycodemax = ARRAY_SIZE(spec->alc_mute_keycode_map);
4326 spec->kb_dev->keycode = spec->alc_mute_keycode_map;
4327 for (i = 0; i < ARRAY_SIZE(spec->alc_mute_keycode_map); i++)
4328 set_bit(spec->alc_mute_keycode_map[i], spec->kb_dev->keybit);
Kailang3694cb22015-12-28 11:35:24 +08004329
4330 if (input_register_device(spec->kb_dev)) {
4331 codec_err(codec, "input_register_device failed\n");
4332 input_free_device(spec->kb_dev);
4333 spec->kb_dev = NULL;
4334 return -ENOMEM;
4335 }
4336
4337 return 0;
4338}
4339
Takashi Iwai01e4a272018-06-19 22:47:30 +02004340/* GPIO1 = set according to SKU external amp
4341 * GPIO2 = mic mute hotkey
4342 * GPIO3 = mute LED
4343 * GPIO4 = mic mute LED
4344 */
David Henningsson33f4acd2015-01-07 15:50:13 +01004345static void alc280_fixup_hp_gpio2_mic_hotkey(struct hda_codec *codec,
4346 const struct hda_fixup *fix, int action)
4347{
David Henningsson33f4acd2015-01-07 15:50:13 +01004348 struct alc_spec *spec = codec->spec;
4349
Takashi Iwai01e4a272018-06-19 22:47:30 +02004350 alc_fixup_hp_gpio_led(codec, action, 0x08, 0x10);
David Henningsson33f4acd2015-01-07 15:50:13 +01004351 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai1c76aa52018-06-21 16:37:54 +02004352 spec->init_amp = ALC_INIT_DEFAULT;
Kailang3694cb22015-12-28 11:35:24 +08004353 if (alc_register_micmute_input_device(codec) != 0)
David Henningsson33f4acd2015-01-07 15:50:13 +01004354 return;
David Henningsson33f4acd2015-01-07 15:50:13 +01004355
Takashi Iwai01e4a272018-06-19 22:47:30 +02004356 spec->gpio_mask |= 0x06;
4357 spec->gpio_dir |= 0x02;
4358 spec->gpio_data |= 0x02;
Takashi Iwai7639a062015-03-03 10:07:24 +01004359 snd_hda_codec_write_cache(codec, codec->core.afg, 0,
David Henningsson33f4acd2015-01-07 15:50:13 +01004360 AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x04);
Takashi Iwai7639a062015-03-03 10:07:24 +01004361 snd_hda_jack_detect_enable_callback(codec, codec->core.afg,
David Henningsson33f4acd2015-01-07 15:50:13 +01004362 gpio2_mic_hotkey_event);
David Henningsson33f4acd2015-01-07 15:50:13 +01004363 return;
4364 }
4365
4366 if (!spec->kb_dev)
4367 return;
4368
4369 switch (action) {
David Henningsson33f4acd2015-01-07 15:50:13 +01004370 case HDA_FIXUP_ACT_FREE:
4371 input_unregister_device(spec->kb_dev);
David Henningsson33f4acd2015-01-07 15:50:13 +01004372 spec->kb_dev = NULL;
4373 }
David Henningsson33f4acd2015-01-07 15:50:13 +01004374}
4375
Takashi Iwai01e4a272018-06-19 22:47:30 +02004376/* Line2 = mic mute hotkey
4377 * GPIO2 = mic mute LED
4378 */
Kailang3694cb22015-12-28 11:35:24 +08004379static void alc233_fixup_lenovo_line2_mic_hotkey(struct hda_codec *codec,
4380 const struct hda_fixup *fix, int action)
4381{
Kailang3694cb22015-12-28 11:35:24 +08004382 struct alc_spec *spec = codec->spec;
4383
Takashi Iwai01e4a272018-06-19 22:47:30 +02004384 alc_fixup_hp_gpio_led(codec, action, 0, 0x04);
Kailang3694cb22015-12-28 11:35:24 +08004385 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai1c76aa52018-06-21 16:37:54 +02004386 spec->init_amp = ALC_INIT_DEFAULT;
Kailang3694cb22015-12-28 11:35:24 +08004387 if (alc_register_micmute_input_device(codec) != 0)
4388 return;
4389
Kailang3694cb22015-12-28 11:35:24 +08004390 snd_hda_jack_detect_enable_callback(codec, 0x1b,
4391 gpio2_mic_hotkey_event);
Kailang3694cb22015-12-28 11:35:24 +08004392 return;
4393 }
4394
4395 if (!spec->kb_dev)
4396 return;
4397
4398 switch (action) {
Kailang3694cb22015-12-28 11:35:24 +08004399 case HDA_FIXUP_ACT_FREE:
4400 input_unregister_device(spec->kb_dev);
4401 spec->kb_dev = NULL;
4402 }
4403}
Takashi Iwaic4696522018-01-15 10:44:35 +01004404#else /* INPUT */
4405#define alc280_fixup_hp_gpio2_mic_hotkey NULL
4406#define alc233_fixup_lenovo_line2_mic_hotkey NULL
4407#endif /* INPUT */
Kailang3694cb22015-12-28 11:35:24 +08004408
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004409static void alc269_fixup_hp_line1_mic1_led(struct hda_codec *codec,
4410 const struct hda_fixup *fix, int action)
4411{
4412 struct alc_spec *spec = codec->spec;
4413
Takashi Iwai1bce62a2018-06-19 23:15:59 +02004414 alc269_fixup_hp_mute_led_micx(codec, fix, action, 0x1a);
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004415 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004416 spec->cap_mute_led_nid = 0x18;
Takashi Iwaid03abec2018-06-19 12:29:13 +02004417 snd_hda_gen_add_micmute_led(codec, alc_cap_micmute_update);
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004418 }
4419}
4420
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004421static const struct coef_fw alc225_pre_hsmode[] = {
Kailang Yang5a367672017-07-21 15:23:53 +08004422 UPDATE_COEF(0x4a, 1<<8, 0),
4423 UPDATE_COEFEX(0x57, 0x05, 1<<14, 0),
4424 UPDATE_COEF(0x63, 3<<14, 3<<14),
4425 UPDATE_COEF(0x4a, 3<<4, 2<<4),
4426 UPDATE_COEF(0x4a, 3<<10, 3<<10),
4427 UPDATE_COEF(0x45, 0x3f<<10, 0x34<<10),
4428 UPDATE_COEF(0x4a, 3<<10, 0),
4429 {}
4430};
4431
David Henningsson73bdd592013-04-15 15:44:14 +02004432static void alc_headset_mode_unplugged(struct hda_codec *codec)
4433{
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004434 static const struct coef_fw coef0255[] = {
Kailang Yang717f43d2019-05-31 17:16:53 +08004435 WRITE_COEF(0x1b, 0x0c0b), /* LDO and MISC control */
Takashi Iwai54db6c32014-08-18 15:11:19 +02004436 WRITE_COEF(0x45, 0xd089), /* UAJ function set to menual mode */
4437 UPDATE_COEFEX(0x57, 0x05, 1<<14, 0), /* Direct Drive HP Amp control(Set to verb control)*/
4438 WRITE_COEF(0x06, 0x6104), /* Set MIC2 Vref gate with HP */
4439 WRITE_COEFEX(0x57, 0x03, 0x8aa6), /* Direct Drive HP Amp control */
4440 {}
4441 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004442 static const struct coef_fw coef0256[] = {
Kailang Yange69e7e02016-05-30 15:58:28 +08004443 WRITE_COEF(0x1b, 0x0c4b), /* LDO and MISC control */
Kailang Yang717f43d2019-05-31 17:16:53 +08004444 WRITE_COEF(0x45, 0xd089), /* UAJ function set to menual mode */
4445 WRITE_COEF(0x06, 0x6104), /* Set MIC2 Vref gate with HP */
4446 WRITE_COEFEX(0x57, 0x03, 0x09a3), /* Direct Drive HP Amp control */
4447 UPDATE_COEFEX(0x57, 0x05, 1<<14, 0), /* Direct Drive HP Amp control(Set to verb control)*/
Kailang Yange69e7e02016-05-30 15:58:28 +08004448 {}
4449 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004450 static const struct coef_fw coef0233[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004451 WRITE_COEF(0x1b, 0x0c0b),
4452 WRITE_COEF(0x45, 0xc429),
4453 UPDATE_COEF(0x35, 0x4000, 0),
4454 WRITE_COEF(0x06, 0x2104),
4455 WRITE_COEF(0x1a, 0x0001),
4456 WRITE_COEF(0x26, 0x0004),
4457 WRITE_COEF(0x32, 0x42a3),
4458 {}
4459 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004460 static const struct coef_fw coef0288[] = {
Kailang Yangf3b70332015-04-08 15:01:17 +08004461 UPDATE_COEF(0x4f, 0xfcc0, 0xc400),
4462 UPDATE_COEF(0x50, 0x2000, 0x2000),
4463 UPDATE_COEF(0x56, 0x0006, 0x0006),
4464 UPDATE_COEF(0x66, 0x0008, 0),
4465 UPDATE_COEF(0x67, 0x2000, 0),
4466 {}
4467 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004468 static const struct coef_fw coef0298[] = {
Kailang Yang89542932017-07-17 15:03:43 +08004469 UPDATE_COEF(0x19, 0x1300, 0x0300),
4470 {}
4471 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004472 static const struct coef_fw coef0292[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004473 WRITE_COEF(0x76, 0x000e),
4474 WRITE_COEF(0x6c, 0x2400),
4475 WRITE_COEF(0x18, 0x7308),
4476 WRITE_COEF(0x6b, 0xc429),
4477 {}
4478 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004479 static const struct coef_fw coef0293[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004480 UPDATE_COEF(0x10, 7<<8, 6<<8), /* SET Line1 JD to 0 */
4481 UPDATE_COEFEX(0x57, 0x05, 1<<15|1<<13, 0x0), /* SET charge pump by verb */
4482 UPDATE_COEFEX(0x57, 0x03, 1<<10, 1<<10), /* SET EN_OSW to 1 */
4483 UPDATE_COEF(0x1a, 1<<3, 1<<3), /* Combo JD gating with LINE1-VREFO */
4484 WRITE_COEF(0x45, 0xc429), /* Set to TRS type */
4485 UPDATE_COEF(0x4a, 0x000f, 0x000e), /* Combo Jack auto detect */
4486 {}
4487 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004488 static const struct coef_fw coef0668[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004489 WRITE_COEF(0x15, 0x0d40),
4490 WRITE_COEF(0xb7, 0x802b),
4491 {}
4492 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004493 static const struct coef_fw coef0225[] = {
Kailang Yang5a367672017-07-21 15:23:53 +08004494 UPDATE_COEF(0x63, 3<<14, 0),
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004495 {}
4496 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004497 static const struct coef_fw coef0274[] = {
Kailang Yang71683c32017-06-20 16:33:50 +08004498 UPDATE_COEF(0x4a, 0x0100, 0),
4499 UPDATE_COEFEX(0x57, 0x05, 0x4000, 0),
4500 UPDATE_COEF(0x6b, 0xf000, 0x5000),
4501 UPDATE_COEF(0x4a, 0x0010, 0),
4502 UPDATE_COEF(0x4a, 0x0c00, 0x0c00),
4503 WRITE_COEF(0x45, 0x5289),
4504 UPDATE_COEF(0x4a, 0x0c00, 0),
4505 {}
4506 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004507
Takashi Iwai7639a062015-03-03 10:07:24 +01004508 switch (codec->core.vendor_id) {
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004509 case 0x10ec0255:
Kailang Yange69e7e02016-05-30 15:58:28 +08004510 alc_process_coef_fw(codec, coef0255);
4511 break;
Kailang Yang736f20a2017-10-20 15:06:34 +08004512 case 0x10ec0236:
Kailang Yang7081adf2015-03-30 17:05:37 +08004513 case 0x10ec0256:
Kailang Yange69e7e02016-05-30 15:58:28 +08004514 alc_process_coef_fw(codec, coef0256);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004515 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004516 case 0x10ec0234:
4517 case 0x10ec0274:
4518 case 0x10ec0294:
4519 alc_process_coef_fw(codec, coef0274);
4520 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004521 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004522 case 0x10ec0283:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004523 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02004524 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004525 case 0x10ec0286:
4526 case 0x10ec0288:
Kailang Yang89542932017-07-17 15:03:43 +08004527 alc_process_coef_fw(codec, coef0288);
4528 break;
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004529 case 0x10ec0298:
Kailang Yang89542932017-07-17 15:03:43 +08004530 alc_process_coef_fw(codec, coef0298);
Kailang Yangf3b70332015-04-08 15:01:17 +08004531 alc_process_coef_fw(codec, coef0288);
4532 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004533 case 0x10ec0292:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004534 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02004535 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004536 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004537 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004538 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004539 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004540 alc_process_coef_fw(codec, coef0668);
David Henningsson73bdd592013-04-15 15:44:14 +02004541 break;
Kailang Yangc2b691e2018-01-17 15:22:55 +08004542 case 0x10ec0215:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004543 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004544 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08004545 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004546 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08004547 case 0x10ec0299:
Kailang Yang4d4b0c52019-01-09 16:23:37 +08004548 alc_process_coef_fw(codec, alc225_pre_hsmode);
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004549 alc_process_coef_fw(codec, coef0225);
4550 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08004551 case 0x10ec0867:
4552 alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
4553 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004554 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01004555 codec_dbg(codec, "Headset jack set to unplugged mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02004556}
4557
4558
4559static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin,
4560 hda_nid_t mic_pin)
4561{
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004562 static const struct coef_fw coef0255[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004563 WRITE_COEFEX(0x57, 0x03, 0x8aa6),
4564 WRITE_COEF(0x06, 0x6100), /* Set MIC2 Vref gate to normal */
4565 {}
4566 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004567 static const struct coef_fw coef0256[] = {
Kailang Yang717f43d2019-05-31 17:16:53 +08004568 UPDATE_COEFEX(0x57, 0x05, 1<<14, 1<<14), /* Direct Drive HP Amp control(Set to verb control)*/
4569 WRITE_COEFEX(0x57, 0x03, 0x09a3),
4570 WRITE_COEF(0x06, 0x6100), /* Set MIC2 Vref gate to normal */
4571 {}
4572 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004573 static const struct coef_fw coef0233[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004574 UPDATE_COEF(0x35, 0, 1<<14),
4575 WRITE_COEF(0x06, 0x2100),
4576 WRITE_COEF(0x1a, 0x0021),
4577 WRITE_COEF(0x26, 0x008c),
4578 {}
4579 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004580 static const struct coef_fw coef0288[] = {
Kailang Yang89542932017-07-17 15:03:43 +08004581 UPDATE_COEF(0x4f, 0x00c0, 0),
Kailang Yangf3b70332015-04-08 15:01:17 +08004582 UPDATE_COEF(0x50, 0x2000, 0),
4583 UPDATE_COEF(0x56, 0x0006, 0),
4584 UPDATE_COEF(0x4f, 0xfcc0, 0xc400),
4585 UPDATE_COEF(0x66, 0x0008, 0x0008),
4586 UPDATE_COEF(0x67, 0x2000, 0x2000),
4587 {}
4588 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004589 static const struct coef_fw coef0292[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004590 WRITE_COEF(0x19, 0xa208),
4591 WRITE_COEF(0x2e, 0xacf0),
4592 {}
4593 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004594 static const struct coef_fw coef0293[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004595 UPDATE_COEFEX(0x57, 0x05, 0, 1<<15|1<<13), /* SET charge pump by verb */
4596 UPDATE_COEFEX(0x57, 0x03, 1<<10, 0), /* SET EN_OSW to 0 */
4597 UPDATE_COEF(0x1a, 1<<3, 0), /* Combo JD gating without LINE1-VREFO */
4598 {}
4599 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004600 static const struct coef_fw coef0688[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004601 WRITE_COEF(0xb7, 0x802b),
4602 WRITE_COEF(0xb5, 0x1040),
4603 UPDATE_COEF(0xc3, 0, 1<<12),
4604 {}
4605 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004606 static const struct coef_fw coef0225[] = {
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004607 UPDATE_COEFEX(0x57, 0x05, 1<<14, 1<<14),
4608 UPDATE_COEF(0x4a, 3<<4, 2<<4),
4609 UPDATE_COEF(0x63, 3<<14, 0),
4610 {}
4611 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004612 static const struct coef_fw coef0274[] = {
Kailang Yang71683c32017-06-20 16:33:50 +08004613 UPDATE_COEFEX(0x57, 0x05, 0x4000, 0x4000),
4614 UPDATE_COEF(0x4a, 0x0010, 0),
4615 UPDATE_COEF(0x6b, 0xf000, 0),
4616 {}
4617 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004618
Takashi Iwai7639a062015-03-03 10:07:24 +01004619 switch (codec->core.vendor_id) {
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004620 case 0x10ec0255:
4621 alc_write_coef_idx(codec, 0x45, 0xc489);
4622 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02004623 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004624 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4625 break;
Kailang Yang717f43d2019-05-31 17:16:53 +08004626 case 0x10ec0236:
4627 case 0x10ec0256:
4628 alc_write_coef_idx(codec, 0x45, 0xc489);
4629 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4630 alc_process_coef_fw(codec, coef0256);
4631 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4632 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004633 case 0x10ec0234:
4634 case 0x10ec0274:
4635 case 0x10ec0294:
4636 alc_write_coef_idx(codec, 0x45, 0x4689);
4637 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4638 alc_process_coef_fw(codec, coef0274);
4639 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4640 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004641 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004642 case 0x10ec0283:
4643 alc_write_coef_idx(codec, 0x45, 0xc429);
4644 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02004645 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02004646 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4647 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004648 case 0x10ec0286:
4649 case 0x10ec0288:
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004650 case 0x10ec0298:
Kailang Yangf3b70332015-04-08 15:01:17 +08004651 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4652 alc_process_coef_fw(codec, coef0288);
4653 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4654 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004655 case 0x10ec0292:
4656 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02004657 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02004658 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004659 case 0x10ec0293:
4660 /* Set to TRS mode */
4661 alc_write_coef_idx(codec, 0x45, 0xc429);
4662 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02004663 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004664 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4665 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08004666 case 0x10ec0867:
4667 alc_update_coefex_idx(codec, 0x57, 0x5, 0, 1<<14);
4668 /* fallthru */
Kailang Yang9eb5d0e2017-01-17 15:40:25 +08004669 case 0x10ec0221:
David Henningsson1f8b46c2015-05-12 14:38:15 +02004670 case 0x10ec0662:
4671 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4672 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4673 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004674 case 0x10ec0668:
4675 alc_write_coef_idx(codec, 0x11, 0x0001);
4676 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02004677 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02004678 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4679 break;
Kailang Yangc2b691e2018-01-17 15:22:55 +08004680 case 0x10ec0215:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004681 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004682 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08004683 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004684 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08004685 case 0x10ec0299:
Kailang Yang5a367672017-07-21 15:23:53 +08004686 alc_process_coef_fw(codec, alc225_pre_hsmode);
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004687 alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x31<<10);
4688 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4689 alc_process_coef_fw(codec, coef0225);
4690 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4691 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004692 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01004693 codec_dbg(codec, "Headset jack set to mic-in mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02004694}
4695
4696static void alc_headset_mode_default(struct hda_codec *codec)
4697{
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004698 static const struct coef_fw coef0225[] = {
Kailang Yang5a367672017-07-21 15:23:53 +08004699 UPDATE_COEF(0x45, 0x3f<<10, 0x30<<10),
4700 UPDATE_COEF(0x45, 0x3f<<10, 0x31<<10),
4701 UPDATE_COEF(0x49, 3<<8, 0<<8),
4702 UPDATE_COEF(0x4a, 3<<4, 3<<4),
4703 UPDATE_COEF(0x63, 3<<14, 0),
4704 UPDATE_COEF(0x67, 0xf000, 0x3000),
David Henningsson2ae95572016-02-25 09:37:05 +01004705 {}
4706 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004707 static const struct coef_fw coef0255[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004708 WRITE_COEF(0x45, 0xc089),
4709 WRITE_COEF(0x45, 0xc489),
4710 WRITE_COEFEX(0x57, 0x03, 0x8ea6),
4711 WRITE_COEF(0x49, 0x0049),
4712 {}
4713 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004714 static const struct coef_fw coef0256[] = {
Kailang Yang717f43d2019-05-31 17:16:53 +08004715 WRITE_COEF(0x45, 0xc489),
4716 WRITE_COEFEX(0x57, 0x03, 0x0da3),
4717 WRITE_COEF(0x49, 0x0049),
4718 UPDATE_COEFEX(0x57, 0x05, 1<<14, 0), /* Direct Drive HP Amp control(Set to verb control)*/
4719 WRITE_COEF(0x06, 0x6100),
4720 {}
4721 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004722 static const struct coef_fw coef0233[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004723 WRITE_COEF(0x06, 0x2100),
4724 WRITE_COEF(0x32, 0x4ea3),
4725 {}
4726 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004727 static const struct coef_fw coef0288[] = {
Kailang Yangf3b70332015-04-08 15:01:17 +08004728 UPDATE_COEF(0x4f, 0xfcc0, 0xc400), /* Set to TRS type */
4729 UPDATE_COEF(0x50, 0x2000, 0x2000),
4730 UPDATE_COEF(0x56, 0x0006, 0x0006),
4731 UPDATE_COEF(0x66, 0x0008, 0),
4732 UPDATE_COEF(0x67, 0x2000, 0),
4733 {}
4734 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004735 static const struct coef_fw coef0292[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004736 WRITE_COEF(0x76, 0x000e),
4737 WRITE_COEF(0x6c, 0x2400),
4738 WRITE_COEF(0x6b, 0xc429),
4739 WRITE_COEF(0x18, 0x7308),
4740 {}
4741 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004742 static const struct coef_fw coef0293[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004743 UPDATE_COEF(0x4a, 0x000f, 0x000e), /* Combo Jack auto detect */
4744 WRITE_COEF(0x45, 0xC429), /* Set to TRS type */
4745 UPDATE_COEF(0x1a, 1<<3, 0), /* Combo JD gating without LINE1-VREFO */
4746 {}
4747 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004748 static const struct coef_fw coef0688[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004749 WRITE_COEF(0x11, 0x0041),
4750 WRITE_COEF(0x15, 0x0d40),
4751 WRITE_COEF(0xb7, 0x802b),
4752 {}
4753 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004754 static const struct coef_fw coef0274[] = {
Kailang Yang71683c32017-06-20 16:33:50 +08004755 WRITE_COEF(0x45, 0x4289),
4756 UPDATE_COEF(0x4a, 0x0010, 0x0010),
4757 UPDATE_COEF(0x6b, 0x0f00, 0),
4758 UPDATE_COEF(0x49, 0x0300, 0x0300),
4759 {}
4760 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004761
Takashi Iwai7639a062015-03-03 10:07:24 +01004762 switch (codec->core.vendor_id) {
Kailang Yangc2b691e2018-01-17 15:22:55 +08004763 case 0x10ec0215:
David Henningsson2ae95572016-02-25 09:37:05 +01004764 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004765 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08004766 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004767 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08004768 case 0x10ec0299:
Kailang Yang5a367672017-07-21 15:23:53 +08004769 alc_process_coef_fw(codec, alc225_pre_hsmode);
David Henningsson2ae95572016-02-25 09:37:05 +01004770 alc_process_coef_fw(codec, coef0225);
4771 break;
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004772 case 0x10ec0255:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004773 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004774 break;
Kailang Yang717f43d2019-05-31 17:16:53 +08004775 case 0x10ec0236:
4776 case 0x10ec0256:
4777 alc_write_coef_idx(codec, 0x1b, 0x0e4b);
4778 alc_write_coef_idx(codec, 0x45, 0xc089);
4779 msleep(50);
4780 alc_process_coef_fw(codec, coef0256);
4781 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004782 case 0x10ec0234:
4783 case 0x10ec0274:
4784 case 0x10ec0294:
4785 alc_process_coef_fw(codec, coef0274);
4786 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004787 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004788 case 0x10ec0283:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004789 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02004790 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004791 case 0x10ec0286:
4792 case 0x10ec0288:
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004793 case 0x10ec0298:
Kailang Yangf3b70332015-04-08 15:01:17 +08004794 alc_process_coef_fw(codec, coef0288);
4795 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004796 case 0x10ec0292:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004797 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02004798 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004799 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004800 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004801 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004802 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004803 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02004804 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08004805 case 0x10ec0867:
4806 alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
4807 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004808 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01004809 codec_dbg(codec, "Headset jack set to headphone (default) mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02004810}
4811
4812/* Iphone type */
4813static void alc_headset_mode_ctia(struct hda_codec *codec)
4814{
Kailang Yang89542932017-07-17 15:03:43 +08004815 int val;
4816
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004817 static const struct coef_fw coef0255[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004818 WRITE_COEF(0x45, 0xd489), /* Set to CTIA type */
4819 WRITE_COEF(0x1b, 0x0c2b),
4820 WRITE_COEFEX(0x57, 0x03, 0x8ea6),
4821 {}
4822 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004823 static const struct coef_fw coef0256[] = {
Kailang Yange69e7e02016-05-30 15:58:28 +08004824 WRITE_COEF(0x45, 0xd489), /* Set to CTIA type */
Kailang Yang717f43d2019-05-31 17:16:53 +08004825 WRITE_COEF(0x1b, 0x0e6b),
Kailang Yange69e7e02016-05-30 15:58:28 +08004826 {}
4827 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004828 static const struct coef_fw coef0233[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004829 WRITE_COEF(0x45, 0xd429),
4830 WRITE_COEF(0x1b, 0x0c2b),
4831 WRITE_COEF(0x32, 0x4ea3),
4832 {}
4833 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004834 static const struct coef_fw coef0288[] = {
Kailang Yangf3b70332015-04-08 15:01:17 +08004835 UPDATE_COEF(0x50, 0x2000, 0x2000),
4836 UPDATE_COEF(0x56, 0x0006, 0x0006),
4837 UPDATE_COEF(0x66, 0x0008, 0),
4838 UPDATE_COEF(0x67, 0x2000, 0),
4839 {}
4840 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004841 static const struct coef_fw coef0292[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004842 WRITE_COEF(0x6b, 0xd429),
4843 WRITE_COEF(0x76, 0x0008),
4844 WRITE_COEF(0x18, 0x7388),
4845 {}
4846 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004847 static const struct coef_fw coef0293[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004848 WRITE_COEF(0x45, 0xd429), /* Set to ctia type */
4849 UPDATE_COEF(0x10, 7<<8, 7<<8), /* SET Line1 JD to 1 */
4850 {}
4851 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004852 static const struct coef_fw coef0688[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004853 WRITE_COEF(0x11, 0x0001),
4854 WRITE_COEF(0x15, 0x0d60),
4855 WRITE_COEF(0xc3, 0x0000),
4856 {}
4857 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004858 static const struct coef_fw coef0225_1[] = {
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004859 UPDATE_COEF(0x45, 0x3f<<10, 0x35<<10),
Kailang Yang5a367672017-07-21 15:23:53 +08004860 UPDATE_COEF(0x63, 3<<14, 2<<14),
4861 {}
4862 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004863 static const struct coef_fw coef0225_2[] = {
Kailang Yang5a367672017-07-21 15:23:53 +08004864 UPDATE_COEF(0x45, 0x3f<<10, 0x35<<10),
4865 UPDATE_COEF(0x63, 3<<14, 1<<14),
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004866 {}
4867 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004868
Takashi Iwai7639a062015-03-03 10:07:24 +01004869 switch (codec->core.vendor_id) {
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004870 case 0x10ec0255:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004871 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004872 break;
Kailang Yang736f20a2017-10-20 15:06:34 +08004873 case 0x10ec0236:
Kailang Yange69e7e02016-05-30 15:58:28 +08004874 case 0x10ec0256:
4875 alc_process_coef_fw(codec, coef0256);
4876 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004877 case 0x10ec0234:
4878 case 0x10ec0274:
4879 case 0x10ec0294:
4880 alc_write_coef_idx(codec, 0x45, 0xd689);
4881 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004882 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004883 case 0x10ec0283:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004884 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02004885 break;
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004886 case 0x10ec0298:
Kailang Yang89542932017-07-17 15:03:43 +08004887 val = alc_read_coef_idx(codec, 0x50);
4888 if (val & (1 << 12)) {
4889 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0020);
4890 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400);
4891 msleep(300);
4892 } else {
4893 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0010);
4894 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400);
4895 msleep(300);
4896 }
4897 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004898 case 0x10ec0286:
4899 case 0x10ec0288:
4900 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400);
4901 msleep(300);
4902 alc_process_coef_fw(codec, coef0288);
4903 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004904 case 0x10ec0292:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004905 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02004906 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004907 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004908 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004909 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004910 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004911 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02004912 break;
Kailang Yangc2b691e2018-01-17 15:22:55 +08004913 case 0x10ec0215:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004914 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004915 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08004916 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004917 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08004918 case 0x10ec0299:
Kailang Yang5a367672017-07-21 15:23:53 +08004919 val = alc_read_coef_idx(codec, 0x45);
4920 if (val & (1 << 9))
4921 alc_process_coef_fw(codec, coef0225_2);
4922 else
4923 alc_process_coef_fw(codec, coef0225_1);
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004924 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08004925 case 0x10ec0867:
4926 alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
4927 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004928 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01004929 codec_dbg(codec, "Headset jack set to iPhone-style headset mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02004930}
4931
4932/* Nokia type */
4933static void alc_headset_mode_omtp(struct hda_codec *codec)
4934{
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004935 static const struct coef_fw coef0255[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004936 WRITE_COEF(0x45, 0xe489), /* Set to OMTP Type */
4937 WRITE_COEF(0x1b, 0x0c2b),
4938 WRITE_COEFEX(0x57, 0x03, 0x8ea6),
4939 {}
4940 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004941 static const struct coef_fw coef0256[] = {
Kailang Yange69e7e02016-05-30 15:58:28 +08004942 WRITE_COEF(0x45, 0xe489), /* Set to OMTP Type */
Kailang Yang717f43d2019-05-31 17:16:53 +08004943 WRITE_COEF(0x1b, 0x0e6b),
Kailang Yange69e7e02016-05-30 15:58:28 +08004944 {}
4945 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004946 static const struct coef_fw coef0233[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004947 WRITE_COEF(0x45, 0xe429),
4948 WRITE_COEF(0x1b, 0x0c2b),
4949 WRITE_COEF(0x32, 0x4ea3),
4950 {}
4951 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004952 static const struct coef_fw coef0288[] = {
Kailang Yangf3b70332015-04-08 15:01:17 +08004953 UPDATE_COEF(0x50, 0x2000, 0x2000),
4954 UPDATE_COEF(0x56, 0x0006, 0x0006),
4955 UPDATE_COEF(0x66, 0x0008, 0),
4956 UPDATE_COEF(0x67, 0x2000, 0),
4957 {}
4958 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004959 static const struct coef_fw coef0292[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004960 WRITE_COEF(0x6b, 0xe429),
4961 WRITE_COEF(0x76, 0x0008),
4962 WRITE_COEF(0x18, 0x7388),
4963 {}
4964 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004965 static const struct coef_fw coef0293[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004966 WRITE_COEF(0x45, 0xe429), /* Set to omtp type */
4967 UPDATE_COEF(0x10, 7<<8, 7<<8), /* SET Line1 JD to 1 */
4968 {}
4969 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004970 static const struct coef_fw coef0688[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004971 WRITE_COEF(0x11, 0x0001),
4972 WRITE_COEF(0x15, 0x0d50),
4973 WRITE_COEF(0xc3, 0x0000),
4974 {}
4975 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004976 static const struct coef_fw coef0225[] = {
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004977 UPDATE_COEF(0x45, 0x3f<<10, 0x39<<10),
Kailang Yang5a367672017-07-21 15:23:53 +08004978 UPDATE_COEF(0x63, 3<<14, 2<<14),
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004979 {}
4980 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004981
Takashi Iwai7639a062015-03-03 10:07:24 +01004982 switch (codec->core.vendor_id) {
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004983 case 0x10ec0255:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004984 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004985 break;
Kailang Yang736f20a2017-10-20 15:06:34 +08004986 case 0x10ec0236:
Kailang Yange69e7e02016-05-30 15:58:28 +08004987 case 0x10ec0256:
4988 alc_process_coef_fw(codec, coef0256);
4989 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004990 case 0x10ec0234:
4991 case 0x10ec0274:
4992 case 0x10ec0294:
4993 alc_write_coef_idx(codec, 0x45, 0xe689);
4994 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004995 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004996 case 0x10ec0283:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004997 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02004998 break;
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004999 case 0x10ec0298:
5000 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0010);/* Headset output enable */
Kailang Yang89542932017-07-17 15:03:43 +08005001 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xe400);
5002 msleep(300);
5003 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08005004 case 0x10ec0286:
5005 case 0x10ec0288:
5006 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xe400);
5007 msleep(300);
5008 alc_process_coef_fw(codec, coef0288);
5009 break;
David Henningsson73bdd592013-04-15 15:44:14 +02005010 case 0x10ec0292:
Takashi Iwai54db6c32014-08-18 15:11:19 +02005011 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02005012 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08005013 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02005014 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08005015 break;
David Henningsson73bdd592013-04-15 15:44:14 +02005016 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02005017 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02005018 break;
Kailang Yangc2b691e2018-01-17 15:22:55 +08005019 case 0x10ec0215:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08005020 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08005021 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08005022 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08005023 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08005024 case 0x10ec0299:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08005025 alc_process_coef_fw(codec, coef0225);
5026 break;
David Henningsson73bdd592013-04-15 15:44:14 +02005027 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01005028 codec_dbg(codec, "Headset jack set to Nokia-style headset mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02005029}
5030
5031static void alc_determine_headset_type(struct hda_codec *codec)
5032{
5033 int val;
5034 bool is_ctia = false;
5035 struct alc_spec *spec = codec->spec;
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01005036 static const struct coef_fw coef0255[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02005037 WRITE_COEF(0x45, 0xd089), /* combo jack auto switch control(Check type)*/
5038 WRITE_COEF(0x49, 0x0149), /* combo jack auto switch control(Vref
5039 conteol) */
5040 {}
5041 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01005042 static const struct coef_fw coef0288[] = {
Kailang Yangf3b70332015-04-08 15:01:17 +08005043 UPDATE_COEF(0x4f, 0xfcc0, 0xd400), /* Check Type */
5044 {}
5045 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01005046 static const struct coef_fw coef0298[] = {
Kailang Yang89542932017-07-17 15:03:43 +08005047 UPDATE_COEF(0x50, 0x2000, 0x2000),
5048 UPDATE_COEF(0x56, 0x0006, 0x0006),
5049 UPDATE_COEF(0x66, 0x0008, 0),
5050 UPDATE_COEF(0x67, 0x2000, 0),
5051 UPDATE_COEF(0x19, 0x1300, 0x1300),
5052 {}
5053 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01005054 static const struct coef_fw coef0293[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02005055 UPDATE_COEF(0x4a, 0x000f, 0x0008), /* Combo Jack auto detect */
5056 WRITE_COEF(0x45, 0xD429), /* Set to ctia type */
5057 {}
5058 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01005059 static const struct coef_fw coef0688[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02005060 WRITE_COEF(0x11, 0x0001),
5061 WRITE_COEF(0xb7, 0x802b),
5062 WRITE_COEF(0x15, 0x0d60),
5063 WRITE_COEF(0xc3, 0x0c00),
5064 {}
5065 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01005066 static const struct coef_fw coef0274[] = {
Kailang Yang71683c32017-06-20 16:33:50 +08005067 UPDATE_COEF(0x4a, 0x0010, 0),
5068 UPDATE_COEF(0x4a, 0x8000, 0),
5069 WRITE_COEF(0x45, 0xd289),
5070 UPDATE_COEF(0x49, 0x0300, 0x0300),
5071 {}
5072 };
David Henningsson73bdd592013-04-15 15:44:14 +02005073
Takashi Iwai7639a062015-03-03 10:07:24 +01005074 switch (codec->core.vendor_id) {
Kailang Yang9a22a8f52013-11-08 15:54:49 +08005075 case 0x10ec0255:
Takashi Iwai54db6c32014-08-18 15:11:19 +02005076 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08005077 msleep(300);
5078 val = alc_read_coef_idx(codec, 0x46);
5079 is_ctia = (val & 0x0070) == 0x0070;
5080 break;
Kailang Yang717f43d2019-05-31 17:16:53 +08005081 case 0x10ec0236:
5082 case 0x10ec0256:
5083 alc_write_coef_idx(codec, 0x1b, 0x0e4b);
5084 alc_write_coef_idx(codec, 0x06, 0x6104);
5085 alc_write_coefex_idx(codec, 0x57, 0x3, 0x09a3);
5086
5087 snd_hda_codec_write(codec, 0x21, 0,
5088 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
5089 msleep(80);
5090 snd_hda_codec_write(codec, 0x21, 0,
5091 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
5092
5093 alc_process_coef_fw(codec, coef0255);
5094 msleep(300);
5095 val = alc_read_coef_idx(codec, 0x46);
5096 is_ctia = (val & 0x0070) == 0x0070;
5097
5098 alc_write_coefex_idx(codec, 0x57, 0x3, 0x0da3);
5099 alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
5100
5101 snd_hda_codec_write(codec, 0x21, 0,
5102 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
5103 msleep(80);
5104 snd_hda_codec_write(codec, 0x21, 0,
5105 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
5106 break;
Kailang Yang71683c32017-06-20 16:33:50 +08005107 case 0x10ec0234:
5108 case 0x10ec0274:
5109 case 0x10ec0294:
5110 alc_process_coef_fw(codec, coef0274);
5111 msleep(80);
5112 val = alc_read_coef_idx(codec, 0x46);
5113 is_ctia = (val & 0x00f0) == 0x00f0;
5114 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08005115 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02005116 case 0x10ec0283:
5117 alc_write_coef_idx(codec, 0x45, 0xd029);
5118 msleep(300);
5119 val = alc_read_coef_idx(codec, 0x46);
5120 is_ctia = (val & 0x0070) == 0x0070;
5121 break;
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08005122 case 0x10ec0298:
Kailang Yang89542932017-07-17 15:03:43 +08005123 snd_hda_codec_write(codec, 0x21, 0,
5124 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
5125 msleep(100);
5126 snd_hda_codec_write(codec, 0x21, 0,
5127 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
5128 msleep(200);
5129
5130 val = alc_read_coef_idx(codec, 0x50);
5131 if (val & (1 << 12)) {
5132 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0020);
5133 alc_process_coef_fw(codec, coef0288);
5134 msleep(350);
5135 val = alc_read_coef_idx(codec, 0x50);
5136 is_ctia = (val & 0x0070) == 0x0070;
5137 } else {
5138 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0010);
5139 alc_process_coef_fw(codec, coef0288);
5140 msleep(350);
5141 val = alc_read_coef_idx(codec, 0x50);
5142 is_ctia = (val & 0x0070) == 0x0070;
5143 }
5144 alc_process_coef_fw(codec, coef0298);
5145 snd_hda_codec_write(codec, 0x21, 0,
5146 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP);
5147 msleep(75);
5148 snd_hda_codec_write(codec, 0x21, 0,
5149 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
5150 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08005151 case 0x10ec0286:
5152 case 0x10ec0288:
5153 alc_process_coef_fw(codec, coef0288);
5154 msleep(350);
5155 val = alc_read_coef_idx(codec, 0x50);
5156 is_ctia = (val & 0x0070) == 0x0070;
5157 break;
David Henningsson73bdd592013-04-15 15:44:14 +02005158 case 0x10ec0292:
5159 alc_write_coef_idx(codec, 0x6b, 0xd429);
5160 msleep(300);
5161 val = alc_read_coef_idx(codec, 0x6c);
5162 is_ctia = (val & 0x001c) == 0x001c;
5163 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08005164 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02005165 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08005166 msleep(300);
5167 val = alc_read_coef_idx(codec, 0x46);
5168 is_ctia = (val & 0x0070) == 0x0070;
5169 break;
David Henningsson73bdd592013-04-15 15:44:14 +02005170 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02005171 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02005172 msleep(300);
5173 val = alc_read_coef_idx(codec, 0xbe);
5174 is_ctia = (val & 0x1c02) == 0x1c02;
5175 break;
Kailang Yangc2b691e2018-01-17 15:22:55 +08005176 case 0x10ec0215:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08005177 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08005178 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08005179 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08005180 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08005181 case 0x10ec0299:
Kailang Yangda911b12018-01-05 16:50:08 +08005182 snd_hda_codec_write(codec, 0x21, 0,
5183 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
5184 msleep(80);
5185 snd_hda_codec_write(codec, 0x21, 0,
5186 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
5187
Kailang Yang5a367672017-07-21 15:23:53 +08005188 alc_process_coef_fw(codec, alc225_pre_hsmode);
5189 alc_update_coef_idx(codec, 0x67, 0xf000, 0x1000);
5190 val = alc_read_coef_idx(codec, 0x45);
5191 if (val & (1 << 9)) {
5192 alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x34<<10);
5193 alc_update_coef_idx(codec, 0x49, 3<<8, 2<<8);
5194 msleep(800);
5195 val = alc_read_coef_idx(codec, 0x46);
5196 is_ctia = (val & 0x00f0) == 0x00f0;
5197 } else {
5198 alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x34<<10);
5199 alc_update_coef_idx(codec, 0x49, 3<<8, 1<<8);
5200 msleep(800);
5201 val = alc_read_coef_idx(codec, 0x46);
5202 is_ctia = (val & 0x00f0) == 0x00f0;
5203 }
5204 alc_update_coef_idx(codec, 0x4a, 7<<6, 7<<6);
5205 alc_update_coef_idx(codec, 0x4a, 3<<4, 3<<4);
5206 alc_update_coef_idx(codec, 0x67, 0xf000, 0x3000);
Kailang Yangda911b12018-01-05 16:50:08 +08005207
5208 snd_hda_codec_write(codec, 0x21, 0,
5209 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
5210 msleep(80);
5211 snd_hda_codec_write(codec, 0x21, 0,
5212 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08005213 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08005214 case 0x10ec0867:
5215 is_ctia = true;
5216 break;
David Henningsson73bdd592013-04-15 15:44:14 +02005217 }
5218
Takashi Iwai4e76a882014-02-25 12:21:03 +01005219 codec_dbg(codec, "Headset jack detected iPhone-style headset: %s\n",
David Henningsson73bdd592013-04-15 15:44:14 +02005220 is_ctia ? "yes" : "no");
5221 spec->current_headset_type = is_ctia ? ALC_HEADSET_TYPE_CTIA : ALC_HEADSET_TYPE_OMTP;
5222}
5223
5224static void alc_update_headset_mode(struct hda_codec *codec)
5225{
5226 struct alc_spec *spec = codec->spec;
5227
5228 hda_nid_t mux_pin = spec->gen.imux_pins[spec->gen.cur_mux[0]];
Takashi Iwai35a39f92019-02-01 11:19:50 +01005229 hda_nid_t hp_pin = alc_get_hp_pin(spec);
David Henningsson73bdd592013-04-15 15:44:14 +02005230
5231 int new_headset_mode;
5232
5233 if (!snd_hda_jack_detect(codec, hp_pin))
5234 new_headset_mode = ALC_HEADSET_MODE_UNPLUGGED;
5235 else if (mux_pin == spec->headset_mic_pin)
5236 new_headset_mode = ALC_HEADSET_MODE_HEADSET;
5237 else if (mux_pin == spec->headphone_mic_pin)
5238 new_headset_mode = ALC_HEADSET_MODE_MIC;
5239 else
5240 new_headset_mode = ALC_HEADSET_MODE_HEADPHONE;
5241
David Henningsson5959a6b2013-11-12 11:10:57 +01005242 if (new_headset_mode == spec->current_headset_mode) {
5243 snd_hda_gen_update_outputs(codec);
David Henningsson73bdd592013-04-15 15:44:14 +02005244 return;
David Henningsson5959a6b2013-11-12 11:10:57 +01005245 }
David Henningsson73bdd592013-04-15 15:44:14 +02005246
5247 switch (new_headset_mode) {
5248 case ALC_HEADSET_MODE_UNPLUGGED:
5249 alc_headset_mode_unplugged(codec);
Kailang Yangaeac1a02019-05-16 16:10:44 +08005250 spec->current_headset_mode = ALC_HEADSET_MODE_UNKNOWN;
5251 spec->current_headset_type = ALC_HEADSET_TYPE_UNKNOWN;
David Henningsson73bdd592013-04-15 15:44:14 +02005252 spec->gen.hp_jack_present = false;
5253 break;
5254 case ALC_HEADSET_MODE_HEADSET:
5255 if (spec->current_headset_type == ALC_HEADSET_TYPE_UNKNOWN)
5256 alc_determine_headset_type(codec);
5257 if (spec->current_headset_type == ALC_HEADSET_TYPE_CTIA)
5258 alc_headset_mode_ctia(codec);
5259 else if (spec->current_headset_type == ALC_HEADSET_TYPE_OMTP)
5260 alc_headset_mode_omtp(codec);
5261 spec->gen.hp_jack_present = true;
5262 break;
5263 case ALC_HEADSET_MODE_MIC:
5264 alc_headset_mode_mic_in(codec, hp_pin, spec->headphone_mic_pin);
5265 spec->gen.hp_jack_present = false;
5266 break;
5267 case ALC_HEADSET_MODE_HEADPHONE:
5268 alc_headset_mode_default(codec);
5269 spec->gen.hp_jack_present = true;
5270 break;
5271 }
5272 if (new_headset_mode != ALC_HEADSET_MODE_MIC) {
5273 snd_hda_set_pin_ctl_cache(codec, hp_pin,
5274 AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN);
David Henningsson1f8b46c2015-05-12 14:38:15 +02005275 if (spec->headphone_mic_pin && spec->headphone_mic_pin != hp_pin)
David Henningsson73bdd592013-04-15 15:44:14 +02005276 snd_hda_set_pin_ctl_cache(codec, spec->headphone_mic_pin,
5277 PIN_VREFHIZ);
5278 }
5279 spec->current_headset_mode = new_headset_mode;
5280
5281 snd_hda_gen_update_outputs(codec);
5282}
5283
5284static void alc_update_headset_mode_hook(struct hda_codec *codec,
Takashi Iwai7fe30712014-01-30 17:59:02 +01005285 struct snd_kcontrol *kcontrol,
5286 struct snd_ctl_elem_value *ucontrol)
David Henningsson73bdd592013-04-15 15:44:14 +02005287{
5288 alc_update_headset_mode(codec);
5289}
5290
Takashi Iwai1a4f69d2014-09-11 15:22:46 +02005291static void alc_update_headset_jack_cb(struct hda_codec *codec,
5292 struct hda_jack_callback *jack)
David Henningsson73bdd592013-04-15 15:44:14 +02005293{
David Henningsson73bdd592013-04-15 15:44:14 +02005294 snd_hda_gen_hp_automute(codec, jack);
5295}
5296
5297static void alc_probe_headset_mode(struct hda_codec *codec)
5298{
5299 int i;
5300 struct alc_spec *spec = codec->spec;
5301 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
5302
5303 /* Find mic pins */
5304 for (i = 0; i < cfg->num_inputs; i++) {
5305 if (cfg->inputs[i].is_headset_mic && !spec->headset_mic_pin)
5306 spec->headset_mic_pin = cfg->inputs[i].pin;
5307 if (cfg->inputs[i].is_headphone_mic && !spec->headphone_mic_pin)
5308 spec->headphone_mic_pin = cfg->inputs[i].pin;
5309 }
5310
Takashi Iwai0bed2aa2018-06-19 12:45:53 +02005311 WARN_ON(spec->gen.cap_sync_hook);
David Henningsson73bdd592013-04-15 15:44:14 +02005312 spec->gen.cap_sync_hook = alc_update_headset_mode_hook;
5313 spec->gen.automute_hook = alc_update_headset_mode;
5314 spec->gen.hp_automute_hook = alc_update_headset_jack_cb;
5315}
5316
5317static void alc_fixup_headset_mode(struct hda_codec *codec,
5318 const struct hda_fixup *fix, int action)
5319{
5320 struct alc_spec *spec = codec->spec;
5321
5322 switch (action) {
5323 case HDA_FIXUP_ACT_PRE_PROBE:
5324 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC | HDA_PINCFG_HEADPHONE_MIC;
5325 break;
5326 case HDA_FIXUP_ACT_PROBE:
5327 alc_probe_headset_mode(codec);
5328 break;
5329 case HDA_FIXUP_ACT_INIT:
Kailang Yangaeac1a02019-05-16 16:10:44 +08005330 if (is_s3_resume(codec) || is_s4_resume(codec)) {
5331 spec->current_headset_mode = ALC_HEADSET_MODE_UNKNOWN;
5332 spec->current_headset_type = ALC_HEADSET_TYPE_UNKNOWN;
5333 }
David Henningsson73bdd592013-04-15 15:44:14 +02005334 alc_update_headset_mode(codec);
5335 break;
5336 }
5337}
5338
5339static void alc_fixup_headset_mode_no_hp_mic(struct hda_codec *codec,
5340 const struct hda_fixup *fix, int action)
5341{
5342 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5343 struct alc_spec *spec = codec->spec;
5344 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
5345 }
5346 else
5347 alc_fixup_headset_mode(codec, fix, action);
5348}
5349
Kailang Yang31278992014-03-03 15:27:22 +08005350static void alc255_set_default_jack_type(struct hda_codec *codec)
5351{
5352 /* Set to iphone type */
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01005353 static const struct coef_fw alc255fw[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02005354 WRITE_COEF(0x1b, 0x880b),
5355 WRITE_COEF(0x45, 0xd089),
5356 WRITE_COEF(0x1b, 0x080b),
5357 WRITE_COEF(0x46, 0x0004),
5358 WRITE_COEF(0x1b, 0x0c0b),
5359 {}
5360 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01005361 static const struct coef_fw alc256fw[] = {
Kailang Yange69e7e02016-05-30 15:58:28 +08005362 WRITE_COEF(0x1b, 0x884b),
5363 WRITE_COEF(0x45, 0xd089),
5364 WRITE_COEF(0x1b, 0x084b),
5365 WRITE_COEF(0x46, 0x0004),
5366 WRITE_COEF(0x1b, 0x0c4b),
5367 {}
5368 };
5369 switch (codec->core.vendor_id) {
5370 case 0x10ec0255:
5371 alc_process_coef_fw(codec, alc255fw);
5372 break;
Kailang Yang736f20a2017-10-20 15:06:34 +08005373 case 0x10ec0236:
Kailang Yange69e7e02016-05-30 15:58:28 +08005374 case 0x10ec0256:
5375 alc_process_coef_fw(codec, alc256fw);
5376 break;
5377 }
Kailang Yang31278992014-03-03 15:27:22 +08005378 msleep(30);
5379}
5380
Kailang Yang9a22a8f52013-11-08 15:54:49 +08005381static void alc_fixup_headset_mode_alc255(struct hda_codec *codec,
5382 const struct hda_fixup *fix, int action)
5383{
5384 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Kailang Yang31278992014-03-03 15:27:22 +08005385 alc255_set_default_jack_type(codec);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08005386 }
5387 alc_fixup_headset_mode(codec, fix, action);
5388}
5389
Kailang Yang31278992014-03-03 15:27:22 +08005390static void alc_fixup_headset_mode_alc255_no_hp_mic(struct hda_codec *codec,
5391 const struct hda_fixup *fix, int action)
5392{
5393 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5394 struct alc_spec *spec = codec->spec;
5395 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
5396 alc255_set_default_jack_type(codec);
5397 }
5398 else
5399 alc_fixup_headset_mode(codec, fix, action);
5400}
5401
Kailang Yange1e62b92015-04-08 16:01:22 +08005402static void alc288_update_headset_jack_cb(struct hda_codec *codec,
5403 struct hda_jack_callback *jack)
5404{
5405 struct alc_spec *spec = codec->spec;
Kailang Yange1e62b92015-04-08 16:01:22 +08005406
5407 alc_update_headset_jack_cb(codec, jack);
5408 /* Headset Mic enable or disable, only for Dell Dino */
Takashi Iwaid44a6862018-06-19 23:04:03 +02005409 alc_update_gpio_data(codec, 0x40, spec->gen.hp_jack_present);
Kailang Yange1e62b92015-04-08 16:01:22 +08005410}
5411
5412static void alc_fixup_headset_mode_dell_alc288(struct hda_codec *codec,
5413 const struct hda_fixup *fix, int action)
5414{
5415 alc_fixup_headset_mode(codec, fix, action);
5416 if (action == HDA_FIXUP_ACT_PROBE) {
5417 struct alc_spec *spec = codec->spec;
Takashi Iwaid44a6862018-06-19 23:04:03 +02005418 /* toggled via hp_automute_hook */
5419 spec->gpio_mask |= 0x40;
5420 spec->gpio_dir |= 0x40;
Kailang Yange1e62b92015-04-08 16:01:22 +08005421 spec->gen.hp_automute_hook = alc288_update_headset_jack_cb;
5422 }
5423}
5424
Hui Wang493a52a2014-01-14 14:07:36 +08005425static void alc_fixup_auto_mute_via_amp(struct hda_codec *codec,
5426 const struct hda_fixup *fix, int action)
5427{
5428 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5429 struct alc_spec *spec = codec->spec;
5430 spec->gen.auto_mute_via_amp = 1;
5431 }
5432}
5433
Takashi Iwai9b745ab2014-03-07 08:37:19 +01005434static void alc_fixup_no_shutup(struct hda_codec *codec,
5435 const struct hda_fixup *fix, int action)
5436{
Takashi Iwaiefe55732018-06-15 11:55:02 +02005437 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai9b745ab2014-03-07 08:37:19 +01005438 struct alc_spec *spec = codec->spec;
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01005439 spec->no_shutup_pins = 1;
Takashi Iwai9b745ab2014-03-07 08:37:19 +01005440 }
5441}
5442
Gabriele Mazzotta5e6db662014-05-20 18:58:26 +02005443static void alc_fixup_disable_aamix(struct hda_codec *codec,
5444 const struct hda_fixup *fix, int action)
5445{
5446 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5447 struct alc_spec *spec = codec->spec;
5448 /* Disable AA-loopback as it causes white noise */
5449 spec->gen.mixer_nid = 0;
5450 }
5451}
5452
Takashi Iwai7f57d802015-09-24 17:36:51 +02005453/* fixup for Thinkpad docks: add dock pins, avoid HP parser fixup */
5454static void alc_fixup_tpt440_dock(struct hda_codec *codec,
5455 const struct hda_fixup *fix, int action)
5456{
5457 static const struct hda_pintbl pincfgs[] = {
5458 { 0x16, 0x21211010 }, /* dock headphone */
5459 { 0x19, 0x21a11010 }, /* dock mic */
5460 { }
5461 };
5462 struct alc_spec *spec = codec->spec;
5463
5464 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Hui Wang871b9062019-08-14 12:09:08 +08005465 spec->reboot_notify = snd_hda_gen_reboot_notify; /* reduce noise */
Takashi Iwai7f57d802015-09-24 17:36:51 +02005466 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
5467 codec->power_save_node = 0; /* avoid click noises */
5468 snd_hda_apply_pincfgs(codec, pincfgs);
5469 }
5470}
5471
Kailang Yang61fcf8e2018-02-02 15:26:46 +08005472static void alc_fixup_tpt470_dock(struct hda_codec *codec,
5473 const struct hda_fixup *fix, int action)
5474{
5475 static const struct hda_pintbl pincfgs[] = {
5476 { 0x17, 0x21211010 }, /* dock headphone */
5477 { 0x19, 0x21a11010 }, /* dock mic */
5478 { }
5479 };
Takashi Iwai54947cd2018-12-03 10:44:15 +01005480 /* Assure the speaker pin to be coupled with DAC NID 0x03; otherwise
5481 * the speaker output becomes too low by some reason on Thinkpads with
5482 * ALC298 codec
5483 */
Michał Mirosławcaf3c042020-01-03 10:23:48 +01005484 static const hda_nid_t preferred_pairs[] = {
Takashi Iwai54947cd2018-12-03 10:44:15 +01005485 0x14, 0x03, 0x17, 0x02, 0x21, 0x02,
5486 0
5487 };
Kailang Yang61fcf8e2018-02-02 15:26:46 +08005488 struct alc_spec *spec = codec->spec;
5489
5490 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai54947cd2018-12-03 10:44:15 +01005491 spec->gen.preferred_dacs = preferred_pairs;
Kailang Yang61fcf8e2018-02-02 15:26:46 +08005492 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
Takashi Iwai71db96d2018-02-26 15:36:38 +01005493 snd_hda_apply_pincfgs(codec, pincfgs);
5494 } else if (action == HDA_FIXUP_ACT_INIT) {
Kailang Yang61fcf8e2018-02-02 15:26:46 +08005495 /* Enable DOCK device */
5496 snd_hda_codec_write(codec, 0x17, 0,
5497 AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0);
5498 /* Enable DOCK device */
5499 snd_hda_codec_write(codec, 0x19, 0,
5500 AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0);
Kailang Yang61fcf8e2018-02-02 15:26:46 +08005501 }
5502}
5503
Gabriele Mazzotta9476d3692015-04-19 19:00:40 +02005504static void alc_shutup_dell_xps13(struct hda_codec *codec)
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02005505{
5506 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01005507 int hp_pin = alc_get_hp_pin(spec);
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02005508
Gabriele Mazzotta9476d3692015-04-19 19:00:40 +02005509 /* Prevent pop noises when headphones are plugged in */
5510 snd_hda_codec_write(codec, hp_pin, 0,
5511 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
5512 msleep(20);
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02005513}
5514
5515static void alc_fixup_dell_xps13(struct hda_codec *codec,
5516 const struct hda_fixup *fix, int action)
5517{
Takashi Iwai3e1b0c42015-04-27 10:43:22 +02005518 struct alc_spec *spec = codec->spec;
5519 struct hda_input_mux *imux = &spec->gen.input_mux;
5520 int i;
Gabriele Mazzottaf38663a2014-08-08 19:34:40 +02005521
Takashi Iwai3e1b0c42015-04-27 10:43:22 +02005522 switch (action) {
5523 case HDA_FIXUP_ACT_PRE_PROBE:
5524 /* mic pin 0x19 must be initialized with Vref Hi-Z, otherwise
5525 * it causes a click noise at start up
5526 */
5527 snd_hda_codec_set_pin_target(codec, 0x19, PIN_VREFHIZ);
Takashi Iwaiefe55732018-06-15 11:55:02 +02005528 spec->shutup = alc_shutup_dell_xps13;
Takashi Iwai3e1b0c42015-04-27 10:43:22 +02005529 break;
5530 case HDA_FIXUP_ACT_PROBE:
Gabriele Mazzottaf38663a2014-08-08 19:34:40 +02005531 /* Make the internal mic the default input source. */
5532 for (i = 0; i < imux->num_items; i++) {
5533 if (spec->gen.imux_pins[i] == 0x12) {
5534 spec->gen.cur_mux[0] = i;
5535 break;
5536 }
5537 }
Takashi Iwai3e1b0c42015-04-27 10:43:22 +02005538 break;
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02005539 }
5540}
5541
David Henningsson1f8b46c2015-05-12 14:38:15 +02005542static void alc_fixup_headset_mode_alc662(struct hda_codec *codec,
5543 const struct hda_fixup *fix, int action)
5544{
5545 struct alc_spec *spec = codec->spec;
5546
5547 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5548 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
5549 spec->gen.hp_mic = 1; /* Mic-in is same pin as headphone */
David Henningssonb40eda62015-05-28 09:40:23 +02005550
5551 /* Disable boost for mic-in permanently. (This code is only called
5552 from quirks that guarantee that the headphone is at NID 0x1b.) */
5553 snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000);
5554 snd_hda_override_wcaps(codec, 0x1b, get_wcaps(codec, 0x1b) & ~AC_WCAP_IN_AMP);
David Henningsson1f8b46c2015-05-12 14:38:15 +02005555 } else
5556 alc_fixup_headset_mode(codec, fix, action);
5557}
5558
David Henningsson73bdd592013-04-15 15:44:14 +02005559static void alc_fixup_headset_mode_alc668(struct hda_codec *codec,
5560 const struct hda_fixup *fix, int action)
5561{
5562 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
David Henningsson73bdd592013-04-15 15:44:14 +02005563 alc_write_coef_idx(codec, 0xc4, 0x8000);
Takashi Iwai98b24882014-08-18 13:47:50 +02005564 alc_update_coef_idx(codec, 0xc2, ~0xfe, 0);
David Henningsson73bdd592013-04-15 15:44:14 +02005565 snd_hda_set_pin_ctl_cache(codec, 0x18, 0);
5566 }
5567 alc_fixup_headset_mode(codec, fix, action);
5568}
5569
Chih-Chung Changbde7bc62013-08-05 16:38:42 +08005570/* Returns the nid of the external mic input pin, or 0 if it cannot be found. */
5571static int find_ext_mic_pin(struct hda_codec *codec)
5572{
5573 struct alc_spec *spec = codec->spec;
5574 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
5575 hda_nid_t nid;
5576 unsigned int defcfg;
5577 int i;
5578
5579 for (i = 0; i < cfg->num_inputs; i++) {
5580 if (cfg->inputs[i].type != AUTO_PIN_MIC)
5581 continue;
5582 nid = cfg->inputs[i].pin;
5583 defcfg = snd_hda_codec_get_pincfg(codec, nid);
5584 if (snd_hda_get_input_pin_attr(defcfg) == INPUT_PIN_ATTR_INT)
5585 continue;
5586 return nid;
5587 }
5588
5589 return 0;
5590}
5591
Dylan Reid08a978d2012-11-18 22:56:40 -08005592static void alc271_hp_gate_mic_jack(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01005593 const struct hda_fixup *fix,
Dylan Reid08a978d2012-11-18 22:56:40 -08005594 int action)
5595{
5596 struct alc_spec *spec = codec->spec;
5597
Takashi Iwai0db75792013-01-23 13:57:20 +01005598 if (action == HDA_FIXUP_ACT_PROBE) {
Chih-Chung Changbde7bc62013-08-05 16:38:42 +08005599 int mic_pin = find_ext_mic_pin(codec);
Takashi Iwai35a39f92019-02-01 11:19:50 +01005600 int hp_pin = alc_get_hp_pin(spec);
Chih-Chung Changbde7bc62013-08-05 16:38:42 +08005601
5602 if (snd_BUG_ON(!mic_pin || !hp_pin))
Takashi Iwai0db75792013-01-23 13:57:20 +01005603 return;
Chih-Chung Changbde7bc62013-08-05 16:38:42 +08005604 snd_hda_jack_set_gating_jack(codec, mic_pin, hp_pin);
Takashi Iwai0db75792013-01-23 13:57:20 +01005605 }
Dylan Reid08a978d2012-11-18 22:56:40 -08005606}
David Henningsson693b6132012-06-22 19:12:10 +02005607
David Henningsson3e0d6112013-04-22 14:30:14 +02005608static void alc269_fixup_limit_int_mic_boost(struct hda_codec *codec,
5609 const struct hda_fixup *fix,
5610 int action)
5611{
5612 struct alc_spec *spec = codec->spec;
5613 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
5614 int i;
5615
5616 /* The mic boosts on level 2 and 3 are too noisy
5617 on the internal mic input.
5618 Therefore limit the boost to 0 or 1. */
5619
5620 if (action != HDA_FIXUP_ACT_PROBE)
5621 return;
5622
5623 for (i = 0; i < cfg->num_inputs; i++) {
5624 hda_nid_t nid = cfg->inputs[i].pin;
5625 unsigned int defcfg;
5626 if (cfg->inputs[i].type != AUTO_PIN_MIC)
5627 continue;
5628 defcfg = snd_hda_codec_get_pincfg(codec, nid);
5629 if (snd_hda_get_input_pin_attr(defcfg) != INPUT_PIN_ATTR_INT)
5630 continue;
5631
5632 snd_hda_override_amp_caps(codec, nid, HDA_INPUT,
5633 (0x00 << AC_AMPCAP_OFFSET_SHIFT) |
5634 (0x01 << AC_AMPCAP_NUM_STEPS_SHIFT) |
5635 (0x2f << AC_AMPCAP_STEP_SIZE_SHIFT) |
5636 (0 << AC_AMPCAP_MUTE_SHIFT));
5637 }
5638}
5639
Kailang Yangcd217a62013-08-22 10:15:24 +02005640static void alc283_hp_automute_hook(struct hda_codec *codec,
Takashi Iwai1a4f69d2014-09-11 15:22:46 +02005641 struct hda_jack_callback *jack)
Kailang Yangcd217a62013-08-22 10:15:24 +02005642{
5643 struct alc_spec *spec = codec->spec;
5644 int vref;
5645
5646 msleep(200);
5647 snd_hda_gen_hp_automute(codec, jack);
5648
5649 vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0;
5650
5651 msleep(600);
5652 snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5653 vref);
5654}
5655
Kailang Yangcd217a62013-08-22 10:15:24 +02005656static void alc283_fixup_chromebook(struct hda_codec *codec,
5657 const struct hda_fixup *fix, int action)
5658{
5659 struct alc_spec *spec = codec->spec;
Kailang Yangcd217a62013-08-22 10:15:24 +02005660
5661 switch (action) {
5662 case HDA_FIXUP_ACT_PRE_PROBE:
Kailang Yang0202e992013-12-02 15:20:15 +08005663 snd_hda_override_wcaps(codec, 0x03, 0);
Takashi Iwaid2e92702013-10-30 07:50:53 +01005664 /* Disable AA-loopback as it causes white noise */
5665 spec->gen.mixer_nid = 0;
Kailang Yang38070212013-11-01 15:57:35 +08005666 break;
5667 case HDA_FIXUP_ACT_INIT:
Kailang Yangde9481c2014-04-07 16:41:52 +08005668 /* MIC2-VREF control */
5669 /* Set to manual mode */
Takashi Iwai98b24882014-08-18 13:47:50 +02005670 alc_update_coef_idx(codec, 0x06, 0x000c, 0);
Kailang Yang0202e992013-12-02 15:20:15 +08005671 /* Enable Line1 input control by verb */
Takashi Iwai98b24882014-08-18 13:47:50 +02005672 alc_update_coef_idx(codec, 0x1a, 0, 1 << 4);
Kailang Yang0202e992013-12-02 15:20:15 +08005673 break;
5674 }
5675}
5676
5677static void alc283_fixup_sense_combo_jack(struct hda_codec *codec,
5678 const struct hda_fixup *fix, int action)
5679{
5680 struct alc_spec *spec = codec->spec;
Kailang Yang0202e992013-12-02 15:20:15 +08005681
5682 switch (action) {
5683 case HDA_FIXUP_ACT_PRE_PROBE:
Kailang Yangcd217a62013-08-22 10:15:24 +02005684 spec->gen.hp_automute_hook = alc283_hp_automute_hook;
5685 break;
5686 case HDA_FIXUP_ACT_INIT:
5687 /* MIC2-VREF control */
5688 /* Set to manual mode */
Takashi Iwai98b24882014-08-18 13:47:50 +02005689 alc_update_coef_idx(codec, 0x06, 0x000c, 0);
Kailang Yangcd217a62013-08-22 10:15:24 +02005690 break;
5691 }
5692}
5693
Takashi Iwai7bba2152013-09-06 15:45:38 +02005694/* mute tablet speaker pin (0x14) via dock plugging in addition */
5695static void asus_tx300_automute(struct hda_codec *codec)
5696{
5697 struct alc_spec *spec = codec->spec;
5698 snd_hda_gen_update_outputs(codec);
5699 if (snd_hda_jack_detect(codec, 0x1b))
5700 spec->gen.mute_bits |= (1ULL << 0x14);
5701}
5702
5703static void alc282_fixup_asus_tx300(struct hda_codec *codec,
5704 const struct hda_fixup *fix, int action)
5705{
5706 struct alc_spec *spec = codec->spec;
Takashi Iwai7bba2152013-09-06 15:45:38 +02005707 static const struct hda_pintbl dock_pins[] = {
5708 { 0x1b, 0x21114000 }, /* dock speaker pin */
5709 {}
5710 };
Takashi Iwai7bba2152013-09-06 15:45:38 +02005711
5712 switch (action) {
5713 case HDA_FIXUP_ACT_PRE_PROBE:
Takashi Iwai1c76aa52018-06-21 16:37:54 +02005714 spec->init_amp = ALC_INIT_DEFAULT;
Takashi Iwaiae065f12018-06-19 23:00:03 +02005715 /* TX300 needs to set up GPIO2 for the speaker amp */
5716 alc_setup_gpio(codec, 0x04);
Takashi Iwai7bba2152013-09-06 15:45:38 +02005717 snd_hda_apply_pincfgs(codec, dock_pins);
5718 spec->gen.auto_mute_via_amp = 1;
5719 spec->gen.automute_hook = asus_tx300_automute;
5720 snd_hda_jack_detect_enable_callback(codec, 0x1b,
Takashi Iwai7bba2152013-09-06 15:45:38 +02005721 snd_hda_gen_hp_automute);
5722 break;
Takashi Iwai5579cd62018-06-19 22:22:41 +02005723 case HDA_FIXUP_ACT_PROBE:
5724 spec->init_amp = ALC_INIT_DEFAULT;
5725 break;
Takashi Iwai7bba2152013-09-06 15:45:38 +02005726 case HDA_FIXUP_ACT_BUILD:
5727 /* this is a bit tricky; give more sane names for the main
5728 * (tablet) speaker and the dock speaker, respectively
5729 */
Takashi Iwai56798e62017-04-11 08:10:52 +02005730 rename_ctl(codec, "Speaker Playback Switch",
5731 "Dock Speaker Playback Switch");
5732 rename_ctl(codec, "Bass Speaker Playback Switch",
5733 "Speaker Playback Switch");
Takashi Iwai7bba2152013-09-06 15:45:38 +02005734 break;
5735 }
5736}
5737
David Henningsson338cae52013-10-07 10:39:59 +02005738static void alc290_fixup_mono_speakers(struct hda_codec *codec,
5739 const struct hda_fixup *fix, int action)
5740{
David Henningsson0f4881d2013-12-20 16:08:13 +01005741 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5742 /* DAC node 0x03 is giving mono output. We therefore want to
5743 make sure 0x14 (front speaker) and 0x15 (headphones) use the
5744 stereo DAC, while leaving 0x17 (bass speaker) for node 0x03. */
Michał Mirosławcaf3c042020-01-03 10:23:48 +01005745 static const hda_nid_t conn1[] = { 0x0c };
5746 snd_hda_override_conn_list(codec, 0x14, ARRAY_SIZE(conn1), conn1);
5747 snd_hda_override_conn_list(codec, 0x15, ARRAY_SIZE(conn1), conn1);
David Henningsson0f4881d2013-12-20 16:08:13 +01005748 }
David Henningsson338cae52013-10-07 10:39:59 +02005749}
5750
Hui Wangdd9aa332016-08-01 10:20:32 +08005751static void alc298_fixup_speaker_volume(struct hda_codec *codec,
5752 const struct hda_fixup *fix, int action)
5753{
5754 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5755 /* The speaker is routed to the Node 0x06 by a mistake, as a result
5756 we can't adjust the speaker's volume since this node does not has
5757 Amp-out capability. we change the speaker's route to:
5758 Node 0x02 (Audio Output) -> Node 0x0c (Audio Mixer) -> Node 0x17 (
5759 Pin Complex), since Node 0x02 has Amp-out caps, we can adjust
5760 speaker's volume now. */
5761
Michał Mirosławcaf3c042020-01-03 10:23:48 +01005762 static const hda_nid_t conn1[] = { 0x0c };
5763 snd_hda_override_conn_list(codec, 0x17, ARRAY_SIZE(conn1), conn1);
Hui Wangdd9aa332016-08-01 10:20:32 +08005764 }
5765}
5766
Takashi Iwaie312a862018-03-06 12:14:17 +01005767/* disable DAC3 (0x06) selection on NID 0x17 as it has no volume amp control */
5768static void alc295_fixup_disable_dac3(struct hda_codec *codec,
5769 const struct hda_fixup *fix, int action)
5770{
5771 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Michał Mirosławcaf3c042020-01-03 10:23:48 +01005772 static const hda_nid_t conn[] = { 0x02, 0x03 };
5773 snd_hda_override_conn_list(codec, 0x17, ARRAY_SIZE(conn), conn);
Takashi Iwaie312a862018-03-06 12:14:17 +01005774 }
5775}
5776
Jaroslav Kyselad2cd7952019-11-29 15:40:27 +01005777/* force NID 0x17 (Bass Speaker) to DAC1 to share it with the main speaker */
5778static void alc285_fixup_speaker2_to_dac1(struct hda_codec *codec,
5779 const struct hda_fixup *fix, int action)
5780{
5781 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Michał Mirosławcaf3c042020-01-03 10:23:48 +01005782 static const hda_nid_t conn[] = { 0x02 };
5783 snd_hda_override_conn_list(codec, 0x17, ARRAY_SIZE(conn), conn);
Jaroslav Kyselad2cd7952019-11-29 15:40:27 +01005784 }
5785}
5786
Keith Packard98973f22015-07-15 12:14:39 -07005787/* Hook to update amp GPIO4 for automute */
5788static void alc280_hp_gpio4_automute_hook(struct hda_codec *codec,
5789 struct hda_jack_callback *jack)
5790{
5791 struct alc_spec *spec = codec->spec;
5792
5793 snd_hda_gen_hp_automute(codec, jack);
5794 /* mute_led_polarity is set to 0, so we pass inverted value here */
5795 alc_update_gpio_led(codec, 0x10, !spec->gen.hp_jack_present);
5796}
5797
5798/* Manage GPIOs for HP EliteBook Folio 9480m.
5799 *
5800 * GPIO4 is the headphone amplifier power control
5801 * GPIO3 is the audio output mute indicator LED
5802 */
5803
5804static void alc280_fixup_hp_9480m(struct hda_codec *codec,
5805 const struct hda_fixup *fix,
5806 int action)
5807{
5808 struct alc_spec *spec = codec->spec;
Keith Packard98973f22015-07-15 12:14:39 -07005809
Takashi Iwai01e4a272018-06-19 22:47:30 +02005810 alc_fixup_hp_gpio_led(codec, action, 0x08, 0);
Keith Packard98973f22015-07-15 12:14:39 -07005811 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai01e4a272018-06-19 22:47:30 +02005812 /* amp at GPIO4; toggled via alc280_hp_gpio4_automute_hook() */
5813 spec->gpio_mask |= 0x10;
5814 spec->gpio_dir |= 0x10;
Keith Packard98973f22015-07-15 12:14:39 -07005815 spec->gen.hp_automute_hook = alc280_hp_gpio4_automute_hook;
Keith Packard98973f22015-07-15 12:14:39 -07005816 }
5817}
5818
Takashi Iwaiae065f12018-06-19 23:00:03 +02005819static void alc275_fixup_gpio4_off(struct hda_codec *codec,
5820 const struct hda_fixup *fix,
5821 int action)
5822{
5823 struct alc_spec *spec = codec->spec;
5824
5825 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5826 spec->gpio_mask |= 0x04;
5827 spec->gpio_dir |= 0x04;
5828 /* set data bit low */
5829 }
5830}
5831
Kailang Yangca169cc2017-04-25 16:17:40 +08005832static void alc233_alc662_fixup_lenovo_dual_codecs(struct hda_codec *codec,
5833 const struct hda_fixup *fix,
5834 int action)
5835{
5836 alc_fixup_dual_codecs(codec, fix, action);
5837 switch (action) {
5838 case HDA_FIXUP_ACT_PRE_PROBE:
5839 /* override card longname to provide a unique UCM profile */
5840 strcpy(codec->card->longname, "HDAudio-Lenovo-DualCodecs");
5841 break;
5842 case HDA_FIXUP_ACT_BUILD:
5843 /* rename Capture controls depending on the codec */
5844 rename_ctl(codec, "Capture Volume",
5845 codec->addr == 0 ?
5846 "Rear-Panel Capture Volume" :
5847 "Front-Panel Capture Volume");
5848 rename_ctl(codec, "Capture Switch",
5849 codec->addr == 0 ?
5850 "Rear-Panel Capture Switch" :
5851 "Front-Panel Capture Switch");
5852 break;
5853 }
5854}
5855
Kailang Yang92266652017-12-14 15:28:58 +08005856/* Forcibly assign NID 0x03 to HP/LO while NID 0x02 to SPK for EQ */
5857static void alc274_fixup_bind_dacs(struct hda_codec *codec,
5858 const struct hda_fixup *fix, int action)
5859{
5860 struct alc_spec *spec = codec->spec;
Michał Mirosławcaf3c042020-01-03 10:23:48 +01005861 static const hda_nid_t preferred_pairs[] = {
Kailang Yang92266652017-12-14 15:28:58 +08005862 0x21, 0x03, 0x1b, 0x03, 0x16, 0x02,
5863 0
5864 };
5865
5866 if (action != HDA_FIXUP_ACT_PRE_PROBE)
5867 return;
5868
5869 spec->gen.preferred_dacs = preferred_pairs;
Kailang Yang0700d3d2019-04-26 16:13:54 +08005870 spec->gen.auto_mute_via_amp = 1;
5871 codec->power_save_node = 0;
Kailang Yang92266652017-12-14 15:28:58 +08005872}
5873
Hui Wangc4cfcf62018-11-26 14:17:16 +08005874/* The DAC of NID 0x3 will introduce click/pop noise on headphones, so invalidate it */
5875static void alc285_fixup_invalidate_dacs(struct hda_codec *codec,
5876 const struct hda_fixup *fix, int action)
5877{
5878 if (action != HDA_FIXUP_ACT_PRE_PROBE)
5879 return;
5880
5881 snd_hda_override_wcaps(codec, 0x03, 0);
5882}
5883
Kailang Yang8983eb62019-04-03 15:31:49 +08005884static void alc295_fixup_chromebook(struct hda_codec *codec,
5885 const struct hda_fixup *fix, int action)
5886{
Kailang Yangd3ba58b2019-05-06 15:09:42 +08005887 struct alc_spec *spec = codec->spec;
5888
Kailang Yang8983eb62019-04-03 15:31:49 +08005889 switch (action) {
Kailang Yangd3ba58b2019-05-06 15:09:42 +08005890 case HDA_FIXUP_ACT_PRE_PROBE:
5891 spec->ultra_low_power = true;
5892 break;
Kailang Yang8983eb62019-04-03 15:31:49 +08005893 case HDA_FIXUP_ACT_INIT:
5894 switch (codec->core.vendor_id) {
5895 case 0x10ec0295:
5896 alc_update_coef_idx(codec, 0x4a, 0x8000, 1 << 15); /* Reset HP JD */
5897 alc_update_coef_idx(codec, 0x4a, 0x8000, 0 << 15);
5898 break;
5899 case 0x10ec0236:
5900 alc_update_coef_idx(codec, 0x1b, 0x8000, 1 << 15); /* Reset HP JD */
5901 alc_update_coef_idx(codec, 0x1b, 0x8000, 0 << 15);
5902 break;
5903 }
5904 break;
5905 }
5906}
5907
Kailang Yangd1dd4212019-01-09 17:05:24 +08005908static void alc_fixup_disable_mic_vref(struct hda_codec *codec,
5909 const struct hda_fixup *fix, int action)
5910{
5911 if (action == HDA_FIXUP_ACT_PRE_PROBE)
5912 snd_hda_codec_set_pin_target(codec, 0x19, PIN_VREFHIZ);
5913}
5914
Takashi Iwaib317b032014-01-08 11:44:21 +01005915/* for hda_fixup_thinkpad_acpi() */
5916#include "thinkpad_helper.c"
David Henningssonb67ae3f2013-11-05 13:11:37 +01005917
Takashi Iwaid5a6cab2018-06-13 12:43:10 +02005918static void alc_fixup_thinkpad_acpi(struct hda_codec *codec,
5919 const struct hda_fixup *fix, int action)
5920{
5921 alc_fixup_no_shutup(codec, fix, action); /* reduce click noise */
5922 hda_fixup_thinkpad_acpi(codec, fix, action);
5923}
5924
Tom Bridenbbf8ff62018-05-29 17:34:20 +01005925/* for alc295_fixup_hp_top_speakers */
5926#include "hp_x360_helper.c"
5927
Takashi Iwai1d045db2011-07-07 18:23:21 +02005928enum {
5929 ALC269_FIXUP_SONY_VAIO,
5930 ALC275_FIXUP_SONY_VAIO_GPIO2,
5931 ALC269_FIXUP_DELL_M101Z,
5932 ALC269_FIXUP_SKU_IGNORE,
5933 ALC269_FIXUP_ASUS_G73JW,
5934 ALC269_FIXUP_LENOVO_EAPD,
5935 ALC275_FIXUP_SONY_HWEQ,
Takashi Iwaie9bd7d52014-05-21 11:06:49 +02005936 ALC275_FIXUP_SONY_DISABLE_AAMIX,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005937 ALC271_FIXUP_DMIC,
Takashi Iwai017f2a12011-07-09 14:42:25 +02005938 ALC269_FIXUP_PCM_44K,
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02005939 ALC269_FIXUP_STEREO_DMIC,
David Henningsson7c478f02013-10-11 10:18:46 +02005940 ALC269_FIXUP_HEADSET_MIC,
Takashi Iwai24519912011-08-16 15:08:49 +02005941 ALC269_FIXUP_QUANTA_MUTE,
5942 ALC269_FIXUP_LIFEBOOK,
David Henningsson2041d562014-06-13 11:15:44 +02005943 ALC269_FIXUP_LIFEBOOK_EXTMIC,
Takashi Iwaicc7016a2015-04-08 20:47:55 +02005944 ALC269_FIXUP_LIFEBOOK_HP_PIN,
Takashi Iwai4df3fd12015-06-29 08:38:02 +02005945 ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT,
Jan-Marek Glogowskifdcc9682018-02-14 11:29:15 +01005946 ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC,
Takashi Iwaia4297b52011-08-23 18:40:12 +02005947 ALC269_FIXUP_AMIC,
5948 ALC269_FIXUP_DMIC,
5949 ALC269VB_FIXUP_AMIC,
5950 ALC269VB_FIXUP_DMIC,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01005951 ALC269_FIXUP_HP_MUTE_LED,
David Henningssond06ac142013-02-18 11:41:55 +01005952 ALC269_FIXUP_HP_MUTE_LED_MIC1,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01005953 ALC269_FIXUP_HP_MUTE_LED_MIC2,
Tom Briden7f783bd2017-03-25 10:12:01 +00005954 ALC269_FIXUP_HP_MUTE_LED_MIC3,
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01005955 ALC269_FIXUP_HP_GPIO_LED,
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08005956 ALC269_FIXUP_HP_GPIO_MIC1_LED,
5957 ALC269_FIXUP_HP_LINE1_MIC1_LED,
David Henningsson693b6132012-06-22 19:12:10 +02005958 ALC269_FIXUP_INV_DMIC,
David Henningsson108cc102012-07-20 10:37:25 +02005959 ALC269_FIXUP_LENOVO_DOCK,
Takashi Iwai9b745ab2014-03-07 08:37:19 +01005960 ALC269_FIXUP_NO_SHUTUP,
David Henningsson88cfcf82013-10-11 10:18:45 +02005961 ALC286_FIXUP_SONY_MIC_NO_PRESENCE,
David Henningsson108cc102012-07-20 10:37:25 +02005962 ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT,
David Henningsson73bdd592013-04-15 15:44:14 +02005963 ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
5964 ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
David Henningsson338cae52013-10-07 10:39:59 +02005965 ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
Kailang Yangfcc6c872017-06-29 15:21:27 +08005966 ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
David Henningsson73bdd592013-04-15 15:44:14 +02005967 ALC269_FIXUP_HEADSET_MODE,
5968 ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC,
Takashi Iwai78197172015-06-27 10:21:13 +02005969 ALC269_FIXUP_ASPIRE_HEADSET_MIC,
David Henningssond240d1d2013-04-15 12:50:02 +02005970 ALC269_FIXUP_ASUS_X101_FUNC,
5971 ALC269_FIXUP_ASUS_X101_VERB,
5972 ALC269_FIXUP_ASUS_X101,
Dylan Reid08a978d2012-11-18 22:56:40 -08005973 ALC271_FIXUP_AMIC_MIC2,
5974 ALC271_FIXUP_HP_GATE_MIC_JACK,
Oleksij Rempelb1e89722013-12-04 20:50:53 +01005975 ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572,
Dylan Reid42397002013-04-05 14:58:22 -07005976 ALC269_FIXUP_ACER_AC700,
David Henningsson3e0d6112013-04-22 14:30:14 +02005977 ALC269_FIXUP_LIMIT_INT_MIC_BOOST,
Oleksij Rempel2cede302013-11-27 17:12:03 +01005978 ALC269VB_FIXUP_ASUS_ZENBOOK,
Takashi Iwai23870832013-11-29 14:13:12 +01005979 ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A,
David Henningsson8e35cd42013-11-06 11:20:01 +01005980 ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED,
Anisse Astier02b504d2013-06-03 11:53:10 +02005981 ALC269VB_FIXUP_ORDISSIMO_EVE2,
Kailang Yangcd217a62013-08-22 10:15:24 +02005982 ALC283_FIXUP_CHROME_BOOK,
Kailang Yang0202e992013-12-02 15:20:15 +08005983 ALC283_FIXUP_SENSE_COMBO_JACK,
Takashi Iwai7bba2152013-09-06 15:45:38 +02005984 ALC282_FIXUP_ASUS_TX300,
Kailang Yang1bb3e062013-09-27 13:10:25 +02005985 ALC283_FIXUP_INT_MIC,
David Henningsson338cae52013-10-07 10:39:59 +02005986 ALC290_FIXUP_MONO_SPEAKERS,
David Henningsson0f4881d2013-12-20 16:08:13 +01005987 ALC290_FIXUP_MONO_SPEAKERS_HSJACK,
5988 ALC290_FIXUP_SUBWOOFER,
5989 ALC290_FIXUP_SUBWOOFER_HSJACK,
David Henningssonb67ae3f2013-11-05 13:11:37 +01005990 ALC269_FIXUP_THINKPAD_ACPI,
David Henningsson56f27012016-01-11 09:33:14 +01005991 ALC269_FIXUP_DMIC_THINKPAD_ACPI,
Chris Chiu5824ce82017-02-28 14:17:11 -06005992 ALC255_FIXUP_ACER_MIC_NO_PRESENCE,
Chris Chiu615966a2017-02-28 14:17:12 -06005993 ALC255_FIXUP_ASUS_MIC_NO_PRESENCE,
Kailang Yang9a22a8f52013-11-08 15:54:49 +08005994 ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Kailang Yang31278992014-03-03 15:27:22 +08005995 ALC255_FIXUP_DELL2_MIC_NO_PRESENCE,
Kailang Yang9a22a8f52013-11-08 15:54:49 +08005996 ALC255_FIXUP_HEADSET_MODE,
Kailang Yang31278992014-03-03 15:27:22 +08005997 ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC,
Kailang Yanga22aa262014-04-23 17:34:28 +08005998 ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
Takashi Iwai1c37c222014-05-06 17:34:42 +02005999 ALC292_FIXUP_TPT440_DOCK,
Takashi Iwai9a811232015-12-09 15:17:43 +01006000 ALC292_FIXUP_TPT440,
Anisse Astierabaa22742016-08-24 09:14:13 +02006001 ALC283_FIXUP_HEADSET_MIC,
Takashi Iwaib3802782018-11-26 17:47:46 +01006002 ALC255_FIXUP_MIC_MUTE_LED,
Takashi Iwai1a22e772014-08-27 08:19:05 +02006003 ALC282_FIXUP_ASPIRE_V5_PINS,
David Henningsson7a5255f2014-10-30 08:26:01 +01006004 ALC280_FIXUP_HP_GPIO4,
Kailang Yangeaa8e5e2014-11-21 15:49:11 +08006005 ALC286_FIXUP_HP_GPIO_LED,
David Henningsson33f4acd2015-01-07 15:50:13 +01006006 ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY,
TienFu Chenb4b33f92015-01-20 15:06:21 +01006007 ALC280_FIXUP_HP_DOCK_PINS,
Jaroslav Kysela04d54662017-03-09 13:29:13 +01006008 ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED,
Keith Packard98973f22015-07-15 12:14:39 -07006009 ALC280_FIXUP_HP_9480M,
Kailang Yange1e62b92015-04-08 16:01:22 +08006010 ALC288_FIXUP_DELL_HEADSET_MODE,
6011 ALC288_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang831bfdf92015-06-26 12:35:17 +08006012 ALC288_FIXUP_DELL_XPS_13,
6013 ALC288_FIXUP_DISABLE_AAMIX,
Takashi Iwai5fab5822020-01-05 09:11:19 +01006014 ALC292_FIXUP_DELL_E7X_AAMIX,
Takashi Iwai8b99aba2015-06-15 11:59:32 +02006015 ALC292_FIXUP_DELL_E7X,
6016 ALC292_FIXUP_DISABLE_AAMIX,
David Henningssonc04017e2015-12-15 14:44:03 +01006017 ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK,
James McDonnell54324222019-09-16 14:53:38 +00006018 ALC298_FIXUP_ALIENWARE_MIC_NO_PRESENCE,
Kailang Yang977e6272015-05-18 15:31:20 +08006019 ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang2f726ae2017-03-31 10:31:40 +08006020 ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE,
Kailang Yang6ed11312015-10-26 15:37:39 +08006021 ALC275_FIXUP_DELL_XPS,
Hui Wang23adc192015-12-08 12:27:18 +08006022 ALC293_FIXUP_LENOVO_SPK_NOISE,
Kailang3694cb22015-12-28 11:35:24 +08006023 ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY,
Kai-Heng Feng3b43b712016-02-25 15:19:38 +08006024 ALC255_FIXUP_DELL_SPK_NOISE,
Kailang Yangd1dd4212019-01-09 17:05:24 +08006025 ALC225_FIXUP_DISABLE_MIC_VREF,
David Henningsson2ae95572016-02-25 09:37:05 +01006026 ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
Takashi Iwaie312a862018-03-06 12:14:17 +01006027 ALC295_FIXUP_DISABLE_DAC3,
Jaroslav Kyselad2cd7952019-11-29 15:40:27 +01006028 ALC285_FIXUP_SPEAKER2_TO_DAC1,
Takashi Iwaif8839822016-02-25 14:31:59 +01006029 ALC280_FIXUP_HP_HEADSET_MIC,
Hui Wange549d192016-04-01 11:00:15 +08006030 ALC221_FIXUP_HP_FRONT_MIC,
Sven Eckelmannc636b952016-04-11 16:55:26 +02006031 ALC292_FIXUP_TPT460,
Hui Wangdd9aa332016-08-01 10:20:32 +08006032 ALC298_FIXUP_SPK_VOLUME,
Kai-Heng Fengfd06c772016-08-30 15:36:34 +08006033 ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER,
Gabriele Mazzotta823ff162016-12-24 19:50:01 +01006034 ALC269_FIXUP_ATIV_BOOK_8,
Kailang Yang9eb5d0e2017-01-17 15:40:25 +08006035 ALC221_FIXUP_HP_MIC_NO_PRESENCE,
Chris Chiuc1732ed2017-02-28 14:17:13 -06006036 ALC256_FIXUP_ASUS_HEADSET_MODE,
6037 ALC256_FIXUP_ASUS_MIC,
Chris Chiueeed4cd2017-02-28 14:17:15 -06006038 ALC256_FIXUP_ASUS_AIO_GPIO2,
Chris Chiu216d7ae2017-02-28 14:17:14 -06006039 ALC233_FIXUP_ASUS_MIC_NO_PRESENCE,
6040 ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE,
Kailang Yangca169cc2017-04-25 16:17:40 +08006041 ALC233_FIXUP_LENOVO_MULTI_CODECS,
Jian-Hong Panea5c7eb2019-04-01 11:25:05 +08006042 ALC233_FIXUP_ACER_HEADSET_MIC,
Hui Wangf33f79f2017-07-07 12:08:29 +08006043 ALC294_FIXUP_LENOVO_MIC_LOCATION,
Kailang Yang5f364132017-07-25 16:28:16 +08006044 ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE,
PeiSen Houb84e8432017-09-01 15:11:56 +08006045 ALC700_FIXUP_INTEL_REFERENCE,
Kailang Yang92266652017-12-14 15:28:58 +08006046 ALC274_FIXUP_DELL_BIND_DACS,
6047 ALC274_FIXUP_DELL_AIO_LINEOUT_VERB,
Kailang Yang61fcf8e2018-02-02 15:26:46 +08006048 ALC298_FIXUP_TPT470_DOCK,
Kailang Yangae104a22018-02-05 16:07:20 +08006049 ALC255_FIXUP_DUMMY_LINEOUT_VERB,
Kailang Yangf0ba9d62018-03-16 11:46:08 +08006050 ALC255_FIXUP_DELL_HEADSET_MIC,
Ayman Bagabas0fbf21c2019-05-23 05:30:11 -04006051 ALC256_FIXUP_HUAWEI_MACH_WX9_PINS,
Tomas Espeletaa2ef03f2019-08-09 16:37:54 +02006052 ALC298_FIXUP_HUAWEI_MBX_STEREO,
Tom Bridenbbf8ff62018-05-29 17:34:20 +01006053 ALC295_FIXUP_HP_X360,
Kailang Yang8a328ac2018-08-21 16:54:41 +08006054 ALC221_FIXUP_HP_HEADSET_MIC,
Hui Wangc4cfcf62018-11-26 14:17:16 +08006055 ALC285_FIXUP_LENOVO_HEADPHONE_NOISE,
Girija Kumar Kasinadhunie8ed64b2018-11-26 13:40:46 -05006056 ALC295_FIXUP_HP_AUTO_MUTE,
Chris Chiu33aaebd2018-12-05 14:48:53 +08006057 ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE,
Chris Chiud8ae4582018-12-07 17:17:11 +08006058 ALC294_FIXUP_ASUS_MIC,
Jian-Hong Pan4e051102018-12-07 17:17:12 +08006059 ALC294_FIXUP_ASUS_HEADSET_MIC,
6060 ALC294_FIXUP_ASUS_SPK,
Jeremy Soller89e3a562019-01-30 16:12:31 -07006061 ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE,
Hui Wangc8c6ee62019-02-14 11:41:33 +08006062 ALC285_FIXUP_LENOVO_PC_BEEP_IN_NOISE,
Jian-Hong Pancbc05fd2019-03-13 17:33:24 +08006063 ALC255_FIXUP_ACER_HEADSET_MIC,
Kailang Yang10f5b1b2019-02-21 16:10:22 +08006064 ALC295_FIXUP_CHROME_BOOK,
Kailang Yang8983eb62019-04-03 15:31:49 +08006065 ALC225_FIXUP_HEADSET_JACK,
Kailang Yang136824e2019-03-14 16:22:45 +08006066 ALC225_FIXUP_DELL_WYSE_AIO_MIC_NO_PRESENCE,
6067 ALC225_FIXUP_WYSE_AUTO_MUTE,
6068 ALC225_FIXUP_WYSE_DISABLE_MIC_VREF,
Jian-Hong Pan667a8f72019-03-15 17:51:09 +08006069 ALC286_FIXUP_ACER_AIO_HEADSET_MIC,
Daniel Drake8c8967a2019-10-17 16:15:01 +08006070 ALC256_FIXUP_ASUS_HEADSET_MIC,
Jian-Hong Pane1037352019-03-22 11:37:18 +08006071 ALC256_FIXUP_ASUS_MIC_NO_PRESENCE,
Bernhard Rosenkraenzere2a829b2019-03-05 00:38:19 +01006072 ALC299_FIXUP_PREDATOR_SPK,
Jan-Marek Glogowskibd9c10b2019-09-15 16:57:28 +02006073 ALC256_FIXUP_MEDION_HEADSET_NO_PRESENCE,
Kailang Yange79c2262019-12-19 14:12:15 +08006074 ALC289_FIXUP_DELL_SPK2,
6075 ALC289_FIXUP_DUAL_SPK,
Chris Chiu48e01502019-12-30 11:11:18 +08006076 ALC294_FIXUP_SPK2_TO_DAC1,
6077 ALC294_FIXUP_ASUS_DUAL_SPK,
Kailang Yang76f7dec2020-02-10 16:30:26 +08006078 ALC285_FIXUP_THINKPAD_HEADSET_JACK,
Jian-Hong Pan8b33a132020-02-25 15:29:21 +08006079 ALC294_FIXUP_ASUS_HPE,
Kai-Heng Fengf5a88b02020-03-27 12:46:25 +08006080 ALC285_FIXUP_HP_GPIO_LED,
Kailang Yang431e76c2020-04-07 14:40:20 +08006081 ALC285_FIXUP_HP_MUTE_LED,
Kailang Yang24164f42020-04-07 14:52:42 +08006082 ALC236_FIXUP_HP_MUTE_LED,
Takashi Iwai1d045db2011-07-07 18:23:21 +02006083};
6084
Takashi Iwai1727a772013-01-10 09:52:52 +01006085static const struct hda_fixup alc269_fixups[] = {
Takashi Iwai1d045db2011-07-07 18:23:21 +02006086 [ALC269_FIXUP_SONY_VAIO] = {
Takashi Iwaifd108212013-01-10 10:18:14 +01006087 .type = HDA_FIXUP_PINCTLS,
6088 .v.pins = (const struct hda_pintbl[]) {
6089 {0x19, PIN_VREFGRD},
Takashi Iwai1d045db2011-07-07 18:23:21 +02006090 {}
6091 }
6092 },
6093 [ALC275_FIXUP_SONY_VAIO_GPIO2] = {
Takashi Iwaiae065f12018-06-19 23:00:03 +02006094 .type = HDA_FIXUP_FUNC,
6095 .v.func = alc275_fixup_gpio4_off,
Takashi Iwai1d045db2011-07-07 18:23:21 +02006096 .chained = true,
6097 .chain_id = ALC269_FIXUP_SONY_VAIO
6098 },
6099 [ALC269_FIXUP_DELL_M101Z] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006100 .type = HDA_FIXUP_VERBS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02006101 .v.verbs = (const struct hda_verb[]) {
6102 /* Enables internal speaker */
6103 {0x20, AC_VERB_SET_COEF_INDEX, 13},
6104 {0x20, AC_VERB_SET_PROC_COEF, 0x4040},
6105 {}
6106 }
6107 },
6108 [ALC269_FIXUP_SKU_IGNORE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006109 .type = HDA_FIXUP_FUNC,
Takashi Iwai23d30f22012-05-07 17:17:32 +02006110 .v.func = alc_fixup_sku_ignore,
Takashi Iwai1d045db2011-07-07 18:23:21 +02006111 },
6112 [ALC269_FIXUP_ASUS_G73JW] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006113 .type = HDA_FIXUP_PINS,
6114 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02006115 { 0x17, 0x99130111 }, /* subwoofer */
6116 { }
6117 }
6118 },
6119 [ALC269_FIXUP_LENOVO_EAPD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006120 .type = HDA_FIXUP_VERBS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02006121 .v.verbs = (const struct hda_verb[]) {
6122 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
6123 {}
6124 }
6125 },
6126 [ALC275_FIXUP_SONY_HWEQ] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006127 .type = HDA_FIXUP_FUNC,
Takashi Iwai1d045db2011-07-07 18:23:21 +02006128 .v.func = alc269_fixup_hweq,
6129 .chained = true,
6130 .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2
6131 },
Takashi Iwaie9bd7d52014-05-21 11:06:49 +02006132 [ALC275_FIXUP_SONY_DISABLE_AAMIX] = {
6133 .type = HDA_FIXUP_FUNC,
6134 .v.func = alc_fixup_disable_aamix,
6135 .chained = true,
6136 .chain_id = ALC269_FIXUP_SONY_VAIO
6137 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02006138 [ALC271_FIXUP_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006139 .type = HDA_FIXUP_FUNC,
Takashi Iwai1d045db2011-07-07 18:23:21 +02006140 .v.func = alc271_fixup_dmic,
6141 },
Takashi Iwai017f2a12011-07-09 14:42:25 +02006142 [ALC269_FIXUP_PCM_44K] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006143 .type = HDA_FIXUP_FUNC,
Takashi Iwai017f2a12011-07-09 14:42:25 +02006144 .v.func = alc269_fixup_pcm_44k,
David Henningsson012e7eb2012-08-08 08:43:37 +02006145 .chained = true,
6146 .chain_id = ALC269_FIXUP_QUANTA_MUTE
Takashi Iwai017f2a12011-07-09 14:42:25 +02006147 },
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02006148 [ALC269_FIXUP_STEREO_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006149 .type = HDA_FIXUP_FUNC,
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02006150 .v.func = alc269_fixup_stereo_dmic,
6151 },
David Henningsson7c478f02013-10-11 10:18:46 +02006152 [ALC269_FIXUP_HEADSET_MIC] = {
6153 .type = HDA_FIXUP_FUNC,
6154 .v.func = alc269_fixup_headset_mic,
6155 },
Takashi Iwai24519912011-08-16 15:08:49 +02006156 [ALC269_FIXUP_QUANTA_MUTE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006157 .type = HDA_FIXUP_FUNC,
Takashi Iwai24519912011-08-16 15:08:49 +02006158 .v.func = alc269_fixup_quanta_mute,
6159 },
6160 [ALC269_FIXUP_LIFEBOOK] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006161 .type = HDA_FIXUP_PINS,
6162 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai24519912011-08-16 15:08:49 +02006163 { 0x1a, 0x2101103f }, /* dock line-out */
6164 { 0x1b, 0x23a11040 }, /* dock mic-in */
6165 { }
6166 },
6167 .chained = true,
6168 .chain_id = ALC269_FIXUP_QUANTA_MUTE
6169 },
David Henningsson2041d562014-06-13 11:15:44 +02006170 [ALC269_FIXUP_LIFEBOOK_EXTMIC] = {
6171 .type = HDA_FIXUP_PINS,
6172 .v.pins = (const struct hda_pintbl[]) {
6173 { 0x19, 0x01a1903c }, /* headset mic, with jack detect */
6174 { }
6175 },
6176 },
Takashi Iwaicc7016a2015-04-08 20:47:55 +02006177 [ALC269_FIXUP_LIFEBOOK_HP_PIN] = {
6178 .type = HDA_FIXUP_PINS,
6179 .v.pins = (const struct hda_pintbl[]) {
6180 { 0x21, 0x0221102f }, /* HP out */
6181 { }
6182 },
6183 },
Takashi Iwai4df3fd12015-06-29 08:38:02 +02006184 [ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT] = {
6185 .type = HDA_FIXUP_FUNC,
6186 .v.func = alc269_fixup_pincfg_no_hp_to_lineout,
6187 },
Jan-Marek Glogowskifdcc9682018-02-14 11:29:15 +01006188 [ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC] = {
6189 .type = HDA_FIXUP_FUNC,
6190 .v.func = alc269_fixup_pincfg_U7x7_headset_mic,
6191 },
Takashi Iwaia4297b52011-08-23 18:40:12 +02006192 [ALC269_FIXUP_AMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006193 .type = HDA_FIXUP_PINS,
6194 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaia4297b52011-08-23 18:40:12 +02006195 { 0x14, 0x99130110 }, /* speaker */
6196 { 0x15, 0x0121401f }, /* HP out */
6197 { 0x18, 0x01a19c20 }, /* mic */
6198 { 0x19, 0x99a3092f }, /* int-mic */
6199 { }
6200 },
6201 },
6202 [ALC269_FIXUP_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006203 .type = HDA_FIXUP_PINS,
6204 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaia4297b52011-08-23 18:40:12 +02006205 { 0x12, 0x99a3092f }, /* int-mic */
6206 { 0x14, 0x99130110 }, /* speaker */
6207 { 0x15, 0x0121401f }, /* HP out */
6208 { 0x18, 0x01a19c20 }, /* mic */
6209 { }
6210 },
6211 },
6212 [ALC269VB_FIXUP_AMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006213 .type = HDA_FIXUP_PINS,
6214 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaia4297b52011-08-23 18:40:12 +02006215 { 0x14, 0x99130110 }, /* speaker */
6216 { 0x18, 0x01a19c20 }, /* mic */
6217 { 0x19, 0x99a3092f }, /* int-mic */
6218 { 0x21, 0x0121401f }, /* HP out */
6219 { }
6220 },
6221 },
David Henningsson2267ea92012-01-03 08:45:56 +01006222 [ALC269VB_FIXUP_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006223 .type = HDA_FIXUP_PINS,
6224 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaia4297b52011-08-23 18:40:12 +02006225 { 0x12, 0x99a3092f }, /* int-mic */
6226 { 0x14, 0x99130110 }, /* speaker */
6227 { 0x18, 0x01a19c20 }, /* mic */
6228 { 0x21, 0x0121401f }, /* HP out */
6229 { }
6230 },
6231 },
Takashi Iwai08fb0d02013-01-10 17:33:58 +01006232 [ALC269_FIXUP_HP_MUTE_LED] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006233 .type = HDA_FIXUP_FUNC,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01006234 .v.func = alc269_fixup_hp_mute_led,
David Henningsson6d3cd5d2013-01-07 12:03:47 +01006235 },
David Henningssond06ac142013-02-18 11:41:55 +01006236 [ALC269_FIXUP_HP_MUTE_LED_MIC1] = {
6237 .type = HDA_FIXUP_FUNC,
6238 .v.func = alc269_fixup_hp_mute_led_mic1,
6239 },
Takashi Iwai08fb0d02013-01-10 17:33:58 +01006240 [ALC269_FIXUP_HP_MUTE_LED_MIC2] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006241 .type = HDA_FIXUP_FUNC,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01006242 .v.func = alc269_fixup_hp_mute_led_mic2,
Takashi Iwai420b0fe2012-03-12 12:35:27 +01006243 },
Tom Briden7f783bd2017-03-25 10:12:01 +00006244 [ALC269_FIXUP_HP_MUTE_LED_MIC3] = {
6245 .type = HDA_FIXUP_FUNC,
6246 .v.func = alc269_fixup_hp_mute_led_mic3,
Girija Kumar Kasinadhunie8ed64b2018-11-26 13:40:46 -05006247 .chained = true,
6248 .chain_id = ALC295_FIXUP_HP_AUTO_MUTE
Tom Briden7f783bd2017-03-25 10:12:01 +00006249 },
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01006250 [ALC269_FIXUP_HP_GPIO_LED] = {
6251 .type = HDA_FIXUP_FUNC,
6252 .v.func = alc269_fixup_hp_gpio_led,
6253 },
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08006254 [ALC269_FIXUP_HP_GPIO_MIC1_LED] = {
6255 .type = HDA_FIXUP_FUNC,
6256 .v.func = alc269_fixup_hp_gpio_mic1_led,
6257 },
6258 [ALC269_FIXUP_HP_LINE1_MIC1_LED] = {
6259 .type = HDA_FIXUP_FUNC,
6260 .v.func = alc269_fixup_hp_line1_mic1_led,
6261 },
David Henningsson693b6132012-06-22 19:12:10 +02006262 [ALC269_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006263 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02006264 .v.func = alc_fixup_inv_dmic,
David Henningsson693b6132012-06-22 19:12:10 +02006265 },
Takashi Iwai9b745ab2014-03-07 08:37:19 +01006266 [ALC269_FIXUP_NO_SHUTUP] = {
6267 .type = HDA_FIXUP_FUNC,
6268 .v.func = alc_fixup_no_shutup,
6269 },
David Henningsson108cc102012-07-20 10:37:25 +02006270 [ALC269_FIXUP_LENOVO_DOCK] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006271 .type = HDA_FIXUP_PINS,
6272 .v.pins = (const struct hda_pintbl[]) {
David Henningsson108cc102012-07-20 10:37:25 +02006273 { 0x19, 0x23a11040 }, /* dock mic */
6274 { 0x1b, 0x2121103f }, /* dock headphone */
6275 { }
6276 },
6277 .chained = true,
6278 .chain_id = ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT
6279 },
6280 [ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006281 .type = HDA_FIXUP_FUNC,
David Henningsson108cc102012-07-20 10:37:25 +02006282 .v.func = alc269_fixup_pincfg_no_hp_to_lineout,
David Henningsson52129002013-11-19 10:25:53 +01006283 .chained = true,
6284 .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
David Henningsson108cc102012-07-20 10:37:25 +02006285 },
David Henningsson73bdd592013-04-15 15:44:14 +02006286 [ALC269_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6287 .type = HDA_FIXUP_PINS,
6288 .v.pins = (const struct hda_pintbl[]) {
6289 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6290 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6291 { }
6292 },
6293 .chained = true,
6294 .chain_id = ALC269_FIXUP_HEADSET_MODE
6295 },
6296 [ALC269_FIXUP_DELL2_MIC_NO_PRESENCE] = {
6297 .type = HDA_FIXUP_PINS,
6298 .v.pins = (const struct hda_pintbl[]) {
6299 { 0x16, 0x21014020 }, /* dock line out */
6300 { 0x19, 0x21a19030 }, /* dock mic */
6301 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6302 { }
6303 },
6304 .chained = true,
6305 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
6306 },
David Henningsson338cae52013-10-07 10:39:59 +02006307 [ALC269_FIXUP_DELL3_MIC_NO_PRESENCE] = {
6308 .type = HDA_FIXUP_PINS,
6309 .v.pins = (const struct hda_pintbl[]) {
6310 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6311 { }
6312 },
6313 .chained = true,
6314 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
6315 },
Kailang Yangfcc6c872017-06-29 15:21:27 +08006316 [ALC269_FIXUP_DELL4_MIC_NO_PRESENCE] = {
6317 .type = HDA_FIXUP_PINS,
6318 .v.pins = (const struct hda_pintbl[]) {
6319 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6320 { 0x1b, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6321 { }
6322 },
6323 .chained = true,
6324 .chain_id = ALC269_FIXUP_HEADSET_MODE
6325 },
David Henningsson73bdd592013-04-15 15:44:14 +02006326 [ALC269_FIXUP_HEADSET_MODE] = {
6327 .type = HDA_FIXUP_FUNC,
6328 .v.func = alc_fixup_headset_mode,
Hui Wang6676f302014-11-18 17:57:41 +08006329 .chained = true,
Takashi Iwaib3802782018-11-26 17:47:46 +01006330 .chain_id = ALC255_FIXUP_MIC_MUTE_LED
David Henningsson73bdd592013-04-15 15:44:14 +02006331 },
6332 [ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC] = {
6333 .type = HDA_FIXUP_FUNC,
6334 .v.func = alc_fixup_headset_mode_no_hp_mic,
6335 },
Takashi Iwai78197172015-06-27 10:21:13 +02006336 [ALC269_FIXUP_ASPIRE_HEADSET_MIC] = {
6337 .type = HDA_FIXUP_PINS,
6338 .v.pins = (const struct hda_pintbl[]) {
6339 { 0x19, 0x01a1913c }, /* headset mic w/o jack detect */
6340 { }
6341 },
6342 .chained = true,
6343 .chain_id = ALC269_FIXUP_HEADSET_MODE,
6344 },
David Henningsson88cfcf82013-10-11 10:18:45 +02006345 [ALC286_FIXUP_SONY_MIC_NO_PRESENCE] = {
6346 .type = HDA_FIXUP_PINS,
6347 .v.pins = (const struct hda_pintbl[]) {
6348 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6349 { }
6350 },
David Henningssonfbc78ad2013-10-11 13:46:04 +02006351 .chained = true,
6352 .chain_id = ALC269_FIXUP_HEADSET_MIC
David Henningsson88cfcf82013-10-11 10:18:45 +02006353 },
Ayman Bagabas0fbf21c2019-05-23 05:30:11 -04006354 [ALC256_FIXUP_HUAWEI_MACH_WX9_PINS] = {
Ayman Bagabas8ac51bb2018-12-12 18:07:57 -05006355 .type = HDA_FIXUP_PINS,
6356 .v.pins = (const struct hda_pintbl[]) {
6357 {0x12, 0x90a60130},
6358 {0x13, 0x40000000},
6359 {0x14, 0x90170110},
6360 {0x18, 0x411111f0},
6361 {0x19, 0x04a11040},
6362 {0x1a, 0x411111f0},
6363 {0x1b, 0x90170112},
6364 {0x1d, 0x40759a05},
6365 {0x1e, 0x411111f0},
6366 {0x21, 0x04211020},
6367 { }
6368 },
Ayman Bagabase2744fd2018-12-12 18:07:59 -05006369 .chained = true,
6370 .chain_id = ALC255_FIXUP_MIC_MUTE_LED
Ayman Bagabas8ac51bb2018-12-12 18:07:57 -05006371 },
Tomas Espeletaa2ef03f2019-08-09 16:37:54 +02006372 [ALC298_FIXUP_HUAWEI_MBX_STEREO] = {
6373 .type = HDA_FIXUP_FUNC,
6374 .v.func = alc298_fixup_huawei_mbx_stereo,
6375 .chained = true,
6376 .chain_id = ALC255_FIXUP_MIC_MUTE_LED
6377 },
David Henningssond240d1d2013-04-15 12:50:02 +02006378 [ALC269_FIXUP_ASUS_X101_FUNC] = {
6379 .type = HDA_FIXUP_FUNC,
6380 .v.func = alc269_fixup_x101_headset_mic,
6381 },
6382 [ALC269_FIXUP_ASUS_X101_VERB] = {
6383 .type = HDA_FIXUP_VERBS,
6384 .v.verbs = (const struct hda_verb[]) {
6385 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6386 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
6387 {0x20, AC_VERB_SET_PROC_COEF, 0x0310},
6388 { }
6389 },
6390 .chained = true,
6391 .chain_id = ALC269_FIXUP_ASUS_X101_FUNC
6392 },
6393 [ALC269_FIXUP_ASUS_X101] = {
6394 .type = HDA_FIXUP_PINS,
6395 .v.pins = (const struct hda_pintbl[]) {
6396 { 0x18, 0x04a1182c }, /* Headset mic */
6397 { }
6398 },
6399 .chained = true,
6400 .chain_id = ALC269_FIXUP_ASUS_X101_VERB
6401 },
Dylan Reid08a978d2012-11-18 22:56:40 -08006402 [ALC271_FIXUP_AMIC_MIC2] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006403 .type = HDA_FIXUP_PINS,
6404 .v.pins = (const struct hda_pintbl[]) {
Dylan Reid08a978d2012-11-18 22:56:40 -08006405 { 0x14, 0x99130110 }, /* speaker */
6406 { 0x19, 0x01a19c20 }, /* mic */
6407 { 0x1b, 0x99a7012f }, /* int-mic */
6408 { 0x21, 0x0121401f }, /* HP out */
6409 { }
6410 },
6411 },
6412 [ALC271_FIXUP_HP_GATE_MIC_JACK] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006413 .type = HDA_FIXUP_FUNC,
Dylan Reid08a978d2012-11-18 22:56:40 -08006414 .v.func = alc271_hp_gate_mic_jack,
6415 .chained = true,
6416 .chain_id = ALC271_FIXUP_AMIC_MIC2,
6417 },
Oleksij Rempelb1e89722013-12-04 20:50:53 +01006418 [ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572] = {
6419 .type = HDA_FIXUP_FUNC,
6420 .v.func = alc269_fixup_limit_int_mic_boost,
6421 .chained = true,
6422 .chain_id = ALC271_FIXUP_HP_GATE_MIC_JACK,
6423 },
Dylan Reid42397002013-04-05 14:58:22 -07006424 [ALC269_FIXUP_ACER_AC700] = {
6425 .type = HDA_FIXUP_PINS,
6426 .v.pins = (const struct hda_pintbl[]) {
6427 { 0x12, 0x99a3092f }, /* int-mic */
6428 { 0x14, 0x99130110 }, /* speaker */
6429 { 0x18, 0x03a11c20 }, /* mic */
6430 { 0x1e, 0x0346101e }, /* SPDIF1 */
6431 { 0x21, 0x0321101f }, /* HP out */
6432 { }
6433 },
6434 .chained = true,
6435 .chain_id = ALC271_FIXUP_DMIC,
6436 },
David Henningsson3e0d6112013-04-22 14:30:14 +02006437 [ALC269_FIXUP_LIMIT_INT_MIC_BOOST] = {
6438 .type = HDA_FIXUP_FUNC,
6439 .v.func = alc269_fixup_limit_int_mic_boost,
David Henningsson27937692013-11-18 11:51:47 +01006440 .chained = true,
6441 .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
David Henningsson3e0d6112013-04-22 14:30:14 +02006442 },
Oleksij Rempel2cede302013-11-27 17:12:03 +01006443 [ALC269VB_FIXUP_ASUS_ZENBOOK] = {
6444 .type = HDA_FIXUP_FUNC,
6445 .v.func = alc269_fixup_limit_int_mic_boost,
6446 .chained = true,
6447 .chain_id = ALC269VB_FIXUP_DMIC,
6448 },
Takashi Iwai23870832013-11-29 14:13:12 +01006449 [ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A] = {
6450 .type = HDA_FIXUP_VERBS,
6451 .v.verbs = (const struct hda_verb[]) {
6452 /* class-D output amp +5dB */
6453 { 0x20, AC_VERB_SET_COEF_INDEX, 0x12 },
6454 { 0x20, AC_VERB_SET_PROC_COEF, 0x2800 },
6455 {}
6456 },
6457 .chained = true,
6458 .chain_id = ALC269VB_FIXUP_ASUS_ZENBOOK,
6459 },
David Henningsson8e35cd42013-11-06 11:20:01 +01006460 [ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED] = {
6461 .type = HDA_FIXUP_FUNC,
6462 .v.func = alc269_fixup_limit_int_mic_boost,
6463 .chained = true,
6464 .chain_id = ALC269_FIXUP_HP_MUTE_LED_MIC1,
6465 },
Anisse Astier02b504d2013-06-03 11:53:10 +02006466 [ALC269VB_FIXUP_ORDISSIMO_EVE2] = {
6467 .type = HDA_FIXUP_PINS,
6468 .v.pins = (const struct hda_pintbl[]) {
6469 { 0x12, 0x99a3092f }, /* int-mic */
6470 { 0x18, 0x03a11d20 }, /* mic */
6471 { 0x19, 0x411111f0 }, /* Unused bogus pin */
6472 { }
6473 },
6474 },
Kailang Yangcd217a62013-08-22 10:15:24 +02006475 [ALC283_FIXUP_CHROME_BOOK] = {
6476 .type = HDA_FIXUP_FUNC,
6477 .v.func = alc283_fixup_chromebook,
6478 },
Kailang Yang0202e992013-12-02 15:20:15 +08006479 [ALC283_FIXUP_SENSE_COMBO_JACK] = {
6480 .type = HDA_FIXUP_FUNC,
6481 .v.func = alc283_fixup_sense_combo_jack,
6482 .chained = true,
6483 .chain_id = ALC283_FIXUP_CHROME_BOOK,
6484 },
Takashi Iwai7bba2152013-09-06 15:45:38 +02006485 [ALC282_FIXUP_ASUS_TX300] = {
6486 .type = HDA_FIXUP_FUNC,
6487 .v.func = alc282_fixup_asus_tx300,
6488 },
Kailang Yang1bb3e062013-09-27 13:10:25 +02006489 [ALC283_FIXUP_INT_MIC] = {
6490 .type = HDA_FIXUP_VERBS,
6491 .v.verbs = (const struct hda_verb[]) {
6492 {0x20, AC_VERB_SET_COEF_INDEX, 0x1a},
6493 {0x20, AC_VERB_SET_PROC_COEF, 0x0011},
6494 { }
6495 },
6496 .chained = true,
6497 .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST
6498 },
David Henningsson0f4881d2013-12-20 16:08:13 +01006499 [ALC290_FIXUP_SUBWOOFER_HSJACK] = {
6500 .type = HDA_FIXUP_PINS,
6501 .v.pins = (const struct hda_pintbl[]) {
6502 { 0x17, 0x90170112 }, /* subwoofer */
6503 { }
6504 },
6505 .chained = true,
6506 .chain_id = ALC290_FIXUP_MONO_SPEAKERS_HSJACK,
6507 },
6508 [ALC290_FIXUP_SUBWOOFER] = {
6509 .type = HDA_FIXUP_PINS,
6510 .v.pins = (const struct hda_pintbl[]) {
6511 { 0x17, 0x90170112 }, /* subwoofer */
6512 { }
6513 },
6514 .chained = true,
6515 .chain_id = ALC290_FIXUP_MONO_SPEAKERS,
6516 },
David Henningsson338cae52013-10-07 10:39:59 +02006517 [ALC290_FIXUP_MONO_SPEAKERS] = {
6518 .type = HDA_FIXUP_FUNC,
6519 .v.func = alc290_fixup_mono_speakers,
David Henningsson0f4881d2013-12-20 16:08:13 +01006520 },
6521 [ALC290_FIXUP_MONO_SPEAKERS_HSJACK] = {
6522 .type = HDA_FIXUP_FUNC,
6523 .v.func = alc290_fixup_mono_speakers,
David Henningsson338cae52013-10-07 10:39:59 +02006524 .chained = true,
6525 .chain_id = ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
6526 },
David Henningssonb67ae3f2013-11-05 13:11:37 +01006527 [ALC269_FIXUP_THINKPAD_ACPI] = {
6528 .type = HDA_FIXUP_FUNC,
Takashi Iwaid5a6cab2018-06-13 12:43:10 +02006529 .v.func = alc_fixup_thinkpad_acpi,
Takashi Iwai09da1112016-09-08 12:15:02 +02006530 .chained = true,
6531 .chain_id = ALC269_FIXUP_SKU_IGNORE,
David Henningssonb67ae3f2013-11-05 13:11:37 +01006532 },
David Henningsson56f27012016-01-11 09:33:14 +01006533 [ALC269_FIXUP_DMIC_THINKPAD_ACPI] = {
6534 .type = HDA_FIXUP_FUNC,
6535 .v.func = alc_fixup_inv_dmic,
6536 .chained = true,
6537 .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
6538 },
Chris Chiu5824ce82017-02-28 14:17:11 -06006539 [ALC255_FIXUP_ACER_MIC_NO_PRESENCE] = {
Hui Wang17d30462019-06-14 16:44:12 +08006540 .type = HDA_FIXUP_PINS,
6541 .v.pins = (const struct hda_pintbl[]) {
6542 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6543 { }
Chris Chiu5824ce82017-02-28 14:17:11 -06006544 },
6545 .chained = true,
Hui Wang17d30462019-06-14 16:44:12 +08006546 .chain_id = ALC255_FIXUP_HEADSET_MODE
Chris Chiu5824ce82017-02-28 14:17:11 -06006547 },
Chris Chiu615966a2017-02-28 14:17:12 -06006548 [ALC255_FIXUP_ASUS_MIC_NO_PRESENCE] = {
6549 .type = HDA_FIXUP_PINS,
6550 .v.pins = (const struct hda_pintbl[]) {
6551 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6552 { }
6553 },
6554 .chained = true,
6555 .chain_id = ALC255_FIXUP_HEADSET_MODE
6556 },
Kailang Yang9a22a8f52013-11-08 15:54:49 +08006557 [ALC255_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6558 .type = HDA_FIXUP_PINS,
6559 .v.pins = (const struct hda_pintbl[]) {
6560 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6561 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6562 { }
6563 },
6564 .chained = true,
6565 .chain_id = ALC255_FIXUP_HEADSET_MODE
6566 },
Kailang Yang31278992014-03-03 15:27:22 +08006567 [ALC255_FIXUP_DELL2_MIC_NO_PRESENCE] = {
6568 .type = HDA_FIXUP_PINS,
6569 .v.pins = (const struct hda_pintbl[]) {
6570 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6571 { }
6572 },
6573 .chained = true,
6574 .chain_id = ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC
6575 },
Kailang Yang9a22a8f52013-11-08 15:54:49 +08006576 [ALC255_FIXUP_HEADSET_MODE] = {
6577 .type = HDA_FIXUP_FUNC,
6578 .v.func = alc_fixup_headset_mode_alc255,
Hui Wang4a83d422014-11-18 17:57:40 +08006579 .chained = true,
Takashi Iwaib3802782018-11-26 17:47:46 +01006580 .chain_id = ALC255_FIXUP_MIC_MUTE_LED
Kailang Yang9a22a8f52013-11-08 15:54:49 +08006581 },
Kailang Yang31278992014-03-03 15:27:22 +08006582 [ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC] = {
6583 .type = HDA_FIXUP_FUNC,
6584 .v.func = alc_fixup_headset_mode_alc255_no_hp_mic,
6585 },
Kailang Yanga22aa262014-04-23 17:34:28 +08006586 [ALC293_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6587 .type = HDA_FIXUP_PINS,
6588 .v.pins = (const struct hda_pintbl[]) {
6589 { 0x18, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6590 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6591 { }
6592 },
6593 .chained = true,
6594 .chain_id = ALC269_FIXUP_HEADSET_MODE
6595 },
Takashi Iwai1c37c222014-05-06 17:34:42 +02006596 [ALC292_FIXUP_TPT440_DOCK] = {
David Henningssonec56af62015-06-24 10:46:33 +02006597 .type = HDA_FIXUP_FUNC,
Takashi Iwai7f57d802015-09-24 17:36:51 +02006598 .v.func = alc_fixup_tpt440_dock,
Takashi Iwai1c37c222014-05-06 17:34:42 +02006599 .chained = true,
6600 .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST
6601 },
Takashi Iwai9a811232015-12-09 15:17:43 +01006602 [ALC292_FIXUP_TPT440] = {
6603 .type = HDA_FIXUP_FUNC,
Takashi Iwai157f0b72015-12-10 23:30:43 +01006604 .v.func = alc_fixup_disable_aamix,
Takashi Iwai9a811232015-12-09 15:17:43 +01006605 .chained = true,
6606 .chain_id = ALC292_FIXUP_TPT440_DOCK,
6607 },
Anisse Astierabaa22742016-08-24 09:14:13 +02006608 [ALC283_FIXUP_HEADSET_MIC] = {
Daniel Drake9dc12862014-07-22 10:58:29 +01006609 .type = HDA_FIXUP_PINS,
6610 .v.pins = (const struct hda_pintbl[]) {
6611 { 0x19, 0x04a110f0 },
6612 { },
6613 },
6614 },
Takashi Iwaib3802782018-11-26 17:47:46 +01006615 [ALC255_FIXUP_MIC_MUTE_LED] = {
Hui Wang00ef9942014-07-31 11:52:38 +08006616 .type = HDA_FIXUP_FUNC,
Takashi Iwaib3802782018-11-26 17:47:46 +01006617 .v.func = snd_hda_gen_fixup_micmute_led,
Hui Wang00ef9942014-07-31 11:52:38 +08006618 },
Takashi Iwai1a22e772014-08-27 08:19:05 +02006619 [ALC282_FIXUP_ASPIRE_V5_PINS] = {
6620 .type = HDA_FIXUP_PINS,
6621 .v.pins = (const struct hda_pintbl[]) {
6622 { 0x12, 0x90a60130 },
6623 { 0x14, 0x90170110 },
6624 { 0x17, 0x40000008 },
6625 { 0x18, 0x411111f0 },
Mateusz Sylwestrzak04206942015-07-19 17:38:56 +02006626 { 0x19, 0x01a1913c },
Takashi Iwai1a22e772014-08-27 08:19:05 +02006627 { 0x1a, 0x411111f0 },
6628 { 0x1b, 0x411111f0 },
6629 { 0x1d, 0x40f89b2d },
6630 { 0x1e, 0x411111f0 },
6631 { 0x21, 0x0321101f },
6632 { },
6633 },
6634 },
David Henningsson7a5255f2014-10-30 08:26:01 +01006635 [ALC280_FIXUP_HP_GPIO4] = {
6636 .type = HDA_FIXUP_FUNC,
6637 .v.func = alc280_fixup_hp_gpio4,
6638 },
Kailang Yangeaa8e5e2014-11-21 15:49:11 +08006639 [ALC286_FIXUP_HP_GPIO_LED] = {
6640 .type = HDA_FIXUP_FUNC,
6641 .v.func = alc286_fixup_hp_gpio_led,
6642 },
David Henningsson33f4acd2015-01-07 15:50:13 +01006643 [ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY] = {
6644 .type = HDA_FIXUP_FUNC,
6645 .v.func = alc280_fixup_hp_gpio2_mic_hotkey,
6646 },
TienFu Chenb4b33f92015-01-20 15:06:21 +01006647 [ALC280_FIXUP_HP_DOCK_PINS] = {
6648 .type = HDA_FIXUP_PINS,
6649 .v.pins = (const struct hda_pintbl[]) {
6650 { 0x1b, 0x21011020 }, /* line-out */
6651 { 0x1a, 0x01a1903c }, /* headset mic */
6652 { 0x18, 0x2181103f }, /* line-in */
6653 { },
6654 },
6655 .chained = true,
6656 .chain_id = ALC280_FIXUP_HP_GPIO4
6657 },
Jaroslav Kysela04d54662017-03-09 13:29:13 +01006658 [ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED] = {
6659 .type = HDA_FIXUP_PINS,
6660 .v.pins = (const struct hda_pintbl[]) {
6661 { 0x1b, 0x21011020 }, /* line-out */
6662 { 0x18, 0x2181103f }, /* line-in */
6663 { },
6664 },
6665 .chained = true,
6666 .chain_id = ALC269_FIXUP_HP_GPIO_MIC1_LED
6667 },
Keith Packard98973f22015-07-15 12:14:39 -07006668 [ALC280_FIXUP_HP_9480M] = {
6669 .type = HDA_FIXUP_FUNC,
6670 .v.func = alc280_fixup_hp_9480m,
6671 },
Kailang Yange1e62b92015-04-08 16:01:22 +08006672 [ALC288_FIXUP_DELL_HEADSET_MODE] = {
6673 .type = HDA_FIXUP_FUNC,
6674 .v.func = alc_fixup_headset_mode_dell_alc288,
6675 .chained = true,
Takashi Iwaib3802782018-11-26 17:47:46 +01006676 .chain_id = ALC255_FIXUP_MIC_MUTE_LED
Kailang Yange1e62b92015-04-08 16:01:22 +08006677 },
6678 [ALC288_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6679 .type = HDA_FIXUP_PINS,
6680 .v.pins = (const struct hda_pintbl[]) {
6681 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6682 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6683 { }
6684 },
6685 .chained = true,
6686 .chain_id = ALC288_FIXUP_DELL_HEADSET_MODE
6687 },
Hui Wang831bfdf92015-06-26 12:35:17 +08006688 [ALC288_FIXUP_DISABLE_AAMIX] = {
6689 .type = HDA_FIXUP_FUNC,
6690 .v.func = alc_fixup_disable_aamix,
6691 .chained = true,
Takashi Iwaid44a6862018-06-19 23:04:03 +02006692 .chain_id = ALC288_FIXUP_DELL1_MIC_NO_PRESENCE
Hui Wang831bfdf92015-06-26 12:35:17 +08006693 },
6694 [ALC288_FIXUP_DELL_XPS_13] = {
6695 .type = HDA_FIXUP_FUNC,
6696 .v.func = alc_fixup_dell_xps13,
6697 .chained = true,
6698 .chain_id = ALC288_FIXUP_DISABLE_AAMIX
6699 },
Takashi Iwai8b99aba2015-06-15 11:59:32 +02006700 [ALC292_FIXUP_DISABLE_AAMIX] = {
6701 .type = HDA_FIXUP_FUNC,
6702 .v.func = alc_fixup_disable_aamix,
Hui Wang831bfdf92015-06-26 12:35:17 +08006703 .chained = true,
6704 .chain_id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE
Takashi Iwai8b99aba2015-06-15 11:59:32 +02006705 },
David Henningssonc04017e2015-12-15 14:44:03 +01006706 [ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK] = {
6707 .type = HDA_FIXUP_FUNC,
6708 .v.func = alc_fixup_disable_aamix,
6709 .chained = true,
6710 .chain_id = ALC293_FIXUP_DELL1_MIC_NO_PRESENCE
6711 },
Takashi Iwai5fab5822020-01-05 09:11:19 +01006712 [ALC292_FIXUP_DELL_E7X_AAMIX] = {
Takashi Iwai8b99aba2015-06-15 11:59:32 +02006713 .type = HDA_FIXUP_FUNC,
6714 .v.func = alc_fixup_dell_xps13,
6715 .chained = true,
6716 .chain_id = ALC292_FIXUP_DISABLE_AAMIX
6717 },
Takashi Iwai5fab5822020-01-05 09:11:19 +01006718 [ALC292_FIXUP_DELL_E7X] = {
6719 .type = HDA_FIXUP_FUNC,
6720 .v.func = snd_hda_gen_fixup_micmute_led,
6721 /* micmute fixup must be applied at last */
6722 .chained_before = true,
6723 .chain_id = ALC292_FIXUP_DELL_E7X_AAMIX,
6724 },
James McDonnell54324222019-09-16 14:53:38 +00006725 [ALC298_FIXUP_ALIENWARE_MIC_NO_PRESENCE] = {
6726 .type = HDA_FIXUP_PINS,
6727 .v.pins = (const struct hda_pintbl[]) {
6728 { 0x18, 0x01a1913c }, /* headset mic w/o jack detect */
6729 { }
6730 },
6731 .chained_before = true,
6732 .chain_id = ALC269_FIXUP_HEADSET_MODE,
6733 },
Kailang Yang977e6272015-05-18 15:31:20 +08006734 [ALC298_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6735 .type = HDA_FIXUP_PINS,
6736 .v.pins = (const struct hda_pintbl[]) {
6737 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6738 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6739 { }
6740 },
6741 .chained = true,
6742 .chain_id = ALC269_FIXUP_HEADSET_MODE
6743 },
Hui Wang2f726ae2017-03-31 10:31:40 +08006744 [ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE] = {
6745 .type = HDA_FIXUP_PINS,
6746 .v.pins = (const struct hda_pintbl[]) {
6747 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6748 { }
6749 },
6750 .chained = true,
6751 .chain_id = ALC269_FIXUP_HEADSET_MODE
6752 },
Kailang Yang6ed11312015-10-26 15:37:39 +08006753 [ALC275_FIXUP_DELL_XPS] = {
6754 .type = HDA_FIXUP_VERBS,
6755 .v.verbs = (const struct hda_verb[]) {
6756 /* Enables internal speaker */
6757 {0x20, AC_VERB_SET_COEF_INDEX, 0x1f},
6758 {0x20, AC_VERB_SET_PROC_COEF, 0x00c0},
6759 {0x20, AC_VERB_SET_COEF_INDEX, 0x30},
6760 {0x20, AC_VERB_SET_PROC_COEF, 0x00b1},
6761 {}
6762 }
6763 },
Hui Wang23adc192015-12-08 12:27:18 +08006764 [ALC293_FIXUP_LENOVO_SPK_NOISE] = {
6765 .type = HDA_FIXUP_FUNC,
6766 .v.func = alc_fixup_disable_aamix,
6767 .chained = true,
6768 .chain_id = ALC269_FIXUP_THINKPAD_ACPI
6769 },
Kailang3694cb22015-12-28 11:35:24 +08006770 [ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY] = {
6771 .type = HDA_FIXUP_FUNC,
6772 .v.func = alc233_fixup_lenovo_line2_mic_hotkey,
6773 },
Kai-Heng Feng3b43b712016-02-25 15:19:38 +08006774 [ALC255_FIXUP_DELL_SPK_NOISE] = {
6775 .type = HDA_FIXUP_FUNC,
6776 .v.func = alc_fixup_disable_aamix,
6777 .chained = true,
6778 .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
6779 },
Kailang Yangd1dd4212019-01-09 17:05:24 +08006780 [ALC225_FIXUP_DISABLE_MIC_VREF] = {
6781 .type = HDA_FIXUP_FUNC,
6782 .v.func = alc_fixup_disable_mic_vref,
6783 .chained = true,
6784 .chain_id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE
6785 },
David Henningsson2ae95572016-02-25 09:37:05 +01006786 [ALC225_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6787 .type = HDA_FIXUP_VERBS,
6788 .v.verbs = (const struct hda_verb[]) {
6789 /* Disable pass-through path for FRONT 14h */
6790 { 0x20, AC_VERB_SET_COEF_INDEX, 0x36 },
6791 { 0x20, AC_VERB_SET_PROC_COEF, 0x57d7 },
6792 {}
6793 },
6794 .chained = true,
Kailang Yangd1dd4212019-01-09 17:05:24 +08006795 .chain_id = ALC225_FIXUP_DISABLE_MIC_VREF
David Henningsson2ae95572016-02-25 09:37:05 +01006796 },
Takashi Iwaif8839822016-02-25 14:31:59 +01006797 [ALC280_FIXUP_HP_HEADSET_MIC] = {
6798 .type = HDA_FIXUP_FUNC,
6799 .v.func = alc_fixup_disable_aamix,
6800 .chained = true,
6801 .chain_id = ALC269_FIXUP_HEADSET_MIC,
6802 },
Hui Wange549d192016-04-01 11:00:15 +08006803 [ALC221_FIXUP_HP_FRONT_MIC] = {
6804 .type = HDA_FIXUP_PINS,
6805 .v.pins = (const struct hda_pintbl[]) {
6806 { 0x19, 0x02a19020 }, /* Front Mic */
6807 { }
6808 },
6809 },
Sven Eckelmannc636b952016-04-11 16:55:26 +02006810 [ALC292_FIXUP_TPT460] = {
6811 .type = HDA_FIXUP_FUNC,
6812 .v.func = alc_fixup_tpt440_dock,
6813 .chained = true,
6814 .chain_id = ALC293_FIXUP_LENOVO_SPK_NOISE,
6815 },
Hui Wangdd9aa332016-08-01 10:20:32 +08006816 [ALC298_FIXUP_SPK_VOLUME] = {
6817 .type = HDA_FIXUP_FUNC,
6818 .v.func = alc298_fixup_speaker_volume,
Hui Wang59ec4b52016-08-04 15:28:04 +08006819 .chained = true,
Hui Wang2f726ae2017-03-31 10:31:40 +08006820 .chain_id = ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE,
Hui Wangdd9aa332016-08-01 10:20:32 +08006821 },
Takashi Iwaie312a862018-03-06 12:14:17 +01006822 [ALC295_FIXUP_DISABLE_DAC3] = {
6823 .type = HDA_FIXUP_FUNC,
6824 .v.func = alc295_fixup_disable_dac3,
6825 },
Jaroslav Kyselad2cd7952019-11-29 15:40:27 +01006826 [ALC285_FIXUP_SPEAKER2_TO_DAC1] = {
6827 .type = HDA_FIXUP_FUNC,
6828 .v.func = alc285_fixup_speaker2_to_dac1,
Hui Wangc37c0ab2020-02-19 13:23:06 +08006829 .chained = true,
6830 .chain_id = ALC269_FIXUP_THINKPAD_ACPI
Jaroslav Kyselad2cd7952019-11-29 15:40:27 +01006831 },
Kai-Heng Fengfd06c772016-08-30 15:36:34 +08006832 [ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER] = {
6833 .type = HDA_FIXUP_PINS,
6834 .v.pins = (const struct hda_pintbl[]) {
6835 { 0x1b, 0x90170151 },
6836 { }
6837 },
6838 .chained = true,
6839 .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
6840 },
Gabriele Mazzotta823ff162016-12-24 19:50:01 +01006841 [ALC269_FIXUP_ATIV_BOOK_8] = {
6842 .type = HDA_FIXUP_FUNC,
6843 .v.func = alc_fixup_auto_mute_via_amp,
6844 .chained = true,
6845 .chain_id = ALC269_FIXUP_NO_SHUTUP
6846 },
Kailang Yang9eb5d0e2017-01-17 15:40:25 +08006847 [ALC221_FIXUP_HP_MIC_NO_PRESENCE] = {
6848 .type = HDA_FIXUP_PINS,
6849 .v.pins = (const struct hda_pintbl[]) {
6850 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6851 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6852 { }
6853 },
6854 .chained = true,
6855 .chain_id = ALC269_FIXUP_HEADSET_MODE
6856 },
Chris Chiuc1732ed2017-02-28 14:17:13 -06006857 [ALC256_FIXUP_ASUS_HEADSET_MODE] = {
6858 .type = HDA_FIXUP_FUNC,
6859 .v.func = alc_fixup_headset_mode,
6860 },
6861 [ALC256_FIXUP_ASUS_MIC] = {
6862 .type = HDA_FIXUP_PINS,
6863 .v.pins = (const struct hda_pintbl[]) {
6864 { 0x13, 0x90a60160 }, /* use as internal mic */
6865 { 0x19, 0x04a11120 }, /* use as headset mic, without its own jack detect */
6866 { }
6867 },
6868 .chained = true,
6869 .chain_id = ALC256_FIXUP_ASUS_HEADSET_MODE
6870 },
Chris Chiueeed4cd2017-02-28 14:17:15 -06006871 [ALC256_FIXUP_ASUS_AIO_GPIO2] = {
Takashi Iwaiae065f12018-06-19 23:00:03 +02006872 .type = HDA_FIXUP_FUNC,
6873 /* Set up GPIO2 for the speaker amp */
6874 .v.func = alc_fixup_gpio4,
Chris Chiueeed4cd2017-02-28 14:17:15 -06006875 },
Chris Chiu216d7ae2017-02-28 14:17:14 -06006876 [ALC233_FIXUP_ASUS_MIC_NO_PRESENCE] = {
6877 .type = HDA_FIXUP_PINS,
6878 .v.pins = (const struct hda_pintbl[]) {
6879 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6880 { }
6881 },
6882 .chained = true,
6883 .chain_id = ALC269_FIXUP_HEADSET_MIC
6884 },
6885 [ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE] = {
6886 .type = HDA_FIXUP_VERBS,
6887 .v.verbs = (const struct hda_verb[]) {
6888 /* Enables internal speaker */
6889 {0x20, AC_VERB_SET_COEF_INDEX, 0x40},
6890 {0x20, AC_VERB_SET_PROC_COEF, 0x8800},
6891 {}
6892 },
6893 .chained = true,
6894 .chain_id = ALC233_FIXUP_ASUS_MIC_NO_PRESENCE
6895 },
Kailang Yangca169cc2017-04-25 16:17:40 +08006896 [ALC233_FIXUP_LENOVO_MULTI_CODECS] = {
6897 .type = HDA_FIXUP_FUNC,
6898 .v.func = alc233_alc662_fixup_lenovo_dual_codecs,
6899 },
Jian-Hong Panea5c7eb2019-04-01 11:25:05 +08006900 [ALC233_FIXUP_ACER_HEADSET_MIC] = {
6901 .type = HDA_FIXUP_VERBS,
6902 .v.verbs = (const struct hda_verb[]) {
6903 { 0x20, AC_VERB_SET_COEF_INDEX, 0x45 },
6904 { 0x20, AC_VERB_SET_PROC_COEF, 0x5089 },
6905 { }
6906 },
6907 .chained = true,
6908 .chain_id = ALC233_FIXUP_ASUS_MIC_NO_PRESENCE
6909 },
Hui Wangf33f79f2017-07-07 12:08:29 +08006910 [ALC294_FIXUP_LENOVO_MIC_LOCATION] = {
6911 .type = HDA_FIXUP_PINS,
6912 .v.pins = (const struct hda_pintbl[]) {
6913 /* Change the mic location from front to right, otherwise there are
6914 two front mics with the same name, pulseaudio can't handle them.
6915 This is just a temporary workaround, after applying this fixup,
6916 there will be one "Front Mic" and one "Mic" in this machine.
6917 */
6918 { 0x1a, 0x04a19040 },
6919 { }
6920 },
6921 },
Kailang Yang5f364132017-07-25 16:28:16 +08006922 [ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE] = {
6923 .type = HDA_FIXUP_PINS,
6924 .v.pins = (const struct hda_pintbl[]) {
6925 { 0x16, 0x0101102f }, /* Rear Headset HP */
6926 { 0x19, 0x02a1913c }, /* use as Front headset mic, without its own jack detect */
6927 { 0x1a, 0x01a19030 }, /* Rear Headset MIC */
6928 { 0x1b, 0x02011020 },
6929 { }
6930 },
6931 .chained = true,
6932 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
6933 },
PeiSen Houb84e8432017-09-01 15:11:56 +08006934 [ALC700_FIXUP_INTEL_REFERENCE] = {
6935 .type = HDA_FIXUP_VERBS,
6936 .v.verbs = (const struct hda_verb[]) {
6937 /* Enables internal speaker */
6938 {0x20, AC_VERB_SET_COEF_INDEX, 0x45},
6939 {0x20, AC_VERB_SET_PROC_COEF, 0x5289},
6940 {0x20, AC_VERB_SET_COEF_INDEX, 0x4A},
6941 {0x20, AC_VERB_SET_PROC_COEF, 0x001b},
6942 {0x58, AC_VERB_SET_COEF_INDEX, 0x00},
6943 {0x58, AC_VERB_SET_PROC_COEF, 0x3888},
6944 {0x20, AC_VERB_SET_COEF_INDEX, 0x6f},
6945 {0x20, AC_VERB_SET_PROC_COEF, 0x2c0b},
6946 {}
6947 }
6948 },
Kailang Yang92266652017-12-14 15:28:58 +08006949 [ALC274_FIXUP_DELL_BIND_DACS] = {
6950 .type = HDA_FIXUP_FUNC,
6951 .v.func = alc274_fixup_bind_dacs,
6952 .chained = true,
6953 .chain_id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE
6954 },
6955 [ALC274_FIXUP_DELL_AIO_LINEOUT_VERB] = {
6956 .type = HDA_FIXUP_PINS,
6957 .v.pins = (const struct hda_pintbl[]) {
6958 { 0x1b, 0x0401102f },
6959 { }
6960 },
6961 .chained = true,
6962 .chain_id = ALC274_FIXUP_DELL_BIND_DACS
6963 },
Kailang Yang61fcf8e2018-02-02 15:26:46 +08006964 [ALC298_FIXUP_TPT470_DOCK] = {
6965 .type = HDA_FIXUP_FUNC,
6966 .v.func = alc_fixup_tpt470_dock,
6967 .chained = true,
6968 .chain_id = ALC293_FIXUP_LENOVO_SPK_NOISE
6969 },
Kailang Yangae104a22018-02-05 16:07:20 +08006970 [ALC255_FIXUP_DUMMY_LINEOUT_VERB] = {
6971 .type = HDA_FIXUP_PINS,
6972 .v.pins = (const struct hda_pintbl[]) {
6973 { 0x14, 0x0201101f },
6974 { }
6975 },
6976 .chained = true,
6977 .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
6978 },
Kailang Yangf0ba9d62018-03-16 11:46:08 +08006979 [ALC255_FIXUP_DELL_HEADSET_MIC] = {
6980 .type = HDA_FIXUP_PINS,
6981 .v.pins = (const struct hda_pintbl[]) {
6982 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6983 { }
6984 },
Hui Wang3ce0d5a2018-04-19 13:29:04 +08006985 .chained = true,
6986 .chain_id = ALC269_FIXUP_HEADSET_MIC
Kailang Yangf0ba9d62018-03-16 11:46:08 +08006987 },
Tom Bridenbbf8ff62018-05-29 17:34:20 +01006988 [ALC295_FIXUP_HP_X360] = {
6989 .type = HDA_FIXUP_FUNC,
6990 .v.func = alc295_fixup_hp_top_speakers,
6991 .chained = true,
6992 .chain_id = ALC269_FIXUP_HP_MUTE_LED_MIC3
Kailang Yang8a328ac2018-08-21 16:54:41 +08006993 },
6994 [ALC221_FIXUP_HP_HEADSET_MIC] = {
6995 .type = HDA_FIXUP_PINS,
6996 .v.pins = (const struct hda_pintbl[]) {
6997 { 0x19, 0x0181313f},
6998 { }
6999 },
7000 .chained = true,
7001 .chain_id = ALC269_FIXUP_HEADSET_MIC
7002 },
Hui Wangc4cfcf62018-11-26 14:17:16 +08007003 [ALC285_FIXUP_LENOVO_HEADPHONE_NOISE] = {
7004 .type = HDA_FIXUP_FUNC,
7005 .v.func = alc285_fixup_invalidate_dacs,
Hui Wang6ba189c2018-12-09 09:16:43 +08007006 .chained = true,
7007 .chain_id = ALC269_FIXUP_THINKPAD_ACPI
Hui Wangc4cfcf62018-11-26 14:17:16 +08007008 },
Girija Kumar Kasinadhunie8ed64b2018-11-26 13:40:46 -05007009 [ALC295_FIXUP_HP_AUTO_MUTE] = {
7010 .type = HDA_FIXUP_FUNC,
7011 .v.func = alc_fixup_auto_mute_via_amp,
7012 },
Chris Chiu33aaebd2018-12-05 14:48:53 +08007013 [ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE] = {
7014 .type = HDA_FIXUP_PINS,
7015 .v.pins = (const struct hda_pintbl[]) {
7016 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
7017 { }
7018 },
7019 .chained = true,
7020 .chain_id = ALC269_FIXUP_HEADSET_MIC
7021 },
Chris Chiud8ae4582018-12-07 17:17:11 +08007022 [ALC294_FIXUP_ASUS_MIC] = {
7023 .type = HDA_FIXUP_PINS,
7024 .v.pins = (const struct hda_pintbl[]) {
7025 { 0x13, 0x90a60160 }, /* use as internal mic */
7026 { 0x19, 0x04a11120 }, /* use as headset mic, without its own jack detect */
7027 { }
7028 },
7029 .chained = true,
7030 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
7031 },
Jian-Hong Pan4e051102018-12-07 17:17:12 +08007032 [ALC294_FIXUP_ASUS_HEADSET_MIC] = {
7033 .type = HDA_FIXUP_PINS,
7034 .v.pins = (const struct hda_pintbl[]) {
Jian-Hong Pan82b01142018-12-27 16:46:31 +08007035 { 0x19, 0x01a1103c }, /* use as headset mic */
Jian-Hong Pan4e051102018-12-07 17:17:12 +08007036 { }
7037 },
7038 .chained = true,
7039 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
7040 },
7041 [ALC294_FIXUP_ASUS_SPK] = {
7042 .type = HDA_FIXUP_VERBS,
7043 .v.verbs = (const struct hda_verb[]) {
7044 /* Set EAPD high */
7045 { 0x20, AC_VERB_SET_COEF_INDEX, 0x40 },
7046 { 0x20, AC_VERB_SET_PROC_COEF, 0x8800 },
7047 { }
7048 },
7049 .chained = true,
7050 .chain_id = ALC294_FIXUP_ASUS_HEADSET_MIC
7051 },
Jaroslav Kyselac8a9afa2019-03-14 09:21:08 +01007052 [ALC295_FIXUP_CHROME_BOOK] = {
Kailang Yange8547472018-11-28 15:32:45 +08007053 .type = HDA_FIXUP_FUNC,
Jaroslav Kyselac8a9afa2019-03-14 09:21:08 +01007054 .v.func = alc295_fixup_chromebook,
Kailang Yang8983eb62019-04-03 15:31:49 +08007055 .chained = true,
7056 .chain_id = ALC225_FIXUP_HEADSET_JACK
7057 },
7058 [ALC225_FIXUP_HEADSET_JACK] = {
7059 .type = HDA_FIXUP_FUNC,
7060 .v.func = alc_fixup_headset_jack,
Kailang Yange8547472018-11-28 15:32:45 +08007061 },
Jeremy Soller89e3a562019-01-30 16:12:31 -07007062 [ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE] = {
7063 .type = HDA_FIXUP_PINS,
7064 .v.pins = (const struct hda_pintbl[]) {
7065 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
7066 { }
7067 },
7068 .chained = true,
7069 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
7070 },
Hui Wangc8c6ee62019-02-14 11:41:33 +08007071 [ALC285_FIXUP_LENOVO_PC_BEEP_IN_NOISE] = {
7072 .type = HDA_FIXUP_VERBS,
7073 .v.verbs = (const struct hda_verb[]) {
7074 /* Disable PCBEEP-IN passthrough */
7075 { 0x20, AC_VERB_SET_COEF_INDEX, 0x36 },
7076 { 0x20, AC_VERB_SET_PROC_COEF, 0x57d7 },
7077 { }
7078 },
7079 .chained = true,
7080 .chain_id = ALC285_FIXUP_LENOVO_HEADPHONE_NOISE
7081 },
Jian-Hong Pancbc05fd2019-03-13 17:33:24 +08007082 [ALC255_FIXUP_ACER_HEADSET_MIC] = {
7083 .type = HDA_FIXUP_PINS,
7084 .v.pins = (const struct hda_pintbl[]) {
7085 { 0x19, 0x03a11130 },
7086 { 0x1a, 0x90a60140 }, /* use as internal mic */
7087 { }
7088 },
7089 .chained = true,
7090 .chain_id = ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC
7091 },
Kailang Yang136824e2019-03-14 16:22:45 +08007092 [ALC225_FIXUP_DELL_WYSE_AIO_MIC_NO_PRESENCE] = {
7093 .type = HDA_FIXUP_PINS,
7094 .v.pins = (const struct hda_pintbl[]) {
7095 { 0x16, 0x01011020 }, /* Rear Line out */
7096 { 0x19, 0x01a1913c }, /* use as Front headset mic, without its own jack detect */
7097 { }
7098 },
7099 .chained = true,
7100 .chain_id = ALC225_FIXUP_WYSE_AUTO_MUTE
7101 },
7102 [ALC225_FIXUP_WYSE_AUTO_MUTE] = {
7103 .type = HDA_FIXUP_FUNC,
7104 .v.func = alc_fixup_auto_mute_via_amp,
7105 .chained = true,
7106 .chain_id = ALC225_FIXUP_WYSE_DISABLE_MIC_VREF
7107 },
7108 [ALC225_FIXUP_WYSE_DISABLE_MIC_VREF] = {
7109 .type = HDA_FIXUP_FUNC,
7110 .v.func = alc_fixup_disable_mic_vref,
7111 .chained = true,
7112 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
7113 },
Jian-Hong Pan667a8f72019-03-15 17:51:09 +08007114 [ALC286_FIXUP_ACER_AIO_HEADSET_MIC] = {
7115 .type = HDA_FIXUP_VERBS,
7116 .v.verbs = (const struct hda_verb[]) {
7117 { 0x20, AC_VERB_SET_COEF_INDEX, 0x4f },
7118 { 0x20, AC_VERB_SET_PROC_COEF, 0x5029 },
7119 { }
7120 },
7121 .chained = true,
7122 .chain_id = ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE
7123 },
Daniel Drake8c8967a2019-10-17 16:15:01 +08007124 [ALC256_FIXUP_ASUS_HEADSET_MIC] = {
7125 .type = HDA_FIXUP_PINS,
7126 .v.pins = (const struct hda_pintbl[]) {
7127 { 0x19, 0x03a11020 }, /* headset mic with jack detect */
7128 { }
7129 },
7130 .chained = true,
7131 .chain_id = ALC256_FIXUP_ASUS_HEADSET_MODE
7132 },
Jian-Hong Pane1037352019-03-22 11:37:18 +08007133 [ALC256_FIXUP_ASUS_MIC_NO_PRESENCE] = {
7134 .type = HDA_FIXUP_PINS,
7135 .v.pins = (const struct hda_pintbl[]) {
7136 { 0x19, 0x04a11120 }, /* use as headset mic, without its own jack detect */
7137 { }
7138 },
7139 .chained = true,
7140 .chain_id = ALC256_FIXUP_ASUS_HEADSET_MODE
7141 },
Bernhard Rosenkraenzere2a829b2019-03-05 00:38:19 +01007142 [ALC299_FIXUP_PREDATOR_SPK] = {
7143 .type = HDA_FIXUP_PINS,
7144 .v.pins = (const struct hda_pintbl[]) {
7145 { 0x21, 0x90170150 }, /* use as headset mic, without its own jack detect */
7146 { }
7147 }
7148 },
Jan-Marek Glogowskibd9c10b2019-09-15 16:57:28 +02007149 [ALC256_FIXUP_MEDION_HEADSET_NO_PRESENCE] = {
7150 .type = HDA_FIXUP_PINS,
7151 .v.pins = (const struct hda_pintbl[]) {
7152 { 0x19, 0x04a11040 },
7153 { 0x21, 0x04211020 },
7154 { }
7155 },
7156 .chained = true,
7157 .chain_id = ALC256_FIXUP_ASUS_HEADSET_MODE
7158 },
Kailang Yange79c2262019-12-19 14:12:15 +08007159 [ALC289_FIXUP_DELL_SPK2] = {
7160 .type = HDA_FIXUP_PINS,
7161 .v.pins = (const struct hda_pintbl[]) {
7162 { 0x17, 0x90170130 }, /* bass spk */
7163 { }
7164 },
7165 .chained = true,
7166 .chain_id = ALC269_FIXUP_DELL4_MIC_NO_PRESENCE
7167 },
7168 [ALC289_FIXUP_DUAL_SPK] = {
7169 .type = HDA_FIXUP_FUNC,
7170 .v.func = alc285_fixup_speaker2_to_dac1,
7171 .chained = true,
7172 .chain_id = ALC289_FIXUP_DELL_SPK2
7173 },
Chris Chiu48e01502019-12-30 11:11:18 +08007174 [ALC294_FIXUP_SPK2_TO_DAC1] = {
7175 .type = HDA_FIXUP_FUNC,
7176 .v.func = alc285_fixup_speaker2_to_dac1,
7177 .chained = true,
7178 .chain_id = ALC294_FIXUP_ASUS_HEADSET_MIC
7179 },
7180 [ALC294_FIXUP_ASUS_DUAL_SPK] = {
Jian-Hong Pan436e2552019-11-25 17:34:06 +08007181 .type = HDA_FIXUP_FUNC,
7182 /* The GPIO must be pulled to initialize the AMP */
7183 .v.func = alc_fixup_gpio4,
7184 .chained = true,
Chris Chiu48e01502019-12-30 11:11:18 +08007185 .chain_id = ALC294_FIXUP_SPK2_TO_DAC1
Jian-Hong Pan436e2552019-11-25 17:34:06 +08007186 },
Kailang Yang76f7dec2020-02-10 16:30:26 +08007187 [ALC285_FIXUP_THINKPAD_HEADSET_JACK] = {
7188 .type = HDA_FIXUP_FUNC,
7189 .v.func = alc_fixup_headset_jack,
7190 .chained = true,
7191 .chain_id = ALC285_FIXUP_SPEAKER2_TO_DAC1
7192 },
Jian-Hong Pan8b33a132020-02-25 15:29:21 +08007193 [ALC294_FIXUP_ASUS_HPE] = {
7194 .type = HDA_FIXUP_VERBS,
7195 .v.verbs = (const struct hda_verb[]) {
7196 /* Set EAPD high */
7197 { 0x20, AC_VERB_SET_COEF_INDEX, 0x0f },
7198 { 0x20, AC_VERB_SET_PROC_COEF, 0x7774 },
7199 { }
7200 },
7201 .chained = true,
7202 .chain_id = ALC294_FIXUP_ASUS_HEADSET_MIC
7203 },
Kai-Heng Fengf5a88b02020-03-27 12:46:25 +08007204 [ALC285_FIXUP_HP_GPIO_LED] = {
7205 .type = HDA_FIXUP_FUNC,
7206 .v.func = alc285_fixup_hp_gpio_led,
7207 },
Kailang Yang431e76c2020-04-07 14:40:20 +08007208 [ALC285_FIXUP_HP_MUTE_LED] = {
7209 .type = HDA_FIXUP_FUNC,
7210 .v.func = alc285_fixup_hp_mute_led,
7211 },
Kailang Yang24164f42020-04-07 14:52:42 +08007212 [ALC236_FIXUP_HP_MUTE_LED] = {
7213 .type = HDA_FIXUP_FUNC,
7214 .v.func = alc236_fixup_hp_mute_led,
7215 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02007216};
7217
7218static const struct snd_pci_quirk alc269_fixup_tbl[] = {
Marius Knausta6b92b62014-03-03 01:48:58 +01007219 SND_PCI_QUIRK(0x1025, 0x0283, "Acer TravelMate 8371", ALC269_FIXUP_INV_DMIC),
David Henningsson693b6132012-06-22 19:12:10 +02007220 SND_PCI_QUIRK(0x1025, 0x029b, "Acer 1810TZ", ALC269_FIXUP_INV_DMIC),
7221 SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC),
David Henningssonaaedfb42013-08-16 14:09:02 +02007222 SND_PCI_QUIRK(0x1025, 0x047c, "Acer AC700", ALC269_FIXUP_ACER_AC700),
Takashi Iwai78197172015-06-27 10:21:13 +02007223 SND_PCI_QUIRK(0x1025, 0x072d, "Acer Aspire V5-571G", ALC269_FIXUP_ASPIRE_HEADSET_MIC),
7224 SND_PCI_QUIRK(0x1025, 0x080d, "Acer Aspire V5-122P", ALC269_FIXUP_ASPIRE_HEADSET_MIC),
David Henningssonaaedfb42013-08-16 14:09:02 +02007225 SND_PCI_QUIRK(0x1025, 0x0740, "Acer AO725", ALC271_FIXUP_HP_GATE_MIC_JACK),
7226 SND_PCI_QUIRK(0x1025, 0x0742, "Acer AO756", ALC271_FIXUP_HP_GATE_MIC_JACK),
Simon South02322ac2016-03-02 23:10:44 -05007227 SND_PCI_QUIRK(0x1025, 0x0762, "Acer Aspire E1-472", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572),
Oleksij Rempelb1e89722013-12-04 20:50:53 +01007228 SND_PCI_QUIRK(0x1025, 0x0775, "Acer Aspire E1-572", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572),
Takashi Iwai1a22e772014-08-27 08:19:05 +02007229 SND_PCI_QUIRK(0x1025, 0x079b, "Acer Aspire V5-573G", ALC282_FIXUP_ASPIRE_V5_PINS),
Chris Chiu705b65f2018-12-05 14:48:54 +08007230 SND_PCI_QUIRK(0x1025, 0x102b, "Acer Aspire C24-860", ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE),
Takashi Iwaib9c2fa52015-11-19 16:39:50 +01007231 SND_PCI_QUIRK(0x1025, 0x106d, "Acer Cloudbook 14", ALC283_FIXUP_CHROME_BOOK),
Chris Chiuc7531e32019-03-21 17:17:31 +08007232 SND_PCI_QUIRK(0x1025, 0x1099, "Acer Aspire E5-523G", ALC255_FIXUP_ACER_MIC_NO_PRESENCE),
7233 SND_PCI_QUIRK(0x1025, 0x110e, "Acer Aspire ES1-432", ALC255_FIXUP_ACER_MIC_NO_PRESENCE),
Bernhard Rosenkraenzere2a829b2019-03-05 00:38:19 +01007234 SND_PCI_QUIRK(0x1025, 0x1246, "Acer Predator Helios 500", ALC299_FIXUP_PREDATOR_SPK),
Jian-Hong Pan667a8f72019-03-15 17:51:09 +08007235 SND_PCI_QUIRK(0x1025, 0x128f, "Acer Veriton Z6860G", ALC286_FIXUP_ACER_AIO_HEADSET_MIC),
7236 SND_PCI_QUIRK(0x1025, 0x1290, "Acer Veriton Z4860G", ALC286_FIXUP_ACER_AIO_HEADSET_MIC),
7237 SND_PCI_QUIRK(0x1025, 0x1291, "Acer Veriton Z4660G", ALC286_FIXUP_ACER_AIO_HEADSET_MIC),
Jian-Hong Pan2733cce2019-03-21 16:39:04 +08007238 SND_PCI_QUIRK(0x1025, 0x1308, "Acer Aspire Z24-890", ALC286_FIXUP_ACER_AIO_HEADSET_MIC),
Jian-Hong Panea5c7eb2019-04-01 11:25:05 +08007239 SND_PCI_QUIRK(0x1025, 0x132a, "Acer TravelMate B114-21", ALC233_FIXUP_ACER_HEADSET_MIC),
Jian-Hong Pancbc05fd2019-03-13 17:33:24 +08007240 SND_PCI_QUIRK(0x1025, 0x1330, "Acer TravelMate X514-51T", ALC255_FIXUP_ACER_HEADSET_MIC),
David Henningssonaaedfb42013-08-16 14:09:02 +02007241 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
Kailang Yang6ed11312015-10-26 15:37:39 +08007242 SND_PCI_QUIRK(0x1028, 0x054b, "Dell XPS one 2710", ALC275_FIXUP_DELL_XPS),
Takashi Iwai86f799b2015-11-14 17:46:31 +01007243 SND_PCI_QUIRK(0x1028, 0x05bd, "Dell Latitude E6440", ALC292_FIXUP_DELL_E7X),
Takashi Iwaicf521032016-01-15 12:59:25 +01007244 SND_PCI_QUIRK(0x1028, 0x05be, "Dell Latitude E6540", ALC292_FIXUP_DELL_E7X),
Takashi Iwai8b99aba2015-06-15 11:59:32 +02007245 SND_PCI_QUIRK(0x1028, 0x05ca, "Dell Latitude E7240", ALC292_FIXUP_DELL_E7X),
7246 SND_PCI_QUIRK(0x1028, 0x05cb, "Dell Latitude E7440", ALC292_FIXUP_DELL_E7X),
David Henningsson0f4881d2013-12-20 16:08:13 +01007247 SND_PCI_QUIRK(0x1028, 0x05da, "Dell Vostro 5460", ALC290_FIXUP_SUBWOOFER),
David Henningsson73bdd592013-04-15 15:44:14 +02007248 SND_PCI_QUIRK(0x1028, 0x05f4, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
7249 SND_PCI_QUIRK(0x1028, 0x05f5, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
7250 SND_PCI_QUIRK(0x1028, 0x05f6, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
David Henningsson0f4881d2013-12-20 16:08:13 +01007251 SND_PCI_QUIRK(0x1028, 0x0615, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK),
7252 SND_PCI_QUIRK(0x1028, 0x0616, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK),
Takashi Iwai98070572016-01-12 21:06:39 +01007253 SND_PCI_QUIRK(0x1028, 0x062c, "Dell Latitude E5550", ALC292_FIXUP_DELL_E7X),
Takashi Iwai42755542015-06-29 10:56:53 +02007254 SND_PCI_QUIRK(0x1028, 0x062e, "Dell Latitude E7450", ALC292_FIXUP_DELL_E7X),
David Henningsson0f4881d2013-12-20 16:08:13 +01007255 SND_PCI_QUIRK(0x1028, 0x0638, "Dell Inspiron 5439", ALC290_FIXUP_MONO_SPEAKERS_HSJACK),
Kailang Yanga22aa262014-04-23 17:34:28 +08007256 SND_PCI_QUIRK(0x1028, 0x064a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
7257 SND_PCI_QUIRK(0x1028, 0x064b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
Hui Wang831bfdf92015-06-26 12:35:17 +08007258 SND_PCI_QUIRK(0x1028, 0x0665, "Dell XPS 13", ALC288_FIXUP_DELL_XPS_13),
Bastien Noceraafecb142016-04-18 11:10:42 +02007259 SND_PCI_QUIRK(0x1028, 0x0669, "Dell Optiplex 9020m", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
Takashi Iwai3a05d122015-07-29 09:04:52 +02007260 SND_PCI_QUIRK(0x1028, 0x069a, "Dell Vostro 5480", ALC290_FIXUP_SUBWOOFER_HSJACK),
Kailang Yang8b724152014-12-17 17:08:59 +08007261 SND_PCI_QUIRK(0x1028, 0x06c7, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
Kailang Yangb7343042014-12-02 14:50:45 +08007262 SND_PCI_QUIRK(0x1028, 0x06d9, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
7263 SND_PCI_QUIRK(0x1028, 0x06da, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
David Henningssonc04017e2015-12-15 14:44:03 +01007264 SND_PCI_QUIRK(0x1028, 0x06db, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
7265 SND_PCI_QUIRK(0x1028, 0x06dd, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
7266 SND_PCI_QUIRK(0x1028, 0x06de, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
7267 SND_PCI_QUIRK(0x1028, 0x06df, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
7268 SND_PCI_QUIRK(0x1028, 0x06e0, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
Kai-Heng Fengfd06c772016-08-30 15:36:34 +08007269 SND_PCI_QUIRK(0x1028, 0x0706, "Dell Inspiron 7559", ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER),
Kai-Heng Feng3b43b712016-02-25 15:19:38 +08007270 SND_PCI_QUIRK(0x1028, 0x0725, "Dell Inspiron 3162", ALC255_FIXUP_DELL_SPK_NOISE),
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01007271 SND_PCI_QUIRK(0x1028, 0x0738, "Dell Precision 5820", ALC269_FIXUP_NO_SHUTUP),
Kai-Heng Feng709ae622018-10-04 11:39:42 +08007272 SND_PCI_QUIRK(0x1028, 0x075c, "Dell XPS 27 7760", ALC298_FIXUP_SPK_VOLUME),
Hui Wangdd9aa332016-08-01 10:20:32 +08007273 SND_PCI_QUIRK(0x1028, 0x075d, "Dell AIO", ALC298_FIXUP_SPK_VOLUME),
Takashi Iwaie312a862018-03-06 12:14:17 +01007274 SND_PCI_QUIRK(0x1028, 0x07b0, "Dell Precision 7520", ALC295_FIXUP_DISABLE_DAC3),
Takashi Iwai493de342017-02-28 17:27:57 +01007275 SND_PCI_QUIRK(0x1028, 0x0798, "Dell Inspiron 17 7000 Gaming", ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER),
Kailang Yang5f364132017-07-25 16:28:16 +08007276 SND_PCI_QUIRK(0x1028, 0x080c, "Dell WYSE", ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE),
Kailang Yang40e2c4e2018-02-02 15:13:09 +08007277 SND_PCI_QUIRK(0x1028, 0x084b, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB),
7278 SND_PCI_QUIRK(0x1028, 0x084e, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB),
Kailang Yangf0ba9d62018-03-16 11:46:08 +08007279 SND_PCI_QUIRK(0x1028, 0x0871, "Dell Precision 3630", ALC255_FIXUP_DELL_HEADSET_MIC),
7280 SND_PCI_QUIRK(0x1028, 0x0872, "Dell Precision 3630", ALC255_FIXUP_DELL_HEADSET_MIC),
Kailang Yangae104a22018-02-05 16:07:20 +08007281 SND_PCI_QUIRK(0x1028, 0x0873, "Dell Precision 3930", ALC255_FIXUP_DUMMY_LINEOUT_VERB),
Kailang Yang136824e2019-03-14 16:22:45 +08007282 SND_PCI_QUIRK(0x1028, 0x08ad, "Dell WYSE AIO", ALC225_FIXUP_DELL_WYSE_AIO_MIC_NO_PRESENCE),
Kailang Yangda484d02019-03-14 15:50:59 +08007283 SND_PCI_QUIRK(0x1028, 0x08ae, "Dell WYSE NB", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE),
Kailang Yangc2a7c55a2019-01-03 15:53:39 +08007284 SND_PCI_QUIRK(0x1028, 0x0935, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB),
Kailang Yange79c2262019-12-19 14:12:15 +08007285 SND_PCI_QUIRK(0x1028, 0x097e, "Dell Precision", ALC289_FIXUP_DUAL_SPK),
7286 SND_PCI_QUIRK(0x1028, 0x097d, "Dell Precision", ALC289_FIXUP_DUAL_SPK),
Kailang Yang78def222020-02-20 15:21:54 +08007287 SND_PCI_QUIRK(0x1028, 0x098d, "Dell Precision", ALC233_FIXUP_ASUS_MIC_NO_PRESENCE),
7288 SND_PCI_QUIRK(0x1028, 0x09bf, "Dell Precision", ALC233_FIXUP_ASUS_MIC_NO_PRESENCE),
Kailang Yanga22aa262014-04-23 17:34:28 +08007289 SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
7290 SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
Takashi Iwai08fb0d02013-01-10 17:33:58 +01007291 SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01007292 SND_PCI_QUIRK(0x103c, 0x18e6, "HP", ALC269_FIXUP_HP_GPIO_LED),
David Henningsson8e35cd42013-11-06 11:20:01 +01007293 SND_PCI_QUIRK(0x103c, 0x218b, "HP", ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED),
David Henningsson33f4acd2015-01-07 15:50:13 +01007294 SND_PCI_QUIRK(0x103c, 0x225f, "HP", ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY),
Kailang Yangc60666b2014-02-21 16:23:35 +08007295 /* ALC282 */
Hui Wang7976eb42015-02-13 11:14:41 +08007296 SND_PCI_QUIRK(0x103c, 0x21f9, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang8a02b162014-06-13 17:16:31 +08007297 SND_PCI_QUIRK(0x103c, 0x2210, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang8a02b162014-06-13 17:16:31 +08007298 SND_PCI_QUIRK(0x103c, 0x2214, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007299 SND_PCI_QUIRK(0x103c, 0x2236, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
7300 SND_PCI_QUIRK(0x103c, 0x2237, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
7301 SND_PCI_QUIRK(0x103c, 0x2238, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
7302 SND_PCI_QUIRK(0x103c, 0x2239, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007303 SND_PCI_QUIRK(0x103c, 0x224b, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
Kailang Yangc60666b2014-02-21 16:23:35 +08007304 SND_PCI_QUIRK(0x103c, 0x2268, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08007305 SND_PCI_QUIRK(0x103c, 0x226a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7306 SND_PCI_QUIRK(0x103c, 0x226b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang8a02b162014-06-13 17:16:31 +08007307 SND_PCI_QUIRK(0x103c, 0x226e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangeaa8e5e2014-11-21 15:49:11 +08007308 SND_PCI_QUIRK(0x103c, 0x2271, "HP", ALC286_FIXUP_HP_GPIO_LED),
TienFu Chenb4b33f92015-01-20 15:06:21 +01007309 SND_PCI_QUIRK(0x103c, 0x2272, "HP", ALC280_FIXUP_HP_DOCK_PINS),
TienFu Chen3271cb22015-02-10 09:09:41 +01007310 SND_PCI_QUIRK(0x103c, 0x2273, "HP", ALC280_FIXUP_HP_DOCK_PINS),
Kailang Yangc60666b2014-02-21 16:23:35 +08007311 SND_PCI_QUIRK(0x103c, 0x229e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08007312 SND_PCI_QUIRK(0x103c, 0x22b2, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7313 SND_PCI_QUIRK(0x103c, 0x22b7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7314 SND_PCI_QUIRK(0x103c, 0x22bf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08007315 SND_PCI_QUIRK(0x103c, 0x22cf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Keith Packard98973f22015-07-15 12:14:39 -07007316 SND_PCI_QUIRK(0x103c, 0x22db, "HP", ALC280_FIXUP_HP_9480M),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007317 SND_PCI_QUIRK(0x103c, 0x22dc, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
7318 SND_PCI_QUIRK(0x103c, 0x22fb, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yangc60666b2014-02-21 16:23:35 +08007319 /* ALC290 */
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007320 SND_PCI_QUIRK(0x103c, 0x221b, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007321 SND_PCI_QUIRK(0x103c, 0x2221, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007322 SND_PCI_QUIRK(0x103c, 0x2225, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007323 SND_PCI_QUIRK(0x103c, 0x2253, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
7324 SND_PCI_QUIRK(0x103c, 0x2254, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
7325 SND_PCI_QUIRK(0x103c, 0x2255, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
7326 SND_PCI_QUIRK(0x103c, 0x2256, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
7327 SND_PCI_QUIRK(0x103c, 0x2257, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007328 SND_PCI_QUIRK(0x103c, 0x2259, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Jaroslav Kysela04d54662017-03-09 13:29:13 +01007329 SND_PCI_QUIRK(0x103c, 0x225a, "HP", ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED),
Kailang Yangc60666b2014-02-21 16:23:35 +08007330 SND_PCI_QUIRK(0x103c, 0x2260, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08007331 SND_PCI_QUIRK(0x103c, 0x2263, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7332 SND_PCI_QUIRK(0x103c, 0x2264, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7333 SND_PCI_QUIRK(0x103c, 0x2265, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007334 SND_PCI_QUIRK(0x103c, 0x2272, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
7335 SND_PCI_QUIRK(0x103c, 0x2273, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007336 SND_PCI_QUIRK(0x103c, 0x2278, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yangc60666b2014-02-21 16:23:35 +08007337 SND_PCI_QUIRK(0x103c, 0x227f, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08007338 SND_PCI_QUIRK(0x103c, 0x2282, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08007339 SND_PCI_QUIRK(0x103c, 0x228b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08007340 SND_PCI_QUIRK(0x103c, 0x228e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7341 SND_PCI_QUIRK(0x103c, 0x22c5, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08007342 SND_PCI_QUIRK(0x103c, 0x22c7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7343 SND_PCI_QUIRK(0x103c, 0x22c8, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08007344 SND_PCI_QUIRK(0x103c, 0x22c4, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang8a02b162014-06-13 17:16:31 +08007345 SND_PCI_QUIRK(0x103c, 0x2334, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7346 SND_PCI_QUIRK(0x103c, 0x2335, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7347 SND_PCI_QUIRK(0x103c, 0x2336, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7348 SND_PCI_QUIRK(0x103c, 0x2337, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Takashi Iwaif8839822016-02-25 14:31:59 +01007349 SND_PCI_QUIRK(0x103c, 0x221c, "HP EliteBook 755 G2", ALC280_FIXUP_HP_HEADSET_MIC),
Jaroslav Kysela167897f2019-03-13 13:40:15 +01007350 SND_PCI_QUIRK(0x103c, 0x802e, "HP Z240 SFF", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
7351 SND_PCI_QUIRK(0x103c, 0x802f, "HP Z240", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
Takashi Iwai563785e2018-11-12 09:43:12 +01007352 SND_PCI_QUIRK(0x103c, 0x820d, "HP Pavilion 15", ALC269_FIXUP_HP_MUTE_LED_MIC3),
Hui Wange549d192016-04-01 11:00:15 +08007353 SND_PCI_QUIRK(0x103c, 0x8256, "HP", ALC221_FIXUP_HP_FRONT_MIC),
Tom Bridenbbf8ff62018-05-29 17:34:20 +01007354 SND_PCI_QUIRK(0x103c, 0x827e, "HP x360", ALC295_FIXUP_HP_X360),
Jaroslav Kysela167897f2019-03-13 13:40:15 +01007355 SND_PCI_QUIRK(0x103c, 0x82bf, "HP G3 mini", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
7356 SND_PCI_QUIRK(0x103c, 0x82c0, "HP G3 mini premium", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
Alexandru Gagniuc56e40eb2018-08-04 11:44:44 -05007357 SND_PCI_QUIRK(0x103c, 0x83b9, "HP Spectre x360", ALC269_FIXUP_HP_MUTE_LED_MIC3),
Takashi Iwai190d0382019-08-13 17:39:56 +02007358 SND_PCI_QUIRK(0x103c, 0x8497, "HP Envy x360", ALC269_FIXUP_HP_MUTE_LED_MIC3),
Sam Bazleyd33cd422019-09-01 03:31:30 +01007359 SND_PCI_QUIRK(0x103c, 0x84e7, "HP Pavilion 15", ALC269_FIXUP_HP_MUTE_LED_MIC3),
Kai-Heng Fengf5a88b02020-03-27 12:46:25 +08007360 SND_PCI_QUIRK(0x103c, 0x8736, "HP", ALC285_FIXUP_HP_GPIO_LED),
Kailang Yang431e76c2020-04-07 14:40:20 +08007361 SND_PCI_QUIRK(0x103c, 0x877a, "HP", ALC285_FIXUP_HP_MUTE_LED),
Kailang Yang24164f42020-04-07 14:52:42 +08007362 SND_PCI_QUIRK(0x103c, 0x877d, "HP", ALC236_FIXUP_HP_MUTE_LED),
Chris Chiuc1732ed2017-02-28 14:17:13 -06007363 SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC),
Takashi Iwai7bba2152013-09-06 15:45:38 +02007364 SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300),
David Henningsson3e0d6112013-04-22 14:30:14 +02007365 SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Wandrille RONCE9cf65332018-12-19 14:52:44 +01007366 SND_PCI_QUIRK(0x1043, 0x10a1, "ASUS UX391UA", ALC294_FIXUP_ASUS_SPK),
Chris Chiuc1732ed2017-02-28 14:17:13 -06007367 SND_PCI_QUIRK(0x1043, 0x10c0, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC),
Takashi Iwai4eab0ea2017-06-06 12:33:17 +02007368 SND_PCI_QUIRK(0x1043, 0x10d0, "ASUS X540LA/X540LJ", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
David Henningsson3e0d6112013-04-22 14:30:14 +02007369 SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Takashi Iwai4eab0ea2017-06-06 12:33:17 +02007370 SND_PCI_QUIRK(0x1043, 0x11c0, "ASUS X556UR", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
7371 SND_PCI_QUIRK(0x1043, 0x1290, "ASUS X441SA", ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE),
7372 SND_PCI_QUIRK(0x1043, 0x12a0, "ASUS X441UV", ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE),
Chris Chiuc1732ed2017-02-28 14:17:13 -06007373 SND_PCI_QUIRK(0x1043, 0x12f0, "ASUS X541UV", ALC256_FIXUP_ASUS_MIC),
7374 SND_PCI_QUIRK(0x1043, 0x12e0, "ASUS X541SA", ALC256_FIXUP_ASUS_MIC),
7375 SND_PCI_QUIRK(0x1043, 0x13b0, "ASUS Z550SA", ALC256_FIXUP_ASUS_MIC),
Oleksij Rempel2cede302013-11-27 17:12:03 +01007376 SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK),
Takashi Iwai23870832013-11-29 14:13:12 +01007377 SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A),
David Henningsson3e0d6112013-04-22 14:30:14 +02007378 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC),
Chris Chiu48e01502019-12-30 11:11:18 +08007379 SND_PCI_QUIRK(0x1043, 0x17d1, "ASUS UX431FL", ALC294_FIXUP_ASUS_DUAL_SPK),
Daniel Drake8c8967a2019-10-17 16:15:01 +08007380 SND_PCI_QUIRK(0x1043, 0x18b1, "Asus MJ401TA", ALC256_FIXUP_ASUS_HEADSET_MIC),
Adam Barber4963d662020-04-10 17:00:32 +08007381 SND_PCI_QUIRK(0x1043, 0x18f1, "Asus FX505DT", ALC256_FIXUP_ASUS_HEADSET_MIC),
Jian-Hong Pan8b33a132020-02-25 15:29:21 +08007382 SND_PCI_QUIRK(0x1043, 0x19ce, "ASUS B9450FA", ALC294_FIXUP_ASUS_HPE),
Takashi Iwai017f2a12011-07-09 14:42:25 +02007383 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
Chris Chiu28e8af82017-06-05 15:05:30 -06007384 SND_PCI_QUIRK(0x1043, 0x1a30, "ASUS X705UD", ALC256_FIXUP_ASUS_MIC),
David Henningsson693b6132012-06-22 19:12:10 +02007385 SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC),
Chris Chiu615966a2017-02-28 14:17:12 -06007386 SND_PCI_QUIRK(0x1043, 0x1bbd, "ASUS Z550MA", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
Takashi Iwai4eab0ea2017-06-06 12:33:17 +02007387 SND_PCI_QUIRK(0x1043, 0x1c23, "Asus X55U", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Chris Chiuc1732ed2017-02-28 14:17:13 -06007388 SND_PCI_QUIRK(0x1043, 0x1ccd, "ASUS X555UB", ALC256_FIXUP_ASUS_MIC),
Chris Chiueeed4cd2017-02-28 14:17:15 -06007389 SND_PCI_QUIRK(0x1043, 0x3030, "ASUS ZN270IE", ALC256_FIXUP_ASUS_AIO_GPIO2),
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02007390 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC),
7391 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC),
7392 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
7393 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
David Henningssond240d1d2013-04-15 12:50:02 +02007394 SND_PCI_QUIRK(0x1043, 0x8516, "ASUS X101CH", ALC269_FIXUP_ASUS_X101),
Takashi Iwaif88abaa2014-02-07 12:07:59 +01007395 SND_PCI_QUIRK(0x104d, 0x90b5, "Sony VAIO Pro 11", ALC286_FIXUP_SONY_MIC_NO_PRESENCE),
David Henningsson88cfcf82013-10-11 10:18:45 +02007396 SND_PCI_QUIRK(0x104d, 0x90b6, "Sony VAIO Pro 13", ALC286_FIXUP_SONY_MIC_NO_PRESENCE),
Takashi Iwai1d045db2011-07-07 18:23:21 +02007397 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
7398 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
7399 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
Takashi Iwaie9bd7d52014-05-21 11:06:49 +02007400 SND_PCI_QUIRK(0x104d, 0x9099, "Sony VAIO S13", ALC275_FIXUP_SONY_DISABLE_AAMIX),
Takashi Iwai24519912011-08-16 15:08:49 +02007401 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook", ALC269_FIXUP_LIFEBOOK),
Takashi Iwai4df3fd12015-06-29 08:38:02 +02007402 SND_PCI_QUIRK(0x10cf, 0x159f, "Lifebook E780", ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT),
Takashi Iwaicc7016a2015-04-08 20:47:55 +02007403 SND_PCI_QUIRK(0x10cf, 0x15dc, "Lifebook T731", ALC269_FIXUP_LIFEBOOK_HP_PIN),
Takashi Iwai88776f32015-05-01 09:20:34 +02007404 SND_PCI_QUIRK(0x10cf, 0x1757, "Lifebook E752", ALC269_FIXUP_LIFEBOOK_HP_PIN),
Jan-Marek Glogowskifdcc9682018-02-14 11:29:15 +01007405 SND_PCI_QUIRK(0x10cf, 0x1629, "Lifebook U7x7", ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC),
David Henningsson2041d562014-06-13 11:15:44 +02007406 SND_PCI_QUIRK(0x10cf, 0x1845, "Lifebook U904", ALC269_FIXUP_LIFEBOOK_EXTMIC),
PeiSen Houb84e8432017-09-01 15:11:56 +08007407 SND_PCI_QUIRK(0x10ec, 0x10f2, "Intel Reference board", ALC700_FIXUP_INTEL_REFERENCE),
YOKOTA Hiroshi0fca97a2018-07-01 18:30:01 +09007408 SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-SZ6", ALC269_FIXUP_HEADSET_MODE),
David Henningssona33cc482014-10-07 10:18:41 +02007409 SND_PCI_QUIRK(0x144d, 0xc109, "Samsung Ativ book 9 (NP900X3G)", ALC269_FIXUP_INV_DMIC),
Gabriele Mazzotta823ff162016-12-24 19:50:01 +01007410 SND_PCI_QUIRK(0x144d, 0xc740, "Samsung Ativ book 8 (NP870Z5G)", ALC269_FIXUP_ATIV_BOOK_8),
Anisse Astierabaa22742016-08-24 09:14:13 +02007411 SND_PCI_QUIRK(0x1458, 0xfa53, "Gigabyte BXBT-2807", ALC283_FIXUP_HEADSET_MIC),
7412 SND_PCI_QUIRK(0x1462, 0xb120, "MSI Cubi MS-B120", ALC283_FIXUP_HEADSET_MIC),
Anisse Astier8cd65272018-11-23 17:59:11 +01007413 SND_PCI_QUIRK(0x1462, 0xb171, "Cubi N 8GL (MS-B171)", ALC283_FIXUP_HEADSET_MIC),
Jeremy Soller89e3a562019-01-30 16:12:31 -07007414 SND_PCI_QUIRK(0x1558, 0x1325, "System76 Darter Pro (darp5)", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
Jeremy Soller80a50522019-05-07 17:11:08 -04007415 SND_PCI_QUIRK(0x1558, 0x8550, "System76 Gazelle (gaze14)", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
Jeremy Soller891afcf2019-05-10 10:15:07 -04007416 SND_PCI_QUIRK(0x1558, 0x8551, "System76 Gazelle (gaze14)", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
7417 SND_PCI_QUIRK(0x1558, 0x8560, "System76 Gazelle (gaze14)", ALC269_FIXUP_HEADSET_MIC),
7418 SND_PCI_QUIRK(0x1558, 0x8561, "System76 Gazelle (gaze14)", ALC269_FIXUP_HEADSET_MIC),
Kailang Yangca169cc2017-04-25 16:17:40 +08007419 SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC233_FIXUP_LENOVO_MULTI_CODECS),
Takashi Iwai1d045db2011-07-07 18:23:21 +02007420 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
7421 SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
7422 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
7423 SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
7424 SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
Takashi Iwai707fba32012-08-02 09:04:39 +02007425 SND_PCI_QUIRK(0x17aa, 0x21f6, "Thinkpad T530", ALC269_FIXUP_LENOVO_DOCK),
Felix Kaechelec8415a42012-08-06 23:02:01 +02007426 SND_PCI_QUIRK(0x17aa, 0x21fa, "Thinkpad X230", ALC269_FIXUP_LENOVO_DOCK),
Stefán Freyr84f98fd2012-10-19 22:46:00 +02007427 SND_PCI_QUIRK(0x17aa, 0x21f3, "Thinkpad T430", ALC269_FIXUP_LENOVO_DOCK),
Philipp A. Mohrenweiser4407be62012-08-06 13:14:18 +02007428 SND_PCI_QUIRK(0x17aa, 0x21fb, "Thinkpad T430s", ALC269_FIXUP_LENOVO_DOCK),
David Henningsson108cc102012-07-20 10:37:25 +02007429 SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK),
David Henningssonaaedfb42013-08-16 14:09:02 +02007430 SND_PCI_QUIRK(0x17aa, 0x2208, "Thinkpad T431s", ALC269_FIXUP_LENOVO_DOCK),
Takashi Iwai9a811232015-12-09 15:17:43 +01007431 SND_PCI_QUIRK(0x17aa, 0x220c, "Thinkpad T440s", ALC292_FIXUP_TPT440),
Takashi Iwai1c37c222014-05-06 17:34:42 +02007432 SND_PCI_QUIRK(0x17aa, 0x220e, "Thinkpad T440p", ALC292_FIXUP_TPT440_DOCK),
Takashi Iwaia12137e2014-06-27 12:14:35 +02007433 SND_PCI_QUIRK(0x17aa, 0x2210, "Thinkpad T540p", ALC292_FIXUP_TPT440_DOCK),
Rick Sherman59a51a62015-08-18 21:04:30 -05007434 SND_PCI_QUIRK(0x17aa, 0x2211, "Thinkpad W541", ALC292_FIXUP_TPT440_DOCK),
Takashi Iwai6d169412014-10-07 17:27:02 +02007435 SND_PCI_QUIRK(0x17aa, 0x2212, "Thinkpad T440", ALC292_FIXUP_TPT440_DOCK),
Lukas Bossard7c215392014-10-29 18:31:07 +01007436 SND_PCI_QUIRK(0x17aa, 0x2214, "Thinkpad X240", ALC292_FIXUP_TPT440_DOCK),
David Henningssona4a9e082013-08-16 14:09:01 +02007437 SND_PCI_QUIRK(0x17aa, 0x2215, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Takashi Iwaib6903c02015-12-10 12:20:20 +01007438 SND_PCI_QUIRK(0x17aa, 0x2218, "Thinkpad X1 Carbon 2nd", ALC292_FIXUP_TPT440_DOCK),
Laura Abbottd05ea7d2015-10-02 11:09:54 -07007439 SND_PCI_QUIRK(0x17aa, 0x2223, "ThinkPad T550", ALC292_FIXUP_TPT440_DOCK),
Yves-Alexis Perezc0278662015-04-11 09:31:35 +02007440 SND_PCI_QUIRK(0x17aa, 0x2226, "ThinkPad X250", ALC292_FIXUP_TPT440_DOCK),
Kailang Yang61fcf8e2018-02-02 15:26:46 +08007441 SND_PCI_QUIRK(0x17aa, 0x222d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7442 SND_PCI_QUIRK(0x17aa, 0x222e, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
Torsten Hilbrichdab38e42016-06-07 13:14:21 +02007443 SND_PCI_QUIRK(0x17aa, 0x2231, "Thinkpad T560", ALC292_FIXUP_TPT460),
Sven Eckelmannc636b952016-04-11 16:55:26 +02007444 SND_PCI_QUIRK(0x17aa, 0x2233, "Thinkpad", ALC292_FIXUP_TPT460),
Kailang Yang61fcf8e2018-02-02 15:26:46 +08007445 SND_PCI_QUIRK(0x17aa, 0x2245, "Thinkpad T470", ALC298_FIXUP_TPT470_DOCK),
7446 SND_PCI_QUIRK(0x17aa, 0x2246, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7447 SND_PCI_QUIRK(0x17aa, 0x2247, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
Dennis Wassenberge4c07b32018-03-08 13:17:54 +01007448 SND_PCI_QUIRK(0x17aa, 0x2249, "Thinkpad", ALC292_FIXUP_TPT460),
Kailang Yang61fcf8e2018-02-02 15:26:46 +08007449 SND_PCI_QUIRK(0x17aa, 0x224b, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7450 SND_PCI_QUIRK(0x17aa, 0x224c, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7451 SND_PCI_QUIRK(0x17aa, 0x224d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
Benjamin Berg85981df2018-02-14 13:29:39 +01007452 SND_PCI_QUIRK(0x17aa, 0x225d, "Thinkpad T480", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Kailang Yang76f7dec2020-02-10 16:30:26 +08007453 SND_PCI_QUIRK(0x17aa, 0x2292, "Thinkpad X1 Yoga 7th", ALC285_FIXUP_THINKPAD_HEADSET_JACK),
7454 SND_PCI_QUIRK(0x17aa, 0x2293, "Thinkpad X1 Carbon 7th", ALC285_FIXUP_THINKPAD_HEADSET_JACK),
Hans de Goedeca707b32020-04-02 19:43:11 +02007455 SND_PCI_QUIRK(0x17aa, 0x22be, "Thinkpad X1 Carbon 8th", ALC285_FIXUP_THINKPAD_HEADSET_JACK),
Kailang3694cb22015-12-28 11:35:24 +08007456 SND_PCI_QUIRK(0x17aa, 0x30bb, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
Hui Wang6ef2f682016-03-11 12:04:02 +08007457 SND_PCI_QUIRK(0x17aa, 0x30e2, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
Hui Wangf33f79f2017-07-07 12:08:29 +08007458 SND_PCI_QUIRK(0x17aa, 0x310c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
Dennis Wassenbergbef33e12019-06-28 10:54:53 +02007459 SND_PCI_QUIRK(0x17aa, 0x3111, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
Hui Wange41fc8c2018-06-25 14:40:56 +08007460 SND_PCI_QUIRK(0x17aa, 0x312a, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
Kailang Yang65811832018-04-25 17:07:27 +08007461 SND_PCI_QUIRK(0x17aa, 0x312f, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
Hui Wang8da5bbf2017-12-22 11:17:46 +08007462 SND_PCI_QUIRK(0x17aa, 0x313c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
Hui Wang2a36c162019-09-04 13:53:27 +08007463 SND_PCI_QUIRK(0x17aa, 0x3151, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC),
Aaron Ma8a6c55d2019-10-24 19:44:39 +08007464 SND_PCI_QUIRK(0x17aa, 0x3176, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC),
7465 SND_PCI_QUIRK(0x17aa, 0x3178, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC),
David Henningsson56f27012016-01-11 09:33:14 +01007466 SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
Takashi Iwaifedb2242014-11-13 07:11:38 +01007467 SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC),
Michał Wadowski56df90b2019-05-14 16:58:00 +02007468 SND_PCI_QUIRK(0x17aa, 0x3978, "Lenovo B50-70", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
David Henningssona4a9e082013-08-16 14:09:01 +02007469 SND_PCI_QUIRK(0x17aa, 0x5013, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Kailang Yang1bb3e062013-09-27 13:10:25 +02007470 SND_PCI_QUIRK(0x17aa, 0x501a, "Thinkpad", ALC283_FIXUP_INT_MIC),
Takashi Iwaic497d9f2014-10-08 12:14:40 +02007471 SND_PCI_QUIRK(0x17aa, 0x501e, "Thinkpad L440", ALC292_FIXUP_TPT440_DOCK),
David Henningssoncd5302c2013-08-19 12:22:33 +02007472 SND_PCI_QUIRK(0x17aa, 0x5026, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Jo-Philipp Wichf2aa1112015-04-13 12:47:26 +02007473 SND_PCI_QUIRK(0x17aa, 0x5034, "Thinkpad T450", ALC292_FIXUP_TPT440_DOCK),
Sebastian Wicki80b311d2015-03-23 17:23:11 +01007474 SND_PCI_QUIRK(0x17aa, 0x5036, "Thinkpad T450s", ALC292_FIXUP_TPT440_DOCK),
Ansgar Hegerfeld09ea9972015-05-14 12:31:32 +02007475 SND_PCI_QUIRK(0x17aa, 0x503c, "Thinkpad L450", ALC292_FIXUP_TPT440_DOCK),
Conrad Kostecki037e1192016-04-26 10:08:10 +02007476 SND_PCI_QUIRK(0x17aa, 0x504a, "ThinkPad X260", ALC292_FIXUP_TPT440_DOCK),
Hui Wang23adc192015-12-08 12:27:18 +08007477 SND_PCI_QUIRK(0x17aa, 0x504b, "Thinkpad", ALC293_FIXUP_LENOVO_SPK_NOISE),
Jaroslav Kysela0f087ee2016-06-24 15:13:16 +02007478 SND_PCI_QUIRK(0x17aa, 0x5050, "Thinkpad T560p", ALC292_FIXUP_TPT460),
Torsten Hilbrich9cd25742016-07-05 10:40:22 +02007479 SND_PCI_QUIRK(0x17aa, 0x5051, "Thinkpad L460", ALC292_FIXUP_TPT460),
Jaroslav Kysela0f087ee2016-06-24 15:13:16 +02007480 SND_PCI_QUIRK(0x17aa, 0x5053, "Thinkpad T460", ALC292_FIXUP_TPT460),
Kailang Yang61fcf8e2018-02-02 15:26:46 +08007481 SND_PCI_QUIRK(0x17aa, 0x505d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7482 SND_PCI_QUIRK(0x17aa, 0x505f, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7483 SND_PCI_QUIRK(0x17aa, 0x5062, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
David Henningssoncd5302c2013-08-19 12:22:33 +02007484 SND_PCI_QUIRK(0x17aa, 0x5109, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Kailang Yang61fcf8e2018-02-02 15:26:46 +08007485 SND_PCI_QUIRK(0x17aa, 0x511e, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7486 SND_PCI_QUIRK(0x17aa, 0x511f, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
David Henningsson012e7eb2012-08-08 08:43:37 +02007487 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K),
Takashi Iwai1d045db2011-07-07 18:23:21 +02007488 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
Ayman Bagabas0fbf21c2019-05-23 05:30:11 -04007489 SND_PCI_QUIRK(0x19e5, 0x3204, "Huawei MACH-WX9", ALC256_FIXUP_HUAWEI_MACH_WX9_PINS),
Anisse Astier02b504d2013-06-03 11:53:10 +02007490 SND_PCI_QUIRK(0x1b7d, 0xa831, "Ordissimo EVE2 ", ALC269VB_FIXUP_ORDISSIMO_EVE2), /* Also known as Malata PC-B1303 */
Hui Wang695d1ec2019-11-21 10:54:27 +08007491 SND_PCI_QUIRK(0x1d72, 0x1901, "RedmiBook 14", ALC256_FIXUP_ASUS_HEADSET_MIC),
Jan-Marek Glogowskibd9c10b2019-09-15 16:57:28 +02007492 SND_PCI_QUIRK(0x10ec, 0x118c, "Medion EE4254 MD62100", ALC256_FIXUP_MEDION_HEADSET_NO_PRESENCE),
Takashi Iwaia4297b52011-08-23 18:40:12 +02007493
Takashi Iwaia7f3eed2012-02-16 13:03:18 +01007494#if 0
Takashi Iwaia4297b52011-08-23 18:40:12 +02007495 /* Below is a quirk table taken from the old code.
7496 * Basically the device should work as is without the fixup table.
7497 * If BIOS doesn't give a proper info, enable the corresponding
7498 * fixup entry.
Jesper Juhl7d7eb9e2012-04-12 22:11:25 +02007499 */
Takashi Iwaia4297b52011-08-23 18:40:12 +02007500 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
7501 ALC269_FIXUP_AMIC),
7502 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269_FIXUP_AMIC),
Takashi Iwaia4297b52011-08-23 18:40:12 +02007503 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269_FIXUP_AMIC),
7504 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_FIXUP_AMIC),
7505 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269_FIXUP_AMIC),
7506 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269_FIXUP_AMIC),
7507 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269_FIXUP_AMIC),
7508 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269_FIXUP_AMIC),
7509 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_FIXUP_AMIC),
7510 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269_FIXUP_AMIC),
7511 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_FIXUP_AMIC),
7512 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_FIXUP_AMIC),
7513 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_FIXUP_AMIC),
7514 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_FIXUP_AMIC),
7515 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_FIXUP_AMIC),
7516 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_FIXUP_AMIC),
7517 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_FIXUP_AMIC),
7518 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_FIXUP_AMIC),
7519 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_FIXUP_AMIC),
7520 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_FIXUP_AMIC),
7521 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_FIXUP_AMIC),
7522 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_FIXUP_AMIC),
7523 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_FIXUP_AMIC),
7524 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_FIXUP_AMIC),
7525 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_FIXUP_AMIC),
7526 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_FIXUP_AMIC),
7527 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_FIXUP_AMIC),
7528 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_FIXUP_AMIC),
7529 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_FIXUP_AMIC),
7530 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_FIXUP_AMIC),
7531 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_FIXUP_AMIC),
7532 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_FIXUP_AMIC),
7533 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_FIXUP_AMIC),
7534 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_FIXUP_AMIC),
7535 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_FIXUP_AMIC),
7536 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_FIXUP_DMIC),
7537 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_FIXUP_AMIC),
7538 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_AMIC),
7539 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_FIXUP_DMIC),
7540 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_FIXUP_DMIC),
7541#endif
7542 {}
7543};
7544
David Henningsson214eef72014-07-22 14:09:35 +02007545static const struct snd_pci_quirk alc269_fixup_vendor_tbl[] = {
7546 SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC),
7547 SND_PCI_QUIRK_VENDOR(0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED),
7548 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
7549 SND_PCI_QUIRK_VENDOR(0x17aa, "Thinkpad", ALC269_FIXUP_THINKPAD_ACPI),
Ayman Bagabas0fbf21c2019-05-23 05:30:11 -04007550 SND_PCI_QUIRK_VENDOR(0x19e5, "Huawei Matebook", ALC255_FIXUP_MIC_MUTE_LED),
David Henningsson214eef72014-07-22 14:09:35 +02007551 {}
7552};
7553
Takashi Iwai1727a772013-01-10 09:52:52 +01007554static const struct hda_model_fixup alc269_fixup_models[] = {
Takashi Iwaia4297b52011-08-23 18:40:12 +02007555 {.id = ALC269_FIXUP_AMIC, .name = "laptop-amic"},
7556 {.id = ALC269_FIXUP_DMIC, .name = "laptop-dmic"},
Takashi Iwai6e72aa52012-06-25 10:52:25 +02007557 {.id = ALC269_FIXUP_STEREO_DMIC, .name = "alc269-dmic"},
7558 {.id = ALC271_FIXUP_DMIC, .name = "alc271-dmic"},
7559 {.id = ALC269_FIXUP_INV_DMIC, .name = "inv-dmic"},
David Henningsson7c478f02013-10-11 10:18:46 +02007560 {.id = ALC269_FIXUP_HEADSET_MIC, .name = "headset-mic"},
Takashi Iwaib0169512015-05-19 10:20:13 +02007561 {.id = ALC269_FIXUP_HEADSET_MODE, .name = "headset-mode"},
7562 {.id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC, .name = "headset-mode-no-hp-mic"},
David Henningsson108cc102012-07-20 10:37:25 +02007563 {.id = ALC269_FIXUP_LENOVO_DOCK, .name = "lenovo-dock"},
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01007564 {.id = ALC269_FIXUP_HP_GPIO_LED, .name = "hp-gpio-led"},
Jaroslav Kysela04d54662017-03-09 13:29:13 +01007565 {.id = ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED, .name = "hp-dock-gpio-mic1-led"},
David Henningssone32aa852013-06-17 11:04:02 +02007566 {.id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "dell-headset-multi"},
7567 {.id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE, .name = "dell-headset-dock"},
Takashi Iwaia26d96c2018-06-26 15:09:25 +02007568 {.id = ALC269_FIXUP_DELL3_MIC_NO_PRESENCE, .name = "dell-headset3"},
7569 {.id = ALC269_FIXUP_DELL4_MIC_NO_PRESENCE, .name = "dell-headset4"},
Kailang Yangbe8ef162014-04-08 15:19:49 +08007570 {.id = ALC283_FIXUP_CHROME_BOOK, .name = "alc283-dac-wcaps"},
Kailang Yang0202e992013-12-02 15:20:15 +08007571 {.id = ALC283_FIXUP_SENSE_COMBO_JACK, .name = "alc283-sense-combo"},
Takashi Iwai1c37c222014-05-06 17:34:42 +02007572 {.id = ALC292_FIXUP_TPT440_DOCK, .name = "tpt440-dock"},
Takashi Iwai9a811232015-12-09 15:17:43 +01007573 {.id = ALC292_FIXUP_TPT440, .name = "tpt440"},
Sven Eckelmannc636b952016-04-11 16:55:26 +02007574 {.id = ALC292_FIXUP_TPT460, .name = "tpt460"},
Takashi Iwaia26d96c2018-06-26 15:09:25 +02007575 {.id = ALC298_FIXUP_TPT470_DOCK, .name = "tpt470-dock"},
Takashi Iwaiba90d6a2017-05-22 16:38:47 +02007576 {.id = ALC233_FIXUP_LENOVO_MULTI_CODECS, .name = "dual-codecs"},
Takashi Iwai28d1d6d2017-10-18 14:01:58 +02007577 {.id = ALC700_FIXUP_INTEL_REFERENCE, .name = "alc700-ref"},
Takashi Iwaia26d96c2018-06-26 15:09:25 +02007578 {.id = ALC269_FIXUP_SONY_VAIO, .name = "vaio"},
7579 {.id = ALC269_FIXUP_DELL_M101Z, .name = "dell-m101z"},
7580 {.id = ALC269_FIXUP_ASUS_G73JW, .name = "asus-g73jw"},
7581 {.id = ALC269_FIXUP_LENOVO_EAPD, .name = "lenovo-eapd"},
7582 {.id = ALC275_FIXUP_SONY_HWEQ, .name = "sony-hweq"},
7583 {.id = ALC269_FIXUP_PCM_44K, .name = "pcm44k"},
7584 {.id = ALC269_FIXUP_LIFEBOOK, .name = "lifebook"},
7585 {.id = ALC269_FIXUP_LIFEBOOK_EXTMIC, .name = "lifebook-extmic"},
7586 {.id = ALC269_FIXUP_LIFEBOOK_HP_PIN, .name = "lifebook-hp-pin"},
7587 {.id = ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC, .name = "lifebook-u7x7"},
7588 {.id = ALC269VB_FIXUP_AMIC, .name = "alc269vb-amic"},
7589 {.id = ALC269VB_FIXUP_DMIC, .name = "alc269vb-dmic"},
7590 {.id = ALC269_FIXUP_HP_MUTE_LED_MIC1, .name = "hp-mute-led-mic1"},
7591 {.id = ALC269_FIXUP_HP_MUTE_LED_MIC2, .name = "hp-mute-led-mic2"},
7592 {.id = ALC269_FIXUP_HP_MUTE_LED_MIC3, .name = "hp-mute-led-mic3"},
7593 {.id = ALC269_FIXUP_HP_GPIO_MIC1_LED, .name = "hp-gpio-mic1"},
7594 {.id = ALC269_FIXUP_HP_LINE1_MIC1_LED, .name = "hp-line1-mic1"},
7595 {.id = ALC269_FIXUP_NO_SHUTUP, .name = "noshutup"},
7596 {.id = ALC286_FIXUP_SONY_MIC_NO_PRESENCE, .name = "sony-nomic"},
7597 {.id = ALC269_FIXUP_ASPIRE_HEADSET_MIC, .name = "aspire-headset-mic"},
7598 {.id = ALC269_FIXUP_ASUS_X101, .name = "asus-x101"},
7599 {.id = ALC271_FIXUP_HP_GATE_MIC_JACK, .name = "acer-ao7xx"},
7600 {.id = ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572, .name = "acer-aspire-e1"},
7601 {.id = ALC269_FIXUP_ACER_AC700, .name = "acer-ac700"},
7602 {.id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST, .name = "limit-mic-boost"},
7603 {.id = ALC269VB_FIXUP_ASUS_ZENBOOK, .name = "asus-zenbook"},
7604 {.id = ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A, .name = "asus-zenbook-ux31a"},
7605 {.id = ALC269VB_FIXUP_ORDISSIMO_EVE2, .name = "ordissimo"},
7606 {.id = ALC282_FIXUP_ASUS_TX300, .name = "asus-tx300"},
7607 {.id = ALC283_FIXUP_INT_MIC, .name = "alc283-int-mic"},
7608 {.id = ALC290_FIXUP_MONO_SPEAKERS_HSJACK, .name = "mono-speakers"},
7609 {.id = ALC290_FIXUP_SUBWOOFER_HSJACK, .name = "alc290-subwoofer"},
7610 {.id = ALC269_FIXUP_THINKPAD_ACPI, .name = "thinkpad"},
7611 {.id = ALC269_FIXUP_DMIC_THINKPAD_ACPI, .name = "dmic-thinkpad"},
7612 {.id = ALC255_FIXUP_ACER_MIC_NO_PRESENCE, .name = "alc255-acer"},
7613 {.id = ALC255_FIXUP_ASUS_MIC_NO_PRESENCE, .name = "alc255-asus"},
7614 {.id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc255-dell1"},
7615 {.id = ALC255_FIXUP_DELL2_MIC_NO_PRESENCE, .name = "alc255-dell2"},
7616 {.id = ALC293_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc293-dell1"},
7617 {.id = ALC283_FIXUP_HEADSET_MIC, .name = "alc283-headset"},
Takashi Iwaib3802782018-11-26 17:47:46 +01007618 {.id = ALC255_FIXUP_MIC_MUTE_LED, .name = "alc255-dell-mute"},
Takashi Iwaia26d96c2018-06-26 15:09:25 +02007619 {.id = ALC282_FIXUP_ASPIRE_V5_PINS, .name = "aspire-v5"},
7620 {.id = ALC280_FIXUP_HP_GPIO4, .name = "hp-gpio4"},
7621 {.id = ALC286_FIXUP_HP_GPIO_LED, .name = "hp-gpio-led"},
7622 {.id = ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY, .name = "hp-gpio2-hotkey"},
7623 {.id = ALC280_FIXUP_HP_DOCK_PINS, .name = "hp-dock-pins"},
7624 {.id = ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED, .name = "hp-dock-gpio-mic"},
7625 {.id = ALC280_FIXUP_HP_9480M, .name = "hp-9480m"},
7626 {.id = ALC288_FIXUP_DELL_HEADSET_MODE, .name = "alc288-dell-headset"},
7627 {.id = ALC288_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc288-dell1"},
7628 {.id = ALC288_FIXUP_DELL_XPS_13, .name = "alc288-dell-xps13"},
7629 {.id = ALC292_FIXUP_DELL_E7X, .name = "dell-e7x"},
7630 {.id = ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK, .name = "alc293-dell"},
7631 {.id = ALC298_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc298-dell1"},
7632 {.id = ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE, .name = "alc298-dell-aio"},
7633 {.id = ALC275_FIXUP_DELL_XPS, .name = "alc275-dell-xps"},
Takashi Iwaia26d96c2018-06-26 15:09:25 +02007634 {.id = ALC293_FIXUP_LENOVO_SPK_NOISE, .name = "lenovo-spk-noise"},
7635 {.id = ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY, .name = "lenovo-hotkey"},
7636 {.id = ALC255_FIXUP_DELL_SPK_NOISE, .name = "dell-spk-noise"},
Kailang Yang82aa0d72019-01-11 17:15:53 +08007637 {.id = ALC225_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc225-dell1"},
Takashi Iwaia26d96c2018-06-26 15:09:25 +02007638 {.id = ALC295_FIXUP_DISABLE_DAC3, .name = "alc295-disable-dac3"},
Jaroslav Kyselad2cd7952019-11-29 15:40:27 +01007639 {.id = ALC285_FIXUP_SPEAKER2_TO_DAC1, .name = "alc285-speaker2-to-dac1"},
Takashi Iwaia26d96c2018-06-26 15:09:25 +02007640 {.id = ALC280_FIXUP_HP_HEADSET_MIC, .name = "alc280-hp-headset"},
7641 {.id = ALC221_FIXUP_HP_FRONT_MIC, .name = "alc221-hp-mic"},
7642 {.id = ALC298_FIXUP_SPK_VOLUME, .name = "alc298-spk-volume"},
7643 {.id = ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER, .name = "dell-inspiron-7559"},
7644 {.id = ALC269_FIXUP_ATIV_BOOK_8, .name = "ativ-book"},
7645 {.id = ALC221_FIXUP_HP_MIC_NO_PRESENCE, .name = "alc221-hp-mic"},
7646 {.id = ALC256_FIXUP_ASUS_HEADSET_MODE, .name = "alc256-asus-headset"},
7647 {.id = ALC256_FIXUP_ASUS_MIC, .name = "alc256-asus-mic"},
7648 {.id = ALC256_FIXUP_ASUS_AIO_GPIO2, .name = "alc256-asus-aio"},
7649 {.id = ALC233_FIXUP_ASUS_MIC_NO_PRESENCE, .name = "alc233-asus"},
7650 {.id = ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE, .name = "alc233-eapd"},
7651 {.id = ALC294_FIXUP_LENOVO_MIC_LOCATION, .name = "alc294-lenovo-mic"},
7652 {.id = ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE, .name = "alc225-wyse"},
7653 {.id = ALC274_FIXUP_DELL_AIO_LINEOUT_VERB, .name = "alc274-dell-aio"},
7654 {.id = ALC255_FIXUP_DUMMY_LINEOUT_VERB, .name = "alc255-dummy-lineout"},
7655 {.id = ALC255_FIXUP_DELL_HEADSET_MIC, .name = "alc255-dell-headset"},
7656 {.id = ALC295_FIXUP_HP_X360, .name = "alc295-hp-x360"},
Kailang Yang8983eb62019-04-03 15:31:49 +08007657 {.id = ALC225_FIXUP_HEADSET_JACK, .name = "alc-headset-jack"},
7658 {.id = ALC295_FIXUP_CHROME_BOOK, .name = "alc-chrome-book"},
Bernhard Rosenkraenzere2a829b2019-03-05 00:38:19 +01007659 {.id = ALC299_FIXUP_PREDATOR_SPK, .name = "predator-spk"},
Tomas Espeletaa2ef03f2019-08-09 16:37:54 +02007660 {.id = ALC298_FIXUP_HUAWEI_MBX_STEREO, .name = "huawei-mbx-stereo"},
Jan-Marek Glogowskibd9c10b2019-09-15 16:57:28 +02007661 {.id = ALC256_FIXUP_MEDION_HEADSET_NO_PRESENCE, .name = "alc256-medion-headset"},
Takashi Iwai1d045db2011-07-07 18:23:21 +02007662 {}
7663};
Kailang Yangcfc5a842016-02-03 15:20:39 +08007664#define ALC225_STANDARD_PINS \
Kailang Yangcfc5a842016-02-03 15:20:39 +08007665 {0x21, 0x04211020}
Takashi Iwai1d045db2011-07-07 18:23:21 +02007666
Hui Wange8191a82015-04-24 13:39:59 +08007667#define ALC256_STANDARD_PINS \
7668 {0x12, 0x90a60140}, \
7669 {0x14, 0x90170110}, \
Hui Wange8191a82015-04-24 13:39:59 +08007670 {0x21, 0x02211020}
7671
David Henningssonfea185e2014-09-03 10:23:04 +02007672#define ALC282_STANDARD_PINS \
Hui Wang11580292015-08-03 11:03:49 +08007673 {0x14, 0x90170110}
Kailang Yange1e62b92015-04-08 16:01:22 +08007674
David Henningssonfea185e2014-09-03 10:23:04 +02007675#define ALC290_STANDARD_PINS \
Hui Wang11580292015-08-03 11:03:49 +08007676 {0x12, 0x99a30130}
David Henningssonfea185e2014-09-03 10:23:04 +02007677
7678#define ALC292_STANDARD_PINS \
7679 {0x14, 0x90170110}, \
Hui Wang11580292015-08-03 11:03:49 +08007680 {0x15, 0x0221401f}
Kailang Yang977e6272015-05-18 15:31:20 +08007681
Hui Wang3f6409702016-09-11 11:26:16 +08007682#define ALC295_STANDARD_PINS \
7683 {0x12, 0xb7a60130}, \
7684 {0x14, 0x90170110}, \
Hui Wang3f6409702016-09-11 11:26:16 +08007685 {0x21, 0x04211020}
7686
Woodrow Shen703867e2015-08-05 12:34:12 +08007687#define ALC298_STANDARD_PINS \
7688 {0x12, 0x90a60130}, \
7689 {0x21, 0x03211020}
7690
Hui Wange1918932014-05-26 16:22:44 +08007691static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
Kailang Yang8a328ac2018-08-21 16:54:41 +08007692 SND_HDA_PIN_QUIRK(0x10ec0221, 0x103c, "HP Workstation", ALC221_FIXUP_HP_HEADSET_MIC,
7693 {0x14, 0x01014020},
7694 {0x17, 0x90170110},
7695 {0x18, 0x02a11030},
7696 {0x19, 0x0181303F},
7697 {0x21, 0x0221102f}),
Chris Chiu5824ce82017-02-28 14:17:11 -06007698 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1025, "Acer", ALC255_FIXUP_ACER_MIC_NO_PRESENCE,
7699 {0x12, 0x90a601c0},
7700 {0x14, 0x90171120},
7701 {0x21, 0x02211030}),
Chris Chiu615966a2017-02-28 14:17:12 -06007702 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1043, "ASUS", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE,
7703 {0x14, 0x90170110},
7704 {0x1b, 0x90a70130},
7705 {0x21, 0x03211020}),
7706 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1043, "ASUS", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE,
7707 {0x1a, 0x90a70130},
7708 {0x1b, 0x90170110},
7709 {0x21, 0x03211020}),
David Henningsson2ae95572016-02-25 09:37:05 +01007710 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
Kailang Yangcfc5a842016-02-03 15:20:39 +08007711 ALC225_STANDARD_PINS,
Hui Wang8a132092016-07-08 14:26:57 +08007712 {0x12, 0xb7a60130},
Kailang Yangcfc5a842016-02-03 15:20:39 +08007713 {0x14, 0x901701a0}),
David Henningsson2ae95572016-02-25 09:37:05 +01007714 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
Kailang Yangcfc5a842016-02-03 15:20:39 +08007715 ALC225_STANDARD_PINS,
Hui Wang8a132092016-07-08 14:26:57 +08007716 {0x12, 0xb7a60130},
Kailang Yangcfc5a842016-02-03 15:20:39 +08007717 {0x14, 0x901701b0}),
Hui Wang8a132092016-07-08 14:26:57 +08007718 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
7719 ALC225_STANDARD_PINS,
7720 {0x12, 0xb7a60150},
7721 {0x14, 0x901701a0}),
7722 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
7723 ALC225_STANDARD_PINS,
7724 {0x12, 0xb7a60150},
7725 {0x14, 0x901701b0}),
7726 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
7727 ALC225_STANDARD_PINS,
7728 {0x12, 0xb7a60130},
7729 {0x1b, 0x90170110}),
Kai-Heng Feng0ce48e12017-11-20 02:29:13 -05007730 SND_HDA_PIN_QUIRK(0x10ec0233, 0x8086, "Intel NUC Skull Canyon", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
7731 {0x1b, 0x01111010},
7732 {0x1e, 0x01451130},
7733 {0x21, 0x02211020}),
Hui Wang986376b2018-05-30 12:33:07 +08007734 SND_HDA_PIN_QUIRK(0x10ec0235, 0x17aa, "Lenovo", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY,
7735 {0x12, 0x90a60140},
7736 {0x14, 0x90170110},
7737 {0x19, 0x02a11030},
7738 {0x21, 0x02211020}),
Hui Wange41fc8c2018-06-25 14:40:56 +08007739 SND_HDA_PIN_QUIRK(0x10ec0235, 0x17aa, "Lenovo", ALC294_FIXUP_LENOVO_MIC_LOCATION,
7740 {0x14, 0x90170110},
7741 {0x19, 0x02a11030},
7742 {0x1a, 0x02a11040},
7743 {0x1b, 0x01014020},
7744 {0x21, 0x0221101f}),
Hui Wangc6b17f12018-07-06 15:14:11 +08007745 SND_HDA_PIN_QUIRK(0x10ec0235, 0x17aa, "Lenovo", ALC294_FIXUP_LENOVO_MIC_LOCATION,
7746 {0x14, 0x90170110},
Hui Wangd06fb562018-10-10 11:57:25 +08007747 {0x19, 0x02a11030},
7748 {0x1a, 0x02a11040},
7749 {0x1b, 0x01011020},
7750 {0x21, 0x0221101f}),
7751 SND_HDA_PIN_QUIRK(0x10ec0235, 0x17aa, "Lenovo", ALC294_FIXUP_LENOVO_MIC_LOCATION,
7752 {0x14, 0x90170110},
Hui Wangc6b17f12018-07-06 15:14:11 +08007753 {0x19, 0x02a11020},
7754 {0x1a, 0x02a11030},
7755 {0x21, 0x0221101f}),
Hui Wangc77900e2014-09-03 11:31:07 +08007756 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE,
Hui Wangc77900e2014-09-03 11:31:07 +08007757 {0x14, 0x90170110},
Hui Wangc77900e2014-09-03 11:31:07 +08007758 {0x21, 0x02211020}),
David Henningsson76c21322014-06-24 14:46:54 +02007759 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang86c72d12016-05-25 12:12:32 +08007760 {0x14, 0x90170130},
7761 {0x21, 0x02211040}),
7762 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningsson76c21322014-06-24 14:46:54 +02007763 {0x12, 0x90a60140},
7764 {0x14, 0x90170110},
David Henningsson76c21322014-06-24 14:46:54 +02007765 {0x21, 0x02211020}),
7766 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7767 {0x12, 0x90a60160},
7768 {0x14, 0x90170120},
David Henningsson76c21322014-06-24 14:46:54 +02007769 {0x21, 0x02211030}),
7770 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang392c9da2016-09-26 10:59:38 +08007771 {0x14, 0x90170110},
7772 {0x1b, 0x02011020},
7773 {0x21, 0x0221101f}),
7774 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang6aecd872016-10-20 14:03:33 +08007775 {0x14, 0x90170110},
7776 {0x1b, 0x01011020},
7777 {0x21, 0x0221101f}),
7778 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssoncba59972015-07-22 10:00:25 +02007779 {0x14, 0x90170130},
David Henningssoncba59972015-07-22 10:00:25 +02007780 {0x1b, 0x01014020},
David Henningssoncba59972015-07-22 10:00:25 +02007781 {0x21, 0x0221103f}),
7782 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang59ec4b52016-08-04 15:28:04 +08007783 {0x14, 0x90170130},
Hui Wang6aecd872016-10-20 14:03:33 +08007784 {0x1b, 0x01011020},
7785 {0x21, 0x0221103f}),
7786 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7787 {0x14, 0x90170130},
Hui Wang59ec4b52016-08-04 15:28:04 +08007788 {0x1b, 0x02011020},
7789 {0x21, 0x0221103f}),
7790 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Woodrow Shene9c28e12015-07-25 10:36:16 +08007791 {0x14, 0x90170150},
Woodrow Shene9c28e12015-07-25 10:36:16 +08007792 {0x1b, 0x02011020},
Woodrow Shene9c28e12015-07-25 10:36:16 +08007793 {0x21, 0x0221105f}),
7794 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Woodrow Shene9c28e12015-07-25 10:36:16 +08007795 {0x14, 0x90170110},
Woodrow Shene9c28e12015-07-25 10:36:16 +08007796 {0x1b, 0x01014020},
Woodrow Shene9c28e12015-07-25 10:36:16 +08007797 {0x21, 0x0221101f}),
7798 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningsson76c21322014-06-24 14:46:54 +02007799 {0x12, 0x90a60160},
7800 {0x14, 0x90170120},
7801 {0x17, 0x90170140},
David Henningsson76c21322014-06-24 14:46:54 +02007802 {0x21, 0x0321102f}),
7803 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7804 {0x12, 0x90a60160},
7805 {0x14, 0x90170130},
David Henningsson76c21322014-06-24 14:46:54 +02007806 {0x21, 0x02211040}),
7807 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7808 {0x12, 0x90a60160},
7809 {0x14, 0x90170140},
David Henningsson76c21322014-06-24 14:46:54 +02007810 {0x21, 0x02211050}),
7811 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7812 {0x12, 0x90a60170},
7813 {0x14, 0x90170120},
David Henningsson76c21322014-06-24 14:46:54 +02007814 {0x21, 0x02211030}),
7815 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7816 {0x12, 0x90a60170},
7817 {0x14, 0x90170130},
David Henningsson76c21322014-06-24 14:46:54 +02007818 {0x21, 0x02211040}),
Hui Wang70658b92015-03-06 14:03:57 +08007819 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang70658b92015-03-06 14:03:57 +08007820 {0x12, 0x90a60170},
Hui Wang0a1f90a2016-01-13 11:51:38 +08007821 {0x14, 0x90171130},
7822 {0x21, 0x02211040}),
7823 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7824 {0x12, 0x90a60170},
Hui Wang70658b92015-03-06 14:03:57 +08007825 {0x14, 0x90170140},
Hui Wang70658b92015-03-06 14:03:57 +08007826 {0x21, 0x02211050}),
David Henningsson9b5a4e32015-05-11 14:04:14 +02007827 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell Inspiron 5548", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningsson9b5a4e32015-05-11 14:04:14 +02007828 {0x12, 0x90a60180},
7829 {0x14, 0x90170130},
David Henningsson9b5a4e32015-05-11 14:04:14 +02007830 {0x21, 0x02211040}),
AceLan Kaof90d83b2016-06-03 14:45:25 +08007831 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell Inspiron 5565", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7832 {0x12, 0x90a60180},
7833 {0x14, 0x90170120},
7834 {0x21, 0x02211030}),
Hui Wang989dbe42016-11-23 16:05:38 +08007835 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7836 {0x1b, 0x01011020},
7837 {0x21, 0x02211010}),
Chris Chiuc1732ed2017-02-28 14:17:13 -06007838 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC,
7839 {0x14, 0x90170110},
7840 {0x1b, 0x90a70130},
7841 {0x21, 0x04211020}),
7842 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC,
7843 {0x14, 0x90170110},
7844 {0x1b, 0x90a70130},
7845 {0x21, 0x03211020}),
Jian-Hong Pane1037352019-03-22 11:37:18 +08007846 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE,
Chris Chiua806ef12019-03-22 11:37:20 +08007847 {0x12, 0x90a60130},
7848 {0x14, 0x90170110},
7849 {0x21, 0x03211020}),
7850 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE,
Jian-Hong Pan6ac371a2019-03-22 11:37:22 +08007851 {0x12, 0x90a60130},
7852 {0x14, 0x90170110},
7853 {0x21, 0x04211020}),
7854 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE,
Jian-Hong Pane1037352019-03-22 11:37:18 +08007855 {0x1a, 0x90a70130},
7856 {0x1b, 0x90170110},
7857 {0x21, 0x03211020}),
David Henningssoncf51eb92014-10-30 08:26:02 +01007858 SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC280_FIXUP_HP_GPIO4,
7859 {0x12, 0x90a60130},
David Henningssoncf51eb92014-10-30 08:26:02 +01007860 {0x14, 0x90170110},
7861 {0x15, 0x0421101f},
Hui Wang11580292015-08-03 11:03:49 +08007862 {0x1a, 0x04a11020}),
Hui Wang02796612014-09-03 11:31:11 +08007863 SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED,
7864 {0x12, 0x90a60140},
Hui Wang02796612014-09-03 11:31:11 +08007865 {0x14, 0x90170110},
7866 {0x15, 0x0421101f},
Hui Wang02796612014-09-03 11:31:11 +08007867 {0x18, 0x02811030},
Hui Wang02796612014-09-03 11:31:11 +08007868 {0x1a, 0x04a1103f},
Hui Wang11580292015-08-03 11:03:49 +08007869 {0x1b, 0x02011020}),
David Henningsson42304472014-07-22 11:42:17 +02007870 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP 15 Touchsmart", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007871 ALC282_STANDARD_PINS,
David Henningsson42304472014-07-22 11:42:17 +02007872 {0x12, 0x99a30130},
David Henningsson42304472014-07-22 11:42:17 +02007873 {0x19, 0x03a11020},
David Henningsson42304472014-07-22 11:42:17 +02007874 {0x21, 0x0321101f}),
Hui Wang2c609992014-09-03 11:31:08 +08007875 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007876 ALC282_STANDARD_PINS,
Hui Wang2c609992014-09-03 11:31:08 +08007877 {0x12, 0x99a30130},
Hui Wang2c609992014-09-03 11:31:08 +08007878 {0x19, 0x03a11020},
Hui Wang2c609992014-09-03 11:31:08 +08007879 {0x21, 0x03211040}),
7880 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007881 ALC282_STANDARD_PINS,
Hui Wang2c609992014-09-03 11:31:08 +08007882 {0x12, 0x99a30130},
Hui Wang2c609992014-09-03 11:31:08 +08007883 {0x19, 0x03a11030},
Hui Wang2c609992014-09-03 11:31:08 +08007884 {0x21, 0x03211020}),
7885 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007886 ALC282_STANDARD_PINS,
Hui Wang2c609992014-09-03 11:31:08 +08007887 {0x12, 0x99a30130},
Hui Wang2c609992014-09-03 11:31:08 +08007888 {0x19, 0x04a11020},
Hui Wang2c609992014-09-03 11:31:08 +08007889 {0x21, 0x0421101f}),
Hui Wang200afc02014-09-03 11:31:10 +08007890 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED,
David Henningssonaec856d2014-09-03 10:23:05 +02007891 ALC282_STANDARD_PINS,
Hui Wang200afc02014-09-03 11:31:10 +08007892 {0x12, 0x90a60140},
Hui Wang200afc02014-09-03 11:31:10 +08007893 {0x19, 0x04a11030},
Hui Wang200afc02014-09-03 11:31:10 +08007894 {0x21, 0x04211020}),
David Henningsson76c21322014-06-24 14:46:54 +02007895 SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007896 ALC282_STANDARD_PINS,
David Henningsson76c21322014-06-24 14:46:54 +02007897 {0x12, 0x90a60130},
David Henningsson76c21322014-06-24 14:46:54 +02007898 {0x21, 0x0321101f}),
7899 SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
7900 {0x12, 0x90a60160},
7901 {0x14, 0x90170120},
David Henningsson76c21322014-06-24 14:46:54 +02007902 {0x21, 0x02211030}),
Hui Wangbc262172014-09-03 11:31:05 +08007903 SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007904 ALC282_STANDARD_PINS,
Hui Wangbc262172014-09-03 11:31:05 +08007905 {0x12, 0x90a60130},
Hui Wangbc262172014-09-03 11:31:05 +08007906 {0x19, 0x03a11020},
Hui Wangbc262172014-09-03 11:31:05 +08007907 {0x21, 0x0321101f}),
Hui Wangc8c6ee62019-02-14 11:41:33 +08007908 SND_HDA_PIN_QUIRK(0x10ec0285, 0x17aa, "Lenovo", ALC285_FIXUP_LENOVO_PC_BEEP_IN_NOISE,
Hui Wangc4cfcf62018-11-26 14:17:16 +08007909 {0x12, 0x90a60130},
7910 {0x14, 0x90170110},
7911 {0x19, 0x04a11040},
7912 {0x21, 0x04211020}),
Chris Chiu33aaebd2018-12-05 14:48:53 +08007913 SND_HDA_PIN_QUIRK(0x10ec0286, 0x1025, "Acer", ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE,
7914 {0x12, 0x90a60130},
7915 {0x17, 0x90170110},
7916 {0x21, 0x02211020}),
Takashi Iwaid44a6862018-06-19 23:04:03 +02007917 SND_HDA_PIN_QUIRK(0x10ec0288, 0x1028, "Dell", ALC288_FIXUP_DELL1_MIC_NO_PRESENCE,
Kailang Yange1e62b92015-04-08 16:01:22 +08007918 {0x12, 0x90a60120},
Kailang Yange1e62b92015-04-08 16:01:22 +08007919 {0x14, 0x90170110},
Kailang Yange1e62b92015-04-08 16:01:22 +08007920 {0x21, 0x0321101f}),
Hui Wange4442bc2014-09-03 11:31:09 +08007921 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007922 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08007923 {0x15, 0x04211040},
Hui Wange4442bc2014-09-03 11:31:09 +08007924 {0x18, 0x90170112},
Hui Wang11580292015-08-03 11:03:49 +08007925 {0x1a, 0x04a11020}),
Hui Wange4442bc2014-09-03 11:31:09 +08007926 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007927 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08007928 {0x15, 0x04211040},
Hui Wange4442bc2014-09-03 11:31:09 +08007929 {0x18, 0x90170110},
Hui Wang11580292015-08-03 11:03:49 +08007930 {0x1a, 0x04a11020}),
Hui Wange4442bc2014-09-03 11:31:09 +08007931 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007932 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08007933 {0x15, 0x0421101f},
Hui Wang11580292015-08-03 11:03:49 +08007934 {0x1a, 0x04a11020}),
Hui Wange4442bc2014-09-03 11:31:09 +08007935 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007936 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08007937 {0x15, 0x04211020},
Hui Wang11580292015-08-03 11:03:49 +08007938 {0x1a, 0x04a11040}),
Hui Wange4442bc2014-09-03 11:31:09 +08007939 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007940 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08007941 {0x14, 0x90170110},
7942 {0x15, 0x04211020},
Hui Wang11580292015-08-03 11:03:49 +08007943 {0x1a, 0x04a11040}),
Hui Wange4442bc2014-09-03 11:31:09 +08007944 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007945 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08007946 {0x14, 0x90170110},
7947 {0x15, 0x04211020},
Hui Wang11580292015-08-03 11:03:49 +08007948 {0x1a, 0x04a11020}),
Hui Wange4442bc2014-09-03 11:31:09 +08007949 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007950 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08007951 {0x14, 0x90170110},
7952 {0x15, 0x0421101f},
Hui Wang11580292015-08-03 11:03:49 +08007953 {0x1a, 0x04a11020}),
Hui Wange8818fa2014-09-03 11:31:04 +08007954 SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007955 ALC292_STANDARD_PINS,
Hui Wange8818fa2014-09-03 11:31:04 +08007956 {0x12, 0x90a60140},
Hui Wange8818fa2014-09-03 11:31:04 +08007957 {0x16, 0x01014020},
Hui Wang11580292015-08-03 11:03:49 +08007958 {0x19, 0x01a19030}),
Hui Wange8818fa2014-09-03 11:31:04 +08007959 SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007960 ALC292_STANDARD_PINS,
Hui Wange8818fa2014-09-03 11:31:04 +08007961 {0x12, 0x90a60140},
Hui Wange8818fa2014-09-03 11:31:04 +08007962 {0x16, 0x01014020},
7963 {0x18, 0x02a19031},
Hui Wang11580292015-08-03 11:03:49 +08007964 {0x19, 0x01a1903e}),
David Henningsson76c21322014-06-24 14:46:54 +02007965 SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007966 ALC292_STANDARD_PINS,
Hui Wang11580292015-08-03 11:03:49 +08007967 {0x12, 0x90a60140}),
David Henningsson76c21322014-06-24 14:46:54 +02007968 SND_HDA_PIN_QUIRK(0x10ec0293, 0x1028, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007969 ALC292_STANDARD_PINS,
David Henningsson76c21322014-06-24 14:46:54 +02007970 {0x13, 0x90a60140},
David Henningsson76c21322014-06-24 14:46:54 +02007971 {0x16, 0x21014020},
Hui Wang11580292015-08-03 11:03:49 +08007972 {0x19, 0x21a19030}),
David Henningssone03fdbd2014-06-27 08:41:59 +02007973 SND_HDA_PIN_QUIRK(0x10ec0293, 0x1028, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007974 ALC292_STANDARD_PINS,
Hui Wang11580292015-08-03 11:03:49 +08007975 {0x13, 0x90a60140}),
Chris Chiud8ae4582018-12-07 17:17:11 +08007976 SND_HDA_PIN_QUIRK(0x10ec0294, 0x1043, "ASUS", ALC294_FIXUP_ASUS_MIC,
7977 {0x14, 0x90170110},
7978 {0x1b, 0x90a70130},
7979 {0x21, 0x04211020}),
Jian-Hong Pan0bea4cc2018-12-07 17:17:13 +08007980 SND_HDA_PIN_QUIRK(0x10ec0294, 0x1043, "ASUS", ALC294_FIXUP_ASUS_SPK,
7981 {0x12, 0x90a60130},
7982 {0x17, 0x90170110},
Jian-Hong Pan8bb37a22019-02-21 17:00:18 +08007983 {0x21, 0x03211020}),
7984 SND_HDA_PIN_QUIRK(0x10ec0294, 0x1043, "ASUS", ALC294_FIXUP_ASUS_SPK,
7985 {0x12, 0x90a60130},
7986 {0x17, 0x90170110},
Jian-Hong Pan0bea4cc2018-12-07 17:17:13 +08007987 {0x21, 0x04211020}),
Takashi Iwai3887c262019-04-30 15:10:01 +02007988 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1043, "ASUS", ALC294_FIXUP_ASUS_SPK,
7989 {0x12, 0x90a60130},
7990 {0x17, 0x90170110},
7991 {0x21, 0x03211020}),
Kailang Yangfbc57122019-07-15 10:41:50 +08007992 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
Kailang Yang0a29c572019-04-24 16:34:25 +08007993 {0x14, 0x90170110},
7994 {0x21, 0x04211020}),
Kailang Yangfbc57122019-07-15 10:41:50 +08007995 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
7996 {0x14, 0x90170110},
7997 {0x21, 0x04211030}),
Hui Wang3f6409702016-09-11 11:26:16 +08007998 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wangf771d5b2016-10-18 10:59:09 +08007999 ALC295_STANDARD_PINS,
8000 {0x17, 0x21014020},
8001 {0x18, 0x21a19030}),
8002 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
8003 ALC295_STANDARD_PINS,
8004 {0x17, 0x21014040},
8005 {0x18, 0x21a19050}),
Hui Wang3f307832017-03-23 10:00:25 +08008006 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
8007 ALC295_STANDARD_PINS),
Kailang Yang977e6272015-05-18 15:31:20 +08008008 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
Woodrow Shen703867e2015-08-05 12:34:12 +08008009 ALC298_STANDARD_PINS,
Takashi Iwai9f502ff2015-08-05 12:09:45 +02008010 {0x17, 0x90170110}),
8011 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
8012 ALC298_STANDARD_PINS,
Woodrow Shen703867e2015-08-05 12:34:12 +08008013 {0x17, 0x90170140}),
8014 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
8015 ALC298_STANDARD_PINS,
Takashi Iwai9f502ff2015-08-05 12:09:45 +02008016 {0x17, 0x90170150}),
Kai-Heng Feng9f1bc2c42017-02-16 15:26:54 +08008017 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_SPK_VOLUME,
8018 {0x12, 0xb7a60140},
8019 {0x13, 0xb7a60150},
8020 {0x17, 0x90170110},
8021 {0x1a, 0x03011020},
8022 {0x21, 0x03211030}),
James McDonnell54324222019-09-16 14:53:38 +00008023 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_ALIENWARE_MIC_NO_PRESENCE,
8024 {0x12, 0xb7a60140},
8025 {0x17, 0x90170110},
8026 {0x1a, 0x03a11030},
8027 {0x21, 0x03211020}),
Kailang Yangfcc6c872017-06-29 15:21:27 +08008028 SND_HDA_PIN_QUIRK(0x10ec0299, 0x1028, "Dell", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
8029 ALC225_STANDARD_PINS,
8030 {0x12, 0xb7a60130},
Kailang Yangfcc6c872017-06-29 15:21:27 +08008031 {0x17, 0x90170110}),
Hui Wange1918932014-05-26 16:22:44 +08008032 {}
8033};
Takashi Iwai1d045db2011-07-07 18:23:21 +02008034
Hui Wang7c0a6932019-08-16 14:27:40 +08008035/* This is the fallback pin_fixup_tbl for alc269 family, to make the tbl match
8036 * more machines, don't need to match all valid pins, just need to match
8037 * all the pins defined in the tbl. Just because of this reason, it is possible
8038 * that a single machine matches multiple tbls, so there is one limitation:
8039 * at most one tbl is allowed to define for the same vendor and same codec
8040 */
8041static const struct snd_hda_pin_quirk alc269_fallback_pin_fixup_tbl[] = {
8042 SND_HDA_PIN_QUIRK(0x10ec0289, 0x1028, "Dell", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
8043 {0x19, 0x40000000},
8044 {0x1b, 0x40000000}),
Hui Wangaed8c7f2019-11-21 10:26:43 +08008045 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
8046 {0x19, 0x40000000},
8047 {0x1a, 0x40000000}),
Hui Wangd64ebdb2019-11-21 10:26:44 +08008048 SND_HDA_PIN_QUIRK(0x10ec0236, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
8049 {0x19, 0x40000000},
8050 {0x1a, 0x40000000}),
Hui Wang5815bdf2019-12-11 13:13:21 +08008051 SND_HDA_PIN_QUIRK(0x10ec0274, 0x1028, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB,
8052 {0x19, 0x40000000},
8053 {0x1a, 0x40000000}),
Hui Wang7c0a6932019-08-16 14:27:40 +08008054 {}
8055};
8056
Takashi Iwai546bb672012-03-07 08:37:19 +01008057static void alc269_fill_coef(struct hda_codec *codec)
Takashi Iwai1d045db2011-07-07 18:23:21 +02008058{
Kailang Yang526af6e2012-03-07 08:25:20 +01008059 struct alc_spec *spec = codec->spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008060 int val;
8061
Kailang Yang526af6e2012-03-07 08:25:20 +01008062 if (spec->codec_variant != ALC269_TYPE_ALC269VB)
Takashi Iwai546bb672012-03-07 08:37:19 +01008063 return;
Kailang Yang526af6e2012-03-07 08:25:20 +01008064
Takashi Iwai1bb7e432011-10-17 16:50:59 +02008065 if ((alc_get_coef0(codec) & 0x00ff) < 0x015) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02008066 alc_write_coef_idx(codec, 0xf, 0x960b);
8067 alc_write_coef_idx(codec, 0xe, 0x8817);
8068 }
8069
Takashi Iwai1bb7e432011-10-17 16:50:59 +02008070 if ((alc_get_coef0(codec) & 0x00ff) == 0x016) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02008071 alc_write_coef_idx(codec, 0xf, 0x960b);
8072 alc_write_coef_idx(codec, 0xe, 0x8814);
8073 }
8074
Takashi Iwai1bb7e432011-10-17 16:50:59 +02008075 if ((alc_get_coef0(codec) & 0x00ff) == 0x017) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02008076 /* Power up output pin */
Takashi Iwai98b24882014-08-18 13:47:50 +02008077 alc_update_coef_idx(codec, 0x04, 0, 1<<11);
Takashi Iwai1d045db2011-07-07 18:23:21 +02008078 }
8079
Takashi Iwai1bb7e432011-10-17 16:50:59 +02008080 if ((alc_get_coef0(codec) & 0x00ff) == 0x018) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02008081 val = alc_read_coef_idx(codec, 0xd);
Takashi Iwaif3ee07d2014-08-15 17:35:00 +02008082 if (val != -1 && (val & 0x0c00) >> 10 != 0x1) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02008083 /* Capless ramp up clock control */
8084 alc_write_coef_idx(codec, 0xd, val | (1<<10));
8085 }
8086 val = alc_read_coef_idx(codec, 0x17);
Takashi Iwaif3ee07d2014-08-15 17:35:00 +02008087 if (val != -1 && (val & 0x01c0) >> 6 != 0x4) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02008088 /* Class D power on reset */
8089 alc_write_coef_idx(codec, 0x17, val | (1<<7));
8090 }
8091 }
8092
Takashi Iwai98b24882014-08-18 13:47:50 +02008093 /* HP */
8094 alc_update_coef_idx(codec, 0x4, 0, 1<<11);
Takashi Iwai1d045db2011-07-07 18:23:21 +02008095}
8096
8097/*
8098 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02008099static int patch_alc269(struct hda_codec *codec)
8100{
8101 struct alc_spec *spec;
Takashi Iwai3de95172012-05-07 18:03:15 +02008102 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008103
Takashi Iwai3de95172012-05-07 18:03:15 +02008104 err = alc_alloc_spec(codec, 0x0b);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008105 if (err < 0)
Takashi Iwai3de95172012-05-07 18:03:15 +02008106 return err;
8107
8108 spec = codec->spec;
Takashi Iwai08c189f2012-12-19 15:22:24 +01008109 spec->gen.shared_mic_vref_pin = 0x18;
Kailang Yang317d9312019-05-23 14:43:04 +08008110 codec->power_save_node = 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008111
Takashi Iwai225068a2015-05-29 10:42:14 +02008112#ifdef CONFIG_PM
8113 codec->patch_ops.suspend = alc269_suspend;
8114 codec->patch_ops.resume = alc269_resume;
8115#endif
Kailang Yangc2d6af52017-06-21 14:50:54 +08008116 spec->shutup = alc_default_shutup;
8117 spec->init_hook = alc_default_init;
Takashi Iwai225068a2015-05-29 10:42:14 +02008118
Takashi Iwai7639a062015-03-03 10:07:24 +01008119 switch (codec->core.vendor_id) {
Kailang Yang065380f2013-01-10 10:25:48 +01008120 case 0x10ec0269:
Takashi Iwai1d045db2011-07-07 18:23:21 +02008121 spec->codec_variant = ALC269_TYPE_ALC269VA;
Takashi Iwai1bb7e432011-10-17 16:50:59 +02008122 switch (alc_get_coef0(codec) & 0x00f0) {
8123 case 0x0010:
Takashi Iwai5100cd02014-02-15 10:03:19 +01008124 if (codec->bus->pci &&
8125 codec->bus->pci->subsystem_vendor == 0x1025 &&
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008126 spec->cdefine.platform_type == 1)
Takashi Iwai20ca0c32011-10-17 16:00:35 +02008127 err = alc_codec_rename(codec, "ALC271X");
Takashi Iwai1d045db2011-07-07 18:23:21 +02008128 spec->codec_variant = ALC269_TYPE_ALC269VB;
Takashi Iwai1bb7e432011-10-17 16:50:59 +02008129 break;
8130 case 0x0020:
Takashi Iwai5100cd02014-02-15 10:03:19 +01008131 if (codec->bus->pci &&
8132 codec->bus->pci->subsystem_vendor == 0x17aa &&
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008133 codec->bus->pci->subsystem_device == 0x21f3)
Takashi Iwai20ca0c32011-10-17 16:00:35 +02008134 err = alc_codec_rename(codec, "ALC3202");
Takashi Iwai1d045db2011-07-07 18:23:21 +02008135 spec->codec_variant = ALC269_TYPE_ALC269VC;
Takashi Iwai1bb7e432011-10-17 16:50:59 +02008136 break;
Kailang Yangadcc70b2012-05-25 08:08:38 +02008137 case 0x0030:
8138 spec->codec_variant = ALC269_TYPE_ALC269VD;
8139 break;
Takashi Iwai1bb7e432011-10-17 16:50:59 +02008140 default:
Takashi Iwai1d045db2011-07-07 18:23:21 +02008141 alc_fix_pll_init(codec, 0x20, 0x04, 15);
Takashi Iwai1bb7e432011-10-17 16:50:59 +02008142 }
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008143 if (err < 0)
8144 goto error;
Kailang Yangc2d6af52017-06-21 14:50:54 +08008145 spec->shutup = alc269_shutup;
Takashi Iwai546bb672012-03-07 08:37:19 +01008146 spec->init_hook = alc269_fill_coef;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008147 alc269_fill_coef(codec);
Kailang Yang065380f2013-01-10 10:25:48 +01008148 break;
8149
8150 case 0x10ec0280:
8151 case 0x10ec0290:
8152 spec->codec_variant = ALC269_TYPE_ALC280;
8153 break;
8154 case 0x10ec0282:
Kailang Yang065380f2013-01-10 10:25:48 +01008155 spec->codec_variant = ALC269_TYPE_ALC282;
Kailang Yang7b5c7a02014-03-18 16:15:54 +08008156 spec->shutup = alc282_shutup;
8157 spec->init_hook = alc282_init;
Kailang Yang065380f2013-01-10 10:25:48 +01008158 break;
Kailang Yang2af02be2013-08-22 10:03:50 +02008159 case 0x10ec0233:
8160 case 0x10ec0283:
8161 spec->codec_variant = ALC269_TYPE_ALC283;
8162 spec->shutup = alc283_shutup;
8163 spec->init_hook = alc283_init;
8164 break;
Kailang Yang065380f2013-01-10 10:25:48 +01008165 case 0x10ec0284:
8166 case 0x10ec0292:
8167 spec->codec_variant = ALC269_TYPE_ALC284;
8168 break;
Kailang Yang161ebf22013-10-24 11:36:33 +02008169 case 0x10ec0293:
Kailang Yang4731d5d2017-06-30 15:22:57 +08008170 spec->codec_variant = ALC269_TYPE_ALC293;
Kailang Yang161ebf22013-10-24 11:36:33 +02008171 break;
Kailang Yang7fc7d042013-04-25 11:04:43 +02008172 case 0x10ec0286:
Kailang Yang7c665932014-04-14 15:09:44 +08008173 case 0x10ec0288:
Kailang Yang7fc7d042013-04-25 11:04:43 +02008174 spec->codec_variant = ALC269_TYPE_ALC286;
8175 break;
Kailang Yang506b62c2014-12-18 17:07:44 +08008176 case 0x10ec0298:
8177 spec->codec_variant = ALC269_TYPE_ALC298;
8178 break;
Kailang Yangea04a1d2018-04-25 15:31:52 +08008179 case 0x10ec0235:
Kailang Yang1d04c9d2013-10-24 11:35:18 +02008180 case 0x10ec0255:
8181 spec->codec_variant = ALC269_TYPE_ALC255;
Kailang Yangab3b8e52018-04-25 16:05:27 +08008182 spec->shutup = alc256_shutup;
8183 spec->init_hook = alc256_init;
Kailang Yang1d04c9d2013-10-24 11:35:18 +02008184 break;
Kailang Yang736f20a2017-10-20 15:06:34 +08008185 case 0x10ec0236:
Kailang Yang4344aec2014-12-17 17:39:05 +08008186 case 0x10ec0256:
8187 spec->codec_variant = ALC269_TYPE_ALC256;
Kailang Yang4a219ef2017-06-16 16:54:35 +08008188 spec->shutup = alc256_shutup;
8189 spec->init_hook = alc256_init;
David Henningsson7d1b6e22015-04-21 10:48:46 +02008190 spec->gen.mixer_nid = 0; /* ALC256 does not have any loopback mixer path */
Kailang Yang4344aec2014-12-17 17:39:05 +08008191 break;
Kailang Yangf429e7e2017-12-05 15:38:24 +08008192 case 0x10ec0257:
8193 spec->codec_variant = ALC269_TYPE_ALC257;
Kailang Yang88d42b22018-03-14 16:08:57 +08008194 spec->shutup = alc256_shutup;
8195 spec->init_hook = alc256_init;
Kailang Yangf429e7e2017-12-05 15:38:24 +08008196 spec->gen.mixer_nid = 0;
8197 break;
Kailang Yang0a6f0602017-06-30 16:00:48 +08008198 case 0x10ec0215:
8199 case 0x10ec0285:
8200 case 0x10ec0289:
8201 spec->codec_variant = ALC269_TYPE_ALC215;
Kailang Yang1b6832be2018-01-17 15:32:03 +08008202 spec->shutup = alc225_shutup;
8203 spec->init_hook = alc225_init;
Kailang Yang0a6f0602017-06-30 16:00:48 +08008204 spec->gen.mixer_nid = 0;
8205 break;
Kailang Yang42314302016-02-03 15:03:50 +08008206 case 0x10ec0225:
Kai-Heng Feng3b36b132020-03-11 14:13:28 +08008207 codec->power_save_node = 1;
8208 /* fall through */
Kailang Yang7d727862016-05-24 16:46:07 +08008209 case 0x10ec0295:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08008210 case 0x10ec0299:
Kailang Yang42314302016-02-03 15:03:50 +08008211 spec->codec_variant = ALC269_TYPE_ALC225;
Kailang Yangda911b12018-01-05 16:50:08 +08008212 spec->shutup = alc225_shutup;
8213 spec->init_hook = alc225_init;
Takashi Iwaic1350bf2017-12-27 09:03:45 +01008214 spec->gen.mixer_nid = 0; /* no loopback on ALC225, ALC295 and ALC299 */
Kailang Yang42314302016-02-03 15:03:50 +08008215 break;
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08008216 case 0x10ec0234:
8217 case 0x10ec0274:
8218 case 0x10ec0294:
8219 spec->codec_variant = ALC269_TYPE_ALC294;
Hui Wang532a7782017-06-26 12:30:32 +08008220 spec->gen.mixer_nid = 0; /* ALC2x4 does not have any loopback mixer path */
Kailang Yang71683c32017-06-20 16:33:50 +08008221 alc_update_coef_idx(codec, 0x6b, 0x0018, (1<<4) | (1<<3)); /* UAJ MIC Vref control by verb */
Kailang Yang693abe12019-01-29 15:38:21 +08008222 spec->init_hook = alc294_init;
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08008223 break;
Kailang Yang1078bef2018-11-08 16:36:15 +08008224 case 0x10ec0300:
8225 spec->codec_variant = ALC269_TYPE_ALC300;
8226 spec->gen.mixer_nid = 0; /* no loopback on ALC300 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02008227 break;
Kailang Yangf0778872019-10-24 15:13:32 +08008228 case 0x10ec0623:
8229 spec->codec_variant = ALC269_TYPE_ALC623;
8230 break;
Kailang Yang6fbae352016-05-30 16:44:20 +08008231 case 0x10ec0700:
8232 case 0x10ec0701:
8233 case 0x10ec0703:
Kailang Yang83629532019-05-02 16:03:26 +08008234 case 0x10ec0711:
Kailang Yang6fbae352016-05-30 16:44:20 +08008235 spec->codec_variant = ALC269_TYPE_ALC700;
8236 spec->gen.mixer_nid = 0; /* ALC700 does not have any loopback mixer path */
Kailang Yang2d7fe612017-11-22 15:21:32 +08008237 alc_update_coef_idx(codec, 0x4a, 1 << 15, 0); /* Combo jack auto trigger control */
Kailang Yang693abe12019-01-29 15:38:21 +08008238 spec->init_hook = alc294_init;
Kailang Yang6fbae352016-05-30 16:44:20 +08008239 break;
8240
Takashi Iwai1d045db2011-07-07 18:23:21 +02008241 }
8242
Kailang Yangad60d502013-06-28 12:03:01 +02008243 if (snd_hda_codec_read(codec, 0x51, 0, AC_VERB_PARAMETERS, 0) == 0x10ec5505) {
Kailang Yang97a26572013-11-29 00:35:26 -05008244 spec->has_alc5505_dsp = 1;
Kailang Yangad60d502013-06-28 12:03:01 +02008245 spec->init_hook = alc5505_dsp_init;
8246 }
8247
Takashi Iwaic9af7532019-05-10 11:01:43 +02008248 alc_pre_init(codec);
8249
Takashi Iwaiefe55732018-06-15 11:55:02 +02008250 snd_hda_pick_fixup(codec, alc269_fixup_models,
8251 alc269_fixup_tbl, alc269_fixups);
Hui Wang0fc1e442019-08-16 14:27:39 +08008252 snd_hda_pick_pin_fixup(codec, alc269_pin_fixup_tbl, alc269_fixups, true);
Hui Wang7c0a6932019-08-16 14:27:40 +08008253 snd_hda_pick_pin_fixup(codec, alc269_fallback_pin_fixup_tbl, alc269_fixups, false);
Takashi Iwaiefe55732018-06-15 11:55:02 +02008254 snd_hda_pick_fixup(codec, NULL, alc269_fixup_vendor_tbl,
8255 alc269_fixups);
8256 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
8257
8258 alc_auto_parse_customize_define(codec);
8259
8260 if (has_cdefine_beep(codec))
8261 spec->gen.beep_nid = 0x01;
8262
Takashi Iwaia4297b52011-08-23 18:40:12 +02008263 /* automatic parse from the BIOS config */
8264 err = alc269_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008265 if (err < 0)
8266 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008267
Takashi Iwaifea80fa2018-06-20 12:52:46 +02008268 if (!spec->gen.no_analog && spec->gen.beep_nid && spec->gen.mixer_nid) {
8269 err = set_beep_amp(spec, spec->gen.mixer_nid, 0x04, HDA_INPUT);
8270 if (err < 0)
8271 goto error;
8272 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02008273
Takashi Iwai1727a772013-01-10 09:52:52 +01008274 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01008275
Takashi Iwai1d045db2011-07-07 18:23:21 +02008276 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008277
8278 error:
8279 alc_free(codec);
8280 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008281}
8282
8283/*
8284 * ALC861
8285 */
8286
Takashi Iwai1d045db2011-07-07 18:23:21 +02008287static int alc861_parse_auto_config(struct hda_codec *codec)
8288{
Takashi Iwai1d045db2011-07-07 18:23:21 +02008289 static const hda_nid_t alc861_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02008290 static const hda_nid_t alc861_ssids[] = { 0x0e, 0x0f, 0x0b, 0 };
8291 return alc_parse_auto_config(codec, alc861_ignore, alc861_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02008292}
8293
Takashi Iwai1d045db2011-07-07 18:23:21 +02008294/* Pin config fixes */
8295enum {
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008296 ALC861_FIXUP_FSC_AMILO_PI1505,
8297 ALC861_FIXUP_AMP_VREF_0F,
8298 ALC861_FIXUP_NO_JACK_DETECT,
8299 ALC861_FIXUP_ASUS_A6RP,
Takashi Iwai6ddf0fd2013-11-29 12:47:34 +01008300 ALC660_FIXUP_ASUS_W7J,
Takashi Iwai1d045db2011-07-07 18:23:21 +02008301};
8302
Takashi Iwai31150f22012-01-30 10:54:08 +01008303/* On some laptops, VREF of pin 0x0f is abused for controlling the main amp */
8304static void alc861_fixup_asus_amp_vref_0f(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01008305 const struct hda_fixup *fix, int action)
Takashi Iwai31150f22012-01-30 10:54:08 +01008306{
8307 struct alc_spec *spec = codec->spec;
8308 unsigned int val;
8309
Takashi Iwai1727a772013-01-10 09:52:52 +01008310 if (action != HDA_FIXUP_ACT_INIT)
Takashi Iwai31150f22012-01-30 10:54:08 +01008311 return;
Takashi Iwaid3f02d62013-01-10 10:12:22 +01008312 val = snd_hda_codec_get_pin_target(codec, 0x0f);
Takashi Iwai31150f22012-01-30 10:54:08 +01008313 if (!(val & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN)))
8314 val |= AC_PINCTL_IN_EN;
8315 val |= AC_PINCTL_VREF_50;
Takashi Iwaicdd03ce2012-04-20 12:34:50 +02008316 snd_hda_set_pin_ctl(codec, 0x0f, val);
Takashi Iwai08c189f2012-12-19 15:22:24 +01008317 spec->gen.keep_vref_in_automute = 1;
Takashi Iwai31150f22012-01-30 10:54:08 +01008318}
8319
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008320/* suppress the jack-detection */
8321static void alc_fixup_no_jack_detect(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01008322 const struct hda_fixup *fix, int action)
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008323{
Takashi Iwai1727a772013-01-10 09:52:52 +01008324 if (action == HDA_FIXUP_ACT_PRE_PROBE)
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008325 codec->no_jack_detect = 1;
Jesper Juhl7d7eb9e2012-04-12 22:11:25 +02008326}
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008327
Takashi Iwai1727a772013-01-10 09:52:52 +01008328static const struct hda_fixup alc861_fixups[] = {
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008329 [ALC861_FIXUP_FSC_AMILO_PI1505] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008330 .type = HDA_FIXUP_PINS,
8331 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02008332 { 0x0b, 0x0221101f }, /* HP */
8333 { 0x0f, 0x90170310 }, /* speaker */
8334 { }
8335 }
8336 },
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008337 [ALC861_FIXUP_AMP_VREF_0F] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008338 .type = HDA_FIXUP_FUNC,
Takashi Iwai31150f22012-01-30 10:54:08 +01008339 .v.func = alc861_fixup_asus_amp_vref_0f,
Takashi Iwai3b25eb62012-01-25 09:55:46 +01008340 },
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008341 [ALC861_FIXUP_NO_JACK_DETECT] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008342 .type = HDA_FIXUP_FUNC,
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008343 .v.func = alc_fixup_no_jack_detect,
8344 },
8345 [ALC861_FIXUP_ASUS_A6RP] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008346 .type = HDA_FIXUP_FUNC,
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008347 .v.func = alc861_fixup_asus_amp_vref_0f,
8348 .chained = true,
8349 .chain_id = ALC861_FIXUP_NO_JACK_DETECT,
Takashi Iwai6ddf0fd2013-11-29 12:47:34 +01008350 },
8351 [ALC660_FIXUP_ASUS_W7J] = {
8352 .type = HDA_FIXUP_VERBS,
8353 .v.verbs = (const struct hda_verb[]) {
8354 /* ASUS W7J needs a magic pin setup on unused NID 0x10
8355 * for enabling outputs
8356 */
8357 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8358 { }
8359 },
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008360 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02008361};
8362
8363static const struct snd_pci_quirk alc861_fixup_tbl[] = {
Takashi Iwai6ddf0fd2013-11-29 12:47:34 +01008364 SND_PCI_QUIRK(0x1043, 0x1253, "ASUS W7J", ALC660_FIXUP_ASUS_W7J),
Takashi Iwaie7ca2372013-12-02 15:27:19 +01008365 SND_PCI_QUIRK(0x1043, 0x1263, "ASUS Z35HL", ALC660_FIXUP_ASUS_W7J),
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008366 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS A6Rp", ALC861_FIXUP_ASUS_A6RP),
8367 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", ALC861_FIXUP_AMP_VREF_0F),
8368 SND_PCI_QUIRK(0x1462, 0x7254, "HP DX2200", ALC861_FIXUP_NO_JACK_DETECT),
8369 SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", ALC861_FIXUP_AMP_VREF_0F),
8370 SND_PCI_QUIRK(0x1584, 0x0000, "Uniwill ECS M31EI", ALC861_FIXUP_AMP_VREF_0F),
8371 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", ALC861_FIXUP_FSC_AMILO_PI1505),
Takashi Iwai1d045db2011-07-07 18:23:21 +02008372 {}
8373};
8374
8375/*
8376 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02008377static int patch_alc861(struct hda_codec *codec)
8378{
8379 struct alc_spec *spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008380 int err;
8381
Takashi Iwai3de95172012-05-07 18:03:15 +02008382 err = alc_alloc_spec(codec, 0x15);
8383 if (err < 0)
8384 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008385
Takashi Iwai3de95172012-05-07 18:03:15 +02008386 spec = codec->spec;
Takashi Iwai2722b532019-08-22 09:55:37 +02008387 if (has_cdefine_beep(codec))
8388 spec->gen.beep_nid = 0x23;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008389
Takashi Iwai225068a2015-05-29 10:42:14 +02008390#ifdef CONFIG_PM
8391 spec->power_hook = alc_power_eapd;
8392#endif
8393
Takashi Iwaic9af7532019-05-10 11:01:43 +02008394 alc_pre_init(codec);
8395
Takashi Iwai1727a772013-01-10 09:52:52 +01008396 snd_hda_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
8397 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02008398
Takashi Iwaicb4e4822011-08-23 17:34:25 +02008399 /* automatic parse from the BIOS config */
8400 err = alc861_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008401 if (err < 0)
8402 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008403
Takashi Iwaifea80fa2018-06-20 12:52:46 +02008404 if (!spec->gen.no_analog) {
8405 err = set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
8406 if (err < 0)
8407 goto error;
8408 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02008409
Takashi Iwai1727a772013-01-10 09:52:52 +01008410 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01008411
Takashi Iwai1d045db2011-07-07 18:23:21 +02008412 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008413
8414 error:
8415 alc_free(codec);
8416 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008417}
8418
8419/*
8420 * ALC861-VD support
8421 *
8422 * Based on ALC882
8423 *
8424 * In addition, an independent DAC
8425 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02008426static int alc861vd_parse_auto_config(struct hda_codec *codec)
8427{
Takashi Iwai1d045db2011-07-07 18:23:21 +02008428 static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02008429 static const hda_nid_t alc861vd_ssids[] = { 0x15, 0x1b, 0x14, 0 };
8430 return alc_parse_auto_config(codec, alc861vd_ignore, alc861vd_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02008431}
8432
Takashi Iwai1d045db2011-07-07 18:23:21 +02008433enum {
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008434 ALC660VD_FIX_ASUS_GPIO1,
8435 ALC861VD_FIX_DALLAS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02008436};
8437
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008438/* exclude VREF80 */
8439static void alc861vd_fixup_dallas(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01008440 const struct hda_fixup *fix, int action)
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008441{
Takashi Iwai1727a772013-01-10 09:52:52 +01008442 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwaib78562b2012-12-17 20:06:49 +01008443 snd_hda_override_pin_caps(codec, 0x18, 0x00000734);
8444 snd_hda_override_pin_caps(codec, 0x19, 0x0000073c);
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008445 }
8446}
8447
Takashi Iwaidf73d832018-06-19 23:05:47 +02008448/* reset GPIO1 */
8449static void alc660vd_fixup_asus_gpio1(struct hda_codec *codec,
8450 const struct hda_fixup *fix, int action)
8451{
8452 struct alc_spec *spec = codec->spec;
8453
8454 if (action == HDA_FIXUP_ACT_PRE_PROBE)
8455 spec->gpio_mask |= 0x02;
8456 alc_fixup_gpio(codec, action, 0x01);
8457}
8458
Takashi Iwai1727a772013-01-10 09:52:52 +01008459static const struct hda_fixup alc861vd_fixups[] = {
Takashi Iwai1d045db2011-07-07 18:23:21 +02008460 [ALC660VD_FIX_ASUS_GPIO1] = {
Takashi Iwaidf73d832018-06-19 23:05:47 +02008461 .type = HDA_FIXUP_FUNC,
8462 .v.func = alc660vd_fixup_asus_gpio1,
Takashi Iwai1d045db2011-07-07 18:23:21 +02008463 },
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008464 [ALC861VD_FIX_DALLAS] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008465 .type = HDA_FIXUP_FUNC,
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008466 .v.func = alc861vd_fixup_dallas,
8467 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02008468};
8469
8470static const struct snd_pci_quirk alc861vd_fixup_tbl[] = {
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008471 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_FIX_DALLAS),
Takashi Iwai1d045db2011-07-07 18:23:21 +02008472 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008473 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_FIX_DALLAS),
Takashi Iwai1d045db2011-07-07 18:23:21 +02008474 {}
8475};
8476
Takashi Iwai1d045db2011-07-07 18:23:21 +02008477/*
8478 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02008479static int patch_alc861vd(struct hda_codec *codec)
8480{
8481 struct alc_spec *spec;
Takashi Iwaicb4e4822011-08-23 17:34:25 +02008482 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008483
Takashi Iwai3de95172012-05-07 18:03:15 +02008484 err = alc_alloc_spec(codec, 0x0b);
8485 if (err < 0)
8486 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008487
Takashi Iwai3de95172012-05-07 18:03:15 +02008488 spec = codec->spec;
Takashi Iwai2722b532019-08-22 09:55:37 +02008489 if (has_cdefine_beep(codec))
8490 spec->gen.beep_nid = 0x23;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008491
Takashi Iwai225068a2015-05-29 10:42:14 +02008492 spec->shutup = alc_eapd_shutup;
8493
Takashi Iwaic9af7532019-05-10 11:01:43 +02008494 alc_pre_init(codec);
8495
Takashi Iwai1727a772013-01-10 09:52:52 +01008496 snd_hda_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
8497 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02008498
Takashi Iwaicb4e4822011-08-23 17:34:25 +02008499 /* automatic parse from the BIOS config */
8500 err = alc861vd_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008501 if (err < 0)
8502 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008503
Takashi Iwaifea80fa2018-06-20 12:52:46 +02008504 if (!spec->gen.no_analog) {
8505 err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
8506 if (err < 0)
8507 goto error;
8508 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02008509
Takashi Iwai1727a772013-01-10 09:52:52 +01008510 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01008511
Takashi Iwai1d045db2011-07-07 18:23:21 +02008512 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008513
8514 error:
8515 alc_free(codec);
8516 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008517}
8518
8519/*
8520 * ALC662 support
8521 *
8522 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
8523 * configuration. Each pin widget can choose any input DACs and a mixer.
8524 * Each ADC is connected from a mixer of all inputs. This makes possible
8525 * 6-channel independent captures.
8526 *
8527 * In addition, an independent DAC for the multi-playback (not used in this
8528 * driver yet).
8529 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02008530
8531/*
8532 * BIOS auto configuration
8533 */
8534
Kailang Yangbc9f98a2007-04-12 13:06:07 +02008535static int alc662_parse_auto_config(struct hda_codec *codec)
8536{
Takashi Iwai4c6d72d2011-05-02 11:30:18 +02008537 static const hda_nid_t alc662_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02008538 static const hda_nid_t alc663_ssids[] = { 0x15, 0x1b, 0x14, 0x21 };
8539 static const hda_nid_t alc662_ssids[] = { 0x15, 0x1b, 0x14, 0 };
8540 const hda_nid_t *ssids;
Takashi Iwaiee979a142008-09-02 15:42:20 +02008541
Takashi Iwai7639a062015-03-03 10:07:24 +01008542 if (codec->core.vendor_id == 0x10ec0272 || codec->core.vendor_id == 0x10ec0663 ||
8543 codec->core.vendor_id == 0x10ec0665 || codec->core.vendor_id == 0x10ec0670 ||
8544 codec->core.vendor_id == 0x10ec0671)
Takashi Iwai3e6179b2011-07-08 16:55:13 +02008545 ssids = alc663_ssids;
Kailang Yang6227cdc2010-02-25 08:36:52 +01008546 else
Takashi Iwai3e6179b2011-07-08 16:55:13 +02008547 ssids = alc662_ssids;
8548 return alc_parse_auto_config(codec, alc662_ignore, ssids);
Kailang Yangbc9f98a2007-04-12 13:06:07 +02008549}
8550
Todd Broch6be79482010-12-07 16:51:05 -08008551static void alc272_fixup_mario(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01008552 const struct hda_fixup *fix, int action)
Takashi Iwai6fc398c2011-01-13 14:36:37 +01008553{
Takashi Iwai9bb1f062013-01-10 17:14:29 +01008554 if (action != HDA_FIXUP_ACT_PRE_PROBE)
Takashi Iwai6fc398c2011-01-13 14:36:37 +01008555 return;
Todd Broch6be79482010-12-07 16:51:05 -08008556 if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT,
8557 (0x3b << AC_AMPCAP_OFFSET_SHIFT) |
8558 (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) |
8559 (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) |
8560 (0 << AC_AMPCAP_MUTE_SHIFT)))
Takashi Iwai4e76a882014-02-25 12:21:03 +01008561 codec_warn(codec, "failed to override amp caps for NID 0x2\n");
Todd Broch6be79482010-12-07 16:51:05 -08008562}
8563
Takashi Iwai8e383952013-10-30 17:41:12 +01008564static const struct snd_pcm_chmap_elem asus_pcm_2_1_chmaps[] = {
8565 { .channels = 2,
8566 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } },
8567 { .channels = 4,
8568 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR,
8569 SNDRV_CHMAP_NA, SNDRV_CHMAP_LFE } }, /* LFE only on right */
8570 { }
8571};
8572
8573/* override the 2.1 chmap */
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01008574static void alc_fixup_bass_chmap(struct hda_codec *codec,
Takashi Iwai8e383952013-10-30 17:41:12 +01008575 const struct hda_fixup *fix, int action)
8576{
8577 if (action == HDA_FIXUP_ACT_BUILD) {
8578 struct alc_spec *spec = codec->spec;
Takashi Iwaibbbc7e82015-02-27 17:43:19 +01008579 spec->gen.pcm_rec[0]->stream[0].chmap = asus_pcm_2_1_chmaps;
Takashi Iwai8e383952013-10-30 17:41:12 +01008580 }
8581}
8582
Takashi Iwaibf686652014-01-13 16:18:25 +01008583/* avoid D3 for keeping GPIO up */
8584static unsigned int gpio_led_power_filter(struct hda_codec *codec,
8585 hda_nid_t nid,
8586 unsigned int power_state)
8587{
8588 struct alc_spec *spec = codec->spec;
Takashi Iwaid261eec2018-06-19 22:32:29 +02008589 if (nid == codec->core.afg && power_state == AC_PWRST_D3 && spec->gpio_data)
Takashi Iwaibf686652014-01-13 16:18:25 +01008590 return AC_PWRST_D0;
8591 return power_state;
8592}
8593
Takashi Iwai3e887f32014-01-10 17:50:58 +01008594static void alc662_fixup_led_gpio1(struct hda_codec *codec,
8595 const struct hda_fixup *fix, int action)
8596{
8597 struct alc_spec *spec = codec->spec;
Takashi Iwai3e887f32014-01-10 17:50:58 +01008598
Takashi Iwai01e4a272018-06-19 22:47:30 +02008599 alc_fixup_hp_gpio_led(codec, action, 0x01, 0);
Takashi Iwai3e887f32014-01-10 17:50:58 +01008600 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai0f32fd192014-11-19 12:16:14 +01008601 spec->mute_led_polarity = 1;
Takashi Iwaibf686652014-01-13 16:18:25 +01008602 codec->power_filter = gpio_led_power_filter;
Takashi Iwai3e887f32014-01-10 17:50:58 +01008603 }
8604}
8605
Kailang Yangc6790c82016-11-25 16:15:17 +08008606static void alc662_usi_automute_hook(struct hda_codec *codec,
8607 struct hda_jack_callback *jack)
8608{
8609 struct alc_spec *spec = codec->spec;
8610 int vref;
8611 msleep(200);
8612 snd_hda_gen_hp_automute(codec, jack);
8613
8614 vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0;
8615 msleep(100);
8616 snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8617 vref);
8618}
8619
8620static void alc662_fixup_usi_headset_mic(struct hda_codec *codec,
8621 const struct hda_fixup *fix, int action)
8622{
8623 struct alc_spec *spec = codec->spec;
8624 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
8625 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
8626 spec->gen.hp_automute_hook = alc662_usi_automute_hook;
8627 }
8628}
8629
Sergey Bostandzhyan00066e92019-09-06 11:33:43 +02008630static void alc662_aspire_ethos_mute_speakers(struct hda_codec *codec,
8631 struct hda_jack_callback *cb)
8632{
8633 /* surround speakers at 0x1b already get muted automatically when
8634 * headphones are plugged in, but we have to mute/unmute the remaining
8635 * channels manually:
8636 * 0x15 - front left/front right
8637 * 0x18 - front center/ LFE
8638 */
8639 if (snd_hda_jack_detect_state(codec, 0x1b) == HDA_JACK_PRESENT) {
8640 snd_hda_set_pin_ctl_cache(codec, 0x15, 0);
8641 snd_hda_set_pin_ctl_cache(codec, 0x18, 0);
8642 } else {
8643 snd_hda_set_pin_ctl_cache(codec, 0x15, PIN_OUT);
8644 snd_hda_set_pin_ctl_cache(codec, 0x18, PIN_OUT);
8645 }
8646}
8647
8648static void alc662_fixup_aspire_ethos_hp(struct hda_codec *codec,
8649 const struct hda_fixup *fix, int action)
8650{
8651 /* Pin 0x1b: shared headphones jack and surround speakers */
8652 if (!is_jack_detectable(codec, 0x1b))
8653 return;
8654
8655 switch (action) {
8656 case HDA_FIXUP_ACT_PRE_PROBE:
8657 snd_hda_jack_detect_enable_callback(codec, 0x1b,
8658 alc662_aspire_ethos_mute_speakers);
Takashi Iwai336820c2019-11-28 21:26:30 +01008659 /* subwoofer needs an extra GPIO setting to become audible */
8660 alc_setup_gpio(codec, 0x02);
Sergey Bostandzhyan00066e92019-09-06 11:33:43 +02008661 break;
8662 case HDA_FIXUP_ACT_INIT:
8663 /* Make sure to start in a correct state, i.e. if
8664 * headphones have been plugged in before powering up the system
8665 */
8666 alc662_aspire_ethos_mute_speakers(codec, NULL);
8667 break;
8668 }
8669}
8670
Kailang Yang5af290282020-01-17 14:04:01 +08008671static void alc671_fixup_hp_headset_mic2(struct hda_codec *codec,
8672 const struct hda_fixup *fix, int action)
8673{
8674 struct alc_spec *spec = codec->spec;
8675
8676 static const struct hda_pintbl pincfgs[] = {
8677 { 0x19, 0x02a11040 }, /* use as headset mic, with its own jack detect */
8678 { 0x1b, 0x0181304f },
8679 { }
8680 };
8681
8682 switch (action) {
8683 case HDA_FIXUP_ACT_PRE_PROBE:
8684 spec->gen.mixer_nid = 0;
8685 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
8686 snd_hda_apply_pincfgs(codec, pincfgs);
8687 break;
8688 case HDA_FIXUP_ACT_INIT:
8689 alc_write_coef_idx(codec, 0x19, 0xa054);
8690 break;
8691 }
8692}
8693
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01008694static const struct coef_fw alc668_coefs[] = {
Kailang Yangf3f91852014-10-24 15:43:46 +08008695 WRITE_COEF(0x01, 0xbebe), WRITE_COEF(0x02, 0xaaaa), WRITE_COEF(0x03, 0x0),
8696 WRITE_COEF(0x04, 0x0180), WRITE_COEF(0x06, 0x0), WRITE_COEF(0x07, 0x0f80),
8697 WRITE_COEF(0x08, 0x0031), WRITE_COEF(0x0a, 0x0060), WRITE_COEF(0x0b, 0x0),
8698 WRITE_COEF(0x0c, 0x7cf7), WRITE_COEF(0x0d, 0x1080), WRITE_COEF(0x0e, 0x7f7f),
8699 WRITE_COEF(0x0f, 0xcccc), WRITE_COEF(0x10, 0xddcc), WRITE_COEF(0x11, 0x0001),
8700 WRITE_COEF(0x13, 0x0), WRITE_COEF(0x14, 0x2aa0), WRITE_COEF(0x17, 0xa940),
8701 WRITE_COEF(0x19, 0x0), WRITE_COEF(0x1a, 0x0), WRITE_COEF(0x1b, 0x0),
8702 WRITE_COEF(0x1c, 0x0), WRITE_COEF(0x1d, 0x0), WRITE_COEF(0x1e, 0x7418),
8703 WRITE_COEF(0x1f, 0x0804), WRITE_COEF(0x20, 0x4200), WRITE_COEF(0x21, 0x0468),
8704 WRITE_COEF(0x22, 0x8ccc), WRITE_COEF(0x23, 0x0250), WRITE_COEF(0x24, 0x7418),
8705 WRITE_COEF(0x27, 0x0), WRITE_COEF(0x28, 0x8ccc), WRITE_COEF(0x2a, 0xff00),
8706 WRITE_COEF(0x2b, 0x8000), WRITE_COEF(0xa7, 0xff00), WRITE_COEF(0xa8, 0x8000),
8707 WRITE_COEF(0xaa, 0x2e17), WRITE_COEF(0xab, 0xa0c0), WRITE_COEF(0xac, 0x0),
8708 WRITE_COEF(0xad, 0x0), WRITE_COEF(0xae, 0x2ac6), WRITE_COEF(0xaf, 0xa480),
8709 WRITE_COEF(0xb0, 0x0), WRITE_COEF(0xb1, 0x0), WRITE_COEF(0xb2, 0x0),
8710 WRITE_COEF(0xb3, 0x0), WRITE_COEF(0xb4, 0x0), WRITE_COEF(0xb5, 0x1040),
8711 WRITE_COEF(0xb6, 0xd697), WRITE_COEF(0xb7, 0x902b), WRITE_COEF(0xb8, 0xd697),
8712 WRITE_COEF(0xb9, 0x902b), WRITE_COEF(0xba, 0xb8ba), WRITE_COEF(0xbb, 0xaaab),
8713 WRITE_COEF(0xbc, 0xaaaf), WRITE_COEF(0xbd, 0x6aaa), WRITE_COEF(0xbe, 0x1c02),
8714 WRITE_COEF(0xc0, 0x00ff), WRITE_COEF(0xc1, 0x0fa6),
8715 {}
8716};
8717
8718static void alc668_restore_default_value(struct hda_codec *codec)
8719{
8720 alc_process_coef_fw(codec, alc668_coefs);
8721}
8722
David Henningsson6cb3b702010-09-09 08:51:44 +02008723enum {
Daniel T Chen2df03512010-10-10 22:39:28 -04008724 ALC662_FIXUP_ASPIRE,
Takashi Iwai3e887f32014-01-10 17:50:58 +01008725 ALC662_FIXUP_LED_GPIO1,
David Henningsson6cb3b702010-09-09 08:51:44 +02008726 ALC662_FIXUP_IDEAPAD,
Todd Broch6be79482010-12-07 16:51:05 -08008727 ALC272_FIXUP_MARIO,
Anisse Astierd2ebd472011-01-20 12:36:21 +01008728 ALC662_FIXUP_CZC_P10T,
David Henningsson94024cd2011-04-29 14:10:55 +02008729 ALC662_FIXUP_SKU_IGNORE,
Takashi Iwaie59ea3e2011-06-29 17:21:00 +02008730 ALC662_FIXUP_HP_RP5800,
Takashi Iwai53c334a2011-08-23 18:27:14 +02008731 ALC662_FIXUP_ASUS_MODE1,
8732 ALC662_FIXUP_ASUS_MODE2,
8733 ALC662_FIXUP_ASUS_MODE3,
8734 ALC662_FIXUP_ASUS_MODE4,
8735 ALC662_FIXUP_ASUS_MODE5,
8736 ALC662_FIXUP_ASUS_MODE6,
8737 ALC662_FIXUP_ASUS_MODE7,
8738 ALC662_FIXUP_ASUS_MODE8,
Takashi Iwai1565cc32012-02-13 12:03:25 +01008739 ALC662_FIXUP_NO_JACK_DETECT,
David Henningssonedfe3bf2012-06-12 13:15:12 +02008740 ALC662_FIXUP_ZOTAC_Z68,
Takashi Iwai125821a2012-06-22 14:30:29 +02008741 ALC662_FIXUP_INV_DMIC,
David Henningsson1f8b46c2015-05-12 14:38:15 +02008742 ALC662_FIXUP_DELL_MIC_NO_PRESENCE,
David Henningsson73bdd592013-04-15 15:44:14 +02008743 ALC668_FIXUP_DELL_MIC_NO_PRESENCE,
David Henningsson1f8b46c2015-05-12 14:38:15 +02008744 ALC662_FIXUP_HEADSET_MODE,
David Henningsson73bdd592013-04-15 15:44:14 +02008745 ALC668_FIXUP_HEADSET_MODE,
David Henningsson8e54b4a2014-02-07 09:31:07 +01008746 ALC662_FIXUP_BASS_MODE4_CHMAP,
David Henningsson61a75f12014-02-07 09:31:08 +01008747 ALC662_FIXUP_BASS_16,
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01008748 ALC662_FIXUP_BASS_1A,
David Henningsson8e54b4a2014-02-07 09:31:07 +01008749 ALC662_FIXUP_BASS_CHMAP,
Hui Wang493a52a2014-01-14 14:07:36 +08008750 ALC668_FIXUP_AUTO_MUTE,
Gabriele Mazzotta5e6db662014-05-20 18:58:26 +02008751 ALC668_FIXUP_DELL_DISABLE_AAMIX,
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02008752 ALC668_FIXUP_DELL_XPS13,
Bobi Mihalca9d4dc582016-03-23 13:26:11 +02008753 ALC662_FIXUP_ASUS_Nx50,
Mikhail Paulyshkafc7438b2017-04-21 08:52:42 +02008754 ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE,
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07008755 ALC668_FIXUP_ASUS_Nx51,
Takashi Iwai5b7c5e12018-10-09 14:20:17 +02008756 ALC668_FIXUP_MIC_COEF,
Takashi Iwai11ba6112018-10-07 09:44:17 +02008757 ALC668_FIXUP_ASUS_G751,
Kailang Yang78f4f7c2016-06-07 11:31:34 +08008758 ALC891_FIXUP_HEADSET_MODE,
8759 ALC891_FIXUP_DELL_MIC_NO_PRESENCE,
Shrirang Bagul9b51fe32016-08-01 13:16:17 +08008760 ALC662_FIXUP_ACER_VERITON,
Takashi Iwai1a3f0992016-10-20 12:14:51 +02008761 ALC892_FIXUP_ASROCK_MOBO,
Kailang Yangc6790c82016-11-25 16:15:17 +08008762 ALC662_FIXUP_USI_FUNC,
8763 ALC662_FIXUP_USI_HEADSET_MODE,
Kailang Yangca169cc2017-04-25 16:17:40 +08008764 ALC662_FIXUP_LENOVO_MULTI_CODECS,
Sergey Bostandzhyan00066e92019-09-06 11:33:43 +02008765 ALC669_FIXUP_ACER_ASPIRE_ETHOS,
Sergey Bostandzhyan00066e92019-09-06 11:33:43 +02008766 ALC669_FIXUP_ACER_ASPIRE_ETHOS_HEADSET,
Kailang Yang5af290282020-01-17 14:04:01 +08008767 ALC671_FIXUP_HP_HEADSET_MIC2,
Jian-Hong Pand858c702020-03-17 16:28:07 +08008768 ALC662_FIXUP_ACER_X2660G_HEADSET_MODE,
Jian-Hong Pana1244582020-03-17 16:28:09 +08008769 ALC662_FIXUP_ACER_NITRO_HEADSET_MODE,
David Henningsson6cb3b702010-09-09 08:51:44 +02008770};
8771
Takashi Iwai1727a772013-01-10 09:52:52 +01008772static const struct hda_fixup alc662_fixups[] = {
Daniel T Chen2df03512010-10-10 22:39:28 -04008773 [ALC662_FIXUP_ASPIRE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008774 .type = HDA_FIXUP_PINS,
8775 .v.pins = (const struct hda_pintbl[]) {
Daniel T Chen2df03512010-10-10 22:39:28 -04008776 { 0x15, 0x99130112 }, /* subwoofer */
8777 { }
8778 }
8779 },
Takashi Iwai3e887f32014-01-10 17:50:58 +01008780 [ALC662_FIXUP_LED_GPIO1] = {
8781 .type = HDA_FIXUP_FUNC,
8782 .v.func = alc662_fixup_led_gpio1,
8783 },
David Henningsson6cb3b702010-09-09 08:51:44 +02008784 [ALC662_FIXUP_IDEAPAD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008785 .type = HDA_FIXUP_PINS,
8786 .v.pins = (const struct hda_pintbl[]) {
David Henningsson6cb3b702010-09-09 08:51:44 +02008787 { 0x17, 0x99130112 }, /* subwoofer */
8788 { }
Takashi Iwai3e887f32014-01-10 17:50:58 +01008789 },
8790 .chained = true,
8791 .chain_id = ALC662_FIXUP_LED_GPIO1,
David Henningsson6cb3b702010-09-09 08:51:44 +02008792 },
Todd Broch6be79482010-12-07 16:51:05 -08008793 [ALC272_FIXUP_MARIO] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008794 .type = HDA_FIXUP_FUNC,
Takashi Iwaib5bfbc62011-01-13 14:22:32 +01008795 .v.func = alc272_fixup_mario,
Anisse Astierd2ebd472011-01-20 12:36:21 +01008796 },
8797 [ALC662_FIXUP_CZC_P10T] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008798 .type = HDA_FIXUP_VERBS,
Anisse Astierd2ebd472011-01-20 12:36:21 +01008799 .v.verbs = (const struct hda_verb[]) {
8800 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
8801 {}
8802 }
8803 },
David Henningsson94024cd2011-04-29 14:10:55 +02008804 [ALC662_FIXUP_SKU_IGNORE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008805 .type = HDA_FIXUP_FUNC,
Takashi Iwai23d30f22012-05-07 17:17:32 +02008806 .v.func = alc_fixup_sku_ignore,
Takashi Iwaic6b35872011-03-28 12:05:31 +02008807 },
Takashi Iwaie59ea3e2011-06-29 17:21:00 +02008808 [ALC662_FIXUP_HP_RP5800] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008809 .type = HDA_FIXUP_PINS,
8810 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaie59ea3e2011-06-29 17:21:00 +02008811 { 0x14, 0x0221201f }, /* HP out */
8812 { }
8813 },
8814 .chained = true,
8815 .chain_id = ALC662_FIXUP_SKU_IGNORE
8816 },
Takashi Iwai53c334a2011-08-23 18:27:14 +02008817 [ALC662_FIXUP_ASUS_MODE1] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008818 .type = HDA_FIXUP_PINS,
8819 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008820 { 0x14, 0x99130110 }, /* speaker */
8821 { 0x18, 0x01a19c20 }, /* mic */
8822 { 0x19, 0x99a3092f }, /* int-mic */
8823 { 0x21, 0x0121401f }, /* HP out */
8824 { }
8825 },
8826 .chained = true,
8827 .chain_id = ALC662_FIXUP_SKU_IGNORE
8828 },
8829 [ALC662_FIXUP_ASUS_MODE2] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008830 .type = HDA_FIXUP_PINS,
8831 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai2996bdb2011-08-18 16:02:24 +02008832 { 0x14, 0x99130110 }, /* speaker */
8833 { 0x18, 0x01a19820 }, /* mic */
8834 { 0x19, 0x99a3092f }, /* int-mic */
8835 { 0x1b, 0x0121401f }, /* HP out */
8836 { }
8837 },
Takashi Iwai53c334a2011-08-23 18:27:14 +02008838 .chained = true,
8839 .chain_id = ALC662_FIXUP_SKU_IGNORE
8840 },
8841 [ALC662_FIXUP_ASUS_MODE3] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008842 .type = HDA_FIXUP_PINS,
8843 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008844 { 0x14, 0x99130110 }, /* speaker */
8845 { 0x15, 0x0121441f }, /* HP */
8846 { 0x18, 0x01a19840 }, /* mic */
8847 { 0x19, 0x99a3094f }, /* int-mic */
8848 { 0x21, 0x01211420 }, /* HP2 */
8849 { }
8850 },
8851 .chained = true,
8852 .chain_id = ALC662_FIXUP_SKU_IGNORE
8853 },
8854 [ALC662_FIXUP_ASUS_MODE4] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008855 .type = HDA_FIXUP_PINS,
8856 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008857 { 0x14, 0x99130110 }, /* speaker */
8858 { 0x16, 0x99130111 }, /* speaker */
8859 { 0x18, 0x01a19840 }, /* mic */
8860 { 0x19, 0x99a3094f }, /* int-mic */
8861 { 0x21, 0x0121441f }, /* HP */
8862 { }
8863 },
8864 .chained = true,
8865 .chain_id = ALC662_FIXUP_SKU_IGNORE
8866 },
8867 [ALC662_FIXUP_ASUS_MODE5] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008868 .type = HDA_FIXUP_PINS,
8869 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008870 { 0x14, 0x99130110 }, /* speaker */
8871 { 0x15, 0x0121441f }, /* HP */
8872 { 0x16, 0x99130111 }, /* speaker */
8873 { 0x18, 0x01a19840 }, /* mic */
8874 { 0x19, 0x99a3094f }, /* int-mic */
8875 { }
8876 },
8877 .chained = true,
8878 .chain_id = ALC662_FIXUP_SKU_IGNORE
8879 },
8880 [ALC662_FIXUP_ASUS_MODE6] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008881 .type = HDA_FIXUP_PINS,
8882 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008883 { 0x14, 0x99130110 }, /* speaker */
8884 { 0x15, 0x01211420 }, /* HP2 */
8885 { 0x18, 0x01a19840 }, /* mic */
8886 { 0x19, 0x99a3094f }, /* int-mic */
8887 { 0x1b, 0x0121441f }, /* HP */
8888 { }
8889 },
8890 .chained = true,
8891 .chain_id = ALC662_FIXUP_SKU_IGNORE
8892 },
8893 [ALC662_FIXUP_ASUS_MODE7] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008894 .type = HDA_FIXUP_PINS,
8895 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008896 { 0x14, 0x99130110 }, /* speaker */
8897 { 0x17, 0x99130111 }, /* speaker */
8898 { 0x18, 0x01a19840 }, /* mic */
8899 { 0x19, 0x99a3094f }, /* int-mic */
8900 { 0x1b, 0x01214020 }, /* HP */
8901 { 0x21, 0x0121401f }, /* HP */
8902 { }
8903 },
8904 .chained = true,
8905 .chain_id = ALC662_FIXUP_SKU_IGNORE
8906 },
8907 [ALC662_FIXUP_ASUS_MODE8] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008908 .type = HDA_FIXUP_PINS,
8909 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008910 { 0x14, 0x99130110 }, /* speaker */
8911 { 0x12, 0x99a30970 }, /* int-mic */
8912 { 0x15, 0x01214020 }, /* HP */
8913 { 0x17, 0x99130111 }, /* speaker */
8914 { 0x18, 0x01a19840 }, /* mic */
8915 { 0x21, 0x0121401f }, /* HP */
8916 { }
8917 },
8918 .chained = true,
8919 .chain_id = ALC662_FIXUP_SKU_IGNORE
Takashi Iwai2996bdb2011-08-18 16:02:24 +02008920 },
Takashi Iwai1565cc32012-02-13 12:03:25 +01008921 [ALC662_FIXUP_NO_JACK_DETECT] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008922 .type = HDA_FIXUP_FUNC,
Takashi Iwai1565cc32012-02-13 12:03:25 +01008923 .v.func = alc_fixup_no_jack_detect,
8924 },
David Henningssonedfe3bf2012-06-12 13:15:12 +02008925 [ALC662_FIXUP_ZOTAC_Z68] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008926 .type = HDA_FIXUP_PINS,
8927 .v.pins = (const struct hda_pintbl[]) {
David Henningssonedfe3bf2012-06-12 13:15:12 +02008928 { 0x1b, 0x02214020 }, /* Front HP */
8929 { }
8930 }
8931 },
Takashi Iwai125821a2012-06-22 14:30:29 +02008932 [ALC662_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008933 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02008934 .v.func = alc_fixup_inv_dmic,
Takashi Iwai125821a2012-06-22 14:30:29 +02008935 },
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02008936 [ALC668_FIXUP_DELL_XPS13] = {
8937 .type = HDA_FIXUP_FUNC,
8938 .v.func = alc_fixup_dell_xps13,
8939 .chained = true,
8940 .chain_id = ALC668_FIXUP_DELL_DISABLE_AAMIX
8941 },
Gabriele Mazzotta5e6db662014-05-20 18:58:26 +02008942 [ALC668_FIXUP_DELL_DISABLE_AAMIX] = {
8943 .type = HDA_FIXUP_FUNC,
8944 .v.func = alc_fixup_disable_aamix,
8945 .chained = true,
8946 .chain_id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE
8947 },
Hui Wang493a52a2014-01-14 14:07:36 +08008948 [ALC668_FIXUP_AUTO_MUTE] = {
8949 .type = HDA_FIXUP_FUNC,
8950 .v.func = alc_fixup_auto_mute_via_amp,
8951 .chained = true,
8952 .chain_id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE
8953 },
David Henningsson1f8b46c2015-05-12 14:38:15 +02008954 [ALC662_FIXUP_DELL_MIC_NO_PRESENCE] = {
8955 .type = HDA_FIXUP_PINS,
8956 .v.pins = (const struct hda_pintbl[]) {
8957 { 0x19, 0x03a1113c }, /* use as headset mic, without its own jack detect */
8958 /* headphone mic by setting pin control of 0x1b (headphone out) to in + vref_50 */
8959 { }
8960 },
8961 .chained = true,
8962 .chain_id = ALC662_FIXUP_HEADSET_MODE
8963 },
8964 [ALC662_FIXUP_HEADSET_MODE] = {
8965 .type = HDA_FIXUP_FUNC,
8966 .v.func = alc_fixup_headset_mode_alc662,
8967 },
David Henningsson73bdd592013-04-15 15:44:14 +02008968 [ALC668_FIXUP_DELL_MIC_NO_PRESENCE] = {
8969 .type = HDA_FIXUP_PINS,
8970 .v.pins = (const struct hda_pintbl[]) {
8971 { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
8972 { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */
8973 { }
8974 },
8975 .chained = true,
8976 .chain_id = ALC668_FIXUP_HEADSET_MODE
8977 },
8978 [ALC668_FIXUP_HEADSET_MODE] = {
8979 .type = HDA_FIXUP_FUNC,
8980 .v.func = alc_fixup_headset_mode_alc668,
8981 },
David Henningsson8e54b4a2014-02-07 09:31:07 +01008982 [ALC662_FIXUP_BASS_MODE4_CHMAP] = {
Takashi Iwai8e383952013-10-30 17:41:12 +01008983 .type = HDA_FIXUP_FUNC,
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01008984 .v.func = alc_fixup_bass_chmap,
Takashi Iwai8e383952013-10-30 17:41:12 +01008985 .chained = true,
8986 .chain_id = ALC662_FIXUP_ASUS_MODE4
8987 },
David Henningsson61a75f12014-02-07 09:31:08 +01008988 [ALC662_FIXUP_BASS_16] = {
8989 .type = HDA_FIXUP_PINS,
8990 .v.pins = (const struct hda_pintbl[]) {
8991 {0x16, 0x80106111}, /* bass speaker */
8992 {}
8993 },
8994 .chained = true,
8995 .chain_id = ALC662_FIXUP_BASS_CHMAP,
8996 },
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01008997 [ALC662_FIXUP_BASS_1A] = {
8998 .type = HDA_FIXUP_PINS,
8999 .v.pins = (const struct hda_pintbl[]) {
9000 {0x1a, 0x80106111}, /* bass speaker */
9001 {}
9002 },
David Henningsson8e54b4a2014-02-07 09:31:07 +01009003 .chained = true,
9004 .chain_id = ALC662_FIXUP_BASS_CHMAP,
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01009005 },
David Henningsson8e54b4a2014-02-07 09:31:07 +01009006 [ALC662_FIXUP_BASS_CHMAP] = {
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01009007 .type = HDA_FIXUP_FUNC,
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01009008 .v.func = alc_fixup_bass_chmap,
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01009009 },
Bobi Mihalca9d4dc582016-03-23 13:26:11 +02009010 [ALC662_FIXUP_ASUS_Nx50] = {
9011 .type = HDA_FIXUP_FUNC,
9012 .v.func = alc_fixup_auto_mute_via_amp,
9013 .chained = true,
9014 .chain_id = ALC662_FIXUP_BASS_1A
9015 },
Mikhail Paulyshkafc7438b2017-04-21 08:52:42 +02009016 [ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE] = {
9017 .type = HDA_FIXUP_FUNC,
9018 .v.func = alc_fixup_headset_mode_alc668,
9019 .chain_id = ALC662_FIXUP_BASS_CHMAP
9020 },
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07009021 [ALC668_FIXUP_ASUS_Nx51] = {
9022 .type = HDA_FIXUP_PINS,
9023 .v.pins = (const struct hda_pintbl[]) {
Mikhail Paulyshkafc7438b2017-04-21 08:52:42 +02009024 { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
9025 { 0x1a, 0x90170151 }, /* bass speaker */
9026 { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07009027 {}
9028 },
9029 .chained = true,
Mikhail Paulyshkafc7438b2017-04-21 08:52:42 +02009030 .chain_id = ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE,
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07009031 },
Takashi Iwai5b7c5e12018-10-09 14:20:17 +02009032 [ALC668_FIXUP_MIC_COEF] = {
Takashi Iwai11ba6112018-10-07 09:44:17 +02009033 .type = HDA_FIXUP_VERBS,
9034 .v.verbs = (const struct hda_verb[]) {
9035 { 0x20, AC_VERB_SET_COEF_INDEX, 0xc3 },
9036 { 0x20, AC_VERB_SET_PROC_COEF, 0x4000 },
9037 {}
9038 },
9039 },
Takashi Iwai5b7c5e12018-10-09 14:20:17 +02009040 [ALC668_FIXUP_ASUS_G751] = {
9041 .type = HDA_FIXUP_PINS,
9042 .v.pins = (const struct hda_pintbl[]) {
9043 { 0x16, 0x0421101f }, /* HP */
9044 {}
9045 },
9046 .chained = true,
9047 .chain_id = ALC668_FIXUP_MIC_COEF
9048 },
Kailang Yang78f4f7c2016-06-07 11:31:34 +08009049 [ALC891_FIXUP_HEADSET_MODE] = {
9050 .type = HDA_FIXUP_FUNC,
9051 .v.func = alc_fixup_headset_mode,
9052 },
9053 [ALC891_FIXUP_DELL_MIC_NO_PRESENCE] = {
9054 .type = HDA_FIXUP_PINS,
9055 .v.pins = (const struct hda_pintbl[]) {
9056 { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
9057 { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */
9058 { }
9059 },
9060 .chained = true,
9061 .chain_id = ALC891_FIXUP_HEADSET_MODE
9062 },
Shrirang Bagul9b51fe32016-08-01 13:16:17 +08009063 [ALC662_FIXUP_ACER_VERITON] = {
9064 .type = HDA_FIXUP_PINS,
9065 .v.pins = (const struct hda_pintbl[]) {
9066 { 0x15, 0x50170120 }, /* no internal speaker */
9067 { }
9068 }
9069 },
Takashi Iwai1a3f0992016-10-20 12:14:51 +02009070 [ALC892_FIXUP_ASROCK_MOBO] = {
9071 .type = HDA_FIXUP_PINS,
9072 .v.pins = (const struct hda_pintbl[]) {
9073 { 0x15, 0x40f000f0 }, /* disabled */
9074 { 0x16, 0x40f000f0 }, /* disabled */
Takashi Iwai1a3f0992016-10-20 12:14:51 +02009075 { }
9076 }
9077 },
Kailang Yangc6790c82016-11-25 16:15:17 +08009078 [ALC662_FIXUP_USI_FUNC] = {
9079 .type = HDA_FIXUP_FUNC,
9080 .v.func = alc662_fixup_usi_headset_mic,
9081 },
9082 [ALC662_FIXUP_USI_HEADSET_MODE] = {
9083 .type = HDA_FIXUP_PINS,
9084 .v.pins = (const struct hda_pintbl[]) {
9085 { 0x19, 0x02a1913c }, /* use as headset mic, without its own jack detect */
9086 { 0x18, 0x01a1903d },
9087 { }
9088 },
9089 .chained = true,
9090 .chain_id = ALC662_FIXUP_USI_FUNC
9091 },
Kailang Yangca169cc2017-04-25 16:17:40 +08009092 [ALC662_FIXUP_LENOVO_MULTI_CODECS] = {
9093 .type = HDA_FIXUP_FUNC,
9094 .v.func = alc233_alc662_fixup_lenovo_dual_codecs,
9095 },
Sergey Bostandzhyan00066e92019-09-06 11:33:43 +02009096 [ALC669_FIXUP_ACER_ASPIRE_ETHOS_HEADSET] = {
9097 .type = HDA_FIXUP_FUNC,
9098 .v.func = alc662_fixup_aspire_ethos_hp,
9099 },
Sergey Bostandzhyan00066e92019-09-06 11:33:43 +02009100 [ALC669_FIXUP_ACER_ASPIRE_ETHOS] = {
9101 .type = HDA_FIXUP_PINS,
9102 .v.pins = (const struct hda_pintbl[]) {
9103 { 0x15, 0x92130110 }, /* front speakers */
9104 { 0x18, 0x99130111 }, /* center/subwoofer */
9105 { 0x1b, 0x11130012 }, /* surround plus jack for HP */
9106 { }
9107 },
9108 .chained = true,
Takashi Iwai336820c2019-11-28 21:26:30 +01009109 .chain_id = ALC669_FIXUP_ACER_ASPIRE_ETHOS_HEADSET
Sergey Bostandzhyan00066e92019-09-06 11:33:43 +02009110 },
Kailang Yang5af290282020-01-17 14:04:01 +08009111 [ALC671_FIXUP_HP_HEADSET_MIC2] = {
9112 .type = HDA_FIXUP_FUNC,
9113 .v.func = alc671_fixup_hp_headset_mic2,
9114 },
Jian-Hong Pand858c702020-03-17 16:28:07 +08009115 [ALC662_FIXUP_ACER_X2660G_HEADSET_MODE] = {
9116 .type = HDA_FIXUP_PINS,
9117 .v.pins = (const struct hda_pintbl[]) {
9118 { 0x1a, 0x02a1113c }, /* use as headset mic, without its own jack detect */
9119 { }
9120 },
9121 .chained = true,
9122 .chain_id = ALC662_FIXUP_USI_FUNC
9123 },
Jian-Hong Pana1244582020-03-17 16:28:09 +08009124 [ALC662_FIXUP_ACER_NITRO_HEADSET_MODE] = {
9125 .type = HDA_FIXUP_PINS,
9126 .v.pins = (const struct hda_pintbl[]) {
9127 { 0x1a, 0x01a11140 }, /* use as headset mic, without its own jack detect */
9128 { 0x1b, 0x0221144f },
9129 { }
9130 },
9131 .chained = true,
9132 .chain_id = ALC662_FIXUP_USI_FUNC
9133 },
David Henningsson6cb3b702010-09-09 08:51:44 +02009134};
9135
Takashi Iwaia9111322011-05-02 11:30:18 +02009136static const struct snd_pci_quirk alc662_fixup_tbl[] = {
Takashi Iwai53c334a2011-08-23 18:27:14 +02009137 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_FIXUP_ASUS_MODE2),
Takashi Iwaid3d38352013-08-19 20:05:50 +02009138 SND_PCI_QUIRK(0x1025, 0x022f, "Acer Aspire One", ALC662_FIXUP_INV_DMIC),
David Henningsson02f6ff92015-12-07 11:29:31 +01009139 SND_PCI_QUIRK(0x1025, 0x0241, "Packard Bell DOTS", ALC662_FIXUP_INV_DMIC),
David Henningssona6c47a82011-02-10 15:39:19 +01009140 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
David Henningsson94024cd2011-04-29 14:10:55 +02009141 SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
Takashi Iwai125821a2012-06-22 14:30:29 +02009142 SND_PCI_QUIRK(0x1025, 0x0349, "eMachines eM250", ALC662_FIXUP_INV_DMIC),
Takashi Iwai18019282013-08-16 08:17:05 +02009143 SND_PCI_QUIRK(0x1025, 0x034a, "Gateway LT27", ALC662_FIXUP_INV_DMIC),
Daniel T Chen2df03512010-10-10 22:39:28 -04009144 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
Jian-Hong Pana1244582020-03-17 16:28:09 +08009145 SND_PCI_QUIRK(0x1025, 0x123c, "Acer Nitro N50-600", ALC662_FIXUP_ACER_NITRO_HEADSET_MODE),
Jian-Hong Pand858c702020-03-17 16:28:07 +08009146 SND_PCI_QUIRK(0x1025, 0x124e, "Acer 2660G", ALC662_FIXUP_ACER_X2660G_HEADSET_MODE),
David Henningsson73bdd592013-04-15 15:44:14 +02009147 SND_PCI_QUIRK(0x1028, 0x05d8, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
9148 SND_PCI_QUIRK(0x1028, 0x05db, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
Takashi Iwaic5d019c2014-07-22 17:33:32 +02009149 SND_PCI_QUIRK(0x1028, 0x05fe, "Dell XPS 15", ALC668_FIXUP_DELL_XPS13),
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02009150 SND_PCI_QUIRK(0x1028, 0x060a, "Dell XPS 13", ALC668_FIXUP_DELL_XPS13),
Niranjan Sivakumar467e1432015-09-05 18:20:35 +02009151 SND_PCI_QUIRK(0x1028, 0x060d, "Dell M3800", ALC668_FIXUP_DELL_XPS13),
David Henningsson09d20142013-11-20 11:43:30 +01009152 SND_PCI_QUIRK(0x1028, 0x0625, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
David Henningssonad8ff992013-11-07 09:28:59 +01009153 SND_PCI_QUIRK(0x1028, 0x0626, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
Kailang Yang8dc9abb2014-04-16 15:53:12 +08009154 SND_PCI_QUIRK(0x1028, 0x0696, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
9155 SND_PCI_QUIRK(0x1028, 0x0698, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
Kailang Yang6a98e342014-10-27 16:20:30 +08009156 SND_PCI_QUIRK(0x1028, 0x069f, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
Takashi Iwaie59ea3e2011-06-29 17:21:00 +02009157 SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800),
Kaho Ng2da2dc92016-05-09 00:27:49 +08009158 SND_PCI_QUIRK(0x1043, 0x1080, "Asus UX501VW", ALC668_FIXUP_HEADSET_MODE),
Bobi Mihalca83a9efb2016-03-23 13:32:33 +02009159 SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_ASUS_Nx50),
Takashi Iwaidb8948e2016-01-18 09:17:30 +01009160 SND_PCI_QUIRK(0x1043, 0x13df, "Asus N550JX", ALC662_FIXUP_BASS_1A),
Bobi Mihalca9d4dc582016-03-23 13:26:11 +02009161 SND_PCI_QUIRK(0x1043, 0x129d, "Asus N750", ALC662_FIXUP_ASUS_Nx50),
Takashi Iwai11ba6112018-10-07 09:44:17 +02009162 SND_PCI_QUIRK(0x1043, 0x12ff, "ASUS G751", ALC668_FIXUP_ASUS_G751),
David Henningsson8e54b4a2014-02-07 09:31:07 +01009163 SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
David Henningsson61a75f12014-02-07 09:31:08 +01009164 SND_PCI_QUIRK(0x1043, 0x15a7, "ASUS UX51VZH", ALC662_FIXUP_BASS_16),
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07009165 SND_PCI_QUIRK(0x1043, 0x177d, "ASUS N551", ALC668_FIXUP_ASUS_Nx51),
9166 SND_PCI_QUIRK(0x1043, 0x17bd, "ASUS N751", ALC668_FIXUP_ASUS_Nx51),
Takashi Iwaic7efff92017-01-04 21:38:16 +01009167 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71SL", ALC662_FIXUP_ASUS_MODE8),
David Henningsson61a75f12014-02-07 09:31:08 +01009168 SND_PCI_QUIRK(0x1043, 0x1b73, "ASUS N55SF", ALC662_FIXUP_BASS_16),
David Henningsson8e54b4a2014-02-07 09:31:07 +01009169 SND_PCI_QUIRK(0x1043, 0x1bf3, "ASUS N76VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
Takashi Iwai1565cc32012-02-13 12:03:25 +01009170 SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT),
Takashi Iwai53c334a2011-08-23 18:27:14 +02009171 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2),
Daniel T Chena0e90ac2010-11-20 10:20:35 -05009172 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
Kailang Yangc6790c82016-11-25 16:15:17 +08009173 SND_PCI_QUIRK(0x14cd, 0x5003, "USI", ALC662_FIXUP_USI_HEADSET_MODE),
Kailang Yangca169cc2017-04-25 16:17:40 +08009174 SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC662_FIXUP_LENOVO_MULTI_CODECS),
Valentine Sinitsynd4118582010-10-01 22:24:08 +06009175 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
David Henningsson6cb3b702010-09-09 08:51:44 +02009176 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
Takashi Iwai1a3f0992016-10-20 12:14:51 +02009177 SND_PCI_QUIRK(0x1849, 0x5892, "ASRock B150M", ALC892_FIXUP_ASROCK_MOBO),
David Henningssonedfe3bf2012-06-12 13:15:12 +02009178 SND_PCI_QUIRK(0x19da, 0xa130, "Zotac Z68", ALC662_FIXUP_ZOTAC_Z68),
Shrirang Bagul9b51fe32016-08-01 13:16:17 +08009179 SND_PCI_QUIRK(0x1b0a, 0x01b8, "ACER Veriton", ALC662_FIXUP_ACER_VERITON),
Anisse Astierd2ebd472011-01-20 12:36:21 +01009180 SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
Sergey Bostandzhyan00066e92019-09-06 11:33:43 +02009181 SND_PCI_QUIRK(0x1025, 0x0566, "Acer Aspire Ethos 8951G", ALC669_FIXUP_ACER_ASPIRE_ETHOS),
Takashi Iwai53c334a2011-08-23 18:27:14 +02009182
9183#if 0
9184 /* Below is a quirk table taken from the old code.
9185 * Basically the device should work as is without the fixup table.
9186 * If BIOS doesn't give a proper info, enable the corresponding
9187 * fixup entry.
Jesper Juhl7d7eb9e2012-04-12 22:11:25 +02009188 */
Takashi Iwai53c334a2011-08-23 18:27:14 +02009189 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC662_FIXUP_ASUS_MODE1),
9190 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC662_FIXUP_ASUS_MODE3),
9191 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC662_FIXUP_ASUS_MODE1),
9192 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC662_FIXUP_ASUS_MODE3),
9193 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
9194 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
9195 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
9196 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC662_FIXUP_ASUS_MODE1),
9197 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC662_FIXUP_ASUS_MODE1),
9198 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
9199 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC662_FIXUP_ASUS_MODE7),
9200 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC662_FIXUP_ASUS_MODE7),
9201 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC662_FIXUP_ASUS_MODE8),
9202 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC662_FIXUP_ASUS_MODE3),
9203 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC662_FIXUP_ASUS_MODE1),
9204 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
9205 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_FIXUP_ASUS_MODE2),
9206 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC662_FIXUP_ASUS_MODE1),
9207 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
9208 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
9209 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
9210 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
9211 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC662_FIXUP_ASUS_MODE1),
9212 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC662_FIXUP_ASUS_MODE3),
9213 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_FIXUP_ASUS_MODE2),
9214 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
9215 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC662_FIXUP_ASUS_MODE5),
9216 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
9217 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
9218 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC662_FIXUP_ASUS_MODE1),
9219 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
9220 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
9221 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC662_FIXUP_ASUS_MODE3),
9222 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC662_FIXUP_ASUS_MODE3),
9223 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC662_FIXUP_ASUS_MODE1),
9224 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC662_FIXUP_ASUS_MODE1),
9225 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC662_FIXUP_ASUS_MODE1),
9226 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC662_FIXUP_ASUS_MODE1),
9227 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC662_FIXUP_ASUS_MODE1),
9228 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
9229 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_FIXUP_ASUS_MODE2),
9230 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC662_FIXUP_ASUS_MODE1),
9231 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
9232 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC662_FIXUP_ASUS_MODE3),
9233 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC662_FIXUP_ASUS_MODE1),
9234 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC662_FIXUP_ASUS_MODE1),
9235 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC662_FIXUP_ASUS_MODE1),
9236 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_FIXUP_ASUS_MODE2),
9237 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
9238 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE4),
9239#endif
David Henningsson6cb3b702010-09-09 08:51:44 +02009240 {}
9241};
9242
Takashi Iwai1727a772013-01-10 09:52:52 +01009243static const struct hda_model_fixup alc662_fixup_models[] = {
Takashi Iwaiaa3841b2018-06-26 07:42:40 +02009244 {.id = ALC662_FIXUP_ASPIRE, .name = "aspire"},
9245 {.id = ALC662_FIXUP_IDEAPAD, .name = "ideapad"},
Todd Broch6be79482010-12-07 16:51:05 -08009246 {.id = ALC272_FIXUP_MARIO, .name = "mario"},
Takashi Iwaiaa3841b2018-06-26 07:42:40 +02009247 {.id = ALC662_FIXUP_HP_RP5800, .name = "hp-rp5800"},
Takashi Iwai53c334a2011-08-23 18:27:14 +02009248 {.id = ALC662_FIXUP_ASUS_MODE1, .name = "asus-mode1"},
9249 {.id = ALC662_FIXUP_ASUS_MODE2, .name = "asus-mode2"},
9250 {.id = ALC662_FIXUP_ASUS_MODE3, .name = "asus-mode3"},
9251 {.id = ALC662_FIXUP_ASUS_MODE4, .name = "asus-mode4"},
9252 {.id = ALC662_FIXUP_ASUS_MODE5, .name = "asus-mode5"},
9253 {.id = ALC662_FIXUP_ASUS_MODE6, .name = "asus-mode6"},
9254 {.id = ALC662_FIXUP_ASUS_MODE7, .name = "asus-mode7"},
9255 {.id = ALC662_FIXUP_ASUS_MODE8, .name = "asus-mode8"},
Takashi Iwaiaa3841b2018-06-26 07:42:40 +02009256 {.id = ALC662_FIXUP_ZOTAC_Z68, .name = "zotac-z68"},
Takashi Iwai6e72aa52012-06-25 10:52:25 +02009257 {.id = ALC662_FIXUP_INV_DMIC, .name = "inv-dmic"},
Takashi Iwaiaa3841b2018-06-26 07:42:40 +02009258 {.id = ALC662_FIXUP_DELL_MIC_NO_PRESENCE, .name = "alc662-headset-multi"},
David Henningssone32aa852013-06-17 11:04:02 +02009259 {.id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE, .name = "dell-headset-multi"},
Takashi Iwaiaa3841b2018-06-26 07:42:40 +02009260 {.id = ALC662_FIXUP_HEADSET_MODE, .name = "alc662-headset"},
9261 {.id = ALC668_FIXUP_HEADSET_MODE, .name = "alc668-headset"},
9262 {.id = ALC662_FIXUP_BASS_16, .name = "bass16"},
9263 {.id = ALC662_FIXUP_BASS_1A, .name = "bass1a"},
9264 {.id = ALC668_FIXUP_AUTO_MUTE, .name = "automute"},
9265 {.id = ALC668_FIXUP_DELL_XPS13, .name = "dell-xps13"},
9266 {.id = ALC662_FIXUP_ASUS_Nx50, .name = "asus-nx50"},
9267 {.id = ALC668_FIXUP_ASUS_Nx51, .name = "asus-nx51"},
Takashi Iwai40c51672018-10-07 09:47:39 +02009268 {.id = ALC668_FIXUP_ASUS_G751, .name = "asus-g751"},
Takashi Iwaiaa3841b2018-06-26 07:42:40 +02009269 {.id = ALC891_FIXUP_HEADSET_MODE, .name = "alc891-headset"},
9270 {.id = ALC891_FIXUP_DELL_MIC_NO_PRESENCE, .name = "alc891-headset-multi"},
9271 {.id = ALC662_FIXUP_ACER_VERITON, .name = "acer-veriton"},
9272 {.id = ALC892_FIXUP_ASROCK_MOBO, .name = "asrock-mobo"},
9273 {.id = ALC662_FIXUP_USI_HEADSET_MODE, .name = "usi-headset"},
Takashi Iwaiba90d6a2017-05-22 16:38:47 +02009274 {.id = ALC662_FIXUP_LENOVO_MULTI_CODECS, .name = "dual-codecs"},
Sergey Bostandzhyan00066e92019-09-06 11:33:43 +02009275 {.id = ALC669_FIXUP_ACER_ASPIRE_ETHOS, .name = "aspire-ethos"},
Todd Broch6be79482010-12-07 16:51:05 -08009276 {}
9277};
David Henningsson6cb3b702010-09-09 08:51:44 +02009278
Hui Wang532895c2014-05-29 15:59:19 +08009279static const struct snd_hda_pin_quirk alc662_pin_fixup_tbl[] = {
Kailang Yang78f4f7c2016-06-07 11:31:34 +08009280 SND_HDA_PIN_QUIRK(0x10ec0867, 0x1028, "Dell", ALC891_FIXUP_DELL_MIC_NO_PRESENCE,
9281 {0x17, 0x02211010},
9282 {0x18, 0x01a19030},
9283 {0x1a, 0x01813040},
9284 {0x21, 0x01014020}),
Hui Wang4b4e0e32019-07-16 15:21:34 +08009285 SND_HDA_PIN_QUIRK(0x10ec0867, 0x1028, "Dell", ALC891_FIXUP_DELL_MIC_NO_PRESENCE,
9286 {0x16, 0x01813030},
9287 {0x17, 0x02211010},
9288 {0x18, 0x01a19040},
9289 {0x21, 0x01014020}),
David Henningsson1f8b46c2015-05-12 14:38:15 +02009290 SND_HDA_PIN_QUIRK(0x10ec0662, 0x1028, "Dell", ALC662_FIXUP_DELL_MIC_NO_PRESENCE,
David Henningsson1f8b46c2015-05-12 14:38:15 +02009291 {0x14, 0x01014010},
David Henningsson1f8b46c2015-05-12 14:38:15 +02009292 {0x18, 0x01a19020},
David Henningsson1f8b46c2015-05-12 14:38:15 +02009293 {0x1a, 0x0181302f},
Hui Wang11580292015-08-03 11:03:49 +08009294 {0x1b, 0x0221401f}),
David Henningsson76c21322014-06-24 14:46:54 +02009295 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
9296 {0x12, 0x99a30130},
9297 {0x14, 0x90170110},
9298 {0x15, 0x0321101f},
Hui Wang11580292015-08-03 11:03:49 +08009299 {0x16, 0x03011020}),
David Henningsson76c21322014-06-24 14:46:54 +02009300 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
9301 {0x12, 0x99a30140},
9302 {0x14, 0x90170110},
9303 {0x15, 0x0321101f},
Hui Wang11580292015-08-03 11:03:49 +08009304 {0x16, 0x03011020}),
David Henningsson76c21322014-06-24 14:46:54 +02009305 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
9306 {0x12, 0x99a30150},
9307 {0x14, 0x90170110},
9308 {0x15, 0x0321101f},
Hui Wang11580292015-08-03 11:03:49 +08009309 {0x16, 0x03011020}),
David Henningsson76c21322014-06-24 14:46:54 +02009310 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
David Henningsson76c21322014-06-24 14:46:54 +02009311 {0x14, 0x90170110},
9312 {0x15, 0x0321101f},
Hui Wang11580292015-08-03 11:03:49 +08009313 {0x16, 0x03011020}),
David Henningsson76c21322014-06-24 14:46:54 +02009314 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell XPS 15", ALC668_FIXUP_AUTO_MUTE,
9315 {0x12, 0x90a60130},
9316 {0x14, 0x90170110},
Hui Wang11580292015-08-03 11:03:49 +08009317 {0x15, 0x0321101f}),
Kailang Yang5af290282020-01-17 14:04:01 +08009318 SND_HDA_PIN_QUIRK(0x10ec0671, 0x103c, "HP cPC", ALC671_FIXUP_HP_HEADSET_MIC2,
9319 {0x14, 0x01014010},
9320 {0x17, 0x90170150},
Kailang Yangf2adbae2020-02-05 15:40:01 +08009321 {0x19, 0x02a11060},
Kailang Yang5af290282020-01-17 14:04:01 +08009322 {0x1b, 0x01813030},
9323 {0x21, 0x02211020}),
9324 SND_HDA_PIN_QUIRK(0x10ec0671, 0x103c, "HP cPC", ALC671_FIXUP_HP_HEADSET_MIC2,
9325 {0x14, 0x01014010},
9326 {0x18, 0x01a19040},
9327 {0x1b, 0x01813030},
9328 {0x21, 0x02211020}),
9329 SND_HDA_PIN_QUIRK(0x10ec0671, 0x103c, "HP cPC", ALC671_FIXUP_HP_HEADSET_MIC2,
9330 {0x14, 0x01014020},
9331 {0x17, 0x90170110},
9332 {0x18, 0x01a19050},
9333 {0x1b, 0x01813040},
9334 {0x21, 0x02211030}),
Hui Wang532895c2014-05-29 15:59:19 +08009335 {}
9336};
9337
Takashi Iwai1d045db2011-07-07 18:23:21 +02009338/*
9339 */
Kailang Yangbc9f98a2007-04-12 13:06:07 +02009340static int patch_alc662(struct hda_codec *codec)
9341{
9342 struct alc_spec *spec;
Takashi Iwai3de95172012-05-07 18:03:15 +02009343 int err;
Kailang Yangbc9f98a2007-04-12 13:06:07 +02009344
Takashi Iwai3de95172012-05-07 18:03:15 +02009345 err = alc_alloc_spec(codec, 0x0b);
9346 if (err < 0)
9347 return err;
Kailang Yangbc9f98a2007-04-12 13:06:07 +02009348
Takashi Iwai3de95172012-05-07 18:03:15 +02009349 spec = codec->spec;
Takashi Iwai1f0f4b82011-06-27 10:52:59 +02009350
Takashi Iwai225068a2015-05-29 10:42:14 +02009351 spec->shutup = alc_eapd_shutup;
9352
Takashi Iwai53c334a2011-08-23 18:27:14 +02009353 /* handle multiple HPs as is */
9354 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
9355
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +02009356 alc_fix_pll_init(codec, 0x20, 0x04, 15);
9357
Takashi Iwai7639a062015-03-03 10:07:24 +01009358 switch (codec->core.vendor_id) {
Kailang Yangf3f91852014-10-24 15:43:46 +08009359 case 0x10ec0668:
9360 spec->init_hook = alc668_restore_default_value;
9361 break;
Kailang Yangf3f91852014-10-24 15:43:46 +08009362 }
Kailang Yang8663ff72012-06-29 09:35:52 +02009363
Takashi Iwaic9af7532019-05-10 11:01:43 +02009364 alc_pre_init(codec);
9365
Takashi Iwai1727a772013-01-10 09:52:52 +01009366 snd_hda_pick_fixup(codec, alc662_fixup_models,
Takashi Iwai8e5a0502012-06-21 15:49:33 +02009367 alc662_fixup_tbl, alc662_fixups);
Hui Wang0fc1e442019-08-16 14:27:39 +08009368 snd_hda_pick_pin_fixup(codec, alc662_pin_fixup_tbl, alc662_fixups, true);
Takashi Iwai1727a772013-01-10 09:52:52 +01009369 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai8e5a0502012-06-21 15:49:33 +02009370
9371 alc_auto_parse_customize_define(codec);
9372
Takashi Iwai7504b6c2013-03-18 11:25:51 +01009373 if (has_cdefine_beep(codec))
9374 spec->gen.beep_nid = 0x01;
9375
Takashi Iwai1bb7e432011-10-17 16:50:59 +02009376 if ((alc_get_coef0(codec) & (1 << 14)) &&
Takashi Iwai5100cd02014-02-15 10:03:19 +01009377 codec->bus->pci && codec->bus->pci->subsystem_vendor == 0x1025 &&
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02009378 spec->cdefine.platform_type == 1) {
Wei Yongjun6134b1a2013-04-18 11:12:59 +08009379 err = alc_codec_rename(codec, "ALC272X");
9380 if (err < 0)
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02009381 goto error;
Takashi Iwai20ca0c32011-10-17 16:00:35 +02009382 }
Kailang Yang274693f2009-12-03 10:07:50 +01009383
Takashi Iwaib9c51062011-08-24 18:08:07 +02009384 /* automatic parse from the BIOS config */
9385 err = alc662_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02009386 if (err < 0)
9387 goto error;
Kailang Yangbc9f98a2007-04-12 13:06:07 +02009388
Takashi Iwai7504b6c2013-03-18 11:25:51 +01009389 if (!spec->gen.no_analog && spec->gen.beep_nid) {
Takashi Iwai7639a062015-03-03 10:07:24 +01009390 switch (codec->core.vendor_id) {
Kailang Yangda00c242010-03-19 11:23:45 +01009391 case 0x10ec0662:
Takashi Iwaifea80fa2018-06-20 12:52:46 +02009392 err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
Kailang Yangda00c242010-03-19 11:23:45 +01009393 break;
9394 case 0x10ec0272:
9395 case 0x10ec0663:
9396 case 0x10ec0665:
Kailang Yang9ad54542013-11-26 15:41:40 +08009397 case 0x10ec0668:
Takashi Iwaifea80fa2018-06-20 12:52:46 +02009398 err = set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
Kailang Yangda00c242010-03-19 11:23:45 +01009399 break;
9400 case 0x10ec0273:
Takashi Iwaifea80fa2018-06-20 12:52:46 +02009401 err = set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
Kailang Yangda00c242010-03-19 11:23:45 +01009402 break;
9403 }
Takashi Iwaifea80fa2018-06-20 12:52:46 +02009404 if (err < 0)
9405 goto error;
Kailang Yangcec27c82010-02-04 14:18:18 +01009406 }
Takashi Iwai2134ea42008-01-10 16:53:55 +01009407
Takashi Iwai1727a772013-01-10 09:52:52 +01009408 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01009409
Kailang Yangbc9f98a2007-04-12 13:06:07 +02009410 return 0;
Kailang Yangbc9f98a2007-04-12 13:06:07 +02009411
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02009412 error:
9413 alc_free(codec);
9414 return err;
Kailang Yangb478b992011-05-18 11:51:15 +02009415}
9416
Kailang Yangbc9f98a2007-04-12 13:06:07 +02009417/*
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009418 * ALC680 support
9419 */
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009420
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009421static int alc680_parse_auto_config(struct hda_codec *codec)
9422{
Takashi Iwai3e6179b2011-07-08 16:55:13 +02009423 return alc_parse_auto_config(codec, NULL, NULL);
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009424}
9425
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009426/*
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009427 */
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009428static int patch_alc680(struct hda_codec *codec)
9429{
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009430 int err;
9431
Takashi Iwai1f0f4b82011-06-27 10:52:59 +02009432 /* ALC680 has no aa-loopback mixer */
Takashi Iwai3de95172012-05-07 18:03:15 +02009433 err = alc_alloc_spec(codec, 0);
9434 if (err < 0)
9435 return err;
Takashi Iwai1f0f4b82011-06-27 10:52:59 +02009436
Takashi Iwai1ebec5f2011-08-15 13:21:48 +02009437 /* automatic parse from the BIOS config */
9438 err = alc680_parse_auto_config(codec);
9439 if (err < 0) {
9440 alc_free(codec);
9441 return err;
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009442 }
9443
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009444 return 0;
9445}
9446
9447/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07009448 * patch entries
9449 */
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009450static const struct hda_device_id snd_hda_id_realtek[] = {
Kailang Yang0a6f0602017-06-30 16:00:48 +08009451 HDA_CODEC_ENTRY(0x10ec0215, "ALC215", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009452 HDA_CODEC_ENTRY(0x10ec0221, "ALC221", patch_alc269),
Hui Wang2a36c162019-09-04 13:53:27 +08009453 HDA_CODEC_ENTRY(0x10ec0222, "ALC222", patch_alc269),
Kailang Yang42314302016-02-03 15:03:50 +08009454 HDA_CODEC_ENTRY(0x10ec0225, "ALC225", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009455 HDA_CODEC_ENTRY(0x10ec0231, "ALC231", patch_alc269),
9456 HDA_CODEC_ENTRY(0x10ec0233, "ALC233", patch_alc269),
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08009457 HDA_CODEC_ENTRY(0x10ec0234, "ALC234", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009458 HDA_CODEC_ENTRY(0x10ec0235, "ALC233", patch_alc269),
Kailang Yang736f20a2017-10-20 15:06:34 +08009459 HDA_CODEC_ENTRY(0x10ec0236, "ALC236", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009460 HDA_CODEC_ENTRY(0x10ec0255, "ALC255", patch_alc269),
9461 HDA_CODEC_ENTRY(0x10ec0256, "ALC256", patch_alc269),
Kailang Yangf429e7e2017-12-05 15:38:24 +08009462 HDA_CODEC_ENTRY(0x10ec0257, "ALC257", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009463 HDA_CODEC_ENTRY(0x10ec0260, "ALC260", patch_alc260),
9464 HDA_CODEC_ENTRY(0x10ec0262, "ALC262", patch_alc262),
9465 HDA_CODEC_ENTRY(0x10ec0267, "ALC267", patch_alc268),
9466 HDA_CODEC_ENTRY(0x10ec0268, "ALC268", patch_alc268),
9467 HDA_CODEC_ENTRY(0x10ec0269, "ALC269", patch_alc269),
9468 HDA_CODEC_ENTRY(0x10ec0270, "ALC270", patch_alc269),
9469 HDA_CODEC_ENTRY(0x10ec0272, "ALC272", patch_alc662),
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08009470 HDA_CODEC_ENTRY(0x10ec0274, "ALC274", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009471 HDA_CODEC_ENTRY(0x10ec0275, "ALC275", patch_alc269),
9472 HDA_CODEC_ENTRY(0x10ec0276, "ALC276", patch_alc269),
9473 HDA_CODEC_ENTRY(0x10ec0280, "ALC280", patch_alc269),
9474 HDA_CODEC_ENTRY(0x10ec0282, "ALC282", patch_alc269),
9475 HDA_CODEC_ENTRY(0x10ec0283, "ALC283", patch_alc269),
9476 HDA_CODEC_ENTRY(0x10ec0284, "ALC284", patch_alc269),
Kailang Yang0a6f0602017-06-30 16:00:48 +08009477 HDA_CODEC_ENTRY(0x10ec0285, "ALC285", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009478 HDA_CODEC_ENTRY(0x10ec0286, "ALC286", patch_alc269),
9479 HDA_CODEC_ENTRY(0x10ec0288, "ALC288", patch_alc269),
Kailang Yang0a6f0602017-06-30 16:00:48 +08009480 HDA_CODEC_ENTRY(0x10ec0289, "ALC289", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009481 HDA_CODEC_ENTRY(0x10ec0290, "ALC290", patch_alc269),
9482 HDA_CODEC_ENTRY(0x10ec0292, "ALC292", patch_alc269),
9483 HDA_CODEC_ENTRY(0x10ec0293, "ALC293", patch_alc269),
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08009484 HDA_CODEC_ENTRY(0x10ec0294, "ALC294", patch_alc269),
Kailang Yang7d727862016-05-24 16:46:07 +08009485 HDA_CODEC_ENTRY(0x10ec0295, "ALC295", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009486 HDA_CODEC_ENTRY(0x10ec0298, "ALC298", patch_alc269),
Kailang Yang28f1f9b2017-01-04 14:49:07 +08009487 HDA_CODEC_ENTRY(0x10ec0299, "ALC299", patch_alc269),
Kailang Yang1078bef2018-11-08 16:36:15 +08009488 HDA_CODEC_ENTRY(0x10ec0300, "ALC300", patch_alc269),
Kailang Yangf0778872019-10-24 15:13:32 +08009489 HDA_CODEC_ENTRY(0x10ec0623, "ALC623", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009490 HDA_CODEC_REV_ENTRY(0x10ec0861, 0x100340, "ALC660", patch_alc861),
9491 HDA_CODEC_ENTRY(0x10ec0660, "ALC660-VD", patch_alc861vd),
9492 HDA_CODEC_ENTRY(0x10ec0861, "ALC861", patch_alc861),
9493 HDA_CODEC_ENTRY(0x10ec0862, "ALC861-VD", patch_alc861vd),
9494 HDA_CODEC_REV_ENTRY(0x10ec0662, 0x100002, "ALC662 rev2", patch_alc882),
9495 HDA_CODEC_REV_ENTRY(0x10ec0662, 0x100101, "ALC662 rev1", patch_alc662),
9496 HDA_CODEC_REV_ENTRY(0x10ec0662, 0x100300, "ALC662 rev3", patch_alc662),
9497 HDA_CODEC_ENTRY(0x10ec0663, "ALC663", patch_alc662),
9498 HDA_CODEC_ENTRY(0x10ec0665, "ALC665", patch_alc662),
9499 HDA_CODEC_ENTRY(0x10ec0667, "ALC667", patch_alc662),
9500 HDA_CODEC_ENTRY(0x10ec0668, "ALC668", patch_alc662),
9501 HDA_CODEC_ENTRY(0x10ec0670, "ALC670", patch_alc662),
9502 HDA_CODEC_ENTRY(0x10ec0671, "ALC671", patch_alc662),
9503 HDA_CODEC_ENTRY(0x10ec0680, "ALC680", patch_alc680),
Kailang Yang6fbae352016-05-30 16:44:20 +08009504 HDA_CODEC_ENTRY(0x10ec0700, "ALC700", patch_alc269),
9505 HDA_CODEC_ENTRY(0x10ec0701, "ALC701", patch_alc269),
9506 HDA_CODEC_ENTRY(0x10ec0703, "ALC703", patch_alc269),
Kailang Yang83629532019-05-02 16:03:26 +08009507 HDA_CODEC_ENTRY(0x10ec0711, "ALC711", patch_alc269),
Kailang Yang78f4f7c2016-06-07 11:31:34 +08009508 HDA_CODEC_ENTRY(0x10ec0867, "ALC891", patch_alc662),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009509 HDA_CODEC_ENTRY(0x10ec0880, "ALC880", patch_alc880),
9510 HDA_CODEC_ENTRY(0x10ec0882, "ALC882", patch_alc882),
9511 HDA_CODEC_ENTRY(0x10ec0883, "ALC883", patch_alc882),
9512 HDA_CODEC_REV_ENTRY(0x10ec0885, 0x100101, "ALC889A", patch_alc882),
9513 HDA_CODEC_REV_ENTRY(0x10ec0885, 0x100103, "ALC889A", patch_alc882),
9514 HDA_CODEC_ENTRY(0x10ec0885, "ALC885", patch_alc882),
9515 HDA_CODEC_ENTRY(0x10ec0887, "ALC887", patch_alc882),
9516 HDA_CODEC_REV_ENTRY(0x10ec0888, 0x100101, "ALC1200", patch_alc882),
9517 HDA_CODEC_ENTRY(0x10ec0888, "ALC888", patch_alc882),
9518 HDA_CODEC_ENTRY(0x10ec0889, "ALC889", patch_alc882),
9519 HDA_CODEC_ENTRY(0x10ec0892, "ALC892", patch_alc662),
9520 HDA_CODEC_ENTRY(0x10ec0899, "ALC898", patch_alc882),
9521 HDA_CODEC_ENTRY(0x10ec0900, "ALC1150", patch_alc882),
Kailang Yang6d9ffcf2020-01-03 16:24:06 +08009522 HDA_CODEC_ENTRY(0x10ec0b00, "ALCS1200A", patch_alc882),
Kailang Yang65553b12017-07-11 15:15:47 +08009523 HDA_CODEC_ENTRY(0x10ec1168, "ALC1220", patch_alc882),
Kailang Yanga535ad52017-01-16 16:59:26 +08009524 HDA_CODEC_ENTRY(0x10ec1220, "ALC1220", patch_alc882),
Linus Torvalds1da177e2005-04-16 15:20:36 -07009525 {} /* terminator */
9526};
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009527MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_realtek);
Takashi Iwai1289e9e2008-11-27 15:47:11 +01009528
9529MODULE_LICENSE("GPL");
9530MODULE_DESCRIPTION("Realtek HD-audio codec");
9531
Takashi Iwaid8a766a2015-02-17 15:25:37 +01009532static struct hda_codec_driver realtek_driver = {
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009533 .id = snd_hda_id_realtek,
Takashi Iwai1289e9e2008-11-27 15:47:11 +01009534};
9535
Takashi Iwaid8a766a2015-02-17 15:25:37 +01009536module_hda_codec_driver(realtek_driver);