blob: 6d73f8beadb6e17f84dbeeb16e54a2df413b0fb6 [file] [log] [blame]
Thomas Gleixnerd0fa1172019-05-20 19:07:57 +02001// SPDX-License-Identifier: GPL-2.0-or-later
Linus Torvalds1da177e2005-04-16 15:20:36 -07002/*
3 * Universal Interface for Intel High Definition Audio Codec
4 *
Takashi Iwai1d045db2011-07-07 18:23:21 +02005 * HD audio interface patch for Realtek ALC codecs
Linus Torvalds1da177e2005-04-16 15:20:36 -07006 *
Kailang Yangdf694da2005-12-05 19:42:22 +01007 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
8 * PeiSen Hou <pshou@realtek.com.tw>
Linus Torvalds1da177e2005-04-16 15:20:36 -07009 * Takashi Iwai <tiwai@suse.de>
Jonathan Woithe409a3e92012-03-27 13:01:01 +103010 * Jonathan Woithe <jwoithe@just42.net>
Linus Torvalds1da177e2005-04-16 15:20:36 -070011 */
12
Linus Torvalds1da177e2005-04-16 15:20:36 -070013#include <linux/init.h>
14#include <linux/delay.h>
15#include <linux/slab.h>
16#include <linux/pci.h>
Takashi Iwai08fb0d02013-01-10 17:33:58 +010017#include <linux/dmi.h>
Paul Gortmakerda155d52011-07-15 12:38:28 -040018#include <linux/module.h>
David Henningsson33f4acd2015-01-07 15:50:13 +010019#include <linux/input.h>
Kai-Heng Feng87dc3642020-04-30 21:52:07 +080020#include <linux/leds.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070021#include <sound/core.h>
Kailang Yang9ad0e492010-09-14 23:22:00 +020022#include <sound/jack.h>
Pierre-Louis Bossartbe57bff2018-08-22 15:24:57 -050023#include <sound/hda_codec.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070024#include "hda_local.h"
Takashi Iwai23d30f22012-05-07 17:17:32 +020025#include "hda_auto_parser.h"
Takashi Iwai1835a0f2011-10-27 22:12:46 +020026#include "hda_jack.h"
Takashi Iwai08c189f2012-12-19 15:22:24 +010027#include "hda_generic.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070028
Takashi Iwaicd63a5f2013-07-05 12:13:59 +020029/* keep halting ALC5505 DSP, for power saving */
30#define HALT_REALTEK_ALC5505
31
Takashi Iwai4a79ba32009-04-22 16:31:35 +020032/* extra amp-initialization sequence types */
33enum {
Takashi Iwai1c76aa52018-06-21 16:37:54 +020034 ALC_INIT_UNDEFINED,
Takashi Iwai4a79ba32009-04-22 16:31:35 +020035 ALC_INIT_NONE,
36 ALC_INIT_DEFAULT,
Takashi Iwai4a79ba32009-04-22 16:31:35 +020037};
38
David Henningsson73bdd592013-04-15 15:44:14 +020039enum {
40 ALC_HEADSET_MODE_UNKNOWN,
41 ALC_HEADSET_MODE_UNPLUGGED,
42 ALC_HEADSET_MODE_HEADSET,
43 ALC_HEADSET_MODE_MIC,
44 ALC_HEADSET_MODE_HEADPHONE,
45};
46
47enum {
48 ALC_HEADSET_TYPE_UNKNOWN,
49 ALC_HEADSET_TYPE_CTIA,
50 ALC_HEADSET_TYPE_OMTP,
51};
52
Hui Wangc7b60a82015-12-28 11:35:25 +080053enum {
54 ALC_KEY_MICMUTE_INDEX,
55};
56
Kailang Yangda00c242010-03-19 11:23:45 +010057struct alc_customize_define {
58 unsigned int sku_cfg;
59 unsigned char port_connectivity;
60 unsigned char check_sum;
61 unsigned char customization;
62 unsigned char external_amp;
63 unsigned int enable_pcbeep:1;
64 unsigned int platform_type:1;
65 unsigned int swap:1;
66 unsigned int override:1;
David Henningsson90622912010-10-14 14:50:18 +020067 unsigned int fixup:1; /* Means that this sku is set by driver, not read from hw */
Kailang Yangda00c242010-03-19 11:23:45 +010068};
69
Linus Torvalds1da177e2005-04-16 15:20:36 -070070struct alc_spec {
Takashi Iwai08c189f2012-12-19 15:22:24 +010071 struct hda_gen_spec gen; /* must be at head */
Takashi Iwai23d30f22012-05-07 17:17:32 +020072
Linus Torvalds1da177e2005-04-16 15:20:36 -070073 /* codec parameterization */
Kailang Yangda00c242010-03-19 11:23:45 +010074 struct alc_customize_define cdefine;
Takashi Iwai08c189f2012-12-19 15:22:24 +010075 unsigned int parse_flags; /* flag for snd_hda_parse_pin_defcfg() */
76
Takashi Iwai5579cd62018-06-19 22:22:41 +020077 /* GPIO bits */
78 unsigned int gpio_mask;
79 unsigned int gpio_dir;
80 unsigned int gpio_data;
Takashi Iwai215c8502018-06-19 22:34:26 +020081 bool gpio_write_delay; /* add a delay before writing gpio_data */
Takashi Iwai5579cd62018-06-19 22:22:41 +020082
Takashi Iwai08fb0d02013-01-10 17:33:58 +010083 /* mute LED for HP laptops, see alc269_fixup_mic_mute_hook() */
84 int mute_led_polarity;
Kai-Heng Fengdbd13172020-04-30 16:32:51 +080085 int micmute_led_polarity;
Takashi Iwai08fb0d02013-01-10 17:33:58 +010086 hda_nid_t mute_led_nid;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +080087 hda_nid_t cap_mute_led_nid;
Takashi Iwai08fb0d02013-01-10 17:33:58 +010088
Takashi Iwai0f32fd192014-11-19 12:16:14 +010089 unsigned int gpio_mute_led_mask;
90 unsigned int gpio_mic_led_mask;
Kailang Yang431e76c2020-04-07 14:40:20 +080091 unsigned int mute_led_coef_idx;
92 unsigned int mute_led_coefbit_mask;
93 unsigned int mute_led_coefbit_on;
94 unsigned int mute_led_coefbit_off;
95 unsigned int mic_led_coef_idx;
96 unsigned int mic_led_coefbit_mask;
97 unsigned int mic_led_coefbit_on;
98 unsigned int mic_led_coefbit_off;
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +010099
David Henningsson73bdd592013-04-15 15:44:14 +0200100 hda_nid_t headset_mic_pin;
101 hda_nid_t headphone_mic_pin;
102 int current_headset_mode;
103 int current_headset_type;
104
Takashi Iwaiae6b8132006-03-03 16:47:17 +0100105 /* hooks */
106 void (*init_hook)(struct hda_codec *codec);
Takashi Iwai83012a72012-08-24 18:38:08 +0200107#ifdef CONFIG_PM
Daniel T Chenc97259d2009-12-27 18:52:08 -0500108 void (*power_hook)(struct hda_codec *codec);
Hector Martinf5de24b2009-12-20 22:51:31 +0100109#endif
Takashi Iwai1c7161532011-04-07 10:37:16 +0200110 void (*shutup)(struct hda_codec *codec);
Takashi Iwai70a09762015-12-15 14:59:58 +0100111 void (*reboot_notify)(struct hda_codec *codec);
Takashi Iwaid922b512011-04-28 12:18:53 +0200112
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200113 int init_amp;
Takashi Iwaid433a672010-09-20 15:11:54 +0200114 int codec_variant; /* flag for other variants */
Kailang Yang97a26572013-11-29 00:35:26 -0500115 unsigned int has_alc5505_dsp:1;
116 unsigned int no_depop_delay:1;
Kailang Yang693abe12019-01-29 15:38:21 +0800117 unsigned int done_hp_init:1;
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +0100118 unsigned int no_shutup_pins:1;
Kailang Yangd3ba58b2019-05-06 15:09:42 +0800119 unsigned int ultra_low_power:1;
Hui Wang476c02e2020-03-29 16:20:18 +0800120 unsigned int has_hs_key:1;
Takashi Iwaie64f14f2009-01-20 18:32:55 +0100121
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200122 /* for PLL fix */
123 hda_nid_t pll_nid;
124 unsigned int pll_coef_idx, pll_coef_bit;
Takashi Iwai1bb7e432011-10-17 16:50:59 +0200125 unsigned int coef0;
David Henningsson33f4acd2015-01-07 15:50:13 +0100126 struct input_dev *kb_dev;
Hui Wangc7b60a82015-12-28 11:35:25 +0800127 u8 alc_mute_keycode_map[1];
Kailang Yangdf694da2005-12-05 19:42:22 +0100128};
129
Takashi Iwai23f0c042009-02-26 13:03:58 +0100130/*
Takashi Iwaif2a227c2014-08-18 13:35:22 +0200131 * COEF access helper functions
132 */
133
134static int alc_read_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
135 unsigned int coef_idx)
136{
137 unsigned int val;
138
139 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, coef_idx);
140 val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PROC_COEF, 0);
141 return val;
142}
143
144#define alc_read_coef_idx(codec, coef_idx) \
145 alc_read_coefex_idx(codec, 0x20, coef_idx)
146
147static void alc_write_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
148 unsigned int coef_idx, unsigned int coef_val)
149{
150 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, coef_idx);
151 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PROC_COEF, coef_val);
152}
153
154#define alc_write_coef_idx(codec, coef_idx, coef_val) \
155 alc_write_coefex_idx(codec, 0x20, coef_idx, coef_val)
156
Takashi Iwai98b24882014-08-18 13:47:50 +0200157static void alc_update_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
158 unsigned int coef_idx, unsigned int mask,
159 unsigned int bits_set)
160{
161 unsigned int val = alc_read_coefex_idx(codec, nid, coef_idx);
162
163 if (val != -1)
164 alc_write_coefex_idx(codec, nid, coef_idx,
165 (val & ~mask) | bits_set);
166}
167
168#define alc_update_coef_idx(codec, coef_idx, mask, bits_set) \
169 alc_update_coefex_idx(codec, 0x20, coef_idx, mask, bits_set)
170
Takashi Iwaif2a227c2014-08-18 13:35:22 +0200171/* a special bypass for COEF 0; read the cached value at the second time */
172static unsigned int alc_get_coef0(struct hda_codec *codec)
173{
174 struct alc_spec *spec = codec->spec;
175
176 if (!spec->coef0)
177 spec->coef0 = alc_read_coef_idx(codec, 0);
178 return spec->coef0;
179}
180
Takashi Iwai54db6c32014-08-18 15:11:19 +0200181/* coef writes/updates batch */
182struct coef_fw {
183 unsigned char nid;
184 unsigned char idx;
185 unsigned short mask;
186 unsigned short val;
187};
188
189#define UPDATE_COEFEX(_nid, _idx, _mask, _val) \
190 { .nid = (_nid), .idx = (_idx), .mask = (_mask), .val = (_val) }
191#define WRITE_COEFEX(_nid, _idx, _val) UPDATE_COEFEX(_nid, _idx, -1, _val)
192#define WRITE_COEF(_idx, _val) WRITE_COEFEX(0x20, _idx, _val)
193#define UPDATE_COEF(_idx, _mask, _val) UPDATE_COEFEX(0x20, _idx, _mask, _val)
194
195static void alc_process_coef_fw(struct hda_codec *codec,
196 const struct coef_fw *fw)
197{
198 for (; fw->nid; fw++) {
199 if (fw->mask == (unsigned short)-1)
200 alc_write_coefex_idx(codec, fw->nid, fw->idx, fw->val);
201 else
202 alc_update_coefex_idx(codec, fw->nid, fw->idx,
203 fw->mask, fw->val);
204 }
205}
206
Takashi Iwaif2a227c2014-08-18 13:35:22 +0200207/*
Takashi Iwai1d045db2011-07-07 18:23:21 +0200208 * GPIO setup tables, used in initialization
Kailang Yangdf694da2005-12-05 19:42:22 +0100209 */
Takashi Iwai5579cd62018-06-19 22:22:41 +0200210
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200211/* Enable GPIO mask and set output */
Takashi Iwai5579cd62018-06-19 22:22:41 +0200212static void alc_setup_gpio(struct hda_codec *codec, unsigned int mask)
213{
214 struct alc_spec *spec = codec->spec;
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200215
Takashi Iwai5579cd62018-06-19 22:22:41 +0200216 spec->gpio_mask |= mask;
217 spec->gpio_dir |= mask;
218 spec->gpio_data |= mask;
219}
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200220
Takashi Iwai5579cd62018-06-19 22:22:41 +0200221static void alc_write_gpio_data(struct hda_codec *codec)
222{
223 struct alc_spec *spec = codec->spec;
224
225 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
226 spec->gpio_data);
227}
228
Takashi Iwaiaaf312d2018-06-19 22:28:22 +0200229static void alc_update_gpio_data(struct hda_codec *codec, unsigned int mask,
230 bool on)
231{
232 struct alc_spec *spec = codec->spec;
233 unsigned int oldval = spec->gpio_data;
234
235 if (on)
236 spec->gpio_data |= mask;
237 else
238 spec->gpio_data &= ~mask;
239 if (oldval != spec->gpio_data)
240 alc_write_gpio_data(codec);
241}
242
Takashi Iwai5579cd62018-06-19 22:22:41 +0200243static void alc_write_gpio(struct hda_codec *codec)
244{
245 struct alc_spec *spec = codec->spec;
246
247 if (!spec->gpio_mask)
248 return;
249
250 snd_hda_codec_write(codec, codec->core.afg, 0,
251 AC_VERB_SET_GPIO_MASK, spec->gpio_mask);
252 snd_hda_codec_write(codec, codec->core.afg, 0,
253 AC_VERB_SET_GPIO_DIRECTION, spec->gpio_dir);
Takashi Iwai215c8502018-06-19 22:34:26 +0200254 if (spec->gpio_write_delay)
255 msleep(1);
Takashi Iwai5579cd62018-06-19 22:22:41 +0200256 alc_write_gpio_data(codec);
257}
258
259static void alc_fixup_gpio(struct hda_codec *codec, int action,
260 unsigned int mask)
261{
262 if (action == HDA_FIXUP_ACT_PRE_PROBE)
263 alc_setup_gpio(codec, mask);
264}
265
266static void alc_fixup_gpio1(struct hda_codec *codec,
267 const struct hda_fixup *fix, int action)
268{
269 alc_fixup_gpio(codec, action, 0x01);
270}
271
272static void alc_fixup_gpio2(struct hda_codec *codec,
273 const struct hda_fixup *fix, int action)
274{
275 alc_fixup_gpio(codec, action, 0x02);
276}
277
278static void alc_fixup_gpio3(struct hda_codec *codec,
279 const struct hda_fixup *fix, int action)
280{
281 alc_fixup_gpio(codec, action, 0x03);
282}
Kailang Yangbdd148a2007-05-08 15:19:08 +0200283
Takashi Iwaiae065f12018-06-19 23:00:03 +0200284static void alc_fixup_gpio4(struct hda_codec *codec,
285 const struct hda_fixup *fix, int action)
286{
287 alc_fixup_gpio(codec, action, 0x04);
288}
289
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200290/*
291 * Fix hardware PLL issue
292 * On some codecs, the analog PLL gating control must be off while
293 * the default value is 1.
294 */
295static void alc_fix_pll(struct hda_codec *codec)
296{
297 struct alc_spec *spec = codec->spec;
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200298
Takashi Iwai98b24882014-08-18 13:47:50 +0200299 if (spec->pll_nid)
300 alc_update_coefex_idx(codec, spec->pll_nid, spec->pll_coef_idx,
301 1 << spec->pll_coef_bit, 0);
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200302}
303
304static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
305 unsigned int coef_idx, unsigned int coef_bit)
306{
307 struct alc_spec *spec = codec->spec;
308 spec->pll_nid = nid;
309 spec->pll_coef_idx = coef_idx;
310 spec->pll_coef_bit = coef_bit;
311 alc_fix_pll(codec);
312}
313
Takashi Iwaicf5a2272012-02-20 16:31:07 +0100314/* update the master volume per volume-knob's unsol event */
Takashi Iwai1a4f69d2014-09-11 15:22:46 +0200315static void alc_update_knob_master(struct hda_codec *codec,
316 struct hda_jack_callback *jack)
Takashi Iwaicf5a2272012-02-20 16:31:07 +0100317{
318 unsigned int val;
319 struct snd_kcontrol *kctl;
320 struct snd_ctl_elem_value *uctl;
321
322 kctl = snd_hda_find_mixer_ctl(codec, "Master Playback Volume");
323 if (!kctl)
324 return;
325 uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
326 if (!uctl)
327 return;
Takashi Iwai2ebab402016-02-09 10:23:52 +0100328 val = snd_hda_codec_read(codec, jack->nid, 0,
Takashi Iwaicf5a2272012-02-20 16:31:07 +0100329 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
330 val &= HDA_AMP_VOLMASK;
331 uctl->value.integer.value[0] = val;
332 uctl->value.integer.value[1] = val;
333 kctl->put(kctl, uctl);
334 kfree(uctl);
335}
336
David Henningsson29adc4b2012-09-25 11:31:00 +0200337static void alc880_unsol_event(struct hda_codec *codec, unsigned int res)
Takashi Iwaif21d78e2012-01-19 12:10:29 +0100338{
David Henningsson29adc4b2012-09-25 11:31:00 +0200339 /* For some reason, the res given from ALC880 is broken.
340 Here we adjust it properly. */
341 snd_hda_jack_unsol_event(codec, res >> 2);
Takashi Iwaif21d78e2012-01-19 12:10:29 +0100342}
343
Kailang Yang394c97f2014-11-12 17:38:08 +0800344/* Change EAPD to verb control */
345static void alc_fill_eapd_coef(struct hda_codec *codec)
346{
347 int coef;
348
349 coef = alc_get_coef0(codec);
350
Takashi Iwai7639a062015-03-03 10:07:24 +0100351 switch (codec->core.vendor_id) {
Kailang Yang394c97f2014-11-12 17:38:08 +0800352 case 0x10ec0262:
353 alc_update_coef_idx(codec, 0x7, 0, 1<<5);
354 break;
355 case 0x10ec0267:
356 case 0x10ec0268:
357 alc_update_coef_idx(codec, 0x7, 0, 1<<13);
358 break;
359 case 0x10ec0269:
360 if ((coef & 0x00f0) == 0x0010)
361 alc_update_coef_idx(codec, 0xd, 0, 1<<14);
362 if ((coef & 0x00f0) == 0x0020)
363 alc_update_coef_idx(codec, 0x4, 1<<15, 0);
364 if ((coef & 0x00f0) == 0x0030)
365 alc_update_coef_idx(codec, 0x10, 1<<9, 0);
366 break;
367 case 0x10ec0280:
368 case 0x10ec0284:
369 case 0x10ec0290:
370 case 0x10ec0292:
371 alc_update_coef_idx(codec, 0x4, 1<<15, 0);
372 break;
Kailang Yang42314302016-02-03 15:03:50 +0800373 case 0x10ec0225:
Takashi Iwai44be77c2017-12-27 08:53:59 +0100374 case 0x10ec0295:
375 case 0x10ec0299:
376 alc_update_coef_idx(codec, 0x67, 0xf000, 0x3000);
377 /* fallthrough */
378 case 0x10ec0215:
Kailang Yang394c97f2014-11-12 17:38:08 +0800379 case 0x10ec0233:
Kailang Yangea04a1d2018-04-25 15:31:52 +0800380 case 0x10ec0235:
Thomas Hebbc4473742020-03-30 12:09:38 -0400381 case 0x10ec0236:
Kailang Yang7fbdcd82020-04-23 14:18:31 +0800382 case 0x10ec0245:
Kailang Yang394c97f2014-11-12 17:38:08 +0800383 case 0x10ec0255:
Thomas Hebbc4473742020-03-30 12:09:38 -0400384 case 0x10ec0256:
Kailang Yangf429e7e2017-12-05 15:38:24 +0800385 case 0x10ec0257:
Kailang Yang394c97f2014-11-12 17:38:08 +0800386 case 0x10ec0282:
387 case 0x10ec0283:
388 case 0x10ec0286:
Kailang Yang630e3612020-05-27 14:10:26 +0800389 case 0x10ec0287:
Kailang Yang394c97f2014-11-12 17:38:08 +0800390 case 0x10ec0288:
Kailang Yang0a6f0602017-06-30 16:00:48 +0800391 case 0x10ec0285:
Kailang Yang506b62c2014-12-18 17:07:44 +0800392 case 0x10ec0298:
Kailang Yang0a6f0602017-06-30 16:00:48 +0800393 case 0x10ec0289:
Kailang Yang1078bef2018-11-08 16:36:15 +0800394 case 0x10ec0300:
Kailang Yang394c97f2014-11-12 17:38:08 +0800395 alc_update_coef_idx(codec, 0x10, 1<<9, 0);
396 break;
Kailang Yang3aabf942017-11-08 15:28:33 +0800397 case 0x10ec0275:
398 alc_update_coef_idx(codec, 0xe, 0, 1<<0);
399 break;
Kailang Yang394c97f2014-11-12 17:38:08 +0800400 case 0x10ec0293:
401 alc_update_coef_idx(codec, 0xa, 1<<13, 0);
402 break;
Kailang Yangdcd4f0d2016-05-04 15:50:18 +0800403 case 0x10ec0234:
404 case 0x10ec0274:
405 case 0x10ec0294:
Kailang Yang6fbae352016-05-30 16:44:20 +0800406 case 0x10ec0700:
407 case 0x10ec0701:
408 case 0x10ec0703:
Kailang Yang83629532019-05-02 16:03:26 +0800409 case 0x10ec0711:
Kailang Yangdcd4f0d2016-05-04 15:50:18 +0800410 alc_update_coef_idx(codec, 0x10, 1<<15, 0);
411 break;
Kailang Yang394c97f2014-11-12 17:38:08 +0800412 case 0x10ec0662:
413 if ((coef & 0x00f0) == 0x0030)
414 alc_update_coef_idx(codec, 0x4, 1<<10, 0); /* EAPD Ctrl */
415 break;
416 case 0x10ec0272:
417 case 0x10ec0273:
418 case 0x10ec0663:
419 case 0x10ec0665:
420 case 0x10ec0670:
421 case 0x10ec0671:
422 case 0x10ec0672:
423 alc_update_coef_idx(codec, 0xd, 0, 1<<14); /* EAPD Ctrl */
424 break;
Kailang Yang9194a1e2020-01-07 17:22:19 +0800425 case 0x10ec0222:
Kailang Yangf0778872019-10-24 15:13:32 +0800426 case 0x10ec0623:
427 alc_update_coef_idx(codec, 0x19, 1<<13, 0);
428 break;
Kailang Yang394c97f2014-11-12 17:38:08 +0800429 case 0x10ec0668:
430 alc_update_coef_idx(codec, 0x7, 3<<13, 0);
431 break;
432 case 0x10ec0867:
433 alc_update_coef_idx(codec, 0x4, 1<<10, 0);
434 break;
435 case 0x10ec0888:
436 if ((coef & 0x00f0) == 0x0020 || (coef & 0x00f0) == 0x0030)
437 alc_update_coef_idx(codec, 0x7, 1<<5, 0);
438 break;
439 case 0x10ec0892:
440 alc_update_coef_idx(codec, 0x7, 1<<5, 0);
441 break;
442 case 0x10ec0899:
443 case 0x10ec0900:
Kailang Yang6d9ffcf2020-01-03 16:24:06 +0800444 case 0x10ec0b00:
Kailang Yang65553b12017-07-11 15:15:47 +0800445 case 0x10ec1168:
Kailang Yanga535ad52017-01-16 16:59:26 +0800446 case 0x10ec1220:
Kailang Yang394c97f2014-11-12 17:38:08 +0800447 alc_update_coef_idx(codec, 0x7, 1<<1, 0);
448 break;
449 }
450}
451
Kailang Yangf9423e72008-05-27 12:32:25 +0200452/* additional initialization for ALC888 variants */
453static void alc888_coef_init(struct hda_codec *codec)
454{
Kailang Yang1df88742014-10-29 16:10:13 +0800455 switch (alc_get_coef0(codec) & 0x00f0) {
456 /* alc888-VA */
457 case 0x00:
458 /* alc888-VB */
459 case 0x10:
460 alc_update_coef_idx(codec, 7, 0, 0x2030); /* Turn EAPD to High */
461 break;
462 }
Jaroslav Kysela87a8c372009-07-23 10:58:29 +0200463}
464
Takashi Iwai3fb4a502010-01-19 15:46:37 +0100465/* turn on/off EAPD control (only if available) */
466static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
467{
468 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
469 return;
470 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
471 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
472 on ? 2 : 0);
473}
474
Takashi Iwai691f1fc2011-04-07 10:31:43 +0200475/* turn on/off EAPD controls of the codec */
476static void alc_auto_setup_eapd(struct hda_codec *codec, bool on)
477{
478 /* We currently only handle front, HP */
Michał Mirosławcaf3c042020-01-03 10:23:48 +0100479 static const hda_nid_t pins[] = {
Hui Wangaf95b412015-03-26 17:14:55 +0800480 0x0f, 0x10, 0x14, 0x15, 0x17, 0
Takashi Iwai39fa84e2011-06-27 15:28:57 +0200481 };
Michał Mirosławcaf3c042020-01-03 10:23:48 +0100482 const hda_nid_t *p;
Takashi Iwai39fa84e2011-06-27 15:28:57 +0200483 for (p = pins; *p; p++)
484 set_eapd(codec, *p, on);
Takashi Iwai691f1fc2011-04-07 10:31:43 +0200485}
486
Kailang Yangdad31972019-05-10 16:28:57 +0800487static int find_ext_mic_pin(struct hda_codec *codec);
488
489static void alc_headset_mic_no_shutup(struct hda_codec *codec)
490{
491 const struct hda_pincfg *pin;
492 int mic_pin = find_ext_mic_pin(codec);
493 int i;
494
495 /* don't shut up pins when unloading the driver; otherwise it breaks
496 * the default pin setup at the next load of the driver
497 */
498 if (codec->bus->shutdown)
499 return;
500
501 snd_array_for_each(&codec->init_pins, i, pin) {
502 /* use read here for syncing after issuing each verb */
503 if (pin->nid != mic_pin)
504 snd_hda_codec_read(codec, pin->nid, 0,
505 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
506 }
507
508 codec->pins_shutup = 1;
509}
510
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +0100511static void alc_shutup_pins(struct hda_codec *codec)
512{
513 struct alc_spec *spec = codec->spec;
514
Kailang Yangdad31972019-05-10 16:28:57 +0800515 switch (codec->core.vendor_id) {
Kailang Yang66c5d712019-12-09 15:56:15 +0800516 case 0x10ec0283:
Kailang Yangdad31972019-05-10 16:28:57 +0800517 case 0x10ec0286:
518 case 0x10ec0288:
519 case 0x10ec0298:
520 alc_headset_mic_no_shutup(codec);
521 break;
522 default:
523 if (!spec->no_shutup_pins)
524 snd_hda_shutup_pins(codec);
525 break;
526 }
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +0100527}
528
Takashi Iwai1c7161532011-04-07 10:37:16 +0200529/* generic shutup callback;
Lars-Peter Clausen4ce8e6a2016-11-08 15:48:06 +0100530 * just turning off EAPD and a little pause for avoiding pop-noise
Takashi Iwai1c7161532011-04-07 10:37:16 +0200531 */
532static void alc_eapd_shutup(struct hda_codec *codec)
533{
Kailang Yang97a26572013-11-29 00:35:26 -0500534 struct alc_spec *spec = codec->spec;
535
Takashi Iwai1c7161532011-04-07 10:37:16 +0200536 alc_auto_setup_eapd(codec, false);
Kailang Yang97a26572013-11-29 00:35:26 -0500537 if (!spec->no_depop_delay)
538 msleep(200);
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +0100539 alc_shutup_pins(codec);
Takashi Iwai1c7161532011-04-07 10:37:16 +0200540}
541
Takashi Iwai1d045db2011-07-07 18:23:21 +0200542/* generic EAPD initialization */
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200543static void alc_auto_init_amp(struct hda_codec *codec, int type)
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200544{
Takashi Iwai39fa84e2011-06-27 15:28:57 +0200545 alc_auto_setup_eapd(codec, true);
Takashi Iwai5579cd62018-06-19 22:22:41 +0200546 alc_write_gpio(codec);
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200547 switch (type) {
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200548 case ALC_INIT_DEFAULT:
Takashi Iwai7639a062015-03-03 10:07:24 +0100549 switch (codec->core.vendor_id) {
Kailang Yangc9b58002007-10-16 14:30:01 +0200550 case 0x10ec0260:
Takashi Iwai98b24882014-08-18 13:47:50 +0200551 alc_update_coefex_idx(codec, 0x1a, 7, 0, 0x2010);
Kailang Yangc9b58002007-10-16 14:30:01 +0200552 break;
Kailang Yangc9b58002007-10-16 14:30:01 +0200553 case 0x10ec0880:
554 case 0x10ec0882:
555 case 0x10ec0883:
556 case 0x10ec0885:
Kailang Yang1df88742014-10-29 16:10:13 +0800557 alc_update_coef_idx(codec, 7, 0, 0x2030);
Kailang Yangc9b58002007-10-16 14:30:01 +0200558 break;
Kailang Yangf9423e72008-05-27 12:32:25 +0200559 case 0x10ec0888:
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200560 alc888_coef_init(codec);
Kailang Yangf9423e72008-05-27 12:32:25 +0200561 break;
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200562 }
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200563 break;
564 }
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200565}
Kailang Yangea1fb292008-08-26 12:58:38 +0200566
Takashi Iwai35a39f92019-02-01 11:19:50 +0100567/* get a primary headphone pin if available */
568static hda_nid_t alc_get_hp_pin(struct alc_spec *spec)
569{
570 if (spec->gen.autocfg.hp_pins[0])
571 return spec->gen.autocfg.hp_pins[0];
572 if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
573 return spec->gen.autocfg.line_out_pins[0];
574 return 0;
575}
Takashi Iwai1d045db2011-07-07 18:23:21 +0200576
577/*
578 * Realtek SSID verification
579 */
580
David Henningsson90622912010-10-14 14:50:18 +0200581/* Could be any non-zero and even value. When used as fixup, tells
582 * the driver to ignore any present sku defines.
583 */
584#define ALC_FIXUP_SKU_IGNORE (2)
585
Takashi Iwai23d30f22012-05-07 17:17:32 +0200586static void alc_fixup_sku_ignore(struct hda_codec *codec,
587 const struct hda_fixup *fix, int action)
588{
589 struct alc_spec *spec = codec->spec;
590 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
591 spec->cdefine.fixup = 1;
592 spec->cdefine.sku_cfg = ALC_FIXUP_SKU_IGNORE;
593 }
594}
595
Mengdong Linb5c66112013-11-29 00:35:35 -0500596static void alc_fixup_no_depop_delay(struct hda_codec *codec,
597 const struct hda_fixup *fix, int action)
598{
599 struct alc_spec *spec = codec->spec;
600
Mengdong Lin84d2dc32013-12-02 22:26:03 -0500601 if (action == HDA_FIXUP_ACT_PROBE) {
Mengdong Linb5c66112013-11-29 00:35:35 -0500602 spec->no_depop_delay = 1;
Mengdong Lin84d2dc32013-12-02 22:26:03 -0500603 codec->depop_delay = 0;
604 }
Mengdong Linb5c66112013-11-29 00:35:35 -0500605}
606
Kailang Yangda00c242010-03-19 11:23:45 +0100607static int alc_auto_parse_customize_define(struct hda_codec *codec)
608{
609 unsigned int ass, tmp, i;
Takashi Iwai7fb56222010-03-22 17:09:47 +0100610 unsigned nid = 0;
Kailang Yangda00c242010-03-19 11:23:45 +0100611 struct alc_spec *spec = codec->spec;
612
Takashi Iwaib6cbe512010-07-28 17:43:36 +0200613 spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
614
David Henningsson90622912010-10-14 14:50:18 +0200615 if (spec->cdefine.fixup) {
616 ass = spec->cdefine.sku_cfg;
617 if (ass == ALC_FIXUP_SKU_IGNORE)
618 return -1;
619 goto do_sku;
620 }
621
Takashi Iwai5100cd02014-02-15 10:03:19 +0100622 if (!codec->bus->pci)
623 return -1;
Takashi Iwai7639a062015-03-03 10:07:24 +0100624 ass = codec->core.subsystem_id & 0xffff;
Takashi Iwaib6cbe512010-07-28 17:43:36 +0200625 if (ass != codec->bus->pci->subsystem_device && (ass & 1))
Kailang Yangda00c242010-03-19 11:23:45 +0100626 goto do_sku;
627
628 nid = 0x1d;
Takashi Iwai7639a062015-03-03 10:07:24 +0100629 if (codec->core.vendor_id == 0x10ec0260)
Kailang Yangda00c242010-03-19 11:23:45 +0100630 nid = 0x17;
631 ass = snd_hda_codec_get_pincfg(codec, nid);
632
633 if (!(ass & 1)) {
Takashi Iwai4e76a882014-02-25 12:21:03 +0100634 codec_info(codec, "%s: SKU not ready 0x%08x\n",
Takashi Iwai7639a062015-03-03 10:07:24 +0100635 codec->core.chip_name, ass);
Kailang Yangda00c242010-03-19 11:23:45 +0100636 return -1;
637 }
638
639 /* check sum */
640 tmp = 0;
641 for (i = 1; i < 16; i++) {
642 if ((ass >> i) & 1)
643 tmp++;
644 }
645 if (((ass >> 16) & 0xf) != tmp)
646 return -1;
647
648 spec->cdefine.port_connectivity = ass >> 30;
649 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
650 spec->cdefine.check_sum = (ass >> 16) & 0xf;
651 spec->cdefine.customization = ass >> 8;
652do_sku:
653 spec->cdefine.sku_cfg = ass;
654 spec->cdefine.external_amp = (ass & 0x38) >> 3;
655 spec->cdefine.platform_type = (ass & 0x4) >> 2;
656 spec->cdefine.swap = (ass & 0x2) >> 1;
657 spec->cdefine.override = ass & 0x1;
658
Takashi Iwai4e76a882014-02-25 12:21:03 +0100659 codec_dbg(codec, "SKU: Nid=0x%x sku_cfg=0x%08x\n",
Kailang Yangda00c242010-03-19 11:23:45 +0100660 nid, spec->cdefine.sku_cfg);
Takashi Iwai4e76a882014-02-25 12:21:03 +0100661 codec_dbg(codec, "SKU: port_connectivity=0x%x\n",
Kailang Yangda00c242010-03-19 11:23:45 +0100662 spec->cdefine.port_connectivity);
Takashi Iwai4e76a882014-02-25 12:21:03 +0100663 codec_dbg(codec, "SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
664 codec_dbg(codec, "SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
665 codec_dbg(codec, "SKU: customization=0x%08x\n", spec->cdefine.customization);
666 codec_dbg(codec, "SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
667 codec_dbg(codec, "SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
668 codec_dbg(codec, "SKU: swap=0x%x\n", spec->cdefine.swap);
669 codec_dbg(codec, "SKU: override=0x%x\n", spec->cdefine.override);
Kailang Yangda00c242010-03-19 11:23:45 +0100670
671 return 0;
672}
673
Takashi Iwai08c189f2012-12-19 15:22:24 +0100674/* return the position of NID in the list, or -1 if not found */
675static int find_idx_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
676{
677 int i;
678 for (i = 0; i < nums; i++)
679 if (list[i] == nid)
680 return i;
681 return -1;
682}
Takashi Iwai1d045db2011-07-07 18:23:21 +0200683/* return true if the given NID is found in the list */
Takashi Iwai3af9ee62011-06-27 12:34:01 +0200684static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
685{
Takashi Iwai21268962011-07-07 15:01:13 +0200686 return find_idx_in_nid_list(nid, list, nums) >= 0;
Takashi Iwai3af9ee62011-06-27 12:34:01 +0200687}
688
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200689/* check subsystem ID and set up device-specific initialization;
690 * return 1 if initialized, 0 if invalid SSID
691 */
692/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
693 * 31 ~ 16 : Manufacture ID
694 * 15 ~ 8 : SKU ID
695 * 7 ~ 0 : Assembly ID
696 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
697 */
Takashi Iwai58c57cf2014-01-07 18:22:49 +0100698static int alc_subsystem_id(struct hda_codec *codec, const hda_nid_t *ports)
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200699{
700 unsigned int ass, tmp, i;
701 unsigned nid;
702 struct alc_spec *spec = codec->spec;
703
David Henningsson90622912010-10-14 14:50:18 +0200704 if (spec->cdefine.fixup) {
705 ass = spec->cdefine.sku_cfg;
706 if (ass == ALC_FIXUP_SKU_IGNORE)
707 return 0;
708 goto do_sku;
709 }
710
Takashi Iwai7639a062015-03-03 10:07:24 +0100711 ass = codec->core.subsystem_id & 0xffff;
Takashi Iwai5100cd02014-02-15 10:03:19 +0100712 if (codec->bus->pci &&
713 ass != codec->bus->pci->subsystem_device && (ass & 1))
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200714 goto do_sku;
715
716 /* invalid SSID, check the special NID pin defcfg instead */
717 /*
Sasha Alexandrdef319f2009-06-16 16:00:15 -0400718 * 31~30 : port connectivity
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200719 * 29~21 : reserve
720 * 20 : PCBEEP input
721 * 19~16 : Check sum (15:1)
722 * 15~1 : Custom
723 * 0 : override
724 */
725 nid = 0x1d;
Takashi Iwai7639a062015-03-03 10:07:24 +0100726 if (codec->core.vendor_id == 0x10ec0260)
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200727 nid = 0x17;
728 ass = snd_hda_codec_get_pincfg(codec, nid);
Takashi Iwai4e76a882014-02-25 12:21:03 +0100729 codec_dbg(codec,
730 "realtek: No valid SSID, checking pincfg 0x%08x for NID 0x%x\n",
Takashi Iwaicb6605c2009-04-28 13:03:19 +0200731 ass, nid);
Kailang Yang6227cdc2010-02-25 08:36:52 +0100732 if (!(ass & 1))
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200733 return 0;
734 if ((ass >> 30) != 1) /* no physical connection */
735 return 0;
736
737 /* check sum */
738 tmp = 0;
739 for (i = 1; i < 16; i++) {
740 if ((ass >> i) & 1)
741 tmp++;
742 }
743 if (((ass >> 16) & 0xf) != tmp)
744 return 0;
745do_sku:
Takashi Iwai4e76a882014-02-25 12:21:03 +0100746 codec_dbg(codec, "realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
Takashi Iwai7639a062015-03-03 10:07:24 +0100747 ass & 0xffff, codec->core.vendor_id);
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200748 /*
749 * 0 : override
750 * 1 : Swap Jack
751 * 2 : 0 --> Desktop, 1 --> Laptop
752 * 3~5 : External Amplifier control
753 * 7~6 : Reserved
754 */
755 tmp = (ass & 0x38) >> 3; /* external Amp control */
Takashi Iwai1c76aa52018-06-21 16:37:54 +0200756 if (spec->init_amp == ALC_INIT_UNDEFINED) {
757 switch (tmp) {
758 case 1:
Takashi Iwai5579cd62018-06-19 22:22:41 +0200759 alc_setup_gpio(codec, 0x01);
Takashi Iwai1c76aa52018-06-21 16:37:54 +0200760 break;
761 case 3:
Takashi Iwai5579cd62018-06-19 22:22:41 +0200762 alc_setup_gpio(codec, 0x02);
Takashi Iwai1c76aa52018-06-21 16:37:54 +0200763 break;
764 case 7:
Takashi Iwai5579cd62018-06-19 22:22:41 +0200765 alc_setup_gpio(codec, 0x03);
Takashi Iwai1c76aa52018-06-21 16:37:54 +0200766 break;
767 case 5:
768 default:
769 spec->init_amp = ALC_INIT_DEFAULT;
770 break;
771 }
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200772 }
773
774 /* is laptop or Desktop and enable the function "Mute internal speaker
775 * when the external headphone out jack is plugged"
776 */
777 if (!(ass & 0x8000))
778 return 1;
779 /*
780 * 10~8 : Jack location
781 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
782 * 14~13: Resvered
783 * 15 : 1 --> enable the function "Mute internal speaker
784 * when the external headphone out jack is plugged"
785 */
Takashi Iwai35a39f92019-02-01 11:19:50 +0100786 if (!alc_get_hp_pin(spec)) {
Takashi Iwai01d48252009-10-06 13:21:54 +0200787 hda_nid_t nid;
Kailang Yangc9b58002007-10-16 14:30:01 +0200788 tmp = (ass >> 11) & 0x3; /* HP to chassis */
Takashi Iwai58c57cf2014-01-07 18:22:49 +0100789 nid = ports[tmp];
Takashi Iwai08c189f2012-12-19 15:22:24 +0100790 if (found_in_nid_list(nid, spec->gen.autocfg.line_out_pins,
791 spec->gen.autocfg.line_outs))
Takashi Iwai3af9ee62011-06-27 12:34:01 +0200792 return 1;
Takashi Iwai08c189f2012-12-19 15:22:24 +0100793 spec->gen.autocfg.hp_pins[0] = nid;
Kailang Yangc9b58002007-10-16 14:30:01 +0200794 }
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200795 return 1;
796}
Kailang Yangea1fb292008-08-26 12:58:38 +0200797
Takashi Iwai3e6179b2011-07-08 16:55:13 +0200798/* Check the validity of ALC subsystem-id
799 * ports contains an array of 4 pin NIDs for port-A, E, D and I */
800static void alc_ssid_check(struct hda_codec *codec, const hda_nid_t *ports)
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200801{
Takashi Iwai58c57cf2014-01-07 18:22:49 +0100802 if (!alc_subsystem_id(codec, ports)) {
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200803 struct alc_spec *spec = codec->spec;
Takashi Iwai67791202020-04-18 21:06:39 +0200804 if (spec->init_amp == ALC_INIT_UNDEFINED) {
805 codec_dbg(codec,
806 "realtek: Enable default setup for auto mode as fallback\n");
807 spec->init_amp = ALC_INIT_DEFAULT;
808 }
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200809 }
Takashi Iwai21268962011-07-07 15:01:13 +0200810}
Takashi Iwai1a1455d2011-04-28 17:36:18 +0200811
Takashi Iwai41e41f12005-06-08 14:48:49 +0200812/*
Takashi Iwai1d045db2011-07-07 18:23:21 +0200813 */
814
David Henningsson9d36a7d2014-10-07 10:18:42 +0200815static void alc_fixup_inv_dmic(struct hda_codec *codec,
816 const struct hda_fixup *fix, int action)
Takashi Iwai125821a2012-06-22 14:30:29 +0200817{
818 struct alc_spec *spec = codec->spec;
Takashi Iwai668d1e92012-11-29 14:10:17 +0100819
David Henningsson9d36a7d2014-10-07 10:18:42 +0200820 spec->gen.inv_dmic_split = 1;
Takashi Iwai6e72aa52012-06-25 10:52:25 +0200821}
822
Takashi Iwai603c4012008-07-30 15:01:44 +0200823
Takashi Iwai2eab6942012-12-18 15:30:41 +0100824static int alc_build_controls(struct hda_codec *codec)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700825{
Takashi Iwaia5cb4632018-06-20 12:50:11 +0200826 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700827
Takashi Iwai08c189f2012-12-19 15:22:24 +0100828 err = snd_hda_gen_build_controls(codec);
829 if (err < 0)
830 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700831
Takashi Iwai1727a772013-01-10 09:52:52 +0100832 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_BUILD);
Takashi Iwai420b0fe2012-03-12 12:35:27 +0100833 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700834}
835
Takashi Iwaie9edcee2005-06-13 14:16:38 +0200836
Linus Torvalds1da177e2005-04-16 15:20:36 -0700837/*
Takashi Iwaiae6b8132006-03-03 16:47:17 +0100838 * Common callbacks
Takashi Iwaie9edcee2005-06-13 14:16:38 +0200839 */
Takashi Iwai16ded522005-06-10 19:58:24 +0200840
Takashi Iwaic9af7532019-05-10 11:01:43 +0200841static void alc_pre_init(struct hda_codec *codec)
842{
843 alc_fill_eapd_coef(codec);
844}
845
Kailang Yangaeac1a02019-05-16 16:10:44 +0800846#define is_s3_resume(codec) \
847 ((codec)->core.dev.power.power_state.event == PM_EVENT_RESUME)
Takashi Iwaic9af7532019-05-10 11:01:43 +0200848#define is_s4_resume(codec) \
849 ((codec)->core.dev.power.power_state.event == PM_EVENT_RESTORE)
850
Linus Torvalds1da177e2005-04-16 15:20:36 -0700851static int alc_init(struct hda_codec *codec)
852{
853 struct alc_spec *spec = codec->spec;
Takashi Iwaie9edcee2005-06-13 14:16:38 +0200854
Takashi Iwaic9af7532019-05-10 11:01:43 +0200855 /* hibernation resume needs the full chip initialization */
856 if (is_s4_resume(codec))
857 alc_pre_init(codec);
858
Takashi Iwai546bb672012-03-07 08:37:19 +0100859 if (spec->init_hook)
860 spec->init_hook(codec);
Kailang Yang526af6e2012-03-07 08:25:20 +0100861
Takashi Iwai89781d02019-08-30 12:03:38 +0200862 spec->gen.skip_verbs = 1; /* applied in below */
Kailang Yang607ca3b2019-04-26 16:35:41 +0800863 snd_hda_gen_init(codec);
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200864 alc_fix_pll(codec);
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200865 alc_auto_init_amp(codec, spec->init_amp);
Takashi Iwai89781d02019-08-30 12:03:38 +0200866 snd_hda_apply_verbs(codec); /* apply verbs here after own init */
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200867
Takashi Iwai1727a772013-01-10 09:52:52 +0100868 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_INIT);
Takashi Iwaie08a0072006-09-07 17:52:14 +0200869
Linus Torvalds1da177e2005-04-16 15:20:36 -0700870 return 0;
871}
872
Takashi Iwaia4e09aa2009-12-27 11:22:24 +0100873static inline void alc_shutup(struct hda_codec *codec)
874{
Takashi Iwai1c7161532011-04-07 10:37:16 +0200875 struct alc_spec *spec = codec->spec;
876
Takashi Iwaic7273bd2018-06-12 16:09:57 +0200877 if (!snd_hda_get_bool_hint(codec, "shutup"))
878 return; /* disabled explicitly by hints */
879
Takashi Iwai1c7161532011-04-07 10:37:16 +0200880 if (spec && spec->shutup)
881 spec->shutup(codec);
Takashi Iwai9bfb2842013-07-24 14:31:50 +0200882 else
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +0100883 alc_shutup_pins(codec);
Takashi Iwaia4e09aa2009-12-27 11:22:24 +0100884}
885
Takashi Iwai70a09762015-12-15 14:59:58 +0100886static void alc_reboot_notify(struct hda_codec *codec)
887{
888 struct alc_spec *spec = codec->spec;
889
890 if (spec && spec->reboot_notify)
891 spec->reboot_notify(codec);
892 else
893 alc_shutup(codec);
894}
895
Takashi Iwai8a02c0c2014-02-10 18:09:45 +0100896#define alc_free snd_hda_gen_free
Linus Torvalds1da177e2005-04-16 15:20:36 -0700897
Takashi Iwai83012a72012-08-24 18:38:08 +0200898#ifdef CONFIG_PM
Daniel T Chenc97259d2009-12-27 18:52:08 -0500899static void alc_power_eapd(struct hda_codec *codec)
900{
Takashi Iwai691f1fc2011-04-07 10:31:43 +0200901 alc_auto_setup_eapd(codec, false);
Daniel T Chenc97259d2009-12-27 18:52:08 -0500902}
903
Takashi Iwai68cb2b52012-07-02 15:20:37 +0200904static int alc_suspend(struct hda_codec *codec)
Hector Martinf5de24b2009-12-20 22:51:31 +0100905{
906 struct alc_spec *spec = codec->spec;
Takashi Iwaia4e09aa2009-12-27 11:22:24 +0100907 alc_shutup(codec);
Hector Martinf5de24b2009-12-20 22:51:31 +0100908 if (spec && spec->power_hook)
Daniel T Chenc97259d2009-12-27 18:52:08 -0500909 spec->power_hook(codec);
Hector Martinf5de24b2009-12-20 22:51:31 +0100910 return 0;
911}
912#endif
913
Takashi Iwai2a439522011-07-26 09:52:50 +0200914#ifdef CONFIG_PM
Takashi Iwaie044c392008-10-27 16:56:24 +0100915static int alc_resume(struct hda_codec *codec)
916{
Kailang Yang97a26572013-11-29 00:35:26 -0500917 struct alc_spec *spec = codec->spec;
918
919 if (!spec->no_depop_delay)
920 msleep(150); /* to avoid pop noise */
Takashi Iwaie044c392008-10-27 16:56:24 +0100921 codec->patch_ops.init(codec);
Takashi Iwai1a462be2020-01-09 10:01:04 +0100922 snd_hda_regmap_sync(codec);
Takashi Iwai9e5341b2010-09-21 09:57:06 +0200923 hda_call_check_power_status(codec, 0x01);
Takashi Iwaie044c392008-10-27 16:56:24 +0100924 return 0;
925}
Takashi Iwaie044c392008-10-27 16:56:24 +0100926#endif
927
Linus Torvalds1da177e2005-04-16 15:20:36 -0700928/*
929 */
Takashi Iwaia9111322011-05-02 11:30:18 +0200930static const struct hda_codec_ops alc_patch_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700931 .build_controls = alc_build_controls,
Takashi Iwai08c189f2012-12-19 15:22:24 +0100932 .build_pcms = snd_hda_gen_build_pcms,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700933 .init = alc_init,
934 .free = alc_free,
David Henningsson29adc4b2012-09-25 11:31:00 +0200935 .unsol_event = snd_hda_jack_unsol_event,
Takashi Iwai2a439522011-07-26 09:52:50 +0200936#ifdef CONFIG_PM
Takashi Iwaie044c392008-10-27 16:56:24 +0100937 .resume = alc_resume,
Hector Martinf5de24b2009-12-20 22:51:31 +0100938 .suspend = alc_suspend,
Takashi Iwaifce52a32013-01-07 12:42:48 +0100939 .check_power_status = snd_hda_gen_check_power_status,
Takashi Iwaicb53c622007-08-10 17:21:45 +0200940#endif
Takashi Iwai70a09762015-12-15 14:59:58 +0100941 .reboot_notify = alc_reboot_notify,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700942};
943
David Henningsson29adc4b2012-09-25 11:31:00 +0200944
Takashi Iwaided255b2015-10-01 17:59:43 +0200945#define alc_codec_rename(codec, name) snd_hda_codec_set_name(codec, name)
Kailang Yangc027ddc2010-03-19 11:33:06 +0100946
Takashi Iwai2fa522b2005-05-12 14:51:12 +0200947/*
Kailang Yang4b016932013-11-28 11:55:09 +0100948 * Rename codecs appropriately from COEF value or subvendor id
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200949 */
950struct alc_codec_rename_table {
951 unsigned int vendor_id;
952 unsigned short coef_mask;
953 unsigned short coef_bits;
954 const char *name;
955};
956
Kailang Yang4b016932013-11-28 11:55:09 +0100957struct alc_codec_rename_pci_table {
958 unsigned int codec_vendor_id;
959 unsigned short pci_subvendor;
960 unsigned short pci_subdevice;
961 const char *name;
962};
963
Takashi Iwai6b0f95c2020-01-05 15:47:18 +0100964static const struct alc_codec_rename_table rename_tbl[] = {
Kailang Yange6e5f7a2014-06-06 16:46:43 +0800965 { 0x10ec0221, 0xf00f, 0x1003, "ALC231" },
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200966 { 0x10ec0269, 0xfff0, 0x3010, "ALC277" },
967 { 0x10ec0269, 0xf0f0, 0x2010, "ALC259" },
968 { 0x10ec0269, 0xf0f0, 0x3010, "ALC258" },
969 { 0x10ec0269, 0x00f0, 0x0010, "ALC269VB" },
970 { 0x10ec0269, 0xffff, 0xa023, "ALC259" },
971 { 0x10ec0269, 0xffff, 0x6023, "ALC281X" },
972 { 0x10ec0269, 0x00f0, 0x0020, "ALC269VC" },
Kailang Yangadcc70b2012-05-25 08:08:38 +0200973 { 0x10ec0269, 0x00f0, 0x0030, "ALC269VD" },
Kailang Yange6e5f7a2014-06-06 16:46:43 +0800974 { 0x10ec0662, 0xffff, 0x4020, "ALC656" },
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200975 { 0x10ec0887, 0x00f0, 0x0030, "ALC887-VD" },
976 { 0x10ec0888, 0x00f0, 0x0030, "ALC888-VD" },
977 { 0x10ec0888, 0xf0f0, 0x3020, "ALC886" },
978 { 0x10ec0899, 0x2000, 0x2000, "ALC899" },
979 { 0x10ec0892, 0xffff, 0x8020, "ALC661" },
980 { 0x10ec0892, 0xffff, 0x8011, "ALC661" },
981 { 0x10ec0892, 0xffff, 0x4011, "ALC656" },
982 { } /* terminator */
983};
984
Takashi Iwai6b0f95c2020-01-05 15:47:18 +0100985static const struct alc_codec_rename_pci_table rename_pci_tbl[] = {
Kailang Yang4b016932013-11-28 11:55:09 +0100986 { 0x10ec0280, 0x1028, 0, "ALC3220" },
987 { 0x10ec0282, 0x1028, 0, "ALC3221" },
988 { 0x10ec0283, 0x1028, 0, "ALC3223" },
Kailang Yang193177d2014-04-23 16:06:13 +0800989 { 0x10ec0288, 0x1028, 0, "ALC3263" },
Kailang Yang4b016932013-11-28 11:55:09 +0100990 { 0x10ec0292, 0x1028, 0, "ALC3226" },
Kailang Yang193177d2014-04-23 16:06:13 +0800991 { 0x10ec0293, 0x1028, 0, "ALC3235" },
Kailang Yang4b016932013-11-28 11:55:09 +0100992 { 0x10ec0255, 0x1028, 0, "ALC3234" },
993 { 0x10ec0668, 0x1028, 0, "ALC3661" },
Kailang Yange6e5f7a2014-06-06 16:46:43 +0800994 { 0x10ec0275, 0x1028, 0, "ALC3260" },
995 { 0x10ec0899, 0x1028, 0, "ALC3861" },
Kailang Yang2c674fa2015-05-05 15:02:42 +0800996 { 0x10ec0298, 0x1028, 0, "ALC3266" },
Kailang Yang736f20a2017-10-20 15:06:34 +0800997 { 0x10ec0236, 0x1028, 0, "ALC3204" },
Kailang Yang82324502015-05-25 17:16:49 +0800998 { 0x10ec0256, 0x1028, 0, "ALC3246" },
Kailang Yang42314302016-02-03 15:03:50 +0800999 { 0x10ec0225, 0x1028, 0, "ALC3253" },
Kailang Yang7d727862016-05-24 16:46:07 +08001000 { 0x10ec0295, 0x1028, 0, "ALC3254" },
Kailang Yang28f1f9b2017-01-04 14:49:07 +08001001 { 0x10ec0299, 0x1028, 0, "ALC3271" },
Kailang Yange6e5f7a2014-06-06 16:46:43 +08001002 { 0x10ec0670, 0x1025, 0, "ALC669X" },
1003 { 0x10ec0676, 0x1025, 0, "ALC679X" },
1004 { 0x10ec0282, 0x1043, 0, "ALC3229" },
1005 { 0x10ec0233, 0x1043, 0, "ALC3236" },
1006 { 0x10ec0280, 0x103c, 0, "ALC3228" },
1007 { 0x10ec0282, 0x103c, 0, "ALC3227" },
1008 { 0x10ec0286, 0x103c, 0, "ALC3242" },
1009 { 0x10ec0290, 0x103c, 0, "ALC3241" },
1010 { 0x10ec0668, 0x103c, 0, "ALC3662" },
1011 { 0x10ec0283, 0x17aa, 0, "ALC3239" },
1012 { 0x10ec0292, 0x17aa, 0, "ALC3232" },
Kailang Yang4b016932013-11-28 11:55:09 +01001013 { } /* terminator */
1014};
1015
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02001016static int alc_codec_rename_from_preset(struct hda_codec *codec)
1017{
1018 const struct alc_codec_rename_table *p;
Kailang Yang4b016932013-11-28 11:55:09 +01001019 const struct alc_codec_rename_pci_table *q;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02001020
1021 for (p = rename_tbl; p->vendor_id; p++) {
Takashi Iwai7639a062015-03-03 10:07:24 +01001022 if (p->vendor_id != codec->core.vendor_id)
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02001023 continue;
Takashi Iwai1bb7e432011-10-17 16:50:59 +02001024 if ((alc_get_coef0(codec) & p->coef_mask) == p->coef_bits)
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02001025 return alc_codec_rename(codec, p->name);
1026 }
Kailang Yang4b016932013-11-28 11:55:09 +01001027
Takashi Iwai5100cd02014-02-15 10:03:19 +01001028 if (!codec->bus->pci)
1029 return 0;
Kailang Yang4b016932013-11-28 11:55:09 +01001030 for (q = rename_pci_tbl; q->codec_vendor_id; q++) {
Takashi Iwai7639a062015-03-03 10:07:24 +01001031 if (q->codec_vendor_id != codec->core.vendor_id)
Kailang Yang4b016932013-11-28 11:55:09 +01001032 continue;
1033 if (q->pci_subvendor != codec->bus->pci->subsystem_vendor)
1034 continue;
1035 if (!q->pci_subdevice ||
1036 q->pci_subdevice == codec->bus->pci->subsystem_device)
1037 return alc_codec_rename(codec, q->name);
1038 }
1039
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02001040 return 0;
1041}
1042
Takashi Iwaie4770622011-07-08 11:11:35 +02001043
1044/*
Takashi Iwai1d045db2011-07-07 18:23:21 +02001045 * Digital-beep handlers
1046 */
1047#ifdef CONFIG_SND_HDA_INPUT_BEEP
Takashi Iwaifea80fa2018-06-20 12:52:46 +02001048
1049/* additional beep mixers; private_value will be overwritten */
1050static const struct snd_kcontrol_new alc_beep_mixer[] = {
1051 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
1052 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
1053};
1054
1055/* set up and create beep controls */
1056static int set_beep_amp(struct alc_spec *spec, hda_nid_t nid,
1057 int idx, int dir)
1058{
1059 struct snd_kcontrol_new *knew;
1060 unsigned int beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir);
1061 int i;
1062
1063 for (i = 0; i < ARRAY_SIZE(alc_beep_mixer); i++) {
1064 knew = snd_hda_gen_add_kctl(&spec->gen, NULL,
1065 &alc_beep_mixer[i]);
1066 if (!knew)
1067 return -ENOMEM;
1068 knew->private_value = beep_amp;
1069 }
1070 return 0;
1071}
Takashi Iwai1d045db2011-07-07 18:23:21 +02001072
1073static const struct snd_pci_quirk beep_white_list[] = {
Duncan Roe71100052012-10-10 14:19:50 +02001074 SND_PCI_QUIRK(0x1043, 0x103c, "ASUS", 1),
W. Trevor Kinga4b7f21d2014-03-29 17:47:24 -07001075 SND_PCI_QUIRK(0x1043, 0x115d, "ASUS", 1),
Takashi Iwai1d045db2011-07-07 18:23:21 +02001076 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
Takashi Iwai8554ee42013-02-25 09:54:43 +01001077 SND_PCI_QUIRK(0x1043, 0x8376, "EeePC", 1),
Takashi Iwai1d045db2011-07-07 18:23:21 +02001078 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
1079 SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1),
1080 SND_PCI_QUIRK(0x1043, 0x834a, "EeePC", 1),
Takashi Iwai78f8baf2012-03-06 14:02:32 +01001081 SND_PCI_QUIRK(0x1458, 0xa002, "GA-MA790X", 1),
Takashi Iwai1d045db2011-07-07 18:23:21 +02001082 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
Takashi Iwai051c78a2019-08-22 09:58:07 +02001083 /* blacklist -- no beep available */
1084 SND_PCI_QUIRK(0x17aa, 0x309e, "Lenovo ThinkCentre M73", 0),
1085 SND_PCI_QUIRK(0x17aa, 0x30a3, "Lenovo ThinkCentre M93", 0),
Takashi Iwai1d045db2011-07-07 18:23:21 +02001086 {}
1087};
1088
1089static inline int has_cdefine_beep(struct hda_codec *codec)
1090{
1091 struct alc_spec *spec = codec->spec;
1092 const struct snd_pci_quirk *q;
1093 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
1094 if (q)
1095 return q->value;
1096 return spec->cdefine.enable_pcbeep;
1097}
1098#else
Takashi Iwaifea80fa2018-06-20 12:52:46 +02001099#define set_beep_amp(spec, nid, idx, dir) 0
Takashi Iwai1d045db2011-07-07 18:23:21 +02001100#define has_cdefine_beep(codec) 0
1101#endif
1102
1103/* parse the BIOS configuration and set up the alc_spec */
1104/* return 1 if successful, 0 if the proper config is not found,
1105 * or a negative error code
1106 */
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001107static int alc_parse_auto_config(struct hda_codec *codec,
1108 const hda_nid_t *ignore_nids,
1109 const hda_nid_t *ssid_nids)
Takashi Iwai1d045db2011-07-07 18:23:21 +02001110{
1111 struct alc_spec *spec = codec->spec;
Takashi Iwai08c189f2012-12-19 15:22:24 +01001112 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001113 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001114
Takashi Iwai53c334a2011-08-23 18:27:14 +02001115 err = snd_hda_parse_pin_defcfg(codec, cfg, ignore_nids,
1116 spec->parse_flags);
Takashi Iwai1d045db2011-07-07 18:23:21 +02001117 if (err < 0)
1118 return err;
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001119
1120 if (ssid_nids)
1121 alc_ssid_check(codec, ssid_nids);
1122
Takashi Iwai08c189f2012-12-19 15:22:24 +01001123 err = snd_hda_gen_parse_auto_config(codec, cfg);
1124 if (err < 0)
1125 return err;
Takashi Iwai070cff42012-02-21 12:54:17 +01001126
Takashi Iwai1d045db2011-07-07 18:23:21 +02001127 return 1;
1128}
1129
Takashi Iwai3de95172012-05-07 18:03:15 +02001130/* common preparation job for alc_spec */
1131static int alc_alloc_spec(struct hda_codec *codec, hda_nid_t mixer_nid)
1132{
1133 struct alc_spec *spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1134 int err;
1135
1136 if (!spec)
1137 return -ENOMEM;
1138 codec->spec = spec;
Takashi Iwai08c189f2012-12-19 15:22:24 +01001139 snd_hda_gen_spec_init(&spec->gen);
1140 spec->gen.mixer_nid = mixer_nid;
1141 spec->gen.own_eapd_ctl = 1;
Takashi Iwai1098b7c2012-12-17 20:03:15 +01001142 codec->single_adc_amp = 1;
Takashi Iwai08c189f2012-12-19 15:22:24 +01001143 /* FIXME: do we need this for all Realtek codec models? */
1144 codec->spdif_status_reset = 1;
Takashi Iwai225068a2015-05-29 10:42:14 +02001145 codec->patch_ops = alc_patch_ops;
Takashi Iwai3de95172012-05-07 18:03:15 +02001146
1147 err = alc_codec_rename_from_preset(codec);
1148 if (err < 0) {
1149 kfree(spec);
1150 return err;
1151 }
1152 return 0;
1153}
1154
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001155static int alc880_parse_auto_config(struct hda_codec *codec)
1156{
1157 static const hda_nid_t alc880_ignore[] = { 0x1d, 0 };
Jesper Juhl7d7eb9e2012-04-12 22:11:25 +02001158 static const hda_nid_t alc880_ssids[] = { 0x15, 0x1b, 0x14, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001159 return alc_parse_auto_config(codec, alc880_ignore, alc880_ssids);
1160}
1161
Takashi Iwai1d045db2011-07-07 18:23:21 +02001162/*
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001163 * ALC880 fix-ups
1164 */
1165enum {
Takashi Iwai411225a2012-02-20 17:48:19 +01001166 ALC880_FIXUP_GPIO1,
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001167 ALC880_FIXUP_GPIO2,
1168 ALC880_FIXUP_MEDION_RIM,
Takashi Iwaidc6af522012-02-17 16:18:59 +01001169 ALC880_FIXUP_LG,
Takashi Iwaidb8a38e2013-08-09 12:34:42 +02001170 ALC880_FIXUP_LG_LW25,
Takashi Iwaif02aab52012-02-17 16:33:56 +01001171 ALC880_FIXUP_W810,
Takashi Iwai27e917f2012-02-17 17:49:54 +01001172 ALC880_FIXUP_EAPD_COEF,
Takashi Iwaib9368f52012-02-17 17:54:44 +01001173 ALC880_FIXUP_TCL_S700,
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001174 ALC880_FIXUP_VOL_KNOB,
1175 ALC880_FIXUP_FUJITSU,
Takashi Iwaiba533812012-02-20 16:36:52 +01001176 ALC880_FIXUP_F1734,
Takashi Iwai817de922012-02-20 17:20:48 +01001177 ALC880_FIXUP_UNIWILL,
Takashi Iwai967b88c2012-02-20 17:31:02 +01001178 ALC880_FIXUP_UNIWILL_DIG,
Takashi Iwai96e225f2012-02-20 17:41:51 +01001179 ALC880_FIXUP_Z71V,
Takashi Iwai487a5882013-11-07 07:29:30 +01001180 ALC880_FIXUP_ASUS_W5A,
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001181 ALC880_FIXUP_3ST_BASE,
1182 ALC880_FIXUP_3ST,
1183 ALC880_FIXUP_3ST_DIG,
1184 ALC880_FIXUP_5ST_BASE,
1185 ALC880_FIXUP_5ST,
1186 ALC880_FIXUP_5ST_DIG,
1187 ALC880_FIXUP_6ST_BASE,
1188 ALC880_FIXUP_6ST,
1189 ALC880_FIXUP_6ST_DIG,
Takashi Iwai53971452013-01-23 18:21:37 +01001190 ALC880_FIXUP_6ST_AUTOMUTE,
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001191};
1192
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001193/* enable the volume-knob widget support on NID 0x21 */
1194static void alc880_fixup_vol_knob(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001195 const struct hda_fixup *fix, int action)
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001196{
Takashi Iwai1727a772013-01-10 09:52:52 +01001197 if (action == HDA_FIXUP_ACT_PROBE)
Takashi Iwai62f949b2014-09-11 14:06:53 +02001198 snd_hda_jack_detect_enable_callback(codec, 0x21,
1199 alc_update_knob_master);
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001200}
1201
Takashi Iwai1727a772013-01-10 09:52:52 +01001202static const struct hda_fixup alc880_fixups[] = {
Takashi Iwai411225a2012-02-20 17:48:19 +01001203 [ALC880_FIXUP_GPIO1] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02001204 .type = HDA_FIXUP_FUNC,
1205 .v.func = alc_fixup_gpio1,
Takashi Iwai411225a2012-02-20 17:48:19 +01001206 },
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001207 [ALC880_FIXUP_GPIO2] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02001208 .type = HDA_FIXUP_FUNC,
1209 .v.func = alc_fixup_gpio2,
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001210 },
1211 [ALC880_FIXUP_MEDION_RIM] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001212 .type = HDA_FIXUP_VERBS,
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001213 .v.verbs = (const struct hda_verb[]) {
1214 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
1215 { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
1216 { }
1217 },
1218 .chained = true,
1219 .chain_id = ALC880_FIXUP_GPIO2,
1220 },
Takashi Iwaidc6af522012-02-17 16:18:59 +01001221 [ALC880_FIXUP_LG] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001222 .type = HDA_FIXUP_PINS,
1223 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaidc6af522012-02-17 16:18:59 +01001224 /* disable bogus unused pins */
1225 { 0x16, 0x411111f0 },
1226 { 0x18, 0x411111f0 },
1227 { 0x1a, 0x411111f0 },
1228 { }
1229 }
1230 },
Takashi Iwaidb8a38e2013-08-09 12:34:42 +02001231 [ALC880_FIXUP_LG_LW25] = {
1232 .type = HDA_FIXUP_PINS,
1233 .v.pins = (const struct hda_pintbl[]) {
1234 { 0x1a, 0x0181344f }, /* line-in */
1235 { 0x1b, 0x0321403f }, /* headphone */
1236 { }
1237 }
1238 },
Takashi Iwaif02aab52012-02-17 16:33:56 +01001239 [ALC880_FIXUP_W810] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001240 .type = HDA_FIXUP_PINS,
1241 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaif02aab52012-02-17 16:33:56 +01001242 /* disable bogus unused pins */
1243 { 0x17, 0x411111f0 },
1244 { }
1245 },
1246 .chained = true,
1247 .chain_id = ALC880_FIXUP_GPIO2,
1248 },
Takashi Iwai27e917f2012-02-17 17:49:54 +01001249 [ALC880_FIXUP_EAPD_COEF] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001250 .type = HDA_FIXUP_VERBS,
Takashi Iwai27e917f2012-02-17 17:49:54 +01001251 .v.verbs = (const struct hda_verb[]) {
1252 /* change to EAPD mode */
1253 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
1254 { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
1255 {}
1256 },
1257 },
Takashi Iwaib9368f52012-02-17 17:54:44 +01001258 [ALC880_FIXUP_TCL_S700] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001259 .type = HDA_FIXUP_VERBS,
Takashi Iwaib9368f52012-02-17 17:54:44 +01001260 .v.verbs = (const struct hda_verb[]) {
1261 /* change to EAPD mode */
1262 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
1263 { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
1264 {}
1265 },
1266 .chained = true,
1267 .chain_id = ALC880_FIXUP_GPIO2,
1268 },
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001269 [ALC880_FIXUP_VOL_KNOB] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001270 .type = HDA_FIXUP_FUNC,
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001271 .v.func = alc880_fixup_vol_knob,
1272 },
1273 [ALC880_FIXUP_FUJITSU] = {
1274 /* override all pins as BIOS on old Amilo is broken */
Takashi Iwai1727a772013-01-10 09:52:52 +01001275 .type = HDA_FIXUP_PINS,
1276 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaibb148bd2015-08-13 18:02:39 +02001277 { 0x14, 0x0121401f }, /* HP */
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001278 { 0x15, 0x99030120 }, /* speaker */
1279 { 0x16, 0x99030130 }, /* bass speaker */
1280 { 0x17, 0x411111f0 }, /* N/A */
1281 { 0x18, 0x411111f0 }, /* N/A */
1282 { 0x19, 0x01a19950 }, /* mic-in */
1283 { 0x1a, 0x411111f0 }, /* N/A */
1284 { 0x1b, 0x411111f0 }, /* N/A */
1285 { 0x1c, 0x411111f0 }, /* N/A */
1286 { 0x1d, 0x411111f0 }, /* N/A */
1287 { 0x1e, 0x01454140 }, /* SPDIF out */
1288 { }
1289 },
1290 .chained = true,
1291 .chain_id = ALC880_FIXUP_VOL_KNOB,
1292 },
Takashi Iwaiba533812012-02-20 16:36:52 +01001293 [ALC880_FIXUP_F1734] = {
1294 /* almost compatible with FUJITSU, but no bass and SPDIF */
Takashi Iwai1727a772013-01-10 09:52:52 +01001295 .type = HDA_FIXUP_PINS,
1296 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaibb148bd2015-08-13 18:02:39 +02001297 { 0x14, 0x0121401f }, /* HP */
Takashi Iwaiba533812012-02-20 16:36:52 +01001298 { 0x15, 0x99030120 }, /* speaker */
1299 { 0x16, 0x411111f0 }, /* N/A */
1300 { 0x17, 0x411111f0 }, /* N/A */
1301 { 0x18, 0x411111f0 }, /* N/A */
1302 { 0x19, 0x01a19950 }, /* mic-in */
1303 { 0x1a, 0x411111f0 }, /* N/A */
1304 { 0x1b, 0x411111f0 }, /* N/A */
1305 { 0x1c, 0x411111f0 }, /* N/A */
1306 { 0x1d, 0x411111f0 }, /* N/A */
1307 { 0x1e, 0x411111f0 }, /* N/A */
1308 { }
1309 },
1310 .chained = true,
1311 .chain_id = ALC880_FIXUP_VOL_KNOB,
1312 },
Takashi Iwai817de922012-02-20 17:20:48 +01001313 [ALC880_FIXUP_UNIWILL] = {
1314 /* need to fix HP and speaker pins to be parsed correctly */
Takashi Iwai1727a772013-01-10 09:52:52 +01001315 .type = HDA_FIXUP_PINS,
1316 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai817de922012-02-20 17:20:48 +01001317 { 0x14, 0x0121411f }, /* HP */
1318 { 0x15, 0x99030120 }, /* speaker */
1319 { 0x16, 0x99030130 }, /* bass speaker */
1320 { }
1321 },
1322 },
Takashi Iwai967b88c2012-02-20 17:31:02 +01001323 [ALC880_FIXUP_UNIWILL_DIG] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001324 .type = HDA_FIXUP_PINS,
1325 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai967b88c2012-02-20 17:31:02 +01001326 /* disable bogus unused pins */
1327 { 0x17, 0x411111f0 },
1328 { 0x19, 0x411111f0 },
1329 { 0x1b, 0x411111f0 },
1330 { 0x1f, 0x411111f0 },
1331 { }
1332 }
1333 },
Takashi Iwai96e225f2012-02-20 17:41:51 +01001334 [ALC880_FIXUP_Z71V] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001335 .type = HDA_FIXUP_PINS,
1336 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai96e225f2012-02-20 17:41:51 +01001337 /* set up the whole pins as BIOS is utterly broken */
1338 { 0x14, 0x99030120 }, /* speaker */
1339 { 0x15, 0x0121411f }, /* HP */
1340 { 0x16, 0x411111f0 }, /* N/A */
1341 { 0x17, 0x411111f0 }, /* N/A */
1342 { 0x18, 0x01a19950 }, /* mic-in */
1343 { 0x19, 0x411111f0 }, /* N/A */
1344 { 0x1a, 0x01813031 }, /* line-in */
1345 { 0x1b, 0x411111f0 }, /* N/A */
1346 { 0x1c, 0x411111f0 }, /* N/A */
1347 { 0x1d, 0x411111f0 }, /* N/A */
1348 { 0x1e, 0x0144111e }, /* SPDIF */
1349 { }
1350 }
1351 },
Takashi Iwai487a5882013-11-07 07:29:30 +01001352 [ALC880_FIXUP_ASUS_W5A] = {
1353 .type = HDA_FIXUP_PINS,
1354 .v.pins = (const struct hda_pintbl[]) {
1355 /* set up the whole pins as BIOS is utterly broken */
1356 { 0x14, 0x0121411f }, /* HP */
1357 { 0x15, 0x411111f0 }, /* N/A */
1358 { 0x16, 0x411111f0 }, /* N/A */
1359 { 0x17, 0x411111f0 }, /* N/A */
1360 { 0x18, 0x90a60160 }, /* mic */
1361 { 0x19, 0x411111f0 }, /* N/A */
1362 { 0x1a, 0x411111f0 }, /* N/A */
1363 { 0x1b, 0x411111f0 }, /* N/A */
1364 { 0x1c, 0x411111f0 }, /* N/A */
1365 { 0x1d, 0x411111f0 }, /* N/A */
1366 { 0x1e, 0xb743111e }, /* SPDIF out */
1367 { }
1368 },
1369 .chained = true,
1370 .chain_id = ALC880_FIXUP_GPIO1,
1371 },
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001372 [ALC880_FIXUP_3ST_BASE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001373 .type = HDA_FIXUP_PINS,
1374 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001375 { 0x14, 0x01014010 }, /* line-out */
1376 { 0x15, 0x411111f0 }, /* N/A */
1377 { 0x16, 0x411111f0 }, /* N/A */
1378 { 0x17, 0x411111f0 }, /* N/A */
1379 { 0x18, 0x01a19c30 }, /* mic-in */
1380 { 0x19, 0x0121411f }, /* HP */
1381 { 0x1a, 0x01813031 }, /* line-in */
1382 { 0x1b, 0x02a19c40 }, /* front-mic */
1383 { 0x1c, 0x411111f0 }, /* N/A */
1384 { 0x1d, 0x411111f0 }, /* N/A */
1385 /* 0x1e is filled in below */
1386 { 0x1f, 0x411111f0 }, /* N/A */
1387 { }
1388 }
1389 },
1390 [ALC880_FIXUP_3ST] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001391 .type = HDA_FIXUP_PINS,
1392 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001393 { 0x1e, 0x411111f0 }, /* N/A */
1394 { }
1395 },
1396 .chained = true,
1397 .chain_id = ALC880_FIXUP_3ST_BASE,
1398 },
1399 [ALC880_FIXUP_3ST_DIG] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001400 .type = HDA_FIXUP_PINS,
1401 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001402 { 0x1e, 0x0144111e }, /* SPDIF */
1403 { }
1404 },
1405 .chained = true,
1406 .chain_id = ALC880_FIXUP_3ST_BASE,
1407 },
1408 [ALC880_FIXUP_5ST_BASE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001409 .type = HDA_FIXUP_PINS,
1410 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001411 { 0x14, 0x01014010 }, /* front */
1412 { 0x15, 0x411111f0 }, /* N/A */
1413 { 0x16, 0x01011411 }, /* CLFE */
1414 { 0x17, 0x01016412 }, /* surr */
1415 { 0x18, 0x01a19c30 }, /* mic-in */
1416 { 0x19, 0x0121411f }, /* HP */
1417 { 0x1a, 0x01813031 }, /* line-in */
1418 { 0x1b, 0x02a19c40 }, /* front-mic */
1419 { 0x1c, 0x411111f0 }, /* N/A */
1420 { 0x1d, 0x411111f0 }, /* N/A */
1421 /* 0x1e is filled in below */
1422 { 0x1f, 0x411111f0 }, /* N/A */
1423 { }
1424 }
1425 },
1426 [ALC880_FIXUP_5ST] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001427 .type = HDA_FIXUP_PINS,
1428 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001429 { 0x1e, 0x411111f0 }, /* N/A */
1430 { }
1431 },
1432 .chained = true,
1433 .chain_id = ALC880_FIXUP_5ST_BASE,
1434 },
1435 [ALC880_FIXUP_5ST_DIG] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001436 .type = HDA_FIXUP_PINS,
1437 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001438 { 0x1e, 0x0144111e }, /* SPDIF */
1439 { }
1440 },
1441 .chained = true,
1442 .chain_id = ALC880_FIXUP_5ST_BASE,
1443 },
1444 [ALC880_FIXUP_6ST_BASE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001445 .type = HDA_FIXUP_PINS,
1446 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001447 { 0x14, 0x01014010 }, /* front */
1448 { 0x15, 0x01016412 }, /* surr */
1449 { 0x16, 0x01011411 }, /* CLFE */
1450 { 0x17, 0x01012414 }, /* side */
1451 { 0x18, 0x01a19c30 }, /* mic-in */
1452 { 0x19, 0x02a19c40 }, /* front-mic */
1453 { 0x1a, 0x01813031 }, /* line-in */
1454 { 0x1b, 0x0121411f }, /* HP */
1455 { 0x1c, 0x411111f0 }, /* N/A */
1456 { 0x1d, 0x411111f0 }, /* N/A */
1457 /* 0x1e is filled in below */
1458 { 0x1f, 0x411111f0 }, /* N/A */
1459 { }
1460 }
1461 },
1462 [ALC880_FIXUP_6ST] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001463 .type = HDA_FIXUP_PINS,
1464 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001465 { 0x1e, 0x411111f0 }, /* N/A */
1466 { }
1467 },
1468 .chained = true,
1469 .chain_id = ALC880_FIXUP_6ST_BASE,
1470 },
1471 [ALC880_FIXUP_6ST_DIG] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001472 .type = HDA_FIXUP_PINS,
1473 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001474 { 0x1e, 0x0144111e }, /* SPDIF */
1475 { }
1476 },
1477 .chained = true,
1478 .chain_id = ALC880_FIXUP_6ST_BASE,
1479 },
Takashi Iwai53971452013-01-23 18:21:37 +01001480 [ALC880_FIXUP_6ST_AUTOMUTE] = {
1481 .type = HDA_FIXUP_PINS,
1482 .v.pins = (const struct hda_pintbl[]) {
1483 { 0x1b, 0x0121401f }, /* HP with jack detect */
1484 { }
1485 },
1486 .chained_before = true,
1487 .chain_id = ALC880_FIXUP_6ST_BASE,
1488 },
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001489};
1490
1491static const struct snd_pci_quirk alc880_fixup_tbl[] = {
Takashi Iwaif02aab52012-02-17 16:33:56 +01001492 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_FIXUP_W810),
Takashi Iwai487a5882013-11-07 07:29:30 +01001493 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS W5A", ALC880_FIXUP_ASUS_W5A),
Takashi Iwai96e225f2012-02-20 17:41:51 +01001494 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_FIXUP_Z71V),
Takashi Iwai29e3fdc2012-02-20 17:56:57 +01001495 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_FIXUP_GPIO1),
David Henningsson6538de02014-06-10 10:52:50 +02001496 SND_PCI_QUIRK(0x147b, 0x1045, "ABit AA8XE", ALC880_FIXUP_6ST_AUTOMUTE),
Takashi Iwai29e3fdc2012-02-20 17:56:57 +01001497 SND_PCI_QUIRK(0x1558, 0x5401, "Clevo GPIO2", ALC880_FIXUP_GPIO2),
Takashi Iwai27e917f2012-02-17 17:49:54 +01001498 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo", ALC880_FIXUP_EAPD_COEF),
Takashi Iwai967b88c2012-02-20 17:31:02 +01001499 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_FIXUP_UNIWILL_DIG),
Takashi Iwaiba533812012-02-20 16:36:52 +01001500 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_FIXUP_F1734),
Takashi Iwai817de922012-02-20 17:20:48 +01001501 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_FIXUP_UNIWILL),
Takashi Iwai7833c7e2012-02-20 17:11:38 +01001502 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_FIXUP_VOL_KNOB),
Takashi Iwaif02aab52012-02-17 16:33:56 +01001503 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_FIXUP_W810),
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001504 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_FIXUP_MEDION_RIM),
Takashi Iwai53971452013-01-23 18:21:37 +01001505 SND_PCI_QUIRK(0x1631, 0xe011, "PB 13201056", ALC880_FIXUP_6ST_AUTOMUTE),
Takashi Iwaia1615742015-08-13 18:05:06 +02001506 SND_PCI_QUIRK(0x1734, 0x107c, "FSC Amilo M1437", ALC880_FIXUP_FUJITSU),
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001507 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FIXUP_FUJITSU),
Takashi Iwaiba533812012-02-20 16:36:52 +01001508 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_FIXUP_F1734),
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001509 SND_PCI_QUIRK(0x1734, 0x10b0, "FSC Amilo Pi1556", ALC880_FIXUP_FUJITSU),
Takashi Iwaidc6af522012-02-17 16:18:59 +01001510 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_FIXUP_LG),
1511 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_FIXUP_LG),
1512 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_FIXUP_LG),
Takashi Iwaidb8a38e2013-08-09 12:34:42 +02001513 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_FIXUP_LG_LW25),
Takashi Iwaib9368f52012-02-17 17:54:44 +01001514 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_FIXUP_TCL_S700),
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001515
1516 /* Below is the copied entries from alc880_quirks.c.
1517 * It's not quite sure whether BIOS sets the correct pin-config table
1518 * on these machines, thus they are kept to be compatible with
1519 * the old static quirks. Once when it's confirmed to work without
1520 * these overrides, it'd be better to remove.
1521 */
1522 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_FIXUP_5ST_DIG),
1523 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_FIXUP_6ST),
1524 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_FIXUP_3ST_DIG),
1525 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_FIXUP_6ST_DIG),
1526 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_FIXUP_6ST_DIG),
1527 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_FIXUP_6ST_DIG),
1528 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_FIXUP_3ST_DIG),
1529 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_FIXUP_3ST),
1530 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_FIXUP_6ST_DIG),
1531 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_FIXUP_3ST),
1532 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_FIXUP_3ST),
1533 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_FIXUP_5ST),
1534 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_FIXUP_5ST),
1535 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_FIXUP_5ST),
1536 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_FIXUP_6ST_DIG),
1537 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_FIXUP_6ST_DIG),
1538 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_FIXUP_6ST_DIG),
1539 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_FIXUP_6ST_DIG),
1540 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_FIXUP_5ST_DIG),
1541 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_FIXUP_5ST_DIG),
1542 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_FIXUP_5ST_DIG),
1543 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_FIXUP_6ST_DIG), /* broken BIOS */
1544 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_FIXUP_6ST_DIG),
1545 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1546 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1547 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1548 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_FIXUP_3ST_DIG),
1549 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1550 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_FIXUP_3ST_DIG),
1551 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_FIXUP_3ST_DIG),
1552 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1553 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1554 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1555 /* default Intel */
1556 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_FIXUP_3ST),
1557 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_FIXUP_5ST_DIG),
1558 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_FIXUP_6ST_DIG),
1559 {}
1560};
1561
Takashi Iwai1727a772013-01-10 09:52:52 +01001562static const struct hda_model_fixup alc880_fixup_models[] = {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001563 {.id = ALC880_FIXUP_3ST, .name = "3stack"},
1564 {.id = ALC880_FIXUP_3ST_DIG, .name = "3stack-digout"},
1565 {.id = ALC880_FIXUP_5ST, .name = "5stack"},
1566 {.id = ALC880_FIXUP_5ST_DIG, .name = "5stack-digout"},
1567 {.id = ALC880_FIXUP_6ST, .name = "6stack"},
1568 {.id = ALC880_FIXUP_6ST_DIG, .name = "6stack-digout"},
Takashi Iwai53971452013-01-23 18:21:37 +01001569 {.id = ALC880_FIXUP_6ST_AUTOMUTE, .name = "6stack-automute"},
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001570 {}
1571};
1572
1573
1574/*
Takashi Iwai1d045db2011-07-07 18:23:21 +02001575 * OK, here we have finally the patch for ALC880
1576 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02001577static int patch_alc880(struct hda_codec *codec)
1578{
1579 struct alc_spec *spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001580 int err;
1581
Takashi Iwai3de95172012-05-07 18:03:15 +02001582 err = alc_alloc_spec(codec, 0x0b);
1583 if (err < 0)
1584 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001585
Takashi Iwai3de95172012-05-07 18:03:15 +02001586 spec = codec->spec;
Takashi Iwai08c189f2012-12-19 15:22:24 +01001587 spec->gen.need_dac_fix = 1;
Takashi Iwai7504b6c2013-03-18 11:25:51 +01001588 spec->gen.beep_nid = 0x01;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001589
Takashi Iwai225068a2015-05-29 10:42:14 +02001590 codec->patch_ops.unsol_event = alc880_unsol_event;
1591
Takashi Iwaic9af7532019-05-10 11:01:43 +02001592 alc_pre_init(codec);
1593
Takashi Iwai1727a772013-01-10 09:52:52 +01001594 snd_hda_pick_fixup(codec, alc880_fixup_models, alc880_fixup_tbl,
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001595 alc880_fixups);
Takashi Iwai1727a772013-01-10 09:52:52 +01001596 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02001597
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001598 /* automatic parse from the BIOS config */
1599 err = alc880_parse_auto_config(codec);
1600 if (err < 0)
1601 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001602
Takashi Iwaifea80fa2018-06-20 12:52:46 +02001603 if (!spec->gen.no_analog) {
1604 err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
1605 if (err < 0)
1606 goto error;
1607 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02001608
Takashi Iwai1727a772013-01-10 09:52:52 +01001609 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01001610
Takashi Iwai1d045db2011-07-07 18:23:21 +02001611 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02001612
1613 error:
1614 alc_free(codec);
1615 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001616}
1617
1618
1619/*
1620 * ALC260 support
1621 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02001622static int alc260_parse_auto_config(struct hda_codec *codec)
1623{
Takashi Iwai1d045db2011-07-07 18:23:21 +02001624 static const hda_nid_t alc260_ignore[] = { 0x17, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001625 static const hda_nid_t alc260_ssids[] = { 0x10, 0x15, 0x0f, 0 };
1626 return alc_parse_auto_config(codec, alc260_ignore, alc260_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02001627}
1628
Takashi Iwai1d045db2011-07-07 18:23:21 +02001629/*
1630 * Pin config fixes
1631 */
1632enum {
Takashi Iwaica8f0422012-02-16 11:51:19 +01001633 ALC260_FIXUP_HP_DC5750,
1634 ALC260_FIXUP_HP_PIN_0F,
1635 ALC260_FIXUP_COEF,
Takashi Iwai15317ab2012-02-16 12:02:53 +01001636 ALC260_FIXUP_GPIO1,
Takashi Iwai20f7d922012-02-16 12:35:16 +01001637 ALC260_FIXUP_GPIO1_TOGGLE,
1638 ALC260_FIXUP_REPLACER,
Takashi Iwai0a1c4fa2012-02-16 12:42:30 +01001639 ALC260_FIXUP_HP_B1900,
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001640 ALC260_FIXUP_KN1,
Takashi Iwai39aedee2013-01-10 17:10:40 +01001641 ALC260_FIXUP_FSC_S7020,
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001642 ALC260_FIXUP_FSC_S7020_JWSE,
Takashi Iwaid08c5ef2013-11-22 08:06:36 +01001643 ALC260_FIXUP_VAIO_PINS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02001644};
1645
Takashi Iwai20f7d922012-02-16 12:35:16 +01001646static void alc260_gpio1_automute(struct hda_codec *codec)
1647{
1648 struct alc_spec *spec = codec->spec;
Takashi Iwaiaaf312d2018-06-19 22:28:22 +02001649
1650 alc_update_gpio_data(codec, 0x01, spec->gen.hp_jack_present);
Takashi Iwai20f7d922012-02-16 12:35:16 +01001651}
1652
1653static void alc260_fixup_gpio1_toggle(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001654 const struct hda_fixup *fix, int action)
Takashi Iwai20f7d922012-02-16 12:35:16 +01001655{
1656 struct alc_spec *spec = codec->spec;
Takashi Iwai1727a772013-01-10 09:52:52 +01001657 if (action == HDA_FIXUP_ACT_PROBE) {
Takashi Iwai20f7d922012-02-16 12:35:16 +01001658 /* although the machine has only one output pin, we need to
1659 * toggle GPIO1 according to the jack state
1660 */
Takashi Iwai08c189f2012-12-19 15:22:24 +01001661 spec->gen.automute_hook = alc260_gpio1_automute;
1662 spec->gen.detect_hp = 1;
1663 spec->gen.automute_speaker = 1;
1664 spec->gen.autocfg.hp_pins[0] = 0x0f; /* copy it for automute */
Takashi Iwai62f949b2014-09-11 14:06:53 +02001665 snd_hda_jack_detect_enable_callback(codec, 0x0f,
Takashi Iwai08c189f2012-12-19 15:22:24 +01001666 snd_hda_gen_hp_automute);
Takashi Iwai5579cd62018-06-19 22:22:41 +02001667 alc_setup_gpio(codec, 0x01);
Takashi Iwai20f7d922012-02-16 12:35:16 +01001668 }
1669}
1670
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001671static void alc260_fixup_kn1(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001672 const struct hda_fixup *fix, int action)
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001673{
1674 struct alc_spec *spec = codec->spec;
Takashi Iwai1727a772013-01-10 09:52:52 +01001675 static const struct hda_pintbl pincfgs[] = {
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001676 { 0x0f, 0x02214000 }, /* HP/speaker */
1677 { 0x12, 0x90a60160 }, /* int mic */
1678 { 0x13, 0x02a19000 }, /* ext mic */
1679 { 0x18, 0x01446000 }, /* SPDIF out */
1680 /* disable bogus I/O pins */
1681 { 0x10, 0x411111f0 },
1682 { 0x11, 0x411111f0 },
1683 { 0x14, 0x411111f0 },
1684 { 0x15, 0x411111f0 },
1685 { 0x16, 0x411111f0 },
1686 { 0x17, 0x411111f0 },
1687 { 0x19, 0x411111f0 },
1688 { }
1689 };
1690
1691 switch (action) {
Takashi Iwai1727a772013-01-10 09:52:52 +01001692 case HDA_FIXUP_ACT_PRE_PROBE:
1693 snd_hda_apply_pincfgs(codec, pincfgs);
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001694 spec->init_amp = ALC_INIT_NONE;
1695 break;
1696 }
1697}
1698
Takashi Iwai39aedee2013-01-10 17:10:40 +01001699static void alc260_fixup_fsc_s7020(struct hda_codec *codec,
1700 const struct hda_fixup *fix, int action)
1701{
1702 struct alc_spec *spec = codec->spec;
Takashi Iwai1c76aa52018-06-21 16:37:54 +02001703 if (action == HDA_FIXUP_ACT_PRE_PROBE)
Takashi Iwaie6e0ee52013-02-18 17:04:20 +01001704 spec->init_amp = ALC_INIT_NONE;
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001705}
1706
1707static void alc260_fixup_fsc_s7020_jwse(struct hda_codec *codec,
1708 const struct hda_fixup *fix, int action)
1709{
1710 struct alc_spec *spec = codec->spec;
1711 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwaif811c3c2013-03-07 18:32:59 +01001712 spec->gen.add_jack_modes = 1;
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001713 spec->gen.hp_mic = 1;
Takashi Iwaie6e0ee52013-02-18 17:04:20 +01001714 }
Takashi Iwai39aedee2013-01-10 17:10:40 +01001715}
1716
Takashi Iwai1727a772013-01-10 09:52:52 +01001717static const struct hda_fixup alc260_fixups[] = {
Takashi Iwaica8f0422012-02-16 11:51:19 +01001718 [ALC260_FIXUP_HP_DC5750] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001719 .type = HDA_FIXUP_PINS,
1720 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02001721 { 0x11, 0x90130110 }, /* speaker */
1722 { }
1723 }
1724 },
Takashi Iwaica8f0422012-02-16 11:51:19 +01001725 [ALC260_FIXUP_HP_PIN_0F] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001726 .type = HDA_FIXUP_PINS,
1727 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaica8f0422012-02-16 11:51:19 +01001728 { 0x0f, 0x01214000 }, /* HP */
1729 { }
1730 }
1731 },
1732 [ALC260_FIXUP_COEF] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001733 .type = HDA_FIXUP_VERBS,
Takashi Iwaica8f0422012-02-16 11:51:19 +01001734 .v.verbs = (const struct hda_verb[]) {
Ronan Marquete30cf2d2014-06-01 18:38:53 +02001735 { 0x1a, AC_VERB_SET_COEF_INDEX, 0x07 },
1736 { 0x1a, AC_VERB_SET_PROC_COEF, 0x3040 },
Takashi Iwaica8f0422012-02-16 11:51:19 +01001737 { }
1738 },
Takashi Iwaica8f0422012-02-16 11:51:19 +01001739 },
Takashi Iwai15317ab2012-02-16 12:02:53 +01001740 [ALC260_FIXUP_GPIO1] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02001741 .type = HDA_FIXUP_FUNC,
1742 .v.func = alc_fixup_gpio1,
Takashi Iwai15317ab2012-02-16 12:02:53 +01001743 },
Takashi Iwai20f7d922012-02-16 12:35:16 +01001744 [ALC260_FIXUP_GPIO1_TOGGLE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001745 .type = HDA_FIXUP_FUNC,
Takashi Iwai20f7d922012-02-16 12:35:16 +01001746 .v.func = alc260_fixup_gpio1_toggle,
1747 .chained = true,
1748 .chain_id = ALC260_FIXUP_HP_PIN_0F,
1749 },
1750 [ALC260_FIXUP_REPLACER] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001751 .type = HDA_FIXUP_VERBS,
Takashi Iwai20f7d922012-02-16 12:35:16 +01001752 .v.verbs = (const struct hda_verb[]) {
Takashi Iwai192a98e2014-06-02 15:16:07 +02001753 { 0x1a, AC_VERB_SET_COEF_INDEX, 0x07 },
1754 { 0x1a, AC_VERB_SET_PROC_COEF, 0x3050 },
Takashi Iwai20f7d922012-02-16 12:35:16 +01001755 { }
1756 },
1757 .chained = true,
1758 .chain_id = ALC260_FIXUP_GPIO1_TOGGLE,
1759 },
Takashi Iwai0a1c4fa2012-02-16 12:42:30 +01001760 [ALC260_FIXUP_HP_B1900] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001761 .type = HDA_FIXUP_FUNC,
Takashi Iwai0a1c4fa2012-02-16 12:42:30 +01001762 .v.func = alc260_fixup_gpio1_toggle,
1763 .chained = true,
1764 .chain_id = ALC260_FIXUP_COEF,
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001765 },
1766 [ALC260_FIXUP_KN1] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001767 .type = HDA_FIXUP_FUNC,
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001768 .v.func = alc260_fixup_kn1,
1769 },
Takashi Iwai39aedee2013-01-10 17:10:40 +01001770 [ALC260_FIXUP_FSC_S7020] = {
1771 .type = HDA_FIXUP_FUNC,
1772 .v.func = alc260_fixup_fsc_s7020,
1773 },
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001774 [ALC260_FIXUP_FSC_S7020_JWSE] = {
1775 .type = HDA_FIXUP_FUNC,
1776 .v.func = alc260_fixup_fsc_s7020_jwse,
1777 .chained = true,
1778 .chain_id = ALC260_FIXUP_FSC_S7020,
1779 },
Takashi Iwaid08c5ef2013-11-22 08:06:36 +01001780 [ALC260_FIXUP_VAIO_PINS] = {
1781 .type = HDA_FIXUP_PINS,
1782 .v.pins = (const struct hda_pintbl[]) {
1783 /* Pin configs are missing completely on some VAIOs */
1784 { 0x0f, 0x01211020 },
1785 { 0x10, 0x0001003f },
1786 { 0x11, 0x411111f0 },
1787 { 0x12, 0x01a15930 },
1788 { 0x13, 0x411111f0 },
1789 { 0x14, 0x411111f0 },
1790 { 0x15, 0x411111f0 },
1791 { 0x16, 0x411111f0 },
1792 { 0x17, 0x411111f0 },
1793 { 0x18, 0x411111f0 },
1794 { 0x19, 0x411111f0 },
1795 { }
1796 }
1797 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02001798};
1799
1800static const struct snd_pci_quirk alc260_fixup_tbl[] = {
Takashi Iwai15317ab2012-02-16 12:02:53 +01001801 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_FIXUP_GPIO1),
Takashi Iwaica8f0422012-02-16 11:51:19 +01001802 SND_PCI_QUIRK(0x1025, 0x007f, "Acer Aspire 9500", ALC260_FIXUP_COEF),
Takashi Iwai15317ab2012-02-16 12:02:53 +01001803 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_FIXUP_GPIO1),
Takashi Iwaica8f0422012-02-16 11:51:19 +01001804 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", ALC260_FIXUP_HP_DC5750),
Takashi Iwai0a1c4fa2012-02-16 12:42:30 +01001805 SND_PCI_QUIRK(0x103c, 0x30ba, "HP Presario B1900", ALC260_FIXUP_HP_B1900),
Takashi Iwaid08c5ef2013-11-22 08:06:36 +01001806 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_FIXUP_VAIO_PINS),
Takashi Iwai0f5a5b82013-11-21 09:12:52 +01001807 SND_PCI_QUIRK(0x104d, 0x81e2, "Sony VAIO TX", ALC260_FIXUP_HP_PIN_0F),
Takashi Iwai39aedee2013-01-10 17:10:40 +01001808 SND_PCI_QUIRK(0x10cf, 0x1326, "FSC LifeBook S7020", ALC260_FIXUP_FSC_S7020),
Takashi Iwaib1f58082012-02-16 12:45:03 +01001809 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FIXUP_GPIO1),
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001810 SND_PCI_QUIRK(0x152d, 0x0729, "Quanta KN1", ALC260_FIXUP_KN1),
Takashi Iwai20f7d922012-02-16 12:35:16 +01001811 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_FIXUP_REPLACER),
Takashi Iwaica8f0422012-02-16 11:51:19 +01001812 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_FIXUP_COEF),
Takashi Iwai1d045db2011-07-07 18:23:21 +02001813 {}
1814};
1815
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001816static const struct hda_model_fixup alc260_fixup_models[] = {
1817 {.id = ALC260_FIXUP_GPIO1, .name = "gpio1"},
1818 {.id = ALC260_FIXUP_COEF, .name = "coef"},
1819 {.id = ALC260_FIXUP_FSC_S7020, .name = "fujitsu"},
1820 {.id = ALC260_FIXUP_FSC_S7020_JWSE, .name = "fujitsu-jwse"},
1821 {}
1822};
1823
Takashi Iwai1d045db2011-07-07 18:23:21 +02001824/*
1825 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02001826static int patch_alc260(struct hda_codec *codec)
1827{
1828 struct alc_spec *spec;
Takashi Iwaic3c2c9e2012-02-16 12:59:55 +01001829 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001830
Takashi Iwai3de95172012-05-07 18:03:15 +02001831 err = alc_alloc_spec(codec, 0x07);
1832 if (err < 0)
1833 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001834
Takashi Iwai3de95172012-05-07 18:03:15 +02001835 spec = codec->spec;
Takashi Iwaiea46c3c2013-01-15 18:45:53 +01001836 /* as quite a few machines require HP amp for speaker outputs,
1837 * it's easier to enable it unconditionally; even if it's unneeded,
1838 * it's almost harmless.
1839 */
1840 spec->gen.prefer_hp_amp = 1;
Takashi Iwai7504b6c2013-03-18 11:25:51 +01001841 spec->gen.beep_nid = 0x01;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001842
Takashi Iwai225068a2015-05-29 10:42:14 +02001843 spec->shutup = alc_eapd_shutup;
1844
Takashi Iwaic9af7532019-05-10 11:01:43 +02001845 alc_pre_init(codec);
1846
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001847 snd_hda_pick_fixup(codec, alc260_fixup_models, alc260_fixup_tbl,
1848 alc260_fixups);
Takashi Iwai1727a772013-01-10 09:52:52 +01001849 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02001850
Takashi Iwaic3c2c9e2012-02-16 12:59:55 +01001851 /* automatic parse from the BIOS config */
1852 err = alc260_parse_auto_config(codec);
1853 if (err < 0)
1854 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001855
Takashi Iwaifea80fa2018-06-20 12:52:46 +02001856 if (!spec->gen.no_analog) {
1857 err = set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
1858 if (err < 0)
1859 goto error;
1860 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02001861
Takashi Iwai1727a772013-01-10 09:52:52 +01001862 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01001863
Takashi Iwai1d045db2011-07-07 18:23:21 +02001864 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02001865
1866 error:
1867 alc_free(codec);
1868 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001869}
1870
1871
1872/*
1873 * ALC882/883/885/888/889 support
1874 *
1875 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
1876 * configuration. Each pin widget can choose any input DACs and a mixer.
1877 * Each ADC is connected from a mixer of all inputs. This makes possible
1878 * 6-channel independent captures.
1879 *
1880 * In addition, an independent DAC for the multi-playback (not used in this
1881 * driver yet).
1882 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02001883
1884/*
1885 * Pin config fixes
1886 */
1887enum {
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01001888 ALC882_FIXUP_ABIT_AW9D_MAX,
1889 ALC882_FIXUP_LENOVO_Y530,
1890 ALC882_FIXUP_PB_M5210,
1891 ALC882_FIXUP_ACER_ASPIRE_7736,
1892 ALC882_FIXUP_ASUS_W90V,
Marton Balint8f239212012-03-05 21:33:23 +01001893 ALC889_FIXUP_CD,
David Henningssonb2c53e22014-01-01 14:01:34 +01001894 ALC889_FIXUP_FRONT_HP_NO_PRESENCE,
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01001895 ALC889_FIXUP_VAIO_TT,
Takashi Iwai0e7cc2e2011-11-09 12:42:48 +01001896 ALC888_FIXUP_EEE1601,
Takashi Iwai177943a32011-11-09 12:55:18 +01001897 ALC882_FIXUP_EAPD,
Takashi Iwai7a6069b2011-11-09 15:22:01 +01001898 ALC883_FIXUP_EAPD,
Takashi Iwai8812c4f2011-11-09 17:39:15 +01001899 ALC883_FIXUP_ACER_EAPD,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001900 ALC882_FIXUP_GPIO1,
1901 ALC882_FIXUP_GPIO2,
Takashi Iwaieb844d52011-11-09 18:03:07 +01001902 ALC882_FIXUP_GPIO3,
Takashi Iwai68ef0562011-11-09 18:24:44 +01001903 ALC889_FIXUP_COEF,
1904 ALC882_FIXUP_ASUS_W2JC,
Takashi Iwaic3e837b2011-11-10 16:01:47 +01001905 ALC882_FIXUP_ACER_ASPIRE_4930G,
1906 ALC882_FIXUP_ACER_ASPIRE_8930G,
1907 ALC882_FIXUP_ASPIRE_8930G_VERBS,
Takashi Iwai56710872011-11-14 17:42:11 +01001908 ALC885_FIXUP_MACPRO_GPIO,
Takashi Iwai02a237b2012-02-13 15:25:07 +01001909 ALC889_FIXUP_DAC_ROUTE,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001910 ALC889_FIXUP_MBP_VREF,
1911 ALC889_FIXUP_IMAC91_VREF,
Adrien Vergée7729a42014-01-24 14:56:14 -05001912 ALC889_FIXUP_MBA11_VREF,
Takashi Iwai0756f092013-12-04 13:59:45 +01001913 ALC889_FIXUP_MBA21_VREF,
Takashi Iwaic20f31e2014-02-03 11:02:10 +01001914 ALC889_FIXUP_MP11_VREF,
Mario Kleiner9f660a12015-12-22 00:45:43 +01001915 ALC889_FIXUP_MP41_VREF,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02001916 ALC882_FIXUP_INV_DMIC,
Takashi Iwaie427c232012-07-29 10:04:08 +02001917 ALC882_FIXUP_NO_PRIMARY_HP,
Takashi Iwai1f0bbf02013-11-28 15:21:21 +01001918 ALC887_FIXUP_ASUS_BASS,
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01001919 ALC887_FIXUP_BASS_CHMAP,
Takashi Iwai7beb3a62017-04-10 18:05:52 +02001920 ALC1220_FIXUP_GB_DUAL_CODECS,
Peisen0202f5c2017-10-26 10:35:36 +08001921 ALC1220_FIXUP_CLEVO_P950,
Richard Sailer80690a22019-04-02 15:52:04 +02001922 ALC1220_FIXUP_CLEVO_PB51ED,
1923 ALC1220_FIXUP_CLEVO_PB51ED_PINS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02001924};
1925
Takashi Iwai68ef0562011-11-09 18:24:44 +01001926static void alc889_fixup_coef(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001927 const struct hda_fixup *fix, int action)
Takashi Iwai68ef0562011-11-09 18:24:44 +01001928{
Takashi Iwai1727a772013-01-10 09:52:52 +01001929 if (action != HDA_FIXUP_ACT_INIT)
Takashi Iwai68ef0562011-11-09 18:24:44 +01001930 return;
Kailang Yang1df88742014-10-29 16:10:13 +08001931 alc_update_coef_idx(codec, 7, 0, 0x2030);
Takashi Iwai68ef0562011-11-09 18:24:44 +01001932}
1933
Takashi Iwai56710872011-11-14 17:42:11 +01001934/* set up GPIO at initialization */
1935static void alc885_fixup_macpro_gpio(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001936 const struct hda_fixup *fix, int action)
Takashi Iwai56710872011-11-14 17:42:11 +01001937{
Takashi Iwai215c8502018-06-19 22:34:26 +02001938 struct alc_spec *spec = codec->spec;
1939
1940 spec->gpio_write_delay = true;
1941 alc_fixup_gpio3(codec, fix, action);
Takashi Iwai56710872011-11-14 17:42:11 +01001942}
1943
Takashi Iwai02a237b2012-02-13 15:25:07 +01001944/* Fix the connection of some pins for ALC889:
1945 * At least, Acer Aspire 5935 shows the connections to DAC3/4 don't
1946 * work correctly (bko#42740)
1947 */
1948static void alc889_fixup_dac_route(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001949 const struct hda_fixup *fix, int action)
Takashi Iwai02a237b2012-02-13 15:25:07 +01001950{
Takashi Iwai1727a772013-01-10 09:52:52 +01001951 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwaief8d60f2012-02-17 10:12:38 +01001952 /* fake the connections during parsing the tree */
Michał Mirosławcaf3c042020-01-03 10:23:48 +01001953 static const hda_nid_t conn1[] = { 0x0c, 0x0d };
1954 static const hda_nid_t conn2[] = { 0x0e, 0x0f };
1955 snd_hda_override_conn_list(codec, 0x14, ARRAY_SIZE(conn1), conn1);
1956 snd_hda_override_conn_list(codec, 0x15, ARRAY_SIZE(conn1), conn1);
1957 snd_hda_override_conn_list(codec, 0x18, ARRAY_SIZE(conn2), conn2);
1958 snd_hda_override_conn_list(codec, 0x1a, ARRAY_SIZE(conn2), conn2);
Takashi Iwai1727a772013-01-10 09:52:52 +01001959 } else if (action == HDA_FIXUP_ACT_PROBE) {
Takashi Iwaief8d60f2012-02-17 10:12:38 +01001960 /* restore the connections */
Michał Mirosławcaf3c042020-01-03 10:23:48 +01001961 static const hda_nid_t conn[] = { 0x0c, 0x0d, 0x0e, 0x0f, 0x26 };
1962 snd_hda_override_conn_list(codec, 0x14, ARRAY_SIZE(conn), conn);
1963 snd_hda_override_conn_list(codec, 0x15, ARRAY_SIZE(conn), conn);
1964 snd_hda_override_conn_list(codec, 0x18, ARRAY_SIZE(conn), conn);
1965 snd_hda_override_conn_list(codec, 0x1a, ARRAY_SIZE(conn), conn);
Takashi Iwai02a237b2012-02-13 15:25:07 +01001966 }
1967}
1968
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001969/* Set VREF on HP pin */
1970static void alc889_fixup_mbp_vref(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001971 const struct hda_fixup *fix, int action)
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001972{
Michał Mirosławcaf3c042020-01-03 10:23:48 +01001973 static const hda_nid_t nids[] = { 0x14, 0x15, 0x19 };
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001974 struct alc_spec *spec = codec->spec;
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001975 int i;
1976
Takashi Iwai1727a772013-01-10 09:52:52 +01001977 if (action != HDA_FIXUP_ACT_INIT)
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001978 return;
1979 for (i = 0; i < ARRAY_SIZE(nids); i++) {
1980 unsigned int val = snd_hda_codec_get_pincfg(codec, nids[i]);
1981 if (get_defcfg_device(val) != AC_JACK_HP_OUT)
1982 continue;
Takashi Iwaid3f02d62013-01-10 10:12:22 +01001983 val = snd_hda_codec_get_pin_target(codec, nids[i]);
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001984 val |= AC_PINCTL_VREF_80;
Takashi Iwaicdd03ce2012-04-20 12:34:50 +02001985 snd_hda_set_pin_ctl(codec, nids[i], val);
Takashi Iwai08c189f2012-12-19 15:22:24 +01001986 spec->gen.keep_vref_in_automute = 1;
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001987 break;
1988 }
1989}
1990
Takashi Iwai0756f092013-12-04 13:59:45 +01001991static void alc889_fixup_mac_pins(struct hda_codec *codec,
1992 const hda_nid_t *nids, int num_nids)
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001993{
1994 struct alc_spec *spec = codec->spec;
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001995 int i;
1996
Takashi Iwai0756f092013-12-04 13:59:45 +01001997 for (i = 0; i < num_nids; i++) {
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001998 unsigned int val;
Takashi Iwaid3f02d62013-01-10 10:12:22 +01001999 val = snd_hda_codec_get_pin_target(codec, nids[i]);
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002000 val |= AC_PINCTL_VREF_50;
Takashi Iwaicdd03ce2012-04-20 12:34:50 +02002001 snd_hda_set_pin_ctl(codec, nids[i], val);
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002002 }
Takashi Iwai08c189f2012-12-19 15:22:24 +01002003 spec->gen.keep_vref_in_automute = 1;
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002004}
2005
Takashi Iwai0756f092013-12-04 13:59:45 +01002006/* Set VREF on speaker pins on imac91 */
2007static void alc889_fixup_imac91_vref(struct hda_codec *codec,
2008 const struct hda_fixup *fix, int action)
2009{
Michał Mirosławcaf3c042020-01-03 10:23:48 +01002010 static const hda_nid_t nids[] = { 0x18, 0x1a };
Takashi Iwai0756f092013-12-04 13:59:45 +01002011
2012 if (action == HDA_FIXUP_ACT_INIT)
2013 alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
2014}
2015
Adrien Vergée7729a42014-01-24 14:56:14 -05002016/* Set VREF on speaker pins on mba11 */
2017static void alc889_fixup_mba11_vref(struct hda_codec *codec,
2018 const struct hda_fixup *fix, int action)
2019{
Michał Mirosławcaf3c042020-01-03 10:23:48 +01002020 static const hda_nid_t nids[] = { 0x18 };
Adrien Vergée7729a42014-01-24 14:56:14 -05002021
2022 if (action == HDA_FIXUP_ACT_INIT)
2023 alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
2024}
2025
Takashi Iwai0756f092013-12-04 13:59:45 +01002026/* Set VREF on speaker pins on mba21 */
2027static void alc889_fixup_mba21_vref(struct hda_codec *codec,
2028 const struct hda_fixup *fix, int action)
2029{
Michał Mirosławcaf3c042020-01-03 10:23:48 +01002030 static const hda_nid_t nids[] = { 0x18, 0x19 };
Takashi Iwai0756f092013-12-04 13:59:45 +01002031
2032 if (action == HDA_FIXUP_ACT_INIT)
2033 alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
2034}
2035
Takashi Iwaie427c232012-07-29 10:04:08 +02002036/* Don't take HP output as primary
Fernando Luis Vázquez Caod9111492013-02-12 16:49:46 +09002037 * Strangely, the speaker output doesn't work on Vaio Z and some Vaio
2038 * all-in-one desktop PCs (for example VGC-LN51JGB) through DAC 0x05
Takashi Iwaie427c232012-07-29 10:04:08 +02002039 */
2040static void alc882_fixup_no_primary_hp(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01002041 const struct hda_fixup *fix, int action)
Takashi Iwaie427c232012-07-29 10:04:08 +02002042{
2043 struct alc_spec *spec = codec->spec;
Takashi Iwaida96fb52013-07-29 16:54:36 +02002044 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai08c189f2012-12-19 15:22:24 +01002045 spec->gen.no_primary_hp = 1;
Takashi Iwaida96fb52013-07-29 16:54:36 +02002046 spec->gen.no_multi_io = 1;
2047 }
Takashi Iwaie427c232012-07-29 10:04:08 +02002048}
2049
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01002050static void alc_fixup_bass_chmap(struct hda_codec *codec,
2051 const struct hda_fixup *fix, int action);
2052
Takashi Iwai7beb3a62017-04-10 18:05:52 +02002053/* For dual-codec configuration, we need to disable some features to avoid
2054 * conflicts of kctls and PCM streams
2055 */
2056static void alc_fixup_dual_codecs(struct hda_codec *codec,
2057 const struct hda_fixup *fix, int action)
2058{
2059 struct alc_spec *spec = codec->spec;
2060
2061 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2062 return;
2063 /* disable vmaster */
2064 spec->gen.suppress_vmaster = 1;
2065 /* auto-mute and auto-mic switch don't work with multiple codecs */
2066 spec->gen.suppress_auto_mute = 1;
2067 spec->gen.suppress_auto_mic = 1;
2068 /* disable aamix as well */
2069 spec->gen.mixer_nid = 0;
2070 /* add location prefix to avoid conflicts */
2071 codec->force_pin_prefix = 1;
2072}
2073
2074static void rename_ctl(struct hda_codec *codec, const char *oldname,
2075 const char *newname)
2076{
2077 struct snd_kcontrol *kctl;
2078
2079 kctl = snd_hda_find_mixer_ctl(codec, oldname);
2080 if (kctl)
2081 strcpy(kctl->id.name, newname);
2082}
2083
2084static void alc1220_fixup_gb_dual_codecs(struct hda_codec *codec,
2085 const struct hda_fixup *fix,
2086 int action)
2087{
2088 alc_fixup_dual_codecs(codec, fix, action);
2089 switch (action) {
2090 case HDA_FIXUP_ACT_PRE_PROBE:
2091 /* override card longname to provide a unique UCM profile */
2092 strcpy(codec->card->longname, "HDAudio-Gigabyte-ALC1220DualCodecs");
2093 break;
2094 case HDA_FIXUP_ACT_BUILD:
2095 /* rename Capture controls depending on the codec */
2096 rename_ctl(codec, "Capture Volume",
2097 codec->addr == 0 ?
2098 "Rear-Panel Capture Volume" :
2099 "Front-Panel Capture Volume");
2100 rename_ctl(codec, "Capture Switch",
2101 codec->addr == 0 ?
2102 "Rear-Panel Capture Switch" :
2103 "Front-Panel Capture Switch");
2104 break;
2105 }
2106}
2107
Peisen0202f5c2017-10-26 10:35:36 +08002108static void alc1220_fixup_clevo_p950(struct hda_codec *codec,
2109 const struct hda_fixup *fix,
2110 int action)
2111{
Michał Mirosławcaf3c042020-01-03 10:23:48 +01002112 static const hda_nid_t conn1[] = { 0x0c };
Peisen0202f5c2017-10-26 10:35:36 +08002113
2114 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2115 return;
2116
2117 alc_update_coef_idx(codec, 0x7, 0, 0x3c3);
2118 /* We therefore want to make sure 0x14 (front headphone) and
2119 * 0x1b (speakers) use the stereo DAC 0x02
2120 */
Michał Mirosławcaf3c042020-01-03 10:23:48 +01002121 snd_hda_override_conn_list(codec, 0x14, ARRAY_SIZE(conn1), conn1);
2122 snd_hda_override_conn_list(codec, 0x1b, ARRAY_SIZE(conn1), conn1);
Peisen0202f5c2017-10-26 10:35:36 +08002123}
2124
Jeremy Soller7f665b12019-02-13 10:56:19 -07002125static void alc_fixup_headset_mode_no_hp_mic(struct hda_codec *codec,
2126 const struct hda_fixup *fix, int action);
2127
Richard Sailer80690a22019-04-02 15:52:04 +02002128static void alc1220_fixup_clevo_pb51ed(struct hda_codec *codec,
Jeremy Soller7f665b12019-02-13 10:56:19 -07002129 const struct hda_fixup *fix,
2130 int action)
2131{
2132 alc1220_fixup_clevo_p950(codec, fix, action);
2133 alc_fixup_headset_mode_no_hp_mic(codec, fix, action);
2134}
2135
Takashi Iwai1727a772013-01-10 09:52:52 +01002136static const struct hda_fixup alc882_fixups[] = {
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002137 [ALC882_FIXUP_ABIT_AW9D_MAX] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002138 .type = HDA_FIXUP_PINS,
2139 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002140 { 0x15, 0x01080104 }, /* side */
2141 { 0x16, 0x01011012 }, /* rear */
2142 { 0x17, 0x01016011 }, /* clfe */
2143 { }
2144 }
2145 },
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002146 [ALC882_FIXUP_LENOVO_Y530] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002147 .type = HDA_FIXUP_PINS,
2148 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002149 { 0x15, 0x99130112 }, /* rear int speakers */
2150 { 0x16, 0x99130111 }, /* subwoofer */
2151 { }
2152 }
2153 },
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002154 [ALC882_FIXUP_PB_M5210] = {
Takashi Iwaifd108212013-01-10 10:18:14 +01002155 .type = HDA_FIXUP_PINCTLS,
2156 .v.pins = (const struct hda_pintbl[]) {
2157 { 0x19, PIN_VREF50 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02002158 {}
2159 }
2160 },
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002161 [ALC882_FIXUP_ACER_ASPIRE_7736] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002162 .type = HDA_FIXUP_FUNC,
Takashi Iwai23d30f22012-05-07 17:17:32 +02002163 .v.func = alc_fixup_sku_ignore,
Takashi Iwai1d045db2011-07-07 18:23:21 +02002164 },
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002165 [ALC882_FIXUP_ASUS_W90V] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002166 .type = HDA_FIXUP_PINS,
2167 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai5cdf7452011-10-26 23:04:08 +02002168 { 0x16, 0x99130110 }, /* fix sequence for CLFE */
2169 { }
2170 }
2171 },
Marton Balint8f239212012-03-05 21:33:23 +01002172 [ALC889_FIXUP_CD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002173 .type = HDA_FIXUP_PINS,
2174 .v.pins = (const struct hda_pintbl[]) {
Marton Balint8f239212012-03-05 21:33:23 +01002175 { 0x1c, 0x993301f0 }, /* CD */
2176 { }
2177 }
2178 },
David Henningssonb2c53e22014-01-01 14:01:34 +01002179 [ALC889_FIXUP_FRONT_HP_NO_PRESENCE] = {
2180 .type = HDA_FIXUP_PINS,
2181 .v.pins = (const struct hda_pintbl[]) {
2182 { 0x1b, 0x02214120 }, /* Front HP jack is flaky, disable jack detect */
2183 { }
2184 },
2185 .chained = true,
2186 .chain_id = ALC889_FIXUP_CD,
2187 },
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002188 [ALC889_FIXUP_VAIO_TT] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002189 .type = HDA_FIXUP_PINS,
2190 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002191 { 0x17, 0x90170111 }, /* hidden surround speaker */
2192 { }
2193 }
2194 },
Takashi Iwai0e7cc2e2011-11-09 12:42:48 +01002195 [ALC888_FIXUP_EEE1601] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002196 .type = HDA_FIXUP_VERBS,
Takashi Iwai0e7cc2e2011-11-09 12:42:48 +01002197 .v.verbs = (const struct hda_verb[]) {
2198 { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b },
2199 { 0x20, AC_VERB_SET_PROC_COEF, 0x0838 },
2200 { }
2201 }
Takashi Iwai177943a32011-11-09 12:55:18 +01002202 },
2203 [ALC882_FIXUP_EAPD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002204 .type = HDA_FIXUP_VERBS,
Takashi Iwai177943a32011-11-09 12:55:18 +01002205 .v.verbs = (const struct hda_verb[]) {
2206 /* change to EAPD mode */
2207 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2208 { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
2209 { }
2210 }
2211 },
Takashi Iwai7a6069b2011-11-09 15:22:01 +01002212 [ALC883_FIXUP_EAPD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002213 .type = HDA_FIXUP_VERBS,
Takashi Iwai7a6069b2011-11-09 15:22:01 +01002214 .v.verbs = (const struct hda_verb[]) {
2215 /* change to EAPD mode */
2216 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2217 { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
2218 { }
2219 }
2220 },
Takashi Iwai8812c4f2011-11-09 17:39:15 +01002221 [ALC883_FIXUP_ACER_EAPD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002222 .type = HDA_FIXUP_VERBS,
Takashi Iwai8812c4f2011-11-09 17:39:15 +01002223 .v.verbs = (const struct hda_verb[]) {
2224 /* eanable EAPD on Acer laptops */
2225 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2226 { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
2227 { }
2228 }
2229 },
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002230 [ALC882_FIXUP_GPIO1] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02002231 .type = HDA_FIXUP_FUNC,
2232 .v.func = alc_fixup_gpio1,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002233 },
2234 [ALC882_FIXUP_GPIO2] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02002235 .type = HDA_FIXUP_FUNC,
2236 .v.func = alc_fixup_gpio2,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002237 },
Takashi Iwaieb844d52011-11-09 18:03:07 +01002238 [ALC882_FIXUP_GPIO3] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02002239 .type = HDA_FIXUP_FUNC,
2240 .v.func = alc_fixup_gpio3,
Takashi Iwaieb844d52011-11-09 18:03:07 +01002241 },
Takashi Iwai68ef0562011-11-09 18:24:44 +01002242 [ALC882_FIXUP_ASUS_W2JC] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02002243 .type = HDA_FIXUP_FUNC,
2244 .v.func = alc_fixup_gpio1,
Takashi Iwai68ef0562011-11-09 18:24:44 +01002245 .chained = true,
2246 .chain_id = ALC882_FIXUP_EAPD,
2247 },
2248 [ALC889_FIXUP_COEF] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002249 .type = HDA_FIXUP_FUNC,
Takashi Iwai68ef0562011-11-09 18:24:44 +01002250 .v.func = alc889_fixup_coef,
2251 },
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002252 [ALC882_FIXUP_ACER_ASPIRE_4930G] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002253 .type = HDA_FIXUP_PINS,
2254 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002255 { 0x16, 0x99130111 }, /* CLFE speaker */
2256 { 0x17, 0x99130112 }, /* surround speaker */
2257 { }
Takashi Iwai038d4fe2012-04-11 17:18:12 +02002258 },
2259 .chained = true,
2260 .chain_id = ALC882_FIXUP_GPIO1,
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002261 },
2262 [ALC882_FIXUP_ACER_ASPIRE_8930G] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002263 .type = HDA_FIXUP_PINS,
2264 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002265 { 0x16, 0x99130111 }, /* CLFE speaker */
2266 { 0x1b, 0x99130112 }, /* surround speaker */
2267 { }
2268 },
2269 .chained = true,
2270 .chain_id = ALC882_FIXUP_ASPIRE_8930G_VERBS,
2271 },
2272 [ALC882_FIXUP_ASPIRE_8930G_VERBS] = {
2273 /* additional init verbs for Acer Aspire 8930G */
Takashi Iwai1727a772013-01-10 09:52:52 +01002274 .type = HDA_FIXUP_VERBS,
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002275 .v.verbs = (const struct hda_verb[]) {
2276 /* Enable all DACs */
2277 /* DAC DISABLE/MUTE 1? */
2278 /* setting bits 1-5 disables DAC nids 0x02-0x06
2279 * apparently. Init=0x38 */
2280 { 0x20, AC_VERB_SET_COEF_INDEX, 0x03 },
2281 { 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
2282 /* DAC DISABLE/MUTE 2? */
2283 /* some bit here disables the other DACs.
2284 * Init=0x4900 */
2285 { 0x20, AC_VERB_SET_COEF_INDEX, 0x08 },
2286 { 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
2287 /* DMIC fix
2288 * This laptop has a stereo digital microphone.
2289 * The mics are only 1cm apart which makes the stereo
2290 * useless. However, either the mic or the ALC889
2291 * makes the signal become a difference/sum signal
2292 * instead of standard stereo, which is annoying.
2293 * So instead we flip this bit which makes the
2294 * codec replicate the sum signal to both channels,
2295 * turning it into a normal mono mic.
2296 */
2297 /* DMIC_CONTROL? Init value = 0x0001 */
2298 { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b },
2299 { 0x20, AC_VERB_SET_PROC_COEF, 0x0003 },
2300 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2301 { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
2302 { }
Takashi Iwai038d4fe2012-04-11 17:18:12 +02002303 },
2304 .chained = true,
2305 .chain_id = ALC882_FIXUP_GPIO1,
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002306 },
Takashi Iwai56710872011-11-14 17:42:11 +01002307 [ALC885_FIXUP_MACPRO_GPIO] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002308 .type = HDA_FIXUP_FUNC,
Takashi Iwai56710872011-11-14 17:42:11 +01002309 .v.func = alc885_fixup_macpro_gpio,
2310 },
Takashi Iwai02a237b2012-02-13 15:25:07 +01002311 [ALC889_FIXUP_DAC_ROUTE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002312 .type = HDA_FIXUP_FUNC,
Takashi Iwai02a237b2012-02-13 15:25:07 +01002313 .v.func = alc889_fixup_dac_route,
2314 },
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002315 [ALC889_FIXUP_MBP_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_mbp_vref,
2318 .chained = true,
2319 .chain_id = ALC882_FIXUP_GPIO1,
2320 },
2321 [ALC889_FIXUP_IMAC91_VREF] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002322 .type = HDA_FIXUP_FUNC,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002323 .v.func = alc889_fixup_imac91_vref,
2324 .chained = true,
2325 .chain_id = ALC882_FIXUP_GPIO1,
2326 },
Adrien Vergée7729a42014-01-24 14:56:14 -05002327 [ALC889_FIXUP_MBA11_VREF] = {
2328 .type = HDA_FIXUP_FUNC,
2329 .v.func = alc889_fixup_mba11_vref,
2330 .chained = true,
2331 .chain_id = ALC889_FIXUP_MBP_VREF,
2332 },
Takashi Iwai0756f092013-12-04 13:59:45 +01002333 [ALC889_FIXUP_MBA21_VREF] = {
2334 .type = HDA_FIXUP_FUNC,
2335 .v.func = alc889_fixup_mba21_vref,
2336 .chained = true,
2337 .chain_id = ALC889_FIXUP_MBP_VREF,
2338 },
Takashi Iwaic20f31e2014-02-03 11:02:10 +01002339 [ALC889_FIXUP_MP11_VREF] = {
2340 .type = HDA_FIXUP_FUNC,
2341 .v.func = alc889_fixup_mba11_vref,
2342 .chained = true,
2343 .chain_id = ALC885_FIXUP_MACPRO_GPIO,
2344 },
Mario Kleiner9f660a12015-12-22 00:45:43 +01002345 [ALC889_FIXUP_MP41_VREF] = {
2346 .type = HDA_FIXUP_FUNC,
2347 .v.func = alc889_fixup_mbp_vref,
2348 .chained = true,
2349 .chain_id = ALC885_FIXUP_MACPRO_GPIO,
2350 },
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002351 [ALC882_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002352 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02002353 .v.func = alc_fixup_inv_dmic,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002354 },
Takashi Iwaie427c232012-07-29 10:04:08 +02002355 [ALC882_FIXUP_NO_PRIMARY_HP] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002356 .type = HDA_FIXUP_FUNC,
Takashi Iwaie427c232012-07-29 10:04:08 +02002357 .v.func = alc882_fixup_no_primary_hp,
2358 },
Takashi Iwai1f0bbf02013-11-28 15:21:21 +01002359 [ALC887_FIXUP_ASUS_BASS] = {
2360 .type = HDA_FIXUP_PINS,
2361 .v.pins = (const struct hda_pintbl[]) {
2362 {0x16, 0x99130130}, /* bass speaker */
2363 {}
2364 },
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01002365 .chained = true,
2366 .chain_id = ALC887_FIXUP_BASS_CHMAP,
2367 },
2368 [ALC887_FIXUP_BASS_CHMAP] = {
2369 .type = HDA_FIXUP_FUNC,
2370 .v.func = alc_fixup_bass_chmap,
Takashi Iwai1f0bbf02013-11-28 15:21:21 +01002371 },
Takashi Iwai7beb3a62017-04-10 18:05:52 +02002372 [ALC1220_FIXUP_GB_DUAL_CODECS] = {
2373 .type = HDA_FIXUP_FUNC,
2374 .v.func = alc1220_fixup_gb_dual_codecs,
2375 },
Peisen0202f5c2017-10-26 10:35:36 +08002376 [ALC1220_FIXUP_CLEVO_P950] = {
2377 .type = HDA_FIXUP_FUNC,
2378 .v.func = alc1220_fixup_clevo_p950,
2379 },
Richard Sailer80690a22019-04-02 15:52:04 +02002380 [ALC1220_FIXUP_CLEVO_PB51ED] = {
Jeremy Soller7f665b12019-02-13 10:56:19 -07002381 .type = HDA_FIXUP_FUNC,
Richard Sailer80690a22019-04-02 15:52:04 +02002382 .v.func = alc1220_fixup_clevo_pb51ed,
Jeremy Soller7f665b12019-02-13 10:56:19 -07002383 },
Richard Sailer80690a22019-04-02 15:52:04 +02002384 [ALC1220_FIXUP_CLEVO_PB51ED_PINS] = {
Jeremy Soller7f665b12019-02-13 10:56:19 -07002385 .type = HDA_FIXUP_PINS,
2386 .v.pins = (const struct hda_pintbl[]) {
2387 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
2388 {}
2389 },
2390 .chained = true,
Richard Sailer80690a22019-04-02 15:52:04 +02002391 .chain_id = ALC1220_FIXUP_CLEVO_PB51ED,
Jeremy Soller7f665b12019-02-13 10:56:19 -07002392 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02002393};
2394
2395static const struct snd_pci_quirk alc882_fixup_tbl[] = {
Takashi Iwai8812c4f2011-11-09 17:39:15 +01002396 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_FIXUP_ACER_EAPD),
2397 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
Takashi Iwaib5d724b2015-06-02 19:57:08 +02002398 SND_PCI_QUIRK(0x1025, 0x0107, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
Takashi Iwai8812c4f2011-11-09 17:39:15 +01002399 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_FIXUP_ACER_EAPD),
2400 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
2401 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_FIXUP_ACER_EAPD),
2402 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_FIXUP_ACER_EAPD),
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002403 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
2404 ALC882_FIXUP_ACER_ASPIRE_4930G),
2405 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
2406 ALC882_FIXUP_ACER_ASPIRE_4930G),
2407 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
2408 ALC882_FIXUP_ACER_ASPIRE_8930G),
2409 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
2410 ALC882_FIXUP_ACER_ASPIRE_8930G),
2411 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
2412 ALC882_FIXUP_ACER_ASPIRE_4930G),
2413 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
2414 ALC882_FIXUP_ACER_ASPIRE_4930G),
2415 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
2416 ALC882_FIXUP_ACER_ASPIRE_4930G),
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002417 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", ALC882_FIXUP_PB_M5210),
Takashi Iwaif5c53d82012-05-07 10:07:33 +02002418 SND_PCI_QUIRK(0x1025, 0x021e, "Acer Aspire 5739G",
2419 ALC882_FIXUP_ACER_ASPIRE_4930G),
Takashi Iwai02a237b2012-02-13 15:25:07 +01002420 SND_PCI_QUIRK(0x1025, 0x0259, "Acer Aspire 5935", ALC889_FIXUP_DAC_ROUTE),
Takashi Iwaife97da12012-04-12 08:00:19 +02002421 SND_PCI_QUIRK(0x1025, 0x026b, "Acer Aspire 8940G", ALC882_FIXUP_ACER_ASPIRE_8930G),
Takashi Iwaiac9b1cd2011-11-09 17:45:55 +01002422 SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", ALC882_FIXUP_ACER_ASPIRE_7736),
Takashi Iwai177943a32011-11-09 12:55:18 +01002423 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_FIXUP_EAPD),
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002424 SND_PCI_QUIRK(0x1043, 0x1873, "ASUS W90V", ALC882_FIXUP_ASUS_W90V),
Takashi Iwai68ef0562011-11-09 18:24:44 +01002425 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_FIXUP_ASUS_W2JC),
Takashi Iwai0e7cc2e2011-11-09 12:42:48 +01002426 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_FIXUP_EEE1601),
Takashi Iwai1f0bbf02013-11-28 15:21:21 +01002427 SND_PCI_QUIRK(0x1043, 0x84bc, "ASUS ET2700", ALC887_FIXUP_ASUS_BASS),
Takashi Iwai85bcf962016-12-06 16:20:36 +01002428 SND_PCI_QUIRK(0x1043, 0x8691, "ASUS ROG Ranger VIII", ALC882_FIXUP_GPIO3),
Takashi Iwaiac9b1cd2011-11-09 17:45:55 +01002429 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT),
Takashi Iwaie427c232012-07-29 10:04:08 +02002430 SND_PCI_QUIRK(0x104d, 0x905a, "Sony Vaio Z", ALC882_FIXUP_NO_PRIMARY_HP),
Sergei A. Trusov3f3c3712017-08-02 20:23:48 +10002431 SND_PCI_QUIRK(0x104d, 0x9060, "Sony Vaio VPCL14M1R", ALC882_FIXUP_NO_PRIMARY_HP),
Fernando Luis Vázquez Cao12e31a72013-02-12 16:47:44 +09002432 SND_PCI_QUIRK(0x104d, 0x9043, "Sony Vaio VGC-LN51JGB", ALC882_FIXUP_NO_PRIMARY_HP),
Takashi Iwaic44d9b12016-02-07 09:38:26 +01002433 SND_PCI_QUIRK(0x104d, 0x9044, "Sony VAIO AiO", ALC882_FIXUP_NO_PRIMARY_HP),
Takashi Iwai56710872011-11-14 17:42:11 +01002434
2435 /* All Apple entries are in codec SSIDs */
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002436 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC889_FIXUP_MBP_VREF),
2437 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC889_FIXUP_MBP_VREF),
2438 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF),
Takashi Iwaic20f31e2014-02-03 11:02:10 +01002439 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC889_FIXUP_MP11_VREF),
Takashi Iwai56710872011-11-14 17:42:11 +01002440 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_FIXUP_MACPRO_GPIO),
2441 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_FIXUP_MACPRO_GPIO),
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002442 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC889_FIXUP_MBP_VREF),
2443 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889_FIXUP_MBP_VREF),
Takashi Iwai56710872011-11-14 17:42:11 +01002444 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_FIXUP_EAPD),
Adrien Vergée7729a42014-01-24 14:56:14 -05002445 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC889_FIXUP_MBA11_VREF),
Takashi Iwai0756f092013-12-04 13:59:45 +01002446 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC889_FIXUP_MBA21_VREF),
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002447 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889_FIXUP_MBP_VREF),
2448 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF),
Takashi Iwai56710872011-11-14 17:42:11 +01002449 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_FIXUP_MACPRO_GPIO),
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002450 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC889_FIXUP_IMAC91_VREF),
2451 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC889_FIXUP_IMAC91_VREF),
2452 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC889_FIXUP_IMAC91_VREF),
Mario Kleiner9f660a12015-12-22 00:45:43 +01002453 SND_PCI_QUIRK(0x106b, 0x4200, "Mac Pro 4,1/5,1", ALC889_FIXUP_MP41_VREF),
Takashi Iwai05193632012-11-12 10:07:36 +01002454 SND_PCI_QUIRK(0x106b, 0x4300, "iMac 9,1", ALC889_FIXUP_IMAC91_VREF),
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002455 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC889_FIXUP_IMAC91_VREF),
2456 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC889_FIXUP_IMAC91_VREF),
Takashi Iwai649ccd02015-07-30 22:30:29 +02002457 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC889_FIXUP_MBA11_VREF),
Takashi Iwai56710872011-11-14 17:42:11 +01002458
Takashi Iwai7a6069b2011-11-09 15:22:01 +01002459 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC882_FIXUP_EAPD),
David Henningssonb2c53e22014-01-01 14:01:34 +01002460 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3/Z87X-UD3H", ALC889_FIXUP_FRONT_HP_NO_PRESENCE),
Takashi Iwai7beb3a62017-04-10 18:05:52 +02002461 SND_PCI_QUIRK(0x1458, 0xa0b8, "Gigabyte AZ370-Gaming", ALC1220_FIXUP_GB_DUAL_CODECS),
Christian Lachner0d45e862020-02-23 10:24:16 +01002462 SND_PCI_QUIRK(0x1458, 0xa0cd, "Gigabyte X570 Aorus Master", ALC1220_FIXUP_CLEVO_P950),
Christian Lachnerd9e8fe02020-05-18 07:38:44 +02002463 SND_PCI_QUIRK(0x1458, 0xa0ce, "Gigabyte X570 Aorus Xtreme", ALC1220_FIXUP_CLEVO_P950),
Takashi Iwaia655e2b2020-02-17 16:19:47 +01002464 SND_PCI_QUIRK(0x1462, 0x1228, "MSI-GP63", ALC1220_FIXUP_CLEVO_P950),
Takashi Iwai1d3aa4a2020-04-08 15:56:45 +02002465 SND_PCI_QUIRK(0x1462, 0x1275, "MSI-GL63", ALC1220_FIXUP_CLEVO_P950),
Takashi Iwai7dafba32020-02-12 09:10:47 +01002466 SND_PCI_QUIRK(0x1462, 0x1276, "MSI-GL73", ALC1220_FIXUP_CLEVO_P950),
Takashi Iwaicc5049a2020-02-18 09:09:15 +01002467 SND_PCI_QUIRK(0x1462, 0x1293, "MSI-GP65", ALC1220_FIXUP_CLEVO_P950),
Takashi Iwaid2c3b142017-06-01 09:35:30 +02002468 SND_PCI_QUIRK(0x1462, 0x7350, "MSI-7350", ALC889_FIXUP_CD),
Takashi Iwai63691582017-05-22 16:32:46 +02002469 SND_PCI_QUIRK(0x1462, 0xda57, "MSI Z270-Gaming", ALC1220_FIXUP_GB_DUAL_CODECS),
Takashi Iwaid2c3b142017-06-01 09:35:30 +02002470 SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3),
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002471 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX),
Peisen0202f5c2017-10-26 10:35:36 +08002472 SND_PCI_QUIRK(0x1558, 0x9501, "Clevo P950HR", ALC1220_FIXUP_CLEVO_P950),
Takashi Iwaif3d737b2018-07-17 17:08:32 +02002473 SND_PCI_QUIRK(0x1558, 0x95e1, "Clevo P95xER", ALC1220_FIXUP_CLEVO_P950),
Jeremy Soller2f0d5202018-05-07 09:28:45 -06002474 SND_PCI_QUIRK(0x1558, 0x95e2, "Clevo P950ER", ALC1220_FIXUP_CLEVO_P950),
Richard Sailer503d90b2019-06-19 13:33:11 +02002475 SND_PCI_QUIRK(0x1558, 0x96e1, "Clevo P960[ER][CDFN]-K", ALC1220_FIXUP_CLEVO_P950),
2476 SND_PCI_QUIRK(0x1558, 0x97e1, "Clevo P970[ER][CDFN]", ALC1220_FIXUP_CLEVO_P950),
2477 SND_PCI_QUIRK(0x1558, 0x65d1, "Clevo PB51[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
2478 SND_PCI_QUIRK(0x1558, 0x67d1, "Clevo PB71[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
PeiSen Hou259eb822020-05-19 08:50:12 +02002479 SND_PCI_QUIRK(0x1558, 0x50d3, "Clevo PC50[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
2480 SND_PCI_QUIRK(0x1558, 0x70d1, "Clevo PC70[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
2481 SND_PCI_QUIRK(0x1558, 0x7714, "Clevo X170", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
Takashi Iwai7a6069b2011-11-09 15:22:01 +01002482 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD),
2483 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD),
Takashi Iwaiac9b1cd2011-11-09 17:45:55 +01002484 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", ALC882_FIXUP_LENOVO_Y530),
Takashi Iwai68ef0562011-11-09 18:24:44 +01002485 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_FIXUP_COEF),
Takashi Iwai1d045db2011-07-07 18:23:21 +02002486 {}
2487};
2488
Takashi Iwai1727a772013-01-10 09:52:52 +01002489static const struct hda_model_fixup alc882_fixup_models[] = {
Takashi Iwai772c2912018-06-26 17:17:53 +02002490 {.id = ALC882_FIXUP_ABIT_AW9D_MAX, .name = "abit-aw9d"},
2491 {.id = ALC882_FIXUP_LENOVO_Y530, .name = "lenovo-y530"},
2492 {.id = ALC882_FIXUP_ACER_ASPIRE_7736, .name = "acer-aspire-7736"},
2493 {.id = ALC882_FIXUP_ASUS_W90V, .name = "asus-w90v"},
2494 {.id = ALC889_FIXUP_CD, .name = "cd"},
2495 {.id = ALC889_FIXUP_FRONT_HP_NO_PRESENCE, .name = "no-front-hp"},
2496 {.id = ALC889_FIXUP_VAIO_TT, .name = "vaio-tt"},
2497 {.id = ALC888_FIXUP_EEE1601, .name = "eee1601"},
2498 {.id = ALC882_FIXUP_EAPD, .name = "alc882-eapd"},
2499 {.id = ALC883_FIXUP_EAPD, .name = "alc883-eapd"},
2500 {.id = ALC882_FIXUP_GPIO1, .name = "gpio1"},
2501 {.id = ALC882_FIXUP_GPIO2, .name = "gpio2"},
2502 {.id = ALC882_FIXUP_GPIO3, .name = "gpio3"},
2503 {.id = ALC889_FIXUP_COEF, .name = "alc889-coef"},
2504 {.id = ALC882_FIXUP_ASUS_W2JC, .name = "asus-w2jc"},
Takashi Iwai912093b2012-04-11 14:03:41 +02002505 {.id = ALC882_FIXUP_ACER_ASPIRE_4930G, .name = "acer-aspire-4930g"},
2506 {.id = ALC882_FIXUP_ACER_ASPIRE_8930G, .name = "acer-aspire-8930g"},
2507 {.id = ALC883_FIXUP_ACER_EAPD, .name = "acer-aspire"},
Takashi Iwai772c2912018-06-26 17:17:53 +02002508 {.id = ALC885_FIXUP_MACPRO_GPIO, .name = "macpro-gpio"},
2509 {.id = ALC889_FIXUP_DAC_ROUTE, .name = "dac-route"},
2510 {.id = ALC889_FIXUP_MBP_VREF, .name = "mbp-vref"},
2511 {.id = ALC889_FIXUP_IMAC91_VREF, .name = "imac91-vref"},
2512 {.id = ALC889_FIXUP_MBA11_VREF, .name = "mba11-vref"},
2513 {.id = ALC889_FIXUP_MBA21_VREF, .name = "mba21-vref"},
2514 {.id = ALC889_FIXUP_MP11_VREF, .name = "mp11-vref"},
2515 {.id = ALC889_FIXUP_MP41_VREF, .name = "mp41-vref"},
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002516 {.id = ALC882_FIXUP_INV_DMIC, .name = "inv-dmic"},
Takashi Iwaie427c232012-07-29 10:04:08 +02002517 {.id = ALC882_FIXUP_NO_PRIMARY_HP, .name = "no-primary-hp"},
Takashi Iwai772c2912018-06-26 17:17:53 +02002518 {.id = ALC887_FIXUP_ASUS_BASS, .name = "asus-bass"},
Takashi Iwaiba90d6a2017-05-22 16:38:47 +02002519 {.id = ALC1220_FIXUP_GB_DUAL_CODECS, .name = "dual-codecs"},
Takashi Iwai772c2912018-06-26 17:17:53 +02002520 {.id = ALC1220_FIXUP_CLEVO_P950, .name = "clevo-p950"},
Takashi Iwai912093b2012-04-11 14:03:41 +02002521 {}
2522};
2523
Takashi Iwai1d045db2011-07-07 18:23:21 +02002524/*
2525 * BIOS auto configuration
2526 */
2527/* almost identical with ALC880 parser... */
2528static int alc882_parse_auto_config(struct hda_codec *codec)
2529{
Takashi Iwai1d045db2011-07-07 18:23:21 +02002530 static const hda_nid_t alc882_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002531 static const hda_nid_t alc882_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2532 return alc_parse_auto_config(codec, alc882_ignore, alc882_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002533}
2534
Takashi Iwai1d045db2011-07-07 18:23:21 +02002535/*
2536 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002537static int patch_alc882(struct hda_codec *codec)
2538{
2539 struct alc_spec *spec;
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002540 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002541
Takashi Iwai3de95172012-05-07 18:03:15 +02002542 err = alc_alloc_spec(codec, 0x0b);
2543 if (err < 0)
2544 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002545
Takashi Iwai3de95172012-05-07 18:03:15 +02002546 spec = codec->spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002547
Takashi Iwai7639a062015-03-03 10:07:24 +01002548 switch (codec->core.vendor_id) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002549 case 0x10ec0882:
2550 case 0x10ec0885:
Takashi Iwaiacf08082014-09-02 07:21:56 +02002551 case 0x10ec0900:
Kailang Yang6d9ffcf2020-01-03 16:24:06 +08002552 case 0x10ec0b00:
Kailang Yanga535ad52017-01-16 16:59:26 +08002553 case 0x10ec1220:
Takashi Iwai1d045db2011-07-07 18:23:21 +02002554 break;
2555 default:
2556 /* ALC883 and variants */
2557 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
2558 break;
2559 }
2560
Takashi Iwaic9af7532019-05-10 11:01:43 +02002561 alc_pre_init(codec);
2562
Takashi Iwai1727a772013-01-10 09:52:52 +01002563 snd_hda_pick_fixup(codec, alc882_fixup_models, alc882_fixup_tbl,
Takashi Iwai912093b2012-04-11 14:03:41 +02002564 alc882_fixups);
Takashi Iwai1727a772013-01-10 09:52:52 +01002565 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002566
2567 alc_auto_parse_customize_define(codec);
2568
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002569 if (has_cdefine_beep(codec))
2570 spec->gen.beep_nid = 0x01;
2571
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002572 /* automatic parse from the BIOS config */
2573 err = alc882_parse_auto_config(codec);
2574 if (err < 0)
2575 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002576
Takashi Iwaifea80fa2018-06-20 12:52:46 +02002577 if (!spec->gen.no_analog && spec->gen.beep_nid) {
2578 err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
2579 if (err < 0)
2580 goto error;
2581 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02002582
Takashi Iwai1727a772013-01-10 09:52:52 +01002583 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01002584
Takashi Iwai1d045db2011-07-07 18:23:21 +02002585 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02002586
2587 error:
2588 alc_free(codec);
2589 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002590}
2591
2592
2593/*
2594 * ALC262 support
2595 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002596static int alc262_parse_auto_config(struct hda_codec *codec)
2597{
Takashi Iwai1d045db2011-07-07 18:23:21 +02002598 static const hda_nid_t alc262_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002599 static const hda_nid_t alc262_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2600 return alc_parse_auto_config(codec, alc262_ignore, alc262_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002601}
2602
2603/*
2604 * Pin config fixes
2605 */
2606enum {
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002607 ALC262_FIXUP_FSC_H270,
Takashi Iwai7513e6d2013-01-18 15:41:34 +01002608 ALC262_FIXUP_FSC_S7110,
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002609 ALC262_FIXUP_HP_Z200,
2610 ALC262_FIXUP_TYAN,
Takashi Iwaic4701502011-11-07 14:20:07 +01002611 ALC262_FIXUP_LENOVO_3000,
Takashi Iwaib42590b2011-11-07 14:41:01 +01002612 ALC262_FIXUP_BENQ,
2613 ALC262_FIXUP_BENQ_T31,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002614 ALC262_FIXUP_INV_DMIC,
Mengdong Linb5c66112013-11-29 00:35:35 -05002615 ALC262_FIXUP_INTEL_BAYLEYBAY,
Takashi Iwai1d045db2011-07-07 18:23:21 +02002616};
2617
Takashi Iwai1727a772013-01-10 09:52:52 +01002618static const struct hda_fixup alc262_fixups[] = {
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002619 [ALC262_FIXUP_FSC_H270] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002620 .type = HDA_FIXUP_PINS,
2621 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002622 { 0x14, 0x99130110 }, /* speaker */
2623 { 0x15, 0x0221142f }, /* front HP */
2624 { 0x1b, 0x0121141f }, /* rear HP */
2625 { }
2626 }
2627 },
Takashi Iwai7513e6d2013-01-18 15:41:34 +01002628 [ALC262_FIXUP_FSC_S7110] = {
2629 .type = HDA_FIXUP_PINS,
2630 .v.pins = (const struct hda_pintbl[]) {
2631 { 0x15, 0x90170110 }, /* speaker */
2632 { }
2633 },
2634 .chained = true,
2635 .chain_id = ALC262_FIXUP_BENQ,
2636 },
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002637 [ALC262_FIXUP_HP_Z200] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002638 .type = HDA_FIXUP_PINS,
2639 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002640 { 0x16, 0x99130120 }, /* internal speaker */
2641 { }
2642 }
2643 },
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002644 [ALC262_FIXUP_TYAN] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002645 .type = HDA_FIXUP_PINS,
2646 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002647 { 0x14, 0x1993e1f0 }, /* int AUX */
2648 { }
2649 }
2650 },
Takashi Iwaic4701502011-11-07 14:20:07 +01002651 [ALC262_FIXUP_LENOVO_3000] = {
Takashi Iwaifd108212013-01-10 10:18:14 +01002652 .type = HDA_FIXUP_PINCTLS,
2653 .v.pins = (const struct hda_pintbl[]) {
2654 { 0x19, PIN_VREF50 },
Takashi Iwaib42590b2011-11-07 14:41:01 +01002655 {}
2656 },
2657 .chained = true,
2658 .chain_id = ALC262_FIXUP_BENQ,
2659 },
2660 [ALC262_FIXUP_BENQ] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002661 .type = HDA_FIXUP_VERBS,
Takashi Iwaib42590b2011-11-07 14:41:01 +01002662 .v.verbs = (const struct hda_verb[]) {
Takashi Iwaic4701502011-11-07 14:20:07 +01002663 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2664 { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
2665 {}
2666 }
2667 },
Takashi Iwaib42590b2011-11-07 14:41:01 +01002668 [ALC262_FIXUP_BENQ_T31] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002669 .type = HDA_FIXUP_VERBS,
Takashi Iwaib42590b2011-11-07 14:41:01 +01002670 .v.verbs = (const struct hda_verb[]) {
2671 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2672 { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
2673 {}
2674 }
2675 },
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002676 [ALC262_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002677 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02002678 .v.func = alc_fixup_inv_dmic,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002679 },
Mengdong Linb5c66112013-11-29 00:35:35 -05002680 [ALC262_FIXUP_INTEL_BAYLEYBAY] = {
2681 .type = HDA_FIXUP_FUNC,
2682 .v.func = alc_fixup_no_depop_delay,
2683 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02002684};
2685
2686static const struct snd_pci_quirk alc262_fixup_tbl[] = {
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002687 SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", ALC262_FIXUP_HP_Z200),
Takashi Iwai7513e6d2013-01-18 15:41:34 +01002688 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu Lifebook S7110", ALC262_FIXUP_FSC_S7110),
Takashi Iwai3dcd3be2011-11-07 14:59:40 +01002689 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FIXUP_BENQ),
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002690 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_FIXUP_TYAN),
Takashi Iwai275ec0c2018-06-22 12:17:45 +02002691 SND_PCI_QUIRK(0x1734, 0x1141, "FSC ESPRIMO U9210", ALC262_FIXUP_FSC_H270),
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002692 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", ALC262_FIXUP_FSC_H270),
Takashi Iwaic4701502011-11-07 14:20:07 +01002693 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000", ALC262_FIXUP_LENOVO_3000),
Takashi Iwaib42590b2011-11-07 14:41:01 +01002694 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_FIXUP_BENQ),
2695 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_FIXUP_BENQ_T31),
Mengdong Linb5c66112013-11-29 00:35:35 -05002696 SND_PCI_QUIRK(0x8086, 0x7270, "BayleyBay", ALC262_FIXUP_INTEL_BAYLEYBAY),
Takashi Iwai1d045db2011-07-07 18:23:21 +02002697 {}
2698};
2699
Takashi Iwai1727a772013-01-10 09:52:52 +01002700static const struct hda_model_fixup alc262_fixup_models[] = {
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002701 {.id = ALC262_FIXUP_INV_DMIC, .name = "inv-dmic"},
Takashi Iwaie43c44d2018-06-26 17:02:08 +02002702 {.id = ALC262_FIXUP_FSC_H270, .name = "fsc-h270"},
2703 {.id = ALC262_FIXUP_FSC_S7110, .name = "fsc-s7110"},
2704 {.id = ALC262_FIXUP_HP_Z200, .name = "hp-z200"},
2705 {.id = ALC262_FIXUP_TYAN, .name = "tyan"},
2706 {.id = ALC262_FIXUP_LENOVO_3000, .name = "lenovo-3000"},
2707 {.id = ALC262_FIXUP_BENQ, .name = "benq"},
2708 {.id = ALC262_FIXUP_BENQ_T31, .name = "benq-t31"},
2709 {.id = ALC262_FIXUP_INTEL_BAYLEYBAY, .name = "bayleybay"},
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002710 {}
2711};
Takashi Iwai1d045db2011-07-07 18:23:21 +02002712
Takashi Iwai1d045db2011-07-07 18:23:21 +02002713/*
2714 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002715static int patch_alc262(struct hda_codec *codec)
2716{
2717 struct alc_spec *spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002718 int err;
2719
Takashi Iwai3de95172012-05-07 18:03:15 +02002720 err = alc_alloc_spec(codec, 0x0b);
2721 if (err < 0)
2722 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002723
Takashi Iwai3de95172012-05-07 18:03:15 +02002724 spec = codec->spec;
Takashi Iwai08c189f2012-12-19 15:22:24 +01002725 spec->gen.shared_mic_vref_pin = 0x18;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002726
Takashi Iwai225068a2015-05-29 10:42:14 +02002727 spec->shutup = alc_eapd_shutup;
2728
Takashi Iwai1d045db2011-07-07 18:23:21 +02002729#if 0
2730 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
2731 * under-run
2732 */
Takashi Iwai98b24882014-08-18 13:47:50 +02002733 alc_update_coefex_idx(codec, 0x1a, 7, 0, 0x80);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002734#endif
Takashi Iwai1d045db2011-07-07 18:23:21 +02002735 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
2736
Takashi Iwaic9af7532019-05-10 11:01:43 +02002737 alc_pre_init(codec);
2738
Takashi Iwai1727a772013-01-10 09:52:52 +01002739 snd_hda_pick_fixup(codec, alc262_fixup_models, alc262_fixup_tbl,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002740 alc262_fixups);
Takashi Iwai1727a772013-01-10 09:52:52 +01002741 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002742
Takashi Iwaiaf741c12012-05-07 18:09:48 +02002743 alc_auto_parse_customize_define(codec);
2744
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002745 if (has_cdefine_beep(codec))
2746 spec->gen.beep_nid = 0x01;
2747
Takashi Iwai42399f72011-11-07 17:18:44 +01002748 /* automatic parse from the BIOS config */
2749 err = alc262_parse_auto_config(codec);
2750 if (err < 0)
2751 goto error;
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002752
Takashi Iwaifea80fa2018-06-20 12:52:46 +02002753 if (!spec->gen.no_analog && spec->gen.beep_nid) {
2754 err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
2755 if (err < 0)
2756 goto error;
2757 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02002758
Takashi Iwai1727a772013-01-10 09:52:52 +01002759 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01002760
Takashi Iwai1d045db2011-07-07 18:23:21 +02002761 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02002762
2763 error:
2764 alc_free(codec);
2765 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002766}
2767
2768/*
2769 * ALC268
2770 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002771/* bind Beep switches of both NID 0x0f and 0x10 */
Takashi Iwaia7177772017-05-10 12:04:08 +02002772static int alc268_beep_switch_put(struct snd_kcontrol *kcontrol,
2773 struct snd_ctl_elem_value *ucontrol)
2774{
2775 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2776 unsigned long pval;
2777 int err;
2778
2779 mutex_lock(&codec->control_mutex);
2780 pval = kcontrol->private_value;
2781 kcontrol->private_value = (pval & ~0xff) | 0x0f;
2782 err = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
2783 if (err >= 0) {
2784 kcontrol->private_value = (pval & ~0xff) | 0x10;
2785 err = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
2786 }
2787 kcontrol->private_value = pval;
2788 mutex_unlock(&codec->control_mutex);
2789 return err;
2790}
Takashi Iwai1d045db2011-07-07 18:23:21 +02002791
2792static const struct snd_kcontrol_new alc268_beep_mixer[] = {
2793 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
Takashi Iwaia7177772017-05-10 12:04:08 +02002794 {
2795 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2796 .name = "Beep Playback Switch",
2797 .subdevice = HDA_SUBDEV_AMP_FLAG,
2798 .info = snd_hda_mixer_amp_switch_info,
2799 .get = snd_hda_mixer_amp_switch_get,
2800 .put = alc268_beep_switch_put,
2801 .private_value = HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT)
2802 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02002803};
2804
2805/* set PCBEEP vol = 0, mute connections */
2806static const struct hda_verb alc268_beep_init_verbs[] = {
2807 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2808 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2809 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2810 { }
2811};
2812
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002813enum {
2814 ALC268_FIXUP_INV_DMIC,
Takashi Iwaicb766402012-10-20 10:55:21 +02002815 ALC268_FIXUP_HP_EAPD,
Takashi Iwai24eff322013-11-04 18:21:08 +01002816 ALC268_FIXUP_SPDIF,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002817};
2818
Takashi Iwai1727a772013-01-10 09:52:52 +01002819static const struct hda_fixup alc268_fixups[] = {
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002820 [ALC268_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002821 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02002822 .v.func = alc_fixup_inv_dmic,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002823 },
Takashi Iwaicb766402012-10-20 10:55:21 +02002824 [ALC268_FIXUP_HP_EAPD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002825 .type = HDA_FIXUP_VERBS,
Takashi Iwaicb766402012-10-20 10:55:21 +02002826 .v.verbs = (const struct hda_verb[]) {
2827 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 0},
2828 {}
2829 }
2830 },
Takashi Iwai24eff322013-11-04 18:21:08 +01002831 [ALC268_FIXUP_SPDIF] = {
2832 .type = HDA_FIXUP_PINS,
2833 .v.pins = (const struct hda_pintbl[]) {
2834 { 0x1e, 0x014b1180 }, /* enable SPDIF out */
2835 {}
2836 }
2837 },
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002838};
2839
Takashi Iwai1727a772013-01-10 09:52:52 +01002840static const struct hda_model_fixup alc268_fixup_models[] = {
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002841 {.id = ALC268_FIXUP_INV_DMIC, .name = "inv-dmic"},
Takashi Iwaicb766402012-10-20 10:55:21 +02002842 {.id = ALC268_FIXUP_HP_EAPD, .name = "hp-eapd"},
Takashi Iwai03bf11c2018-06-26 16:56:41 +02002843 {.id = ALC268_FIXUP_SPDIF, .name = "spdif"},
Takashi Iwaicb766402012-10-20 10:55:21 +02002844 {}
2845};
2846
2847static const struct snd_pci_quirk alc268_fixup_tbl[] = {
Takashi Iwai24eff322013-11-04 18:21:08 +01002848 SND_PCI_QUIRK(0x1025, 0x0139, "Acer TravelMate 6293", ALC268_FIXUP_SPDIF),
David Henningssonfcd8f3b2013-01-28 05:45:47 +01002849 SND_PCI_QUIRK(0x1025, 0x015b, "Acer AOA 150 (ZG5)", ALC268_FIXUP_INV_DMIC),
Takashi Iwaicb766402012-10-20 10:55:21 +02002850 /* below is codec SSID since multiple Toshiba laptops have the
2851 * same PCI SSID 1179:ff00
2852 */
2853 SND_PCI_QUIRK(0x1179, 0xff06, "Toshiba P200", ALC268_FIXUP_HP_EAPD),
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002854 {}
2855};
2856
Takashi Iwai1d045db2011-07-07 18:23:21 +02002857/*
2858 * BIOS auto configuration
2859 */
2860static int alc268_parse_auto_config(struct hda_codec *codec)
2861{
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002862 static const hda_nid_t alc268_ssids[] = { 0x15, 0x1b, 0x14, 0 };
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002863 return alc_parse_auto_config(codec, NULL, alc268_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002864}
2865
Takashi Iwai1d045db2011-07-07 18:23:21 +02002866/*
2867 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002868static int patch_alc268(struct hda_codec *codec)
2869{
2870 struct alc_spec *spec;
Takashi Iwaia5cb4632018-06-20 12:50:11 +02002871 int i, err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002872
Takashi Iwai1d045db2011-07-07 18:23:21 +02002873 /* ALC268 has no aa-loopback mixer */
Takashi Iwai3de95172012-05-07 18:03:15 +02002874 err = alc_alloc_spec(codec, 0);
2875 if (err < 0)
2876 return err;
2877
2878 spec = codec->spec;
Takashi Iwai2722b532019-08-22 09:55:37 +02002879 if (has_cdefine_beep(codec))
2880 spec->gen.beep_nid = 0x01;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002881
Takashi Iwai225068a2015-05-29 10:42:14 +02002882 spec->shutup = alc_eapd_shutup;
2883
Takashi Iwaic9af7532019-05-10 11:01:43 +02002884 alc_pre_init(codec);
2885
Takashi Iwai1727a772013-01-10 09:52:52 +01002886 snd_hda_pick_fixup(codec, alc268_fixup_models, alc268_fixup_tbl, alc268_fixups);
2887 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002888
Takashi Iwai6ebb8052011-08-16 15:15:40 +02002889 /* automatic parse from the BIOS config */
2890 err = alc268_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02002891 if (err < 0)
2892 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002893
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002894 if (err > 0 && !spec->gen.no_analog &&
2895 spec->gen.autocfg.speaker_pins[0] != 0x1d) {
Takashi Iwaia5cb4632018-06-20 12:50:11 +02002896 for (i = 0; i < ARRAY_SIZE(alc268_beep_mixer); i++) {
2897 if (!snd_hda_gen_add_kctl(&spec->gen, NULL,
2898 &alc268_beep_mixer[i])) {
2899 err = -ENOMEM;
2900 goto error;
2901 }
2902 }
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002903 snd_hda_add_verbs(codec, alc268_beep_init_verbs);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002904 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
2905 /* override the amp caps for beep generator */
2906 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
2907 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
2908 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
2909 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
2910 (0 << AC_AMPCAP_MUTE_SHIFT));
2911 }
2912
Takashi Iwai1727a772013-01-10 09:52:52 +01002913 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002914
Takashi Iwai1d045db2011-07-07 18:23:21 +02002915 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02002916
2917 error:
2918 alc_free(codec);
2919 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002920}
2921
2922/*
2923 * ALC269
2924 */
Takashi Iwai08c189f2012-12-19 15:22:24 +01002925
Takashi Iwai1d045db2011-07-07 18:23:21 +02002926static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002927 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002928};
2929
2930static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002931 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002932};
2933
Takashi Iwai1d045db2011-07-07 18:23:21 +02002934/* different alc269-variants */
2935enum {
2936 ALC269_TYPE_ALC269VA,
2937 ALC269_TYPE_ALC269VB,
2938 ALC269_TYPE_ALC269VC,
Kailang Yangadcc70b2012-05-25 08:08:38 +02002939 ALC269_TYPE_ALC269VD,
Kailang Yang065380f2013-01-10 10:25:48 +01002940 ALC269_TYPE_ALC280,
2941 ALC269_TYPE_ALC282,
Kailang Yang2af02be2013-08-22 10:03:50 +02002942 ALC269_TYPE_ALC283,
Kailang Yang065380f2013-01-10 10:25:48 +01002943 ALC269_TYPE_ALC284,
Kailang Yang4731d5d2017-06-30 15:22:57 +08002944 ALC269_TYPE_ALC293,
Kailang Yang7fc7d042013-04-25 11:04:43 +02002945 ALC269_TYPE_ALC286,
Kailang Yang506b62c2014-12-18 17:07:44 +08002946 ALC269_TYPE_ALC298,
Kailang Yang1d04c9d2013-10-24 11:35:18 +02002947 ALC269_TYPE_ALC255,
Kailang Yang4344aec2014-12-17 17:39:05 +08002948 ALC269_TYPE_ALC256,
Kailang Yangf429e7e2017-12-05 15:38:24 +08002949 ALC269_TYPE_ALC257,
Kailang Yang0a6f0602017-06-30 16:00:48 +08002950 ALC269_TYPE_ALC215,
Kailang Yang42314302016-02-03 15:03:50 +08002951 ALC269_TYPE_ALC225,
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08002952 ALC269_TYPE_ALC294,
Kailang Yang1078bef2018-11-08 16:36:15 +08002953 ALC269_TYPE_ALC300,
Kailang Yangf0778872019-10-24 15:13:32 +08002954 ALC269_TYPE_ALC623,
Kailang Yang6fbae352016-05-30 16:44:20 +08002955 ALC269_TYPE_ALC700,
Takashi Iwai1d045db2011-07-07 18:23:21 +02002956};
2957
2958/*
2959 * BIOS auto configuration
2960 */
2961static int alc269_parse_auto_config(struct hda_codec *codec)
2962{
Takashi Iwai1d045db2011-07-07 18:23:21 +02002963 static const hda_nid_t alc269_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002964 static const hda_nid_t alc269_ssids[] = { 0, 0x1b, 0x14, 0x21 };
2965 static const hda_nid_t alc269va_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2966 struct alc_spec *spec = codec->spec;
Kailang Yangadcc70b2012-05-25 08:08:38 +02002967 const hda_nid_t *ssids;
2968
2969 switch (spec->codec_variant) {
2970 case ALC269_TYPE_ALC269VA:
2971 case ALC269_TYPE_ALC269VC:
Kailang Yang065380f2013-01-10 10:25:48 +01002972 case ALC269_TYPE_ALC280:
2973 case ALC269_TYPE_ALC284:
Kailang Yang4731d5d2017-06-30 15:22:57 +08002974 case ALC269_TYPE_ALC293:
Kailang Yangadcc70b2012-05-25 08:08:38 +02002975 ssids = alc269va_ssids;
2976 break;
2977 case ALC269_TYPE_ALC269VB:
2978 case ALC269_TYPE_ALC269VD:
Kailang Yang065380f2013-01-10 10:25:48 +01002979 case ALC269_TYPE_ALC282:
Kailang Yang2af02be2013-08-22 10:03:50 +02002980 case ALC269_TYPE_ALC283:
Kailang Yang7fc7d042013-04-25 11:04:43 +02002981 case ALC269_TYPE_ALC286:
Kailang Yang506b62c2014-12-18 17:07:44 +08002982 case ALC269_TYPE_ALC298:
Kailang Yang1d04c9d2013-10-24 11:35:18 +02002983 case ALC269_TYPE_ALC255:
Kailang Yang4344aec2014-12-17 17:39:05 +08002984 case ALC269_TYPE_ALC256:
Kailang Yangf429e7e2017-12-05 15:38:24 +08002985 case ALC269_TYPE_ALC257:
Kailang Yang0a6f0602017-06-30 16:00:48 +08002986 case ALC269_TYPE_ALC215:
Kailang Yang42314302016-02-03 15:03:50 +08002987 case ALC269_TYPE_ALC225:
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08002988 case ALC269_TYPE_ALC294:
Kailang Yang1078bef2018-11-08 16:36:15 +08002989 case ALC269_TYPE_ALC300:
Kailang Yangf0778872019-10-24 15:13:32 +08002990 case ALC269_TYPE_ALC623:
Kailang Yang6fbae352016-05-30 16:44:20 +08002991 case ALC269_TYPE_ALC700:
Kailang Yangadcc70b2012-05-25 08:08:38 +02002992 ssids = alc269_ssids;
2993 break;
2994 default:
2995 ssids = alc269_ssids;
2996 break;
2997 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02002998
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002999 return alc_parse_auto_config(codec, alc269_ignore, ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02003000}
3001
Hui Wang476c02e2020-03-29 16:20:18 +08003002static const struct hda_jack_keymap alc_headset_btn_keymap[] = {
3003 { SND_JACK_BTN_0, KEY_PLAYPAUSE },
3004 { SND_JACK_BTN_1, KEY_VOICECOMMAND },
3005 { SND_JACK_BTN_2, KEY_VOLUMEUP },
3006 { SND_JACK_BTN_3, KEY_VOLUMEDOWN },
3007 {}
3008};
3009
3010static void alc_headset_btn_callback(struct hda_codec *codec,
3011 struct hda_jack_callback *jack)
3012{
3013 int report = 0;
3014
3015 if (jack->unsol_res & (7 << 13))
3016 report |= SND_JACK_BTN_0;
3017
3018 if (jack->unsol_res & (1 << 16 | 3 << 8))
3019 report |= SND_JACK_BTN_1;
3020
3021 /* Volume up key */
3022 if (jack->unsol_res & (7 << 23))
3023 report |= SND_JACK_BTN_2;
3024
3025 /* Volume down key */
3026 if (jack->unsol_res & (7 << 10))
3027 report |= SND_JACK_BTN_3;
3028
3029 jack->jack->button_state = report;
3030}
3031
3032static void alc_disable_headset_jack_key(struct hda_codec *codec)
3033{
3034 struct alc_spec *spec = codec->spec;
3035
3036 if (!spec->has_hs_key)
3037 return;
3038
3039 switch (codec->core.vendor_id) {
3040 case 0x10ec0215:
3041 case 0x10ec0225:
3042 case 0x10ec0285:
3043 case 0x10ec0295:
3044 case 0x10ec0289:
3045 case 0x10ec0299:
3046 alc_write_coef_idx(codec, 0x48, 0x0);
3047 alc_update_coef_idx(codec, 0x49, 0x0045, 0x0);
3048 alc_update_coef_idx(codec, 0x44, 0x0045 << 8, 0x0);
3049 break;
3050 case 0x10ec0236:
3051 case 0x10ec0256:
3052 alc_write_coef_idx(codec, 0x48, 0x0);
3053 alc_update_coef_idx(codec, 0x49, 0x0045, 0x0);
3054 break;
3055 }
3056}
3057
3058static void alc_enable_headset_jack_key(struct hda_codec *codec)
3059{
3060 struct alc_spec *spec = codec->spec;
3061
3062 if (!spec->has_hs_key)
3063 return;
3064
3065 switch (codec->core.vendor_id) {
3066 case 0x10ec0215:
3067 case 0x10ec0225:
3068 case 0x10ec0285:
3069 case 0x10ec0295:
3070 case 0x10ec0289:
3071 case 0x10ec0299:
3072 alc_write_coef_idx(codec, 0x48, 0xd011);
3073 alc_update_coef_idx(codec, 0x49, 0x007f, 0x0045);
3074 alc_update_coef_idx(codec, 0x44, 0x007f << 8, 0x0045 << 8);
3075 break;
3076 case 0x10ec0236:
3077 case 0x10ec0256:
3078 alc_write_coef_idx(codec, 0x48, 0xd011);
3079 alc_update_coef_idx(codec, 0x49, 0x007f, 0x0045);
3080 break;
3081 }
3082}
3083
3084static void alc_fixup_headset_jack(struct hda_codec *codec,
3085 const struct hda_fixup *fix, int action)
3086{
3087 struct alc_spec *spec = codec->spec;
3088
3089 switch (action) {
3090 case HDA_FIXUP_ACT_PRE_PROBE:
3091 spec->has_hs_key = 1;
3092 snd_hda_jack_detect_enable_callback(codec, 0x55,
3093 alc_headset_btn_callback);
3094 snd_hda_jack_add_kctl(codec, 0x55, "Headset Jack", false,
3095 SND_JACK_HEADSET, alc_headset_btn_keymap);
3096 break;
3097 case HDA_FIXUP_ACT_INIT:
3098 alc_enable_headset_jack_key(codec);
3099 break;
3100 }
3101}
3102
Kailang Yang1387e2d2012-11-08 10:23:18 +01003103static void alc269vb_toggle_power_output(struct hda_codec *codec, int power_up)
Takashi Iwai1d045db2011-07-07 18:23:21 +02003104{
Takashi Iwai98b24882014-08-18 13:47:50 +02003105 alc_update_coef_idx(codec, 0x04, 1 << 11, power_up ? (1 << 11) : 0);
Takashi Iwai1d045db2011-07-07 18:23:21 +02003106}
3107
3108static void alc269_shutup(struct hda_codec *codec)
3109{
Kailang Yangadcc70b2012-05-25 08:08:38 +02003110 struct alc_spec *spec = codec->spec;
3111
Kailang Yang1387e2d2012-11-08 10:23:18 +01003112 if (spec->codec_variant == ALC269_TYPE_ALC269VB)
3113 alc269vb_toggle_power_output(codec, 0);
3114 if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
3115 (alc_get_coef0(codec) & 0x00ff) == 0x018) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02003116 msleep(150);
3117 }
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003118 alc_shutup_pins(codec);
Takashi Iwai1d045db2011-07-07 18:23:21 +02003119}
3120
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01003121static const struct coef_fw alc282_coefs[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02003122 WRITE_COEF(0x03, 0x0002), /* Power Down Control */
Kailang Yang32fa7e42014-10-24 16:26:01 +08003123 UPDATE_COEF(0x05, 0xff3f, 0x0700), /* FIFO and filter clock */
Takashi Iwai54db6c32014-08-18 15:11:19 +02003124 WRITE_COEF(0x07, 0x0200), /* DMIC control */
3125 UPDATE_COEF(0x06, 0x00f0, 0), /* Analog clock */
3126 UPDATE_COEF(0x08, 0xfffc, 0x0c2c), /* JD */
3127 WRITE_COEF(0x0a, 0xcccc), /* JD offset1 */
3128 WRITE_COEF(0x0b, 0xcccc), /* JD offset2 */
3129 WRITE_COEF(0x0e, 0x6e00), /* LDO1/2/3, DAC/ADC */
3130 UPDATE_COEF(0x0f, 0xf800, 0x1000), /* JD */
3131 UPDATE_COEF(0x10, 0xfc00, 0x0c00), /* Capless */
3132 WRITE_COEF(0x6f, 0x0), /* Class D test 4 */
3133 UPDATE_COEF(0x0c, 0xfe00, 0), /* IO power down directly */
3134 WRITE_COEF(0x34, 0xa0c0), /* ANC */
3135 UPDATE_COEF(0x16, 0x0008, 0), /* AGC MUX */
3136 UPDATE_COEF(0x1d, 0x00e0, 0), /* DAC simple content protection */
3137 UPDATE_COEF(0x1f, 0x00e0, 0), /* ADC simple content protection */
3138 WRITE_COEF(0x21, 0x8804), /* DAC ADC Zero Detection */
3139 WRITE_COEF(0x63, 0x2902), /* PLL */
3140 WRITE_COEF(0x68, 0xa080), /* capless control 2 */
3141 WRITE_COEF(0x69, 0x3400), /* capless control 3 */
3142 WRITE_COEF(0x6a, 0x2f3e), /* capless control 4 */
3143 WRITE_COEF(0x6b, 0x0), /* capless control 5 */
3144 UPDATE_COEF(0x6d, 0x0fff, 0x0900), /* class D test 2 */
3145 WRITE_COEF(0x6e, 0x110a), /* class D test 3 */
3146 UPDATE_COEF(0x70, 0x00f8, 0x00d8), /* class D test 5 */
3147 WRITE_COEF(0x71, 0x0014), /* class D test 6 */
3148 WRITE_COEF(0x72, 0xc2ba), /* classD OCP */
3149 UPDATE_COEF(0x77, 0x0f80, 0), /* classD pure DC test */
3150 WRITE_COEF(0x6c, 0xfc06), /* Class D amp control */
3151 {}
3152};
3153
Kailang Yangcb149cb2014-03-18 16:45:32 +08003154static void alc282_restore_default_value(struct hda_codec *codec)
3155{
Takashi Iwai54db6c32014-08-18 15:11:19 +02003156 alc_process_coef_fw(codec, alc282_coefs);
Kailang Yangcb149cb2014-03-18 16:45:32 +08003157}
3158
Kailang Yang7b5c7a02014-03-18 16:15:54 +08003159static void alc282_init(struct hda_codec *codec)
3160{
3161 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003162 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang7b5c7a02014-03-18 16:15:54 +08003163 bool hp_pin_sense;
3164 int coef78;
3165
Kailang Yangcb149cb2014-03-18 16:45:32 +08003166 alc282_restore_default_value(codec);
3167
Kailang Yang7b5c7a02014-03-18 16:15:54 +08003168 if (!hp_pin)
3169 return;
3170 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3171 coef78 = alc_read_coef_idx(codec, 0x78);
3172
3173 /* Index 0x78 Direct Drive HP AMP LPM Control 1 */
3174 /* Headphone capless set to high power mode */
3175 alc_write_coef_idx(codec, 0x78, 0x9004);
3176
3177 if (hp_pin_sense)
3178 msleep(2);
3179
3180 snd_hda_codec_write(codec, hp_pin, 0,
3181 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3182
3183 if (hp_pin_sense)
3184 msleep(85);
3185
3186 snd_hda_codec_write(codec, hp_pin, 0,
3187 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3188
3189 if (hp_pin_sense)
3190 msleep(100);
3191
3192 /* Headphone capless set to normal mode */
3193 alc_write_coef_idx(codec, 0x78, coef78);
3194}
3195
3196static void alc282_shutup(struct hda_codec *codec)
3197{
3198 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003199 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang7b5c7a02014-03-18 16:15:54 +08003200 bool hp_pin_sense;
3201 int coef78;
3202
3203 if (!hp_pin) {
3204 alc269_shutup(codec);
3205 return;
3206 }
3207
3208 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3209 coef78 = alc_read_coef_idx(codec, 0x78);
3210 alc_write_coef_idx(codec, 0x78, 0x9004);
3211
3212 if (hp_pin_sense)
3213 msleep(2);
3214
3215 snd_hda_codec_write(codec, hp_pin, 0,
3216 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3217
3218 if (hp_pin_sense)
3219 msleep(85);
3220
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003221 if (!spec->no_shutup_pins)
3222 snd_hda_codec_write(codec, hp_pin, 0,
3223 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
Kailang Yang7b5c7a02014-03-18 16:15:54 +08003224
3225 if (hp_pin_sense)
3226 msleep(100);
3227
3228 alc_auto_setup_eapd(codec, false);
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003229 alc_shutup_pins(codec);
Kailang Yang7b5c7a02014-03-18 16:15:54 +08003230 alc_write_coef_idx(codec, 0x78, coef78);
3231}
3232
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01003233static const struct coef_fw alc283_coefs[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02003234 WRITE_COEF(0x03, 0x0002), /* Power Down Control */
Kailang Yang56779862014-10-24 16:17:51 +08003235 UPDATE_COEF(0x05, 0xff3f, 0x0700), /* FIFO and filter clock */
Takashi Iwai54db6c32014-08-18 15:11:19 +02003236 WRITE_COEF(0x07, 0x0200), /* DMIC control */
3237 UPDATE_COEF(0x06, 0x00f0, 0), /* Analog clock */
3238 UPDATE_COEF(0x08, 0xfffc, 0x0c2c), /* JD */
3239 WRITE_COEF(0x0a, 0xcccc), /* JD offset1 */
3240 WRITE_COEF(0x0b, 0xcccc), /* JD offset2 */
3241 WRITE_COEF(0x0e, 0x6fc0), /* LDO1/2/3, DAC/ADC */
3242 UPDATE_COEF(0x0f, 0xf800, 0x1000), /* JD */
3243 UPDATE_COEF(0x10, 0xfc00, 0x0c00), /* Capless */
3244 WRITE_COEF(0x3a, 0x0), /* Class D test 4 */
3245 UPDATE_COEF(0x0c, 0xfe00, 0x0), /* IO power down directly */
3246 WRITE_COEF(0x22, 0xa0c0), /* ANC */
3247 UPDATE_COEFEX(0x53, 0x01, 0x000f, 0x0008), /* AGC MUX */
3248 UPDATE_COEF(0x1d, 0x00e0, 0), /* DAC simple content protection */
3249 UPDATE_COEF(0x1f, 0x00e0, 0), /* ADC simple content protection */
3250 WRITE_COEF(0x21, 0x8804), /* DAC ADC Zero Detection */
3251 WRITE_COEF(0x2e, 0x2902), /* PLL */
3252 WRITE_COEF(0x33, 0xa080), /* capless control 2 */
3253 WRITE_COEF(0x34, 0x3400), /* capless control 3 */
3254 WRITE_COEF(0x35, 0x2f3e), /* capless control 4 */
3255 WRITE_COEF(0x36, 0x0), /* capless control 5 */
3256 UPDATE_COEF(0x38, 0x0fff, 0x0900), /* class D test 2 */
3257 WRITE_COEF(0x39, 0x110a), /* class D test 3 */
3258 UPDATE_COEF(0x3b, 0x00f8, 0x00d8), /* class D test 5 */
3259 WRITE_COEF(0x3c, 0x0014), /* class D test 6 */
3260 WRITE_COEF(0x3d, 0xc2ba), /* classD OCP */
3261 UPDATE_COEF(0x42, 0x0f80, 0x0), /* classD pure DC test */
3262 WRITE_COEF(0x49, 0x0), /* test mode */
3263 UPDATE_COEF(0x40, 0xf800, 0x9800), /* Class D DC enable */
3264 UPDATE_COEF(0x42, 0xf000, 0x2000), /* DC offset */
3265 WRITE_COEF(0x37, 0xfc06), /* Class D amp control */
Kailang Yang56779862014-10-24 16:17:51 +08003266 UPDATE_COEF(0x1b, 0x8000, 0), /* HP JD control */
Takashi Iwai54db6c32014-08-18 15:11:19 +02003267 {}
3268};
3269
Kailang Yang6bd55b02014-03-17 13:51:27 +08003270static void alc283_restore_default_value(struct hda_codec *codec)
3271{
Takashi Iwai54db6c32014-08-18 15:11:19 +02003272 alc_process_coef_fw(codec, alc283_coefs);
Kailang Yang6bd55b02014-03-17 13:51:27 +08003273}
3274
Kailang Yang2af02be2013-08-22 10:03:50 +02003275static void alc283_init(struct hda_codec *codec)
3276{
3277 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003278 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang2af02be2013-08-22 10:03:50 +02003279 bool hp_pin_sense;
Kailang Yang2af02be2013-08-22 10:03:50 +02003280
Kailang Yang6bd55b02014-03-17 13:51:27 +08003281 alc283_restore_default_value(codec);
3282
Kailang Yang2af02be2013-08-22 10:03:50 +02003283 if (!hp_pin)
3284 return;
Kailang Yanga59d7192015-04-08 16:34:00 +08003285
3286 msleep(30);
Kailang Yang2af02be2013-08-22 10:03:50 +02003287 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3288
3289 /* Index 0x43 Direct Drive HP AMP LPM Control 1 */
3290 /* Headphone capless set to high power mode */
3291 alc_write_coef_idx(codec, 0x43, 0x9004);
3292
3293 snd_hda_codec_write(codec, hp_pin, 0,
3294 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3295
3296 if (hp_pin_sense)
3297 msleep(85);
3298
3299 snd_hda_codec_write(codec, hp_pin, 0,
3300 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3301
3302 if (hp_pin_sense)
3303 msleep(85);
3304 /* Index 0x46 Combo jack auto switch control 2 */
3305 /* 3k pull low control for Headset jack. */
Takashi Iwai98b24882014-08-18 13:47:50 +02003306 alc_update_coef_idx(codec, 0x46, 3 << 12, 0);
Kailang Yang2af02be2013-08-22 10:03:50 +02003307 /* Headphone capless set to normal mode */
3308 alc_write_coef_idx(codec, 0x43, 0x9614);
3309}
3310
3311static void alc283_shutup(struct hda_codec *codec)
3312{
3313 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003314 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang2af02be2013-08-22 10:03:50 +02003315 bool hp_pin_sense;
Kailang Yang2af02be2013-08-22 10:03:50 +02003316
3317 if (!hp_pin) {
3318 alc269_shutup(codec);
3319 return;
3320 }
3321
3322 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3323
3324 alc_write_coef_idx(codec, 0x43, 0x9004);
3325
Harsha Priyab450b172014-10-09 11:04:56 +00003326 /*depop hp during suspend*/
3327 alc_write_coef_idx(codec, 0x06, 0x2100);
3328
Kailang Yang2af02be2013-08-22 10:03:50 +02003329 snd_hda_codec_write(codec, hp_pin, 0,
3330 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3331
3332 if (hp_pin_sense)
Kailang Yang88011c092013-10-24 15:45:24 +02003333 msleep(100);
Kailang Yang2af02be2013-08-22 10:03:50 +02003334
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003335 if (!spec->no_shutup_pins)
3336 snd_hda_codec_write(codec, hp_pin, 0,
3337 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
Kailang Yang2af02be2013-08-22 10:03:50 +02003338
Takashi Iwai98b24882014-08-18 13:47:50 +02003339 alc_update_coef_idx(codec, 0x46, 0, 3 << 12);
Kailang Yang2af02be2013-08-22 10:03:50 +02003340
3341 if (hp_pin_sense)
Kailang Yang88011c092013-10-24 15:45:24 +02003342 msleep(100);
Kailang Yang0435b3f2014-04-08 17:14:14 +08003343 alc_auto_setup_eapd(codec, false);
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003344 alc_shutup_pins(codec);
Kailang Yang2af02be2013-08-22 10:03:50 +02003345 alc_write_coef_idx(codec, 0x43, 0x9614);
3346}
3347
Kailang Yang4a219ef2017-06-16 16:54:35 +08003348static void alc256_init(struct hda_codec *codec)
3349{
3350 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003351 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang4a219ef2017-06-16 16:54:35 +08003352 bool hp_pin_sense;
3353
3354 if (!hp_pin)
Kailang Yang6447c962019-05-08 16:27:03 +08003355 hp_pin = 0x21;
Kailang Yang4a219ef2017-06-16 16:54:35 +08003356
3357 msleep(30);
3358
3359 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3360
3361 if (hp_pin_sense)
3362 msleep(2);
3363
3364 alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */
Kailang Yang6447c962019-05-08 16:27:03 +08003365 if (spec->ultra_low_power) {
3366 alc_update_coef_idx(codec, 0x03, 1<<1, 1<<1);
3367 alc_update_coef_idx(codec, 0x08, 3<<2, 3<<2);
3368 alc_update_coef_idx(codec, 0x08, 7<<4, 0);
3369 alc_update_coef_idx(codec, 0x3b, 1<<15, 0);
3370 alc_update_coef_idx(codec, 0x0e, 7<<6, 7<<6);
3371 msleep(30);
3372 }
Kailang Yang4a219ef2017-06-16 16:54:35 +08003373
3374 snd_hda_codec_write(codec, hp_pin, 0,
3375 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3376
Kailang Yang6447c962019-05-08 16:27:03 +08003377 if (hp_pin_sense || spec->ultra_low_power)
Kailang Yang4a219ef2017-06-16 16:54:35 +08003378 msleep(85);
3379
3380 snd_hda_codec_write(codec, hp_pin, 0,
3381 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3382
Kailang Yang6447c962019-05-08 16:27:03 +08003383 if (hp_pin_sense || spec->ultra_low_power)
Kailang Yang4a219ef2017-06-16 16:54:35 +08003384 msleep(100);
3385
3386 alc_update_coef_idx(codec, 0x46, 3 << 12, 0);
3387 alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x4); /* Hight power */
Kailang Yang88d42b22018-03-14 16:08:57 +08003388 alc_update_coefex_idx(codec, 0x53, 0x02, 0x8000, 1 << 15); /* Clear bit */
3389 alc_update_coefex_idx(codec, 0x53, 0x02, 0x8000, 0 << 15);
Thomas Hebbc4473742020-03-30 12:09:38 -04003390 /*
3391 * Expose headphone mic (or possibly Line In on some machines) instead
3392 * of PC Beep on 1Ah, and disable 1Ah loopback for all outputs. See
3393 * Documentation/sound/hd-audio/realtek-pc-beep.rst for details of
3394 * this register.
3395 */
3396 alc_write_coef_idx(codec, 0x36, 0x5757);
Kailang Yang4a219ef2017-06-16 16:54:35 +08003397}
3398
3399static void alc256_shutup(struct hda_codec *codec)
3400{
3401 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003402 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang4a219ef2017-06-16 16:54:35 +08003403 bool hp_pin_sense;
3404
Kailang Yang6447c962019-05-08 16:27:03 +08003405 if (!hp_pin)
3406 hp_pin = 0x21;
Kailang Yang4a219ef2017-06-16 16:54:35 +08003407
3408 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3409
3410 if (hp_pin_sense)
3411 msleep(2);
3412
3413 snd_hda_codec_write(codec, hp_pin, 0,
3414 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3415
Kailang Yang6447c962019-05-08 16:27:03 +08003416 if (hp_pin_sense || spec->ultra_low_power)
Kailang Yang4a219ef2017-06-16 16:54:35 +08003417 msleep(85);
3418
Takashi Iwai1c9609e2018-01-19 14:18:34 +01003419 /* 3k pull low control for Headset jack. */
3420 /* NOTE: call this before clearing the pin, otherwise codec stalls */
3421 alc_update_coef_idx(codec, 0x46, 0, 3 << 12);
3422
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003423 if (!spec->no_shutup_pins)
3424 snd_hda_codec_write(codec, hp_pin, 0,
3425 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
Kailang Yang4a219ef2017-06-16 16:54:35 +08003426
Kailang Yang6447c962019-05-08 16:27:03 +08003427 if (hp_pin_sense || spec->ultra_low_power)
Kailang Yang4a219ef2017-06-16 16:54:35 +08003428 msleep(100);
3429
3430 alc_auto_setup_eapd(codec, false);
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003431 alc_shutup_pins(codec);
Kailang Yang6447c962019-05-08 16:27:03 +08003432 if (spec->ultra_low_power) {
3433 msleep(50);
3434 alc_update_coef_idx(codec, 0x03, 1<<1, 0);
3435 alc_update_coef_idx(codec, 0x08, 7<<4, 7<<4);
3436 alc_update_coef_idx(codec, 0x08, 3<<2, 0);
3437 alc_update_coef_idx(codec, 0x3b, 1<<15, 1<<15);
3438 alc_update_coef_idx(codec, 0x0e, 7<<6, 0);
3439 msleep(30);
3440 }
Kailang Yang4a219ef2017-06-16 16:54:35 +08003441}
3442
Kailang Yangda911b12018-01-05 16:50:08 +08003443static void alc225_init(struct hda_codec *codec)
3444{
3445 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003446 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yangda911b12018-01-05 16:50:08 +08003447 bool hp1_pin_sense, hp2_pin_sense;
3448
3449 if (!hp_pin)
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003450 hp_pin = 0x21;
Kailang Yangda911b12018-01-05 16:50:08 +08003451 msleep(30);
3452
3453 hp1_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3454 hp2_pin_sense = snd_hda_jack_detect(codec, 0x16);
3455
3456 if (hp1_pin_sense || hp2_pin_sense)
3457 msleep(2);
3458
3459 alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003460 if (spec->ultra_low_power) {
3461 alc_update_coef_idx(codec, 0x08, 0x0f << 2, 3<<2);
3462 alc_update_coef_idx(codec, 0x0e, 7<<6, 7<<6);
3463 alc_update_coef_idx(codec, 0x33, 1<<11, 0);
3464 msleep(30);
3465 }
Kailang Yangda911b12018-01-05 16:50:08 +08003466
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_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3470 if (hp2_pin_sense)
3471 snd_hda_codec_write(codec, 0x16, 0,
3472 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
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(85);
3476
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003477 if (hp1_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003478 snd_hda_codec_write(codec, hp_pin, 0,
3479 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3480 if (hp2_pin_sense)
3481 snd_hda_codec_write(codec, 0x16, 0,
3482 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3483
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003484 if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003485 msleep(100);
3486
3487 alc_update_coef_idx(codec, 0x4a, 3 << 10, 0);
3488 alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x4); /* Hight power */
3489}
3490
3491static void alc225_shutup(struct hda_codec *codec)
3492{
3493 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003494 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yangda911b12018-01-05 16:50:08 +08003495 bool hp1_pin_sense, hp2_pin_sense;
3496
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003497 if (!hp_pin)
3498 hp_pin = 0x21;
Hui Wang476c02e2020-03-29 16:20:18 +08003499
3500 alc_disable_headset_jack_key(codec);
Kailang Yangda911b12018-01-05 16:50:08 +08003501 /* 3k pull low control for Headset jack. */
3502 alc_update_coef_idx(codec, 0x4a, 0, 3 << 10);
3503
3504 hp1_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3505 hp2_pin_sense = snd_hda_jack_detect(codec, 0x16);
3506
3507 if (hp1_pin_sense || hp2_pin_sense)
3508 msleep(2);
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_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3513 if (hp2_pin_sense)
3514 snd_hda_codec_write(codec, 0x16, 0,
3515 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
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(85);
3519
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003520 if (hp1_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003521 snd_hda_codec_write(codec, hp_pin, 0,
3522 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
3523 if (hp2_pin_sense)
3524 snd_hda_codec_write(codec, 0x16, 0,
3525 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
3526
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003527 if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003528 msleep(100);
3529
3530 alc_auto_setup_eapd(codec, false);
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003531 alc_shutup_pins(codec);
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003532 if (spec->ultra_low_power) {
3533 msleep(50);
3534 alc_update_coef_idx(codec, 0x08, 0x0f << 2, 0x0c << 2);
3535 alc_update_coef_idx(codec, 0x0e, 7<<6, 0);
3536 alc_update_coef_idx(codec, 0x33, 1<<11, 1<<11);
3537 alc_update_coef_idx(codec, 0x4a, 3<<4, 2<<4);
3538 msleep(30);
3539 }
Hui Wang476c02e2020-03-29 16:20:18 +08003540
3541 alc_update_coef_idx(codec, 0x4a, 3 << 10, 0);
3542 alc_enable_headset_jack_key(codec);
Kailang Yangda911b12018-01-05 16:50:08 +08003543}
3544
Kailang Yangc2d6af52017-06-21 14:50:54 +08003545static void alc_default_init(struct hda_codec *codec)
3546{
3547 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003548 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yangc2d6af52017-06-21 14:50:54 +08003549 bool hp_pin_sense;
3550
3551 if (!hp_pin)
3552 return;
3553
3554 msleep(30);
3555
3556 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3557
3558 if (hp_pin_sense)
3559 msleep(2);
3560
3561 snd_hda_codec_write(codec, hp_pin, 0,
3562 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3563
3564 if (hp_pin_sense)
3565 msleep(85);
3566
3567 snd_hda_codec_write(codec, hp_pin, 0,
3568 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3569
3570 if (hp_pin_sense)
3571 msleep(100);
3572}
3573
3574static void alc_default_shutup(struct hda_codec *codec)
3575{
3576 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003577 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yangc2d6af52017-06-21 14:50:54 +08003578 bool hp_pin_sense;
3579
3580 if (!hp_pin) {
3581 alc269_shutup(codec);
3582 return;
3583 }
3584
3585 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3586
3587 if (hp_pin_sense)
3588 msleep(2);
3589
3590 snd_hda_codec_write(codec, hp_pin, 0,
3591 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3592
3593 if (hp_pin_sense)
3594 msleep(85);
3595
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003596 if (!spec->no_shutup_pins)
3597 snd_hda_codec_write(codec, hp_pin, 0,
3598 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
Kailang Yangc2d6af52017-06-21 14:50:54 +08003599
3600 if (hp_pin_sense)
3601 msleep(100);
3602
3603 alc_auto_setup_eapd(codec, false);
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003604 alc_shutup_pins(codec);
Kailang Yangc2d6af52017-06-21 14:50:54 +08003605}
3606
Kailang Yang693abe12019-01-29 15:38:21 +08003607static void alc294_hp_init(struct hda_codec *codec)
3608{
3609 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003610 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang693abe12019-01-29 15:38:21 +08003611 int i, val;
3612
3613 if (!hp_pin)
3614 return;
3615
3616 snd_hda_codec_write(codec, hp_pin, 0,
3617 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3618
3619 msleep(100);
3620
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003621 if (!spec->no_shutup_pins)
3622 snd_hda_codec_write(codec, hp_pin, 0,
3623 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
Kailang Yang693abe12019-01-29 15:38:21 +08003624
3625 alc_update_coef_idx(codec, 0x6f, 0x000f, 0);/* Set HP depop to manual mode */
3626 alc_update_coefex_idx(codec, 0x58, 0x00, 0x8000, 0x8000); /* HP depop procedure start */
3627
3628 /* Wait for depop procedure finish */
3629 val = alc_read_coefex_idx(codec, 0x58, 0x01);
3630 for (i = 0; i < 20 && val & 0x0080; i++) {
3631 msleep(50);
3632 val = alc_read_coefex_idx(codec, 0x58, 0x01);
3633 }
3634 /* Set HP depop to auto mode */
3635 alc_update_coef_idx(codec, 0x6f, 0x000f, 0x000b);
3636 msleep(50);
3637}
3638
3639static void alc294_init(struct hda_codec *codec)
3640{
3641 struct alc_spec *spec = codec->spec;
3642
Takashi Iwaif6ef4e02019-01-29 14:14:51 +01003643 /* required only at boot or S4 resume time */
3644 if (!spec->done_hp_init ||
3645 codec->core.dev.power.power_state.event == PM_EVENT_RESTORE) {
Kailang Yang693abe12019-01-29 15:38:21 +08003646 alc294_hp_init(codec);
3647 spec->done_hp_init = true;
3648 }
3649 alc_default_init(codec);
3650}
3651
Kailang Yangad60d502013-06-28 12:03:01 +02003652static void alc5505_coef_set(struct hda_codec *codec, unsigned int index_reg,
3653 unsigned int val)
3654{
3655 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_COEF_INDEX, index_reg >> 1);
3656 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_PROC_COEF, val & 0xffff); /* LSB */
3657 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_PROC_COEF, val >> 16); /* MSB */
3658}
3659
3660static int alc5505_coef_get(struct hda_codec *codec, unsigned int index_reg)
3661{
3662 unsigned int val;
3663
3664 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_COEF_INDEX, index_reg >> 1);
3665 val = snd_hda_codec_read(codec, 0x51, 0, AC_VERB_GET_PROC_COEF, 0)
3666 & 0xffff;
3667 val |= snd_hda_codec_read(codec, 0x51, 0, AC_VERB_GET_PROC_COEF, 0)
3668 << 16;
3669 return val;
3670}
3671
3672static void alc5505_dsp_halt(struct hda_codec *codec)
3673{
3674 unsigned int val;
3675
3676 alc5505_coef_set(codec, 0x3000, 0x000c); /* DSP CPU stop */
3677 alc5505_coef_set(codec, 0x880c, 0x0008); /* DDR enter self refresh */
3678 alc5505_coef_set(codec, 0x61c0, 0x11110080); /* Clock control for PLL and CPU */
3679 alc5505_coef_set(codec, 0x6230, 0xfc0d4011); /* Disable Input OP */
3680 alc5505_coef_set(codec, 0x61b4, 0x040a2b03); /* Stop PLL2 */
3681 alc5505_coef_set(codec, 0x61b0, 0x00005b17); /* Stop PLL1 */
3682 alc5505_coef_set(codec, 0x61b8, 0x04133303); /* Stop PLL3 */
3683 val = alc5505_coef_get(codec, 0x6220);
3684 alc5505_coef_set(codec, 0x6220, (val | 0x3000)); /* switch Ringbuffer clock to DBUS clock */
3685}
3686
3687static void alc5505_dsp_back_from_halt(struct hda_codec *codec)
3688{
3689 alc5505_coef_set(codec, 0x61b8, 0x04133302);
3690 alc5505_coef_set(codec, 0x61b0, 0x00005b16);
3691 alc5505_coef_set(codec, 0x61b4, 0x040a2b02);
3692 alc5505_coef_set(codec, 0x6230, 0xf80d4011);
3693 alc5505_coef_set(codec, 0x6220, 0x2002010f);
3694 alc5505_coef_set(codec, 0x880c, 0x00000004);
3695}
3696
3697static void alc5505_dsp_init(struct hda_codec *codec)
3698{
3699 unsigned int val;
3700
3701 alc5505_dsp_halt(codec);
3702 alc5505_dsp_back_from_halt(codec);
3703 alc5505_coef_set(codec, 0x61b0, 0x5b14); /* PLL1 control */
3704 alc5505_coef_set(codec, 0x61b0, 0x5b16);
3705 alc5505_coef_set(codec, 0x61b4, 0x04132b00); /* PLL2 control */
3706 alc5505_coef_set(codec, 0x61b4, 0x04132b02);
3707 alc5505_coef_set(codec, 0x61b8, 0x041f3300); /* PLL3 control*/
3708 alc5505_coef_set(codec, 0x61b8, 0x041f3302);
3709 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_CODEC_RESET, 0); /* Function reset */
3710 alc5505_coef_set(codec, 0x61b8, 0x041b3302);
3711 alc5505_coef_set(codec, 0x61b8, 0x04173302);
3712 alc5505_coef_set(codec, 0x61b8, 0x04163302);
3713 alc5505_coef_set(codec, 0x8800, 0x348b328b); /* DRAM control */
3714 alc5505_coef_set(codec, 0x8808, 0x00020022); /* DRAM control */
3715 alc5505_coef_set(codec, 0x8818, 0x00000400); /* DRAM control */
3716
3717 val = alc5505_coef_get(codec, 0x6200) >> 16; /* Read revision ID */
3718 if (val <= 3)
3719 alc5505_coef_set(codec, 0x6220, 0x2002010f); /* I/O PAD Configuration */
3720 else
3721 alc5505_coef_set(codec, 0x6220, 0x6002018f);
3722
3723 alc5505_coef_set(codec, 0x61ac, 0x055525f0); /**/
3724 alc5505_coef_set(codec, 0x61c0, 0x12230080); /* Clock control */
3725 alc5505_coef_set(codec, 0x61b4, 0x040e2b02); /* PLL2 control */
3726 alc5505_coef_set(codec, 0x61bc, 0x010234f8); /* OSC Control */
3727 alc5505_coef_set(codec, 0x880c, 0x00000004); /* DRAM Function control */
3728 alc5505_coef_set(codec, 0x880c, 0x00000003);
3729 alc5505_coef_set(codec, 0x880c, 0x00000010);
Takashi Iwaicd63a5f2013-07-05 12:13:59 +02003730
3731#ifdef HALT_REALTEK_ALC5505
3732 alc5505_dsp_halt(codec);
3733#endif
Kailang Yangad60d502013-06-28 12:03:01 +02003734}
3735
Takashi Iwaicd63a5f2013-07-05 12:13:59 +02003736#ifdef HALT_REALTEK_ALC5505
Pierre-Louis Bossart8a718212020-01-11 15:47:35 -06003737#define alc5505_dsp_suspend(codec) do { } while (0) /* NOP */
3738#define alc5505_dsp_resume(codec) do { } while (0) /* NOP */
Takashi Iwaicd63a5f2013-07-05 12:13:59 +02003739#else
3740#define alc5505_dsp_suspend(codec) alc5505_dsp_halt(codec)
3741#define alc5505_dsp_resume(codec) alc5505_dsp_back_from_halt(codec)
3742#endif
3743
Takashi Iwai2a439522011-07-26 09:52:50 +02003744#ifdef CONFIG_PM
Kailang Yangad60d502013-06-28 12:03:01 +02003745static int alc269_suspend(struct hda_codec *codec)
3746{
3747 struct alc_spec *spec = codec->spec;
3748
3749 if (spec->has_alc5505_dsp)
Takashi Iwaicd63a5f2013-07-05 12:13:59 +02003750 alc5505_dsp_suspend(codec);
Kailang Yangad60d502013-06-28 12:03:01 +02003751 return alc_suspend(codec);
3752}
3753
Takashi Iwai1d045db2011-07-07 18:23:21 +02003754static int alc269_resume(struct hda_codec *codec)
3755{
Kailang Yangadcc70b2012-05-25 08:08:38 +02003756 struct alc_spec *spec = codec->spec;
3757
Kailang Yang1387e2d2012-11-08 10:23:18 +01003758 if (spec->codec_variant == ALC269_TYPE_ALC269VB)
3759 alc269vb_toggle_power_output(codec, 0);
3760 if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
Kailang Yangadcc70b2012-05-25 08:08:38 +02003761 (alc_get_coef0(codec) & 0x00ff) == 0x018) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02003762 msleep(150);
3763 }
3764
3765 codec->patch_ops.init(codec);
3766
Kailang Yang1387e2d2012-11-08 10:23:18 +01003767 if (spec->codec_variant == ALC269_TYPE_ALC269VB)
3768 alc269vb_toggle_power_output(codec, 1);
3769 if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
Kailang Yangadcc70b2012-05-25 08:08:38 +02003770 (alc_get_coef0(codec) & 0x00ff) == 0x017) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02003771 msleep(200);
3772 }
3773
Takashi Iwai1a462be2020-01-09 10:01:04 +01003774 snd_hda_regmap_sync(codec);
Takashi Iwai1d045db2011-07-07 18:23:21 +02003775 hda_call_check_power_status(codec, 0x01);
Hui Wangf4753712014-08-19 12:07:03 +08003776
3777 /* on some machine, the BIOS will clear the codec gpio data when enter
3778 * suspend, and won't restore the data after resume, so we restore it
3779 * in the driver.
3780 */
Takashi Iwaid261eec2018-06-19 22:32:29 +02003781 if (spec->gpio_data)
3782 alc_write_gpio_data(codec);
Hui Wangf4753712014-08-19 12:07:03 +08003783
Kailang Yangad60d502013-06-28 12:03:01 +02003784 if (spec->has_alc5505_dsp)
Takashi Iwaicd63a5f2013-07-05 12:13:59 +02003785 alc5505_dsp_resume(codec);
Kailang Yangc5177c82013-07-24 14:39:49 +02003786
Takashi Iwai1d045db2011-07-07 18:23:21 +02003787 return 0;
3788}
Takashi Iwai2a439522011-07-26 09:52:50 +02003789#endif /* CONFIG_PM */
Takashi Iwai1d045db2011-07-07 18:23:21 +02003790
David Henningsson108cc102012-07-20 10:37:25 +02003791static void alc269_fixup_pincfg_no_hp_to_lineout(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003792 const struct hda_fixup *fix, int action)
David Henningsson108cc102012-07-20 10:37:25 +02003793{
3794 struct alc_spec *spec = codec->spec;
3795
Takashi Iwai1727a772013-01-10 09:52:52 +01003796 if (action == HDA_FIXUP_ACT_PRE_PROBE)
David Henningsson108cc102012-07-20 10:37:25 +02003797 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
3798}
3799
Jan-Marek Glogowskifdcc9682018-02-14 11:29:15 +01003800static void alc269_fixup_pincfg_U7x7_headset_mic(struct hda_codec *codec,
3801 const struct hda_fixup *fix,
3802 int action)
3803{
3804 unsigned int cfg_headphone = snd_hda_codec_get_pincfg(codec, 0x21);
3805 unsigned int cfg_headset_mic = snd_hda_codec_get_pincfg(codec, 0x19);
3806
3807 if (cfg_headphone && cfg_headset_mic == 0x411111f0)
3808 snd_hda_codec_set_pincfg(codec, 0x19,
3809 (cfg_headphone & ~AC_DEFCFG_DEVICE) |
3810 (AC_JACK_MIC_IN << AC_DEFCFG_DEVICE_SHIFT));
3811}
3812
Takashi Iwai1d045db2011-07-07 18:23:21 +02003813static void alc269_fixup_hweq(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003814 const struct hda_fixup *fix, int action)
Takashi Iwai1d045db2011-07-07 18:23:21 +02003815{
Takashi Iwai98b24882014-08-18 13:47:50 +02003816 if (action == HDA_FIXUP_ACT_INIT)
3817 alc_update_coef_idx(codec, 0x1e, 0, 0x80);
Takashi Iwai1d045db2011-07-07 18:23:21 +02003818}
3819
David Henningsson7c478f02013-10-11 10:18:46 +02003820static void alc269_fixup_headset_mic(struct hda_codec *codec,
3821 const struct hda_fixup *fix, int action)
3822{
3823 struct alc_spec *spec = codec->spec;
3824
3825 if (action == HDA_FIXUP_ACT_PRE_PROBE)
3826 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
3827}
3828
Takashi Iwai1d045db2011-07-07 18:23:21 +02003829static void alc271_fixup_dmic(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003830 const struct hda_fixup *fix, int action)
Takashi Iwai1d045db2011-07-07 18:23:21 +02003831{
3832 static const struct hda_verb verbs[] = {
3833 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
3834 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
3835 {}
3836 };
3837 unsigned int cfg;
3838
Takashi Iwai7639a062015-03-03 10:07:24 +01003839 if (strcmp(codec->core.chip_name, "ALC271X") &&
3840 strcmp(codec->core.chip_name, "ALC269VB"))
Takashi Iwai1d045db2011-07-07 18:23:21 +02003841 return;
3842 cfg = snd_hda_codec_get_pincfg(codec, 0x12);
3843 if (get_defcfg_connect(cfg) == AC_JACK_PORT_FIXED)
3844 snd_hda_sequence_write(codec, verbs);
3845}
3846
Takashi Iwai017f2a12011-07-09 14:42:25 +02003847static void alc269_fixup_pcm_44k(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003848 const struct hda_fixup *fix, int action)
Takashi Iwai017f2a12011-07-09 14:42:25 +02003849{
3850 struct alc_spec *spec = codec->spec;
3851
Takashi Iwai1727a772013-01-10 09:52:52 +01003852 if (action != HDA_FIXUP_ACT_PROBE)
Takashi Iwai017f2a12011-07-09 14:42:25 +02003853 return;
3854
3855 /* Due to a hardware problem on Lenovo Ideadpad, we need to
3856 * fix the sample rate of analog I/O to 44.1kHz
3857 */
Takashi Iwai08c189f2012-12-19 15:22:24 +01003858 spec->gen.stream_analog_playback = &alc269_44k_pcm_analog_playback;
3859 spec->gen.stream_analog_capture = &alc269_44k_pcm_analog_capture;
Takashi Iwai017f2a12011-07-09 14:42:25 +02003860}
3861
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02003862static void alc269_fixup_stereo_dmic(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003863 const struct hda_fixup *fix, int action)
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02003864{
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02003865 /* The digital-mic unit sends PDM (differential signal) instead of
3866 * the standard PCM, thus you can't record a valid mono stream as is.
3867 * Below is a workaround specific to ALC269 to control the dmic
3868 * signal source as mono.
3869 */
Takashi Iwai98b24882014-08-18 13:47:50 +02003870 if (action == HDA_FIXUP_ACT_INIT)
3871 alc_update_coef_idx(codec, 0x07, 0, 0x80);
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02003872}
3873
Takashi Iwai24519912011-08-16 15:08:49 +02003874static void alc269_quanta_automute(struct hda_codec *codec)
3875{
Takashi Iwai08c189f2012-12-19 15:22:24 +01003876 snd_hda_gen_update_outputs(codec);
Takashi Iwai24519912011-08-16 15:08:49 +02003877
Takashi Iwai1687ccc2014-08-18 13:49:35 +02003878 alc_write_coef_idx(codec, 0x0c, 0x680);
3879 alc_write_coef_idx(codec, 0x0c, 0x480);
Takashi Iwai24519912011-08-16 15:08:49 +02003880}
3881
3882static void alc269_fixup_quanta_mute(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003883 const struct hda_fixup *fix, int action)
Takashi Iwai24519912011-08-16 15:08:49 +02003884{
3885 struct alc_spec *spec = codec->spec;
Takashi Iwai1727a772013-01-10 09:52:52 +01003886 if (action != HDA_FIXUP_ACT_PROBE)
Takashi Iwai24519912011-08-16 15:08:49 +02003887 return;
Takashi Iwai08c189f2012-12-19 15:22:24 +01003888 spec->gen.automute_hook = alc269_quanta_automute;
Takashi Iwai24519912011-08-16 15:08:49 +02003889}
3890
David Henningssond240d1d2013-04-15 12:50:02 +02003891static void alc269_x101_hp_automute_hook(struct hda_codec *codec,
Takashi Iwai1a4f69d2014-09-11 15:22:46 +02003892 struct hda_jack_callback *jack)
David Henningssond240d1d2013-04-15 12:50:02 +02003893{
3894 struct alc_spec *spec = codec->spec;
3895 int vref;
3896 msleep(200);
3897 snd_hda_gen_hp_automute(codec, jack);
3898
3899 vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0;
3900 msleep(100);
3901 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3902 vref);
3903 msleep(500);
3904 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3905 vref);
3906}
3907
Tomas Espeletaa2ef03f2019-08-09 16:37:54 +02003908/*
3909 * Magic sequence to make Huawei Matebook X right speaker working (bko#197801)
3910 */
3911struct hda_alc298_mbxinit {
3912 unsigned char value_0x23;
3913 unsigned char value_0x25;
3914};
3915
3916static void alc298_huawei_mbx_stereo_seq(struct hda_codec *codec,
3917 const struct hda_alc298_mbxinit *initval,
3918 bool first)
3919{
3920 snd_hda_codec_write(codec, 0x06, 0, AC_VERB_SET_DIGI_CONVERT_3, 0x0);
3921 alc_write_coef_idx(codec, 0x26, 0xb000);
3922
3923 if (first)
3924 snd_hda_codec_write(codec, 0x21, 0, AC_VERB_GET_PIN_SENSE, 0x0);
3925
3926 snd_hda_codec_write(codec, 0x6, 0, AC_VERB_SET_DIGI_CONVERT_3, 0x80);
3927 alc_write_coef_idx(codec, 0x26, 0xf000);
3928 alc_write_coef_idx(codec, 0x23, initval->value_0x23);
3929
3930 if (initval->value_0x23 != 0x1e)
3931 alc_write_coef_idx(codec, 0x25, initval->value_0x25);
3932
3933 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0x26);
3934 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, 0xb010);
3935}
3936
3937static void alc298_fixup_huawei_mbx_stereo(struct hda_codec *codec,
3938 const struct hda_fixup *fix,
3939 int action)
3940{
3941 /* Initialization magic */
3942 static const struct hda_alc298_mbxinit dac_init[] = {
3943 {0x0c, 0x00}, {0x0d, 0x00}, {0x0e, 0x00}, {0x0f, 0x00},
3944 {0x10, 0x00}, {0x1a, 0x40}, {0x1b, 0x82}, {0x1c, 0x00},
3945 {0x1d, 0x00}, {0x1e, 0x00}, {0x1f, 0x00},
3946 {0x20, 0xc2}, {0x21, 0xc8}, {0x22, 0x26}, {0x23, 0x24},
3947 {0x27, 0xff}, {0x28, 0xff}, {0x29, 0xff}, {0x2a, 0x8f},
3948 {0x2b, 0x02}, {0x2c, 0x48}, {0x2d, 0x34}, {0x2e, 0x00},
3949 {0x2f, 0x00},
3950 {0x30, 0x00}, {0x31, 0x00}, {0x32, 0x00}, {0x33, 0x00},
3951 {0x34, 0x00}, {0x35, 0x01}, {0x36, 0x93}, {0x37, 0x0c},
3952 {0x38, 0x00}, {0x39, 0x00}, {0x3a, 0xf8}, {0x38, 0x80},
3953 {}
3954 };
3955 const struct hda_alc298_mbxinit *seq;
3956
3957 if (action != HDA_FIXUP_ACT_INIT)
3958 return;
3959
3960 /* Start */
3961 snd_hda_codec_write(codec, 0x06, 0, AC_VERB_SET_DIGI_CONVERT_3, 0x00);
3962 snd_hda_codec_write(codec, 0x06, 0, AC_VERB_SET_DIGI_CONVERT_3, 0x80);
3963 alc_write_coef_idx(codec, 0x26, 0xf000);
3964 alc_write_coef_idx(codec, 0x22, 0x31);
3965 alc_write_coef_idx(codec, 0x23, 0x0b);
3966 alc_write_coef_idx(codec, 0x25, 0x00);
3967 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0x26);
3968 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, 0xb010);
3969
3970 for (seq = dac_init; seq->value_0x23; seq++)
3971 alc298_huawei_mbx_stereo_seq(codec, seq, seq == dac_init);
3972}
3973
David Henningssond240d1d2013-04-15 12:50:02 +02003974static void alc269_fixup_x101_headset_mic(struct hda_codec *codec,
3975 const struct hda_fixup *fix, int action)
3976{
3977 struct alc_spec *spec = codec->spec;
3978 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3979 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
3980 spec->gen.hp_automute_hook = alc269_x101_hp_automute_hook;
3981 }
3982}
3983
3984
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003985/* update mute-LED according to the speaker mute state via mic VREF pin */
3986static void alc269_fixup_mic_mute_hook(void *private_data, int enabled)
David Henningsson6d3cd5d2013-01-07 12:03:47 +01003987{
3988 struct hda_codec *codec = private_data;
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003989 struct alc_spec *spec = codec->spec;
3990 unsigned int pinval;
3991
3992 if (spec->mute_led_polarity)
3993 enabled = !enabled;
Takashi Iwai415d5552014-04-03 11:51:21 +02003994 pinval = snd_hda_codec_get_pin_target(codec, spec->mute_led_nid);
3995 pinval &= ~AC_PINCTL_VREFEN;
3996 pinval |= enabled ? AC_PINCTL_VREF_HIZ : AC_PINCTL_VREF_80;
Takashi Iwaie40bdb02018-03-17 22:40:18 +01003997 if (spec->mute_led_nid) {
3998 /* temporarily power up/down for setting VREF */
3999 snd_hda_power_up_pm(codec);
Takashi Iwai08fb0d02013-01-10 17:33:58 +01004000 snd_hda_set_pin_ctl_cache(codec, spec->mute_led_nid, pinval);
Takashi Iwaie40bdb02018-03-17 22:40:18 +01004001 snd_hda_power_down_pm(codec);
4002 }
David Henningsson6d3cd5d2013-01-07 12:03:47 +01004003}
4004
David Henningssond5b6b652013-11-06 10:50:44 +01004005/* Make sure the led works even in runtime suspend */
4006static unsigned int led_power_filter(struct hda_codec *codec,
4007 hda_nid_t nid,
4008 unsigned int power_state)
4009{
4010 struct alc_spec *spec = codec->spec;
4011
Hui Wang50dd9052014-07-08 17:56:15 +08004012 if (power_state != AC_PWRST_D3 || nid == 0 ||
4013 (nid != spec->mute_led_nid && nid != spec->cap_mute_led_nid))
David Henningssond5b6b652013-11-06 10:50:44 +01004014 return power_state;
4015
4016 /* Set pin ctl again, it might have just been set to 0 */
4017 snd_hda_set_pin_ctl(codec, nid,
4018 snd_hda_codec_get_pin_target(codec, nid));
4019
Takashi Iwaicffd3962015-04-09 10:30:25 +02004020 return snd_hda_gen_path_power_filter(codec, nid, power_state);
David Henningssond5b6b652013-11-06 10:50:44 +01004021}
4022
Takashi Iwai08fb0d02013-01-10 17:33:58 +01004023static void alc269_fixup_hp_mute_led(struct hda_codec *codec,
4024 const struct hda_fixup *fix, int action)
David Henningsson6d3cd5d2013-01-07 12:03:47 +01004025{
4026 struct alc_spec *spec = codec->spec;
Takashi Iwai08fb0d02013-01-10 17:33:58 +01004027 const struct dmi_device *dev = NULL;
4028
4029 if (action != HDA_FIXUP_ACT_PRE_PROBE)
4030 return;
4031
4032 while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) {
4033 int pol, pin;
4034 if (sscanf(dev->name, "HP_Mute_LED_%d_%x", &pol, &pin) != 2)
4035 continue;
4036 if (pin < 0x0a || pin >= 0x10)
4037 break;
4038 spec->mute_led_polarity = pol;
4039 spec->mute_led_nid = pin - 0x0a + 0x18;
4040 spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook;
Takashi Iwaifd25a972012-12-20 14:57:18 +01004041 spec->gen.vmaster_mute_enum = 1;
David Henningssond5b6b652013-11-06 10:50:44 +01004042 codec->power_filter = led_power_filter;
Takashi Iwai4e76a882014-02-25 12:21:03 +01004043 codec_dbg(codec,
4044 "Detected mute LED for %x:%d\n", spec->mute_led_nid,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01004045 spec->mute_led_polarity);
David Henningsson6d3cd5d2013-01-07 12:03:47 +01004046 break;
4047 }
4048}
4049
Takashi Iwai85c467d2018-05-29 11:38:38 +02004050static void alc269_fixup_hp_mute_led_micx(struct hda_codec *codec,
4051 const struct hda_fixup *fix,
4052 int action, hda_nid_t pin)
David Henningssond06ac142013-02-18 11:41:55 +01004053{
4054 struct alc_spec *spec = codec->spec;
Takashi Iwai85c467d2018-05-29 11:38:38 +02004055
David Henningssond06ac142013-02-18 11:41:55 +01004056 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4057 spec->mute_led_polarity = 0;
Takashi Iwai85c467d2018-05-29 11:38:38 +02004058 spec->mute_led_nid = pin;
David Henningssond06ac142013-02-18 11:41:55 +01004059 spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook;
4060 spec->gen.vmaster_mute_enum = 1;
David Henningssond5b6b652013-11-06 10:50:44 +01004061 codec->power_filter = led_power_filter;
David Henningssond06ac142013-02-18 11:41:55 +01004062 }
4063}
4064
Takashi Iwai85c467d2018-05-29 11:38:38 +02004065static void alc269_fixup_hp_mute_led_mic1(struct hda_codec *codec,
4066 const struct hda_fixup *fix, int action)
4067{
4068 alc269_fixup_hp_mute_led_micx(codec, fix, action, 0x18);
4069}
4070
Takashi Iwai08fb0d02013-01-10 17:33:58 +01004071static void alc269_fixup_hp_mute_led_mic2(struct hda_codec *codec,
4072 const struct hda_fixup *fix, int action)
Takashi Iwai420b0fe2012-03-12 12:35:27 +01004073{
Takashi Iwai85c467d2018-05-29 11:38:38 +02004074 alc269_fixup_hp_mute_led_micx(codec, fix, action, 0x19);
Takashi Iwai420b0fe2012-03-12 12:35:27 +01004075}
4076
Tom Briden7f783bd2017-03-25 10:12:01 +00004077static void alc269_fixup_hp_mute_led_mic3(struct hda_codec *codec,
4078 const struct hda_fixup *fix, int action)
4079{
Takashi Iwai85c467d2018-05-29 11:38:38 +02004080 alc269_fixup_hp_mute_led_micx(codec, fix, action, 0x1b);
Tom Briden7f783bd2017-03-25 10:12:01 +00004081}
4082
Takashi Iwai0f32fd192014-11-19 12:16:14 +01004083/* update LED status via GPIO */
4084static void alc_update_gpio_led(struct hda_codec *codec, unsigned int mask,
Kai-Heng Fengdbd13172020-04-30 16:32:51 +08004085 int polarity, bool enabled)
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01004086{
Kai-Heng Fengdbd13172020-04-30 16:32:51 +08004087 if (polarity)
Takashi Iwai0f32fd192014-11-19 12:16:14 +01004088 enabled = !enabled;
Takashi Iwaid261eec2018-06-19 22:32:29 +02004089 alc_update_gpio_data(codec, mask, !enabled); /* muted -> LED on */
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01004090}
4091
Takashi Iwai0f32fd192014-11-19 12:16:14 +01004092/* turn on/off mute LED via GPIO per vmaster hook */
4093static void alc_fixup_gpio_mute_hook(void *private_data, int enabled)
4094{
4095 struct hda_codec *codec = private_data;
4096 struct alc_spec *spec = codec->spec;
4097
Kai-Heng Fengdbd13172020-04-30 16:32:51 +08004098 alc_update_gpio_led(codec, spec->gpio_mute_led_mask,
4099 spec->mute_led_polarity, enabled);
Takashi Iwai0f32fd192014-11-19 12:16:14 +01004100}
4101
4102/* turn on/off mic-mute LED via GPIO per capture hook */
Takashi Iwaid03abec2018-06-19 12:29:13 +02004103static void alc_gpio_micmute_update(struct hda_codec *codec)
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01004104{
4105 struct alc_spec *spec = codec->spec;
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01004106
Takashi Iwaid03abec2018-06-19 12:29:13 +02004107 alc_update_gpio_led(codec, spec->gpio_mic_led_mask,
Kai-Heng Fengdbd13172020-04-30 16:32:51 +08004108 spec->micmute_led_polarity,
Takashi Iwaid03abec2018-06-19 12:29:13 +02004109 spec->gen.micmute_led.led_value);
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01004110}
4111
Kai-Heng Feng87dc3642020-04-30 21:52:07 +08004112#if IS_REACHABLE(CONFIG_LEDS_TRIGGER_AUDIO)
4113static int micmute_led_set(struct led_classdev *led_cdev,
4114 enum led_brightness brightness)
4115{
4116 struct hda_codec *codec = dev_to_hda_codec(led_cdev->dev->parent);
4117 struct alc_spec *spec = codec->spec;
4118
4119 alc_update_gpio_led(codec, spec->gpio_mic_led_mask,
4120 spec->micmute_led_polarity, !!brightness);
4121 return 0;
4122}
4123
4124static struct led_classdev micmute_led_cdev = {
4125 .name = "hda::micmute",
4126 .max_brightness = 1,
4127 .brightness_set_blocking = micmute_led_set,
4128 .default_trigger = "audio-micmute",
4129};
4130#endif
4131
Takashi Iwai01e4a272018-06-19 22:47:30 +02004132/* setup mute and mic-mute GPIO bits, add hooks appropriately */
4133static void alc_fixup_hp_gpio_led(struct hda_codec *codec,
4134 int action,
4135 unsigned int mute_mask,
4136 unsigned int micmute_mask)
4137{
4138 struct alc_spec *spec = codec->spec;
Takashi Iwai0127f592020-05-01 09:28:56 +02004139#if IS_REACHABLE(CONFIG_LEDS_TRIGGER_AUDIO)
Kai-Heng Feng87dc3642020-04-30 21:52:07 +08004140 int err;
Takashi Iwai0127f592020-05-01 09:28:56 +02004141#endif
Takashi Iwai01e4a272018-06-19 22:47:30 +02004142
4143 alc_fixup_gpio(codec, action, mute_mask | micmute_mask);
4144
4145 if (action != HDA_FIXUP_ACT_PRE_PROBE)
4146 return;
4147 if (mute_mask) {
4148 spec->gpio_mute_led_mask = mute_mask;
4149 spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook;
4150 }
4151 if (micmute_mask) {
4152 spec->gpio_mic_led_mask = micmute_mask;
4153 snd_hda_gen_add_micmute_led(codec, alc_gpio_micmute_update);
Kai-Heng Feng87dc3642020-04-30 21:52:07 +08004154
4155#if IS_REACHABLE(CONFIG_LEDS_TRIGGER_AUDIO)
4156 micmute_led_cdev.brightness = ledtrig_audio_get(LED_AUDIO_MICMUTE);
4157 err = devm_led_classdev_register(&codec->core.dev, &micmute_led_cdev);
4158 if (err)
4159 codec_warn(codec, "failed to register micmute LED\n");
4160#endif
Takashi Iwai01e4a272018-06-19 22:47:30 +02004161 }
4162}
4163
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01004164static void alc269_fixup_hp_gpio_led(struct hda_codec *codec,
4165 const struct hda_fixup *fix, int action)
4166{
Takashi Iwai01e4a272018-06-19 22:47:30 +02004167 alc_fixup_hp_gpio_led(codec, action, 0x08, 0x10);
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01004168}
4169
Kai-Heng Fengf5a88b02020-03-27 12:46:25 +08004170static void alc285_fixup_hp_gpio_led(struct hda_codec *codec,
4171 const struct hda_fixup *fix, int action)
4172{
Kai-Heng Feng3e0650a2020-04-30 16:32:52 +08004173 struct alc_spec *spec = codec->spec;
4174
4175 spec->micmute_led_polarity = 1;
4176
4177 alc_fixup_hp_gpio_led(codec, action, 0x04, 0x01);
Kai-Heng Fengf5a88b02020-03-27 12:46:25 +08004178}
4179
Kailang Yangeaa8e5e2014-11-21 15:49:11 +08004180static void alc286_fixup_hp_gpio_led(struct hda_codec *codec,
4181 const struct hda_fixup *fix, int action)
4182{
Takashi Iwai01e4a272018-06-19 22:47:30 +02004183 alc_fixup_hp_gpio_led(codec, action, 0x02, 0x20);
Takashi Iwai1d045db2011-07-07 18:23:21 +02004184}
4185
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004186/* turn on/off mic-mute LED per capture hook */
Takashi Iwaid03abec2018-06-19 12:29:13 +02004187static void alc_cap_micmute_update(struct hda_codec *codec)
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004188{
4189 struct alc_spec *spec = codec->spec;
Takashi Iwaid03abec2018-06-19 12:29:13 +02004190 unsigned int pinval;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004191
Takashi Iwaid03abec2018-06-19 12:29:13 +02004192 if (!spec->cap_mute_led_nid)
4193 return;
Hui Wangfc1fad92014-07-08 17:56:14 +08004194 pinval = snd_hda_codec_get_pin_target(codec, spec->cap_mute_led_nid);
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004195 pinval &= ~AC_PINCTL_VREFEN;
Takashi Iwaid03abec2018-06-19 12:29:13 +02004196 if (spec->gen.micmute_led.led_value)
4197 pinval |= AC_PINCTL_VREF_80;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004198 else
Takashi Iwaid03abec2018-06-19 12:29:13 +02004199 pinval |= AC_PINCTL_VREF_HIZ;
4200 snd_hda_set_pin_ctl_cache(codec, spec->cap_mute_led_nid, pinval);
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004201}
4202
4203static void alc269_fixup_hp_gpio_mic1_led(struct hda_codec *codec,
4204 const struct hda_fixup *fix, int action)
4205{
4206 struct alc_spec *spec = codec->spec;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004207
Takashi Iwai01e4a272018-06-19 22:47:30 +02004208 alc_fixup_hp_gpio_led(codec, action, 0x08, 0);
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004209 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai01e4a272018-06-19 22:47:30 +02004210 /* Like hp_gpio_mic1_led, but also needs GPIO4 low to
4211 * enable headphone amp
4212 */
4213 spec->gpio_mask |= 0x10;
4214 spec->gpio_dir |= 0x10;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004215 spec->cap_mute_led_nid = 0x18;
Takashi Iwaid03abec2018-06-19 12:29:13 +02004216 snd_hda_gen_add_micmute_led(codec, alc_cap_micmute_update);
Hui Wang50dd9052014-07-08 17:56:15 +08004217 codec->power_filter = led_power_filter;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004218 }
4219}
4220
David Henningsson7a5255f2014-10-30 08:26:01 +01004221static void alc280_fixup_hp_gpio4(struct hda_codec *codec,
4222 const struct hda_fixup *fix, int action)
4223{
David Henningsson7a5255f2014-10-30 08:26:01 +01004224 struct alc_spec *spec = codec->spec;
David Henningsson7a5255f2014-10-30 08:26:01 +01004225
Takashi Iwai01e4a272018-06-19 22:47:30 +02004226 alc_fixup_hp_gpio_led(codec, action, 0x08, 0);
David Henningsson7a5255f2014-10-30 08:26:01 +01004227 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
David Henningsson7a5255f2014-10-30 08:26:01 +01004228 spec->cap_mute_led_nid = 0x18;
Takashi Iwaid03abec2018-06-19 12:29:13 +02004229 snd_hda_gen_add_micmute_led(codec, alc_cap_micmute_update);
David Henningsson7a5255f2014-10-30 08:26:01 +01004230 codec->power_filter = led_power_filter;
4231 }
4232}
4233
Kailang Yang431e76c2020-04-07 14:40:20 +08004234/* update mute-LED according to the speaker mute state via COEF bit */
4235static void alc_fixup_mute_led_coefbit_hook(void *private_data, int enabled)
4236{
4237 struct hda_codec *codec = private_data;
4238 struct alc_spec *spec = codec->spec;
4239
4240 if (spec->mute_led_polarity)
4241 enabled = !enabled;
4242
4243 /* temporarily power up/down for setting COEF bit */
4244 enabled ? alc_update_coef_idx(codec, spec->mute_led_coef_idx,
4245 spec->mute_led_coefbit_mask, spec->mute_led_coefbit_off) :
4246 alc_update_coef_idx(codec, spec->mute_led_coef_idx,
4247 spec->mute_led_coefbit_mask, spec->mute_led_coefbit_on);
4248}
4249
4250static void alc285_fixup_hp_mute_led_coefbit(struct hda_codec *codec,
4251 const struct hda_fixup *fix,
4252 int action)
4253{
4254 struct alc_spec *spec = codec->spec;
4255
4256 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4257 spec->mute_led_polarity = 0;
4258 spec->mute_led_coef_idx = 0x0b;
4259 spec->mute_led_coefbit_mask = 1<<3;
4260 spec->mute_led_coefbit_on = 1<<3;
4261 spec->mute_led_coefbit_off = 0;
4262 spec->gen.vmaster_mute.hook = alc_fixup_mute_led_coefbit_hook;
4263 spec->gen.vmaster_mute_enum = 1;
4264 }
4265}
4266
Kailang Yang24164f42020-04-07 14:52:42 +08004267static void alc236_fixup_hp_mute_led_coefbit(struct hda_codec *codec,
4268 const struct hda_fixup *fix,
4269 int action)
4270{
4271 struct alc_spec *spec = codec->spec;
4272
4273 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4274 spec->mute_led_polarity = 0;
4275 spec->mute_led_coef_idx = 0x34;
4276 spec->mute_led_coefbit_mask = 1<<5;
4277 spec->mute_led_coefbit_on = 0;
4278 spec->mute_led_coefbit_off = 1<<5;
4279 spec->gen.vmaster_mute.hook = alc_fixup_mute_led_coefbit_hook;
4280 spec->gen.vmaster_mute_enum = 1;
4281 }
4282}
4283
Kailang Yang431e76c2020-04-07 14:40:20 +08004284/* turn on/off mic-mute LED per capture hook by coef bit */
4285static void alc_hp_cap_micmute_update(struct hda_codec *codec)
4286{
4287 struct alc_spec *spec = codec->spec;
4288
4289 if (spec->gen.micmute_led.led_value)
4290 alc_update_coef_idx(codec, spec->mic_led_coef_idx,
4291 spec->mic_led_coefbit_mask, spec->mic_led_coefbit_on);
4292 else
4293 alc_update_coef_idx(codec, spec->mic_led_coef_idx,
4294 spec->mic_led_coefbit_mask, spec->mic_led_coefbit_off);
4295}
4296
4297static void alc285_fixup_hp_coef_micmute_led(struct hda_codec *codec,
4298 const struct hda_fixup *fix, int action)
4299{
4300 struct alc_spec *spec = codec->spec;
4301
4302 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4303 spec->mic_led_coef_idx = 0x19;
4304 spec->mic_led_coefbit_mask = 1<<13;
4305 spec->mic_led_coefbit_on = 1<<13;
4306 spec->mic_led_coefbit_off = 0;
4307 snd_hda_gen_add_micmute_led(codec, alc_hp_cap_micmute_update);
4308 }
4309}
4310
Kailang Yang24164f42020-04-07 14:52:42 +08004311static void alc236_fixup_hp_coef_micmute_led(struct hda_codec *codec,
4312 const struct hda_fixup *fix, int action)
4313{
4314 struct alc_spec *spec = codec->spec;
4315
4316 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4317 spec->mic_led_coef_idx = 0x35;
4318 spec->mic_led_coefbit_mask = 3<<2;
4319 spec->mic_led_coefbit_on = 2<<2;
4320 spec->mic_led_coefbit_off = 1<<2;
4321 snd_hda_gen_add_micmute_led(codec, alc_hp_cap_micmute_update);
4322 }
4323}
4324
Kailang Yang431e76c2020-04-07 14:40:20 +08004325static void alc285_fixup_hp_mute_led(struct hda_codec *codec,
4326 const struct hda_fixup *fix, int action)
4327{
4328 alc285_fixup_hp_mute_led_coefbit(codec, fix, action);
4329 alc285_fixup_hp_coef_micmute_led(codec, fix, action);
4330}
4331
Kailang Yang24164f42020-04-07 14:52:42 +08004332static void alc236_fixup_hp_mute_led(struct hda_codec *codec,
4333 const struct hda_fixup *fix, int action)
4334{
4335 alc236_fixup_hp_mute_led_coefbit(codec, fix, action);
4336 alc236_fixup_hp_coef_micmute_led(codec, fix, action);
4337}
4338
Takashi Iwai6a30aba2018-04-27 17:17:35 +02004339#if IS_REACHABLE(CONFIG_INPUT)
David Henningsson33f4acd2015-01-07 15:50:13 +01004340static void gpio2_mic_hotkey_event(struct hda_codec *codec,
4341 struct hda_jack_callback *event)
4342{
4343 struct alc_spec *spec = codec->spec;
4344
4345 /* GPIO2 just toggles on a keypress/keyrelease cycle. Therefore
4346 send both key on and key off event for every interrupt. */
Hui Wangc7b60a82015-12-28 11:35:25 +08004347 input_report_key(spec->kb_dev, spec->alc_mute_keycode_map[ALC_KEY_MICMUTE_INDEX], 1);
David Henningsson33f4acd2015-01-07 15:50:13 +01004348 input_sync(spec->kb_dev);
Hui Wangc7b60a82015-12-28 11:35:25 +08004349 input_report_key(spec->kb_dev, spec->alc_mute_keycode_map[ALC_KEY_MICMUTE_INDEX], 0);
David Henningsson33f4acd2015-01-07 15:50:13 +01004350 input_sync(spec->kb_dev);
4351}
David Henningsson33f4acd2015-01-07 15:50:13 +01004352
Kailang3694cb22015-12-28 11:35:24 +08004353static int alc_register_micmute_input_device(struct hda_codec *codec)
4354{
4355 struct alc_spec *spec = codec->spec;
Hui Wangc7b60a82015-12-28 11:35:25 +08004356 int i;
Kailang3694cb22015-12-28 11:35:24 +08004357
4358 spec->kb_dev = input_allocate_device();
4359 if (!spec->kb_dev) {
4360 codec_err(codec, "Out of memory (input_allocate_device)\n");
4361 return -ENOMEM;
4362 }
Hui Wangc7b60a82015-12-28 11:35:25 +08004363
4364 spec->alc_mute_keycode_map[ALC_KEY_MICMUTE_INDEX] = KEY_MICMUTE;
4365
Kailang3694cb22015-12-28 11:35:24 +08004366 spec->kb_dev->name = "Microphone Mute Button";
4367 spec->kb_dev->evbit[0] = BIT_MASK(EV_KEY);
Hui Wangc7b60a82015-12-28 11:35:25 +08004368 spec->kb_dev->keycodesize = sizeof(spec->alc_mute_keycode_map[0]);
4369 spec->kb_dev->keycodemax = ARRAY_SIZE(spec->alc_mute_keycode_map);
4370 spec->kb_dev->keycode = spec->alc_mute_keycode_map;
4371 for (i = 0; i < ARRAY_SIZE(spec->alc_mute_keycode_map); i++)
4372 set_bit(spec->alc_mute_keycode_map[i], spec->kb_dev->keybit);
Kailang3694cb22015-12-28 11:35:24 +08004373
4374 if (input_register_device(spec->kb_dev)) {
4375 codec_err(codec, "input_register_device failed\n");
4376 input_free_device(spec->kb_dev);
4377 spec->kb_dev = NULL;
4378 return -ENOMEM;
4379 }
4380
4381 return 0;
4382}
4383
Takashi Iwai01e4a272018-06-19 22:47:30 +02004384/* GPIO1 = set according to SKU external amp
4385 * GPIO2 = mic mute hotkey
4386 * GPIO3 = mute LED
4387 * GPIO4 = mic mute LED
4388 */
David Henningsson33f4acd2015-01-07 15:50:13 +01004389static void alc280_fixup_hp_gpio2_mic_hotkey(struct hda_codec *codec,
4390 const struct hda_fixup *fix, int action)
4391{
David Henningsson33f4acd2015-01-07 15:50:13 +01004392 struct alc_spec *spec = codec->spec;
4393
Takashi Iwai01e4a272018-06-19 22:47:30 +02004394 alc_fixup_hp_gpio_led(codec, action, 0x08, 0x10);
David Henningsson33f4acd2015-01-07 15:50:13 +01004395 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai1c76aa52018-06-21 16:37:54 +02004396 spec->init_amp = ALC_INIT_DEFAULT;
Kailang3694cb22015-12-28 11:35:24 +08004397 if (alc_register_micmute_input_device(codec) != 0)
David Henningsson33f4acd2015-01-07 15:50:13 +01004398 return;
David Henningsson33f4acd2015-01-07 15:50:13 +01004399
Takashi Iwai01e4a272018-06-19 22:47:30 +02004400 spec->gpio_mask |= 0x06;
4401 spec->gpio_dir |= 0x02;
4402 spec->gpio_data |= 0x02;
Takashi Iwai7639a062015-03-03 10:07:24 +01004403 snd_hda_codec_write_cache(codec, codec->core.afg, 0,
David Henningsson33f4acd2015-01-07 15:50:13 +01004404 AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x04);
Takashi Iwai7639a062015-03-03 10:07:24 +01004405 snd_hda_jack_detect_enable_callback(codec, codec->core.afg,
David Henningsson33f4acd2015-01-07 15:50:13 +01004406 gpio2_mic_hotkey_event);
David Henningsson33f4acd2015-01-07 15:50:13 +01004407 return;
4408 }
4409
4410 if (!spec->kb_dev)
4411 return;
4412
4413 switch (action) {
David Henningsson33f4acd2015-01-07 15:50:13 +01004414 case HDA_FIXUP_ACT_FREE:
4415 input_unregister_device(spec->kb_dev);
David Henningsson33f4acd2015-01-07 15:50:13 +01004416 spec->kb_dev = NULL;
4417 }
David Henningsson33f4acd2015-01-07 15:50:13 +01004418}
4419
Takashi Iwai01e4a272018-06-19 22:47:30 +02004420/* Line2 = mic mute hotkey
4421 * GPIO2 = mic mute LED
4422 */
Kailang3694cb22015-12-28 11:35:24 +08004423static void alc233_fixup_lenovo_line2_mic_hotkey(struct hda_codec *codec,
4424 const struct hda_fixup *fix, int action)
4425{
Kailang3694cb22015-12-28 11:35:24 +08004426 struct alc_spec *spec = codec->spec;
4427
Takashi Iwai01e4a272018-06-19 22:47:30 +02004428 alc_fixup_hp_gpio_led(codec, action, 0, 0x04);
Kailang3694cb22015-12-28 11:35:24 +08004429 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai1c76aa52018-06-21 16:37:54 +02004430 spec->init_amp = ALC_INIT_DEFAULT;
Kailang3694cb22015-12-28 11:35:24 +08004431 if (alc_register_micmute_input_device(codec) != 0)
4432 return;
4433
Kailang3694cb22015-12-28 11:35:24 +08004434 snd_hda_jack_detect_enable_callback(codec, 0x1b,
4435 gpio2_mic_hotkey_event);
Kailang3694cb22015-12-28 11:35:24 +08004436 return;
4437 }
4438
4439 if (!spec->kb_dev)
4440 return;
4441
4442 switch (action) {
Kailang3694cb22015-12-28 11:35:24 +08004443 case HDA_FIXUP_ACT_FREE:
4444 input_unregister_device(spec->kb_dev);
4445 spec->kb_dev = NULL;
4446 }
4447}
Takashi Iwaic4696522018-01-15 10:44:35 +01004448#else /* INPUT */
4449#define alc280_fixup_hp_gpio2_mic_hotkey NULL
4450#define alc233_fixup_lenovo_line2_mic_hotkey NULL
4451#endif /* INPUT */
Kailang3694cb22015-12-28 11:35:24 +08004452
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004453static void alc269_fixup_hp_line1_mic1_led(struct hda_codec *codec,
4454 const struct hda_fixup *fix, int action)
4455{
4456 struct alc_spec *spec = codec->spec;
4457
Takashi Iwai1bce62a2018-06-19 23:15:59 +02004458 alc269_fixup_hp_mute_led_micx(codec, fix, action, 0x1a);
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004459 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004460 spec->cap_mute_led_nid = 0x18;
Takashi Iwaid03abec2018-06-19 12:29:13 +02004461 snd_hda_gen_add_micmute_led(codec, alc_cap_micmute_update);
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004462 }
4463}
4464
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004465static const struct coef_fw alc225_pre_hsmode[] = {
Kailang Yang5a367672017-07-21 15:23:53 +08004466 UPDATE_COEF(0x4a, 1<<8, 0),
4467 UPDATE_COEFEX(0x57, 0x05, 1<<14, 0),
4468 UPDATE_COEF(0x63, 3<<14, 3<<14),
4469 UPDATE_COEF(0x4a, 3<<4, 2<<4),
4470 UPDATE_COEF(0x4a, 3<<10, 3<<10),
4471 UPDATE_COEF(0x45, 0x3f<<10, 0x34<<10),
4472 UPDATE_COEF(0x4a, 3<<10, 0),
4473 {}
4474};
4475
David Henningsson73bdd592013-04-15 15:44:14 +02004476static void alc_headset_mode_unplugged(struct hda_codec *codec)
4477{
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004478 static const struct coef_fw coef0255[] = {
Kailang Yang717f43d2019-05-31 17:16:53 +08004479 WRITE_COEF(0x1b, 0x0c0b), /* LDO and MISC control */
Takashi Iwai54db6c32014-08-18 15:11:19 +02004480 WRITE_COEF(0x45, 0xd089), /* UAJ function set to menual mode */
4481 UPDATE_COEFEX(0x57, 0x05, 1<<14, 0), /* Direct Drive HP Amp control(Set to verb control)*/
4482 WRITE_COEF(0x06, 0x6104), /* Set MIC2 Vref gate with HP */
4483 WRITE_COEFEX(0x57, 0x03, 0x8aa6), /* Direct Drive HP Amp control */
4484 {}
4485 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004486 static const struct coef_fw coef0256[] = {
Kailang Yange69e7e02016-05-30 15:58:28 +08004487 WRITE_COEF(0x1b, 0x0c4b), /* LDO and MISC control */
Kailang Yang717f43d2019-05-31 17:16:53 +08004488 WRITE_COEF(0x45, 0xd089), /* UAJ function set to menual mode */
4489 WRITE_COEF(0x06, 0x6104), /* Set MIC2 Vref gate with HP */
4490 WRITE_COEFEX(0x57, 0x03, 0x09a3), /* Direct Drive HP Amp control */
4491 UPDATE_COEFEX(0x57, 0x05, 1<<14, 0), /* Direct Drive HP Amp control(Set to verb control)*/
Kailang Yange69e7e02016-05-30 15:58:28 +08004492 {}
4493 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004494 static const struct coef_fw coef0233[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004495 WRITE_COEF(0x1b, 0x0c0b),
4496 WRITE_COEF(0x45, 0xc429),
4497 UPDATE_COEF(0x35, 0x4000, 0),
4498 WRITE_COEF(0x06, 0x2104),
4499 WRITE_COEF(0x1a, 0x0001),
4500 WRITE_COEF(0x26, 0x0004),
4501 WRITE_COEF(0x32, 0x42a3),
4502 {}
4503 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004504 static const struct coef_fw coef0288[] = {
Kailang Yangf3b70332015-04-08 15:01:17 +08004505 UPDATE_COEF(0x4f, 0xfcc0, 0xc400),
4506 UPDATE_COEF(0x50, 0x2000, 0x2000),
4507 UPDATE_COEF(0x56, 0x0006, 0x0006),
4508 UPDATE_COEF(0x66, 0x0008, 0),
4509 UPDATE_COEF(0x67, 0x2000, 0),
4510 {}
4511 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004512 static const struct coef_fw coef0298[] = {
Kailang Yang89542932017-07-17 15:03:43 +08004513 UPDATE_COEF(0x19, 0x1300, 0x0300),
4514 {}
4515 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004516 static const struct coef_fw coef0292[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004517 WRITE_COEF(0x76, 0x000e),
4518 WRITE_COEF(0x6c, 0x2400),
4519 WRITE_COEF(0x18, 0x7308),
4520 WRITE_COEF(0x6b, 0xc429),
4521 {}
4522 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004523 static const struct coef_fw coef0293[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004524 UPDATE_COEF(0x10, 7<<8, 6<<8), /* SET Line1 JD to 0 */
4525 UPDATE_COEFEX(0x57, 0x05, 1<<15|1<<13, 0x0), /* SET charge pump by verb */
4526 UPDATE_COEFEX(0x57, 0x03, 1<<10, 1<<10), /* SET EN_OSW to 1 */
4527 UPDATE_COEF(0x1a, 1<<3, 1<<3), /* Combo JD gating with LINE1-VREFO */
4528 WRITE_COEF(0x45, 0xc429), /* Set to TRS type */
4529 UPDATE_COEF(0x4a, 0x000f, 0x000e), /* Combo Jack auto detect */
4530 {}
4531 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004532 static const struct coef_fw coef0668[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004533 WRITE_COEF(0x15, 0x0d40),
4534 WRITE_COEF(0xb7, 0x802b),
4535 {}
4536 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004537 static const struct coef_fw coef0225[] = {
Kailang Yang5a367672017-07-21 15:23:53 +08004538 UPDATE_COEF(0x63, 3<<14, 0),
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004539 {}
4540 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004541 static const struct coef_fw coef0274[] = {
Kailang Yang71683c32017-06-20 16:33:50 +08004542 UPDATE_COEF(0x4a, 0x0100, 0),
4543 UPDATE_COEFEX(0x57, 0x05, 0x4000, 0),
4544 UPDATE_COEF(0x6b, 0xf000, 0x5000),
4545 UPDATE_COEF(0x4a, 0x0010, 0),
4546 UPDATE_COEF(0x4a, 0x0c00, 0x0c00),
4547 WRITE_COEF(0x45, 0x5289),
4548 UPDATE_COEF(0x4a, 0x0c00, 0),
4549 {}
4550 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004551
Takashi Iwai7639a062015-03-03 10:07:24 +01004552 switch (codec->core.vendor_id) {
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004553 case 0x10ec0255:
Kailang Yange69e7e02016-05-30 15:58:28 +08004554 alc_process_coef_fw(codec, coef0255);
4555 break;
Kailang Yang736f20a2017-10-20 15:06:34 +08004556 case 0x10ec0236:
Kailang Yang7081adf2015-03-30 17:05:37 +08004557 case 0x10ec0256:
Kailang Yange69e7e02016-05-30 15:58:28 +08004558 alc_process_coef_fw(codec, coef0256);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004559 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004560 case 0x10ec0234:
4561 case 0x10ec0274:
4562 case 0x10ec0294:
4563 alc_process_coef_fw(codec, coef0274);
4564 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004565 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004566 case 0x10ec0283:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004567 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02004568 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004569 case 0x10ec0286:
4570 case 0x10ec0288:
Kailang Yang89542932017-07-17 15:03:43 +08004571 alc_process_coef_fw(codec, coef0288);
4572 break;
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004573 case 0x10ec0298:
Kailang Yang89542932017-07-17 15:03:43 +08004574 alc_process_coef_fw(codec, coef0298);
Kailang Yangf3b70332015-04-08 15:01:17 +08004575 alc_process_coef_fw(codec, coef0288);
4576 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004577 case 0x10ec0292:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004578 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02004579 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004580 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004581 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004582 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004583 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004584 alc_process_coef_fw(codec, coef0668);
David Henningsson73bdd592013-04-15 15:44:14 +02004585 break;
Kailang Yangc2b691e2018-01-17 15:22:55 +08004586 case 0x10ec0215:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004587 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004588 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08004589 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004590 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08004591 case 0x10ec0299:
Kailang Yang4d4b0c52019-01-09 16:23:37 +08004592 alc_process_coef_fw(codec, alc225_pre_hsmode);
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004593 alc_process_coef_fw(codec, coef0225);
4594 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08004595 case 0x10ec0867:
4596 alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
4597 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004598 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01004599 codec_dbg(codec, "Headset jack set to unplugged mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02004600}
4601
4602
4603static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin,
4604 hda_nid_t mic_pin)
4605{
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004606 static const struct coef_fw coef0255[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004607 WRITE_COEFEX(0x57, 0x03, 0x8aa6),
4608 WRITE_COEF(0x06, 0x6100), /* Set MIC2 Vref gate to normal */
4609 {}
4610 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004611 static const struct coef_fw coef0256[] = {
Kailang Yang717f43d2019-05-31 17:16:53 +08004612 UPDATE_COEFEX(0x57, 0x05, 1<<14, 1<<14), /* Direct Drive HP Amp control(Set to verb control)*/
4613 WRITE_COEFEX(0x57, 0x03, 0x09a3),
4614 WRITE_COEF(0x06, 0x6100), /* Set MIC2 Vref gate to normal */
4615 {}
4616 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004617 static const struct coef_fw coef0233[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004618 UPDATE_COEF(0x35, 0, 1<<14),
4619 WRITE_COEF(0x06, 0x2100),
4620 WRITE_COEF(0x1a, 0x0021),
4621 WRITE_COEF(0x26, 0x008c),
4622 {}
4623 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004624 static const struct coef_fw coef0288[] = {
Kailang Yang89542932017-07-17 15:03:43 +08004625 UPDATE_COEF(0x4f, 0x00c0, 0),
Kailang Yangf3b70332015-04-08 15:01:17 +08004626 UPDATE_COEF(0x50, 0x2000, 0),
4627 UPDATE_COEF(0x56, 0x0006, 0),
4628 UPDATE_COEF(0x4f, 0xfcc0, 0xc400),
4629 UPDATE_COEF(0x66, 0x0008, 0x0008),
4630 UPDATE_COEF(0x67, 0x2000, 0x2000),
4631 {}
4632 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004633 static const struct coef_fw coef0292[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004634 WRITE_COEF(0x19, 0xa208),
4635 WRITE_COEF(0x2e, 0xacf0),
4636 {}
4637 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004638 static const struct coef_fw coef0293[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004639 UPDATE_COEFEX(0x57, 0x05, 0, 1<<15|1<<13), /* SET charge pump by verb */
4640 UPDATE_COEFEX(0x57, 0x03, 1<<10, 0), /* SET EN_OSW to 0 */
4641 UPDATE_COEF(0x1a, 1<<3, 0), /* Combo JD gating without LINE1-VREFO */
4642 {}
4643 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004644 static const struct coef_fw coef0688[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004645 WRITE_COEF(0xb7, 0x802b),
4646 WRITE_COEF(0xb5, 0x1040),
4647 UPDATE_COEF(0xc3, 0, 1<<12),
4648 {}
4649 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004650 static const struct coef_fw coef0225[] = {
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004651 UPDATE_COEFEX(0x57, 0x05, 1<<14, 1<<14),
4652 UPDATE_COEF(0x4a, 3<<4, 2<<4),
4653 UPDATE_COEF(0x63, 3<<14, 0),
4654 {}
4655 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004656 static const struct coef_fw coef0274[] = {
Kailang Yang71683c32017-06-20 16:33:50 +08004657 UPDATE_COEFEX(0x57, 0x05, 0x4000, 0x4000),
4658 UPDATE_COEF(0x4a, 0x0010, 0),
4659 UPDATE_COEF(0x6b, 0xf000, 0),
4660 {}
4661 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004662
Takashi Iwai7639a062015-03-03 10:07:24 +01004663 switch (codec->core.vendor_id) {
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004664 case 0x10ec0255:
4665 alc_write_coef_idx(codec, 0x45, 0xc489);
4666 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02004667 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004668 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4669 break;
Kailang Yang717f43d2019-05-31 17:16:53 +08004670 case 0x10ec0236:
4671 case 0x10ec0256:
4672 alc_write_coef_idx(codec, 0x45, 0xc489);
4673 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4674 alc_process_coef_fw(codec, coef0256);
4675 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4676 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004677 case 0x10ec0234:
4678 case 0x10ec0274:
4679 case 0x10ec0294:
4680 alc_write_coef_idx(codec, 0x45, 0x4689);
4681 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4682 alc_process_coef_fw(codec, coef0274);
4683 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4684 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004685 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004686 case 0x10ec0283:
4687 alc_write_coef_idx(codec, 0x45, 0xc429);
4688 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02004689 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02004690 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4691 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004692 case 0x10ec0286:
4693 case 0x10ec0288:
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004694 case 0x10ec0298:
Kailang Yangf3b70332015-04-08 15:01:17 +08004695 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4696 alc_process_coef_fw(codec, coef0288);
4697 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4698 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004699 case 0x10ec0292:
4700 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02004701 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02004702 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004703 case 0x10ec0293:
4704 /* Set to TRS mode */
4705 alc_write_coef_idx(codec, 0x45, 0xc429);
4706 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02004707 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004708 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4709 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08004710 case 0x10ec0867:
4711 alc_update_coefex_idx(codec, 0x57, 0x5, 0, 1<<14);
4712 /* fallthru */
Kailang Yang9eb5d0e2017-01-17 15:40:25 +08004713 case 0x10ec0221:
David Henningsson1f8b46c2015-05-12 14:38:15 +02004714 case 0x10ec0662:
4715 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4716 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4717 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004718 case 0x10ec0668:
4719 alc_write_coef_idx(codec, 0x11, 0x0001);
4720 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02004721 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02004722 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4723 break;
Kailang Yangc2b691e2018-01-17 15:22:55 +08004724 case 0x10ec0215:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004725 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004726 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08004727 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004728 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08004729 case 0x10ec0299:
Kailang Yang5a367672017-07-21 15:23:53 +08004730 alc_process_coef_fw(codec, alc225_pre_hsmode);
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004731 alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x31<<10);
4732 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4733 alc_process_coef_fw(codec, coef0225);
4734 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4735 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004736 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01004737 codec_dbg(codec, "Headset jack set to mic-in mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02004738}
4739
4740static void alc_headset_mode_default(struct hda_codec *codec)
4741{
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004742 static const struct coef_fw coef0225[] = {
Kailang Yang5a367672017-07-21 15:23:53 +08004743 UPDATE_COEF(0x45, 0x3f<<10, 0x30<<10),
4744 UPDATE_COEF(0x45, 0x3f<<10, 0x31<<10),
4745 UPDATE_COEF(0x49, 3<<8, 0<<8),
4746 UPDATE_COEF(0x4a, 3<<4, 3<<4),
4747 UPDATE_COEF(0x63, 3<<14, 0),
4748 UPDATE_COEF(0x67, 0xf000, 0x3000),
David Henningsson2ae95572016-02-25 09:37:05 +01004749 {}
4750 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004751 static const struct coef_fw coef0255[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004752 WRITE_COEF(0x45, 0xc089),
4753 WRITE_COEF(0x45, 0xc489),
4754 WRITE_COEFEX(0x57, 0x03, 0x8ea6),
4755 WRITE_COEF(0x49, 0x0049),
4756 {}
4757 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004758 static const struct coef_fw coef0256[] = {
Kailang Yang717f43d2019-05-31 17:16:53 +08004759 WRITE_COEF(0x45, 0xc489),
4760 WRITE_COEFEX(0x57, 0x03, 0x0da3),
4761 WRITE_COEF(0x49, 0x0049),
4762 UPDATE_COEFEX(0x57, 0x05, 1<<14, 0), /* Direct Drive HP Amp control(Set to verb control)*/
4763 WRITE_COEF(0x06, 0x6100),
4764 {}
4765 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004766 static const struct coef_fw coef0233[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004767 WRITE_COEF(0x06, 0x2100),
4768 WRITE_COEF(0x32, 0x4ea3),
4769 {}
4770 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004771 static const struct coef_fw coef0288[] = {
Kailang Yangf3b70332015-04-08 15:01:17 +08004772 UPDATE_COEF(0x4f, 0xfcc0, 0xc400), /* Set to TRS type */
4773 UPDATE_COEF(0x50, 0x2000, 0x2000),
4774 UPDATE_COEF(0x56, 0x0006, 0x0006),
4775 UPDATE_COEF(0x66, 0x0008, 0),
4776 UPDATE_COEF(0x67, 0x2000, 0),
4777 {}
4778 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004779 static const struct coef_fw coef0292[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004780 WRITE_COEF(0x76, 0x000e),
4781 WRITE_COEF(0x6c, 0x2400),
4782 WRITE_COEF(0x6b, 0xc429),
4783 WRITE_COEF(0x18, 0x7308),
4784 {}
4785 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004786 static const struct coef_fw coef0293[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004787 UPDATE_COEF(0x4a, 0x000f, 0x000e), /* Combo Jack auto detect */
4788 WRITE_COEF(0x45, 0xC429), /* Set to TRS type */
4789 UPDATE_COEF(0x1a, 1<<3, 0), /* Combo JD gating without LINE1-VREFO */
4790 {}
4791 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004792 static const struct coef_fw coef0688[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004793 WRITE_COEF(0x11, 0x0041),
4794 WRITE_COEF(0x15, 0x0d40),
4795 WRITE_COEF(0xb7, 0x802b),
4796 {}
4797 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004798 static const struct coef_fw coef0274[] = {
Kailang Yang71683c32017-06-20 16:33:50 +08004799 WRITE_COEF(0x45, 0x4289),
4800 UPDATE_COEF(0x4a, 0x0010, 0x0010),
4801 UPDATE_COEF(0x6b, 0x0f00, 0),
4802 UPDATE_COEF(0x49, 0x0300, 0x0300),
4803 {}
4804 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004805
Takashi Iwai7639a062015-03-03 10:07:24 +01004806 switch (codec->core.vendor_id) {
Kailang Yangc2b691e2018-01-17 15:22:55 +08004807 case 0x10ec0215:
David Henningsson2ae95572016-02-25 09:37:05 +01004808 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004809 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08004810 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004811 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08004812 case 0x10ec0299:
Kailang Yang5a367672017-07-21 15:23:53 +08004813 alc_process_coef_fw(codec, alc225_pre_hsmode);
David Henningsson2ae95572016-02-25 09:37:05 +01004814 alc_process_coef_fw(codec, coef0225);
4815 break;
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004816 case 0x10ec0255:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004817 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004818 break;
Kailang Yang717f43d2019-05-31 17:16:53 +08004819 case 0x10ec0236:
4820 case 0x10ec0256:
4821 alc_write_coef_idx(codec, 0x1b, 0x0e4b);
4822 alc_write_coef_idx(codec, 0x45, 0xc089);
4823 msleep(50);
4824 alc_process_coef_fw(codec, coef0256);
4825 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004826 case 0x10ec0234:
4827 case 0x10ec0274:
4828 case 0x10ec0294:
4829 alc_process_coef_fw(codec, coef0274);
4830 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004831 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004832 case 0x10ec0283:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004833 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02004834 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004835 case 0x10ec0286:
4836 case 0x10ec0288:
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004837 case 0x10ec0298:
Kailang Yangf3b70332015-04-08 15:01:17 +08004838 alc_process_coef_fw(codec, coef0288);
4839 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004840 case 0x10ec0292:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004841 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02004842 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004843 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004844 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004845 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004846 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004847 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02004848 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08004849 case 0x10ec0867:
4850 alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
4851 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004852 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01004853 codec_dbg(codec, "Headset jack set to headphone (default) mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02004854}
4855
4856/* Iphone type */
4857static void alc_headset_mode_ctia(struct hda_codec *codec)
4858{
Kailang Yang89542932017-07-17 15:03:43 +08004859 int val;
4860
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004861 static const struct coef_fw coef0255[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004862 WRITE_COEF(0x45, 0xd489), /* Set to CTIA type */
4863 WRITE_COEF(0x1b, 0x0c2b),
4864 WRITE_COEFEX(0x57, 0x03, 0x8ea6),
4865 {}
4866 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004867 static const struct coef_fw coef0256[] = {
Kailang Yange69e7e02016-05-30 15:58:28 +08004868 WRITE_COEF(0x45, 0xd489), /* Set to CTIA type */
Kailang Yang717f43d2019-05-31 17:16:53 +08004869 WRITE_COEF(0x1b, 0x0e6b),
Kailang Yange69e7e02016-05-30 15:58:28 +08004870 {}
4871 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004872 static const struct coef_fw coef0233[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004873 WRITE_COEF(0x45, 0xd429),
4874 WRITE_COEF(0x1b, 0x0c2b),
4875 WRITE_COEF(0x32, 0x4ea3),
4876 {}
4877 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004878 static const struct coef_fw coef0288[] = {
Kailang Yangf3b70332015-04-08 15:01:17 +08004879 UPDATE_COEF(0x50, 0x2000, 0x2000),
4880 UPDATE_COEF(0x56, 0x0006, 0x0006),
4881 UPDATE_COEF(0x66, 0x0008, 0),
4882 UPDATE_COEF(0x67, 0x2000, 0),
4883 {}
4884 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004885 static const struct coef_fw coef0292[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004886 WRITE_COEF(0x6b, 0xd429),
4887 WRITE_COEF(0x76, 0x0008),
4888 WRITE_COEF(0x18, 0x7388),
4889 {}
4890 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004891 static const struct coef_fw coef0293[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004892 WRITE_COEF(0x45, 0xd429), /* Set to ctia type */
4893 UPDATE_COEF(0x10, 7<<8, 7<<8), /* SET Line1 JD to 1 */
4894 {}
4895 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004896 static const struct coef_fw coef0688[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004897 WRITE_COEF(0x11, 0x0001),
4898 WRITE_COEF(0x15, 0x0d60),
4899 WRITE_COEF(0xc3, 0x0000),
4900 {}
4901 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004902 static const struct coef_fw coef0225_1[] = {
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004903 UPDATE_COEF(0x45, 0x3f<<10, 0x35<<10),
Kailang Yang5a367672017-07-21 15:23:53 +08004904 UPDATE_COEF(0x63, 3<<14, 2<<14),
4905 {}
4906 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004907 static const struct coef_fw coef0225_2[] = {
Kailang Yang5a367672017-07-21 15:23:53 +08004908 UPDATE_COEF(0x45, 0x3f<<10, 0x35<<10),
4909 UPDATE_COEF(0x63, 3<<14, 1<<14),
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004910 {}
4911 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004912
Takashi Iwai7639a062015-03-03 10:07:24 +01004913 switch (codec->core.vendor_id) {
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004914 case 0x10ec0255:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004915 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004916 break;
Kailang Yang736f20a2017-10-20 15:06:34 +08004917 case 0x10ec0236:
Kailang Yange69e7e02016-05-30 15:58:28 +08004918 case 0x10ec0256:
4919 alc_process_coef_fw(codec, coef0256);
4920 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004921 case 0x10ec0234:
4922 case 0x10ec0274:
4923 case 0x10ec0294:
4924 alc_write_coef_idx(codec, 0x45, 0xd689);
4925 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004926 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004927 case 0x10ec0283:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004928 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02004929 break;
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004930 case 0x10ec0298:
Kailang Yang89542932017-07-17 15:03:43 +08004931 val = alc_read_coef_idx(codec, 0x50);
4932 if (val & (1 << 12)) {
4933 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0020);
4934 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400);
4935 msleep(300);
4936 } else {
4937 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0010);
4938 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400);
4939 msleep(300);
4940 }
4941 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004942 case 0x10ec0286:
4943 case 0x10ec0288:
4944 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400);
4945 msleep(300);
4946 alc_process_coef_fw(codec, coef0288);
4947 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004948 case 0x10ec0292:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004949 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02004950 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004951 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004952 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004953 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004954 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004955 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02004956 break;
Kailang Yangc2b691e2018-01-17 15:22:55 +08004957 case 0x10ec0215:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004958 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004959 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08004960 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004961 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08004962 case 0x10ec0299:
Kailang Yang5a367672017-07-21 15:23:53 +08004963 val = alc_read_coef_idx(codec, 0x45);
4964 if (val & (1 << 9))
4965 alc_process_coef_fw(codec, coef0225_2);
4966 else
4967 alc_process_coef_fw(codec, coef0225_1);
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004968 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08004969 case 0x10ec0867:
4970 alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
4971 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004972 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01004973 codec_dbg(codec, "Headset jack set to iPhone-style headset mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02004974}
4975
4976/* Nokia type */
4977static void alc_headset_mode_omtp(struct hda_codec *codec)
4978{
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004979 static const struct coef_fw coef0255[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004980 WRITE_COEF(0x45, 0xe489), /* Set to OMTP Type */
4981 WRITE_COEF(0x1b, 0x0c2b),
4982 WRITE_COEFEX(0x57, 0x03, 0x8ea6),
4983 {}
4984 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004985 static const struct coef_fw coef0256[] = {
Kailang Yange69e7e02016-05-30 15:58:28 +08004986 WRITE_COEF(0x45, 0xe489), /* Set to OMTP Type */
Kailang Yang717f43d2019-05-31 17:16:53 +08004987 WRITE_COEF(0x1b, 0x0e6b),
Kailang Yange69e7e02016-05-30 15:58:28 +08004988 {}
4989 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004990 static const struct coef_fw coef0233[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004991 WRITE_COEF(0x45, 0xe429),
4992 WRITE_COEF(0x1b, 0x0c2b),
4993 WRITE_COEF(0x32, 0x4ea3),
4994 {}
4995 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01004996 static const struct coef_fw coef0288[] = {
Kailang Yangf3b70332015-04-08 15:01:17 +08004997 UPDATE_COEF(0x50, 0x2000, 0x2000),
4998 UPDATE_COEF(0x56, 0x0006, 0x0006),
4999 UPDATE_COEF(0x66, 0x0008, 0),
5000 UPDATE_COEF(0x67, 0x2000, 0),
5001 {}
5002 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01005003 static const struct coef_fw coef0292[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02005004 WRITE_COEF(0x6b, 0xe429),
5005 WRITE_COEF(0x76, 0x0008),
5006 WRITE_COEF(0x18, 0x7388),
5007 {}
5008 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01005009 static const struct coef_fw coef0293[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02005010 WRITE_COEF(0x45, 0xe429), /* Set to omtp type */
5011 UPDATE_COEF(0x10, 7<<8, 7<<8), /* SET Line1 JD to 1 */
5012 {}
5013 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01005014 static const struct coef_fw coef0688[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02005015 WRITE_COEF(0x11, 0x0001),
5016 WRITE_COEF(0x15, 0x0d50),
5017 WRITE_COEF(0xc3, 0x0000),
5018 {}
5019 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01005020 static const struct coef_fw coef0225[] = {
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08005021 UPDATE_COEF(0x45, 0x3f<<10, 0x39<<10),
Kailang Yang5a367672017-07-21 15:23:53 +08005022 UPDATE_COEF(0x63, 3<<14, 2<<14),
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08005023 {}
5024 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02005025
Takashi Iwai7639a062015-03-03 10:07:24 +01005026 switch (codec->core.vendor_id) {
Kailang Yang9a22a8f52013-11-08 15:54:49 +08005027 case 0x10ec0255:
Takashi Iwai54db6c32014-08-18 15:11:19 +02005028 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08005029 break;
Kailang Yang736f20a2017-10-20 15:06:34 +08005030 case 0x10ec0236:
Kailang Yange69e7e02016-05-30 15:58:28 +08005031 case 0x10ec0256:
5032 alc_process_coef_fw(codec, coef0256);
5033 break;
Kailang Yang71683c32017-06-20 16:33:50 +08005034 case 0x10ec0234:
5035 case 0x10ec0274:
5036 case 0x10ec0294:
5037 alc_write_coef_idx(codec, 0x45, 0xe689);
5038 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08005039 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02005040 case 0x10ec0283:
Takashi Iwai54db6c32014-08-18 15:11:19 +02005041 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02005042 break;
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08005043 case 0x10ec0298:
5044 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0010);/* Headset output enable */
Kailang Yang89542932017-07-17 15:03:43 +08005045 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xe400);
5046 msleep(300);
5047 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08005048 case 0x10ec0286:
5049 case 0x10ec0288:
5050 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xe400);
5051 msleep(300);
5052 alc_process_coef_fw(codec, coef0288);
5053 break;
David Henningsson73bdd592013-04-15 15:44:14 +02005054 case 0x10ec0292:
Takashi Iwai54db6c32014-08-18 15:11:19 +02005055 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02005056 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08005057 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02005058 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08005059 break;
David Henningsson73bdd592013-04-15 15:44:14 +02005060 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02005061 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02005062 break;
Kailang Yangc2b691e2018-01-17 15:22:55 +08005063 case 0x10ec0215:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08005064 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08005065 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08005066 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08005067 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08005068 case 0x10ec0299:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08005069 alc_process_coef_fw(codec, coef0225);
5070 break;
David Henningsson73bdd592013-04-15 15:44:14 +02005071 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01005072 codec_dbg(codec, "Headset jack set to Nokia-style headset mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02005073}
5074
5075static void alc_determine_headset_type(struct hda_codec *codec)
5076{
5077 int val;
5078 bool is_ctia = false;
5079 struct alc_spec *spec = codec->spec;
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01005080 static const struct coef_fw coef0255[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02005081 WRITE_COEF(0x45, 0xd089), /* combo jack auto switch control(Check type)*/
5082 WRITE_COEF(0x49, 0x0149), /* combo jack auto switch control(Vref
5083 conteol) */
5084 {}
5085 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01005086 static const struct coef_fw coef0288[] = {
Kailang Yangf3b70332015-04-08 15:01:17 +08005087 UPDATE_COEF(0x4f, 0xfcc0, 0xd400), /* Check Type */
5088 {}
5089 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01005090 static const struct coef_fw coef0298[] = {
Kailang Yang89542932017-07-17 15:03:43 +08005091 UPDATE_COEF(0x50, 0x2000, 0x2000),
5092 UPDATE_COEF(0x56, 0x0006, 0x0006),
5093 UPDATE_COEF(0x66, 0x0008, 0),
5094 UPDATE_COEF(0x67, 0x2000, 0),
5095 UPDATE_COEF(0x19, 0x1300, 0x1300),
5096 {}
5097 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01005098 static const struct coef_fw coef0293[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02005099 UPDATE_COEF(0x4a, 0x000f, 0x0008), /* Combo Jack auto detect */
5100 WRITE_COEF(0x45, 0xD429), /* Set to ctia type */
5101 {}
5102 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01005103 static const struct coef_fw coef0688[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02005104 WRITE_COEF(0x11, 0x0001),
5105 WRITE_COEF(0xb7, 0x802b),
5106 WRITE_COEF(0x15, 0x0d60),
5107 WRITE_COEF(0xc3, 0x0c00),
5108 {}
5109 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01005110 static const struct coef_fw coef0274[] = {
Kailang Yang71683c32017-06-20 16:33:50 +08005111 UPDATE_COEF(0x4a, 0x0010, 0),
5112 UPDATE_COEF(0x4a, 0x8000, 0),
5113 WRITE_COEF(0x45, 0xd289),
5114 UPDATE_COEF(0x49, 0x0300, 0x0300),
5115 {}
5116 };
David Henningsson73bdd592013-04-15 15:44:14 +02005117
Takashi Iwai7639a062015-03-03 10:07:24 +01005118 switch (codec->core.vendor_id) {
Kailang Yang9a22a8f52013-11-08 15:54:49 +08005119 case 0x10ec0255:
Takashi Iwai54db6c32014-08-18 15:11:19 +02005120 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08005121 msleep(300);
5122 val = alc_read_coef_idx(codec, 0x46);
5123 is_ctia = (val & 0x0070) == 0x0070;
5124 break;
Kailang Yang717f43d2019-05-31 17:16:53 +08005125 case 0x10ec0236:
5126 case 0x10ec0256:
5127 alc_write_coef_idx(codec, 0x1b, 0x0e4b);
5128 alc_write_coef_idx(codec, 0x06, 0x6104);
5129 alc_write_coefex_idx(codec, 0x57, 0x3, 0x09a3);
5130
5131 snd_hda_codec_write(codec, 0x21, 0,
5132 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
5133 msleep(80);
5134 snd_hda_codec_write(codec, 0x21, 0,
5135 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
5136
5137 alc_process_coef_fw(codec, coef0255);
5138 msleep(300);
5139 val = alc_read_coef_idx(codec, 0x46);
5140 is_ctia = (val & 0x0070) == 0x0070;
5141
5142 alc_write_coefex_idx(codec, 0x57, 0x3, 0x0da3);
5143 alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
5144
5145 snd_hda_codec_write(codec, 0x21, 0,
5146 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
5147 msleep(80);
5148 snd_hda_codec_write(codec, 0x21, 0,
5149 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
5150 break;
Kailang Yang71683c32017-06-20 16:33:50 +08005151 case 0x10ec0234:
5152 case 0x10ec0274:
5153 case 0x10ec0294:
5154 alc_process_coef_fw(codec, coef0274);
5155 msleep(80);
5156 val = alc_read_coef_idx(codec, 0x46);
5157 is_ctia = (val & 0x00f0) == 0x00f0;
5158 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08005159 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02005160 case 0x10ec0283:
5161 alc_write_coef_idx(codec, 0x45, 0xd029);
5162 msleep(300);
5163 val = alc_read_coef_idx(codec, 0x46);
5164 is_ctia = (val & 0x0070) == 0x0070;
5165 break;
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08005166 case 0x10ec0298:
Kailang Yang89542932017-07-17 15:03:43 +08005167 snd_hda_codec_write(codec, 0x21, 0,
5168 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
5169 msleep(100);
5170 snd_hda_codec_write(codec, 0x21, 0,
5171 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
5172 msleep(200);
5173
5174 val = alc_read_coef_idx(codec, 0x50);
5175 if (val & (1 << 12)) {
5176 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0020);
5177 alc_process_coef_fw(codec, coef0288);
5178 msleep(350);
5179 val = alc_read_coef_idx(codec, 0x50);
5180 is_ctia = (val & 0x0070) == 0x0070;
5181 } else {
5182 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0010);
5183 alc_process_coef_fw(codec, coef0288);
5184 msleep(350);
5185 val = alc_read_coef_idx(codec, 0x50);
5186 is_ctia = (val & 0x0070) == 0x0070;
5187 }
5188 alc_process_coef_fw(codec, coef0298);
5189 snd_hda_codec_write(codec, 0x21, 0,
5190 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP);
5191 msleep(75);
5192 snd_hda_codec_write(codec, 0x21, 0,
5193 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
5194 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08005195 case 0x10ec0286:
5196 case 0x10ec0288:
5197 alc_process_coef_fw(codec, coef0288);
5198 msleep(350);
5199 val = alc_read_coef_idx(codec, 0x50);
5200 is_ctia = (val & 0x0070) == 0x0070;
5201 break;
David Henningsson73bdd592013-04-15 15:44:14 +02005202 case 0x10ec0292:
5203 alc_write_coef_idx(codec, 0x6b, 0xd429);
5204 msleep(300);
5205 val = alc_read_coef_idx(codec, 0x6c);
5206 is_ctia = (val & 0x001c) == 0x001c;
5207 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08005208 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02005209 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08005210 msleep(300);
5211 val = alc_read_coef_idx(codec, 0x46);
5212 is_ctia = (val & 0x0070) == 0x0070;
5213 break;
David Henningsson73bdd592013-04-15 15:44:14 +02005214 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02005215 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02005216 msleep(300);
5217 val = alc_read_coef_idx(codec, 0xbe);
5218 is_ctia = (val & 0x1c02) == 0x1c02;
5219 break;
Kailang Yangc2b691e2018-01-17 15:22:55 +08005220 case 0x10ec0215:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08005221 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08005222 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08005223 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08005224 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08005225 case 0x10ec0299:
Kailang Yangda911b12018-01-05 16:50:08 +08005226 snd_hda_codec_write(codec, 0x21, 0,
5227 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
5228 msleep(80);
5229 snd_hda_codec_write(codec, 0x21, 0,
5230 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
5231
Kailang Yang5a367672017-07-21 15:23:53 +08005232 alc_process_coef_fw(codec, alc225_pre_hsmode);
5233 alc_update_coef_idx(codec, 0x67, 0xf000, 0x1000);
5234 val = alc_read_coef_idx(codec, 0x45);
5235 if (val & (1 << 9)) {
5236 alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x34<<10);
5237 alc_update_coef_idx(codec, 0x49, 3<<8, 2<<8);
5238 msleep(800);
5239 val = alc_read_coef_idx(codec, 0x46);
5240 is_ctia = (val & 0x00f0) == 0x00f0;
5241 } else {
5242 alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x34<<10);
5243 alc_update_coef_idx(codec, 0x49, 3<<8, 1<<8);
5244 msleep(800);
5245 val = alc_read_coef_idx(codec, 0x46);
5246 is_ctia = (val & 0x00f0) == 0x00f0;
5247 }
5248 alc_update_coef_idx(codec, 0x4a, 7<<6, 7<<6);
5249 alc_update_coef_idx(codec, 0x4a, 3<<4, 3<<4);
5250 alc_update_coef_idx(codec, 0x67, 0xf000, 0x3000);
Kailang Yangda911b12018-01-05 16:50:08 +08005251
5252 snd_hda_codec_write(codec, 0x21, 0,
5253 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
5254 msleep(80);
5255 snd_hda_codec_write(codec, 0x21, 0,
5256 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08005257 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08005258 case 0x10ec0867:
5259 is_ctia = true;
5260 break;
David Henningsson73bdd592013-04-15 15:44:14 +02005261 }
5262
Takashi Iwai4e76a882014-02-25 12:21:03 +01005263 codec_dbg(codec, "Headset jack detected iPhone-style headset: %s\n",
David Henningsson73bdd592013-04-15 15:44:14 +02005264 is_ctia ? "yes" : "no");
5265 spec->current_headset_type = is_ctia ? ALC_HEADSET_TYPE_CTIA : ALC_HEADSET_TYPE_OMTP;
5266}
5267
5268static void alc_update_headset_mode(struct hda_codec *codec)
5269{
5270 struct alc_spec *spec = codec->spec;
5271
5272 hda_nid_t mux_pin = spec->gen.imux_pins[spec->gen.cur_mux[0]];
Takashi Iwai35a39f92019-02-01 11:19:50 +01005273 hda_nid_t hp_pin = alc_get_hp_pin(spec);
David Henningsson73bdd592013-04-15 15:44:14 +02005274
5275 int new_headset_mode;
5276
5277 if (!snd_hda_jack_detect(codec, hp_pin))
5278 new_headset_mode = ALC_HEADSET_MODE_UNPLUGGED;
5279 else if (mux_pin == spec->headset_mic_pin)
5280 new_headset_mode = ALC_HEADSET_MODE_HEADSET;
5281 else if (mux_pin == spec->headphone_mic_pin)
5282 new_headset_mode = ALC_HEADSET_MODE_MIC;
5283 else
5284 new_headset_mode = ALC_HEADSET_MODE_HEADPHONE;
5285
David Henningsson5959a6b2013-11-12 11:10:57 +01005286 if (new_headset_mode == spec->current_headset_mode) {
5287 snd_hda_gen_update_outputs(codec);
David Henningsson73bdd592013-04-15 15:44:14 +02005288 return;
David Henningsson5959a6b2013-11-12 11:10:57 +01005289 }
David Henningsson73bdd592013-04-15 15:44:14 +02005290
5291 switch (new_headset_mode) {
5292 case ALC_HEADSET_MODE_UNPLUGGED:
5293 alc_headset_mode_unplugged(codec);
Kailang Yangaeac1a02019-05-16 16:10:44 +08005294 spec->current_headset_mode = ALC_HEADSET_MODE_UNKNOWN;
5295 spec->current_headset_type = ALC_HEADSET_TYPE_UNKNOWN;
David Henningsson73bdd592013-04-15 15:44:14 +02005296 spec->gen.hp_jack_present = false;
5297 break;
5298 case ALC_HEADSET_MODE_HEADSET:
5299 if (spec->current_headset_type == ALC_HEADSET_TYPE_UNKNOWN)
5300 alc_determine_headset_type(codec);
5301 if (spec->current_headset_type == ALC_HEADSET_TYPE_CTIA)
5302 alc_headset_mode_ctia(codec);
5303 else if (spec->current_headset_type == ALC_HEADSET_TYPE_OMTP)
5304 alc_headset_mode_omtp(codec);
5305 spec->gen.hp_jack_present = true;
5306 break;
5307 case ALC_HEADSET_MODE_MIC:
5308 alc_headset_mode_mic_in(codec, hp_pin, spec->headphone_mic_pin);
5309 spec->gen.hp_jack_present = false;
5310 break;
5311 case ALC_HEADSET_MODE_HEADPHONE:
5312 alc_headset_mode_default(codec);
5313 spec->gen.hp_jack_present = true;
5314 break;
5315 }
5316 if (new_headset_mode != ALC_HEADSET_MODE_MIC) {
5317 snd_hda_set_pin_ctl_cache(codec, hp_pin,
5318 AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN);
David Henningsson1f8b46c2015-05-12 14:38:15 +02005319 if (spec->headphone_mic_pin && spec->headphone_mic_pin != hp_pin)
David Henningsson73bdd592013-04-15 15:44:14 +02005320 snd_hda_set_pin_ctl_cache(codec, spec->headphone_mic_pin,
5321 PIN_VREFHIZ);
5322 }
5323 spec->current_headset_mode = new_headset_mode;
5324
5325 snd_hda_gen_update_outputs(codec);
5326}
5327
5328static void alc_update_headset_mode_hook(struct hda_codec *codec,
Takashi Iwai7fe30712014-01-30 17:59:02 +01005329 struct snd_kcontrol *kcontrol,
5330 struct snd_ctl_elem_value *ucontrol)
David Henningsson73bdd592013-04-15 15:44:14 +02005331{
5332 alc_update_headset_mode(codec);
5333}
5334
Takashi Iwai1a4f69d2014-09-11 15:22:46 +02005335static void alc_update_headset_jack_cb(struct hda_codec *codec,
5336 struct hda_jack_callback *jack)
David Henningsson73bdd592013-04-15 15:44:14 +02005337{
David Henningsson73bdd592013-04-15 15:44:14 +02005338 snd_hda_gen_hp_automute(codec, jack);
5339}
5340
5341static void alc_probe_headset_mode(struct hda_codec *codec)
5342{
5343 int i;
5344 struct alc_spec *spec = codec->spec;
5345 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
5346
5347 /* Find mic pins */
5348 for (i = 0; i < cfg->num_inputs; i++) {
5349 if (cfg->inputs[i].is_headset_mic && !spec->headset_mic_pin)
5350 spec->headset_mic_pin = cfg->inputs[i].pin;
5351 if (cfg->inputs[i].is_headphone_mic && !spec->headphone_mic_pin)
5352 spec->headphone_mic_pin = cfg->inputs[i].pin;
5353 }
5354
Takashi Iwai0bed2aa2018-06-19 12:45:53 +02005355 WARN_ON(spec->gen.cap_sync_hook);
David Henningsson73bdd592013-04-15 15:44:14 +02005356 spec->gen.cap_sync_hook = alc_update_headset_mode_hook;
5357 spec->gen.automute_hook = alc_update_headset_mode;
5358 spec->gen.hp_automute_hook = alc_update_headset_jack_cb;
5359}
5360
5361static void alc_fixup_headset_mode(struct hda_codec *codec,
5362 const struct hda_fixup *fix, int action)
5363{
5364 struct alc_spec *spec = codec->spec;
5365
5366 switch (action) {
5367 case HDA_FIXUP_ACT_PRE_PROBE:
5368 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC | HDA_PINCFG_HEADPHONE_MIC;
5369 break;
5370 case HDA_FIXUP_ACT_PROBE:
5371 alc_probe_headset_mode(codec);
5372 break;
5373 case HDA_FIXUP_ACT_INIT:
Kailang Yangaeac1a02019-05-16 16:10:44 +08005374 if (is_s3_resume(codec) || is_s4_resume(codec)) {
5375 spec->current_headset_mode = ALC_HEADSET_MODE_UNKNOWN;
5376 spec->current_headset_type = ALC_HEADSET_TYPE_UNKNOWN;
5377 }
David Henningsson73bdd592013-04-15 15:44:14 +02005378 alc_update_headset_mode(codec);
5379 break;
5380 }
5381}
5382
5383static void alc_fixup_headset_mode_no_hp_mic(struct hda_codec *codec,
5384 const struct hda_fixup *fix, int action)
5385{
5386 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5387 struct alc_spec *spec = codec->spec;
5388 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
5389 }
5390 else
5391 alc_fixup_headset_mode(codec, fix, action);
5392}
5393
Kailang Yang31278992014-03-03 15:27:22 +08005394static void alc255_set_default_jack_type(struct hda_codec *codec)
5395{
5396 /* Set to iphone type */
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01005397 static const struct coef_fw alc255fw[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02005398 WRITE_COEF(0x1b, 0x880b),
5399 WRITE_COEF(0x45, 0xd089),
5400 WRITE_COEF(0x1b, 0x080b),
5401 WRITE_COEF(0x46, 0x0004),
5402 WRITE_COEF(0x1b, 0x0c0b),
5403 {}
5404 };
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01005405 static const struct coef_fw alc256fw[] = {
Kailang Yange69e7e02016-05-30 15:58:28 +08005406 WRITE_COEF(0x1b, 0x884b),
5407 WRITE_COEF(0x45, 0xd089),
5408 WRITE_COEF(0x1b, 0x084b),
5409 WRITE_COEF(0x46, 0x0004),
5410 WRITE_COEF(0x1b, 0x0c4b),
5411 {}
5412 };
5413 switch (codec->core.vendor_id) {
5414 case 0x10ec0255:
5415 alc_process_coef_fw(codec, alc255fw);
5416 break;
Kailang Yang736f20a2017-10-20 15:06:34 +08005417 case 0x10ec0236:
Kailang Yange69e7e02016-05-30 15:58:28 +08005418 case 0x10ec0256:
5419 alc_process_coef_fw(codec, alc256fw);
5420 break;
5421 }
Kailang Yang31278992014-03-03 15:27:22 +08005422 msleep(30);
5423}
5424
Kailang Yang9a22a8f52013-11-08 15:54:49 +08005425static void alc_fixup_headset_mode_alc255(struct hda_codec *codec,
5426 const struct hda_fixup *fix, int action)
5427{
5428 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Kailang Yang31278992014-03-03 15:27:22 +08005429 alc255_set_default_jack_type(codec);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08005430 }
5431 alc_fixup_headset_mode(codec, fix, action);
5432}
5433
Kailang Yang31278992014-03-03 15:27:22 +08005434static void alc_fixup_headset_mode_alc255_no_hp_mic(struct hda_codec *codec,
5435 const struct hda_fixup *fix, int action)
5436{
5437 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5438 struct alc_spec *spec = codec->spec;
5439 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
5440 alc255_set_default_jack_type(codec);
5441 }
5442 else
5443 alc_fixup_headset_mode(codec, fix, action);
5444}
5445
Kailang Yange1e62b92015-04-08 16:01:22 +08005446static void alc288_update_headset_jack_cb(struct hda_codec *codec,
5447 struct hda_jack_callback *jack)
5448{
5449 struct alc_spec *spec = codec->spec;
Kailang Yange1e62b92015-04-08 16:01:22 +08005450
5451 alc_update_headset_jack_cb(codec, jack);
5452 /* Headset Mic enable or disable, only for Dell Dino */
Takashi Iwaid44a6862018-06-19 23:04:03 +02005453 alc_update_gpio_data(codec, 0x40, spec->gen.hp_jack_present);
Kailang Yange1e62b92015-04-08 16:01:22 +08005454}
5455
5456static void alc_fixup_headset_mode_dell_alc288(struct hda_codec *codec,
5457 const struct hda_fixup *fix, int action)
5458{
5459 alc_fixup_headset_mode(codec, fix, action);
5460 if (action == HDA_FIXUP_ACT_PROBE) {
5461 struct alc_spec *spec = codec->spec;
Takashi Iwaid44a6862018-06-19 23:04:03 +02005462 /* toggled via hp_automute_hook */
5463 spec->gpio_mask |= 0x40;
5464 spec->gpio_dir |= 0x40;
Kailang Yange1e62b92015-04-08 16:01:22 +08005465 spec->gen.hp_automute_hook = alc288_update_headset_jack_cb;
5466 }
5467}
5468
Hui Wang493a52a2014-01-14 14:07:36 +08005469static void alc_fixup_auto_mute_via_amp(struct hda_codec *codec,
5470 const struct hda_fixup *fix, int action)
5471{
5472 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5473 struct alc_spec *spec = codec->spec;
5474 spec->gen.auto_mute_via_amp = 1;
5475 }
5476}
5477
Takashi Iwai9b745ab2014-03-07 08:37:19 +01005478static void alc_fixup_no_shutup(struct hda_codec *codec,
5479 const struct hda_fixup *fix, int action)
5480{
Takashi Iwaiefe55732018-06-15 11:55:02 +02005481 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai9b745ab2014-03-07 08:37:19 +01005482 struct alc_spec *spec = codec->spec;
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01005483 spec->no_shutup_pins = 1;
Takashi Iwai9b745ab2014-03-07 08:37:19 +01005484 }
5485}
5486
Gabriele Mazzotta5e6db662014-05-20 18:58:26 +02005487static void alc_fixup_disable_aamix(struct hda_codec *codec,
5488 const struct hda_fixup *fix, int action)
5489{
5490 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5491 struct alc_spec *spec = codec->spec;
5492 /* Disable AA-loopback as it causes white noise */
5493 spec->gen.mixer_nid = 0;
5494 }
5495}
5496
Takashi Iwai7f57d802015-09-24 17:36:51 +02005497/* fixup for Thinkpad docks: add dock pins, avoid HP parser fixup */
5498static void alc_fixup_tpt440_dock(struct hda_codec *codec,
5499 const struct hda_fixup *fix, int action)
5500{
5501 static const struct hda_pintbl pincfgs[] = {
5502 { 0x16, 0x21211010 }, /* dock headphone */
5503 { 0x19, 0x21a11010 }, /* dock mic */
5504 { }
5505 };
5506 struct alc_spec *spec = codec->spec;
5507
5508 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Hui Wang871b9062019-08-14 12:09:08 +08005509 spec->reboot_notify = snd_hda_gen_reboot_notify; /* reduce noise */
Takashi Iwai7f57d802015-09-24 17:36:51 +02005510 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
5511 codec->power_save_node = 0; /* avoid click noises */
5512 snd_hda_apply_pincfgs(codec, pincfgs);
5513 }
5514}
5515
Kailang Yang61fcf8e2018-02-02 15:26:46 +08005516static void alc_fixup_tpt470_dock(struct hda_codec *codec,
5517 const struct hda_fixup *fix, int action)
5518{
5519 static const struct hda_pintbl pincfgs[] = {
5520 { 0x17, 0x21211010 }, /* dock headphone */
5521 { 0x19, 0x21a11010 }, /* dock mic */
5522 { }
5523 };
5524 struct alc_spec *spec = codec->spec;
5525
5526 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5527 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
Takashi Iwai71db96d2018-02-26 15:36:38 +01005528 snd_hda_apply_pincfgs(codec, pincfgs);
5529 } else if (action == HDA_FIXUP_ACT_INIT) {
Kailang Yang61fcf8e2018-02-02 15:26:46 +08005530 /* Enable DOCK device */
5531 snd_hda_codec_write(codec, 0x17, 0,
5532 AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0);
5533 /* Enable DOCK device */
5534 snd_hda_codec_write(codec, 0x19, 0,
5535 AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0);
Kailang Yang61fcf8e2018-02-02 15:26:46 +08005536 }
5537}
5538
Takashi Iwai399c01a2020-05-26 08:24:06 +02005539static void alc_fixup_tpt470_dacs(struct hda_codec *codec,
5540 const struct hda_fixup *fix, int action)
5541{
5542 /* Assure the speaker pin to be coupled with DAC NID 0x03; otherwise
5543 * the speaker output becomes too low by some reason on Thinkpads with
5544 * ALC298 codec
5545 */
5546 static const hda_nid_t preferred_pairs[] = {
5547 0x14, 0x03, 0x17, 0x02, 0x21, 0x02,
5548 0
5549 };
5550 struct alc_spec *spec = codec->spec;
5551
5552 if (action == HDA_FIXUP_ACT_PRE_PROBE)
5553 spec->gen.preferred_dacs = preferred_pairs;
5554}
5555
Gabriele Mazzotta9476d3692015-04-19 19:00:40 +02005556static void alc_shutup_dell_xps13(struct hda_codec *codec)
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02005557{
5558 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01005559 int hp_pin = alc_get_hp_pin(spec);
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02005560
Gabriele Mazzotta9476d3692015-04-19 19:00:40 +02005561 /* Prevent pop noises when headphones are plugged in */
5562 snd_hda_codec_write(codec, hp_pin, 0,
5563 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
5564 msleep(20);
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02005565}
5566
5567static void alc_fixup_dell_xps13(struct hda_codec *codec,
5568 const struct hda_fixup *fix, int action)
5569{
Takashi Iwai3e1b0c42015-04-27 10:43:22 +02005570 struct alc_spec *spec = codec->spec;
5571 struct hda_input_mux *imux = &spec->gen.input_mux;
5572 int i;
Gabriele Mazzottaf38663a2014-08-08 19:34:40 +02005573
Takashi Iwai3e1b0c42015-04-27 10:43:22 +02005574 switch (action) {
5575 case HDA_FIXUP_ACT_PRE_PROBE:
5576 /* mic pin 0x19 must be initialized with Vref Hi-Z, otherwise
5577 * it causes a click noise at start up
5578 */
5579 snd_hda_codec_set_pin_target(codec, 0x19, PIN_VREFHIZ);
Takashi Iwaiefe55732018-06-15 11:55:02 +02005580 spec->shutup = alc_shutup_dell_xps13;
Takashi Iwai3e1b0c42015-04-27 10:43:22 +02005581 break;
5582 case HDA_FIXUP_ACT_PROBE:
Gabriele Mazzottaf38663a2014-08-08 19:34:40 +02005583 /* Make the internal mic the default input source. */
5584 for (i = 0; i < imux->num_items; i++) {
5585 if (spec->gen.imux_pins[i] == 0x12) {
5586 spec->gen.cur_mux[0] = i;
5587 break;
5588 }
5589 }
Takashi Iwai3e1b0c42015-04-27 10:43:22 +02005590 break;
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02005591 }
5592}
5593
David Henningsson1f8b46c2015-05-12 14:38:15 +02005594static void alc_fixup_headset_mode_alc662(struct hda_codec *codec,
5595 const struct hda_fixup *fix, int action)
5596{
5597 struct alc_spec *spec = codec->spec;
5598
5599 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5600 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
5601 spec->gen.hp_mic = 1; /* Mic-in is same pin as headphone */
David Henningssonb40eda62015-05-28 09:40:23 +02005602
5603 /* Disable boost for mic-in permanently. (This code is only called
5604 from quirks that guarantee that the headphone is at NID 0x1b.) */
5605 snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000);
5606 snd_hda_override_wcaps(codec, 0x1b, get_wcaps(codec, 0x1b) & ~AC_WCAP_IN_AMP);
David Henningsson1f8b46c2015-05-12 14:38:15 +02005607 } else
5608 alc_fixup_headset_mode(codec, fix, action);
5609}
5610
David Henningsson73bdd592013-04-15 15:44:14 +02005611static void alc_fixup_headset_mode_alc668(struct hda_codec *codec,
5612 const struct hda_fixup *fix, int action)
5613{
5614 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
David Henningsson73bdd592013-04-15 15:44:14 +02005615 alc_write_coef_idx(codec, 0xc4, 0x8000);
Takashi Iwai98b24882014-08-18 13:47:50 +02005616 alc_update_coef_idx(codec, 0xc2, ~0xfe, 0);
David Henningsson73bdd592013-04-15 15:44:14 +02005617 snd_hda_set_pin_ctl_cache(codec, 0x18, 0);
5618 }
5619 alc_fixup_headset_mode(codec, fix, action);
5620}
5621
Chih-Chung Changbde7bc62013-08-05 16:38:42 +08005622/* Returns the nid of the external mic input pin, or 0 if it cannot be found. */
5623static int find_ext_mic_pin(struct hda_codec *codec)
5624{
5625 struct alc_spec *spec = codec->spec;
5626 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
5627 hda_nid_t nid;
5628 unsigned int defcfg;
5629 int i;
5630
5631 for (i = 0; i < cfg->num_inputs; i++) {
5632 if (cfg->inputs[i].type != AUTO_PIN_MIC)
5633 continue;
5634 nid = cfg->inputs[i].pin;
5635 defcfg = snd_hda_codec_get_pincfg(codec, nid);
5636 if (snd_hda_get_input_pin_attr(defcfg) == INPUT_PIN_ATTR_INT)
5637 continue;
5638 return nid;
5639 }
5640
5641 return 0;
5642}
5643
Dylan Reid08a978d2012-11-18 22:56:40 -08005644static void alc271_hp_gate_mic_jack(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01005645 const struct hda_fixup *fix,
Dylan Reid08a978d2012-11-18 22:56:40 -08005646 int action)
5647{
5648 struct alc_spec *spec = codec->spec;
5649
Takashi Iwai0db75792013-01-23 13:57:20 +01005650 if (action == HDA_FIXUP_ACT_PROBE) {
Chih-Chung Changbde7bc62013-08-05 16:38:42 +08005651 int mic_pin = find_ext_mic_pin(codec);
Takashi Iwai35a39f92019-02-01 11:19:50 +01005652 int hp_pin = alc_get_hp_pin(spec);
Chih-Chung Changbde7bc62013-08-05 16:38:42 +08005653
5654 if (snd_BUG_ON(!mic_pin || !hp_pin))
Takashi Iwai0db75792013-01-23 13:57:20 +01005655 return;
Chih-Chung Changbde7bc62013-08-05 16:38:42 +08005656 snd_hda_jack_set_gating_jack(codec, mic_pin, hp_pin);
Takashi Iwai0db75792013-01-23 13:57:20 +01005657 }
Dylan Reid08a978d2012-11-18 22:56:40 -08005658}
David Henningsson693b6132012-06-22 19:12:10 +02005659
David Henningsson3e0d6112013-04-22 14:30:14 +02005660static void alc269_fixup_limit_int_mic_boost(struct hda_codec *codec,
5661 const struct hda_fixup *fix,
5662 int action)
5663{
5664 struct alc_spec *spec = codec->spec;
5665 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
5666 int i;
5667
5668 /* The mic boosts on level 2 and 3 are too noisy
5669 on the internal mic input.
5670 Therefore limit the boost to 0 or 1. */
5671
5672 if (action != HDA_FIXUP_ACT_PROBE)
5673 return;
5674
5675 for (i = 0; i < cfg->num_inputs; i++) {
5676 hda_nid_t nid = cfg->inputs[i].pin;
5677 unsigned int defcfg;
5678 if (cfg->inputs[i].type != AUTO_PIN_MIC)
5679 continue;
5680 defcfg = snd_hda_codec_get_pincfg(codec, nid);
5681 if (snd_hda_get_input_pin_attr(defcfg) != INPUT_PIN_ATTR_INT)
5682 continue;
5683
5684 snd_hda_override_amp_caps(codec, nid, HDA_INPUT,
5685 (0x00 << AC_AMPCAP_OFFSET_SHIFT) |
5686 (0x01 << AC_AMPCAP_NUM_STEPS_SHIFT) |
5687 (0x2f << AC_AMPCAP_STEP_SIZE_SHIFT) |
5688 (0 << AC_AMPCAP_MUTE_SHIFT));
5689 }
5690}
5691
Kailang Yangcd217a62013-08-22 10:15:24 +02005692static void alc283_hp_automute_hook(struct hda_codec *codec,
Takashi Iwai1a4f69d2014-09-11 15:22:46 +02005693 struct hda_jack_callback *jack)
Kailang Yangcd217a62013-08-22 10:15:24 +02005694{
5695 struct alc_spec *spec = codec->spec;
5696 int vref;
5697
5698 msleep(200);
5699 snd_hda_gen_hp_automute(codec, jack);
5700
5701 vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0;
5702
5703 msleep(600);
5704 snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5705 vref);
5706}
5707
Kailang Yangcd217a62013-08-22 10:15:24 +02005708static void alc283_fixup_chromebook(struct hda_codec *codec,
5709 const struct hda_fixup *fix, int action)
5710{
5711 struct alc_spec *spec = codec->spec;
Kailang Yangcd217a62013-08-22 10:15:24 +02005712
5713 switch (action) {
5714 case HDA_FIXUP_ACT_PRE_PROBE:
Kailang Yang0202e992013-12-02 15:20:15 +08005715 snd_hda_override_wcaps(codec, 0x03, 0);
Takashi Iwaid2e92702013-10-30 07:50:53 +01005716 /* Disable AA-loopback as it causes white noise */
5717 spec->gen.mixer_nid = 0;
Kailang Yang38070212013-11-01 15:57:35 +08005718 break;
5719 case HDA_FIXUP_ACT_INIT:
Kailang Yangde9481c2014-04-07 16:41:52 +08005720 /* MIC2-VREF control */
5721 /* Set to manual mode */
Takashi Iwai98b24882014-08-18 13:47:50 +02005722 alc_update_coef_idx(codec, 0x06, 0x000c, 0);
Kailang Yang0202e992013-12-02 15:20:15 +08005723 /* Enable Line1 input control by verb */
Takashi Iwai98b24882014-08-18 13:47:50 +02005724 alc_update_coef_idx(codec, 0x1a, 0, 1 << 4);
Kailang Yang0202e992013-12-02 15:20:15 +08005725 break;
5726 }
5727}
5728
5729static void alc283_fixup_sense_combo_jack(struct hda_codec *codec,
5730 const struct hda_fixup *fix, int action)
5731{
5732 struct alc_spec *spec = codec->spec;
Kailang Yang0202e992013-12-02 15:20:15 +08005733
5734 switch (action) {
5735 case HDA_FIXUP_ACT_PRE_PROBE:
Kailang Yangcd217a62013-08-22 10:15:24 +02005736 spec->gen.hp_automute_hook = alc283_hp_automute_hook;
5737 break;
5738 case HDA_FIXUP_ACT_INIT:
5739 /* MIC2-VREF control */
5740 /* Set to manual mode */
Takashi Iwai98b24882014-08-18 13:47:50 +02005741 alc_update_coef_idx(codec, 0x06, 0x000c, 0);
Kailang Yangcd217a62013-08-22 10:15:24 +02005742 break;
5743 }
5744}
5745
Takashi Iwai7bba2152013-09-06 15:45:38 +02005746/* mute tablet speaker pin (0x14) via dock plugging in addition */
5747static void asus_tx300_automute(struct hda_codec *codec)
5748{
5749 struct alc_spec *spec = codec->spec;
5750 snd_hda_gen_update_outputs(codec);
5751 if (snd_hda_jack_detect(codec, 0x1b))
5752 spec->gen.mute_bits |= (1ULL << 0x14);
5753}
5754
5755static void alc282_fixup_asus_tx300(struct hda_codec *codec,
5756 const struct hda_fixup *fix, int action)
5757{
5758 struct alc_spec *spec = codec->spec;
Takashi Iwai7bba2152013-09-06 15:45:38 +02005759 static const struct hda_pintbl dock_pins[] = {
5760 { 0x1b, 0x21114000 }, /* dock speaker pin */
5761 {}
5762 };
Takashi Iwai7bba2152013-09-06 15:45:38 +02005763
5764 switch (action) {
5765 case HDA_FIXUP_ACT_PRE_PROBE:
Takashi Iwai1c76aa52018-06-21 16:37:54 +02005766 spec->init_amp = ALC_INIT_DEFAULT;
Takashi Iwaiae065f12018-06-19 23:00:03 +02005767 /* TX300 needs to set up GPIO2 for the speaker amp */
5768 alc_setup_gpio(codec, 0x04);
Takashi Iwai7bba2152013-09-06 15:45:38 +02005769 snd_hda_apply_pincfgs(codec, dock_pins);
5770 spec->gen.auto_mute_via_amp = 1;
5771 spec->gen.automute_hook = asus_tx300_automute;
5772 snd_hda_jack_detect_enable_callback(codec, 0x1b,
Takashi Iwai7bba2152013-09-06 15:45:38 +02005773 snd_hda_gen_hp_automute);
5774 break;
Takashi Iwai5579cd62018-06-19 22:22:41 +02005775 case HDA_FIXUP_ACT_PROBE:
5776 spec->init_amp = ALC_INIT_DEFAULT;
5777 break;
Takashi Iwai7bba2152013-09-06 15:45:38 +02005778 case HDA_FIXUP_ACT_BUILD:
5779 /* this is a bit tricky; give more sane names for the main
5780 * (tablet) speaker and the dock speaker, respectively
5781 */
Takashi Iwai56798e62017-04-11 08:10:52 +02005782 rename_ctl(codec, "Speaker Playback Switch",
5783 "Dock Speaker Playback Switch");
5784 rename_ctl(codec, "Bass Speaker Playback Switch",
5785 "Speaker Playback Switch");
Takashi Iwai7bba2152013-09-06 15:45:38 +02005786 break;
5787 }
5788}
5789
David Henningsson338cae52013-10-07 10:39:59 +02005790static void alc290_fixup_mono_speakers(struct hda_codec *codec,
5791 const struct hda_fixup *fix, int action)
5792{
David Henningsson0f4881d2013-12-20 16:08:13 +01005793 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5794 /* DAC node 0x03 is giving mono output. We therefore want to
5795 make sure 0x14 (front speaker) and 0x15 (headphones) use the
5796 stereo DAC, while leaving 0x17 (bass speaker) for node 0x03. */
Michał Mirosławcaf3c042020-01-03 10:23:48 +01005797 static const hda_nid_t conn1[] = { 0x0c };
5798 snd_hda_override_conn_list(codec, 0x14, ARRAY_SIZE(conn1), conn1);
5799 snd_hda_override_conn_list(codec, 0x15, ARRAY_SIZE(conn1), conn1);
David Henningsson0f4881d2013-12-20 16:08:13 +01005800 }
David Henningsson338cae52013-10-07 10:39:59 +02005801}
5802
Hui Wangdd9aa332016-08-01 10:20:32 +08005803static void alc298_fixup_speaker_volume(struct hda_codec *codec,
5804 const struct hda_fixup *fix, int action)
5805{
5806 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5807 /* The speaker is routed to the Node 0x06 by a mistake, as a result
5808 we can't adjust the speaker's volume since this node does not has
5809 Amp-out capability. we change the speaker's route to:
5810 Node 0x02 (Audio Output) -> Node 0x0c (Audio Mixer) -> Node 0x17 (
5811 Pin Complex), since Node 0x02 has Amp-out caps, we can adjust
5812 speaker's volume now. */
5813
Michał Mirosławcaf3c042020-01-03 10:23:48 +01005814 static const hda_nid_t conn1[] = { 0x0c };
5815 snd_hda_override_conn_list(codec, 0x17, ARRAY_SIZE(conn1), conn1);
Hui Wangdd9aa332016-08-01 10:20:32 +08005816 }
5817}
5818
Takashi Iwaie312a862018-03-06 12:14:17 +01005819/* disable DAC3 (0x06) selection on NID 0x17 as it has no volume amp control */
5820static void alc295_fixup_disable_dac3(struct hda_codec *codec,
5821 const struct hda_fixup *fix, int action)
5822{
5823 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Michał Mirosławcaf3c042020-01-03 10:23:48 +01005824 static const hda_nid_t conn[] = { 0x02, 0x03 };
5825 snd_hda_override_conn_list(codec, 0x17, ARRAY_SIZE(conn), conn);
Takashi Iwaie312a862018-03-06 12:14:17 +01005826 }
5827}
5828
Jaroslav Kyselad2cd7952019-11-29 15:40:27 +01005829/* force NID 0x17 (Bass Speaker) to DAC1 to share it with the main speaker */
5830static void alc285_fixup_speaker2_to_dac1(struct hda_codec *codec,
5831 const struct hda_fixup *fix, int action)
5832{
5833 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Michał Mirosławcaf3c042020-01-03 10:23:48 +01005834 static const hda_nid_t conn[] = { 0x02 };
5835 snd_hda_override_conn_list(codec, 0x17, ARRAY_SIZE(conn), conn);
Jaroslav Kyselad2cd7952019-11-29 15:40:27 +01005836 }
5837}
5838
Keith Packard98973f22015-07-15 12:14:39 -07005839/* Hook to update amp GPIO4 for automute */
5840static void alc280_hp_gpio4_automute_hook(struct hda_codec *codec,
5841 struct hda_jack_callback *jack)
5842{
5843 struct alc_spec *spec = codec->spec;
5844
5845 snd_hda_gen_hp_automute(codec, jack);
5846 /* mute_led_polarity is set to 0, so we pass inverted value here */
Kai-Heng Fengdbd13172020-04-30 16:32:51 +08005847 alc_update_gpio_led(codec, 0x10, spec->mute_led_polarity,
5848 !spec->gen.hp_jack_present);
Keith Packard98973f22015-07-15 12:14:39 -07005849}
5850
5851/* Manage GPIOs for HP EliteBook Folio 9480m.
5852 *
5853 * GPIO4 is the headphone amplifier power control
5854 * GPIO3 is the audio output mute indicator LED
5855 */
5856
5857static void alc280_fixup_hp_9480m(struct hda_codec *codec,
5858 const struct hda_fixup *fix,
5859 int action)
5860{
5861 struct alc_spec *spec = codec->spec;
Keith Packard98973f22015-07-15 12:14:39 -07005862
Takashi Iwai01e4a272018-06-19 22:47:30 +02005863 alc_fixup_hp_gpio_led(codec, action, 0x08, 0);
Keith Packard98973f22015-07-15 12:14:39 -07005864 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai01e4a272018-06-19 22:47:30 +02005865 /* amp at GPIO4; toggled via alc280_hp_gpio4_automute_hook() */
5866 spec->gpio_mask |= 0x10;
5867 spec->gpio_dir |= 0x10;
Keith Packard98973f22015-07-15 12:14:39 -07005868 spec->gen.hp_automute_hook = alc280_hp_gpio4_automute_hook;
Keith Packard98973f22015-07-15 12:14:39 -07005869 }
5870}
5871
Takashi Iwaiae065f12018-06-19 23:00:03 +02005872static void alc275_fixup_gpio4_off(struct hda_codec *codec,
5873 const struct hda_fixup *fix,
5874 int action)
5875{
5876 struct alc_spec *spec = codec->spec;
5877
5878 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5879 spec->gpio_mask |= 0x04;
5880 spec->gpio_dir |= 0x04;
5881 /* set data bit low */
5882 }
5883}
5884
Kailang Yangca169cc2017-04-25 16:17:40 +08005885static void alc233_alc662_fixup_lenovo_dual_codecs(struct hda_codec *codec,
5886 const struct hda_fixup *fix,
5887 int action)
5888{
5889 alc_fixup_dual_codecs(codec, fix, action);
5890 switch (action) {
5891 case HDA_FIXUP_ACT_PRE_PROBE:
5892 /* override card longname to provide a unique UCM profile */
5893 strcpy(codec->card->longname, "HDAudio-Lenovo-DualCodecs");
5894 break;
5895 case HDA_FIXUP_ACT_BUILD:
5896 /* rename Capture controls depending on the codec */
5897 rename_ctl(codec, "Capture Volume",
5898 codec->addr == 0 ?
5899 "Rear-Panel Capture Volume" :
5900 "Front-Panel Capture Volume");
5901 rename_ctl(codec, "Capture Switch",
5902 codec->addr == 0 ?
5903 "Rear-Panel Capture Switch" :
5904 "Front-Panel Capture Switch");
5905 break;
5906 }
5907}
5908
Kai-Heng Feng52e4e362020-05-03 23:24:47 +08005909static void alc225_fixup_s3_pop_noise(struct hda_codec *codec,
5910 const struct hda_fixup *fix, int action)
5911{
5912 if (action != HDA_FIXUP_ACT_PRE_PROBE)
5913 return;
5914
5915 codec->power_save_node = 1;
5916}
5917
Kailang Yang92266652017-12-14 15:28:58 +08005918/* Forcibly assign NID 0x03 to HP/LO while NID 0x02 to SPK for EQ */
5919static void alc274_fixup_bind_dacs(struct hda_codec *codec,
5920 const struct hda_fixup *fix, int action)
5921{
5922 struct alc_spec *spec = codec->spec;
Michał Mirosławcaf3c042020-01-03 10:23:48 +01005923 static const hda_nid_t preferred_pairs[] = {
Kailang Yang92266652017-12-14 15:28:58 +08005924 0x21, 0x03, 0x1b, 0x03, 0x16, 0x02,
5925 0
5926 };
5927
5928 if (action != HDA_FIXUP_ACT_PRE_PROBE)
5929 return;
5930
5931 spec->gen.preferred_dacs = preferred_pairs;
Kailang Yang0700d3d2019-04-26 16:13:54 +08005932 spec->gen.auto_mute_via_amp = 1;
5933 codec->power_save_node = 0;
Kailang Yang92266652017-12-14 15:28:58 +08005934}
5935
Hui Wangc4cfcf62018-11-26 14:17:16 +08005936/* The DAC of NID 0x3 will introduce click/pop noise on headphones, so invalidate it */
5937static void alc285_fixup_invalidate_dacs(struct hda_codec *codec,
5938 const struct hda_fixup *fix, int action)
5939{
5940 if (action != HDA_FIXUP_ACT_PRE_PROBE)
5941 return;
5942
5943 snd_hda_override_wcaps(codec, 0x03, 0);
5944}
5945
Kailang Yang8983eb62019-04-03 15:31:49 +08005946static void alc295_fixup_chromebook(struct hda_codec *codec,
5947 const struct hda_fixup *fix, int action)
5948{
Kailang Yangd3ba58b2019-05-06 15:09:42 +08005949 struct alc_spec *spec = codec->spec;
5950
Kailang Yang8983eb62019-04-03 15:31:49 +08005951 switch (action) {
Kailang Yangd3ba58b2019-05-06 15:09:42 +08005952 case HDA_FIXUP_ACT_PRE_PROBE:
5953 spec->ultra_low_power = true;
5954 break;
Kailang Yang8983eb62019-04-03 15:31:49 +08005955 case HDA_FIXUP_ACT_INIT:
5956 switch (codec->core.vendor_id) {
5957 case 0x10ec0295:
5958 alc_update_coef_idx(codec, 0x4a, 0x8000, 1 << 15); /* Reset HP JD */
5959 alc_update_coef_idx(codec, 0x4a, 0x8000, 0 << 15);
5960 break;
5961 case 0x10ec0236:
5962 alc_update_coef_idx(codec, 0x1b, 0x8000, 1 << 15); /* Reset HP JD */
5963 alc_update_coef_idx(codec, 0x1b, 0x8000, 0 << 15);
5964 break;
5965 }
5966 break;
5967 }
5968}
5969
Kailang Yangd1dd4212019-01-09 17:05:24 +08005970static void alc_fixup_disable_mic_vref(struct hda_codec *codec,
5971 const struct hda_fixup *fix, int action)
5972{
5973 if (action == HDA_FIXUP_ACT_PRE_PROBE)
5974 snd_hda_codec_set_pin_target(codec, 0x19, PIN_VREFHIZ);
5975}
5976
Takashi Iwaib317b032014-01-08 11:44:21 +01005977/* for hda_fixup_thinkpad_acpi() */
5978#include "thinkpad_helper.c"
David Henningssonb67ae3f2013-11-05 13:11:37 +01005979
Takashi Iwaid5a6cab2018-06-13 12:43:10 +02005980static void alc_fixup_thinkpad_acpi(struct hda_codec *codec,
5981 const struct hda_fixup *fix, int action)
5982{
5983 alc_fixup_no_shutup(codec, fix, action); /* reduce click noise */
5984 hda_fixup_thinkpad_acpi(codec, fix, action);
5985}
5986
Tom Bridenbbf8ff62018-05-29 17:34:20 +01005987/* for alc295_fixup_hp_top_speakers */
5988#include "hp_x360_helper.c"
5989
Takashi Iwai1d045db2011-07-07 18:23:21 +02005990enum {
5991 ALC269_FIXUP_SONY_VAIO,
5992 ALC275_FIXUP_SONY_VAIO_GPIO2,
5993 ALC269_FIXUP_DELL_M101Z,
5994 ALC269_FIXUP_SKU_IGNORE,
5995 ALC269_FIXUP_ASUS_G73JW,
5996 ALC269_FIXUP_LENOVO_EAPD,
5997 ALC275_FIXUP_SONY_HWEQ,
Takashi Iwaie9bd7d52014-05-21 11:06:49 +02005998 ALC275_FIXUP_SONY_DISABLE_AAMIX,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005999 ALC271_FIXUP_DMIC,
Takashi Iwai017f2a12011-07-09 14:42:25 +02006000 ALC269_FIXUP_PCM_44K,
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02006001 ALC269_FIXUP_STEREO_DMIC,
David Henningsson7c478f02013-10-11 10:18:46 +02006002 ALC269_FIXUP_HEADSET_MIC,
Takashi Iwai24519912011-08-16 15:08:49 +02006003 ALC269_FIXUP_QUANTA_MUTE,
6004 ALC269_FIXUP_LIFEBOOK,
David Henningsson2041d562014-06-13 11:15:44 +02006005 ALC269_FIXUP_LIFEBOOK_EXTMIC,
Takashi Iwaicc7016a2015-04-08 20:47:55 +02006006 ALC269_FIXUP_LIFEBOOK_HP_PIN,
Takashi Iwai4df3fd12015-06-29 08:38:02 +02006007 ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT,
Jan-Marek Glogowskifdcc9682018-02-14 11:29:15 +01006008 ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC,
Takashi Iwaia4297b52011-08-23 18:40:12 +02006009 ALC269_FIXUP_AMIC,
6010 ALC269_FIXUP_DMIC,
6011 ALC269VB_FIXUP_AMIC,
6012 ALC269VB_FIXUP_DMIC,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01006013 ALC269_FIXUP_HP_MUTE_LED,
David Henningssond06ac142013-02-18 11:41:55 +01006014 ALC269_FIXUP_HP_MUTE_LED_MIC1,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01006015 ALC269_FIXUP_HP_MUTE_LED_MIC2,
Tom Briden7f783bd2017-03-25 10:12:01 +00006016 ALC269_FIXUP_HP_MUTE_LED_MIC3,
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01006017 ALC269_FIXUP_HP_GPIO_LED,
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08006018 ALC269_FIXUP_HP_GPIO_MIC1_LED,
6019 ALC269_FIXUP_HP_LINE1_MIC1_LED,
David Henningsson693b6132012-06-22 19:12:10 +02006020 ALC269_FIXUP_INV_DMIC,
David Henningsson108cc102012-07-20 10:37:25 +02006021 ALC269_FIXUP_LENOVO_DOCK,
Takashi Iwaib590b382020-05-14 18:05:33 +02006022 ALC269_FIXUP_LENOVO_DOCK_LIMIT_BOOST,
Takashi Iwai9b745ab2014-03-07 08:37:19 +01006023 ALC269_FIXUP_NO_SHUTUP,
David Henningsson88cfcf82013-10-11 10:18:45 +02006024 ALC286_FIXUP_SONY_MIC_NO_PRESENCE,
David Henningsson108cc102012-07-20 10:37:25 +02006025 ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT,
David Henningsson73bdd592013-04-15 15:44:14 +02006026 ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
6027 ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
David Henningsson338cae52013-10-07 10:39:59 +02006028 ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
Kailang Yangfcc6c872017-06-29 15:21:27 +08006029 ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
David Henningsson73bdd592013-04-15 15:44:14 +02006030 ALC269_FIXUP_HEADSET_MODE,
6031 ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC,
Takashi Iwai78197172015-06-27 10:21:13 +02006032 ALC269_FIXUP_ASPIRE_HEADSET_MIC,
David Henningssond240d1d2013-04-15 12:50:02 +02006033 ALC269_FIXUP_ASUS_X101_FUNC,
6034 ALC269_FIXUP_ASUS_X101_VERB,
6035 ALC269_FIXUP_ASUS_X101,
Dylan Reid08a978d2012-11-18 22:56:40 -08006036 ALC271_FIXUP_AMIC_MIC2,
6037 ALC271_FIXUP_HP_GATE_MIC_JACK,
Oleksij Rempelb1e89722013-12-04 20:50:53 +01006038 ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572,
Dylan Reid42397002013-04-05 14:58:22 -07006039 ALC269_FIXUP_ACER_AC700,
David Henningsson3e0d6112013-04-22 14:30:14 +02006040 ALC269_FIXUP_LIMIT_INT_MIC_BOOST,
Oleksij Rempel2cede302013-11-27 17:12:03 +01006041 ALC269VB_FIXUP_ASUS_ZENBOOK,
Takashi Iwai23870832013-11-29 14:13:12 +01006042 ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A,
David Henningsson8e35cd42013-11-06 11:20:01 +01006043 ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED,
Anisse Astier02b504d2013-06-03 11:53:10 +02006044 ALC269VB_FIXUP_ORDISSIMO_EVE2,
Kailang Yangcd217a62013-08-22 10:15:24 +02006045 ALC283_FIXUP_CHROME_BOOK,
Kailang Yang0202e992013-12-02 15:20:15 +08006046 ALC283_FIXUP_SENSE_COMBO_JACK,
Takashi Iwai7bba2152013-09-06 15:45:38 +02006047 ALC282_FIXUP_ASUS_TX300,
Kailang Yang1bb3e062013-09-27 13:10:25 +02006048 ALC283_FIXUP_INT_MIC,
David Henningsson338cae52013-10-07 10:39:59 +02006049 ALC290_FIXUP_MONO_SPEAKERS,
David Henningsson0f4881d2013-12-20 16:08:13 +01006050 ALC290_FIXUP_MONO_SPEAKERS_HSJACK,
6051 ALC290_FIXUP_SUBWOOFER,
6052 ALC290_FIXUP_SUBWOOFER_HSJACK,
David Henningssonb67ae3f2013-11-05 13:11:37 +01006053 ALC269_FIXUP_THINKPAD_ACPI,
David Henningsson56f27012016-01-11 09:33:14 +01006054 ALC269_FIXUP_DMIC_THINKPAD_ACPI,
Chris Chiu5824ce82017-02-28 14:17:11 -06006055 ALC255_FIXUP_ACER_MIC_NO_PRESENCE,
Chris Chiu615966a2017-02-28 14:17:12 -06006056 ALC255_FIXUP_ASUS_MIC_NO_PRESENCE,
Kailang Yang9a22a8f52013-11-08 15:54:49 +08006057 ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Kailang Yang31278992014-03-03 15:27:22 +08006058 ALC255_FIXUP_DELL2_MIC_NO_PRESENCE,
Kailang Yang9a22a8f52013-11-08 15:54:49 +08006059 ALC255_FIXUP_HEADSET_MODE,
Kailang Yang31278992014-03-03 15:27:22 +08006060 ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC,
Kailang Yanga22aa262014-04-23 17:34:28 +08006061 ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
Takashi Iwai1c37c222014-05-06 17:34:42 +02006062 ALC292_FIXUP_TPT440_DOCK,
Takashi Iwai9a811232015-12-09 15:17:43 +01006063 ALC292_FIXUP_TPT440,
Anisse Astierabaa22742016-08-24 09:14:13 +02006064 ALC283_FIXUP_HEADSET_MIC,
Takashi Iwaib3802782018-11-26 17:47:46 +01006065 ALC255_FIXUP_MIC_MUTE_LED,
Takashi Iwai1a22e772014-08-27 08:19:05 +02006066 ALC282_FIXUP_ASPIRE_V5_PINS,
David Henningsson7a5255f2014-10-30 08:26:01 +01006067 ALC280_FIXUP_HP_GPIO4,
Kailang Yangeaa8e5e2014-11-21 15:49:11 +08006068 ALC286_FIXUP_HP_GPIO_LED,
David Henningsson33f4acd2015-01-07 15:50:13 +01006069 ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY,
TienFu Chenb4b33f92015-01-20 15:06:21 +01006070 ALC280_FIXUP_HP_DOCK_PINS,
Jaroslav Kysela04d54662017-03-09 13:29:13 +01006071 ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED,
Keith Packard98973f22015-07-15 12:14:39 -07006072 ALC280_FIXUP_HP_9480M,
Kailang Yange1e62b92015-04-08 16:01:22 +08006073 ALC288_FIXUP_DELL_HEADSET_MODE,
6074 ALC288_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang831bfdf92015-06-26 12:35:17 +08006075 ALC288_FIXUP_DELL_XPS_13,
6076 ALC288_FIXUP_DISABLE_AAMIX,
Takashi Iwai5fab5822020-01-05 09:11:19 +01006077 ALC292_FIXUP_DELL_E7X_AAMIX,
Takashi Iwai8b99aba2015-06-15 11:59:32 +02006078 ALC292_FIXUP_DELL_E7X,
6079 ALC292_FIXUP_DISABLE_AAMIX,
David Henningssonc04017e2015-12-15 14:44:03 +01006080 ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK,
James McDonnell54324222019-09-16 14:53:38 +00006081 ALC298_FIXUP_ALIENWARE_MIC_NO_PRESENCE,
Kailang Yang977e6272015-05-18 15:31:20 +08006082 ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang2f726ae2017-03-31 10:31:40 +08006083 ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE,
Kailang Yang6ed11312015-10-26 15:37:39 +08006084 ALC275_FIXUP_DELL_XPS,
Hui Wang23adc192015-12-08 12:27:18 +08006085 ALC293_FIXUP_LENOVO_SPK_NOISE,
Kailang3694cb22015-12-28 11:35:24 +08006086 ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY,
Kai-Heng Feng3b43b712016-02-25 15:19:38 +08006087 ALC255_FIXUP_DELL_SPK_NOISE,
Kailang Yangd1dd4212019-01-09 17:05:24 +08006088 ALC225_FIXUP_DISABLE_MIC_VREF,
David Henningsson2ae95572016-02-25 09:37:05 +01006089 ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
Takashi Iwaie312a862018-03-06 12:14:17 +01006090 ALC295_FIXUP_DISABLE_DAC3,
Jaroslav Kyselad2cd7952019-11-29 15:40:27 +01006091 ALC285_FIXUP_SPEAKER2_TO_DAC1,
Takashi Iwaif8839822016-02-25 14:31:59 +01006092 ALC280_FIXUP_HP_HEADSET_MIC,
Hui Wange549d192016-04-01 11:00:15 +08006093 ALC221_FIXUP_HP_FRONT_MIC,
Sven Eckelmannc636b952016-04-11 16:55:26 +02006094 ALC292_FIXUP_TPT460,
Hui Wangdd9aa332016-08-01 10:20:32 +08006095 ALC298_FIXUP_SPK_VOLUME,
Kai-Heng Fengfd06c772016-08-30 15:36:34 +08006096 ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER,
Gabriele Mazzotta823ff162016-12-24 19:50:01 +01006097 ALC269_FIXUP_ATIV_BOOK_8,
Kailang Yang9eb5d0e2017-01-17 15:40:25 +08006098 ALC221_FIXUP_HP_MIC_NO_PRESENCE,
Chris Chiuc1732ed2017-02-28 14:17:13 -06006099 ALC256_FIXUP_ASUS_HEADSET_MODE,
6100 ALC256_FIXUP_ASUS_MIC,
Chris Chiueeed4cd2017-02-28 14:17:15 -06006101 ALC256_FIXUP_ASUS_AIO_GPIO2,
Chris Chiu216d7ae2017-02-28 14:17:14 -06006102 ALC233_FIXUP_ASUS_MIC_NO_PRESENCE,
6103 ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE,
Kailang Yangca169cc2017-04-25 16:17:40 +08006104 ALC233_FIXUP_LENOVO_MULTI_CODECS,
Jian-Hong Panea5c7eb2019-04-01 11:25:05 +08006105 ALC233_FIXUP_ACER_HEADSET_MIC,
Hui Wangf33f79f2017-07-07 12:08:29 +08006106 ALC294_FIXUP_LENOVO_MIC_LOCATION,
Kailang Yang5f364132017-07-25 16:28:16 +08006107 ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE,
Kai-Heng Feng52e4e362020-05-03 23:24:47 +08006108 ALC225_FIXUP_S3_POP_NOISE,
PeiSen Houb84e8432017-09-01 15:11:56 +08006109 ALC700_FIXUP_INTEL_REFERENCE,
Kailang Yang92266652017-12-14 15:28:58 +08006110 ALC274_FIXUP_DELL_BIND_DACS,
6111 ALC274_FIXUP_DELL_AIO_LINEOUT_VERB,
Takashi Iwai399c01a2020-05-26 08:24:06 +02006112 ALC298_FIXUP_TPT470_DOCK_FIX,
Kailang Yang61fcf8e2018-02-02 15:26:46 +08006113 ALC298_FIXUP_TPT470_DOCK,
Kailang Yangae104a22018-02-05 16:07:20 +08006114 ALC255_FIXUP_DUMMY_LINEOUT_VERB,
Kailang Yangf0ba9d62018-03-16 11:46:08 +08006115 ALC255_FIXUP_DELL_HEADSET_MIC,
Ayman Bagabas0fbf21c2019-05-23 05:30:11 -04006116 ALC256_FIXUP_HUAWEI_MACH_WX9_PINS,
Tomas Espeletaa2ef03f2019-08-09 16:37:54 +02006117 ALC298_FIXUP_HUAWEI_MBX_STEREO,
Tom Bridenbbf8ff62018-05-29 17:34:20 +01006118 ALC295_FIXUP_HP_X360,
Kailang Yang8a328ac2018-08-21 16:54:41 +08006119 ALC221_FIXUP_HP_HEADSET_MIC,
Hui Wangc4cfcf62018-11-26 14:17:16 +08006120 ALC285_FIXUP_LENOVO_HEADPHONE_NOISE,
Girija Kumar Kasinadhunie8ed64b2018-11-26 13:40:46 -05006121 ALC295_FIXUP_HP_AUTO_MUTE,
Chris Chiu33aaebd2018-12-05 14:48:53 +08006122 ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE,
Chris Chiud8ae4582018-12-07 17:17:11 +08006123 ALC294_FIXUP_ASUS_MIC,
Jian-Hong Pan4e051102018-12-07 17:17:12 +08006124 ALC294_FIXUP_ASUS_HEADSET_MIC,
6125 ALC294_FIXUP_ASUS_SPK,
Jeremy Soller89e3a562019-01-30 16:12:31 -07006126 ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE,
Hui Wangc8c6ee62019-02-14 11:41:33 +08006127 ALC285_FIXUP_LENOVO_PC_BEEP_IN_NOISE,
Jian-Hong Pancbc05fd2019-03-13 17:33:24 +08006128 ALC255_FIXUP_ACER_HEADSET_MIC,
Kailang Yang10f5b1b2019-02-21 16:10:22 +08006129 ALC295_FIXUP_CHROME_BOOK,
Kailang Yang8983eb62019-04-03 15:31:49 +08006130 ALC225_FIXUP_HEADSET_JACK,
Kailang Yang136824e2019-03-14 16:22:45 +08006131 ALC225_FIXUP_DELL_WYSE_AIO_MIC_NO_PRESENCE,
6132 ALC225_FIXUP_WYSE_AUTO_MUTE,
6133 ALC225_FIXUP_WYSE_DISABLE_MIC_VREF,
Jian-Hong Pan667a8f72019-03-15 17:51:09 +08006134 ALC286_FIXUP_ACER_AIO_HEADSET_MIC,
Daniel Drake8c8967a2019-10-17 16:15:01 +08006135 ALC256_FIXUP_ASUS_HEADSET_MIC,
Jian-Hong Pane1037352019-03-22 11:37:18 +08006136 ALC256_FIXUP_ASUS_MIC_NO_PRESENCE,
Bernhard Rosenkraenzere2a829b2019-03-05 00:38:19 +01006137 ALC299_FIXUP_PREDATOR_SPK,
Jan-Marek Glogowskibd9c10b2019-09-15 16:57:28 +02006138 ALC256_FIXUP_MEDION_HEADSET_NO_PRESENCE,
Kailang Yange79c2262019-12-19 14:12:15 +08006139 ALC289_FIXUP_DELL_SPK2,
6140 ALC289_FIXUP_DUAL_SPK,
Chris Chiu48e01502019-12-30 11:11:18 +08006141 ALC294_FIXUP_SPK2_TO_DAC1,
6142 ALC294_FIXUP_ASUS_DUAL_SPK,
Kailang Yang76f7dec2020-02-10 16:30:26 +08006143 ALC285_FIXUP_THINKPAD_HEADSET_JACK,
Jian-Hong Pan8b33a132020-02-25 15:29:21 +08006144 ALC294_FIXUP_ASUS_HPE,
Takashi Iwai1b94e592020-05-12 09:32:03 +02006145 ALC294_FIXUP_ASUS_COEF_1B,
Kai-Heng Fengf5a88b02020-03-27 12:46:25 +08006146 ALC285_FIXUP_HP_GPIO_LED,
Kailang Yang431e76c2020-04-07 14:40:20 +08006147 ALC285_FIXUP_HP_MUTE_LED,
Kailang Yang24164f42020-04-07 14:52:42 +08006148 ALC236_FIXUP_HP_MUTE_LED,
Mike Pozulp14425f12020-05-09 20:28:37 -07006149 ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET,
Chris Chiu9e433422020-05-12 14:15:24 +08006150 ALC295_FIXUP_ASUS_MIC_NO_PRESENCE,
Takashi Iwai1d045db2011-07-07 18:23:21 +02006151};
6152
Takashi Iwai1727a772013-01-10 09:52:52 +01006153static const struct hda_fixup alc269_fixups[] = {
Takashi Iwai1d045db2011-07-07 18:23:21 +02006154 [ALC269_FIXUP_SONY_VAIO] = {
Takashi Iwaifd108212013-01-10 10:18:14 +01006155 .type = HDA_FIXUP_PINCTLS,
6156 .v.pins = (const struct hda_pintbl[]) {
6157 {0x19, PIN_VREFGRD},
Takashi Iwai1d045db2011-07-07 18:23:21 +02006158 {}
6159 }
6160 },
6161 [ALC275_FIXUP_SONY_VAIO_GPIO2] = {
Takashi Iwaiae065f12018-06-19 23:00:03 +02006162 .type = HDA_FIXUP_FUNC,
6163 .v.func = alc275_fixup_gpio4_off,
Takashi Iwai1d045db2011-07-07 18:23:21 +02006164 .chained = true,
6165 .chain_id = ALC269_FIXUP_SONY_VAIO
6166 },
6167 [ALC269_FIXUP_DELL_M101Z] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006168 .type = HDA_FIXUP_VERBS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02006169 .v.verbs = (const struct hda_verb[]) {
6170 /* Enables internal speaker */
6171 {0x20, AC_VERB_SET_COEF_INDEX, 13},
6172 {0x20, AC_VERB_SET_PROC_COEF, 0x4040},
6173 {}
6174 }
6175 },
6176 [ALC269_FIXUP_SKU_IGNORE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006177 .type = HDA_FIXUP_FUNC,
Takashi Iwai23d30f22012-05-07 17:17:32 +02006178 .v.func = alc_fixup_sku_ignore,
Takashi Iwai1d045db2011-07-07 18:23:21 +02006179 },
6180 [ALC269_FIXUP_ASUS_G73JW] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006181 .type = HDA_FIXUP_PINS,
6182 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02006183 { 0x17, 0x99130111 }, /* subwoofer */
6184 { }
6185 }
6186 },
6187 [ALC269_FIXUP_LENOVO_EAPD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006188 .type = HDA_FIXUP_VERBS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02006189 .v.verbs = (const struct hda_verb[]) {
6190 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
6191 {}
6192 }
6193 },
6194 [ALC275_FIXUP_SONY_HWEQ] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006195 .type = HDA_FIXUP_FUNC,
Takashi Iwai1d045db2011-07-07 18:23:21 +02006196 .v.func = alc269_fixup_hweq,
6197 .chained = true,
6198 .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2
6199 },
Takashi Iwaie9bd7d52014-05-21 11:06:49 +02006200 [ALC275_FIXUP_SONY_DISABLE_AAMIX] = {
6201 .type = HDA_FIXUP_FUNC,
6202 .v.func = alc_fixup_disable_aamix,
6203 .chained = true,
6204 .chain_id = ALC269_FIXUP_SONY_VAIO
6205 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02006206 [ALC271_FIXUP_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006207 .type = HDA_FIXUP_FUNC,
Takashi Iwai1d045db2011-07-07 18:23:21 +02006208 .v.func = alc271_fixup_dmic,
6209 },
Takashi Iwai017f2a12011-07-09 14:42:25 +02006210 [ALC269_FIXUP_PCM_44K] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006211 .type = HDA_FIXUP_FUNC,
Takashi Iwai017f2a12011-07-09 14:42:25 +02006212 .v.func = alc269_fixup_pcm_44k,
David Henningsson012e7eb2012-08-08 08:43:37 +02006213 .chained = true,
6214 .chain_id = ALC269_FIXUP_QUANTA_MUTE
Takashi Iwai017f2a12011-07-09 14:42:25 +02006215 },
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02006216 [ALC269_FIXUP_STEREO_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006217 .type = HDA_FIXUP_FUNC,
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02006218 .v.func = alc269_fixup_stereo_dmic,
6219 },
David Henningsson7c478f02013-10-11 10:18:46 +02006220 [ALC269_FIXUP_HEADSET_MIC] = {
6221 .type = HDA_FIXUP_FUNC,
6222 .v.func = alc269_fixup_headset_mic,
6223 },
Takashi Iwai24519912011-08-16 15:08:49 +02006224 [ALC269_FIXUP_QUANTA_MUTE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006225 .type = HDA_FIXUP_FUNC,
Takashi Iwai24519912011-08-16 15:08:49 +02006226 .v.func = alc269_fixup_quanta_mute,
6227 },
6228 [ALC269_FIXUP_LIFEBOOK] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006229 .type = HDA_FIXUP_PINS,
6230 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai24519912011-08-16 15:08:49 +02006231 { 0x1a, 0x2101103f }, /* dock line-out */
6232 { 0x1b, 0x23a11040 }, /* dock mic-in */
6233 { }
6234 },
6235 .chained = true,
6236 .chain_id = ALC269_FIXUP_QUANTA_MUTE
6237 },
David Henningsson2041d562014-06-13 11:15:44 +02006238 [ALC269_FIXUP_LIFEBOOK_EXTMIC] = {
6239 .type = HDA_FIXUP_PINS,
6240 .v.pins = (const struct hda_pintbl[]) {
6241 { 0x19, 0x01a1903c }, /* headset mic, with jack detect */
6242 { }
6243 },
6244 },
Takashi Iwaicc7016a2015-04-08 20:47:55 +02006245 [ALC269_FIXUP_LIFEBOOK_HP_PIN] = {
6246 .type = HDA_FIXUP_PINS,
6247 .v.pins = (const struct hda_pintbl[]) {
6248 { 0x21, 0x0221102f }, /* HP out */
6249 { }
6250 },
6251 },
Takashi Iwai4df3fd12015-06-29 08:38:02 +02006252 [ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT] = {
6253 .type = HDA_FIXUP_FUNC,
6254 .v.func = alc269_fixup_pincfg_no_hp_to_lineout,
6255 },
Jan-Marek Glogowskifdcc9682018-02-14 11:29:15 +01006256 [ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC] = {
6257 .type = HDA_FIXUP_FUNC,
6258 .v.func = alc269_fixup_pincfg_U7x7_headset_mic,
6259 },
Takashi Iwaia4297b52011-08-23 18:40:12 +02006260 [ALC269_FIXUP_AMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006261 .type = HDA_FIXUP_PINS,
6262 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaia4297b52011-08-23 18:40:12 +02006263 { 0x14, 0x99130110 }, /* speaker */
6264 { 0x15, 0x0121401f }, /* HP out */
6265 { 0x18, 0x01a19c20 }, /* mic */
6266 { 0x19, 0x99a3092f }, /* int-mic */
6267 { }
6268 },
6269 },
6270 [ALC269_FIXUP_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006271 .type = HDA_FIXUP_PINS,
6272 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaia4297b52011-08-23 18:40:12 +02006273 { 0x12, 0x99a3092f }, /* int-mic */
6274 { 0x14, 0x99130110 }, /* speaker */
6275 { 0x15, 0x0121401f }, /* HP out */
6276 { 0x18, 0x01a19c20 }, /* mic */
6277 { }
6278 },
6279 },
6280 [ALC269VB_FIXUP_AMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006281 .type = HDA_FIXUP_PINS,
6282 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaia4297b52011-08-23 18:40:12 +02006283 { 0x14, 0x99130110 }, /* speaker */
6284 { 0x18, 0x01a19c20 }, /* mic */
6285 { 0x19, 0x99a3092f }, /* int-mic */
6286 { 0x21, 0x0121401f }, /* HP out */
6287 { }
6288 },
6289 },
David Henningsson2267ea92012-01-03 08:45:56 +01006290 [ALC269VB_FIXUP_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006291 .type = HDA_FIXUP_PINS,
6292 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaia4297b52011-08-23 18:40:12 +02006293 { 0x12, 0x99a3092f }, /* int-mic */
6294 { 0x14, 0x99130110 }, /* speaker */
6295 { 0x18, 0x01a19c20 }, /* mic */
6296 { 0x21, 0x0121401f }, /* HP out */
6297 { }
6298 },
6299 },
Takashi Iwai08fb0d02013-01-10 17:33:58 +01006300 [ALC269_FIXUP_HP_MUTE_LED] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006301 .type = HDA_FIXUP_FUNC,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01006302 .v.func = alc269_fixup_hp_mute_led,
David Henningsson6d3cd5d2013-01-07 12:03:47 +01006303 },
David Henningssond06ac142013-02-18 11:41:55 +01006304 [ALC269_FIXUP_HP_MUTE_LED_MIC1] = {
6305 .type = HDA_FIXUP_FUNC,
6306 .v.func = alc269_fixup_hp_mute_led_mic1,
6307 },
Takashi Iwai08fb0d02013-01-10 17:33:58 +01006308 [ALC269_FIXUP_HP_MUTE_LED_MIC2] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006309 .type = HDA_FIXUP_FUNC,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01006310 .v.func = alc269_fixup_hp_mute_led_mic2,
Takashi Iwai420b0fe2012-03-12 12:35:27 +01006311 },
Tom Briden7f783bd2017-03-25 10:12:01 +00006312 [ALC269_FIXUP_HP_MUTE_LED_MIC3] = {
6313 .type = HDA_FIXUP_FUNC,
6314 .v.func = alc269_fixup_hp_mute_led_mic3,
Girija Kumar Kasinadhunie8ed64b2018-11-26 13:40:46 -05006315 .chained = true,
6316 .chain_id = ALC295_FIXUP_HP_AUTO_MUTE
Tom Briden7f783bd2017-03-25 10:12:01 +00006317 },
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01006318 [ALC269_FIXUP_HP_GPIO_LED] = {
6319 .type = HDA_FIXUP_FUNC,
6320 .v.func = alc269_fixup_hp_gpio_led,
6321 },
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08006322 [ALC269_FIXUP_HP_GPIO_MIC1_LED] = {
6323 .type = HDA_FIXUP_FUNC,
6324 .v.func = alc269_fixup_hp_gpio_mic1_led,
6325 },
6326 [ALC269_FIXUP_HP_LINE1_MIC1_LED] = {
6327 .type = HDA_FIXUP_FUNC,
6328 .v.func = alc269_fixup_hp_line1_mic1_led,
6329 },
David Henningsson693b6132012-06-22 19:12:10 +02006330 [ALC269_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006331 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02006332 .v.func = alc_fixup_inv_dmic,
David Henningsson693b6132012-06-22 19:12:10 +02006333 },
Takashi Iwai9b745ab2014-03-07 08:37:19 +01006334 [ALC269_FIXUP_NO_SHUTUP] = {
6335 .type = HDA_FIXUP_FUNC,
6336 .v.func = alc_fixup_no_shutup,
6337 },
David Henningsson108cc102012-07-20 10:37:25 +02006338 [ALC269_FIXUP_LENOVO_DOCK] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006339 .type = HDA_FIXUP_PINS,
6340 .v.pins = (const struct hda_pintbl[]) {
David Henningsson108cc102012-07-20 10:37:25 +02006341 { 0x19, 0x23a11040 }, /* dock mic */
6342 { 0x1b, 0x2121103f }, /* dock headphone */
6343 { }
6344 },
6345 .chained = true,
6346 .chain_id = ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT
6347 },
Takashi Iwaib590b382020-05-14 18:05:33 +02006348 [ALC269_FIXUP_LENOVO_DOCK_LIMIT_BOOST] = {
6349 .type = HDA_FIXUP_FUNC,
6350 .v.func = alc269_fixup_limit_int_mic_boost,
6351 .chained = true,
6352 .chain_id = ALC269_FIXUP_LENOVO_DOCK,
6353 },
David Henningsson108cc102012-07-20 10:37:25 +02006354 [ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006355 .type = HDA_FIXUP_FUNC,
David Henningsson108cc102012-07-20 10:37:25 +02006356 .v.func = alc269_fixup_pincfg_no_hp_to_lineout,
David Henningsson52129002013-11-19 10:25:53 +01006357 .chained = true,
6358 .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
David Henningsson108cc102012-07-20 10:37:25 +02006359 },
David Henningsson73bdd592013-04-15 15:44:14 +02006360 [ALC269_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6361 .type = HDA_FIXUP_PINS,
6362 .v.pins = (const struct hda_pintbl[]) {
6363 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6364 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6365 { }
6366 },
6367 .chained = true,
6368 .chain_id = ALC269_FIXUP_HEADSET_MODE
6369 },
6370 [ALC269_FIXUP_DELL2_MIC_NO_PRESENCE] = {
6371 .type = HDA_FIXUP_PINS,
6372 .v.pins = (const struct hda_pintbl[]) {
6373 { 0x16, 0x21014020 }, /* dock line out */
6374 { 0x19, 0x21a19030 }, /* dock mic */
6375 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6376 { }
6377 },
6378 .chained = true,
6379 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
6380 },
David Henningsson338cae52013-10-07 10:39:59 +02006381 [ALC269_FIXUP_DELL3_MIC_NO_PRESENCE] = {
6382 .type = HDA_FIXUP_PINS,
6383 .v.pins = (const struct hda_pintbl[]) {
6384 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6385 { }
6386 },
6387 .chained = true,
6388 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
6389 },
Kailang Yangfcc6c872017-06-29 15:21:27 +08006390 [ALC269_FIXUP_DELL4_MIC_NO_PRESENCE] = {
6391 .type = HDA_FIXUP_PINS,
6392 .v.pins = (const struct hda_pintbl[]) {
6393 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6394 { 0x1b, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6395 { }
6396 },
6397 .chained = true,
6398 .chain_id = ALC269_FIXUP_HEADSET_MODE
6399 },
David Henningsson73bdd592013-04-15 15:44:14 +02006400 [ALC269_FIXUP_HEADSET_MODE] = {
6401 .type = HDA_FIXUP_FUNC,
6402 .v.func = alc_fixup_headset_mode,
Hui Wang6676f302014-11-18 17:57:41 +08006403 .chained = true,
Takashi Iwaib3802782018-11-26 17:47:46 +01006404 .chain_id = ALC255_FIXUP_MIC_MUTE_LED
David Henningsson73bdd592013-04-15 15:44:14 +02006405 },
6406 [ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC] = {
6407 .type = HDA_FIXUP_FUNC,
6408 .v.func = alc_fixup_headset_mode_no_hp_mic,
6409 },
Takashi Iwai78197172015-06-27 10:21:13 +02006410 [ALC269_FIXUP_ASPIRE_HEADSET_MIC] = {
6411 .type = HDA_FIXUP_PINS,
6412 .v.pins = (const struct hda_pintbl[]) {
6413 { 0x19, 0x01a1913c }, /* headset mic w/o jack detect */
6414 { }
6415 },
6416 .chained = true,
6417 .chain_id = ALC269_FIXUP_HEADSET_MODE,
6418 },
David Henningsson88cfcf82013-10-11 10:18:45 +02006419 [ALC286_FIXUP_SONY_MIC_NO_PRESENCE] = {
6420 .type = HDA_FIXUP_PINS,
6421 .v.pins = (const struct hda_pintbl[]) {
6422 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6423 { }
6424 },
David Henningssonfbc78ad2013-10-11 13:46:04 +02006425 .chained = true,
6426 .chain_id = ALC269_FIXUP_HEADSET_MIC
David Henningsson88cfcf82013-10-11 10:18:45 +02006427 },
Ayman Bagabas0fbf21c2019-05-23 05:30:11 -04006428 [ALC256_FIXUP_HUAWEI_MACH_WX9_PINS] = {
Ayman Bagabas8ac51bb2018-12-12 18:07:57 -05006429 .type = HDA_FIXUP_PINS,
6430 .v.pins = (const struct hda_pintbl[]) {
6431 {0x12, 0x90a60130},
6432 {0x13, 0x40000000},
6433 {0x14, 0x90170110},
6434 {0x18, 0x411111f0},
6435 {0x19, 0x04a11040},
6436 {0x1a, 0x411111f0},
6437 {0x1b, 0x90170112},
6438 {0x1d, 0x40759a05},
6439 {0x1e, 0x411111f0},
6440 {0x21, 0x04211020},
6441 { }
6442 },
Ayman Bagabase2744fd2018-12-12 18:07:59 -05006443 .chained = true,
6444 .chain_id = ALC255_FIXUP_MIC_MUTE_LED
Ayman Bagabas8ac51bb2018-12-12 18:07:57 -05006445 },
Tomas Espeletaa2ef03f2019-08-09 16:37:54 +02006446 [ALC298_FIXUP_HUAWEI_MBX_STEREO] = {
6447 .type = HDA_FIXUP_FUNC,
6448 .v.func = alc298_fixup_huawei_mbx_stereo,
6449 .chained = true,
6450 .chain_id = ALC255_FIXUP_MIC_MUTE_LED
6451 },
David Henningssond240d1d2013-04-15 12:50:02 +02006452 [ALC269_FIXUP_ASUS_X101_FUNC] = {
6453 .type = HDA_FIXUP_FUNC,
6454 .v.func = alc269_fixup_x101_headset_mic,
6455 },
6456 [ALC269_FIXUP_ASUS_X101_VERB] = {
6457 .type = HDA_FIXUP_VERBS,
6458 .v.verbs = (const struct hda_verb[]) {
6459 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6460 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
6461 {0x20, AC_VERB_SET_PROC_COEF, 0x0310},
6462 { }
6463 },
6464 .chained = true,
6465 .chain_id = ALC269_FIXUP_ASUS_X101_FUNC
6466 },
6467 [ALC269_FIXUP_ASUS_X101] = {
6468 .type = HDA_FIXUP_PINS,
6469 .v.pins = (const struct hda_pintbl[]) {
6470 { 0x18, 0x04a1182c }, /* Headset mic */
6471 { }
6472 },
6473 .chained = true,
6474 .chain_id = ALC269_FIXUP_ASUS_X101_VERB
6475 },
Dylan Reid08a978d2012-11-18 22:56:40 -08006476 [ALC271_FIXUP_AMIC_MIC2] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006477 .type = HDA_FIXUP_PINS,
6478 .v.pins = (const struct hda_pintbl[]) {
Dylan Reid08a978d2012-11-18 22:56:40 -08006479 { 0x14, 0x99130110 }, /* speaker */
6480 { 0x19, 0x01a19c20 }, /* mic */
6481 { 0x1b, 0x99a7012f }, /* int-mic */
6482 { 0x21, 0x0121401f }, /* HP out */
6483 { }
6484 },
6485 },
6486 [ALC271_FIXUP_HP_GATE_MIC_JACK] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006487 .type = HDA_FIXUP_FUNC,
Dylan Reid08a978d2012-11-18 22:56:40 -08006488 .v.func = alc271_hp_gate_mic_jack,
6489 .chained = true,
6490 .chain_id = ALC271_FIXUP_AMIC_MIC2,
6491 },
Oleksij Rempelb1e89722013-12-04 20:50:53 +01006492 [ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572] = {
6493 .type = HDA_FIXUP_FUNC,
6494 .v.func = alc269_fixup_limit_int_mic_boost,
6495 .chained = true,
6496 .chain_id = ALC271_FIXUP_HP_GATE_MIC_JACK,
6497 },
Dylan Reid42397002013-04-05 14:58:22 -07006498 [ALC269_FIXUP_ACER_AC700] = {
6499 .type = HDA_FIXUP_PINS,
6500 .v.pins = (const struct hda_pintbl[]) {
6501 { 0x12, 0x99a3092f }, /* int-mic */
6502 { 0x14, 0x99130110 }, /* speaker */
6503 { 0x18, 0x03a11c20 }, /* mic */
6504 { 0x1e, 0x0346101e }, /* SPDIF1 */
6505 { 0x21, 0x0321101f }, /* HP out */
6506 { }
6507 },
6508 .chained = true,
6509 .chain_id = ALC271_FIXUP_DMIC,
6510 },
David Henningsson3e0d6112013-04-22 14:30:14 +02006511 [ALC269_FIXUP_LIMIT_INT_MIC_BOOST] = {
6512 .type = HDA_FIXUP_FUNC,
6513 .v.func = alc269_fixup_limit_int_mic_boost,
David Henningsson27937692013-11-18 11:51:47 +01006514 .chained = true,
6515 .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
David Henningsson3e0d6112013-04-22 14:30:14 +02006516 },
Oleksij Rempel2cede302013-11-27 17:12:03 +01006517 [ALC269VB_FIXUP_ASUS_ZENBOOK] = {
6518 .type = HDA_FIXUP_FUNC,
6519 .v.func = alc269_fixup_limit_int_mic_boost,
6520 .chained = true,
6521 .chain_id = ALC269VB_FIXUP_DMIC,
6522 },
Takashi Iwai23870832013-11-29 14:13:12 +01006523 [ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A] = {
6524 .type = HDA_FIXUP_VERBS,
6525 .v.verbs = (const struct hda_verb[]) {
6526 /* class-D output amp +5dB */
6527 { 0x20, AC_VERB_SET_COEF_INDEX, 0x12 },
6528 { 0x20, AC_VERB_SET_PROC_COEF, 0x2800 },
6529 {}
6530 },
6531 .chained = true,
6532 .chain_id = ALC269VB_FIXUP_ASUS_ZENBOOK,
6533 },
David Henningsson8e35cd42013-11-06 11:20:01 +01006534 [ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED] = {
6535 .type = HDA_FIXUP_FUNC,
6536 .v.func = alc269_fixup_limit_int_mic_boost,
6537 .chained = true,
6538 .chain_id = ALC269_FIXUP_HP_MUTE_LED_MIC1,
6539 },
Anisse Astier02b504d2013-06-03 11:53:10 +02006540 [ALC269VB_FIXUP_ORDISSIMO_EVE2] = {
6541 .type = HDA_FIXUP_PINS,
6542 .v.pins = (const struct hda_pintbl[]) {
6543 { 0x12, 0x99a3092f }, /* int-mic */
6544 { 0x18, 0x03a11d20 }, /* mic */
6545 { 0x19, 0x411111f0 }, /* Unused bogus pin */
6546 { }
6547 },
6548 },
Kailang Yangcd217a62013-08-22 10:15:24 +02006549 [ALC283_FIXUP_CHROME_BOOK] = {
6550 .type = HDA_FIXUP_FUNC,
6551 .v.func = alc283_fixup_chromebook,
6552 },
Kailang Yang0202e992013-12-02 15:20:15 +08006553 [ALC283_FIXUP_SENSE_COMBO_JACK] = {
6554 .type = HDA_FIXUP_FUNC,
6555 .v.func = alc283_fixup_sense_combo_jack,
6556 .chained = true,
6557 .chain_id = ALC283_FIXUP_CHROME_BOOK,
6558 },
Takashi Iwai7bba2152013-09-06 15:45:38 +02006559 [ALC282_FIXUP_ASUS_TX300] = {
6560 .type = HDA_FIXUP_FUNC,
6561 .v.func = alc282_fixup_asus_tx300,
6562 },
Kailang Yang1bb3e062013-09-27 13:10:25 +02006563 [ALC283_FIXUP_INT_MIC] = {
6564 .type = HDA_FIXUP_VERBS,
6565 .v.verbs = (const struct hda_verb[]) {
6566 {0x20, AC_VERB_SET_COEF_INDEX, 0x1a},
6567 {0x20, AC_VERB_SET_PROC_COEF, 0x0011},
6568 { }
6569 },
6570 .chained = true,
6571 .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST
6572 },
David Henningsson0f4881d2013-12-20 16:08:13 +01006573 [ALC290_FIXUP_SUBWOOFER_HSJACK] = {
6574 .type = HDA_FIXUP_PINS,
6575 .v.pins = (const struct hda_pintbl[]) {
6576 { 0x17, 0x90170112 }, /* subwoofer */
6577 { }
6578 },
6579 .chained = true,
6580 .chain_id = ALC290_FIXUP_MONO_SPEAKERS_HSJACK,
6581 },
6582 [ALC290_FIXUP_SUBWOOFER] = {
6583 .type = HDA_FIXUP_PINS,
6584 .v.pins = (const struct hda_pintbl[]) {
6585 { 0x17, 0x90170112 }, /* subwoofer */
6586 { }
6587 },
6588 .chained = true,
6589 .chain_id = ALC290_FIXUP_MONO_SPEAKERS,
6590 },
David Henningsson338cae52013-10-07 10:39:59 +02006591 [ALC290_FIXUP_MONO_SPEAKERS] = {
6592 .type = HDA_FIXUP_FUNC,
6593 .v.func = alc290_fixup_mono_speakers,
David Henningsson0f4881d2013-12-20 16:08:13 +01006594 },
6595 [ALC290_FIXUP_MONO_SPEAKERS_HSJACK] = {
6596 .type = HDA_FIXUP_FUNC,
6597 .v.func = alc290_fixup_mono_speakers,
David Henningsson338cae52013-10-07 10:39:59 +02006598 .chained = true,
6599 .chain_id = ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
6600 },
David Henningssonb67ae3f2013-11-05 13:11:37 +01006601 [ALC269_FIXUP_THINKPAD_ACPI] = {
6602 .type = HDA_FIXUP_FUNC,
Takashi Iwaid5a6cab2018-06-13 12:43:10 +02006603 .v.func = alc_fixup_thinkpad_acpi,
Takashi Iwai09da1112016-09-08 12:15:02 +02006604 .chained = true,
6605 .chain_id = ALC269_FIXUP_SKU_IGNORE,
David Henningssonb67ae3f2013-11-05 13:11:37 +01006606 },
David Henningsson56f27012016-01-11 09:33:14 +01006607 [ALC269_FIXUP_DMIC_THINKPAD_ACPI] = {
6608 .type = HDA_FIXUP_FUNC,
6609 .v.func = alc_fixup_inv_dmic,
6610 .chained = true,
6611 .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
6612 },
Chris Chiu5824ce82017-02-28 14:17:11 -06006613 [ALC255_FIXUP_ACER_MIC_NO_PRESENCE] = {
Hui Wang17d30462019-06-14 16:44:12 +08006614 .type = HDA_FIXUP_PINS,
6615 .v.pins = (const struct hda_pintbl[]) {
6616 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6617 { }
Chris Chiu5824ce82017-02-28 14:17:11 -06006618 },
6619 .chained = true,
Hui Wang17d30462019-06-14 16:44:12 +08006620 .chain_id = ALC255_FIXUP_HEADSET_MODE
Chris Chiu5824ce82017-02-28 14:17:11 -06006621 },
Chris Chiu615966a2017-02-28 14:17:12 -06006622 [ALC255_FIXUP_ASUS_MIC_NO_PRESENCE] = {
6623 .type = HDA_FIXUP_PINS,
6624 .v.pins = (const struct hda_pintbl[]) {
6625 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6626 { }
6627 },
6628 .chained = true,
6629 .chain_id = ALC255_FIXUP_HEADSET_MODE
6630 },
Kailang Yang9a22a8f52013-11-08 15:54:49 +08006631 [ALC255_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6632 .type = HDA_FIXUP_PINS,
6633 .v.pins = (const struct hda_pintbl[]) {
6634 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6635 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6636 { }
6637 },
6638 .chained = true,
6639 .chain_id = ALC255_FIXUP_HEADSET_MODE
6640 },
Kailang Yang31278992014-03-03 15:27:22 +08006641 [ALC255_FIXUP_DELL2_MIC_NO_PRESENCE] = {
6642 .type = HDA_FIXUP_PINS,
6643 .v.pins = (const struct hda_pintbl[]) {
6644 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6645 { }
6646 },
6647 .chained = true,
6648 .chain_id = ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC
6649 },
Kailang Yang9a22a8f52013-11-08 15:54:49 +08006650 [ALC255_FIXUP_HEADSET_MODE] = {
6651 .type = HDA_FIXUP_FUNC,
6652 .v.func = alc_fixup_headset_mode_alc255,
Hui Wang4a83d422014-11-18 17:57:40 +08006653 .chained = true,
Takashi Iwaib3802782018-11-26 17:47:46 +01006654 .chain_id = ALC255_FIXUP_MIC_MUTE_LED
Kailang Yang9a22a8f52013-11-08 15:54:49 +08006655 },
Kailang Yang31278992014-03-03 15:27:22 +08006656 [ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC] = {
6657 .type = HDA_FIXUP_FUNC,
6658 .v.func = alc_fixup_headset_mode_alc255_no_hp_mic,
6659 },
Kailang Yanga22aa262014-04-23 17:34:28 +08006660 [ALC293_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6661 .type = HDA_FIXUP_PINS,
6662 .v.pins = (const struct hda_pintbl[]) {
6663 { 0x18, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6664 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6665 { }
6666 },
6667 .chained = true,
6668 .chain_id = ALC269_FIXUP_HEADSET_MODE
6669 },
Takashi Iwai1c37c222014-05-06 17:34:42 +02006670 [ALC292_FIXUP_TPT440_DOCK] = {
David Henningssonec56af62015-06-24 10:46:33 +02006671 .type = HDA_FIXUP_FUNC,
Takashi Iwai7f57d802015-09-24 17:36:51 +02006672 .v.func = alc_fixup_tpt440_dock,
Takashi Iwai1c37c222014-05-06 17:34:42 +02006673 .chained = true,
6674 .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST
6675 },
Takashi Iwai9a811232015-12-09 15:17:43 +01006676 [ALC292_FIXUP_TPT440] = {
6677 .type = HDA_FIXUP_FUNC,
Takashi Iwai157f0b72015-12-10 23:30:43 +01006678 .v.func = alc_fixup_disable_aamix,
Takashi Iwai9a811232015-12-09 15:17:43 +01006679 .chained = true,
6680 .chain_id = ALC292_FIXUP_TPT440_DOCK,
6681 },
Anisse Astierabaa22742016-08-24 09:14:13 +02006682 [ALC283_FIXUP_HEADSET_MIC] = {
Daniel Drake9dc12862014-07-22 10:58:29 +01006683 .type = HDA_FIXUP_PINS,
6684 .v.pins = (const struct hda_pintbl[]) {
6685 { 0x19, 0x04a110f0 },
6686 { },
6687 },
6688 },
Takashi Iwaib3802782018-11-26 17:47:46 +01006689 [ALC255_FIXUP_MIC_MUTE_LED] = {
Hui Wang00ef9942014-07-31 11:52:38 +08006690 .type = HDA_FIXUP_FUNC,
Takashi Iwaib3802782018-11-26 17:47:46 +01006691 .v.func = snd_hda_gen_fixup_micmute_led,
Hui Wang00ef9942014-07-31 11:52:38 +08006692 },
Takashi Iwai1a22e772014-08-27 08:19:05 +02006693 [ALC282_FIXUP_ASPIRE_V5_PINS] = {
6694 .type = HDA_FIXUP_PINS,
6695 .v.pins = (const struct hda_pintbl[]) {
6696 { 0x12, 0x90a60130 },
6697 { 0x14, 0x90170110 },
6698 { 0x17, 0x40000008 },
6699 { 0x18, 0x411111f0 },
Mateusz Sylwestrzak04206942015-07-19 17:38:56 +02006700 { 0x19, 0x01a1913c },
Takashi Iwai1a22e772014-08-27 08:19:05 +02006701 { 0x1a, 0x411111f0 },
6702 { 0x1b, 0x411111f0 },
6703 { 0x1d, 0x40f89b2d },
6704 { 0x1e, 0x411111f0 },
6705 { 0x21, 0x0321101f },
6706 { },
6707 },
6708 },
David Henningsson7a5255f2014-10-30 08:26:01 +01006709 [ALC280_FIXUP_HP_GPIO4] = {
6710 .type = HDA_FIXUP_FUNC,
6711 .v.func = alc280_fixup_hp_gpio4,
6712 },
Kailang Yangeaa8e5e2014-11-21 15:49:11 +08006713 [ALC286_FIXUP_HP_GPIO_LED] = {
6714 .type = HDA_FIXUP_FUNC,
6715 .v.func = alc286_fixup_hp_gpio_led,
6716 },
David Henningsson33f4acd2015-01-07 15:50:13 +01006717 [ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY] = {
6718 .type = HDA_FIXUP_FUNC,
6719 .v.func = alc280_fixup_hp_gpio2_mic_hotkey,
6720 },
TienFu Chenb4b33f92015-01-20 15:06:21 +01006721 [ALC280_FIXUP_HP_DOCK_PINS] = {
6722 .type = HDA_FIXUP_PINS,
6723 .v.pins = (const struct hda_pintbl[]) {
6724 { 0x1b, 0x21011020 }, /* line-out */
6725 { 0x1a, 0x01a1903c }, /* headset mic */
6726 { 0x18, 0x2181103f }, /* line-in */
6727 { },
6728 },
6729 .chained = true,
6730 .chain_id = ALC280_FIXUP_HP_GPIO4
6731 },
Jaroslav Kysela04d54662017-03-09 13:29:13 +01006732 [ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED] = {
6733 .type = HDA_FIXUP_PINS,
6734 .v.pins = (const struct hda_pintbl[]) {
6735 { 0x1b, 0x21011020 }, /* line-out */
6736 { 0x18, 0x2181103f }, /* line-in */
6737 { },
6738 },
6739 .chained = true,
6740 .chain_id = ALC269_FIXUP_HP_GPIO_MIC1_LED
6741 },
Keith Packard98973f22015-07-15 12:14:39 -07006742 [ALC280_FIXUP_HP_9480M] = {
6743 .type = HDA_FIXUP_FUNC,
6744 .v.func = alc280_fixup_hp_9480m,
6745 },
Kailang Yange1e62b92015-04-08 16:01:22 +08006746 [ALC288_FIXUP_DELL_HEADSET_MODE] = {
6747 .type = HDA_FIXUP_FUNC,
6748 .v.func = alc_fixup_headset_mode_dell_alc288,
6749 .chained = true,
Takashi Iwaib3802782018-11-26 17:47:46 +01006750 .chain_id = ALC255_FIXUP_MIC_MUTE_LED
Kailang Yange1e62b92015-04-08 16:01:22 +08006751 },
6752 [ALC288_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6753 .type = HDA_FIXUP_PINS,
6754 .v.pins = (const struct hda_pintbl[]) {
6755 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6756 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6757 { }
6758 },
6759 .chained = true,
6760 .chain_id = ALC288_FIXUP_DELL_HEADSET_MODE
6761 },
Hui Wang831bfdf92015-06-26 12:35:17 +08006762 [ALC288_FIXUP_DISABLE_AAMIX] = {
6763 .type = HDA_FIXUP_FUNC,
6764 .v.func = alc_fixup_disable_aamix,
6765 .chained = true,
Takashi Iwaid44a6862018-06-19 23:04:03 +02006766 .chain_id = ALC288_FIXUP_DELL1_MIC_NO_PRESENCE
Hui Wang831bfdf92015-06-26 12:35:17 +08006767 },
6768 [ALC288_FIXUP_DELL_XPS_13] = {
6769 .type = HDA_FIXUP_FUNC,
6770 .v.func = alc_fixup_dell_xps13,
6771 .chained = true,
6772 .chain_id = ALC288_FIXUP_DISABLE_AAMIX
6773 },
Takashi Iwai8b99aba2015-06-15 11:59:32 +02006774 [ALC292_FIXUP_DISABLE_AAMIX] = {
6775 .type = HDA_FIXUP_FUNC,
6776 .v.func = alc_fixup_disable_aamix,
Hui Wang831bfdf92015-06-26 12:35:17 +08006777 .chained = true,
6778 .chain_id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE
Takashi Iwai8b99aba2015-06-15 11:59:32 +02006779 },
David Henningssonc04017e2015-12-15 14:44:03 +01006780 [ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK] = {
6781 .type = HDA_FIXUP_FUNC,
6782 .v.func = alc_fixup_disable_aamix,
6783 .chained = true,
6784 .chain_id = ALC293_FIXUP_DELL1_MIC_NO_PRESENCE
6785 },
Takashi Iwai5fab5822020-01-05 09:11:19 +01006786 [ALC292_FIXUP_DELL_E7X_AAMIX] = {
Takashi Iwai8b99aba2015-06-15 11:59:32 +02006787 .type = HDA_FIXUP_FUNC,
6788 .v.func = alc_fixup_dell_xps13,
6789 .chained = true,
6790 .chain_id = ALC292_FIXUP_DISABLE_AAMIX
6791 },
Takashi Iwai5fab5822020-01-05 09:11:19 +01006792 [ALC292_FIXUP_DELL_E7X] = {
6793 .type = HDA_FIXUP_FUNC,
6794 .v.func = snd_hda_gen_fixup_micmute_led,
6795 /* micmute fixup must be applied at last */
6796 .chained_before = true,
6797 .chain_id = ALC292_FIXUP_DELL_E7X_AAMIX,
6798 },
James McDonnell54324222019-09-16 14:53:38 +00006799 [ALC298_FIXUP_ALIENWARE_MIC_NO_PRESENCE] = {
6800 .type = HDA_FIXUP_PINS,
6801 .v.pins = (const struct hda_pintbl[]) {
6802 { 0x18, 0x01a1913c }, /* headset mic w/o jack detect */
6803 { }
6804 },
6805 .chained_before = true,
6806 .chain_id = ALC269_FIXUP_HEADSET_MODE,
6807 },
Kailang Yang977e6272015-05-18 15:31:20 +08006808 [ALC298_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6809 .type = HDA_FIXUP_PINS,
6810 .v.pins = (const struct hda_pintbl[]) {
6811 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6812 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6813 { }
6814 },
6815 .chained = true,
6816 .chain_id = ALC269_FIXUP_HEADSET_MODE
6817 },
Hui Wang2f726ae2017-03-31 10:31:40 +08006818 [ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE] = {
6819 .type = HDA_FIXUP_PINS,
6820 .v.pins = (const struct hda_pintbl[]) {
6821 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6822 { }
6823 },
6824 .chained = true,
6825 .chain_id = ALC269_FIXUP_HEADSET_MODE
6826 },
Kailang Yang6ed11312015-10-26 15:37:39 +08006827 [ALC275_FIXUP_DELL_XPS] = {
6828 .type = HDA_FIXUP_VERBS,
6829 .v.verbs = (const struct hda_verb[]) {
6830 /* Enables internal speaker */
6831 {0x20, AC_VERB_SET_COEF_INDEX, 0x1f},
6832 {0x20, AC_VERB_SET_PROC_COEF, 0x00c0},
6833 {0x20, AC_VERB_SET_COEF_INDEX, 0x30},
6834 {0x20, AC_VERB_SET_PROC_COEF, 0x00b1},
6835 {}
6836 }
6837 },
Hui Wang23adc192015-12-08 12:27:18 +08006838 [ALC293_FIXUP_LENOVO_SPK_NOISE] = {
6839 .type = HDA_FIXUP_FUNC,
6840 .v.func = alc_fixup_disable_aamix,
6841 .chained = true,
6842 .chain_id = ALC269_FIXUP_THINKPAD_ACPI
6843 },
Kailang3694cb22015-12-28 11:35:24 +08006844 [ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY] = {
6845 .type = HDA_FIXUP_FUNC,
6846 .v.func = alc233_fixup_lenovo_line2_mic_hotkey,
6847 },
Kai-Heng Feng3b43b712016-02-25 15:19:38 +08006848 [ALC255_FIXUP_DELL_SPK_NOISE] = {
6849 .type = HDA_FIXUP_FUNC,
6850 .v.func = alc_fixup_disable_aamix,
6851 .chained = true,
6852 .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
6853 },
Kailang Yangd1dd4212019-01-09 17:05:24 +08006854 [ALC225_FIXUP_DISABLE_MIC_VREF] = {
6855 .type = HDA_FIXUP_FUNC,
6856 .v.func = alc_fixup_disable_mic_vref,
6857 .chained = true,
6858 .chain_id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE
6859 },
David Henningsson2ae95572016-02-25 09:37:05 +01006860 [ALC225_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6861 .type = HDA_FIXUP_VERBS,
6862 .v.verbs = (const struct hda_verb[]) {
6863 /* Disable pass-through path for FRONT 14h */
6864 { 0x20, AC_VERB_SET_COEF_INDEX, 0x36 },
6865 { 0x20, AC_VERB_SET_PROC_COEF, 0x57d7 },
6866 {}
6867 },
6868 .chained = true,
Kailang Yangd1dd4212019-01-09 17:05:24 +08006869 .chain_id = ALC225_FIXUP_DISABLE_MIC_VREF
David Henningsson2ae95572016-02-25 09:37:05 +01006870 },
Takashi Iwaif8839822016-02-25 14:31:59 +01006871 [ALC280_FIXUP_HP_HEADSET_MIC] = {
6872 .type = HDA_FIXUP_FUNC,
6873 .v.func = alc_fixup_disable_aamix,
6874 .chained = true,
6875 .chain_id = ALC269_FIXUP_HEADSET_MIC,
6876 },
Hui Wange549d192016-04-01 11:00:15 +08006877 [ALC221_FIXUP_HP_FRONT_MIC] = {
6878 .type = HDA_FIXUP_PINS,
6879 .v.pins = (const struct hda_pintbl[]) {
6880 { 0x19, 0x02a19020 }, /* Front Mic */
6881 { }
6882 },
6883 },
Sven Eckelmannc636b952016-04-11 16:55:26 +02006884 [ALC292_FIXUP_TPT460] = {
6885 .type = HDA_FIXUP_FUNC,
6886 .v.func = alc_fixup_tpt440_dock,
6887 .chained = true,
6888 .chain_id = ALC293_FIXUP_LENOVO_SPK_NOISE,
6889 },
Hui Wangdd9aa332016-08-01 10:20:32 +08006890 [ALC298_FIXUP_SPK_VOLUME] = {
6891 .type = HDA_FIXUP_FUNC,
6892 .v.func = alc298_fixup_speaker_volume,
Hui Wang59ec4b52016-08-04 15:28:04 +08006893 .chained = true,
Hui Wang2f726ae2017-03-31 10:31:40 +08006894 .chain_id = ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE,
Hui Wangdd9aa332016-08-01 10:20:32 +08006895 },
Takashi Iwaie312a862018-03-06 12:14:17 +01006896 [ALC295_FIXUP_DISABLE_DAC3] = {
6897 .type = HDA_FIXUP_FUNC,
6898 .v.func = alc295_fixup_disable_dac3,
6899 },
Jaroslav Kyselad2cd7952019-11-29 15:40:27 +01006900 [ALC285_FIXUP_SPEAKER2_TO_DAC1] = {
6901 .type = HDA_FIXUP_FUNC,
6902 .v.func = alc285_fixup_speaker2_to_dac1,
Hui Wangc37c0ab2020-02-19 13:23:06 +08006903 .chained = true,
6904 .chain_id = ALC269_FIXUP_THINKPAD_ACPI
Jaroslav Kyselad2cd7952019-11-29 15:40:27 +01006905 },
Kai-Heng Fengfd06c772016-08-30 15:36:34 +08006906 [ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER] = {
6907 .type = HDA_FIXUP_PINS,
6908 .v.pins = (const struct hda_pintbl[]) {
6909 { 0x1b, 0x90170151 },
6910 { }
6911 },
6912 .chained = true,
6913 .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
6914 },
Gabriele Mazzotta823ff162016-12-24 19:50:01 +01006915 [ALC269_FIXUP_ATIV_BOOK_8] = {
6916 .type = HDA_FIXUP_FUNC,
6917 .v.func = alc_fixup_auto_mute_via_amp,
6918 .chained = true,
6919 .chain_id = ALC269_FIXUP_NO_SHUTUP
6920 },
Kailang Yang9eb5d0e2017-01-17 15:40:25 +08006921 [ALC221_FIXUP_HP_MIC_NO_PRESENCE] = {
6922 .type = HDA_FIXUP_PINS,
6923 .v.pins = (const struct hda_pintbl[]) {
6924 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6925 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6926 { }
6927 },
6928 .chained = true,
6929 .chain_id = ALC269_FIXUP_HEADSET_MODE
6930 },
Chris Chiuc1732ed2017-02-28 14:17:13 -06006931 [ALC256_FIXUP_ASUS_HEADSET_MODE] = {
6932 .type = HDA_FIXUP_FUNC,
6933 .v.func = alc_fixup_headset_mode,
6934 },
6935 [ALC256_FIXUP_ASUS_MIC] = {
6936 .type = HDA_FIXUP_PINS,
6937 .v.pins = (const struct hda_pintbl[]) {
6938 { 0x13, 0x90a60160 }, /* use as internal mic */
6939 { 0x19, 0x04a11120 }, /* use as headset mic, without its own jack detect */
6940 { }
6941 },
6942 .chained = true,
6943 .chain_id = ALC256_FIXUP_ASUS_HEADSET_MODE
6944 },
Chris Chiueeed4cd2017-02-28 14:17:15 -06006945 [ALC256_FIXUP_ASUS_AIO_GPIO2] = {
Takashi Iwaiae065f12018-06-19 23:00:03 +02006946 .type = HDA_FIXUP_FUNC,
6947 /* Set up GPIO2 for the speaker amp */
6948 .v.func = alc_fixup_gpio4,
Chris Chiueeed4cd2017-02-28 14:17:15 -06006949 },
Chris Chiu216d7ae2017-02-28 14:17:14 -06006950 [ALC233_FIXUP_ASUS_MIC_NO_PRESENCE] = {
6951 .type = HDA_FIXUP_PINS,
6952 .v.pins = (const struct hda_pintbl[]) {
6953 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6954 { }
6955 },
6956 .chained = true,
6957 .chain_id = ALC269_FIXUP_HEADSET_MIC
6958 },
6959 [ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE] = {
6960 .type = HDA_FIXUP_VERBS,
6961 .v.verbs = (const struct hda_verb[]) {
6962 /* Enables internal speaker */
6963 {0x20, AC_VERB_SET_COEF_INDEX, 0x40},
6964 {0x20, AC_VERB_SET_PROC_COEF, 0x8800},
6965 {}
6966 },
6967 .chained = true,
6968 .chain_id = ALC233_FIXUP_ASUS_MIC_NO_PRESENCE
6969 },
Kailang Yangca169cc2017-04-25 16:17:40 +08006970 [ALC233_FIXUP_LENOVO_MULTI_CODECS] = {
6971 .type = HDA_FIXUP_FUNC,
6972 .v.func = alc233_alc662_fixup_lenovo_dual_codecs,
6973 },
Jian-Hong Panea5c7eb2019-04-01 11:25:05 +08006974 [ALC233_FIXUP_ACER_HEADSET_MIC] = {
6975 .type = HDA_FIXUP_VERBS,
6976 .v.verbs = (const struct hda_verb[]) {
6977 { 0x20, AC_VERB_SET_COEF_INDEX, 0x45 },
6978 { 0x20, AC_VERB_SET_PROC_COEF, 0x5089 },
6979 { }
6980 },
6981 .chained = true,
6982 .chain_id = ALC233_FIXUP_ASUS_MIC_NO_PRESENCE
6983 },
Hui Wangf33f79f2017-07-07 12:08:29 +08006984 [ALC294_FIXUP_LENOVO_MIC_LOCATION] = {
6985 .type = HDA_FIXUP_PINS,
6986 .v.pins = (const struct hda_pintbl[]) {
6987 /* Change the mic location from front to right, otherwise there are
6988 two front mics with the same name, pulseaudio can't handle them.
6989 This is just a temporary workaround, after applying this fixup,
6990 there will be one "Front Mic" and one "Mic" in this machine.
6991 */
6992 { 0x1a, 0x04a19040 },
6993 { }
6994 },
6995 },
Kailang Yang5f364132017-07-25 16:28:16 +08006996 [ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE] = {
6997 .type = HDA_FIXUP_PINS,
6998 .v.pins = (const struct hda_pintbl[]) {
6999 { 0x16, 0x0101102f }, /* Rear Headset HP */
7000 { 0x19, 0x02a1913c }, /* use as Front headset mic, without its own jack detect */
7001 { 0x1a, 0x01a19030 }, /* Rear Headset MIC */
7002 { 0x1b, 0x02011020 },
7003 { }
7004 },
7005 .chained = true,
Kai-Heng Feng52e4e362020-05-03 23:24:47 +08007006 .chain_id = ALC225_FIXUP_S3_POP_NOISE
7007 },
7008 [ALC225_FIXUP_S3_POP_NOISE] = {
7009 .type = HDA_FIXUP_FUNC,
7010 .v.func = alc225_fixup_s3_pop_noise,
7011 .chained = true,
Kailang Yang5f364132017-07-25 16:28:16 +08007012 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
7013 },
PeiSen Houb84e8432017-09-01 15:11:56 +08007014 [ALC700_FIXUP_INTEL_REFERENCE] = {
7015 .type = HDA_FIXUP_VERBS,
7016 .v.verbs = (const struct hda_verb[]) {
7017 /* Enables internal speaker */
7018 {0x20, AC_VERB_SET_COEF_INDEX, 0x45},
7019 {0x20, AC_VERB_SET_PROC_COEF, 0x5289},
7020 {0x20, AC_VERB_SET_COEF_INDEX, 0x4A},
7021 {0x20, AC_VERB_SET_PROC_COEF, 0x001b},
7022 {0x58, AC_VERB_SET_COEF_INDEX, 0x00},
7023 {0x58, AC_VERB_SET_PROC_COEF, 0x3888},
7024 {0x20, AC_VERB_SET_COEF_INDEX, 0x6f},
7025 {0x20, AC_VERB_SET_PROC_COEF, 0x2c0b},
7026 {}
7027 }
7028 },
Kailang Yang92266652017-12-14 15:28:58 +08007029 [ALC274_FIXUP_DELL_BIND_DACS] = {
7030 .type = HDA_FIXUP_FUNC,
7031 .v.func = alc274_fixup_bind_dacs,
7032 .chained = true,
7033 .chain_id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE
7034 },
7035 [ALC274_FIXUP_DELL_AIO_LINEOUT_VERB] = {
7036 .type = HDA_FIXUP_PINS,
7037 .v.pins = (const struct hda_pintbl[]) {
7038 { 0x1b, 0x0401102f },
7039 { }
7040 },
7041 .chained = true,
7042 .chain_id = ALC274_FIXUP_DELL_BIND_DACS
7043 },
Takashi Iwai399c01a2020-05-26 08:24:06 +02007044 [ALC298_FIXUP_TPT470_DOCK_FIX] = {
Kailang Yang61fcf8e2018-02-02 15:26:46 +08007045 .type = HDA_FIXUP_FUNC,
7046 .v.func = alc_fixup_tpt470_dock,
7047 .chained = true,
7048 .chain_id = ALC293_FIXUP_LENOVO_SPK_NOISE
7049 },
Takashi Iwai399c01a2020-05-26 08:24:06 +02007050 [ALC298_FIXUP_TPT470_DOCK] = {
7051 .type = HDA_FIXUP_FUNC,
7052 .v.func = alc_fixup_tpt470_dacs,
7053 .chained = true,
7054 .chain_id = ALC298_FIXUP_TPT470_DOCK_FIX
7055 },
Kailang Yangae104a22018-02-05 16:07:20 +08007056 [ALC255_FIXUP_DUMMY_LINEOUT_VERB] = {
7057 .type = HDA_FIXUP_PINS,
7058 .v.pins = (const struct hda_pintbl[]) {
7059 { 0x14, 0x0201101f },
7060 { }
7061 },
7062 .chained = true,
7063 .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
7064 },
Kailang Yangf0ba9d62018-03-16 11:46:08 +08007065 [ALC255_FIXUP_DELL_HEADSET_MIC] = {
7066 .type = HDA_FIXUP_PINS,
7067 .v.pins = (const struct hda_pintbl[]) {
7068 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
7069 { }
7070 },
Hui Wang3ce0d5a2018-04-19 13:29:04 +08007071 .chained = true,
7072 .chain_id = ALC269_FIXUP_HEADSET_MIC
Kailang Yangf0ba9d62018-03-16 11:46:08 +08007073 },
Tom Bridenbbf8ff62018-05-29 17:34:20 +01007074 [ALC295_FIXUP_HP_X360] = {
7075 .type = HDA_FIXUP_FUNC,
7076 .v.func = alc295_fixup_hp_top_speakers,
7077 .chained = true,
7078 .chain_id = ALC269_FIXUP_HP_MUTE_LED_MIC3
Kailang Yang8a328ac2018-08-21 16:54:41 +08007079 },
7080 [ALC221_FIXUP_HP_HEADSET_MIC] = {
7081 .type = HDA_FIXUP_PINS,
7082 .v.pins = (const struct hda_pintbl[]) {
7083 { 0x19, 0x0181313f},
7084 { }
7085 },
7086 .chained = true,
7087 .chain_id = ALC269_FIXUP_HEADSET_MIC
7088 },
Hui Wangc4cfcf62018-11-26 14:17:16 +08007089 [ALC285_FIXUP_LENOVO_HEADPHONE_NOISE] = {
7090 .type = HDA_FIXUP_FUNC,
7091 .v.func = alc285_fixup_invalidate_dacs,
Hui Wang6ba189c2018-12-09 09:16:43 +08007092 .chained = true,
7093 .chain_id = ALC269_FIXUP_THINKPAD_ACPI
Hui Wangc4cfcf62018-11-26 14:17:16 +08007094 },
Girija Kumar Kasinadhunie8ed64b2018-11-26 13:40:46 -05007095 [ALC295_FIXUP_HP_AUTO_MUTE] = {
7096 .type = HDA_FIXUP_FUNC,
7097 .v.func = alc_fixup_auto_mute_via_amp,
7098 },
Chris Chiu33aaebd2018-12-05 14:48:53 +08007099 [ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE] = {
7100 .type = HDA_FIXUP_PINS,
7101 .v.pins = (const struct hda_pintbl[]) {
7102 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
7103 { }
7104 },
7105 .chained = true,
7106 .chain_id = ALC269_FIXUP_HEADSET_MIC
7107 },
Chris Chiud8ae4582018-12-07 17:17:11 +08007108 [ALC294_FIXUP_ASUS_MIC] = {
7109 .type = HDA_FIXUP_PINS,
7110 .v.pins = (const struct hda_pintbl[]) {
7111 { 0x13, 0x90a60160 }, /* use as internal mic */
7112 { 0x19, 0x04a11120 }, /* use as headset mic, without its own jack detect */
7113 { }
7114 },
7115 .chained = true,
7116 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
7117 },
Jian-Hong Pan4e051102018-12-07 17:17:12 +08007118 [ALC294_FIXUP_ASUS_HEADSET_MIC] = {
7119 .type = HDA_FIXUP_PINS,
7120 .v.pins = (const struct hda_pintbl[]) {
Jian-Hong Pan82b01142018-12-27 16:46:31 +08007121 { 0x19, 0x01a1103c }, /* use as headset mic */
Jian-Hong Pan4e051102018-12-07 17:17:12 +08007122 { }
7123 },
7124 .chained = true,
7125 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
7126 },
7127 [ALC294_FIXUP_ASUS_SPK] = {
7128 .type = HDA_FIXUP_VERBS,
7129 .v.verbs = (const struct hda_verb[]) {
7130 /* Set EAPD high */
7131 { 0x20, AC_VERB_SET_COEF_INDEX, 0x40 },
7132 { 0x20, AC_VERB_SET_PROC_COEF, 0x8800 },
7133 { }
7134 },
7135 .chained = true,
7136 .chain_id = ALC294_FIXUP_ASUS_HEADSET_MIC
7137 },
Jaroslav Kyselac8a9afa2019-03-14 09:21:08 +01007138 [ALC295_FIXUP_CHROME_BOOK] = {
Kailang Yange8547472018-11-28 15:32:45 +08007139 .type = HDA_FIXUP_FUNC,
Jaroslav Kyselac8a9afa2019-03-14 09:21:08 +01007140 .v.func = alc295_fixup_chromebook,
Kailang Yang8983eb62019-04-03 15:31:49 +08007141 .chained = true,
7142 .chain_id = ALC225_FIXUP_HEADSET_JACK
7143 },
7144 [ALC225_FIXUP_HEADSET_JACK] = {
7145 .type = HDA_FIXUP_FUNC,
7146 .v.func = alc_fixup_headset_jack,
Kailang Yange8547472018-11-28 15:32:45 +08007147 },
Jeremy Soller89e3a562019-01-30 16:12:31 -07007148 [ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE] = {
7149 .type = HDA_FIXUP_PINS,
7150 .v.pins = (const struct hda_pintbl[]) {
7151 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
7152 { }
7153 },
7154 .chained = true,
7155 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
7156 },
Hui Wangc8c6ee62019-02-14 11:41:33 +08007157 [ALC285_FIXUP_LENOVO_PC_BEEP_IN_NOISE] = {
7158 .type = HDA_FIXUP_VERBS,
7159 .v.verbs = (const struct hda_verb[]) {
7160 /* Disable PCBEEP-IN passthrough */
7161 { 0x20, AC_VERB_SET_COEF_INDEX, 0x36 },
7162 { 0x20, AC_VERB_SET_PROC_COEF, 0x57d7 },
7163 { }
7164 },
7165 .chained = true,
7166 .chain_id = ALC285_FIXUP_LENOVO_HEADPHONE_NOISE
7167 },
Jian-Hong Pancbc05fd2019-03-13 17:33:24 +08007168 [ALC255_FIXUP_ACER_HEADSET_MIC] = {
7169 .type = HDA_FIXUP_PINS,
7170 .v.pins = (const struct hda_pintbl[]) {
7171 { 0x19, 0x03a11130 },
7172 { 0x1a, 0x90a60140 }, /* use as internal mic */
7173 { }
7174 },
7175 .chained = true,
7176 .chain_id = ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC
7177 },
Kailang Yang136824e2019-03-14 16:22:45 +08007178 [ALC225_FIXUP_DELL_WYSE_AIO_MIC_NO_PRESENCE] = {
7179 .type = HDA_FIXUP_PINS,
7180 .v.pins = (const struct hda_pintbl[]) {
7181 { 0x16, 0x01011020 }, /* Rear Line out */
7182 { 0x19, 0x01a1913c }, /* use as Front headset mic, without its own jack detect */
7183 { }
7184 },
7185 .chained = true,
7186 .chain_id = ALC225_FIXUP_WYSE_AUTO_MUTE
7187 },
7188 [ALC225_FIXUP_WYSE_AUTO_MUTE] = {
7189 .type = HDA_FIXUP_FUNC,
7190 .v.func = alc_fixup_auto_mute_via_amp,
7191 .chained = true,
7192 .chain_id = ALC225_FIXUP_WYSE_DISABLE_MIC_VREF
7193 },
7194 [ALC225_FIXUP_WYSE_DISABLE_MIC_VREF] = {
7195 .type = HDA_FIXUP_FUNC,
7196 .v.func = alc_fixup_disable_mic_vref,
7197 .chained = true,
7198 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
7199 },
Jian-Hong Pan667a8f72019-03-15 17:51:09 +08007200 [ALC286_FIXUP_ACER_AIO_HEADSET_MIC] = {
7201 .type = HDA_FIXUP_VERBS,
7202 .v.verbs = (const struct hda_verb[]) {
7203 { 0x20, AC_VERB_SET_COEF_INDEX, 0x4f },
7204 { 0x20, AC_VERB_SET_PROC_COEF, 0x5029 },
7205 { }
7206 },
7207 .chained = true,
7208 .chain_id = ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE
7209 },
Daniel Drake8c8967a2019-10-17 16:15:01 +08007210 [ALC256_FIXUP_ASUS_HEADSET_MIC] = {
7211 .type = HDA_FIXUP_PINS,
7212 .v.pins = (const struct hda_pintbl[]) {
7213 { 0x19, 0x03a11020 }, /* headset mic with jack detect */
7214 { }
7215 },
7216 .chained = true,
7217 .chain_id = ALC256_FIXUP_ASUS_HEADSET_MODE
7218 },
Jian-Hong Pane1037352019-03-22 11:37:18 +08007219 [ALC256_FIXUP_ASUS_MIC_NO_PRESENCE] = {
7220 .type = HDA_FIXUP_PINS,
7221 .v.pins = (const struct hda_pintbl[]) {
7222 { 0x19, 0x04a11120 }, /* use as headset mic, without its own jack detect */
7223 { }
7224 },
7225 .chained = true,
7226 .chain_id = ALC256_FIXUP_ASUS_HEADSET_MODE
7227 },
Bernhard Rosenkraenzere2a829b2019-03-05 00:38:19 +01007228 [ALC299_FIXUP_PREDATOR_SPK] = {
7229 .type = HDA_FIXUP_PINS,
7230 .v.pins = (const struct hda_pintbl[]) {
7231 { 0x21, 0x90170150 }, /* use as headset mic, without its own jack detect */
7232 { }
7233 }
7234 },
Jan-Marek Glogowskibd9c10b2019-09-15 16:57:28 +02007235 [ALC256_FIXUP_MEDION_HEADSET_NO_PRESENCE] = {
7236 .type = HDA_FIXUP_PINS,
7237 .v.pins = (const struct hda_pintbl[]) {
7238 { 0x19, 0x04a11040 },
7239 { 0x21, 0x04211020 },
7240 { }
7241 },
7242 .chained = true,
7243 .chain_id = ALC256_FIXUP_ASUS_HEADSET_MODE
7244 },
Kailang Yange79c2262019-12-19 14:12:15 +08007245 [ALC289_FIXUP_DELL_SPK2] = {
7246 .type = HDA_FIXUP_PINS,
7247 .v.pins = (const struct hda_pintbl[]) {
7248 { 0x17, 0x90170130 }, /* bass spk */
7249 { }
7250 },
7251 .chained = true,
7252 .chain_id = ALC269_FIXUP_DELL4_MIC_NO_PRESENCE
7253 },
7254 [ALC289_FIXUP_DUAL_SPK] = {
7255 .type = HDA_FIXUP_FUNC,
7256 .v.func = alc285_fixup_speaker2_to_dac1,
7257 .chained = true,
7258 .chain_id = ALC289_FIXUP_DELL_SPK2
7259 },
Chris Chiu48e01502019-12-30 11:11:18 +08007260 [ALC294_FIXUP_SPK2_TO_DAC1] = {
7261 .type = HDA_FIXUP_FUNC,
7262 .v.func = alc285_fixup_speaker2_to_dac1,
7263 .chained = true,
7264 .chain_id = ALC294_FIXUP_ASUS_HEADSET_MIC
7265 },
7266 [ALC294_FIXUP_ASUS_DUAL_SPK] = {
Jian-Hong Pan436e2552019-11-25 17:34:06 +08007267 .type = HDA_FIXUP_FUNC,
7268 /* The GPIO must be pulled to initialize the AMP */
7269 .v.func = alc_fixup_gpio4,
7270 .chained = true,
Chris Chiu48e01502019-12-30 11:11:18 +08007271 .chain_id = ALC294_FIXUP_SPK2_TO_DAC1
Jian-Hong Pan436e2552019-11-25 17:34:06 +08007272 },
Kailang Yang76f7dec2020-02-10 16:30:26 +08007273 [ALC285_FIXUP_THINKPAD_HEADSET_JACK] = {
7274 .type = HDA_FIXUP_FUNC,
7275 .v.func = alc_fixup_headset_jack,
7276 .chained = true,
7277 .chain_id = ALC285_FIXUP_SPEAKER2_TO_DAC1
7278 },
Jian-Hong Pan8b33a132020-02-25 15:29:21 +08007279 [ALC294_FIXUP_ASUS_HPE] = {
7280 .type = HDA_FIXUP_VERBS,
7281 .v.verbs = (const struct hda_verb[]) {
7282 /* Set EAPD high */
7283 { 0x20, AC_VERB_SET_COEF_INDEX, 0x0f },
7284 { 0x20, AC_VERB_SET_PROC_COEF, 0x7774 },
7285 { }
7286 },
7287 .chained = true,
7288 .chain_id = ALC294_FIXUP_ASUS_HEADSET_MIC
7289 },
Takashi Iwai1b94e592020-05-12 09:32:03 +02007290 [ALC294_FIXUP_ASUS_COEF_1B] = {
7291 .type = HDA_FIXUP_VERBS,
7292 .v.verbs = (const struct hda_verb[]) {
7293 /* Set bit 10 to correct noisy output after reboot from
7294 * Windows 10 (due to pop noise reduction?)
7295 */
7296 { 0x20, AC_VERB_SET_COEF_INDEX, 0x1b },
7297 { 0x20, AC_VERB_SET_PROC_COEF, 0x4e4b },
7298 { }
7299 },
7300 },
Kai-Heng Fengf5a88b02020-03-27 12:46:25 +08007301 [ALC285_FIXUP_HP_GPIO_LED] = {
7302 .type = HDA_FIXUP_FUNC,
7303 .v.func = alc285_fixup_hp_gpio_led,
7304 },
Kailang Yang431e76c2020-04-07 14:40:20 +08007305 [ALC285_FIXUP_HP_MUTE_LED] = {
7306 .type = HDA_FIXUP_FUNC,
7307 .v.func = alc285_fixup_hp_mute_led,
7308 },
Kailang Yang24164f42020-04-07 14:52:42 +08007309 [ALC236_FIXUP_HP_MUTE_LED] = {
7310 .type = HDA_FIXUP_FUNC,
7311 .v.func = alc236_fixup_hp_mute_led,
7312 },
Mike Pozulp14425f12020-05-09 20:28:37 -07007313 [ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET] = {
7314 .type = HDA_FIXUP_VERBS,
7315 .v.verbs = (const struct hda_verb[]) {
7316 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc5 },
7317 { }
7318 },
7319 },
Chris Chiu9e433422020-05-12 14:15:24 +08007320 [ALC295_FIXUP_ASUS_MIC_NO_PRESENCE] = {
7321 .type = HDA_FIXUP_PINS,
7322 .v.pins = (const struct hda_pintbl[]) {
7323 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
7324 { }
7325 },
7326 .chained = true,
7327 .chain_id = ALC269_FIXUP_HEADSET_MODE
7328 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02007329};
7330
7331static const struct snd_pci_quirk alc269_fixup_tbl[] = {
Marius Knausta6b92b62014-03-03 01:48:58 +01007332 SND_PCI_QUIRK(0x1025, 0x0283, "Acer TravelMate 8371", ALC269_FIXUP_INV_DMIC),
David Henningsson693b6132012-06-22 19:12:10 +02007333 SND_PCI_QUIRK(0x1025, 0x029b, "Acer 1810TZ", ALC269_FIXUP_INV_DMIC),
7334 SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC),
David Henningssonaaedfb42013-08-16 14:09:02 +02007335 SND_PCI_QUIRK(0x1025, 0x047c, "Acer AC700", ALC269_FIXUP_ACER_AC700),
Takashi Iwai78197172015-06-27 10:21:13 +02007336 SND_PCI_QUIRK(0x1025, 0x072d, "Acer Aspire V5-571G", ALC269_FIXUP_ASPIRE_HEADSET_MIC),
7337 SND_PCI_QUIRK(0x1025, 0x080d, "Acer Aspire V5-122P", ALC269_FIXUP_ASPIRE_HEADSET_MIC),
David Henningssonaaedfb42013-08-16 14:09:02 +02007338 SND_PCI_QUIRK(0x1025, 0x0740, "Acer AO725", ALC271_FIXUP_HP_GATE_MIC_JACK),
7339 SND_PCI_QUIRK(0x1025, 0x0742, "Acer AO756", ALC271_FIXUP_HP_GATE_MIC_JACK),
Simon South02322ac2016-03-02 23:10:44 -05007340 SND_PCI_QUIRK(0x1025, 0x0762, "Acer Aspire E1-472", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572),
Oleksij Rempelb1e89722013-12-04 20:50:53 +01007341 SND_PCI_QUIRK(0x1025, 0x0775, "Acer Aspire E1-572", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572),
Takashi Iwai1a22e772014-08-27 08:19:05 +02007342 SND_PCI_QUIRK(0x1025, 0x079b, "Acer Aspire V5-573G", ALC282_FIXUP_ASPIRE_V5_PINS),
Chris Chiu705b65f2018-12-05 14:48:54 +08007343 SND_PCI_QUIRK(0x1025, 0x102b, "Acer Aspire C24-860", ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE),
Takashi Iwaib9c2fa52015-11-19 16:39:50 +01007344 SND_PCI_QUIRK(0x1025, 0x106d, "Acer Cloudbook 14", ALC283_FIXUP_CHROME_BOOK),
Chris Chiuc7531e32019-03-21 17:17:31 +08007345 SND_PCI_QUIRK(0x1025, 0x1099, "Acer Aspire E5-523G", ALC255_FIXUP_ACER_MIC_NO_PRESENCE),
7346 SND_PCI_QUIRK(0x1025, 0x110e, "Acer Aspire ES1-432", ALC255_FIXUP_ACER_MIC_NO_PRESENCE),
Bernhard Rosenkraenzere2a829b2019-03-05 00:38:19 +01007347 SND_PCI_QUIRK(0x1025, 0x1246, "Acer Predator Helios 500", ALC299_FIXUP_PREDATOR_SPK),
Jian-Hong Pan667a8f72019-03-15 17:51:09 +08007348 SND_PCI_QUIRK(0x1025, 0x128f, "Acer Veriton Z6860G", ALC286_FIXUP_ACER_AIO_HEADSET_MIC),
7349 SND_PCI_QUIRK(0x1025, 0x1290, "Acer Veriton Z4860G", ALC286_FIXUP_ACER_AIO_HEADSET_MIC),
7350 SND_PCI_QUIRK(0x1025, 0x1291, "Acer Veriton Z4660G", ALC286_FIXUP_ACER_AIO_HEADSET_MIC),
Jian-Hong Pan2733cce2019-03-21 16:39:04 +08007351 SND_PCI_QUIRK(0x1025, 0x1308, "Acer Aspire Z24-890", ALC286_FIXUP_ACER_AIO_HEADSET_MIC),
Jian-Hong Panea5c7eb2019-04-01 11:25:05 +08007352 SND_PCI_QUIRK(0x1025, 0x132a, "Acer TravelMate B114-21", ALC233_FIXUP_ACER_HEADSET_MIC),
Jian-Hong Pancbc05fd2019-03-13 17:33:24 +08007353 SND_PCI_QUIRK(0x1025, 0x1330, "Acer TravelMate X514-51T", ALC255_FIXUP_ACER_HEADSET_MIC),
David Henningssonaaedfb42013-08-16 14:09:02 +02007354 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
Kailang Yang6ed11312015-10-26 15:37:39 +08007355 SND_PCI_QUIRK(0x1028, 0x054b, "Dell XPS one 2710", ALC275_FIXUP_DELL_XPS),
Takashi Iwai86f799b2015-11-14 17:46:31 +01007356 SND_PCI_QUIRK(0x1028, 0x05bd, "Dell Latitude E6440", ALC292_FIXUP_DELL_E7X),
Takashi Iwaicf521032016-01-15 12:59:25 +01007357 SND_PCI_QUIRK(0x1028, 0x05be, "Dell Latitude E6540", ALC292_FIXUP_DELL_E7X),
Takashi Iwai8b99aba2015-06-15 11:59:32 +02007358 SND_PCI_QUIRK(0x1028, 0x05ca, "Dell Latitude E7240", ALC292_FIXUP_DELL_E7X),
7359 SND_PCI_QUIRK(0x1028, 0x05cb, "Dell Latitude E7440", ALC292_FIXUP_DELL_E7X),
David Henningsson0f4881d2013-12-20 16:08:13 +01007360 SND_PCI_QUIRK(0x1028, 0x05da, "Dell Vostro 5460", ALC290_FIXUP_SUBWOOFER),
David Henningsson73bdd592013-04-15 15:44:14 +02007361 SND_PCI_QUIRK(0x1028, 0x05f4, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
7362 SND_PCI_QUIRK(0x1028, 0x05f5, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
7363 SND_PCI_QUIRK(0x1028, 0x05f6, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
David Henningsson0f4881d2013-12-20 16:08:13 +01007364 SND_PCI_QUIRK(0x1028, 0x0615, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK),
7365 SND_PCI_QUIRK(0x1028, 0x0616, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK),
Takashi Iwai98070572016-01-12 21:06:39 +01007366 SND_PCI_QUIRK(0x1028, 0x062c, "Dell Latitude E5550", ALC292_FIXUP_DELL_E7X),
Takashi Iwai42755542015-06-29 10:56:53 +02007367 SND_PCI_QUIRK(0x1028, 0x062e, "Dell Latitude E7450", ALC292_FIXUP_DELL_E7X),
David Henningsson0f4881d2013-12-20 16:08:13 +01007368 SND_PCI_QUIRK(0x1028, 0x0638, "Dell Inspiron 5439", ALC290_FIXUP_MONO_SPEAKERS_HSJACK),
Kailang Yanga22aa262014-04-23 17:34:28 +08007369 SND_PCI_QUIRK(0x1028, 0x064a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
7370 SND_PCI_QUIRK(0x1028, 0x064b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
Hui Wang831bfdf92015-06-26 12:35:17 +08007371 SND_PCI_QUIRK(0x1028, 0x0665, "Dell XPS 13", ALC288_FIXUP_DELL_XPS_13),
Bastien Noceraafecb142016-04-18 11:10:42 +02007372 SND_PCI_QUIRK(0x1028, 0x0669, "Dell Optiplex 9020m", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
Takashi Iwai3a05d122015-07-29 09:04:52 +02007373 SND_PCI_QUIRK(0x1028, 0x069a, "Dell Vostro 5480", ALC290_FIXUP_SUBWOOFER_HSJACK),
Kailang Yang8b724152014-12-17 17:08:59 +08007374 SND_PCI_QUIRK(0x1028, 0x06c7, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
Kailang Yangb7343042014-12-02 14:50:45 +08007375 SND_PCI_QUIRK(0x1028, 0x06d9, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
7376 SND_PCI_QUIRK(0x1028, 0x06da, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
David Henningssonc04017e2015-12-15 14:44:03 +01007377 SND_PCI_QUIRK(0x1028, 0x06db, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
7378 SND_PCI_QUIRK(0x1028, 0x06dd, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
7379 SND_PCI_QUIRK(0x1028, 0x06de, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
7380 SND_PCI_QUIRK(0x1028, 0x06df, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
7381 SND_PCI_QUIRK(0x1028, 0x06e0, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
Kai-Heng Fengfd06c772016-08-30 15:36:34 +08007382 SND_PCI_QUIRK(0x1028, 0x0706, "Dell Inspiron 7559", ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER),
Kai-Heng Feng3b43b712016-02-25 15:19:38 +08007383 SND_PCI_QUIRK(0x1028, 0x0725, "Dell Inspiron 3162", ALC255_FIXUP_DELL_SPK_NOISE),
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01007384 SND_PCI_QUIRK(0x1028, 0x0738, "Dell Precision 5820", ALC269_FIXUP_NO_SHUTUP),
Kai-Heng Feng709ae622018-10-04 11:39:42 +08007385 SND_PCI_QUIRK(0x1028, 0x075c, "Dell XPS 27 7760", ALC298_FIXUP_SPK_VOLUME),
Hui Wangdd9aa332016-08-01 10:20:32 +08007386 SND_PCI_QUIRK(0x1028, 0x075d, "Dell AIO", ALC298_FIXUP_SPK_VOLUME),
Takashi Iwaie312a862018-03-06 12:14:17 +01007387 SND_PCI_QUIRK(0x1028, 0x07b0, "Dell Precision 7520", ALC295_FIXUP_DISABLE_DAC3),
Takashi Iwai493de342017-02-28 17:27:57 +01007388 SND_PCI_QUIRK(0x1028, 0x0798, "Dell Inspiron 17 7000 Gaming", ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER),
Kailang Yang5f364132017-07-25 16:28:16 +08007389 SND_PCI_QUIRK(0x1028, 0x080c, "Dell WYSE", ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE),
Kailang Yang40e2c4e2018-02-02 15:13:09 +08007390 SND_PCI_QUIRK(0x1028, 0x084b, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB),
7391 SND_PCI_QUIRK(0x1028, 0x084e, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB),
Kailang Yangf0ba9d62018-03-16 11:46:08 +08007392 SND_PCI_QUIRK(0x1028, 0x0871, "Dell Precision 3630", ALC255_FIXUP_DELL_HEADSET_MIC),
7393 SND_PCI_QUIRK(0x1028, 0x0872, "Dell Precision 3630", ALC255_FIXUP_DELL_HEADSET_MIC),
Kailang Yangae104a22018-02-05 16:07:20 +08007394 SND_PCI_QUIRK(0x1028, 0x0873, "Dell Precision 3930", ALC255_FIXUP_DUMMY_LINEOUT_VERB),
Kailang Yang136824e2019-03-14 16:22:45 +08007395 SND_PCI_QUIRK(0x1028, 0x08ad, "Dell WYSE AIO", ALC225_FIXUP_DELL_WYSE_AIO_MIC_NO_PRESENCE),
Kailang Yangda484d02019-03-14 15:50:59 +08007396 SND_PCI_QUIRK(0x1028, 0x08ae, "Dell WYSE NB", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE),
Kailang Yangc2a7c55a2019-01-03 15:53:39 +08007397 SND_PCI_QUIRK(0x1028, 0x0935, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB),
Kailang Yange79c2262019-12-19 14:12:15 +08007398 SND_PCI_QUIRK(0x1028, 0x097e, "Dell Precision", ALC289_FIXUP_DUAL_SPK),
7399 SND_PCI_QUIRK(0x1028, 0x097d, "Dell Precision", ALC289_FIXUP_DUAL_SPK),
Kailang Yang78def222020-02-20 15:21:54 +08007400 SND_PCI_QUIRK(0x1028, 0x098d, "Dell Precision", ALC233_FIXUP_ASUS_MIC_NO_PRESENCE),
7401 SND_PCI_QUIRK(0x1028, 0x09bf, "Dell Precision", ALC233_FIXUP_ASUS_MIC_NO_PRESENCE),
Kailang Yanga22aa262014-04-23 17:34:28 +08007402 SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
7403 SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
Takashi Iwai08fb0d02013-01-10 17:33:58 +01007404 SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01007405 SND_PCI_QUIRK(0x103c, 0x18e6, "HP", ALC269_FIXUP_HP_GPIO_LED),
David Henningsson8e35cd42013-11-06 11:20:01 +01007406 SND_PCI_QUIRK(0x103c, 0x218b, "HP", ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED),
David Henningsson33f4acd2015-01-07 15:50:13 +01007407 SND_PCI_QUIRK(0x103c, 0x225f, "HP", ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY),
Kailang Yangc60666b2014-02-21 16:23:35 +08007408 /* ALC282 */
Hui Wang7976eb42015-02-13 11:14:41 +08007409 SND_PCI_QUIRK(0x103c, 0x21f9, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang8a02b162014-06-13 17:16:31 +08007410 SND_PCI_QUIRK(0x103c, 0x2210, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang8a02b162014-06-13 17:16:31 +08007411 SND_PCI_QUIRK(0x103c, 0x2214, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007412 SND_PCI_QUIRK(0x103c, 0x2236, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
7413 SND_PCI_QUIRK(0x103c, 0x2237, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
7414 SND_PCI_QUIRK(0x103c, 0x2238, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
7415 SND_PCI_QUIRK(0x103c, 0x2239, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007416 SND_PCI_QUIRK(0x103c, 0x224b, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
Kailang Yangc60666b2014-02-21 16:23:35 +08007417 SND_PCI_QUIRK(0x103c, 0x2268, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08007418 SND_PCI_QUIRK(0x103c, 0x226a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7419 SND_PCI_QUIRK(0x103c, 0x226b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang8a02b162014-06-13 17:16:31 +08007420 SND_PCI_QUIRK(0x103c, 0x226e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangeaa8e5e2014-11-21 15:49:11 +08007421 SND_PCI_QUIRK(0x103c, 0x2271, "HP", ALC286_FIXUP_HP_GPIO_LED),
TienFu Chenb4b33f92015-01-20 15:06:21 +01007422 SND_PCI_QUIRK(0x103c, 0x2272, "HP", ALC280_FIXUP_HP_DOCK_PINS),
TienFu Chen3271cb22015-02-10 09:09:41 +01007423 SND_PCI_QUIRK(0x103c, 0x2273, "HP", ALC280_FIXUP_HP_DOCK_PINS),
Kailang Yangc60666b2014-02-21 16:23:35 +08007424 SND_PCI_QUIRK(0x103c, 0x229e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08007425 SND_PCI_QUIRK(0x103c, 0x22b2, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7426 SND_PCI_QUIRK(0x103c, 0x22b7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7427 SND_PCI_QUIRK(0x103c, 0x22bf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08007428 SND_PCI_QUIRK(0x103c, 0x22cf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Keith Packard98973f22015-07-15 12:14:39 -07007429 SND_PCI_QUIRK(0x103c, 0x22db, "HP", ALC280_FIXUP_HP_9480M),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007430 SND_PCI_QUIRK(0x103c, 0x22dc, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
7431 SND_PCI_QUIRK(0x103c, 0x22fb, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yangc60666b2014-02-21 16:23:35 +08007432 /* ALC290 */
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007433 SND_PCI_QUIRK(0x103c, 0x221b, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007434 SND_PCI_QUIRK(0x103c, 0x2221, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007435 SND_PCI_QUIRK(0x103c, 0x2225, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007436 SND_PCI_QUIRK(0x103c, 0x2253, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
7437 SND_PCI_QUIRK(0x103c, 0x2254, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
7438 SND_PCI_QUIRK(0x103c, 0x2255, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
7439 SND_PCI_QUIRK(0x103c, 0x2256, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
7440 SND_PCI_QUIRK(0x103c, 0x2257, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007441 SND_PCI_QUIRK(0x103c, 0x2259, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Jaroslav Kysela04d54662017-03-09 13:29:13 +01007442 SND_PCI_QUIRK(0x103c, 0x225a, "HP", ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED),
Kailang Yangc60666b2014-02-21 16:23:35 +08007443 SND_PCI_QUIRK(0x103c, 0x2260, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08007444 SND_PCI_QUIRK(0x103c, 0x2263, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7445 SND_PCI_QUIRK(0x103c, 0x2264, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7446 SND_PCI_QUIRK(0x103c, 0x2265, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007447 SND_PCI_QUIRK(0x103c, 0x2272, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
7448 SND_PCI_QUIRK(0x103c, 0x2273, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007449 SND_PCI_QUIRK(0x103c, 0x2278, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yangc60666b2014-02-21 16:23:35 +08007450 SND_PCI_QUIRK(0x103c, 0x227f, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08007451 SND_PCI_QUIRK(0x103c, 0x2282, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08007452 SND_PCI_QUIRK(0x103c, 0x228b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08007453 SND_PCI_QUIRK(0x103c, 0x228e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7454 SND_PCI_QUIRK(0x103c, 0x22c5, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08007455 SND_PCI_QUIRK(0x103c, 0x22c7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7456 SND_PCI_QUIRK(0x103c, 0x22c8, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08007457 SND_PCI_QUIRK(0x103c, 0x22c4, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang8a02b162014-06-13 17:16:31 +08007458 SND_PCI_QUIRK(0x103c, 0x2334, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7459 SND_PCI_QUIRK(0x103c, 0x2335, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7460 SND_PCI_QUIRK(0x103c, 0x2336, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7461 SND_PCI_QUIRK(0x103c, 0x2337, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Takashi Iwaif8839822016-02-25 14:31:59 +01007462 SND_PCI_QUIRK(0x103c, 0x221c, "HP EliteBook 755 G2", ALC280_FIXUP_HP_HEADSET_MIC),
Jaroslav Kysela167897f2019-03-13 13:40:15 +01007463 SND_PCI_QUIRK(0x103c, 0x802e, "HP Z240 SFF", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
7464 SND_PCI_QUIRK(0x103c, 0x802f, "HP Z240", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
Takashi Iwai563785e2018-11-12 09:43:12 +01007465 SND_PCI_QUIRK(0x103c, 0x820d, "HP Pavilion 15", ALC269_FIXUP_HP_MUTE_LED_MIC3),
Hui Wange549d192016-04-01 11:00:15 +08007466 SND_PCI_QUIRK(0x103c, 0x8256, "HP", ALC221_FIXUP_HP_FRONT_MIC),
Tom Bridenbbf8ff62018-05-29 17:34:20 +01007467 SND_PCI_QUIRK(0x103c, 0x827e, "HP x360", ALC295_FIXUP_HP_X360),
Jaroslav Kysela167897f2019-03-13 13:40:15 +01007468 SND_PCI_QUIRK(0x103c, 0x82bf, "HP G3 mini", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
7469 SND_PCI_QUIRK(0x103c, 0x82c0, "HP G3 mini premium", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
Alexandru Gagniuc56e40eb2018-08-04 11:44:44 -05007470 SND_PCI_QUIRK(0x103c, 0x83b9, "HP Spectre x360", ALC269_FIXUP_HP_MUTE_LED_MIC3),
Takashi Iwai190d0382019-08-13 17:39:56 +02007471 SND_PCI_QUIRK(0x103c, 0x8497, "HP Envy x360", ALC269_FIXUP_HP_MUTE_LED_MIC3),
Sam Bazleyd33cd422019-09-01 03:31:30 +01007472 SND_PCI_QUIRK(0x103c, 0x84e7, "HP Pavilion 15", ALC269_FIXUP_HP_MUTE_LED_MIC3),
Kai-Heng Fengf5a88b02020-03-27 12:46:25 +08007473 SND_PCI_QUIRK(0x103c, 0x8736, "HP", ALC285_FIXUP_HP_GPIO_LED),
Kailang Yang431e76c2020-04-07 14:40:20 +08007474 SND_PCI_QUIRK(0x103c, 0x877a, "HP", ALC285_FIXUP_HP_MUTE_LED),
Kailang Yang24164f42020-04-07 14:52:42 +08007475 SND_PCI_QUIRK(0x103c, 0x877d, "HP", ALC236_FIXUP_HP_MUTE_LED),
Chris Chiuc1732ed2017-02-28 14:17:13 -06007476 SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC),
Takashi Iwai7bba2152013-09-06 15:45:38 +02007477 SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300),
David Henningsson3e0d6112013-04-22 14:30:14 +02007478 SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Wandrille RONCE9cf65332018-12-19 14:52:44 +01007479 SND_PCI_QUIRK(0x1043, 0x10a1, "ASUS UX391UA", ALC294_FIXUP_ASUS_SPK),
Chris Chiuc1732ed2017-02-28 14:17:13 -06007480 SND_PCI_QUIRK(0x1043, 0x10c0, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC),
Takashi Iwai4eab0ea2017-06-06 12:33:17 +02007481 SND_PCI_QUIRK(0x1043, 0x10d0, "ASUS X540LA/X540LJ", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
David Henningsson3e0d6112013-04-22 14:30:14 +02007482 SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Takashi Iwai4eab0ea2017-06-06 12:33:17 +02007483 SND_PCI_QUIRK(0x1043, 0x11c0, "ASUS X556UR", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
7484 SND_PCI_QUIRK(0x1043, 0x1290, "ASUS X441SA", ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE),
7485 SND_PCI_QUIRK(0x1043, 0x12a0, "ASUS X441UV", ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE),
Chris Chiuc1732ed2017-02-28 14:17:13 -06007486 SND_PCI_QUIRK(0x1043, 0x12f0, "ASUS X541UV", ALC256_FIXUP_ASUS_MIC),
7487 SND_PCI_QUIRK(0x1043, 0x12e0, "ASUS X541SA", ALC256_FIXUP_ASUS_MIC),
7488 SND_PCI_QUIRK(0x1043, 0x13b0, "ASUS Z550SA", ALC256_FIXUP_ASUS_MIC),
Oleksij Rempel2cede302013-11-27 17:12:03 +01007489 SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK),
Takashi Iwai23870832013-11-29 14:13:12 +01007490 SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A),
David Henningsson3e0d6112013-04-22 14:30:14 +02007491 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC),
Chris Chiu48e01502019-12-30 11:11:18 +08007492 SND_PCI_QUIRK(0x1043, 0x17d1, "ASUS UX431FL", ALC294_FIXUP_ASUS_DUAL_SPK),
Daniel Drake8c8967a2019-10-17 16:15:01 +08007493 SND_PCI_QUIRK(0x1043, 0x18b1, "Asus MJ401TA", ALC256_FIXUP_ASUS_HEADSET_MIC),
Adam Barber4963d662020-04-10 17:00:32 +08007494 SND_PCI_QUIRK(0x1043, 0x18f1, "Asus FX505DT", ALC256_FIXUP_ASUS_HEADSET_MIC),
Jian-Hong Pan8b33a132020-02-25 15:29:21 +08007495 SND_PCI_QUIRK(0x1043, 0x19ce, "ASUS B9450FA", ALC294_FIXUP_ASUS_HPE),
Jian-Hong Pan7900e812020-05-12 14:15:28 +08007496 SND_PCI_QUIRK(0x1043, 0x19e1, "ASUS UX581LV", ALC295_FIXUP_ASUS_MIC_NO_PRESENCE),
Takashi Iwai017f2a12011-07-09 14:42:25 +02007497 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
Chris Chiu28e8af82017-06-05 15:05:30 -06007498 SND_PCI_QUIRK(0x1043, 0x1a30, "ASUS X705UD", ALC256_FIXUP_ASUS_MIC),
Takashi Iwai1b94e592020-05-12 09:32:03 +02007499 SND_PCI_QUIRK(0x1043, 0x1b11, "ASUS UX431DA", ALC294_FIXUP_ASUS_COEF_1B),
David Henningsson693b6132012-06-22 19:12:10 +02007500 SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC),
Chris Chiu615966a2017-02-28 14:17:12 -06007501 SND_PCI_QUIRK(0x1043, 0x1bbd, "ASUS Z550MA", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
Takashi Iwai4eab0ea2017-06-06 12:33:17 +02007502 SND_PCI_QUIRK(0x1043, 0x1c23, "Asus X55U", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Chris Chiuc1732ed2017-02-28 14:17:13 -06007503 SND_PCI_QUIRK(0x1043, 0x1ccd, "ASUS X555UB", ALC256_FIXUP_ASUS_MIC),
Chris Chiueeed4cd2017-02-28 14:17:15 -06007504 SND_PCI_QUIRK(0x1043, 0x3030, "ASUS ZN270IE", ALC256_FIXUP_ASUS_AIO_GPIO2),
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02007505 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC),
7506 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC),
7507 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
7508 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
David Henningssond240d1d2013-04-15 12:50:02 +02007509 SND_PCI_QUIRK(0x1043, 0x8516, "ASUS X101CH", ALC269_FIXUP_ASUS_X101),
Takashi Iwaif88abaa2014-02-07 12:07:59 +01007510 SND_PCI_QUIRK(0x104d, 0x90b5, "Sony VAIO Pro 11", ALC286_FIXUP_SONY_MIC_NO_PRESENCE),
David Henningsson88cfcf82013-10-11 10:18:45 +02007511 SND_PCI_QUIRK(0x104d, 0x90b6, "Sony VAIO Pro 13", ALC286_FIXUP_SONY_MIC_NO_PRESENCE),
Takashi Iwai1d045db2011-07-07 18:23:21 +02007512 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
7513 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
7514 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
Takashi Iwaie9bd7d52014-05-21 11:06:49 +02007515 SND_PCI_QUIRK(0x104d, 0x9099, "Sony VAIO S13", ALC275_FIXUP_SONY_DISABLE_AAMIX),
Takashi Iwai24519912011-08-16 15:08:49 +02007516 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook", ALC269_FIXUP_LIFEBOOK),
Takashi Iwai4df3fd12015-06-29 08:38:02 +02007517 SND_PCI_QUIRK(0x10cf, 0x159f, "Lifebook E780", ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT),
Takashi Iwaicc7016a2015-04-08 20:47:55 +02007518 SND_PCI_QUIRK(0x10cf, 0x15dc, "Lifebook T731", ALC269_FIXUP_LIFEBOOK_HP_PIN),
Takashi Iwai88776f32015-05-01 09:20:34 +02007519 SND_PCI_QUIRK(0x10cf, 0x1757, "Lifebook E752", ALC269_FIXUP_LIFEBOOK_HP_PIN),
Jan-Marek Glogowskifdcc9682018-02-14 11:29:15 +01007520 SND_PCI_QUIRK(0x10cf, 0x1629, "Lifebook U7x7", ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC),
David Henningsson2041d562014-06-13 11:15:44 +02007521 SND_PCI_QUIRK(0x10cf, 0x1845, "Lifebook U904", ALC269_FIXUP_LIFEBOOK_EXTMIC),
PeiSen Houb84e8432017-09-01 15:11:56 +08007522 SND_PCI_QUIRK(0x10ec, 0x10f2, "Intel Reference board", ALC700_FIXUP_INTEL_REFERENCE),
YOKOTA Hiroshi0fca97a2018-07-01 18:30:01 +09007523 SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-SZ6", ALC269_FIXUP_HEADSET_MODE),
David Henningssona33cc482014-10-07 10:18:41 +02007524 SND_PCI_QUIRK(0x144d, 0xc109, "Samsung Ativ book 9 (NP900X3G)", ALC269_FIXUP_INV_DMIC),
Mike Pozulp14425f12020-05-09 20:28:37 -07007525 SND_PCI_QUIRK(0x144d, 0xc169, "Samsung Notebook 9 Pen (NP930SBE-K01US)", ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET),
7526 SND_PCI_QUIRK(0x144d, 0xc176, "Samsung Notebook 9 Pro (NP930MBE-K04US)", ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET),
Gabriele Mazzotta823ff162016-12-24 19:50:01 +01007527 SND_PCI_QUIRK(0x144d, 0xc740, "Samsung Ativ book 8 (NP870Z5G)", ALC269_FIXUP_ATIV_BOOK_8),
Anisse Astierabaa22742016-08-24 09:14:13 +02007528 SND_PCI_QUIRK(0x1458, 0xfa53, "Gigabyte BXBT-2807", ALC283_FIXUP_HEADSET_MIC),
7529 SND_PCI_QUIRK(0x1462, 0xb120, "MSI Cubi MS-B120", ALC283_FIXUP_HEADSET_MIC),
Anisse Astier8cd65272018-11-23 17:59:11 +01007530 SND_PCI_QUIRK(0x1462, 0xb171, "Cubi N 8GL (MS-B171)", ALC283_FIXUP_HEADSET_MIC),
Jeremy Soller89e3a562019-01-30 16:12:31 -07007531 SND_PCI_QUIRK(0x1558, 0x1325, "System76 Darter Pro (darp5)", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
Jeremy Soller80a50522019-05-07 17:11:08 -04007532 SND_PCI_QUIRK(0x1558, 0x8550, "System76 Gazelle (gaze14)", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
Jeremy Soller891afcf2019-05-10 10:15:07 -04007533 SND_PCI_QUIRK(0x1558, 0x8551, "System76 Gazelle (gaze14)", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
7534 SND_PCI_QUIRK(0x1558, 0x8560, "System76 Gazelle (gaze14)", ALC269_FIXUP_HEADSET_MIC),
7535 SND_PCI_QUIRK(0x1558, 0x8561, "System76 Gazelle (gaze14)", ALC269_FIXUP_HEADSET_MIC),
Kailang Yangca169cc2017-04-25 16:17:40 +08007536 SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC233_FIXUP_LENOVO_MULTI_CODECS),
Hui Wangef0b3202020-04-27 11:00:39 +08007537 SND_PCI_QUIRK(0x17aa, 0x1048, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC),
Takashi Iwai1d045db2011-07-07 18:23:21 +02007538 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
7539 SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
7540 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
7541 SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
7542 SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
Takashi Iwaib590b382020-05-14 18:05:33 +02007543 SND_PCI_QUIRK(0x17aa, 0x21f6, "Thinkpad T530", ALC269_FIXUP_LENOVO_DOCK_LIMIT_BOOST),
Felix Kaechelec8415a42012-08-06 23:02:01 +02007544 SND_PCI_QUIRK(0x17aa, 0x21fa, "Thinkpad X230", ALC269_FIXUP_LENOVO_DOCK),
Stefán Freyr84f98fd2012-10-19 22:46:00 +02007545 SND_PCI_QUIRK(0x17aa, 0x21f3, "Thinkpad T430", ALC269_FIXUP_LENOVO_DOCK),
Philipp A. Mohrenweiser4407be62012-08-06 13:14:18 +02007546 SND_PCI_QUIRK(0x17aa, 0x21fb, "Thinkpad T430s", ALC269_FIXUP_LENOVO_DOCK),
David Henningsson108cc102012-07-20 10:37:25 +02007547 SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK),
David Henningssonaaedfb42013-08-16 14:09:02 +02007548 SND_PCI_QUIRK(0x17aa, 0x2208, "Thinkpad T431s", ALC269_FIXUP_LENOVO_DOCK),
Takashi Iwai9a811232015-12-09 15:17:43 +01007549 SND_PCI_QUIRK(0x17aa, 0x220c, "Thinkpad T440s", ALC292_FIXUP_TPT440),
Takashi Iwai1c37c222014-05-06 17:34:42 +02007550 SND_PCI_QUIRK(0x17aa, 0x220e, "Thinkpad T440p", ALC292_FIXUP_TPT440_DOCK),
Takashi Iwaia12137e2014-06-27 12:14:35 +02007551 SND_PCI_QUIRK(0x17aa, 0x2210, "Thinkpad T540p", ALC292_FIXUP_TPT440_DOCK),
Rick Sherman59a51a62015-08-18 21:04:30 -05007552 SND_PCI_QUIRK(0x17aa, 0x2211, "Thinkpad W541", ALC292_FIXUP_TPT440_DOCK),
Takashi Iwai6d169412014-10-07 17:27:02 +02007553 SND_PCI_QUIRK(0x17aa, 0x2212, "Thinkpad T440", ALC292_FIXUP_TPT440_DOCK),
Lukas Bossard7c215392014-10-29 18:31:07 +01007554 SND_PCI_QUIRK(0x17aa, 0x2214, "Thinkpad X240", ALC292_FIXUP_TPT440_DOCK),
David Henningssona4a9e082013-08-16 14:09:01 +02007555 SND_PCI_QUIRK(0x17aa, 0x2215, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Takashi Iwaib6903c02015-12-10 12:20:20 +01007556 SND_PCI_QUIRK(0x17aa, 0x2218, "Thinkpad X1 Carbon 2nd", ALC292_FIXUP_TPT440_DOCK),
Laura Abbottd05ea7d2015-10-02 11:09:54 -07007557 SND_PCI_QUIRK(0x17aa, 0x2223, "ThinkPad T550", ALC292_FIXUP_TPT440_DOCK),
Yves-Alexis Perezc0278662015-04-11 09:31:35 +02007558 SND_PCI_QUIRK(0x17aa, 0x2226, "ThinkPad X250", ALC292_FIXUP_TPT440_DOCK),
Kailang Yang61fcf8e2018-02-02 15:26:46 +08007559 SND_PCI_QUIRK(0x17aa, 0x222d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7560 SND_PCI_QUIRK(0x17aa, 0x222e, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
Torsten Hilbrichdab38e42016-06-07 13:14:21 +02007561 SND_PCI_QUIRK(0x17aa, 0x2231, "Thinkpad T560", ALC292_FIXUP_TPT460),
Sven Eckelmannc636b952016-04-11 16:55:26 +02007562 SND_PCI_QUIRK(0x17aa, 0x2233, "Thinkpad", ALC292_FIXUP_TPT460),
Kailang Yang61fcf8e2018-02-02 15:26:46 +08007563 SND_PCI_QUIRK(0x17aa, 0x2245, "Thinkpad T470", ALC298_FIXUP_TPT470_DOCK),
7564 SND_PCI_QUIRK(0x17aa, 0x2246, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7565 SND_PCI_QUIRK(0x17aa, 0x2247, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
Dennis Wassenberge4c07b32018-03-08 13:17:54 +01007566 SND_PCI_QUIRK(0x17aa, 0x2249, "Thinkpad", ALC292_FIXUP_TPT460),
Kailang Yang61fcf8e2018-02-02 15:26:46 +08007567 SND_PCI_QUIRK(0x17aa, 0x224b, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7568 SND_PCI_QUIRK(0x17aa, 0x224c, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7569 SND_PCI_QUIRK(0x17aa, 0x224d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
Benjamin Berg85981df2018-02-14 13:29:39 +01007570 SND_PCI_QUIRK(0x17aa, 0x225d, "Thinkpad T480", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Kailang Yang76f7dec2020-02-10 16:30:26 +08007571 SND_PCI_QUIRK(0x17aa, 0x2292, "Thinkpad X1 Yoga 7th", ALC285_FIXUP_THINKPAD_HEADSET_JACK),
7572 SND_PCI_QUIRK(0x17aa, 0x2293, "Thinkpad X1 Carbon 7th", ALC285_FIXUP_THINKPAD_HEADSET_JACK),
Hans de Goedeca707b32020-04-02 19:43:11 +02007573 SND_PCI_QUIRK(0x17aa, 0x22be, "Thinkpad X1 Carbon 8th", ALC285_FIXUP_THINKPAD_HEADSET_JACK),
Kailang3694cb22015-12-28 11:35:24 +08007574 SND_PCI_QUIRK(0x17aa, 0x30bb, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
Hui Wang6ef2f682016-03-11 12:04:02 +08007575 SND_PCI_QUIRK(0x17aa, 0x30e2, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
Hui Wangf33f79f2017-07-07 12:08:29 +08007576 SND_PCI_QUIRK(0x17aa, 0x310c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
Dennis Wassenbergbef33e12019-06-28 10:54:53 +02007577 SND_PCI_QUIRK(0x17aa, 0x3111, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
Hui Wange41fc8c2018-06-25 14:40:56 +08007578 SND_PCI_QUIRK(0x17aa, 0x312a, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
Kailang Yang65811832018-04-25 17:07:27 +08007579 SND_PCI_QUIRK(0x17aa, 0x312f, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
Hui Wang8da5bbf2017-12-22 11:17:46 +08007580 SND_PCI_QUIRK(0x17aa, 0x313c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
Hui Wang2a36c162019-09-04 13:53:27 +08007581 SND_PCI_QUIRK(0x17aa, 0x3151, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC),
Aaron Ma8a6c55d2019-10-24 19:44:39 +08007582 SND_PCI_QUIRK(0x17aa, 0x3176, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC),
7583 SND_PCI_QUIRK(0x17aa, 0x3178, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC),
David Henningsson56f27012016-01-11 09:33:14 +01007584 SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
Takashi Iwaifedb2242014-11-13 07:11:38 +01007585 SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC),
Michał Wadowski56df90b2019-05-14 16:58:00 +02007586 SND_PCI_QUIRK(0x17aa, 0x3978, "Lenovo B50-70", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
David Henningssona4a9e082013-08-16 14:09:01 +02007587 SND_PCI_QUIRK(0x17aa, 0x5013, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Kailang Yang1bb3e062013-09-27 13:10:25 +02007588 SND_PCI_QUIRK(0x17aa, 0x501a, "Thinkpad", ALC283_FIXUP_INT_MIC),
Takashi Iwaic497d9f2014-10-08 12:14:40 +02007589 SND_PCI_QUIRK(0x17aa, 0x501e, "Thinkpad L440", ALC292_FIXUP_TPT440_DOCK),
David Henningssoncd5302c2013-08-19 12:22:33 +02007590 SND_PCI_QUIRK(0x17aa, 0x5026, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Jo-Philipp Wichf2aa1112015-04-13 12:47:26 +02007591 SND_PCI_QUIRK(0x17aa, 0x5034, "Thinkpad T450", ALC292_FIXUP_TPT440_DOCK),
Sebastian Wicki80b311d2015-03-23 17:23:11 +01007592 SND_PCI_QUIRK(0x17aa, 0x5036, "Thinkpad T450s", ALC292_FIXUP_TPT440_DOCK),
Ansgar Hegerfeld09ea9972015-05-14 12:31:32 +02007593 SND_PCI_QUIRK(0x17aa, 0x503c, "Thinkpad L450", ALC292_FIXUP_TPT440_DOCK),
Conrad Kostecki037e1192016-04-26 10:08:10 +02007594 SND_PCI_QUIRK(0x17aa, 0x504a, "ThinkPad X260", ALC292_FIXUP_TPT440_DOCK),
Hui Wang23adc192015-12-08 12:27:18 +08007595 SND_PCI_QUIRK(0x17aa, 0x504b, "Thinkpad", ALC293_FIXUP_LENOVO_SPK_NOISE),
Jaroslav Kysela0f087ee2016-06-24 15:13:16 +02007596 SND_PCI_QUIRK(0x17aa, 0x5050, "Thinkpad T560p", ALC292_FIXUP_TPT460),
Torsten Hilbrich9cd25742016-07-05 10:40:22 +02007597 SND_PCI_QUIRK(0x17aa, 0x5051, "Thinkpad L460", ALC292_FIXUP_TPT460),
Jaroslav Kysela0f087ee2016-06-24 15:13:16 +02007598 SND_PCI_QUIRK(0x17aa, 0x5053, "Thinkpad T460", ALC292_FIXUP_TPT460),
Kailang Yang61fcf8e2018-02-02 15:26:46 +08007599 SND_PCI_QUIRK(0x17aa, 0x505d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7600 SND_PCI_QUIRK(0x17aa, 0x505f, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7601 SND_PCI_QUIRK(0x17aa, 0x5062, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
David Henningssoncd5302c2013-08-19 12:22:33 +02007602 SND_PCI_QUIRK(0x17aa, 0x5109, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Kailang Yang61fcf8e2018-02-02 15:26:46 +08007603 SND_PCI_QUIRK(0x17aa, 0x511e, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7604 SND_PCI_QUIRK(0x17aa, 0x511f, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
David Henningsson012e7eb2012-08-08 08:43:37 +02007605 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K),
Takashi Iwai1d045db2011-07-07 18:23:21 +02007606 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
Ayman Bagabas0fbf21c2019-05-23 05:30:11 -04007607 SND_PCI_QUIRK(0x19e5, 0x3204, "Huawei MACH-WX9", ALC256_FIXUP_HUAWEI_MACH_WX9_PINS),
Anisse Astier02b504d2013-06-03 11:53:10 +02007608 SND_PCI_QUIRK(0x1b7d, 0xa831, "Ordissimo EVE2 ", ALC269VB_FIXUP_ORDISSIMO_EVE2), /* Also known as Malata PC-B1303 */
Hui Wang695d1ec2019-11-21 10:54:27 +08007609 SND_PCI_QUIRK(0x1d72, 0x1901, "RedmiBook 14", ALC256_FIXUP_ASUS_HEADSET_MIC),
Jan-Marek Glogowskibd9c10b2019-09-15 16:57:28 +02007610 SND_PCI_QUIRK(0x10ec, 0x118c, "Medion EE4254 MD62100", ALC256_FIXUP_MEDION_HEADSET_NO_PRESENCE),
Takashi Iwaia4297b52011-08-23 18:40:12 +02007611
Takashi Iwaia7f3eed2012-02-16 13:03:18 +01007612#if 0
Takashi Iwaia4297b52011-08-23 18:40:12 +02007613 /* Below is a quirk table taken from the old code.
7614 * Basically the device should work as is without the fixup table.
7615 * If BIOS doesn't give a proper info, enable the corresponding
7616 * fixup entry.
Jesper Juhl7d7eb9e2012-04-12 22:11:25 +02007617 */
Takashi Iwaia4297b52011-08-23 18:40:12 +02007618 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
7619 ALC269_FIXUP_AMIC),
7620 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269_FIXUP_AMIC),
Takashi Iwaia4297b52011-08-23 18:40:12 +02007621 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269_FIXUP_AMIC),
7622 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_FIXUP_AMIC),
7623 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269_FIXUP_AMIC),
7624 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269_FIXUP_AMIC),
7625 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269_FIXUP_AMIC),
7626 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269_FIXUP_AMIC),
7627 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_FIXUP_AMIC),
7628 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269_FIXUP_AMIC),
7629 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_FIXUP_AMIC),
7630 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_FIXUP_AMIC),
7631 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_FIXUP_AMIC),
7632 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_FIXUP_AMIC),
7633 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_FIXUP_AMIC),
7634 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_FIXUP_AMIC),
7635 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_FIXUP_AMIC),
7636 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_FIXUP_AMIC),
7637 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_FIXUP_AMIC),
7638 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_FIXUP_AMIC),
7639 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_FIXUP_AMIC),
7640 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_FIXUP_AMIC),
7641 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_FIXUP_AMIC),
7642 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_FIXUP_AMIC),
7643 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_FIXUP_AMIC),
7644 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_FIXUP_AMIC),
7645 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_FIXUP_AMIC),
7646 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_FIXUP_AMIC),
7647 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_FIXUP_AMIC),
7648 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_FIXUP_AMIC),
7649 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_FIXUP_AMIC),
7650 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_FIXUP_AMIC),
7651 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_FIXUP_AMIC),
7652 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_FIXUP_AMIC),
7653 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_FIXUP_AMIC),
7654 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_FIXUP_DMIC),
7655 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_FIXUP_AMIC),
7656 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_AMIC),
7657 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_FIXUP_DMIC),
7658 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_FIXUP_DMIC),
7659#endif
7660 {}
7661};
7662
David Henningsson214eef72014-07-22 14:09:35 +02007663static const struct snd_pci_quirk alc269_fixup_vendor_tbl[] = {
7664 SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC),
7665 SND_PCI_QUIRK_VENDOR(0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED),
7666 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
7667 SND_PCI_QUIRK_VENDOR(0x17aa, "Thinkpad", ALC269_FIXUP_THINKPAD_ACPI),
Ayman Bagabas0fbf21c2019-05-23 05:30:11 -04007668 SND_PCI_QUIRK_VENDOR(0x19e5, "Huawei Matebook", ALC255_FIXUP_MIC_MUTE_LED),
David Henningsson214eef72014-07-22 14:09:35 +02007669 {}
7670};
7671
Takashi Iwai1727a772013-01-10 09:52:52 +01007672static const struct hda_model_fixup alc269_fixup_models[] = {
Takashi Iwaia4297b52011-08-23 18:40:12 +02007673 {.id = ALC269_FIXUP_AMIC, .name = "laptop-amic"},
7674 {.id = ALC269_FIXUP_DMIC, .name = "laptop-dmic"},
Takashi Iwai6e72aa52012-06-25 10:52:25 +02007675 {.id = ALC269_FIXUP_STEREO_DMIC, .name = "alc269-dmic"},
7676 {.id = ALC271_FIXUP_DMIC, .name = "alc271-dmic"},
7677 {.id = ALC269_FIXUP_INV_DMIC, .name = "inv-dmic"},
David Henningsson7c478f02013-10-11 10:18:46 +02007678 {.id = ALC269_FIXUP_HEADSET_MIC, .name = "headset-mic"},
Takashi Iwaib0169512015-05-19 10:20:13 +02007679 {.id = ALC269_FIXUP_HEADSET_MODE, .name = "headset-mode"},
7680 {.id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC, .name = "headset-mode-no-hp-mic"},
David Henningsson108cc102012-07-20 10:37:25 +02007681 {.id = ALC269_FIXUP_LENOVO_DOCK, .name = "lenovo-dock"},
Takashi Iwaib590b382020-05-14 18:05:33 +02007682 {.id = ALC269_FIXUP_LENOVO_DOCK_LIMIT_BOOST, .name = "lenovo-dock-limit-boost"},
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01007683 {.id = ALC269_FIXUP_HP_GPIO_LED, .name = "hp-gpio-led"},
Jaroslav Kysela04d54662017-03-09 13:29:13 +01007684 {.id = ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED, .name = "hp-dock-gpio-mic1-led"},
David Henningssone32aa852013-06-17 11:04:02 +02007685 {.id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "dell-headset-multi"},
7686 {.id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE, .name = "dell-headset-dock"},
Takashi Iwaia26d96c2018-06-26 15:09:25 +02007687 {.id = ALC269_FIXUP_DELL3_MIC_NO_PRESENCE, .name = "dell-headset3"},
7688 {.id = ALC269_FIXUP_DELL4_MIC_NO_PRESENCE, .name = "dell-headset4"},
Kailang Yangbe8ef162014-04-08 15:19:49 +08007689 {.id = ALC283_FIXUP_CHROME_BOOK, .name = "alc283-dac-wcaps"},
Kailang Yang0202e992013-12-02 15:20:15 +08007690 {.id = ALC283_FIXUP_SENSE_COMBO_JACK, .name = "alc283-sense-combo"},
Takashi Iwai1c37c222014-05-06 17:34:42 +02007691 {.id = ALC292_FIXUP_TPT440_DOCK, .name = "tpt440-dock"},
Takashi Iwai9a811232015-12-09 15:17:43 +01007692 {.id = ALC292_FIXUP_TPT440, .name = "tpt440"},
Sven Eckelmannc636b952016-04-11 16:55:26 +02007693 {.id = ALC292_FIXUP_TPT460, .name = "tpt460"},
Takashi Iwai399c01a2020-05-26 08:24:06 +02007694 {.id = ALC298_FIXUP_TPT470_DOCK_FIX, .name = "tpt470-dock-fix"},
Takashi Iwaia26d96c2018-06-26 15:09:25 +02007695 {.id = ALC298_FIXUP_TPT470_DOCK, .name = "tpt470-dock"},
Takashi Iwaiba90d6a2017-05-22 16:38:47 +02007696 {.id = ALC233_FIXUP_LENOVO_MULTI_CODECS, .name = "dual-codecs"},
Takashi Iwai28d1d6d2017-10-18 14:01:58 +02007697 {.id = ALC700_FIXUP_INTEL_REFERENCE, .name = "alc700-ref"},
Takashi Iwaia26d96c2018-06-26 15:09:25 +02007698 {.id = ALC269_FIXUP_SONY_VAIO, .name = "vaio"},
7699 {.id = ALC269_FIXUP_DELL_M101Z, .name = "dell-m101z"},
7700 {.id = ALC269_FIXUP_ASUS_G73JW, .name = "asus-g73jw"},
7701 {.id = ALC269_FIXUP_LENOVO_EAPD, .name = "lenovo-eapd"},
7702 {.id = ALC275_FIXUP_SONY_HWEQ, .name = "sony-hweq"},
7703 {.id = ALC269_FIXUP_PCM_44K, .name = "pcm44k"},
7704 {.id = ALC269_FIXUP_LIFEBOOK, .name = "lifebook"},
7705 {.id = ALC269_FIXUP_LIFEBOOK_EXTMIC, .name = "lifebook-extmic"},
7706 {.id = ALC269_FIXUP_LIFEBOOK_HP_PIN, .name = "lifebook-hp-pin"},
7707 {.id = ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC, .name = "lifebook-u7x7"},
7708 {.id = ALC269VB_FIXUP_AMIC, .name = "alc269vb-amic"},
7709 {.id = ALC269VB_FIXUP_DMIC, .name = "alc269vb-dmic"},
7710 {.id = ALC269_FIXUP_HP_MUTE_LED_MIC1, .name = "hp-mute-led-mic1"},
7711 {.id = ALC269_FIXUP_HP_MUTE_LED_MIC2, .name = "hp-mute-led-mic2"},
7712 {.id = ALC269_FIXUP_HP_MUTE_LED_MIC3, .name = "hp-mute-led-mic3"},
7713 {.id = ALC269_FIXUP_HP_GPIO_MIC1_LED, .name = "hp-gpio-mic1"},
7714 {.id = ALC269_FIXUP_HP_LINE1_MIC1_LED, .name = "hp-line1-mic1"},
7715 {.id = ALC269_FIXUP_NO_SHUTUP, .name = "noshutup"},
7716 {.id = ALC286_FIXUP_SONY_MIC_NO_PRESENCE, .name = "sony-nomic"},
7717 {.id = ALC269_FIXUP_ASPIRE_HEADSET_MIC, .name = "aspire-headset-mic"},
7718 {.id = ALC269_FIXUP_ASUS_X101, .name = "asus-x101"},
7719 {.id = ALC271_FIXUP_HP_GATE_MIC_JACK, .name = "acer-ao7xx"},
7720 {.id = ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572, .name = "acer-aspire-e1"},
7721 {.id = ALC269_FIXUP_ACER_AC700, .name = "acer-ac700"},
7722 {.id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST, .name = "limit-mic-boost"},
7723 {.id = ALC269VB_FIXUP_ASUS_ZENBOOK, .name = "asus-zenbook"},
7724 {.id = ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A, .name = "asus-zenbook-ux31a"},
7725 {.id = ALC269VB_FIXUP_ORDISSIMO_EVE2, .name = "ordissimo"},
7726 {.id = ALC282_FIXUP_ASUS_TX300, .name = "asus-tx300"},
7727 {.id = ALC283_FIXUP_INT_MIC, .name = "alc283-int-mic"},
7728 {.id = ALC290_FIXUP_MONO_SPEAKERS_HSJACK, .name = "mono-speakers"},
7729 {.id = ALC290_FIXUP_SUBWOOFER_HSJACK, .name = "alc290-subwoofer"},
7730 {.id = ALC269_FIXUP_THINKPAD_ACPI, .name = "thinkpad"},
7731 {.id = ALC269_FIXUP_DMIC_THINKPAD_ACPI, .name = "dmic-thinkpad"},
7732 {.id = ALC255_FIXUP_ACER_MIC_NO_PRESENCE, .name = "alc255-acer"},
7733 {.id = ALC255_FIXUP_ASUS_MIC_NO_PRESENCE, .name = "alc255-asus"},
7734 {.id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc255-dell1"},
7735 {.id = ALC255_FIXUP_DELL2_MIC_NO_PRESENCE, .name = "alc255-dell2"},
7736 {.id = ALC293_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc293-dell1"},
7737 {.id = ALC283_FIXUP_HEADSET_MIC, .name = "alc283-headset"},
Takashi Iwaib3802782018-11-26 17:47:46 +01007738 {.id = ALC255_FIXUP_MIC_MUTE_LED, .name = "alc255-dell-mute"},
Takashi Iwaia26d96c2018-06-26 15:09:25 +02007739 {.id = ALC282_FIXUP_ASPIRE_V5_PINS, .name = "aspire-v5"},
7740 {.id = ALC280_FIXUP_HP_GPIO4, .name = "hp-gpio4"},
7741 {.id = ALC286_FIXUP_HP_GPIO_LED, .name = "hp-gpio-led"},
7742 {.id = ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY, .name = "hp-gpio2-hotkey"},
7743 {.id = ALC280_FIXUP_HP_DOCK_PINS, .name = "hp-dock-pins"},
7744 {.id = ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED, .name = "hp-dock-gpio-mic"},
7745 {.id = ALC280_FIXUP_HP_9480M, .name = "hp-9480m"},
7746 {.id = ALC288_FIXUP_DELL_HEADSET_MODE, .name = "alc288-dell-headset"},
7747 {.id = ALC288_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc288-dell1"},
7748 {.id = ALC288_FIXUP_DELL_XPS_13, .name = "alc288-dell-xps13"},
7749 {.id = ALC292_FIXUP_DELL_E7X, .name = "dell-e7x"},
7750 {.id = ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK, .name = "alc293-dell"},
7751 {.id = ALC298_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc298-dell1"},
7752 {.id = ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE, .name = "alc298-dell-aio"},
7753 {.id = ALC275_FIXUP_DELL_XPS, .name = "alc275-dell-xps"},
Takashi Iwaia26d96c2018-06-26 15:09:25 +02007754 {.id = ALC293_FIXUP_LENOVO_SPK_NOISE, .name = "lenovo-spk-noise"},
7755 {.id = ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY, .name = "lenovo-hotkey"},
7756 {.id = ALC255_FIXUP_DELL_SPK_NOISE, .name = "dell-spk-noise"},
Kailang Yang82aa0d72019-01-11 17:15:53 +08007757 {.id = ALC225_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc225-dell1"},
Takashi Iwaia26d96c2018-06-26 15:09:25 +02007758 {.id = ALC295_FIXUP_DISABLE_DAC3, .name = "alc295-disable-dac3"},
Jaroslav Kyselad2cd7952019-11-29 15:40:27 +01007759 {.id = ALC285_FIXUP_SPEAKER2_TO_DAC1, .name = "alc285-speaker2-to-dac1"},
Takashi Iwaia26d96c2018-06-26 15:09:25 +02007760 {.id = ALC280_FIXUP_HP_HEADSET_MIC, .name = "alc280-hp-headset"},
7761 {.id = ALC221_FIXUP_HP_FRONT_MIC, .name = "alc221-hp-mic"},
7762 {.id = ALC298_FIXUP_SPK_VOLUME, .name = "alc298-spk-volume"},
7763 {.id = ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER, .name = "dell-inspiron-7559"},
7764 {.id = ALC269_FIXUP_ATIV_BOOK_8, .name = "ativ-book"},
7765 {.id = ALC221_FIXUP_HP_MIC_NO_PRESENCE, .name = "alc221-hp-mic"},
7766 {.id = ALC256_FIXUP_ASUS_HEADSET_MODE, .name = "alc256-asus-headset"},
7767 {.id = ALC256_FIXUP_ASUS_MIC, .name = "alc256-asus-mic"},
7768 {.id = ALC256_FIXUP_ASUS_AIO_GPIO2, .name = "alc256-asus-aio"},
7769 {.id = ALC233_FIXUP_ASUS_MIC_NO_PRESENCE, .name = "alc233-asus"},
7770 {.id = ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE, .name = "alc233-eapd"},
7771 {.id = ALC294_FIXUP_LENOVO_MIC_LOCATION, .name = "alc294-lenovo-mic"},
7772 {.id = ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE, .name = "alc225-wyse"},
7773 {.id = ALC274_FIXUP_DELL_AIO_LINEOUT_VERB, .name = "alc274-dell-aio"},
7774 {.id = ALC255_FIXUP_DUMMY_LINEOUT_VERB, .name = "alc255-dummy-lineout"},
7775 {.id = ALC255_FIXUP_DELL_HEADSET_MIC, .name = "alc255-dell-headset"},
7776 {.id = ALC295_FIXUP_HP_X360, .name = "alc295-hp-x360"},
Kailang Yang8983eb62019-04-03 15:31:49 +08007777 {.id = ALC225_FIXUP_HEADSET_JACK, .name = "alc-headset-jack"},
7778 {.id = ALC295_FIXUP_CHROME_BOOK, .name = "alc-chrome-book"},
Bernhard Rosenkraenzere2a829b2019-03-05 00:38:19 +01007779 {.id = ALC299_FIXUP_PREDATOR_SPK, .name = "predator-spk"},
Tomas Espeletaa2ef03f2019-08-09 16:37:54 +02007780 {.id = ALC298_FIXUP_HUAWEI_MBX_STEREO, .name = "huawei-mbx-stereo"},
Jan-Marek Glogowskibd9c10b2019-09-15 16:57:28 +02007781 {.id = ALC256_FIXUP_MEDION_HEADSET_NO_PRESENCE, .name = "alc256-medion-headset"},
Takashi Iwai1d045db2011-07-07 18:23:21 +02007782 {}
7783};
Kailang Yangcfc5a842016-02-03 15:20:39 +08007784#define ALC225_STANDARD_PINS \
Kailang Yangcfc5a842016-02-03 15:20:39 +08007785 {0x21, 0x04211020}
Takashi Iwai1d045db2011-07-07 18:23:21 +02007786
Hui Wange8191a82015-04-24 13:39:59 +08007787#define ALC256_STANDARD_PINS \
7788 {0x12, 0x90a60140}, \
7789 {0x14, 0x90170110}, \
Hui Wange8191a82015-04-24 13:39:59 +08007790 {0x21, 0x02211020}
7791
David Henningssonfea185e2014-09-03 10:23:04 +02007792#define ALC282_STANDARD_PINS \
Hui Wang11580292015-08-03 11:03:49 +08007793 {0x14, 0x90170110}
Kailang Yange1e62b92015-04-08 16:01:22 +08007794
David Henningssonfea185e2014-09-03 10:23:04 +02007795#define ALC290_STANDARD_PINS \
Hui Wang11580292015-08-03 11:03:49 +08007796 {0x12, 0x99a30130}
David Henningssonfea185e2014-09-03 10:23:04 +02007797
7798#define ALC292_STANDARD_PINS \
7799 {0x14, 0x90170110}, \
Hui Wang11580292015-08-03 11:03:49 +08007800 {0x15, 0x0221401f}
Kailang Yang977e6272015-05-18 15:31:20 +08007801
Hui Wang3f6409702016-09-11 11:26:16 +08007802#define ALC295_STANDARD_PINS \
7803 {0x12, 0xb7a60130}, \
7804 {0x14, 0x90170110}, \
Hui Wang3f6409702016-09-11 11:26:16 +08007805 {0x21, 0x04211020}
7806
Woodrow Shen703867e2015-08-05 12:34:12 +08007807#define ALC298_STANDARD_PINS \
7808 {0x12, 0x90a60130}, \
7809 {0x21, 0x03211020}
7810
Hui Wange1918932014-05-26 16:22:44 +08007811static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
Kailang Yang8a328ac2018-08-21 16:54:41 +08007812 SND_HDA_PIN_QUIRK(0x10ec0221, 0x103c, "HP Workstation", ALC221_FIXUP_HP_HEADSET_MIC,
7813 {0x14, 0x01014020},
7814 {0x17, 0x90170110},
7815 {0x18, 0x02a11030},
7816 {0x19, 0x0181303F},
7817 {0x21, 0x0221102f}),
Chris Chiu5824ce82017-02-28 14:17:11 -06007818 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1025, "Acer", ALC255_FIXUP_ACER_MIC_NO_PRESENCE,
7819 {0x12, 0x90a601c0},
7820 {0x14, 0x90171120},
7821 {0x21, 0x02211030}),
Chris Chiu615966a2017-02-28 14:17:12 -06007822 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1043, "ASUS", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE,
7823 {0x14, 0x90170110},
7824 {0x1b, 0x90a70130},
7825 {0x21, 0x03211020}),
7826 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1043, "ASUS", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE,
7827 {0x1a, 0x90a70130},
7828 {0x1b, 0x90170110},
7829 {0x21, 0x03211020}),
David Henningsson2ae95572016-02-25 09:37:05 +01007830 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
Kailang Yangcfc5a842016-02-03 15:20:39 +08007831 ALC225_STANDARD_PINS,
Hui Wang8a132092016-07-08 14:26:57 +08007832 {0x12, 0xb7a60130},
Kailang Yangcfc5a842016-02-03 15:20:39 +08007833 {0x14, 0x901701a0}),
David Henningsson2ae95572016-02-25 09:37:05 +01007834 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
Kailang Yangcfc5a842016-02-03 15:20:39 +08007835 ALC225_STANDARD_PINS,
Hui Wang8a132092016-07-08 14:26:57 +08007836 {0x12, 0xb7a60130},
Kailang Yangcfc5a842016-02-03 15:20:39 +08007837 {0x14, 0x901701b0}),
Hui Wang8a132092016-07-08 14:26:57 +08007838 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
7839 ALC225_STANDARD_PINS,
7840 {0x12, 0xb7a60150},
7841 {0x14, 0x901701a0}),
7842 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
7843 ALC225_STANDARD_PINS,
7844 {0x12, 0xb7a60150},
7845 {0x14, 0x901701b0}),
7846 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
7847 ALC225_STANDARD_PINS,
7848 {0x12, 0xb7a60130},
7849 {0x1b, 0x90170110}),
Kai-Heng Feng0ce48e12017-11-20 02:29:13 -05007850 SND_HDA_PIN_QUIRK(0x10ec0233, 0x8086, "Intel NUC Skull Canyon", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
7851 {0x1b, 0x01111010},
7852 {0x1e, 0x01451130},
7853 {0x21, 0x02211020}),
Hui Wang986376b2018-05-30 12:33:07 +08007854 SND_HDA_PIN_QUIRK(0x10ec0235, 0x17aa, "Lenovo", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY,
7855 {0x12, 0x90a60140},
7856 {0x14, 0x90170110},
7857 {0x19, 0x02a11030},
7858 {0x21, 0x02211020}),
Hui Wange41fc8c2018-06-25 14:40:56 +08007859 SND_HDA_PIN_QUIRK(0x10ec0235, 0x17aa, "Lenovo", ALC294_FIXUP_LENOVO_MIC_LOCATION,
7860 {0x14, 0x90170110},
7861 {0x19, 0x02a11030},
7862 {0x1a, 0x02a11040},
7863 {0x1b, 0x01014020},
7864 {0x21, 0x0221101f}),
Hui Wangc6b17f12018-07-06 15:14:11 +08007865 SND_HDA_PIN_QUIRK(0x10ec0235, 0x17aa, "Lenovo", ALC294_FIXUP_LENOVO_MIC_LOCATION,
7866 {0x14, 0x90170110},
Hui Wangd06fb562018-10-10 11:57:25 +08007867 {0x19, 0x02a11030},
7868 {0x1a, 0x02a11040},
7869 {0x1b, 0x01011020},
7870 {0x21, 0x0221101f}),
7871 SND_HDA_PIN_QUIRK(0x10ec0235, 0x17aa, "Lenovo", ALC294_FIXUP_LENOVO_MIC_LOCATION,
7872 {0x14, 0x90170110},
Hui Wangc6b17f12018-07-06 15:14:11 +08007873 {0x19, 0x02a11020},
7874 {0x1a, 0x02a11030},
7875 {0x21, 0x0221101f}),
Hui Wangc77900e2014-09-03 11:31:07 +08007876 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE,
Hui Wangc77900e2014-09-03 11:31:07 +08007877 {0x14, 0x90170110},
Hui Wangc77900e2014-09-03 11:31:07 +08007878 {0x21, 0x02211020}),
David Henningsson76c21322014-06-24 14:46:54 +02007879 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang86c72d12016-05-25 12:12:32 +08007880 {0x14, 0x90170130},
7881 {0x21, 0x02211040}),
7882 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningsson76c21322014-06-24 14:46:54 +02007883 {0x12, 0x90a60140},
7884 {0x14, 0x90170110},
David Henningsson76c21322014-06-24 14:46:54 +02007885 {0x21, 0x02211020}),
7886 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7887 {0x12, 0x90a60160},
7888 {0x14, 0x90170120},
David Henningsson76c21322014-06-24 14:46:54 +02007889 {0x21, 0x02211030}),
7890 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang392c9da2016-09-26 10:59:38 +08007891 {0x14, 0x90170110},
7892 {0x1b, 0x02011020},
7893 {0x21, 0x0221101f}),
7894 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang6aecd872016-10-20 14:03:33 +08007895 {0x14, 0x90170110},
7896 {0x1b, 0x01011020},
7897 {0x21, 0x0221101f}),
7898 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssoncba59972015-07-22 10:00:25 +02007899 {0x14, 0x90170130},
David Henningssoncba59972015-07-22 10:00:25 +02007900 {0x1b, 0x01014020},
David Henningssoncba59972015-07-22 10:00:25 +02007901 {0x21, 0x0221103f}),
7902 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang59ec4b52016-08-04 15:28:04 +08007903 {0x14, 0x90170130},
Hui Wang6aecd872016-10-20 14:03:33 +08007904 {0x1b, 0x01011020},
7905 {0x21, 0x0221103f}),
7906 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7907 {0x14, 0x90170130},
Hui Wang59ec4b52016-08-04 15:28:04 +08007908 {0x1b, 0x02011020},
7909 {0x21, 0x0221103f}),
7910 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Woodrow Shene9c28e12015-07-25 10:36:16 +08007911 {0x14, 0x90170150},
Woodrow Shene9c28e12015-07-25 10:36:16 +08007912 {0x1b, 0x02011020},
Woodrow Shene9c28e12015-07-25 10:36:16 +08007913 {0x21, 0x0221105f}),
7914 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Woodrow Shene9c28e12015-07-25 10:36:16 +08007915 {0x14, 0x90170110},
Woodrow Shene9c28e12015-07-25 10:36:16 +08007916 {0x1b, 0x01014020},
Woodrow Shene9c28e12015-07-25 10:36:16 +08007917 {0x21, 0x0221101f}),
7918 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningsson76c21322014-06-24 14:46:54 +02007919 {0x12, 0x90a60160},
7920 {0x14, 0x90170120},
7921 {0x17, 0x90170140},
David Henningsson76c21322014-06-24 14:46:54 +02007922 {0x21, 0x0321102f}),
7923 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7924 {0x12, 0x90a60160},
7925 {0x14, 0x90170130},
David Henningsson76c21322014-06-24 14:46:54 +02007926 {0x21, 0x02211040}),
7927 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7928 {0x12, 0x90a60160},
7929 {0x14, 0x90170140},
David Henningsson76c21322014-06-24 14:46:54 +02007930 {0x21, 0x02211050}),
7931 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7932 {0x12, 0x90a60170},
7933 {0x14, 0x90170120},
David Henningsson76c21322014-06-24 14:46:54 +02007934 {0x21, 0x02211030}),
7935 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7936 {0x12, 0x90a60170},
7937 {0x14, 0x90170130},
David Henningsson76c21322014-06-24 14:46:54 +02007938 {0x21, 0x02211040}),
Hui Wang70658b92015-03-06 14:03:57 +08007939 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang70658b92015-03-06 14:03:57 +08007940 {0x12, 0x90a60170},
Hui Wang0a1f90a2016-01-13 11:51:38 +08007941 {0x14, 0x90171130},
7942 {0x21, 0x02211040}),
7943 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7944 {0x12, 0x90a60170},
Hui Wang70658b92015-03-06 14:03:57 +08007945 {0x14, 0x90170140},
Hui Wang70658b92015-03-06 14:03:57 +08007946 {0x21, 0x02211050}),
David Henningsson9b5a4e32015-05-11 14:04:14 +02007947 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell Inspiron 5548", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningsson9b5a4e32015-05-11 14:04:14 +02007948 {0x12, 0x90a60180},
7949 {0x14, 0x90170130},
David Henningsson9b5a4e32015-05-11 14:04:14 +02007950 {0x21, 0x02211040}),
AceLan Kaof90d83b2016-06-03 14:45:25 +08007951 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell Inspiron 5565", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7952 {0x12, 0x90a60180},
7953 {0x14, 0x90170120},
7954 {0x21, 0x02211030}),
Hui Wang989dbe42016-11-23 16:05:38 +08007955 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7956 {0x1b, 0x01011020},
7957 {0x21, 0x02211010}),
Chris Chiuc1732ed2017-02-28 14:17:13 -06007958 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC,
7959 {0x14, 0x90170110},
7960 {0x1b, 0x90a70130},
7961 {0x21, 0x04211020}),
7962 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC,
7963 {0x14, 0x90170110},
7964 {0x1b, 0x90a70130},
7965 {0x21, 0x03211020}),
Jian-Hong Pane1037352019-03-22 11:37:18 +08007966 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE,
Chris Chiua806ef12019-03-22 11:37:20 +08007967 {0x12, 0x90a60130},
7968 {0x14, 0x90170110},
7969 {0x21, 0x03211020}),
7970 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE,
Jian-Hong Pan6ac371a2019-03-22 11:37:22 +08007971 {0x12, 0x90a60130},
7972 {0x14, 0x90170110},
7973 {0x21, 0x04211020}),
7974 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE,
Jian-Hong Pane1037352019-03-22 11:37:18 +08007975 {0x1a, 0x90a70130},
7976 {0x1b, 0x90170110},
7977 {0x21, 0x03211020}),
David Henningssoncf51eb92014-10-30 08:26:02 +01007978 SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC280_FIXUP_HP_GPIO4,
7979 {0x12, 0x90a60130},
David Henningssoncf51eb92014-10-30 08:26:02 +01007980 {0x14, 0x90170110},
7981 {0x15, 0x0421101f},
Hui Wang11580292015-08-03 11:03:49 +08007982 {0x1a, 0x04a11020}),
Hui Wang02796612014-09-03 11:31:11 +08007983 SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED,
7984 {0x12, 0x90a60140},
Hui Wang02796612014-09-03 11:31:11 +08007985 {0x14, 0x90170110},
7986 {0x15, 0x0421101f},
Hui Wang02796612014-09-03 11:31:11 +08007987 {0x18, 0x02811030},
Hui Wang02796612014-09-03 11:31:11 +08007988 {0x1a, 0x04a1103f},
Hui Wang11580292015-08-03 11:03:49 +08007989 {0x1b, 0x02011020}),
David Henningsson42304472014-07-22 11:42:17 +02007990 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP 15 Touchsmart", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007991 ALC282_STANDARD_PINS,
David Henningsson42304472014-07-22 11:42:17 +02007992 {0x12, 0x99a30130},
David Henningsson42304472014-07-22 11:42:17 +02007993 {0x19, 0x03a11020},
David Henningsson42304472014-07-22 11:42:17 +02007994 {0x21, 0x0321101f}),
Hui Wang2c609992014-09-03 11:31:08 +08007995 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007996 ALC282_STANDARD_PINS,
Hui Wang2c609992014-09-03 11:31:08 +08007997 {0x12, 0x99a30130},
Hui Wang2c609992014-09-03 11:31:08 +08007998 {0x19, 0x03a11020},
Hui Wang2c609992014-09-03 11:31:08 +08007999 {0x21, 0x03211040}),
8000 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02008001 ALC282_STANDARD_PINS,
Hui Wang2c609992014-09-03 11:31:08 +08008002 {0x12, 0x99a30130},
Hui Wang2c609992014-09-03 11:31:08 +08008003 {0x19, 0x03a11030},
Hui Wang2c609992014-09-03 11:31:08 +08008004 {0x21, 0x03211020}),
8005 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02008006 ALC282_STANDARD_PINS,
Hui Wang2c609992014-09-03 11:31:08 +08008007 {0x12, 0x99a30130},
Hui Wang2c609992014-09-03 11:31:08 +08008008 {0x19, 0x04a11020},
Hui Wang2c609992014-09-03 11:31:08 +08008009 {0x21, 0x0421101f}),
Hui Wang200afc02014-09-03 11:31:10 +08008010 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED,
David Henningssonaec856d2014-09-03 10:23:05 +02008011 ALC282_STANDARD_PINS,
Hui Wang200afc02014-09-03 11:31:10 +08008012 {0x12, 0x90a60140},
Hui Wang200afc02014-09-03 11:31:10 +08008013 {0x19, 0x04a11030},
Hui Wang200afc02014-09-03 11:31:10 +08008014 {0x21, 0x04211020}),
David Henningsson76c21322014-06-24 14:46:54 +02008015 SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02008016 ALC282_STANDARD_PINS,
David Henningsson76c21322014-06-24 14:46:54 +02008017 {0x12, 0x90a60130},
David Henningsson76c21322014-06-24 14:46:54 +02008018 {0x21, 0x0321101f}),
8019 SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
8020 {0x12, 0x90a60160},
8021 {0x14, 0x90170120},
David Henningsson76c21322014-06-24 14:46:54 +02008022 {0x21, 0x02211030}),
Hui Wangbc262172014-09-03 11:31:05 +08008023 SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02008024 ALC282_STANDARD_PINS,
Hui Wangbc262172014-09-03 11:31:05 +08008025 {0x12, 0x90a60130},
Hui Wangbc262172014-09-03 11:31:05 +08008026 {0x19, 0x03a11020},
Hui Wangbc262172014-09-03 11:31:05 +08008027 {0x21, 0x0321101f}),
Hui Wangc8c6ee62019-02-14 11:41:33 +08008028 SND_HDA_PIN_QUIRK(0x10ec0285, 0x17aa, "Lenovo", ALC285_FIXUP_LENOVO_PC_BEEP_IN_NOISE,
Hui Wangc4cfcf62018-11-26 14:17:16 +08008029 {0x12, 0x90a60130},
8030 {0x14, 0x90170110},
8031 {0x19, 0x04a11040},
8032 {0x21, 0x04211020}),
Chris Chiu33aaebd2018-12-05 14:48:53 +08008033 SND_HDA_PIN_QUIRK(0x10ec0286, 0x1025, "Acer", ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE,
8034 {0x12, 0x90a60130},
8035 {0x17, 0x90170110},
8036 {0x21, 0x02211020}),
Takashi Iwaid44a6862018-06-19 23:04:03 +02008037 SND_HDA_PIN_QUIRK(0x10ec0288, 0x1028, "Dell", ALC288_FIXUP_DELL1_MIC_NO_PRESENCE,
Kailang Yange1e62b92015-04-08 16:01:22 +08008038 {0x12, 0x90a60120},
Kailang Yange1e62b92015-04-08 16:01:22 +08008039 {0x14, 0x90170110},
Kailang Yange1e62b92015-04-08 16:01:22 +08008040 {0x21, 0x0321101f}),
Hui Wange4442bc2014-09-03 11:31:09 +08008041 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02008042 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08008043 {0x15, 0x04211040},
Hui Wange4442bc2014-09-03 11:31:09 +08008044 {0x18, 0x90170112},
Hui Wang11580292015-08-03 11:03:49 +08008045 {0x1a, 0x04a11020}),
Hui Wange4442bc2014-09-03 11:31:09 +08008046 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02008047 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08008048 {0x15, 0x04211040},
Hui Wange4442bc2014-09-03 11:31:09 +08008049 {0x18, 0x90170110},
Hui Wang11580292015-08-03 11:03:49 +08008050 {0x1a, 0x04a11020}),
Hui Wange4442bc2014-09-03 11:31:09 +08008051 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02008052 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08008053 {0x15, 0x0421101f},
Hui Wang11580292015-08-03 11:03:49 +08008054 {0x1a, 0x04a11020}),
Hui Wange4442bc2014-09-03 11:31:09 +08008055 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02008056 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08008057 {0x15, 0x04211020},
Hui Wang11580292015-08-03 11:03:49 +08008058 {0x1a, 0x04a11040}),
Hui Wange4442bc2014-09-03 11:31:09 +08008059 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02008060 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08008061 {0x14, 0x90170110},
8062 {0x15, 0x04211020},
Hui Wang11580292015-08-03 11:03:49 +08008063 {0x1a, 0x04a11040}),
Hui Wange4442bc2014-09-03 11:31:09 +08008064 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02008065 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08008066 {0x14, 0x90170110},
8067 {0x15, 0x04211020},
Hui Wang11580292015-08-03 11:03:49 +08008068 {0x1a, 0x04a11020}),
Hui Wange4442bc2014-09-03 11:31:09 +08008069 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02008070 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08008071 {0x14, 0x90170110},
8072 {0x15, 0x0421101f},
Hui Wang11580292015-08-03 11:03:49 +08008073 {0x1a, 0x04a11020}),
Hui Wange8818fa2014-09-03 11:31:04 +08008074 SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02008075 ALC292_STANDARD_PINS,
Hui Wange8818fa2014-09-03 11:31:04 +08008076 {0x12, 0x90a60140},
Hui Wange8818fa2014-09-03 11:31:04 +08008077 {0x16, 0x01014020},
Hui Wang11580292015-08-03 11:03:49 +08008078 {0x19, 0x01a19030}),
Hui Wange8818fa2014-09-03 11:31:04 +08008079 SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02008080 ALC292_STANDARD_PINS,
Hui Wange8818fa2014-09-03 11:31:04 +08008081 {0x12, 0x90a60140},
Hui Wange8818fa2014-09-03 11:31:04 +08008082 {0x16, 0x01014020},
8083 {0x18, 0x02a19031},
Hui Wang11580292015-08-03 11:03:49 +08008084 {0x19, 0x01a1903e}),
David Henningsson76c21322014-06-24 14:46:54 +02008085 SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02008086 ALC292_STANDARD_PINS,
Hui Wang11580292015-08-03 11:03:49 +08008087 {0x12, 0x90a60140}),
David Henningsson76c21322014-06-24 14:46:54 +02008088 SND_HDA_PIN_QUIRK(0x10ec0293, 0x1028, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02008089 ALC292_STANDARD_PINS,
David Henningsson76c21322014-06-24 14:46:54 +02008090 {0x13, 0x90a60140},
David Henningsson76c21322014-06-24 14:46:54 +02008091 {0x16, 0x21014020},
Hui Wang11580292015-08-03 11:03:49 +08008092 {0x19, 0x21a19030}),
David Henningssone03fdbd2014-06-27 08:41:59 +02008093 SND_HDA_PIN_QUIRK(0x10ec0293, 0x1028, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02008094 ALC292_STANDARD_PINS,
Hui Wang11580292015-08-03 11:03:49 +08008095 {0x13, 0x90a60140}),
Chris Chiud8ae4582018-12-07 17:17:11 +08008096 SND_HDA_PIN_QUIRK(0x10ec0294, 0x1043, "ASUS", ALC294_FIXUP_ASUS_MIC,
8097 {0x14, 0x90170110},
8098 {0x1b, 0x90a70130},
8099 {0x21, 0x04211020}),
Jian-Hong Pan0bea4cc2018-12-07 17:17:13 +08008100 SND_HDA_PIN_QUIRK(0x10ec0294, 0x1043, "ASUS", ALC294_FIXUP_ASUS_SPK,
8101 {0x12, 0x90a60130},
8102 {0x17, 0x90170110},
Jian-Hong Pan8bb37a22019-02-21 17:00:18 +08008103 {0x21, 0x03211020}),
8104 SND_HDA_PIN_QUIRK(0x10ec0294, 0x1043, "ASUS", ALC294_FIXUP_ASUS_SPK,
8105 {0x12, 0x90a60130},
8106 {0x17, 0x90170110},
Jian-Hong Pan0bea4cc2018-12-07 17:17:13 +08008107 {0x21, 0x04211020}),
Takashi Iwai3887c262019-04-30 15:10:01 +02008108 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1043, "ASUS", ALC294_FIXUP_ASUS_SPK,
8109 {0x12, 0x90a60130},
8110 {0x17, 0x90170110},
8111 {0x21, 0x03211020}),
Chris Chiu9e433422020-05-12 14:15:24 +08008112 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1043, "ASUS", ALC295_FIXUP_ASUS_MIC_NO_PRESENCE,
Jian-Hong Panad97d662020-05-12 14:15:26 +08008113 {0x12, 0x90a60120},
8114 {0x17, 0x90170110},
8115 {0x21, 0x04211030}),
8116 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1043, "ASUS", ALC295_FIXUP_ASUS_MIC_NO_PRESENCE,
Chris Chiu9e433422020-05-12 14:15:24 +08008117 {0x12, 0x90a60130},
8118 {0x17, 0x90170110},
8119 {0x21, 0x03211020}),
8120 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1043, "ASUS", ALC295_FIXUP_ASUS_MIC_NO_PRESENCE,
8121 {0x12, 0x90a60130},
8122 {0x17, 0x90170110},
8123 {0x21, 0x03211020}),
Kailang Yangfbc57122019-07-15 10:41:50 +08008124 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
Kailang Yang0a29c572019-04-24 16:34:25 +08008125 {0x14, 0x90170110},
8126 {0x21, 0x04211020}),
Kailang Yangfbc57122019-07-15 10:41:50 +08008127 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
8128 {0x14, 0x90170110},
8129 {0x21, 0x04211030}),
Hui Wang3f6409702016-09-11 11:26:16 +08008130 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wangf771d5b2016-10-18 10:59:09 +08008131 ALC295_STANDARD_PINS,
8132 {0x17, 0x21014020},
8133 {0x18, 0x21a19030}),
8134 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
8135 ALC295_STANDARD_PINS,
8136 {0x17, 0x21014040},
8137 {0x18, 0x21a19050}),
Hui Wang3f307832017-03-23 10:00:25 +08008138 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
8139 ALC295_STANDARD_PINS),
Kailang Yang977e6272015-05-18 15:31:20 +08008140 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
Woodrow Shen703867e2015-08-05 12:34:12 +08008141 ALC298_STANDARD_PINS,
Takashi Iwai9f502ff2015-08-05 12:09:45 +02008142 {0x17, 0x90170110}),
8143 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
8144 ALC298_STANDARD_PINS,
Woodrow Shen703867e2015-08-05 12:34:12 +08008145 {0x17, 0x90170140}),
8146 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
8147 ALC298_STANDARD_PINS,
Takashi Iwai9f502ff2015-08-05 12:09:45 +02008148 {0x17, 0x90170150}),
Kai-Heng Feng9f1bc2c42017-02-16 15:26:54 +08008149 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_SPK_VOLUME,
8150 {0x12, 0xb7a60140},
8151 {0x13, 0xb7a60150},
8152 {0x17, 0x90170110},
8153 {0x1a, 0x03011020},
8154 {0x21, 0x03211030}),
James McDonnell54324222019-09-16 14:53:38 +00008155 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_ALIENWARE_MIC_NO_PRESENCE,
8156 {0x12, 0xb7a60140},
8157 {0x17, 0x90170110},
8158 {0x1a, 0x03a11030},
8159 {0x21, 0x03211020}),
Kailang Yangfcc6c872017-06-29 15:21:27 +08008160 SND_HDA_PIN_QUIRK(0x10ec0299, 0x1028, "Dell", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
8161 ALC225_STANDARD_PINS,
8162 {0x12, 0xb7a60130},
Kailang Yangfcc6c872017-06-29 15:21:27 +08008163 {0x17, 0x90170110}),
Hui Wang573fcbf2020-06-08 19:55:41 +08008164 SND_HDA_PIN_QUIRK(0x10ec0623, 0x17aa, "Lenovo", ALC283_FIXUP_HEADSET_MIC,
8165 {0x14, 0x01014010},
8166 {0x17, 0x90170120},
8167 {0x18, 0x02a11030},
8168 {0x19, 0x02a1103f},
8169 {0x21, 0x0221101f}),
Hui Wange1918932014-05-26 16:22:44 +08008170 {}
8171};
Takashi Iwai1d045db2011-07-07 18:23:21 +02008172
Hui Wang7c0a6932019-08-16 14:27:40 +08008173/* This is the fallback pin_fixup_tbl for alc269 family, to make the tbl match
8174 * more machines, don't need to match all valid pins, just need to match
8175 * all the pins defined in the tbl. Just because of this reason, it is possible
8176 * that a single machine matches multiple tbls, so there is one limitation:
8177 * at most one tbl is allowed to define for the same vendor and same codec
8178 */
8179static const struct snd_hda_pin_quirk alc269_fallback_pin_fixup_tbl[] = {
8180 SND_HDA_PIN_QUIRK(0x10ec0289, 0x1028, "Dell", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
8181 {0x19, 0x40000000},
8182 {0x1b, 0x40000000}),
Hui Wangaed8c7f2019-11-21 10:26:43 +08008183 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
8184 {0x19, 0x40000000},
8185 {0x1a, 0x40000000}),
Hui Wangd64ebdb2019-11-21 10:26:44 +08008186 SND_HDA_PIN_QUIRK(0x10ec0236, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
8187 {0x19, 0x40000000},
8188 {0x1a, 0x40000000}),
Hui Wang5815bdf2019-12-11 13:13:21 +08008189 SND_HDA_PIN_QUIRK(0x10ec0274, 0x1028, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB,
8190 {0x19, 0x40000000},
8191 {0x1a, 0x40000000}),
Hui Wang7c0a6932019-08-16 14:27:40 +08008192 {}
8193};
8194
Takashi Iwai546bb672012-03-07 08:37:19 +01008195static void alc269_fill_coef(struct hda_codec *codec)
Takashi Iwai1d045db2011-07-07 18:23:21 +02008196{
Kailang Yang526af6e2012-03-07 08:25:20 +01008197 struct alc_spec *spec = codec->spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008198 int val;
8199
Kailang Yang526af6e2012-03-07 08:25:20 +01008200 if (spec->codec_variant != ALC269_TYPE_ALC269VB)
Takashi Iwai546bb672012-03-07 08:37:19 +01008201 return;
Kailang Yang526af6e2012-03-07 08:25:20 +01008202
Takashi Iwai1bb7e432011-10-17 16:50:59 +02008203 if ((alc_get_coef0(codec) & 0x00ff) < 0x015) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02008204 alc_write_coef_idx(codec, 0xf, 0x960b);
8205 alc_write_coef_idx(codec, 0xe, 0x8817);
8206 }
8207
Takashi Iwai1bb7e432011-10-17 16:50:59 +02008208 if ((alc_get_coef0(codec) & 0x00ff) == 0x016) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02008209 alc_write_coef_idx(codec, 0xf, 0x960b);
8210 alc_write_coef_idx(codec, 0xe, 0x8814);
8211 }
8212
Takashi Iwai1bb7e432011-10-17 16:50:59 +02008213 if ((alc_get_coef0(codec) & 0x00ff) == 0x017) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02008214 /* Power up output pin */
Takashi Iwai98b24882014-08-18 13:47:50 +02008215 alc_update_coef_idx(codec, 0x04, 0, 1<<11);
Takashi Iwai1d045db2011-07-07 18:23:21 +02008216 }
8217
Takashi Iwai1bb7e432011-10-17 16:50:59 +02008218 if ((alc_get_coef0(codec) & 0x00ff) == 0x018) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02008219 val = alc_read_coef_idx(codec, 0xd);
Takashi Iwaif3ee07d2014-08-15 17:35:00 +02008220 if (val != -1 && (val & 0x0c00) >> 10 != 0x1) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02008221 /* Capless ramp up clock control */
8222 alc_write_coef_idx(codec, 0xd, val | (1<<10));
8223 }
8224 val = alc_read_coef_idx(codec, 0x17);
Takashi Iwaif3ee07d2014-08-15 17:35:00 +02008225 if (val != -1 && (val & 0x01c0) >> 6 != 0x4) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02008226 /* Class D power on reset */
8227 alc_write_coef_idx(codec, 0x17, val | (1<<7));
8228 }
8229 }
8230
Takashi Iwai98b24882014-08-18 13:47:50 +02008231 /* HP */
8232 alc_update_coef_idx(codec, 0x4, 0, 1<<11);
Takashi Iwai1d045db2011-07-07 18:23:21 +02008233}
8234
8235/*
8236 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02008237static int patch_alc269(struct hda_codec *codec)
8238{
8239 struct alc_spec *spec;
Takashi Iwai3de95172012-05-07 18:03:15 +02008240 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008241
Takashi Iwai3de95172012-05-07 18:03:15 +02008242 err = alc_alloc_spec(codec, 0x0b);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008243 if (err < 0)
Takashi Iwai3de95172012-05-07 18:03:15 +02008244 return err;
8245
8246 spec = codec->spec;
Takashi Iwai08c189f2012-12-19 15:22:24 +01008247 spec->gen.shared_mic_vref_pin = 0x18;
Kailang Yang317d9312019-05-23 14:43:04 +08008248 codec->power_save_node = 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008249
Takashi Iwai225068a2015-05-29 10:42:14 +02008250#ifdef CONFIG_PM
8251 codec->patch_ops.suspend = alc269_suspend;
8252 codec->patch_ops.resume = alc269_resume;
8253#endif
Kailang Yangc2d6af52017-06-21 14:50:54 +08008254 spec->shutup = alc_default_shutup;
8255 spec->init_hook = alc_default_init;
Takashi Iwai225068a2015-05-29 10:42:14 +02008256
Takashi Iwai7639a062015-03-03 10:07:24 +01008257 switch (codec->core.vendor_id) {
Kailang Yang065380f2013-01-10 10:25:48 +01008258 case 0x10ec0269:
Takashi Iwai1d045db2011-07-07 18:23:21 +02008259 spec->codec_variant = ALC269_TYPE_ALC269VA;
Takashi Iwai1bb7e432011-10-17 16:50:59 +02008260 switch (alc_get_coef0(codec) & 0x00f0) {
8261 case 0x0010:
Takashi Iwai5100cd02014-02-15 10:03:19 +01008262 if (codec->bus->pci &&
8263 codec->bus->pci->subsystem_vendor == 0x1025 &&
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008264 spec->cdefine.platform_type == 1)
Takashi Iwai20ca0c32011-10-17 16:00:35 +02008265 err = alc_codec_rename(codec, "ALC271X");
Takashi Iwai1d045db2011-07-07 18:23:21 +02008266 spec->codec_variant = ALC269_TYPE_ALC269VB;
Takashi Iwai1bb7e432011-10-17 16:50:59 +02008267 break;
8268 case 0x0020:
Takashi Iwai5100cd02014-02-15 10:03:19 +01008269 if (codec->bus->pci &&
8270 codec->bus->pci->subsystem_vendor == 0x17aa &&
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008271 codec->bus->pci->subsystem_device == 0x21f3)
Takashi Iwai20ca0c32011-10-17 16:00:35 +02008272 err = alc_codec_rename(codec, "ALC3202");
Takashi Iwai1d045db2011-07-07 18:23:21 +02008273 spec->codec_variant = ALC269_TYPE_ALC269VC;
Takashi Iwai1bb7e432011-10-17 16:50:59 +02008274 break;
Kailang Yangadcc70b2012-05-25 08:08:38 +02008275 case 0x0030:
8276 spec->codec_variant = ALC269_TYPE_ALC269VD;
8277 break;
Takashi Iwai1bb7e432011-10-17 16:50:59 +02008278 default:
Takashi Iwai1d045db2011-07-07 18:23:21 +02008279 alc_fix_pll_init(codec, 0x20, 0x04, 15);
Takashi Iwai1bb7e432011-10-17 16:50:59 +02008280 }
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008281 if (err < 0)
8282 goto error;
Kailang Yangc2d6af52017-06-21 14:50:54 +08008283 spec->shutup = alc269_shutup;
Takashi Iwai546bb672012-03-07 08:37:19 +01008284 spec->init_hook = alc269_fill_coef;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008285 alc269_fill_coef(codec);
Kailang Yang065380f2013-01-10 10:25:48 +01008286 break;
8287
8288 case 0x10ec0280:
8289 case 0x10ec0290:
8290 spec->codec_variant = ALC269_TYPE_ALC280;
8291 break;
8292 case 0x10ec0282:
Kailang Yang065380f2013-01-10 10:25:48 +01008293 spec->codec_variant = ALC269_TYPE_ALC282;
Kailang Yang7b5c7a02014-03-18 16:15:54 +08008294 spec->shutup = alc282_shutup;
8295 spec->init_hook = alc282_init;
Kailang Yang065380f2013-01-10 10:25:48 +01008296 break;
Kailang Yang2af02be2013-08-22 10:03:50 +02008297 case 0x10ec0233:
8298 case 0x10ec0283:
8299 spec->codec_variant = ALC269_TYPE_ALC283;
8300 spec->shutup = alc283_shutup;
8301 spec->init_hook = alc283_init;
8302 break;
Kailang Yang065380f2013-01-10 10:25:48 +01008303 case 0x10ec0284:
8304 case 0x10ec0292:
8305 spec->codec_variant = ALC269_TYPE_ALC284;
8306 break;
Kailang Yang161ebf22013-10-24 11:36:33 +02008307 case 0x10ec0293:
Kailang Yang4731d5d2017-06-30 15:22:57 +08008308 spec->codec_variant = ALC269_TYPE_ALC293;
Kailang Yang161ebf22013-10-24 11:36:33 +02008309 break;
Kailang Yang7fc7d042013-04-25 11:04:43 +02008310 case 0x10ec0286:
Kailang Yang7c665932014-04-14 15:09:44 +08008311 case 0x10ec0288:
Kailang Yang7fc7d042013-04-25 11:04:43 +02008312 spec->codec_variant = ALC269_TYPE_ALC286;
8313 break;
Kailang Yang506b62c2014-12-18 17:07:44 +08008314 case 0x10ec0298:
8315 spec->codec_variant = ALC269_TYPE_ALC298;
8316 break;
Kailang Yangea04a1d2018-04-25 15:31:52 +08008317 case 0x10ec0235:
Kailang Yang1d04c9d2013-10-24 11:35:18 +02008318 case 0x10ec0255:
8319 spec->codec_variant = ALC269_TYPE_ALC255;
Kailang Yangab3b8e52018-04-25 16:05:27 +08008320 spec->shutup = alc256_shutup;
8321 spec->init_hook = alc256_init;
Kailang Yang1d04c9d2013-10-24 11:35:18 +02008322 break;
Kailang Yang736f20a2017-10-20 15:06:34 +08008323 case 0x10ec0236:
Kailang Yang4344aec2014-12-17 17:39:05 +08008324 case 0x10ec0256:
8325 spec->codec_variant = ALC269_TYPE_ALC256;
Kailang Yang4a219ef2017-06-16 16:54:35 +08008326 spec->shutup = alc256_shutup;
8327 spec->init_hook = alc256_init;
David Henningsson7d1b6e22015-04-21 10:48:46 +02008328 spec->gen.mixer_nid = 0; /* ALC256 does not have any loopback mixer path */
Kailang Yang4344aec2014-12-17 17:39:05 +08008329 break;
Kailang Yangf429e7e2017-12-05 15:38:24 +08008330 case 0x10ec0257:
8331 spec->codec_variant = ALC269_TYPE_ALC257;
Kailang Yang88d42b22018-03-14 16:08:57 +08008332 spec->shutup = alc256_shutup;
8333 spec->init_hook = alc256_init;
Kailang Yangf429e7e2017-12-05 15:38:24 +08008334 spec->gen.mixer_nid = 0;
8335 break;
Kailang Yang0a6f0602017-06-30 16:00:48 +08008336 case 0x10ec0215:
Kailang Yang7fbdcd82020-04-23 14:18:31 +08008337 case 0x10ec0245:
Kailang Yang0a6f0602017-06-30 16:00:48 +08008338 case 0x10ec0285:
Kailang Yang630e3612020-05-27 14:10:26 +08008339 case 0x10ec0287:
Kailang Yang0a6f0602017-06-30 16:00:48 +08008340 case 0x10ec0289:
8341 spec->codec_variant = ALC269_TYPE_ALC215;
Kailang Yang1b6832be2018-01-17 15:32:03 +08008342 spec->shutup = alc225_shutup;
8343 spec->init_hook = alc225_init;
Kailang Yang0a6f0602017-06-30 16:00:48 +08008344 spec->gen.mixer_nid = 0;
8345 break;
Kailang Yang42314302016-02-03 15:03:50 +08008346 case 0x10ec0225:
Kailang Yang7d727862016-05-24 16:46:07 +08008347 case 0x10ec0295:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08008348 case 0x10ec0299:
Kailang Yang42314302016-02-03 15:03:50 +08008349 spec->codec_variant = ALC269_TYPE_ALC225;
Kailang Yangda911b12018-01-05 16:50:08 +08008350 spec->shutup = alc225_shutup;
8351 spec->init_hook = alc225_init;
Takashi Iwaic1350bf2017-12-27 09:03:45 +01008352 spec->gen.mixer_nid = 0; /* no loopback on ALC225, ALC295 and ALC299 */
Kailang Yang42314302016-02-03 15:03:50 +08008353 break;
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08008354 case 0x10ec0234:
8355 case 0x10ec0274:
8356 case 0x10ec0294:
8357 spec->codec_variant = ALC269_TYPE_ALC294;
Hui Wang532a7782017-06-26 12:30:32 +08008358 spec->gen.mixer_nid = 0; /* ALC2x4 does not have any loopback mixer path */
Kailang Yang71683c32017-06-20 16:33:50 +08008359 alc_update_coef_idx(codec, 0x6b, 0x0018, (1<<4) | (1<<3)); /* UAJ MIC Vref control by verb */
Kailang Yang693abe12019-01-29 15:38:21 +08008360 spec->init_hook = alc294_init;
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08008361 break;
Kailang Yang1078bef2018-11-08 16:36:15 +08008362 case 0x10ec0300:
8363 spec->codec_variant = ALC269_TYPE_ALC300;
8364 spec->gen.mixer_nid = 0; /* no loopback on ALC300 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02008365 break;
Kailang Yangf0778872019-10-24 15:13:32 +08008366 case 0x10ec0623:
8367 spec->codec_variant = ALC269_TYPE_ALC623;
8368 break;
Kailang Yang6fbae352016-05-30 16:44:20 +08008369 case 0x10ec0700:
8370 case 0x10ec0701:
8371 case 0x10ec0703:
Kailang Yang83629532019-05-02 16:03:26 +08008372 case 0x10ec0711:
Kailang Yang6fbae352016-05-30 16:44:20 +08008373 spec->codec_variant = ALC269_TYPE_ALC700;
8374 spec->gen.mixer_nid = 0; /* ALC700 does not have any loopback mixer path */
Kailang Yang2d7fe612017-11-22 15:21:32 +08008375 alc_update_coef_idx(codec, 0x4a, 1 << 15, 0); /* Combo jack auto trigger control */
Kailang Yang693abe12019-01-29 15:38:21 +08008376 spec->init_hook = alc294_init;
Kailang Yang6fbae352016-05-30 16:44:20 +08008377 break;
8378
Takashi Iwai1d045db2011-07-07 18:23:21 +02008379 }
8380
Kailang Yangad60d502013-06-28 12:03:01 +02008381 if (snd_hda_codec_read(codec, 0x51, 0, AC_VERB_PARAMETERS, 0) == 0x10ec5505) {
Kailang Yang97a26572013-11-29 00:35:26 -05008382 spec->has_alc5505_dsp = 1;
Kailang Yangad60d502013-06-28 12:03:01 +02008383 spec->init_hook = alc5505_dsp_init;
8384 }
8385
Takashi Iwaic9af7532019-05-10 11:01:43 +02008386 alc_pre_init(codec);
8387
Takashi Iwaiefe55732018-06-15 11:55:02 +02008388 snd_hda_pick_fixup(codec, alc269_fixup_models,
8389 alc269_fixup_tbl, alc269_fixups);
Hui Wang0fc1e442019-08-16 14:27:39 +08008390 snd_hda_pick_pin_fixup(codec, alc269_pin_fixup_tbl, alc269_fixups, true);
Hui Wang7c0a6932019-08-16 14:27:40 +08008391 snd_hda_pick_pin_fixup(codec, alc269_fallback_pin_fixup_tbl, alc269_fixups, false);
Takashi Iwaiefe55732018-06-15 11:55:02 +02008392 snd_hda_pick_fixup(codec, NULL, alc269_fixup_vendor_tbl,
8393 alc269_fixups);
8394 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
8395
8396 alc_auto_parse_customize_define(codec);
8397
8398 if (has_cdefine_beep(codec))
8399 spec->gen.beep_nid = 0x01;
8400
Takashi Iwaia4297b52011-08-23 18:40:12 +02008401 /* automatic parse from the BIOS config */
8402 err = alc269_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008403 if (err < 0)
8404 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008405
Takashi Iwaifea80fa2018-06-20 12:52:46 +02008406 if (!spec->gen.no_analog && spec->gen.beep_nid && spec->gen.mixer_nid) {
8407 err = set_beep_amp(spec, spec->gen.mixer_nid, 0x04, HDA_INPUT);
8408 if (err < 0)
8409 goto error;
8410 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02008411
Takashi Iwai1727a772013-01-10 09:52:52 +01008412 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01008413
Takashi Iwai1d045db2011-07-07 18:23:21 +02008414 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008415
8416 error:
8417 alc_free(codec);
8418 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008419}
8420
8421/*
8422 * ALC861
8423 */
8424
Takashi Iwai1d045db2011-07-07 18:23:21 +02008425static int alc861_parse_auto_config(struct hda_codec *codec)
8426{
Takashi Iwai1d045db2011-07-07 18:23:21 +02008427 static const hda_nid_t alc861_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02008428 static const hda_nid_t alc861_ssids[] = { 0x0e, 0x0f, 0x0b, 0 };
8429 return alc_parse_auto_config(codec, alc861_ignore, alc861_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02008430}
8431
Takashi Iwai1d045db2011-07-07 18:23:21 +02008432/* Pin config fixes */
8433enum {
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008434 ALC861_FIXUP_FSC_AMILO_PI1505,
8435 ALC861_FIXUP_AMP_VREF_0F,
8436 ALC861_FIXUP_NO_JACK_DETECT,
8437 ALC861_FIXUP_ASUS_A6RP,
Takashi Iwai6ddf0fd2013-11-29 12:47:34 +01008438 ALC660_FIXUP_ASUS_W7J,
Takashi Iwai1d045db2011-07-07 18:23:21 +02008439};
8440
Takashi Iwai31150f22012-01-30 10:54:08 +01008441/* On some laptops, VREF of pin 0x0f is abused for controlling the main amp */
8442static void alc861_fixup_asus_amp_vref_0f(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01008443 const struct hda_fixup *fix, int action)
Takashi Iwai31150f22012-01-30 10:54:08 +01008444{
8445 struct alc_spec *spec = codec->spec;
8446 unsigned int val;
8447
Takashi Iwai1727a772013-01-10 09:52:52 +01008448 if (action != HDA_FIXUP_ACT_INIT)
Takashi Iwai31150f22012-01-30 10:54:08 +01008449 return;
Takashi Iwaid3f02d62013-01-10 10:12:22 +01008450 val = snd_hda_codec_get_pin_target(codec, 0x0f);
Takashi Iwai31150f22012-01-30 10:54:08 +01008451 if (!(val & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN)))
8452 val |= AC_PINCTL_IN_EN;
8453 val |= AC_PINCTL_VREF_50;
Takashi Iwaicdd03ce2012-04-20 12:34:50 +02008454 snd_hda_set_pin_ctl(codec, 0x0f, val);
Takashi Iwai08c189f2012-12-19 15:22:24 +01008455 spec->gen.keep_vref_in_automute = 1;
Takashi Iwai31150f22012-01-30 10:54:08 +01008456}
8457
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008458/* suppress the jack-detection */
8459static void alc_fixup_no_jack_detect(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01008460 const struct hda_fixup *fix, int action)
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008461{
Takashi Iwai1727a772013-01-10 09:52:52 +01008462 if (action == HDA_FIXUP_ACT_PRE_PROBE)
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008463 codec->no_jack_detect = 1;
Jesper Juhl7d7eb9e2012-04-12 22:11:25 +02008464}
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008465
Takashi Iwai1727a772013-01-10 09:52:52 +01008466static const struct hda_fixup alc861_fixups[] = {
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008467 [ALC861_FIXUP_FSC_AMILO_PI1505] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008468 .type = HDA_FIXUP_PINS,
8469 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02008470 { 0x0b, 0x0221101f }, /* HP */
8471 { 0x0f, 0x90170310 }, /* speaker */
8472 { }
8473 }
8474 },
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008475 [ALC861_FIXUP_AMP_VREF_0F] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008476 .type = HDA_FIXUP_FUNC,
Takashi Iwai31150f22012-01-30 10:54:08 +01008477 .v.func = alc861_fixup_asus_amp_vref_0f,
Takashi Iwai3b25eb62012-01-25 09:55:46 +01008478 },
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008479 [ALC861_FIXUP_NO_JACK_DETECT] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008480 .type = HDA_FIXUP_FUNC,
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008481 .v.func = alc_fixup_no_jack_detect,
8482 },
8483 [ALC861_FIXUP_ASUS_A6RP] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008484 .type = HDA_FIXUP_FUNC,
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008485 .v.func = alc861_fixup_asus_amp_vref_0f,
8486 .chained = true,
8487 .chain_id = ALC861_FIXUP_NO_JACK_DETECT,
Takashi Iwai6ddf0fd2013-11-29 12:47:34 +01008488 },
8489 [ALC660_FIXUP_ASUS_W7J] = {
8490 .type = HDA_FIXUP_VERBS,
8491 .v.verbs = (const struct hda_verb[]) {
8492 /* ASUS W7J needs a magic pin setup on unused NID 0x10
8493 * for enabling outputs
8494 */
8495 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8496 { }
8497 },
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008498 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02008499};
8500
8501static const struct snd_pci_quirk alc861_fixup_tbl[] = {
Takashi Iwai6ddf0fd2013-11-29 12:47:34 +01008502 SND_PCI_QUIRK(0x1043, 0x1253, "ASUS W7J", ALC660_FIXUP_ASUS_W7J),
Takashi Iwaie7ca2372013-12-02 15:27:19 +01008503 SND_PCI_QUIRK(0x1043, 0x1263, "ASUS Z35HL", ALC660_FIXUP_ASUS_W7J),
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008504 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS A6Rp", ALC861_FIXUP_ASUS_A6RP),
8505 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", ALC861_FIXUP_AMP_VREF_0F),
8506 SND_PCI_QUIRK(0x1462, 0x7254, "HP DX2200", ALC861_FIXUP_NO_JACK_DETECT),
8507 SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", ALC861_FIXUP_AMP_VREF_0F),
8508 SND_PCI_QUIRK(0x1584, 0x0000, "Uniwill ECS M31EI", ALC861_FIXUP_AMP_VREF_0F),
8509 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", ALC861_FIXUP_FSC_AMILO_PI1505),
Takashi Iwai1d045db2011-07-07 18:23:21 +02008510 {}
8511};
8512
8513/*
8514 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02008515static int patch_alc861(struct hda_codec *codec)
8516{
8517 struct alc_spec *spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008518 int err;
8519
Takashi Iwai3de95172012-05-07 18:03:15 +02008520 err = alc_alloc_spec(codec, 0x15);
8521 if (err < 0)
8522 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008523
Takashi Iwai3de95172012-05-07 18:03:15 +02008524 spec = codec->spec;
Takashi Iwai2722b532019-08-22 09:55:37 +02008525 if (has_cdefine_beep(codec))
8526 spec->gen.beep_nid = 0x23;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008527
Takashi Iwai225068a2015-05-29 10:42:14 +02008528#ifdef CONFIG_PM
8529 spec->power_hook = alc_power_eapd;
8530#endif
8531
Takashi Iwaic9af7532019-05-10 11:01:43 +02008532 alc_pre_init(codec);
8533
Takashi Iwai1727a772013-01-10 09:52:52 +01008534 snd_hda_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
8535 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02008536
Takashi Iwaicb4e4822011-08-23 17:34:25 +02008537 /* automatic parse from the BIOS config */
8538 err = alc861_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008539 if (err < 0)
8540 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008541
Takashi Iwaifea80fa2018-06-20 12:52:46 +02008542 if (!spec->gen.no_analog) {
8543 err = set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
8544 if (err < 0)
8545 goto error;
8546 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02008547
Takashi Iwai1727a772013-01-10 09:52:52 +01008548 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01008549
Takashi Iwai1d045db2011-07-07 18:23:21 +02008550 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008551
8552 error:
8553 alc_free(codec);
8554 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008555}
8556
8557/*
8558 * ALC861-VD support
8559 *
8560 * Based on ALC882
8561 *
8562 * In addition, an independent DAC
8563 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02008564static int alc861vd_parse_auto_config(struct hda_codec *codec)
8565{
Takashi Iwai1d045db2011-07-07 18:23:21 +02008566 static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02008567 static const hda_nid_t alc861vd_ssids[] = { 0x15, 0x1b, 0x14, 0 };
8568 return alc_parse_auto_config(codec, alc861vd_ignore, alc861vd_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02008569}
8570
Takashi Iwai1d045db2011-07-07 18:23:21 +02008571enum {
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008572 ALC660VD_FIX_ASUS_GPIO1,
8573 ALC861VD_FIX_DALLAS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02008574};
8575
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008576/* exclude VREF80 */
8577static void alc861vd_fixup_dallas(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01008578 const struct hda_fixup *fix, int action)
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008579{
Takashi Iwai1727a772013-01-10 09:52:52 +01008580 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwaib78562b2012-12-17 20:06:49 +01008581 snd_hda_override_pin_caps(codec, 0x18, 0x00000734);
8582 snd_hda_override_pin_caps(codec, 0x19, 0x0000073c);
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008583 }
8584}
8585
Takashi Iwaidf73d832018-06-19 23:05:47 +02008586/* reset GPIO1 */
8587static void alc660vd_fixup_asus_gpio1(struct hda_codec *codec,
8588 const struct hda_fixup *fix, int action)
8589{
8590 struct alc_spec *spec = codec->spec;
8591
8592 if (action == HDA_FIXUP_ACT_PRE_PROBE)
8593 spec->gpio_mask |= 0x02;
8594 alc_fixup_gpio(codec, action, 0x01);
8595}
8596
Takashi Iwai1727a772013-01-10 09:52:52 +01008597static const struct hda_fixup alc861vd_fixups[] = {
Takashi Iwai1d045db2011-07-07 18:23:21 +02008598 [ALC660VD_FIX_ASUS_GPIO1] = {
Takashi Iwaidf73d832018-06-19 23:05:47 +02008599 .type = HDA_FIXUP_FUNC,
8600 .v.func = alc660vd_fixup_asus_gpio1,
Takashi Iwai1d045db2011-07-07 18:23:21 +02008601 },
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008602 [ALC861VD_FIX_DALLAS] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008603 .type = HDA_FIXUP_FUNC,
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008604 .v.func = alc861vd_fixup_dallas,
8605 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02008606};
8607
8608static const struct snd_pci_quirk alc861vd_fixup_tbl[] = {
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008609 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_FIX_DALLAS),
Takashi Iwai1d045db2011-07-07 18:23:21 +02008610 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008611 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_FIX_DALLAS),
Takashi Iwai1d045db2011-07-07 18:23:21 +02008612 {}
8613};
8614
Takashi Iwai1d045db2011-07-07 18:23:21 +02008615/*
8616 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02008617static int patch_alc861vd(struct hda_codec *codec)
8618{
8619 struct alc_spec *spec;
Takashi Iwaicb4e4822011-08-23 17:34:25 +02008620 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008621
Takashi Iwai3de95172012-05-07 18:03:15 +02008622 err = alc_alloc_spec(codec, 0x0b);
8623 if (err < 0)
8624 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008625
Takashi Iwai3de95172012-05-07 18:03:15 +02008626 spec = codec->spec;
Takashi Iwai2722b532019-08-22 09:55:37 +02008627 if (has_cdefine_beep(codec))
8628 spec->gen.beep_nid = 0x23;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008629
Takashi Iwai225068a2015-05-29 10:42:14 +02008630 spec->shutup = alc_eapd_shutup;
8631
Takashi Iwaic9af7532019-05-10 11:01:43 +02008632 alc_pre_init(codec);
8633
Takashi Iwai1727a772013-01-10 09:52:52 +01008634 snd_hda_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
8635 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02008636
Takashi Iwaicb4e4822011-08-23 17:34:25 +02008637 /* automatic parse from the BIOS config */
8638 err = alc861vd_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008639 if (err < 0)
8640 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008641
Takashi Iwaifea80fa2018-06-20 12:52:46 +02008642 if (!spec->gen.no_analog) {
8643 err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
8644 if (err < 0)
8645 goto error;
8646 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02008647
Takashi Iwai1727a772013-01-10 09:52:52 +01008648 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01008649
Takashi Iwai1d045db2011-07-07 18:23:21 +02008650 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008651
8652 error:
8653 alc_free(codec);
8654 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008655}
8656
8657/*
8658 * ALC662 support
8659 *
8660 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
8661 * configuration. Each pin widget can choose any input DACs and a mixer.
8662 * Each ADC is connected from a mixer of all inputs. This makes possible
8663 * 6-channel independent captures.
8664 *
8665 * In addition, an independent DAC for the multi-playback (not used in this
8666 * driver yet).
8667 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02008668
8669/*
8670 * BIOS auto configuration
8671 */
8672
Kailang Yangbc9f98a2007-04-12 13:06:07 +02008673static int alc662_parse_auto_config(struct hda_codec *codec)
8674{
Takashi Iwai4c6d72d2011-05-02 11:30:18 +02008675 static const hda_nid_t alc662_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02008676 static const hda_nid_t alc663_ssids[] = { 0x15, 0x1b, 0x14, 0x21 };
8677 static const hda_nid_t alc662_ssids[] = { 0x15, 0x1b, 0x14, 0 };
8678 const hda_nid_t *ssids;
Takashi Iwaiee979a142008-09-02 15:42:20 +02008679
Takashi Iwai7639a062015-03-03 10:07:24 +01008680 if (codec->core.vendor_id == 0x10ec0272 || codec->core.vendor_id == 0x10ec0663 ||
8681 codec->core.vendor_id == 0x10ec0665 || codec->core.vendor_id == 0x10ec0670 ||
8682 codec->core.vendor_id == 0x10ec0671)
Takashi Iwai3e6179b2011-07-08 16:55:13 +02008683 ssids = alc663_ssids;
Kailang Yang6227cdc2010-02-25 08:36:52 +01008684 else
Takashi Iwai3e6179b2011-07-08 16:55:13 +02008685 ssids = alc662_ssids;
8686 return alc_parse_auto_config(codec, alc662_ignore, ssids);
Kailang Yangbc9f98a2007-04-12 13:06:07 +02008687}
8688
Todd Broch6be79482010-12-07 16:51:05 -08008689static void alc272_fixup_mario(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01008690 const struct hda_fixup *fix, int action)
Takashi Iwai6fc398c2011-01-13 14:36:37 +01008691{
Takashi Iwai9bb1f062013-01-10 17:14:29 +01008692 if (action != HDA_FIXUP_ACT_PRE_PROBE)
Takashi Iwai6fc398c2011-01-13 14:36:37 +01008693 return;
Todd Broch6be79482010-12-07 16:51:05 -08008694 if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT,
8695 (0x3b << AC_AMPCAP_OFFSET_SHIFT) |
8696 (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) |
8697 (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) |
8698 (0 << AC_AMPCAP_MUTE_SHIFT)))
Takashi Iwai4e76a882014-02-25 12:21:03 +01008699 codec_warn(codec, "failed to override amp caps for NID 0x2\n");
Todd Broch6be79482010-12-07 16:51:05 -08008700}
8701
Takashi Iwai8e383952013-10-30 17:41:12 +01008702static const struct snd_pcm_chmap_elem asus_pcm_2_1_chmaps[] = {
8703 { .channels = 2,
8704 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } },
8705 { .channels = 4,
8706 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR,
8707 SNDRV_CHMAP_NA, SNDRV_CHMAP_LFE } }, /* LFE only on right */
8708 { }
8709};
8710
8711/* override the 2.1 chmap */
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01008712static void alc_fixup_bass_chmap(struct hda_codec *codec,
Takashi Iwai8e383952013-10-30 17:41:12 +01008713 const struct hda_fixup *fix, int action)
8714{
8715 if (action == HDA_FIXUP_ACT_BUILD) {
8716 struct alc_spec *spec = codec->spec;
Takashi Iwaibbbc7e82015-02-27 17:43:19 +01008717 spec->gen.pcm_rec[0]->stream[0].chmap = asus_pcm_2_1_chmaps;
Takashi Iwai8e383952013-10-30 17:41:12 +01008718 }
8719}
8720
Takashi Iwaibf686652014-01-13 16:18:25 +01008721/* avoid D3 for keeping GPIO up */
8722static unsigned int gpio_led_power_filter(struct hda_codec *codec,
8723 hda_nid_t nid,
8724 unsigned int power_state)
8725{
8726 struct alc_spec *spec = codec->spec;
Takashi Iwaid261eec2018-06-19 22:32:29 +02008727 if (nid == codec->core.afg && power_state == AC_PWRST_D3 && spec->gpio_data)
Takashi Iwaibf686652014-01-13 16:18:25 +01008728 return AC_PWRST_D0;
8729 return power_state;
8730}
8731
Takashi Iwai3e887f32014-01-10 17:50:58 +01008732static void alc662_fixup_led_gpio1(struct hda_codec *codec,
8733 const struct hda_fixup *fix, int action)
8734{
8735 struct alc_spec *spec = codec->spec;
Takashi Iwai3e887f32014-01-10 17:50:58 +01008736
Takashi Iwai01e4a272018-06-19 22:47:30 +02008737 alc_fixup_hp_gpio_led(codec, action, 0x01, 0);
Takashi Iwai3e887f32014-01-10 17:50:58 +01008738 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai0f32fd192014-11-19 12:16:14 +01008739 spec->mute_led_polarity = 1;
Takashi Iwaibf686652014-01-13 16:18:25 +01008740 codec->power_filter = gpio_led_power_filter;
Takashi Iwai3e887f32014-01-10 17:50:58 +01008741 }
8742}
8743
Kailang Yangc6790c82016-11-25 16:15:17 +08008744static void alc662_usi_automute_hook(struct hda_codec *codec,
8745 struct hda_jack_callback *jack)
8746{
8747 struct alc_spec *spec = codec->spec;
8748 int vref;
8749 msleep(200);
8750 snd_hda_gen_hp_automute(codec, jack);
8751
8752 vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0;
8753 msleep(100);
8754 snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8755 vref);
8756}
8757
8758static void alc662_fixup_usi_headset_mic(struct hda_codec *codec,
8759 const struct hda_fixup *fix, int action)
8760{
8761 struct alc_spec *spec = codec->spec;
8762 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
8763 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
8764 spec->gen.hp_automute_hook = alc662_usi_automute_hook;
8765 }
8766}
8767
Sergey Bostandzhyan00066e92019-09-06 11:33:43 +02008768static void alc662_aspire_ethos_mute_speakers(struct hda_codec *codec,
8769 struct hda_jack_callback *cb)
8770{
8771 /* surround speakers at 0x1b already get muted automatically when
8772 * headphones are plugged in, but we have to mute/unmute the remaining
8773 * channels manually:
8774 * 0x15 - front left/front right
8775 * 0x18 - front center/ LFE
8776 */
8777 if (snd_hda_jack_detect_state(codec, 0x1b) == HDA_JACK_PRESENT) {
8778 snd_hda_set_pin_ctl_cache(codec, 0x15, 0);
8779 snd_hda_set_pin_ctl_cache(codec, 0x18, 0);
8780 } else {
8781 snd_hda_set_pin_ctl_cache(codec, 0x15, PIN_OUT);
8782 snd_hda_set_pin_ctl_cache(codec, 0x18, PIN_OUT);
8783 }
8784}
8785
8786static void alc662_fixup_aspire_ethos_hp(struct hda_codec *codec,
8787 const struct hda_fixup *fix, int action)
8788{
8789 /* Pin 0x1b: shared headphones jack and surround speakers */
8790 if (!is_jack_detectable(codec, 0x1b))
8791 return;
8792
8793 switch (action) {
8794 case HDA_FIXUP_ACT_PRE_PROBE:
8795 snd_hda_jack_detect_enable_callback(codec, 0x1b,
8796 alc662_aspire_ethos_mute_speakers);
Takashi Iwai336820c2019-11-28 21:26:30 +01008797 /* subwoofer needs an extra GPIO setting to become audible */
8798 alc_setup_gpio(codec, 0x02);
Sergey Bostandzhyan00066e92019-09-06 11:33:43 +02008799 break;
8800 case HDA_FIXUP_ACT_INIT:
8801 /* Make sure to start in a correct state, i.e. if
8802 * headphones have been plugged in before powering up the system
8803 */
8804 alc662_aspire_ethos_mute_speakers(codec, NULL);
8805 break;
8806 }
8807}
8808
Kailang Yang5af290282020-01-17 14:04:01 +08008809static void alc671_fixup_hp_headset_mic2(struct hda_codec *codec,
8810 const struct hda_fixup *fix, int action)
8811{
8812 struct alc_spec *spec = codec->spec;
8813
8814 static const struct hda_pintbl pincfgs[] = {
8815 { 0x19, 0x02a11040 }, /* use as headset mic, with its own jack detect */
8816 { 0x1b, 0x0181304f },
8817 { }
8818 };
8819
8820 switch (action) {
8821 case HDA_FIXUP_ACT_PRE_PROBE:
8822 spec->gen.mixer_nid = 0;
8823 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
8824 snd_hda_apply_pincfgs(codec, pincfgs);
8825 break;
8826 case HDA_FIXUP_ACT_INIT:
8827 alc_write_coef_idx(codec, 0x19, 0xa054);
8828 break;
8829 }
8830}
8831
Takashi Iwai6b0f95c2020-01-05 15:47:18 +01008832static const struct coef_fw alc668_coefs[] = {
Kailang Yangf3f91852014-10-24 15:43:46 +08008833 WRITE_COEF(0x01, 0xbebe), WRITE_COEF(0x02, 0xaaaa), WRITE_COEF(0x03, 0x0),
8834 WRITE_COEF(0x04, 0x0180), WRITE_COEF(0x06, 0x0), WRITE_COEF(0x07, 0x0f80),
8835 WRITE_COEF(0x08, 0x0031), WRITE_COEF(0x0a, 0x0060), WRITE_COEF(0x0b, 0x0),
8836 WRITE_COEF(0x0c, 0x7cf7), WRITE_COEF(0x0d, 0x1080), WRITE_COEF(0x0e, 0x7f7f),
8837 WRITE_COEF(0x0f, 0xcccc), WRITE_COEF(0x10, 0xddcc), WRITE_COEF(0x11, 0x0001),
8838 WRITE_COEF(0x13, 0x0), WRITE_COEF(0x14, 0x2aa0), WRITE_COEF(0x17, 0xa940),
8839 WRITE_COEF(0x19, 0x0), WRITE_COEF(0x1a, 0x0), WRITE_COEF(0x1b, 0x0),
8840 WRITE_COEF(0x1c, 0x0), WRITE_COEF(0x1d, 0x0), WRITE_COEF(0x1e, 0x7418),
8841 WRITE_COEF(0x1f, 0x0804), WRITE_COEF(0x20, 0x4200), WRITE_COEF(0x21, 0x0468),
8842 WRITE_COEF(0x22, 0x8ccc), WRITE_COEF(0x23, 0x0250), WRITE_COEF(0x24, 0x7418),
8843 WRITE_COEF(0x27, 0x0), WRITE_COEF(0x28, 0x8ccc), WRITE_COEF(0x2a, 0xff00),
8844 WRITE_COEF(0x2b, 0x8000), WRITE_COEF(0xa7, 0xff00), WRITE_COEF(0xa8, 0x8000),
8845 WRITE_COEF(0xaa, 0x2e17), WRITE_COEF(0xab, 0xa0c0), WRITE_COEF(0xac, 0x0),
8846 WRITE_COEF(0xad, 0x0), WRITE_COEF(0xae, 0x2ac6), WRITE_COEF(0xaf, 0xa480),
8847 WRITE_COEF(0xb0, 0x0), WRITE_COEF(0xb1, 0x0), WRITE_COEF(0xb2, 0x0),
8848 WRITE_COEF(0xb3, 0x0), WRITE_COEF(0xb4, 0x0), WRITE_COEF(0xb5, 0x1040),
8849 WRITE_COEF(0xb6, 0xd697), WRITE_COEF(0xb7, 0x902b), WRITE_COEF(0xb8, 0xd697),
8850 WRITE_COEF(0xb9, 0x902b), WRITE_COEF(0xba, 0xb8ba), WRITE_COEF(0xbb, 0xaaab),
8851 WRITE_COEF(0xbc, 0xaaaf), WRITE_COEF(0xbd, 0x6aaa), WRITE_COEF(0xbe, 0x1c02),
8852 WRITE_COEF(0xc0, 0x00ff), WRITE_COEF(0xc1, 0x0fa6),
8853 {}
8854};
8855
8856static void alc668_restore_default_value(struct hda_codec *codec)
8857{
8858 alc_process_coef_fw(codec, alc668_coefs);
8859}
8860
David Henningsson6cb3b702010-09-09 08:51:44 +02008861enum {
Daniel T Chen2df03512010-10-10 22:39:28 -04008862 ALC662_FIXUP_ASPIRE,
Takashi Iwai3e887f32014-01-10 17:50:58 +01008863 ALC662_FIXUP_LED_GPIO1,
David Henningsson6cb3b702010-09-09 08:51:44 +02008864 ALC662_FIXUP_IDEAPAD,
Todd Broch6be79482010-12-07 16:51:05 -08008865 ALC272_FIXUP_MARIO,
Anisse Astierd2ebd472011-01-20 12:36:21 +01008866 ALC662_FIXUP_CZC_P10T,
David Henningsson94024cd2011-04-29 14:10:55 +02008867 ALC662_FIXUP_SKU_IGNORE,
Takashi Iwaie59ea3e2011-06-29 17:21:00 +02008868 ALC662_FIXUP_HP_RP5800,
Takashi Iwai53c334a2011-08-23 18:27:14 +02008869 ALC662_FIXUP_ASUS_MODE1,
8870 ALC662_FIXUP_ASUS_MODE2,
8871 ALC662_FIXUP_ASUS_MODE3,
8872 ALC662_FIXUP_ASUS_MODE4,
8873 ALC662_FIXUP_ASUS_MODE5,
8874 ALC662_FIXUP_ASUS_MODE6,
8875 ALC662_FIXUP_ASUS_MODE7,
8876 ALC662_FIXUP_ASUS_MODE8,
Takashi Iwai1565cc32012-02-13 12:03:25 +01008877 ALC662_FIXUP_NO_JACK_DETECT,
David Henningssonedfe3bf2012-06-12 13:15:12 +02008878 ALC662_FIXUP_ZOTAC_Z68,
Takashi Iwai125821a2012-06-22 14:30:29 +02008879 ALC662_FIXUP_INV_DMIC,
David Henningsson1f8b46c2015-05-12 14:38:15 +02008880 ALC662_FIXUP_DELL_MIC_NO_PRESENCE,
David Henningsson73bdd592013-04-15 15:44:14 +02008881 ALC668_FIXUP_DELL_MIC_NO_PRESENCE,
David Henningsson1f8b46c2015-05-12 14:38:15 +02008882 ALC662_FIXUP_HEADSET_MODE,
David Henningsson73bdd592013-04-15 15:44:14 +02008883 ALC668_FIXUP_HEADSET_MODE,
David Henningsson8e54b4a2014-02-07 09:31:07 +01008884 ALC662_FIXUP_BASS_MODE4_CHMAP,
David Henningsson61a75f12014-02-07 09:31:08 +01008885 ALC662_FIXUP_BASS_16,
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01008886 ALC662_FIXUP_BASS_1A,
David Henningsson8e54b4a2014-02-07 09:31:07 +01008887 ALC662_FIXUP_BASS_CHMAP,
Hui Wang493a52a2014-01-14 14:07:36 +08008888 ALC668_FIXUP_AUTO_MUTE,
Gabriele Mazzotta5e6db662014-05-20 18:58:26 +02008889 ALC668_FIXUP_DELL_DISABLE_AAMIX,
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02008890 ALC668_FIXUP_DELL_XPS13,
Bobi Mihalca9d4dc582016-03-23 13:26:11 +02008891 ALC662_FIXUP_ASUS_Nx50,
Mikhail Paulyshkafc7438b2017-04-21 08:52:42 +02008892 ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE,
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07008893 ALC668_FIXUP_ASUS_Nx51,
Takashi Iwai5b7c5e12018-10-09 14:20:17 +02008894 ALC668_FIXUP_MIC_COEF,
Takashi Iwai11ba6112018-10-07 09:44:17 +02008895 ALC668_FIXUP_ASUS_G751,
Kailang Yang78f4f7c2016-06-07 11:31:34 +08008896 ALC891_FIXUP_HEADSET_MODE,
8897 ALC891_FIXUP_DELL_MIC_NO_PRESENCE,
Shrirang Bagul9b51fe32016-08-01 13:16:17 +08008898 ALC662_FIXUP_ACER_VERITON,
Takashi Iwai1a3f0992016-10-20 12:14:51 +02008899 ALC892_FIXUP_ASROCK_MOBO,
Kailang Yangc6790c82016-11-25 16:15:17 +08008900 ALC662_FIXUP_USI_FUNC,
8901 ALC662_FIXUP_USI_HEADSET_MODE,
Kailang Yangca169cc2017-04-25 16:17:40 +08008902 ALC662_FIXUP_LENOVO_MULTI_CODECS,
Sergey Bostandzhyan00066e92019-09-06 11:33:43 +02008903 ALC669_FIXUP_ACER_ASPIRE_ETHOS,
Sergey Bostandzhyan00066e92019-09-06 11:33:43 +02008904 ALC669_FIXUP_ACER_ASPIRE_ETHOS_HEADSET,
Kailang Yang5af290282020-01-17 14:04:01 +08008905 ALC671_FIXUP_HP_HEADSET_MIC2,
Jian-Hong Pand858c702020-03-17 16:28:07 +08008906 ALC662_FIXUP_ACER_X2660G_HEADSET_MODE,
Jian-Hong Pana1244582020-03-17 16:28:09 +08008907 ALC662_FIXUP_ACER_NITRO_HEADSET_MODE,
David Henningsson6cb3b702010-09-09 08:51:44 +02008908};
8909
Takashi Iwai1727a772013-01-10 09:52:52 +01008910static const struct hda_fixup alc662_fixups[] = {
Daniel T Chen2df03512010-10-10 22:39:28 -04008911 [ALC662_FIXUP_ASPIRE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008912 .type = HDA_FIXUP_PINS,
8913 .v.pins = (const struct hda_pintbl[]) {
Daniel T Chen2df03512010-10-10 22:39:28 -04008914 { 0x15, 0x99130112 }, /* subwoofer */
8915 { }
8916 }
8917 },
Takashi Iwai3e887f32014-01-10 17:50:58 +01008918 [ALC662_FIXUP_LED_GPIO1] = {
8919 .type = HDA_FIXUP_FUNC,
8920 .v.func = alc662_fixup_led_gpio1,
8921 },
David Henningsson6cb3b702010-09-09 08:51:44 +02008922 [ALC662_FIXUP_IDEAPAD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008923 .type = HDA_FIXUP_PINS,
8924 .v.pins = (const struct hda_pintbl[]) {
David Henningsson6cb3b702010-09-09 08:51:44 +02008925 { 0x17, 0x99130112 }, /* subwoofer */
8926 { }
Takashi Iwai3e887f32014-01-10 17:50:58 +01008927 },
8928 .chained = true,
8929 .chain_id = ALC662_FIXUP_LED_GPIO1,
David Henningsson6cb3b702010-09-09 08:51:44 +02008930 },
Todd Broch6be79482010-12-07 16:51:05 -08008931 [ALC272_FIXUP_MARIO] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008932 .type = HDA_FIXUP_FUNC,
Takashi Iwaib5bfbc62011-01-13 14:22:32 +01008933 .v.func = alc272_fixup_mario,
Anisse Astierd2ebd472011-01-20 12:36:21 +01008934 },
8935 [ALC662_FIXUP_CZC_P10T] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008936 .type = HDA_FIXUP_VERBS,
Anisse Astierd2ebd472011-01-20 12:36:21 +01008937 .v.verbs = (const struct hda_verb[]) {
8938 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
8939 {}
8940 }
8941 },
David Henningsson94024cd2011-04-29 14:10:55 +02008942 [ALC662_FIXUP_SKU_IGNORE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008943 .type = HDA_FIXUP_FUNC,
Takashi Iwai23d30f22012-05-07 17:17:32 +02008944 .v.func = alc_fixup_sku_ignore,
Takashi Iwaic6b35872011-03-28 12:05:31 +02008945 },
Takashi Iwaie59ea3e2011-06-29 17:21:00 +02008946 [ALC662_FIXUP_HP_RP5800] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008947 .type = HDA_FIXUP_PINS,
8948 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaie59ea3e2011-06-29 17:21:00 +02008949 { 0x14, 0x0221201f }, /* HP out */
8950 { }
8951 },
8952 .chained = true,
8953 .chain_id = ALC662_FIXUP_SKU_IGNORE
8954 },
Takashi Iwai53c334a2011-08-23 18:27:14 +02008955 [ALC662_FIXUP_ASUS_MODE1] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008956 .type = HDA_FIXUP_PINS,
8957 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008958 { 0x14, 0x99130110 }, /* speaker */
8959 { 0x18, 0x01a19c20 }, /* mic */
8960 { 0x19, 0x99a3092f }, /* int-mic */
8961 { 0x21, 0x0121401f }, /* HP out */
8962 { }
8963 },
8964 .chained = true,
8965 .chain_id = ALC662_FIXUP_SKU_IGNORE
8966 },
8967 [ALC662_FIXUP_ASUS_MODE2] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008968 .type = HDA_FIXUP_PINS,
8969 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai2996bdb2011-08-18 16:02:24 +02008970 { 0x14, 0x99130110 }, /* speaker */
8971 { 0x18, 0x01a19820 }, /* mic */
8972 { 0x19, 0x99a3092f }, /* int-mic */
8973 { 0x1b, 0x0121401f }, /* HP out */
8974 { }
8975 },
Takashi Iwai53c334a2011-08-23 18:27:14 +02008976 .chained = true,
8977 .chain_id = ALC662_FIXUP_SKU_IGNORE
8978 },
8979 [ALC662_FIXUP_ASUS_MODE3] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008980 .type = HDA_FIXUP_PINS,
8981 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008982 { 0x14, 0x99130110 }, /* speaker */
8983 { 0x15, 0x0121441f }, /* HP */
8984 { 0x18, 0x01a19840 }, /* mic */
8985 { 0x19, 0x99a3094f }, /* int-mic */
8986 { 0x21, 0x01211420 }, /* HP2 */
8987 { }
8988 },
8989 .chained = true,
8990 .chain_id = ALC662_FIXUP_SKU_IGNORE
8991 },
8992 [ALC662_FIXUP_ASUS_MODE4] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008993 .type = HDA_FIXUP_PINS,
8994 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008995 { 0x14, 0x99130110 }, /* speaker */
8996 { 0x16, 0x99130111 }, /* speaker */
8997 { 0x18, 0x01a19840 }, /* mic */
8998 { 0x19, 0x99a3094f }, /* int-mic */
8999 { 0x21, 0x0121441f }, /* HP */
9000 { }
9001 },
9002 .chained = true,
9003 .chain_id = ALC662_FIXUP_SKU_IGNORE
9004 },
9005 [ALC662_FIXUP_ASUS_MODE5] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01009006 .type = HDA_FIXUP_PINS,
9007 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02009008 { 0x14, 0x99130110 }, /* speaker */
9009 { 0x15, 0x0121441f }, /* HP */
9010 { 0x16, 0x99130111 }, /* speaker */
9011 { 0x18, 0x01a19840 }, /* mic */
9012 { 0x19, 0x99a3094f }, /* int-mic */
9013 { }
9014 },
9015 .chained = true,
9016 .chain_id = ALC662_FIXUP_SKU_IGNORE
9017 },
9018 [ALC662_FIXUP_ASUS_MODE6] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01009019 .type = HDA_FIXUP_PINS,
9020 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02009021 { 0x14, 0x99130110 }, /* speaker */
9022 { 0x15, 0x01211420 }, /* HP2 */
9023 { 0x18, 0x01a19840 }, /* mic */
9024 { 0x19, 0x99a3094f }, /* int-mic */
9025 { 0x1b, 0x0121441f }, /* HP */
9026 { }
9027 },
9028 .chained = true,
9029 .chain_id = ALC662_FIXUP_SKU_IGNORE
9030 },
9031 [ALC662_FIXUP_ASUS_MODE7] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01009032 .type = HDA_FIXUP_PINS,
9033 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02009034 { 0x14, 0x99130110 }, /* speaker */
9035 { 0x17, 0x99130111 }, /* speaker */
9036 { 0x18, 0x01a19840 }, /* mic */
9037 { 0x19, 0x99a3094f }, /* int-mic */
9038 { 0x1b, 0x01214020 }, /* HP */
9039 { 0x21, 0x0121401f }, /* HP */
9040 { }
9041 },
9042 .chained = true,
9043 .chain_id = ALC662_FIXUP_SKU_IGNORE
9044 },
9045 [ALC662_FIXUP_ASUS_MODE8] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01009046 .type = HDA_FIXUP_PINS,
9047 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02009048 { 0x14, 0x99130110 }, /* speaker */
9049 { 0x12, 0x99a30970 }, /* int-mic */
9050 { 0x15, 0x01214020 }, /* HP */
9051 { 0x17, 0x99130111 }, /* speaker */
9052 { 0x18, 0x01a19840 }, /* mic */
9053 { 0x21, 0x0121401f }, /* HP */
9054 { }
9055 },
9056 .chained = true,
9057 .chain_id = ALC662_FIXUP_SKU_IGNORE
Takashi Iwai2996bdb2011-08-18 16:02:24 +02009058 },
Takashi Iwai1565cc32012-02-13 12:03:25 +01009059 [ALC662_FIXUP_NO_JACK_DETECT] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01009060 .type = HDA_FIXUP_FUNC,
Takashi Iwai1565cc32012-02-13 12:03:25 +01009061 .v.func = alc_fixup_no_jack_detect,
9062 },
David Henningssonedfe3bf2012-06-12 13:15:12 +02009063 [ALC662_FIXUP_ZOTAC_Z68] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01009064 .type = HDA_FIXUP_PINS,
9065 .v.pins = (const struct hda_pintbl[]) {
David Henningssonedfe3bf2012-06-12 13:15:12 +02009066 { 0x1b, 0x02214020 }, /* Front HP */
9067 { }
9068 }
9069 },
Takashi Iwai125821a2012-06-22 14:30:29 +02009070 [ALC662_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01009071 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02009072 .v.func = alc_fixup_inv_dmic,
Takashi Iwai125821a2012-06-22 14:30:29 +02009073 },
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02009074 [ALC668_FIXUP_DELL_XPS13] = {
9075 .type = HDA_FIXUP_FUNC,
9076 .v.func = alc_fixup_dell_xps13,
9077 .chained = true,
9078 .chain_id = ALC668_FIXUP_DELL_DISABLE_AAMIX
9079 },
Gabriele Mazzotta5e6db662014-05-20 18:58:26 +02009080 [ALC668_FIXUP_DELL_DISABLE_AAMIX] = {
9081 .type = HDA_FIXUP_FUNC,
9082 .v.func = alc_fixup_disable_aamix,
9083 .chained = true,
9084 .chain_id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE
9085 },
Hui Wang493a52a2014-01-14 14:07:36 +08009086 [ALC668_FIXUP_AUTO_MUTE] = {
9087 .type = HDA_FIXUP_FUNC,
9088 .v.func = alc_fixup_auto_mute_via_amp,
9089 .chained = true,
9090 .chain_id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE
9091 },
David Henningsson1f8b46c2015-05-12 14:38:15 +02009092 [ALC662_FIXUP_DELL_MIC_NO_PRESENCE] = {
9093 .type = HDA_FIXUP_PINS,
9094 .v.pins = (const struct hda_pintbl[]) {
9095 { 0x19, 0x03a1113c }, /* use as headset mic, without its own jack detect */
9096 /* headphone mic by setting pin control of 0x1b (headphone out) to in + vref_50 */
9097 { }
9098 },
9099 .chained = true,
9100 .chain_id = ALC662_FIXUP_HEADSET_MODE
9101 },
9102 [ALC662_FIXUP_HEADSET_MODE] = {
9103 .type = HDA_FIXUP_FUNC,
9104 .v.func = alc_fixup_headset_mode_alc662,
9105 },
David Henningsson73bdd592013-04-15 15:44:14 +02009106 [ALC668_FIXUP_DELL_MIC_NO_PRESENCE] = {
9107 .type = HDA_FIXUP_PINS,
9108 .v.pins = (const struct hda_pintbl[]) {
9109 { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
9110 { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */
9111 { }
9112 },
9113 .chained = true,
9114 .chain_id = ALC668_FIXUP_HEADSET_MODE
9115 },
9116 [ALC668_FIXUP_HEADSET_MODE] = {
9117 .type = HDA_FIXUP_FUNC,
9118 .v.func = alc_fixup_headset_mode_alc668,
9119 },
David Henningsson8e54b4a2014-02-07 09:31:07 +01009120 [ALC662_FIXUP_BASS_MODE4_CHMAP] = {
Takashi Iwai8e383952013-10-30 17:41:12 +01009121 .type = HDA_FIXUP_FUNC,
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01009122 .v.func = alc_fixup_bass_chmap,
Takashi Iwai8e383952013-10-30 17:41:12 +01009123 .chained = true,
9124 .chain_id = ALC662_FIXUP_ASUS_MODE4
9125 },
David Henningsson61a75f12014-02-07 09:31:08 +01009126 [ALC662_FIXUP_BASS_16] = {
9127 .type = HDA_FIXUP_PINS,
9128 .v.pins = (const struct hda_pintbl[]) {
9129 {0x16, 0x80106111}, /* bass speaker */
9130 {}
9131 },
9132 .chained = true,
9133 .chain_id = ALC662_FIXUP_BASS_CHMAP,
9134 },
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01009135 [ALC662_FIXUP_BASS_1A] = {
9136 .type = HDA_FIXUP_PINS,
9137 .v.pins = (const struct hda_pintbl[]) {
9138 {0x1a, 0x80106111}, /* bass speaker */
9139 {}
9140 },
David Henningsson8e54b4a2014-02-07 09:31:07 +01009141 .chained = true,
9142 .chain_id = ALC662_FIXUP_BASS_CHMAP,
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01009143 },
David Henningsson8e54b4a2014-02-07 09:31:07 +01009144 [ALC662_FIXUP_BASS_CHMAP] = {
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01009145 .type = HDA_FIXUP_FUNC,
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01009146 .v.func = alc_fixup_bass_chmap,
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01009147 },
Bobi Mihalca9d4dc582016-03-23 13:26:11 +02009148 [ALC662_FIXUP_ASUS_Nx50] = {
9149 .type = HDA_FIXUP_FUNC,
9150 .v.func = alc_fixup_auto_mute_via_amp,
9151 .chained = true,
9152 .chain_id = ALC662_FIXUP_BASS_1A
9153 },
Mikhail Paulyshkafc7438b2017-04-21 08:52:42 +02009154 [ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE] = {
9155 .type = HDA_FIXUP_FUNC,
9156 .v.func = alc_fixup_headset_mode_alc668,
9157 .chain_id = ALC662_FIXUP_BASS_CHMAP
9158 },
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07009159 [ALC668_FIXUP_ASUS_Nx51] = {
9160 .type = HDA_FIXUP_PINS,
9161 .v.pins = (const struct hda_pintbl[]) {
Mikhail Paulyshkafc7438b2017-04-21 08:52:42 +02009162 { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
9163 { 0x1a, 0x90170151 }, /* bass speaker */
9164 { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07009165 {}
9166 },
9167 .chained = true,
Mikhail Paulyshkafc7438b2017-04-21 08:52:42 +02009168 .chain_id = ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE,
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07009169 },
Takashi Iwai5b7c5e12018-10-09 14:20:17 +02009170 [ALC668_FIXUP_MIC_COEF] = {
Takashi Iwai11ba6112018-10-07 09:44:17 +02009171 .type = HDA_FIXUP_VERBS,
9172 .v.verbs = (const struct hda_verb[]) {
9173 { 0x20, AC_VERB_SET_COEF_INDEX, 0xc3 },
9174 { 0x20, AC_VERB_SET_PROC_COEF, 0x4000 },
9175 {}
9176 },
9177 },
Takashi Iwai5b7c5e12018-10-09 14:20:17 +02009178 [ALC668_FIXUP_ASUS_G751] = {
9179 .type = HDA_FIXUP_PINS,
9180 .v.pins = (const struct hda_pintbl[]) {
9181 { 0x16, 0x0421101f }, /* HP */
9182 {}
9183 },
9184 .chained = true,
9185 .chain_id = ALC668_FIXUP_MIC_COEF
9186 },
Kailang Yang78f4f7c2016-06-07 11:31:34 +08009187 [ALC891_FIXUP_HEADSET_MODE] = {
9188 .type = HDA_FIXUP_FUNC,
9189 .v.func = alc_fixup_headset_mode,
9190 },
9191 [ALC891_FIXUP_DELL_MIC_NO_PRESENCE] = {
9192 .type = HDA_FIXUP_PINS,
9193 .v.pins = (const struct hda_pintbl[]) {
9194 { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
9195 { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */
9196 { }
9197 },
9198 .chained = true,
9199 .chain_id = ALC891_FIXUP_HEADSET_MODE
9200 },
Shrirang Bagul9b51fe32016-08-01 13:16:17 +08009201 [ALC662_FIXUP_ACER_VERITON] = {
9202 .type = HDA_FIXUP_PINS,
9203 .v.pins = (const struct hda_pintbl[]) {
9204 { 0x15, 0x50170120 }, /* no internal speaker */
9205 { }
9206 }
9207 },
Takashi Iwai1a3f0992016-10-20 12:14:51 +02009208 [ALC892_FIXUP_ASROCK_MOBO] = {
9209 .type = HDA_FIXUP_PINS,
9210 .v.pins = (const struct hda_pintbl[]) {
9211 { 0x15, 0x40f000f0 }, /* disabled */
9212 { 0x16, 0x40f000f0 }, /* disabled */
Takashi Iwai1a3f0992016-10-20 12:14:51 +02009213 { }
9214 }
9215 },
Kailang Yangc6790c82016-11-25 16:15:17 +08009216 [ALC662_FIXUP_USI_FUNC] = {
9217 .type = HDA_FIXUP_FUNC,
9218 .v.func = alc662_fixup_usi_headset_mic,
9219 },
9220 [ALC662_FIXUP_USI_HEADSET_MODE] = {
9221 .type = HDA_FIXUP_PINS,
9222 .v.pins = (const struct hda_pintbl[]) {
9223 { 0x19, 0x02a1913c }, /* use as headset mic, without its own jack detect */
9224 { 0x18, 0x01a1903d },
9225 { }
9226 },
9227 .chained = true,
9228 .chain_id = ALC662_FIXUP_USI_FUNC
9229 },
Kailang Yangca169cc2017-04-25 16:17:40 +08009230 [ALC662_FIXUP_LENOVO_MULTI_CODECS] = {
9231 .type = HDA_FIXUP_FUNC,
9232 .v.func = alc233_alc662_fixup_lenovo_dual_codecs,
9233 },
Sergey Bostandzhyan00066e92019-09-06 11:33:43 +02009234 [ALC669_FIXUP_ACER_ASPIRE_ETHOS_HEADSET] = {
9235 .type = HDA_FIXUP_FUNC,
9236 .v.func = alc662_fixup_aspire_ethos_hp,
9237 },
Sergey Bostandzhyan00066e92019-09-06 11:33:43 +02009238 [ALC669_FIXUP_ACER_ASPIRE_ETHOS] = {
9239 .type = HDA_FIXUP_PINS,
9240 .v.pins = (const struct hda_pintbl[]) {
9241 { 0x15, 0x92130110 }, /* front speakers */
9242 { 0x18, 0x99130111 }, /* center/subwoofer */
9243 { 0x1b, 0x11130012 }, /* surround plus jack for HP */
9244 { }
9245 },
9246 .chained = true,
Takashi Iwai336820c2019-11-28 21:26:30 +01009247 .chain_id = ALC669_FIXUP_ACER_ASPIRE_ETHOS_HEADSET
Sergey Bostandzhyan00066e92019-09-06 11:33:43 +02009248 },
Kailang Yang5af290282020-01-17 14:04:01 +08009249 [ALC671_FIXUP_HP_HEADSET_MIC2] = {
9250 .type = HDA_FIXUP_FUNC,
9251 .v.func = alc671_fixup_hp_headset_mic2,
9252 },
Jian-Hong Pand858c702020-03-17 16:28:07 +08009253 [ALC662_FIXUP_ACER_X2660G_HEADSET_MODE] = {
9254 .type = HDA_FIXUP_PINS,
9255 .v.pins = (const struct hda_pintbl[]) {
9256 { 0x1a, 0x02a1113c }, /* use as headset mic, without its own jack detect */
9257 { }
9258 },
9259 .chained = true,
9260 .chain_id = ALC662_FIXUP_USI_FUNC
9261 },
Jian-Hong Pana1244582020-03-17 16:28:09 +08009262 [ALC662_FIXUP_ACER_NITRO_HEADSET_MODE] = {
9263 .type = HDA_FIXUP_PINS,
9264 .v.pins = (const struct hda_pintbl[]) {
9265 { 0x1a, 0x01a11140 }, /* use as headset mic, without its own jack detect */
9266 { 0x1b, 0x0221144f },
9267 { }
9268 },
9269 .chained = true,
9270 .chain_id = ALC662_FIXUP_USI_FUNC
9271 },
David Henningsson6cb3b702010-09-09 08:51:44 +02009272};
9273
Takashi Iwaia9111322011-05-02 11:30:18 +02009274static const struct snd_pci_quirk alc662_fixup_tbl[] = {
Takashi Iwai53c334a2011-08-23 18:27:14 +02009275 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_FIXUP_ASUS_MODE2),
Takashi Iwaid3d38352013-08-19 20:05:50 +02009276 SND_PCI_QUIRK(0x1025, 0x022f, "Acer Aspire One", ALC662_FIXUP_INV_DMIC),
David Henningsson02f6ff92015-12-07 11:29:31 +01009277 SND_PCI_QUIRK(0x1025, 0x0241, "Packard Bell DOTS", ALC662_FIXUP_INV_DMIC),
David Henningssona6c47a82011-02-10 15:39:19 +01009278 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
David Henningsson94024cd2011-04-29 14:10:55 +02009279 SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
Takashi Iwai125821a2012-06-22 14:30:29 +02009280 SND_PCI_QUIRK(0x1025, 0x0349, "eMachines eM250", ALC662_FIXUP_INV_DMIC),
Takashi Iwai18019282013-08-16 08:17:05 +02009281 SND_PCI_QUIRK(0x1025, 0x034a, "Gateway LT27", ALC662_FIXUP_INV_DMIC),
Daniel T Chen2df03512010-10-10 22:39:28 -04009282 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
Jian-Hong Pana1244582020-03-17 16:28:09 +08009283 SND_PCI_QUIRK(0x1025, 0x123c, "Acer Nitro N50-600", ALC662_FIXUP_ACER_NITRO_HEADSET_MODE),
Jian-Hong Pand858c702020-03-17 16:28:07 +08009284 SND_PCI_QUIRK(0x1025, 0x124e, "Acer 2660G", ALC662_FIXUP_ACER_X2660G_HEADSET_MODE),
David Henningsson73bdd592013-04-15 15:44:14 +02009285 SND_PCI_QUIRK(0x1028, 0x05d8, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
9286 SND_PCI_QUIRK(0x1028, 0x05db, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
Takashi Iwaic5d019c2014-07-22 17:33:32 +02009287 SND_PCI_QUIRK(0x1028, 0x05fe, "Dell XPS 15", ALC668_FIXUP_DELL_XPS13),
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02009288 SND_PCI_QUIRK(0x1028, 0x060a, "Dell XPS 13", ALC668_FIXUP_DELL_XPS13),
Niranjan Sivakumar467e1432015-09-05 18:20:35 +02009289 SND_PCI_QUIRK(0x1028, 0x060d, "Dell M3800", ALC668_FIXUP_DELL_XPS13),
David Henningsson09d20142013-11-20 11:43:30 +01009290 SND_PCI_QUIRK(0x1028, 0x0625, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
David Henningssonad8ff99e2013-11-07 09:28:59 +01009291 SND_PCI_QUIRK(0x1028, 0x0626, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
Kailang Yang8dc9abb2014-04-16 15:53:12 +08009292 SND_PCI_QUIRK(0x1028, 0x0696, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
9293 SND_PCI_QUIRK(0x1028, 0x0698, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
Kailang Yang6a98e342014-10-27 16:20:30 +08009294 SND_PCI_QUIRK(0x1028, 0x069f, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
Takashi Iwaie59ea3e2011-06-29 17:21:00 +02009295 SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800),
Kaho Ng2da2dc92016-05-09 00:27:49 +08009296 SND_PCI_QUIRK(0x1043, 0x1080, "Asus UX501VW", ALC668_FIXUP_HEADSET_MODE),
Bobi Mihalca83a9efb2016-03-23 13:32:33 +02009297 SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_ASUS_Nx50),
Takashi Iwaidb8948e2016-01-18 09:17:30 +01009298 SND_PCI_QUIRK(0x1043, 0x13df, "Asus N550JX", ALC662_FIXUP_BASS_1A),
Bobi Mihalca9d4dc582016-03-23 13:26:11 +02009299 SND_PCI_QUIRK(0x1043, 0x129d, "Asus N750", ALC662_FIXUP_ASUS_Nx50),
Takashi Iwai11ba6112018-10-07 09:44:17 +02009300 SND_PCI_QUIRK(0x1043, 0x12ff, "ASUS G751", ALC668_FIXUP_ASUS_G751),
David Henningsson8e54b4a2014-02-07 09:31:07 +01009301 SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
David Henningsson61a75f12014-02-07 09:31:08 +01009302 SND_PCI_QUIRK(0x1043, 0x15a7, "ASUS UX51VZH", ALC662_FIXUP_BASS_16),
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07009303 SND_PCI_QUIRK(0x1043, 0x177d, "ASUS N551", ALC668_FIXUP_ASUS_Nx51),
9304 SND_PCI_QUIRK(0x1043, 0x17bd, "ASUS N751", ALC668_FIXUP_ASUS_Nx51),
Takashi Iwaic7efff92017-01-04 21:38:16 +01009305 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71SL", ALC662_FIXUP_ASUS_MODE8),
David Henningsson61a75f12014-02-07 09:31:08 +01009306 SND_PCI_QUIRK(0x1043, 0x1b73, "ASUS N55SF", ALC662_FIXUP_BASS_16),
David Henningsson8e54b4a2014-02-07 09:31:07 +01009307 SND_PCI_QUIRK(0x1043, 0x1bf3, "ASUS N76VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
Takashi Iwai1565cc32012-02-13 12:03:25 +01009308 SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT),
Takashi Iwai53c334a2011-08-23 18:27:14 +02009309 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2),
Daniel T Chena0e90ac2010-11-20 10:20:35 -05009310 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
Kailang Yangc6790c82016-11-25 16:15:17 +08009311 SND_PCI_QUIRK(0x14cd, 0x5003, "USI", ALC662_FIXUP_USI_HEADSET_MODE),
Kailang Yangca169cc2017-04-25 16:17:40 +08009312 SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC662_FIXUP_LENOVO_MULTI_CODECS),
Valentine Sinitsynd4118582010-10-01 22:24:08 +06009313 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
David Henningsson6cb3b702010-09-09 08:51:44 +02009314 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
Takashi Iwai1a3f0992016-10-20 12:14:51 +02009315 SND_PCI_QUIRK(0x1849, 0x5892, "ASRock B150M", ALC892_FIXUP_ASROCK_MOBO),
David Henningssonedfe3bf2012-06-12 13:15:12 +02009316 SND_PCI_QUIRK(0x19da, 0xa130, "Zotac Z68", ALC662_FIXUP_ZOTAC_Z68),
Shrirang Bagul9b51fe32016-08-01 13:16:17 +08009317 SND_PCI_QUIRK(0x1b0a, 0x01b8, "ACER Veriton", ALC662_FIXUP_ACER_VERITON),
Anisse Astierd2ebd472011-01-20 12:36:21 +01009318 SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
Sergey Bostandzhyan00066e92019-09-06 11:33:43 +02009319 SND_PCI_QUIRK(0x1025, 0x0566, "Acer Aspire Ethos 8951G", ALC669_FIXUP_ACER_ASPIRE_ETHOS),
Takashi Iwai53c334a2011-08-23 18:27:14 +02009320
9321#if 0
9322 /* Below is a quirk table taken from the old code.
9323 * Basically the device should work as is without the fixup table.
9324 * If BIOS doesn't give a proper info, enable the corresponding
9325 * fixup entry.
Jesper Juhl7d7eb9e2012-04-12 22:11:25 +02009326 */
Takashi Iwai53c334a2011-08-23 18:27:14 +02009327 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC662_FIXUP_ASUS_MODE1),
9328 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC662_FIXUP_ASUS_MODE3),
9329 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC662_FIXUP_ASUS_MODE1),
9330 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC662_FIXUP_ASUS_MODE3),
9331 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
9332 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
9333 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
9334 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC662_FIXUP_ASUS_MODE1),
9335 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC662_FIXUP_ASUS_MODE1),
9336 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
9337 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC662_FIXUP_ASUS_MODE7),
9338 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC662_FIXUP_ASUS_MODE7),
9339 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC662_FIXUP_ASUS_MODE8),
9340 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC662_FIXUP_ASUS_MODE3),
9341 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC662_FIXUP_ASUS_MODE1),
9342 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
9343 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_FIXUP_ASUS_MODE2),
9344 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC662_FIXUP_ASUS_MODE1),
9345 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
9346 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
9347 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
9348 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
9349 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC662_FIXUP_ASUS_MODE1),
9350 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC662_FIXUP_ASUS_MODE3),
9351 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_FIXUP_ASUS_MODE2),
9352 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
9353 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC662_FIXUP_ASUS_MODE5),
9354 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
9355 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
9356 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC662_FIXUP_ASUS_MODE1),
9357 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
9358 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
9359 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC662_FIXUP_ASUS_MODE3),
9360 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC662_FIXUP_ASUS_MODE3),
9361 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC662_FIXUP_ASUS_MODE1),
9362 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC662_FIXUP_ASUS_MODE1),
9363 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC662_FIXUP_ASUS_MODE1),
9364 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC662_FIXUP_ASUS_MODE1),
9365 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC662_FIXUP_ASUS_MODE1),
9366 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
9367 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_FIXUP_ASUS_MODE2),
9368 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC662_FIXUP_ASUS_MODE1),
9369 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
9370 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC662_FIXUP_ASUS_MODE3),
9371 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC662_FIXUP_ASUS_MODE1),
9372 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC662_FIXUP_ASUS_MODE1),
9373 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC662_FIXUP_ASUS_MODE1),
9374 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_FIXUP_ASUS_MODE2),
9375 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
9376 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE4),
9377#endif
David Henningsson6cb3b702010-09-09 08:51:44 +02009378 {}
9379};
9380
Takashi Iwai1727a772013-01-10 09:52:52 +01009381static const struct hda_model_fixup alc662_fixup_models[] = {
Takashi Iwaiaa3841b2018-06-26 07:42:40 +02009382 {.id = ALC662_FIXUP_ASPIRE, .name = "aspire"},
9383 {.id = ALC662_FIXUP_IDEAPAD, .name = "ideapad"},
Todd Broch6be79482010-12-07 16:51:05 -08009384 {.id = ALC272_FIXUP_MARIO, .name = "mario"},
Takashi Iwaiaa3841b2018-06-26 07:42:40 +02009385 {.id = ALC662_FIXUP_HP_RP5800, .name = "hp-rp5800"},
Takashi Iwai53c334a2011-08-23 18:27:14 +02009386 {.id = ALC662_FIXUP_ASUS_MODE1, .name = "asus-mode1"},
9387 {.id = ALC662_FIXUP_ASUS_MODE2, .name = "asus-mode2"},
9388 {.id = ALC662_FIXUP_ASUS_MODE3, .name = "asus-mode3"},
9389 {.id = ALC662_FIXUP_ASUS_MODE4, .name = "asus-mode4"},
9390 {.id = ALC662_FIXUP_ASUS_MODE5, .name = "asus-mode5"},
9391 {.id = ALC662_FIXUP_ASUS_MODE6, .name = "asus-mode6"},
9392 {.id = ALC662_FIXUP_ASUS_MODE7, .name = "asus-mode7"},
9393 {.id = ALC662_FIXUP_ASUS_MODE8, .name = "asus-mode8"},
Takashi Iwaiaa3841b2018-06-26 07:42:40 +02009394 {.id = ALC662_FIXUP_ZOTAC_Z68, .name = "zotac-z68"},
Takashi Iwai6e72aa52012-06-25 10:52:25 +02009395 {.id = ALC662_FIXUP_INV_DMIC, .name = "inv-dmic"},
Takashi Iwaiaa3841b2018-06-26 07:42:40 +02009396 {.id = ALC662_FIXUP_DELL_MIC_NO_PRESENCE, .name = "alc662-headset-multi"},
David Henningssone32aa852013-06-17 11:04:02 +02009397 {.id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE, .name = "dell-headset-multi"},
Takashi Iwaiaa3841b2018-06-26 07:42:40 +02009398 {.id = ALC662_FIXUP_HEADSET_MODE, .name = "alc662-headset"},
9399 {.id = ALC668_FIXUP_HEADSET_MODE, .name = "alc668-headset"},
9400 {.id = ALC662_FIXUP_BASS_16, .name = "bass16"},
9401 {.id = ALC662_FIXUP_BASS_1A, .name = "bass1a"},
9402 {.id = ALC668_FIXUP_AUTO_MUTE, .name = "automute"},
9403 {.id = ALC668_FIXUP_DELL_XPS13, .name = "dell-xps13"},
9404 {.id = ALC662_FIXUP_ASUS_Nx50, .name = "asus-nx50"},
9405 {.id = ALC668_FIXUP_ASUS_Nx51, .name = "asus-nx51"},
Takashi Iwai40c51672018-10-07 09:47:39 +02009406 {.id = ALC668_FIXUP_ASUS_G751, .name = "asus-g751"},
Takashi Iwaiaa3841b2018-06-26 07:42:40 +02009407 {.id = ALC891_FIXUP_HEADSET_MODE, .name = "alc891-headset"},
9408 {.id = ALC891_FIXUP_DELL_MIC_NO_PRESENCE, .name = "alc891-headset-multi"},
9409 {.id = ALC662_FIXUP_ACER_VERITON, .name = "acer-veriton"},
9410 {.id = ALC892_FIXUP_ASROCK_MOBO, .name = "asrock-mobo"},
9411 {.id = ALC662_FIXUP_USI_HEADSET_MODE, .name = "usi-headset"},
Takashi Iwaiba90d6a2017-05-22 16:38:47 +02009412 {.id = ALC662_FIXUP_LENOVO_MULTI_CODECS, .name = "dual-codecs"},
Sergey Bostandzhyan00066e92019-09-06 11:33:43 +02009413 {.id = ALC669_FIXUP_ACER_ASPIRE_ETHOS, .name = "aspire-ethos"},
Todd Broch6be79482010-12-07 16:51:05 -08009414 {}
9415};
David Henningsson6cb3b702010-09-09 08:51:44 +02009416
Hui Wang532895c2014-05-29 15:59:19 +08009417static const struct snd_hda_pin_quirk alc662_pin_fixup_tbl[] = {
Kailang Yang78f4f7c2016-06-07 11:31:34 +08009418 SND_HDA_PIN_QUIRK(0x10ec0867, 0x1028, "Dell", ALC891_FIXUP_DELL_MIC_NO_PRESENCE,
9419 {0x17, 0x02211010},
9420 {0x18, 0x01a19030},
9421 {0x1a, 0x01813040},
9422 {0x21, 0x01014020}),
Hui Wang4b4e0e32019-07-16 15:21:34 +08009423 SND_HDA_PIN_QUIRK(0x10ec0867, 0x1028, "Dell", ALC891_FIXUP_DELL_MIC_NO_PRESENCE,
9424 {0x16, 0x01813030},
9425 {0x17, 0x02211010},
9426 {0x18, 0x01a19040},
9427 {0x21, 0x01014020}),
David Henningsson1f8b46c2015-05-12 14:38:15 +02009428 SND_HDA_PIN_QUIRK(0x10ec0662, 0x1028, "Dell", ALC662_FIXUP_DELL_MIC_NO_PRESENCE,
David Henningsson1f8b46c2015-05-12 14:38:15 +02009429 {0x14, 0x01014010},
David Henningsson1f8b46c2015-05-12 14:38:15 +02009430 {0x18, 0x01a19020},
David Henningsson1f8b46c2015-05-12 14:38:15 +02009431 {0x1a, 0x0181302f},
Hui Wang11580292015-08-03 11:03:49 +08009432 {0x1b, 0x0221401f}),
David Henningsson76c21322014-06-24 14:46:54 +02009433 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
9434 {0x12, 0x99a30130},
9435 {0x14, 0x90170110},
9436 {0x15, 0x0321101f},
Hui Wang11580292015-08-03 11:03:49 +08009437 {0x16, 0x03011020}),
David Henningsson76c21322014-06-24 14:46:54 +02009438 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
9439 {0x12, 0x99a30140},
9440 {0x14, 0x90170110},
9441 {0x15, 0x0321101f},
Hui Wang11580292015-08-03 11:03:49 +08009442 {0x16, 0x03011020}),
David Henningsson76c21322014-06-24 14:46:54 +02009443 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
9444 {0x12, 0x99a30150},
9445 {0x14, 0x90170110},
9446 {0x15, 0x0321101f},
Hui Wang11580292015-08-03 11:03:49 +08009447 {0x16, 0x03011020}),
David Henningsson76c21322014-06-24 14:46:54 +02009448 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
David Henningsson76c21322014-06-24 14:46:54 +02009449 {0x14, 0x90170110},
9450 {0x15, 0x0321101f},
Hui Wang11580292015-08-03 11:03:49 +08009451 {0x16, 0x03011020}),
David Henningsson76c21322014-06-24 14:46:54 +02009452 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell XPS 15", ALC668_FIXUP_AUTO_MUTE,
9453 {0x12, 0x90a60130},
9454 {0x14, 0x90170110},
Hui Wang11580292015-08-03 11:03:49 +08009455 {0x15, 0x0321101f}),
Kailang Yang5af290282020-01-17 14:04:01 +08009456 SND_HDA_PIN_QUIRK(0x10ec0671, 0x103c, "HP cPC", ALC671_FIXUP_HP_HEADSET_MIC2,
9457 {0x14, 0x01014010},
9458 {0x17, 0x90170150},
Kailang Yangf2adbae2020-02-05 15:40:01 +08009459 {0x19, 0x02a11060},
Kailang Yang5af290282020-01-17 14:04:01 +08009460 {0x1b, 0x01813030},
9461 {0x21, 0x02211020}),
9462 SND_HDA_PIN_QUIRK(0x10ec0671, 0x103c, "HP cPC", ALC671_FIXUP_HP_HEADSET_MIC2,
9463 {0x14, 0x01014010},
9464 {0x18, 0x01a19040},
9465 {0x1b, 0x01813030},
9466 {0x21, 0x02211020}),
9467 SND_HDA_PIN_QUIRK(0x10ec0671, 0x103c, "HP cPC", ALC671_FIXUP_HP_HEADSET_MIC2,
9468 {0x14, 0x01014020},
9469 {0x17, 0x90170110},
9470 {0x18, 0x01a19050},
9471 {0x1b, 0x01813040},
9472 {0x21, 0x02211030}),
Hui Wang532895c2014-05-29 15:59:19 +08009473 {}
9474};
9475
Takashi Iwai1d045db2011-07-07 18:23:21 +02009476/*
9477 */
Kailang Yangbc9f98a2007-04-12 13:06:07 +02009478static int patch_alc662(struct hda_codec *codec)
9479{
9480 struct alc_spec *spec;
Takashi Iwai3de95172012-05-07 18:03:15 +02009481 int err;
Kailang Yangbc9f98a2007-04-12 13:06:07 +02009482
Takashi Iwai3de95172012-05-07 18:03:15 +02009483 err = alc_alloc_spec(codec, 0x0b);
9484 if (err < 0)
9485 return err;
Kailang Yangbc9f98a2007-04-12 13:06:07 +02009486
Takashi Iwai3de95172012-05-07 18:03:15 +02009487 spec = codec->spec;
Takashi Iwai1f0f4b82011-06-27 10:52:59 +02009488
Takashi Iwai225068a2015-05-29 10:42:14 +02009489 spec->shutup = alc_eapd_shutup;
9490
Takashi Iwai53c334a2011-08-23 18:27:14 +02009491 /* handle multiple HPs as is */
9492 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
9493
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +02009494 alc_fix_pll_init(codec, 0x20, 0x04, 15);
9495
Takashi Iwai7639a062015-03-03 10:07:24 +01009496 switch (codec->core.vendor_id) {
Kailang Yangf3f91852014-10-24 15:43:46 +08009497 case 0x10ec0668:
9498 spec->init_hook = alc668_restore_default_value;
9499 break;
Kailang Yangf3f91852014-10-24 15:43:46 +08009500 }
Kailang Yang8663ff72012-06-29 09:35:52 +02009501
Takashi Iwaic9af7532019-05-10 11:01:43 +02009502 alc_pre_init(codec);
9503
Takashi Iwai1727a772013-01-10 09:52:52 +01009504 snd_hda_pick_fixup(codec, alc662_fixup_models,
Takashi Iwai8e5a0502012-06-21 15:49:33 +02009505 alc662_fixup_tbl, alc662_fixups);
Hui Wang0fc1e442019-08-16 14:27:39 +08009506 snd_hda_pick_pin_fixup(codec, alc662_pin_fixup_tbl, alc662_fixups, true);
Takashi Iwai1727a772013-01-10 09:52:52 +01009507 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai8e5a0502012-06-21 15:49:33 +02009508
9509 alc_auto_parse_customize_define(codec);
9510
Takashi Iwai7504b6c2013-03-18 11:25:51 +01009511 if (has_cdefine_beep(codec))
9512 spec->gen.beep_nid = 0x01;
9513
Takashi Iwai1bb7e432011-10-17 16:50:59 +02009514 if ((alc_get_coef0(codec) & (1 << 14)) &&
Takashi Iwai5100cd02014-02-15 10:03:19 +01009515 codec->bus->pci && codec->bus->pci->subsystem_vendor == 0x1025 &&
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02009516 spec->cdefine.platform_type == 1) {
Wei Yongjun6134b1a2013-04-18 11:12:59 +08009517 err = alc_codec_rename(codec, "ALC272X");
9518 if (err < 0)
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02009519 goto error;
Takashi Iwai20ca0c32011-10-17 16:00:35 +02009520 }
Kailang Yang274693f2009-12-03 10:07:50 +01009521
Takashi Iwaib9c51062011-08-24 18:08:07 +02009522 /* automatic parse from the BIOS config */
9523 err = alc662_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02009524 if (err < 0)
9525 goto error;
Kailang Yangbc9f98a2007-04-12 13:06:07 +02009526
Takashi Iwai7504b6c2013-03-18 11:25:51 +01009527 if (!spec->gen.no_analog && spec->gen.beep_nid) {
Takashi Iwai7639a062015-03-03 10:07:24 +01009528 switch (codec->core.vendor_id) {
Kailang Yangda00c242010-03-19 11:23:45 +01009529 case 0x10ec0662:
Takashi Iwaifea80fa2018-06-20 12:52:46 +02009530 err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
Kailang Yangda00c242010-03-19 11:23:45 +01009531 break;
9532 case 0x10ec0272:
9533 case 0x10ec0663:
9534 case 0x10ec0665:
Kailang Yang9ad54542013-11-26 15:41:40 +08009535 case 0x10ec0668:
Takashi Iwaifea80fa2018-06-20 12:52:46 +02009536 err = set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
Kailang Yangda00c242010-03-19 11:23:45 +01009537 break;
9538 case 0x10ec0273:
Takashi Iwaifea80fa2018-06-20 12:52:46 +02009539 err = set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
Kailang Yangda00c242010-03-19 11:23:45 +01009540 break;
9541 }
Takashi Iwaifea80fa2018-06-20 12:52:46 +02009542 if (err < 0)
9543 goto error;
Kailang Yangcec27c82010-02-04 14:18:18 +01009544 }
Takashi Iwai2134ea42008-01-10 16:53:55 +01009545
Takashi Iwai1727a772013-01-10 09:52:52 +01009546 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01009547
Kailang Yangbc9f98a2007-04-12 13:06:07 +02009548 return 0;
Kailang Yangbc9f98a2007-04-12 13:06:07 +02009549
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02009550 error:
9551 alc_free(codec);
9552 return err;
Kailang Yangb478b992011-05-18 11:51:15 +02009553}
9554
Kailang Yangbc9f98a2007-04-12 13:06:07 +02009555/*
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009556 * ALC680 support
9557 */
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009558
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009559static int alc680_parse_auto_config(struct hda_codec *codec)
9560{
Takashi Iwai3e6179b2011-07-08 16:55:13 +02009561 return alc_parse_auto_config(codec, NULL, NULL);
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009562}
9563
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009564/*
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009565 */
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009566static int patch_alc680(struct hda_codec *codec)
9567{
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009568 int err;
9569
Takashi Iwai1f0f4b82011-06-27 10:52:59 +02009570 /* ALC680 has no aa-loopback mixer */
Takashi Iwai3de95172012-05-07 18:03:15 +02009571 err = alc_alloc_spec(codec, 0);
9572 if (err < 0)
9573 return err;
Takashi Iwai1f0f4b82011-06-27 10:52:59 +02009574
Takashi Iwai1ebec5f2011-08-15 13:21:48 +02009575 /* automatic parse from the BIOS config */
9576 err = alc680_parse_auto_config(codec);
9577 if (err < 0) {
9578 alc_free(codec);
9579 return err;
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009580 }
9581
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009582 return 0;
9583}
9584
9585/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07009586 * patch entries
9587 */
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009588static const struct hda_device_id snd_hda_id_realtek[] = {
Kailang Yang0a6f0602017-06-30 16:00:48 +08009589 HDA_CODEC_ENTRY(0x10ec0215, "ALC215", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009590 HDA_CODEC_ENTRY(0x10ec0221, "ALC221", patch_alc269),
Hui Wang2a36c162019-09-04 13:53:27 +08009591 HDA_CODEC_ENTRY(0x10ec0222, "ALC222", patch_alc269),
Kailang Yang42314302016-02-03 15:03:50 +08009592 HDA_CODEC_ENTRY(0x10ec0225, "ALC225", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009593 HDA_CODEC_ENTRY(0x10ec0231, "ALC231", patch_alc269),
9594 HDA_CODEC_ENTRY(0x10ec0233, "ALC233", patch_alc269),
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08009595 HDA_CODEC_ENTRY(0x10ec0234, "ALC234", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009596 HDA_CODEC_ENTRY(0x10ec0235, "ALC233", patch_alc269),
Kailang Yang736f20a2017-10-20 15:06:34 +08009597 HDA_CODEC_ENTRY(0x10ec0236, "ALC236", patch_alc269),
Kailang Yang7fbdcd82020-04-23 14:18:31 +08009598 HDA_CODEC_ENTRY(0x10ec0245, "ALC245", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009599 HDA_CODEC_ENTRY(0x10ec0255, "ALC255", patch_alc269),
9600 HDA_CODEC_ENTRY(0x10ec0256, "ALC256", patch_alc269),
Kailang Yangf429e7e2017-12-05 15:38:24 +08009601 HDA_CODEC_ENTRY(0x10ec0257, "ALC257", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009602 HDA_CODEC_ENTRY(0x10ec0260, "ALC260", patch_alc260),
9603 HDA_CODEC_ENTRY(0x10ec0262, "ALC262", patch_alc262),
9604 HDA_CODEC_ENTRY(0x10ec0267, "ALC267", patch_alc268),
9605 HDA_CODEC_ENTRY(0x10ec0268, "ALC268", patch_alc268),
9606 HDA_CODEC_ENTRY(0x10ec0269, "ALC269", patch_alc269),
9607 HDA_CODEC_ENTRY(0x10ec0270, "ALC270", patch_alc269),
9608 HDA_CODEC_ENTRY(0x10ec0272, "ALC272", patch_alc662),
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08009609 HDA_CODEC_ENTRY(0x10ec0274, "ALC274", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009610 HDA_CODEC_ENTRY(0x10ec0275, "ALC275", patch_alc269),
9611 HDA_CODEC_ENTRY(0x10ec0276, "ALC276", patch_alc269),
9612 HDA_CODEC_ENTRY(0x10ec0280, "ALC280", patch_alc269),
9613 HDA_CODEC_ENTRY(0x10ec0282, "ALC282", patch_alc269),
9614 HDA_CODEC_ENTRY(0x10ec0283, "ALC283", patch_alc269),
9615 HDA_CODEC_ENTRY(0x10ec0284, "ALC284", patch_alc269),
Kailang Yang0a6f0602017-06-30 16:00:48 +08009616 HDA_CODEC_ENTRY(0x10ec0285, "ALC285", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009617 HDA_CODEC_ENTRY(0x10ec0286, "ALC286", patch_alc269),
Kailang Yang630e3612020-05-27 14:10:26 +08009618 HDA_CODEC_ENTRY(0x10ec0287, "ALC287", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009619 HDA_CODEC_ENTRY(0x10ec0288, "ALC288", patch_alc269),
Kailang Yang0a6f0602017-06-30 16:00:48 +08009620 HDA_CODEC_ENTRY(0x10ec0289, "ALC289", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009621 HDA_CODEC_ENTRY(0x10ec0290, "ALC290", patch_alc269),
9622 HDA_CODEC_ENTRY(0x10ec0292, "ALC292", patch_alc269),
9623 HDA_CODEC_ENTRY(0x10ec0293, "ALC293", patch_alc269),
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08009624 HDA_CODEC_ENTRY(0x10ec0294, "ALC294", patch_alc269),
Kailang Yang7d727862016-05-24 16:46:07 +08009625 HDA_CODEC_ENTRY(0x10ec0295, "ALC295", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009626 HDA_CODEC_ENTRY(0x10ec0298, "ALC298", patch_alc269),
Kailang Yang28f1f9b2017-01-04 14:49:07 +08009627 HDA_CODEC_ENTRY(0x10ec0299, "ALC299", patch_alc269),
Kailang Yang1078bef2018-11-08 16:36:15 +08009628 HDA_CODEC_ENTRY(0x10ec0300, "ALC300", patch_alc269),
Kailang Yangf0778872019-10-24 15:13:32 +08009629 HDA_CODEC_ENTRY(0x10ec0623, "ALC623", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009630 HDA_CODEC_REV_ENTRY(0x10ec0861, 0x100340, "ALC660", patch_alc861),
9631 HDA_CODEC_ENTRY(0x10ec0660, "ALC660-VD", patch_alc861vd),
9632 HDA_CODEC_ENTRY(0x10ec0861, "ALC861", patch_alc861),
9633 HDA_CODEC_ENTRY(0x10ec0862, "ALC861-VD", patch_alc861vd),
9634 HDA_CODEC_REV_ENTRY(0x10ec0662, 0x100002, "ALC662 rev2", patch_alc882),
9635 HDA_CODEC_REV_ENTRY(0x10ec0662, 0x100101, "ALC662 rev1", patch_alc662),
9636 HDA_CODEC_REV_ENTRY(0x10ec0662, 0x100300, "ALC662 rev3", patch_alc662),
9637 HDA_CODEC_ENTRY(0x10ec0663, "ALC663", patch_alc662),
9638 HDA_CODEC_ENTRY(0x10ec0665, "ALC665", patch_alc662),
9639 HDA_CODEC_ENTRY(0x10ec0667, "ALC667", patch_alc662),
9640 HDA_CODEC_ENTRY(0x10ec0668, "ALC668", patch_alc662),
9641 HDA_CODEC_ENTRY(0x10ec0670, "ALC670", patch_alc662),
9642 HDA_CODEC_ENTRY(0x10ec0671, "ALC671", patch_alc662),
9643 HDA_CODEC_ENTRY(0x10ec0680, "ALC680", patch_alc680),
Kailang Yang6fbae352016-05-30 16:44:20 +08009644 HDA_CODEC_ENTRY(0x10ec0700, "ALC700", patch_alc269),
9645 HDA_CODEC_ENTRY(0x10ec0701, "ALC701", patch_alc269),
9646 HDA_CODEC_ENTRY(0x10ec0703, "ALC703", patch_alc269),
Kailang Yang83629532019-05-02 16:03:26 +08009647 HDA_CODEC_ENTRY(0x10ec0711, "ALC711", patch_alc269),
Kailang Yang78f4f7c2016-06-07 11:31:34 +08009648 HDA_CODEC_ENTRY(0x10ec0867, "ALC891", patch_alc662),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009649 HDA_CODEC_ENTRY(0x10ec0880, "ALC880", patch_alc880),
9650 HDA_CODEC_ENTRY(0x10ec0882, "ALC882", patch_alc882),
9651 HDA_CODEC_ENTRY(0x10ec0883, "ALC883", patch_alc882),
9652 HDA_CODEC_REV_ENTRY(0x10ec0885, 0x100101, "ALC889A", patch_alc882),
9653 HDA_CODEC_REV_ENTRY(0x10ec0885, 0x100103, "ALC889A", patch_alc882),
9654 HDA_CODEC_ENTRY(0x10ec0885, "ALC885", patch_alc882),
9655 HDA_CODEC_ENTRY(0x10ec0887, "ALC887", patch_alc882),
9656 HDA_CODEC_REV_ENTRY(0x10ec0888, 0x100101, "ALC1200", patch_alc882),
9657 HDA_CODEC_ENTRY(0x10ec0888, "ALC888", patch_alc882),
9658 HDA_CODEC_ENTRY(0x10ec0889, "ALC889", patch_alc882),
9659 HDA_CODEC_ENTRY(0x10ec0892, "ALC892", patch_alc662),
9660 HDA_CODEC_ENTRY(0x10ec0899, "ALC898", patch_alc882),
9661 HDA_CODEC_ENTRY(0x10ec0900, "ALC1150", patch_alc882),
Kailang Yang6d9ffcf2020-01-03 16:24:06 +08009662 HDA_CODEC_ENTRY(0x10ec0b00, "ALCS1200A", patch_alc882),
Kailang Yang65553b12017-07-11 15:15:47 +08009663 HDA_CODEC_ENTRY(0x10ec1168, "ALC1220", patch_alc882),
Kailang Yanga535ad52017-01-16 16:59:26 +08009664 HDA_CODEC_ENTRY(0x10ec1220, "ALC1220", patch_alc882),
Linus Torvalds1da177e2005-04-16 15:20:36 -07009665 {} /* terminator */
9666};
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009667MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_realtek);
Takashi Iwai1289e9e2008-11-27 15:47:11 +01009668
9669MODULE_LICENSE("GPL");
9670MODULE_DESCRIPTION("Realtek HD-audio codec");
9671
Takashi Iwaid8a766a2015-02-17 15:25:37 +01009672static struct hda_codec_driver realtek_driver = {
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009673 .id = snd_hda_id_realtek,
Takashi Iwai1289e9e2008-11-27 15:47:11 +01009674};
9675
Takashi Iwaid8a766a2015-02-17 15:25:37 +01009676module_hda_codec_driver(realtek_driver);