blob: 7fb3d6868f7c75cf0961c65641ae83f7c91d43c6 [file] [log] [blame]
Thomas Gleixnerd0fa1172019-05-20 19:07:57 +02001// SPDX-License-Identifier: GPL-2.0-or-later
Linus Torvalds1da177e2005-04-16 15:20:36 -07002/*
3 * Universal Interface for Intel High Definition Audio Codec
4 *
Takashi Iwai1d045db2011-07-07 18:23:21 +02005 * HD audio interface patch for Realtek ALC codecs
Linus Torvalds1da177e2005-04-16 15:20:36 -07006 *
Kailang Yangdf694da2005-12-05 19:42:22 +01007 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
8 * PeiSen Hou <pshou@realtek.com.tw>
Linus Torvalds1da177e2005-04-16 15:20:36 -07009 * Takashi Iwai <tiwai@suse.de>
Jonathan Woithe409a3e92012-03-27 13:01:01 +103010 * Jonathan Woithe <jwoithe@just42.net>
Linus Torvalds1da177e2005-04-16 15:20:36 -070011 */
12
Linus Torvalds1da177e2005-04-16 15:20:36 -070013#include <linux/init.h>
14#include <linux/delay.h>
15#include <linux/slab.h>
16#include <linux/pci.h>
Takashi Iwai08fb0d02013-01-10 17:33:58 +010017#include <linux/dmi.h>
Paul Gortmakerda155d52011-07-15 12:38:28 -040018#include <linux/module.h>
David Henningsson33f4acd2015-01-07 15:50:13 +010019#include <linux/input.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070020#include <sound/core.h>
Kailang Yang9ad0e492010-09-14 23:22:00 +020021#include <sound/jack.h>
Pierre-Louis Bossartbe57bff2018-08-22 15:24:57 -050022#include <sound/hda_codec.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070023#include "hda_local.h"
Takashi Iwai23d30f22012-05-07 17:17:32 +020024#include "hda_auto_parser.h"
Takashi Iwai1835a0f2011-10-27 22:12:46 +020025#include "hda_jack.h"
Takashi Iwai08c189f2012-12-19 15:22:24 +010026#include "hda_generic.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070027
Takashi Iwaicd63a5f2013-07-05 12:13:59 +020028/* keep halting ALC5505 DSP, for power saving */
29#define HALT_REALTEK_ALC5505
30
Takashi Iwai4a79ba32009-04-22 16:31:35 +020031/* extra amp-initialization sequence types */
32enum {
Takashi Iwai1c76aa52018-06-21 16:37:54 +020033 ALC_INIT_UNDEFINED,
Takashi Iwai4a79ba32009-04-22 16:31:35 +020034 ALC_INIT_NONE,
35 ALC_INIT_DEFAULT,
Takashi Iwai4a79ba32009-04-22 16:31:35 +020036};
37
David Henningsson73bdd592013-04-15 15:44:14 +020038enum {
39 ALC_HEADSET_MODE_UNKNOWN,
40 ALC_HEADSET_MODE_UNPLUGGED,
41 ALC_HEADSET_MODE_HEADSET,
42 ALC_HEADSET_MODE_MIC,
43 ALC_HEADSET_MODE_HEADPHONE,
44};
45
46enum {
47 ALC_HEADSET_TYPE_UNKNOWN,
48 ALC_HEADSET_TYPE_CTIA,
49 ALC_HEADSET_TYPE_OMTP,
50};
51
Hui Wangc7b60a82015-12-28 11:35:25 +080052enum {
53 ALC_KEY_MICMUTE_INDEX,
54};
55
Kailang Yangda00c242010-03-19 11:23:45 +010056struct alc_customize_define {
57 unsigned int sku_cfg;
58 unsigned char port_connectivity;
59 unsigned char check_sum;
60 unsigned char customization;
61 unsigned char external_amp;
62 unsigned int enable_pcbeep:1;
63 unsigned int platform_type:1;
64 unsigned int swap:1;
65 unsigned int override:1;
David Henningsson90622912010-10-14 14:50:18 +020066 unsigned int fixup:1; /* Means that this sku is set by driver, not read from hw */
Kailang Yangda00c242010-03-19 11:23:45 +010067};
68
Linus Torvalds1da177e2005-04-16 15:20:36 -070069struct alc_spec {
Takashi Iwai08c189f2012-12-19 15:22:24 +010070 struct hda_gen_spec gen; /* must be at head */
Takashi Iwai23d30f22012-05-07 17:17:32 +020071
Linus Torvalds1da177e2005-04-16 15:20:36 -070072 /* codec parameterization */
Kailang Yangda00c242010-03-19 11:23:45 +010073 struct alc_customize_define cdefine;
Takashi Iwai08c189f2012-12-19 15:22:24 +010074 unsigned int parse_flags; /* flag for snd_hda_parse_pin_defcfg() */
75
Takashi Iwai5579cd62018-06-19 22:22:41 +020076 /* GPIO bits */
77 unsigned int gpio_mask;
78 unsigned int gpio_dir;
79 unsigned int gpio_data;
Takashi Iwai215c8502018-06-19 22:34:26 +020080 bool gpio_write_delay; /* add a delay before writing gpio_data */
Takashi Iwai5579cd62018-06-19 22:22:41 +020081
Takashi Iwai08fb0d02013-01-10 17:33:58 +010082 /* mute LED for HP laptops, see alc269_fixup_mic_mute_hook() */
83 int mute_led_polarity;
84 hda_nid_t mute_led_nid;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +080085 hda_nid_t cap_mute_led_nid;
Takashi Iwai08fb0d02013-01-10 17:33:58 +010086
Takashi Iwai0f32fd192014-11-19 12:16:14 +010087 unsigned int gpio_mute_led_mask;
88 unsigned int gpio_mic_led_mask;
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +010089
David Henningsson73bdd592013-04-15 15:44:14 +020090 hda_nid_t headset_mic_pin;
91 hda_nid_t headphone_mic_pin;
92 int current_headset_mode;
93 int current_headset_type;
94
Takashi Iwaiae6b8132006-03-03 16:47:17 +010095 /* hooks */
96 void (*init_hook)(struct hda_codec *codec);
Takashi Iwai83012a72012-08-24 18:38:08 +020097#ifdef CONFIG_PM
Daniel T Chenc97259d2009-12-27 18:52:08 -050098 void (*power_hook)(struct hda_codec *codec);
Hector Martinf5de24b2009-12-20 22:51:31 +010099#endif
Takashi Iwai1c7161532011-04-07 10:37:16 +0200100 void (*shutup)(struct hda_codec *codec);
Takashi Iwai70a09762015-12-15 14:59:58 +0100101 void (*reboot_notify)(struct hda_codec *codec);
Takashi Iwaid922b512011-04-28 12:18:53 +0200102
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200103 int init_amp;
Takashi Iwaid433a672010-09-20 15:11:54 +0200104 int codec_variant; /* flag for other variants */
Kailang Yang97a26572013-11-29 00:35:26 -0500105 unsigned int has_alc5505_dsp:1;
106 unsigned int no_depop_delay:1;
Kailang Yang693abe12019-01-29 15:38:21 +0800107 unsigned int done_hp_init:1;
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +0100108 unsigned int no_shutup_pins:1;
Kailang Yangd3ba58b2019-05-06 15:09:42 +0800109 unsigned int ultra_low_power:1;
Takashi Iwaie64f14f2009-01-20 18:32:55 +0100110
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200111 /* for PLL fix */
112 hda_nid_t pll_nid;
113 unsigned int pll_coef_idx, pll_coef_bit;
Takashi Iwai1bb7e432011-10-17 16:50:59 +0200114 unsigned int coef0;
David Henningsson33f4acd2015-01-07 15:50:13 +0100115 struct input_dev *kb_dev;
Hui Wangc7b60a82015-12-28 11:35:25 +0800116 u8 alc_mute_keycode_map[1];
Kailang Yangdf694da2005-12-05 19:42:22 +0100117};
118
Takashi Iwai23f0c042009-02-26 13:03:58 +0100119/*
Takashi Iwaif2a227c2014-08-18 13:35:22 +0200120 * COEF access helper functions
121 */
122
123static int alc_read_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
124 unsigned int coef_idx)
125{
126 unsigned int val;
127
128 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, coef_idx);
129 val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PROC_COEF, 0);
130 return val;
131}
132
133#define alc_read_coef_idx(codec, coef_idx) \
134 alc_read_coefex_idx(codec, 0x20, coef_idx)
135
136static void alc_write_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
137 unsigned int coef_idx, unsigned int coef_val)
138{
139 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, coef_idx);
140 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PROC_COEF, coef_val);
141}
142
143#define alc_write_coef_idx(codec, coef_idx, coef_val) \
144 alc_write_coefex_idx(codec, 0x20, coef_idx, coef_val)
145
Takashi Iwai98b24882014-08-18 13:47:50 +0200146static void alc_update_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
147 unsigned int coef_idx, unsigned int mask,
148 unsigned int bits_set)
149{
150 unsigned int val = alc_read_coefex_idx(codec, nid, coef_idx);
151
152 if (val != -1)
153 alc_write_coefex_idx(codec, nid, coef_idx,
154 (val & ~mask) | bits_set);
155}
156
157#define alc_update_coef_idx(codec, coef_idx, mask, bits_set) \
158 alc_update_coefex_idx(codec, 0x20, coef_idx, mask, bits_set)
159
Takashi Iwaif2a227c2014-08-18 13:35:22 +0200160/* a special bypass for COEF 0; read the cached value at the second time */
161static unsigned int alc_get_coef0(struct hda_codec *codec)
162{
163 struct alc_spec *spec = codec->spec;
164
165 if (!spec->coef0)
166 spec->coef0 = alc_read_coef_idx(codec, 0);
167 return spec->coef0;
168}
169
Takashi Iwai54db6c32014-08-18 15:11:19 +0200170/* coef writes/updates batch */
171struct coef_fw {
172 unsigned char nid;
173 unsigned char idx;
174 unsigned short mask;
175 unsigned short val;
176};
177
178#define UPDATE_COEFEX(_nid, _idx, _mask, _val) \
179 { .nid = (_nid), .idx = (_idx), .mask = (_mask), .val = (_val) }
180#define WRITE_COEFEX(_nid, _idx, _val) UPDATE_COEFEX(_nid, _idx, -1, _val)
181#define WRITE_COEF(_idx, _val) WRITE_COEFEX(0x20, _idx, _val)
182#define UPDATE_COEF(_idx, _mask, _val) UPDATE_COEFEX(0x20, _idx, _mask, _val)
183
184static void alc_process_coef_fw(struct hda_codec *codec,
185 const struct coef_fw *fw)
186{
187 for (; fw->nid; fw++) {
188 if (fw->mask == (unsigned short)-1)
189 alc_write_coefex_idx(codec, fw->nid, fw->idx, fw->val);
190 else
191 alc_update_coefex_idx(codec, fw->nid, fw->idx,
192 fw->mask, fw->val);
193 }
194}
195
Takashi Iwaif2a227c2014-08-18 13:35:22 +0200196/*
Takashi Iwai1d045db2011-07-07 18:23:21 +0200197 * GPIO setup tables, used in initialization
Kailang Yangdf694da2005-12-05 19:42:22 +0100198 */
Takashi Iwai5579cd62018-06-19 22:22:41 +0200199
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200200/* Enable GPIO mask and set output */
Takashi Iwai5579cd62018-06-19 22:22:41 +0200201static void alc_setup_gpio(struct hda_codec *codec, unsigned int mask)
202{
203 struct alc_spec *spec = codec->spec;
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200204
Takashi Iwai5579cd62018-06-19 22:22:41 +0200205 spec->gpio_mask |= mask;
206 spec->gpio_dir |= mask;
207 spec->gpio_data |= mask;
208}
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200209
Takashi Iwai5579cd62018-06-19 22:22:41 +0200210static void alc_write_gpio_data(struct hda_codec *codec)
211{
212 struct alc_spec *spec = codec->spec;
213
214 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
215 spec->gpio_data);
216}
217
Takashi Iwaiaaf312d2018-06-19 22:28:22 +0200218static void alc_update_gpio_data(struct hda_codec *codec, unsigned int mask,
219 bool on)
220{
221 struct alc_spec *spec = codec->spec;
222 unsigned int oldval = spec->gpio_data;
223
224 if (on)
225 spec->gpio_data |= mask;
226 else
227 spec->gpio_data &= ~mask;
228 if (oldval != spec->gpio_data)
229 alc_write_gpio_data(codec);
230}
231
Takashi Iwai5579cd62018-06-19 22:22:41 +0200232static void alc_write_gpio(struct hda_codec *codec)
233{
234 struct alc_spec *spec = codec->spec;
235
236 if (!spec->gpio_mask)
237 return;
238
239 snd_hda_codec_write(codec, codec->core.afg, 0,
240 AC_VERB_SET_GPIO_MASK, spec->gpio_mask);
241 snd_hda_codec_write(codec, codec->core.afg, 0,
242 AC_VERB_SET_GPIO_DIRECTION, spec->gpio_dir);
Takashi Iwai215c8502018-06-19 22:34:26 +0200243 if (spec->gpio_write_delay)
244 msleep(1);
Takashi Iwai5579cd62018-06-19 22:22:41 +0200245 alc_write_gpio_data(codec);
246}
247
248static void alc_fixup_gpio(struct hda_codec *codec, int action,
249 unsigned int mask)
250{
251 if (action == HDA_FIXUP_ACT_PRE_PROBE)
252 alc_setup_gpio(codec, mask);
253}
254
255static void alc_fixup_gpio1(struct hda_codec *codec,
256 const struct hda_fixup *fix, int action)
257{
258 alc_fixup_gpio(codec, action, 0x01);
259}
260
261static void alc_fixup_gpio2(struct hda_codec *codec,
262 const struct hda_fixup *fix, int action)
263{
264 alc_fixup_gpio(codec, action, 0x02);
265}
266
267static void alc_fixup_gpio3(struct hda_codec *codec,
268 const struct hda_fixup *fix, int action)
269{
270 alc_fixup_gpio(codec, action, 0x03);
271}
Kailang Yangbdd148a2007-05-08 15:19:08 +0200272
Takashi Iwaiae065f12018-06-19 23:00:03 +0200273static void alc_fixup_gpio4(struct hda_codec *codec,
274 const struct hda_fixup *fix, int action)
275{
276 alc_fixup_gpio(codec, action, 0x04);
277}
278
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200279/*
280 * Fix hardware PLL issue
281 * On some codecs, the analog PLL gating control must be off while
282 * the default value is 1.
283 */
284static void alc_fix_pll(struct hda_codec *codec)
285{
286 struct alc_spec *spec = codec->spec;
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200287
Takashi Iwai98b24882014-08-18 13:47:50 +0200288 if (spec->pll_nid)
289 alc_update_coefex_idx(codec, spec->pll_nid, spec->pll_coef_idx,
290 1 << spec->pll_coef_bit, 0);
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200291}
292
293static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
294 unsigned int coef_idx, unsigned int coef_bit)
295{
296 struct alc_spec *spec = codec->spec;
297 spec->pll_nid = nid;
298 spec->pll_coef_idx = coef_idx;
299 spec->pll_coef_bit = coef_bit;
300 alc_fix_pll(codec);
301}
302
Takashi Iwaicf5a2272012-02-20 16:31:07 +0100303/* update the master volume per volume-knob's unsol event */
Takashi Iwai1a4f69d2014-09-11 15:22:46 +0200304static void alc_update_knob_master(struct hda_codec *codec,
305 struct hda_jack_callback *jack)
Takashi Iwaicf5a2272012-02-20 16:31:07 +0100306{
307 unsigned int val;
308 struct snd_kcontrol *kctl;
309 struct snd_ctl_elem_value *uctl;
310
311 kctl = snd_hda_find_mixer_ctl(codec, "Master Playback Volume");
312 if (!kctl)
313 return;
314 uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
315 if (!uctl)
316 return;
Takashi Iwai2ebab402016-02-09 10:23:52 +0100317 val = snd_hda_codec_read(codec, jack->nid, 0,
Takashi Iwaicf5a2272012-02-20 16:31:07 +0100318 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
319 val &= HDA_AMP_VOLMASK;
320 uctl->value.integer.value[0] = val;
321 uctl->value.integer.value[1] = val;
322 kctl->put(kctl, uctl);
323 kfree(uctl);
324}
325
David Henningsson29adc4b2012-09-25 11:31:00 +0200326static void alc880_unsol_event(struct hda_codec *codec, unsigned int res)
Takashi Iwaif21d78e2012-01-19 12:10:29 +0100327{
David Henningsson29adc4b2012-09-25 11:31:00 +0200328 /* For some reason, the res given from ALC880 is broken.
329 Here we adjust it properly. */
330 snd_hda_jack_unsol_event(codec, res >> 2);
Takashi Iwaif21d78e2012-01-19 12:10:29 +0100331}
332
Kailang Yang394c97f2014-11-12 17:38:08 +0800333/* Change EAPD to verb control */
334static void alc_fill_eapd_coef(struct hda_codec *codec)
335{
336 int coef;
337
338 coef = alc_get_coef0(codec);
339
Takashi Iwai7639a062015-03-03 10:07:24 +0100340 switch (codec->core.vendor_id) {
Kailang Yang394c97f2014-11-12 17:38:08 +0800341 case 0x10ec0262:
342 alc_update_coef_idx(codec, 0x7, 0, 1<<5);
343 break;
344 case 0x10ec0267:
345 case 0x10ec0268:
346 alc_update_coef_idx(codec, 0x7, 0, 1<<13);
347 break;
348 case 0x10ec0269:
349 if ((coef & 0x00f0) == 0x0010)
350 alc_update_coef_idx(codec, 0xd, 0, 1<<14);
351 if ((coef & 0x00f0) == 0x0020)
352 alc_update_coef_idx(codec, 0x4, 1<<15, 0);
353 if ((coef & 0x00f0) == 0x0030)
354 alc_update_coef_idx(codec, 0x10, 1<<9, 0);
355 break;
356 case 0x10ec0280:
357 case 0x10ec0284:
358 case 0x10ec0290:
359 case 0x10ec0292:
360 alc_update_coef_idx(codec, 0x4, 1<<15, 0);
361 break;
Kailang Yang42314302016-02-03 15:03:50 +0800362 case 0x10ec0225:
Takashi Iwai44be77c2017-12-27 08:53:59 +0100363 case 0x10ec0295:
364 case 0x10ec0299:
365 alc_update_coef_idx(codec, 0x67, 0xf000, 0x3000);
366 /* fallthrough */
367 case 0x10ec0215:
Kailang Yang394c97f2014-11-12 17:38:08 +0800368 case 0x10ec0233:
Kailang Yangea04a1d2018-04-25 15:31:52 +0800369 case 0x10ec0235:
Kailang Yang394c97f2014-11-12 17:38:08 +0800370 case 0x10ec0255:
Kailang Yangf429e7e2017-12-05 15:38:24 +0800371 case 0x10ec0257:
Kailang Yang394c97f2014-11-12 17:38:08 +0800372 case 0x10ec0282:
373 case 0x10ec0283:
374 case 0x10ec0286:
375 case 0x10ec0288:
Kailang Yang0a6f0602017-06-30 16:00:48 +0800376 case 0x10ec0285:
Kailang Yang506b62c2014-12-18 17:07:44 +0800377 case 0x10ec0298:
Kailang Yang0a6f0602017-06-30 16:00:48 +0800378 case 0x10ec0289:
Kailang Yang1078bef2018-11-08 16:36:15 +0800379 case 0x10ec0300:
Kailang Yang394c97f2014-11-12 17:38:08 +0800380 alc_update_coef_idx(codec, 0x10, 1<<9, 0);
381 break;
Kailang Yange1e8c1f2019-11-26 17:04:23 +0800382 case 0x10ec0236:
383 case 0x10ec0256:
384 alc_write_coef_idx(codec, 0x36, 0x5757);
385 alc_update_coef_idx(codec, 0x10, 1<<9, 0);
386 break;
Kailang Yang3aabf942017-11-08 15:28:33 +0800387 case 0x10ec0275:
388 alc_update_coef_idx(codec, 0xe, 0, 1<<0);
389 break;
Kailang Yang394c97f2014-11-12 17:38:08 +0800390 case 0x10ec0293:
391 alc_update_coef_idx(codec, 0xa, 1<<13, 0);
392 break;
Kailang Yangdcd4f0d2016-05-04 15:50:18 +0800393 case 0x10ec0234:
394 case 0x10ec0274:
395 case 0x10ec0294:
Kailang Yang6fbae352016-05-30 16:44:20 +0800396 case 0x10ec0700:
397 case 0x10ec0701:
398 case 0x10ec0703:
Kailang Yang83629532019-05-02 16:03:26 +0800399 case 0x10ec0711:
Kailang Yangdcd4f0d2016-05-04 15:50:18 +0800400 alc_update_coef_idx(codec, 0x10, 1<<15, 0);
401 break;
Kailang Yang394c97f2014-11-12 17:38:08 +0800402 case 0x10ec0662:
403 if ((coef & 0x00f0) == 0x0030)
404 alc_update_coef_idx(codec, 0x4, 1<<10, 0); /* EAPD Ctrl */
405 break;
406 case 0x10ec0272:
407 case 0x10ec0273:
408 case 0x10ec0663:
409 case 0x10ec0665:
410 case 0x10ec0670:
411 case 0x10ec0671:
412 case 0x10ec0672:
413 alc_update_coef_idx(codec, 0xd, 0, 1<<14); /* EAPD Ctrl */
414 break;
Kailang Yangf0778872019-10-24 15:13:32 +0800415 case 0x10ec0623:
416 alc_update_coef_idx(codec, 0x19, 1<<13, 0);
417 break;
Kailang Yang394c97f2014-11-12 17:38:08 +0800418 case 0x10ec0668:
419 alc_update_coef_idx(codec, 0x7, 3<<13, 0);
420 break;
421 case 0x10ec0867:
422 alc_update_coef_idx(codec, 0x4, 1<<10, 0);
423 break;
424 case 0x10ec0888:
425 if ((coef & 0x00f0) == 0x0020 || (coef & 0x00f0) == 0x0030)
426 alc_update_coef_idx(codec, 0x7, 1<<5, 0);
427 break;
428 case 0x10ec0892:
429 alc_update_coef_idx(codec, 0x7, 1<<5, 0);
430 break;
431 case 0x10ec0899:
432 case 0x10ec0900:
Kailang Yang65553b12017-07-11 15:15:47 +0800433 case 0x10ec1168:
Kailang Yanga535ad52017-01-16 16:59:26 +0800434 case 0x10ec1220:
Kailang Yang394c97f2014-11-12 17:38:08 +0800435 alc_update_coef_idx(codec, 0x7, 1<<1, 0);
436 break;
437 }
438}
439
Kailang Yangf9423e72008-05-27 12:32:25 +0200440/* additional initialization for ALC888 variants */
441static void alc888_coef_init(struct hda_codec *codec)
442{
Kailang Yang1df88742014-10-29 16:10:13 +0800443 switch (alc_get_coef0(codec) & 0x00f0) {
444 /* alc888-VA */
445 case 0x00:
446 /* alc888-VB */
447 case 0x10:
448 alc_update_coef_idx(codec, 7, 0, 0x2030); /* Turn EAPD to High */
449 break;
450 }
Jaroslav Kysela87a8c372009-07-23 10:58:29 +0200451}
452
Takashi Iwai3fb4a502010-01-19 15:46:37 +0100453/* turn on/off EAPD control (only if available) */
454static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
455{
456 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
457 return;
458 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
459 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
460 on ? 2 : 0);
461}
462
Takashi Iwai691f1fc2011-04-07 10:31:43 +0200463/* turn on/off EAPD controls of the codec */
464static void alc_auto_setup_eapd(struct hda_codec *codec, bool on)
465{
466 /* We currently only handle front, HP */
Michał Mirosławcaf3c042020-01-03 10:23:48 +0100467 static const hda_nid_t pins[] = {
Hui Wangaf95b412015-03-26 17:14:55 +0800468 0x0f, 0x10, 0x14, 0x15, 0x17, 0
Takashi Iwai39fa84e2011-06-27 15:28:57 +0200469 };
Michał Mirosławcaf3c042020-01-03 10:23:48 +0100470 const hda_nid_t *p;
Takashi Iwai39fa84e2011-06-27 15:28:57 +0200471 for (p = pins; *p; p++)
472 set_eapd(codec, *p, on);
Takashi Iwai691f1fc2011-04-07 10:31:43 +0200473}
474
Kailang Yangdad31972019-05-10 16:28:57 +0800475static int find_ext_mic_pin(struct hda_codec *codec);
476
477static void alc_headset_mic_no_shutup(struct hda_codec *codec)
478{
479 const struct hda_pincfg *pin;
480 int mic_pin = find_ext_mic_pin(codec);
481 int i;
482
483 /* don't shut up pins when unloading the driver; otherwise it breaks
484 * the default pin setup at the next load of the driver
485 */
486 if (codec->bus->shutdown)
487 return;
488
489 snd_array_for_each(&codec->init_pins, i, pin) {
490 /* use read here for syncing after issuing each verb */
491 if (pin->nid != mic_pin)
492 snd_hda_codec_read(codec, pin->nid, 0,
493 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
494 }
495
496 codec->pins_shutup = 1;
497}
498
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +0100499static void alc_shutup_pins(struct hda_codec *codec)
500{
501 struct alc_spec *spec = codec->spec;
502
Kailang Yangdad31972019-05-10 16:28:57 +0800503 switch (codec->core.vendor_id) {
504 case 0x10ec0286:
505 case 0x10ec0288:
506 case 0x10ec0298:
507 alc_headset_mic_no_shutup(codec);
508 break;
509 default:
510 if (!spec->no_shutup_pins)
511 snd_hda_shutup_pins(codec);
512 break;
513 }
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +0100514}
515
Takashi Iwai1c7161532011-04-07 10:37:16 +0200516/* generic shutup callback;
Lars-Peter Clausen4ce8e6a2016-11-08 15:48:06 +0100517 * just turning off EAPD and a little pause for avoiding pop-noise
Takashi Iwai1c7161532011-04-07 10:37:16 +0200518 */
519static void alc_eapd_shutup(struct hda_codec *codec)
520{
Kailang Yang97a26572013-11-29 00:35:26 -0500521 struct alc_spec *spec = codec->spec;
522
Takashi Iwai1c7161532011-04-07 10:37:16 +0200523 alc_auto_setup_eapd(codec, false);
Kailang Yang97a26572013-11-29 00:35:26 -0500524 if (!spec->no_depop_delay)
525 msleep(200);
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +0100526 alc_shutup_pins(codec);
Takashi Iwai1c7161532011-04-07 10:37:16 +0200527}
528
Takashi Iwai1d045db2011-07-07 18:23:21 +0200529/* generic EAPD initialization */
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200530static void alc_auto_init_amp(struct hda_codec *codec, int type)
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200531{
Takashi Iwai39fa84e2011-06-27 15:28:57 +0200532 alc_auto_setup_eapd(codec, true);
Takashi Iwai5579cd62018-06-19 22:22:41 +0200533 alc_write_gpio(codec);
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200534 switch (type) {
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200535 case ALC_INIT_DEFAULT:
Takashi Iwai7639a062015-03-03 10:07:24 +0100536 switch (codec->core.vendor_id) {
Kailang Yangc9b58002007-10-16 14:30:01 +0200537 case 0x10ec0260:
Takashi Iwai98b24882014-08-18 13:47:50 +0200538 alc_update_coefex_idx(codec, 0x1a, 7, 0, 0x2010);
Kailang Yangc9b58002007-10-16 14:30:01 +0200539 break;
Kailang Yangc9b58002007-10-16 14:30:01 +0200540 case 0x10ec0880:
541 case 0x10ec0882:
542 case 0x10ec0883:
543 case 0x10ec0885:
Kailang Yang1df88742014-10-29 16:10:13 +0800544 alc_update_coef_idx(codec, 7, 0, 0x2030);
Kailang Yangc9b58002007-10-16 14:30:01 +0200545 break;
Kailang Yangf9423e72008-05-27 12:32:25 +0200546 case 0x10ec0888:
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200547 alc888_coef_init(codec);
Kailang Yangf9423e72008-05-27 12:32:25 +0200548 break;
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200549 }
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200550 break;
551 }
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200552}
Kailang Yangea1fb292008-08-26 12:58:38 +0200553
Takashi Iwai35a39f92019-02-01 11:19:50 +0100554/* get a primary headphone pin if available */
555static hda_nid_t alc_get_hp_pin(struct alc_spec *spec)
556{
557 if (spec->gen.autocfg.hp_pins[0])
558 return spec->gen.autocfg.hp_pins[0];
559 if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
560 return spec->gen.autocfg.line_out_pins[0];
561 return 0;
562}
Takashi Iwai1d045db2011-07-07 18:23:21 +0200563
564/*
565 * Realtek SSID verification
566 */
567
David Henningsson90622912010-10-14 14:50:18 +0200568/* Could be any non-zero and even value. When used as fixup, tells
569 * the driver to ignore any present sku defines.
570 */
571#define ALC_FIXUP_SKU_IGNORE (2)
572
Takashi Iwai23d30f22012-05-07 17:17:32 +0200573static void alc_fixup_sku_ignore(struct hda_codec *codec,
574 const struct hda_fixup *fix, int action)
575{
576 struct alc_spec *spec = codec->spec;
577 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
578 spec->cdefine.fixup = 1;
579 spec->cdefine.sku_cfg = ALC_FIXUP_SKU_IGNORE;
580 }
581}
582
Mengdong Linb5c66112013-11-29 00:35:35 -0500583static void alc_fixup_no_depop_delay(struct hda_codec *codec,
584 const struct hda_fixup *fix, int action)
585{
586 struct alc_spec *spec = codec->spec;
587
Mengdong Lin84d2dc32013-12-02 22:26:03 -0500588 if (action == HDA_FIXUP_ACT_PROBE) {
Mengdong Linb5c66112013-11-29 00:35:35 -0500589 spec->no_depop_delay = 1;
Mengdong Lin84d2dc32013-12-02 22:26:03 -0500590 codec->depop_delay = 0;
591 }
Mengdong Linb5c66112013-11-29 00:35:35 -0500592}
593
Kailang Yangda00c242010-03-19 11:23:45 +0100594static int alc_auto_parse_customize_define(struct hda_codec *codec)
595{
596 unsigned int ass, tmp, i;
Takashi Iwai7fb56222010-03-22 17:09:47 +0100597 unsigned nid = 0;
Kailang Yangda00c242010-03-19 11:23:45 +0100598 struct alc_spec *spec = codec->spec;
599
Takashi Iwaib6cbe512010-07-28 17:43:36 +0200600 spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
601
David Henningsson90622912010-10-14 14:50:18 +0200602 if (spec->cdefine.fixup) {
603 ass = spec->cdefine.sku_cfg;
604 if (ass == ALC_FIXUP_SKU_IGNORE)
605 return -1;
606 goto do_sku;
607 }
608
Takashi Iwai5100cd02014-02-15 10:03:19 +0100609 if (!codec->bus->pci)
610 return -1;
Takashi Iwai7639a062015-03-03 10:07:24 +0100611 ass = codec->core.subsystem_id & 0xffff;
Takashi Iwaib6cbe512010-07-28 17:43:36 +0200612 if (ass != codec->bus->pci->subsystem_device && (ass & 1))
Kailang Yangda00c242010-03-19 11:23:45 +0100613 goto do_sku;
614
615 nid = 0x1d;
Takashi Iwai7639a062015-03-03 10:07:24 +0100616 if (codec->core.vendor_id == 0x10ec0260)
Kailang Yangda00c242010-03-19 11:23:45 +0100617 nid = 0x17;
618 ass = snd_hda_codec_get_pincfg(codec, nid);
619
620 if (!(ass & 1)) {
Takashi Iwai4e76a882014-02-25 12:21:03 +0100621 codec_info(codec, "%s: SKU not ready 0x%08x\n",
Takashi Iwai7639a062015-03-03 10:07:24 +0100622 codec->core.chip_name, ass);
Kailang Yangda00c242010-03-19 11:23:45 +0100623 return -1;
624 }
625
626 /* check sum */
627 tmp = 0;
628 for (i = 1; i < 16; i++) {
629 if ((ass >> i) & 1)
630 tmp++;
631 }
632 if (((ass >> 16) & 0xf) != tmp)
633 return -1;
634
635 spec->cdefine.port_connectivity = ass >> 30;
636 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
637 spec->cdefine.check_sum = (ass >> 16) & 0xf;
638 spec->cdefine.customization = ass >> 8;
639do_sku:
640 spec->cdefine.sku_cfg = ass;
641 spec->cdefine.external_amp = (ass & 0x38) >> 3;
642 spec->cdefine.platform_type = (ass & 0x4) >> 2;
643 spec->cdefine.swap = (ass & 0x2) >> 1;
644 spec->cdefine.override = ass & 0x1;
645
Takashi Iwai4e76a882014-02-25 12:21:03 +0100646 codec_dbg(codec, "SKU: Nid=0x%x sku_cfg=0x%08x\n",
Kailang Yangda00c242010-03-19 11:23:45 +0100647 nid, spec->cdefine.sku_cfg);
Takashi Iwai4e76a882014-02-25 12:21:03 +0100648 codec_dbg(codec, "SKU: port_connectivity=0x%x\n",
Kailang Yangda00c242010-03-19 11:23:45 +0100649 spec->cdefine.port_connectivity);
Takashi Iwai4e76a882014-02-25 12:21:03 +0100650 codec_dbg(codec, "SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
651 codec_dbg(codec, "SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
652 codec_dbg(codec, "SKU: customization=0x%08x\n", spec->cdefine.customization);
653 codec_dbg(codec, "SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
654 codec_dbg(codec, "SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
655 codec_dbg(codec, "SKU: swap=0x%x\n", spec->cdefine.swap);
656 codec_dbg(codec, "SKU: override=0x%x\n", spec->cdefine.override);
Kailang Yangda00c242010-03-19 11:23:45 +0100657
658 return 0;
659}
660
Takashi Iwai08c189f2012-12-19 15:22:24 +0100661/* return the position of NID in the list, or -1 if not found */
662static int find_idx_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
663{
664 int i;
665 for (i = 0; i < nums; i++)
666 if (list[i] == nid)
667 return i;
668 return -1;
669}
Takashi Iwai1d045db2011-07-07 18:23:21 +0200670/* return true if the given NID is found in the list */
Takashi Iwai3af9ee62011-06-27 12:34:01 +0200671static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
672{
Takashi Iwai21268962011-07-07 15:01:13 +0200673 return find_idx_in_nid_list(nid, list, nums) >= 0;
Takashi Iwai3af9ee62011-06-27 12:34:01 +0200674}
675
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200676/* check subsystem ID and set up device-specific initialization;
677 * return 1 if initialized, 0 if invalid SSID
678 */
679/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
680 * 31 ~ 16 : Manufacture ID
681 * 15 ~ 8 : SKU ID
682 * 7 ~ 0 : Assembly ID
683 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
684 */
Takashi Iwai58c57cf2014-01-07 18:22:49 +0100685static int alc_subsystem_id(struct hda_codec *codec, const hda_nid_t *ports)
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200686{
687 unsigned int ass, tmp, i;
688 unsigned nid;
689 struct alc_spec *spec = codec->spec;
690
David Henningsson90622912010-10-14 14:50:18 +0200691 if (spec->cdefine.fixup) {
692 ass = spec->cdefine.sku_cfg;
693 if (ass == ALC_FIXUP_SKU_IGNORE)
694 return 0;
695 goto do_sku;
696 }
697
Takashi Iwai7639a062015-03-03 10:07:24 +0100698 ass = codec->core.subsystem_id & 0xffff;
Takashi Iwai5100cd02014-02-15 10:03:19 +0100699 if (codec->bus->pci &&
700 ass != codec->bus->pci->subsystem_device && (ass & 1))
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200701 goto do_sku;
702
703 /* invalid SSID, check the special NID pin defcfg instead */
704 /*
Sasha Alexandrdef319f2009-06-16 16:00:15 -0400705 * 31~30 : port connectivity
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200706 * 29~21 : reserve
707 * 20 : PCBEEP input
708 * 19~16 : Check sum (15:1)
709 * 15~1 : Custom
710 * 0 : override
711 */
712 nid = 0x1d;
Takashi Iwai7639a062015-03-03 10:07:24 +0100713 if (codec->core.vendor_id == 0x10ec0260)
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200714 nid = 0x17;
715 ass = snd_hda_codec_get_pincfg(codec, nid);
Takashi Iwai4e76a882014-02-25 12:21:03 +0100716 codec_dbg(codec,
717 "realtek: No valid SSID, checking pincfg 0x%08x for NID 0x%x\n",
Takashi Iwaicb6605c2009-04-28 13:03:19 +0200718 ass, nid);
Kailang Yang6227cdc2010-02-25 08:36:52 +0100719 if (!(ass & 1))
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200720 return 0;
721 if ((ass >> 30) != 1) /* no physical connection */
722 return 0;
723
724 /* check sum */
725 tmp = 0;
726 for (i = 1; i < 16; i++) {
727 if ((ass >> i) & 1)
728 tmp++;
729 }
730 if (((ass >> 16) & 0xf) != tmp)
731 return 0;
732do_sku:
Takashi Iwai4e76a882014-02-25 12:21:03 +0100733 codec_dbg(codec, "realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
Takashi Iwai7639a062015-03-03 10:07:24 +0100734 ass & 0xffff, codec->core.vendor_id);
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200735 /*
736 * 0 : override
737 * 1 : Swap Jack
738 * 2 : 0 --> Desktop, 1 --> Laptop
739 * 3~5 : External Amplifier control
740 * 7~6 : Reserved
741 */
742 tmp = (ass & 0x38) >> 3; /* external Amp control */
Takashi Iwai1c76aa52018-06-21 16:37:54 +0200743 if (spec->init_amp == ALC_INIT_UNDEFINED) {
744 switch (tmp) {
745 case 1:
Takashi Iwai5579cd62018-06-19 22:22:41 +0200746 alc_setup_gpio(codec, 0x01);
Takashi Iwai1c76aa52018-06-21 16:37:54 +0200747 break;
748 case 3:
Takashi Iwai5579cd62018-06-19 22:22:41 +0200749 alc_setup_gpio(codec, 0x02);
Takashi Iwai1c76aa52018-06-21 16:37:54 +0200750 break;
751 case 7:
Takashi Iwai5579cd62018-06-19 22:22:41 +0200752 alc_setup_gpio(codec, 0x03);
Takashi Iwai1c76aa52018-06-21 16:37:54 +0200753 break;
754 case 5:
755 default:
756 spec->init_amp = ALC_INIT_DEFAULT;
757 break;
758 }
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200759 }
760
761 /* is laptop or Desktop and enable the function "Mute internal speaker
762 * when the external headphone out jack is plugged"
763 */
764 if (!(ass & 0x8000))
765 return 1;
766 /*
767 * 10~8 : Jack location
768 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
769 * 14~13: Resvered
770 * 15 : 1 --> enable the function "Mute internal speaker
771 * when the external headphone out jack is plugged"
772 */
Takashi Iwai35a39f92019-02-01 11:19:50 +0100773 if (!alc_get_hp_pin(spec)) {
Takashi Iwai01d48252009-10-06 13:21:54 +0200774 hda_nid_t nid;
Kailang Yangc9b58002007-10-16 14:30:01 +0200775 tmp = (ass >> 11) & 0x3; /* HP to chassis */
Takashi Iwai58c57cf2014-01-07 18:22:49 +0100776 nid = ports[tmp];
Takashi Iwai08c189f2012-12-19 15:22:24 +0100777 if (found_in_nid_list(nid, spec->gen.autocfg.line_out_pins,
778 spec->gen.autocfg.line_outs))
Takashi Iwai3af9ee62011-06-27 12:34:01 +0200779 return 1;
Takashi Iwai08c189f2012-12-19 15:22:24 +0100780 spec->gen.autocfg.hp_pins[0] = nid;
Kailang Yangc9b58002007-10-16 14:30:01 +0200781 }
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200782 return 1;
783}
Kailang Yangea1fb292008-08-26 12:58:38 +0200784
Takashi Iwai3e6179b2011-07-08 16:55:13 +0200785/* Check the validity of ALC subsystem-id
786 * ports contains an array of 4 pin NIDs for port-A, E, D and I */
787static void alc_ssid_check(struct hda_codec *codec, const hda_nid_t *ports)
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200788{
Takashi Iwai58c57cf2014-01-07 18:22:49 +0100789 if (!alc_subsystem_id(codec, ports)) {
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200790 struct alc_spec *spec = codec->spec;
Takashi Iwai4e76a882014-02-25 12:21:03 +0100791 codec_dbg(codec,
792 "realtek: Enable default setup for auto mode as fallback\n");
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200793 spec->init_amp = ALC_INIT_DEFAULT;
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200794 }
Takashi Iwai21268962011-07-07 15:01:13 +0200795}
Takashi Iwai1a1455d2011-04-28 17:36:18 +0200796
Takashi Iwai41e41f12005-06-08 14:48:49 +0200797/*
Takashi Iwai1d045db2011-07-07 18:23:21 +0200798 */
799
David Henningsson9d36a7d2014-10-07 10:18:42 +0200800static void alc_fixup_inv_dmic(struct hda_codec *codec,
801 const struct hda_fixup *fix, int action)
Takashi Iwai125821a2012-06-22 14:30:29 +0200802{
803 struct alc_spec *spec = codec->spec;
Takashi Iwai668d1e92012-11-29 14:10:17 +0100804
David Henningsson9d36a7d2014-10-07 10:18:42 +0200805 spec->gen.inv_dmic_split = 1;
Takashi Iwai6e72aa52012-06-25 10:52:25 +0200806}
807
Takashi Iwai603c4012008-07-30 15:01:44 +0200808
Takashi Iwai2eab6942012-12-18 15:30:41 +0100809static int alc_build_controls(struct hda_codec *codec)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700810{
Takashi Iwaia5cb4632018-06-20 12:50:11 +0200811 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700812
Takashi Iwai08c189f2012-12-19 15:22:24 +0100813 err = snd_hda_gen_build_controls(codec);
814 if (err < 0)
815 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700816
Takashi Iwai1727a772013-01-10 09:52:52 +0100817 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_BUILD);
Takashi Iwai420b0fe2012-03-12 12:35:27 +0100818 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700819}
820
Takashi Iwaie9edcee2005-06-13 14:16:38 +0200821
Linus Torvalds1da177e2005-04-16 15:20:36 -0700822/*
Takashi Iwaiae6b8132006-03-03 16:47:17 +0100823 * Common callbacks
Takashi Iwaie9edcee2005-06-13 14:16:38 +0200824 */
Takashi Iwai16ded522005-06-10 19:58:24 +0200825
Takashi Iwaic9af7532019-05-10 11:01:43 +0200826static void alc_pre_init(struct hda_codec *codec)
827{
828 alc_fill_eapd_coef(codec);
829}
830
Kailang Yangaeac1a02019-05-16 16:10:44 +0800831#define is_s3_resume(codec) \
832 ((codec)->core.dev.power.power_state.event == PM_EVENT_RESUME)
Takashi Iwaic9af7532019-05-10 11:01:43 +0200833#define is_s4_resume(codec) \
834 ((codec)->core.dev.power.power_state.event == PM_EVENT_RESTORE)
835
Linus Torvalds1da177e2005-04-16 15:20:36 -0700836static int alc_init(struct hda_codec *codec)
837{
838 struct alc_spec *spec = codec->spec;
Takashi Iwaie9edcee2005-06-13 14:16:38 +0200839
Takashi Iwaic9af7532019-05-10 11:01:43 +0200840 /* hibernation resume needs the full chip initialization */
841 if (is_s4_resume(codec))
842 alc_pre_init(codec);
843
Takashi Iwai546bb672012-03-07 08:37:19 +0100844 if (spec->init_hook)
845 spec->init_hook(codec);
Kailang Yang526af6e2012-03-07 08:25:20 +0100846
Takashi Iwai89781d02019-08-30 12:03:38 +0200847 spec->gen.skip_verbs = 1; /* applied in below */
Kailang Yang607ca3b2019-04-26 16:35:41 +0800848 snd_hda_gen_init(codec);
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200849 alc_fix_pll(codec);
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200850 alc_auto_init_amp(codec, spec->init_amp);
Takashi Iwai89781d02019-08-30 12:03:38 +0200851 snd_hda_apply_verbs(codec); /* apply verbs here after own init */
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200852
Takashi Iwai1727a772013-01-10 09:52:52 +0100853 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_INIT);
Takashi Iwaie08a0072006-09-07 17:52:14 +0200854
Linus Torvalds1da177e2005-04-16 15:20:36 -0700855 return 0;
856}
857
Takashi Iwaia4e09aa2009-12-27 11:22:24 +0100858static inline void alc_shutup(struct hda_codec *codec)
859{
Takashi Iwai1c7161532011-04-07 10:37:16 +0200860 struct alc_spec *spec = codec->spec;
861
Takashi Iwaic7273bd2018-06-12 16:09:57 +0200862 if (!snd_hda_get_bool_hint(codec, "shutup"))
863 return; /* disabled explicitly by hints */
864
Takashi Iwai1c7161532011-04-07 10:37:16 +0200865 if (spec && spec->shutup)
866 spec->shutup(codec);
Takashi Iwai9bfb2842013-07-24 14:31:50 +0200867 else
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +0100868 alc_shutup_pins(codec);
Takashi Iwaia4e09aa2009-12-27 11:22:24 +0100869}
870
Takashi Iwai70a09762015-12-15 14:59:58 +0100871static void alc_reboot_notify(struct hda_codec *codec)
872{
873 struct alc_spec *spec = codec->spec;
874
875 if (spec && spec->reboot_notify)
876 spec->reboot_notify(codec);
877 else
878 alc_shutup(codec);
879}
880
Takashi Iwai8a02c0c2014-02-10 18:09:45 +0100881#define alc_free snd_hda_gen_free
Linus Torvalds1da177e2005-04-16 15:20:36 -0700882
Takashi Iwai83012a72012-08-24 18:38:08 +0200883#ifdef CONFIG_PM
Daniel T Chenc97259d2009-12-27 18:52:08 -0500884static void alc_power_eapd(struct hda_codec *codec)
885{
Takashi Iwai691f1fc2011-04-07 10:31:43 +0200886 alc_auto_setup_eapd(codec, false);
Daniel T Chenc97259d2009-12-27 18:52:08 -0500887}
888
Takashi Iwai68cb2b52012-07-02 15:20:37 +0200889static int alc_suspend(struct hda_codec *codec)
Hector Martinf5de24b2009-12-20 22:51:31 +0100890{
891 struct alc_spec *spec = codec->spec;
Takashi Iwaia4e09aa2009-12-27 11:22:24 +0100892 alc_shutup(codec);
Hector Martinf5de24b2009-12-20 22:51:31 +0100893 if (spec && spec->power_hook)
Daniel T Chenc97259d2009-12-27 18:52:08 -0500894 spec->power_hook(codec);
Hector Martinf5de24b2009-12-20 22:51:31 +0100895 return 0;
896}
897#endif
898
Takashi Iwai2a439522011-07-26 09:52:50 +0200899#ifdef CONFIG_PM
Takashi Iwaie044c392008-10-27 16:56:24 +0100900static int alc_resume(struct hda_codec *codec)
901{
Kailang Yang97a26572013-11-29 00:35:26 -0500902 struct alc_spec *spec = codec->spec;
903
904 if (!spec->no_depop_delay)
905 msleep(150); /* to avoid pop noise */
Takashi Iwaie044c392008-10-27 16:56:24 +0100906 codec->patch_ops.init(codec);
Takashi Iwaieeecd9d2015-02-25 15:18:50 +0100907 regcache_sync(codec->core.regmap);
Takashi Iwai9e5341b2010-09-21 09:57:06 +0200908 hda_call_check_power_status(codec, 0x01);
Takashi Iwaie044c392008-10-27 16:56:24 +0100909 return 0;
910}
Takashi Iwaie044c392008-10-27 16:56:24 +0100911#endif
912
Linus Torvalds1da177e2005-04-16 15:20:36 -0700913/*
914 */
Takashi Iwaia9111322011-05-02 11:30:18 +0200915static const struct hda_codec_ops alc_patch_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700916 .build_controls = alc_build_controls,
Takashi Iwai08c189f2012-12-19 15:22:24 +0100917 .build_pcms = snd_hda_gen_build_pcms,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700918 .init = alc_init,
919 .free = alc_free,
David Henningsson29adc4b2012-09-25 11:31:00 +0200920 .unsol_event = snd_hda_jack_unsol_event,
Takashi Iwai2a439522011-07-26 09:52:50 +0200921#ifdef CONFIG_PM
Takashi Iwaie044c392008-10-27 16:56:24 +0100922 .resume = alc_resume,
Hector Martinf5de24b2009-12-20 22:51:31 +0100923 .suspend = alc_suspend,
Takashi Iwaifce52a32013-01-07 12:42:48 +0100924 .check_power_status = snd_hda_gen_check_power_status,
Takashi Iwaicb53c622007-08-10 17:21:45 +0200925#endif
Takashi Iwai70a09762015-12-15 14:59:58 +0100926 .reboot_notify = alc_reboot_notify,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700927};
928
David Henningsson29adc4b2012-09-25 11:31:00 +0200929
Takashi Iwaided255b2015-10-01 17:59:43 +0200930#define alc_codec_rename(codec, name) snd_hda_codec_set_name(codec, name)
Kailang Yangc027ddc2010-03-19 11:33:06 +0100931
Takashi Iwai2fa522b2005-05-12 14:51:12 +0200932/*
Kailang Yang4b016932013-11-28 11:55:09 +0100933 * Rename codecs appropriately from COEF value or subvendor id
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200934 */
935struct alc_codec_rename_table {
936 unsigned int vendor_id;
937 unsigned short coef_mask;
938 unsigned short coef_bits;
939 const char *name;
940};
941
Kailang Yang4b016932013-11-28 11:55:09 +0100942struct alc_codec_rename_pci_table {
943 unsigned int codec_vendor_id;
944 unsigned short pci_subvendor;
945 unsigned short pci_subdevice;
946 const char *name;
947};
948
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200949static struct alc_codec_rename_table rename_tbl[] = {
Kailang Yange6e5f7a2014-06-06 16:46:43 +0800950 { 0x10ec0221, 0xf00f, 0x1003, "ALC231" },
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200951 { 0x10ec0269, 0xfff0, 0x3010, "ALC277" },
952 { 0x10ec0269, 0xf0f0, 0x2010, "ALC259" },
953 { 0x10ec0269, 0xf0f0, 0x3010, "ALC258" },
954 { 0x10ec0269, 0x00f0, 0x0010, "ALC269VB" },
955 { 0x10ec0269, 0xffff, 0xa023, "ALC259" },
956 { 0x10ec0269, 0xffff, 0x6023, "ALC281X" },
957 { 0x10ec0269, 0x00f0, 0x0020, "ALC269VC" },
Kailang Yangadcc70b2012-05-25 08:08:38 +0200958 { 0x10ec0269, 0x00f0, 0x0030, "ALC269VD" },
Kailang Yange6e5f7a2014-06-06 16:46:43 +0800959 { 0x10ec0662, 0xffff, 0x4020, "ALC656" },
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200960 { 0x10ec0887, 0x00f0, 0x0030, "ALC887-VD" },
961 { 0x10ec0888, 0x00f0, 0x0030, "ALC888-VD" },
962 { 0x10ec0888, 0xf0f0, 0x3020, "ALC886" },
963 { 0x10ec0899, 0x2000, 0x2000, "ALC899" },
964 { 0x10ec0892, 0xffff, 0x8020, "ALC661" },
965 { 0x10ec0892, 0xffff, 0x8011, "ALC661" },
966 { 0x10ec0892, 0xffff, 0x4011, "ALC656" },
967 { } /* terminator */
968};
969
Kailang Yang4b016932013-11-28 11:55:09 +0100970static struct alc_codec_rename_pci_table rename_pci_tbl[] = {
971 { 0x10ec0280, 0x1028, 0, "ALC3220" },
972 { 0x10ec0282, 0x1028, 0, "ALC3221" },
973 { 0x10ec0283, 0x1028, 0, "ALC3223" },
Kailang Yang193177d2014-04-23 16:06:13 +0800974 { 0x10ec0288, 0x1028, 0, "ALC3263" },
Kailang Yang4b016932013-11-28 11:55:09 +0100975 { 0x10ec0292, 0x1028, 0, "ALC3226" },
Kailang Yang193177d2014-04-23 16:06:13 +0800976 { 0x10ec0293, 0x1028, 0, "ALC3235" },
Kailang Yang4b016932013-11-28 11:55:09 +0100977 { 0x10ec0255, 0x1028, 0, "ALC3234" },
978 { 0x10ec0668, 0x1028, 0, "ALC3661" },
Kailang Yange6e5f7a2014-06-06 16:46:43 +0800979 { 0x10ec0275, 0x1028, 0, "ALC3260" },
980 { 0x10ec0899, 0x1028, 0, "ALC3861" },
Kailang Yang2c674fa2015-05-05 15:02:42 +0800981 { 0x10ec0298, 0x1028, 0, "ALC3266" },
Kailang Yang736f20a2017-10-20 15:06:34 +0800982 { 0x10ec0236, 0x1028, 0, "ALC3204" },
Kailang Yang82324502015-05-25 17:16:49 +0800983 { 0x10ec0256, 0x1028, 0, "ALC3246" },
Kailang Yang42314302016-02-03 15:03:50 +0800984 { 0x10ec0225, 0x1028, 0, "ALC3253" },
Kailang Yang7d727862016-05-24 16:46:07 +0800985 { 0x10ec0295, 0x1028, 0, "ALC3254" },
Kailang Yang28f1f9b2017-01-04 14:49:07 +0800986 { 0x10ec0299, 0x1028, 0, "ALC3271" },
Kailang Yange6e5f7a2014-06-06 16:46:43 +0800987 { 0x10ec0670, 0x1025, 0, "ALC669X" },
988 { 0x10ec0676, 0x1025, 0, "ALC679X" },
989 { 0x10ec0282, 0x1043, 0, "ALC3229" },
990 { 0x10ec0233, 0x1043, 0, "ALC3236" },
991 { 0x10ec0280, 0x103c, 0, "ALC3228" },
992 { 0x10ec0282, 0x103c, 0, "ALC3227" },
993 { 0x10ec0286, 0x103c, 0, "ALC3242" },
994 { 0x10ec0290, 0x103c, 0, "ALC3241" },
995 { 0x10ec0668, 0x103c, 0, "ALC3662" },
996 { 0x10ec0283, 0x17aa, 0, "ALC3239" },
997 { 0x10ec0292, 0x17aa, 0, "ALC3232" },
Kailang Yang4b016932013-11-28 11:55:09 +0100998 { } /* terminator */
999};
1000
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02001001static int alc_codec_rename_from_preset(struct hda_codec *codec)
1002{
1003 const struct alc_codec_rename_table *p;
Kailang Yang4b016932013-11-28 11:55:09 +01001004 const struct alc_codec_rename_pci_table *q;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02001005
1006 for (p = rename_tbl; p->vendor_id; p++) {
Takashi Iwai7639a062015-03-03 10:07:24 +01001007 if (p->vendor_id != codec->core.vendor_id)
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02001008 continue;
Takashi Iwai1bb7e432011-10-17 16:50:59 +02001009 if ((alc_get_coef0(codec) & p->coef_mask) == p->coef_bits)
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02001010 return alc_codec_rename(codec, p->name);
1011 }
Kailang Yang4b016932013-11-28 11:55:09 +01001012
Takashi Iwai5100cd02014-02-15 10:03:19 +01001013 if (!codec->bus->pci)
1014 return 0;
Kailang Yang4b016932013-11-28 11:55:09 +01001015 for (q = rename_pci_tbl; q->codec_vendor_id; q++) {
Takashi Iwai7639a062015-03-03 10:07:24 +01001016 if (q->codec_vendor_id != codec->core.vendor_id)
Kailang Yang4b016932013-11-28 11:55:09 +01001017 continue;
1018 if (q->pci_subvendor != codec->bus->pci->subsystem_vendor)
1019 continue;
1020 if (!q->pci_subdevice ||
1021 q->pci_subdevice == codec->bus->pci->subsystem_device)
1022 return alc_codec_rename(codec, q->name);
1023 }
1024
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02001025 return 0;
1026}
1027
Takashi Iwaie4770622011-07-08 11:11:35 +02001028
1029/*
Takashi Iwai1d045db2011-07-07 18:23:21 +02001030 * Digital-beep handlers
1031 */
1032#ifdef CONFIG_SND_HDA_INPUT_BEEP
Takashi Iwaifea80fa2018-06-20 12:52:46 +02001033
1034/* additional beep mixers; private_value will be overwritten */
1035static const struct snd_kcontrol_new alc_beep_mixer[] = {
1036 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
1037 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
1038};
1039
1040/* set up and create beep controls */
1041static int set_beep_amp(struct alc_spec *spec, hda_nid_t nid,
1042 int idx, int dir)
1043{
1044 struct snd_kcontrol_new *knew;
1045 unsigned int beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir);
1046 int i;
1047
1048 for (i = 0; i < ARRAY_SIZE(alc_beep_mixer); i++) {
1049 knew = snd_hda_gen_add_kctl(&spec->gen, NULL,
1050 &alc_beep_mixer[i]);
1051 if (!knew)
1052 return -ENOMEM;
1053 knew->private_value = beep_amp;
1054 }
1055 return 0;
1056}
Takashi Iwai1d045db2011-07-07 18:23:21 +02001057
1058static const struct snd_pci_quirk beep_white_list[] = {
Duncan Roe71100052012-10-10 14:19:50 +02001059 SND_PCI_QUIRK(0x1043, 0x103c, "ASUS", 1),
W. Trevor Kinga4b7f21d2014-03-29 17:47:24 -07001060 SND_PCI_QUIRK(0x1043, 0x115d, "ASUS", 1),
Takashi Iwai1d045db2011-07-07 18:23:21 +02001061 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
Takashi Iwai8554ee42013-02-25 09:54:43 +01001062 SND_PCI_QUIRK(0x1043, 0x8376, "EeePC", 1),
Takashi Iwai1d045db2011-07-07 18:23:21 +02001063 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
1064 SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1),
1065 SND_PCI_QUIRK(0x1043, 0x834a, "EeePC", 1),
Takashi Iwai78f8baf2012-03-06 14:02:32 +01001066 SND_PCI_QUIRK(0x1458, 0xa002, "GA-MA790X", 1),
Takashi Iwai1d045db2011-07-07 18:23:21 +02001067 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
Takashi Iwai051c78a2019-08-22 09:58:07 +02001068 /* blacklist -- no beep available */
1069 SND_PCI_QUIRK(0x17aa, 0x309e, "Lenovo ThinkCentre M73", 0),
1070 SND_PCI_QUIRK(0x17aa, 0x30a3, "Lenovo ThinkCentre M93", 0),
Takashi Iwai1d045db2011-07-07 18:23:21 +02001071 {}
1072};
1073
1074static inline int has_cdefine_beep(struct hda_codec *codec)
1075{
1076 struct alc_spec *spec = codec->spec;
1077 const struct snd_pci_quirk *q;
1078 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
1079 if (q)
1080 return q->value;
1081 return spec->cdefine.enable_pcbeep;
1082}
1083#else
Takashi Iwaifea80fa2018-06-20 12:52:46 +02001084#define set_beep_amp(spec, nid, idx, dir) 0
Takashi Iwai1d045db2011-07-07 18:23:21 +02001085#define has_cdefine_beep(codec) 0
1086#endif
1087
1088/* parse the BIOS configuration and set up the alc_spec */
1089/* return 1 if successful, 0 if the proper config is not found,
1090 * or a negative error code
1091 */
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001092static int alc_parse_auto_config(struct hda_codec *codec,
1093 const hda_nid_t *ignore_nids,
1094 const hda_nid_t *ssid_nids)
Takashi Iwai1d045db2011-07-07 18:23:21 +02001095{
1096 struct alc_spec *spec = codec->spec;
Takashi Iwai08c189f2012-12-19 15:22:24 +01001097 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001098 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001099
Takashi Iwai53c334a2011-08-23 18:27:14 +02001100 err = snd_hda_parse_pin_defcfg(codec, cfg, ignore_nids,
1101 spec->parse_flags);
Takashi Iwai1d045db2011-07-07 18:23:21 +02001102 if (err < 0)
1103 return err;
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001104
1105 if (ssid_nids)
1106 alc_ssid_check(codec, ssid_nids);
1107
Takashi Iwai08c189f2012-12-19 15:22:24 +01001108 err = snd_hda_gen_parse_auto_config(codec, cfg);
1109 if (err < 0)
1110 return err;
Takashi Iwai070cff42012-02-21 12:54:17 +01001111
Takashi Iwai1d045db2011-07-07 18:23:21 +02001112 return 1;
1113}
1114
Takashi Iwai3de95172012-05-07 18:03:15 +02001115/* common preparation job for alc_spec */
1116static int alc_alloc_spec(struct hda_codec *codec, hda_nid_t mixer_nid)
1117{
1118 struct alc_spec *spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1119 int err;
1120
1121 if (!spec)
1122 return -ENOMEM;
1123 codec->spec = spec;
Takashi Iwai08c189f2012-12-19 15:22:24 +01001124 snd_hda_gen_spec_init(&spec->gen);
1125 spec->gen.mixer_nid = mixer_nid;
1126 spec->gen.own_eapd_ctl = 1;
Takashi Iwai1098b7c2012-12-17 20:03:15 +01001127 codec->single_adc_amp = 1;
Takashi Iwai08c189f2012-12-19 15:22:24 +01001128 /* FIXME: do we need this for all Realtek codec models? */
1129 codec->spdif_status_reset = 1;
Takashi Iwai225068a2015-05-29 10:42:14 +02001130 codec->patch_ops = alc_patch_ops;
Takashi Iwai3de95172012-05-07 18:03:15 +02001131
1132 err = alc_codec_rename_from_preset(codec);
1133 if (err < 0) {
1134 kfree(spec);
1135 return err;
1136 }
1137 return 0;
1138}
1139
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001140static int alc880_parse_auto_config(struct hda_codec *codec)
1141{
1142 static const hda_nid_t alc880_ignore[] = { 0x1d, 0 };
Jesper Juhl7d7eb9e2012-04-12 22:11:25 +02001143 static const hda_nid_t alc880_ssids[] = { 0x15, 0x1b, 0x14, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001144 return alc_parse_auto_config(codec, alc880_ignore, alc880_ssids);
1145}
1146
Takashi Iwai1d045db2011-07-07 18:23:21 +02001147/*
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001148 * ALC880 fix-ups
1149 */
1150enum {
Takashi Iwai411225a2012-02-20 17:48:19 +01001151 ALC880_FIXUP_GPIO1,
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001152 ALC880_FIXUP_GPIO2,
1153 ALC880_FIXUP_MEDION_RIM,
Takashi Iwaidc6af522012-02-17 16:18:59 +01001154 ALC880_FIXUP_LG,
Takashi Iwaidb8a38e2013-08-09 12:34:42 +02001155 ALC880_FIXUP_LG_LW25,
Takashi Iwaif02aab52012-02-17 16:33:56 +01001156 ALC880_FIXUP_W810,
Takashi Iwai27e917f2012-02-17 17:49:54 +01001157 ALC880_FIXUP_EAPD_COEF,
Takashi Iwaib9368f52012-02-17 17:54:44 +01001158 ALC880_FIXUP_TCL_S700,
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001159 ALC880_FIXUP_VOL_KNOB,
1160 ALC880_FIXUP_FUJITSU,
Takashi Iwaiba533812012-02-20 16:36:52 +01001161 ALC880_FIXUP_F1734,
Takashi Iwai817de922012-02-20 17:20:48 +01001162 ALC880_FIXUP_UNIWILL,
Takashi Iwai967b88c2012-02-20 17:31:02 +01001163 ALC880_FIXUP_UNIWILL_DIG,
Takashi Iwai96e225f2012-02-20 17:41:51 +01001164 ALC880_FIXUP_Z71V,
Takashi Iwai487a5882013-11-07 07:29:30 +01001165 ALC880_FIXUP_ASUS_W5A,
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001166 ALC880_FIXUP_3ST_BASE,
1167 ALC880_FIXUP_3ST,
1168 ALC880_FIXUP_3ST_DIG,
1169 ALC880_FIXUP_5ST_BASE,
1170 ALC880_FIXUP_5ST,
1171 ALC880_FIXUP_5ST_DIG,
1172 ALC880_FIXUP_6ST_BASE,
1173 ALC880_FIXUP_6ST,
1174 ALC880_FIXUP_6ST_DIG,
Takashi Iwai53971452013-01-23 18:21:37 +01001175 ALC880_FIXUP_6ST_AUTOMUTE,
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001176};
1177
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001178/* enable the volume-knob widget support on NID 0x21 */
1179static void alc880_fixup_vol_knob(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001180 const struct hda_fixup *fix, int action)
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001181{
Takashi Iwai1727a772013-01-10 09:52:52 +01001182 if (action == HDA_FIXUP_ACT_PROBE)
Takashi Iwai62f949b2014-09-11 14:06:53 +02001183 snd_hda_jack_detect_enable_callback(codec, 0x21,
1184 alc_update_knob_master);
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001185}
1186
Takashi Iwai1727a772013-01-10 09:52:52 +01001187static const struct hda_fixup alc880_fixups[] = {
Takashi Iwai411225a2012-02-20 17:48:19 +01001188 [ALC880_FIXUP_GPIO1] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02001189 .type = HDA_FIXUP_FUNC,
1190 .v.func = alc_fixup_gpio1,
Takashi Iwai411225a2012-02-20 17:48:19 +01001191 },
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001192 [ALC880_FIXUP_GPIO2] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02001193 .type = HDA_FIXUP_FUNC,
1194 .v.func = alc_fixup_gpio2,
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001195 },
1196 [ALC880_FIXUP_MEDION_RIM] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001197 .type = HDA_FIXUP_VERBS,
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001198 .v.verbs = (const struct hda_verb[]) {
1199 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
1200 { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
1201 { }
1202 },
1203 .chained = true,
1204 .chain_id = ALC880_FIXUP_GPIO2,
1205 },
Takashi Iwaidc6af522012-02-17 16:18:59 +01001206 [ALC880_FIXUP_LG] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001207 .type = HDA_FIXUP_PINS,
1208 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaidc6af522012-02-17 16:18:59 +01001209 /* disable bogus unused pins */
1210 { 0x16, 0x411111f0 },
1211 { 0x18, 0x411111f0 },
1212 { 0x1a, 0x411111f0 },
1213 { }
1214 }
1215 },
Takashi Iwaidb8a38e2013-08-09 12:34:42 +02001216 [ALC880_FIXUP_LG_LW25] = {
1217 .type = HDA_FIXUP_PINS,
1218 .v.pins = (const struct hda_pintbl[]) {
1219 { 0x1a, 0x0181344f }, /* line-in */
1220 { 0x1b, 0x0321403f }, /* headphone */
1221 { }
1222 }
1223 },
Takashi Iwaif02aab52012-02-17 16:33:56 +01001224 [ALC880_FIXUP_W810] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001225 .type = HDA_FIXUP_PINS,
1226 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaif02aab52012-02-17 16:33:56 +01001227 /* disable bogus unused pins */
1228 { 0x17, 0x411111f0 },
1229 { }
1230 },
1231 .chained = true,
1232 .chain_id = ALC880_FIXUP_GPIO2,
1233 },
Takashi Iwai27e917f2012-02-17 17:49:54 +01001234 [ALC880_FIXUP_EAPD_COEF] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001235 .type = HDA_FIXUP_VERBS,
Takashi Iwai27e917f2012-02-17 17:49:54 +01001236 .v.verbs = (const struct hda_verb[]) {
1237 /* change to EAPD mode */
1238 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
1239 { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
1240 {}
1241 },
1242 },
Takashi Iwaib9368f52012-02-17 17:54:44 +01001243 [ALC880_FIXUP_TCL_S700] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001244 .type = HDA_FIXUP_VERBS,
Takashi Iwaib9368f52012-02-17 17:54:44 +01001245 .v.verbs = (const struct hda_verb[]) {
1246 /* change to EAPD mode */
1247 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
1248 { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
1249 {}
1250 },
1251 .chained = true,
1252 .chain_id = ALC880_FIXUP_GPIO2,
1253 },
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001254 [ALC880_FIXUP_VOL_KNOB] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001255 .type = HDA_FIXUP_FUNC,
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001256 .v.func = alc880_fixup_vol_knob,
1257 },
1258 [ALC880_FIXUP_FUJITSU] = {
1259 /* override all pins as BIOS on old Amilo is broken */
Takashi Iwai1727a772013-01-10 09:52:52 +01001260 .type = HDA_FIXUP_PINS,
1261 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaibb148bd2015-08-13 18:02:39 +02001262 { 0x14, 0x0121401f }, /* HP */
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001263 { 0x15, 0x99030120 }, /* speaker */
1264 { 0x16, 0x99030130 }, /* bass speaker */
1265 { 0x17, 0x411111f0 }, /* N/A */
1266 { 0x18, 0x411111f0 }, /* N/A */
1267 { 0x19, 0x01a19950 }, /* mic-in */
1268 { 0x1a, 0x411111f0 }, /* N/A */
1269 { 0x1b, 0x411111f0 }, /* N/A */
1270 { 0x1c, 0x411111f0 }, /* N/A */
1271 { 0x1d, 0x411111f0 }, /* N/A */
1272 { 0x1e, 0x01454140 }, /* SPDIF out */
1273 { }
1274 },
1275 .chained = true,
1276 .chain_id = ALC880_FIXUP_VOL_KNOB,
1277 },
Takashi Iwaiba533812012-02-20 16:36:52 +01001278 [ALC880_FIXUP_F1734] = {
1279 /* almost compatible with FUJITSU, but no bass and SPDIF */
Takashi Iwai1727a772013-01-10 09:52:52 +01001280 .type = HDA_FIXUP_PINS,
1281 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaibb148bd2015-08-13 18:02:39 +02001282 { 0x14, 0x0121401f }, /* HP */
Takashi Iwaiba533812012-02-20 16:36:52 +01001283 { 0x15, 0x99030120 }, /* speaker */
1284 { 0x16, 0x411111f0 }, /* N/A */
1285 { 0x17, 0x411111f0 }, /* N/A */
1286 { 0x18, 0x411111f0 }, /* N/A */
1287 { 0x19, 0x01a19950 }, /* mic-in */
1288 { 0x1a, 0x411111f0 }, /* N/A */
1289 { 0x1b, 0x411111f0 }, /* N/A */
1290 { 0x1c, 0x411111f0 }, /* N/A */
1291 { 0x1d, 0x411111f0 }, /* N/A */
1292 { 0x1e, 0x411111f0 }, /* N/A */
1293 { }
1294 },
1295 .chained = true,
1296 .chain_id = ALC880_FIXUP_VOL_KNOB,
1297 },
Takashi Iwai817de922012-02-20 17:20:48 +01001298 [ALC880_FIXUP_UNIWILL] = {
1299 /* need to fix HP and speaker pins to be parsed correctly */
Takashi Iwai1727a772013-01-10 09:52:52 +01001300 .type = HDA_FIXUP_PINS,
1301 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai817de922012-02-20 17:20:48 +01001302 { 0x14, 0x0121411f }, /* HP */
1303 { 0x15, 0x99030120 }, /* speaker */
1304 { 0x16, 0x99030130 }, /* bass speaker */
1305 { }
1306 },
1307 },
Takashi Iwai967b88c2012-02-20 17:31:02 +01001308 [ALC880_FIXUP_UNIWILL_DIG] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001309 .type = HDA_FIXUP_PINS,
1310 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai967b88c2012-02-20 17:31:02 +01001311 /* disable bogus unused pins */
1312 { 0x17, 0x411111f0 },
1313 { 0x19, 0x411111f0 },
1314 { 0x1b, 0x411111f0 },
1315 { 0x1f, 0x411111f0 },
1316 { }
1317 }
1318 },
Takashi Iwai96e225f2012-02-20 17:41:51 +01001319 [ALC880_FIXUP_Z71V] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001320 .type = HDA_FIXUP_PINS,
1321 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai96e225f2012-02-20 17:41:51 +01001322 /* set up the whole pins as BIOS is utterly broken */
1323 { 0x14, 0x99030120 }, /* speaker */
1324 { 0x15, 0x0121411f }, /* HP */
1325 { 0x16, 0x411111f0 }, /* N/A */
1326 { 0x17, 0x411111f0 }, /* N/A */
1327 { 0x18, 0x01a19950 }, /* mic-in */
1328 { 0x19, 0x411111f0 }, /* N/A */
1329 { 0x1a, 0x01813031 }, /* line-in */
1330 { 0x1b, 0x411111f0 }, /* N/A */
1331 { 0x1c, 0x411111f0 }, /* N/A */
1332 { 0x1d, 0x411111f0 }, /* N/A */
1333 { 0x1e, 0x0144111e }, /* SPDIF */
1334 { }
1335 }
1336 },
Takashi Iwai487a5882013-11-07 07:29:30 +01001337 [ALC880_FIXUP_ASUS_W5A] = {
1338 .type = HDA_FIXUP_PINS,
1339 .v.pins = (const struct hda_pintbl[]) {
1340 /* set up the whole pins as BIOS is utterly broken */
1341 { 0x14, 0x0121411f }, /* HP */
1342 { 0x15, 0x411111f0 }, /* N/A */
1343 { 0x16, 0x411111f0 }, /* N/A */
1344 { 0x17, 0x411111f0 }, /* N/A */
1345 { 0x18, 0x90a60160 }, /* mic */
1346 { 0x19, 0x411111f0 }, /* N/A */
1347 { 0x1a, 0x411111f0 }, /* N/A */
1348 { 0x1b, 0x411111f0 }, /* N/A */
1349 { 0x1c, 0x411111f0 }, /* N/A */
1350 { 0x1d, 0x411111f0 }, /* N/A */
1351 { 0x1e, 0xb743111e }, /* SPDIF out */
1352 { }
1353 },
1354 .chained = true,
1355 .chain_id = ALC880_FIXUP_GPIO1,
1356 },
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001357 [ALC880_FIXUP_3ST_BASE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001358 .type = HDA_FIXUP_PINS,
1359 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001360 { 0x14, 0x01014010 }, /* line-out */
1361 { 0x15, 0x411111f0 }, /* N/A */
1362 { 0x16, 0x411111f0 }, /* N/A */
1363 { 0x17, 0x411111f0 }, /* N/A */
1364 { 0x18, 0x01a19c30 }, /* mic-in */
1365 { 0x19, 0x0121411f }, /* HP */
1366 { 0x1a, 0x01813031 }, /* line-in */
1367 { 0x1b, 0x02a19c40 }, /* front-mic */
1368 { 0x1c, 0x411111f0 }, /* N/A */
1369 { 0x1d, 0x411111f0 }, /* N/A */
1370 /* 0x1e is filled in below */
1371 { 0x1f, 0x411111f0 }, /* N/A */
1372 { }
1373 }
1374 },
1375 [ALC880_FIXUP_3ST] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001376 .type = HDA_FIXUP_PINS,
1377 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001378 { 0x1e, 0x411111f0 }, /* N/A */
1379 { }
1380 },
1381 .chained = true,
1382 .chain_id = ALC880_FIXUP_3ST_BASE,
1383 },
1384 [ALC880_FIXUP_3ST_DIG] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001385 .type = HDA_FIXUP_PINS,
1386 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001387 { 0x1e, 0x0144111e }, /* SPDIF */
1388 { }
1389 },
1390 .chained = true,
1391 .chain_id = ALC880_FIXUP_3ST_BASE,
1392 },
1393 [ALC880_FIXUP_5ST_BASE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001394 .type = HDA_FIXUP_PINS,
1395 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001396 { 0x14, 0x01014010 }, /* front */
1397 { 0x15, 0x411111f0 }, /* N/A */
1398 { 0x16, 0x01011411 }, /* CLFE */
1399 { 0x17, 0x01016412 }, /* surr */
1400 { 0x18, 0x01a19c30 }, /* mic-in */
1401 { 0x19, 0x0121411f }, /* HP */
1402 { 0x1a, 0x01813031 }, /* line-in */
1403 { 0x1b, 0x02a19c40 }, /* front-mic */
1404 { 0x1c, 0x411111f0 }, /* N/A */
1405 { 0x1d, 0x411111f0 }, /* N/A */
1406 /* 0x1e is filled in below */
1407 { 0x1f, 0x411111f0 }, /* N/A */
1408 { }
1409 }
1410 },
1411 [ALC880_FIXUP_5ST] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001412 .type = HDA_FIXUP_PINS,
1413 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001414 { 0x1e, 0x411111f0 }, /* N/A */
1415 { }
1416 },
1417 .chained = true,
1418 .chain_id = ALC880_FIXUP_5ST_BASE,
1419 },
1420 [ALC880_FIXUP_5ST_DIG] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001421 .type = HDA_FIXUP_PINS,
1422 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001423 { 0x1e, 0x0144111e }, /* SPDIF */
1424 { }
1425 },
1426 .chained = true,
1427 .chain_id = ALC880_FIXUP_5ST_BASE,
1428 },
1429 [ALC880_FIXUP_6ST_BASE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001430 .type = HDA_FIXUP_PINS,
1431 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001432 { 0x14, 0x01014010 }, /* front */
1433 { 0x15, 0x01016412 }, /* surr */
1434 { 0x16, 0x01011411 }, /* CLFE */
1435 { 0x17, 0x01012414 }, /* side */
1436 { 0x18, 0x01a19c30 }, /* mic-in */
1437 { 0x19, 0x02a19c40 }, /* front-mic */
1438 { 0x1a, 0x01813031 }, /* line-in */
1439 { 0x1b, 0x0121411f }, /* HP */
1440 { 0x1c, 0x411111f0 }, /* N/A */
1441 { 0x1d, 0x411111f0 }, /* N/A */
1442 /* 0x1e is filled in below */
1443 { 0x1f, 0x411111f0 }, /* N/A */
1444 { }
1445 }
1446 },
1447 [ALC880_FIXUP_6ST] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001448 .type = HDA_FIXUP_PINS,
1449 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001450 { 0x1e, 0x411111f0 }, /* N/A */
1451 { }
1452 },
1453 .chained = true,
1454 .chain_id = ALC880_FIXUP_6ST_BASE,
1455 },
1456 [ALC880_FIXUP_6ST_DIG] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001457 .type = HDA_FIXUP_PINS,
1458 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001459 { 0x1e, 0x0144111e }, /* SPDIF */
1460 { }
1461 },
1462 .chained = true,
1463 .chain_id = ALC880_FIXUP_6ST_BASE,
1464 },
Takashi Iwai53971452013-01-23 18:21:37 +01001465 [ALC880_FIXUP_6ST_AUTOMUTE] = {
1466 .type = HDA_FIXUP_PINS,
1467 .v.pins = (const struct hda_pintbl[]) {
1468 { 0x1b, 0x0121401f }, /* HP with jack detect */
1469 { }
1470 },
1471 .chained_before = true,
1472 .chain_id = ALC880_FIXUP_6ST_BASE,
1473 },
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001474};
1475
1476static const struct snd_pci_quirk alc880_fixup_tbl[] = {
Takashi Iwaif02aab52012-02-17 16:33:56 +01001477 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_FIXUP_W810),
Takashi Iwai487a5882013-11-07 07:29:30 +01001478 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS W5A", ALC880_FIXUP_ASUS_W5A),
Takashi Iwai96e225f2012-02-20 17:41:51 +01001479 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_FIXUP_Z71V),
Takashi Iwai29e3fdc2012-02-20 17:56:57 +01001480 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_FIXUP_GPIO1),
David Henningsson6538de02014-06-10 10:52:50 +02001481 SND_PCI_QUIRK(0x147b, 0x1045, "ABit AA8XE", ALC880_FIXUP_6ST_AUTOMUTE),
Takashi Iwai29e3fdc2012-02-20 17:56:57 +01001482 SND_PCI_QUIRK(0x1558, 0x5401, "Clevo GPIO2", ALC880_FIXUP_GPIO2),
Takashi Iwai27e917f2012-02-17 17:49:54 +01001483 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo", ALC880_FIXUP_EAPD_COEF),
Takashi Iwai967b88c2012-02-20 17:31:02 +01001484 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_FIXUP_UNIWILL_DIG),
Takashi Iwaiba533812012-02-20 16:36:52 +01001485 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_FIXUP_F1734),
Takashi Iwai817de922012-02-20 17:20:48 +01001486 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_FIXUP_UNIWILL),
Takashi Iwai7833c7e2012-02-20 17:11:38 +01001487 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_FIXUP_VOL_KNOB),
Takashi Iwaif02aab52012-02-17 16:33:56 +01001488 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_FIXUP_W810),
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001489 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_FIXUP_MEDION_RIM),
Takashi Iwai53971452013-01-23 18:21:37 +01001490 SND_PCI_QUIRK(0x1631, 0xe011, "PB 13201056", ALC880_FIXUP_6ST_AUTOMUTE),
Takashi Iwaia1615742015-08-13 18:05:06 +02001491 SND_PCI_QUIRK(0x1734, 0x107c, "FSC Amilo M1437", ALC880_FIXUP_FUJITSU),
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001492 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FIXUP_FUJITSU),
Takashi Iwaiba533812012-02-20 16:36:52 +01001493 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_FIXUP_F1734),
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001494 SND_PCI_QUIRK(0x1734, 0x10b0, "FSC Amilo Pi1556", ALC880_FIXUP_FUJITSU),
Takashi Iwaidc6af522012-02-17 16:18:59 +01001495 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_FIXUP_LG),
1496 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_FIXUP_LG),
1497 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_FIXUP_LG),
Takashi Iwaidb8a38e2013-08-09 12:34:42 +02001498 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_FIXUP_LG_LW25),
Takashi Iwaib9368f52012-02-17 17:54:44 +01001499 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_FIXUP_TCL_S700),
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001500
1501 /* Below is the copied entries from alc880_quirks.c.
1502 * It's not quite sure whether BIOS sets the correct pin-config table
1503 * on these machines, thus they are kept to be compatible with
1504 * the old static quirks. Once when it's confirmed to work without
1505 * these overrides, it'd be better to remove.
1506 */
1507 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_FIXUP_5ST_DIG),
1508 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_FIXUP_6ST),
1509 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_FIXUP_3ST_DIG),
1510 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_FIXUP_6ST_DIG),
1511 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_FIXUP_6ST_DIG),
1512 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_FIXUP_6ST_DIG),
1513 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_FIXUP_3ST_DIG),
1514 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_FIXUP_3ST),
1515 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_FIXUP_6ST_DIG),
1516 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_FIXUP_3ST),
1517 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_FIXUP_3ST),
1518 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_FIXUP_5ST),
1519 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_FIXUP_5ST),
1520 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_FIXUP_5ST),
1521 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_FIXUP_6ST_DIG),
1522 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_FIXUP_6ST_DIG),
1523 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_FIXUP_6ST_DIG),
1524 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_FIXUP_6ST_DIG),
1525 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_FIXUP_5ST_DIG),
1526 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_FIXUP_5ST_DIG),
1527 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_FIXUP_5ST_DIG),
1528 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_FIXUP_6ST_DIG), /* broken BIOS */
1529 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_FIXUP_6ST_DIG),
1530 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1531 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1532 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1533 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_FIXUP_3ST_DIG),
1534 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1535 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_FIXUP_3ST_DIG),
1536 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_FIXUP_3ST_DIG),
1537 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1538 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1539 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1540 /* default Intel */
1541 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_FIXUP_3ST),
1542 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_FIXUP_5ST_DIG),
1543 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_FIXUP_6ST_DIG),
1544 {}
1545};
1546
Takashi Iwai1727a772013-01-10 09:52:52 +01001547static const struct hda_model_fixup alc880_fixup_models[] = {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001548 {.id = ALC880_FIXUP_3ST, .name = "3stack"},
1549 {.id = ALC880_FIXUP_3ST_DIG, .name = "3stack-digout"},
1550 {.id = ALC880_FIXUP_5ST, .name = "5stack"},
1551 {.id = ALC880_FIXUP_5ST_DIG, .name = "5stack-digout"},
1552 {.id = ALC880_FIXUP_6ST, .name = "6stack"},
1553 {.id = ALC880_FIXUP_6ST_DIG, .name = "6stack-digout"},
Takashi Iwai53971452013-01-23 18:21:37 +01001554 {.id = ALC880_FIXUP_6ST_AUTOMUTE, .name = "6stack-automute"},
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001555 {}
1556};
1557
1558
1559/*
Takashi Iwai1d045db2011-07-07 18:23:21 +02001560 * OK, here we have finally the patch for ALC880
1561 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02001562static int patch_alc880(struct hda_codec *codec)
1563{
1564 struct alc_spec *spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001565 int err;
1566
Takashi Iwai3de95172012-05-07 18:03:15 +02001567 err = alc_alloc_spec(codec, 0x0b);
1568 if (err < 0)
1569 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001570
Takashi Iwai3de95172012-05-07 18:03:15 +02001571 spec = codec->spec;
Takashi Iwai08c189f2012-12-19 15:22:24 +01001572 spec->gen.need_dac_fix = 1;
Takashi Iwai7504b6c2013-03-18 11:25:51 +01001573 spec->gen.beep_nid = 0x01;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001574
Takashi Iwai225068a2015-05-29 10:42:14 +02001575 codec->patch_ops.unsol_event = alc880_unsol_event;
1576
Takashi Iwaic9af7532019-05-10 11:01:43 +02001577 alc_pre_init(codec);
1578
Takashi Iwai1727a772013-01-10 09:52:52 +01001579 snd_hda_pick_fixup(codec, alc880_fixup_models, alc880_fixup_tbl,
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001580 alc880_fixups);
Takashi Iwai1727a772013-01-10 09:52:52 +01001581 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02001582
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001583 /* automatic parse from the BIOS config */
1584 err = alc880_parse_auto_config(codec);
1585 if (err < 0)
1586 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001587
Takashi Iwaifea80fa2018-06-20 12:52:46 +02001588 if (!spec->gen.no_analog) {
1589 err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
1590 if (err < 0)
1591 goto error;
1592 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02001593
Takashi Iwai1727a772013-01-10 09:52:52 +01001594 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01001595
Takashi Iwai1d045db2011-07-07 18:23:21 +02001596 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02001597
1598 error:
1599 alc_free(codec);
1600 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001601}
1602
1603
1604/*
1605 * ALC260 support
1606 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02001607static int alc260_parse_auto_config(struct hda_codec *codec)
1608{
Takashi Iwai1d045db2011-07-07 18:23:21 +02001609 static const hda_nid_t alc260_ignore[] = { 0x17, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001610 static const hda_nid_t alc260_ssids[] = { 0x10, 0x15, 0x0f, 0 };
1611 return alc_parse_auto_config(codec, alc260_ignore, alc260_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02001612}
1613
Takashi Iwai1d045db2011-07-07 18:23:21 +02001614/*
1615 * Pin config fixes
1616 */
1617enum {
Takashi Iwaica8f0422012-02-16 11:51:19 +01001618 ALC260_FIXUP_HP_DC5750,
1619 ALC260_FIXUP_HP_PIN_0F,
1620 ALC260_FIXUP_COEF,
Takashi Iwai15317ab2012-02-16 12:02:53 +01001621 ALC260_FIXUP_GPIO1,
Takashi Iwai20f7d922012-02-16 12:35:16 +01001622 ALC260_FIXUP_GPIO1_TOGGLE,
1623 ALC260_FIXUP_REPLACER,
Takashi Iwai0a1c4fa2012-02-16 12:42:30 +01001624 ALC260_FIXUP_HP_B1900,
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001625 ALC260_FIXUP_KN1,
Takashi Iwai39aedee2013-01-10 17:10:40 +01001626 ALC260_FIXUP_FSC_S7020,
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001627 ALC260_FIXUP_FSC_S7020_JWSE,
Takashi Iwaid08c5ef2013-11-22 08:06:36 +01001628 ALC260_FIXUP_VAIO_PINS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02001629};
1630
Takashi Iwai20f7d922012-02-16 12:35:16 +01001631static void alc260_gpio1_automute(struct hda_codec *codec)
1632{
1633 struct alc_spec *spec = codec->spec;
Takashi Iwaiaaf312d2018-06-19 22:28:22 +02001634
1635 alc_update_gpio_data(codec, 0x01, spec->gen.hp_jack_present);
Takashi Iwai20f7d922012-02-16 12:35:16 +01001636}
1637
1638static void alc260_fixup_gpio1_toggle(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001639 const struct hda_fixup *fix, int action)
Takashi Iwai20f7d922012-02-16 12:35:16 +01001640{
1641 struct alc_spec *spec = codec->spec;
Takashi Iwai1727a772013-01-10 09:52:52 +01001642 if (action == HDA_FIXUP_ACT_PROBE) {
Takashi Iwai20f7d922012-02-16 12:35:16 +01001643 /* although the machine has only one output pin, we need to
1644 * toggle GPIO1 according to the jack state
1645 */
Takashi Iwai08c189f2012-12-19 15:22:24 +01001646 spec->gen.automute_hook = alc260_gpio1_automute;
1647 spec->gen.detect_hp = 1;
1648 spec->gen.automute_speaker = 1;
1649 spec->gen.autocfg.hp_pins[0] = 0x0f; /* copy it for automute */
Takashi Iwai62f949b2014-09-11 14:06:53 +02001650 snd_hda_jack_detect_enable_callback(codec, 0x0f,
Takashi Iwai08c189f2012-12-19 15:22:24 +01001651 snd_hda_gen_hp_automute);
Takashi Iwai5579cd62018-06-19 22:22:41 +02001652 alc_setup_gpio(codec, 0x01);
Takashi Iwai20f7d922012-02-16 12:35:16 +01001653 }
1654}
1655
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001656static void alc260_fixup_kn1(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001657 const struct hda_fixup *fix, int action)
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001658{
1659 struct alc_spec *spec = codec->spec;
Takashi Iwai1727a772013-01-10 09:52:52 +01001660 static const struct hda_pintbl pincfgs[] = {
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001661 { 0x0f, 0x02214000 }, /* HP/speaker */
1662 { 0x12, 0x90a60160 }, /* int mic */
1663 { 0x13, 0x02a19000 }, /* ext mic */
1664 { 0x18, 0x01446000 }, /* SPDIF out */
1665 /* disable bogus I/O pins */
1666 { 0x10, 0x411111f0 },
1667 { 0x11, 0x411111f0 },
1668 { 0x14, 0x411111f0 },
1669 { 0x15, 0x411111f0 },
1670 { 0x16, 0x411111f0 },
1671 { 0x17, 0x411111f0 },
1672 { 0x19, 0x411111f0 },
1673 { }
1674 };
1675
1676 switch (action) {
Takashi Iwai1727a772013-01-10 09:52:52 +01001677 case HDA_FIXUP_ACT_PRE_PROBE:
1678 snd_hda_apply_pincfgs(codec, pincfgs);
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001679 spec->init_amp = ALC_INIT_NONE;
1680 break;
1681 }
1682}
1683
Takashi Iwai39aedee2013-01-10 17:10:40 +01001684static void alc260_fixup_fsc_s7020(struct hda_codec *codec,
1685 const struct hda_fixup *fix, int action)
1686{
1687 struct alc_spec *spec = codec->spec;
Takashi Iwai1c76aa52018-06-21 16:37:54 +02001688 if (action == HDA_FIXUP_ACT_PRE_PROBE)
Takashi Iwaie6e0ee52013-02-18 17:04:20 +01001689 spec->init_amp = ALC_INIT_NONE;
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001690}
1691
1692static void alc260_fixup_fsc_s7020_jwse(struct hda_codec *codec,
1693 const struct hda_fixup *fix, int action)
1694{
1695 struct alc_spec *spec = codec->spec;
1696 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwaif811c3c2013-03-07 18:32:59 +01001697 spec->gen.add_jack_modes = 1;
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001698 spec->gen.hp_mic = 1;
Takashi Iwaie6e0ee52013-02-18 17:04:20 +01001699 }
Takashi Iwai39aedee2013-01-10 17:10:40 +01001700}
1701
Takashi Iwai1727a772013-01-10 09:52:52 +01001702static const struct hda_fixup alc260_fixups[] = {
Takashi Iwaica8f0422012-02-16 11:51:19 +01001703 [ALC260_FIXUP_HP_DC5750] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001704 .type = HDA_FIXUP_PINS,
1705 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02001706 { 0x11, 0x90130110 }, /* speaker */
1707 { }
1708 }
1709 },
Takashi Iwaica8f0422012-02-16 11:51:19 +01001710 [ALC260_FIXUP_HP_PIN_0F] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001711 .type = HDA_FIXUP_PINS,
1712 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaica8f0422012-02-16 11:51:19 +01001713 { 0x0f, 0x01214000 }, /* HP */
1714 { }
1715 }
1716 },
1717 [ALC260_FIXUP_COEF] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001718 .type = HDA_FIXUP_VERBS,
Takashi Iwaica8f0422012-02-16 11:51:19 +01001719 .v.verbs = (const struct hda_verb[]) {
Ronan Marquete30cf2d2014-06-01 18:38:53 +02001720 { 0x1a, AC_VERB_SET_COEF_INDEX, 0x07 },
1721 { 0x1a, AC_VERB_SET_PROC_COEF, 0x3040 },
Takashi Iwaica8f0422012-02-16 11:51:19 +01001722 { }
1723 },
Takashi Iwaica8f0422012-02-16 11:51:19 +01001724 },
Takashi Iwai15317ab2012-02-16 12:02:53 +01001725 [ALC260_FIXUP_GPIO1] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02001726 .type = HDA_FIXUP_FUNC,
1727 .v.func = alc_fixup_gpio1,
Takashi Iwai15317ab2012-02-16 12:02:53 +01001728 },
Takashi Iwai20f7d922012-02-16 12:35:16 +01001729 [ALC260_FIXUP_GPIO1_TOGGLE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001730 .type = HDA_FIXUP_FUNC,
Takashi Iwai20f7d922012-02-16 12:35:16 +01001731 .v.func = alc260_fixup_gpio1_toggle,
1732 .chained = true,
1733 .chain_id = ALC260_FIXUP_HP_PIN_0F,
1734 },
1735 [ALC260_FIXUP_REPLACER] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001736 .type = HDA_FIXUP_VERBS,
Takashi Iwai20f7d922012-02-16 12:35:16 +01001737 .v.verbs = (const struct hda_verb[]) {
Takashi Iwai192a98e2014-06-02 15:16:07 +02001738 { 0x1a, AC_VERB_SET_COEF_INDEX, 0x07 },
1739 { 0x1a, AC_VERB_SET_PROC_COEF, 0x3050 },
Takashi Iwai20f7d922012-02-16 12:35:16 +01001740 { }
1741 },
1742 .chained = true,
1743 .chain_id = ALC260_FIXUP_GPIO1_TOGGLE,
1744 },
Takashi Iwai0a1c4fa2012-02-16 12:42:30 +01001745 [ALC260_FIXUP_HP_B1900] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001746 .type = HDA_FIXUP_FUNC,
Takashi Iwai0a1c4fa2012-02-16 12:42:30 +01001747 .v.func = alc260_fixup_gpio1_toggle,
1748 .chained = true,
1749 .chain_id = ALC260_FIXUP_COEF,
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001750 },
1751 [ALC260_FIXUP_KN1] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001752 .type = HDA_FIXUP_FUNC,
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001753 .v.func = alc260_fixup_kn1,
1754 },
Takashi Iwai39aedee2013-01-10 17:10:40 +01001755 [ALC260_FIXUP_FSC_S7020] = {
1756 .type = HDA_FIXUP_FUNC,
1757 .v.func = alc260_fixup_fsc_s7020,
1758 },
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001759 [ALC260_FIXUP_FSC_S7020_JWSE] = {
1760 .type = HDA_FIXUP_FUNC,
1761 .v.func = alc260_fixup_fsc_s7020_jwse,
1762 .chained = true,
1763 .chain_id = ALC260_FIXUP_FSC_S7020,
1764 },
Takashi Iwaid08c5ef2013-11-22 08:06:36 +01001765 [ALC260_FIXUP_VAIO_PINS] = {
1766 .type = HDA_FIXUP_PINS,
1767 .v.pins = (const struct hda_pintbl[]) {
1768 /* Pin configs are missing completely on some VAIOs */
1769 { 0x0f, 0x01211020 },
1770 { 0x10, 0x0001003f },
1771 { 0x11, 0x411111f0 },
1772 { 0x12, 0x01a15930 },
1773 { 0x13, 0x411111f0 },
1774 { 0x14, 0x411111f0 },
1775 { 0x15, 0x411111f0 },
1776 { 0x16, 0x411111f0 },
1777 { 0x17, 0x411111f0 },
1778 { 0x18, 0x411111f0 },
1779 { 0x19, 0x411111f0 },
1780 { }
1781 }
1782 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02001783};
1784
1785static const struct snd_pci_quirk alc260_fixup_tbl[] = {
Takashi Iwai15317ab2012-02-16 12:02:53 +01001786 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_FIXUP_GPIO1),
Takashi Iwaica8f0422012-02-16 11:51:19 +01001787 SND_PCI_QUIRK(0x1025, 0x007f, "Acer Aspire 9500", ALC260_FIXUP_COEF),
Takashi Iwai15317ab2012-02-16 12:02:53 +01001788 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_FIXUP_GPIO1),
Takashi Iwaica8f0422012-02-16 11:51:19 +01001789 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", ALC260_FIXUP_HP_DC5750),
Takashi Iwai0a1c4fa2012-02-16 12:42:30 +01001790 SND_PCI_QUIRK(0x103c, 0x30ba, "HP Presario B1900", ALC260_FIXUP_HP_B1900),
Takashi Iwaid08c5ef2013-11-22 08:06:36 +01001791 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_FIXUP_VAIO_PINS),
Takashi Iwai0f5a5b82013-11-21 09:12:52 +01001792 SND_PCI_QUIRK(0x104d, 0x81e2, "Sony VAIO TX", ALC260_FIXUP_HP_PIN_0F),
Takashi Iwai39aedee2013-01-10 17:10:40 +01001793 SND_PCI_QUIRK(0x10cf, 0x1326, "FSC LifeBook S7020", ALC260_FIXUP_FSC_S7020),
Takashi Iwaib1f58082012-02-16 12:45:03 +01001794 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FIXUP_GPIO1),
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001795 SND_PCI_QUIRK(0x152d, 0x0729, "Quanta KN1", ALC260_FIXUP_KN1),
Takashi Iwai20f7d922012-02-16 12:35:16 +01001796 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_FIXUP_REPLACER),
Takashi Iwaica8f0422012-02-16 11:51:19 +01001797 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_FIXUP_COEF),
Takashi Iwai1d045db2011-07-07 18:23:21 +02001798 {}
1799};
1800
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001801static const struct hda_model_fixup alc260_fixup_models[] = {
1802 {.id = ALC260_FIXUP_GPIO1, .name = "gpio1"},
1803 {.id = ALC260_FIXUP_COEF, .name = "coef"},
1804 {.id = ALC260_FIXUP_FSC_S7020, .name = "fujitsu"},
1805 {.id = ALC260_FIXUP_FSC_S7020_JWSE, .name = "fujitsu-jwse"},
1806 {}
1807};
1808
Takashi Iwai1d045db2011-07-07 18:23:21 +02001809/*
1810 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02001811static int patch_alc260(struct hda_codec *codec)
1812{
1813 struct alc_spec *spec;
Takashi Iwaic3c2c9e2012-02-16 12:59:55 +01001814 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001815
Takashi Iwai3de95172012-05-07 18:03:15 +02001816 err = alc_alloc_spec(codec, 0x07);
1817 if (err < 0)
1818 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001819
Takashi Iwai3de95172012-05-07 18:03:15 +02001820 spec = codec->spec;
Takashi Iwaiea46c3c2013-01-15 18:45:53 +01001821 /* as quite a few machines require HP amp for speaker outputs,
1822 * it's easier to enable it unconditionally; even if it's unneeded,
1823 * it's almost harmless.
1824 */
1825 spec->gen.prefer_hp_amp = 1;
Takashi Iwai7504b6c2013-03-18 11:25:51 +01001826 spec->gen.beep_nid = 0x01;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001827
Takashi Iwai225068a2015-05-29 10:42:14 +02001828 spec->shutup = alc_eapd_shutup;
1829
Takashi Iwaic9af7532019-05-10 11:01:43 +02001830 alc_pre_init(codec);
1831
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001832 snd_hda_pick_fixup(codec, alc260_fixup_models, alc260_fixup_tbl,
1833 alc260_fixups);
Takashi Iwai1727a772013-01-10 09:52:52 +01001834 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02001835
Takashi Iwaic3c2c9e2012-02-16 12:59:55 +01001836 /* automatic parse from the BIOS config */
1837 err = alc260_parse_auto_config(codec);
1838 if (err < 0)
1839 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001840
Takashi Iwaifea80fa2018-06-20 12:52:46 +02001841 if (!spec->gen.no_analog) {
1842 err = set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
1843 if (err < 0)
1844 goto error;
1845 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02001846
Takashi Iwai1727a772013-01-10 09:52:52 +01001847 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01001848
Takashi Iwai1d045db2011-07-07 18:23:21 +02001849 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02001850
1851 error:
1852 alc_free(codec);
1853 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001854}
1855
1856
1857/*
1858 * ALC882/883/885/888/889 support
1859 *
1860 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
1861 * configuration. Each pin widget can choose any input DACs and a mixer.
1862 * Each ADC is connected from a mixer of all inputs. This makes possible
1863 * 6-channel independent captures.
1864 *
1865 * In addition, an independent DAC for the multi-playback (not used in this
1866 * driver yet).
1867 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02001868
1869/*
1870 * Pin config fixes
1871 */
1872enum {
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01001873 ALC882_FIXUP_ABIT_AW9D_MAX,
1874 ALC882_FIXUP_LENOVO_Y530,
1875 ALC882_FIXUP_PB_M5210,
1876 ALC882_FIXUP_ACER_ASPIRE_7736,
1877 ALC882_FIXUP_ASUS_W90V,
Marton Balint8f239212012-03-05 21:33:23 +01001878 ALC889_FIXUP_CD,
David Henningssonb2c53e22014-01-01 14:01:34 +01001879 ALC889_FIXUP_FRONT_HP_NO_PRESENCE,
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01001880 ALC889_FIXUP_VAIO_TT,
Takashi Iwai0e7cc2e2011-11-09 12:42:48 +01001881 ALC888_FIXUP_EEE1601,
Takashi Iwai177943a32011-11-09 12:55:18 +01001882 ALC882_FIXUP_EAPD,
Takashi Iwai7a6069b2011-11-09 15:22:01 +01001883 ALC883_FIXUP_EAPD,
Takashi Iwai8812c4f2011-11-09 17:39:15 +01001884 ALC883_FIXUP_ACER_EAPD,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001885 ALC882_FIXUP_GPIO1,
1886 ALC882_FIXUP_GPIO2,
Takashi Iwaieb844d52011-11-09 18:03:07 +01001887 ALC882_FIXUP_GPIO3,
Takashi Iwai68ef0562011-11-09 18:24:44 +01001888 ALC889_FIXUP_COEF,
1889 ALC882_FIXUP_ASUS_W2JC,
Takashi Iwaic3e837b2011-11-10 16:01:47 +01001890 ALC882_FIXUP_ACER_ASPIRE_4930G,
1891 ALC882_FIXUP_ACER_ASPIRE_8930G,
1892 ALC882_FIXUP_ASPIRE_8930G_VERBS,
Takashi Iwai56710872011-11-14 17:42:11 +01001893 ALC885_FIXUP_MACPRO_GPIO,
Takashi Iwai02a237b2012-02-13 15:25:07 +01001894 ALC889_FIXUP_DAC_ROUTE,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001895 ALC889_FIXUP_MBP_VREF,
1896 ALC889_FIXUP_IMAC91_VREF,
Adrien Vergée7729a42014-01-24 14:56:14 -05001897 ALC889_FIXUP_MBA11_VREF,
Takashi Iwai0756f092013-12-04 13:59:45 +01001898 ALC889_FIXUP_MBA21_VREF,
Takashi Iwaic20f31e2014-02-03 11:02:10 +01001899 ALC889_FIXUP_MP11_VREF,
Mario Kleiner9f660a12015-12-22 00:45:43 +01001900 ALC889_FIXUP_MP41_VREF,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02001901 ALC882_FIXUP_INV_DMIC,
Takashi Iwaie427c232012-07-29 10:04:08 +02001902 ALC882_FIXUP_NO_PRIMARY_HP,
Takashi Iwai1f0bbf02013-11-28 15:21:21 +01001903 ALC887_FIXUP_ASUS_BASS,
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01001904 ALC887_FIXUP_BASS_CHMAP,
Takashi Iwai7beb3a62017-04-10 18:05:52 +02001905 ALC1220_FIXUP_GB_DUAL_CODECS,
Peisen0202f5c2017-10-26 10:35:36 +08001906 ALC1220_FIXUP_CLEVO_P950,
Richard Sailer80690a22019-04-02 15:52:04 +02001907 ALC1220_FIXUP_CLEVO_PB51ED,
1908 ALC1220_FIXUP_CLEVO_PB51ED_PINS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02001909};
1910
Takashi Iwai68ef0562011-11-09 18:24:44 +01001911static void alc889_fixup_coef(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001912 const struct hda_fixup *fix, int action)
Takashi Iwai68ef0562011-11-09 18:24:44 +01001913{
Takashi Iwai1727a772013-01-10 09:52:52 +01001914 if (action != HDA_FIXUP_ACT_INIT)
Takashi Iwai68ef0562011-11-09 18:24:44 +01001915 return;
Kailang Yang1df88742014-10-29 16:10:13 +08001916 alc_update_coef_idx(codec, 7, 0, 0x2030);
Takashi Iwai68ef0562011-11-09 18:24:44 +01001917}
1918
Takashi Iwai56710872011-11-14 17:42:11 +01001919/* set up GPIO at initialization */
1920static void alc885_fixup_macpro_gpio(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001921 const struct hda_fixup *fix, int action)
Takashi Iwai56710872011-11-14 17:42:11 +01001922{
Takashi Iwai215c8502018-06-19 22:34:26 +02001923 struct alc_spec *spec = codec->spec;
1924
1925 spec->gpio_write_delay = true;
1926 alc_fixup_gpio3(codec, fix, action);
Takashi Iwai56710872011-11-14 17:42:11 +01001927}
1928
Takashi Iwai02a237b2012-02-13 15:25:07 +01001929/* Fix the connection of some pins for ALC889:
1930 * At least, Acer Aspire 5935 shows the connections to DAC3/4 don't
1931 * work correctly (bko#42740)
1932 */
1933static void alc889_fixup_dac_route(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001934 const struct hda_fixup *fix, int action)
Takashi Iwai02a237b2012-02-13 15:25:07 +01001935{
Takashi Iwai1727a772013-01-10 09:52:52 +01001936 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwaief8d60f2012-02-17 10:12:38 +01001937 /* fake the connections during parsing the tree */
Michał Mirosławcaf3c042020-01-03 10:23:48 +01001938 static const hda_nid_t conn1[] = { 0x0c, 0x0d };
1939 static const hda_nid_t conn2[] = { 0x0e, 0x0f };
1940 snd_hda_override_conn_list(codec, 0x14, ARRAY_SIZE(conn1), conn1);
1941 snd_hda_override_conn_list(codec, 0x15, ARRAY_SIZE(conn1), conn1);
1942 snd_hda_override_conn_list(codec, 0x18, ARRAY_SIZE(conn2), conn2);
1943 snd_hda_override_conn_list(codec, 0x1a, ARRAY_SIZE(conn2), conn2);
Takashi Iwai1727a772013-01-10 09:52:52 +01001944 } else if (action == HDA_FIXUP_ACT_PROBE) {
Takashi Iwaief8d60f2012-02-17 10:12:38 +01001945 /* restore the connections */
Michał Mirosławcaf3c042020-01-03 10:23:48 +01001946 static const hda_nid_t conn[] = { 0x0c, 0x0d, 0x0e, 0x0f, 0x26 };
1947 snd_hda_override_conn_list(codec, 0x14, ARRAY_SIZE(conn), conn);
1948 snd_hda_override_conn_list(codec, 0x15, ARRAY_SIZE(conn), conn);
1949 snd_hda_override_conn_list(codec, 0x18, ARRAY_SIZE(conn), conn);
1950 snd_hda_override_conn_list(codec, 0x1a, ARRAY_SIZE(conn), conn);
Takashi Iwai02a237b2012-02-13 15:25:07 +01001951 }
1952}
1953
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001954/* Set VREF on HP pin */
1955static void alc889_fixup_mbp_vref(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001956 const struct hda_fixup *fix, int action)
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001957{
Michał Mirosławcaf3c042020-01-03 10:23:48 +01001958 static const hda_nid_t nids[] = { 0x14, 0x15, 0x19 };
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001959 struct alc_spec *spec = codec->spec;
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001960 int i;
1961
Takashi Iwai1727a772013-01-10 09:52:52 +01001962 if (action != HDA_FIXUP_ACT_INIT)
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001963 return;
1964 for (i = 0; i < ARRAY_SIZE(nids); i++) {
1965 unsigned int val = snd_hda_codec_get_pincfg(codec, nids[i]);
1966 if (get_defcfg_device(val) != AC_JACK_HP_OUT)
1967 continue;
Takashi Iwaid3f02d62013-01-10 10:12:22 +01001968 val = snd_hda_codec_get_pin_target(codec, nids[i]);
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001969 val |= AC_PINCTL_VREF_80;
Takashi Iwaicdd03ce2012-04-20 12:34:50 +02001970 snd_hda_set_pin_ctl(codec, nids[i], val);
Takashi Iwai08c189f2012-12-19 15:22:24 +01001971 spec->gen.keep_vref_in_automute = 1;
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001972 break;
1973 }
1974}
1975
Takashi Iwai0756f092013-12-04 13:59:45 +01001976static void alc889_fixup_mac_pins(struct hda_codec *codec,
1977 const hda_nid_t *nids, int num_nids)
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001978{
1979 struct alc_spec *spec = codec->spec;
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001980 int i;
1981
Takashi Iwai0756f092013-12-04 13:59:45 +01001982 for (i = 0; i < num_nids; i++) {
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001983 unsigned int val;
Takashi Iwaid3f02d62013-01-10 10:12:22 +01001984 val = snd_hda_codec_get_pin_target(codec, nids[i]);
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001985 val |= AC_PINCTL_VREF_50;
Takashi Iwaicdd03ce2012-04-20 12:34:50 +02001986 snd_hda_set_pin_ctl(codec, nids[i], val);
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001987 }
Takashi Iwai08c189f2012-12-19 15:22:24 +01001988 spec->gen.keep_vref_in_automute = 1;
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001989}
1990
Takashi Iwai0756f092013-12-04 13:59:45 +01001991/* Set VREF on speaker pins on imac91 */
1992static void alc889_fixup_imac91_vref(struct hda_codec *codec,
1993 const struct hda_fixup *fix, int action)
1994{
Michał Mirosławcaf3c042020-01-03 10:23:48 +01001995 static const hda_nid_t nids[] = { 0x18, 0x1a };
Takashi Iwai0756f092013-12-04 13:59:45 +01001996
1997 if (action == HDA_FIXUP_ACT_INIT)
1998 alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
1999}
2000
Adrien Vergée7729a42014-01-24 14:56:14 -05002001/* Set VREF on speaker pins on mba11 */
2002static void alc889_fixup_mba11_vref(struct hda_codec *codec,
2003 const struct hda_fixup *fix, int action)
2004{
Michał Mirosławcaf3c042020-01-03 10:23:48 +01002005 static const hda_nid_t nids[] = { 0x18 };
Adrien Vergée7729a42014-01-24 14:56:14 -05002006
2007 if (action == HDA_FIXUP_ACT_INIT)
2008 alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
2009}
2010
Takashi Iwai0756f092013-12-04 13:59:45 +01002011/* Set VREF on speaker pins on mba21 */
2012static void alc889_fixup_mba21_vref(struct hda_codec *codec,
2013 const struct hda_fixup *fix, int action)
2014{
Michał Mirosławcaf3c042020-01-03 10:23:48 +01002015 static const hda_nid_t nids[] = { 0x18, 0x19 };
Takashi Iwai0756f092013-12-04 13:59:45 +01002016
2017 if (action == HDA_FIXUP_ACT_INIT)
2018 alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
2019}
2020
Takashi Iwaie427c232012-07-29 10:04:08 +02002021/* Don't take HP output as primary
Fernando Luis Vázquez Caod9111492013-02-12 16:49:46 +09002022 * Strangely, the speaker output doesn't work on Vaio Z and some Vaio
2023 * all-in-one desktop PCs (for example VGC-LN51JGB) through DAC 0x05
Takashi Iwaie427c232012-07-29 10:04:08 +02002024 */
2025static void alc882_fixup_no_primary_hp(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01002026 const struct hda_fixup *fix, int action)
Takashi Iwaie427c232012-07-29 10:04:08 +02002027{
2028 struct alc_spec *spec = codec->spec;
Takashi Iwaida96fb52013-07-29 16:54:36 +02002029 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai08c189f2012-12-19 15:22:24 +01002030 spec->gen.no_primary_hp = 1;
Takashi Iwaida96fb52013-07-29 16:54:36 +02002031 spec->gen.no_multi_io = 1;
2032 }
Takashi Iwaie427c232012-07-29 10:04:08 +02002033}
2034
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01002035static void alc_fixup_bass_chmap(struct hda_codec *codec,
2036 const struct hda_fixup *fix, int action);
2037
Takashi Iwai7beb3a62017-04-10 18:05:52 +02002038/* For dual-codec configuration, we need to disable some features to avoid
2039 * conflicts of kctls and PCM streams
2040 */
2041static void alc_fixup_dual_codecs(struct hda_codec *codec,
2042 const struct hda_fixup *fix, int action)
2043{
2044 struct alc_spec *spec = codec->spec;
2045
2046 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2047 return;
2048 /* disable vmaster */
2049 spec->gen.suppress_vmaster = 1;
2050 /* auto-mute and auto-mic switch don't work with multiple codecs */
2051 spec->gen.suppress_auto_mute = 1;
2052 spec->gen.suppress_auto_mic = 1;
2053 /* disable aamix as well */
2054 spec->gen.mixer_nid = 0;
2055 /* add location prefix to avoid conflicts */
2056 codec->force_pin_prefix = 1;
2057}
2058
2059static void rename_ctl(struct hda_codec *codec, const char *oldname,
2060 const char *newname)
2061{
2062 struct snd_kcontrol *kctl;
2063
2064 kctl = snd_hda_find_mixer_ctl(codec, oldname);
2065 if (kctl)
2066 strcpy(kctl->id.name, newname);
2067}
2068
2069static void alc1220_fixup_gb_dual_codecs(struct hda_codec *codec,
2070 const struct hda_fixup *fix,
2071 int action)
2072{
2073 alc_fixup_dual_codecs(codec, fix, action);
2074 switch (action) {
2075 case HDA_FIXUP_ACT_PRE_PROBE:
2076 /* override card longname to provide a unique UCM profile */
2077 strcpy(codec->card->longname, "HDAudio-Gigabyte-ALC1220DualCodecs");
2078 break;
2079 case HDA_FIXUP_ACT_BUILD:
2080 /* rename Capture controls depending on the codec */
2081 rename_ctl(codec, "Capture Volume",
2082 codec->addr == 0 ?
2083 "Rear-Panel Capture Volume" :
2084 "Front-Panel Capture Volume");
2085 rename_ctl(codec, "Capture Switch",
2086 codec->addr == 0 ?
2087 "Rear-Panel Capture Switch" :
2088 "Front-Panel Capture Switch");
2089 break;
2090 }
2091}
2092
Peisen0202f5c2017-10-26 10:35:36 +08002093static void alc1220_fixup_clevo_p950(struct hda_codec *codec,
2094 const struct hda_fixup *fix,
2095 int action)
2096{
Michał Mirosławcaf3c042020-01-03 10:23:48 +01002097 static const hda_nid_t conn1[] = { 0x0c };
Peisen0202f5c2017-10-26 10:35:36 +08002098
2099 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2100 return;
2101
2102 alc_update_coef_idx(codec, 0x7, 0, 0x3c3);
2103 /* We therefore want to make sure 0x14 (front headphone) and
2104 * 0x1b (speakers) use the stereo DAC 0x02
2105 */
Michał Mirosławcaf3c042020-01-03 10:23:48 +01002106 snd_hda_override_conn_list(codec, 0x14, ARRAY_SIZE(conn1), conn1);
2107 snd_hda_override_conn_list(codec, 0x1b, ARRAY_SIZE(conn1), conn1);
Peisen0202f5c2017-10-26 10:35:36 +08002108}
2109
Jeremy Soller7f665b12019-02-13 10:56:19 -07002110static void alc_fixup_headset_mode_no_hp_mic(struct hda_codec *codec,
2111 const struct hda_fixup *fix, int action);
2112
Richard Sailer80690a22019-04-02 15:52:04 +02002113static void alc1220_fixup_clevo_pb51ed(struct hda_codec *codec,
Jeremy Soller7f665b12019-02-13 10:56:19 -07002114 const struct hda_fixup *fix,
2115 int action)
2116{
2117 alc1220_fixup_clevo_p950(codec, fix, action);
2118 alc_fixup_headset_mode_no_hp_mic(codec, fix, action);
2119}
2120
Takashi Iwai1727a772013-01-10 09:52:52 +01002121static const struct hda_fixup alc882_fixups[] = {
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002122 [ALC882_FIXUP_ABIT_AW9D_MAX] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002123 .type = HDA_FIXUP_PINS,
2124 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002125 { 0x15, 0x01080104 }, /* side */
2126 { 0x16, 0x01011012 }, /* rear */
2127 { 0x17, 0x01016011 }, /* clfe */
2128 { }
2129 }
2130 },
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002131 [ALC882_FIXUP_LENOVO_Y530] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002132 .type = HDA_FIXUP_PINS,
2133 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002134 { 0x15, 0x99130112 }, /* rear int speakers */
2135 { 0x16, 0x99130111 }, /* subwoofer */
2136 { }
2137 }
2138 },
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002139 [ALC882_FIXUP_PB_M5210] = {
Takashi Iwaifd108212013-01-10 10:18:14 +01002140 .type = HDA_FIXUP_PINCTLS,
2141 .v.pins = (const struct hda_pintbl[]) {
2142 { 0x19, PIN_VREF50 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02002143 {}
2144 }
2145 },
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002146 [ALC882_FIXUP_ACER_ASPIRE_7736] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002147 .type = HDA_FIXUP_FUNC,
Takashi Iwai23d30f22012-05-07 17:17:32 +02002148 .v.func = alc_fixup_sku_ignore,
Takashi Iwai1d045db2011-07-07 18:23:21 +02002149 },
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002150 [ALC882_FIXUP_ASUS_W90V] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002151 .type = HDA_FIXUP_PINS,
2152 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai5cdf7452011-10-26 23:04:08 +02002153 { 0x16, 0x99130110 }, /* fix sequence for CLFE */
2154 { }
2155 }
2156 },
Marton Balint8f239212012-03-05 21:33:23 +01002157 [ALC889_FIXUP_CD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002158 .type = HDA_FIXUP_PINS,
2159 .v.pins = (const struct hda_pintbl[]) {
Marton Balint8f239212012-03-05 21:33:23 +01002160 { 0x1c, 0x993301f0 }, /* CD */
2161 { }
2162 }
2163 },
David Henningssonb2c53e22014-01-01 14:01:34 +01002164 [ALC889_FIXUP_FRONT_HP_NO_PRESENCE] = {
2165 .type = HDA_FIXUP_PINS,
2166 .v.pins = (const struct hda_pintbl[]) {
2167 { 0x1b, 0x02214120 }, /* Front HP jack is flaky, disable jack detect */
2168 { }
2169 },
2170 .chained = true,
2171 .chain_id = ALC889_FIXUP_CD,
2172 },
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002173 [ALC889_FIXUP_VAIO_TT] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002174 .type = HDA_FIXUP_PINS,
2175 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002176 { 0x17, 0x90170111 }, /* hidden surround speaker */
2177 { }
2178 }
2179 },
Takashi Iwai0e7cc2e2011-11-09 12:42:48 +01002180 [ALC888_FIXUP_EEE1601] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002181 .type = HDA_FIXUP_VERBS,
Takashi Iwai0e7cc2e2011-11-09 12:42:48 +01002182 .v.verbs = (const struct hda_verb[]) {
2183 { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b },
2184 { 0x20, AC_VERB_SET_PROC_COEF, 0x0838 },
2185 { }
2186 }
Takashi Iwai177943a32011-11-09 12:55:18 +01002187 },
2188 [ALC882_FIXUP_EAPD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002189 .type = HDA_FIXUP_VERBS,
Takashi Iwai177943a32011-11-09 12:55:18 +01002190 .v.verbs = (const struct hda_verb[]) {
2191 /* change to EAPD mode */
2192 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2193 { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
2194 { }
2195 }
2196 },
Takashi Iwai7a6069b2011-11-09 15:22:01 +01002197 [ALC883_FIXUP_EAPD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002198 .type = HDA_FIXUP_VERBS,
Takashi Iwai7a6069b2011-11-09 15:22:01 +01002199 .v.verbs = (const struct hda_verb[]) {
2200 /* change to EAPD mode */
2201 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2202 { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
2203 { }
2204 }
2205 },
Takashi Iwai8812c4f2011-11-09 17:39:15 +01002206 [ALC883_FIXUP_ACER_EAPD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002207 .type = HDA_FIXUP_VERBS,
Takashi Iwai8812c4f2011-11-09 17:39:15 +01002208 .v.verbs = (const struct hda_verb[]) {
2209 /* eanable EAPD on Acer laptops */
2210 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2211 { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
2212 { }
2213 }
2214 },
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002215 [ALC882_FIXUP_GPIO1] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02002216 .type = HDA_FIXUP_FUNC,
2217 .v.func = alc_fixup_gpio1,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002218 },
2219 [ALC882_FIXUP_GPIO2] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02002220 .type = HDA_FIXUP_FUNC,
2221 .v.func = alc_fixup_gpio2,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002222 },
Takashi Iwaieb844d52011-11-09 18:03:07 +01002223 [ALC882_FIXUP_GPIO3] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02002224 .type = HDA_FIXUP_FUNC,
2225 .v.func = alc_fixup_gpio3,
Takashi Iwaieb844d52011-11-09 18:03:07 +01002226 },
Takashi Iwai68ef0562011-11-09 18:24:44 +01002227 [ALC882_FIXUP_ASUS_W2JC] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02002228 .type = HDA_FIXUP_FUNC,
2229 .v.func = alc_fixup_gpio1,
Takashi Iwai68ef0562011-11-09 18:24:44 +01002230 .chained = true,
2231 .chain_id = ALC882_FIXUP_EAPD,
2232 },
2233 [ALC889_FIXUP_COEF] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002234 .type = HDA_FIXUP_FUNC,
Takashi Iwai68ef0562011-11-09 18:24:44 +01002235 .v.func = alc889_fixup_coef,
2236 },
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002237 [ALC882_FIXUP_ACER_ASPIRE_4930G] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002238 .type = HDA_FIXUP_PINS,
2239 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002240 { 0x16, 0x99130111 }, /* CLFE speaker */
2241 { 0x17, 0x99130112 }, /* surround speaker */
2242 { }
Takashi Iwai038d4fe2012-04-11 17:18:12 +02002243 },
2244 .chained = true,
2245 .chain_id = ALC882_FIXUP_GPIO1,
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002246 },
2247 [ALC882_FIXUP_ACER_ASPIRE_8930G] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002248 .type = HDA_FIXUP_PINS,
2249 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002250 { 0x16, 0x99130111 }, /* CLFE speaker */
2251 { 0x1b, 0x99130112 }, /* surround speaker */
2252 { }
2253 },
2254 .chained = true,
2255 .chain_id = ALC882_FIXUP_ASPIRE_8930G_VERBS,
2256 },
2257 [ALC882_FIXUP_ASPIRE_8930G_VERBS] = {
2258 /* additional init verbs for Acer Aspire 8930G */
Takashi Iwai1727a772013-01-10 09:52:52 +01002259 .type = HDA_FIXUP_VERBS,
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002260 .v.verbs = (const struct hda_verb[]) {
2261 /* Enable all DACs */
2262 /* DAC DISABLE/MUTE 1? */
2263 /* setting bits 1-5 disables DAC nids 0x02-0x06
2264 * apparently. Init=0x38 */
2265 { 0x20, AC_VERB_SET_COEF_INDEX, 0x03 },
2266 { 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
2267 /* DAC DISABLE/MUTE 2? */
2268 /* some bit here disables the other DACs.
2269 * Init=0x4900 */
2270 { 0x20, AC_VERB_SET_COEF_INDEX, 0x08 },
2271 { 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
2272 /* DMIC fix
2273 * This laptop has a stereo digital microphone.
2274 * The mics are only 1cm apart which makes the stereo
2275 * useless. However, either the mic or the ALC889
2276 * makes the signal become a difference/sum signal
2277 * instead of standard stereo, which is annoying.
2278 * So instead we flip this bit which makes the
2279 * codec replicate the sum signal to both channels,
2280 * turning it into a normal mono mic.
2281 */
2282 /* DMIC_CONTROL? Init value = 0x0001 */
2283 { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b },
2284 { 0x20, AC_VERB_SET_PROC_COEF, 0x0003 },
2285 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2286 { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
2287 { }
Takashi Iwai038d4fe2012-04-11 17:18:12 +02002288 },
2289 .chained = true,
2290 .chain_id = ALC882_FIXUP_GPIO1,
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002291 },
Takashi Iwai56710872011-11-14 17:42:11 +01002292 [ALC885_FIXUP_MACPRO_GPIO] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002293 .type = HDA_FIXUP_FUNC,
Takashi Iwai56710872011-11-14 17:42:11 +01002294 .v.func = alc885_fixup_macpro_gpio,
2295 },
Takashi Iwai02a237b2012-02-13 15:25:07 +01002296 [ALC889_FIXUP_DAC_ROUTE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002297 .type = HDA_FIXUP_FUNC,
Takashi Iwai02a237b2012-02-13 15:25:07 +01002298 .v.func = alc889_fixup_dac_route,
2299 },
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002300 [ALC889_FIXUP_MBP_VREF] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002301 .type = HDA_FIXUP_FUNC,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002302 .v.func = alc889_fixup_mbp_vref,
2303 .chained = true,
2304 .chain_id = ALC882_FIXUP_GPIO1,
2305 },
2306 [ALC889_FIXUP_IMAC91_VREF] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002307 .type = HDA_FIXUP_FUNC,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002308 .v.func = alc889_fixup_imac91_vref,
2309 .chained = true,
2310 .chain_id = ALC882_FIXUP_GPIO1,
2311 },
Adrien Vergée7729a42014-01-24 14:56:14 -05002312 [ALC889_FIXUP_MBA11_VREF] = {
2313 .type = HDA_FIXUP_FUNC,
2314 .v.func = alc889_fixup_mba11_vref,
2315 .chained = true,
2316 .chain_id = ALC889_FIXUP_MBP_VREF,
2317 },
Takashi Iwai0756f092013-12-04 13:59:45 +01002318 [ALC889_FIXUP_MBA21_VREF] = {
2319 .type = HDA_FIXUP_FUNC,
2320 .v.func = alc889_fixup_mba21_vref,
2321 .chained = true,
2322 .chain_id = ALC889_FIXUP_MBP_VREF,
2323 },
Takashi Iwaic20f31e2014-02-03 11:02:10 +01002324 [ALC889_FIXUP_MP11_VREF] = {
2325 .type = HDA_FIXUP_FUNC,
2326 .v.func = alc889_fixup_mba11_vref,
2327 .chained = true,
2328 .chain_id = ALC885_FIXUP_MACPRO_GPIO,
2329 },
Mario Kleiner9f660a12015-12-22 00:45:43 +01002330 [ALC889_FIXUP_MP41_VREF] = {
2331 .type = HDA_FIXUP_FUNC,
2332 .v.func = alc889_fixup_mbp_vref,
2333 .chained = true,
2334 .chain_id = ALC885_FIXUP_MACPRO_GPIO,
2335 },
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002336 [ALC882_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002337 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02002338 .v.func = alc_fixup_inv_dmic,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002339 },
Takashi Iwaie427c232012-07-29 10:04:08 +02002340 [ALC882_FIXUP_NO_PRIMARY_HP] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002341 .type = HDA_FIXUP_FUNC,
Takashi Iwaie427c232012-07-29 10:04:08 +02002342 .v.func = alc882_fixup_no_primary_hp,
2343 },
Takashi Iwai1f0bbf02013-11-28 15:21:21 +01002344 [ALC887_FIXUP_ASUS_BASS] = {
2345 .type = HDA_FIXUP_PINS,
2346 .v.pins = (const struct hda_pintbl[]) {
2347 {0x16, 0x99130130}, /* bass speaker */
2348 {}
2349 },
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01002350 .chained = true,
2351 .chain_id = ALC887_FIXUP_BASS_CHMAP,
2352 },
2353 [ALC887_FIXUP_BASS_CHMAP] = {
2354 .type = HDA_FIXUP_FUNC,
2355 .v.func = alc_fixup_bass_chmap,
Takashi Iwai1f0bbf02013-11-28 15:21:21 +01002356 },
Takashi Iwai7beb3a62017-04-10 18:05:52 +02002357 [ALC1220_FIXUP_GB_DUAL_CODECS] = {
2358 .type = HDA_FIXUP_FUNC,
2359 .v.func = alc1220_fixup_gb_dual_codecs,
2360 },
Peisen0202f5c2017-10-26 10:35:36 +08002361 [ALC1220_FIXUP_CLEVO_P950] = {
2362 .type = HDA_FIXUP_FUNC,
2363 .v.func = alc1220_fixup_clevo_p950,
2364 },
Richard Sailer80690a22019-04-02 15:52:04 +02002365 [ALC1220_FIXUP_CLEVO_PB51ED] = {
Jeremy Soller7f665b12019-02-13 10:56:19 -07002366 .type = HDA_FIXUP_FUNC,
Richard Sailer80690a22019-04-02 15:52:04 +02002367 .v.func = alc1220_fixup_clevo_pb51ed,
Jeremy Soller7f665b12019-02-13 10:56:19 -07002368 },
Richard Sailer80690a22019-04-02 15:52:04 +02002369 [ALC1220_FIXUP_CLEVO_PB51ED_PINS] = {
Jeremy Soller7f665b12019-02-13 10:56:19 -07002370 .type = HDA_FIXUP_PINS,
2371 .v.pins = (const struct hda_pintbl[]) {
2372 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
2373 {}
2374 },
2375 .chained = true,
Richard Sailer80690a22019-04-02 15:52:04 +02002376 .chain_id = ALC1220_FIXUP_CLEVO_PB51ED,
Jeremy Soller7f665b12019-02-13 10:56:19 -07002377 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02002378};
2379
2380static const struct snd_pci_quirk alc882_fixup_tbl[] = {
Takashi Iwai8812c4f2011-11-09 17:39:15 +01002381 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_FIXUP_ACER_EAPD),
2382 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
Takashi Iwaib5d724b2015-06-02 19:57:08 +02002383 SND_PCI_QUIRK(0x1025, 0x0107, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
Takashi Iwai8812c4f2011-11-09 17:39:15 +01002384 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_FIXUP_ACER_EAPD),
2385 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
2386 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_FIXUP_ACER_EAPD),
2387 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_FIXUP_ACER_EAPD),
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002388 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
2389 ALC882_FIXUP_ACER_ASPIRE_4930G),
2390 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
2391 ALC882_FIXUP_ACER_ASPIRE_4930G),
2392 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
2393 ALC882_FIXUP_ACER_ASPIRE_8930G),
2394 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
2395 ALC882_FIXUP_ACER_ASPIRE_8930G),
2396 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
2397 ALC882_FIXUP_ACER_ASPIRE_4930G),
2398 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
2399 ALC882_FIXUP_ACER_ASPIRE_4930G),
2400 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
2401 ALC882_FIXUP_ACER_ASPIRE_4930G),
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002402 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", ALC882_FIXUP_PB_M5210),
Takashi Iwaif5c53d82012-05-07 10:07:33 +02002403 SND_PCI_QUIRK(0x1025, 0x021e, "Acer Aspire 5739G",
2404 ALC882_FIXUP_ACER_ASPIRE_4930G),
Takashi Iwai02a237b2012-02-13 15:25:07 +01002405 SND_PCI_QUIRK(0x1025, 0x0259, "Acer Aspire 5935", ALC889_FIXUP_DAC_ROUTE),
Takashi Iwaife97da12012-04-12 08:00:19 +02002406 SND_PCI_QUIRK(0x1025, 0x026b, "Acer Aspire 8940G", ALC882_FIXUP_ACER_ASPIRE_8930G),
Takashi Iwaiac9b1cd2011-11-09 17:45:55 +01002407 SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", ALC882_FIXUP_ACER_ASPIRE_7736),
Takashi Iwai177943a32011-11-09 12:55:18 +01002408 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_FIXUP_EAPD),
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002409 SND_PCI_QUIRK(0x1043, 0x1873, "ASUS W90V", ALC882_FIXUP_ASUS_W90V),
Takashi Iwai68ef0562011-11-09 18:24:44 +01002410 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_FIXUP_ASUS_W2JC),
Takashi Iwai0e7cc2e2011-11-09 12:42:48 +01002411 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_FIXUP_EEE1601),
Takashi Iwai1f0bbf02013-11-28 15:21:21 +01002412 SND_PCI_QUIRK(0x1043, 0x84bc, "ASUS ET2700", ALC887_FIXUP_ASUS_BASS),
Takashi Iwai85bcf962016-12-06 16:20:36 +01002413 SND_PCI_QUIRK(0x1043, 0x8691, "ASUS ROG Ranger VIII", ALC882_FIXUP_GPIO3),
Takashi Iwaiac9b1cd2011-11-09 17:45:55 +01002414 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT),
Takashi Iwaie427c232012-07-29 10:04:08 +02002415 SND_PCI_QUIRK(0x104d, 0x905a, "Sony Vaio Z", ALC882_FIXUP_NO_PRIMARY_HP),
Sergei A. Trusov3f3c3712017-08-02 20:23:48 +10002416 SND_PCI_QUIRK(0x104d, 0x9060, "Sony Vaio VPCL14M1R", ALC882_FIXUP_NO_PRIMARY_HP),
Fernando Luis Vázquez Cao12e31a72013-02-12 16:47:44 +09002417 SND_PCI_QUIRK(0x104d, 0x9043, "Sony Vaio VGC-LN51JGB", ALC882_FIXUP_NO_PRIMARY_HP),
Takashi Iwaic44d9b12016-02-07 09:38:26 +01002418 SND_PCI_QUIRK(0x104d, 0x9044, "Sony VAIO AiO", ALC882_FIXUP_NO_PRIMARY_HP),
Takashi Iwai56710872011-11-14 17:42:11 +01002419
2420 /* All Apple entries are in codec SSIDs */
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002421 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC889_FIXUP_MBP_VREF),
2422 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC889_FIXUP_MBP_VREF),
2423 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF),
Takashi Iwaic20f31e2014-02-03 11:02:10 +01002424 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC889_FIXUP_MP11_VREF),
Takashi Iwai56710872011-11-14 17:42:11 +01002425 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_FIXUP_MACPRO_GPIO),
2426 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_FIXUP_MACPRO_GPIO),
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002427 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC889_FIXUP_MBP_VREF),
2428 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889_FIXUP_MBP_VREF),
Takashi Iwai56710872011-11-14 17:42:11 +01002429 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_FIXUP_EAPD),
Adrien Vergée7729a42014-01-24 14:56:14 -05002430 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC889_FIXUP_MBA11_VREF),
Takashi Iwai0756f092013-12-04 13:59:45 +01002431 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC889_FIXUP_MBA21_VREF),
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002432 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889_FIXUP_MBP_VREF),
2433 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF),
Takashi Iwai56710872011-11-14 17:42:11 +01002434 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_FIXUP_MACPRO_GPIO),
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002435 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC889_FIXUP_IMAC91_VREF),
2436 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC889_FIXUP_IMAC91_VREF),
2437 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC889_FIXUP_IMAC91_VREF),
Mario Kleiner9f660a12015-12-22 00:45:43 +01002438 SND_PCI_QUIRK(0x106b, 0x4200, "Mac Pro 4,1/5,1", ALC889_FIXUP_MP41_VREF),
Takashi Iwai05193632012-11-12 10:07:36 +01002439 SND_PCI_QUIRK(0x106b, 0x4300, "iMac 9,1", ALC889_FIXUP_IMAC91_VREF),
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002440 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC889_FIXUP_IMAC91_VREF),
2441 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC889_FIXUP_IMAC91_VREF),
Takashi Iwai649ccd02015-07-30 22:30:29 +02002442 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC889_FIXUP_MBA11_VREF),
Takashi Iwai56710872011-11-14 17:42:11 +01002443
Takashi Iwai7a6069b2011-11-09 15:22:01 +01002444 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC882_FIXUP_EAPD),
David Henningssonb2c53e22014-01-01 14:01:34 +01002445 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3/Z87X-UD3H", ALC889_FIXUP_FRONT_HP_NO_PRESENCE),
Takashi Iwai7beb3a62017-04-10 18:05:52 +02002446 SND_PCI_QUIRK(0x1458, 0xa0b8, "Gigabyte AZ370-Gaming", ALC1220_FIXUP_GB_DUAL_CODECS),
Takashi Iwaid2c3b142017-06-01 09:35:30 +02002447 SND_PCI_QUIRK(0x1462, 0x7350, "MSI-7350", ALC889_FIXUP_CD),
Takashi Iwai63691582017-05-22 16:32:46 +02002448 SND_PCI_QUIRK(0x1462, 0xda57, "MSI Z270-Gaming", ALC1220_FIXUP_GB_DUAL_CODECS),
Takashi Iwaid2c3b142017-06-01 09:35:30 +02002449 SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3),
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002450 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX),
Peisen0202f5c2017-10-26 10:35:36 +08002451 SND_PCI_QUIRK(0x1558, 0x9501, "Clevo P950HR", ALC1220_FIXUP_CLEVO_P950),
Takashi Iwaif3d737b2018-07-17 17:08:32 +02002452 SND_PCI_QUIRK(0x1558, 0x95e1, "Clevo P95xER", ALC1220_FIXUP_CLEVO_P950),
Jeremy Soller2f0d5202018-05-07 09:28:45 -06002453 SND_PCI_QUIRK(0x1558, 0x95e2, "Clevo P950ER", ALC1220_FIXUP_CLEVO_P950),
Richard Sailer503d90b2019-06-19 13:33:11 +02002454 SND_PCI_QUIRK(0x1558, 0x96e1, "Clevo P960[ER][CDFN]-K", ALC1220_FIXUP_CLEVO_P950),
2455 SND_PCI_QUIRK(0x1558, 0x97e1, "Clevo P970[ER][CDFN]", ALC1220_FIXUP_CLEVO_P950),
2456 SND_PCI_QUIRK(0x1558, 0x65d1, "Clevo PB51[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
2457 SND_PCI_QUIRK(0x1558, 0x67d1, "Clevo PB71[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
Takashi Iwai7a6069b2011-11-09 15:22:01 +01002458 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD),
2459 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD),
Takashi Iwaiac9b1cd2011-11-09 17:45:55 +01002460 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", ALC882_FIXUP_LENOVO_Y530),
Takashi Iwai68ef0562011-11-09 18:24:44 +01002461 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_FIXUP_COEF),
Takashi Iwai1d045db2011-07-07 18:23:21 +02002462 {}
2463};
2464
Takashi Iwai1727a772013-01-10 09:52:52 +01002465static const struct hda_model_fixup alc882_fixup_models[] = {
Takashi Iwai772c2912018-06-26 17:17:53 +02002466 {.id = ALC882_FIXUP_ABIT_AW9D_MAX, .name = "abit-aw9d"},
2467 {.id = ALC882_FIXUP_LENOVO_Y530, .name = "lenovo-y530"},
2468 {.id = ALC882_FIXUP_ACER_ASPIRE_7736, .name = "acer-aspire-7736"},
2469 {.id = ALC882_FIXUP_ASUS_W90V, .name = "asus-w90v"},
2470 {.id = ALC889_FIXUP_CD, .name = "cd"},
2471 {.id = ALC889_FIXUP_FRONT_HP_NO_PRESENCE, .name = "no-front-hp"},
2472 {.id = ALC889_FIXUP_VAIO_TT, .name = "vaio-tt"},
2473 {.id = ALC888_FIXUP_EEE1601, .name = "eee1601"},
2474 {.id = ALC882_FIXUP_EAPD, .name = "alc882-eapd"},
2475 {.id = ALC883_FIXUP_EAPD, .name = "alc883-eapd"},
2476 {.id = ALC882_FIXUP_GPIO1, .name = "gpio1"},
2477 {.id = ALC882_FIXUP_GPIO2, .name = "gpio2"},
2478 {.id = ALC882_FIXUP_GPIO3, .name = "gpio3"},
2479 {.id = ALC889_FIXUP_COEF, .name = "alc889-coef"},
2480 {.id = ALC882_FIXUP_ASUS_W2JC, .name = "asus-w2jc"},
Takashi Iwai912093b2012-04-11 14:03:41 +02002481 {.id = ALC882_FIXUP_ACER_ASPIRE_4930G, .name = "acer-aspire-4930g"},
2482 {.id = ALC882_FIXUP_ACER_ASPIRE_8930G, .name = "acer-aspire-8930g"},
2483 {.id = ALC883_FIXUP_ACER_EAPD, .name = "acer-aspire"},
Takashi Iwai772c2912018-06-26 17:17:53 +02002484 {.id = ALC885_FIXUP_MACPRO_GPIO, .name = "macpro-gpio"},
2485 {.id = ALC889_FIXUP_DAC_ROUTE, .name = "dac-route"},
2486 {.id = ALC889_FIXUP_MBP_VREF, .name = "mbp-vref"},
2487 {.id = ALC889_FIXUP_IMAC91_VREF, .name = "imac91-vref"},
2488 {.id = ALC889_FIXUP_MBA11_VREF, .name = "mba11-vref"},
2489 {.id = ALC889_FIXUP_MBA21_VREF, .name = "mba21-vref"},
2490 {.id = ALC889_FIXUP_MP11_VREF, .name = "mp11-vref"},
2491 {.id = ALC889_FIXUP_MP41_VREF, .name = "mp41-vref"},
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002492 {.id = ALC882_FIXUP_INV_DMIC, .name = "inv-dmic"},
Takashi Iwaie427c232012-07-29 10:04:08 +02002493 {.id = ALC882_FIXUP_NO_PRIMARY_HP, .name = "no-primary-hp"},
Takashi Iwai772c2912018-06-26 17:17:53 +02002494 {.id = ALC887_FIXUP_ASUS_BASS, .name = "asus-bass"},
Takashi Iwaiba90d6a2017-05-22 16:38:47 +02002495 {.id = ALC1220_FIXUP_GB_DUAL_CODECS, .name = "dual-codecs"},
Takashi Iwai772c2912018-06-26 17:17:53 +02002496 {.id = ALC1220_FIXUP_CLEVO_P950, .name = "clevo-p950"},
Takashi Iwai912093b2012-04-11 14:03:41 +02002497 {}
2498};
2499
Takashi Iwai1d045db2011-07-07 18:23:21 +02002500/*
2501 * BIOS auto configuration
2502 */
2503/* almost identical with ALC880 parser... */
2504static int alc882_parse_auto_config(struct hda_codec *codec)
2505{
Takashi Iwai1d045db2011-07-07 18:23:21 +02002506 static const hda_nid_t alc882_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002507 static const hda_nid_t alc882_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2508 return alc_parse_auto_config(codec, alc882_ignore, alc882_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002509}
2510
Takashi Iwai1d045db2011-07-07 18:23:21 +02002511/*
2512 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002513static int patch_alc882(struct hda_codec *codec)
2514{
2515 struct alc_spec *spec;
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002516 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002517
Takashi Iwai3de95172012-05-07 18:03:15 +02002518 err = alc_alloc_spec(codec, 0x0b);
2519 if (err < 0)
2520 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002521
Takashi Iwai3de95172012-05-07 18:03:15 +02002522 spec = codec->spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002523
Takashi Iwai7639a062015-03-03 10:07:24 +01002524 switch (codec->core.vendor_id) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002525 case 0x10ec0882:
2526 case 0x10ec0885:
Takashi Iwaiacf08082014-09-02 07:21:56 +02002527 case 0x10ec0900:
Kailang Yanga535ad52017-01-16 16:59:26 +08002528 case 0x10ec1220:
Takashi Iwai1d045db2011-07-07 18:23:21 +02002529 break;
2530 default:
2531 /* ALC883 and variants */
2532 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
2533 break;
2534 }
2535
Takashi Iwaic9af7532019-05-10 11:01:43 +02002536 alc_pre_init(codec);
2537
Takashi Iwai1727a772013-01-10 09:52:52 +01002538 snd_hda_pick_fixup(codec, alc882_fixup_models, alc882_fixup_tbl,
Takashi Iwai912093b2012-04-11 14:03:41 +02002539 alc882_fixups);
Takashi Iwai1727a772013-01-10 09:52:52 +01002540 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002541
2542 alc_auto_parse_customize_define(codec);
2543
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002544 if (has_cdefine_beep(codec))
2545 spec->gen.beep_nid = 0x01;
2546
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002547 /* automatic parse from the BIOS config */
2548 err = alc882_parse_auto_config(codec);
2549 if (err < 0)
2550 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002551
Takashi Iwaifea80fa2018-06-20 12:52:46 +02002552 if (!spec->gen.no_analog && spec->gen.beep_nid) {
2553 err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
2554 if (err < 0)
2555 goto error;
2556 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02002557
Takashi Iwai1727a772013-01-10 09:52:52 +01002558 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01002559
Takashi Iwai1d045db2011-07-07 18:23:21 +02002560 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02002561
2562 error:
2563 alc_free(codec);
2564 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002565}
2566
2567
2568/*
2569 * ALC262 support
2570 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002571static int alc262_parse_auto_config(struct hda_codec *codec)
2572{
Takashi Iwai1d045db2011-07-07 18:23:21 +02002573 static const hda_nid_t alc262_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002574 static const hda_nid_t alc262_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2575 return alc_parse_auto_config(codec, alc262_ignore, alc262_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002576}
2577
2578/*
2579 * Pin config fixes
2580 */
2581enum {
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002582 ALC262_FIXUP_FSC_H270,
Takashi Iwai7513e6d2013-01-18 15:41:34 +01002583 ALC262_FIXUP_FSC_S7110,
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002584 ALC262_FIXUP_HP_Z200,
2585 ALC262_FIXUP_TYAN,
Takashi Iwaic4701502011-11-07 14:20:07 +01002586 ALC262_FIXUP_LENOVO_3000,
Takashi Iwaib42590b2011-11-07 14:41:01 +01002587 ALC262_FIXUP_BENQ,
2588 ALC262_FIXUP_BENQ_T31,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002589 ALC262_FIXUP_INV_DMIC,
Mengdong Linb5c66112013-11-29 00:35:35 -05002590 ALC262_FIXUP_INTEL_BAYLEYBAY,
Takashi Iwai1d045db2011-07-07 18:23:21 +02002591};
2592
Takashi Iwai1727a772013-01-10 09:52:52 +01002593static const struct hda_fixup alc262_fixups[] = {
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002594 [ALC262_FIXUP_FSC_H270] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002595 .type = HDA_FIXUP_PINS,
2596 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002597 { 0x14, 0x99130110 }, /* speaker */
2598 { 0x15, 0x0221142f }, /* front HP */
2599 { 0x1b, 0x0121141f }, /* rear HP */
2600 { }
2601 }
2602 },
Takashi Iwai7513e6d2013-01-18 15:41:34 +01002603 [ALC262_FIXUP_FSC_S7110] = {
2604 .type = HDA_FIXUP_PINS,
2605 .v.pins = (const struct hda_pintbl[]) {
2606 { 0x15, 0x90170110 }, /* speaker */
2607 { }
2608 },
2609 .chained = true,
2610 .chain_id = ALC262_FIXUP_BENQ,
2611 },
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002612 [ALC262_FIXUP_HP_Z200] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002613 .type = HDA_FIXUP_PINS,
2614 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002615 { 0x16, 0x99130120 }, /* internal speaker */
2616 { }
2617 }
2618 },
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002619 [ALC262_FIXUP_TYAN] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002620 .type = HDA_FIXUP_PINS,
2621 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002622 { 0x14, 0x1993e1f0 }, /* int AUX */
2623 { }
2624 }
2625 },
Takashi Iwaic4701502011-11-07 14:20:07 +01002626 [ALC262_FIXUP_LENOVO_3000] = {
Takashi Iwaifd108212013-01-10 10:18:14 +01002627 .type = HDA_FIXUP_PINCTLS,
2628 .v.pins = (const struct hda_pintbl[]) {
2629 { 0x19, PIN_VREF50 },
Takashi Iwaib42590b2011-11-07 14:41:01 +01002630 {}
2631 },
2632 .chained = true,
2633 .chain_id = ALC262_FIXUP_BENQ,
2634 },
2635 [ALC262_FIXUP_BENQ] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002636 .type = HDA_FIXUP_VERBS,
Takashi Iwaib42590b2011-11-07 14:41:01 +01002637 .v.verbs = (const struct hda_verb[]) {
Takashi Iwaic4701502011-11-07 14:20:07 +01002638 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2639 { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
2640 {}
2641 }
2642 },
Takashi Iwaib42590b2011-11-07 14:41:01 +01002643 [ALC262_FIXUP_BENQ_T31] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002644 .type = HDA_FIXUP_VERBS,
Takashi Iwaib42590b2011-11-07 14:41:01 +01002645 .v.verbs = (const struct hda_verb[]) {
2646 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2647 { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
2648 {}
2649 }
2650 },
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002651 [ALC262_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002652 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02002653 .v.func = alc_fixup_inv_dmic,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002654 },
Mengdong Linb5c66112013-11-29 00:35:35 -05002655 [ALC262_FIXUP_INTEL_BAYLEYBAY] = {
2656 .type = HDA_FIXUP_FUNC,
2657 .v.func = alc_fixup_no_depop_delay,
2658 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02002659};
2660
2661static const struct snd_pci_quirk alc262_fixup_tbl[] = {
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002662 SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", ALC262_FIXUP_HP_Z200),
Takashi Iwai7513e6d2013-01-18 15:41:34 +01002663 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu Lifebook S7110", ALC262_FIXUP_FSC_S7110),
Takashi Iwai3dcd3be2011-11-07 14:59:40 +01002664 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FIXUP_BENQ),
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002665 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_FIXUP_TYAN),
Takashi Iwai275ec0c2018-06-22 12:17:45 +02002666 SND_PCI_QUIRK(0x1734, 0x1141, "FSC ESPRIMO U9210", ALC262_FIXUP_FSC_H270),
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002667 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", ALC262_FIXUP_FSC_H270),
Takashi Iwaic4701502011-11-07 14:20:07 +01002668 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000", ALC262_FIXUP_LENOVO_3000),
Takashi Iwaib42590b2011-11-07 14:41:01 +01002669 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_FIXUP_BENQ),
2670 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_FIXUP_BENQ_T31),
Mengdong Linb5c66112013-11-29 00:35:35 -05002671 SND_PCI_QUIRK(0x8086, 0x7270, "BayleyBay", ALC262_FIXUP_INTEL_BAYLEYBAY),
Takashi Iwai1d045db2011-07-07 18:23:21 +02002672 {}
2673};
2674
Takashi Iwai1727a772013-01-10 09:52:52 +01002675static const struct hda_model_fixup alc262_fixup_models[] = {
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002676 {.id = ALC262_FIXUP_INV_DMIC, .name = "inv-dmic"},
Takashi Iwaie43c44d2018-06-26 17:02:08 +02002677 {.id = ALC262_FIXUP_FSC_H270, .name = "fsc-h270"},
2678 {.id = ALC262_FIXUP_FSC_S7110, .name = "fsc-s7110"},
2679 {.id = ALC262_FIXUP_HP_Z200, .name = "hp-z200"},
2680 {.id = ALC262_FIXUP_TYAN, .name = "tyan"},
2681 {.id = ALC262_FIXUP_LENOVO_3000, .name = "lenovo-3000"},
2682 {.id = ALC262_FIXUP_BENQ, .name = "benq"},
2683 {.id = ALC262_FIXUP_BENQ_T31, .name = "benq-t31"},
2684 {.id = ALC262_FIXUP_INTEL_BAYLEYBAY, .name = "bayleybay"},
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002685 {}
2686};
Takashi Iwai1d045db2011-07-07 18:23:21 +02002687
Takashi Iwai1d045db2011-07-07 18:23:21 +02002688/*
2689 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002690static int patch_alc262(struct hda_codec *codec)
2691{
2692 struct alc_spec *spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002693 int err;
2694
Takashi Iwai3de95172012-05-07 18:03:15 +02002695 err = alc_alloc_spec(codec, 0x0b);
2696 if (err < 0)
2697 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002698
Takashi Iwai3de95172012-05-07 18:03:15 +02002699 spec = codec->spec;
Takashi Iwai08c189f2012-12-19 15:22:24 +01002700 spec->gen.shared_mic_vref_pin = 0x18;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002701
Takashi Iwai225068a2015-05-29 10:42:14 +02002702 spec->shutup = alc_eapd_shutup;
2703
Takashi Iwai1d045db2011-07-07 18:23:21 +02002704#if 0
2705 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
2706 * under-run
2707 */
Takashi Iwai98b24882014-08-18 13:47:50 +02002708 alc_update_coefex_idx(codec, 0x1a, 7, 0, 0x80);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002709#endif
Takashi Iwai1d045db2011-07-07 18:23:21 +02002710 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
2711
Takashi Iwaic9af7532019-05-10 11:01:43 +02002712 alc_pre_init(codec);
2713
Takashi Iwai1727a772013-01-10 09:52:52 +01002714 snd_hda_pick_fixup(codec, alc262_fixup_models, alc262_fixup_tbl,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002715 alc262_fixups);
Takashi Iwai1727a772013-01-10 09:52:52 +01002716 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002717
Takashi Iwaiaf741c12012-05-07 18:09:48 +02002718 alc_auto_parse_customize_define(codec);
2719
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002720 if (has_cdefine_beep(codec))
2721 spec->gen.beep_nid = 0x01;
2722
Takashi Iwai42399f72011-11-07 17:18:44 +01002723 /* automatic parse from the BIOS config */
2724 err = alc262_parse_auto_config(codec);
2725 if (err < 0)
2726 goto error;
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002727
Takashi Iwaifea80fa2018-06-20 12:52:46 +02002728 if (!spec->gen.no_analog && spec->gen.beep_nid) {
2729 err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
2730 if (err < 0)
2731 goto error;
2732 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02002733
Takashi Iwai1727a772013-01-10 09:52:52 +01002734 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01002735
Takashi Iwai1d045db2011-07-07 18:23:21 +02002736 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02002737
2738 error:
2739 alc_free(codec);
2740 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002741}
2742
2743/*
2744 * ALC268
2745 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002746/* bind Beep switches of both NID 0x0f and 0x10 */
Takashi Iwaia7177772017-05-10 12:04:08 +02002747static int alc268_beep_switch_put(struct snd_kcontrol *kcontrol,
2748 struct snd_ctl_elem_value *ucontrol)
2749{
2750 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2751 unsigned long pval;
2752 int err;
2753
2754 mutex_lock(&codec->control_mutex);
2755 pval = kcontrol->private_value;
2756 kcontrol->private_value = (pval & ~0xff) | 0x0f;
2757 err = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
2758 if (err >= 0) {
2759 kcontrol->private_value = (pval & ~0xff) | 0x10;
2760 err = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
2761 }
2762 kcontrol->private_value = pval;
2763 mutex_unlock(&codec->control_mutex);
2764 return err;
2765}
Takashi Iwai1d045db2011-07-07 18:23:21 +02002766
2767static const struct snd_kcontrol_new alc268_beep_mixer[] = {
2768 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
Takashi Iwaia7177772017-05-10 12:04:08 +02002769 {
2770 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2771 .name = "Beep Playback Switch",
2772 .subdevice = HDA_SUBDEV_AMP_FLAG,
2773 .info = snd_hda_mixer_amp_switch_info,
2774 .get = snd_hda_mixer_amp_switch_get,
2775 .put = alc268_beep_switch_put,
2776 .private_value = HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT)
2777 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02002778};
2779
2780/* set PCBEEP vol = 0, mute connections */
2781static const struct hda_verb alc268_beep_init_verbs[] = {
2782 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2783 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2784 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2785 { }
2786};
2787
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002788enum {
2789 ALC268_FIXUP_INV_DMIC,
Takashi Iwaicb766402012-10-20 10:55:21 +02002790 ALC268_FIXUP_HP_EAPD,
Takashi Iwai24eff322013-11-04 18:21:08 +01002791 ALC268_FIXUP_SPDIF,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002792};
2793
Takashi Iwai1727a772013-01-10 09:52:52 +01002794static const struct hda_fixup alc268_fixups[] = {
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002795 [ALC268_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002796 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02002797 .v.func = alc_fixup_inv_dmic,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002798 },
Takashi Iwaicb766402012-10-20 10:55:21 +02002799 [ALC268_FIXUP_HP_EAPD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002800 .type = HDA_FIXUP_VERBS,
Takashi Iwaicb766402012-10-20 10:55:21 +02002801 .v.verbs = (const struct hda_verb[]) {
2802 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 0},
2803 {}
2804 }
2805 },
Takashi Iwai24eff322013-11-04 18:21:08 +01002806 [ALC268_FIXUP_SPDIF] = {
2807 .type = HDA_FIXUP_PINS,
2808 .v.pins = (const struct hda_pintbl[]) {
2809 { 0x1e, 0x014b1180 }, /* enable SPDIF out */
2810 {}
2811 }
2812 },
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002813};
2814
Takashi Iwai1727a772013-01-10 09:52:52 +01002815static const struct hda_model_fixup alc268_fixup_models[] = {
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002816 {.id = ALC268_FIXUP_INV_DMIC, .name = "inv-dmic"},
Takashi Iwaicb766402012-10-20 10:55:21 +02002817 {.id = ALC268_FIXUP_HP_EAPD, .name = "hp-eapd"},
Takashi Iwai03bf11c2018-06-26 16:56:41 +02002818 {.id = ALC268_FIXUP_SPDIF, .name = "spdif"},
Takashi Iwaicb766402012-10-20 10:55:21 +02002819 {}
2820};
2821
2822static const struct snd_pci_quirk alc268_fixup_tbl[] = {
Takashi Iwai24eff322013-11-04 18:21:08 +01002823 SND_PCI_QUIRK(0x1025, 0x0139, "Acer TravelMate 6293", ALC268_FIXUP_SPDIF),
David Henningssonfcd8f3b2013-01-28 05:45:47 +01002824 SND_PCI_QUIRK(0x1025, 0x015b, "Acer AOA 150 (ZG5)", ALC268_FIXUP_INV_DMIC),
Takashi Iwaicb766402012-10-20 10:55:21 +02002825 /* below is codec SSID since multiple Toshiba laptops have the
2826 * same PCI SSID 1179:ff00
2827 */
2828 SND_PCI_QUIRK(0x1179, 0xff06, "Toshiba P200", ALC268_FIXUP_HP_EAPD),
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002829 {}
2830};
2831
Takashi Iwai1d045db2011-07-07 18:23:21 +02002832/*
2833 * BIOS auto configuration
2834 */
2835static int alc268_parse_auto_config(struct hda_codec *codec)
2836{
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002837 static const hda_nid_t alc268_ssids[] = { 0x15, 0x1b, 0x14, 0 };
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002838 return alc_parse_auto_config(codec, NULL, alc268_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002839}
2840
Takashi Iwai1d045db2011-07-07 18:23:21 +02002841/*
2842 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002843static int patch_alc268(struct hda_codec *codec)
2844{
2845 struct alc_spec *spec;
Takashi Iwaia5cb4632018-06-20 12:50:11 +02002846 int i, err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002847
Takashi Iwai1d045db2011-07-07 18:23:21 +02002848 /* ALC268 has no aa-loopback mixer */
Takashi Iwai3de95172012-05-07 18:03:15 +02002849 err = alc_alloc_spec(codec, 0);
2850 if (err < 0)
2851 return err;
2852
2853 spec = codec->spec;
Takashi Iwai2722b532019-08-22 09:55:37 +02002854 if (has_cdefine_beep(codec))
2855 spec->gen.beep_nid = 0x01;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002856
Takashi Iwai225068a2015-05-29 10:42:14 +02002857 spec->shutup = alc_eapd_shutup;
2858
Takashi Iwaic9af7532019-05-10 11:01:43 +02002859 alc_pre_init(codec);
2860
Takashi Iwai1727a772013-01-10 09:52:52 +01002861 snd_hda_pick_fixup(codec, alc268_fixup_models, alc268_fixup_tbl, alc268_fixups);
2862 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002863
Takashi Iwai6ebb8052011-08-16 15:15:40 +02002864 /* automatic parse from the BIOS config */
2865 err = alc268_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02002866 if (err < 0)
2867 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002868
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002869 if (err > 0 && !spec->gen.no_analog &&
2870 spec->gen.autocfg.speaker_pins[0] != 0x1d) {
Takashi Iwaia5cb4632018-06-20 12:50:11 +02002871 for (i = 0; i < ARRAY_SIZE(alc268_beep_mixer); i++) {
2872 if (!snd_hda_gen_add_kctl(&spec->gen, NULL,
2873 &alc268_beep_mixer[i])) {
2874 err = -ENOMEM;
2875 goto error;
2876 }
2877 }
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002878 snd_hda_add_verbs(codec, alc268_beep_init_verbs);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002879 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
2880 /* override the amp caps for beep generator */
2881 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
2882 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
2883 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
2884 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
2885 (0 << AC_AMPCAP_MUTE_SHIFT));
2886 }
2887
Takashi Iwai1727a772013-01-10 09:52:52 +01002888 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002889
Takashi Iwai1d045db2011-07-07 18:23:21 +02002890 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02002891
2892 error:
2893 alc_free(codec);
2894 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002895}
2896
2897/*
2898 * ALC269
2899 */
Takashi Iwai08c189f2012-12-19 15:22:24 +01002900
Takashi Iwai1d045db2011-07-07 18:23:21 +02002901static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002902 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002903};
2904
2905static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002906 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002907};
2908
Takashi Iwai1d045db2011-07-07 18:23:21 +02002909/* different alc269-variants */
2910enum {
2911 ALC269_TYPE_ALC269VA,
2912 ALC269_TYPE_ALC269VB,
2913 ALC269_TYPE_ALC269VC,
Kailang Yangadcc70b2012-05-25 08:08:38 +02002914 ALC269_TYPE_ALC269VD,
Kailang Yang065380f2013-01-10 10:25:48 +01002915 ALC269_TYPE_ALC280,
2916 ALC269_TYPE_ALC282,
Kailang Yang2af02be2013-08-22 10:03:50 +02002917 ALC269_TYPE_ALC283,
Kailang Yang065380f2013-01-10 10:25:48 +01002918 ALC269_TYPE_ALC284,
Kailang Yang4731d5d2017-06-30 15:22:57 +08002919 ALC269_TYPE_ALC293,
Kailang Yang7fc7d042013-04-25 11:04:43 +02002920 ALC269_TYPE_ALC286,
Kailang Yang506b62c2014-12-18 17:07:44 +08002921 ALC269_TYPE_ALC298,
Kailang Yang1d04c9d2013-10-24 11:35:18 +02002922 ALC269_TYPE_ALC255,
Kailang Yang4344aec2014-12-17 17:39:05 +08002923 ALC269_TYPE_ALC256,
Kailang Yangf429e7e2017-12-05 15:38:24 +08002924 ALC269_TYPE_ALC257,
Kailang Yang0a6f0602017-06-30 16:00:48 +08002925 ALC269_TYPE_ALC215,
Kailang Yang42314302016-02-03 15:03:50 +08002926 ALC269_TYPE_ALC225,
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08002927 ALC269_TYPE_ALC294,
Kailang Yang1078bef2018-11-08 16:36:15 +08002928 ALC269_TYPE_ALC300,
Kailang Yangf0778872019-10-24 15:13:32 +08002929 ALC269_TYPE_ALC623,
Kailang Yang6fbae352016-05-30 16:44:20 +08002930 ALC269_TYPE_ALC700,
Takashi Iwai1d045db2011-07-07 18:23:21 +02002931};
2932
2933/*
2934 * BIOS auto configuration
2935 */
2936static int alc269_parse_auto_config(struct hda_codec *codec)
2937{
Takashi Iwai1d045db2011-07-07 18:23:21 +02002938 static const hda_nid_t alc269_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002939 static const hda_nid_t alc269_ssids[] = { 0, 0x1b, 0x14, 0x21 };
2940 static const hda_nid_t alc269va_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2941 struct alc_spec *spec = codec->spec;
Kailang Yangadcc70b2012-05-25 08:08:38 +02002942 const hda_nid_t *ssids;
2943
2944 switch (spec->codec_variant) {
2945 case ALC269_TYPE_ALC269VA:
2946 case ALC269_TYPE_ALC269VC:
Kailang Yang065380f2013-01-10 10:25:48 +01002947 case ALC269_TYPE_ALC280:
2948 case ALC269_TYPE_ALC284:
Kailang Yang4731d5d2017-06-30 15:22:57 +08002949 case ALC269_TYPE_ALC293:
Kailang Yangadcc70b2012-05-25 08:08:38 +02002950 ssids = alc269va_ssids;
2951 break;
2952 case ALC269_TYPE_ALC269VB:
2953 case ALC269_TYPE_ALC269VD:
Kailang Yang065380f2013-01-10 10:25:48 +01002954 case ALC269_TYPE_ALC282:
Kailang Yang2af02be2013-08-22 10:03:50 +02002955 case ALC269_TYPE_ALC283:
Kailang Yang7fc7d042013-04-25 11:04:43 +02002956 case ALC269_TYPE_ALC286:
Kailang Yang506b62c2014-12-18 17:07:44 +08002957 case ALC269_TYPE_ALC298:
Kailang Yang1d04c9d2013-10-24 11:35:18 +02002958 case ALC269_TYPE_ALC255:
Kailang Yang4344aec2014-12-17 17:39:05 +08002959 case ALC269_TYPE_ALC256:
Kailang Yangf429e7e2017-12-05 15:38:24 +08002960 case ALC269_TYPE_ALC257:
Kailang Yang0a6f0602017-06-30 16:00:48 +08002961 case ALC269_TYPE_ALC215:
Kailang Yang42314302016-02-03 15:03:50 +08002962 case ALC269_TYPE_ALC225:
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08002963 case ALC269_TYPE_ALC294:
Kailang Yang1078bef2018-11-08 16:36:15 +08002964 case ALC269_TYPE_ALC300:
Kailang Yangf0778872019-10-24 15:13:32 +08002965 case ALC269_TYPE_ALC623:
Kailang Yang6fbae352016-05-30 16:44:20 +08002966 case ALC269_TYPE_ALC700:
Kailang Yangadcc70b2012-05-25 08:08:38 +02002967 ssids = alc269_ssids;
2968 break;
2969 default:
2970 ssids = alc269_ssids;
2971 break;
2972 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02002973
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002974 return alc_parse_auto_config(codec, alc269_ignore, ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002975}
2976
Kailang Yang1387e2d2012-11-08 10:23:18 +01002977static void alc269vb_toggle_power_output(struct hda_codec *codec, int power_up)
Takashi Iwai1d045db2011-07-07 18:23:21 +02002978{
Takashi Iwai98b24882014-08-18 13:47:50 +02002979 alc_update_coef_idx(codec, 0x04, 1 << 11, power_up ? (1 << 11) : 0);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002980}
2981
2982static void alc269_shutup(struct hda_codec *codec)
2983{
Kailang Yangadcc70b2012-05-25 08:08:38 +02002984 struct alc_spec *spec = codec->spec;
2985
Kailang Yang1387e2d2012-11-08 10:23:18 +01002986 if (spec->codec_variant == ALC269_TYPE_ALC269VB)
2987 alc269vb_toggle_power_output(codec, 0);
2988 if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
2989 (alc_get_coef0(codec) & 0x00ff) == 0x018) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002990 msleep(150);
2991 }
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01002992 alc_shutup_pins(codec);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002993}
2994
Takashi Iwai54db6c32014-08-18 15:11:19 +02002995static struct coef_fw alc282_coefs[] = {
2996 WRITE_COEF(0x03, 0x0002), /* Power Down Control */
Kailang Yang32fa7e42014-10-24 16:26:01 +08002997 UPDATE_COEF(0x05, 0xff3f, 0x0700), /* FIFO and filter clock */
Takashi Iwai54db6c32014-08-18 15:11:19 +02002998 WRITE_COEF(0x07, 0x0200), /* DMIC control */
2999 UPDATE_COEF(0x06, 0x00f0, 0), /* Analog clock */
3000 UPDATE_COEF(0x08, 0xfffc, 0x0c2c), /* JD */
3001 WRITE_COEF(0x0a, 0xcccc), /* JD offset1 */
3002 WRITE_COEF(0x0b, 0xcccc), /* JD offset2 */
3003 WRITE_COEF(0x0e, 0x6e00), /* LDO1/2/3, DAC/ADC */
3004 UPDATE_COEF(0x0f, 0xf800, 0x1000), /* JD */
3005 UPDATE_COEF(0x10, 0xfc00, 0x0c00), /* Capless */
3006 WRITE_COEF(0x6f, 0x0), /* Class D test 4 */
3007 UPDATE_COEF(0x0c, 0xfe00, 0), /* IO power down directly */
3008 WRITE_COEF(0x34, 0xa0c0), /* ANC */
3009 UPDATE_COEF(0x16, 0x0008, 0), /* AGC MUX */
3010 UPDATE_COEF(0x1d, 0x00e0, 0), /* DAC simple content protection */
3011 UPDATE_COEF(0x1f, 0x00e0, 0), /* ADC simple content protection */
3012 WRITE_COEF(0x21, 0x8804), /* DAC ADC Zero Detection */
3013 WRITE_COEF(0x63, 0x2902), /* PLL */
3014 WRITE_COEF(0x68, 0xa080), /* capless control 2 */
3015 WRITE_COEF(0x69, 0x3400), /* capless control 3 */
3016 WRITE_COEF(0x6a, 0x2f3e), /* capless control 4 */
3017 WRITE_COEF(0x6b, 0x0), /* capless control 5 */
3018 UPDATE_COEF(0x6d, 0x0fff, 0x0900), /* class D test 2 */
3019 WRITE_COEF(0x6e, 0x110a), /* class D test 3 */
3020 UPDATE_COEF(0x70, 0x00f8, 0x00d8), /* class D test 5 */
3021 WRITE_COEF(0x71, 0x0014), /* class D test 6 */
3022 WRITE_COEF(0x72, 0xc2ba), /* classD OCP */
3023 UPDATE_COEF(0x77, 0x0f80, 0), /* classD pure DC test */
3024 WRITE_COEF(0x6c, 0xfc06), /* Class D amp control */
3025 {}
3026};
3027
Kailang Yangcb149cb2014-03-18 16:45:32 +08003028static void alc282_restore_default_value(struct hda_codec *codec)
3029{
Takashi Iwai54db6c32014-08-18 15:11:19 +02003030 alc_process_coef_fw(codec, alc282_coefs);
Kailang Yangcb149cb2014-03-18 16:45:32 +08003031}
3032
Kailang Yang7b5c7a02014-03-18 16:15:54 +08003033static void alc282_init(struct hda_codec *codec)
3034{
3035 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003036 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang7b5c7a02014-03-18 16:15:54 +08003037 bool hp_pin_sense;
3038 int coef78;
3039
Kailang Yangcb149cb2014-03-18 16:45:32 +08003040 alc282_restore_default_value(codec);
3041
Kailang Yang7b5c7a02014-03-18 16:15:54 +08003042 if (!hp_pin)
3043 return;
3044 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3045 coef78 = alc_read_coef_idx(codec, 0x78);
3046
3047 /* Index 0x78 Direct Drive HP AMP LPM Control 1 */
3048 /* Headphone capless set to high power mode */
3049 alc_write_coef_idx(codec, 0x78, 0x9004);
3050
3051 if (hp_pin_sense)
3052 msleep(2);
3053
3054 snd_hda_codec_write(codec, hp_pin, 0,
3055 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3056
3057 if (hp_pin_sense)
3058 msleep(85);
3059
3060 snd_hda_codec_write(codec, hp_pin, 0,
3061 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3062
3063 if (hp_pin_sense)
3064 msleep(100);
3065
3066 /* Headphone capless set to normal mode */
3067 alc_write_coef_idx(codec, 0x78, coef78);
3068}
3069
3070static void alc282_shutup(struct hda_codec *codec)
3071{
3072 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003073 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang7b5c7a02014-03-18 16:15:54 +08003074 bool hp_pin_sense;
3075 int coef78;
3076
3077 if (!hp_pin) {
3078 alc269_shutup(codec);
3079 return;
3080 }
3081
3082 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3083 coef78 = alc_read_coef_idx(codec, 0x78);
3084 alc_write_coef_idx(codec, 0x78, 0x9004);
3085
3086 if (hp_pin_sense)
3087 msleep(2);
3088
3089 snd_hda_codec_write(codec, hp_pin, 0,
3090 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3091
3092 if (hp_pin_sense)
3093 msleep(85);
3094
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003095 if (!spec->no_shutup_pins)
3096 snd_hda_codec_write(codec, hp_pin, 0,
3097 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
Kailang Yang7b5c7a02014-03-18 16:15:54 +08003098
3099 if (hp_pin_sense)
3100 msleep(100);
3101
3102 alc_auto_setup_eapd(codec, false);
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003103 alc_shutup_pins(codec);
Kailang Yang7b5c7a02014-03-18 16:15:54 +08003104 alc_write_coef_idx(codec, 0x78, coef78);
3105}
3106
Takashi Iwai54db6c32014-08-18 15:11:19 +02003107static struct coef_fw alc283_coefs[] = {
3108 WRITE_COEF(0x03, 0x0002), /* Power Down Control */
Kailang Yang56779862014-10-24 16:17:51 +08003109 UPDATE_COEF(0x05, 0xff3f, 0x0700), /* FIFO and filter clock */
Takashi Iwai54db6c32014-08-18 15:11:19 +02003110 WRITE_COEF(0x07, 0x0200), /* DMIC control */
3111 UPDATE_COEF(0x06, 0x00f0, 0), /* Analog clock */
3112 UPDATE_COEF(0x08, 0xfffc, 0x0c2c), /* JD */
3113 WRITE_COEF(0x0a, 0xcccc), /* JD offset1 */
3114 WRITE_COEF(0x0b, 0xcccc), /* JD offset2 */
3115 WRITE_COEF(0x0e, 0x6fc0), /* LDO1/2/3, DAC/ADC */
3116 UPDATE_COEF(0x0f, 0xf800, 0x1000), /* JD */
3117 UPDATE_COEF(0x10, 0xfc00, 0x0c00), /* Capless */
3118 WRITE_COEF(0x3a, 0x0), /* Class D test 4 */
3119 UPDATE_COEF(0x0c, 0xfe00, 0x0), /* IO power down directly */
3120 WRITE_COEF(0x22, 0xa0c0), /* ANC */
3121 UPDATE_COEFEX(0x53, 0x01, 0x000f, 0x0008), /* AGC MUX */
3122 UPDATE_COEF(0x1d, 0x00e0, 0), /* DAC simple content protection */
3123 UPDATE_COEF(0x1f, 0x00e0, 0), /* ADC simple content protection */
3124 WRITE_COEF(0x21, 0x8804), /* DAC ADC Zero Detection */
3125 WRITE_COEF(0x2e, 0x2902), /* PLL */
3126 WRITE_COEF(0x33, 0xa080), /* capless control 2 */
3127 WRITE_COEF(0x34, 0x3400), /* capless control 3 */
3128 WRITE_COEF(0x35, 0x2f3e), /* capless control 4 */
3129 WRITE_COEF(0x36, 0x0), /* capless control 5 */
3130 UPDATE_COEF(0x38, 0x0fff, 0x0900), /* class D test 2 */
3131 WRITE_COEF(0x39, 0x110a), /* class D test 3 */
3132 UPDATE_COEF(0x3b, 0x00f8, 0x00d8), /* class D test 5 */
3133 WRITE_COEF(0x3c, 0x0014), /* class D test 6 */
3134 WRITE_COEF(0x3d, 0xc2ba), /* classD OCP */
3135 UPDATE_COEF(0x42, 0x0f80, 0x0), /* classD pure DC test */
3136 WRITE_COEF(0x49, 0x0), /* test mode */
3137 UPDATE_COEF(0x40, 0xf800, 0x9800), /* Class D DC enable */
3138 UPDATE_COEF(0x42, 0xf000, 0x2000), /* DC offset */
3139 WRITE_COEF(0x37, 0xfc06), /* Class D amp control */
Kailang Yang56779862014-10-24 16:17:51 +08003140 UPDATE_COEF(0x1b, 0x8000, 0), /* HP JD control */
Takashi Iwai54db6c32014-08-18 15:11:19 +02003141 {}
3142};
3143
Kailang Yang6bd55b02014-03-17 13:51:27 +08003144static void alc283_restore_default_value(struct hda_codec *codec)
3145{
Takashi Iwai54db6c32014-08-18 15:11:19 +02003146 alc_process_coef_fw(codec, alc283_coefs);
Kailang Yang6bd55b02014-03-17 13:51:27 +08003147}
3148
Kailang Yang2af02be2013-08-22 10:03:50 +02003149static void alc283_init(struct hda_codec *codec)
3150{
3151 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003152 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang2af02be2013-08-22 10:03:50 +02003153 bool hp_pin_sense;
Kailang Yang2af02be2013-08-22 10:03:50 +02003154
Kailang Yang6bd55b02014-03-17 13:51:27 +08003155 alc283_restore_default_value(codec);
3156
Kailang Yang2af02be2013-08-22 10:03:50 +02003157 if (!hp_pin)
3158 return;
Kailang Yanga59d7192015-04-08 16:34:00 +08003159
3160 msleep(30);
Kailang Yang2af02be2013-08-22 10:03:50 +02003161 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3162
3163 /* Index 0x43 Direct Drive HP AMP LPM Control 1 */
3164 /* Headphone capless set to high power mode */
3165 alc_write_coef_idx(codec, 0x43, 0x9004);
3166
3167 snd_hda_codec_write(codec, hp_pin, 0,
3168 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3169
3170 if (hp_pin_sense)
3171 msleep(85);
3172
3173 snd_hda_codec_write(codec, hp_pin, 0,
3174 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3175
3176 if (hp_pin_sense)
3177 msleep(85);
3178 /* Index 0x46 Combo jack auto switch control 2 */
3179 /* 3k pull low control for Headset jack. */
Takashi Iwai98b24882014-08-18 13:47:50 +02003180 alc_update_coef_idx(codec, 0x46, 3 << 12, 0);
Kailang Yang2af02be2013-08-22 10:03:50 +02003181 /* Headphone capless set to normal mode */
3182 alc_write_coef_idx(codec, 0x43, 0x9614);
3183}
3184
3185static void alc283_shutup(struct hda_codec *codec)
3186{
3187 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003188 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang2af02be2013-08-22 10:03:50 +02003189 bool hp_pin_sense;
Kailang Yang2af02be2013-08-22 10:03:50 +02003190
3191 if (!hp_pin) {
3192 alc269_shutup(codec);
3193 return;
3194 }
3195
3196 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3197
3198 alc_write_coef_idx(codec, 0x43, 0x9004);
3199
Harsha Priyab450b172014-10-09 11:04:56 +00003200 /*depop hp during suspend*/
3201 alc_write_coef_idx(codec, 0x06, 0x2100);
3202
Kailang Yang2af02be2013-08-22 10:03:50 +02003203 snd_hda_codec_write(codec, hp_pin, 0,
3204 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3205
3206 if (hp_pin_sense)
Kailang Yang88011c092013-10-24 15:45:24 +02003207 msleep(100);
Kailang Yang2af02be2013-08-22 10:03:50 +02003208
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003209 if (!spec->no_shutup_pins)
3210 snd_hda_codec_write(codec, hp_pin, 0,
3211 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
Kailang Yang2af02be2013-08-22 10:03:50 +02003212
Takashi Iwai98b24882014-08-18 13:47:50 +02003213 alc_update_coef_idx(codec, 0x46, 0, 3 << 12);
Kailang Yang2af02be2013-08-22 10:03:50 +02003214
3215 if (hp_pin_sense)
Kailang Yang88011c092013-10-24 15:45:24 +02003216 msleep(100);
Kailang Yang0435b3f2014-04-08 17:14:14 +08003217 alc_auto_setup_eapd(codec, false);
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003218 alc_shutup_pins(codec);
Kailang Yang2af02be2013-08-22 10:03:50 +02003219 alc_write_coef_idx(codec, 0x43, 0x9614);
3220}
3221
Kailang Yang4a219ef2017-06-16 16:54:35 +08003222static void alc256_init(struct hda_codec *codec)
3223{
3224 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003225 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang4a219ef2017-06-16 16:54:35 +08003226 bool hp_pin_sense;
3227
3228 if (!hp_pin)
Kailang Yang6447c962019-05-08 16:27:03 +08003229 hp_pin = 0x21;
Kailang Yang4a219ef2017-06-16 16:54:35 +08003230
3231 msleep(30);
3232
3233 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3234
3235 if (hp_pin_sense)
3236 msleep(2);
3237
3238 alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */
Kailang Yang6447c962019-05-08 16:27:03 +08003239 if (spec->ultra_low_power) {
3240 alc_update_coef_idx(codec, 0x03, 1<<1, 1<<1);
3241 alc_update_coef_idx(codec, 0x08, 3<<2, 3<<2);
3242 alc_update_coef_idx(codec, 0x08, 7<<4, 0);
3243 alc_update_coef_idx(codec, 0x3b, 1<<15, 0);
3244 alc_update_coef_idx(codec, 0x0e, 7<<6, 7<<6);
3245 msleep(30);
3246 }
Kailang Yang4a219ef2017-06-16 16:54:35 +08003247
3248 snd_hda_codec_write(codec, hp_pin, 0,
3249 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3250
Kailang Yang6447c962019-05-08 16:27:03 +08003251 if (hp_pin_sense || spec->ultra_low_power)
Kailang Yang4a219ef2017-06-16 16:54:35 +08003252 msleep(85);
3253
3254 snd_hda_codec_write(codec, hp_pin, 0,
3255 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3256
Kailang Yang6447c962019-05-08 16:27:03 +08003257 if (hp_pin_sense || spec->ultra_low_power)
Kailang Yang4a219ef2017-06-16 16:54:35 +08003258 msleep(100);
3259
3260 alc_update_coef_idx(codec, 0x46, 3 << 12, 0);
3261 alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x4); /* Hight power */
Kailang Yang88d42b22018-03-14 16:08:57 +08003262 alc_update_coefex_idx(codec, 0x53, 0x02, 0x8000, 1 << 15); /* Clear bit */
3263 alc_update_coefex_idx(codec, 0x53, 0x02, 0x8000, 0 << 15);
Kailang Yangd07a9a42019-07-04 16:02:10 +08003264 alc_update_coef_idx(codec, 0x36, 1 << 13, 1 << 5); /* Switch pcbeep path to Line in path*/
Kailang Yang4a219ef2017-06-16 16:54:35 +08003265}
3266
3267static void alc256_shutup(struct hda_codec *codec)
3268{
3269 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003270 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang4a219ef2017-06-16 16:54:35 +08003271 bool hp_pin_sense;
3272
Kailang Yang6447c962019-05-08 16:27:03 +08003273 if (!hp_pin)
3274 hp_pin = 0x21;
Kailang Yang4a219ef2017-06-16 16:54:35 +08003275
3276 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3277
3278 if (hp_pin_sense)
3279 msleep(2);
3280
3281 snd_hda_codec_write(codec, hp_pin, 0,
3282 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3283
Kailang Yang6447c962019-05-08 16:27:03 +08003284 if (hp_pin_sense || spec->ultra_low_power)
Kailang Yang4a219ef2017-06-16 16:54:35 +08003285 msleep(85);
3286
Takashi Iwai1c9609e2018-01-19 14:18:34 +01003287 /* 3k pull low control for Headset jack. */
3288 /* NOTE: call this before clearing the pin, otherwise codec stalls */
3289 alc_update_coef_idx(codec, 0x46, 0, 3 << 12);
3290
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003291 if (!spec->no_shutup_pins)
3292 snd_hda_codec_write(codec, hp_pin, 0,
3293 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
Kailang Yang4a219ef2017-06-16 16:54:35 +08003294
Kailang Yang6447c962019-05-08 16:27:03 +08003295 if (hp_pin_sense || spec->ultra_low_power)
Kailang Yang4a219ef2017-06-16 16:54:35 +08003296 msleep(100);
3297
3298 alc_auto_setup_eapd(codec, false);
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003299 alc_shutup_pins(codec);
Kailang Yang6447c962019-05-08 16:27:03 +08003300 if (spec->ultra_low_power) {
3301 msleep(50);
3302 alc_update_coef_idx(codec, 0x03, 1<<1, 0);
3303 alc_update_coef_idx(codec, 0x08, 7<<4, 7<<4);
3304 alc_update_coef_idx(codec, 0x08, 3<<2, 0);
3305 alc_update_coef_idx(codec, 0x3b, 1<<15, 1<<15);
3306 alc_update_coef_idx(codec, 0x0e, 7<<6, 0);
3307 msleep(30);
3308 }
Kailang Yang4a219ef2017-06-16 16:54:35 +08003309}
3310
Kailang Yangda911b12018-01-05 16:50:08 +08003311static void alc225_init(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 Yangda911b12018-01-05 16:50:08 +08003315 bool hp1_pin_sense, hp2_pin_sense;
3316
3317 if (!hp_pin)
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003318 hp_pin = 0x21;
Kailang Yangda911b12018-01-05 16:50:08 +08003319 msleep(30);
3320
3321 hp1_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3322 hp2_pin_sense = snd_hda_jack_detect(codec, 0x16);
3323
3324 if (hp1_pin_sense || hp2_pin_sense)
3325 msleep(2);
3326
3327 alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003328 if (spec->ultra_low_power) {
3329 alc_update_coef_idx(codec, 0x08, 0x0f << 2, 3<<2);
3330 alc_update_coef_idx(codec, 0x0e, 7<<6, 7<<6);
3331 alc_update_coef_idx(codec, 0x33, 1<<11, 0);
3332 msleep(30);
3333 }
Kailang Yangda911b12018-01-05 16:50:08 +08003334
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003335 if (hp1_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003336 snd_hda_codec_write(codec, hp_pin, 0,
3337 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3338 if (hp2_pin_sense)
3339 snd_hda_codec_write(codec, 0x16, 0,
3340 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3341
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003342 if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003343 msleep(85);
3344
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003345 if (hp1_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003346 snd_hda_codec_write(codec, hp_pin, 0,
3347 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3348 if (hp2_pin_sense)
3349 snd_hda_codec_write(codec, 0x16, 0,
3350 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3351
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003352 if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003353 msleep(100);
3354
3355 alc_update_coef_idx(codec, 0x4a, 3 << 10, 0);
3356 alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x4); /* Hight power */
3357}
3358
3359static void alc225_shutup(struct hda_codec *codec)
3360{
3361 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003362 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yangda911b12018-01-05 16:50:08 +08003363 bool hp1_pin_sense, hp2_pin_sense;
3364
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003365 if (!hp_pin)
3366 hp_pin = 0x21;
Kailang Yangda911b12018-01-05 16:50:08 +08003367 /* 3k pull low control for Headset jack. */
3368 alc_update_coef_idx(codec, 0x4a, 0, 3 << 10);
3369
3370 hp1_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3371 hp2_pin_sense = snd_hda_jack_detect(codec, 0x16);
3372
3373 if (hp1_pin_sense || hp2_pin_sense)
3374 msleep(2);
3375
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003376 if (hp1_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003377 snd_hda_codec_write(codec, hp_pin, 0,
3378 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3379 if (hp2_pin_sense)
3380 snd_hda_codec_write(codec, 0x16, 0,
3381 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3382
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003383 if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003384 msleep(85);
3385
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003386 if (hp1_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003387 snd_hda_codec_write(codec, hp_pin, 0,
3388 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
3389 if (hp2_pin_sense)
3390 snd_hda_codec_write(codec, 0x16, 0,
3391 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
3392
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003393 if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003394 msleep(100);
3395
3396 alc_auto_setup_eapd(codec, false);
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003397 alc_shutup_pins(codec);
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003398 if (spec->ultra_low_power) {
3399 msleep(50);
3400 alc_update_coef_idx(codec, 0x08, 0x0f << 2, 0x0c << 2);
3401 alc_update_coef_idx(codec, 0x0e, 7<<6, 0);
3402 alc_update_coef_idx(codec, 0x33, 1<<11, 1<<11);
3403 alc_update_coef_idx(codec, 0x4a, 3<<4, 2<<4);
3404 msleep(30);
3405 }
Kailang Yangda911b12018-01-05 16:50:08 +08003406}
3407
Kailang Yangc2d6af52017-06-21 14:50:54 +08003408static void alc_default_init(struct hda_codec *codec)
3409{
3410 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003411 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yangc2d6af52017-06-21 14:50:54 +08003412 bool hp_pin_sense;
3413
3414 if (!hp_pin)
3415 return;
3416
3417 msleep(30);
3418
3419 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3420
3421 if (hp_pin_sense)
3422 msleep(2);
3423
3424 snd_hda_codec_write(codec, hp_pin, 0,
3425 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3426
3427 if (hp_pin_sense)
3428 msleep(85);
3429
3430 snd_hda_codec_write(codec, hp_pin, 0,
3431 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3432
3433 if (hp_pin_sense)
3434 msleep(100);
3435}
3436
3437static void alc_default_shutup(struct hda_codec *codec)
3438{
3439 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003440 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yangc2d6af52017-06-21 14:50:54 +08003441 bool hp_pin_sense;
3442
3443 if (!hp_pin) {
3444 alc269_shutup(codec);
3445 return;
3446 }
3447
3448 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3449
3450 if (hp_pin_sense)
3451 msleep(2);
3452
3453 snd_hda_codec_write(codec, hp_pin, 0,
3454 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3455
3456 if (hp_pin_sense)
3457 msleep(85);
3458
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003459 if (!spec->no_shutup_pins)
3460 snd_hda_codec_write(codec, hp_pin, 0,
3461 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
Kailang Yangc2d6af52017-06-21 14:50:54 +08003462
3463 if (hp_pin_sense)
3464 msleep(100);
3465
3466 alc_auto_setup_eapd(codec, false);
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003467 alc_shutup_pins(codec);
Kailang Yangc2d6af52017-06-21 14:50:54 +08003468}
3469
Kailang Yang693abe12019-01-29 15:38:21 +08003470static void alc294_hp_init(struct hda_codec *codec)
3471{
3472 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003473 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang693abe12019-01-29 15:38:21 +08003474 int i, val;
3475
3476 if (!hp_pin)
3477 return;
3478
3479 snd_hda_codec_write(codec, hp_pin, 0,
3480 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3481
3482 msleep(100);
3483
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003484 if (!spec->no_shutup_pins)
3485 snd_hda_codec_write(codec, hp_pin, 0,
3486 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
Kailang Yang693abe12019-01-29 15:38:21 +08003487
3488 alc_update_coef_idx(codec, 0x6f, 0x000f, 0);/* Set HP depop to manual mode */
3489 alc_update_coefex_idx(codec, 0x58, 0x00, 0x8000, 0x8000); /* HP depop procedure start */
3490
3491 /* Wait for depop procedure finish */
3492 val = alc_read_coefex_idx(codec, 0x58, 0x01);
3493 for (i = 0; i < 20 && val & 0x0080; i++) {
3494 msleep(50);
3495 val = alc_read_coefex_idx(codec, 0x58, 0x01);
3496 }
3497 /* Set HP depop to auto mode */
3498 alc_update_coef_idx(codec, 0x6f, 0x000f, 0x000b);
3499 msleep(50);
3500}
3501
3502static void alc294_init(struct hda_codec *codec)
3503{
3504 struct alc_spec *spec = codec->spec;
3505
Takashi Iwaif6ef4e02019-01-29 14:14:51 +01003506 /* required only at boot or S4 resume time */
3507 if (!spec->done_hp_init ||
3508 codec->core.dev.power.power_state.event == PM_EVENT_RESTORE) {
Kailang Yang693abe12019-01-29 15:38:21 +08003509 alc294_hp_init(codec);
3510 spec->done_hp_init = true;
3511 }
3512 alc_default_init(codec);
3513}
3514
Kailang Yangad60d502013-06-28 12:03:01 +02003515static void alc5505_coef_set(struct hda_codec *codec, unsigned int index_reg,
3516 unsigned int val)
3517{
3518 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_COEF_INDEX, index_reg >> 1);
3519 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_PROC_COEF, val & 0xffff); /* LSB */
3520 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_PROC_COEF, val >> 16); /* MSB */
3521}
3522
3523static int alc5505_coef_get(struct hda_codec *codec, unsigned int index_reg)
3524{
3525 unsigned int val;
3526
3527 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_COEF_INDEX, index_reg >> 1);
3528 val = snd_hda_codec_read(codec, 0x51, 0, AC_VERB_GET_PROC_COEF, 0)
3529 & 0xffff;
3530 val |= snd_hda_codec_read(codec, 0x51, 0, AC_VERB_GET_PROC_COEF, 0)
3531 << 16;
3532 return val;
3533}
3534
3535static void alc5505_dsp_halt(struct hda_codec *codec)
3536{
3537 unsigned int val;
3538
3539 alc5505_coef_set(codec, 0x3000, 0x000c); /* DSP CPU stop */
3540 alc5505_coef_set(codec, 0x880c, 0x0008); /* DDR enter self refresh */
3541 alc5505_coef_set(codec, 0x61c0, 0x11110080); /* Clock control for PLL and CPU */
3542 alc5505_coef_set(codec, 0x6230, 0xfc0d4011); /* Disable Input OP */
3543 alc5505_coef_set(codec, 0x61b4, 0x040a2b03); /* Stop PLL2 */
3544 alc5505_coef_set(codec, 0x61b0, 0x00005b17); /* Stop PLL1 */
3545 alc5505_coef_set(codec, 0x61b8, 0x04133303); /* Stop PLL3 */
3546 val = alc5505_coef_get(codec, 0x6220);
3547 alc5505_coef_set(codec, 0x6220, (val | 0x3000)); /* switch Ringbuffer clock to DBUS clock */
3548}
3549
3550static void alc5505_dsp_back_from_halt(struct hda_codec *codec)
3551{
3552 alc5505_coef_set(codec, 0x61b8, 0x04133302);
3553 alc5505_coef_set(codec, 0x61b0, 0x00005b16);
3554 alc5505_coef_set(codec, 0x61b4, 0x040a2b02);
3555 alc5505_coef_set(codec, 0x6230, 0xf80d4011);
3556 alc5505_coef_set(codec, 0x6220, 0x2002010f);
3557 alc5505_coef_set(codec, 0x880c, 0x00000004);
3558}
3559
3560static void alc5505_dsp_init(struct hda_codec *codec)
3561{
3562 unsigned int val;
3563
3564 alc5505_dsp_halt(codec);
3565 alc5505_dsp_back_from_halt(codec);
3566 alc5505_coef_set(codec, 0x61b0, 0x5b14); /* PLL1 control */
3567 alc5505_coef_set(codec, 0x61b0, 0x5b16);
3568 alc5505_coef_set(codec, 0x61b4, 0x04132b00); /* PLL2 control */
3569 alc5505_coef_set(codec, 0x61b4, 0x04132b02);
3570 alc5505_coef_set(codec, 0x61b8, 0x041f3300); /* PLL3 control*/
3571 alc5505_coef_set(codec, 0x61b8, 0x041f3302);
3572 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_CODEC_RESET, 0); /* Function reset */
3573 alc5505_coef_set(codec, 0x61b8, 0x041b3302);
3574 alc5505_coef_set(codec, 0x61b8, 0x04173302);
3575 alc5505_coef_set(codec, 0x61b8, 0x04163302);
3576 alc5505_coef_set(codec, 0x8800, 0x348b328b); /* DRAM control */
3577 alc5505_coef_set(codec, 0x8808, 0x00020022); /* DRAM control */
3578 alc5505_coef_set(codec, 0x8818, 0x00000400); /* DRAM control */
3579
3580 val = alc5505_coef_get(codec, 0x6200) >> 16; /* Read revision ID */
3581 if (val <= 3)
3582 alc5505_coef_set(codec, 0x6220, 0x2002010f); /* I/O PAD Configuration */
3583 else
3584 alc5505_coef_set(codec, 0x6220, 0x6002018f);
3585
3586 alc5505_coef_set(codec, 0x61ac, 0x055525f0); /**/
3587 alc5505_coef_set(codec, 0x61c0, 0x12230080); /* Clock control */
3588 alc5505_coef_set(codec, 0x61b4, 0x040e2b02); /* PLL2 control */
3589 alc5505_coef_set(codec, 0x61bc, 0x010234f8); /* OSC Control */
3590 alc5505_coef_set(codec, 0x880c, 0x00000004); /* DRAM Function control */
3591 alc5505_coef_set(codec, 0x880c, 0x00000003);
3592 alc5505_coef_set(codec, 0x880c, 0x00000010);
Takashi Iwaicd63a5f2013-07-05 12:13:59 +02003593
3594#ifdef HALT_REALTEK_ALC5505
3595 alc5505_dsp_halt(codec);
3596#endif
Kailang Yangad60d502013-06-28 12:03:01 +02003597}
3598
Takashi Iwaicd63a5f2013-07-05 12:13:59 +02003599#ifdef HALT_REALTEK_ALC5505
3600#define alc5505_dsp_suspend(codec) /* NOP */
3601#define alc5505_dsp_resume(codec) /* NOP */
3602#else
3603#define alc5505_dsp_suspend(codec) alc5505_dsp_halt(codec)
3604#define alc5505_dsp_resume(codec) alc5505_dsp_back_from_halt(codec)
3605#endif
3606
Takashi Iwai2a439522011-07-26 09:52:50 +02003607#ifdef CONFIG_PM
Kailang Yangad60d502013-06-28 12:03:01 +02003608static int alc269_suspend(struct hda_codec *codec)
3609{
3610 struct alc_spec *spec = codec->spec;
3611
3612 if (spec->has_alc5505_dsp)
Takashi Iwaicd63a5f2013-07-05 12:13:59 +02003613 alc5505_dsp_suspend(codec);
Kailang Yangad60d502013-06-28 12:03:01 +02003614 return alc_suspend(codec);
3615}
3616
Takashi Iwai1d045db2011-07-07 18:23:21 +02003617static int alc269_resume(struct hda_codec *codec)
3618{
Kailang Yangadcc70b2012-05-25 08:08:38 +02003619 struct alc_spec *spec = codec->spec;
3620
Kailang Yang1387e2d2012-11-08 10:23:18 +01003621 if (spec->codec_variant == ALC269_TYPE_ALC269VB)
3622 alc269vb_toggle_power_output(codec, 0);
3623 if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
Kailang Yangadcc70b2012-05-25 08:08:38 +02003624 (alc_get_coef0(codec) & 0x00ff) == 0x018) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02003625 msleep(150);
3626 }
3627
3628 codec->patch_ops.init(codec);
3629
Kailang Yang1387e2d2012-11-08 10:23:18 +01003630 if (spec->codec_variant == ALC269_TYPE_ALC269VB)
3631 alc269vb_toggle_power_output(codec, 1);
3632 if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
Kailang Yangadcc70b2012-05-25 08:08:38 +02003633 (alc_get_coef0(codec) & 0x00ff) == 0x017) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02003634 msleep(200);
3635 }
3636
Takashi Iwaieeecd9d2015-02-25 15:18:50 +01003637 regcache_sync(codec->core.regmap);
Takashi Iwai1d045db2011-07-07 18:23:21 +02003638 hda_call_check_power_status(codec, 0x01);
Hui Wangf4753712014-08-19 12:07:03 +08003639
3640 /* on some machine, the BIOS will clear the codec gpio data when enter
3641 * suspend, and won't restore the data after resume, so we restore it
3642 * in the driver.
3643 */
Takashi Iwaid261eec2018-06-19 22:32:29 +02003644 if (spec->gpio_data)
3645 alc_write_gpio_data(codec);
Hui Wangf4753712014-08-19 12:07:03 +08003646
Kailang Yangad60d502013-06-28 12:03:01 +02003647 if (spec->has_alc5505_dsp)
Takashi Iwaicd63a5f2013-07-05 12:13:59 +02003648 alc5505_dsp_resume(codec);
Kailang Yangc5177c82013-07-24 14:39:49 +02003649
Takashi Iwai1d045db2011-07-07 18:23:21 +02003650 return 0;
3651}
Takashi Iwai2a439522011-07-26 09:52:50 +02003652#endif /* CONFIG_PM */
Takashi Iwai1d045db2011-07-07 18:23:21 +02003653
David Henningsson108cc102012-07-20 10:37:25 +02003654static void alc269_fixup_pincfg_no_hp_to_lineout(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003655 const struct hda_fixup *fix, int action)
David Henningsson108cc102012-07-20 10:37:25 +02003656{
3657 struct alc_spec *spec = codec->spec;
3658
Takashi Iwai1727a772013-01-10 09:52:52 +01003659 if (action == HDA_FIXUP_ACT_PRE_PROBE)
David Henningsson108cc102012-07-20 10:37:25 +02003660 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
3661}
3662
Jan-Marek Glogowskifdcc9682018-02-14 11:29:15 +01003663static void alc269_fixup_pincfg_U7x7_headset_mic(struct hda_codec *codec,
3664 const struct hda_fixup *fix,
3665 int action)
3666{
3667 unsigned int cfg_headphone = snd_hda_codec_get_pincfg(codec, 0x21);
3668 unsigned int cfg_headset_mic = snd_hda_codec_get_pincfg(codec, 0x19);
3669
3670 if (cfg_headphone && cfg_headset_mic == 0x411111f0)
3671 snd_hda_codec_set_pincfg(codec, 0x19,
3672 (cfg_headphone & ~AC_DEFCFG_DEVICE) |
3673 (AC_JACK_MIC_IN << AC_DEFCFG_DEVICE_SHIFT));
3674}
3675
Takashi Iwai1d045db2011-07-07 18:23:21 +02003676static void alc269_fixup_hweq(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003677 const struct hda_fixup *fix, int action)
Takashi Iwai1d045db2011-07-07 18:23:21 +02003678{
Takashi Iwai98b24882014-08-18 13:47:50 +02003679 if (action == HDA_FIXUP_ACT_INIT)
3680 alc_update_coef_idx(codec, 0x1e, 0, 0x80);
Takashi Iwai1d045db2011-07-07 18:23:21 +02003681}
3682
David Henningsson7c478f02013-10-11 10:18:46 +02003683static void alc269_fixup_headset_mic(struct hda_codec *codec,
3684 const struct hda_fixup *fix, int action)
3685{
3686 struct alc_spec *spec = codec->spec;
3687
3688 if (action == HDA_FIXUP_ACT_PRE_PROBE)
3689 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
3690}
3691
Takashi Iwai1d045db2011-07-07 18:23:21 +02003692static void alc271_fixup_dmic(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003693 const struct hda_fixup *fix, int action)
Takashi Iwai1d045db2011-07-07 18:23:21 +02003694{
3695 static const struct hda_verb verbs[] = {
3696 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
3697 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
3698 {}
3699 };
3700 unsigned int cfg;
3701
Takashi Iwai7639a062015-03-03 10:07:24 +01003702 if (strcmp(codec->core.chip_name, "ALC271X") &&
3703 strcmp(codec->core.chip_name, "ALC269VB"))
Takashi Iwai1d045db2011-07-07 18:23:21 +02003704 return;
3705 cfg = snd_hda_codec_get_pincfg(codec, 0x12);
3706 if (get_defcfg_connect(cfg) == AC_JACK_PORT_FIXED)
3707 snd_hda_sequence_write(codec, verbs);
3708}
3709
Takashi Iwai017f2a12011-07-09 14:42:25 +02003710static void alc269_fixup_pcm_44k(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003711 const struct hda_fixup *fix, int action)
Takashi Iwai017f2a12011-07-09 14:42:25 +02003712{
3713 struct alc_spec *spec = codec->spec;
3714
Takashi Iwai1727a772013-01-10 09:52:52 +01003715 if (action != HDA_FIXUP_ACT_PROBE)
Takashi Iwai017f2a12011-07-09 14:42:25 +02003716 return;
3717
3718 /* Due to a hardware problem on Lenovo Ideadpad, we need to
3719 * fix the sample rate of analog I/O to 44.1kHz
3720 */
Takashi Iwai08c189f2012-12-19 15:22:24 +01003721 spec->gen.stream_analog_playback = &alc269_44k_pcm_analog_playback;
3722 spec->gen.stream_analog_capture = &alc269_44k_pcm_analog_capture;
Takashi Iwai017f2a12011-07-09 14:42:25 +02003723}
3724
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02003725static void alc269_fixup_stereo_dmic(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003726 const struct hda_fixup *fix, int action)
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02003727{
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02003728 /* The digital-mic unit sends PDM (differential signal) instead of
3729 * the standard PCM, thus you can't record a valid mono stream as is.
3730 * Below is a workaround specific to ALC269 to control the dmic
3731 * signal source as mono.
3732 */
Takashi Iwai98b24882014-08-18 13:47:50 +02003733 if (action == HDA_FIXUP_ACT_INIT)
3734 alc_update_coef_idx(codec, 0x07, 0, 0x80);
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02003735}
3736
Takashi Iwai24519912011-08-16 15:08:49 +02003737static void alc269_quanta_automute(struct hda_codec *codec)
3738{
Takashi Iwai08c189f2012-12-19 15:22:24 +01003739 snd_hda_gen_update_outputs(codec);
Takashi Iwai24519912011-08-16 15:08:49 +02003740
Takashi Iwai1687ccc2014-08-18 13:49:35 +02003741 alc_write_coef_idx(codec, 0x0c, 0x680);
3742 alc_write_coef_idx(codec, 0x0c, 0x480);
Takashi Iwai24519912011-08-16 15:08:49 +02003743}
3744
3745static void alc269_fixup_quanta_mute(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003746 const struct hda_fixup *fix, int action)
Takashi Iwai24519912011-08-16 15:08:49 +02003747{
3748 struct alc_spec *spec = codec->spec;
Takashi Iwai1727a772013-01-10 09:52:52 +01003749 if (action != HDA_FIXUP_ACT_PROBE)
Takashi Iwai24519912011-08-16 15:08:49 +02003750 return;
Takashi Iwai08c189f2012-12-19 15:22:24 +01003751 spec->gen.automute_hook = alc269_quanta_automute;
Takashi Iwai24519912011-08-16 15:08:49 +02003752}
3753
David Henningssond240d1d2013-04-15 12:50:02 +02003754static void alc269_x101_hp_automute_hook(struct hda_codec *codec,
Takashi Iwai1a4f69d2014-09-11 15:22:46 +02003755 struct hda_jack_callback *jack)
David Henningssond240d1d2013-04-15 12:50:02 +02003756{
3757 struct alc_spec *spec = codec->spec;
3758 int vref;
3759 msleep(200);
3760 snd_hda_gen_hp_automute(codec, jack);
3761
3762 vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0;
3763 msleep(100);
3764 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3765 vref);
3766 msleep(500);
3767 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3768 vref);
3769}
3770
Tomas Espeletaa2ef03f2019-08-09 16:37:54 +02003771/*
3772 * Magic sequence to make Huawei Matebook X right speaker working (bko#197801)
3773 */
3774struct hda_alc298_mbxinit {
3775 unsigned char value_0x23;
3776 unsigned char value_0x25;
3777};
3778
3779static void alc298_huawei_mbx_stereo_seq(struct hda_codec *codec,
3780 const struct hda_alc298_mbxinit *initval,
3781 bool first)
3782{
3783 snd_hda_codec_write(codec, 0x06, 0, AC_VERB_SET_DIGI_CONVERT_3, 0x0);
3784 alc_write_coef_idx(codec, 0x26, 0xb000);
3785
3786 if (first)
3787 snd_hda_codec_write(codec, 0x21, 0, AC_VERB_GET_PIN_SENSE, 0x0);
3788
3789 snd_hda_codec_write(codec, 0x6, 0, AC_VERB_SET_DIGI_CONVERT_3, 0x80);
3790 alc_write_coef_idx(codec, 0x26, 0xf000);
3791 alc_write_coef_idx(codec, 0x23, initval->value_0x23);
3792
3793 if (initval->value_0x23 != 0x1e)
3794 alc_write_coef_idx(codec, 0x25, initval->value_0x25);
3795
3796 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0x26);
3797 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, 0xb010);
3798}
3799
3800static void alc298_fixup_huawei_mbx_stereo(struct hda_codec *codec,
3801 const struct hda_fixup *fix,
3802 int action)
3803{
3804 /* Initialization magic */
3805 static const struct hda_alc298_mbxinit dac_init[] = {
3806 {0x0c, 0x00}, {0x0d, 0x00}, {0x0e, 0x00}, {0x0f, 0x00},
3807 {0x10, 0x00}, {0x1a, 0x40}, {0x1b, 0x82}, {0x1c, 0x00},
3808 {0x1d, 0x00}, {0x1e, 0x00}, {0x1f, 0x00},
3809 {0x20, 0xc2}, {0x21, 0xc8}, {0x22, 0x26}, {0x23, 0x24},
3810 {0x27, 0xff}, {0x28, 0xff}, {0x29, 0xff}, {0x2a, 0x8f},
3811 {0x2b, 0x02}, {0x2c, 0x48}, {0x2d, 0x34}, {0x2e, 0x00},
3812 {0x2f, 0x00},
3813 {0x30, 0x00}, {0x31, 0x00}, {0x32, 0x00}, {0x33, 0x00},
3814 {0x34, 0x00}, {0x35, 0x01}, {0x36, 0x93}, {0x37, 0x0c},
3815 {0x38, 0x00}, {0x39, 0x00}, {0x3a, 0xf8}, {0x38, 0x80},
3816 {}
3817 };
3818 const struct hda_alc298_mbxinit *seq;
3819
3820 if (action != HDA_FIXUP_ACT_INIT)
3821 return;
3822
3823 /* Start */
3824 snd_hda_codec_write(codec, 0x06, 0, AC_VERB_SET_DIGI_CONVERT_3, 0x00);
3825 snd_hda_codec_write(codec, 0x06, 0, AC_VERB_SET_DIGI_CONVERT_3, 0x80);
3826 alc_write_coef_idx(codec, 0x26, 0xf000);
3827 alc_write_coef_idx(codec, 0x22, 0x31);
3828 alc_write_coef_idx(codec, 0x23, 0x0b);
3829 alc_write_coef_idx(codec, 0x25, 0x00);
3830 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0x26);
3831 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, 0xb010);
3832
3833 for (seq = dac_init; seq->value_0x23; seq++)
3834 alc298_huawei_mbx_stereo_seq(codec, seq, seq == dac_init);
3835}
3836
David Henningssond240d1d2013-04-15 12:50:02 +02003837static void alc269_fixup_x101_headset_mic(struct hda_codec *codec,
3838 const struct hda_fixup *fix, int action)
3839{
3840 struct alc_spec *spec = codec->spec;
3841 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3842 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
3843 spec->gen.hp_automute_hook = alc269_x101_hp_automute_hook;
3844 }
3845}
3846
3847
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003848/* update mute-LED according to the speaker mute state via mic VREF pin */
3849static void alc269_fixup_mic_mute_hook(void *private_data, int enabled)
David Henningsson6d3cd5d2013-01-07 12:03:47 +01003850{
3851 struct hda_codec *codec = private_data;
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003852 struct alc_spec *spec = codec->spec;
3853 unsigned int pinval;
3854
3855 if (spec->mute_led_polarity)
3856 enabled = !enabled;
Takashi Iwai415d5552014-04-03 11:51:21 +02003857 pinval = snd_hda_codec_get_pin_target(codec, spec->mute_led_nid);
3858 pinval &= ~AC_PINCTL_VREFEN;
3859 pinval |= enabled ? AC_PINCTL_VREF_HIZ : AC_PINCTL_VREF_80;
Takashi Iwaie40bdb02018-03-17 22:40:18 +01003860 if (spec->mute_led_nid) {
3861 /* temporarily power up/down for setting VREF */
3862 snd_hda_power_up_pm(codec);
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003863 snd_hda_set_pin_ctl_cache(codec, spec->mute_led_nid, pinval);
Takashi Iwaie40bdb02018-03-17 22:40:18 +01003864 snd_hda_power_down_pm(codec);
3865 }
David Henningsson6d3cd5d2013-01-07 12:03:47 +01003866}
3867
David Henningssond5b6b652013-11-06 10:50:44 +01003868/* Make sure the led works even in runtime suspend */
3869static unsigned int led_power_filter(struct hda_codec *codec,
3870 hda_nid_t nid,
3871 unsigned int power_state)
3872{
3873 struct alc_spec *spec = codec->spec;
3874
Hui Wang50dd9052014-07-08 17:56:15 +08003875 if (power_state != AC_PWRST_D3 || nid == 0 ||
3876 (nid != spec->mute_led_nid && nid != spec->cap_mute_led_nid))
David Henningssond5b6b652013-11-06 10:50:44 +01003877 return power_state;
3878
3879 /* Set pin ctl again, it might have just been set to 0 */
3880 snd_hda_set_pin_ctl(codec, nid,
3881 snd_hda_codec_get_pin_target(codec, nid));
3882
Takashi Iwaicffd3962015-04-09 10:30:25 +02003883 return snd_hda_gen_path_power_filter(codec, nid, power_state);
David Henningssond5b6b652013-11-06 10:50:44 +01003884}
3885
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003886static void alc269_fixup_hp_mute_led(struct hda_codec *codec,
3887 const struct hda_fixup *fix, int action)
David Henningsson6d3cd5d2013-01-07 12:03:47 +01003888{
3889 struct alc_spec *spec = codec->spec;
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003890 const struct dmi_device *dev = NULL;
3891
3892 if (action != HDA_FIXUP_ACT_PRE_PROBE)
3893 return;
3894
3895 while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) {
3896 int pol, pin;
3897 if (sscanf(dev->name, "HP_Mute_LED_%d_%x", &pol, &pin) != 2)
3898 continue;
3899 if (pin < 0x0a || pin >= 0x10)
3900 break;
3901 spec->mute_led_polarity = pol;
3902 spec->mute_led_nid = pin - 0x0a + 0x18;
3903 spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook;
Takashi Iwaifd25a972012-12-20 14:57:18 +01003904 spec->gen.vmaster_mute_enum = 1;
David Henningssond5b6b652013-11-06 10:50:44 +01003905 codec->power_filter = led_power_filter;
Takashi Iwai4e76a882014-02-25 12:21:03 +01003906 codec_dbg(codec,
3907 "Detected mute LED for %x:%d\n", spec->mute_led_nid,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003908 spec->mute_led_polarity);
David Henningsson6d3cd5d2013-01-07 12:03:47 +01003909 break;
3910 }
3911}
3912
Takashi Iwai85c467d2018-05-29 11:38:38 +02003913static void alc269_fixup_hp_mute_led_micx(struct hda_codec *codec,
3914 const struct hda_fixup *fix,
3915 int action, hda_nid_t pin)
David Henningssond06ac142013-02-18 11:41:55 +01003916{
3917 struct alc_spec *spec = codec->spec;
Takashi Iwai85c467d2018-05-29 11:38:38 +02003918
David Henningssond06ac142013-02-18 11:41:55 +01003919 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3920 spec->mute_led_polarity = 0;
Takashi Iwai85c467d2018-05-29 11:38:38 +02003921 spec->mute_led_nid = pin;
David Henningssond06ac142013-02-18 11:41:55 +01003922 spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook;
3923 spec->gen.vmaster_mute_enum = 1;
David Henningssond5b6b652013-11-06 10:50:44 +01003924 codec->power_filter = led_power_filter;
David Henningssond06ac142013-02-18 11:41:55 +01003925 }
3926}
3927
Takashi Iwai85c467d2018-05-29 11:38:38 +02003928static void alc269_fixup_hp_mute_led_mic1(struct hda_codec *codec,
3929 const struct hda_fixup *fix, int action)
3930{
3931 alc269_fixup_hp_mute_led_micx(codec, fix, action, 0x18);
3932}
3933
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003934static void alc269_fixup_hp_mute_led_mic2(struct hda_codec *codec,
3935 const struct hda_fixup *fix, int action)
Takashi Iwai420b0fe2012-03-12 12:35:27 +01003936{
Takashi Iwai85c467d2018-05-29 11:38:38 +02003937 alc269_fixup_hp_mute_led_micx(codec, fix, action, 0x19);
Takashi Iwai420b0fe2012-03-12 12:35:27 +01003938}
3939
Tom Briden7f783bd2017-03-25 10:12:01 +00003940static void alc269_fixup_hp_mute_led_mic3(struct hda_codec *codec,
3941 const struct hda_fixup *fix, int action)
3942{
Takashi Iwai85c467d2018-05-29 11:38:38 +02003943 alc269_fixup_hp_mute_led_micx(codec, fix, action, 0x1b);
Tom Briden7f783bd2017-03-25 10:12:01 +00003944}
3945
Takashi Iwai0f32fd192014-11-19 12:16:14 +01003946/* update LED status via GPIO */
3947static void alc_update_gpio_led(struct hda_codec *codec, unsigned int mask,
3948 bool enabled)
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003949{
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003950 struct alc_spec *spec = codec->spec;
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003951
Takashi Iwai0f32fd192014-11-19 12:16:14 +01003952 if (spec->mute_led_polarity)
3953 enabled = !enabled;
Takashi Iwaid261eec2018-06-19 22:32:29 +02003954 alc_update_gpio_data(codec, mask, !enabled); /* muted -> LED on */
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003955}
3956
Takashi Iwai0f32fd192014-11-19 12:16:14 +01003957/* turn on/off mute LED via GPIO per vmaster hook */
3958static void alc_fixup_gpio_mute_hook(void *private_data, int enabled)
3959{
3960 struct hda_codec *codec = private_data;
3961 struct alc_spec *spec = codec->spec;
3962
3963 alc_update_gpio_led(codec, spec->gpio_mute_led_mask, enabled);
3964}
3965
3966/* turn on/off mic-mute LED via GPIO per capture hook */
Takashi Iwaid03abec2018-06-19 12:29:13 +02003967static void alc_gpio_micmute_update(struct hda_codec *codec)
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003968{
3969 struct alc_spec *spec = codec->spec;
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003970
Takashi Iwaid03abec2018-06-19 12:29:13 +02003971 alc_update_gpio_led(codec, spec->gpio_mic_led_mask,
3972 spec->gen.micmute_led.led_value);
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003973}
3974
Takashi Iwai01e4a272018-06-19 22:47:30 +02003975/* setup mute and mic-mute GPIO bits, add hooks appropriately */
3976static void alc_fixup_hp_gpio_led(struct hda_codec *codec,
3977 int action,
3978 unsigned int mute_mask,
3979 unsigned int micmute_mask)
3980{
3981 struct alc_spec *spec = codec->spec;
3982
3983 alc_fixup_gpio(codec, action, mute_mask | micmute_mask);
3984
3985 if (action != HDA_FIXUP_ACT_PRE_PROBE)
3986 return;
3987 if (mute_mask) {
3988 spec->gpio_mute_led_mask = mute_mask;
3989 spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook;
3990 }
3991 if (micmute_mask) {
3992 spec->gpio_mic_led_mask = micmute_mask;
3993 snd_hda_gen_add_micmute_led(codec, alc_gpio_micmute_update);
3994 }
3995}
3996
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003997static void alc269_fixup_hp_gpio_led(struct hda_codec *codec,
3998 const struct hda_fixup *fix, int action)
3999{
Takashi Iwai01e4a272018-06-19 22:47:30 +02004000 alc_fixup_hp_gpio_led(codec, action, 0x08, 0x10);
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01004001}
4002
Kailang Yangeaa8e5e2014-11-21 15:49:11 +08004003static void alc286_fixup_hp_gpio_led(struct hda_codec *codec,
4004 const struct hda_fixup *fix, int action)
4005{
Takashi Iwai01e4a272018-06-19 22:47:30 +02004006 alc_fixup_hp_gpio_led(codec, action, 0x02, 0x20);
Takashi Iwai1d045db2011-07-07 18:23:21 +02004007}
4008
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004009/* turn on/off mic-mute LED per capture hook */
Takashi Iwaid03abec2018-06-19 12:29:13 +02004010static void alc_cap_micmute_update(struct hda_codec *codec)
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004011{
4012 struct alc_spec *spec = codec->spec;
Takashi Iwaid03abec2018-06-19 12:29:13 +02004013 unsigned int pinval;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004014
Takashi Iwaid03abec2018-06-19 12:29:13 +02004015 if (!spec->cap_mute_led_nid)
4016 return;
Hui Wangfc1fad92014-07-08 17:56:14 +08004017 pinval = snd_hda_codec_get_pin_target(codec, spec->cap_mute_led_nid);
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004018 pinval &= ~AC_PINCTL_VREFEN;
Takashi Iwaid03abec2018-06-19 12:29:13 +02004019 if (spec->gen.micmute_led.led_value)
4020 pinval |= AC_PINCTL_VREF_80;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004021 else
Takashi Iwaid03abec2018-06-19 12:29:13 +02004022 pinval |= AC_PINCTL_VREF_HIZ;
4023 snd_hda_set_pin_ctl_cache(codec, spec->cap_mute_led_nid, pinval);
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004024}
4025
4026static void alc269_fixup_hp_gpio_mic1_led(struct hda_codec *codec,
4027 const struct hda_fixup *fix, int action)
4028{
4029 struct alc_spec *spec = codec->spec;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004030
Takashi Iwai01e4a272018-06-19 22:47:30 +02004031 alc_fixup_hp_gpio_led(codec, action, 0x08, 0);
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004032 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai01e4a272018-06-19 22:47:30 +02004033 /* Like hp_gpio_mic1_led, but also needs GPIO4 low to
4034 * enable headphone amp
4035 */
4036 spec->gpio_mask |= 0x10;
4037 spec->gpio_dir |= 0x10;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004038 spec->cap_mute_led_nid = 0x18;
Takashi Iwaid03abec2018-06-19 12:29:13 +02004039 snd_hda_gen_add_micmute_led(codec, alc_cap_micmute_update);
Hui Wang50dd9052014-07-08 17:56:15 +08004040 codec->power_filter = led_power_filter;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004041 }
4042}
4043
David Henningsson7a5255f2014-10-30 08:26:01 +01004044static void alc280_fixup_hp_gpio4(struct hda_codec *codec,
4045 const struct hda_fixup *fix, int action)
4046{
David Henningsson7a5255f2014-10-30 08:26:01 +01004047 struct alc_spec *spec = codec->spec;
David Henningsson7a5255f2014-10-30 08:26:01 +01004048
Takashi Iwai01e4a272018-06-19 22:47:30 +02004049 alc_fixup_hp_gpio_led(codec, action, 0x08, 0);
David Henningsson7a5255f2014-10-30 08:26:01 +01004050 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
David Henningsson7a5255f2014-10-30 08:26:01 +01004051 spec->cap_mute_led_nid = 0x18;
Takashi Iwaid03abec2018-06-19 12:29:13 +02004052 snd_hda_gen_add_micmute_led(codec, alc_cap_micmute_update);
David Henningsson7a5255f2014-10-30 08:26:01 +01004053 codec->power_filter = led_power_filter;
4054 }
4055}
4056
Takashi Iwai6a30aba2018-04-27 17:17:35 +02004057#if IS_REACHABLE(CONFIG_INPUT)
David Henningsson33f4acd2015-01-07 15:50:13 +01004058static void gpio2_mic_hotkey_event(struct hda_codec *codec,
4059 struct hda_jack_callback *event)
4060{
4061 struct alc_spec *spec = codec->spec;
4062
4063 /* GPIO2 just toggles on a keypress/keyrelease cycle. Therefore
4064 send both key on and key off event for every interrupt. */
Hui Wangc7b60a82015-12-28 11:35:25 +08004065 input_report_key(spec->kb_dev, spec->alc_mute_keycode_map[ALC_KEY_MICMUTE_INDEX], 1);
David Henningsson33f4acd2015-01-07 15:50:13 +01004066 input_sync(spec->kb_dev);
Hui Wangc7b60a82015-12-28 11:35:25 +08004067 input_report_key(spec->kb_dev, spec->alc_mute_keycode_map[ALC_KEY_MICMUTE_INDEX], 0);
David Henningsson33f4acd2015-01-07 15:50:13 +01004068 input_sync(spec->kb_dev);
4069}
David Henningsson33f4acd2015-01-07 15:50:13 +01004070
Kailang3694cb22015-12-28 11:35:24 +08004071static int alc_register_micmute_input_device(struct hda_codec *codec)
4072{
4073 struct alc_spec *spec = codec->spec;
Hui Wangc7b60a82015-12-28 11:35:25 +08004074 int i;
Kailang3694cb22015-12-28 11:35:24 +08004075
4076 spec->kb_dev = input_allocate_device();
4077 if (!spec->kb_dev) {
4078 codec_err(codec, "Out of memory (input_allocate_device)\n");
4079 return -ENOMEM;
4080 }
Hui Wangc7b60a82015-12-28 11:35:25 +08004081
4082 spec->alc_mute_keycode_map[ALC_KEY_MICMUTE_INDEX] = KEY_MICMUTE;
4083
Kailang3694cb22015-12-28 11:35:24 +08004084 spec->kb_dev->name = "Microphone Mute Button";
4085 spec->kb_dev->evbit[0] = BIT_MASK(EV_KEY);
Hui Wangc7b60a82015-12-28 11:35:25 +08004086 spec->kb_dev->keycodesize = sizeof(spec->alc_mute_keycode_map[0]);
4087 spec->kb_dev->keycodemax = ARRAY_SIZE(spec->alc_mute_keycode_map);
4088 spec->kb_dev->keycode = spec->alc_mute_keycode_map;
4089 for (i = 0; i < ARRAY_SIZE(spec->alc_mute_keycode_map); i++)
4090 set_bit(spec->alc_mute_keycode_map[i], spec->kb_dev->keybit);
Kailang3694cb22015-12-28 11:35:24 +08004091
4092 if (input_register_device(spec->kb_dev)) {
4093 codec_err(codec, "input_register_device failed\n");
4094 input_free_device(spec->kb_dev);
4095 spec->kb_dev = NULL;
4096 return -ENOMEM;
4097 }
4098
4099 return 0;
4100}
4101
Takashi Iwai01e4a272018-06-19 22:47:30 +02004102/* GPIO1 = set according to SKU external amp
4103 * GPIO2 = mic mute hotkey
4104 * GPIO3 = mute LED
4105 * GPIO4 = mic mute LED
4106 */
David Henningsson33f4acd2015-01-07 15:50:13 +01004107static void alc280_fixup_hp_gpio2_mic_hotkey(struct hda_codec *codec,
4108 const struct hda_fixup *fix, int action)
4109{
David Henningsson33f4acd2015-01-07 15:50:13 +01004110 struct alc_spec *spec = codec->spec;
4111
Takashi Iwai01e4a272018-06-19 22:47:30 +02004112 alc_fixup_hp_gpio_led(codec, action, 0x08, 0x10);
David Henningsson33f4acd2015-01-07 15:50:13 +01004113 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai1c76aa52018-06-21 16:37:54 +02004114 spec->init_amp = ALC_INIT_DEFAULT;
Kailang3694cb22015-12-28 11:35:24 +08004115 if (alc_register_micmute_input_device(codec) != 0)
David Henningsson33f4acd2015-01-07 15:50:13 +01004116 return;
David Henningsson33f4acd2015-01-07 15:50:13 +01004117
Takashi Iwai01e4a272018-06-19 22:47:30 +02004118 spec->gpio_mask |= 0x06;
4119 spec->gpio_dir |= 0x02;
4120 spec->gpio_data |= 0x02;
Takashi Iwai7639a062015-03-03 10:07:24 +01004121 snd_hda_codec_write_cache(codec, codec->core.afg, 0,
David Henningsson33f4acd2015-01-07 15:50:13 +01004122 AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x04);
Takashi Iwai7639a062015-03-03 10:07:24 +01004123 snd_hda_jack_detect_enable_callback(codec, codec->core.afg,
David Henningsson33f4acd2015-01-07 15:50:13 +01004124 gpio2_mic_hotkey_event);
David Henningsson33f4acd2015-01-07 15:50:13 +01004125 return;
4126 }
4127
4128 if (!spec->kb_dev)
4129 return;
4130
4131 switch (action) {
David Henningsson33f4acd2015-01-07 15:50:13 +01004132 case HDA_FIXUP_ACT_FREE:
4133 input_unregister_device(spec->kb_dev);
David Henningsson33f4acd2015-01-07 15:50:13 +01004134 spec->kb_dev = NULL;
4135 }
David Henningsson33f4acd2015-01-07 15:50:13 +01004136}
4137
Takashi Iwai01e4a272018-06-19 22:47:30 +02004138/* Line2 = mic mute hotkey
4139 * GPIO2 = mic mute LED
4140 */
Kailang3694cb22015-12-28 11:35:24 +08004141static void alc233_fixup_lenovo_line2_mic_hotkey(struct hda_codec *codec,
4142 const struct hda_fixup *fix, int action)
4143{
Kailang3694cb22015-12-28 11:35:24 +08004144 struct alc_spec *spec = codec->spec;
4145
Takashi Iwai01e4a272018-06-19 22:47:30 +02004146 alc_fixup_hp_gpio_led(codec, action, 0, 0x04);
Kailang3694cb22015-12-28 11:35:24 +08004147 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai1c76aa52018-06-21 16:37:54 +02004148 spec->init_amp = ALC_INIT_DEFAULT;
Kailang3694cb22015-12-28 11:35:24 +08004149 if (alc_register_micmute_input_device(codec) != 0)
4150 return;
4151
Kailang3694cb22015-12-28 11:35:24 +08004152 snd_hda_jack_detect_enable_callback(codec, 0x1b,
4153 gpio2_mic_hotkey_event);
Kailang3694cb22015-12-28 11:35:24 +08004154 return;
4155 }
4156
4157 if (!spec->kb_dev)
4158 return;
4159
4160 switch (action) {
Kailang3694cb22015-12-28 11:35:24 +08004161 case HDA_FIXUP_ACT_FREE:
4162 input_unregister_device(spec->kb_dev);
4163 spec->kb_dev = NULL;
4164 }
4165}
Takashi Iwaic4696522018-01-15 10:44:35 +01004166#else /* INPUT */
4167#define alc280_fixup_hp_gpio2_mic_hotkey NULL
4168#define alc233_fixup_lenovo_line2_mic_hotkey NULL
4169#endif /* INPUT */
Kailang3694cb22015-12-28 11:35:24 +08004170
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004171static void alc269_fixup_hp_line1_mic1_led(struct hda_codec *codec,
4172 const struct hda_fixup *fix, int action)
4173{
4174 struct alc_spec *spec = codec->spec;
4175
Takashi Iwai1bce62a2018-06-19 23:15:59 +02004176 alc269_fixup_hp_mute_led_micx(codec, fix, action, 0x1a);
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004177 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004178 spec->cap_mute_led_nid = 0x18;
Takashi Iwaid03abec2018-06-19 12:29:13 +02004179 snd_hda_gen_add_micmute_led(codec, alc_cap_micmute_update);
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004180 }
4181}
4182
Kailang Yang5a367672017-07-21 15:23:53 +08004183static struct coef_fw alc225_pre_hsmode[] = {
4184 UPDATE_COEF(0x4a, 1<<8, 0),
4185 UPDATE_COEFEX(0x57, 0x05, 1<<14, 0),
4186 UPDATE_COEF(0x63, 3<<14, 3<<14),
4187 UPDATE_COEF(0x4a, 3<<4, 2<<4),
4188 UPDATE_COEF(0x4a, 3<<10, 3<<10),
4189 UPDATE_COEF(0x45, 0x3f<<10, 0x34<<10),
4190 UPDATE_COEF(0x4a, 3<<10, 0),
4191 {}
4192};
4193
David Henningsson73bdd592013-04-15 15:44:14 +02004194static void alc_headset_mode_unplugged(struct hda_codec *codec)
4195{
Takashi Iwai54db6c32014-08-18 15:11:19 +02004196 static struct coef_fw coef0255[] = {
Kailang Yang717f43d2019-05-31 17:16:53 +08004197 WRITE_COEF(0x1b, 0x0c0b), /* LDO and MISC control */
Takashi Iwai54db6c32014-08-18 15:11:19 +02004198 WRITE_COEF(0x45, 0xd089), /* UAJ function set to menual mode */
4199 UPDATE_COEFEX(0x57, 0x05, 1<<14, 0), /* Direct Drive HP Amp control(Set to verb control)*/
4200 WRITE_COEF(0x06, 0x6104), /* Set MIC2 Vref gate with HP */
4201 WRITE_COEFEX(0x57, 0x03, 0x8aa6), /* Direct Drive HP Amp control */
4202 {}
4203 };
Kailang Yange69e7e02016-05-30 15:58:28 +08004204 static struct coef_fw coef0256[] = {
4205 WRITE_COEF(0x1b, 0x0c4b), /* LDO and MISC control */
Kailang Yang717f43d2019-05-31 17:16:53 +08004206 WRITE_COEF(0x45, 0xd089), /* UAJ function set to menual mode */
4207 WRITE_COEF(0x06, 0x6104), /* Set MIC2 Vref gate with HP */
4208 WRITE_COEFEX(0x57, 0x03, 0x09a3), /* Direct Drive HP Amp control */
4209 UPDATE_COEFEX(0x57, 0x05, 1<<14, 0), /* Direct Drive HP Amp control(Set to verb control)*/
Kailang Yange69e7e02016-05-30 15:58:28 +08004210 {}
4211 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004212 static struct coef_fw coef0233[] = {
4213 WRITE_COEF(0x1b, 0x0c0b),
4214 WRITE_COEF(0x45, 0xc429),
4215 UPDATE_COEF(0x35, 0x4000, 0),
4216 WRITE_COEF(0x06, 0x2104),
4217 WRITE_COEF(0x1a, 0x0001),
4218 WRITE_COEF(0x26, 0x0004),
4219 WRITE_COEF(0x32, 0x42a3),
4220 {}
4221 };
Kailang Yangf3b70332015-04-08 15:01:17 +08004222 static struct coef_fw coef0288[] = {
4223 UPDATE_COEF(0x4f, 0xfcc0, 0xc400),
4224 UPDATE_COEF(0x50, 0x2000, 0x2000),
4225 UPDATE_COEF(0x56, 0x0006, 0x0006),
4226 UPDATE_COEF(0x66, 0x0008, 0),
4227 UPDATE_COEF(0x67, 0x2000, 0),
4228 {}
4229 };
Kailang Yang89542932017-07-17 15:03:43 +08004230 static struct coef_fw coef0298[] = {
4231 UPDATE_COEF(0x19, 0x1300, 0x0300),
4232 {}
4233 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004234 static struct coef_fw coef0292[] = {
4235 WRITE_COEF(0x76, 0x000e),
4236 WRITE_COEF(0x6c, 0x2400),
4237 WRITE_COEF(0x18, 0x7308),
4238 WRITE_COEF(0x6b, 0xc429),
4239 {}
4240 };
4241 static struct coef_fw coef0293[] = {
4242 UPDATE_COEF(0x10, 7<<8, 6<<8), /* SET Line1 JD to 0 */
4243 UPDATE_COEFEX(0x57, 0x05, 1<<15|1<<13, 0x0), /* SET charge pump by verb */
4244 UPDATE_COEFEX(0x57, 0x03, 1<<10, 1<<10), /* SET EN_OSW to 1 */
4245 UPDATE_COEF(0x1a, 1<<3, 1<<3), /* Combo JD gating with LINE1-VREFO */
4246 WRITE_COEF(0x45, 0xc429), /* Set to TRS type */
4247 UPDATE_COEF(0x4a, 0x000f, 0x000e), /* Combo Jack auto detect */
4248 {}
4249 };
4250 static struct coef_fw coef0668[] = {
4251 WRITE_COEF(0x15, 0x0d40),
4252 WRITE_COEF(0xb7, 0x802b),
4253 {}
4254 };
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004255 static struct coef_fw coef0225[] = {
Kailang Yang5a367672017-07-21 15:23:53 +08004256 UPDATE_COEF(0x63, 3<<14, 0),
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004257 {}
4258 };
Kailang Yang71683c32017-06-20 16:33:50 +08004259 static struct coef_fw coef0274[] = {
4260 UPDATE_COEF(0x4a, 0x0100, 0),
4261 UPDATE_COEFEX(0x57, 0x05, 0x4000, 0),
4262 UPDATE_COEF(0x6b, 0xf000, 0x5000),
4263 UPDATE_COEF(0x4a, 0x0010, 0),
4264 UPDATE_COEF(0x4a, 0x0c00, 0x0c00),
4265 WRITE_COEF(0x45, 0x5289),
4266 UPDATE_COEF(0x4a, 0x0c00, 0),
4267 {}
4268 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004269
Takashi Iwai7639a062015-03-03 10:07:24 +01004270 switch (codec->core.vendor_id) {
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004271 case 0x10ec0255:
Kailang Yange69e7e02016-05-30 15:58:28 +08004272 alc_process_coef_fw(codec, coef0255);
4273 break;
Kailang Yang736f20a2017-10-20 15:06:34 +08004274 case 0x10ec0236:
Kailang Yang7081adf2015-03-30 17:05:37 +08004275 case 0x10ec0256:
Kailang Yange69e7e02016-05-30 15:58:28 +08004276 alc_process_coef_fw(codec, coef0256);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004277 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004278 case 0x10ec0234:
4279 case 0x10ec0274:
4280 case 0x10ec0294:
4281 alc_process_coef_fw(codec, coef0274);
4282 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004283 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004284 case 0x10ec0283:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004285 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02004286 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004287 case 0x10ec0286:
4288 case 0x10ec0288:
Kailang Yang89542932017-07-17 15:03:43 +08004289 alc_process_coef_fw(codec, coef0288);
4290 break;
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004291 case 0x10ec0298:
Kailang Yang89542932017-07-17 15:03:43 +08004292 alc_process_coef_fw(codec, coef0298);
Kailang Yangf3b70332015-04-08 15:01:17 +08004293 alc_process_coef_fw(codec, coef0288);
4294 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004295 case 0x10ec0292:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004296 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02004297 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004298 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004299 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004300 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004301 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004302 alc_process_coef_fw(codec, coef0668);
David Henningsson73bdd592013-04-15 15:44:14 +02004303 break;
Kailang Yangc2b691e2018-01-17 15:22:55 +08004304 case 0x10ec0215:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004305 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004306 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08004307 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004308 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08004309 case 0x10ec0299:
Kailang Yang4d4b0c52019-01-09 16:23:37 +08004310 alc_process_coef_fw(codec, alc225_pre_hsmode);
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004311 alc_process_coef_fw(codec, coef0225);
4312 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08004313 case 0x10ec0867:
4314 alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
4315 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004316 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01004317 codec_dbg(codec, "Headset jack set to unplugged mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02004318}
4319
4320
4321static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin,
4322 hda_nid_t mic_pin)
4323{
Takashi Iwai54db6c32014-08-18 15:11:19 +02004324 static struct coef_fw coef0255[] = {
4325 WRITE_COEFEX(0x57, 0x03, 0x8aa6),
4326 WRITE_COEF(0x06, 0x6100), /* Set MIC2 Vref gate to normal */
4327 {}
4328 };
Kailang Yang717f43d2019-05-31 17:16:53 +08004329 static struct coef_fw coef0256[] = {
4330 UPDATE_COEFEX(0x57, 0x05, 1<<14, 1<<14), /* Direct Drive HP Amp control(Set to verb control)*/
4331 WRITE_COEFEX(0x57, 0x03, 0x09a3),
4332 WRITE_COEF(0x06, 0x6100), /* Set MIC2 Vref gate to normal */
4333 {}
4334 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004335 static struct coef_fw coef0233[] = {
4336 UPDATE_COEF(0x35, 0, 1<<14),
4337 WRITE_COEF(0x06, 0x2100),
4338 WRITE_COEF(0x1a, 0x0021),
4339 WRITE_COEF(0x26, 0x008c),
4340 {}
4341 };
Kailang Yangf3b70332015-04-08 15:01:17 +08004342 static struct coef_fw coef0288[] = {
Kailang Yang89542932017-07-17 15:03:43 +08004343 UPDATE_COEF(0x4f, 0x00c0, 0),
Kailang Yangf3b70332015-04-08 15:01:17 +08004344 UPDATE_COEF(0x50, 0x2000, 0),
4345 UPDATE_COEF(0x56, 0x0006, 0),
4346 UPDATE_COEF(0x4f, 0xfcc0, 0xc400),
4347 UPDATE_COEF(0x66, 0x0008, 0x0008),
4348 UPDATE_COEF(0x67, 0x2000, 0x2000),
4349 {}
4350 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004351 static struct coef_fw coef0292[] = {
4352 WRITE_COEF(0x19, 0xa208),
4353 WRITE_COEF(0x2e, 0xacf0),
4354 {}
4355 };
4356 static struct coef_fw coef0293[] = {
4357 UPDATE_COEFEX(0x57, 0x05, 0, 1<<15|1<<13), /* SET charge pump by verb */
4358 UPDATE_COEFEX(0x57, 0x03, 1<<10, 0), /* SET EN_OSW to 0 */
4359 UPDATE_COEF(0x1a, 1<<3, 0), /* Combo JD gating without LINE1-VREFO */
4360 {}
4361 };
4362 static struct coef_fw coef0688[] = {
4363 WRITE_COEF(0xb7, 0x802b),
4364 WRITE_COEF(0xb5, 0x1040),
4365 UPDATE_COEF(0xc3, 0, 1<<12),
4366 {}
4367 };
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004368 static struct coef_fw coef0225[] = {
4369 UPDATE_COEFEX(0x57, 0x05, 1<<14, 1<<14),
4370 UPDATE_COEF(0x4a, 3<<4, 2<<4),
4371 UPDATE_COEF(0x63, 3<<14, 0),
4372 {}
4373 };
Kailang Yang71683c32017-06-20 16:33:50 +08004374 static struct coef_fw coef0274[] = {
4375 UPDATE_COEFEX(0x57, 0x05, 0x4000, 0x4000),
4376 UPDATE_COEF(0x4a, 0x0010, 0),
4377 UPDATE_COEF(0x6b, 0xf000, 0),
4378 {}
4379 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004380
Takashi Iwai7639a062015-03-03 10:07:24 +01004381 switch (codec->core.vendor_id) {
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004382 case 0x10ec0255:
4383 alc_write_coef_idx(codec, 0x45, 0xc489);
4384 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02004385 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004386 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4387 break;
Kailang Yang717f43d2019-05-31 17:16:53 +08004388 case 0x10ec0236:
4389 case 0x10ec0256:
4390 alc_write_coef_idx(codec, 0x45, 0xc489);
4391 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4392 alc_process_coef_fw(codec, coef0256);
4393 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4394 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004395 case 0x10ec0234:
4396 case 0x10ec0274:
4397 case 0x10ec0294:
4398 alc_write_coef_idx(codec, 0x45, 0x4689);
4399 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4400 alc_process_coef_fw(codec, coef0274);
4401 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4402 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004403 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004404 case 0x10ec0283:
4405 alc_write_coef_idx(codec, 0x45, 0xc429);
4406 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02004407 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02004408 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4409 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004410 case 0x10ec0286:
4411 case 0x10ec0288:
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004412 case 0x10ec0298:
Kailang Yangf3b70332015-04-08 15:01:17 +08004413 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4414 alc_process_coef_fw(codec, coef0288);
4415 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4416 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004417 case 0x10ec0292:
4418 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02004419 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02004420 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004421 case 0x10ec0293:
4422 /* Set to TRS mode */
4423 alc_write_coef_idx(codec, 0x45, 0xc429);
4424 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02004425 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004426 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4427 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08004428 case 0x10ec0867:
4429 alc_update_coefex_idx(codec, 0x57, 0x5, 0, 1<<14);
4430 /* fallthru */
Kailang Yang9eb5d0e2017-01-17 15:40:25 +08004431 case 0x10ec0221:
David Henningsson1f8b46c2015-05-12 14:38:15 +02004432 case 0x10ec0662:
4433 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4434 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4435 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004436 case 0x10ec0668:
4437 alc_write_coef_idx(codec, 0x11, 0x0001);
4438 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02004439 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02004440 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4441 break;
Kailang Yangc2b691e2018-01-17 15:22:55 +08004442 case 0x10ec0215:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004443 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004444 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08004445 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004446 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08004447 case 0x10ec0299:
Kailang Yang5a367672017-07-21 15:23:53 +08004448 alc_process_coef_fw(codec, alc225_pre_hsmode);
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004449 alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x31<<10);
4450 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4451 alc_process_coef_fw(codec, coef0225);
4452 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4453 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004454 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01004455 codec_dbg(codec, "Headset jack set to mic-in mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02004456}
4457
4458static void alc_headset_mode_default(struct hda_codec *codec)
4459{
David Henningsson2ae95572016-02-25 09:37:05 +01004460 static struct coef_fw coef0225[] = {
Kailang Yang5a367672017-07-21 15:23:53 +08004461 UPDATE_COEF(0x45, 0x3f<<10, 0x30<<10),
4462 UPDATE_COEF(0x45, 0x3f<<10, 0x31<<10),
4463 UPDATE_COEF(0x49, 3<<8, 0<<8),
4464 UPDATE_COEF(0x4a, 3<<4, 3<<4),
4465 UPDATE_COEF(0x63, 3<<14, 0),
4466 UPDATE_COEF(0x67, 0xf000, 0x3000),
David Henningsson2ae95572016-02-25 09:37:05 +01004467 {}
4468 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004469 static struct coef_fw coef0255[] = {
4470 WRITE_COEF(0x45, 0xc089),
4471 WRITE_COEF(0x45, 0xc489),
4472 WRITE_COEFEX(0x57, 0x03, 0x8ea6),
4473 WRITE_COEF(0x49, 0x0049),
4474 {}
4475 };
Kailang Yang717f43d2019-05-31 17:16:53 +08004476 static struct coef_fw coef0256[] = {
4477 WRITE_COEF(0x45, 0xc489),
4478 WRITE_COEFEX(0x57, 0x03, 0x0da3),
4479 WRITE_COEF(0x49, 0x0049),
4480 UPDATE_COEFEX(0x57, 0x05, 1<<14, 0), /* Direct Drive HP Amp control(Set to verb control)*/
4481 WRITE_COEF(0x06, 0x6100),
4482 {}
4483 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004484 static struct coef_fw coef0233[] = {
4485 WRITE_COEF(0x06, 0x2100),
4486 WRITE_COEF(0x32, 0x4ea3),
4487 {}
4488 };
Kailang Yangf3b70332015-04-08 15:01:17 +08004489 static struct coef_fw coef0288[] = {
4490 UPDATE_COEF(0x4f, 0xfcc0, 0xc400), /* Set to TRS type */
4491 UPDATE_COEF(0x50, 0x2000, 0x2000),
4492 UPDATE_COEF(0x56, 0x0006, 0x0006),
4493 UPDATE_COEF(0x66, 0x0008, 0),
4494 UPDATE_COEF(0x67, 0x2000, 0),
4495 {}
4496 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004497 static struct coef_fw coef0292[] = {
4498 WRITE_COEF(0x76, 0x000e),
4499 WRITE_COEF(0x6c, 0x2400),
4500 WRITE_COEF(0x6b, 0xc429),
4501 WRITE_COEF(0x18, 0x7308),
4502 {}
4503 };
4504 static struct coef_fw coef0293[] = {
4505 UPDATE_COEF(0x4a, 0x000f, 0x000e), /* Combo Jack auto detect */
4506 WRITE_COEF(0x45, 0xC429), /* Set to TRS type */
4507 UPDATE_COEF(0x1a, 1<<3, 0), /* Combo JD gating without LINE1-VREFO */
4508 {}
4509 };
4510 static struct coef_fw coef0688[] = {
4511 WRITE_COEF(0x11, 0x0041),
4512 WRITE_COEF(0x15, 0x0d40),
4513 WRITE_COEF(0xb7, 0x802b),
4514 {}
4515 };
Kailang Yang71683c32017-06-20 16:33:50 +08004516 static struct coef_fw coef0274[] = {
4517 WRITE_COEF(0x45, 0x4289),
4518 UPDATE_COEF(0x4a, 0x0010, 0x0010),
4519 UPDATE_COEF(0x6b, 0x0f00, 0),
4520 UPDATE_COEF(0x49, 0x0300, 0x0300),
4521 {}
4522 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004523
Takashi Iwai7639a062015-03-03 10:07:24 +01004524 switch (codec->core.vendor_id) {
Kailang Yangc2b691e2018-01-17 15:22:55 +08004525 case 0x10ec0215:
David Henningsson2ae95572016-02-25 09:37:05 +01004526 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004527 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08004528 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004529 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08004530 case 0x10ec0299:
Kailang Yang5a367672017-07-21 15:23:53 +08004531 alc_process_coef_fw(codec, alc225_pre_hsmode);
David Henningsson2ae95572016-02-25 09:37:05 +01004532 alc_process_coef_fw(codec, coef0225);
4533 break;
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004534 case 0x10ec0255:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004535 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004536 break;
Kailang Yang717f43d2019-05-31 17:16:53 +08004537 case 0x10ec0236:
4538 case 0x10ec0256:
4539 alc_write_coef_idx(codec, 0x1b, 0x0e4b);
4540 alc_write_coef_idx(codec, 0x45, 0xc089);
4541 msleep(50);
4542 alc_process_coef_fw(codec, coef0256);
4543 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004544 case 0x10ec0234:
4545 case 0x10ec0274:
4546 case 0x10ec0294:
4547 alc_process_coef_fw(codec, coef0274);
4548 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004549 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004550 case 0x10ec0283:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004551 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02004552 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004553 case 0x10ec0286:
4554 case 0x10ec0288:
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004555 case 0x10ec0298:
Kailang Yangf3b70332015-04-08 15:01:17 +08004556 alc_process_coef_fw(codec, coef0288);
4557 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004558 case 0x10ec0292:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004559 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02004560 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004561 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004562 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004563 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004564 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004565 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02004566 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08004567 case 0x10ec0867:
4568 alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
4569 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004570 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01004571 codec_dbg(codec, "Headset jack set to headphone (default) mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02004572}
4573
4574/* Iphone type */
4575static void alc_headset_mode_ctia(struct hda_codec *codec)
4576{
Kailang Yang89542932017-07-17 15:03:43 +08004577 int val;
4578
Takashi Iwai54db6c32014-08-18 15:11:19 +02004579 static struct coef_fw coef0255[] = {
4580 WRITE_COEF(0x45, 0xd489), /* Set to CTIA type */
4581 WRITE_COEF(0x1b, 0x0c2b),
4582 WRITE_COEFEX(0x57, 0x03, 0x8ea6),
4583 {}
4584 };
Kailang Yange69e7e02016-05-30 15:58:28 +08004585 static struct coef_fw coef0256[] = {
4586 WRITE_COEF(0x45, 0xd489), /* Set to CTIA type */
Kailang Yang717f43d2019-05-31 17:16:53 +08004587 WRITE_COEF(0x1b, 0x0e6b),
Kailang Yange69e7e02016-05-30 15:58:28 +08004588 {}
4589 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004590 static struct coef_fw coef0233[] = {
4591 WRITE_COEF(0x45, 0xd429),
4592 WRITE_COEF(0x1b, 0x0c2b),
4593 WRITE_COEF(0x32, 0x4ea3),
4594 {}
4595 };
Kailang Yangf3b70332015-04-08 15:01:17 +08004596 static struct coef_fw coef0288[] = {
4597 UPDATE_COEF(0x50, 0x2000, 0x2000),
4598 UPDATE_COEF(0x56, 0x0006, 0x0006),
4599 UPDATE_COEF(0x66, 0x0008, 0),
4600 UPDATE_COEF(0x67, 0x2000, 0),
4601 {}
4602 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004603 static struct coef_fw coef0292[] = {
4604 WRITE_COEF(0x6b, 0xd429),
4605 WRITE_COEF(0x76, 0x0008),
4606 WRITE_COEF(0x18, 0x7388),
4607 {}
4608 };
4609 static struct coef_fw coef0293[] = {
4610 WRITE_COEF(0x45, 0xd429), /* Set to ctia type */
4611 UPDATE_COEF(0x10, 7<<8, 7<<8), /* SET Line1 JD to 1 */
4612 {}
4613 };
4614 static struct coef_fw coef0688[] = {
4615 WRITE_COEF(0x11, 0x0001),
4616 WRITE_COEF(0x15, 0x0d60),
4617 WRITE_COEF(0xc3, 0x0000),
4618 {}
4619 };
Kailang Yang5a367672017-07-21 15:23:53 +08004620 static struct coef_fw coef0225_1[] = {
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004621 UPDATE_COEF(0x45, 0x3f<<10, 0x35<<10),
Kailang Yang5a367672017-07-21 15:23:53 +08004622 UPDATE_COEF(0x63, 3<<14, 2<<14),
4623 {}
4624 };
4625 static struct coef_fw coef0225_2[] = {
4626 UPDATE_COEF(0x45, 0x3f<<10, 0x35<<10),
4627 UPDATE_COEF(0x63, 3<<14, 1<<14),
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004628 {}
4629 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004630
Takashi Iwai7639a062015-03-03 10:07:24 +01004631 switch (codec->core.vendor_id) {
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004632 case 0x10ec0255:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004633 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004634 break;
Kailang Yang736f20a2017-10-20 15:06:34 +08004635 case 0x10ec0236:
Kailang Yange69e7e02016-05-30 15:58:28 +08004636 case 0x10ec0256:
4637 alc_process_coef_fw(codec, coef0256);
4638 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004639 case 0x10ec0234:
4640 case 0x10ec0274:
4641 case 0x10ec0294:
4642 alc_write_coef_idx(codec, 0x45, 0xd689);
4643 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004644 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004645 case 0x10ec0283:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004646 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02004647 break;
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004648 case 0x10ec0298:
Kailang Yang89542932017-07-17 15:03:43 +08004649 val = alc_read_coef_idx(codec, 0x50);
4650 if (val & (1 << 12)) {
4651 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0020);
4652 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400);
4653 msleep(300);
4654 } else {
4655 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0010);
4656 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400);
4657 msleep(300);
4658 }
4659 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004660 case 0x10ec0286:
4661 case 0x10ec0288:
4662 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400);
4663 msleep(300);
4664 alc_process_coef_fw(codec, coef0288);
4665 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004666 case 0x10ec0292:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004667 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02004668 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004669 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004670 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004671 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004672 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004673 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02004674 break;
Kailang Yangc2b691e2018-01-17 15:22:55 +08004675 case 0x10ec0215:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004676 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004677 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08004678 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004679 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08004680 case 0x10ec0299:
Kailang Yang5a367672017-07-21 15:23:53 +08004681 val = alc_read_coef_idx(codec, 0x45);
4682 if (val & (1 << 9))
4683 alc_process_coef_fw(codec, coef0225_2);
4684 else
4685 alc_process_coef_fw(codec, coef0225_1);
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004686 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08004687 case 0x10ec0867:
4688 alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
4689 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004690 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01004691 codec_dbg(codec, "Headset jack set to iPhone-style headset mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02004692}
4693
4694/* Nokia type */
4695static void alc_headset_mode_omtp(struct hda_codec *codec)
4696{
Takashi Iwai54db6c32014-08-18 15:11:19 +02004697 static struct coef_fw coef0255[] = {
4698 WRITE_COEF(0x45, 0xe489), /* Set to OMTP Type */
4699 WRITE_COEF(0x1b, 0x0c2b),
4700 WRITE_COEFEX(0x57, 0x03, 0x8ea6),
4701 {}
4702 };
Kailang Yange69e7e02016-05-30 15:58:28 +08004703 static struct coef_fw coef0256[] = {
4704 WRITE_COEF(0x45, 0xe489), /* Set to OMTP Type */
Kailang Yang717f43d2019-05-31 17:16:53 +08004705 WRITE_COEF(0x1b, 0x0e6b),
Kailang Yange69e7e02016-05-30 15:58:28 +08004706 {}
4707 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004708 static struct coef_fw coef0233[] = {
4709 WRITE_COEF(0x45, 0xe429),
4710 WRITE_COEF(0x1b, 0x0c2b),
4711 WRITE_COEF(0x32, 0x4ea3),
4712 {}
4713 };
Kailang Yangf3b70332015-04-08 15:01:17 +08004714 static struct coef_fw coef0288[] = {
4715 UPDATE_COEF(0x50, 0x2000, 0x2000),
4716 UPDATE_COEF(0x56, 0x0006, 0x0006),
4717 UPDATE_COEF(0x66, 0x0008, 0),
4718 UPDATE_COEF(0x67, 0x2000, 0),
4719 {}
4720 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004721 static struct coef_fw coef0292[] = {
4722 WRITE_COEF(0x6b, 0xe429),
4723 WRITE_COEF(0x76, 0x0008),
4724 WRITE_COEF(0x18, 0x7388),
4725 {}
4726 };
4727 static struct coef_fw coef0293[] = {
4728 WRITE_COEF(0x45, 0xe429), /* Set to omtp type */
4729 UPDATE_COEF(0x10, 7<<8, 7<<8), /* SET Line1 JD to 1 */
4730 {}
4731 };
4732 static struct coef_fw coef0688[] = {
4733 WRITE_COEF(0x11, 0x0001),
4734 WRITE_COEF(0x15, 0x0d50),
4735 WRITE_COEF(0xc3, 0x0000),
4736 {}
4737 };
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004738 static struct coef_fw coef0225[] = {
4739 UPDATE_COEF(0x45, 0x3f<<10, 0x39<<10),
Kailang Yang5a367672017-07-21 15:23:53 +08004740 UPDATE_COEF(0x63, 3<<14, 2<<14),
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004741 {}
4742 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004743
Takashi Iwai7639a062015-03-03 10:07:24 +01004744 switch (codec->core.vendor_id) {
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004745 case 0x10ec0255:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004746 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004747 break;
Kailang Yang736f20a2017-10-20 15:06:34 +08004748 case 0x10ec0236:
Kailang Yange69e7e02016-05-30 15:58:28 +08004749 case 0x10ec0256:
4750 alc_process_coef_fw(codec, coef0256);
4751 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004752 case 0x10ec0234:
4753 case 0x10ec0274:
4754 case 0x10ec0294:
4755 alc_write_coef_idx(codec, 0x45, 0xe689);
4756 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004757 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004758 case 0x10ec0283:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004759 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02004760 break;
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004761 case 0x10ec0298:
4762 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0010);/* Headset output enable */
Kailang Yang89542932017-07-17 15:03:43 +08004763 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xe400);
4764 msleep(300);
4765 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004766 case 0x10ec0286:
4767 case 0x10ec0288:
4768 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xe400);
4769 msleep(300);
4770 alc_process_coef_fw(codec, coef0288);
4771 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004772 case 0x10ec0292:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004773 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02004774 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004775 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004776 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004777 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004778 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004779 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02004780 break;
Kailang Yangc2b691e2018-01-17 15:22:55 +08004781 case 0x10ec0215:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004782 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004783 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08004784 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004785 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08004786 case 0x10ec0299:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004787 alc_process_coef_fw(codec, coef0225);
4788 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004789 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01004790 codec_dbg(codec, "Headset jack set to Nokia-style headset mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02004791}
4792
4793static void alc_determine_headset_type(struct hda_codec *codec)
4794{
4795 int val;
4796 bool is_ctia = false;
4797 struct alc_spec *spec = codec->spec;
Takashi Iwai54db6c32014-08-18 15:11:19 +02004798 static struct coef_fw coef0255[] = {
4799 WRITE_COEF(0x45, 0xd089), /* combo jack auto switch control(Check type)*/
4800 WRITE_COEF(0x49, 0x0149), /* combo jack auto switch control(Vref
4801 conteol) */
4802 {}
4803 };
Kailang Yangf3b70332015-04-08 15:01:17 +08004804 static struct coef_fw coef0288[] = {
4805 UPDATE_COEF(0x4f, 0xfcc0, 0xd400), /* Check Type */
4806 {}
4807 };
Kailang Yang89542932017-07-17 15:03:43 +08004808 static struct coef_fw coef0298[] = {
4809 UPDATE_COEF(0x50, 0x2000, 0x2000),
4810 UPDATE_COEF(0x56, 0x0006, 0x0006),
4811 UPDATE_COEF(0x66, 0x0008, 0),
4812 UPDATE_COEF(0x67, 0x2000, 0),
4813 UPDATE_COEF(0x19, 0x1300, 0x1300),
4814 {}
4815 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004816 static struct coef_fw coef0293[] = {
4817 UPDATE_COEF(0x4a, 0x000f, 0x0008), /* Combo Jack auto detect */
4818 WRITE_COEF(0x45, 0xD429), /* Set to ctia type */
4819 {}
4820 };
4821 static struct coef_fw coef0688[] = {
4822 WRITE_COEF(0x11, 0x0001),
4823 WRITE_COEF(0xb7, 0x802b),
4824 WRITE_COEF(0x15, 0x0d60),
4825 WRITE_COEF(0xc3, 0x0c00),
4826 {}
4827 };
Kailang Yang71683c32017-06-20 16:33:50 +08004828 static struct coef_fw coef0274[] = {
4829 UPDATE_COEF(0x4a, 0x0010, 0),
4830 UPDATE_COEF(0x4a, 0x8000, 0),
4831 WRITE_COEF(0x45, 0xd289),
4832 UPDATE_COEF(0x49, 0x0300, 0x0300),
4833 {}
4834 };
David Henningsson73bdd592013-04-15 15:44:14 +02004835
Takashi Iwai7639a062015-03-03 10:07:24 +01004836 switch (codec->core.vendor_id) {
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004837 case 0x10ec0255:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004838 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004839 msleep(300);
4840 val = alc_read_coef_idx(codec, 0x46);
4841 is_ctia = (val & 0x0070) == 0x0070;
4842 break;
Kailang Yang717f43d2019-05-31 17:16:53 +08004843 case 0x10ec0236:
4844 case 0x10ec0256:
4845 alc_write_coef_idx(codec, 0x1b, 0x0e4b);
4846 alc_write_coef_idx(codec, 0x06, 0x6104);
4847 alc_write_coefex_idx(codec, 0x57, 0x3, 0x09a3);
4848
4849 snd_hda_codec_write(codec, 0x21, 0,
4850 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
4851 msleep(80);
4852 snd_hda_codec_write(codec, 0x21, 0,
4853 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
4854
4855 alc_process_coef_fw(codec, coef0255);
4856 msleep(300);
4857 val = alc_read_coef_idx(codec, 0x46);
4858 is_ctia = (val & 0x0070) == 0x0070;
4859
4860 alc_write_coefex_idx(codec, 0x57, 0x3, 0x0da3);
4861 alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
4862
4863 snd_hda_codec_write(codec, 0x21, 0,
4864 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
4865 msleep(80);
4866 snd_hda_codec_write(codec, 0x21, 0,
4867 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
4868 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004869 case 0x10ec0234:
4870 case 0x10ec0274:
4871 case 0x10ec0294:
4872 alc_process_coef_fw(codec, coef0274);
4873 msleep(80);
4874 val = alc_read_coef_idx(codec, 0x46);
4875 is_ctia = (val & 0x00f0) == 0x00f0;
4876 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004877 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004878 case 0x10ec0283:
4879 alc_write_coef_idx(codec, 0x45, 0xd029);
4880 msleep(300);
4881 val = alc_read_coef_idx(codec, 0x46);
4882 is_ctia = (val & 0x0070) == 0x0070;
4883 break;
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004884 case 0x10ec0298:
Kailang Yang89542932017-07-17 15:03:43 +08004885 snd_hda_codec_write(codec, 0x21, 0,
4886 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
4887 msleep(100);
4888 snd_hda_codec_write(codec, 0x21, 0,
4889 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
4890 msleep(200);
4891
4892 val = alc_read_coef_idx(codec, 0x50);
4893 if (val & (1 << 12)) {
4894 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0020);
4895 alc_process_coef_fw(codec, coef0288);
4896 msleep(350);
4897 val = alc_read_coef_idx(codec, 0x50);
4898 is_ctia = (val & 0x0070) == 0x0070;
4899 } else {
4900 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0010);
4901 alc_process_coef_fw(codec, coef0288);
4902 msleep(350);
4903 val = alc_read_coef_idx(codec, 0x50);
4904 is_ctia = (val & 0x0070) == 0x0070;
4905 }
4906 alc_process_coef_fw(codec, coef0298);
4907 snd_hda_codec_write(codec, 0x21, 0,
4908 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP);
4909 msleep(75);
4910 snd_hda_codec_write(codec, 0x21, 0,
4911 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
4912 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004913 case 0x10ec0286:
4914 case 0x10ec0288:
4915 alc_process_coef_fw(codec, coef0288);
4916 msleep(350);
4917 val = alc_read_coef_idx(codec, 0x50);
4918 is_ctia = (val & 0x0070) == 0x0070;
4919 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004920 case 0x10ec0292:
4921 alc_write_coef_idx(codec, 0x6b, 0xd429);
4922 msleep(300);
4923 val = alc_read_coef_idx(codec, 0x6c);
4924 is_ctia = (val & 0x001c) == 0x001c;
4925 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004926 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004927 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004928 msleep(300);
4929 val = alc_read_coef_idx(codec, 0x46);
4930 is_ctia = (val & 0x0070) == 0x0070;
4931 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004932 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004933 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02004934 msleep(300);
4935 val = alc_read_coef_idx(codec, 0xbe);
4936 is_ctia = (val & 0x1c02) == 0x1c02;
4937 break;
Kailang Yangc2b691e2018-01-17 15:22:55 +08004938 case 0x10ec0215:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004939 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004940 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08004941 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004942 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08004943 case 0x10ec0299:
Kailang Yangda911b12018-01-05 16:50:08 +08004944 snd_hda_codec_write(codec, 0x21, 0,
4945 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
4946 msleep(80);
4947 snd_hda_codec_write(codec, 0x21, 0,
4948 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
4949
Kailang Yang5a367672017-07-21 15:23:53 +08004950 alc_process_coef_fw(codec, alc225_pre_hsmode);
4951 alc_update_coef_idx(codec, 0x67, 0xf000, 0x1000);
4952 val = alc_read_coef_idx(codec, 0x45);
4953 if (val & (1 << 9)) {
4954 alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x34<<10);
4955 alc_update_coef_idx(codec, 0x49, 3<<8, 2<<8);
4956 msleep(800);
4957 val = alc_read_coef_idx(codec, 0x46);
4958 is_ctia = (val & 0x00f0) == 0x00f0;
4959 } else {
4960 alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x34<<10);
4961 alc_update_coef_idx(codec, 0x49, 3<<8, 1<<8);
4962 msleep(800);
4963 val = alc_read_coef_idx(codec, 0x46);
4964 is_ctia = (val & 0x00f0) == 0x00f0;
4965 }
4966 alc_update_coef_idx(codec, 0x4a, 7<<6, 7<<6);
4967 alc_update_coef_idx(codec, 0x4a, 3<<4, 3<<4);
4968 alc_update_coef_idx(codec, 0x67, 0xf000, 0x3000);
Kailang Yangda911b12018-01-05 16:50:08 +08004969
4970 snd_hda_codec_write(codec, 0x21, 0,
4971 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
4972 msleep(80);
4973 snd_hda_codec_write(codec, 0x21, 0,
4974 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004975 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08004976 case 0x10ec0867:
4977 is_ctia = true;
4978 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004979 }
4980
Takashi Iwai4e76a882014-02-25 12:21:03 +01004981 codec_dbg(codec, "Headset jack detected iPhone-style headset: %s\n",
David Henningsson73bdd592013-04-15 15:44:14 +02004982 is_ctia ? "yes" : "no");
4983 spec->current_headset_type = is_ctia ? ALC_HEADSET_TYPE_CTIA : ALC_HEADSET_TYPE_OMTP;
4984}
4985
4986static void alc_update_headset_mode(struct hda_codec *codec)
4987{
4988 struct alc_spec *spec = codec->spec;
4989
4990 hda_nid_t mux_pin = spec->gen.imux_pins[spec->gen.cur_mux[0]];
Takashi Iwai35a39f92019-02-01 11:19:50 +01004991 hda_nid_t hp_pin = alc_get_hp_pin(spec);
David Henningsson73bdd592013-04-15 15:44:14 +02004992
4993 int new_headset_mode;
4994
4995 if (!snd_hda_jack_detect(codec, hp_pin))
4996 new_headset_mode = ALC_HEADSET_MODE_UNPLUGGED;
4997 else if (mux_pin == spec->headset_mic_pin)
4998 new_headset_mode = ALC_HEADSET_MODE_HEADSET;
4999 else if (mux_pin == spec->headphone_mic_pin)
5000 new_headset_mode = ALC_HEADSET_MODE_MIC;
5001 else
5002 new_headset_mode = ALC_HEADSET_MODE_HEADPHONE;
5003
David Henningsson5959a6b2013-11-12 11:10:57 +01005004 if (new_headset_mode == spec->current_headset_mode) {
5005 snd_hda_gen_update_outputs(codec);
David Henningsson73bdd592013-04-15 15:44:14 +02005006 return;
David Henningsson5959a6b2013-11-12 11:10:57 +01005007 }
David Henningsson73bdd592013-04-15 15:44:14 +02005008
5009 switch (new_headset_mode) {
5010 case ALC_HEADSET_MODE_UNPLUGGED:
5011 alc_headset_mode_unplugged(codec);
Kailang Yangaeac1a02019-05-16 16:10:44 +08005012 spec->current_headset_mode = ALC_HEADSET_MODE_UNKNOWN;
5013 spec->current_headset_type = ALC_HEADSET_TYPE_UNKNOWN;
David Henningsson73bdd592013-04-15 15:44:14 +02005014 spec->gen.hp_jack_present = false;
5015 break;
5016 case ALC_HEADSET_MODE_HEADSET:
5017 if (spec->current_headset_type == ALC_HEADSET_TYPE_UNKNOWN)
5018 alc_determine_headset_type(codec);
5019 if (spec->current_headset_type == ALC_HEADSET_TYPE_CTIA)
5020 alc_headset_mode_ctia(codec);
5021 else if (spec->current_headset_type == ALC_HEADSET_TYPE_OMTP)
5022 alc_headset_mode_omtp(codec);
5023 spec->gen.hp_jack_present = true;
5024 break;
5025 case ALC_HEADSET_MODE_MIC:
5026 alc_headset_mode_mic_in(codec, hp_pin, spec->headphone_mic_pin);
5027 spec->gen.hp_jack_present = false;
5028 break;
5029 case ALC_HEADSET_MODE_HEADPHONE:
5030 alc_headset_mode_default(codec);
5031 spec->gen.hp_jack_present = true;
5032 break;
5033 }
5034 if (new_headset_mode != ALC_HEADSET_MODE_MIC) {
5035 snd_hda_set_pin_ctl_cache(codec, hp_pin,
5036 AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN);
David Henningsson1f8b46c2015-05-12 14:38:15 +02005037 if (spec->headphone_mic_pin && spec->headphone_mic_pin != hp_pin)
David Henningsson73bdd592013-04-15 15:44:14 +02005038 snd_hda_set_pin_ctl_cache(codec, spec->headphone_mic_pin,
5039 PIN_VREFHIZ);
5040 }
5041 spec->current_headset_mode = new_headset_mode;
5042
5043 snd_hda_gen_update_outputs(codec);
5044}
5045
5046static void alc_update_headset_mode_hook(struct hda_codec *codec,
Takashi Iwai7fe30712014-01-30 17:59:02 +01005047 struct snd_kcontrol *kcontrol,
5048 struct snd_ctl_elem_value *ucontrol)
David Henningsson73bdd592013-04-15 15:44:14 +02005049{
5050 alc_update_headset_mode(codec);
5051}
5052
Takashi Iwai1a4f69d2014-09-11 15:22:46 +02005053static void alc_update_headset_jack_cb(struct hda_codec *codec,
5054 struct hda_jack_callback *jack)
David Henningsson73bdd592013-04-15 15:44:14 +02005055{
David Henningsson73bdd592013-04-15 15:44:14 +02005056 snd_hda_gen_hp_automute(codec, jack);
5057}
5058
5059static void alc_probe_headset_mode(struct hda_codec *codec)
5060{
5061 int i;
5062 struct alc_spec *spec = codec->spec;
5063 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
5064
5065 /* Find mic pins */
5066 for (i = 0; i < cfg->num_inputs; i++) {
5067 if (cfg->inputs[i].is_headset_mic && !spec->headset_mic_pin)
5068 spec->headset_mic_pin = cfg->inputs[i].pin;
5069 if (cfg->inputs[i].is_headphone_mic && !spec->headphone_mic_pin)
5070 spec->headphone_mic_pin = cfg->inputs[i].pin;
5071 }
5072
Takashi Iwai0bed2aa2018-06-19 12:45:53 +02005073 WARN_ON(spec->gen.cap_sync_hook);
David Henningsson73bdd592013-04-15 15:44:14 +02005074 spec->gen.cap_sync_hook = alc_update_headset_mode_hook;
5075 spec->gen.automute_hook = alc_update_headset_mode;
5076 spec->gen.hp_automute_hook = alc_update_headset_jack_cb;
5077}
5078
5079static void alc_fixup_headset_mode(struct hda_codec *codec,
5080 const struct hda_fixup *fix, int action)
5081{
5082 struct alc_spec *spec = codec->spec;
5083
5084 switch (action) {
5085 case HDA_FIXUP_ACT_PRE_PROBE:
5086 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC | HDA_PINCFG_HEADPHONE_MIC;
5087 break;
5088 case HDA_FIXUP_ACT_PROBE:
5089 alc_probe_headset_mode(codec);
5090 break;
5091 case HDA_FIXUP_ACT_INIT:
Kailang Yangaeac1a02019-05-16 16:10:44 +08005092 if (is_s3_resume(codec) || is_s4_resume(codec)) {
5093 spec->current_headset_mode = ALC_HEADSET_MODE_UNKNOWN;
5094 spec->current_headset_type = ALC_HEADSET_TYPE_UNKNOWN;
5095 }
David Henningsson73bdd592013-04-15 15:44:14 +02005096 alc_update_headset_mode(codec);
5097 break;
5098 }
5099}
5100
5101static void alc_fixup_headset_mode_no_hp_mic(struct hda_codec *codec,
5102 const struct hda_fixup *fix, int action)
5103{
5104 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5105 struct alc_spec *spec = codec->spec;
5106 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
5107 }
5108 else
5109 alc_fixup_headset_mode(codec, fix, action);
5110}
5111
Kailang Yang31278992014-03-03 15:27:22 +08005112static void alc255_set_default_jack_type(struct hda_codec *codec)
5113{
5114 /* Set to iphone type */
Kailang Yange69e7e02016-05-30 15:58:28 +08005115 static struct coef_fw alc255fw[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02005116 WRITE_COEF(0x1b, 0x880b),
5117 WRITE_COEF(0x45, 0xd089),
5118 WRITE_COEF(0x1b, 0x080b),
5119 WRITE_COEF(0x46, 0x0004),
5120 WRITE_COEF(0x1b, 0x0c0b),
5121 {}
5122 };
Kailang Yange69e7e02016-05-30 15:58:28 +08005123 static struct coef_fw alc256fw[] = {
5124 WRITE_COEF(0x1b, 0x884b),
5125 WRITE_COEF(0x45, 0xd089),
5126 WRITE_COEF(0x1b, 0x084b),
5127 WRITE_COEF(0x46, 0x0004),
5128 WRITE_COEF(0x1b, 0x0c4b),
5129 {}
5130 };
5131 switch (codec->core.vendor_id) {
5132 case 0x10ec0255:
5133 alc_process_coef_fw(codec, alc255fw);
5134 break;
Kailang Yang736f20a2017-10-20 15:06:34 +08005135 case 0x10ec0236:
Kailang Yange69e7e02016-05-30 15:58:28 +08005136 case 0x10ec0256:
5137 alc_process_coef_fw(codec, alc256fw);
5138 break;
5139 }
Kailang Yang31278992014-03-03 15:27:22 +08005140 msleep(30);
5141}
5142
Kailang Yang9a22a8f52013-11-08 15:54:49 +08005143static void alc_fixup_headset_mode_alc255(struct hda_codec *codec,
5144 const struct hda_fixup *fix, int action)
5145{
5146 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Kailang Yang31278992014-03-03 15:27:22 +08005147 alc255_set_default_jack_type(codec);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08005148 }
5149 alc_fixup_headset_mode(codec, fix, action);
5150}
5151
Kailang Yang31278992014-03-03 15:27:22 +08005152static void alc_fixup_headset_mode_alc255_no_hp_mic(struct hda_codec *codec,
5153 const struct hda_fixup *fix, int action)
5154{
5155 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5156 struct alc_spec *spec = codec->spec;
5157 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
5158 alc255_set_default_jack_type(codec);
5159 }
5160 else
5161 alc_fixup_headset_mode(codec, fix, action);
5162}
5163
Kailang Yange1e62b92015-04-08 16:01:22 +08005164static void alc288_update_headset_jack_cb(struct hda_codec *codec,
5165 struct hda_jack_callback *jack)
5166{
5167 struct alc_spec *spec = codec->spec;
Kailang Yange1e62b92015-04-08 16:01:22 +08005168
5169 alc_update_headset_jack_cb(codec, jack);
5170 /* Headset Mic enable or disable, only for Dell Dino */
Takashi Iwaid44a6862018-06-19 23:04:03 +02005171 alc_update_gpio_data(codec, 0x40, spec->gen.hp_jack_present);
Kailang Yange1e62b92015-04-08 16:01:22 +08005172}
5173
5174static void alc_fixup_headset_mode_dell_alc288(struct hda_codec *codec,
5175 const struct hda_fixup *fix, int action)
5176{
5177 alc_fixup_headset_mode(codec, fix, action);
5178 if (action == HDA_FIXUP_ACT_PROBE) {
5179 struct alc_spec *spec = codec->spec;
Takashi Iwaid44a6862018-06-19 23:04:03 +02005180 /* toggled via hp_automute_hook */
5181 spec->gpio_mask |= 0x40;
5182 spec->gpio_dir |= 0x40;
Kailang Yange1e62b92015-04-08 16:01:22 +08005183 spec->gen.hp_automute_hook = alc288_update_headset_jack_cb;
5184 }
5185}
5186
Hui Wang493a52a2014-01-14 14:07:36 +08005187static void alc_fixup_auto_mute_via_amp(struct hda_codec *codec,
5188 const struct hda_fixup *fix, int action)
5189{
5190 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5191 struct alc_spec *spec = codec->spec;
5192 spec->gen.auto_mute_via_amp = 1;
5193 }
5194}
5195
Takashi Iwai9b745ab2014-03-07 08:37:19 +01005196static void alc_fixup_no_shutup(struct hda_codec *codec,
5197 const struct hda_fixup *fix, int action)
5198{
Takashi Iwaiefe55732018-06-15 11:55:02 +02005199 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai9b745ab2014-03-07 08:37:19 +01005200 struct alc_spec *spec = codec->spec;
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01005201 spec->no_shutup_pins = 1;
Takashi Iwai9b745ab2014-03-07 08:37:19 +01005202 }
5203}
5204
Gabriele Mazzotta5e6db662014-05-20 18:58:26 +02005205static void alc_fixup_disable_aamix(struct hda_codec *codec,
5206 const struct hda_fixup *fix, int action)
5207{
5208 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5209 struct alc_spec *spec = codec->spec;
5210 /* Disable AA-loopback as it causes white noise */
5211 spec->gen.mixer_nid = 0;
5212 }
5213}
5214
Takashi Iwai7f57d802015-09-24 17:36:51 +02005215/* fixup for Thinkpad docks: add dock pins, avoid HP parser fixup */
5216static void alc_fixup_tpt440_dock(struct hda_codec *codec,
5217 const struct hda_fixup *fix, int action)
5218{
5219 static const struct hda_pintbl pincfgs[] = {
5220 { 0x16, 0x21211010 }, /* dock headphone */
5221 { 0x19, 0x21a11010 }, /* dock mic */
5222 { }
5223 };
5224 struct alc_spec *spec = codec->spec;
5225
5226 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Hui Wang871b9062019-08-14 12:09:08 +08005227 spec->reboot_notify = snd_hda_gen_reboot_notify; /* reduce noise */
Takashi Iwai7f57d802015-09-24 17:36:51 +02005228 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
5229 codec->power_save_node = 0; /* avoid click noises */
5230 snd_hda_apply_pincfgs(codec, pincfgs);
5231 }
5232}
5233
Kailang Yang61fcf8e2018-02-02 15:26:46 +08005234static void alc_fixup_tpt470_dock(struct hda_codec *codec,
5235 const struct hda_fixup *fix, int action)
5236{
5237 static const struct hda_pintbl pincfgs[] = {
5238 { 0x17, 0x21211010 }, /* dock headphone */
5239 { 0x19, 0x21a11010 }, /* dock mic */
5240 { }
5241 };
Takashi Iwai54947cd2018-12-03 10:44:15 +01005242 /* Assure the speaker pin to be coupled with DAC NID 0x03; otherwise
5243 * the speaker output becomes too low by some reason on Thinkpads with
5244 * ALC298 codec
5245 */
Michał Mirosławcaf3c042020-01-03 10:23:48 +01005246 static const hda_nid_t preferred_pairs[] = {
Takashi Iwai54947cd2018-12-03 10:44:15 +01005247 0x14, 0x03, 0x17, 0x02, 0x21, 0x02,
5248 0
5249 };
Kailang Yang61fcf8e2018-02-02 15:26:46 +08005250 struct alc_spec *spec = codec->spec;
5251
5252 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai54947cd2018-12-03 10:44:15 +01005253 spec->gen.preferred_dacs = preferred_pairs;
Kailang Yang61fcf8e2018-02-02 15:26:46 +08005254 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
Takashi Iwai71db96d2018-02-26 15:36:38 +01005255 snd_hda_apply_pincfgs(codec, pincfgs);
5256 } else if (action == HDA_FIXUP_ACT_INIT) {
Kailang Yang61fcf8e2018-02-02 15:26:46 +08005257 /* Enable DOCK device */
5258 snd_hda_codec_write(codec, 0x17, 0,
5259 AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0);
5260 /* Enable DOCK device */
5261 snd_hda_codec_write(codec, 0x19, 0,
5262 AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0);
Kailang Yang61fcf8e2018-02-02 15:26:46 +08005263 }
5264}
5265
Gabriele Mazzotta9476d3692015-04-19 19:00:40 +02005266static void alc_shutup_dell_xps13(struct hda_codec *codec)
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02005267{
5268 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01005269 int hp_pin = alc_get_hp_pin(spec);
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02005270
Gabriele Mazzotta9476d3692015-04-19 19:00:40 +02005271 /* Prevent pop noises when headphones are plugged in */
5272 snd_hda_codec_write(codec, hp_pin, 0,
5273 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
5274 msleep(20);
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02005275}
5276
5277static void alc_fixup_dell_xps13(struct hda_codec *codec,
5278 const struct hda_fixup *fix, int action)
5279{
Takashi Iwai3e1b0c42015-04-27 10:43:22 +02005280 struct alc_spec *spec = codec->spec;
5281 struct hda_input_mux *imux = &spec->gen.input_mux;
5282 int i;
Gabriele Mazzottaf38663a2014-08-08 19:34:40 +02005283
Takashi Iwai3e1b0c42015-04-27 10:43:22 +02005284 switch (action) {
5285 case HDA_FIXUP_ACT_PRE_PROBE:
5286 /* mic pin 0x19 must be initialized with Vref Hi-Z, otherwise
5287 * it causes a click noise at start up
5288 */
5289 snd_hda_codec_set_pin_target(codec, 0x19, PIN_VREFHIZ);
Takashi Iwaiefe55732018-06-15 11:55:02 +02005290 spec->shutup = alc_shutup_dell_xps13;
Takashi Iwai3e1b0c42015-04-27 10:43:22 +02005291 break;
5292 case HDA_FIXUP_ACT_PROBE:
Gabriele Mazzottaf38663a2014-08-08 19:34:40 +02005293 /* Make the internal mic the default input source. */
5294 for (i = 0; i < imux->num_items; i++) {
5295 if (spec->gen.imux_pins[i] == 0x12) {
5296 spec->gen.cur_mux[0] = i;
5297 break;
5298 }
5299 }
Takashi Iwai3e1b0c42015-04-27 10:43:22 +02005300 break;
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02005301 }
5302}
5303
David Henningsson1f8b46c2015-05-12 14:38:15 +02005304static void alc_fixup_headset_mode_alc662(struct hda_codec *codec,
5305 const struct hda_fixup *fix, int action)
5306{
5307 struct alc_spec *spec = codec->spec;
5308
5309 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5310 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
5311 spec->gen.hp_mic = 1; /* Mic-in is same pin as headphone */
David Henningssonb40eda62015-05-28 09:40:23 +02005312
5313 /* Disable boost for mic-in permanently. (This code is only called
5314 from quirks that guarantee that the headphone is at NID 0x1b.) */
5315 snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000);
5316 snd_hda_override_wcaps(codec, 0x1b, get_wcaps(codec, 0x1b) & ~AC_WCAP_IN_AMP);
David Henningsson1f8b46c2015-05-12 14:38:15 +02005317 } else
5318 alc_fixup_headset_mode(codec, fix, action);
5319}
5320
David Henningsson73bdd592013-04-15 15:44:14 +02005321static void alc_fixup_headset_mode_alc668(struct hda_codec *codec,
5322 const struct hda_fixup *fix, int action)
5323{
5324 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
David Henningsson73bdd592013-04-15 15:44:14 +02005325 alc_write_coef_idx(codec, 0xc4, 0x8000);
Takashi Iwai98b24882014-08-18 13:47:50 +02005326 alc_update_coef_idx(codec, 0xc2, ~0xfe, 0);
David Henningsson73bdd592013-04-15 15:44:14 +02005327 snd_hda_set_pin_ctl_cache(codec, 0x18, 0);
5328 }
5329 alc_fixup_headset_mode(codec, fix, action);
5330}
5331
Chih-Chung Changbde7bc62013-08-05 16:38:42 +08005332/* Returns the nid of the external mic input pin, or 0 if it cannot be found. */
5333static int find_ext_mic_pin(struct hda_codec *codec)
5334{
5335 struct alc_spec *spec = codec->spec;
5336 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
5337 hda_nid_t nid;
5338 unsigned int defcfg;
5339 int i;
5340
5341 for (i = 0; i < cfg->num_inputs; i++) {
5342 if (cfg->inputs[i].type != AUTO_PIN_MIC)
5343 continue;
5344 nid = cfg->inputs[i].pin;
5345 defcfg = snd_hda_codec_get_pincfg(codec, nid);
5346 if (snd_hda_get_input_pin_attr(defcfg) == INPUT_PIN_ATTR_INT)
5347 continue;
5348 return nid;
5349 }
5350
5351 return 0;
5352}
5353
Dylan Reid08a978d2012-11-18 22:56:40 -08005354static void alc271_hp_gate_mic_jack(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01005355 const struct hda_fixup *fix,
Dylan Reid08a978d2012-11-18 22:56:40 -08005356 int action)
5357{
5358 struct alc_spec *spec = codec->spec;
5359
Takashi Iwai0db75792013-01-23 13:57:20 +01005360 if (action == HDA_FIXUP_ACT_PROBE) {
Chih-Chung Changbde7bc62013-08-05 16:38:42 +08005361 int mic_pin = find_ext_mic_pin(codec);
Takashi Iwai35a39f92019-02-01 11:19:50 +01005362 int hp_pin = alc_get_hp_pin(spec);
Chih-Chung Changbde7bc62013-08-05 16:38:42 +08005363
5364 if (snd_BUG_ON(!mic_pin || !hp_pin))
Takashi Iwai0db75792013-01-23 13:57:20 +01005365 return;
Chih-Chung Changbde7bc62013-08-05 16:38:42 +08005366 snd_hda_jack_set_gating_jack(codec, mic_pin, hp_pin);
Takashi Iwai0db75792013-01-23 13:57:20 +01005367 }
Dylan Reid08a978d2012-11-18 22:56:40 -08005368}
David Henningsson693b6132012-06-22 19:12:10 +02005369
Kai-Heng Feng1099f482019-10-03 12:39:19 +08005370static void alc256_fixup_dell_xps_13_headphone_noise2(struct hda_codec *codec,
5371 const struct hda_fixup *fix,
5372 int action)
5373{
5374 if (action != HDA_FIXUP_ACT_PRE_PROBE)
5375 return;
5376
5377 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 0, HDA_AMP_VOLMASK, 1);
5378 snd_hda_override_wcaps(codec, 0x1a, get_wcaps(codec, 0x1a) & ~AC_WCAP_IN_AMP);
5379}
5380
David Henningsson3e0d6112013-04-22 14:30:14 +02005381static void alc269_fixup_limit_int_mic_boost(struct hda_codec *codec,
5382 const struct hda_fixup *fix,
5383 int action)
5384{
5385 struct alc_spec *spec = codec->spec;
5386 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
5387 int i;
5388
5389 /* The mic boosts on level 2 and 3 are too noisy
5390 on the internal mic input.
5391 Therefore limit the boost to 0 or 1. */
5392
5393 if (action != HDA_FIXUP_ACT_PROBE)
5394 return;
5395
5396 for (i = 0; i < cfg->num_inputs; i++) {
5397 hda_nid_t nid = cfg->inputs[i].pin;
5398 unsigned int defcfg;
5399 if (cfg->inputs[i].type != AUTO_PIN_MIC)
5400 continue;
5401 defcfg = snd_hda_codec_get_pincfg(codec, nid);
5402 if (snd_hda_get_input_pin_attr(defcfg) != INPUT_PIN_ATTR_INT)
5403 continue;
5404
5405 snd_hda_override_amp_caps(codec, nid, HDA_INPUT,
5406 (0x00 << AC_AMPCAP_OFFSET_SHIFT) |
5407 (0x01 << AC_AMPCAP_NUM_STEPS_SHIFT) |
5408 (0x2f << AC_AMPCAP_STEP_SIZE_SHIFT) |
5409 (0 << AC_AMPCAP_MUTE_SHIFT));
5410 }
5411}
5412
Kailang Yangcd217a62013-08-22 10:15:24 +02005413static void alc283_hp_automute_hook(struct hda_codec *codec,
Takashi Iwai1a4f69d2014-09-11 15:22:46 +02005414 struct hda_jack_callback *jack)
Kailang Yangcd217a62013-08-22 10:15:24 +02005415{
5416 struct alc_spec *spec = codec->spec;
5417 int vref;
5418
5419 msleep(200);
5420 snd_hda_gen_hp_automute(codec, jack);
5421
5422 vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0;
5423
5424 msleep(600);
5425 snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5426 vref);
5427}
5428
Kailang Yangcd217a62013-08-22 10:15:24 +02005429static void alc283_fixup_chromebook(struct hda_codec *codec,
5430 const struct hda_fixup *fix, int action)
5431{
5432 struct alc_spec *spec = codec->spec;
Kailang Yangcd217a62013-08-22 10:15:24 +02005433
5434 switch (action) {
5435 case HDA_FIXUP_ACT_PRE_PROBE:
Kailang Yang0202e992013-12-02 15:20:15 +08005436 snd_hda_override_wcaps(codec, 0x03, 0);
Takashi Iwaid2e92702013-10-30 07:50:53 +01005437 /* Disable AA-loopback as it causes white noise */
5438 spec->gen.mixer_nid = 0;
Kailang Yang38070212013-11-01 15:57:35 +08005439 break;
5440 case HDA_FIXUP_ACT_INIT:
Kailang Yangde9481c2014-04-07 16:41:52 +08005441 /* MIC2-VREF control */
5442 /* Set to manual mode */
Takashi Iwai98b24882014-08-18 13:47:50 +02005443 alc_update_coef_idx(codec, 0x06, 0x000c, 0);
Kailang Yang0202e992013-12-02 15:20:15 +08005444 /* Enable Line1 input control by verb */
Takashi Iwai98b24882014-08-18 13:47:50 +02005445 alc_update_coef_idx(codec, 0x1a, 0, 1 << 4);
Kailang Yang0202e992013-12-02 15:20:15 +08005446 break;
5447 }
5448}
5449
5450static void alc283_fixup_sense_combo_jack(struct hda_codec *codec,
5451 const struct hda_fixup *fix, int action)
5452{
5453 struct alc_spec *spec = codec->spec;
Kailang Yang0202e992013-12-02 15:20:15 +08005454
5455 switch (action) {
5456 case HDA_FIXUP_ACT_PRE_PROBE:
Kailang Yangcd217a62013-08-22 10:15:24 +02005457 spec->gen.hp_automute_hook = alc283_hp_automute_hook;
5458 break;
5459 case HDA_FIXUP_ACT_INIT:
5460 /* MIC2-VREF control */
5461 /* Set to manual mode */
Takashi Iwai98b24882014-08-18 13:47:50 +02005462 alc_update_coef_idx(codec, 0x06, 0x000c, 0);
Kailang Yangcd217a62013-08-22 10:15:24 +02005463 break;
5464 }
5465}
5466
Takashi Iwai7bba2152013-09-06 15:45:38 +02005467/* mute tablet speaker pin (0x14) via dock plugging in addition */
5468static void asus_tx300_automute(struct hda_codec *codec)
5469{
5470 struct alc_spec *spec = codec->spec;
5471 snd_hda_gen_update_outputs(codec);
5472 if (snd_hda_jack_detect(codec, 0x1b))
5473 spec->gen.mute_bits |= (1ULL << 0x14);
5474}
5475
5476static void alc282_fixup_asus_tx300(struct hda_codec *codec,
5477 const struct hda_fixup *fix, int action)
5478{
5479 struct alc_spec *spec = codec->spec;
Takashi Iwai7bba2152013-09-06 15:45:38 +02005480 static const struct hda_pintbl dock_pins[] = {
5481 { 0x1b, 0x21114000 }, /* dock speaker pin */
5482 {}
5483 };
Takashi Iwai7bba2152013-09-06 15:45:38 +02005484
5485 switch (action) {
5486 case HDA_FIXUP_ACT_PRE_PROBE:
Takashi Iwai1c76aa52018-06-21 16:37:54 +02005487 spec->init_amp = ALC_INIT_DEFAULT;
Takashi Iwaiae065f12018-06-19 23:00:03 +02005488 /* TX300 needs to set up GPIO2 for the speaker amp */
5489 alc_setup_gpio(codec, 0x04);
Takashi Iwai7bba2152013-09-06 15:45:38 +02005490 snd_hda_apply_pincfgs(codec, dock_pins);
5491 spec->gen.auto_mute_via_amp = 1;
5492 spec->gen.automute_hook = asus_tx300_automute;
5493 snd_hda_jack_detect_enable_callback(codec, 0x1b,
Takashi Iwai7bba2152013-09-06 15:45:38 +02005494 snd_hda_gen_hp_automute);
5495 break;
Takashi Iwai5579cd62018-06-19 22:22:41 +02005496 case HDA_FIXUP_ACT_PROBE:
5497 spec->init_amp = ALC_INIT_DEFAULT;
5498 break;
Takashi Iwai7bba2152013-09-06 15:45:38 +02005499 case HDA_FIXUP_ACT_BUILD:
5500 /* this is a bit tricky; give more sane names for the main
5501 * (tablet) speaker and the dock speaker, respectively
5502 */
Takashi Iwai56798e62017-04-11 08:10:52 +02005503 rename_ctl(codec, "Speaker Playback Switch",
5504 "Dock Speaker Playback Switch");
5505 rename_ctl(codec, "Bass Speaker Playback Switch",
5506 "Speaker Playback Switch");
Takashi Iwai7bba2152013-09-06 15:45:38 +02005507 break;
5508 }
5509}
5510
David Henningsson338cae52013-10-07 10:39:59 +02005511static void alc290_fixup_mono_speakers(struct hda_codec *codec,
5512 const struct hda_fixup *fix, int action)
5513{
David Henningsson0f4881d2013-12-20 16:08:13 +01005514 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5515 /* DAC node 0x03 is giving mono output. We therefore want to
5516 make sure 0x14 (front speaker) and 0x15 (headphones) use the
5517 stereo DAC, while leaving 0x17 (bass speaker) for node 0x03. */
Michał Mirosławcaf3c042020-01-03 10:23:48 +01005518 static const hda_nid_t conn1[] = { 0x0c };
5519 snd_hda_override_conn_list(codec, 0x14, ARRAY_SIZE(conn1), conn1);
5520 snd_hda_override_conn_list(codec, 0x15, ARRAY_SIZE(conn1), conn1);
David Henningsson0f4881d2013-12-20 16:08:13 +01005521 }
David Henningsson338cae52013-10-07 10:39:59 +02005522}
5523
Hui Wangdd9aa332016-08-01 10:20:32 +08005524static void alc298_fixup_speaker_volume(struct hda_codec *codec,
5525 const struct hda_fixup *fix, int action)
5526{
5527 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5528 /* The speaker is routed to the Node 0x06 by a mistake, as a result
5529 we can't adjust the speaker's volume since this node does not has
5530 Amp-out capability. we change the speaker's route to:
5531 Node 0x02 (Audio Output) -> Node 0x0c (Audio Mixer) -> Node 0x17 (
5532 Pin Complex), since Node 0x02 has Amp-out caps, we can adjust
5533 speaker's volume now. */
5534
Michał Mirosławcaf3c042020-01-03 10:23:48 +01005535 static const hda_nid_t conn1[] = { 0x0c };
5536 snd_hda_override_conn_list(codec, 0x17, ARRAY_SIZE(conn1), conn1);
Hui Wangdd9aa332016-08-01 10:20:32 +08005537 }
5538}
5539
Takashi Iwaie312a862018-03-06 12:14:17 +01005540/* disable DAC3 (0x06) selection on NID 0x17 as it has no volume amp control */
5541static void alc295_fixup_disable_dac3(struct hda_codec *codec,
5542 const struct hda_fixup *fix, int action)
5543{
5544 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Michał Mirosławcaf3c042020-01-03 10:23:48 +01005545 static const hda_nid_t conn[] = { 0x02, 0x03 };
5546 snd_hda_override_conn_list(codec, 0x17, ARRAY_SIZE(conn), conn);
Takashi Iwaie312a862018-03-06 12:14:17 +01005547 }
5548}
5549
Jaroslav Kyselad2cd7952019-11-29 15:40:27 +01005550/* force NID 0x17 (Bass Speaker) to DAC1 to share it with the main speaker */
5551static void alc285_fixup_speaker2_to_dac1(struct hda_codec *codec,
5552 const struct hda_fixup *fix, int action)
5553{
5554 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Michał Mirosławcaf3c042020-01-03 10:23:48 +01005555 static const hda_nid_t conn[] = { 0x02 };
5556 snd_hda_override_conn_list(codec, 0x17, ARRAY_SIZE(conn), conn);
Jaroslav Kyselad2cd7952019-11-29 15:40:27 +01005557 }
5558}
5559
Keith Packard98973f22015-07-15 12:14:39 -07005560/* Hook to update amp GPIO4 for automute */
5561static void alc280_hp_gpio4_automute_hook(struct hda_codec *codec,
5562 struct hda_jack_callback *jack)
5563{
5564 struct alc_spec *spec = codec->spec;
5565
5566 snd_hda_gen_hp_automute(codec, jack);
5567 /* mute_led_polarity is set to 0, so we pass inverted value here */
5568 alc_update_gpio_led(codec, 0x10, !spec->gen.hp_jack_present);
5569}
5570
5571/* Manage GPIOs for HP EliteBook Folio 9480m.
5572 *
5573 * GPIO4 is the headphone amplifier power control
5574 * GPIO3 is the audio output mute indicator LED
5575 */
5576
5577static void alc280_fixup_hp_9480m(struct hda_codec *codec,
5578 const struct hda_fixup *fix,
5579 int action)
5580{
5581 struct alc_spec *spec = codec->spec;
Keith Packard98973f22015-07-15 12:14:39 -07005582
Takashi Iwai01e4a272018-06-19 22:47:30 +02005583 alc_fixup_hp_gpio_led(codec, action, 0x08, 0);
Keith Packard98973f22015-07-15 12:14:39 -07005584 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai01e4a272018-06-19 22:47:30 +02005585 /* amp at GPIO4; toggled via alc280_hp_gpio4_automute_hook() */
5586 spec->gpio_mask |= 0x10;
5587 spec->gpio_dir |= 0x10;
Keith Packard98973f22015-07-15 12:14:39 -07005588 spec->gen.hp_automute_hook = alc280_hp_gpio4_automute_hook;
Keith Packard98973f22015-07-15 12:14:39 -07005589 }
5590}
5591
Takashi Iwaiae065f12018-06-19 23:00:03 +02005592static void alc275_fixup_gpio4_off(struct hda_codec *codec,
5593 const struct hda_fixup *fix,
5594 int action)
5595{
5596 struct alc_spec *spec = codec->spec;
5597
5598 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5599 spec->gpio_mask |= 0x04;
5600 spec->gpio_dir |= 0x04;
5601 /* set data bit low */
5602 }
5603}
5604
Kailang Yangca169cc2017-04-25 16:17:40 +08005605static void alc233_alc662_fixup_lenovo_dual_codecs(struct hda_codec *codec,
5606 const struct hda_fixup *fix,
5607 int action)
5608{
5609 alc_fixup_dual_codecs(codec, fix, action);
5610 switch (action) {
5611 case HDA_FIXUP_ACT_PRE_PROBE:
5612 /* override card longname to provide a unique UCM profile */
5613 strcpy(codec->card->longname, "HDAudio-Lenovo-DualCodecs");
5614 break;
5615 case HDA_FIXUP_ACT_BUILD:
5616 /* rename Capture controls depending on the codec */
5617 rename_ctl(codec, "Capture Volume",
5618 codec->addr == 0 ?
5619 "Rear-Panel Capture Volume" :
5620 "Front-Panel Capture Volume");
5621 rename_ctl(codec, "Capture Switch",
5622 codec->addr == 0 ?
5623 "Rear-Panel Capture Switch" :
5624 "Front-Panel Capture Switch");
5625 break;
5626 }
5627}
5628
Kailang Yang92266652017-12-14 15:28:58 +08005629/* Forcibly assign NID 0x03 to HP/LO while NID 0x02 to SPK for EQ */
5630static void alc274_fixup_bind_dacs(struct hda_codec *codec,
5631 const struct hda_fixup *fix, int action)
5632{
5633 struct alc_spec *spec = codec->spec;
Michał Mirosławcaf3c042020-01-03 10:23:48 +01005634 static const hda_nid_t preferred_pairs[] = {
Kailang Yang92266652017-12-14 15:28:58 +08005635 0x21, 0x03, 0x1b, 0x03, 0x16, 0x02,
5636 0
5637 };
5638
5639 if (action != HDA_FIXUP_ACT_PRE_PROBE)
5640 return;
5641
5642 spec->gen.preferred_dacs = preferred_pairs;
Kailang Yang0700d3d2019-04-26 16:13:54 +08005643 spec->gen.auto_mute_via_amp = 1;
5644 codec->power_save_node = 0;
Kailang Yang92266652017-12-14 15:28:58 +08005645}
5646
Hui Wangc4cfcf62018-11-26 14:17:16 +08005647/* The DAC of NID 0x3 will introduce click/pop noise on headphones, so invalidate it */
5648static void alc285_fixup_invalidate_dacs(struct hda_codec *codec,
5649 const struct hda_fixup *fix, int action)
5650{
5651 if (action != HDA_FIXUP_ACT_PRE_PROBE)
5652 return;
5653
5654 snd_hda_override_wcaps(codec, 0x03, 0);
5655}
5656
Kailang Yange8547472018-11-28 15:32:45 +08005657static const struct hda_jack_keymap alc_headset_btn_keymap[] = {
5658 { SND_JACK_BTN_0, KEY_PLAYPAUSE },
5659 { SND_JACK_BTN_1, KEY_VOICECOMMAND },
5660 { SND_JACK_BTN_2, KEY_VOLUMEUP },
5661 { SND_JACK_BTN_3, KEY_VOLUMEDOWN },
5662 {}
5663};
5664
5665static void alc_headset_btn_callback(struct hda_codec *codec,
5666 struct hda_jack_callback *jack)
5667{
5668 int report = 0;
5669
5670 if (jack->unsol_res & (7 << 13))
5671 report |= SND_JACK_BTN_0;
5672
5673 if (jack->unsol_res & (1 << 16 | 3 << 8))
5674 report |= SND_JACK_BTN_1;
5675
5676 /* Volume up key */
5677 if (jack->unsol_res & (7 << 23))
5678 report |= SND_JACK_BTN_2;
5679
5680 /* Volume down key */
5681 if (jack->unsol_res & (7 << 10))
5682 report |= SND_JACK_BTN_3;
5683
5684 jack->jack->button_state = report;
5685}
5686
Kailang Yang8983eb62019-04-03 15:31:49 +08005687static void alc_fixup_headset_jack(struct hda_codec *codec,
Kailang Yange8547472018-11-28 15:32:45 +08005688 const struct hda_fixup *fix, int action)
5689{
5690
5691 switch (action) {
5692 case HDA_FIXUP_ACT_PRE_PROBE:
5693 snd_hda_jack_detect_enable_callback(codec, 0x55,
5694 alc_headset_btn_callback);
5695 snd_hda_jack_add_kctl(codec, 0x55, "Headset Jack", false,
5696 SND_JACK_HEADSET, alc_headset_btn_keymap);
5697 break;
5698 case HDA_FIXUP_ACT_INIT:
5699 switch (codec->core.vendor_id) {
5700 case 0x10ec0225:
5701 case 0x10ec0295:
5702 case 0x10ec0299:
5703 alc_write_coef_idx(codec, 0x48, 0xd011);
5704 alc_update_coef_idx(codec, 0x49, 0x007f, 0x0045);
5705 alc_update_coef_idx(codec, 0x44, 0x007f << 8, 0x0045 << 8);
5706 break;
5707 case 0x10ec0236:
5708 case 0x10ec0256:
5709 alc_write_coef_idx(codec, 0x48, 0xd011);
5710 alc_update_coef_idx(codec, 0x49, 0x007f, 0x0045);
5711 break;
5712 }
5713 break;
5714 }
5715}
5716
Kailang Yang8983eb62019-04-03 15:31:49 +08005717static void alc295_fixup_chromebook(struct hda_codec *codec,
5718 const struct hda_fixup *fix, int action)
5719{
Kailang Yangd3ba58b2019-05-06 15:09:42 +08005720 struct alc_spec *spec = codec->spec;
5721
Kailang Yang8983eb62019-04-03 15:31:49 +08005722 switch (action) {
Kailang Yangd3ba58b2019-05-06 15:09:42 +08005723 case HDA_FIXUP_ACT_PRE_PROBE:
5724 spec->ultra_low_power = true;
5725 break;
Kailang Yang8983eb62019-04-03 15:31:49 +08005726 case HDA_FIXUP_ACT_INIT:
5727 switch (codec->core.vendor_id) {
5728 case 0x10ec0295:
5729 alc_update_coef_idx(codec, 0x4a, 0x8000, 1 << 15); /* Reset HP JD */
5730 alc_update_coef_idx(codec, 0x4a, 0x8000, 0 << 15);
5731 break;
5732 case 0x10ec0236:
5733 alc_update_coef_idx(codec, 0x1b, 0x8000, 1 << 15); /* Reset HP JD */
5734 alc_update_coef_idx(codec, 0x1b, 0x8000, 0 << 15);
5735 break;
5736 }
5737 break;
5738 }
5739}
5740
Kailang Yangd1dd4212019-01-09 17:05:24 +08005741static void alc_fixup_disable_mic_vref(struct hda_codec *codec,
5742 const struct hda_fixup *fix, int action)
5743{
5744 if (action == HDA_FIXUP_ACT_PRE_PROBE)
5745 snd_hda_codec_set_pin_target(codec, 0x19, PIN_VREFHIZ);
5746}
5747
Takashi Iwaib317b032014-01-08 11:44:21 +01005748/* for hda_fixup_thinkpad_acpi() */
5749#include "thinkpad_helper.c"
David Henningssonb67ae3f2013-11-05 13:11:37 +01005750
Takashi Iwaid5a6cab2018-06-13 12:43:10 +02005751static void alc_fixup_thinkpad_acpi(struct hda_codec *codec,
5752 const struct hda_fixup *fix, int action)
5753{
5754 alc_fixup_no_shutup(codec, fix, action); /* reduce click noise */
5755 hda_fixup_thinkpad_acpi(codec, fix, action);
5756}
5757
Tom Bridenbbf8ff62018-05-29 17:34:20 +01005758/* for alc295_fixup_hp_top_speakers */
5759#include "hp_x360_helper.c"
5760
Takashi Iwai1d045db2011-07-07 18:23:21 +02005761enum {
5762 ALC269_FIXUP_SONY_VAIO,
5763 ALC275_FIXUP_SONY_VAIO_GPIO2,
5764 ALC269_FIXUP_DELL_M101Z,
5765 ALC269_FIXUP_SKU_IGNORE,
5766 ALC269_FIXUP_ASUS_G73JW,
5767 ALC269_FIXUP_LENOVO_EAPD,
5768 ALC275_FIXUP_SONY_HWEQ,
Takashi Iwaie9bd7d52014-05-21 11:06:49 +02005769 ALC275_FIXUP_SONY_DISABLE_AAMIX,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005770 ALC271_FIXUP_DMIC,
Takashi Iwai017f2a12011-07-09 14:42:25 +02005771 ALC269_FIXUP_PCM_44K,
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02005772 ALC269_FIXUP_STEREO_DMIC,
David Henningsson7c478f02013-10-11 10:18:46 +02005773 ALC269_FIXUP_HEADSET_MIC,
Takashi Iwai24519912011-08-16 15:08:49 +02005774 ALC269_FIXUP_QUANTA_MUTE,
5775 ALC269_FIXUP_LIFEBOOK,
David Henningsson2041d562014-06-13 11:15:44 +02005776 ALC269_FIXUP_LIFEBOOK_EXTMIC,
Takashi Iwaicc7016a2015-04-08 20:47:55 +02005777 ALC269_FIXUP_LIFEBOOK_HP_PIN,
Takashi Iwai4df3fd12015-06-29 08:38:02 +02005778 ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT,
Jan-Marek Glogowskifdcc9682018-02-14 11:29:15 +01005779 ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC,
Takashi Iwaia4297b52011-08-23 18:40:12 +02005780 ALC269_FIXUP_AMIC,
5781 ALC269_FIXUP_DMIC,
5782 ALC269VB_FIXUP_AMIC,
5783 ALC269VB_FIXUP_DMIC,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01005784 ALC269_FIXUP_HP_MUTE_LED,
David Henningssond06ac142013-02-18 11:41:55 +01005785 ALC269_FIXUP_HP_MUTE_LED_MIC1,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01005786 ALC269_FIXUP_HP_MUTE_LED_MIC2,
Tom Briden7f783bd2017-03-25 10:12:01 +00005787 ALC269_FIXUP_HP_MUTE_LED_MIC3,
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01005788 ALC269_FIXUP_HP_GPIO_LED,
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08005789 ALC269_FIXUP_HP_GPIO_MIC1_LED,
5790 ALC269_FIXUP_HP_LINE1_MIC1_LED,
David Henningsson693b6132012-06-22 19:12:10 +02005791 ALC269_FIXUP_INV_DMIC,
David Henningsson108cc102012-07-20 10:37:25 +02005792 ALC269_FIXUP_LENOVO_DOCK,
Takashi Iwai9b745ab2014-03-07 08:37:19 +01005793 ALC269_FIXUP_NO_SHUTUP,
David Henningsson88cfcf82013-10-11 10:18:45 +02005794 ALC286_FIXUP_SONY_MIC_NO_PRESENCE,
David Henningsson108cc102012-07-20 10:37:25 +02005795 ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT,
David Henningsson73bdd592013-04-15 15:44:14 +02005796 ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
5797 ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
David Henningsson338cae52013-10-07 10:39:59 +02005798 ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
Kailang Yangfcc6c872017-06-29 15:21:27 +08005799 ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
David Henningsson73bdd592013-04-15 15:44:14 +02005800 ALC269_FIXUP_HEADSET_MODE,
5801 ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC,
Takashi Iwai78197172015-06-27 10:21:13 +02005802 ALC269_FIXUP_ASPIRE_HEADSET_MIC,
David Henningssond240d1d2013-04-15 12:50:02 +02005803 ALC269_FIXUP_ASUS_X101_FUNC,
5804 ALC269_FIXUP_ASUS_X101_VERB,
5805 ALC269_FIXUP_ASUS_X101,
Dylan Reid08a978d2012-11-18 22:56:40 -08005806 ALC271_FIXUP_AMIC_MIC2,
5807 ALC271_FIXUP_HP_GATE_MIC_JACK,
Oleksij Rempelb1e89722013-12-04 20:50:53 +01005808 ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572,
Dylan Reid42397002013-04-05 14:58:22 -07005809 ALC269_FIXUP_ACER_AC700,
David Henningsson3e0d6112013-04-22 14:30:14 +02005810 ALC269_FIXUP_LIMIT_INT_MIC_BOOST,
Oleksij Rempel2cede302013-11-27 17:12:03 +01005811 ALC269VB_FIXUP_ASUS_ZENBOOK,
Takashi Iwai23870832013-11-29 14:13:12 +01005812 ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A,
David Henningsson8e35cd42013-11-06 11:20:01 +01005813 ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED,
Anisse Astier02b504d2013-06-03 11:53:10 +02005814 ALC269VB_FIXUP_ORDISSIMO_EVE2,
Kailang Yangcd217a62013-08-22 10:15:24 +02005815 ALC283_FIXUP_CHROME_BOOK,
Kailang Yang0202e992013-12-02 15:20:15 +08005816 ALC283_FIXUP_SENSE_COMBO_JACK,
Takashi Iwai7bba2152013-09-06 15:45:38 +02005817 ALC282_FIXUP_ASUS_TX300,
Kailang Yang1bb3e062013-09-27 13:10:25 +02005818 ALC283_FIXUP_INT_MIC,
David Henningsson338cae52013-10-07 10:39:59 +02005819 ALC290_FIXUP_MONO_SPEAKERS,
David Henningsson0f4881d2013-12-20 16:08:13 +01005820 ALC290_FIXUP_MONO_SPEAKERS_HSJACK,
5821 ALC290_FIXUP_SUBWOOFER,
5822 ALC290_FIXUP_SUBWOOFER_HSJACK,
David Henningssonb67ae3f2013-11-05 13:11:37 +01005823 ALC269_FIXUP_THINKPAD_ACPI,
David Henningsson56f27012016-01-11 09:33:14 +01005824 ALC269_FIXUP_DMIC_THINKPAD_ACPI,
Chris Chiu5824ce82017-02-28 14:17:11 -06005825 ALC255_FIXUP_ACER_MIC_NO_PRESENCE,
Chris Chiu615966a2017-02-28 14:17:12 -06005826 ALC255_FIXUP_ASUS_MIC_NO_PRESENCE,
Kailang Yang9a22a8f52013-11-08 15:54:49 +08005827 ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Kailang Yang31278992014-03-03 15:27:22 +08005828 ALC255_FIXUP_DELL2_MIC_NO_PRESENCE,
Kailang Yang9a22a8f52013-11-08 15:54:49 +08005829 ALC255_FIXUP_HEADSET_MODE,
Kailang Yang31278992014-03-03 15:27:22 +08005830 ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC,
Kailang Yanga22aa262014-04-23 17:34:28 +08005831 ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
Takashi Iwai1c37c222014-05-06 17:34:42 +02005832 ALC292_FIXUP_TPT440_DOCK,
Takashi Iwai9a811232015-12-09 15:17:43 +01005833 ALC292_FIXUP_TPT440,
Anisse Astierabaa22742016-08-24 09:14:13 +02005834 ALC283_FIXUP_HEADSET_MIC,
Takashi Iwaib3802782018-11-26 17:47:46 +01005835 ALC255_FIXUP_MIC_MUTE_LED,
Takashi Iwai1a22e772014-08-27 08:19:05 +02005836 ALC282_FIXUP_ASPIRE_V5_PINS,
David Henningsson7a5255f2014-10-30 08:26:01 +01005837 ALC280_FIXUP_HP_GPIO4,
Kailang Yangeaa8e5e2014-11-21 15:49:11 +08005838 ALC286_FIXUP_HP_GPIO_LED,
David Henningsson33f4acd2015-01-07 15:50:13 +01005839 ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY,
TienFu Chenb4b33f92015-01-20 15:06:21 +01005840 ALC280_FIXUP_HP_DOCK_PINS,
Jaroslav Kysela04d54662017-03-09 13:29:13 +01005841 ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED,
Keith Packard98973f22015-07-15 12:14:39 -07005842 ALC280_FIXUP_HP_9480M,
Kailang Yange1e62b92015-04-08 16:01:22 +08005843 ALC288_FIXUP_DELL_HEADSET_MODE,
5844 ALC288_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang831bfdf92015-06-26 12:35:17 +08005845 ALC288_FIXUP_DELL_XPS_13,
5846 ALC288_FIXUP_DISABLE_AAMIX,
Takashi Iwai5fab5822020-01-05 09:11:19 +01005847 ALC292_FIXUP_DELL_E7X_AAMIX,
Takashi Iwai8b99aba2015-06-15 11:59:32 +02005848 ALC292_FIXUP_DELL_E7X,
5849 ALC292_FIXUP_DISABLE_AAMIX,
David Henningssonc04017e2015-12-15 14:44:03 +01005850 ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK,
James McDonnell54324222019-09-16 14:53:38 +00005851 ALC298_FIXUP_ALIENWARE_MIC_NO_PRESENCE,
Kailang Yang977e6272015-05-18 15:31:20 +08005852 ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang2f726ae2017-03-31 10:31:40 +08005853 ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE,
Kailang Yang6ed11312015-10-26 15:37:39 +08005854 ALC275_FIXUP_DELL_XPS,
Hui Wang8c697292015-11-24 11:08:18 +08005855 ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE,
Kai-Heng Feng1099f482019-10-03 12:39:19 +08005856 ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE2,
Hui Wang23adc192015-12-08 12:27:18 +08005857 ALC293_FIXUP_LENOVO_SPK_NOISE,
Kailang3694cb22015-12-28 11:35:24 +08005858 ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY,
Kai-Heng Feng3b43b712016-02-25 15:19:38 +08005859 ALC255_FIXUP_DELL_SPK_NOISE,
Kailang Yangd1dd4212019-01-09 17:05:24 +08005860 ALC225_FIXUP_DISABLE_MIC_VREF,
David Henningsson2ae95572016-02-25 09:37:05 +01005861 ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
Takashi Iwaie312a862018-03-06 12:14:17 +01005862 ALC295_FIXUP_DISABLE_DAC3,
Jaroslav Kyselad2cd7952019-11-29 15:40:27 +01005863 ALC285_FIXUP_SPEAKER2_TO_DAC1,
Takashi Iwaif8839822016-02-25 14:31:59 +01005864 ALC280_FIXUP_HP_HEADSET_MIC,
Hui Wange549d192016-04-01 11:00:15 +08005865 ALC221_FIXUP_HP_FRONT_MIC,
Sven Eckelmannc636b952016-04-11 16:55:26 +02005866 ALC292_FIXUP_TPT460,
Hui Wangdd9aa332016-08-01 10:20:32 +08005867 ALC298_FIXUP_SPK_VOLUME,
Kai-Heng Fengfd06c772016-08-30 15:36:34 +08005868 ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER,
Gabriele Mazzotta823ff162016-12-24 19:50:01 +01005869 ALC269_FIXUP_ATIV_BOOK_8,
Kailang Yang9eb5d0e2017-01-17 15:40:25 +08005870 ALC221_FIXUP_HP_MIC_NO_PRESENCE,
Chris Chiuc1732ed2017-02-28 14:17:13 -06005871 ALC256_FIXUP_ASUS_HEADSET_MODE,
5872 ALC256_FIXUP_ASUS_MIC,
Chris Chiueeed4cd2017-02-28 14:17:15 -06005873 ALC256_FIXUP_ASUS_AIO_GPIO2,
Chris Chiu216d7ae2017-02-28 14:17:14 -06005874 ALC233_FIXUP_ASUS_MIC_NO_PRESENCE,
5875 ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE,
Kailang Yangca169cc2017-04-25 16:17:40 +08005876 ALC233_FIXUP_LENOVO_MULTI_CODECS,
Jian-Hong Panea5c7eb2019-04-01 11:25:05 +08005877 ALC233_FIXUP_ACER_HEADSET_MIC,
Hui Wangf33f79f2017-07-07 12:08:29 +08005878 ALC294_FIXUP_LENOVO_MIC_LOCATION,
Kailang Yang5f364132017-07-25 16:28:16 +08005879 ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE,
PeiSen Houb84e8432017-09-01 15:11:56 +08005880 ALC700_FIXUP_INTEL_REFERENCE,
Kailang Yang92266652017-12-14 15:28:58 +08005881 ALC274_FIXUP_DELL_BIND_DACS,
5882 ALC274_FIXUP_DELL_AIO_LINEOUT_VERB,
Kailang Yang61fcf8e2018-02-02 15:26:46 +08005883 ALC298_FIXUP_TPT470_DOCK,
Kailang Yangae104a22018-02-05 16:07:20 +08005884 ALC255_FIXUP_DUMMY_LINEOUT_VERB,
Kailang Yangf0ba9d62018-03-16 11:46:08 +08005885 ALC255_FIXUP_DELL_HEADSET_MIC,
Ayman Bagabas0fbf21c2019-05-23 05:30:11 -04005886 ALC256_FIXUP_HUAWEI_MACH_WX9_PINS,
Tomas Espeletaa2ef03f2019-08-09 16:37:54 +02005887 ALC298_FIXUP_HUAWEI_MBX_STEREO,
Tom Bridenbbf8ff62018-05-29 17:34:20 +01005888 ALC295_FIXUP_HP_X360,
Kailang Yang8a328ac2018-08-21 16:54:41 +08005889 ALC221_FIXUP_HP_HEADSET_MIC,
Hui Wangc4cfcf62018-11-26 14:17:16 +08005890 ALC285_FIXUP_LENOVO_HEADPHONE_NOISE,
Girija Kumar Kasinadhunie8ed64b2018-11-26 13:40:46 -05005891 ALC295_FIXUP_HP_AUTO_MUTE,
Chris Chiu33aaebd2018-12-05 14:48:53 +08005892 ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE,
Chris Chiud8ae4582018-12-07 17:17:11 +08005893 ALC294_FIXUP_ASUS_MIC,
Jian-Hong Pan4e051102018-12-07 17:17:12 +08005894 ALC294_FIXUP_ASUS_HEADSET_MIC,
5895 ALC294_FIXUP_ASUS_SPK,
Jeremy Soller89e3a562019-01-30 16:12:31 -07005896 ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE,
Hui Wangc8c6ee62019-02-14 11:41:33 +08005897 ALC285_FIXUP_LENOVO_PC_BEEP_IN_NOISE,
Jian-Hong Pancbc05fd2019-03-13 17:33:24 +08005898 ALC255_FIXUP_ACER_HEADSET_MIC,
Kailang Yang10f5b1b2019-02-21 16:10:22 +08005899 ALC295_FIXUP_CHROME_BOOK,
Kailang Yang8983eb62019-04-03 15:31:49 +08005900 ALC225_FIXUP_HEADSET_JACK,
Kailang Yang136824e2019-03-14 16:22:45 +08005901 ALC225_FIXUP_DELL_WYSE_AIO_MIC_NO_PRESENCE,
5902 ALC225_FIXUP_WYSE_AUTO_MUTE,
5903 ALC225_FIXUP_WYSE_DISABLE_MIC_VREF,
Jian-Hong Pan667a8f72019-03-15 17:51:09 +08005904 ALC286_FIXUP_ACER_AIO_HEADSET_MIC,
Daniel Drake8c8967a2019-10-17 16:15:01 +08005905 ALC256_FIXUP_ASUS_HEADSET_MIC,
Jian-Hong Pane1037352019-03-22 11:37:18 +08005906 ALC256_FIXUP_ASUS_MIC_NO_PRESENCE,
Bernhard Rosenkraenzere2a829b2019-03-05 00:38:19 +01005907 ALC299_FIXUP_PREDATOR_SPK,
Jian-Hong Pan60083f92019-09-02 18:00:56 +08005908 ALC294_FIXUP_ASUS_INTSPK_HEADSET_MIC,
Jan-Marek Glogowskibd9c10b2019-09-15 16:57:28 +02005909 ALC256_FIXUP_MEDION_HEADSET_NO_PRESENCE,
Jian-Hong Pan436e2552019-11-25 17:34:06 +08005910 ALC294_FIXUP_ASUS_INTSPK_GPIO,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005911};
5912
Takashi Iwai1727a772013-01-10 09:52:52 +01005913static const struct hda_fixup alc269_fixups[] = {
Takashi Iwai1d045db2011-07-07 18:23:21 +02005914 [ALC269_FIXUP_SONY_VAIO] = {
Takashi Iwaifd108212013-01-10 10:18:14 +01005915 .type = HDA_FIXUP_PINCTLS,
5916 .v.pins = (const struct hda_pintbl[]) {
5917 {0x19, PIN_VREFGRD},
Takashi Iwai1d045db2011-07-07 18:23:21 +02005918 {}
5919 }
5920 },
5921 [ALC275_FIXUP_SONY_VAIO_GPIO2] = {
Takashi Iwaiae065f12018-06-19 23:00:03 +02005922 .type = HDA_FIXUP_FUNC,
5923 .v.func = alc275_fixup_gpio4_off,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005924 .chained = true,
5925 .chain_id = ALC269_FIXUP_SONY_VAIO
5926 },
5927 [ALC269_FIXUP_DELL_M101Z] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005928 .type = HDA_FIXUP_VERBS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005929 .v.verbs = (const struct hda_verb[]) {
5930 /* Enables internal speaker */
5931 {0x20, AC_VERB_SET_COEF_INDEX, 13},
5932 {0x20, AC_VERB_SET_PROC_COEF, 0x4040},
5933 {}
5934 }
5935 },
5936 [ALC269_FIXUP_SKU_IGNORE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005937 .type = HDA_FIXUP_FUNC,
Takashi Iwai23d30f22012-05-07 17:17:32 +02005938 .v.func = alc_fixup_sku_ignore,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005939 },
5940 [ALC269_FIXUP_ASUS_G73JW] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005941 .type = HDA_FIXUP_PINS,
5942 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02005943 { 0x17, 0x99130111 }, /* subwoofer */
5944 { }
5945 }
5946 },
5947 [ALC269_FIXUP_LENOVO_EAPD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005948 .type = HDA_FIXUP_VERBS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005949 .v.verbs = (const struct hda_verb[]) {
5950 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
5951 {}
5952 }
5953 },
5954 [ALC275_FIXUP_SONY_HWEQ] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005955 .type = HDA_FIXUP_FUNC,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005956 .v.func = alc269_fixup_hweq,
5957 .chained = true,
5958 .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2
5959 },
Takashi Iwaie9bd7d52014-05-21 11:06:49 +02005960 [ALC275_FIXUP_SONY_DISABLE_AAMIX] = {
5961 .type = HDA_FIXUP_FUNC,
5962 .v.func = alc_fixup_disable_aamix,
5963 .chained = true,
5964 .chain_id = ALC269_FIXUP_SONY_VAIO
5965 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02005966 [ALC271_FIXUP_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005967 .type = HDA_FIXUP_FUNC,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005968 .v.func = alc271_fixup_dmic,
5969 },
Takashi Iwai017f2a12011-07-09 14:42:25 +02005970 [ALC269_FIXUP_PCM_44K] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005971 .type = HDA_FIXUP_FUNC,
Takashi Iwai017f2a12011-07-09 14:42:25 +02005972 .v.func = alc269_fixup_pcm_44k,
David Henningsson012e7eb2012-08-08 08:43:37 +02005973 .chained = true,
5974 .chain_id = ALC269_FIXUP_QUANTA_MUTE
Takashi Iwai017f2a12011-07-09 14:42:25 +02005975 },
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02005976 [ALC269_FIXUP_STEREO_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005977 .type = HDA_FIXUP_FUNC,
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02005978 .v.func = alc269_fixup_stereo_dmic,
5979 },
David Henningsson7c478f02013-10-11 10:18:46 +02005980 [ALC269_FIXUP_HEADSET_MIC] = {
5981 .type = HDA_FIXUP_FUNC,
5982 .v.func = alc269_fixup_headset_mic,
5983 },
Takashi Iwai24519912011-08-16 15:08:49 +02005984 [ALC269_FIXUP_QUANTA_MUTE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005985 .type = HDA_FIXUP_FUNC,
Takashi Iwai24519912011-08-16 15:08:49 +02005986 .v.func = alc269_fixup_quanta_mute,
5987 },
5988 [ALC269_FIXUP_LIFEBOOK] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005989 .type = HDA_FIXUP_PINS,
5990 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai24519912011-08-16 15:08:49 +02005991 { 0x1a, 0x2101103f }, /* dock line-out */
5992 { 0x1b, 0x23a11040 }, /* dock mic-in */
5993 { }
5994 },
5995 .chained = true,
5996 .chain_id = ALC269_FIXUP_QUANTA_MUTE
5997 },
David Henningsson2041d562014-06-13 11:15:44 +02005998 [ALC269_FIXUP_LIFEBOOK_EXTMIC] = {
5999 .type = HDA_FIXUP_PINS,
6000 .v.pins = (const struct hda_pintbl[]) {
6001 { 0x19, 0x01a1903c }, /* headset mic, with jack detect */
6002 { }
6003 },
6004 },
Takashi Iwaicc7016a2015-04-08 20:47:55 +02006005 [ALC269_FIXUP_LIFEBOOK_HP_PIN] = {
6006 .type = HDA_FIXUP_PINS,
6007 .v.pins = (const struct hda_pintbl[]) {
6008 { 0x21, 0x0221102f }, /* HP out */
6009 { }
6010 },
6011 },
Takashi Iwai4df3fd12015-06-29 08:38:02 +02006012 [ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT] = {
6013 .type = HDA_FIXUP_FUNC,
6014 .v.func = alc269_fixup_pincfg_no_hp_to_lineout,
6015 },
Jan-Marek Glogowskifdcc9682018-02-14 11:29:15 +01006016 [ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC] = {
6017 .type = HDA_FIXUP_FUNC,
6018 .v.func = alc269_fixup_pincfg_U7x7_headset_mic,
6019 },
Takashi Iwaia4297b52011-08-23 18:40:12 +02006020 [ALC269_FIXUP_AMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006021 .type = HDA_FIXUP_PINS,
6022 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaia4297b52011-08-23 18:40:12 +02006023 { 0x14, 0x99130110 }, /* speaker */
6024 { 0x15, 0x0121401f }, /* HP out */
6025 { 0x18, 0x01a19c20 }, /* mic */
6026 { 0x19, 0x99a3092f }, /* int-mic */
6027 { }
6028 },
6029 },
6030 [ALC269_FIXUP_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006031 .type = HDA_FIXUP_PINS,
6032 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaia4297b52011-08-23 18:40:12 +02006033 { 0x12, 0x99a3092f }, /* int-mic */
6034 { 0x14, 0x99130110 }, /* speaker */
6035 { 0x15, 0x0121401f }, /* HP out */
6036 { 0x18, 0x01a19c20 }, /* mic */
6037 { }
6038 },
6039 },
6040 [ALC269VB_FIXUP_AMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006041 .type = HDA_FIXUP_PINS,
6042 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaia4297b52011-08-23 18:40:12 +02006043 { 0x14, 0x99130110 }, /* speaker */
6044 { 0x18, 0x01a19c20 }, /* mic */
6045 { 0x19, 0x99a3092f }, /* int-mic */
6046 { 0x21, 0x0121401f }, /* HP out */
6047 { }
6048 },
6049 },
David Henningsson2267ea92012-01-03 08:45:56 +01006050 [ALC269VB_FIXUP_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006051 .type = HDA_FIXUP_PINS,
6052 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaia4297b52011-08-23 18:40:12 +02006053 { 0x12, 0x99a3092f }, /* int-mic */
6054 { 0x14, 0x99130110 }, /* speaker */
6055 { 0x18, 0x01a19c20 }, /* mic */
6056 { 0x21, 0x0121401f }, /* HP out */
6057 { }
6058 },
6059 },
Takashi Iwai08fb0d02013-01-10 17:33:58 +01006060 [ALC269_FIXUP_HP_MUTE_LED] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006061 .type = HDA_FIXUP_FUNC,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01006062 .v.func = alc269_fixup_hp_mute_led,
David Henningsson6d3cd5d2013-01-07 12:03:47 +01006063 },
David Henningssond06ac142013-02-18 11:41:55 +01006064 [ALC269_FIXUP_HP_MUTE_LED_MIC1] = {
6065 .type = HDA_FIXUP_FUNC,
6066 .v.func = alc269_fixup_hp_mute_led_mic1,
6067 },
Takashi Iwai08fb0d02013-01-10 17:33:58 +01006068 [ALC269_FIXUP_HP_MUTE_LED_MIC2] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006069 .type = HDA_FIXUP_FUNC,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01006070 .v.func = alc269_fixup_hp_mute_led_mic2,
Takashi Iwai420b0fe2012-03-12 12:35:27 +01006071 },
Tom Briden7f783bd2017-03-25 10:12:01 +00006072 [ALC269_FIXUP_HP_MUTE_LED_MIC3] = {
6073 .type = HDA_FIXUP_FUNC,
6074 .v.func = alc269_fixup_hp_mute_led_mic3,
Girija Kumar Kasinadhunie8ed64b2018-11-26 13:40:46 -05006075 .chained = true,
6076 .chain_id = ALC295_FIXUP_HP_AUTO_MUTE
Tom Briden7f783bd2017-03-25 10:12:01 +00006077 },
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01006078 [ALC269_FIXUP_HP_GPIO_LED] = {
6079 .type = HDA_FIXUP_FUNC,
6080 .v.func = alc269_fixup_hp_gpio_led,
6081 },
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08006082 [ALC269_FIXUP_HP_GPIO_MIC1_LED] = {
6083 .type = HDA_FIXUP_FUNC,
6084 .v.func = alc269_fixup_hp_gpio_mic1_led,
6085 },
6086 [ALC269_FIXUP_HP_LINE1_MIC1_LED] = {
6087 .type = HDA_FIXUP_FUNC,
6088 .v.func = alc269_fixup_hp_line1_mic1_led,
6089 },
David Henningsson693b6132012-06-22 19:12:10 +02006090 [ALC269_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006091 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02006092 .v.func = alc_fixup_inv_dmic,
David Henningsson693b6132012-06-22 19:12:10 +02006093 },
Takashi Iwai9b745ab2014-03-07 08:37:19 +01006094 [ALC269_FIXUP_NO_SHUTUP] = {
6095 .type = HDA_FIXUP_FUNC,
6096 .v.func = alc_fixup_no_shutup,
6097 },
David Henningsson108cc102012-07-20 10:37:25 +02006098 [ALC269_FIXUP_LENOVO_DOCK] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006099 .type = HDA_FIXUP_PINS,
6100 .v.pins = (const struct hda_pintbl[]) {
David Henningsson108cc102012-07-20 10:37:25 +02006101 { 0x19, 0x23a11040 }, /* dock mic */
6102 { 0x1b, 0x2121103f }, /* dock headphone */
6103 { }
6104 },
6105 .chained = true,
6106 .chain_id = ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT
6107 },
6108 [ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006109 .type = HDA_FIXUP_FUNC,
David Henningsson108cc102012-07-20 10:37:25 +02006110 .v.func = alc269_fixup_pincfg_no_hp_to_lineout,
David Henningsson52129002013-11-19 10:25:53 +01006111 .chained = true,
6112 .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
David Henningsson108cc102012-07-20 10:37:25 +02006113 },
David Henningsson73bdd592013-04-15 15:44:14 +02006114 [ALC269_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6115 .type = HDA_FIXUP_PINS,
6116 .v.pins = (const struct hda_pintbl[]) {
6117 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6118 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6119 { }
6120 },
6121 .chained = true,
6122 .chain_id = ALC269_FIXUP_HEADSET_MODE
6123 },
6124 [ALC269_FIXUP_DELL2_MIC_NO_PRESENCE] = {
6125 .type = HDA_FIXUP_PINS,
6126 .v.pins = (const struct hda_pintbl[]) {
6127 { 0x16, 0x21014020 }, /* dock line out */
6128 { 0x19, 0x21a19030 }, /* dock mic */
6129 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6130 { }
6131 },
6132 .chained = true,
6133 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
6134 },
David Henningsson338cae52013-10-07 10:39:59 +02006135 [ALC269_FIXUP_DELL3_MIC_NO_PRESENCE] = {
6136 .type = HDA_FIXUP_PINS,
6137 .v.pins = (const struct hda_pintbl[]) {
6138 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6139 { }
6140 },
6141 .chained = true,
6142 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
6143 },
Kailang Yangfcc6c872017-06-29 15:21:27 +08006144 [ALC269_FIXUP_DELL4_MIC_NO_PRESENCE] = {
6145 .type = HDA_FIXUP_PINS,
6146 .v.pins = (const struct hda_pintbl[]) {
6147 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6148 { 0x1b, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6149 { }
6150 },
6151 .chained = true,
6152 .chain_id = ALC269_FIXUP_HEADSET_MODE
6153 },
David Henningsson73bdd592013-04-15 15:44:14 +02006154 [ALC269_FIXUP_HEADSET_MODE] = {
6155 .type = HDA_FIXUP_FUNC,
6156 .v.func = alc_fixup_headset_mode,
Hui Wang6676f302014-11-18 17:57:41 +08006157 .chained = true,
Takashi Iwaib3802782018-11-26 17:47:46 +01006158 .chain_id = ALC255_FIXUP_MIC_MUTE_LED
David Henningsson73bdd592013-04-15 15:44:14 +02006159 },
6160 [ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC] = {
6161 .type = HDA_FIXUP_FUNC,
6162 .v.func = alc_fixup_headset_mode_no_hp_mic,
6163 },
Takashi Iwai78197172015-06-27 10:21:13 +02006164 [ALC269_FIXUP_ASPIRE_HEADSET_MIC] = {
6165 .type = HDA_FIXUP_PINS,
6166 .v.pins = (const struct hda_pintbl[]) {
6167 { 0x19, 0x01a1913c }, /* headset mic w/o jack detect */
6168 { }
6169 },
6170 .chained = true,
6171 .chain_id = ALC269_FIXUP_HEADSET_MODE,
6172 },
David Henningsson88cfcf82013-10-11 10:18:45 +02006173 [ALC286_FIXUP_SONY_MIC_NO_PRESENCE] = {
6174 .type = HDA_FIXUP_PINS,
6175 .v.pins = (const struct hda_pintbl[]) {
6176 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6177 { }
6178 },
David Henningssonfbc78ad2013-10-11 13:46:04 +02006179 .chained = true,
6180 .chain_id = ALC269_FIXUP_HEADSET_MIC
David Henningsson88cfcf82013-10-11 10:18:45 +02006181 },
Ayman Bagabas0fbf21c2019-05-23 05:30:11 -04006182 [ALC256_FIXUP_HUAWEI_MACH_WX9_PINS] = {
Ayman Bagabas8ac51bb2018-12-12 18:07:57 -05006183 .type = HDA_FIXUP_PINS,
6184 .v.pins = (const struct hda_pintbl[]) {
6185 {0x12, 0x90a60130},
6186 {0x13, 0x40000000},
6187 {0x14, 0x90170110},
6188 {0x18, 0x411111f0},
6189 {0x19, 0x04a11040},
6190 {0x1a, 0x411111f0},
6191 {0x1b, 0x90170112},
6192 {0x1d, 0x40759a05},
6193 {0x1e, 0x411111f0},
6194 {0x21, 0x04211020},
6195 { }
6196 },
Ayman Bagabase2744fd2018-12-12 18:07:59 -05006197 .chained = true,
6198 .chain_id = ALC255_FIXUP_MIC_MUTE_LED
Ayman Bagabas8ac51bb2018-12-12 18:07:57 -05006199 },
Tomas Espeletaa2ef03f2019-08-09 16:37:54 +02006200 [ALC298_FIXUP_HUAWEI_MBX_STEREO] = {
6201 .type = HDA_FIXUP_FUNC,
6202 .v.func = alc298_fixup_huawei_mbx_stereo,
6203 .chained = true,
6204 .chain_id = ALC255_FIXUP_MIC_MUTE_LED
6205 },
David Henningssond240d1d2013-04-15 12:50:02 +02006206 [ALC269_FIXUP_ASUS_X101_FUNC] = {
6207 .type = HDA_FIXUP_FUNC,
6208 .v.func = alc269_fixup_x101_headset_mic,
6209 },
6210 [ALC269_FIXUP_ASUS_X101_VERB] = {
6211 .type = HDA_FIXUP_VERBS,
6212 .v.verbs = (const struct hda_verb[]) {
6213 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6214 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
6215 {0x20, AC_VERB_SET_PROC_COEF, 0x0310},
6216 { }
6217 },
6218 .chained = true,
6219 .chain_id = ALC269_FIXUP_ASUS_X101_FUNC
6220 },
6221 [ALC269_FIXUP_ASUS_X101] = {
6222 .type = HDA_FIXUP_PINS,
6223 .v.pins = (const struct hda_pintbl[]) {
6224 { 0x18, 0x04a1182c }, /* Headset mic */
6225 { }
6226 },
6227 .chained = true,
6228 .chain_id = ALC269_FIXUP_ASUS_X101_VERB
6229 },
Dylan Reid08a978d2012-11-18 22:56:40 -08006230 [ALC271_FIXUP_AMIC_MIC2] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006231 .type = HDA_FIXUP_PINS,
6232 .v.pins = (const struct hda_pintbl[]) {
Dylan Reid08a978d2012-11-18 22:56:40 -08006233 { 0x14, 0x99130110 }, /* speaker */
6234 { 0x19, 0x01a19c20 }, /* mic */
6235 { 0x1b, 0x99a7012f }, /* int-mic */
6236 { 0x21, 0x0121401f }, /* HP out */
6237 { }
6238 },
6239 },
6240 [ALC271_FIXUP_HP_GATE_MIC_JACK] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006241 .type = HDA_FIXUP_FUNC,
Dylan Reid08a978d2012-11-18 22:56:40 -08006242 .v.func = alc271_hp_gate_mic_jack,
6243 .chained = true,
6244 .chain_id = ALC271_FIXUP_AMIC_MIC2,
6245 },
Oleksij Rempelb1e89722013-12-04 20:50:53 +01006246 [ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572] = {
6247 .type = HDA_FIXUP_FUNC,
6248 .v.func = alc269_fixup_limit_int_mic_boost,
6249 .chained = true,
6250 .chain_id = ALC271_FIXUP_HP_GATE_MIC_JACK,
6251 },
Dylan Reid42397002013-04-05 14:58:22 -07006252 [ALC269_FIXUP_ACER_AC700] = {
6253 .type = HDA_FIXUP_PINS,
6254 .v.pins = (const struct hda_pintbl[]) {
6255 { 0x12, 0x99a3092f }, /* int-mic */
6256 { 0x14, 0x99130110 }, /* speaker */
6257 { 0x18, 0x03a11c20 }, /* mic */
6258 { 0x1e, 0x0346101e }, /* SPDIF1 */
6259 { 0x21, 0x0321101f }, /* HP out */
6260 { }
6261 },
6262 .chained = true,
6263 .chain_id = ALC271_FIXUP_DMIC,
6264 },
David Henningsson3e0d6112013-04-22 14:30:14 +02006265 [ALC269_FIXUP_LIMIT_INT_MIC_BOOST] = {
6266 .type = HDA_FIXUP_FUNC,
6267 .v.func = alc269_fixup_limit_int_mic_boost,
David Henningsson27937692013-11-18 11:51:47 +01006268 .chained = true,
6269 .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
David Henningsson3e0d6112013-04-22 14:30:14 +02006270 },
Oleksij Rempel2cede302013-11-27 17:12:03 +01006271 [ALC269VB_FIXUP_ASUS_ZENBOOK] = {
6272 .type = HDA_FIXUP_FUNC,
6273 .v.func = alc269_fixup_limit_int_mic_boost,
6274 .chained = true,
6275 .chain_id = ALC269VB_FIXUP_DMIC,
6276 },
Takashi Iwai23870832013-11-29 14:13:12 +01006277 [ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A] = {
6278 .type = HDA_FIXUP_VERBS,
6279 .v.verbs = (const struct hda_verb[]) {
6280 /* class-D output amp +5dB */
6281 { 0x20, AC_VERB_SET_COEF_INDEX, 0x12 },
6282 { 0x20, AC_VERB_SET_PROC_COEF, 0x2800 },
6283 {}
6284 },
6285 .chained = true,
6286 .chain_id = ALC269VB_FIXUP_ASUS_ZENBOOK,
6287 },
David Henningsson8e35cd42013-11-06 11:20:01 +01006288 [ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED] = {
6289 .type = HDA_FIXUP_FUNC,
6290 .v.func = alc269_fixup_limit_int_mic_boost,
6291 .chained = true,
6292 .chain_id = ALC269_FIXUP_HP_MUTE_LED_MIC1,
6293 },
Anisse Astier02b504d2013-06-03 11:53:10 +02006294 [ALC269VB_FIXUP_ORDISSIMO_EVE2] = {
6295 .type = HDA_FIXUP_PINS,
6296 .v.pins = (const struct hda_pintbl[]) {
6297 { 0x12, 0x99a3092f }, /* int-mic */
6298 { 0x18, 0x03a11d20 }, /* mic */
6299 { 0x19, 0x411111f0 }, /* Unused bogus pin */
6300 { }
6301 },
6302 },
Kailang Yangcd217a62013-08-22 10:15:24 +02006303 [ALC283_FIXUP_CHROME_BOOK] = {
6304 .type = HDA_FIXUP_FUNC,
6305 .v.func = alc283_fixup_chromebook,
6306 },
Kailang Yang0202e992013-12-02 15:20:15 +08006307 [ALC283_FIXUP_SENSE_COMBO_JACK] = {
6308 .type = HDA_FIXUP_FUNC,
6309 .v.func = alc283_fixup_sense_combo_jack,
6310 .chained = true,
6311 .chain_id = ALC283_FIXUP_CHROME_BOOK,
6312 },
Takashi Iwai7bba2152013-09-06 15:45:38 +02006313 [ALC282_FIXUP_ASUS_TX300] = {
6314 .type = HDA_FIXUP_FUNC,
6315 .v.func = alc282_fixup_asus_tx300,
6316 },
Kailang Yang1bb3e062013-09-27 13:10:25 +02006317 [ALC283_FIXUP_INT_MIC] = {
6318 .type = HDA_FIXUP_VERBS,
6319 .v.verbs = (const struct hda_verb[]) {
6320 {0x20, AC_VERB_SET_COEF_INDEX, 0x1a},
6321 {0x20, AC_VERB_SET_PROC_COEF, 0x0011},
6322 { }
6323 },
6324 .chained = true,
6325 .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST
6326 },
David Henningsson0f4881d2013-12-20 16:08:13 +01006327 [ALC290_FIXUP_SUBWOOFER_HSJACK] = {
6328 .type = HDA_FIXUP_PINS,
6329 .v.pins = (const struct hda_pintbl[]) {
6330 { 0x17, 0x90170112 }, /* subwoofer */
6331 { }
6332 },
6333 .chained = true,
6334 .chain_id = ALC290_FIXUP_MONO_SPEAKERS_HSJACK,
6335 },
6336 [ALC290_FIXUP_SUBWOOFER] = {
6337 .type = HDA_FIXUP_PINS,
6338 .v.pins = (const struct hda_pintbl[]) {
6339 { 0x17, 0x90170112 }, /* subwoofer */
6340 { }
6341 },
6342 .chained = true,
6343 .chain_id = ALC290_FIXUP_MONO_SPEAKERS,
6344 },
David Henningsson338cae52013-10-07 10:39:59 +02006345 [ALC290_FIXUP_MONO_SPEAKERS] = {
6346 .type = HDA_FIXUP_FUNC,
6347 .v.func = alc290_fixup_mono_speakers,
David Henningsson0f4881d2013-12-20 16:08:13 +01006348 },
6349 [ALC290_FIXUP_MONO_SPEAKERS_HSJACK] = {
6350 .type = HDA_FIXUP_FUNC,
6351 .v.func = alc290_fixup_mono_speakers,
David Henningsson338cae52013-10-07 10:39:59 +02006352 .chained = true,
6353 .chain_id = ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
6354 },
David Henningssonb67ae3f2013-11-05 13:11:37 +01006355 [ALC269_FIXUP_THINKPAD_ACPI] = {
6356 .type = HDA_FIXUP_FUNC,
Takashi Iwaid5a6cab2018-06-13 12:43:10 +02006357 .v.func = alc_fixup_thinkpad_acpi,
Takashi Iwai09da1112016-09-08 12:15:02 +02006358 .chained = true,
6359 .chain_id = ALC269_FIXUP_SKU_IGNORE,
David Henningssonb67ae3f2013-11-05 13:11:37 +01006360 },
David Henningsson56f27012016-01-11 09:33:14 +01006361 [ALC269_FIXUP_DMIC_THINKPAD_ACPI] = {
6362 .type = HDA_FIXUP_FUNC,
6363 .v.func = alc_fixup_inv_dmic,
6364 .chained = true,
6365 .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
6366 },
Chris Chiu5824ce82017-02-28 14:17:11 -06006367 [ALC255_FIXUP_ACER_MIC_NO_PRESENCE] = {
Hui Wang17d30462019-06-14 16:44:12 +08006368 .type = HDA_FIXUP_PINS,
6369 .v.pins = (const struct hda_pintbl[]) {
6370 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6371 { }
Chris Chiu5824ce82017-02-28 14:17:11 -06006372 },
6373 .chained = true,
Hui Wang17d30462019-06-14 16:44:12 +08006374 .chain_id = ALC255_FIXUP_HEADSET_MODE
Chris Chiu5824ce82017-02-28 14:17:11 -06006375 },
Chris Chiu615966a2017-02-28 14:17:12 -06006376 [ALC255_FIXUP_ASUS_MIC_NO_PRESENCE] = {
6377 .type = HDA_FIXUP_PINS,
6378 .v.pins = (const struct hda_pintbl[]) {
6379 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6380 { }
6381 },
6382 .chained = true,
6383 .chain_id = ALC255_FIXUP_HEADSET_MODE
6384 },
Kailang Yang9a22a8f52013-11-08 15:54:49 +08006385 [ALC255_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6386 .type = HDA_FIXUP_PINS,
6387 .v.pins = (const struct hda_pintbl[]) {
6388 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6389 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6390 { }
6391 },
6392 .chained = true,
6393 .chain_id = ALC255_FIXUP_HEADSET_MODE
6394 },
Kailang Yang31278992014-03-03 15:27:22 +08006395 [ALC255_FIXUP_DELL2_MIC_NO_PRESENCE] = {
6396 .type = HDA_FIXUP_PINS,
6397 .v.pins = (const struct hda_pintbl[]) {
6398 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6399 { }
6400 },
6401 .chained = true,
6402 .chain_id = ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC
6403 },
Kailang Yang9a22a8f52013-11-08 15:54:49 +08006404 [ALC255_FIXUP_HEADSET_MODE] = {
6405 .type = HDA_FIXUP_FUNC,
6406 .v.func = alc_fixup_headset_mode_alc255,
Hui Wang4a83d422014-11-18 17:57:40 +08006407 .chained = true,
Takashi Iwaib3802782018-11-26 17:47:46 +01006408 .chain_id = ALC255_FIXUP_MIC_MUTE_LED
Kailang Yang9a22a8f52013-11-08 15:54:49 +08006409 },
Kailang Yang31278992014-03-03 15:27:22 +08006410 [ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC] = {
6411 .type = HDA_FIXUP_FUNC,
6412 .v.func = alc_fixup_headset_mode_alc255_no_hp_mic,
6413 },
Kailang Yanga22aa262014-04-23 17:34:28 +08006414 [ALC293_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6415 .type = HDA_FIXUP_PINS,
6416 .v.pins = (const struct hda_pintbl[]) {
6417 { 0x18, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6418 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6419 { }
6420 },
6421 .chained = true,
6422 .chain_id = ALC269_FIXUP_HEADSET_MODE
6423 },
Takashi Iwai1c37c222014-05-06 17:34:42 +02006424 [ALC292_FIXUP_TPT440_DOCK] = {
David Henningssonec56af62015-06-24 10:46:33 +02006425 .type = HDA_FIXUP_FUNC,
Takashi Iwai7f57d802015-09-24 17:36:51 +02006426 .v.func = alc_fixup_tpt440_dock,
Takashi Iwai1c37c222014-05-06 17:34:42 +02006427 .chained = true,
6428 .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST
6429 },
Takashi Iwai9a811232015-12-09 15:17:43 +01006430 [ALC292_FIXUP_TPT440] = {
6431 .type = HDA_FIXUP_FUNC,
Takashi Iwai157f0b72015-12-10 23:30:43 +01006432 .v.func = alc_fixup_disable_aamix,
Takashi Iwai9a811232015-12-09 15:17:43 +01006433 .chained = true,
6434 .chain_id = ALC292_FIXUP_TPT440_DOCK,
6435 },
Anisse Astierabaa22742016-08-24 09:14:13 +02006436 [ALC283_FIXUP_HEADSET_MIC] = {
Daniel Drake9dc12862014-07-22 10:58:29 +01006437 .type = HDA_FIXUP_PINS,
6438 .v.pins = (const struct hda_pintbl[]) {
6439 { 0x19, 0x04a110f0 },
6440 { },
6441 },
6442 },
Takashi Iwaib3802782018-11-26 17:47:46 +01006443 [ALC255_FIXUP_MIC_MUTE_LED] = {
Hui Wang00ef9942014-07-31 11:52:38 +08006444 .type = HDA_FIXUP_FUNC,
Takashi Iwaib3802782018-11-26 17:47:46 +01006445 .v.func = snd_hda_gen_fixup_micmute_led,
Hui Wang00ef9942014-07-31 11:52:38 +08006446 },
Takashi Iwai1a22e772014-08-27 08:19:05 +02006447 [ALC282_FIXUP_ASPIRE_V5_PINS] = {
6448 .type = HDA_FIXUP_PINS,
6449 .v.pins = (const struct hda_pintbl[]) {
6450 { 0x12, 0x90a60130 },
6451 { 0x14, 0x90170110 },
6452 { 0x17, 0x40000008 },
6453 { 0x18, 0x411111f0 },
Mateusz Sylwestrzak04206942015-07-19 17:38:56 +02006454 { 0x19, 0x01a1913c },
Takashi Iwai1a22e772014-08-27 08:19:05 +02006455 { 0x1a, 0x411111f0 },
6456 { 0x1b, 0x411111f0 },
6457 { 0x1d, 0x40f89b2d },
6458 { 0x1e, 0x411111f0 },
6459 { 0x21, 0x0321101f },
6460 { },
6461 },
6462 },
David Henningsson7a5255f2014-10-30 08:26:01 +01006463 [ALC280_FIXUP_HP_GPIO4] = {
6464 .type = HDA_FIXUP_FUNC,
6465 .v.func = alc280_fixup_hp_gpio4,
6466 },
Kailang Yangeaa8e5e2014-11-21 15:49:11 +08006467 [ALC286_FIXUP_HP_GPIO_LED] = {
6468 .type = HDA_FIXUP_FUNC,
6469 .v.func = alc286_fixup_hp_gpio_led,
6470 },
David Henningsson33f4acd2015-01-07 15:50:13 +01006471 [ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY] = {
6472 .type = HDA_FIXUP_FUNC,
6473 .v.func = alc280_fixup_hp_gpio2_mic_hotkey,
6474 },
TienFu Chenb4b33f92015-01-20 15:06:21 +01006475 [ALC280_FIXUP_HP_DOCK_PINS] = {
6476 .type = HDA_FIXUP_PINS,
6477 .v.pins = (const struct hda_pintbl[]) {
6478 { 0x1b, 0x21011020 }, /* line-out */
6479 { 0x1a, 0x01a1903c }, /* headset mic */
6480 { 0x18, 0x2181103f }, /* line-in */
6481 { },
6482 },
6483 .chained = true,
6484 .chain_id = ALC280_FIXUP_HP_GPIO4
6485 },
Jaroslav Kysela04d54662017-03-09 13:29:13 +01006486 [ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED] = {
6487 .type = HDA_FIXUP_PINS,
6488 .v.pins = (const struct hda_pintbl[]) {
6489 { 0x1b, 0x21011020 }, /* line-out */
6490 { 0x18, 0x2181103f }, /* line-in */
6491 { },
6492 },
6493 .chained = true,
6494 .chain_id = ALC269_FIXUP_HP_GPIO_MIC1_LED
6495 },
Keith Packard98973f22015-07-15 12:14:39 -07006496 [ALC280_FIXUP_HP_9480M] = {
6497 .type = HDA_FIXUP_FUNC,
6498 .v.func = alc280_fixup_hp_9480m,
6499 },
Kailang Yange1e62b92015-04-08 16:01:22 +08006500 [ALC288_FIXUP_DELL_HEADSET_MODE] = {
6501 .type = HDA_FIXUP_FUNC,
6502 .v.func = alc_fixup_headset_mode_dell_alc288,
6503 .chained = true,
Takashi Iwaib3802782018-11-26 17:47:46 +01006504 .chain_id = ALC255_FIXUP_MIC_MUTE_LED
Kailang Yange1e62b92015-04-08 16:01:22 +08006505 },
6506 [ALC288_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6507 .type = HDA_FIXUP_PINS,
6508 .v.pins = (const struct hda_pintbl[]) {
6509 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6510 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6511 { }
6512 },
6513 .chained = true,
6514 .chain_id = ALC288_FIXUP_DELL_HEADSET_MODE
6515 },
Hui Wang831bfdf92015-06-26 12:35:17 +08006516 [ALC288_FIXUP_DISABLE_AAMIX] = {
6517 .type = HDA_FIXUP_FUNC,
6518 .v.func = alc_fixup_disable_aamix,
6519 .chained = true,
Takashi Iwaid44a6862018-06-19 23:04:03 +02006520 .chain_id = ALC288_FIXUP_DELL1_MIC_NO_PRESENCE
Hui Wang831bfdf92015-06-26 12:35:17 +08006521 },
6522 [ALC288_FIXUP_DELL_XPS_13] = {
6523 .type = HDA_FIXUP_FUNC,
6524 .v.func = alc_fixup_dell_xps13,
6525 .chained = true,
6526 .chain_id = ALC288_FIXUP_DISABLE_AAMIX
6527 },
Takashi Iwai8b99aba2015-06-15 11:59:32 +02006528 [ALC292_FIXUP_DISABLE_AAMIX] = {
6529 .type = HDA_FIXUP_FUNC,
6530 .v.func = alc_fixup_disable_aamix,
Hui Wang831bfdf92015-06-26 12:35:17 +08006531 .chained = true,
6532 .chain_id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE
Takashi Iwai8b99aba2015-06-15 11:59:32 +02006533 },
David Henningssonc04017e2015-12-15 14:44:03 +01006534 [ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK] = {
6535 .type = HDA_FIXUP_FUNC,
6536 .v.func = alc_fixup_disable_aamix,
6537 .chained = true,
6538 .chain_id = ALC293_FIXUP_DELL1_MIC_NO_PRESENCE
6539 },
Takashi Iwai5fab5822020-01-05 09:11:19 +01006540 [ALC292_FIXUP_DELL_E7X_AAMIX] = {
Takashi Iwai8b99aba2015-06-15 11:59:32 +02006541 .type = HDA_FIXUP_FUNC,
6542 .v.func = alc_fixup_dell_xps13,
6543 .chained = true,
6544 .chain_id = ALC292_FIXUP_DISABLE_AAMIX
6545 },
Takashi Iwai5fab5822020-01-05 09:11:19 +01006546 [ALC292_FIXUP_DELL_E7X] = {
6547 .type = HDA_FIXUP_FUNC,
6548 .v.func = snd_hda_gen_fixup_micmute_led,
6549 /* micmute fixup must be applied at last */
6550 .chained_before = true,
6551 .chain_id = ALC292_FIXUP_DELL_E7X_AAMIX,
6552 },
James McDonnell54324222019-09-16 14:53:38 +00006553 [ALC298_FIXUP_ALIENWARE_MIC_NO_PRESENCE] = {
6554 .type = HDA_FIXUP_PINS,
6555 .v.pins = (const struct hda_pintbl[]) {
6556 { 0x18, 0x01a1913c }, /* headset mic w/o jack detect */
6557 { }
6558 },
6559 .chained_before = true,
6560 .chain_id = ALC269_FIXUP_HEADSET_MODE,
6561 },
Kailang Yang977e6272015-05-18 15:31:20 +08006562 [ALC298_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6563 .type = HDA_FIXUP_PINS,
6564 .v.pins = (const struct hda_pintbl[]) {
6565 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6566 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6567 { }
6568 },
6569 .chained = true,
6570 .chain_id = ALC269_FIXUP_HEADSET_MODE
6571 },
Hui Wang2f726ae2017-03-31 10:31:40 +08006572 [ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE] = {
6573 .type = HDA_FIXUP_PINS,
6574 .v.pins = (const struct hda_pintbl[]) {
6575 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6576 { }
6577 },
6578 .chained = true,
6579 .chain_id = ALC269_FIXUP_HEADSET_MODE
6580 },
Kailang Yang6ed11312015-10-26 15:37:39 +08006581 [ALC275_FIXUP_DELL_XPS] = {
6582 .type = HDA_FIXUP_VERBS,
6583 .v.verbs = (const struct hda_verb[]) {
6584 /* Enables internal speaker */
6585 {0x20, AC_VERB_SET_COEF_INDEX, 0x1f},
6586 {0x20, AC_VERB_SET_PROC_COEF, 0x00c0},
6587 {0x20, AC_VERB_SET_COEF_INDEX, 0x30},
6588 {0x20, AC_VERB_SET_PROC_COEF, 0x00b1},
6589 {}
6590 }
6591 },
Hui Wang8c697292015-11-24 11:08:18 +08006592 [ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE] = {
6593 .type = HDA_FIXUP_VERBS,
6594 .v.verbs = (const struct hda_verb[]) {
6595 /* Disable pass-through path for FRONT 14h */
6596 {0x20, AC_VERB_SET_COEF_INDEX, 0x36},
6597 {0x20, AC_VERB_SET_PROC_COEF, 0x1737},
6598 {}
6599 },
6600 .chained = true,
6601 .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
6602 },
Kai-Heng Feng1099f482019-10-03 12:39:19 +08006603 [ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE2] = {
6604 .type = HDA_FIXUP_FUNC,
6605 .v.func = alc256_fixup_dell_xps_13_headphone_noise2,
6606 .chained = true,
6607 .chain_id = ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE
6608 },
Hui Wang23adc192015-12-08 12:27:18 +08006609 [ALC293_FIXUP_LENOVO_SPK_NOISE] = {
6610 .type = HDA_FIXUP_FUNC,
6611 .v.func = alc_fixup_disable_aamix,
6612 .chained = true,
6613 .chain_id = ALC269_FIXUP_THINKPAD_ACPI
6614 },
Kailang3694cb22015-12-28 11:35:24 +08006615 [ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY] = {
6616 .type = HDA_FIXUP_FUNC,
6617 .v.func = alc233_fixup_lenovo_line2_mic_hotkey,
6618 },
Kai-Heng Feng3b43b712016-02-25 15:19:38 +08006619 [ALC255_FIXUP_DELL_SPK_NOISE] = {
6620 .type = HDA_FIXUP_FUNC,
6621 .v.func = alc_fixup_disable_aamix,
6622 .chained = true,
6623 .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
6624 },
Kailang Yangd1dd4212019-01-09 17:05:24 +08006625 [ALC225_FIXUP_DISABLE_MIC_VREF] = {
6626 .type = HDA_FIXUP_FUNC,
6627 .v.func = alc_fixup_disable_mic_vref,
6628 .chained = true,
6629 .chain_id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE
6630 },
David Henningsson2ae95572016-02-25 09:37:05 +01006631 [ALC225_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6632 .type = HDA_FIXUP_VERBS,
6633 .v.verbs = (const struct hda_verb[]) {
6634 /* Disable pass-through path for FRONT 14h */
6635 { 0x20, AC_VERB_SET_COEF_INDEX, 0x36 },
6636 { 0x20, AC_VERB_SET_PROC_COEF, 0x57d7 },
6637 {}
6638 },
6639 .chained = true,
Kailang Yangd1dd4212019-01-09 17:05:24 +08006640 .chain_id = ALC225_FIXUP_DISABLE_MIC_VREF
David Henningsson2ae95572016-02-25 09:37:05 +01006641 },
Takashi Iwaif8839822016-02-25 14:31:59 +01006642 [ALC280_FIXUP_HP_HEADSET_MIC] = {
6643 .type = HDA_FIXUP_FUNC,
6644 .v.func = alc_fixup_disable_aamix,
6645 .chained = true,
6646 .chain_id = ALC269_FIXUP_HEADSET_MIC,
6647 },
Hui Wange549d192016-04-01 11:00:15 +08006648 [ALC221_FIXUP_HP_FRONT_MIC] = {
6649 .type = HDA_FIXUP_PINS,
6650 .v.pins = (const struct hda_pintbl[]) {
6651 { 0x19, 0x02a19020 }, /* Front Mic */
6652 { }
6653 },
6654 },
Sven Eckelmannc636b952016-04-11 16:55:26 +02006655 [ALC292_FIXUP_TPT460] = {
6656 .type = HDA_FIXUP_FUNC,
6657 .v.func = alc_fixup_tpt440_dock,
6658 .chained = true,
6659 .chain_id = ALC293_FIXUP_LENOVO_SPK_NOISE,
6660 },
Hui Wangdd9aa332016-08-01 10:20:32 +08006661 [ALC298_FIXUP_SPK_VOLUME] = {
6662 .type = HDA_FIXUP_FUNC,
6663 .v.func = alc298_fixup_speaker_volume,
Hui Wang59ec4b52016-08-04 15:28:04 +08006664 .chained = true,
Hui Wang2f726ae2017-03-31 10:31:40 +08006665 .chain_id = ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE,
Hui Wangdd9aa332016-08-01 10:20:32 +08006666 },
Takashi Iwaie312a862018-03-06 12:14:17 +01006667 [ALC295_FIXUP_DISABLE_DAC3] = {
6668 .type = HDA_FIXUP_FUNC,
6669 .v.func = alc295_fixup_disable_dac3,
6670 },
Jaroslav Kyselad2cd7952019-11-29 15:40:27 +01006671 [ALC285_FIXUP_SPEAKER2_TO_DAC1] = {
6672 .type = HDA_FIXUP_FUNC,
6673 .v.func = alc285_fixup_speaker2_to_dac1,
6674 },
Kai-Heng Fengfd06c772016-08-30 15:36:34 +08006675 [ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER] = {
6676 .type = HDA_FIXUP_PINS,
6677 .v.pins = (const struct hda_pintbl[]) {
6678 { 0x1b, 0x90170151 },
6679 { }
6680 },
6681 .chained = true,
6682 .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
6683 },
Gabriele Mazzotta823ff162016-12-24 19:50:01 +01006684 [ALC269_FIXUP_ATIV_BOOK_8] = {
6685 .type = HDA_FIXUP_FUNC,
6686 .v.func = alc_fixup_auto_mute_via_amp,
6687 .chained = true,
6688 .chain_id = ALC269_FIXUP_NO_SHUTUP
6689 },
Kailang Yang9eb5d0e2017-01-17 15:40:25 +08006690 [ALC221_FIXUP_HP_MIC_NO_PRESENCE] = {
6691 .type = HDA_FIXUP_PINS,
6692 .v.pins = (const struct hda_pintbl[]) {
6693 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6694 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6695 { }
6696 },
6697 .chained = true,
6698 .chain_id = ALC269_FIXUP_HEADSET_MODE
6699 },
Chris Chiuc1732ed2017-02-28 14:17:13 -06006700 [ALC256_FIXUP_ASUS_HEADSET_MODE] = {
6701 .type = HDA_FIXUP_FUNC,
6702 .v.func = alc_fixup_headset_mode,
6703 },
6704 [ALC256_FIXUP_ASUS_MIC] = {
6705 .type = HDA_FIXUP_PINS,
6706 .v.pins = (const struct hda_pintbl[]) {
6707 { 0x13, 0x90a60160 }, /* use as internal mic */
6708 { 0x19, 0x04a11120 }, /* use as headset mic, without its own jack detect */
6709 { }
6710 },
6711 .chained = true,
6712 .chain_id = ALC256_FIXUP_ASUS_HEADSET_MODE
6713 },
Chris Chiueeed4cd2017-02-28 14:17:15 -06006714 [ALC256_FIXUP_ASUS_AIO_GPIO2] = {
Takashi Iwaiae065f12018-06-19 23:00:03 +02006715 .type = HDA_FIXUP_FUNC,
6716 /* Set up GPIO2 for the speaker amp */
6717 .v.func = alc_fixup_gpio4,
Chris Chiueeed4cd2017-02-28 14:17:15 -06006718 },
Chris Chiu216d7ae2017-02-28 14:17:14 -06006719 [ALC233_FIXUP_ASUS_MIC_NO_PRESENCE] = {
6720 .type = HDA_FIXUP_PINS,
6721 .v.pins = (const struct hda_pintbl[]) {
6722 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6723 { }
6724 },
6725 .chained = true,
6726 .chain_id = ALC269_FIXUP_HEADSET_MIC
6727 },
6728 [ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE] = {
6729 .type = HDA_FIXUP_VERBS,
6730 .v.verbs = (const struct hda_verb[]) {
6731 /* Enables internal speaker */
6732 {0x20, AC_VERB_SET_COEF_INDEX, 0x40},
6733 {0x20, AC_VERB_SET_PROC_COEF, 0x8800},
6734 {}
6735 },
6736 .chained = true,
6737 .chain_id = ALC233_FIXUP_ASUS_MIC_NO_PRESENCE
6738 },
Kailang Yangca169cc2017-04-25 16:17:40 +08006739 [ALC233_FIXUP_LENOVO_MULTI_CODECS] = {
6740 .type = HDA_FIXUP_FUNC,
6741 .v.func = alc233_alc662_fixup_lenovo_dual_codecs,
6742 },
Jian-Hong Panea5c7eb2019-04-01 11:25:05 +08006743 [ALC233_FIXUP_ACER_HEADSET_MIC] = {
6744 .type = HDA_FIXUP_VERBS,
6745 .v.verbs = (const struct hda_verb[]) {
6746 { 0x20, AC_VERB_SET_COEF_INDEX, 0x45 },
6747 { 0x20, AC_VERB_SET_PROC_COEF, 0x5089 },
6748 { }
6749 },
6750 .chained = true,
6751 .chain_id = ALC233_FIXUP_ASUS_MIC_NO_PRESENCE
6752 },
Hui Wangf33f79f2017-07-07 12:08:29 +08006753 [ALC294_FIXUP_LENOVO_MIC_LOCATION] = {
6754 .type = HDA_FIXUP_PINS,
6755 .v.pins = (const struct hda_pintbl[]) {
6756 /* Change the mic location from front to right, otherwise there are
6757 two front mics with the same name, pulseaudio can't handle them.
6758 This is just a temporary workaround, after applying this fixup,
6759 there will be one "Front Mic" and one "Mic" in this machine.
6760 */
6761 { 0x1a, 0x04a19040 },
6762 { }
6763 },
6764 },
Kailang Yang5f364132017-07-25 16:28:16 +08006765 [ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE] = {
6766 .type = HDA_FIXUP_PINS,
6767 .v.pins = (const struct hda_pintbl[]) {
6768 { 0x16, 0x0101102f }, /* Rear Headset HP */
6769 { 0x19, 0x02a1913c }, /* use as Front headset mic, without its own jack detect */
6770 { 0x1a, 0x01a19030 }, /* Rear Headset MIC */
6771 { 0x1b, 0x02011020 },
6772 { }
6773 },
6774 .chained = true,
6775 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
6776 },
PeiSen Houb84e8432017-09-01 15:11:56 +08006777 [ALC700_FIXUP_INTEL_REFERENCE] = {
6778 .type = HDA_FIXUP_VERBS,
6779 .v.verbs = (const struct hda_verb[]) {
6780 /* Enables internal speaker */
6781 {0x20, AC_VERB_SET_COEF_INDEX, 0x45},
6782 {0x20, AC_VERB_SET_PROC_COEF, 0x5289},
6783 {0x20, AC_VERB_SET_COEF_INDEX, 0x4A},
6784 {0x20, AC_VERB_SET_PROC_COEF, 0x001b},
6785 {0x58, AC_VERB_SET_COEF_INDEX, 0x00},
6786 {0x58, AC_VERB_SET_PROC_COEF, 0x3888},
6787 {0x20, AC_VERB_SET_COEF_INDEX, 0x6f},
6788 {0x20, AC_VERB_SET_PROC_COEF, 0x2c0b},
6789 {}
6790 }
6791 },
Kailang Yang92266652017-12-14 15:28:58 +08006792 [ALC274_FIXUP_DELL_BIND_DACS] = {
6793 .type = HDA_FIXUP_FUNC,
6794 .v.func = alc274_fixup_bind_dacs,
6795 .chained = true,
6796 .chain_id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE
6797 },
6798 [ALC274_FIXUP_DELL_AIO_LINEOUT_VERB] = {
6799 .type = HDA_FIXUP_PINS,
6800 .v.pins = (const struct hda_pintbl[]) {
6801 { 0x1b, 0x0401102f },
6802 { }
6803 },
6804 .chained = true,
6805 .chain_id = ALC274_FIXUP_DELL_BIND_DACS
6806 },
Kailang Yang61fcf8e2018-02-02 15:26:46 +08006807 [ALC298_FIXUP_TPT470_DOCK] = {
6808 .type = HDA_FIXUP_FUNC,
6809 .v.func = alc_fixup_tpt470_dock,
6810 .chained = true,
6811 .chain_id = ALC293_FIXUP_LENOVO_SPK_NOISE
6812 },
Kailang Yangae104a22018-02-05 16:07:20 +08006813 [ALC255_FIXUP_DUMMY_LINEOUT_VERB] = {
6814 .type = HDA_FIXUP_PINS,
6815 .v.pins = (const struct hda_pintbl[]) {
6816 { 0x14, 0x0201101f },
6817 { }
6818 },
6819 .chained = true,
6820 .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
6821 },
Kailang Yangf0ba9d62018-03-16 11:46:08 +08006822 [ALC255_FIXUP_DELL_HEADSET_MIC] = {
6823 .type = HDA_FIXUP_PINS,
6824 .v.pins = (const struct hda_pintbl[]) {
6825 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6826 { }
6827 },
Hui Wang3ce0d5a2018-04-19 13:29:04 +08006828 .chained = true,
6829 .chain_id = ALC269_FIXUP_HEADSET_MIC
Kailang Yangf0ba9d62018-03-16 11:46:08 +08006830 },
Tom Bridenbbf8ff62018-05-29 17:34:20 +01006831 [ALC295_FIXUP_HP_X360] = {
6832 .type = HDA_FIXUP_FUNC,
6833 .v.func = alc295_fixup_hp_top_speakers,
6834 .chained = true,
6835 .chain_id = ALC269_FIXUP_HP_MUTE_LED_MIC3
Kailang Yang8a328ac2018-08-21 16:54:41 +08006836 },
6837 [ALC221_FIXUP_HP_HEADSET_MIC] = {
6838 .type = HDA_FIXUP_PINS,
6839 .v.pins = (const struct hda_pintbl[]) {
6840 { 0x19, 0x0181313f},
6841 { }
6842 },
6843 .chained = true,
6844 .chain_id = ALC269_FIXUP_HEADSET_MIC
6845 },
Hui Wangc4cfcf62018-11-26 14:17:16 +08006846 [ALC285_FIXUP_LENOVO_HEADPHONE_NOISE] = {
6847 .type = HDA_FIXUP_FUNC,
6848 .v.func = alc285_fixup_invalidate_dacs,
Hui Wang6ba189c2018-12-09 09:16:43 +08006849 .chained = true,
6850 .chain_id = ALC269_FIXUP_THINKPAD_ACPI
Hui Wangc4cfcf62018-11-26 14:17:16 +08006851 },
Girija Kumar Kasinadhunie8ed64b2018-11-26 13:40:46 -05006852 [ALC295_FIXUP_HP_AUTO_MUTE] = {
6853 .type = HDA_FIXUP_FUNC,
6854 .v.func = alc_fixup_auto_mute_via_amp,
6855 },
Chris Chiu33aaebd2018-12-05 14:48:53 +08006856 [ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE] = {
6857 .type = HDA_FIXUP_PINS,
6858 .v.pins = (const struct hda_pintbl[]) {
6859 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6860 { }
6861 },
6862 .chained = true,
6863 .chain_id = ALC269_FIXUP_HEADSET_MIC
6864 },
Chris Chiud8ae4582018-12-07 17:17:11 +08006865 [ALC294_FIXUP_ASUS_MIC] = {
6866 .type = HDA_FIXUP_PINS,
6867 .v.pins = (const struct hda_pintbl[]) {
6868 { 0x13, 0x90a60160 }, /* use as internal mic */
6869 { 0x19, 0x04a11120 }, /* use as headset mic, without its own jack detect */
6870 { }
6871 },
6872 .chained = true,
6873 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
6874 },
Jian-Hong Pan4e051102018-12-07 17:17:12 +08006875 [ALC294_FIXUP_ASUS_HEADSET_MIC] = {
6876 .type = HDA_FIXUP_PINS,
6877 .v.pins = (const struct hda_pintbl[]) {
Jian-Hong Pan82b01142018-12-27 16:46:31 +08006878 { 0x19, 0x01a1103c }, /* use as headset mic */
Jian-Hong Pan4e051102018-12-07 17:17:12 +08006879 { }
6880 },
6881 .chained = true,
6882 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
6883 },
6884 [ALC294_FIXUP_ASUS_SPK] = {
6885 .type = HDA_FIXUP_VERBS,
6886 .v.verbs = (const struct hda_verb[]) {
6887 /* Set EAPD high */
6888 { 0x20, AC_VERB_SET_COEF_INDEX, 0x40 },
6889 { 0x20, AC_VERB_SET_PROC_COEF, 0x8800 },
6890 { }
6891 },
6892 .chained = true,
6893 .chain_id = ALC294_FIXUP_ASUS_HEADSET_MIC
6894 },
Jaroslav Kyselac8a9afa2019-03-14 09:21:08 +01006895 [ALC295_FIXUP_CHROME_BOOK] = {
Kailang Yange8547472018-11-28 15:32:45 +08006896 .type = HDA_FIXUP_FUNC,
Jaroslav Kyselac8a9afa2019-03-14 09:21:08 +01006897 .v.func = alc295_fixup_chromebook,
Kailang Yang8983eb62019-04-03 15:31:49 +08006898 .chained = true,
6899 .chain_id = ALC225_FIXUP_HEADSET_JACK
6900 },
6901 [ALC225_FIXUP_HEADSET_JACK] = {
6902 .type = HDA_FIXUP_FUNC,
6903 .v.func = alc_fixup_headset_jack,
Kailang Yange8547472018-11-28 15:32:45 +08006904 },
Jeremy Soller89e3a562019-01-30 16:12:31 -07006905 [ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE] = {
6906 .type = HDA_FIXUP_PINS,
6907 .v.pins = (const struct hda_pintbl[]) {
6908 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6909 { }
6910 },
6911 .chained = true,
6912 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
6913 },
Hui Wangc8c6ee62019-02-14 11:41:33 +08006914 [ALC285_FIXUP_LENOVO_PC_BEEP_IN_NOISE] = {
6915 .type = HDA_FIXUP_VERBS,
6916 .v.verbs = (const struct hda_verb[]) {
6917 /* Disable PCBEEP-IN passthrough */
6918 { 0x20, AC_VERB_SET_COEF_INDEX, 0x36 },
6919 { 0x20, AC_VERB_SET_PROC_COEF, 0x57d7 },
6920 { }
6921 },
6922 .chained = true,
6923 .chain_id = ALC285_FIXUP_LENOVO_HEADPHONE_NOISE
6924 },
Jian-Hong Pancbc05fd2019-03-13 17:33:24 +08006925 [ALC255_FIXUP_ACER_HEADSET_MIC] = {
6926 .type = HDA_FIXUP_PINS,
6927 .v.pins = (const struct hda_pintbl[]) {
6928 { 0x19, 0x03a11130 },
6929 { 0x1a, 0x90a60140 }, /* use as internal mic */
6930 { }
6931 },
6932 .chained = true,
6933 .chain_id = ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC
6934 },
Kailang Yang136824e2019-03-14 16:22:45 +08006935 [ALC225_FIXUP_DELL_WYSE_AIO_MIC_NO_PRESENCE] = {
6936 .type = HDA_FIXUP_PINS,
6937 .v.pins = (const struct hda_pintbl[]) {
6938 { 0x16, 0x01011020 }, /* Rear Line out */
6939 { 0x19, 0x01a1913c }, /* use as Front headset mic, without its own jack detect */
6940 { }
6941 },
6942 .chained = true,
6943 .chain_id = ALC225_FIXUP_WYSE_AUTO_MUTE
6944 },
6945 [ALC225_FIXUP_WYSE_AUTO_MUTE] = {
6946 .type = HDA_FIXUP_FUNC,
6947 .v.func = alc_fixup_auto_mute_via_amp,
6948 .chained = true,
6949 .chain_id = ALC225_FIXUP_WYSE_DISABLE_MIC_VREF
6950 },
6951 [ALC225_FIXUP_WYSE_DISABLE_MIC_VREF] = {
6952 .type = HDA_FIXUP_FUNC,
6953 .v.func = alc_fixup_disable_mic_vref,
6954 .chained = true,
6955 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
6956 },
Jian-Hong Pan667a8f72019-03-15 17:51:09 +08006957 [ALC286_FIXUP_ACER_AIO_HEADSET_MIC] = {
6958 .type = HDA_FIXUP_VERBS,
6959 .v.verbs = (const struct hda_verb[]) {
6960 { 0x20, AC_VERB_SET_COEF_INDEX, 0x4f },
6961 { 0x20, AC_VERB_SET_PROC_COEF, 0x5029 },
6962 { }
6963 },
6964 .chained = true,
6965 .chain_id = ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE
6966 },
Daniel Drake8c8967a2019-10-17 16:15:01 +08006967 [ALC256_FIXUP_ASUS_HEADSET_MIC] = {
6968 .type = HDA_FIXUP_PINS,
6969 .v.pins = (const struct hda_pintbl[]) {
6970 { 0x19, 0x03a11020 }, /* headset mic with jack detect */
6971 { }
6972 },
6973 .chained = true,
6974 .chain_id = ALC256_FIXUP_ASUS_HEADSET_MODE
6975 },
Jian-Hong Pane1037352019-03-22 11:37:18 +08006976 [ALC256_FIXUP_ASUS_MIC_NO_PRESENCE] = {
6977 .type = HDA_FIXUP_PINS,
6978 .v.pins = (const struct hda_pintbl[]) {
6979 { 0x19, 0x04a11120 }, /* use as headset mic, without its own jack detect */
6980 { }
6981 },
6982 .chained = true,
6983 .chain_id = ALC256_FIXUP_ASUS_HEADSET_MODE
6984 },
Bernhard Rosenkraenzere2a829b2019-03-05 00:38:19 +01006985 [ALC299_FIXUP_PREDATOR_SPK] = {
6986 .type = HDA_FIXUP_PINS,
6987 .v.pins = (const struct hda_pintbl[]) {
6988 { 0x21, 0x90170150 }, /* use as headset mic, without its own jack detect */
6989 { }
6990 }
6991 },
Jian-Hong Pan60083f92019-09-02 18:00:56 +08006992 [ALC294_FIXUP_ASUS_INTSPK_HEADSET_MIC] = {
6993 .type = HDA_FIXUP_PINS,
6994 .v.pins = (const struct hda_pintbl[]) {
6995 { 0x14, 0x411111f0 }, /* disable confusing internal speaker */
6996 { 0x19, 0x04a11150 }, /* use as headset mic, without its own jack detect */
6997 { }
6998 },
6999 .chained = true,
7000 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
7001 },
Jan-Marek Glogowskibd9c10b2019-09-15 16:57:28 +02007002 [ALC256_FIXUP_MEDION_HEADSET_NO_PRESENCE] = {
7003 .type = HDA_FIXUP_PINS,
7004 .v.pins = (const struct hda_pintbl[]) {
7005 { 0x19, 0x04a11040 },
7006 { 0x21, 0x04211020 },
7007 { }
7008 },
7009 .chained = true,
7010 .chain_id = ALC256_FIXUP_ASUS_HEADSET_MODE
7011 },
Jian-Hong Pan436e2552019-11-25 17:34:06 +08007012 [ALC294_FIXUP_ASUS_INTSPK_GPIO] = {
7013 .type = HDA_FIXUP_FUNC,
7014 /* The GPIO must be pulled to initialize the AMP */
7015 .v.func = alc_fixup_gpio4,
7016 .chained = true,
7017 .chain_id = ALC294_FIXUP_ASUS_INTSPK_HEADSET_MIC
7018 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02007019};
7020
7021static const struct snd_pci_quirk alc269_fixup_tbl[] = {
Marius Knausta6b92b62014-03-03 01:48:58 +01007022 SND_PCI_QUIRK(0x1025, 0x0283, "Acer TravelMate 8371", ALC269_FIXUP_INV_DMIC),
David Henningsson693b6132012-06-22 19:12:10 +02007023 SND_PCI_QUIRK(0x1025, 0x029b, "Acer 1810TZ", ALC269_FIXUP_INV_DMIC),
7024 SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC),
David Henningssonaaedfb42013-08-16 14:09:02 +02007025 SND_PCI_QUIRK(0x1025, 0x047c, "Acer AC700", ALC269_FIXUP_ACER_AC700),
Takashi Iwai78197172015-06-27 10:21:13 +02007026 SND_PCI_QUIRK(0x1025, 0x072d, "Acer Aspire V5-571G", ALC269_FIXUP_ASPIRE_HEADSET_MIC),
7027 SND_PCI_QUIRK(0x1025, 0x080d, "Acer Aspire V5-122P", ALC269_FIXUP_ASPIRE_HEADSET_MIC),
David Henningssonaaedfb42013-08-16 14:09:02 +02007028 SND_PCI_QUIRK(0x1025, 0x0740, "Acer AO725", ALC271_FIXUP_HP_GATE_MIC_JACK),
7029 SND_PCI_QUIRK(0x1025, 0x0742, "Acer AO756", ALC271_FIXUP_HP_GATE_MIC_JACK),
Simon South02322ac2016-03-02 23:10:44 -05007030 SND_PCI_QUIRK(0x1025, 0x0762, "Acer Aspire E1-472", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572),
Oleksij Rempelb1e89722013-12-04 20:50:53 +01007031 SND_PCI_QUIRK(0x1025, 0x0775, "Acer Aspire E1-572", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572),
Takashi Iwai1a22e772014-08-27 08:19:05 +02007032 SND_PCI_QUIRK(0x1025, 0x079b, "Acer Aspire V5-573G", ALC282_FIXUP_ASPIRE_V5_PINS),
Chris Chiu705b65f2018-12-05 14:48:54 +08007033 SND_PCI_QUIRK(0x1025, 0x102b, "Acer Aspire C24-860", ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE),
Takashi Iwaib9c2fa52015-11-19 16:39:50 +01007034 SND_PCI_QUIRK(0x1025, 0x106d, "Acer Cloudbook 14", ALC283_FIXUP_CHROME_BOOK),
Chris Chiuc7531e32019-03-21 17:17:31 +08007035 SND_PCI_QUIRK(0x1025, 0x1099, "Acer Aspire E5-523G", ALC255_FIXUP_ACER_MIC_NO_PRESENCE),
7036 SND_PCI_QUIRK(0x1025, 0x110e, "Acer Aspire ES1-432", ALC255_FIXUP_ACER_MIC_NO_PRESENCE),
Bernhard Rosenkraenzere2a829b2019-03-05 00:38:19 +01007037 SND_PCI_QUIRK(0x1025, 0x1246, "Acer Predator Helios 500", ALC299_FIXUP_PREDATOR_SPK),
Jian-Hong Pan667a8f72019-03-15 17:51:09 +08007038 SND_PCI_QUIRK(0x1025, 0x128f, "Acer Veriton Z6860G", ALC286_FIXUP_ACER_AIO_HEADSET_MIC),
7039 SND_PCI_QUIRK(0x1025, 0x1290, "Acer Veriton Z4860G", ALC286_FIXUP_ACER_AIO_HEADSET_MIC),
7040 SND_PCI_QUIRK(0x1025, 0x1291, "Acer Veriton Z4660G", ALC286_FIXUP_ACER_AIO_HEADSET_MIC),
Jian-Hong Pan2733cce2019-03-21 16:39:04 +08007041 SND_PCI_QUIRK(0x1025, 0x1308, "Acer Aspire Z24-890", ALC286_FIXUP_ACER_AIO_HEADSET_MIC),
Jian-Hong Panea5c7eb2019-04-01 11:25:05 +08007042 SND_PCI_QUIRK(0x1025, 0x132a, "Acer TravelMate B114-21", ALC233_FIXUP_ACER_HEADSET_MIC),
Jian-Hong Pancbc05fd2019-03-13 17:33:24 +08007043 SND_PCI_QUIRK(0x1025, 0x1330, "Acer TravelMate X514-51T", ALC255_FIXUP_ACER_HEADSET_MIC),
David Henningssonaaedfb42013-08-16 14:09:02 +02007044 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
Kailang Yang6ed11312015-10-26 15:37:39 +08007045 SND_PCI_QUIRK(0x1028, 0x054b, "Dell XPS one 2710", ALC275_FIXUP_DELL_XPS),
Takashi Iwai86f799b2015-11-14 17:46:31 +01007046 SND_PCI_QUIRK(0x1028, 0x05bd, "Dell Latitude E6440", ALC292_FIXUP_DELL_E7X),
Takashi Iwaicf521032016-01-15 12:59:25 +01007047 SND_PCI_QUIRK(0x1028, 0x05be, "Dell Latitude E6540", ALC292_FIXUP_DELL_E7X),
Takashi Iwai8b99aba2015-06-15 11:59:32 +02007048 SND_PCI_QUIRK(0x1028, 0x05ca, "Dell Latitude E7240", ALC292_FIXUP_DELL_E7X),
7049 SND_PCI_QUIRK(0x1028, 0x05cb, "Dell Latitude E7440", ALC292_FIXUP_DELL_E7X),
David Henningsson0f4881d2013-12-20 16:08:13 +01007050 SND_PCI_QUIRK(0x1028, 0x05da, "Dell Vostro 5460", ALC290_FIXUP_SUBWOOFER),
David Henningsson73bdd592013-04-15 15:44:14 +02007051 SND_PCI_QUIRK(0x1028, 0x05f4, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
7052 SND_PCI_QUIRK(0x1028, 0x05f5, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
7053 SND_PCI_QUIRK(0x1028, 0x05f6, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
David Henningsson0f4881d2013-12-20 16:08:13 +01007054 SND_PCI_QUIRK(0x1028, 0x0615, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK),
7055 SND_PCI_QUIRK(0x1028, 0x0616, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK),
Takashi Iwai98070572016-01-12 21:06:39 +01007056 SND_PCI_QUIRK(0x1028, 0x062c, "Dell Latitude E5550", ALC292_FIXUP_DELL_E7X),
Takashi Iwai42755542015-06-29 10:56:53 +02007057 SND_PCI_QUIRK(0x1028, 0x062e, "Dell Latitude E7450", ALC292_FIXUP_DELL_E7X),
David Henningsson0f4881d2013-12-20 16:08:13 +01007058 SND_PCI_QUIRK(0x1028, 0x0638, "Dell Inspiron 5439", ALC290_FIXUP_MONO_SPEAKERS_HSJACK),
Kailang Yanga22aa262014-04-23 17:34:28 +08007059 SND_PCI_QUIRK(0x1028, 0x064a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
7060 SND_PCI_QUIRK(0x1028, 0x064b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
Hui Wang831bfdf92015-06-26 12:35:17 +08007061 SND_PCI_QUIRK(0x1028, 0x0665, "Dell XPS 13", ALC288_FIXUP_DELL_XPS_13),
Bastien Noceraafecb142016-04-18 11:10:42 +02007062 SND_PCI_QUIRK(0x1028, 0x0669, "Dell Optiplex 9020m", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
Takashi Iwai3a05d122015-07-29 09:04:52 +02007063 SND_PCI_QUIRK(0x1028, 0x069a, "Dell Vostro 5480", ALC290_FIXUP_SUBWOOFER_HSJACK),
Kailang Yang8b724152014-12-17 17:08:59 +08007064 SND_PCI_QUIRK(0x1028, 0x06c7, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
Kailang Yangb7343042014-12-02 14:50:45 +08007065 SND_PCI_QUIRK(0x1028, 0x06d9, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
7066 SND_PCI_QUIRK(0x1028, 0x06da, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
David Henningssonc04017e2015-12-15 14:44:03 +01007067 SND_PCI_QUIRK(0x1028, 0x06db, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
7068 SND_PCI_QUIRK(0x1028, 0x06dd, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
7069 SND_PCI_QUIRK(0x1028, 0x06de, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
7070 SND_PCI_QUIRK(0x1028, 0x06df, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
7071 SND_PCI_QUIRK(0x1028, 0x06e0, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
Kai-Heng Feng1099f482019-10-03 12:39:19 +08007072 SND_PCI_QUIRK(0x1028, 0x0704, "Dell XPS 13 9350", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE2),
Kai-Heng Fengfd06c772016-08-30 15:36:34 +08007073 SND_PCI_QUIRK(0x1028, 0x0706, "Dell Inspiron 7559", ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER),
Kai-Heng Feng3b43b712016-02-25 15:19:38 +08007074 SND_PCI_QUIRK(0x1028, 0x0725, "Dell Inspiron 3162", ALC255_FIXUP_DELL_SPK_NOISE),
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01007075 SND_PCI_QUIRK(0x1028, 0x0738, "Dell Precision 5820", ALC269_FIXUP_NO_SHUTUP),
Kai-Heng Feng1099f482019-10-03 12:39:19 +08007076 SND_PCI_QUIRK(0x1028, 0x075b, "Dell XPS 13 9360", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE2),
Kai-Heng Feng709ae622018-10-04 11:39:42 +08007077 SND_PCI_QUIRK(0x1028, 0x075c, "Dell XPS 27 7760", ALC298_FIXUP_SPK_VOLUME),
Hui Wangdd9aa332016-08-01 10:20:32 +08007078 SND_PCI_QUIRK(0x1028, 0x075d, "Dell AIO", ALC298_FIXUP_SPK_VOLUME),
Takashi Iwaie312a862018-03-06 12:14:17 +01007079 SND_PCI_QUIRK(0x1028, 0x07b0, "Dell Precision 7520", ALC295_FIXUP_DISABLE_DAC3),
Takashi Iwai493de342017-02-28 17:27:57 +01007080 SND_PCI_QUIRK(0x1028, 0x0798, "Dell Inspiron 17 7000 Gaming", ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER),
Kailang Yang5f364132017-07-25 16:28:16 +08007081 SND_PCI_QUIRK(0x1028, 0x080c, "Dell WYSE", ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE),
Kai-Heng Feng1099f482019-10-03 12:39:19 +08007082 SND_PCI_QUIRK(0x1028, 0x082a, "Dell XPS 13 9360", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE2),
Kailang Yang40e2c4e2018-02-02 15:13:09 +08007083 SND_PCI_QUIRK(0x1028, 0x084b, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB),
7084 SND_PCI_QUIRK(0x1028, 0x084e, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB),
Kailang Yangf0ba9d62018-03-16 11:46:08 +08007085 SND_PCI_QUIRK(0x1028, 0x0871, "Dell Precision 3630", ALC255_FIXUP_DELL_HEADSET_MIC),
7086 SND_PCI_QUIRK(0x1028, 0x0872, "Dell Precision 3630", ALC255_FIXUP_DELL_HEADSET_MIC),
Kailang Yangae104a22018-02-05 16:07:20 +08007087 SND_PCI_QUIRK(0x1028, 0x0873, "Dell Precision 3930", ALC255_FIXUP_DUMMY_LINEOUT_VERB),
Kailang Yang136824e2019-03-14 16:22:45 +08007088 SND_PCI_QUIRK(0x1028, 0x08ad, "Dell WYSE AIO", ALC225_FIXUP_DELL_WYSE_AIO_MIC_NO_PRESENCE),
Kailang Yangda484d02019-03-14 15:50:59 +08007089 SND_PCI_QUIRK(0x1028, 0x08ae, "Dell WYSE NB", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE),
Kailang Yangc2a7c55a2019-01-03 15:53:39 +08007090 SND_PCI_QUIRK(0x1028, 0x0935, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB),
Kailang Yanga22aa262014-04-23 17:34:28 +08007091 SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
7092 SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
Takashi Iwai08fb0d02013-01-10 17:33:58 +01007093 SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01007094 SND_PCI_QUIRK(0x103c, 0x18e6, "HP", ALC269_FIXUP_HP_GPIO_LED),
David Henningsson8e35cd42013-11-06 11:20:01 +01007095 SND_PCI_QUIRK(0x103c, 0x218b, "HP", ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED),
David Henningsson33f4acd2015-01-07 15:50:13 +01007096 SND_PCI_QUIRK(0x103c, 0x225f, "HP", ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY),
Kailang Yangc60666b2014-02-21 16:23:35 +08007097 /* ALC282 */
Hui Wang7976eb42015-02-13 11:14:41 +08007098 SND_PCI_QUIRK(0x103c, 0x21f9, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang8a02b162014-06-13 17:16:31 +08007099 SND_PCI_QUIRK(0x103c, 0x2210, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang8a02b162014-06-13 17:16:31 +08007100 SND_PCI_QUIRK(0x103c, 0x2214, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007101 SND_PCI_QUIRK(0x103c, 0x2236, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
7102 SND_PCI_QUIRK(0x103c, 0x2237, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
7103 SND_PCI_QUIRK(0x103c, 0x2238, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
7104 SND_PCI_QUIRK(0x103c, 0x2239, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007105 SND_PCI_QUIRK(0x103c, 0x224b, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
Kailang Yangc60666b2014-02-21 16:23:35 +08007106 SND_PCI_QUIRK(0x103c, 0x2268, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08007107 SND_PCI_QUIRK(0x103c, 0x226a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7108 SND_PCI_QUIRK(0x103c, 0x226b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang8a02b162014-06-13 17:16:31 +08007109 SND_PCI_QUIRK(0x103c, 0x226e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangeaa8e5e2014-11-21 15:49:11 +08007110 SND_PCI_QUIRK(0x103c, 0x2271, "HP", ALC286_FIXUP_HP_GPIO_LED),
TienFu Chenb4b33f92015-01-20 15:06:21 +01007111 SND_PCI_QUIRK(0x103c, 0x2272, "HP", ALC280_FIXUP_HP_DOCK_PINS),
TienFu Chen3271cb22015-02-10 09:09:41 +01007112 SND_PCI_QUIRK(0x103c, 0x2273, "HP", ALC280_FIXUP_HP_DOCK_PINS),
Kailang Yangc60666b2014-02-21 16:23:35 +08007113 SND_PCI_QUIRK(0x103c, 0x229e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08007114 SND_PCI_QUIRK(0x103c, 0x22b2, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7115 SND_PCI_QUIRK(0x103c, 0x22b7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7116 SND_PCI_QUIRK(0x103c, 0x22bf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08007117 SND_PCI_QUIRK(0x103c, 0x22cf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Keith Packard98973f22015-07-15 12:14:39 -07007118 SND_PCI_QUIRK(0x103c, 0x22db, "HP", ALC280_FIXUP_HP_9480M),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007119 SND_PCI_QUIRK(0x103c, 0x22dc, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
7120 SND_PCI_QUIRK(0x103c, 0x22fb, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yangc60666b2014-02-21 16:23:35 +08007121 /* ALC290 */
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007122 SND_PCI_QUIRK(0x103c, 0x221b, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007123 SND_PCI_QUIRK(0x103c, 0x2221, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007124 SND_PCI_QUIRK(0x103c, 0x2225, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007125 SND_PCI_QUIRK(0x103c, 0x2253, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
7126 SND_PCI_QUIRK(0x103c, 0x2254, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
7127 SND_PCI_QUIRK(0x103c, 0x2255, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
7128 SND_PCI_QUIRK(0x103c, 0x2256, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
7129 SND_PCI_QUIRK(0x103c, 0x2257, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007130 SND_PCI_QUIRK(0x103c, 0x2259, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Jaroslav Kysela04d54662017-03-09 13:29:13 +01007131 SND_PCI_QUIRK(0x103c, 0x225a, "HP", ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED),
Kailang Yangc60666b2014-02-21 16:23:35 +08007132 SND_PCI_QUIRK(0x103c, 0x2260, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08007133 SND_PCI_QUIRK(0x103c, 0x2263, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7134 SND_PCI_QUIRK(0x103c, 0x2264, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7135 SND_PCI_QUIRK(0x103c, 0x2265, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007136 SND_PCI_QUIRK(0x103c, 0x2272, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
7137 SND_PCI_QUIRK(0x103c, 0x2273, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007138 SND_PCI_QUIRK(0x103c, 0x2278, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yangc60666b2014-02-21 16:23:35 +08007139 SND_PCI_QUIRK(0x103c, 0x227f, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08007140 SND_PCI_QUIRK(0x103c, 0x2282, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08007141 SND_PCI_QUIRK(0x103c, 0x228b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08007142 SND_PCI_QUIRK(0x103c, 0x228e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7143 SND_PCI_QUIRK(0x103c, 0x22c5, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08007144 SND_PCI_QUIRK(0x103c, 0x22c7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7145 SND_PCI_QUIRK(0x103c, 0x22c8, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08007146 SND_PCI_QUIRK(0x103c, 0x22c4, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang8a02b162014-06-13 17:16:31 +08007147 SND_PCI_QUIRK(0x103c, 0x2334, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7148 SND_PCI_QUIRK(0x103c, 0x2335, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7149 SND_PCI_QUIRK(0x103c, 0x2336, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7150 SND_PCI_QUIRK(0x103c, 0x2337, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Takashi Iwaif8839822016-02-25 14:31:59 +01007151 SND_PCI_QUIRK(0x103c, 0x221c, "HP EliteBook 755 G2", ALC280_FIXUP_HP_HEADSET_MIC),
Jaroslav Kysela167897f2019-03-13 13:40:15 +01007152 SND_PCI_QUIRK(0x103c, 0x802e, "HP Z240 SFF", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
7153 SND_PCI_QUIRK(0x103c, 0x802f, "HP Z240", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
Takashi Iwai563785e2018-11-12 09:43:12 +01007154 SND_PCI_QUIRK(0x103c, 0x820d, "HP Pavilion 15", ALC269_FIXUP_HP_MUTE_LED_MIC3),
Hui Wange549d192016-04-01 11:00:15 +08007155 SND_PCI_QUIRK(0x103c, 0x8256, "HP", ALC221_FIXUP_HP_FRONT_MIC),
Tom Bridenbbf8ff62018-05-29 17:34:20 +01007156 SND_PCI_QUIRK(0x103c, 0x827e, "HP x360", ALC295_FIXUP_HP_X360),
Jaroslav Kysela167897f2019-03-13 13:40:15 +01007157 SND_PCI_QUIRK(0x103c, 0x82bf, "HP G3 mini", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
7158 SND_PCI_QUIRK(0x103c, 0x82c0, "HP G3 mini premium", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
Alexandru Gagniuc56e40eb2018-08-04 11:44:44 -05007159 SND_PCI_QUIRK(0x103c, 0x83b9, "HP Spectre x360", ALC269_FIXUP_HP_MUTE_LED_MIC3),
Takashi Iwai190d0382019-08-13 17:39:56 +02007160 SND_PCI_QUIRK(0x103c, 0x8497, "HP Envy x360", ALC269_FIXUP_HP_MUTE_LED_MIC3),
Sam Bazleyd33cd422019-09-01 03:31:30 +01007161 SND_PCI_QUIRK(0x103c, 0x84e7, "HP Pavilion 15", ALC269_FIXUP_HP_MUTE_LED_MIC3),
Chris Chiuc1732ed2017-02-28 14:17:13 -06007162 SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC),
Takashi Iwai7bba2152013-09-06 15:45:38 +02007163 SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300),
David Henningsson3e0d6112013-04-22 14:30:14 +02007164 SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Wandrille RONCE9cf65332018-12-19 14:52:44 +01007165 SND_PCI_QUIRK(0x1043, 0x10a1, "ASUS UX391UA", ALC294_FIXUP_ASUS_SPK),
Chris Chiuc1732ed2017-02-28 14:17:13 -06007166 SND_PCI_QUIRK(0x1043, 0x10c0, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC),
Takashi Iwai4eab0ea2017-06-06 12:33:17 +02007167 SND_PCI_QUIRK(0x1043, 0x10d0, "ASUS X540LA/X540LJ", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
David Henningsson3e0d6112013-04-22 14:30:14 +02007168 SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Takashi Iwai4eab0ea2017-06-06 12:33:17 +02007169 SND_PCI_QUIRK(0x1043, 0x11c0, "ASUS X556UR", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
7170 SND_PCI_QUIRK(0x1043, 0x1290, "ASUS X441SA", ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE),
7171 SND_PCI_QUIRK(0x1043, 0x12a0, "ASUS X441UV", ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE),
Chris Chiuc1732ed2017-02-28 14:17:13 -06007172 SND_PCI_QUIRK(0x1043, 0x12f0, "ASUS X541UV", ALC256_FIXUP_ASUS_MIC),
7173 SND_PCI_QUIRK(0x1043, 0x12e0, "ASUS X541SA", ALC256_FIXUP_ASUS_MIC),
7174 SND_PCI_QUIRK(0x1043, 0x13b0, "ASUS Z550SA", ALC256_FIXUP_ASUS_MIC),
Oleksij Rempel2cede302013-11-27 17:12:03 +01007175 SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK),
Takashi Iwai23870832013-11-29 14:13:12 +01007176 SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A),
David Henningsson3e0d6112013-04-22 14:30:14 +02007177 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC),
Jian-Hong Pan436e2552019-11-25 17:34:06 +08007178 SND_PCI_QUIRK(0x1043, 0x17d1, "ASUS UX431FL", ALC294_FIXUP_ASUS_INTSPK_GPIO),
Daniel Drake8c8967a2019-10-17 16:15:01 +08007179 SND_PCI_QUIRK(0x1043, 0x18b1, "Asus MJ401TA", ALC256_FIXUP_ASUS_HEADSET_MIC),
Takashi Iwai017f2a12011-07-09 14:42:25 +02007180 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
Chris Chiu28e8af82017-06-05 15:05:30 -06007181 SND_PCI_QUIRK(0x1043, 0x1a30, "ASUS X705UD", ALC256_FIXUP_ASUS_MIC),
David Henningsson693b6132012-06-22 19:12:10 +02007182 SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC),
Chris Chiu615966a2017-02-28 14:17:12 -06007183 SND_PCI_QUIRK(0x1043, 0x1bbd, "ASUS Z550MA", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
Takashi Iwai4eab0ea2017-06-06 12:33:17 +02007184 SND_PCI_QUIRK(0x1043, 0x1c23, "Asus X55U", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Chris Chiuc1732ed2017-02-28 14:17:13 -06007185 SND_PCI_QUIRK(0x1043, 0x1ccd, "ASUS X555UB", ALC256_FIXUP_ASUS_MIC),
Chris Chiueeed4cd2017-02-28 14:17:15 -06007186 SND_PCI_QUIRK(0x1043, 0x3030, "ASUS ZN270IE", ALC256_FIXUP_ASUS_AIO_GPIO2),
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02007187 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC),
7188 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC),
7189 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
7190 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
David Henningssond240d1d2013-04-15 12:50:02 +02007191 SND_PCI_QUIRK(0x1043, 0x8516, "ASUS X101CH", ALC269_FIXUP_ASUS_X101),
Takashi Iwaif88abaa2014-02-07 12:07:59 +01007192 SND_PCI_QUIRK(0x104d, 0x90b5, "Sony VAIO Pro 11", ALC286_FIXUP_SONY_MIC_NO_PRESENCE),
David Henningsson88cfcf82013-10-11 10:18:45 +02007193 SND_PCI_QUIRK(0x104d, 0x90b6, "Sony VAIO Pro 13", ALC286_FIXUP_SONY_MIC_NO_PRESENCE),
Takashi Iwai1d045db2011-07-07 18:23:21 +02007194 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
7195 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
7196 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
Takashi Iwaie9bd7d52014-05-21 11:06:49 +02007197 SND_PCI_QUIRK(0x104d, 0x9099, "Sony VAIO S13", ALC275_FIXUP_SONY_DISABLE_AAMIX),
Takashi Iwai24519912011-08-16 15:08:49 +02007198 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook", ALC269_FIXUP_LIFEBOOK),
Takashi Iwai4df3fd12015-06-29 08:38:02 +02007199 SND_PCI_QUIRK(0x10cf, 0x159f, "Lifebook E780", ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT),
Takashi Iwaicc7016a2015-04-08 20:47:55 +02007200 SND_PCI_QUIRK(0x10cf, 0x15dc, "Lifebook T731", ALC269_FIXUP_LIFEBOOK_HP_PIN),
Takashi Iwai88776f32015-05-01 09:20:34 +02007201 SND_PCI_QUIRK(0x10cf, 0x1757, "Lifebook E752", ALC269_FIXUP_LIFEBOOK_HP_PIN),
Jan-Marek Glogowskifdcc9682018-02-14 11:29:15 +01007202 SND_PCI_QUIRK(0x10cf, 0x1629, "Lifebook U7x7", ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC),
David Henningsson2041d562014-06-13 11:15:44 +02007203 SND_PCI_QUIRK(0x10cf, 0x1845, "Lifebook U904", ALC269_FIXUP_LIFEBOOK_EXTMIC),
PeiSen Houb84e8432017-09-01 15:11:56 +08007204 SND_PCI_QUIRK(0x10ec, 0x10f2, "Intel Reference board", ALC700_FIXUP_INTEL_REFERENCE),
YOKOTA Hiroshi0fca97a2018-07-01 18:30:01 +09007205 SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-SZ6", ALC269_FIXUP_HEADSET_MODE),
David Henningssona33cc482014-10-07 10:18:41 +02007206 SND_PCI_QUIRK(0x144d, 0xc109, "Samsung Ativ book 9 (NP900X3G)", ALC269_FIXUP_INV_DMIC),
Gabriele Mazzotta823ff162016-12-24 19:50:01 +01007207 SND_PCI_QUIRK(0x144d, 0xc740, "Samsung Ativ book 8 (NP870Z5G)", ALC269_FIXUP_ATIV_BOOK_8),
Anisse Astierabaa22742016-08-24 09:14:13 +02007208 SND_PCI_QUIRK(0x1458, 0xfa53, "Gigabyte BXBT-2807", ALC283_FIXUP_HEADSET_MIC),
7209 SND_PCI_QUIRK(0x1462, 0xb120, "MSI Cubi MS-B120", ALC283_FIXUP_HEADSET_MIC),
Anisse Astier8cd65272018-11-23 17:59:11 +01007210 SND_PCI_QUIRK(0x1462, 0xb171, "Cubi N 8GL (MS-B171)", ALC283_FIXUP_HEADSET_MIC),
Jeremy Soller89e3a562019-01-30 16:12:31 -07007211 SND_PCI_QUIRK(0x1558, 0x1325, "System76 Darter Pro (darp5)", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
Jeremy Soller80a50522019-05-07 17:11:08 -04007212 SND_PCI_QUIRK(0x1558, 0x8550, "System76 Gazelle (gaze14)", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
Jeremy Soller891afcf2019-05-10 10:15:07 -04007213 SND_PCI_QUIRK(0x1558, 0x8551, "System76 Gazelle (gaze14)", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
7214 SND_PCI_QUIRK(0x1558, 0x8560, "System76 Gazelle (gaze14)", ALC269_FIXUP_HEADSET_MIC),
7215 SND_PCI_QUIRK(0x1558, 0x8561, "System76 Gazelle (gaze14)", ALC269_FIXUP_HEADSET_MIC),
Kailang Yangca169cc2017-04-25 16:17:40 +08007216 SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC233_FIXUP_LENOVO_MULTI_CODECS),
Takashi Iwai1d045db2011-07-07 18:23:21 +02007217 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
7218 SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
7219 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
7220 SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
7221 SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
Takashi Iwai707fba32012-08-02 09:04:39 +02007222 SND_PCI_QUIRK(0x17aa, 0x21f6, "Thinkpad T530", ALC269_FIXUP_LENOVO_DOCK),
Felix Kaechelec8415a42012-08-06 23:02:01 +02007223 SND_PCI_QUIRK(0x17aa, 0x21fa, "Thinkpad X230", ALC269_FIXUP_LENOVO_DOCK),
Stefán Freyr84f98fd2012-10-19 22:46:00 +02007224 SND_PCI_QUIRK(0x17aa, 0x21f3, "Thinkpad T430", ALC269_FIXUP_LENOVO_DOCK),
Philipp A. Mohrenweiser4407be62012-08-06 13:14:18 +02007225 SND_PCI_QUIRK(0x17aa, 0x21fb, "Thinkpad T430s", ALC269_FIXUP_LENOVO_DOCK),
David Henningsson108cc102012-07-20 10:37:25 +02007226 SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK),
David Henningssonaaedfb42013-08-16 14:09:02 +02007227 SND_PCI_QUIRK(0x17aa, 0x2208, "Thinkpad T431s", ALC269_FIXUP_LENOVO_DOCK),
Takashi Iwai9a811232015-12-09 15:17:43 +01007228 SND_PCI_QUIRK(0x17aa, 0x220c, "Thinkpad T440s", ALC292_FIXUP_TPT440),
Takashi Iwai1c37c222014-05-06 17:34:42 +02007229 SND_PCI_QUIRK(0x17aa, 0x220e, "Thinkpad T440p", ALC292_FIXUP_TPT440_DOCK),
Takashi Iwaia12137e2014-06-27 12:14:35 +02007230 SND_PCI_QUIRK(0x17aa, 0x2210, "Thinkpad T540p", ALC292_FIXUP_TPT440_DOCK),
Rick Sherman59a51a62015-08-18 21:04:30 -05007231 SND_PCI_QUIRK(0x17aa, 0x2211, "Thinkpad W541", ALC292_FIXUP_TPT440_DOCK),
Takashi Iwai6d169412014-10-07 17:27:02 +02007232 SND_PCI_QUIRK(0x17aa, 0x2212, "Thinkpad T440", ALC292_FIXUP_TPT440_DOCK),
Lukas Bossard7c215392014-10-29 18:31:07 +01007233 SND_PCI_QUIRK(0x17aa, 0x2214, "Thinkpad X240", ALC292_FIXUP_TPT440_DOCK),
David Henningssona4a9e082013-08-16 14:09:01 +02007234 SND_PCI_QUIRK(0x17aa, 0x2215, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Takashi Iwaib6903c02015-12-10 12:20:20 +01007235 SND_PCI_QUIRK(0x17aa, 0x2218, "Thinkpad X1 Carbon 2nd", ALC292_FIXUP_TPT440_DOCK),
Laura Abbottd05ea7d2015-10-02 11:09:54 -07007236 SND_PCI_QUIRK(0x17aa, 0x2223, "ThinkPad T550", ALC292_FIXUP_TPT440_DOCK),
Yves-Alexis Perezc0278662015-04-11 09:31:35 +02007237 SND_PCI_QUIRK(0x17aa, 0x2226, "ThinkPad X250", ALC292_FIXUP_TPT440_DOCK),
Kailang Yang61fcf8e2018-02-02 15:26:46 +08007238 SND_PCI_QUIRK(0x17aa, 0x222d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7239 SND_PCI_QUIRK(0x17aa, 0x222e, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
Torsten Hilbrichdab38e42016-06-07 13:14:21 +02007240 SND_PCI_QUIRK(0x17aa, 0x2231, "Thinkpad T560", ALC292_FIXUP_TPT460),
Sven Eckelmannc636b952016-04-11 16:55:26 +02007241 SND_PCI_QUIRK(0x17aa, 0x2233, "Thinkpad", ALC292_FIXUP_TPT460),
Kailang Yang61fcf8e2018-02-02 15:26:46 +08007242 SND_PCI_QUIRK(0x17aa, 0x2245, "Thinkpad T470", ALC298_FIXUP_TPT470_DOCK),
7243 SND_PCI_QUIRK(0x17aa, 0x2246, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7244 SND_PCI_QUIRK(0x17aa, 0x2247, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
Dennis Wassenberge4c07b32018-03-08 13:17:54 +01007245 SND_PCI_QUIRK(0x17aa, 0x2249, "Thinkpad", ALC292_FIXUP_TPT460),
Kailang Yang61fcf8e2018-02-02 15:26:46 +08007246 SND_PCI_QUIRK(0x17aa, 0x224b, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7247 SND_PCI_QUIRK(0x17aa, 0x224c, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7248 SND_PCI_QUIRK(0x17aa, 0x224d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
Benjamin Berg85981df2018-02-14 13:29:39 +01007249 SND_PCI_QUIRK(0x17aa, 0x225d, "Thinkpad T480", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Jaroslav Kyselad2cd7952019-11-29 15:40:27 +01007250 SND_PCI_QUIRK(0x17aa, 0x2293, "Thinkpad X1 Carbon 7th", ALC285_FIXUP_SPEAKER2_TO_DAC1),
Kailang3694cb22015-12-28 11:35:24 +08007251 SND_PCI_QUIRK(0x17aa, 0x30bb, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
Hui Wang6ef2f682016-03-11 12:04:02 +08007252 SND_PCI_QUIRK(0x17aa, 0x30e2, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
Hui Wangf33f79f2017-07-07 12:08:29 +08007253 SND_PCI_QUIRK(0x17aa, 0x310c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
Dennis Wassenbergbef33e12019-06-28 10:54:53 +02007254 SND_PCI_QUIRK(0x17aa, 0x3111, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
Hui Wange41fc8c2018-06-25 14:40:56 +08007255 SND_PCI_QUIRK(0x17aa, 0x312a, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
Kailang Yang65811832018-04-25 17:07:27 +08007256 SND_PCI_QUIRK(0x17aa, 0x312f, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
Hui Wang8da5bbf2017-12-22 11:17:46 +08007257 SND_PCI_QUIRK(0x17aa, 0x313c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
Hui Wang2a36c162019-09-04 13:53:27 +08007258 SND_PCI_QUIRK(0x17aa, 0x3151, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC),
Aaron Ma8a6c55d2019-10-24 19:44:39 +08007259 SND_PCI_QUIRK(0x17aa, 0x3176, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC),
7260 SND_PCI_QUIRK(0x17aa, 0x3178, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC),
David Henningsson56f27012016-01-11 09:33:14 +01007261 SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
Takashi Iwaifedb2242014-11-13 07:11:38 +01007262 SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC),
Michał Wadowski56df90b2019-05-14 16:58:00 +02007263 SND_PCI_QUIRK(0x17aa, 0x3978, "Lenovo B50-70", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
David Henningssona4a9e082013-08-16 14:09:01 +02007264 SND_PCI_QUIRK(0x17aa, 0x5013, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Kailang Yang1bb3e062013-09-27 13:10:25 +02007265 SND_PCI_QUIRK(0x17aa, 0x501a, "Thinkpad", ALC283_FIXUP_INT_MIC),
Takashi Iwaic497d9f2014-10-08 12:14:40 +02007266 SND_PCI_QUIRK(0x17aa, 0x501e, "Thinkpad L440", ALC292_FIXUP_TPT440_DOCK),
David Henningssoncd5302c2013-08-19 12:22:33 +02007267 SND_PCI_QUIRK(0x17aa, 0x5026, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Jo-Philipp Wichf2aa1112015-04-13 12:47:26 +02007268 SND_PCI_QUIRK(0x17aa, 0x5034, "Thinkpad T450", ALC292_FIXUP_TPT440_DOCK),
Sebastian Wicki80b311d2015-03-23 17:23:11 +01007269 SND_PCI_QUIRK(0x17aa, 0x5036, "Thinkpad T450s", ALC292_FIXUP_TPT440_DOCK),
Ansgar Hegerfeld09ea9972015-05-14 12:31:32 +02007270 SND_PCI_QUIRK(0x17aa, 0x503c, "Thinkpad L450", ALC292_FIXUP_TPT440_DOCK),
Conrad Kostecki037e1192016-04-26 10:08:10 +02007271 SND_PCI_QUIRK(0x17aa, 0x504a, "ThinkPad X260", ALC292_FIXUP_TPT440_DOCK),
Hui Wang23adc192015-12-08 12:27:18 +08007272 SND_PCI_QUIRK(0x17aa, 0x504b, "Thinkpad", ALC293_FIXUP_LENOVO_SPK_NOISE),
Jaroslav Kysela0f087ee2016-06-24 15:13:16 +02007273 SND_PCI_QUIRK(0x17aa, 0x5050, "Thinkpad T560p", ALC292_FIXUP_TPT460),
Torsten Hilbrich9cd25742016-07-05 10:40:22 +02007274 SND_PCI_QUIRK(0x17aa, 0x5051, "Thinkpad L460", ALC292_FIXUP_TPT460),
Jaroslav Kysela0f087ee2016-06-24 15:13:16 +02007275 SND_PCI_QUIRK(0x17aa, 0x5053, "Thinkpad T460", ALC292_FIXUP_TPT460),
Kailang Yang61fcf8e2018-02-02 15:26:46 +08007276 SND_PCI_QUIRK(0x17aa, 0x505d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7277 SND_PCI_QUIRK(0x17aa, 0x505f, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7278 SND_PCI_QUIRK(0x17aa, 0x5062, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
David Henningssoncd5302c2013-08-19 12:22:33 +02007279 SND_PCI_QUIRK(0x17aa, 0x5109, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Kailang Yang61fcf8e2018-02-02 15:26:46 +08007280 SND_PCI_QUIRK(0x17aa, 0x511e, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7281 SND_PCI_QUIRK(0x17aa, 0x511f, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
David Henningsson012e7eb2012-08-08 08:43:37 +02007282 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K),
Takashi Iwai1d045db2011-07-07 18:23:21 +02007283 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
Ayman Bagabas0fbf21c2019-05-23 05:30:11 -04007284 SND_PCI_QUIRK(0x19e5, 0x3204, "Huawei MACH-WX9", ALC256_FIXUP_HUAWEI_MACH_WX9_PINS),
Anisse Astier02b504d2013-06-03 11:53:10 +02007285 SND_PCI_QUIRK(0x1b7d, 0xa831, "Ordissimo EVE2 ", ALC269VB_FIXUP_ORDISSIMO_EVE2), /* Also known as Malata PC-B1303 */
Hui Wang695d1ec2019-11-21 10:54:27 +08007286 SND_PCI_QUIRK(0x1d72, 0x1901, "RedmiBook 14", ALC256_FIXUP_ASUS_HEADSET_MIC),
Jan-Marek Glogowskibd9c10b2019-09-15 16:57:28 +02007287 SND_PCI_QUIRK(0x10ec, 0x118c, "Medion EE4254 MD62100", ALC256_FIXUP_MEDION_HEADSET_NO_PRESENCE),
Takashi Iwaia4297b52011-08-23 18:40:12 +02007288
Takashi Iwaia7f3eed2012-02-16 13:03:18 +01007289#if 0
Takashi Iwaia4297b52011-08-23 18:40:12 +02007290 /* Below is a quirk table taken from the old code.
7291 * Basically the device should work as is without the fixup table.
7292 * If BIOS doesn't give a proper info, enable the corresponding
7293 * fixup entry.
Jesper Juhl7d7eb9e2012-04-12 22:11:25 +02007294 */
Takashi Iwaia4297b52011-08-23 18:40:12 +02007295 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
7296 ALC269_FIXUP_AMIC),
7297 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269_FIXUP_AMIC),
Takashi Iwaia4297b52011-08-23 18:40:12 +02007298 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269_FIXUP_AMIC),
7299 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_FIXUP_AMIC),
7300 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269_FIXUP_AMIC),
7301 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269_FIXUP_AMIC),
7302 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269_FIXUP_AMIC),
7303 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269_FIXUP_AMIC),
7304 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_FIXUP_AMIC),
7305 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269_FIXUP_AMIC),
7306 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_FIXUP_AMIC),
7307 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_FIXUP_AMIC),
7308 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_FIXUP_AMIC),
7309 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_FIXUP_AMIC),
7310 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_FIXUP_AMIC),
7311 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_FIXUP_AMIC),
7312 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_FIXUP_AMIC),
7313 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_FIXUP_AMIC),
7314 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_FIXUP_AMIC),
7315 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_FIXUP_AMIC),
7316 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_FIXUP_AMIC),
7317 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_FIXUP_AMIC),
7318 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_FIXUP_AMIC),
7319 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_FIXUP_AMIC),
7320 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_FIXUP_AMIC),
7321 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_FIXUP_AMIC),
7322 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_FIXUP_AMIC),
7323 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_FIXUP_AMIC),
7324 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_FIXUP_AMIC),
7325 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_FIXUP_AMIC),
7326 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_FIXUP_AMIC),
7327 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_FIXUP_AMIC),
7328 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_FIXUP_AMIC),
7329 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_FIXUP_AMIC),
7330 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_FIXUP_AMIC),
7331 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_FIXUP_DMIC),
7332 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_FIXUP_AMIC),
7333 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_AMIC),
7334 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_FIXUP_DMIC),
7335 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_FIXUP_DMIC),
7336#endif
7337 {}
7338};
7339
David Henningsson214eef72014-07-22 14:09:35 +02007340static const struct snd_pci_quirk alc269_fixup_vendor_tbl[] = {
7341 SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC),
7342 SND_PCI_QUIRK_VENDOR(0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED),
7343 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
7344 SND_PCI_QUIRK_VENDOR(0x17aa, "Thinkpad", ALC269_FIXUP_THINKPAD_ACPI),
Ayman Bagabas0fbf21c2019-05-23 05:30:11 -04007345 SND_PCI_QUIRK_VENDOR(0x19e5, "Huawei Matebook", ALC255_FIXUP_MIC_MUTE_LED),
David Henningsson214eef72014-07-22 14:09:35 +02007346 {}
7347};
7348
Takashi Iwai1727a772013-01-10 09:52:52 +01007349static const struct hda_model_fixup alc269_fixup_models[] = {
Takashi Iwaia4297b52011-08-23 18:40:12 +02007350 {.id = ALC269_FIXUP_AMIC, .name = "laptop-amic"},
7351 {.id = ALC269_FIXUP_DMIC, .name = "laptop-dmic"},
Takashi Iwai6e72aa52012-06-25 10:52:25 +02007352 {.id = ALC269_FIXUP_STEREO_DMIC, .name = "alc269-dmic"},
7353 {.id = ALC271_FIXUP_DMIC, .name = "alc271-dmic"},
7354 {.id = ALC269_FIXUP_INV_DMIC, .name = "inv-dmic"},
David Henningsson7c478f02013-10-11 10:18:46 +02007355 {.id = ALC269_FIXUP_HEADSET_MIC, .name = "headset-mic"},
Takashi Iwaib0169512015-05-19 10:20:13 +02007356 {.id = ALC269_FIXUP_HEADSET_MODE, .name = "headset-mode"},
7357 {.id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC, .name = "headset-mode-no-hp-mic"},
David Henningsson108cc102012-07-20 10:37:25 +02007358 {.id = ALC269_FIXUP_LENOVO_DOCK, .name = "lenovo-dock"},
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01007359 {.id = ALC269_FIXUP_HP_GPIO_LED, .name = "hp-gpio-led"},
Jaroslav Kysela04d54662017-03-09 13:29:13 +01007360 {.id = ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED, .name = "hp-dock-gpio-mic1-led"},
David Henningssone32aa852013-06-17 11:04:02 +02007361 {.id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "dell-headset-multi"},
7362 {.id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE, .name = "dell-headset-dock"},
Takashi Iwaia26d96c2018-06-26 15:09:25 +02007363 {.id = ALC269_FIXUP_DELL3_MIC_NO_PRESENCE, .name = "dell-headset3"},
7364 {.id = ALC269_FIXUP_DELL4_MIC_NO_PRESENCE, .name = "dell-headset4"},
Kailang Yangbe8ef162014-04-08 15:19:49 +08007365 {.id = ALC283_FIXUP_CHROME_BOOK, .name = "alc283-dac-wcaps"},
Kailang Yang0202e992013-12-02 15:20:15 +08007366 {.id = ALC283_FIXUP_SENSE_COMBO_JACK, .name = "alc283-sense-combo"},
Takashi Iwai1c37c222014-05-06 17:34:42 +02007367 {.id = ALC292_FIXUP_TPT440_DOCK, .name = "tpt440-dock"},
Takashi Iwai9a811232015-12-09 15:17:43 +01007368 {.id = ALC292_FIXUP_TPT440, .name = "tpt440"},
Sven Eckelmannc636b952016-04-11 16:55:26 +02007369 {.id = ALC292_FIXUP_TPT460, .name = "tpt460"},
Takashi Iwaia26d96c2018-06-26 15:09:25 +02007370 {.id = ALC298_FIXUP_TPT470_DOCK, .name = "tpt470-dock"},
Takashi Iwaiba90d6a2017-05-22 16:38:47 +02007371 {.id = ALC233_FIXUP_LENOVO_MULTI_CODECS, .name = "dual-codecs"},
Takashi Iwai28d1d6d2017-10-18 14:01:58 +02007372 {.id = ALC700_FIXUP_INTEL_REFERENCE, .name = "alc700-ref"},
Takashi Iwaia26d96c2018-06-26 15:09:25 +02007373 {.id = ALC269_FIXUP_SONY_VAIO, .name = "vaio"},
7374 {.id = ALC269_FIXUP_DELL_M101Z, .name = "dell-m101z"},
7375 {.id = ALC269_FIXUP_ASUS_G73JW, .name = "asus-g73jw"},
7376 {.id = ALC269_FIXUP_LENOVO_EAPD, .name = "lenovo-eapd"},
7377 {.id = ALC275_FIXUP_SONY_HWEQ, .name = "sony-hweq"},
7378 {.id = ALC269_FIXUP_PCM_44K, .name = "pcm44k"},
7379 {.id = ALC269_FIXUP_LIFEBOOK, .name = "lifebook"},
7380 {.id = ALC269_FIXUP_LIFEBOOK_EXTMIC, .name = "lifebook-extmic"},
7381 {.id = ALC269_FIXUP_LIFEBOOK_HP_PIN, .name = "lifebook-hp-pin"},
7382 {.id = ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC, .name = "lifebook-u7x7"},
7383 {.id = ALC269VB_FIXUP_AMIC, .name = "alc269vb-amic"},
7384 {.id = ALC269VB_FIXUP_DMIC, .name = "alc269vb-dmic"},
7385 {.id = ALC269_FIXUP_HP_MUTE_LED_MIC1, .name = "hp-mute-led-mic1"},
7386 {.id = ALC269_FIXUP_HP_MUTE_LED_MIC2, .name = "hp-mute-led-mic2"},
7387 {.id = ALC269_FIXUP_HP_MUTE_LED_MIC3, .name = "hp-mute-led-mic3"},
7388 {.id = ALC269_FIXUP_HP_GPIO_MIC1_LED, .name = "hp-gpio-mic1"},
7389 {.id = ALC269_FIXUP_HP_LINE1_MIC1_LED, .name = "hp-line1-mic1"},
7390 {.id = ALC269_FIXUP_NO_SHUTUP, .name = "noshutup"},
7391 {.id = ALC286_FIXUP_SONY_MIC_NO_PRESENCE, .name = "sony-nomic"},
7392 {.id = ALC269_FIXUP_ASPIRE_HEADSET_MIC, .name = "aspire-headset-mic"},
7393 {.id = ALC269_FIXUP_ASUS_X101, .name = "asus-x101"},
7394 {.id = ALC271_FIXUP_HP_GATE_MIC_JACK, .name = "acer-ao7xx"},
7395 {.id = ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572, .name = "acer-aspire-e1"},
7396 {.id = ALC269_FIXUP_ACER_AC700, .name = "acer-ac700"},
7397 {.id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST, .name = "limit-mic-boost"},
7398 {.id = ALC269VB_FIXUP_ASUS_ZENBOOK, .name = "asus-zenbook"},
7399 {.id = ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A, .name = "asus-zenbook-ux31a"},
7400 {.id = ALC269VB_FIXUP_ORDISSIMO_EVE2, .name = "ordissimo"},
7401 {.id = ALC282_FIXUP_ASUS_TX300, .name = "asus-tx300"},
7402 {.id = ALC283_FIXUP_INT_MIC, .name = "alc283-int-mic"},
7403 {.id = ALC290_FIXUP_MONO_SPEAKERS_HSJACK, .name = "mono-speakers"},
7404 {.id = ALC290_FIXUP_SUBWOOFER_HSJACK, .name = "alc290-subwoofer"},
7405 {.id = ALC269_FIXUP_THINKPAD_ACPI, .name = "thinkpad"},
7406 {.id = ALC269_FIXUP_DMIC_THINKPAD_ACPI, .name = "dmic-thinkpad"},
7407 {.id = ALC255_FIXUP_ACER_MIC_NO_PRESENCE, .name = "alc255-acer"},
7408 {.id = ALC255_FIXUP_ASUS_MIC_NO_PRESENCE, .name = "alc255-asus"},
7409 {.id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc255-dell1"},
7410 {.id = ALC255_FIXUP_DELL2_MIC_NO_PRESENCE, .name = "alc255-dell2"},
7411 {.id = ALC293_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc293-dell1"},
7412 {.id = ALC283_FIXUP_HEADSET_MIC, .name = "alc283-headset"},
Takashi Iwaib3802782018-11-26 17:47:46 +01007413 {.id = ALC255_FIXUP_MIC_MUTE_LED, .name = "alc255-dell-mute"},
Takashi Iwaia26d96c2018-06-26 15:09:25 +02007414 {.id = ALC282_FIXUP_ASPIRE_V5_PINS, .name = "aspire-v5"},
7415 {.id = ALC280_FIXUP_HP_GPIO4, .name = "hp-gpio4"},
7416 {.id = ALC286_FIXUP_HP_GPIO_LED, .name = "hp-gpio-led"},
7417 {.id = ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY, .name = "hp-gpio2-hotkey"},
7418 {.id = ALC280_FIXUP_HP_DOCK_PINS, .name = "hp-dock-pins"},
7419 {.id = ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED, .name = "hp-dock-gpio-mic"},
7420 {.id = ALC280_FIXUP_HP_9480M, .name = "hp-9480m"},
7421 {.id = ALC288_FIXUP_DELL_HEADSET_MODE, .name = "alc288-dell-headset"},
7422 {.id = ALC288_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc288-dell1"},
7423 {.id = ALC288_FIXUP_DELL_XPS_13, .name = "alc288-dell-xps13"},
7424 {.id = ALC292_FIXUP_DELL_E7X, .name = "dell-e7x"},
7425 {.id = ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK, .name = "alc293-dell"},
7426 {.id = ALC298_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc298-dell1"},
7427 {.id = ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE, .name = "alc298-dell-aio"},
7428 {.id = ALC275_FIXUP_DELL_XPS, .name = "alc275-dell-xps"},
7429 {.id = ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE, .name = "alc256-dell-xps13"},
7430 {.id = ALC293_FIXUP_LENOVO_SPK_NOISE, .name = "lenovo-spk-noise"},
7431 {.id = ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY, .name = "lenovo-hotkey"},
7432 {.id = ALC255_FIXUP_DELL_SPK_NOISE, .name = "dell-spk-noise"},
Kailang Yang82aa0d72019-01-11 17:15:53 +08007433 {.id = ALC225_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc225-dell1"},
Takashi Iwaia26d96c2018-06-26 15:09:25 +02007434 {.id = ALC295_FIXUP_DISABLE_DAC3, .name = "alc295-disable-dac3"},
Jaroslav Kyselad2cd7952019-11-29 15:40:27 +01007435 {.id = ALC285_FIXUP_SPEAKER2_TO_DAC1, .name = "alc285-speaker2-to-dac1"},
Takashi Iwaia26d96c2018-06-26 15:09:25 +02007436 {.id = ALC280_FIXUP_HP_HEADSET_MIC, .name = "alc280-hp-headset"},
7437 {.id = ALC221_FIXUP_HP_FRONT_MIC, .name = "alc221-hp-mic"},
7438 {.id = ALC298_FIXUP_SPK_VOLUME, .name = "alc298-spk-volume"},
7439 {.id = ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER, .name = "dell-inspiron-7559"},
7440 {.id = ALC269_FIXUP_ATIV_BOOK_8, .name = "ativ-book"},
7441 {.id = ALC221_FIXUP_HP_MIC_NO_PRESENCE, .name = "alc221-hp-mic"},
7442 {.id = ALC256_FIXUP_ASUS_HEADSET_MODE, .name = "alc256-asus-headset"},
7443 {.id = ALC256_FIXUP_ASUS_MIC, .name = "alc256-asus-mic"},
7444 {.id = ALC256_FIXUP_ASUS_AIO_GPIO2, .name = "alc256-asus-aio"},
7445 {.id = ALC233_FIXUP_ASUS_MIC_NO_PRESENCE, .name = "alc233-asus"},
7446 {.id = ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE, .name = "alc233-eapd"},
7447 {.id = ALC294_FIXUP_LENOVO_MIC_LOCATION, .name = "alc294-lenovo-mic"},
7448 {.id = ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE, .name = "alc225-wyse"},
7449 {.id = ALC274_FIXUP_DELL_AIO_LINEOUT_VERB, .name = "alc274-dell-aio"},
7450 {.id = ALC255_FIXUP_DUMMY_LINEOUT_VERB, .name = "alc255-dummy-lineout"},
7451 {.id = ALC255_FIXUP_DELL_HEADSET_MIC, .name = "alc255-dell-headset"},
7452 {.id = ALC295_FIXUP_HP_X360, .name = "alc295-hp-x360"},
Kailang Yang8983eb62019-04-03 15:31:49 +08007453 {.id = ALC225_FIXUP_HEADSET_JACK, .name = "alc-headset-jack"},
7454 {.id = ALC295_FIXUP_CHROME_BOOK, .name = "alc-chrome-book"},
Bernhard Rosenkraenzere2a829b2019-03-05 00:38:19 +01007455 {.id = ALC299_FIXUP_PREDATOR_SPK, .name = "predator-spk"},
Tomas Espeletaa2ef03f2019-08-09 16:37:54 +02007456 {.id = ALC298_FIXUP_HUAWEI_MBX_STEREO, .name = "huawei-mbx-stereo"},
Jan-Marek Glogowskibd9c10b2019-09-15 16:57:28 +02007457 {.id = ALC256_FIXUP_MEDION_HEADSET_NO_PRESENCE, .name = "alc256-medion-headset"},
Takashi Iwai1d045db2011-07-07 18:23:21 +02007458 {}
7459};
Kailang Yangcfc5a842016-02-03 15:20:39 +08007460#define ALC225_STANDARD_PINS \
Kailang Yangcfc5a842016-02-03 15:20:39 +08007461 {0x21, 0x04211020}
Takashi Iwai1d045db2011-07-07 18:23:21 +02007462
Hui Wange8191a82015-04-24 13:39:59 +08007463#define ALC256_STANDARD_PINS \
7464 {0x12, 0x90a60140}, \
7465 {0x14, 0x90170110}, \
Hui Wange8191a82015-04-24 13:39:59 +08007466 {0x21, 0x02211020}
7467
David Henningssonfea185e2014-09-03 10:23:04 +02007468#define ALC282_STANDARD_PINS \
Hui Wang11580292015-08-03 11:03:49 +08007469 {0x14, 0x90170110}
Kailang Yange1e62b92015-04-08 16:01:22 +08007470
David Henningssonfea185e2014-09-03 10:23:04 +02007471#define ALC290_STANDARD_PINS \
Hui Wang11580292015-08-03 11:03:49 +08007472 {0x12, 0x99a30130}
David Henningssonfea185e2014-09-03 10:23:04 +02007473
7474#define ALC292_STANDARD_PINS \
7475 {0x14, 0x90170110}, \
Hui Wang11580292015-08-03 11:03:49 +08007476 {0x15, 0x0221401f}
Kailang Yang977e6272015-05-18 15:31:20 +08007477
Hui Wang3f6409702016-09-11 11:26:16 +08007478#define ALC295_STANDARD_PINS \
7479 {0x12, 0xb7a60130}, \
7480 {0x14, 0x90170110}, \
Hui Wang3f6409702016-09-11 11:26:16 +08007481 {0x21, 0x04211020}
7482
Woodrow Shen703867e2015-08-05 12:34:12 +08007483#define ALC298_STANDARD_PINS \
7484 {0x12, 0x90a60130}, \
7485 {0x21, 0x03211020}
7486
Hui Wange1918932014-05-26 16:22:44 +08007487static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
Kailang Yang8a328ac2018-08-21 16:54:41 +08007488 SND_HDA_PIN_QUIRK(0x10ec0221, 0x103c, "HP Workstation", ALC221_FIXUP_HP_HEADSET_MIC,
7489 {0x14, 0x01014020},
7490 {0x17, 0x90170110},
7491 {0x18, 0x02a11030},
7492 {0x19, 0x0181303F},
7493 {0x21, 0x0221102f}),
Chris Chiu5824ce82017-02-28 14:17:11 -06007494 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1025, "Acer", ALC255_FIXUP_ACER_MIC_NO_PRESENCE,
7495 {0x12, 0x90a601c0},
7496 {0x14, 0x90171120},
7497 {0x21, 0x02211030}),
Chris Chiu615966a2017-02-28 14:17:12 -06007498 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1043, "ASUS", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE,
7499 {0x14, 0x90170110},
7500 {0x1b, 0x90a70130},
7501 {0x21, 0x03211020}),
7502 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1043, "ASUS", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE,
7503 {0x1a, 0x90a70130},
7504 {0x1b, 0x90170110},
7505 {0x21, 0x03211020}),
David Henningsson2ae95572016-02-25 09:37:05 +01007506 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
Kailang Yangcfc5a842016-02-03 15:20:39 +08007507 ALC225_STANDARD_PINS,
Hui Wang8a132092016-07-08 14:26:57 +08007508 {0x12, 0xb7a60130},
Kailang Yangcfc5a842016-02-03 15:20:39 +08007509 {0x14, 0x901701a0}),
David Henningsson2ae95572016-02-25 09:37:05 +01007510 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
Kailang Yangcfc5a842016-02-03 15:20:39 +08007511 ALC225_STANDARD_PINS,
Hui Wang8a132092016-07-08 14:26:57 +08007512 {0x12, 0xb7a60130},
Kailang Yangcfc5a842016-02-03 15:20:39 +08007513 {0x14, 0x901701b0}),
Hui Wang8a132092016-07-08 14:26:57 +08007514 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
7515 ALC225_STANDARD_PINS,
7516 {0x12, 0xb7a60150},
7517 {0x14, 0x901701a0}),
7518 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
7519 ALC225_STANDARD_PINS,
7520 {0x12, 0xb7a60150},
7521 {0x14, 0x901701b0}),
7522 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
7523 ALC225_STANDARD_PINS,
7524 {0x12, 0xb7a60130},
7525 {0x1b, 0x90170110}),
Kai-Heng Feng0ce48e12017-11-20 02:29:13 -05007526 SND_HDA_PIN_QUIRK(0x10ec0233, 0x8086, "Intel NUC Skull Canyon", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
7527 {0x1b, 0x01111010},
7528 {0x1e, 0x01451130},
7529 {0x21, 0x02211020}),
Hui Wang986376b2018-05-30 12:33:07 +08007530 SND_HDA_PIN_QUIRK(0x10ec0235, 0x17aa, "Lenovo", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY,
7531 {0x12, 0x90a60140},
7532 {0x14, 0x90170110},
7533 {0x19, 0x02a11030},
7534 {0x21, 0x02211020}),
Hui Wange41fc8c2018-06-25 14:40:56 +08007535 SND_HDA_PIN_QUIRK(0x10ec0235, 0x17aa, "Lenovo", ALC294_FIXUP_LENOVO_MIC_LOCATION,
7536 {0x14, 0x90170110},
7537 {0x19, 0x02a11030},
7538 {0x1a, 0x02a11040},
7539 {0x1b, 0x01014020},
7540 {0x21, 0x0221101f}),
Hui Wangc6b17f12018-07-06 15:14:11 +08007541 SND_HDA_PIN_QUIRK(0x10ec0235, 0x17aa, "Lenovo", ALC294_FIXUP_LENOVO_MIC_LOCATION,
7542 {0x14, 0x90170110},
Hui Wangd06fb562018-10-10 11:57:25 +08007543 {0x19, 0x02a11030},
7544 {0x1a, 0x02a11040},
7545 {0x1b, 0x01011020},
7546 {0x21, 0x0221101f}),
7547 SND_HDA_PIN_QUIRK(0x10ec0235, 0x17aa, "Lenovo", ALC294_FIXUP_LENOVO_MIC_LOCATION,
7548 {0x14, 0x90170110},
Hui Wangc6b17f12018-07-06 15:14:11 +08007549 {0x19, 0x02a11020},
7550 {0x1a, 0x02a11030},
7551 {0x21, 0x0221101f}),
Hui Wangc77900e2014-09-03 11:31:07 +08007552 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE,
Hui Wangc77900e2014-09-03 11:31:07 +08007553 {0x14, 0x90170110},
Hui Wangc77900e2014-09-03 11:31:07 +08007554 {0x21, 0x02211020}),
David Henningsson76c21322014-06-24 14:46:54 +02007555 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang86c72d12016-05-25 12:12:32 +08007556 {0x14, 0x90170130},
7557 {0x21, 0x02211040}),
7558 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningsson76c21322014-06-24 14:46:54 +02007559 {0x12, 0x90a60140},
7560 {0x14, 0x90170110},
David Henningsson76c21322014-06-24 14:46:54 +02007561 {0x21, 0x02211020}),
7562 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7563 {0x12, 0x90a60160},
7564 {0x14, 0x90170120},
David Henningsson76c21322014-06-24 14:46:54 +02007565 {0x21, 0x02211030}),
7566 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang392c9da2016-09-26 10:59:38 +08007567 {0x14, 0x90170110},
7568 {0x1b, 0x02011020},
7569 {0x21, 0x0221101f}),
7570 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang6aecd872016-10-20 14:03:33 +08007571 {0x14, 0x90170110},
7572 {0x1b, 0x01011020},
7573 {0x21, 0x0221101f}),
7574 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssoncba59972015-07-22 10:00:25 +02007575 {0x14, 0x90170130},
David Henningssoncba59972015-07-22 10:00:25 +02007576 {0x1b, 0x01014020},
David Henningssoncba59972015-07-22 10:00:25 +02007577 {0x21, 0x0221103f}),
7578 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang59ec4b52016-08-04 15:28:04 +08007579 {0x14, 0x90170130},
Hui Wang6aecd872016-10-20 14:03:33 +08007580 {0x1b, 0x01011020},
7581 {0x21, 0x0221103f}),
7582 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7583 {0x14, 0x90170130},
Hui Wang59ec4b52016-08-04 15:28:04 +08007584 {0x1b, 0x02011020},
7585 {0x21, 0x0221103f}),
7586 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Woodrow Shene9c28e12015-07-25 10:36:16 +08007587 {0x14, 0x90170150},
Woodrow Shene9c28e12015-07-25 10:36:16 +08007588 {0x1b, 0x02011020},
Woodrow Shene9c28e12015-07-25 10:36:16 +08007589 {0x21, 0x0221105f}),
7590 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Woodrow Shene9c28e12015-07-25 10:36:16 +08007591 {0x14, 0x90170110},
Woodrow Shene9c28e12015-07-25 10:36:16 +08007592 {0x1b, 0x01014020},
Woodrow Shene9c28e12015-07-25 10:36:16 +08007593 {0x21, 0x0221101f}),
7594 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningsson76c21322014-06-24 14:46:54 +02007595 {0x12, 0x90a60160},
7596 {0x14, 0x90170120},
7597 {0x17, 0x90170140},
David Henningsson76c21322014-06-24 14:46:54 +02007598 {0x21, 0x0321102f}),
7599 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7600 {0x12, 0x90a60160},
7601 {0x14, 0x90170130},
David Henningsson76c21322014-06-24 14:46:54 +02007602 {0x21, 0x02211040}),
7603 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7604 {0x12, 0x90a60160},
7605 {0x14, 0x90170140},
David Henningsson76c21322014-06-24 14:46:54 +02007606 {0x21, 0x02211050}),
7607 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7608 {0x12, 0x90a60170},
7609 {0x14, 0x90170120},
David Henningsson76c21322014-06-24 14:46:54 +02007610 {0x21, 0x02211030}),
7611 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7612 {0x12, 0x90a60170},
7613 {0x14, 0x90170130},
David Henningsson76c21322014-06-24 14:46:54 +02007614 {0x21, 0x02211040}),
Hui Wang70658b92015-03-06 14:03:57 +08007615 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang70658b92015-03-06 14:03:57 +08007616 {0x12, 0x90a60170},
Hui Wang0a1f90a2016-01-13 11:51:38 +08007617 {0x14, 0x90171130},
7618 {0x21, 0x02211040}),
7619 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7620 {0x12, 0x90a60170},
Hui Wang70658b92015-03-06 14:03:57 +08007621 {0x14, 0x90170140},
Hui Wang70658b92015-03-06 14:03:57 +08007622 {0x21, 0x02211050}),
David Henningsson9b5a4e32015-05-11 14:04:14 +02007623 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell Inspiron 5548", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningsson9b5a4e32015-05-11 14:04:14 +02007624 {0x12, 0x90a60180},
7625 {0x14, 0x90170130},
David Henningsson9b5a4e32015-05-11 14:04:14 +02007626 {0x21, 0x02211040}),
AceLan Kaof90d83b2016-06-03 14:45:25 +08007627 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell Inspiron 5565", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7628 {0x12, 0x90a60180},
7629 {0x14, 0x90170120},
7630 {0x21, 0x02211030}),
Hui Wang989dbe42016-11-23 16:05:38 +08007631 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7632 {0x1b, 0x01011020},
7633 {0x21, 0x02211010}),
Chris Chiuc1732ed2017-02-28 14:17:13 -06007634 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC,
7635 {0x14, 0x90170110},
7636 {0x1b, 0x90a70130},
7637 {0x21, 0x04211020}),
7638 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC,
7639 {0x14, 0x90170110},
7640 {0x1b, 0x90a70130},
7641 {0x21, 0x03211020}),
Jian-Hong Pane1037352019-03-22 11:37:18 +08007642 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE,
Chris Chiua806ef12019-03-22 11:37:20 +08007643 {0x12, 0x90a60130},
7644 {0x14, 0x90170110},
7645 {0x21, 0x03211020}),
7646 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE,
Jian-Hong Pan6ac371a2019-03-22 11:37:22 +08007647 {0x12, 0x90a60130},
7648 {0x14, 0x90170110},
7649 {0x21, 0x04211020}),
7650 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE,
Jian-Hong Pane1037352019-03-22 11:37:18 +08007651 {0x1a, 0x90a70130},
7652 {0x1b, 0x90170110},
7653 {0x21, 0x03211020}),
David Henningssoncf51eb92014-10-30 08:26:02 +01007654 SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC280_FIXUP_HP_GPIO4,
7655 {0x12, 0x90a60130},
David Henningssoncf51eb92014-10-30 08:26:02 +01007656 {0x14, 0x90170110},
7657 {0x15, 0x0421101f},
Hui Wang11580292015-08-03 11:03:49 +08007658 {0x1a, 0x04a11020}),
Hui Wang02796612014-09-03 11:31:11 +08007659 SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED,
7660 {0x12, 0x90a60140},
Hui Wang02796612014-09-03 11:31:11 +08007661 {0x14, 0x90170110},
7662 {0x15, 0x0421101f},
Hui Wang02796612014-09-03 11:31:11 +08007663 {0x18, 0x02811030},
Hui Wang02796612014-09-03 11:31:11 +08007664 {0x1a, 0x04a1103f},
Hui Wang11580292015-08-03 11:03:49 +08007665 {0x1b, 0x02011020}),
David Henningsson42304472014-07-22 11:42:17 +02007666 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP 15 Touchsmart", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007667 ALC282_STANDARD_PINS,
David Henningsson42304472014-07-22 11:42:17 +02007668 {0x12, 0x99a30130},
David Henningsson42304472014-07-22 11:42:17 +02007669 {0x19, 0x03a11020},
David Henningsson42304472014-07-22 11:42:17 +02007670 {0x21, 0x0321101f}),
Hui Wang2c609992014-09-03 11:31:08 +08007671 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007672 ALC282_STANDARD_PINS,
Hui Wang2c609992014-09-03 11:31:08 +08007673 {0x12, 0x99a30130},
Hui Wang2c609992014-09-03 11:31:08 +08007674 {0x19, 0x03a11020},
Hui Wang2c609992014-09-03 11:31:08 +08007675 {0x21, 0x03211040}),
7676 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007677 ALC282_STANDARD_PINS,
Hui Wang2c609992014-09-03 11:31:08 +08007678 {0x12, 0x99a30130},
Hui Wang2c609992014-09-03 11:31:08 +08007679 {0x19, 0x03a11030},
Hui Wang2c609992014-09-03 11:31:08 +08007680 {0x21, 0x03211020}),
7681 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007682 ALC282_STANDARD_PINS,
Hui Wang2c609992014-09-03 11:31:08 +08007683 {0x12, 0x99a30130},
Hui Wang2c609992014-09-03 11:31:08 +08007684 {0x19, 0x04a11020},
Hui Wang2c609992014-09-03 11:31:08 +08007685 {0x21, 0x0421101f}),
Hui Wang200afc02014-09-03 11:31:10 +08007686 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED,
David Henningssonaec856d2014-09-03 10:23:05 +02007687 ALC282_STANDARD_PINS,
Hui Wang200afc02014-09-03 11:31:10 +08007688 {0x12, 0x90a60140},
Hui Wang200afc02014-09-03 11:31:10 +08007689 {0x19, 0x04a11030},
Hui Wang200afc02014-09-03 11:31:10 +08007690 {0x21, 0x04211020}),
David Henningsson76c21322014-06-24 14:46:54 +02007691 SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007692 ALC282_STANDARD_PINS,
David Henningsson76c21322014-06-24 14:46:54 +02007693 {0x12, 0x90a60130},
David Henningsson76c21322014-06-24 14:46:54 +02007694 {0x21, 0x0321101f}),
7695 SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
7696 {0x12, 0x90a60160},
7697 {0x14, 0x90170120},
David Henningsson76c21322014-06-24 14:46:54 +02007698 {0x21, 0x02211030}),
Hui Wangbc262172014-09-03 11:31:05 +08007699 SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007700 ALC282_STANDARD_PINS,
Hui Wangbc262172014-09-03 11:31:05 +08007701 {0x12, 0x90a60130},
Hui Wangbc262172014-09-03 11:31:05 +08007702 {0x19, 0x03a11020},
Hui Wangbc262172014-09-03 11:31:05 +08007703 {0x21, 0x0321101f}),
Hui Wangc8c6ee62019-02-14 11:41:33 +08007704 SND_HDA_PIN_QUIRK(0x10ec0285, 0x17aa, "Lenovo", ALC285_FIXUP_LENOVO_PC_BEEP_IN_NOISE,
Hui Wangc4cfcf62018-11-26 14:17:16 +08007705 {0x12, 0x90a60130},
7706 {0x14, 0x90170110},
7707 {0x19, 0x04a11040},
7708 {0x21, 0x04211020}),
Chris Chiu33aaebd2018-12-05 14:48:53 +08007709 SND_HDA_PIN_QUIRK(0x10ec0286, 0x1025, "Acer", ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE,
7710 {0x12, 0x90a60130},
7711 {0x17, 0x90170110},
7712 {0x21, 0x02211020}),
Takashi Iwaid44a6862018-06-19 23:04:03 +02007713 SND_HDA_PIN_QUIRK(0x10ec0288, 0x1028, "Dell", ALC288_FIXUP_DELL1_MIC_NO_PRESENCE,
Kailang Yange1e62b92015-04-08 16:01:22 +08007714 {0x12, 0x90a60120},
Kailang Yange1e62b92015-04-08 16:01:22 +08007715 {0x14, 0x90170110},
Kailang Yange1e62b92015-04-08 16:01:22 +08007716 {0x21, 0x0321101f}),
Hui Wange4442bc2014-09-03 11:31:09 +08007717 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007718 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08007719 {0x15, 0x04211040},
Hui Wange4442bc2014-09-03 11:31:09 +08007720 {0x18, 0x90170112},
Hui Wang11580292015-08-03 11:03:49 +08007721 {0x1a, 0x04a11020}),
Hui Wange4442bc2014-09-03 11:31:09 +08007722 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007723 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08007724 {0x15, 0x04211040},
Hui Wange4442bc2014-09-03 11:31:09 +08007725 {0x18, 0x90170110},
Hui Wang11580292015-08-03 11:03:49 +08007726 {0x1a, 0x04a11020}),
Hui Wange4442bc2014-09-03 11:31:09 +08007727 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007728 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08007729 {0x15, 0x0421101f},
Hui Wang11580292015-08-03 11:03:49 +08007730 {0x1a, 0x04a11020}),
Hui Wange4442bc2014-09-03 11:31:09 +08007731 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007732 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08007733 {0x15, 0x04211020},
Hui Wang11580292015-08-03 11:03:49 +08007734 {0x1a, 0x04a11040}),
Hui Wange4442bc2014-09-03 11:31:09 +08007735 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007736 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08007737 {0x14, 0x90170110},
7738 {0x15, 0x04211020},
Hui Wang11580292015-08-03 11:03:49 +08007739 {0x1a, 0x04a11040}),
Hui Wange4442bc2014-09-03 11:31:09 +08007740 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007741 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08007742 {0x14, 0x90170110},
7743 {0x15, 0x04211020},
Hui Wang11580292015-08-03 11:03:49 +08007744 {0x1a, 0x04a11020}),
Hui Wange4442bc2014-09-03 11:31:09 +08007745 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007746 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08007747 {0x14, 0x90170110},
7748 {0x15, 0x0421101f},
Hui Wang11580292015-08-03 11:03:49 +08007749 {0x1a, 0x04a11020}),
Hui Wange8818fa2014-09-03 11:31:04 +08007750 SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007751 ALC292_STANDARD_PINS,
Hui Wange8818fa2014-09-03 11:31:04 +08007752 {0x12, 0x90a60140},
Hui Wange8818fa2014-09-03 11:31:04 +08007753 {0x16, 0x01014020},
Hui Wang11580292015-08-03 11:03:49 +08007754 {0x19, 0x01a19030}),
Hui Wange8818fa2014-09-03 11:31:04 +08007755 SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007756 ALC292_STANDARD_PINS,
Hui Wange8818fa2014-09-03 11:31:04 +08007757 {0x12, 0x90a60140},
Hui Wange8818fa2014-09-03 11:31:04 +08007758 {0x16, 0x01014020},
7759 {0x18, 0x02a19031},
Hui Wang11580292015-08-03 11:03:49 +08007760 {0x19, 0x01a1903e}),
David Henningsson76c21322014-06-24 14:46:54 +02007761 SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007762 ALC292_STANDARD_PINS,
Hui Wang11580292015-08-03 11:03:49 +08007763 {0x12, 0x90a60140}),
David Henningsson76c21322014-06-24 14:46:54 +02007764 SND_HDA_PIN_QUIRK(0x10ec0293, 0x1028, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007765 ALC292_STANDARD_PINS,
David Henningsson76c21322014-06-24 14:46:54 +02007766 {0x13, 0x90a60140},
David Henningsson76c21322014-06-24 14:46:54 +02007767 {0x16, 0x21014020},
Hui Wang11580292015-08-03 11:03:49 +08007768 {0x19, 0x21a19030}),
David Henningssone03fdbd2014-06-27 08:41:59 +02007769 SND_HDA_PIN_QUIRK(0x10ec0293, 0x1028, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007770 ALC292_STANDARD_PINS,
Hui Wang11580292015-08-03 11:03:49 +08007771 {0x13, 0x90a60140}),
Chris Chiud8ae4582018-12-07 17:17:11 +08007772 SND_HDA_PIN_QUIRK(0x10ec0294, 0x1043, "ASUS", ALC294_FIXUP_ASUS_MIC,
7773 {0x14, 0x90170110},
7774 {0x1b, 0x90a70130},
7775 {0x21, 0x04211020}),
Jian-Hong Pan0bea4cc2018-12-07 17:17:13 +08007776 SND_HDA_PIN_QUIRK(0x10ec0294, 0x1043, "ASUS", ALC294_FIXUP_ASUS_SPK,
7777 {0x12, 0x90a60130},
7778 {0x17, 0x90170110},
Jian-Hong Pan8bb37a22019-02-21 17:00:18 +08007779 {0x21, 0x03211020}),
7780 SND_HDA_PIN_QUIRK(0x10ec0294, 0x1043, "ASUS", ALC294_FIXUP_ASUS_SPK,
7781 {0x12, 0x90a60130},
7782 {0x17, 0x90170110},
Jian-Hong Pan0bea4cc2018-12-07 17:17:13 +08007783 {0x21, 0x04211020}),
Takashi Iwai3887c262019-04-30 15:10:01 +02007784 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1043, "ASUS", ALC294_FIXUP_ASUS_SPK,
7785 {0x12, 0x90a60130},
7786 {0x17, 0x90170110},
7787 {0x21, 0x03211020}),
Kailang Yangfbc57122019-07-15 10:41:50 +08007788 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
Kailang Yang0a29c572019-04-24 16:34:25 +08007789 {0x14, 0x90170110},
7790 {0x21, 0x04211020}),
Kailang Yangfbc57122019-07-15 10:41:50 +08007791 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
7792 {0x14, 0x90170110},
7793 {0x21, 0x04211030}),
Hui Wang3f6409702016-09-11 11:26:16 +08007794 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wangf771d5b2016-10-18 10:59:09 +08007795 ALC295_STANDARD_PINS,
7796 {0x17, 0x21014020},
7797 {0x18, 0x21a19030}),
7798 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
7799 ALC295_STANDARD_PINS,
7800 {0x17, 0x21014040},
7801 {0x18, 0x21a19050}),
Hui Wang3f307832017-03-23 10:00:25 +08007802 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
7803 ALC295_STANDARD_PINS),
Kailang Yang977e6272015-05-18 15:31:20 +08007804 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
Woodrow Shen703867e2015-08-05 12:34:12 +08007805 ALC298_STANDARD_PINS,
Takashi Iwai9f502ff2015-08-05 12:09:45 +02007806 {0x17, 0x90170110}),
7807 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
7808 ALC298_STANDARD_PINS,
Woodrow Shen703867e2015-08-05 12:34:12 +08007809 {0x17, 0x90170140}),
7810 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
7811 ALC298_STANDARD_PINS,
Takashi Iwai9f502ff2015-08-05 12:09:45 +02007812 {0x17, 0x90170150}),
Kai-Heng Feng9f1bc2c42017-02-16 15:26:54 +08007813 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_SPK_VOLUME,
7814 {0x12, 0xb7a60140},
7815 {0x13, 0xb7a60150},
7816 {0x17, 0x90170110},
7817 {0x1a, 0x03011020},
7818 {0x21, 0x03211030}),
James McDonnell54324222019-09-16 14:53:38 +00007819 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_ALIENWARE_MIC_NO_PRESENCE,
7820 {0x12, 0xb7a60140},
7821 {0x17, 0x90170110},
7822 {0x1a, 0x03a11030},
7823 {0x21, 0x03211020}),
Kailang Yangfcc6c872017-06-29 15:21:27 +08007824 SND_HDA_PIN_QUIRK(0x10ec0299, 0x1028, "Dell", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
7825 ALC225_STANDARD_PINS,
7826 {0x12, 0xb7a60130},
Kailang Yangfcc6c872017-06-29 15:21:27 +08007827 {0x17, 0x90170110}),
Hui Wange1918932014-05-26 16:22:44 +08007828 {}
7829};
Takashi Iwai1d045db2011-07-07 18:23:21 +02007830
Hui Wang7c0a6932019-08-16 14:27:40 +08007831/* This is the fallback pin_fixup_tbl for alc269 family, to make the tbl match
7832 * more machines, don't need to match all valid pins, just need to match
7833 * all the pins defined in the tbl. Just because of this reason, it is possible
7834 * that a single machine matches multiple tbls, so there is one limitation:
7835 * at most one tbl is allowed to define for the same vendor and same codec
7836 */
7837static const struct snd_hda_pin_quirk alc269_fallback_pin_fixup_tbl[] = {
7838 SND_HDA_PIN_QUIRK(0x10ec0289, 0x1028, "Dell", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
7839 {0x19, 0x40000000},
7840 {0x1b, 0x40000000}),
Hui Wangaed8c7f2019-11-21 10:26:43 +08007841 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7842 {0x19, 0x40000000},
7843 {0x1a, 0x40000000}),
Hui Wangd64ebdb2019-11-21 10:26:44 +08007844 SND_HDA_PIN_QUIRK(0x10ec0236, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7845 {0x19, 0x40000000},
7846 {0x1a, 0x40000000}),
Hui Wang5815bdf2019-12-11 13:13:21 +08007847 SND_HDA_PIN_QUIRK(0x10ec0274, 0x1028, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB,
7848 {0x19, 0x40000000},
7849 {0x1a, 0x40000000}),
Hui Wang7c0a6932019-08-16 14:27:40 +08007850 {}
7851};
7852
Takashi Iwai546bb672012-03-07 08:37:19 +01007853static void alc269_fill_coef(struct hda_codec *codec)
Takashi Iwai1d045db2011-07-07 18:23:21 +02007854{
Kailang Yang526af6e2012-03-07 08:25:20 +01007855 struct alc_spec *spec = codec->spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02007856 int val;
7857
Kailang Yang526af6e2012-03-07 08:25:20 +01007858 if (spec->codec_variant != ALC269_TYPE_ALC269VB)
Takashi Iwai546bb672012-03-07 08:37:19 +01007859 return;
Kailang Yang526af6e2012-03-07 08:25:20 +01007860
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007861 if ((alc_get_coef0(codec) & 0x00ff) < 0x015) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02007862 alc_write_coef_idx(codec, 0xf, 0x960b);
7863 alc_write_coef_idx(codec, 0xe, 0x8817);
7864 }
7865
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007866 if ((alc_get_coef0(codec) & 0x00ff) == 0x016) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02007867 alc_write_coef_idx(codec, 0xf, 0x960b);
7868 alc_write_coef_idx(codec, 0xe, 0x8814);
7869 }
7870
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007871 if ((alc_get_coef0(codec) & 0x00ff) == 0x017) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02007872 /* Power up output pin */
Takashi Iwai98b24882014-08-18 13:47:50 +02007873 alc_update_coef_idx(codec, 0x04, 0, 1<<11);
Takashi Iwai1d045db2011-07-07 18:23:21 +02007874 }
7875
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007876 if ((alc_get_coef0(codec) & 0x00ff) == 0x018) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02007877 val = alc_read_coef_idx(codec, 0xd);
Takashi Iwaif3ee07d2014-08-15 17:35:00 +02007878 if (val != -1 && (val & 0x0c00) >> 10 != 0x1) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02007879 /* Capless ramp up clock control */
7880 alc_write_coef_idx(codec, 0xd, val | (1<<10));
7881 }
7882 val = alc_read_coef_idx(codec, 0x17);
Takashi Iwaif3ee07d2014-08-15 17:35:00 +02007883 if (val != -1 && (val & 0x01c0) >> 6 != 0x4) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02007884 /* Class D power on reset */
7885 alc_write_coef_idx(codec, 0x17, val | (1<<7));
7886 }
7887 }
7888
Takashi Iwai98b24882014-08-18 13:47:50 +02007889 /* HP */
7890 alc_update_coef_idx(codec, 0x4, 0, 1<<11);
Takashi Iwai1d045db2011-07-07 18:23:21 +02007891}
7892
7893/*
7894 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02007895static int patch_alc269(struct hda_codec *codec)
7896{
7897 struct alc_spec *spec;
Takashi Iwai3de95172012-05-07 18:03:15 +02007898 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02007899
Takashi Iwai3de95172012-05-07 18:03:15 +02007900 err = alc_alloc_spec(codec, 0x0b);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007901 if (err < 0)
Takashi Iwai3de95172012-05-07 18:03:15 +02007902 return err;
7903
7904 spec = codec->spec;
Takashi Iwai08c189f2012-12-19 15:22:24 +01007905 spec->gen.shared_mic_vref_pin = 0x18;
Kailang Yang317d9312019-05-23 14:43:04 +08007906 codec->power_save_node = 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007907
Takashi Iwai225068a2015-05-29 10:42:14 +02007908#ifdef CONFIG_PM
7909 codec->patch_ops.suspend = alc269_suspend;
7910 codec->patch_ops.resume = alc269_resume;
7911#endif
Kailang Yangc2d6af52017-06-21 14:50:54 +08007912 spec->shutup = alc_default_shutup;
7913 spec->init_hook = alc_default_init;
Takashi Iwai225068a2015-05-29 10:42:14 +02007914
Takashi Iwai7639a062015-03-03 10:07:24 +01007915 switch (codec->core.vendor_id) {
Kailang Yang065380f2013-01-10 10:25:48 +01007916 case 0x10ec0269:
Takashi Iwai1d045db2011-07-07 18:23:21 +02007917 spec->codec_variant = ALC269_TYPE_ALC269VA;
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007918 switch (alc_get_coef0(codec) & 0x00f0) {
7919 case 0x0010:
Takashi Iwai5100cd02014-02-15 10:03:19 +01007920 if (codec->bus->pci &&
7921 codec->bus->pci->subsystem_vendor == 0x1025 &&
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007922 spec->cdefine.platform_type == 1)
Takashi Iwai20ca0c32011-10-17 16:00:35 +02007923 err = alc_codec_rename(codec, "ALC271X");
Takashi Iwai1d045db2011-07-07 18:23:21 +02007924 spec->codec_variant = ALC269_TYPE_ALC269VB;
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007925 break;
7926 case 0x0020:
Takashi Iwai5100cd02014-02-15 10:03:19 +01007927 if (codec->bus->pci &&
7928 codec->bus->pci->subsystem_vendor == 0x17aa &&
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007929 codec->bus->pci->subsystem_device == 0x21f3)
Takashi Iwai20ca0c32011-10-17 16:00:35 +02007930 err = alc_codec_rename(codec, "ALC3202");
Takashi Iwai1d045db2011-07-07 18:23:21 +02007931 spec->codec_variant = ALC269_TYPE_ALC269VC;
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007932 break;
Kailang Yangadcc70b2012-05-25 08:08:38 +02007933 case 0x0030:
7934 spec->codec_variant = ALC269_TYPE_ALC269VD;
7935 break;
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007936 default:
Takashi Iwai1d045db2011-07-07 18:23:21 +02007937 alc_fix_pll_init(codec, 0x20, 0x04, 15);
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007938 }
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007939 if (err < 0)
7940 goto error;
Kailang Yangc2d6af52017-06-21 14:50:54 +08007941 spec->shutup = alc269_shutup;
Takashi Iwai546bb672012-03-07 08:37:19 +01007942 spec->init_hook = alc269_fill_coef;
Takashi Iwai1d045db2011-07-07 18:23:21 +02007943 alc269_fill_coef(codec);
Kailang Yang065380f2013-01-10 10:25:48 +01007944 break;
7945
7946 case 0x10ec0280:
7947 case 0x10ec0290:
7948 spec->codec_variant = ALC269_TYPE_ALC280;
7949 break;
7950 case 0x10ec0282:
Kailang Yang065380f2013-01-10 10:25:48 +01007951 spec->codec_variant = ALC269_TYPE_ALC282;
Kailang Yang7b5c7a02014-03-18 16:15:54 +08007952 spec->shutup = alc282_shutup;
7953 spec->init_hook = alc282_init;
Kailang Yang065380f2013-01-10 10:25:48 +01007954 break;
Kailang Yang2af02be2013-08-22 10:03:50 +02007955 case 0x10ec0233:
7956 case 0x10ec0283:
7957 spec->codec_variant = ALC269_TYPE_ALC283;
7958 spec->shutup = alc283_shutup;
7959 spec->init_hook = alc283_init;
7960 break;
Kailang Yang065380f2013-01-10 10:25:48 +01007961 case 0x10ec0284:
7962 case 0x10ec0292:
7963 spec->codec_variant = ALC269_TYPE_ALC284;
7964 break;
Kailang Yang161ebf22013-10-24 11:36:33 +02007965 case 0x10ec0293:
Kailang Yang4731d5d2017-06-30 15:22:57 +08007966 spec->codec_variant = ALC269_TYPE_ALC293;
Kailang Yang161ebf22013-10-24 11:36:33 +02007967 break;
Kailang Yang7fc7d042013-04-25 11:04:43 +02007968 case 0x10ec0286:
Kailang Yang7c665932014-04-14 15:09:44 +08007969 case 0x10ec0288:
Kailang Yang7fc7d042013-04-25 11:04:43 +02007970 spec->codec_variant = ALC269_TYPE_ALC286;
7971 break;
Kailang Yang506b62c2014-12-18 17:07:44 +08007972 case 0x10ec0298:
7973 spec->codec_variant = ALC269_TYPE_ALC298;
7974 break;
Kailang Yangea04a1d2018-04-25 15:31:52 +08007975 case 0x10ec0235:
Kailang Yang1d04c9d2013-10-24 11:35:18 +02007976 case 0x10ec0255:
7977 spec->codec_variant = ALC269_TYPE_ALC255;
Kailang Yangab3b8e52018-04-25 16:05:27 +08007978 spec->shutup = alc256_shutup;
7979 spec->init_hook = alc256_init;
Kailang Yang1d04c9d2013-10-24 11:35:18 +02007980 break;
Kailang Yang736f20a2017-10-20 15:06:34 +08007981 case 0x10ec0236:
Kailang Yang4344aec2014-12-17 17:39:05 +08007982 case 0x10ec0256:
7983 spec->codec_variant = ALC269_TYPE_ALC256;
Kailang Yang4a219ef2017-06-16 16:54:35 +08007984 spec->shutup = alc256_shutup;
7985 spec->init_hook = alc256_init;
David Henningsson7d1b6e22015-04-21 10:48:46 +02007986 spec->gen.mixer_nid = 0; /* ALC256 does not have any loopback mixer path */
Kailang Yang4344aec2014-12-17 17:39:05 +08007987 break;
Kailang Yangf429e7e2017-12-05 15:38:24 +08007988 case 0x10ec0257:
7989 spec->codec_variant = ALC269_TYPE_ALC257;
Kailang Yang88d42b22018-03-14 16:08:57 +08007990 spec->shutup = alc256_shutup;
7991 spec->init_hook = alc256_init;
Kailang Yangf429e7e2017-12-05 15:38:24 +08007992 spec->gen.mixer_nid = 0;
7993 break;
Kailang Yang0a6f0602017-06-30 16:00:48 +08007994 case 0x10ec0215:
7995 case 0x10ec0285:
7996 case 0x10ec0289:
7997 spec->codec_variant = ALC269_TYPE_ALC215;
Kailang Yang1b6832be2018-01-17 15:32:03 +08007998 spec->shutup = alc225_shutup;
7999 spec->init_hook = alc225_init;
Kailang Yang0a6f0602017-06-30 16:00:48 +08008000 spec->gen.mixer_nid = 0;
8001 break;
Kailang Yang42314302016-02-03 15:03:50 +08008002 case 0x10ec0225:
Kailang Yang7d727862016-05-24 16:46:07 +08008003 case 0x10ec0295:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08008004 case 0x10ec0299:
Kailang Yang42314302016-02-03 15:03:50 +08008005 spec->codec_variant = ALC269_TYPE_ALC225;
Kailang Yangda911b12018-01-05 16:50:08 +08008006 spec->shutup = alc225_shutup;
8007 spec->init_hook = alc225_init;
Takashi Iwaic1350bf2017-12-27 09:03:45 +01008008 spec->gen.mixer_nid = 0; /* no loopback on ALC225, ALC295 and ALC299 */
Kailang Yang42314302016-02-03 15:03:50 +08008009 break;
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08008010 case 0x10ec0234:
8011 case 0x10ec0274:
8012 case 0x10ec0294:
8013 spec->codec_variant = ALC269_TYPE_ALC294;
Hui Wang532a7782017-06-26 12:30:32 +08008014 spec->gen.mixer_nid = 0; /* ALC2x4 does not have any loopback mixer path */
Kailang Yang71683c32017-06-20 16:33:50 +08008015 alc_update_coef_idx(codec, 0x6b, 0x0018, (1<<4) | (1<<3)); /* UAJ MIC Vref control by verb */
Kailang Yang693abe12019-01-29 15:38:21 +08008016 spec->init_hook = alc294_init;
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08008017 break;
Kailang Yang1078bef2018-11-08 16:36:15 +08008018 case 0x10ec0300:
8019 spec->codec_variant = ALC269_TYPE_ALC300;
8020 spec->gen.mixer_nid = 0; /* no loopback on ALC300 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02008021 break;
Kailang Yangf0778872019-10-24 15:13:32 +08008022 case 0x10ec0623:
8023 spec->codec_variant = ALC269_TYPE_ALC623;
8024 break;
Kailang Yang6fbae352016-05-30 16:44:20 +08008025 case 0x10ec0700:
8026 case 0x10ec0701:
8027 case 0x10ec0703:
Kailang Yang83629532019-05-02 16:03:26 +08008028 case 0x10ec0711:
Kailang Yang6fbae352016-05-30 16:44:20 +08008029 spec->codec_variant = ALC269_TYPE_ALC700;
8030 spec->gen.mixer_nid = 0; /* ALC700 does not have any loopback mixer path */
Kailang Yang2d7fe612017-11-22 15:21:32 +08008031 alc_update_coef_idx(codec, 0x4a, 1 << 15, 0); /* Combo jack auto trigger control */
Kailang Yang693abe12019-01-29 15:38:21 +08008032 spec->init_hook = alc294_init;
Kailang Yang6fbae352016-05-30 16:44:20 +08008033 break;
8034
Takashi Iwai1d045db2011-07-07 18:23:21 +02008035 }
8036
Kailang Yangad60d502013-06-28 12:03:01 +02008037 if (snd_hda_codec_read(codec, 0x51, 0, AC_VERB_PARAMETERS, 0) == 0x10ec5505) {
Kailang Yang97a26572013-11-29 00:35:26 -05008038 spec->has_alc5505_dsp = 1;
Kailang Yangad60d502013-06-28 12:03:01 +02008039 spec->init_hook = alc5505_dsp_init;
8040 }
8041
Takashi Iwaic9af7532019-05-10 11:01:43 +02008042 alc_pre_init(codec);
8043
Takashi Iwaiefe55732018-06-15 11:55:02 +02008044 snd_hda_pick_fixup(codec, alc269_fixup_models,
8045 alc269_fixup_tbl, alc269_fixups);
Hui Wang0fc1e442019-08-16 14:27:39 +08008046 snd_hda_pick_pin_fixup(codec, alc269_pin_fixup_tbl, alc269_fixups, true);
Hui Wang7c0a6932019-08-16 14:27:40 +08008047 snd_hda_pick_pin_fixup(codec, alc269_fallback_pin_fixup_tbl, alc269_fixups, false);
Takashi Iwaiefe55732018-06-15 11:55:02 +02008048 snd_hda_pick_fixup(codec, NULL, alc269_fixup_vendor_tbl,
8049 alc269_fixups);
8050 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
8051
8052 alc_auto_parse_customize_define(codec);
8053
8054 if (has_cdefine_beep(codec))
8055 spec->gen.beep_nid = 0x01;
8056
Takashi Iwaia4297b52011-08-23 18:40:12 +02008057 /* automatic parse from the BIOS config */
8058 err = alc269_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008059 if (err < 0)
8060 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008061
Takashi Iwaifea80fa2018-06-20 12:52:46 +02008062 if (!spec->gen.no_analog && spec->gen.beep_nid && spec->gen.mixer_nid) {
8063 err = set_beep_amp(spec, spec->gen.mixer_nid, 0x04, HDA_INPUT);
8064 if (err < 0)
8065 goto error;
8066 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02008067
Takashi Iwai1727a772013-01-10 09:52:52 +01008068 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01008069
Takashi Iwai1d045db2011-07-07 18:23:21 +02008070 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008071
8072 error:
8073 alc_free(codec);
8074 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008075}
8076
8077/*
8078 * ALC861
8079 */
8080
Takashi Iwai1d045db2011-07-07 18:23:21 +02008081static int alc861_parse_auto_config(struct hda_codec *codec)
8082{
Takashi Iwai1d045db2011-07-07 18:23:21 +02008083 static const hda_nid_t alc861_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02008084 static const hda_nid_t alc861_ssids[] = { 0x0e, 0x0f, 0x0b, 0 };
8085 return alc_parse_auto_config(codec, alc861_ignore, alc861_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02008086}
8087
Takashi Iwai1d045db2011-07-07 18:23:21 +02008088/* Pin config fixes */
8089enum {
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008090 ALC861_FIXUP_FSC_AMILO_PI1505,
8091 ALC861_FIXUP_AMP_VREF_0F,
8092 ALC861_FIXUP_NO_JACK_DETECT,
8093 ALC861_FIXUP_ASUS_A6RP,
Takashi Iwai6ddf0fd2013-11-29 12:47:34 +01008094 ALC660_FIXUP_ASUS_W7J,
Takashi Iwai1d045db2011-07-07 18:23:21 +02008095};
8096
Takashi Iwai31150f22012-01-30 10:54:08 +01008097/* On some laptops, VREF of pin 0x0f is abused for controlling the main amp */
8098static void alc861_fixup_asus_amp_vref_0f(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01008099 const struct hda_fixup *fix, int action)
Takashi Iwai31150f22012-01-30 10:54:08 +01008100{
8101 struct alc_spec *spec = codec->spec;
8102 unsigned int val;
8103
Takashi Iwai1727a772013-01-10 09:52:52 +01008104 if (action != HDA_FIXUP_ACT_INIT)
Takashi Iwai31150f22012-01-30 10:54:08 +01008105 return;
Takashi Iwaid3f02d62013-01-10 10:12:22 +01008106 val = snd_hda_codec_get_pin_target(codec, 0x0f);
Takashi Iwai31150f22012-01-30 10:54:08 +01008107 if (!(val & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN)))
8108 val |= AC_PINCTL_IN_EN;
8109 val |= AC_PINCTL_VREF_50;
Takashi Iwaicdd03ce2012-04-20 12:34:50 +02008110 snd_hda_set_pin_ctl(codec, 0x0f, val);
Takashi Iwai08c189f2012-12-19 15:22:24 +01008111 spec->gen.keep_vref_in_automute = 1;
Takashi Iwai31150f22012-01-30 10:54:08 +01008112}
8113
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008114/* suppress the jack-detection */
8115static void alc_fixup_no_jack_detect(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01008116 const struct hda_fixup *fix, int action)
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008117{
Takashi Iwai1727a772013-01-10 09:52:52 +01008118 if (action == HDA_FIXUP_ACT_PRE_PROBE)
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008119 codec->no_jack_detect = 1;
Jesper Juhl7d7eb9e2012-04-12 22:11:25 +02008120}
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008121
Takashi Iwai1727a772013-01-10 09:52:52 +01008122static const struct hda_fixup alc861_fixups[] = {
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008123 [ALC861_FIXUP_FSC_AMILO_PI1505] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008124 .type = HDA_FIXUP_PINS,
8125 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02008126 { 0x0b, 0x0221101f }, /* HP */
8127 { 0x0f, 0x90170310 }, /* speaker */
8128 { }
8129 }
8130 },
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008131 [ALC861_FIXUP_AMP_VREF_0F] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008132 .type = HDA_FIXUP_FUNC,
Takashi Iwai31150f22012-01-30 10:54:08 +01008133 .v.func = alc861_fixup_asus_amp_vref_0f,
Takashi Iwai3b25eb62012-01-25 09:55:46 +01008134 },
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008135 [ALC861_FIXUP_NO_JACK_DETECT] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008136 .type = HDA_FIXUP_FUNC,
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008137 .v.func = alc_fixup_no_jack_detect,
8138 },
8139 [ALC861_FIXUP_ASUS_A6RP] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008140 .type = HDA_FIXUP_FUNC,
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008141 .v.func = alc861_fixup_asus_amp_vref_0f,
8142 .chained = true,
8143 .chain_id = ALC861_FIXUP_NO_JACK_DETECT,
Takashi Iwai6ddf0fd2013-11-29 12:47:34 +01008144 },
8145 [ALC660_FIXUP_ASUS_W7J] = {
8146 .type = HDA_FIXUP_VERBS,
8147 .v.verbs = (const struct hda_verb[]) {
8148 /* ASUS W7J needs a magic pin setup on unused NID 0x10
8149 * for enabling outputs
8150 */
8151 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8152 { }
8153 },
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008154 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02008155};
8156
8157static const struct snd_pci_quirk alc861_fixup_tbl[] = {
Takashi Iwai6ddf0fd2013-11-29 12:47:34 +01008158 SND_PCI_QUIRK(0x1043, 0x1253, "ASUS W7J", ALC660_FIXUP_ASUS_W7J),
Takashi Iwaie7ca2372013-12-02 15:27:19 +01008159 SND_PCI_QUIRK(0x1043, 0x1263, "ASUS Z35HL", ALC660_FIXUP_ASUS_W7J),
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008160 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS A6Rp", ALC861_FIXUP_ASUS_A6RP),
8161 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", ALC861_FIXUP_AMP_VREF_0F),
8162 SND_PCI_QUIRK(0x1462, 0x7254, "HP DX2200", ALC861_FIXUP_NO_JACK_DETECT),
8163 SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", ALC861_FIXUP_AMP_VREF_0F),
8164 SND_PCI_QUIRK(0x1584, 0x0000, "Uniwill ECS M31EI", ALC861_FIXUP_AMP_VREF_0F),
8165 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", ALC861_FIXUP_FSC_AMILO_PI1505),
Takashi Iwai1d045db2011-07-07 18:23:21 +02008166 {}
8167};
8168
8169/*
8170 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02008171static int patch_alc861(struct hda_codec *codec)
8172{
8173 struct alc_spec *spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008174 int err;
8175
Takashi Iwai3de95172012-05-07 18:03:15 +02008176 err = alc_alloc_spec(codec, 0x15);
8177 if (err < 0)
8178 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008179
Takashi Iwai3de95172012-05-07 18:03:15 +02008180 spec = codec->spec;
Takashi Iwai2722b532019-08-22 09:55:37 +02008181 if (has_cdefine_beep(codec))
8182 spec->gen.beep_nid = 0x23;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008183
Takashi Iwai225068a2015-05-29 10:42:14 +02008184#ifdef CONFIG_PM
8185 spec->power_hook = alc_power_eapd;
8186#endif
8187
Takashi Iwaic9af7532019-05-10 11:01:43 +02008188 alc_pre_init(codec);
8189
Takashi Iwai1727a772013-01-10 09:52:52 +01008190 snd_hda_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
8191 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02008192
Takashi Iwaicb4e4822011-08-23 17:34:25 +02008193 /* automatic parse from the BIOS config */
8194 err = alc861_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008195 if (err < 0)
8196 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008197
Takashi Iwaifea80fa2018-06-20 12:52:46 +02008198 if (!spec->gen.no_analog) {
8199 err = set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
8200 if (err < 0)
8201 goto error;
8202 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02008203
Takashi Iwai1727a772013-01-10 09:52:52 +01008204 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01008205
Takashi Iwai1d045db2011-07-07 18:23:21 +02008206 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008207
8208 error:
8209 alc_free(codec);
8210 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008211}
8212
8213/*
8214 * ALC861-VD support
8215 *
8216 * Based on ALC882
8217 *
8218 * In addition, an independent DAC
8219 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02008220static int alc861vd_parse_auto_config(struct hda_codec *codec)
8221{
Takashi Iwai1d045db2011-07-07 18:23:21 +02008222 static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02008223 static const hda_nid_t alc861vd_ssids[] = { 0x15, 0x1b, 0x14, 0 };
8224 return alc_parse_auto_config(codec, alc861vd_ignore, alc861vd_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02008225}
8226
Takashi Iwai1d045db2011-07-07 18:23:21 +02008227enum {
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008228 ALC660VD_FIX_ASUS_GPIO1,
8229 ALC861VD_FIX_DALLAS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02008230};
8231
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008232/* exclude VREF80 */
8233static void alc861vd_fixup_dallas(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01008234 const struct hda_fixup *fix, int action)
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008235{
Takashi Iwai1727a772013-01-10 09:52:52 +01008236 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwaib78562b2012-12-17 20:06:49 +01008237 snd_hda_override_pin_caps(codec, 0x18, 0x00000734);
8238 snd_hda_override_pin_caps(codec, 0x19, 0x0000073c);
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008239 }
8240}
8241
Takashi Iwaidf73d832018-06-19 23:05:47 +02008242/* reset GPIO1 */
8243static void alc660vd_fixup_asus_gpio1(struct hda_codec *codec,
8244 const struct hda_fixup *fix, int action)
8245{
8246 struct alc_spec *spec = codec->spec;
8247
8248 if (action == HDA_FIXUP_ACT_PRE_PROBE)
8249 spec->gpio_mask |= 0x02;
8250 alc_fixup_gpio(codec, action, 0x01);
8251}
8252
Takashi Iwai1727a772013-01-10 09:52:52 +01008253static const struct hda_fixup alc861vd_fixups[] = {
Takashi Iwai1d045db2011-07-07 18:23:21 +02008254 [ALC660VD_FIX_ASUS_GPIO1] = {
Takashi Iwaidf73d832018-06-19 23:05:47 +02008255 .type = HDA_FIXUP_FUNC,
8256 .v.func = alc660vd_fixup_asus_gpio1,
Takashi Iwai1d045db2011-07-07 18:23:21 +02008257 },
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008258 [ALC861VD_FIX_DALLAS] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008259 .type = HDA_FIXUP_FUNC,
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008260 .v.func = alc861vd_fixup_dallas,
8261 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02008262};
8263
8264static const struct snd_pci_quirk alc861vd_fixup_tbl[] = {
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008265 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_FIX_DALLAS),
Takashi Iwai1d045db2011-07-07 18:23:21 +02008266 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008267 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_FIX_DALLAS),
Takashi Iwai1d045db2011-07-07 18:23:21 +02008268 {}
8269};
8270
Takashi Iwai1d045db2011-07-07 18:23:21 +02008271/*
8272 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02008273static int patch_alc861vd(struct hda_codec *codec)
8274{
8275 struct alc_spec *spec;
Takashi Iwaicb4e4822011-08-23 17:34:25 +02008276 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008277
Takashi Iwai3de95172012-05-07 18:03:15 +02008278 err = alc_alloc_spec(codec, 0x0b);
8279 if (err < 0)
8280 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008281
Takashi Iwai3de95172012-05-07 18:03:15 +02008282 spec = codec->spec;
Takashi Iwai2722b532019-08-22 09:55:37 +02008283 if (has_cdefine_beep(codec))
8284 spec->gen.beep_nid = 0x23;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008285
Takashi Iwai225068a2015-05-29 10:42:14 +02008286 spec->shutup = alc_eapd_shutup;
8287
Takashi Iwaic9af7532019-05-10 11:01:43 +02008288 alc_pre_init(codec);
8289
Takashi Iwai1727a772013-01-10 09:52:52 +01008290 snd_hda_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
8291 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02008292
Takashi Iwaicb4e4822011-08-23 17:34:25 +02008293 /* automatic parse from the BIOS config */
8294 err = alc861vd_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008295 if (err < 0)
8296 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008297
Takashi Iwaifea80fa2018-06-20 12:52:46 +02008298 if (!spec->gen.no_analog) {
8299 err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
8300 if (err < 0)
8301 goto error;
8302 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02008303
Takashi Iwai1727a772013-01-10 09:52:52 +01008304 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01008305
Takashi Iwai1d045db2011-07-07 18:23:21 +02008306 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008307
8308 error:
8309 alc_free(codec);
8310 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008311}
8312
8313/*
8314 * ALC662 support
8315 *
8316 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
8317 * configuration. Each pin widget can choose any input DACs and a mixer.
8318 * Each ADC is connected from a mixer of all inputs. This makes possible
8319 * 6-channel independent captures.
8320 *
8321 * In addition, an independent DAC for the multi-playback (not used in this
8322 * driver yet).
8323 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02008324
8325/*
8326 * BIOS auto configuration
8327 */
8328
Kailang Yangbc9f98a2007-04-12 13:06:07 +02008329static int alc662_parse_auto_config(struct hda_codec *codec)
8330{
Takashi Iwai4c6d72d2011-05-02 11:30:18 +02008331 static const hda_nid_t alc662_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02008332 static const hda_nid_t alc663_ssids[] = { 0x15, 0x1b, 0x14, 0x21 };
8333 static const hda_nid_t alc662_ssids[] = { 0x15, 0x1b, 0x14, 0 };
8334 const hda_nid_t *ssids;
Takashi Iwaiee979a142008-09-02 15:42:20 +02008335
Takashi Iwai7639a062015-03-03 10:07:24 +01008336 if (codec->core.vendor_id == 0x10ec0272 || codec->core.vendor_id == 0x10ec0663 ||
8337 codec->core.vendor_id == 0x10ec0665 || codec->core.vendor_id == 0x10ec0670 ||
8338 codec->core.vendor_id == 0x10ec0671)
Takashi Iwai3e6179b2011-07-08 16:55:13 +02008339 ssids = alc663_ssids;
Kailang Yang6227cdc2010-02-25 08:36:52 +01008340 else
Takashi Iwai3e6179b2011-07-08 16:55:13 +02008341 ssids = alc662_ssids;
8342 return alc_parse_auto_config(codec, alc662_ignore, ssids);
Kailang Yangbc9f98a2007-04-12 13:06:07 +02008343}
8344
Todd Broch6be79482010-12-07 16:51:05 -08008345static void alc272_fixup_mario(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01008346 const struct hda_fixup *fix, int action)
Takashi Iwai6fc398c2011-01-13 14:36:37 +01008347{
Takashi Iwai9bb1f062013-01-10 17:14:29 +01008348 if (action != HDA_FIXUP_ACT_PRE_PROBE)
Takashi Iwai6fc398c2011-01-13 14:36:37 +01008349 return;
Todd Broch6be79482010-12-07 16:51:05 -08008350 if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT,
8351 (0x3b << AC_AMPCAP_OFFSET_SHIFT) |
8352 (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) |
8353 (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) |
8354 (0 << AC_AMPCAP_MUTE_SHIFT)))
Takashi Iwai4e76a882014-02-25 12:21:03 +01008355 codec_warn(codec, "failed to override amp caps for NID 0x2\n");
Todd Broch6be79482010-12-07 16:51:05 -08008356}
8357
Takashi Iwai8e383952013-10-30 17:41:12 +01008358static const struct snd_pcm_chmap_elem asus_pcm_2_1_chmaps[] = {
8359 { .channels = 2,
8360 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } },
8361 { .channels = 4,
8362 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR,
8363 SNDRV_CHMAP_NA, SNDRV_CHMAP_LFE } }, /* LFE only on right */
8364 { }
8365};
8366
8367/* override the 2.1 chmap */
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01008368static void alc_fixup_bass_chmap(struct hda_codec *codec,
Takashi Iwai8e383952013-10-30 17:41:12 +01008369 const struct hda_fixup *fix, int action)
8370{
8371 if (action == HDA_FIXUP_ACT_BUILD) {
8372 struct alc_spec *spec = codec->spec;
Takashi Iwaibbbc7e82015-02-27 17:43:19 +01008373 spec->gen.pcm_rec[0]->stream[0].chmap = asus_pcm_2_1_chmaps;
Takashi Iwai8e383952013-10-30 17:41:12 +01008374 }
8375}
8376
Takashi Iwaibf686652014-01-13 16:18:25 +01008377/* avoid D3 for keeping GPIO up */
8378static unsigned int gpio_led_power_filter(struct hda_codec *codec,
8379 hda_nid_t nid,
8380 unsigned int power_state)
8381{
8382 struct alc_spec *spec = codec->spec;
Takashi Iwaid261eec2018-06-19 22:32:29 +02008383 if (nid == codec->core.afg && power_state == AC_PWRST_D3 && spec->gpio_data)
Takashi Iwaibf686652014-01-13 16:18:25 +01008384 return AC_PWRST_D0;
8385 return power_state;
8386}
8387
Takashi Iwai3e887f32014-01-10 17:50:58 +01008388static void alc662_fixup_led_gpio1(struct hda_codec *codec,
8389 const struct hda_fixup *fix, int action)
8390{
8391 struct alc_spec *spec = codec->spec;
Takashi Iwai3e887f32014-01-10 17:50:58 +01008392
Takashi Iwai01e4a272018-06-19 22:47:30 +02008393 alc_fixup_hp_gpio_led(codec, action, 0x01, 0);
Takashi Iwai3e887f32014-01-10 17:50:58 +01008394 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai0f32fd192014-11-19 12:16:14 +01008395 spec->mute_led_polarity = 1;
Takashi Iwaibf686652014-01-13 16:18:25 +01008396 codec->power_filter = gpio_led_power_filter;
Takashi Iwai3e887f32014-01-10 17:50:58 +01008397 }
8398}
8399
Kailang Yangc6790c82016-11-25 16:15:17 +08008400static void alc662_usi_automute_hook(struct hda_codec *codec,
8401 struct hda_jack_callback *jack)
8402{
8403 struct alc_spec *spec = codec->spec;
8404 int vref;
8405 msleep(200);
8406 snd_hda_gen_hp_automute(codec, jack);
8407
8408 vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0;
8409 msleep(100);
8410 snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8411 vref);
8412}
8413
8414static void alc662_fixup_usi_headset_mic(struct hda_codec *codec,
8415 const struct hda_fixup *fix, int action)
8416{
8417 struct alc_spec *spec = codec->spec;
8418 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
8419 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
8420 spec->gen.hp_automute_hook = alc662_usi_automute_hook;
8421 }
8422}
8423
Sergey Bostandzhyan00066e92019-09-06 11:33:43 +02008424static void alc662_aspire_ethos_mute_speakers(struct hda_codec *codec,
8425 struct hda_jack_callback *cb)
8426{
8427 /* surround speakers at 0x1b already get muted automatically when
8428 * headphones are plugged in, but we have to mute/unmute the remaining
8429 * channels manually:
8430 * 0x15 - front left/front right
8431 * 0x18 - front center/ LFE
8432 */
8433 if (snd_hda_jack_detect_state(codec, 0x1b) == HDA_JACK_PRESENT) {
8434 snd_hda_set_pin_ctl_cache(codec, 0x15, 0);
8435 snd_hda_set_pin_ctl_cache(codec, 0x18, 0);
8436 } else {
8437 snd_hda_set_pin_ctl_cache(codec, 0x15, PIN_OUT);
8438 snd_hda_set_pin_ctl_cache(codec, 0x18, PIN_OUT);
8439 }
8440}
8441
8442static void alc662_fixup_aspire_ethos_hp(struct hda_codec *codec,
8443 const struct hda_fixup *fix, int action)
8444{
8445 /* Pin 0x1b: shared headphones jack and surround speakers */
8446 if (!is_jack_detectable(codec, 0x1b))
8447 return;
8448
8449 switch (action) {
8450 case HDA_FIXUP_ACT_PRE_PROBE:
8451 snd_hda_jack_detect_enable_callback(codec, 0x1b,
8452 alc662_aspire_ethos_mute_speakers);
Takashi Iwai336820c2019-11-28 21:26:30 +01008453 /* subwoofer needs an extra GPIO setting to become audible */
8454 alc_setup_gpio(codec, 0x02);
Sergey Bostandzhyan00066e92019-09-06 11:33:43 +02008455 break;
8456 case HDA_FIXUP_ACT_INIT:
8457 /* Make sure to start in a correct state, i.e. if
8458 * headphones have been plugged in before powering up the system
8459 */
8460 alc662_aspire_ethos_mute_speakers(codec, NULL);
8461 break;
8462 }
8463}
8464
Kailang Yangf3f91852014-10-24 15:43:46 +08008465static struct coef_fw alc668_coefs[] = {
8466 WRITE_COEF(0x01, 0xbebe), WRITE_COEF(0x02, 0xaaaa), WRITE_COEF(0x03, 0x0),
8467 WRITE_COEF(0x04, 0x0180), WRITE_COEF(0x06, 0x0), WRITE_COEF(0x07, 0x0f80),
8468 WRITE_COEF(0x08, 0x0031), WRITE_COEF(0x0a, 0x0060), WRITE_COEF(0x0b, 0x0),
8469 WRITE_COEF(0x0c, 0x7cf7), WRITE_COEF(0x0d, 0x1080), WRITE_COEF(0x0e, 0x7f7f),
8470 WRITE_COEF(0x0f, 0xcccc), WRITE_COEF(0x10, 0xddcc), WRITE_COEF(0x11, 0x0001),
8471 WRITE_COEF(0x13, 0x0), WRITE_COEF(0x14, 0x2aa0), WRITE_COEF(0x17, 0xa940),
8472 WRITE_COEF(0x19, 0x0), WRITE_COEF(0x1a, 0x0), WRITE_COEF(0x1b, 0x0),
8473 WRITE_COEF(0x1c, 0x0), WRITE_COEF(0x1d, 0x0), WRITE_COEF(0x1e, 0x7418),
8474 WRITE_COEF(0x1f, 0x0804), WRITE_COEF(0x20, 0x4200), WRITE_COEF(0x21, 0x0468),
8475 WRITE_COEF(0x22, 0x8ccc), WRITE_COEF(0x23, 0x0250), WRITE_COEF(0x24, 0x7418),
8476 WRITE_COEF(0x27, 0x0), WRITE_COEF(0x28, 0x8ccc), WRITE_COEF(0x2a, 0xff00),
8477 WRITE_COEF(0x2b, 0x8000), WRITE_COEF(0xa7, 0xff00), WRITE_COEF(0xa8, 0x8000),
8478 WRITE_COEF(0xaa, 0x2e17), WRITE_COEF(0xab, 0xa0c0), WRITE_COEF(0xac, 0x0),
8479 WRITE_COEF(0xad, 0x0), WRITE_COEF(0xae, 0x2ac6), WRITE_COEF(0xaf, 0xa480),
8480 WRITE_COEF(0xb0, 0x0), WRITE_COEF(0xb1, 0x0), WRITE_COEF(0xb2, 0x0),
8481 WRITE_COEF(0xb3, 0x0), WRITE_COEF(0xb4, 0x0), WRITE_COEF(0xb5, 0x1040),
8482 WRITE_COEF(0xb6, 0xd697), WRITE_COEF(0xb7, 0x902b), WRITE_COEF(0xb8, 0xd697),
8483 WRITE_COEF(0xb9, 0x902b), WRITE_COEF(0xba, 0xb8ba), WRITE_COEF(0xbb, 0xaaab),
8484 WRITE_COEF(0xbc, 0xaaaf), WRITE_COEF(0xbd, 0x6aaa), WRITE_COEF(0xbe, 0x1c02),
8485 WRITE_COEF(0xc0, 0x00ff), WRITE_COEF(0xc1, 0x0fa6),
8486 {}
8487};
8488
8489static void alc668_restore_default_value(struct hda_codec *codec)
8490{
8491 alc_process_coef_fw(codec, alc668_coefs);
8492}
8493
David Henningsson6cb3b702010-09-09 08:51:44 +02008494enum {
Daniel T Chen2df03512010-10-10 22:39:28 -04008495 ALC662_FIXUP_ASPIRE,
Takashi Iwai3e887f32014-01-10 17:50:58 +01008496 ALC662_FIXUP_LED_GPIO1,
David Henningsson6cb3b702010-09-09 08:51:44 +02008497 ALC662_FIXUP_IDEAPAD,
Todd Broch6be79482010-12-07 16:51:05 -08008498 ALC272_FIXUP_MARIO,
Anisse Astierd2ebd472011-01-20 12:36:21 +01008499 ALC662_FIXUP_CZC_P10T,
David Henningsson94024cd2011-04-29 14:10:55 +02008500 ALC662_FIXUP_SKU_IGNORE,
Takashi Iwaie59ea3e2011-06-29 17:21:00 +02008501 ALC662_FIXUP_HP_RP5800,
Takashi Iwai53c334a2011-08-23 18:27:14 +02008502 ALC662_FIXUP_ASUS_MODE1,
8503 ALC662_FIXUP_ASUS_MODE2,
8504 ALC662_FIXUP_ASUS_MODE3,
8505 ALC662_FIXUP_ASUS_MODE4,
8506 ALC662_FIXUP_ASUS_MODE5,
8507 ALC662_FIXUP_ASUS_MODE6,
8508 ALC662_FIXUP_ASUS_MODE7,
8509 ALC662_FIXUP_ASUS_MODE8,
Takashi Iwai1565cc32012-02-13 12:03:25 +01008510 ALC662_FIXUP_NO_JACK_DETECT,
David Henningssonedfe3bf2012-06-12 13:15:12 +02008511 ALC662_FIXUP_ZOTAC_Z68,
Takashi Iwai125821a2012-06-22 14:30:29 +02008512 ALC662_FIXUP_INV_DMIC,
David Henningsson1f8b46c2015-05-12 14:38:15 +02008513 ALC662_FIXUP_DELL_MIC_NO_PRESENCE,
David Henningsson73bdd592013-04-15 15:44:14 +02008514 ALC668_FIXUP_DELL_MIC_NO_PRESENCE,
David Henningsson1f8b46c2015-05-12 14:38:15 +02008515 ALC662_FIXUP_HEADSET_MODE,
David Henningsson73bdd592013-04-15 15:44:14 +02008516 ALC668_FIXUP_HEADSET_MODE,
David Henningsson8e54b4a2014-02-07 09:31:07 +01008517 ALC662_FIXUP_BASS_MODE4_CHMAP,
David Henningsson61a75f12014-02-07 09:31:08 +01008518 ALC662_FIXUP_BASS_16,
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01008519 ALC662_FIXUP_BASS_1A,
David Henningsson8e54b4a2014-02-07 09:31:07 +01008520 ALC662_FIXUP_BASS_CHMAP,
Hui Wang493a52a2014-01-14 14:07:36 +08008521 ALC668_FIXUP_AUTO_MUTE,
Gabriele Mazzotta5e6db662014-05-20 18:58:26 +02008522 ALC668_FIXUP_DELL_DISABLE_AAMIX,
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02008523 ALC668_FIXUP_DELL_XPS13,
Bobi Mihalca9d4dc582016-03-23 13:26:11 +02008524 ALC662_FIXUP_ASUS_Nx50,
Mikhail Paulyshkafc7438b2017-04-21 08:52:42 +02008525 ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE,
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07008526 ALC668_FIXUP_ASUS_Nx51,
Takashi Iwai5b7c5e12018-10-09 14:20:17 +02008527 ALC668_FIXUP_MIC_COEF,
Takashi Iwai11ba6112018-10-07 09:44:17 +02008528 ALC668_FIXUP_ASUS_G751,
Kailang Yang78f4f7c2016-06-07 11:31:34 +08008529 ALC891_FIXUP_HEADSET_MODE,
8530 ALC891_FIXUP_DELL_MIC_NO_PRESENCE,
Shrirang Bagul9b51fe32016-08-01 13:16:17 +08008531 ALC662_FIXUP_ACER_VERITON,
Takashi Iwai1a3f0992016-10-20 12:14:51 +02008532 ALC892_FIXUP_ASROCK_MOBO,
Kailang Yangc6790c82016-11-25 16:15:17 +08008533 ALC662_FIXUP_USI_FUNC,
8534 ALC662_FIXUP_USI_HEADSET_MODE,
Kailang Yangca169cc2017-04-25 16:17:40 +08008535 ALC662_FIXUP_LENOVO_MULTI_CODECS,
Sergey Bostandzhyan00066e92019-09-06 11:33:43 +02008536 ALC669_FIXUP_ACER_ASPIRE_ETHOS,
Sergey Bostandzhyan00066e92019-09-06 11:33:43 +02008537 ALC669_FIXUP_ACER_ASPIRE_ETHOS_HEADSET,
David Henningsson6cb3b702010-09-09 08:51:44 +02008538};
8539
Takashi Iwai1727a772013-01-10 09:52:52 +01008540static const struct hda_fixup alc662_fixups[] = {
Daniel T Chen2df03512010-10-10 22:39:28 -04008541 [ALC662_FIXUP_ASPIRE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008542 .type = HDA_FIXUP_PINS,
8543 .v.pins = (const struct hda_pintbl[]) {
Daniel T Chen2df03512010-10-10 22:39:28 -04008544 { 0x15, 0x99130112 }, /* subwoofer */
8545 { }
8546 }
8547 },
Takashi Iwai3e887f32014-01-10 17:50:58 +01008548 [ALC662_FIXUP_LED_GPIO1] = {
8549 .type = HDA_FIXUP_FUNC,
8550 .v.func = alc662_fixup_led_gpio1,
8551 },
David Henningsson6cb3b702010-09-09 08:51:44 +02008552 [ALC662_FIXUP_IDEAPAD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008553 .type = HDA_FIXUP_PINS,
8554 .v.pins = (const struct hda_pintbl[]) {
David Henningsson6cb3b702010-09-09 08:51:44 +02008555 { 0x17, 0x99130112 }, /* subwoofer */
8556 { }
Takashi Iwai3e887f32014-01-10 17:50:58 +01008557 },
8558 .chained = true,
8559 .chain_id = ALC662_FIXUP_LED_GPIO1,
David Henningsson6cb3b702010-09-09 08:51:44 +02008560 },
Todd Broch6be79482010-12-07 16:51:05 -08008561 [ALC272_FIXUP_MARIO] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008562 .type = HDA_FIXUP_FUNC,
Takashi Iwaib5bfbc62011-01-13 14:22:32 +01008563 .v.func = alc272_fixup_mario,
Anisse Astierd2ebd472011-01-20 12:36:21 +01008564 },
8565 [ALC662_FIXUP_CZC_P10T] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008566 .type = HDA_FIXUP_VERBS,
Anisse Astierd2ebd472011-01-20 12:36:21 +01008567 .v.verbs = (const struct hda_verb[]) {
8568 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
8569 {}
8570 }
8571 },
David Henningsson94024cd2011-04-29 14:10:55 +02008572 [ALC662_FIXUP_SKU_IGNORE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008573 .type = HDA_FIXUP_FUNC,
Takashi Iwai23d30f22012-05-07 17:17:32 +02008574 .v.func = alc_fixup_sku_ignore,
Takashi Iwaic6b35872011-03-28 12:05:31 +02008575 },
Takashi Iwaie59ea3e2011-06-29 17:21:00 +02008576 [ALC662_FIXUP_HP_RP5800] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008577 .type = HDA_FIXUP_PINS,
8578 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaie59ea3e2011-06-29 17:21:00 +02008579 { 0x14, 0x0221201f }, /* HP out */
8580 { }
8581 },
8582 .chained = true,
8583 .chain_id = ALC662_FIXUP_SKU_IGNORE
8584 },
Takashi Iwai53c334a2011-08-23 18:27:14 +02008585 [ALC662_FIXUP_ASUS_MODE1] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008586 .type = HDA_FIXUP_PINS,
8587 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008588 { 0x14, 0x99130110 }, /* speaker */
8589 { 0x18, 0x01a19c20 }, /* mic */
8590 { 0x19, 0x99a3092f }, /* int-mic */
8591 { 0x21, 0x0121401f }, /* HP out */
8592 { }
8593 },
8594 .chained = true,
8595 .chain_id = ALC662_FIXUP_SKU_IGNORE
8596 },
8597 [ALC662_FIXUP_ASUS_MODE2] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008598 .type = HDA_FIXUP_PINS,
8599 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai2996bdb2011-08-18 16:02:24 +02008600 { 0x14, 0x99130110 }, /* speaker */
8601 { 0x18, 0x01a19820 }, /* mic */
8602 { 0x19, 0x99a3092f }, /* int-mic */
8603 { 0x1b, 0x0121401f }, /* HP out */
8604 { }
8605 },
Takashi Iwai53c334a2011-08-23 18:27:14 +02008606 .chained = true,
8607 .chain_id = ALC662_FIXUP_SKU_IGNORE
8608 },
8609 [ALC662_FIXUP_ASUS_MODE3] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008610 .type = HDA_FIXUP_PINS,
8611 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008612 { 0x14, 0x99130110 }, /* speaker */
8613 { 0x15, 0x0121441f }, /* HP */
8614 { 0x18, 0x01a19840 }, /* mic */
8615 { 0x19, 0x99a3094f }, /* int-mic */
8616 { 0x21, 0x01211420 }, /* HP2 */
8617 { }
8618 },
8619 .chained = true,
8620 .chain_id = ALC662_FIXUP_SKU_IGNORE
8621 },
8622 [ALC662_FIXUP_ASUS_MODE4] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008623 .type = HDA_FIXUP_PINS,
8624 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008625 { 0x14, 0x99130110 }, /* speaker */
8626 { 0x16, 0x99130111 }, /* speaker */
8627 { 0x18, 0x01a19840 }, /* mic */
8628 { 0x19, 0x99a3094f }, /* int-mic */
8629 { 0x21, 0x0121441f }, /* HP */
8630 { }
8631 },
8632 .chained = true,
8633 .chain_id = ALC662_FIXUP_SKU_IGNORE
8634 },
8635 [ALC662_FIXUP_ASUS_MODE5] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008636 .type = HDA_FIXUP_PINS,
8637 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008638 { 0x14, 0x99130110 }, /* speaker */
8639 { 0x15, 0x0121441f }, /* HP */
8640 { 0x16, 0x99130111 }, /* speaker */
8641 { 0x18, 0x01a19840 }, /* mic */
8642 { 0x19, 0x99a3094f }, /* int-mic */
8643 { }
8644 },
8645 .chained = true,
8646 .chain_id = ALC662_FIXUP_SKU_IGNORE
8647 },
8648 [ALC662_FIXUP_ASUS_MODE6] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008649 .type = HDA_FIXUP_PINS,
8650 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008651 { 0x14, 0x99130110 }, /* speaker */
8652 { 0x15, 0x01211420 }, /* HP2 */
8653 { 0x18, 0x01a19840 }, /* mic */
8654 { 0x19, 0x99a3094f }, /* int-mic */
8655 { 0x1b, 0x0121441f }, /* HP */
8656 { }
8657 },
8658 .chained = true,
8659 .chain_id = ALC662_FIXUP_SKU_IGNORE
8660 },
8661 [ALC662_FIXUP_ASUS_MODE7] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008662 .type = HDA_FIXUP_PINS,
8663 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008664 { 0x14, 0x99130110 }, /* speaker */
8665 { 0x17, 0x99130111 }, /* speaker */
8666 { 0x18, 0x01a19840 }, /* mic */
8667 { 0x19, 0x99a3094f }, /* int-mic */
8668 { 0x1b, 0x01214020 }, /* HP */
8669 { 0x21, 0x0121401f }, /* HP */
8670 { }
8671 },
8672 .chained = true,
8673 .chain_id = ALC662_FIXUP_SKU_IGNORE
8674 },
8675 [ALC662_FIXUP_ASUS_MODE8] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008676 .type = HDA_FIXUP_PINS,
8677 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008678 { 0x14, 0x99130110 }, /* speaker */
8679 { 0x12, 0x99a30970 }, /* int-mic */
8680 { 0x15, 0x01214020 }, /* HP */
8681 { 0x17, 0x99130111 }, /* speaker */
8682 { 0x18, 0x01a19840 }, /* mic */
8683 { 0x21, 0x0121401f }, /* HP */
8684 { }
8685 },
8686 .chained = true,
8687 .chain_id = ALC662_FIXUP_SKU_IGNORE
Takashi Iwai2996bdb2011-08-18 16:02:24 +02008688 },
Takashi Iwai1565cc32012-02-13 12:03:25 +01008689 [ALC662_FIXUP_NO_JACK_DETECT] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008690 .type = HDA_FIXUP_FUNC,
Takashi Iwai1565cc32012-02-13 12:03:25 +01008691 .v.func = alc_fixup_no_jack_detect,
8692 },
David Henningssonedfe3bf2012-06-12 13:15:12 +02008693 [ALC662_FIXUP_ZOTAC_Z68] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008694 .type = HDA_FIXUP_PINS,
8695 .v.pins = (const struct hda_pintbl[]) {
David Henningssonedfe3bf2012-06-12 13:15:12 +02008696 { 0x1b, 0x02214020 }, /* Front HP */
8697 { }
8698 }
8699 },
Takashi Iwai125821a2012-06-22 14:30:29 +02008700 [ALC662_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008701 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02008702 .v.func = alc_fixup_inv_dmic,
Takashi Iwai125821a2012-06-22 14:30:29 +02008703 },
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02008704 [ALC668_FIXUP_DELL_XPS13] = {
8705 .type = HDA_FIXUP_FUNC,
8706 .v.func = alc_fixup_dell_xps13,
8707 .chained = true,
8708 .chain_id = ALC668_FIXUP_DELL_DISABLE_AAMIX
8709 },
Gabriele Mazzotta5e6db662014-05-20 18:58:26 +02008710 [ALC668_FIXUP_DELL_DISABLE_AAMIX] = {
8711 .type = HDA_FIXUP_FUNC,
8712 .v.func = alc_fixup_disable_aamix,
8713 .chained = true,
8714 .chain_id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE
8715 },
Hui Wang493a52a2014-01-14 14:07:36 +08008716 [ALC668_FIXUP_AUTO_MUTE] = {
8717 .type = HDA_FIXUP_FUNC,
8718 .v.func = alc_fixup_auto_mute_via_amp,
8719 .chained = true,
8720 .chain_id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE
8721 },
David Henningsson1f8b46c2015-05-12 14:38:15 +02008722 [ALC662_FIXUP_DELL_MIC_NO_PRESENCE] = {
8723 .type = HDA_FIXUP_PINS,
8724 .v.pins = (const struct hda_pintbl[]) {
8725 { 0x19, 0x03a1113c }, /* use as headset mic, without its own jack detect */
8726 /* headphone mic by setting pin control of 0x1b (headphone out) to in + vref_50 */
8727 { }
8728 },
8729 .chained = true,
8730 .chain_id = ALC662_FIXUP_HEADSET_MODE
8731 },
8732 [ALC662_FIXUP_HEADSET_MODE] = {
8733 .type = HDA_FIXUP_FUNC,
8734 .v.func = alc_fixup_headset_mode_alc662,
8735 },
David Henningsson73bdd592013-04-15 15:44:14 +02008736 [ALC668_FIXUP_DELL_MIC_NO_PRESENCE] = {
8737 .type = HDA_FIXUP_PINS,
8738 .v.pins = (const struct hda_pintbl[]) {
8739 { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
8740 { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */
8741 { }
8742 },
8743 .chained = true,
8744 .chain_id = ALC668_FIXUP_HEADSET_MODE
8745 },
8746 [ALC668_FIXUP_HEADSET_MODE] = {
8747 .type = HDA_FIXUP_FUNC,
8748 .v.func = alc_fixup_headset_mode_alc668,
8749 },
David Henningsson8e54b4a2014-02-07 09:31:07 +01008750 [ALC662_FIXUP_BASS_MODE4_CHMAP] = {
Takashi Iwai8e383952013-10-30 17:41:12 +01008751 .type = HDA_FIXUP_FUNC,
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01008752 .v.func = alc_fixup_bass_chmap,
Takashi Iwai8e383952013-10-30 17:41:12 +01008753 .chained = true,
8754 .chain_id = ALC662_FIXUP_ASUS_MODE4
8755 },
David Henningsson61a75f12014-02-07 09:31:08 +01008756 [ALC662_FIXUP_BASS_16] = {
8757 .type = HDA_FIXUP_PINS,
8758 .v.pins = (const struct hda_pintbl[]) {
8759 {0x16, 0x80106111}, /* bass speaker */
8760 {}
8761 },
8762 .chained = true,
8763 .chain_id = ALC662_FIXUP_BASS_CHMAP,
8764 },
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01008765 [ALC662_FIXUP_BASS_1A] = {
8766 .type = HDA_FIXUP_PINS,
8767 .v.pins = (const struct hda_pintbl[]) {
8768 {0x1a, 0x80106111}, /* bass speaker */
8769 {}
8770 },
David Henningsson8e54b4a2014-02-07 09:31:07 +01008771 .chained = true,
8772 .chain_id = ALC662_FIXUP_BASS_CHMAP,
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01008773 },
David Henningsson8e54b4a2014-02-07 09:31:07 +01008774 [ALC662_FIXUP_BASS_CHMAP] = {
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01008775 .type = HDA_FIXUP_FUNC,
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01008776 .v.func = alc_fixup_bass_chmap,
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01008777 },
Bobi Mihalca9d4dc582016-03-23 13:26:11 +02008778 [ALC662_FIXUP_ASUS_Nx50] = {
8779 .type = HDA_FIXUP_FUNC,
8780 .v.func = alc_fixup_auto_mute_via_amp,
8781 .chained = true,
8782 .chain_id = ALC662_FIXUP_BASS_1A
8783 },
Mikhail Paulyshkafc7438b2017-04-21 08:52:42 +02008784 [ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE] = {
8785 .type = HDA_FIXUP_FUNC,
8786 .v.func = alc_fixup_headset_mode_alc668,
8787 .chain_id = ALC662_FIXUP_BASS_CHMAP
8788 },
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07008789 [ALC668_FIXUP_ASUS_Nx51] = {
8790 .type = HDA_FIXUP_PINS,
8791 .v.pins = (const struct hda_pintbl[]) {
Mikhail Paulyshkafc7438b2017-04-21 08:52:42 +02008792 { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
8793 { 0x1a, 0x90170151 }, /* bass speaker */
8794 { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07008795 {}
8796 },
8797 .chained = true,
Mikhail Paulyshkafc7438b2017-04-21 08:52:42 +02008798 .chain_id = ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE,
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07008799 },
Takashi Iwai5b7c5e12018-10-09 14:20:17 +02008800 [ALC668_FIXUP_MIC_COEF] = {
Takashi Iwai11ba6112018-10-07 09:44:17 +02008801 .type = HDA_FIXUP_VERBS,
8802 .v.verbs = (const struct hda_verb[]) {
8803 { 0x20, AC_VERB_SET_COEF_INDEX, 0xc3 },
8804 { 0x20, AC_VERB_SET_PROC_COEF, 0x4000 },
8805 {}
8806 },
8807 },
Takashi Iwai5b7c5e12018-10-09 14:20:17 +02008808 [ALC668_FIXUP_ASUS_G751] = {
8809 .type = HDA_FIXUP_PINS,
8810 .v.pins = (const struct hda_pintbl[]) {
8811 { 0x16, 0x0421101f }, /* HP */
8812 {}
8813 },
8814 .chained = true,
8815 .chain_id = ALC668_FIXUP_MIC_COEF
8816 },
Kailang Yang78f4f7c2016-06-07 11:31:34 +08008817 [ALC891_FIXUP_HEADSET_MODE] = {
8818 .type = HDA_FIXUP_FUNC,
8819 .v.func = alc_fixup_headset_mode,
8820 },
8821 [ALC891_FIXUP_DELL_MIC_NO_PRESENCE] = {
8822 .type = HDA_FIXUP_PINS,
8823 .v.pins = (const struct hda_pintbl[]) {
8824 { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
8825 { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */
8826 { }
8827 },
8828 .chained = true,
8829 .chain_id = ALC891_FIXUP_HEADSET_MODE
8830 },
Shrirang Bagul9b51fe32016-08-01 13:16:17 +08008831 [ALC662_FIXUP_ACER_VERITON] = {
8832 .type = HDA_FIXUP_PINS,
8833 .v.pins = (const struct hda_pintbl[]) {
8834 { 0x15, 0x50170120 }, /* no internal speaker */
8835 { }
8836 }
8837 },
Takashi Iwai1a3f0992016-10-20 12:14:51 +02008838 [ALC892_FIXUP_ASROCK_MOBO] = {
8839 .type = HDA_FIXUP_PINS,
8840 .v.pins = (const struct hda_pintbl[]) {
8841 { 0x15, 0x40f000f0 }, /* disabled */
8842 { 0x16, 0x40f000f0 }, /* disabled */
Takashi Iwai1a3f0992016-10-20 12:14:51 +02008843 { }
8844 }
8845 },
Kailang Yangc6790c82016-11-25 16:15:17 +08008846 [ALC662_FIXUP_USI_FUNC] = {
8847 .type = HDA_FIXUP_FUNC,
8848 .v.func = alc662_fixup_usi_headset_mic,
8849 },
8850 [ALC662_FIXUP_USI_HEADSET_MODE] = {
8851 .type = HDA_FIXUP_PINS,
8852 .v.pins = (const struct hda_pintbl[]) {
8853 { 0x19, 0x02a1913c }, /* use as headset mic, without its own jack detect */
8854 { 0x18, 0x01a1903d },
8855 { }
8856 },
8857 .chained = true,
8858 .chain_id = ALC662_FIXUP_USI_FUNC
8859 },
Kailang Yangca169cc2017-04-25 16:17:40 +08008860 [ALC662_FIXUP_LENOVO_MULTI_CODECS] = {
8861 .type = HDA_FIXUP_FUNC,
8862 .v.func = alc233_alc662_fixup_lenovo_dual_codecs,
8863 },
Sergey Bostandzhyan00066e92019-09-06 11:33:43 +02008864 [ALC669_FIXUP_ACER_ASPIRE_ETHOS_HEADSET] = {
8865 .type = HDA_FIXUP_FUNC,
8866 .v.func = alc662_fixup_aspire_ethos_hp,
8867 },
Sergey Bostandzhyan00066e92019-09-06 11:33:43 +02008868 [ALC669_FIXUP_ACER_ASPIRE_ETHOS] = {
8869 .type = HDA_FIXUP_PINS,
8870 .v.pins = (const struct hda_pintbl[]) {
8871 { 0x15, 0x92130110 }, /* front speakers */
8872 { 0x18, 0x99130111 }, /* center/subwoofer */
8873 { 0x1b, 0x11130012 }, /* surround plus jack for HP */
8874 { }
8875 },
8876 .chained = true,
Takashi Iwai336820c2019-11-28 21:26:30 +01008877 .chain_id = ALC669_FIXUP_ACER_ASPIRE_ETHOS_HEADSET
Sergey Bostandzhyan00066e92019-09-06 11:33:43 +02008878 },
David Henningsson6cb3b702010-09-09 08:51:44 +02008879};
8880
Takashi Iwaia9111322011-05-02 11:30:18 +02008881static const struct snd_pci_quirk alc662_fixup_tbl[] = {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008882 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_FIXUP_ASUS_MODE2),
Takashi Iwaid3d38352013-08-19 20:05:50 +02008883 SND_PCI_QUIRK(0x1025, 0x022f, "Acer Aspire One", ALC662_FIXUP_INV_DMIC),
David Henningsson02f6ff92015-12-07 11:29:31 +01008884 SND_PCI_QUIRK(0x1025, 0x0241, "Packard Bell DOTS", ALC662_FIXUP_INV_DMIC),
David Henningssona6c47a82011-02-10 15:39:19 +01008885 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
David Henningsson94024cd2011-04-29 14:10:55 +02008886 SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
Takashi Iwai125821a2012-06-22 14:30:29 +02008887 SND_PCI_QUIRK(0x1025, 0x0349, "eMachines eM250", ALC662_FIXUP_INV_DMIC),
Takashi Iwai18019282013-08-16 08:17:05 +02008888 SND_PCI_QUIRK(0x1025, 0x034a, "Gateway LT27", ALC662_FIXUP_INV_DMIC),
Daniel T Chen2df03512010-10-10 22:39:28 -04008889 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
David Henningsson73bdd592013-04-15 15:44:14 +02008890 SND_PCI_QUIRK(0x1028, 0x05d8, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
8891 SND_PCI_QUIRK(0x1028, 0x05db, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
Takashi Iwaic5d019c2014-07-22 17:33:32 +02008892 SND_PCI_QUIRK(0x1028, 0x05fe, "Dell XPS 15", ALC668_FIXUP_DELL_XPS13),
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02008893 SND_PCI_QUIRK(0x1028, 0x060a, "Dell XPS 13", ALC668_FIXUP_DELL_XPS13),
Niranjan Sivakumar467e1432015-09-05 18:20:35 +02008894 SND_PCI_QUIRK(0x1028, 0x060d, "Dell M3800", ALC668_FIXUP_DELL_XPS13),
David Henningsson09d20142013-11-20 11:43:30 +01008895 SND_PCI_QUIRK(0x1028, 0x0625, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
David Henningssonad8ff99e2013-11-07 09:28:59 +01008896 SND_PCI_QUIRK(0x1028, 0x0626, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
Kailang Yang8dc9abb2014-04-16 15:53:12 +08008897 SND_PCI_QUIRK(0x1028, 0x0696, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
8898 SND_PCI_QUIRK(0x1028, 0x0698, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
Kailang Yang6a98e342014-10-27 16:20:30 +08008899 SND_PCI_QUIRK(0x1028, 0x069f, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
Takashi Iwaie59ea3e2011-06-29 17:21:00 +02008900 SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800),
Kaho Ng2da2dc92016-05-09 00:27:49 +08008901 SND_PCI_QUIRK(0x1043, 0x1080, "Asus UX501VW", ALC668_FIXUP_HEADSET_MODE),
Bobi Mihalca83a9efb2016-03-23 13:32:33 +02008902 SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_ASUS_Nx50),
Takashi Iwaidb8948e2016-01-18 09:17:30 +01008903 SND_PCI_QUIRK(0x1043, 0x13df, "Asus N550JX", ALC662_FIXUP_BASS_1A),
Bobi Mihalca9d4dc582016-03-23 13:26:11 +02008904 SND_PCI_QUIRK(0x1043, 0x129d, "Asus N750", ALC662_FIXUP_ASUS_Nx50),
Takashi Iwai11ba6112018-10-07 09:44:17 +02008905 SND_PCI_QUIRK(0x1043, 0x12ff, "ASUS G751", ALC668_FIXUP_ASUS_G751),
David Henningsson8e54b4a2014-02-07 09:31:07 +01008906 SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
David Henningsson61a75f12014-02-07 09:31:08 +01008907 SND_PCI_QUIRK(0x1043, 0x15a7, "ASUS UX51VZH", ALC662_FIXUP_BASS_16),
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07008908 SND_PCI_QUIRK(0x1043, 0x177d, "ASUS N551", ALC668_FIXUP_ASUS_Nx51),
8909 SND_PCI_QUIRK(0x1043, 0x17bd, "ASUS N751", ALC668_FIXUP_ASUS_Nx51),
Takashi Iwaic7efff92017-01-04 21:38:16 +01008910 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71SL", ALC662_FIXUP_ASUS_MODE8),
David Henningsson61a75f12014-02-07 09:31:08 +01008911 SND_PCI_QUIRK(0x1043, 0x1b73, "ASUS N55SF", ALC662_FIXUP_BASS_16),
David Henningsson8e54b4a2014-02-07 09:31:07 +01008912 SND_PCI_QUIRK(0x1043, 0x1bf3, "ASUS N76VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
Takashi Iwai1565cc32012-02-13 12:03:25 +01008913 SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT),
Takashi Iwai53c334a2011-08-23 18:27:14 +02008914 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2),
Daniel T Chena0e90ac2010-11-20 10:20:35 -05008915 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
Kailang Yangc6790c82016-11-25 16:15:17 +08008916 SND_PCI_QUIRK(0x14cd, 0x5003, "USI", ALC662_FIXUP_USI_HEADSET_MODE),
Kailang Yangca169cc2017-04-25 16:17:40 +08008917 SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC662_FIXUP_LENOVO_MULTI_CODECS),
Valentine Sinitsynd4118582010-10-01 22:24:08 +06008918 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
David Henningsson6cb3b702010-09-09 08:51:44 +02008919 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
Takashi Iwai1a3f0992016-10-20 12:14:51 +02008920 SND_PCI_QUIRK(0x1849, 0x5892, "ASRock B150M", ALC892_FIXUP_ASROCK_MOBO),
David Henningssonedfe3bf2012-06-12 13:15:12 +02008921 SND_PCI_QUIRK(0x19da, 0xa130, "Zotac Z68", ALC662_FIXUP_ZOTAC_Z68),
Shrirang Bagul9b51fe32016-08-01 13:16:17 +08008922 SND_PCI_QUIRK(0x1b0a, 0x01b8, "ACER Veriton", ALC662_FIXUP_ACER_VERITON),
Anisse Astierd2ebd472011-01-20 12:36:21 +01008923 SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
Sergey Bostandzhyan00066e92019-09-06 11:33:43 +02008924 SND_PCI_QUIRK(0x1025, 0x0566, "Acer Aspire Ethos 8951G", ALC669_FIXUP_ACER_ASPIRE_ETHOS),
Takashi Iwai53c334a2011-08-23 18:27:14 +02008925
8926#if 0
8927 /* Below is a quirk table taken from the old code.
8928 * Basically the device should work as is without the fixup table.
8929 * If BIOS doesn't give a proper info, enable the corresponding
8930 * fixup entry.
Jesper Juhl7d7eb9e2012-04-12 22:11:25 +02008931 */
Takashi Iwai53c334a2011-08-23 18:27:14 +02008932 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC662_FIXUP_ASUS_MODE1),
8933 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC662_FIXUP_ASUS_MODE3),
8934 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC662_FIXUP_ASUS_MODE1),
8935 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC662_FIXUP_ASUS_MODE3),
8936 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
8937 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8938 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
8939 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC662_FIXUP_ASUS_MODE1),
8940 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC662_FIXUP_ASUS_MODE1),
8941 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8942 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC662_FIXUP_ASUS_MODE7),
8943 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC662_FIXUP_ASUS_MODE7),
8944 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC662_FIXUP_ASUS_MODE8),
8945 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC662_FIXUP_ASUS_MODE3),
8946 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC662_FIXUP_ASUS_MODE1),
8947 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8948 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_FIXUP_ASUS_MODE2),
8949 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC662_FIXUP_ASUS_MODE1),
8950 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8951 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
8952 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
8953 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8954 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC662_FIXUP_ASUS_MODE1),
8955 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC662_FIXUP_ASUS_MODE3),
8956 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_FIXUP_ASUS_MODE2),
8957 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8958 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC662_FIXUP_ASUS_MODE5),
8959 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
8960 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8961 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC662_FIXUP_ASUS_MODE1),
8962 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8963 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8964 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC662_FIXUP_ASUS_MODE3),
8965 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC662_FIXUP_ASUS_MODE3),
8966 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC662_FIXUP_ASUS_MODE1),
8967 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC662_FIXUP_ASUS_MODE1),
8968 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC662_FIXUP_ASUS_MODE1),
8969 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC662_FIXUP_ASUS_MODE1),
8970 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC662_FIXUP_ASUS_MODE1),
8971 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8972 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_FIXUP_ASUS_MODE2),
8973 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC662_FIXUP_ASUS_MODE1),
8974 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
8975 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC662_FIXUP_ASUS_MODE3),
8976 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC662_FIXUP_ASUS_MODE1),
8977 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC662_FIXUP_ASUS_MODE1),
8978 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC662_FIXUP_ASUS_MODE1),
8979 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_FIXUP_ASUS_MODE2),
8980 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
8981 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE4),
8982#endif
David Henningsson6cb3b702010-09-09 08:51:44 +02008983 {}
8984};
8985
Takashi Iwai1727a772013-01-10 09:52:52 +01008986static const struct hda_model_fixup alc662_fixup_models[] = {
Takashi Iwaiaa3841b2018-06-26 07:42:40 +02008987 {.id = ALC662_FIXUP_ASPIRE, .name = "aspire"},
8988 {.id = ALC662_FIXUP_IDEAPAD, .name = "ideapad"},
Todd Broch6be79482010-12-07 16:51:05 -08008989 {.id = ALC272_FIXUP_MARIO, .name = "mario"},
Takashi Iwaiaa3841b2018-06-26 07:42:40 +02008990 {.id = ALC662_FIXUP_HP_RP5800, .name = "hp-rp5800"},
Takashi Iwai53c334a2011-08-23 18:27:14 +02008991 {.id = ALC662_FIXUP_ASUS_MODE1, .name = "asus-mode1"},
8992 {.id = ALC662_FIXUP_ASUS_MODE2, .name = "asus-mode2"},
8993 {.id = ALC662_FIXUP_ASUS_MODE3, .name = "asus-mode3"},
8994 {.id = ALC662_FIXUP_ASUS_MODE4, .name = "asus-mode4"},
8995 {.id = ALC662_FIXUP_ASUS_MODE5, .name = "asus-mode5"},
8996 {.id = ALC662_FIXUP_ASUS_MODE6, .name = "asus-mode6"},
8997 {.id = ALC662_FIXUP_ASUS_MODE7, .name = "asus-mode7"},
8998 {.id = ALC662_FIXUP_ASUS_MODE8, .name = "asus-mode8"},
Takashi Iwaiaa3841b2018-06-26 07:42:40 +02008999 {.id = ALC662_FIXUP_ZOTAC_Z68, .name = "zotac-z68"},
Takashi Iwai6e72aa52012-06-25 10:52:25 +02009000 {.id = ALC662_FIXUP_INV_DMIC, .name = "inv-dmic"},
Takashi Iwaiaa3841b2018-06-26 07:42:40 +02009001 {.id = ALC662_FIXUP_DELL_MIC_NO_PRESENCE, .name = "alc662-headset-multi"},
David Henningssone32aa852013-06-17 11:04:02 +02009002 {.id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE, .name = "dell-headset-multi"},
Takashi Iwaiaa3841b2018-06-26 07:42:40 +02009003 {.id = ALC662_FIXUP_HEADSET_MODE, .name = "alc662-headset"},
9004 {.id = ALC668_FIXUP_HEADSET_MODE, .name = "alc668-headset"},
9005 {.id = ALC662_FIXUP_BASS_16, .name = "bass16"},
9006 {.id = ALC662_FIXUP_BASS_1A, .name = "bass1a"},
9007 {.id = ALC668_FIXUP_AUTO_MUTE, .name = "automute"},
9008 {.id = ALC668_FIXUP_DELL_XPS13, .name = "dell-xps13"},
9009 {.id = ALC662_FIXUP_ASUS_Nx50, .name = "asus-nx50"},
9010 {.id = ALC668_FIXUP_ASUS_Nx51, .name = "asus-nx51"},
Takashi Iwai40c51672018-10-07 09:47:39 +02009011 {.id = ALC668_FIXUP_ASUS_G751, .name = "asus-g751"},
Takashi Iwaiaa3841b2018-06-26 07:42:40 +02009012 {.id = ALC891_FIXUP_HEADSET_MODE, .name = "alc891-headset"},
9013 {.id = ALC891_FIXUP_DELL_MIC_NO_PRESENCE, .name = "alc891-headset-multi"},
9014 {.id = ALC662_FIXUP_ACER_VERITON, .name = "acer-veriton"},
9015 {.id = ALC892_FIXUP_ASROCK_MOBO, .name = "asrock-mobo"},
9016 {.id = ALC662_FIXUP_USI_HEADSET_MODE, .name = "usi-headset"},
Takashi Iwaiba90d6a2017-05-22 16:38:47 +02009017 {.id = ALC662_FIXUP_LENOVO_MULTI_CODECS, .name = "dual-codecs"},
Sergey Bostandzhyan00066e92019-09-06 11:33:43 +02009018 {.id = ALC669_FIXUP_ACER_ASPIRE_ETHOS, .name = "aspire-ethos"},
Todd Broch6be79482010-12-07 16:51:05 -08009019 {}
9020};
David Henningsson6cb3b702010-09-09 08:51:44 +02009021
Hui Wang532895c2014-05-29 15:59:19 +08009022static const struct snd_hda_pin_quirk alc662_pin_fixup_tbl[] = {
Kailang Yang78f4f7c2016-06-07 11:31:34 +08009023 SND_HDA_PIN_QUIRK(0x10ec0867, 0x1028, "Dell", ALC891_FIXUP_DELL_MIC_NO_PRESENCE,
9024 {0x17, 0x02211010},
9025 {0x18, 0x01a19030},
9026 {0x1a, 0x01813040},
9027 {0x21, 0x01014020}),
Hui Wang4b4e0e32019-07-16 15:21:34 +08009028 SND_HDA_PIN_QUIRK(0x10ec0867, 0x1028, "Dell", ALC891_FIXUP_DELL_MIC_NO_PRESENCE,
9029 {0x16, 0x01813030},
9030 {0x17, 0x02211010},
9031 {0x18, 0x01a19040},
9032 {0x21, 0x01014020}),
David Henningsson1f8b46c2015-05-12 14:38:15 +02009033 SND_HDA_PIN_QUIRK(0x10ec0662, 0x1028, "Dell", ALC662_FIXUP_DELL_MIC_NO_PRESENCE,
David Henningsson1f8b46c2015-05-12 14:38:15 +02009034 {0x14, 0x01014010},
David Henningsson1f8b46c2015-05-12 14:38:15 +02009035 {0x18, 0x01a19020},
David Henningsson1f8b46c2015-05-12 14:38:15 +02009036 {0x1a, 0x0181302f},
Hui Wang11580292015-08-03 11:03:49 +08009037 {0x1b, 0x0221401f}),
David Henningsson76c21322014-06-24 14:46:54 +02009038 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
9039 {0x12, 0x99a30130},
9040 {0x14, 0x90170110},
9041 {0x15, 0x0321101f},
Hui Wang11580292015-08-03 11:03:49 +08009042 {0x16, 0x03011020}),
David Henningsson76c21322014-06-24 14:46:54 +02009043 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
9044 {0x12, 0x99a30140},
9045 {0x14, 0x90170110},
9046 {0x15, 0x0321101f},
Hui Wang11580292015-08-03 11:03:49 +08009047 {0x16, 0x03011020}),
David Henningsson76c21322014-06-24 14:46:54 +02009048 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
9049 {0x12, 0x99a30150},
9050 {0x14, 0x90170110},
9051 {0x15, 0x0321101f},
Hui Wang11580292015-08-03 11:03:49 +08009052 {0x16, 0x03011020}),
David Henningsson76c21322014-06-24 14:46:54 +02009053 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
David Henningsson76c21322014-06-24 14:46:54 +02009054 {0x14, 0x90170110},
9055 {0x15, 0x0321101f},
Hui Wang11580292015-08-03 11:03:49 +08009056 {0x16, 0x03011020}),
David Henningsson76c21322014-06-24 14:46:54 +02009057 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell XPS 15", ALC668_FIXUP_AUTO_MUTE,
9058 {0x12, 0x90a60130},
9059 {0x14, 0x90170110},
Hui Wang11580292015-08-03 11:03:49 +08009060 {0x15, 0x0321101f}),
Hui Wang532895c2014-05-29 15:59:19 +08009061 {}
9062};
9063
Takashi Iwai1d045db2011-07-07 18:23:21 +02009064/*
9065 */
Kailang Yangbc9f98a2007-04-12 13:06:07 +02009066static int patch_alc662(struct hda_codec *codec)
9067{
9068 struct alc_spec *spec;
Takashi Iwai3de95172012-05-07 18:03:15 +02009069 int err;
Kailang Yangbc9f98a2007-04-12 13:06:07 +02009070
Takashi Iwai3de95172012-05-07 18:03:15 +02009071 err = alc_alloc_spec(codec, 0x0b);
9072 if (err < 0)
9073 return err;
Kailang Yangbc9f98a2007-04-12 13:06:07 +02009074
Takashi Iwai3de95172012-05-07 18:03:15 +02009075 spec = codec->spec;
Takashi Iwai1f0f4b82011-06-27 10:52:59 +02009076
Takashi Iwai225068a2015-05-29 10:42:14 +02009077 spec->shutup = alc_eapd_shutup;
9078
Takashi Iwai53c334a2011-08-23 18:27:14 +02009079 /* handle multiple HPs as is */
9080 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
9081
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +02009082 alc_fix_pll_init(codec, 0x20, 0x04, 15);
9083
Takashi Iwai7639a062015-03-03 10:07:24 +01009084 switch (codec->core.vendor_id) {
Kailang Yangf3f91852014-10-24 15:43:46 +08009085 case 0x10ec0668:
9086 spec->init_hook = alc668_restore_default_value;
9087 break;
Kailang Yangf3f91852014-10-24 15:43:46 +08009088 }
Kailang Yang8663ff72012-06-29 09:35:52 +02009089
Takashi Iwaic9af7532019-05-10 11:01:43 +02009090 alc_pre_init(codec);
9091
Takashi Iwai1727a772013-01-10 09:52:52 +01009092 snd_hda_pick_fixup(codec, alc662_fixup_models,
Takashi Iwai8e5a0502012-06-21 15:49:33 +02009093 alc662_fixup_tbl, alc662_fixups);
Hui Wang0fc1e442019-08-16 14:27:39 +08009094 snd_hda_pick_pin_fixup(codec, alc662_pin_fixup_tbl, alc662_fixups, true);
Takashi Iwai1727a772013-01-10 09:52:52 +01009095 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai8e5a0502012-06-21 15:49:33 +02009096
9097 alc_auto_parse_customize_define(codec);
9098
Takashi Iwai7504b6c2013-03-18 11:25:51 +01009099 if (has_cdefine_beep(codec))
9100 spec->gen.beep_nid = 0x01;
9101
Takashi Iwai1bb7e432011-10-17 16:50:59 +02009102 if ((alc_get_coef0(codec) & (1 << 14)) &&
Takashi Iwai5100cd02014-02-15 10:03:19 +01009103 codec->bus->pci && codec->bus->pci->subsystem_vendor == 0x1025 &&
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02009104 spec->cdefine.platform_type == 1) {
Wei Yongjun6134b1a2013-04-18 11:12:59 +08009105 err = alc_codec_rename(codec, "ALC272X");
9106 if (err < 0)
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02009107 goto error;
Takashi Iwai20ca0c32011-10-17 16:00:35 +02009108 }
Kailang Yang274693f2009-12-03 10:07:50 +01009109
Takashi Iwaib9c51062011-08-24 18:08:07 +02009110 /* automatic parse from the BIOS config */
9111 err = alc662_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02009112 if (err < 0)
9113 goto error;
Kailang Yangbc9f98a2007-04-12 13:06:07 +02009114
Takashi Iwai7504b6c2013-03-18 11:25:51 +01009115 if (!spec->gen.no_analog && spec->gen.beep_nid) {
Takashi Iwai7639a062015-03-03 10:07:24 +01009116 switch (codec->core.vendor_id) {
Kailang Yangda00c242010-03-19 11:23:45 +01009117 case 0x10ec0662:
Takashi Iwaifea80fa2018-06-20 12:52:46 +02009118 err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
Kailang Yangda00c242010-03-19 11:23:45 +01009119 break;
9120 case 0x10ec0272:
9121 case 0x10ec0663:
9122 case 0x10ec0665:
Kailang Yang9ad54542013-11-26 15:41:40 +08009123 case 0x10ec0668:
Takashi Iwaifea80fa2018-06-20 12:52:46 +02009124 err = set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
Kailang Yangda00c242010-03-19 11:23:45 +01009125 break;
9126 case 0x10ec0273:
Takashi Iwaifea80fa2018-06-20 12:52:46 +02009127 err = set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
Kailang Yangda00c242010-03-19 11:23:45 +01009128 break;
9129 }
Takashi Iwaifea80fa2018-06-20 12:52:46 +02009130 if (err < 0)
9131 goto error;
Kailang Yangcec27c82010-02-04 14:18:18 +01009132 }
Takashi Iwai2134ea42008-01-10 16:53:55 +01009133
Takashi Iwai1727a772013-01-10 09:52:52 +01009134 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01009135
Kailang Yangbc9f98a2007-04-12 13:06:07 +02009136 return 0;
Kailang Yangbc9f98a2007-04-12 13:06:07 +02009137
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02009138 error:
9139 alc_free(codec);
9140 return err;
Kailang Yangb478b992011-05-18 11:51:15 +02009141}
9142
Kailang Yangbc9f98a2007-04-12 13:06:07 +02009143/*
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009144 * ALC680 support
9145 */
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009146
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009147static int alc680_parse_auto_config(struct hda_codec *codec)
9148{
Takashi Iwai3e6179b2011-07-08 16:55:13 +02009149 return alc_parse_auto_config(codec, NULL, NULL);
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009150}
9151
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009152/*
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009153 */
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009154static int patch_alc680(struct hda_codec *codec)
9155{
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009156 int err;
9157
Takashi Iwai1f0f4b82011-06-27 10:52:59 +02009158 /* ALC680 has no aa-loopback mixer */
Takashi Iwai3de95172012-05-07 18:03:15 +02009159 err = alc_alloc_spec(codec, 0);
9160 if (err < 0)
9161 return err;
Takashi Iwai1f0f4b82011-06-27 10:52:59 +02009162
Takashi Iwai1ebec5f2011-08-15 13:21:48 +02009163 /* automatic parse from the BIOS config */
9164 err = alc680_parse_auto_config(codec);
9165 if (err < 0) {
9166 alc_free(codec);
9167 return err;
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009168 }
9169
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009170 return 0;
9171}
9172
9173/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07009174 * patch entries
9175 */
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009176static const struct hda_device_id snd_hda_id_realtek[] = {
Kailang Yang0a6f0602017-06-30 16:00:48 +08009177 HDA_CODEC_ENTRY(0x10ec0215, "ALC215", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009178 HDA_CODEC_ENTRY(0x10ec0221, "ALC221", patch_alc269),
Hui Wang2a36c162019-09-04 13:53:27 +08009179 HDA_CODEC_ENTRY(0x10ec0222, "ALC222", patch_alc269),
Kailang Yang42314302016-02-03 15:03:50 +08009180 HDA_CODEC_ENTRY(0x10ec0225, "ALC225", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009181 HDA_CODEC_ENTRY(0x10ec0231, "ALC231", patch_alc269),
9182 HDA_CODEC_ENTRY(0x10ec0233, "ALC233", patch_alc269),
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08009183 HDA_CODEC_ENTRY(0x10ec0234, "ALC234", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009184 HDA_CODEC_ENTRY(0x10ec0235, "ALC233", patch_alc269),
Kailang Yang736f20a2017-10-20 15:06:34 +08009185 HDA_CODEC_ENTRY(0x10ec0236, "ALC236", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009186 HDA_CODEC_ENTRY(0x10ec0255, "ALC255", patch_alc269),
9187 HDA_CODEC_ENTRY(0x10ec0256, "ALC256", patch_alc269),
Kailang Yangf429e7e2017-12-05 15:38:24 +08009188 HDA_CODEC_ENTRY(0x10ec0257, "ALC257", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009189 HDA_CODEC_ENTRY(0x10ec0260, "ALC260", patch_alc260),
9190 HDA_CODEC_ENTRY(0x10ec0262, "ALC262", patch_alc262),
9191 HDA_CODEC_ENTRY(0x10ec0267, "ALC267", patch_alc268),
9192 HDA_CODEC_ENTRY(0x10ec0268, "ALC268", patch_alc268),
9193 HDA_CODEC_ENTRY(0x10ec0269, "ALC269", patch_alc269),
9194 HDA_CODEC_ENTRY(0x10ec0270, "ALC270", patch_alc269),
9195 HDA_CODEC_ENTRY(0x10ec0272, "ALC272", patch_alc662),
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08009196 HDA_CODEC_ENTRY(0x10ec0274, "ALC274", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009197 HDA_CODEC_ENTRY(0x10ec0275, "ALC275", patch_alc269),
9198 HDA_CODEC_ENTRY(0x10ec0276, "ALC276", patch_alc269),
9199 HDA_CODEC_ENTRY(0x10ec0280, "ALC280", patch_alc269),
9200 HDA_CODEC_ENTRY(0x10ec0282, "ALC282", patch_alc269),
9201 HDA_CODEC_ENTRY(0x10ec0283, "ALC283", patch_alc269),
9202 HDA_CODEC_ENTRY(0x10ec0284, "ALC284", patch_alc269),
Kailang Yang0a6f0602017-06-30 16:00:48 +08009203 HDA_CODEC_ENTRY(0x10ec0285, "ALC285", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009204 HDA_CODEC_ENTRY(0x10ec0286, "ALC286", patch_alc269),
9205 HDA_CODEC_ENTRY(0x10ec0288, "ALC288", patch_alc269),
Kailang Yang0a6f0602017-06-30 16:00:48 +08009206 HDA_CODEC_ENTRY(0x10ec0289, "ALC289", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009207 HDA_CODEC_ENTRY(0x10ec0290, "ALC290", patch_alc269),
9208 HDA_CODEC_ENTRY(0x10ec0292, "ALC292", patch_alc269),
9209 HDA_CODEC_ENTRY(0x10ec0293, "ALC293", patch_alc269),
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08009210 HDA_CODEC_ENTRY(0x10ec0294, "ALC294", patch_alc269),
Kailang Yang7d727862016-05-24 16:46:07 +08009211 HDA_CODEC_ENTRY(0x10ec0295, "ALC295", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009212 HDA_CODEC_ENTRY(0x10ec0298, "ALC298", patch_alc269),
Kailang Yang28f1f9b2017-01-04 14:49:07 +08009213 HDA_CODEC_ENTRY(0x10ec0299, "ALC299", patch_alc269),
Kailang Yang1078bef2018-11-08 16:36:15 +08009214 HDA_CODEC_ENTRY(0x10ec0300, "ALC300", patch_alc269),
Kailang Yangf0778872019-10-24 15:13:32 +08009215 HDA_CODEC_ENTRY(0x10ec0623, "ALC623", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009216 HDA_CODEC_REV_ENTRY(0x10ec0861, 0x100340, "ALC660", patch_alc861),
9217 HDA_CODEC_ENTRY(0x10ec0660, "ALC660-VD", patch_alc861vd),
9218 HDA_CODEC_ENTRY(0x10ec0861, "ALC861", patch_alc861),
9219 HDA_CODEC_ENTRY(0x10ec0862, "ALC861-VD", patch_alc861vd),
9220 HDA_CODEC_REV_ENTRY(0x10ec0662, 0x100002, "ALC662 rev2", patch_alc882),
9221 HDA_CODEC_REV_ENTRY(0x10ec0662, 0x100101, "ALC662 rev1", patch_alc662),
9222 HDA_CODEC_REV_ENTRY(0x10ec0662, 0x100300, "ALC662 rev3", patch_alc662),
9223 HDA_CODEC_ENTRY(0x10ec0663, "ALC663", patch_alc662),
9224 HDA_CODEC_ENTRY(0x10ec0665, "ALC665", patch_alc662),
9225 HDA_CODEC_ENTRY(0x10ec0667, "ALC667", patch_alc662),
9226 HDA_CODEC_ENTRY(0x10ec0668, "ALC668", patch_alc662),
9227 HDA_CODEC_ENTRY(0x10ec0670, "ALC670", patch_alc662),
9228 HDA_CODEC_ENTRY(0x10ec0671, "ALC671", patch_alc662),
9229 HDA_CODEC_ENTRY(0x10ec0680, "ALC680", patch_alc680),
Kailang Yang6fbae352016-05-30 16:44:20 +08009230 HDA_CODEC_ENTRY(0x10ec0700, "ALC700", patch_alc269),
9231 HDA_CODEC_ENTRY(0x10ec0701, "ALC701", patch_alc269),
9232 HDA_CODEC_ENTRY(0x10ec0703, "ALC703", patch_alc269),
Kailang Yang83629532019-05-02 16:03:26 +08009233 HDA_CODEC_ENTRY(0x10ec0711, "ALC711", patch_alc269),
Kailang Yang78f4f7c2016-06-07 11:31:34 +08009234 HDA_CODEC_ENTRY(0x10ec0867, "ALC891", patch_alc662),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009235 HDA_CODEC_ENTRY(0x10ec0880, "ALC880", patch_alc880),
9236 HDA_CODEC_ENTRY(0x10ec0882, "ALC882", patch_alc882),
9237 HDA_CODEC_ENTRY(0x10ec0883, "ALC883", patch_alc882),
9238 HDA_CODEC_REV_ENTRY(0x10ec0885, 0x100101, "ALC889A", patch_alc882),
9239 HDA_CODEC_REV_ENTRY(0x10ec0885, 0x100103, "ALC889A", patch_alc882),
9240 HDA_CODEC_ENTRY(0x10ec0885, "ALC885", patch_alc882),
9241 HDA_CODEC_ENTRY(0x10ec0887, "ALC887", patch_alc882),
9242 HDA_CODEC_REV_ENTRY(0x10ec0888, 0x100101, "ALC1200", patch_alc882),
9243 HDA_CODEC_ENTRY(0x10ec0888, "ALC888", patch_alc882),
9244 HDA_CODEC_ENTRY(0x10ec0889, "ALC889", patch_alc882),
9245 HDA_CODEC_ENTRY(0x10ec0892, "ALC892", patch_alc662),
9246 HDA_CODEC_ENTRY(0x10ec0899, "ALC898", patch_alc882),
9247 HDA_CODEC_ENTRY(0x10ec0900, "ALC1150", patch_alc882),
Kailang Yang65553b12017-07-11 15:15:47 +08009248 HDA_CODEC_ENTRY(0x10ec1168, "ALC1220", patch_alc882),
Kailang Yanga535ad52017-01-16 16:59:26 +08009249 HDA_CODEC_ENTRY(0x10ec1220, "ALC1220", patch_alc882),
Linus Torvalds1da177e2005-04-16 15:20:36 -07009250 {} /* terminator */
9251};
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009252MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_realtek);
Takashi Iwai1289e9e2008-11-27 15:47:11 +01009253
9254MODULE_LICENSE("GPL");
9255MODULE_DESCRIPTION("Realtek HD-audio codec");
9256
Takashi Iwaid8a766a2015-02-17 15:25:37 +01009257static struct hda_codec_driver realtek_driver = {
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009258 .id = snd_hda_id_realtek,
Takashi Iwai1289e9e2008-11-27 15:47:11 +01009259};
9260
Takashi Iwaid8a766a2015-02-17 15:25:37 +01009261module_hda_codec_driver(realtek_driver);