blob: c1ddfd2fac522c8c5f663495ad3ad750f77b8120 [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 Yang736f20a2017-10-20 15:06:34 +0800370 case 0x10ec0236:
Kailang Yang394c97f2014-11-12 17:38:08 +0800371 case 0x10ec0255:
Kailang Yang4344aec2014-12-17 17:39:05 +0800372 case 0x10ec0256:
Kailang Yangf429e7e2017-12-05 15:38:24 +0800373 case 0x10ec0257:
Kailang Yang394c97f2014-11-12 17:38:08 +0800374 case 0x10ec0282:
375 case 0x10ec0283:
376 case 0x10ec0286:
377 case 0x10ec0288:
Kailang Yang0a6f0602017-06-30 16:00:48 +0800378 case 0x10ec0285:
Kailang Yang506b62c2014-12-18 17:07:44 +0800379 case 0x10ec0298:
Kailang Yang0a6f0602017-06-30 16:00:48 +0800380 case 0x10ec0289:
Kailang Yang1078bef2018-11-08 16:36:15 +0800381 case 0x10ec0300:
Kailang Yang394c97f2014-11-12 17:38:08 +0800382 alc_update_coef_idx(codec, 0x10, 1<<9, 0);
383 break;
Kailang Yang3aabf942017-11-08 15:28:33 +0800384 case 0x10ec0275:
385 alc_update_coef_idx(codec, 0xe, 0, 1<<0);
386 break;
Kailang Yang394c97f2014-11-12 17:38:08 +0800387 case 0x10ec0293:
388 alc_update_coef_idx(codec, 0xa, 1<<13, 0);
389 break;
Kailang Yangdcd4f0d2016-05-04 15:50:18 +0800390 case 0x10ec0234:
391 case 0x10ec0274:
392 case 0x10ec0294:
Kailang Yang6fbae352016-05-30 16:44:20 +0800393 case 0x10ec0700:
394 case 0x10ec0701:
395 case 0x10ec0703:
Kailang Yangdcd4f0d2016-05-04 15:50:18 +0800396 alc_update_coef_idx(codec, 0x10, 1<<15, 0);
397 break;
Kailang Yang394c97f2014-11-12 17:38:08 +0800398 case 0x10ec0662:
399 if ((coef & 0x00f0) == 0x0030)
400 alc_update_coef_idx(codec, 0x4, 1<<10, 0); /* EAPD Ctrl */
401 break;
402 case 0x10ec0272:
403 case 0x10ec0273:
404 case 0x10ec0663:
405 case 0x10ec0665:
406 case 0x10ec0670:
407 case 0x10ec0671:
408 case 0x10ec0672:
409 alc_update_coef_idx(codec, 0xd, 0, 1<<14); /* EAPD Ctrl */
410 break;
411 case 0x10ec0668:
412 alc_update_coef_idx(codec, 0x7, 3<<13, 0);
413 break;
414 case 0x10ec0867:
415 alc_update_coef_idx(codec, 0x4, 1<<10, 0);
416 break;
417 case 0x10ec0888:
418 if ((coef & 0x00f0) == 0x0020 || (coef & 0x00f0) == 0x0030)
419 alc_update_coef_idx(codec, 0x7, 1<<5, 0);
420 break;
421 case 0x10ec0892:
422 alc_update_coef_idx(codec, 0x7, 1<<5, 0);
423 break;
424 case 0x10ec0899:
425 case 0x10ec0900:
Kailang Yang65553b12017-07-11 15:15:47 +0800426 case 0x10ec1168:
Kailang Yanga535ad52017-01-16 16:59:26 +0800427 case 0x10ec1220:
Kailang Yang394c97f2014-11-12 17:38:08 +0800428 alc_update_coef_idx(codec, 0x7, 1<<1, 0);
429 break;
430 }
431}
432
Kailang Yangf9423e72008-05-27 12:32:25 +0200433/* additional initialization for ALC888 variants */
434static void alc888_coef_init(struct hda_codec *codec)
435{
Kailang Yang1df88742014-10-29 16:10:13 +0800436 switch (alc_get_coef0(codec) & 0x00f0) {
437 /* alc888-VA */
438 case 0x00:
439 /* alc888-VB */
440 case 0x10:
441 alc_update_coef_idx(codec, 7, 0, 0x2030); /* Turn EAPD to High */
442 break;
443 }
Jaroslav Kysela87a8c372009-07-23 10:58:29 +0200444}
445
Takashi Iwai3fb4a502010-01-19 15:46:37 +0100446/* turn on/off EAPD control (only if available) */
447static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
448{
449 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
450 return;
451 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
452 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
453 on ? 2 : 0);
454}
455
Takashi Iwai691f1fc2011-04-07 10:31:43 +0200456/* turn on/off EAPD controls of the codec */
457static void alc_auto_setup_eapd(struct hda_codec *codec, bool on)
458{
459 /* We currently only handle front, HP */
Takashi Iwai39fa84e2011-06-27 15:28:57 +0200460 static hda_nid_t pins[] = {
Hui Wangaf95b412015-03-26 17:14:55 +0800461 0x0f, 0x10, 0x14, 0x15, 0x17, 0
Takashi Iwai39fa84e2011-06-27 15:28:57 +0200462 };
463 hda_nid_t *p;
464 for (p = pins; *p; p++)
465 set_eapd(codec, *p, on);
Takashi Iwai691f1fc2011-04-07 10:31:43 +0200466}
467
Kailang Yangdad31972019-05-10 16:28:57 +0800468static int find_ext_mic_pin(struct hda_codec *codec);
469
470static void alc_headset_mic_no_shutup(struct hda_codec *codec)
471{
472 const struct hda_pincfg *pin;
473 int mic_pin = find_ext_mic_pin(codec);
474 int i;
475
476 /* don't shut up pins when unloading the driver; otherwise it breaks
477 * the default pin setup at the next load of the driver
478 */
479 if (codec->bus->shutdown)
480 return;
481
482 snd_array_for_each(&codec->init_pins, i, pin) {
483 /* use read here for syncing after issuing each verb */
484 if (pin->nid != mic_pin)
485 snd_hda_codec_read(codec, pin->nid, 0,
486 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
487 }
488
489 codec->pins_shutup = 1;
490}
491
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +0100492static void alc_shutup_pins(struct hda_codec *codec)
493{
494 struct alc_spec *spec = codec->spec;
495
Kailang Yangdad31972019-05-10 16:28:57 +0800496 switch (codec->core.vendor_id) {
497 case 0x10ec0286:
498 case 0x10ec0288:
499 case 0x10ec0298:
500 alc_headset_mic_no_shutup(codec);
501 break;
502 default:
503 if (!spec->no_shutup_pins)
504 snd_hda_shutup_pins(codec);
505 break;
506 }
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +0100507}
508
Takashi Iwai1c7161532011-04-07 10:37:16 +0200509/* generic shutup callback;
Lars-Peter Clausen4ce8e6a2016-11-08 15:48:06 +0100510 * just turning off EAPD and a little pause for avoiding pop-noise
Takashi Iwai1c7161532011-04-07 10:37:16 +0200511 */
512static void alc_eapd_shutup(struct hda_codec *codec)
513{
Kailang Yang97a26572013-11-29 00:35:26 -0500514 struct alc_spec *spec = codec->spec;
515
Takashi Iwai1c7161532011-04-07 10:37:16 +0200516 alc_auto_setup_eapd(codec, false);
Kailang Yang97a26572013-11-29 00:35:26 -0500517 if (!spec->no_depop_delay)
518 msleep(200);
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +0100519 alc_shutup_pins(codec);
Takashi Iwai1c7161532011-04-07 10:37:16 +0200520}
521
Takashi Iwai1d045db2011-07-07 18:23:21 +0200522/* generic EAPD initialization */
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200523static void alc_auto_init_amp(struct hda_codec *codec, int type)
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200524{
Takashi Iwai39fa84e2011-06-27 15:28:57 +0200525 alc_auto_setup_eapd(codec, true);
Takashi Iwai5579cd62018-06-19 22:22:41 +0200526 alc_write_gpio(codec);
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200527 switch (type) {
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200528 case ALC_INIT_DEFAULT:
Takashi Iwai7639a062015-03-03 10:07:24 +0100529 switch (codec->core.vendor_id) {
Kailang Yangc9b58002007-10-16 14:30:01 +0200530 case 0x10ec0260:
Takashi Iwai98b24882014-08-18 13:47:50 +0200531 alc_update_coefex_idx(codec, 0x1a, 7, 0, 0x2010);
Kailang Yangc9b58002007-10-16 14:30:01 +0200532 break;
Kailang Yangc9b58002007-10-16 14:30:01 +0200533 case 0x10ec0880:
534 case 0x10ec0882:
535 case 0x10ec0883:
536 case 0x10ec0885:
Kailang Yang1df88742014-10-29 16:10:13 +0800537 alc_update_coef_idx(codec, 7, 0, 0x2030);
Kailang Yangc9b58002007-10-16 14:30:01 +0200538 break;
Kailang Yangf9423e72008-05-27 12:32:25 +0200539 case 0x10ec0888:
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200540 alc888_coef_init(codec);
Kailang Yangf9423e72008-05-27 12:32:25 +0200541 break;
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200542 }
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200543 break;
544 }
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200545}
Kailang Yangea1fb292008-08-26 12:58:38 +0200546
Takashi Iwai35a39f92019-02-01 11:19:50 +0100547/* get a primary headphone pin if available */
548static hda_nid_t alc_get_hp_pin(struct alc_spec *spec)
549{
550 if (spec->gen.autocfg.hp_pins[0])
551 return spec->gen.autocfg.hp_pins[0];
552 if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
553 return spec->gen.autocfg.line_out_pins[0];
554 return 0;
555}
Takashi Iwai1d045db2011-07-07 18:23:21 +0200556
557/*
558 * Realtek SSID verification
559 */
560
David Henningsson90622912010-10-14 14:50:18 +0200561/* Could be any non-zero and even value. When used as fixup, tells
562 * the driver to ignore any present sku defines.
563 */
564#define ALC_FIXUP_SKU_IGNORE (2)
565
Takashi Iwai23d30f22012-05-07 17:17:32 +0200566static void alc_fixup_sku_ignore(struct hda_codec *codec,
567 const struct hda_fixup *fix, int action)
568{
569 struct alc_spec *spec = codec->spec;
570 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
571 spec->cdefine.fixup = 1;
572 spec->cdefine.sku_cfg = ALC_FIXUP_SKU_IGNORE;
573 }
574}
575
Mengdong Linb5c66112013-11-29 00:35:35 -0500576static void alc_fixup_no_depop_delay(struct hda_codec *codec,
577 const struct hda_fixup *fix, int action)
578{
579 struct alc_spec *spec = codec->spec;
580
Mengdong Lin84d2dc32013-12-02 22:26:03 -0500581 if (action == HDA_FIXUP_ACT_PROBE) {
Mengdong Linb5c66112013-11-29 00:35:35 -0500582 spec->no_depop_delay = 1;
Mengdong Lin84d2dc32013-12-02 22:26:03 -0500583 codec->depop_delay = 0;
584 }
Mengdong Linb5c66112013-11-29 00:35:35 -0500585}
586
Kailang Yangda00c242010-03-19 11:23:45 +0100587static int alc_auto_parse_customize_define(struct hda_codec *codec)
588{
589 unsigned int ass, tmp, i;
Takashi Iwai7fb56222010-03-22 17:09:47 +0100590 unsigned nid = 0;
Kailang Yangda00c242010-03-19 11:23:45 +0100591 struct alc_spec *spec = codec->spec;
592
Takashi Iwaib6cbe512010-07-28 17:43:36 +0200593 spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
594
David Henningsson90622912010-10-14 14:50:18 +0200595 if (spec->cdefine.fixup) {
596 ass = spec->cdefine.sku_cfg;
597 if (ass == ALC_FIXUP_SKU_IGNORE)
598 return -1;
599 goto do_sku;
600 }
601
Takashi Iwai5100cd02014-02-15 10:03:19 +0100602 if (!codec->bus->pci)
603 return -1;
Takashi Iwai7639a062015-03-03 10:07:24 +0100604 ass = codec->core.subsystem_id & 0xffff;
Takashi Iwaib6cbe512010-07-28 17:43:36 +0200605 if (ass != codec->bus->pci->subsystem_device && (ass & 1))
Kailang Yangda00c242010-03-19 11:23:45 +0100606 goto do_sku;
607
608 nid = 0x1d;
Takashi Iwai7639a062015-03-03 10:07:24 +0100609 if (codec->core.vendor_id == 0x10ec0260)
Kailang Yangda00c242010-03-19 11:23:45 +0100610 nid = 0x17;
611 ass = snd_hda_codec_get_pincfg(codec, nid);
612
613 if (!(ass & 1)) {
Takashi Iwai4e76a882014-02-25 12:21:03 +0100614 codec_info(codec, "%s: SKU not ready 0x%08x\n",
Takashi Iwai7639a062015-03-03 10:07:24 +0100615 codec->core.chip_name, ass);
Kailang Yangda00c242010-03-19 11:23:45 +0100616 return -1;
617 }
618
619 /* check sum */
620 tmp = 0;
621 for (i = 1; i < 16; i++) {
622 if ((ass >> i) & 1)
623 tmp++;
624 }
625 if (((ass >> 16) & 0xf) != tmp)
626 return -1;
627
628 spec->cdefine.port_connectivity = ass >> 30;
629 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
630 spec->cdefine.check_sum = (ass >> 16) & 0xf;
631 spec->cdefine.customization = ass >> 8;
632do_sku:
633 spec->cdefine.sku_cfg = ass;
634 spec->cdefine.external_amp = (ass & 0x38) >> 3;
635 spec->cdefine.platform_type = (ass & 0x4) >> 2;
636 spec->cdefine.swap = (ass & 0x2) >> 1;
637 spec->cdefine.override = ass & 0x1;
638
Takashi Iwai4e76a882014-02-25 12:21:03 +0100639 codec_dbg(codec, "SKU: Nid=0x%x sku_cfg=0x%08x\n",
Kailang Yangda00c242010-03-19 11:23:45 +0100640 nid, spec->cdefine.sku_cfg);
Takashi Iwai4e76a882014-02-25 12:21:03 +0100641 codec_dbg(codec, "SKU: port_connectivity=0x%x\n",
Kailang Yangda00c242010-03-19 11:23:45 +0100642 spec->cdefine.port_connectivity);
Takashi Iwai4e76a882014-02-25 12:21:03 +0100643 codec_dbg(codec, "SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
644 codec_dbg(codec, "SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
645 codec_dbg(codec, "SKU: customization=0x%08x\n", spec->cdefine.customization);
646 codec_dbg(codec, "SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
647 codec_dbg(codec, "SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
648 codec_dbg(codec, "SKU: swap=0x%x\n", spec->cdefine.swap);
649 codec_dbg(codec, "SKU: override=0x%x\n", spec->cdefine.override);
Kailang Yangda00c242010-03-19 11:23:45 +0100650
651 return 0;
652}
653
Takashi Iwai08c189f2012-12-19 15:22:24 +0100654/* return the position of NID in the list, or -1 if not found */
655static int find_idx_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
656{
657 int i;
658 for (i = 0; i < nums; i++)
659 if (list[i] == nid)
660 return i;
661 return -1;
662}
Takashi Iwai1d045db2011-07-07 18:23:21 +0200663/* return true if the given NID is found in the list */
Takashi Iwai3af9ee62011-06-27 12:34:01 +0200664static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
665{
Takashi Iwai21268962011-07-07 15:01:13 +0200666 return find_idx_in_nid_list(nid, list, nums) >= 0;
Takashi Iwai3af9ee62011-06-27 12:34:01 +0200667}
668
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200669/* check subsystem ID and set up device-specific initialization;
670 * return 1 if initialized, 0 if invalid SSID
671 */
672/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
673 * 31 ~ 16 : Manufacture ID
674 * 15 ~ 8 : SKU ID
675 * 7 ~ 0 : Assembly ID
676 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
677 */
Takashi Iwai58c57cf2014-01-07 18:22:49 +0100678static int alc_subsystem_id(struct hda_codec *codec, const hda_nid_t *ports)
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200679{
680 unsigned int ass, tmp, i;
681 unsigned nid;
682 struct alc_spec *spec = codec->spec;
683
David Henningsson90622912010-10-14 14:50:18 +0200684 if (spec->cdefine.fixup) {
685 ass = spec->cdefine.sku_cfg;
686 if (ass == ALC_FIXUP_SKU_IGNORE)
687 return 0;
688 goto do_sku;
689 }
690
Takashi Iwai7639a062015-03-03 10:07:24 +0100691 ass = codec->core.subsystem_id & 0xffff;
Takashi Iwai5100cd02014-02-15 10:03:19 +0100692 if (codec->bus->pci &&
693 ass != codec->bus->pci->subsystem_device && (ass & 1))
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200694 goto do_sku;
695
696 /* invalid SSID, check the special NID pin defcfg instead */
697 /*
Sasha Alexandrdef319f2009-06-16 16:00:15 -0400698 * 31~30 : port connectivity
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200699 * 29~21 : reserve
700 * 20 : PCBEEP input
701 * 19~16 : Check sum (15:1)
702 * 15~1 : Custom
703 * 0 : override
704 */
705 nid = 0x1d;
Takashi Iwai7639a062015-03-03 10:07:24 +0100706 if (codec->core.vendor_id == 0x10ec0260)
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200707 nid = 0x17;
708 ass = snd_hda_codec_get_pincfg(codec, nid);
Takashi Iwai4e76a882014-02-25 12:21:03 +0100709 codec_dbg(codec,
710 "realtek: No valid SSID, checking pincfg 0x%08x for NID 0x%x\n",
Takashi Iwaicb6605c2009-04-28 13:03:19 +0200711 ass, nid);
Kailang Yang6227cdc2010-02-25 08:36:52 +0100712 if (!(ass & 1))
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200713 return 0;
714 if ((ass >> 30) != 1) /* no physical connection */
715 return 0;
716
717 /* check sum */
718 tmp = 0;
719 for (i = 1; i < 16; i++) {
720 if ((ass >> i) & 1)
721 tmp++;
722 }
723 if (((ass >> 16) & 0xf) != tmp)
724 return 0;
725do_sku:
Takashi Iwai4e76a882014-02-25 12:21:03 +0100726 codec_dbg(codec, "realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
Takashi Iwai7639a062015-03-03 10:07:24 +0100727 ass & 0xffff, codec->core.vendor_id);
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200728 /*
729 * 0 : override
730 * 1 : Swap Jack
731 * 2 : 0 --> Desktop, 1 --> Laptop
732 * 3~5 : External Amplifier control
733 * 7~6 : Reserved
734 */
735 tmp = (ass & 0x38) >> 3; /* external Amp control */
Takashi Iwai1c76aa52018-06-21 16:37:54 +0200736 if (spec->init_amp == ALC_INIT_UNDEFINED) {
737 switch (tmp) {
738 case 1:
Takashi Iwai5579cd62018-06-19 22:22:41 +0200739 alc_setup_gpio(codec, 0x01);
Takashi Iwai1c76aa52018-06-21 16:37:54 +0200740 break;
741 case 3:
Takashi Iwai5579cd62018-06-19 22:22:41 +0200742 alc_setup_gpio(codec, 0x02);
Takashi Iwai1c76aa52018-06-21 16:37:54 +0200743 break;
744 case 7:
Takashi Iwai5579cd62018-06-19 22:22:41 +0200745 alc_setup_gpio(codec, 0x03);
Takashi Iwai1c76aa52018-06-21 16:37:54 +0200746 break;
747 case 5:
748 default:
749 spec->init_amp = ALC_INIT_DEFAULT;
750 break;
751 }
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200752 }
753
754 /* is laptop or Desktop and enable the function "Mute internal speaker
755 * when the external headphone out jack is plugged"
756 */
757 if (!(ass & 0x8000))
758 return 1;
759 /*
760 * 10~8 : Jack location
761 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
762 * 14~13: Resvered
763 * 15 : 1 --> enable the function "Mute internal speaker
764 * when the external headphone out jack is plugged"
765 */
Takashi Iwai35a39f92019-02-01 11:19:50 +0100766 if (!alc_get_hp_pin(spec)) {
Takashi Iwai01d48252009-10-06 13:21:54 +0200767 hda_nid_t nid;
Kailang Yangc9b58002007-10-16 14:30:01 +0200768 tmp = (ass >> 11) & 0x3; /* HP to chassis */
Takashi Iwai58c57cf2014-01-07 18:22:49 +0100769 nid = ports[tmp];
Takashi Iwai08c189f2012-12-19 15:22:24 +0100770 if (found_in_nid_list(nid, spec->gen.autocfg.line_out_pins,
771 spec->gen.autocfg.line_outs))
Takashi Iwai3af9ee62011-06-27 12:34:01 +0200772 return 1;
Takashi Iwai08c189f2012-12-19 15:22:24 +0100773 spec->gen.autocfg.hp_pins[0] = nid;
Kailang Yangc9b58002007-10-16 14:30:01 +0200774 }
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200775 return 1;
776}
Kailang Yangea1fb292008-08-26 12:58:38 +0200777
Takashi Iwai3e6179b2011-07-08 16:55:13 +0200778/* Check the validity of ALC subsystem-id
779 * ports contains an array of 4 pin NIDs for port-A, E, D and I */
780static void alc_ssid_check(struct hda_codec *codec, const hda_nid_t *ports)
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200781{
Takashi Iwai58c57cf2014-01-07 18:22:49 +0100782 if (!alc_subsystem_id(codec, ports)) {
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200783 struct alc_spec *spec = codec->spec;
Takashi Iwai4e76a882014-02-25 12:21:03 +0100784 codec_dbg(codec,
785 "realtek: Enable default setup for auto mode as fallback\n");
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200786 spec->init_amp = ALC_INIT_DEFAULT;
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200787 }
Takashi Iwai21268962011-07-07 15:01:13 +0200788}
Takashi Iwai1a1455d2011-04-28 17:36:18 +0200789
Takashi Iwai41e41f12005-06-08 14:48:49 +0200790/*
Takashi Iwai1d045db2011-07-07 18:23:21 +0200791 */
792
David Henningsson9d36a7d2014-10-07 10:18:42 +0200793static void alc_fixup_inv_dmic(struct hda_codec *codec,
794 const struct hda_fixup *fix, int action)
Takashi Iwai125821a2012-06-22 14:30:29 +0200795{
796 struct alc_spec *spec = codec->spec;
Takashi Iwai668d1e92012-11-29 14:10:17 +0100797
David Henningsson9d36a7d2014-10-07 10:18:42 +0200798 spec->gen.inv_dmic_split = 1;
Takashi Iwai6e72aa52012-06-25 10:52:25 +0200799}
800
Takashi Iwai603c4012008-07-30 15:01:44 +0200801
Takashi Iwai2eab6942012-12-18 15:30:41 +0100802static int alc_build_controls(struct hda_codec *codec)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700803{
Takashi Iwaia5cb4632018-06-20 12:50:11 +0200804 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700805
Takashi Iwai08c189f2012-12-19 15:22:24 +0100806 err = snd_hda_gen_build_controls(codec);
807 if (err < 0)
808 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700809
Takashi Iwai1727a772013-01-10 09:52:52 +0100810 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_BUILD);
Takashi Iwai420b0fe2012-03-12 12:35:27 +0100811 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700812}
813
Takashi Iwaie9edcee2005-06-13 14:16:38 +0200814
Linus Torvalds1da177e2005-04-16 15:20:36 -0700815/*
Takashi Iwaiae6b8132006-03-03 16:47:17 +0100816 * Common callbacks
Takashi Iwaie9edcee2005-06-13 14:16:38 +0200817 */
Takashi Iwai16ded522005-06-10 19:58:24 +0200818
Takashi Iwaic9af7532019-05-10 11:01:43 +0200819static void alc_pre_init(struct hda_codec *codec)
820{
821 alc_fill_eapd_coef(codec);
822}
823
Kailang Yangaeac1a02019-05-16 16:10:44 +0800824#define is_s3_resume(codec) \
825 ((codec)->core.dev.power.power_state.event == PM_EVENT_RESUME)
Takashi Iwaic9af7532019-05-10 11:01:43 +0200826#define is_s4_resume(codec) \
827 ((codec)->core.dev.power.power_state.event == PM_EVENT_RESTORE)
828
Linus Torvalds1da177e2005-04-16 15:20:36 -0700829static int alc_init(struct hda_codec *codec)
830{
831 struct alc_spec *spec = codec->spec;
Takashi Iwaie9edcee2005-06-13 14:16:38 +0200832
Takashi Iwaic9af7532019-05-10 11:01:43 +0200833 /* hibernation resume needs the full chip initialization */
834 if (is_s4_resume(codec))
835 alc_pre_init(codec);
836
Takashi Iwai546bb672012-03-07 08:37:19 +0100837 if (spec->init_hook)
838 spec->init_hook(codec);
Kailang Yang526af6e2012-03-07 08:25:20 +0100839
Takashi Iwai89781d02019-08-30 12:03:38 +0200840 spec->gen.skip_verbs = 1; /* applied in below */
Kailang Yang607ca3b2019-04-26 16:35:41 +0800841 snd_hda_gen_init(codec);
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200842 alc_fix_pll(codec);
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200843 alc_auto_init_amp(codec, spec->init_amp);
Takashi Iwai89781d02019-08-30 12:03:38 +0200844 snd_hda_apply_verbs(codec); /* apply verbs here after own init */
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200845
Takashi Iwai1727a772013-01-10 09:52:52 +0100846 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_INIT);
Takashi Iwaie08a0072006-09-07 17:52:14 +0200847
Linus Torvalds1da177e2005-04-16 15:20:36 -0700848 return 0;
849}
850
Takashi Iwaia4e09aa2009-12-27 11:22:24 +0100851static inline void alc_shutup(struct hda_codec *codec)
852{
Takashi Iwai1c7161532011-04-07 10:37:16 +0200853 struct alc_spec *spec = codec->spec;
854
Takashi Iwaic7273bd2018-06-12 16:09:57 +0200855 if (!snd_hda_get_bool_hint(codec, "shutup"))
856 return; /* disabled explicitly by hints */
857
Takashi Iwai1c7161532011-04-07 10:37:16 +0200858 if (spec && spec->shutup)
859 spec->shutup(codec);
Takashi Iwai9bfb2842013-07-24 14:31:50 +0200860 else
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +0100861 alc_shutup_pins(codec);
Takashi Iwaia4e09aa2009-12-27 11:22:24 +0100862}
863
Takashi Iwai70a09762015-12-15 14:59:58 +0100864static void alc_reboot_notify(struct hda_codec *codec)
865{
866 struct alc_spec *spec = codec->spec;
867
868 if (spec && spec->reboot_notify)
869 spec->reboot_notify(codec);
870 else
871 alc_shutup(codec);
872}
873
Takashi Iwai8a02c0c2014-02-10 18:09:45 +0100874#define alc_free snd_hda_gen_free
Linus Torvalds1da177e2005-04-16 15:20:36 -0700875
Takashi Iwai83012a72012-08-24 18:38:08 +0200876#ifdef CONFIG_PM
Daniel T Chenc97259d2009-12-27 18:52:08 -0500877static void alc_power_eapd(struct hda_codec *codec)
878{
Takashi Iwai691f1fc2011-04-07 10:31:43 +0200879 alc_auto_setup_eapd(codec, false);
Daniel T Chenc97259d2009-12-27 18:52:08 -0500880}
881
Takashi Iwai68cb2b52012-07-02 15:20:37 +0200882static int alc_suspend(struct hda_codec *codec)
Hector Martinf5de24b2009-12-20 22:51:31 +0100883{
884 struct alc_spec *spec = codec->spec;
Takashi Iwaia4e09aa2009-12-27 11:22:24 +0100885 alc_shutup(codec);
Hector Martinf5de24b2009-12-20 22:51:31 +0100886 if (spec && spec->power_hook)
Daniel T Chenc97259d2009-12-27 18:52:08 -0500887 spec->power_hook(codec);
Hector Martinf5de24b2009-12-20 22:51:31 +0100888 return 0;
889}
890#endif
891
Takashi Iwai2a439522011-07-26 09:52:50 +0200892#ifdef CONFIG_PM
Takashi Iwaie044c392008-10-27 16:56:24 +0100893static int alc_resume(struct hda_codec *codec)
894{
Kailang Yang97a26572013-11-29 00:35:26 -0500895 struct alc_spec *spec = codec->spec;
896
897 if (!spec->no_depop_delay)
898 msleep(150); /* to avoid pop noise */
Takashi Iwaie044c392008-10-27 16:56:24 +0100899 codec->patch_ops.init(codec);
Takashi Iwaieeecd9d2015-02-25 15:18:50 +0100900 regcache_sync(codec->core.regmap);
Takashi Iwai9e5341b2010-09-21 09:57:06 +0200901 hda_call_check_power_status(codec, 0x01);
Takashi Iwaie044c392008-10-27 16:56:24 +0100902 return 0;
903}
Takashi Iwaie044c392008-10-27 16:56:24 +0100904#endif
905
Linus Torvalds1da177e2005-04-16 15:20:36 -0700906/*
907 */
Takashi Iwaia9111322011-05-02 11:30:18 +0200908static const struct hda_codec_ops alc_patch_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700909 .build_controls = alc_build_controls,
Takashi Iwai08c189f2012-12-19 15:22:24 +0100910 .build_pcms = snd_hda_gen_build_pcms,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700911 .init = alc_init,
912 .free = alc_free,
David Henningsson29adc4b2012-09-25 11:31:00 +0200913 .unsol_event = snd_hda_jack_unsol_event,
Takashi Iwai2a439522011-07-26 09:52:50 +0200914#ifdef CONFIG_PM
Takashi Iwaie044c392008-10-27 16:56:24 +0100915 .resume = alc_resume,
Hector Martinf5de24b2009-12-20 22:51:31 +0100916 .suspend = alc_suspend,
Takashi Iwaifce52a32013-01-07 12:42:48 +0100917 .check_power_status = snd_hda_gen_check_power_status,
Takashi Iwaicb53c622007-08-10 17:21:45 +0200918#endif
Takashi Iwai70a09762015-12-15 14:59:58 +0100919 .reboot_notify = alc_reboot_notify,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700920};
921
David Henningsson29adc4b2012-09-25 11:31:00 +0200922
Takashi Iwaided255b2015-10-01 17:59:43 +0200923#define alc_codec_rename(codec, name) snd_hda_codec_set_name(codec, name)
Kailang Yangc027ddc2010-03-19 11:33:06 +0100924
Takashi Iwai2fa522b2005-05-12 14:51:12 +0200925/*
Kailang Yang4b016932013-11-28 11:55:09 +0100926 * Rename codecs appropriately from COEF value or subvendor id
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200927 */
928struct alc_codec_rename_table {
929 unsigned int vendor_id;
930 unsigned short coef_mask;
931 unsigned short coef_bits;
932 const char *name;
933};
934
Kailang Yang4b016932013-11-28 11:55:09 +0100935struct alc_codec_rename_pci_table {
936 unsigned int codec_vendor_id;
937 unsigned short pci_subvendor;
938 unsigned short pci_subdevice;
939 const char *name;
940};
941
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200942static struct alc_codec_rename_table rename_tbl[] = {
Kailang Yange6e5f7a2014-06-06 16:46:43 +0800943 { 0x10ec0221, 0xf00f, 0x1003, "ALC231" },
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200944 { 0x10ec0269, 0xfff0, 0x3010, "ALC277" },
945 { 0x10ec0269, 0xf0f0, 0x2010, "ALC259" },
946 { 0x10ec0269, 0xf0f0, 0x3010, "ALC258" },
947 { 0x10ec0269, 0x00f0, 0x0010, "ALC269VB" },
948 { 0x10ec0269, 0xffff, 0xa023, "ALC259" },
949 { 0x10ec0269, 0xffff, 0x6023, "ALC281X" },
950 { 0x10ec0269, 0x00f0, 0x0020, "ALC269VC" },
Kailang Yangadcc70b2012-05-25 08:08:38 +0200951 { 0x10ec0269, 0x00f0, 0x0030, "ALC269VD" },
Kailang Yange6e5f7a2014-06-06 16:46:43 +0800952 { 0x10ec0662, 0xffff, 0x4020, "ALC656" },
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200953 { 0x10ec0887, 0x00f0, 0x0030, "ALC887-VD" },
954 { 0x10ec0888, 0x00f0, 0x0030, "ALC888-VD" },
955 { 0x10ec0888, 0xf0f0, 0x3020, "ALC886" },
956 { 0x10ec0899, 0x2000, 0x2000, "ALC899" },
957 { 0x10ec0892, 0xffff, 0x8020, "ALC661" },
958 { 0x10ec0892, 0xffff, 0x8011, "ALC661" },
959 { 0x10ec0892, 0xffff, 0x4011, "ALC656" },
960 { } /* terminator */
961};
962
Kailang Yang4b016932013-11-28 11:55:09 +0100963static struct alc_codec_rename_pci_table rename_pci_tbl[] = {
964 { 0x10ec0280, 0x1028, 0, "ALC3220" },
965 { 0x10ec0282, 0x1028, 0, "ALC3221" },
966 { 0x10ec0283, 0x1028, 0, "ALC3223" },
Kailang Yang193177d2014-04-23 16:06:13 +0800967 { 0x10ec0288, 0x1028, 0, "ALC3263" },
Kailang Yang4b016932013-11-28 11:55:09 +0100968 { 0x10ec0292, 0x1028, 0, "ALC3226" },
Kailang Yang193177d2014-04-23 16:06:13 +0800969 { 0x10ec0293, 0x1028, 0, "ALC3235" },
Kailang Yang4b016932013-11-28 11:55:09 +0100970 { 0x10ec0255, 0x1028, 0, "ALC3234" },
971 { 0x10ec0668, 0x1028, 0, "ALC3661" },
Kailang Yange6e5f7a2014-06-06 16:46:43 +0800972 { 0x10ec0275, 0x1028, 0, "ALC3260" },
973 { 0x10ec0899, 0x1028, 0, "ALC3861" },
Kailang Yang2c674fa2015-05-05 15:02:42 +0800974 { 0x10ec0298, 0x1028, 0, "ALC3266" },
Kailang Yang736f20a2017-10-20 15:06:34 +0800975 { 0x10ec0236, 0x1028, 0, "ALC3204" },
Kailang Yang82324502015-05-25 17:16:49 +0800976 { 0x10ec0256, 0x1028, 0, "ALC3246" },
Kailang Yang42314302016-02-03 15:03:50 +0800977 { 0x10ec0225, 0x1028, 0, "ALC3253" },
Kailang Yang7d727862016-05-24 16:46:07 +0800978 { 0x10ec0295, 0x1028, 0, "ALC3254" },
Kailang Yang28f1f9b2017-01-04 14:49:07 +0800979 { 0x10ec0299, 0x1028, 0, "ALC3271" },
Kailang Yange6e5f7a2014-06-06 16:46:43 +0800980 { 0x10ec0670, 0x1025, 0, "ALC669X" },
981 { 0x10ec0676, 0x1025, 0, "ALC679X" },
982 { 0x10ec0282, 0x1043, 0, "ALC3229" },
983 { 0x10ec0233, 0x1043, 0, "ALC3236" },
984 { 0x10ec0280, 0x103c, 0, "ALC3228" },
985 { 0x10ec0282, 0x103c, 0, "ALC3227" },
986 { 0x10ec0286, 0x103c, 0, "ALC3242" },
987 { 0x10ec0290, 0x103c, 0, "ALC3241" },
988 { 0x10ec0668, 0x103c, 0, "ALC3662" },
989 { 0x10ec0283, 0x17aa, 0, "ALC3239" },
990 { 0x10ec0292, 0x17aa, 0, "ALC3232" },
Kailang Yang4b016932013-11-28 11:55:09 +0100991 { } /* terminator */
992};
993
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200994static int alc_codec_rename_from_preset(struct hda_codec *codec)
995{
996 const struct alc_codec_rename_table *p;
Kailang Yang4b016932013-11-28 11:55:09 +0100997 const struct alc_codec_rename_pci_table *q;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200998
999 for (p = rename_tbl; p->vendor_id; p++) {
Takashi Iwai7639a062015-03-03 10:07:24 +01001000 if (p->vendor_id != codec->core.vendor_id)
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02001001 continue;
Takashi Iwai1bb7e432011-10-17 16:50:59 +02001002 if ((alc_get_coef0(codec) & p->coef_mask) == p->coef_bits)
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02001003 return alc_codec_rename(codec, p->name);
1004 }
Kailang Yang4b016932013-11-28 11:55:09 +01001005
Takashi Iwai5100cd02014-02-15 10:03:19 +01001006 if (!codec->bus->pci)
1007 return 0;
Kailang Yang4b016932013-11-28 11:55:09 +01001008 for (q = rename_pci_tbl; q->codec_vendor_id; q++) {
Takashi Iwai7639a062015-03-03 10:07:24 +01001009 if (q->codec_vendor_id != codec->core.vendor_id)
Kailang Yang4b016932013-11-28 11:55:09 +01001010 continue;
1011 if (q->pci_subvendor != codec->bus->pci->subsystem_vendor)
1012 continue;
1013 if (!q->pci_subdevice ||
1014 q->pci_subdevice == codec->bus->pci->subsystem_device)
1015 return alc_codec_rename(codec, q->name);
1016 }
1017
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02001018 return 0;
1019}
1020
Takashi Iwaie4770622011-07-08 11:11:35 +02001021
1022/*
Takashi Iwai1d045db2011-07-07 18:23:21 +02001023 * Digital-beep handlers
1024 */
1025#ifdef CONFIG_SND_HDA_INPUT_BEEP
Takashi Iwaifea80fa2018-06-20 12:52:46 +02001026
1027/* additional beep mixers; private_value will be overwritten */
1028static const struct snd_kcontrol_new alc_beep_mixer[] = {
1029 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
1030 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
1031};
1032
1033/* set up and create beep controls */
1034static int set_beep_amp(struct alc_spec *spec, hda_nid_t nid,
1035 int idx, int dir)
1036{
1037 struct snd_kcontrol_new *knew;
1038 unsigned int beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir);
1039 int i;
1040
1041 for (i = 0; i < ARRAY_SIZE(alc_beep_mixer); i++) {
1042 knew = snd_hda_gen_add_kctl(&spec->gen, NULL,
1043 &alc_beep_mixer[i]);
1044 if (!knew)
1045 return -ENOMEM;
1046 knew->private_value = beep_amp;
1047 }
1048 return 0;
1049}
Takashi Iwai1d045db2011-07-07 18:23:21 +02001050
1051static const struct snd_pci_quirk beep_white_list[] = {
Duncan Roe71100052012-10-10 14:19:50 +02001052 SND_PCI_QUIRK(0x1043, 0x103c, "ASUS", 1),
W. Trevor Kinga4b7f21d2014-03-29 17:47:24 -07001053 SND_PCI_QUIRK(0x1043, 0x115d, "ASUS", 1),
Takashi Iwai1d045db2011-07-07 18:23:21 +02001054 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
Takashi Iwai8554ee42013-02-25 09:54:43 +01001055 SND_PCI_QUIRK(0x1043, 0x8376, "EeePC", 1),
Takashi Iwai1d045db2011-07-07 18:23:21 +02001056 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
1057 SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1),
1058 SND_PCI_QUIRK(0x1043, 0x834a, "EeePC", 1),
Takashi Iwai78f8baf2012-03-06 14:02:32 +01001059 SND_PCI_QUIRK(0x1458, 0xa002, "GA-MA790X", 1),
Takashi Iwai1d045db2011-07-07 18:23:21 +02001060 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
1061 {}
1062};
1063
1064static inline int has_cdefine_beep(struct hda_codec *codec)
1065{
1066 struct alc_spec *spec = codec->spec;
1067 const struct snd_pci_quirk *q;
1068 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
1069 if (q)
1070 return q->value;
1071 return spec->cdefine.enable_pcbeep;
1072}
1073#else
Takashi Iwaifea80fa2018-06-20 12:52:46 +02001074#define set_beep_amp(spec, nid, idx, dir) 0
Takashi Iwai1d045db2011-07-07 18:23:21 +02001075#define has_cdefine_beep(codec) 0
1076#endif
1077
1078/* parse the BIOS configuration and set up the alc_spec */
1079/* return 1 if successful, 0 if the proper config is not found,
1080 * or a negative error code
1081 */
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001082static int alc_parse_auto_config(struct hda_codec *codec,
1083 const hda_nid_t *ignore_nids,
1084 const hda_nid_t *ssid_nids)
Takashi Iwai1d045db2011-07-07 18:23:21 +02001085{
1086 struct alc_spec *spec = codec->spec;
Takashi Iwai08c189f2012-12-19 15:22:24 +01001087 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001088 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001089
Takashi Iwai53c334a2011-08-23 18:27:14 +02001090 err = snd_hda_parse_pin_defcfg(codec, cfg, ignore_nids,
1091 spec->parse_flags);
Takashi Iwai1d045db2011-07-07 18:23:21 +02001092 if (err < 0)
1093 return err;
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001094
1095 if (ssid_nids)
1096 alc_ssid_check(codec, ssid_nids);
1097
Takashi Iwai08c189f2012-12-19 15:22:24 +01001098 err = snd_hda_gen_parse_auto_config(codec, cfg);
1099 if (err < 0)
1100 return err;
Takashi Iwai070cff42012-02-21 12:54:17 +01001101
Takashi Iwai1d045db2011-07-07 18:23:21 +02001102 return 1;
1103}
1104
Takashi Iwai3de95172012-05-07 18:03:15 +02001105/* common preparation job for alc_spec */
1106static int alc_alloc_spec(struct hda_codec *codec, hda_nid_t mixer_nid)
1107{
1108 struct alc_spec *spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1109 int err;
1110
1111 if (!spec)
1112 return -ENOMEM;
1113 codec->spec = spec;
Takashi Iwai08c189f2012-12-19 15:22:24 +01001114 snd_hda_gen_spec_init(&spec->gen);
1115 spec->gen.mixer_nid = mixer_nid;
1116 spec->gen.own_eapd_ctl = 1;
Takashi Iwai1098b7c2012-12-17 20:03:15 +01001117 codec->single_adc_amp = 1;
Takashi Iwai08c189f2012-12-19 15:22:24 +01001118 /* FIXME: do we need this for all Realtek codec models? */
1119 codec->spdif_status_reset = 1;
Takashi Iwai225068a2015-05-29 10:42:14 +02001120 codec->patch_ops = alc_patch_ops;
Takashi Iwai3de95172012-05-07 18:03:15 +02001121
1122 err = alc_codec_rename_from_preset(codec);
1123 if (err < 0) {
1124 kfree(spec);
1125 return err;
1126 }
1127 return 0;
1128}
1129
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001130static int alc880_parse_auto_config(struct hda_codec *codec)
1131{
1132 static const hda_nid_t alc880_ignore[] = { 0x1d, 0 };
Jesper Juhl7d7eb9e2012-04-12 22:11:25 +02001133 static const hda_nid_t alc880_ssids[] = { 0x15, 0x1b, 0x14, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001134 return alc_parse_auto_config(codec, alc880_ignore, alc880_ssids);
1135}
1136
Takashi Iwai1d045db2011-07-07 18:23:21 +02001137/*
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001138 * ALC880 fix-ups
1139 */
1140enum {
Takashi Iwai411225a2012-02-20 17:48:19 +01001141 ALC880_FIXUP_GPIO1,
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001142 ALC880_FIXUP_GPIO2,
1143 ALC880_FIXUP_MEDION_RIM,
Takashi Iwaidc6af522012-02-17 16:18:59 +01001144 ALC880_FIXUP_LG,
Takashi Iwaidb8a38e2013-08-09 12:34:42 +02001145 ALC880_FIXUP_LG_LW25,
Takashi Iwaif02aab52012-02-17 16:33:56 +01001146 ALC880_FIXUP_W810,
Takashi Iwai27e917f2012-02-17 17:49:54 +01001147 ALC880_FIXUP_EAPD_COEF,
Takashi Iwaib9368f52012-02-17 17:54:44 +01001148 ALC880_FIXUP_TCL_S700,
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001149 ALC880_FIXUP_VOL_KNOB,
1150 ALC880_FIXUP_FUJITSU,
Takashi Iwaiba533812012-02-20 16:36:52 +01001151 ALC880_FIXUP_F1734,
Takashi Iwai817de922012-02-20 17:20:48 +01001152 ALC880_FIXUP_UNIWILL,
Takashi Iwai967b88c2012-02-20 17:31:02 +01001153 ALC880_FIXUP_UNIWILL_DIG,
Takashi Iwai96e225f2012-02-20 17:41:51 +01001154 ALC880_FIXUP_Z71V,
Takashi Iwai487a5882013-11-07 07:29:30 +01001155 ALC880_FIXUP_ASUS_W5A,
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001156 ALC880_FIXUP_3ST_BASE,
1157 ALC880_FIXUP_3ST,
1158 ALC880_FIXUP_3ST_DIG,
1159 ALC880_FIXUP_5ST_BASE,
1160 ALC880_FIXUP_5ST,
1161 ALC880_FIXUP_5ST_DIG,
1162 ALC880_FIXUP_6ST_BASE,
1163 ALC880_FIXUP_6ST,
1164 ALC880_FIXUP_6ST_DIG,
Takashi Iwai53971452013-01-23 18:21:37 +01001165 ALC880_FIXUP_6ST_AUTOMUTE,
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001166};
1167
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001168/* enable the volume-knob widget support on NID 0x21 */
1169static void alc880_fixup_vol_knob(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001170 const struct hda_fixup *fix, int action)
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001171{
Takashi Iwai1727a772013-01-10 09:52:52 +01001172 if (action == HDA_FIXUP_ACT_PROBE)
Takashi Iwai62f949b2014-09-11 14:06:53 +02001173 snd_hda_jack_detect_enable_callback(codec, 0x21,
1174 alc_update_knob_master);
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001175}
1176
Takashi Iwai1727a772013-01-10 09:52:52 +01001177static const struct hda_fixup alc880_fixups[] = {
Takashi Iwai411225a2012-02-20 17:48:19 +01001178 [ALC880_FIXUP_GPIO1] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02001179 .type = HDA_FIXUP_FUNC,
1180 .v.func = alc_fixup_gpio1,
Takashi Iwai411225a2012-02-20 17:48:19 +01001181 },
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001182 [ALC880_FIXUP_GPIO2] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02001183 .type = HDA_FIXUP_FUNC,
1184 .v.func = alc_fixup_gpio2,
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001185 },
1186 [ALC880_FIXUP_MEDION_RIM] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001187 .type = HDA_FIXUP_VERBS,
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001188 .v.verbs = (const struct hda_verb[]) {
1189 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
1190 { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
1191 { }
1192 },
1193 .chained = true,
1194 .chain_id = ALC880_FIXUP_GPIO2,
1195 },
Takashi Iwaidc6af522012-02-17 16:18:59 +01001196 [ALC880_FIXUP_LG] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001197 .type = HDA_FIXUP_PINS,
1198 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaidc6af522012-02-17 16:18:59 +01001199 /* disable bogus unused pins */
1200 { 0x16, 0x411111f0 },
1201 { 0x18, 0x411111f0 },
1202 { 0x1a, 0x411111f0 },
1203 { }
1204 }
1205 },
Takashi Iwaidb8a38e2013-08-09 12:34:42 +02001206 [ALC880_FIXUP_LG_LW25] = {
1207 .type = HDA_FIXUP_PINS,
1208 .v.pins = (const struct hda_pintbl[]) {
1209 { 0x1a, 0x0181344f }, /* line-in */
1210 { 0x1b, 0x0321403f }, /* headphone */
1211 { }
1212 }
1213 },
Takashi Iwaif02aab52012-02-17 16:33:56 +01001214 [ALC880_FIXUP_W810] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001215 .type = HDA_FIXUP_PINS,
1216 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaif02aab52012-02-17 16:33:56 +01001217 /* disable bogus unused pins */
1218 { 0x17, 0x411111f0 },
1219 { }
1220 },
1221 .chained = true,
1222 .chain_id = ALC880_FIXUP_GPIO2,
1223 },
Takashi Iwai27e917f2012-02-17 17:49:54 +01001224 [ALC880_FIXUP_EAPD_COEF] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001225 .type = HDA_FIXUP_VERBS,
Takashi Iwai27e917f2012-02-17 17:49:54 +01001226 .v.verbs = (const struct hda_verb[]) {
1227 /* change to EAPD mode */
1228 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
1229 { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
1230 {}
1231 },
1232 },
Takashi Iwaib9368f52012-02-17 17:54:44 +01001233 [ALC880_FIXUP_TCL_S700] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001234 .type = HDA_FIXUP_VERBS,
Takashi Iwaib9368f52012-02-17 17:54:44 +01001235 .v.verbs = (const struct hda_verb[]) {
1236 /* change to EAPD mode */
1237 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
1238 { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
1239 {}
1240 },
1241 .chained = true,
1242 .chain_id = ALC880_FIXUP_GPIO2,
1243 },
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001244 [ALC880_FIXUP_VOL_KNOB] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001245 .type = HDA_FIXUP_FUNC,
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001246 .v.func = alc880_fixup_vol_knob,
1247 },
1248 [ALC880_FIXUP_FUJITSU] = {
1249 /* override all pins as BIOS on old Amilo is broken */
Takashi Iwai1727a772013-01-10 09:52:52 +01001250 .type = HDA_FIXUP_PINS,
1251 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaibb148bd2015-08-13 18:02:39 +02001252 { 0x14, 0x0121401f }, /* HP */
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001253 { 0x15, 0x99030120 }, /* speaker */
1254 { 0x16, 0x99030130 }, /* bass speaker */
1255 { 0x17, 0x411111f0 }, /* N/A */
1256 { 0x18, 0x411111f0 }, /* N/A */
1257 { 0x19, 0x01a19950 }, /* mic-in */
1258 { 0x1a, 0x411111f0 }, /* N/A */
1259 { 0x1b, 0x411111f0 }, /* N/A */
1260 { 0x1c, 0x411111f0 }, /* N/A */
1261 { 0x1d, 0x411111f0 }, /* N/A */
1262 { 0x1e, 0x01454140 }, /* SPDIF out */
1263 { }
1264 },
1265 .chained = true,
1266 .chain_id = ALC880_FIXUP_VOL_KNOB,
1267 },
Takashi Iwaiba533812012-02-20 16:36:52 +01001268 [ALC880_FIXUP_F1734] = {
1269 /* almost compatible with FUJITSU, but no bass and SPDIF */
Takashi Iwai1727a772013-01-10 09:52:52 +01001270 .type = HDA_FIXUP_PINS,
1271 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaibb148bd2015-08-13 18:02:39 +02001272 { 0x14, 0x0121401f }, /* HP */
Takashi Iwaiba533812012-02-20 16:36:52 +01001273 { 0x15, 0x99030120 }, /* speaker */
1274 { 0x16, 0x411111f0 }, /* N/A */
1275 { 0x17, 0x411111f0 }, /* N/A */
1276 { 0x18, 0x411111f0 }, /* N/A */
1277 { 0x19, 0x01a19950 }, /* mic-in */
1278 { 0x1a, 0x411111f0 }, /* N/A */
1279 { 0x1b, 0x411111f0 }, /* N/A */
1280 { 0x1c, 0x411111f0 }, /* N/A */
1281 { 0x1d, 0x411111f0 }, /* N/A */
1282 { 0x1e, 0x411111f0 }, /* N/A */
1283 { }
1284 },
1285 .chained = true,
1286 .chain_id = ALC880_FIXUP_VOL_KNOB,
1287 },
Takashi Iwai817de922012-02-20 17:20:48 +01001288 [ALC880_FIXUP_UNIWILL] = {
1289 /* need to fix HP and speaker pins to be parsed correctly */
Takashi Iwai1727a772013-01-10 09:52:52 +01001290 .type = HDA_FIXUP_PINS,
1291 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai817de922012-02-20 17:20:48 +01001292 { 0x14, 0x0121411f }, /* HP */
1293 { 0x15, 0x99030120 }, /* speaker */
1294 { 0x16, 0x99030130 }, /* bass speaker */
1295 { }
1296 },
1297 },
Takashi Iwai967b88c2012-02-20 17:31:02 +01001298 [ALC880_FIXUP_UNIWILL_DIG] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001299 .type = HDA_FIXUP_PINS,
1300 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai967b88c2012-02-20 17:31:02 +01001301 /* disable bogus unused pins */
1302 { 0x17, 0x411111f0 },
1303 { 0x19, 0x411111f0 },
1304 { 0x1b, 0x411111f0 },
1305 { 0x1f, 0x411111f0 },
1306 { }
1307 }
1308 },
Takashi Iwai96e225f2012-02-20 17:41:51 +01001309 [ALC880_FIXUP_Z71V] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001310 .type = HDA_FIXUP_PINS,
1311 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai96e225f2012-02-20 17:41:51 +01001312 /* set up the whole pins as BIOS is utterly broken */
1313 { 0x14, 0x99030120 }, /* speaker */
1314 { 0x15, 0x0121411f }, /* HP */
1315 { 0x16, 0x411111f0 }, /* N/A */
1316 { 0x17, 0x411111f0 }, /* N/A */
1317 { 0x18, 0x01a19950 }, /* mic-in */
1318 { 0x19, 0x411111f0 }, /* N/A */
1319 { 0x1a, 0x01813031 }, /* line-in */
1320 { 0x1b, 0x411111f0 }, /* N/A */
1321 { 0x1c, 0x411111f0 }, /* N/A */
1322 { 0x1d, 0x411111f0 }, /* N/A */
1323 { 0x1e, 0x0144111e }, /* SPDIF */
1324 { }
1325 }
1326 },
Takashi Iwai487a5882013-11-07 07:29:30 +01001327 [ALC880_FIXUP_ASUS_W5A] = {
1328 .type = HDA_FIXUP_PINS,
1329 .v.pins = (const struct hda_pintbl[]) {
1330 /* set up the whole pins as BIOS is utterly broken */
1331 { 0x14, 0x0121411f }, /* HP */
1332 { 0x15, 0x411111f0 }, /* N/A */
1333 { 0x16, 0x411111f0 }, /* N/A */
1334 { 0x17, 0x411111f0 }, /* N/A */
1335 { 0x18, 0x90a60160 }, /* mic */
1336 { 0x19, 0x411111f0 }, /* N/A */
1337 { 0x1a, 0x411111f0 }, /* N/A */
1338 { 0x1b, 0x411111f0 }, /* N/A */
1339 { 0x1c, 0x411111f0 }, /* N/A */
1340 { 0x1d, 0x411111f0 }, /* N/A */
1341 { 0x1e, 0xb743111e }, /* SPDIF out */
1342 { }
1343 },
1344 .chained = true,
1345 .chain_id = ALC880_FIXUP_GPIO1,
1346 },
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001347 [ALC880_FIXUP_3ST_BASE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001348 .type = HDA_FIXUP_PINS,
1349 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001350 { 0x14, 0x01014010 }, /* line-out */
1351 { 0x15, 0x411111f0 }, /* N/A */
1352 { 0x16, 0x411111f0 }, /* N/A */
1353 { 0x17, 0x411111f0 }, /* N/A */
1354 { 0x18, 0x01a19c30 }, /* mic-in */
1355 { 0x19, 0x0121411f }, /* HP */
1356 { 0x1a, 0x01813031 }, /* line-in */
1357 { 0x1b, 0x02a19c40 }, /* front-mic */
1358 { 0x1c, 0x411111f0 }, /* N/A */
1359 { 0x1d, 0x411111f0 }, /* N/A */
1360 /* 0x1e is filled in below */
1361 { 0x1f, 0x411111f0 }, /* N/A */
1362 { }
1363 }
1364 },
1365 [ALC880_FIXUP_3ST] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001366 .type = HDA_FIXUP_PINS,
1367 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001368 { 0x1e, 0x411111f0 }, /* N/A */
1369 { }
1370 },
1371 .chained = true,
1372 .chain_id = ALC880_FIXUP_3ST_BASE,
1373 },
1374 [ALC880_FIXUP_3ST_DIG] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001375 .type = HDA_FIXUP_PINS,
1376 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001377 { 0x1e, 0x0144111e }, /* SPDIF */
1378 { }
1379 },
1380 .chained = true,
1381 .chain_id = ALC880_FIXUP_3ST_BASE,
1382 },
1383 [ALC880_FIXUP_5ST_BASE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001384 .type = HDA_FIXUP_PINS,
1385 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001386 { 0x14, 0x01014010 }, /* front */
1387 { 0x15, 0x411111f0 }, /* N/A */
1388 { 0x16, 0x01011411 }, /* CLFE */
1389 { 0x17, 0x01016412 }, /* surr */
1390 { 0x18, 0x01a19c30 }, /* mic-in */
1391 { 0x19, 0x0121411f }, /* HP */
1392 { 0x1a, 0x01813031 }, /* line-in */
1393 { 0x1b, 0x02a19c40 }, /* front-mic */
1394 { 0x1c, 0x411111f0 }, /* N/A */
1395 { 0x1d, 0x411111f0 }, /* N/A */
1396 /* 0x1e is filled in below */
1397 { 0x1f, 0x411111f0 }, /* N/A */
1398 { }
1399 }
1400 },
1401 [ALC880_FIXUP_5ST] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001402 .type = HDA_FIXUP_PINS,
1403 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001404 { 0x1e, 0x411111f0 }, /* N/A */
1405 { }
1406 },
1407 .chained = true,
1408 .chain_id = ALC880_FIXUP_5ST_BASE,
1409 },
1410 [ALC880_FIXUP_5ST_DIG] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001411 .type = HDA_FIXUP_PINS,
1412 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001413 { 0x1e, 0x0144111e }, /* SPDIF */
1414 { }
1415 },
1416 .chained = true,
1417 .chain_id = ALC880_FIXUP_5ST_BASE,
1418 },
1419 [ALC880_FIXUP_6ST_BASE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001420 .type = HDA_FIXUP_PINS,
1421 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001422 { 0x14, 0x01014010 }, /* front */
1423 { 0x15, 0x01016412 }, /* surr */
1424 { 0x16, 0x01011411 }, /* CLFE */
1425 { 0x17, 0x01012414 }, /* side */
1426 { 0x18, 0x01a19c30 }, /* mic-in */
1427 { 0x19, 0x02a19c40 }, /* front-mic */
1428 { 0x1a, 0x01813031 }, /* line-in */
1429 { 0x1b, 0x0121411f }, /* HP */
1430 { 0x1c, 0x411111f0 }, /* N/A */
1431 { 0x1d, 0x411111f0 }, /* N/A */
1432 /* 0x1e is filled in below */
1433 { 0x1f, 0x411111f0 }, /* N/A */
1434 { }
1435 }
1436 },
1437 [ALC880_FIXUP_6ST] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001438 .type = HDA_FIXUP_PINS,
1439 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001440 { 0x1e, 0x411111f0 }, /* N/A */
1441 { }
1442 },
1443 .chained = true,
1444 .chain_id = ALC880_FIXUP_6ST_BASE,
1445 },
1446 [ALC880_FIXUP_6ST_DIG] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001447 .type = HDA_FIXUP_PINS,
1448 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001449 { 0x1e, 0x0144111e }, /* SPDIF */
1450 { }
1451 },
1452 .chained = true,
1453 .chain_id = ALC880_FIXUP_6ST_BASE,
1454 },
Takashi Iwai53971452013-01-23 18:21:37 +01001455 [ALC880_FIXUP_6ST_AUTOMUTE] = {
1456 .type = HDA_FIXUP_PINS,
1457 .v.pins = (const struct hda_pintbl[]) {
1458 { 0x1b, 0x0121401f }, /* HP with jack detect */
1459 { }
1460 },
1461 .chained_before = true,
1462 .chain_id = ALC880_FIXUP_6ST_BASE,
1463 },
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001464};
1465
1466static const struct snd_pci_quirk alc880_fixup_tbl[] = {
Takashi Iwaif02aab52012-02-17 16:33:56 +01001467 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_FIXUP_W810),
Takashi Iwai487a5882013-11-07 07:29:30 +01001468 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS W5A", ALC880_FIXUP_ASUS_W5A),
Takashi Iwai96e225f2012-02-20 17:41:51 +01001469 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_FIXUP_Z71V),
Takashi Iwai29e3fdc2012-02-20 17:56:57 +01001470 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_FIXUP_GPIO1),
David Henningsson6538de02014-06-10 10:52:50 +02001471 SND_PCI_QUIRK(0x147b, 0x1045, "ABit AA8XE", ALC880_FIXUP_6ST_AUTOMUTE),
Takashi Iwai29e3fdc2012-02-20 17:56:57 +01001472 SND_PCI_QUIRK(0x1558, 0x5401, "Clevo GPIO2", ALC880_FIXUP_GPIO2),
Takashi Iwai27e917f2012-02-17 17:49:54 +01001473 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo", ALC880_FIXUP_EAPD_COEF),
Takashi Iwai967b88c2012-02-20 17:31:02 +01001474 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_FIXUP_UNIWILL_DIG),
Takashi Iwaiba533812012-02-20 16:36:52 +01001475 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_FIXUP_F1734),
Takashi Iwai817de922012-02-20 17:20:48 +01001476 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_FIXUP_UNIWILL),
Takashi Iwai7833c7e2012-02-20 17:11:38 +01001477 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_FIXUP_VOL_KNOB),
Takashi Iwaif02aab52012-02-17 16:33:56 +01001478 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_FIXUP_W810),
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001479 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_FIXUP_MEDION_RIM),
Takashi Iwai53971452013-01-23 18:21:37 +01001480 SND_PCI_QUIRK(0x1631, 0xe011, "PB 13201056", ALC880_FIXUP_6ST_AUTOMUTE),
Takashi Iwaia1615742015-08-13 18:05:06 +02001481 SND_PCI_QUIRK(0x1734, 0x107c, "FSC Amilo M1437", ALC880_FIXUP_FUJITSU),
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001482 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FIXUP_FUJITSU),
Takashi Iwaiba533812012-02-20 16:36:52 +01001483 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_FIXUP_F1734),
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001484 SND_PCI_QUIRK(0x1734, 0x10b0, "FSC Amilo Pi1556", ALC880_FIXUP_FUJITSU),
Takashi Iwaidc6af522012-02-17 16:18:59 +01001485 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_FIXUP_LG),
1486 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_FIXUP_LG),
1487 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_FIXUP_LG),
Takashi Iwaidb8a38e2013-08-09 12:34:42 +02001488 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_FIXUP_LG_LW25),
Takashi Iwaib9368f52012-02-17 17:54:44 +01001489 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_FIXUP_TCL_S700),
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001490
1491 /* Below is the copied entries from alc880_quirks.c.
1492 * It's not quite sure whether BIOS sets the correct pin-config table
1493 * on these machines, thus they are kept to be compatible with
1494 * the old static quirks. Once when it's confirmed to work without
1495 * these overrides, it'd be better to remove.
1496 */
1497 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_FIXUP_5ST_DIG),
1498 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_FIXUP_6ST),
1499 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_FIXUP_3ST_DIG),
1500 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_FIXUP_6ST_DIG),
1501 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_FIXUP_6ST_DIG),
1502 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_FIXUP_6ST_DIG),
1503 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_FIXUP_3ST_DIG),
1504 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_FIXUP_3ST),
1505 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_FIXUP_6ST_DIG),
1506 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_FIXUP_3ST),
1507 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_FIXUP_3ST),
1508 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_FIXUP_5ST),
1509 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_FIXUP_5ST),
1510 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_FIXUP_5ST),
1511 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_FIXUP_6ST_DIG),
1512 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_FIXUP_6ST_DIG),
1513 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_FIXUP_6ST_DIG),
1514 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_FIXUP_6ST_DIG),
1515 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_FIXUP_5ST_DIG),
1516 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_FIXUP_5ST_DIG),
1517 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_FIXUP_5ST_DIG),
1518 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_FIXUP_6ST_DIG), /* broken BIOS */
1519 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_FIXUP_6ST_DIG),
1520 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1521 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1522 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1523 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_FIXUP_3ST_DIG),
1524 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1525 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_FIXUP_3ST_DIG),
1526 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_FIXUP_3ST_DIG),
1527 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1528 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1529 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1530 /* default Intel */
1531 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_FIXUP_3ST),
1532 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_FIXUP_5ST_DIG),
1533 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_FIXUP_6ST_DIG),
1534 {}
1535};
1536
Takashi Iwai1727a772013-01-10 09:52:52 +01001537static const struct hda_model_fixup alc880_fixup_models[] = {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001538 {.id = ALC880_FIXUP_3ST, .name = "3stack"},
1539 {.id = ALC880_FIXUP_3ST_DIG, .name = "3stack-digout"},
1540 {.id = ALC880_FIXUP_5ST, .name = "5stack"},
1541 {.id = ALC880_FIXUP_5ST_DIG, .name = "5stack-digout"},
1542 {.id = ALC880_FIXUP_6ST, .name = "6stack"},
1543 {.id = ALC880_FIXUP_6ST_DIG, .name = "6stack-digout"},
Takashi Iwai53971452013-01-23 18:21:37 +01001544 {.id = ALC880_FIXUP_6ST_AUTOMUTE, .name = "6stack-automute"},
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001545 {}
1546};
1547
1548
1549/*
Takashi Iwai1d045db2011-07-07 18:23:21 +02001550 * OK, here we have finally the patch for ALC880
1551 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02001552static int patch_alc880(struct hda_codec *codec)
1553{
1554 struct alc_spec *spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001555 int err;
1556
Takashi Iwai3de95172012-05-07 18:03:15 +02001557 err = alc_alloc_spec(codec, 0x0b);
1558 if (err < 0)
1559 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001560
Takashi Iwai3de95172012-05-07 18:03:15 +02001561 spec = codec->spec;
Takashi Iwai08c189f2012-12-19 15:22:24 +01001562 spec->gen.need_dac_fix = 1;
Takashi Iwai7504b6c2013-03-18 11:25:51 +01001563 spec->gen.beep_nid = 0x01;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001564
Takashi Iwai225068a2015-05-29 10:42:14 +02001565 codec->patch_ops.unsol_event = alc880_unsol_event;
1566
Takashi Iwaic9af7532019-05-10 11:01:43 +02001567 alc_pre_init(codec);
1568
Takashi Iwai1727a772013-01-10 09:52:52 +01001569 snd_hda_pick_fixup(codec, alc880_fixup_models, alc880_fixup_tbl,
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001570 alc880_fixups);
Takashi Iwai1727a772013-01-10 09:52:52 +01001571 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02001572
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001573 /* automatic parse from the BIOS config */
1574 err = alc880_parse_auto_config(codec);
1575 if (err < 0)
1576 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001577
Takashi Iwaifea80fa2018-06-20 12:52:46 +02001578 if (!spec->gen.no_analog) {
1579 err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
1580 if (err < 0)
1581 goto error;
1582 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02001583
Takashi Iwai1727a772013-01-10 09:52:52 +01001584 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01001585
Takashi Iwai1d045db2011-07-07 18:23:21 +02001586 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02001587
1588 error:
1589 alc_free(codec);
1590 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001591}
1592
1593
1594/*
1595 * ALC260 support
1596 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02001597static int alc260_parse_auto_config(struct hda_codec *codec)
1598{
Takashi Iwai1d045db2011-07-07 18:23:21 +02001599 static const hda_nid_t alc260_ignore[] = { 0x17, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001600 static const hda_nid_t alc260_ssids[] = { 0x10, 0x15, 0x0f, 0 };
1601 return alc_parse_auto_config(codec, alc260_ignore, alc260_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02001602}
1603
Takashi Iwai1d045db2011-07-07 18:23:21 +02001604/*
1605 * Pin config fixes
1606 */
1607enum {
Takashi Iwaica8f0422012-02-16 11:51:19 +01001608 ALC260_FIXUP_HP_DC5750,
1609 ALC260_FIXUP_HP_PIN_0F,
1610 ALC260_FIXUP_COEF,
Takashi Iwai15317ab2012-02-16 12:02:53 +01001611 ALC260_FIXUP_GPIO1,
Takashi Iwai20f7d922012-02-16 12:35:16 +01001612 ALC260_FIXUP_GPIO1_TOGGLE,
1613 ALC260_FIXUP_REPLACER,
Takashi Iwai0a1c4fa2012-02-16 12:42:30 +01001614 ALC260_FIXUP_HP_B1900,
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001615 ALC260_FIXUP_KN1,
Takashi Iwai39aedee2013-01-10 17:10:40 +01001616 ALC260_FIXUP_FSC_S7020,
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001617 ALC260_FIXUP_FSC_S7020_JWSE,
Takashi Iwaid08c5ef2013-11-22 08:06:36 +01001618 ALC260_FIXUP_VAIO_PINS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02001619};
1620
Takashi Iwai20f7d922012-02-16 12:35:16 +01001621static void alc260_gpio1_automute(struct hda_codec *codec)
1622{
1623 struct alc_spec *spec = codec->spec;
Takashi Iwaiaaf312d2018-06-19 22:28:22 +02001624
1625 alc_update_gpio_data(codec, 0x01, spec->gen.hp_jack_present);
Takashi Iwai20f7d922012-02-16 12:35:16 +01001626}
1627
1628static void alc260_fixup_gpio1_toggle(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001629 const struct hda_fixup *fix, int action)
Takashi Iwai20f7d922012-02-16 12:35:16 +01001630{
1631 struct alc_spec *spec = codec->spec;
Takashi Iwai1727a772013-01-10 09:52:52 +01001632 if (action == HDA_FIXUP_ACT_PROBE) {
Takashi Iwai20f7d922012-02-16 12:35:16 +01001633 /* although the machine has only one output pin, we need to
1634 * toggle GPIO1 according to the jack state
1635 */
Takashi Iwai08c189f2012-12-19 15:22:24 +01001636 spec->gen.automute_hook = alc260_gpio1_automute;
1637 spec->gen.detect_hp = 1;
1638 spec->gen.automute_speaker = 1;
1639 spec->gen.autocfg.hp_pins[0] = 0x0f; /* copy it for automute */
Takashi Iwai62f949b2014-09-11 14:06:53 +02001640 snd_hda_jack_detect_enable_callback(codec, 0x0f,
Takashi Iwai08c189f2012-12-19 15:22:24 +01001641 snd_hda_gen_hp_automute);
Takashi Iwai5579cd62018-06-19 22:22:41 +02001642 alc_setup_gpio(codec, 0x01);
Takashi Iwai20f7d922012-02-16 12:35:16 +01001643 }
1644}
1645
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001646static void alc260_fixup_kn1(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001647 const struct hda_fixup *fix, int action)
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001648{
1649 struct alc_spec *spec = codec->spec;
Takashi Iwai1727a772013-01-10 09:52:52 +01001650 static const struct hda_pintbl pincfgs[] = {
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001651 { 0x0f, 0x02214000 }, /* HP/speaker */
1652 { 0x12, 0x90a60160 }, /* int mic */
1653 { 0x13, 0x02a19000 }, /* ext mic */
1654 { 0x18, 0x01446000 }, /* SPDIF out */
1655 /* disable bogus I/O pins */
1656 { 0x10, 0x411111f0 },
1657 { 0x11, 0x411111f0 },
1658 { 0x14, 0x411111f0 },
1659 { 0x15, 0x411111f0 },
1660 { 0x16, 0x411111f0 },
1661 { 0x17, 0x411111f0 },
1662 { 0x19, 0x411111f0 },
1663 { }
1664 };
1665
1666 switch (action) {
Takashi Iwai1727a772013-01-10 09:52:52 +01001667 case HDA_FIXUP_ACT_PRE_PROBE:
1668 snd_hda_apply_pincfgs(codec, pincfgs);
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001669 spec->init_amp = ALC_INIT_NONE;
1670 break;
1671 }
1672}
1673
Takashi Iwai39aedee2013-01-10 17:10:40 +01001674static void alc260_fixup_fsc_s7020(struct hda_codec *codec,
1675 const struct hda_fixup *fix, int action)
1676{
1677 struct alc_spec *spec = codec->spec;
Takashi Iwai1c76aa52018-06-21 16:37:54 +02001678 if (action == HDA_FIXUP_ACT_PRE_PROBE)
Takashi Iwaie6e0ee52013-02-18 17:04:20 +01001679 spec->init_amp = ALC_INIT_NONE;
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001680}
1681
1682static void alc260_fixup_fsc_s7020_jwse(struct hda_codec *codec,
1683 const struct hda_fixup *fix, int action)
1684{
1685 struct alc_spec *spec = codec->spec;
1686 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwaif811c3c2013-03-07 18:32:59 +01001687 spec->gen.add_jack_modes = 1;
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001688 spec->gen.hp_mic = 1;
Takashi Iwaie6e0ee52013-02-18 17:04:20 +01001689 }
Takashi Iwai39aedee2013-01-10 17:10:40 +01001690}
1691
Takashi Iwai1727a772013-01-10 09:52:52 +01001692static const struct hda_fixup alc260_fixups[] = {
Takashi Iwaica8f0422012-02-16 11:51:19 +01001693 [ALC260_FIXUP_HP_DC5750] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001694 .type = HDA_FIXUP_PINS,
1695 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02001696 { 0x11, 0x90130110 }, /* speaker */
1697 { }
1698 }
1699 },
Takashi Iwaica8f0422012-02-16 11:51:19 +01001700 [ALC260_FIXUP_HP_PIN_0F] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001701 .type = HDA_FIXUP_PINS,
1702 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaica8f0422012-02-16 11:51:19 +01001703 { 0x0f, 0x01214000 }, /* HP */
1704 { }
1705 }
1706 },
1707 [ALC260_FIXUP_COEF] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001708 .type = HDA_FIXUP_VERBS,
Takashi Iwaica8f0422012-02-16 11:51:19 +01001709 .v.verbs = (const struct hda_verb[]) {
Ronan Marquete30cf2d2014-06-01 18:38:53 +02001710 { 0x1a, AC_VERB_SET_COEF_INDEX, 0x07 },
1711 { 0x1a, AC_VERB_SET_PROC_COEF, 0x3040 },
Takashi Iwaica8f0422012-02-16 11:51:19 +01001712 { }
1713 },
Takashi Iwaica8f0422012-02-16 11:51:19 +01001714 },
Takashi Iwai15317ab2012-02-16 12:02:53 +01001715 [ALC260_FIXUP_GPIO1] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02001716 .type = HDA_FIXUP_FUNC,
1717 .v.func = alc_fixup_gpio1,
Takashi Iwai15317ab2012-02-16 12:02:53 +01001718 },
Takashi Iwai20f7d922012-02-16 12:35:16 +01001719 [ALC260_FIXUP_GPIO1_TOGGLE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001720 .type = HDA_FIXUP_FUNC,
Takashi Iwai20f7d922012-02-16 12:35:16 +01001721 .v.func = alc260_fixup_gpio1_toggle,
1722 .chained = true,
1723 .chain_id = ALC260_FIXUP_HP_PIN_0F,
1724 },
1725 [ALC260_FIXUP_REPLACER] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001726 .type = HDA_FIXUP_VERBS,
Takashi Iwai20f7d922012-02-16 12:35:16 +01001727 .v.verbs = (const struct hda_verb[]) {
Takashi Iwai192a98e2014-06-02 15:16:07 +02001728 { 0x1a, AC_VERB_SET_COEF_INDEX, 0x07 },
1729 { 0x1a, AC_VERB_SET_PROC_COEF, 0x3050 },
Takashi Iwai20f7d922012-02-16 12:35:16 +01001730 { }
1731 },
1732 .chained = true,
1733 .chain_id = ALC260_FIXUP_GPIO1_TOGGLE,
1734 },
Takashi Iwai0a1c4fa2012-02-16 12:42:30 +01001735 [ALC260_FIXUP_HP_B1900] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001736 .type = HDA_FIXUP_FUNC,
Takashi Iwai0a1c4fa2012-02-16 12:42:30 +01001737 .v.func = alc260_fixup_gpio1_toggle,
1738 .chained = true,
1739 .chain_id = ALC260_FIXUP_COEF,
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001740 },
1741 [ALC260_FIXUP_KN1] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001742 .type = HDA_FIXUP_FUNC,
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001743 .v.func = alc260_fixup_kn1,
1744 },
Takashi Iwai39aedee2013-01-10 17:10:40 +01001745 [ALC260_FIXUP_FSC_S7020] = {
1746 .type = HDA_FIXUP_FUNC,
1747 .v.func = alc260_fixup_fsc_s7020,
1748 },
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001749 [ALC260_FIXUP_FSC_S7020_JWSE] = {
1750 .type = HDA_FIXUP_FUNC,
1751 .v.func = alc260_fixup_fsc_s7020_jwse,
1752 .chained = true,
1753 .chain_id = ALC260_FIXUP_FSC_S7020,
1754 },
Takashi Iwaid08c5ef2013-11-22 08:06:36 +01001755 [ALC260_FIXUP_VAIO_PINS] = {
1756 .type = HDA_FIXUP_PINS,
1757 .v.pins = (const struct hda_pintbl[]) {
1758 /* Pin configs are missing completely on some VAIOs */
1759 { 0x0f, 0x01211020 },
1760 { 0x10, 0x0001003f },
1761 { 0x11, 0x411111f0 },
1762 { 0x12, 0x01a15930 },
1763 { 0x13, 0x411111f0 },
1764 { 0x14, 0x411111f0 },
1765 { 0x15, 0x411111f0 },
1766 { 0x16, 0x411111f0 },
1767 { 0x17, 0x411111f0 },
1768 { 0x18, 0x411111f0 },
1769 { 0x19, 0x411111f0 },
1770 { }
1771 }
1772 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02001773};
1774
1775static const struct snd_pci_quirk alc260_fixup_tbl[] = {
Takashi Iwai15317ab2012-02-16 12:02:53 +01001776 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_FIXUP_GPIO1),
Takashi Iwaica8f0422012-02-16 11:51:19 +01001777 SND_PCI_QUIRK(0x1025, 0x007f, "Acer Aspire 9500", ALC260_FIXUP_COEF),
Takashi Iwai15317ab2012-02-16 12:02:53 +01001778 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_FIXUP_GPIO1),
Takashi Iwaica8f0422012-02-16 11:51:19 +01001779 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", ALC260_FIXUP_HP_DC5750),
Takashi Iwai0a1c4fa2012-02-16 12:42:30 +01001780 SND_PCI_QUIRK(0x103c, 0x30ba, "HP Presario B1900", ALC260_FIXUP_HP_B1900),
Takashi Iwaid08c5ef2013-11-22 08:06:36 +01001781 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_FIXUP_VAIO_PINS),
Takashi Iwai0f5a5b82013-11-21 09:12:52 +01001782 SND_PCI_QUIRK(0x104d, 0x81e2, "Sony VAIO TX", ALC260_FIXUP_HP_PIN_0F),
Takashi Iwai39aedee2013-01-10 17:10:40 +01001783 SND_PCI_QUIRK(0x10cf, 0x1326, "FSC LifeBook S7020", ALC260_FIXUP_FSC_S7020),
Takashi Iwaib1f58082012-02-16 12:45:03 +01001784 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FIXUP_GPIO1),
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001785 SND_PCI_QUIRK(0x152d, 0x0729, "Quanta KN1", ALC260_FIXUP_KN1),
Takashi Iwai20f7d922012-02-16 12:35:16 +01001786 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_FIXUP_REPLACER),
Takashi Iwaica8f0422012-02-16 11:51:19 +01001787 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_FIXUP_COEF),
Takashi Iwai1d045db2011-07-07 18:23:21 +02001788 {}
1789};
1790
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001791static const struct hda_model_fixup alc260_fixup_models[] = {
1792 {.id = ALC260_FIXUP_GPIO1, .name = "gpio1"},
1793 {.id = ALC260_FIXUP_COEF, .name = "coef"},
1794 {.id = ALC260_FIXUP_FSC_S7020, .name = "fujitsu"},
1795 {.id = ALC260_FIXUP_FSC_S7020_JWSE, .name = "fujitsu-jwse"},
1796 {}
1797};
1798
Takashi Iwai1d045db2011-07-07 18:23:21 +02001799/*
1800 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02001801static int patch_alc260(struct hda_codec *codec)
1802{
1803 struct alc_spec *spec;
Takashi Iwaic3c2c9e2012-02-16 12:59:55 +01001804 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001805
Takashi Iwai3de95172012-05-07 18:03:15 +02001806 err = alc_alloc_spec(codec, 0x07);
1807 if (err < 0)
1808 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001809
Takashi Iwai3de95172012-05-07 18:03:15 +02001810 spec = codec->spec;
Takashi Iwaiea46c3c2013-01-15 18:45:53 +01001811 /* as quite a few machines require HP amp for speaker outputs,
1812 * it's easier to enable it unconditionally; even if it's unneeded,
1813 * it's almost harmless.
1814 */
1815 spec->gen.prefer_hp_amp = 1;
Takashi Iwai7504b6c2013-03-18 11:25:51 +01001816 spec->gen.beep_nid = 0x01;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001817
Takashi Iwai225068a2015-05-29 10:42:14 +02001818 spec->shutup = alc_eapd_shutup;
1819
Takashi Iwaic9af7532019-05-10 11:01:43 +02001820 alc_pre_init(codec);
1821
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001822 snd_hda_pick_fixup(codec, alc260_fixup_models, alc260_fixup_tbl,
1823 alc260_fixups);
Takashi Iwai1727a772013-01-10 09:52:52 +01001824 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02001825
Takashi Iwaic3c2c9e2012-02-16 12:59:55 +01001826 /* automatic parse from the BIOS config */
1827 err = alc260_parse_auto_config(codec);
1828 if (err < 0)
1829 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001830
Takashi Iwaifea80fa2018-06-20 12:52:46 +02001831 if (!spec->gen.no_analog) {
1832 err = set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
1833 if (err < 0)
1834 goto error;
1835 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02001836
Takashi Iwai1727a772013-01-10 09:52:52 +01001837 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01001838
Takashi Iwai1d045db2011-07-07 18:23:21 +02001839 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02001840
1841 error:
1842 alc_free(codec);
1843 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001844}
1845
1846
1847/*
1848 * ALC882/883/885/888/889 support
1849 *
1850 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
1851 * configuration. Each pin widget can choose any input DACs and a mixer.
1852 * Each ADC is connected from a mixer of all inputs. This makes possible
1853 * 6-channel independent captures.
1854 *
1855 * In addition, an independent DAC for the multi-playback (not used in this
1856 * driver yet).
1857 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02001858
1859/*
1860 * Pin config fixes
1861 */
1862enum {
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01001863 ALC882_FIXUP_ABIT_AW9D_MAX,
1864 ALC882_FIXUP_LENOVO_Y530,
1865 ALC882_FIXUP_PB_M5210,
1866 ALC882_FIXUP_ACER_ASPIRE_7736,
1867 ALC882_FIXUP_ASUS_W90V,
Marton Balint8f239212012-03-05 21:33:23 +01001868 ALC889_FIXUP_CD,
David Henningssonb2c53e22014-01-01 14:01:34 +01001869 ALC889_FIXUP_FRONT_HP_NO_PRESENCE,
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01001870 ALC889_FIXUP_VAIO_TT,
Takashi Iwai0e7cc2e2011-11-09 12:42:48 +01001871 ALC888_FIXUP_EEE1601,
Takashi Iwai177943a32011-11-09 12:55:18 +01001872 ALC882_FIXUP_EAPD,
Takashi Iwai7a6069b2011-11-09 15:22:01 +01001873 ALC883_FIXUP_EAPD,
Takashi Iwai8812c4f2011-11-09 17:39:15 +01001874 ALC883_FIXUP_ACER_EAPD,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001875 ALC882_FIXUP_GPIO1,
1876 ALC882_FIXUP_GPIO2,
Takashi Iwaieb844d52011-11-09 18:03:07 +01001877 ALC882_FIXUP_GPIO3,
Takashi Iwai68ef0562011-11-09 18:24:44 +01001878 ALC889_FIXUP_COEF,
1879 ALC882_FIXUP_ASUS_W2JC,
Takashi Iwaic3e837b2011-11-10 16:01:47 +01001880 ALC882_FIXUP_ACER_ASPIRE_4930G,
1881 ALC882_FIXUP_ACER_ASPIRE_8930G,
1882 ALC882_FIXUP_ASPIRE_8930G_VERBS,
Takashi Iwai56710872011-11-14 17:42:11 +01001883 ALC885_FIXUP_MACPRO_GPIO,
Takashi Iwai02a237b2012-02-13 15:25:07 +01001884 ALC889_FIXUP_DAC_ROUTE,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001885 ALC889_FIXUP_MBP_VREF,
1886 ALC889_FIXUP_IMAC91_VREF,
Adrien Vergée7729a42014-01-24 14:56:14 -05001887 ALC889_FIXUP_MBA11_VREF,
Takashi Iwai0756f092013-12-04 13:59:45 +01001888 ALC889_FIXUP_MBA21_VREF,
Takashi Iwaic20f31e2014-02-03 11:02:10 +01001889 ALC889_FIXUP_MP11_VREF,
Mario Kleiner9f660a12015-12-22 00:45:43 +01001890 ALC889_FIXUP_MP41_VREF,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02001891 ALC882_FIXUP_INV_DMIC,
Takashi Iwaie427c232012-07-29 10:04:08 +02001892 ALC882_FIXUP_NO_PRIMARY_HP,
Takashi Iwai1f0bbf02013-11-28 15:21:21 +01001893 ALC887_FIXUP_ASUS_BASS,
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01001894 ALC887_FIXUP_BASS_CHMAP,
Takashi Iwai7beb3a62017-04-10 18:05:52 +02001895 ALC1220_FIXUP_GB_DUAL_CODECS,
Peisen0202f5c2017-10-26 10:35:36 +08001896 ALC1220_FIXUP_CLEVO_P950,
Richard Sailer80690a22019-04-02 15:52:04 +02001897 ALC1220_FIXUP_CLEVO_PB51ED,
1898 ALC1220_FIXUP_CLEVO_PB51ED_PINS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02001899};
1900
Takashi Iwai68ef0562011-11-09 18:24:44 +01001901static void alc889_fixup_coef(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001902 const struct hda_fixup *fix, int action)
Takashi Iwai68ef0562011-11-09 18:24:44 +01001903{
Takashi Iwai1727a772013-01-10 09:52:52 +01001904 if (action != HDA_FIXUP_ACT_INIT)
Takashi Iwai68ef0562011-11-09 18:24:44 +01001905 return;
Kailang Yang1df88742014-10-29 16:10:13 +08001906 alc_update_coef_idx(codec, 7, 0, 0x2030);
Takashi Iwai68ef0562011-11-09 18:24:44 +01001907}
1908
Takashi Iwai56710872011-11-14 17:42:11 +01001909/* set up GPIO at initialization */
1910static void alc885_fixup_macpro_gpio(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001911 const struct hda_fixup *fix, int action)
Takashi Iwai56710872011-11-14 17:42:11 +01001912{
Takashi Iwai215c8502018-06-19 22:34:26 +02001913 struct alc_spec *spec = codec->spec;
1914
1915 spec->gpio_write_delay = true;
1916 alc_fixup_gpio3(codec, fix, action);
Takashi Iwai56710872011-11-14 17:42:11 +01001917}
1918
Takashi Iwai02a237b2012-02-13 15:25:07 +01001919/* Fix the connection of some pins for ALC889:
1920 * At least, Acer Aspire 5935 shows the connections to DAC3/4 don't
1921 * work correctly (bko#42740)
1922 */
1923static void alc889_fixup_dac_route(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001924 const struct hda_fixup *fix, int action)
Takashi Iwai02a237b2012-02-13 15:25:07 +01001925{
Takashi Iwai1727a772013-01-10 09:52:52 +01001926 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwaief8d60f2012-02-17 10:12:38 +01001927 /* fake the connections during parsing the tree */
Takashi Iwai02a237b2012-02-13 15:25:07 +01001928 hda_nid_t conn1[2] = { 0x0c, 0x0d };
1929 hda_nid_t conn2[2] = { 0x0e, 0x0f };
1930 snd_hda_override_conn_list(codec, 0x14, 2, conn1);
1931 snd_hda_override_conn_list(codec, 0x15, 2, conn1);
1932 snd_hda_override_conn_list(codec, 0x18, 2, conn2);
1933 snd_hda_override_conn_list(codec, 0x1a, 2, conn2);
Takashi Iwai1727a772013-01-10 09:52:52 +01001934 } else if (action == HDA_FIXUP_ACT_PROBE) {
Takashi Iwaief8d60f2012-02-17 10:12:38 +01001935 /* restore the connections */
1936 hda_nid_t conn[5] = { 0x0c, 0x0d, 0x0e, 0x0f, 0x26 };
1937 snd_hda_override_conn_list(codec, 0x14, 5, conn);
1938 snd_hda_override_conn_list(codec, 0x15, 5, conn);
1939 snd_hda_override_conn_list(codec, 0x18, 5, conn);
1940 snd_hda_override_conn_list(codec, 0x1a, 5, conn);
Takashi Iwai02a237b2012-02-13 15:25:07 +01001941 }
1942}
1943
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001944/* Set VREF on HP pin */
1945static void alc889_fixup_mbp_vref(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001946 const struct hda_fixup *fix, int action)
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001947{
1948 struct alc_spec *spec = codec->spec;
Mario Kleiner9f660a12015-12-22 00:45:43 +01001949 static hda_nid_t nids[3] = { 0x14, 0x15, 0x19 };
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001950 int i;
1951
Takashi Iwai1727a772013-01-10 09:52:52 +01001952 if (action != HDA_FIXUP_ACT_INIT)
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001953 return;
1954 for (i = 0; i < ARRAY_SIZE(nids); i++) {
1955 unsigned int val = snd_hda_codec_get_pincfg(codec, nids[i]);
1956 if (get_defcfg_device(val) != AC_JACK_HP_OUT)
1957 continue;
Takashi Iwaid3f02d62013-01-10 10:12:22 +01001958 val = snd_hda_codec_get_pin_target(codec, nids[i]);
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001959 val |= AC_PINCTL_VREF_80;
Takashi Iwaicdd03ce2012-04-20 12:34:50 +02001960 snd_hda_set_pin_ctl(codec, nids[i], val);
Takashi Iwai08c189f2012-12-19 15:22:24 +01001961 spec->gen.keep_vref_in_automute = 1;
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001962 break;
1963 }
1964}
1965
Takashi Iwai0756f092013-12-04 13:59:45 +01001966static void alc889_fixup_mac_pins(struct hda_codec *codec,
1967 const hda_nid_t *nids, int num_nids)
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001968{
1969 struct alc_spec *spec = codec->spec;
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001970 int i;
1971
Takashi Iwai0756f092013-12-04 13:59:45 +01001972 for (i = 0; i < num_nids; i++) {
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001973 unsigned int val;
Takashi Iwaid3f02d62013-01-10 10:12:22 +01001974 val = snd_hda_codec_get_pin_target(codec, nids[i]);
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001975 val |= AC_PINCTL_VREF_50;
Takashi Iwaicdd03ce2012-04-20 12:34:50 +02001976 snd_hda_set_pin_ctl(codec, nids[i], val);
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001977 }
Takashi Iwai08c189f2012-12-19 15:22:24 +01001978 spec->gen.keep_vref_in_automute = 1;
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001979}
1980
Takashi Iwai0756f092013-12-04 13:59:45 +01001981/* Set VREF on speaker pins on imac91 */
1982static void alc889_fixup_imac91_vref(struct hda_codec *codec,
1983 const struct hda_fixup *fix, int action)
1984{
1985 static hda_nid_t nids[2] = { 0x18, 0x1a };
1986
1987 if (action == HDA_FIXUP_ACT_INIT)
1988 alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
1989}
1990
Adrien Vergée7729a42014-01-24 14:56:14 -05001991/* Set VREF on speaker pins on mba11 */
1992static void alc889_fixup_mba11_vref(struct hda_codec *codec,
1993 const struct hda_fixup *fix, int action)
1994{
1995 static hda_nid_t nids[1] = { 0x18 };
1996
1997 if (action == HDA_FIXUP_ACT_INIT)
1998 alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
1999}
2000
Takashi Iwai0756f092013-12-04 13:59:45 +01002001/* Set VREF on speaker pins on mba21 */
2002static void alc889_fixup_mba21_vref(struct hda_codec *codec,
2003 const struct hda_fixup *fix, int action)
2004{
2005 static hda_nid_t nids[2] = { 0x18, 0x19 };
2006
2007 if (action == HDA_FIXUP_ACT_INIT)
2008 alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
2009}
2010
Takashi Iwaie427c232012-07-29 10:04:08 +02002011/* Don't take HP output as primary
Fernando Luis Vázquez Caod9111492013-02-12 16:49:46 +09002012 * Strangely, the speaker output doesn't work on Vaio Z and some Vaio
2013 * all-in-one desktop PCs (for example VGC-LN51JGB) through DAC 0x05
Takashi Iwaie427c232012-07-29 10:04:08 +02002014 */
2015static void alc882_fixup_no_primary_hp(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01002016 const struct hda_fixup *fix, int action)
Takashi Iwaie427c232012-07-29 10:04:08 +02002017{
2018 struct alc_spec *spec = codec->spec;
Takashi Iwaida96fb52013-07-29 16:54:36 +02002019 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai08c189f2012-12-19 15:22:24 +01002020 spec->gen.no_primary_hp = 1;
Takashi Iwaida96fb52013-07-29 16:54:36 +02002021 spec->gen.no_multi_io = 1;
2022 }
Takashi Iwaie427c232012-07-29 10:04:08 +02002023}
2024
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01002025static void alc_fixup_bass_chmap(struct hda_codec *codec,
2026 const struct hda_fixup *fix, int action);
2027
Takashi Iwai7beb3a62017-04-10 18:05:52 +02002028/* For dual-codec configuration, we need to disable some features to avoid
2029 * conflicts of kctls and PCM streams
2030 */
2031static void alc_fixup_dual_codecs(struct hda_codec *codec,
2032 const struct hda_fixup *fix, int action)
2033{
2034 struct alc_spec *spec = codec->spec;
2035
2036 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2037 return;
2038 /* disable vmaster */
2039 spec->gen.suppress_vmaster = 1;
2040 /* auto-mute and auto-mic switch don't work with multiple codecs */
2041 spec->gen.suppress_auto_mute = 1;
2042 spec->gen.suppress_auto_mic = 1;
2043 /* disable aamix as well */
2044 spec->gen.mixer_nid = 0;
2045 /* add location prefix to avoid conflicts */
2046 codec->force_pin_prefix = 1;
2047}
2048
2049static void rename_ctl(struct hda_codec *codec, const char *oldname,
2050 const char *newname)
2051{
2052 struct snd_kcontrol *kctl;
2053
2054 kctl = snd_hda_find_mixer_ctl(codec, oldname);
2055 if (kctl)
2056 strcpy(kctl->id.name, newname);
2057}
2058
2059static void alc1220_fixup_gb_dual_codecs(struct hda_codec *codec,
2060 const struct hda_fixup *fix,
2061 int action)
2062{
2063 alc_fixup_dual_codecs(codec, fix, action);
2064 switch (action) {
2065 case HDA_FIXUP_ACT_PRE_PROBE:
2066 /* override card longname to provide a unique UCM profile */
2067 strcpy(codec->card->longname, "HDAudio-Gigabyte-ALC1220DualCodecs");
2068 break;
2069 case HDA_FIXUP_ACT_BUILD:
2070 /* rename Capture controls depending on the codec */
2071 rename_ctl(codec, "Capture Volume",
2072 codec->addr == 0 ?
2073 "Rear-Panel Capture Volume" :
2074 "Front-Panel Capture Volume");
2075 rename_ctl(codec, "Capture Switch",
2076 codec->addr == 0 ?
2077 "Rear-Panel Capture Switch" :
2078 "Front-Panel Capture Switch");
2079 break;
2080 }
2081}
2082
Peisen0202f5c2017-10-26 10:35:36 +08002083static void alc1220_fixup_clevo_p950(struct hda_codec *codec,
2084 const struct hda_fixup *fix,
2085 int action)
2086{
2087 hda_nid_t conn1[1] = { 0x0c };
2088
2089 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2090 return;
2091
2092 alc_update_coef_idx(codec, 0x7, 0, 0x3c3);
2093 /* We therefore want to make sure 0x14 (front headphone) and
2094 * 0x1b (speakers) use the stereo DAC 0x02
2095 */
2096 snd_hda_override_conn_list(codec, 0x14, 1, conn1);
2097 snd_hda_override_conn_list(codec, 0x1b, 1, conn1);
2098}
2099
Jeremy Soller7f665b12019-02-13 10:56:19 -07002100static void alc_fixup_headset_mode_no_hp_mic(struct hda_codec *codec,
2101 const struct hda_fixup *fix, int action);
2102
Richard Sailer80690a22019-04-02 15:52:04 +02002103static void alc1220_fixup_clevo_pb51ed(struct hda_codec *codec,
Jeremy Soller7f665b12019-02-13 10:56:19 -07002104 const struct hda_fixup *fix,
2105 int action)
2106{
2107 alc1220_fixup_clevo_p950(codec, fix, action);
2108 alc_fixup_headset_mode_no_hp_mic(codec, fix, action);
2109}
2110
Takashi Iwai1727a772013-01-10 09:52:52 +01002111static const struct hda_fixup alc882_fixups[] = {
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002112 [ALC882_FIXUP_ABIT_AW9D_MAX] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002113 .type = HDA_FIXUP_PINS,
2114 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002115 { 0x15, 0x01080104 }, /* side */
2116 { 0x16, 0x01011012 }, /* rear */
2117 { 0x17, 0x01016011 }, /* clfe */
2118 { }
2119 }
2120 },
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002121 [ALC882_FIXUP_LENOVO_Y530] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002122 .type = HDA_FIXUP_PINS,
2123 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002124 { 0x15, 0x99130112 }, /* rear int speakers */
2125 { 0x16, 0x99130111 }, /* subwoofer */
2126 { }
2127 }
2128 },
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002129 [ALC882_FIXUP_PB_M5210] = {
Takashi Iwaifd108212013-01-10 10:18:14 +01002130 .type = HDA_FIXUP_PINCTLS,
2131 .v.pins = (const struct hda_pintbl[]) {
2132 { 0x19, PIN_VREF50 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02002133 {}
2134 }
2135 },
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002136 [ALC882_FIXUP_ACER_ASPIRE_7736] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002137 .type = HDA_FIXUP_FUNC,
Takashi Iwai23d30f22012-05-07 17:17:32 +02002138 .v.func = alc_fixup_sku_ignore,
Takashi Iwai1d045db2011-07-07 18:23:21 +02002139 },
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002140 [ALC882_FIXUP_ASUS_W90V] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002141 .type = HDA_FIXUP_PINS,
2142 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai5cdf7452011-10-26 23:04:08 +02002143 { 0x16, 0x99130110 }, /* fix sequence for CLFE */
2144 { }
2145 }
2146 },
Marton Balint8f239212012-03-05 21:33:23 +01002147 [ALC889_FIXUP_CD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002148 .type = HDA_FIXUP_PINS,
2149 .v.pins = (const struct hda_pintbl[]) {
Marton Balint8f239212012-03-05 21:33:23 +01002150 { 0x1c, 0x993301f0 }, /* CD */
2151 { }
2152 }
2153 },
David Henningssonb2c53e22014-01-01 14:01:34 +01002154 [ALC889_FIXUP_FRONT_HP_NO_PRESENCE] = {
2155 .type = HDA_FIXUP_PINS,
2156 .v.pins = (const struct hda_pintbl[]) {
2157 { 0x1b, 0x02214120 }, /* Front HP jack is flaky, disable jack detect */
2158 { }
2159 },
2160 .chained = true,
2161 .chain_id = ALC889_FIXUP_CD,
2162 },
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002163 [ALC889_FIXUP_VAIO_TT] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002164 .type = HDA_FIXUP_PINS,
2165 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002166 { 0x17, 0x90170111 }, /* hidden surround speaker */
2167 { }
2168 }
2169 },
Takashi Iwai0e7cc2e2011-11-09 12:42:48 +01002170 [ALC888_FIXUP_EEE1601] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002171 .type = HDA_FIXUP_VERBS,
Takashi Iwai0e7cc2e2011-11-09 12:42:48 +01002172 .v.verbs = (const struct hda_verb[]) {
2173 { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b },
2174 { 0x20, AC_VERB_SET_PROC_COEF, 0x0838 },
2175 { }
2176 }
Takashi Iwai177943a32011-11-09 12:55:18 +01002177 },
2178 [ALC882_FIXUP_EAPD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002179 .type = HDA_FIXUP_VERBS,
Takashi Iwai177943a32011-11-09 12:55:18 +01002180 .v.verbs = (const struct hda_verb[]) {
2181 /* change to EAPD mode */
2182 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2183 { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
2184 { }
2185 }
2186 },
Takashi Iwai7a6069b2011-11-09 15:22:01 +01002187 [ALC883_FIXUP_EAPD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002188 .type = HDA_FIXUP_VERBS,
Takashi Iwai7a6069b2011-11-09 15:22:01 +01002189 .v.verbs = (const struct hda_verb[]) {
2190 /* change to EAPD mode */
2191 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2192 { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
2193 { }
2194 }
2195 },
Takashi Iwai8812c4f2011-11-09 17:39:15 +01002196 [ALC883_FIXUP_ACER_EAPD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002197 .type = HDA_FIXUP_VERBS,
Takashi Iwai8812c4f2011-11-09 17:39:15 +01002198 .v.verbs = (const struct hda_verb[]) {
2199 /* eanable EAPD on Acer laptops */
2200 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2201 { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
2202 { }
2203 }
2204 },
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002205 [ALC882_FIXUP_GPIO1] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02002206 .type = HDA_FIXUP_FUNC,
2207 .v.func = alc_fixup_gpio1,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002208 },
2209 [ALC882_FIXUP_GPIO2] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02002210 .type = HDA_FIXUP_FUNC,
2211 .v.func = alc_fixup_gpio2,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002212 },
Takashi Iwaieb844d52011-11-09 18:03:07 +01002213 [ALC882_FIXUP_GPIO3] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02002214 .type = HDA_FIXUP_FUNC,
2215 .v.func = alc_fixup_gpio3,
Takashi Iwaieb844d52011-11-09 18:03:07 +01002216 },
Takashi Iwai68ef0562011-11-09 18:24:44 +01002217 [ALC882_FIXUP_ASUS_W2JC] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02002218 .type = HDA_FIXUP_FUNC,
2219 .v.func = alc_fixup_gpio1,
Takashi Iwai68ef0562011-11-09 18:24:44 +01002220 .chained = true,
2221 .chain_id = ALC882_FIXUP_EAPD,
2222 },
2223 [ALC889_FIXUP_COEF] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002224 .type = HDA_FIXUP_FUNC,
Takashi Iwai68ef0562011-11-09 18:24:44 +01002225 .v.func = alc889_fixup_coef,
2226 },
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002227 [ALC882_FIXUP_ACER_ASPIRE_4930G] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002228 .type = HDA_FIXUP_PINS,
2229 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002230 { 0x16, 0x99130111 }, /* CLFE speaker */
2231 { 0x17, 0x99130112 }, /* surround speaker */
2232 { }
Takashi Iwai038d4fe2012-04-11 17:18:12 +02002233 },
2234 .chained = true,
2235 .chain_id = ALC882_FIXUP_GPIO1,
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002236 },
2237 [ALC882_FIXUP_ACER_ASPIRE_8930G] = {
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 { 0x1b, 0x99130112 }, /* surround speaker */
2242 { }
2243 },
2244 .chained = true,
2245 .chain_id = ALC882_FIXUP_ASPIRE_8930G_VERBS,
2246 },
2247 [ALC882_FIXUP_ASPIRE_8930G_VERBS] = {
2248 /* additional init verbs for Acer Aspire 8930G */
Takashi Iwai1727a772013-01-10 09:52:52 +01002249 .type = HDA_FIXUP_VERBS,
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002250 .v.verbs = (const struct hda_verb[]) {
2251 /* Enable all DACs */
2252 /* DAC DISABLE/MUTE 1? */
2253 /* setting bits 1-5 disables DAC nids 0x02-0x06
2254 * apparently. Init=0x38 */
2255 { 0x20, AC_VERB_SET_COEF_INDEX, 0x03 },
2256 { 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
2257 /* DAC DISABLE/MUTE 2? */
2258 /* some bit here disables the other DACs.
2259 * Init=0x4900 */
2260 { 0x20, AC_VERB_SET_COEF_INDEX, 0x08 },
2261 { 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
2262 /* DMIC fix
2263 * This laptop has a stereo digital microphone.
2264 * The mics are only 1cm apart which makes the stereo
2265 * useless. However, either the mic or the ALC889
2266 * makes the signal become a difference/sum signal
2267 * instead of standard stereo, which is annoying.
2268 * So instead we flip this bit which makes the
2269 * codec replicate the sum signal to both channels,
2270 * turning it into a normal mono mic.
2271 */
2272 /* DMIC_CONTROL? Init value = 0x0001 */
2273 { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b },
2274 { 0x20, AC_VERB_SET_PROC_COEF, 0x0003 },
2275 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2276 { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
2277 { }
Takashi Iwai038d4fe2012-04-11 17:18:12 +02002278 },
2279 .chained = true,
2280 .chain_id = ALC882_FIXUP_GPIO1,
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002281 },
Takashi Iwai56710872011-11-14 17:42:11 +01002282 [ALC885_FIXUP_MACPRO_GPIO] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002283 .type = HDA_FIXUP_FUNC,
Takashi Iwai56710872011-11-14 17:42:11 +01002284 .v.func = alc885_fixup_macpro_gpio,
2285 },
Takashi Iwai02a237b2012-02-13 15:25:07 +01002286 [ALC889_FIXUP_DAC_ROUTE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002287 .type = HDA_FIXUP_FUNC,
Takashi Iwai02a237b2012-02-13 15:25:07 +01002288 .v.func = alc889_fixup_dac_route,
2289 },
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002290 [ALC889_FIXUP_MBP_VREF] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002291 .type = HDA_FIXUP_FUNC,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002292 .v.func = alc889_fixup_mbp_vref,
2293 .chained = true,
2294 .chain_id = ALC882_FIXUP_GPIO1,
2295 },
2296 [ALC889_FIXUP_IMAC91_VREF] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002297 .type = HDA_FIXUP_FUNC,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002298 .v.func = alc889_fixup_imac91_vref,
2299 .chained = true,
2300 .chain_id = ALC882_FIXUP_GPIO1,
2301 },
Adrien Vergée7729a42014-01-24 14:56:14 -05002302 [ALC889_FIXUP_MBA11_VREF] = {
2303 .type = HDA_FIXUP_FUNC,
2304 .v.func = alc889_fixup_mba11_vref,
2305 .chained = true,
2306 .chain_id = ALC889_FIXUP_MBP_VREF,
2307 },
Takashi Iwai0756f092013-12-04 13:59:45 +01002308 [ALC889_FIXUP_MBA21_VREF] = {
2309 .type = HDA_FIXUP_FUNC,
2310 .v.func = alc889_fixup_mba21_vref,
2311 .chained = true,
2312 .chain_id = ALC889_FIXUP_MBP_VREF,
2313 },
Takashi Iwaic20f31e2014-02-03 11:02:10 +01002314 [ALC889_FIXUP_MP11_VREF] = {
2315 .type = HDA_FIXUP_FUNC,
2316 .v.func = alc889_fixup_mba11_vref,
2317 .chained = true,
2318 .chain_id = ALC885_FIXUP_MACPRO_GPIO,
2319 },
Mario Kleiner9f660a12015-12-22 00:45:43 +01002320 [ALC889_FIXUP_MP41_VREF] = {
2321 .type = HDA_FIXUP_FUNC,
2322 .v.func = alc889_fixup_mbp_vref,
2323 .chained = true,
2324 .chain_id = ALC885_FIXUP_MACPRO_GPIO,
2325 },
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002326 [ALC882_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002327 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02002328 .v.func = alc_fixup_inv_dmic,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002329 },
Takashi Iwaie427c232012-07-29 10:04:08 +02002330 [ALC882_FIXUP_NO_PRIMARY_HP] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002331 .type = HDA_FIXUP_FUNC,
Takashi Iwaie427c232012-07-29 10:04:08 +02002332 .v.func = alc882_fixup_no_primary_hp,
2333 },
Takashi Iwai1f0bbf02013-11-28 15:21:21 +01002334 [ALC887_FIXUP_ASUS_BASS] = {
2335 .type = HDA_FIXUP_PINS,
2336 .v.pins = (const struct hda_pintbl[]) {
2337 {0x16, 0x99130130}, /* bass speaker */
2338 {}
2339 },
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01002340 .chained = true,
2341 .chain_id = ALC887_FIXUP_BASS_CHMAP,
2342 },
2343 [ALC887_FIXUP_BASS_CHMAP] = {
2344 .type = HDA_FIXUP_FUNC,
2345 .v.func = alc_fixup_bass_chmap,
Takashi Iwai1f0bbf02013-11-28 15:21:21 +01002346 },
Takashi Iwai7beb3a62017-04-10 18:05:52 +02002347 [ALC1220_FIXUP_GB_DUAL_CODECS] = {
2348 .type = HDA_FIXUP_FUNC,
2349 .v.func = alc1220_fixup_gb_dual_codecs,
2350 },
Peisen0202f5c2017-10-26 10:35:36 +08002351 [ALC1220_FIXUP_CLEVO_P950] = {
2352 .type = HDA_FIXUP_FUNC,
2353 .v.func = alc1220_fixup_clevo_p950,
2354 },
Richard Sailer80690a22019-04-02 15:52:04 +02002355 [ALC1220_FIXUP_CLEVO_PB51ED] = {
Jeremy Soller7f665b12019-02-13 10:56:19 -07002356 .type = HDA_FIXUP_FUNC,
Richard Sailer80690a22019-04-02 15:52:04 +02002357 .v.func = alc1220_fixup_clevo_pb51ed,
Jeremy Soller7f665b12019-02-13 10:56:19 -07002358 },
Richard Sailer80690a22019-04-02 15:52:04 +02002359 [ALC1220_FIXUP_CLEVO_PB51ED_PINS] = {
Jeremy Soller7f665b12019-02-13 10:56:19 -07002360 .type = HDA_FIXUP_PINS,
2361 .v.pins = (const struct hda_pintbl[]) {
2362 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
2363 {}
2364 },
2365 .chained = true,
Richard Sailer80690a22019-04-02 15:52:04 +02002366 .chain_id = ALC1220_FIXUP_CLEVO_PB51ED,
Jeremy Soller7f665b12019-02-13 10:56:19 -07002367 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02002368};
2369
2370static const struct snd_pci_quirk alc882_fixup_tbl[] = {
Takashi Iwai8812c4f2011-11-09 17:39:15 +01002371 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_FIXUP_ACER_EAPD),
2372 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
Takashi Iwaib5d724b2015-06-02 19:57:08 +02002373 SND_PCI_QUIRK(0x1025, 0x0107, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
Takashi Iwai8812c4f2011-11-09 17:39:15 +01002374 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_FIXUP_ACER_EAPD),
2375 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
2376 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_FIXUP_ACER_EAPD),
2377 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_FIXUP_ACER_EAPD),
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002378 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
2379 ALC882_FIXUP_ACER_ASPIRE_4930G),
2380 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
2381 ALC882_FIXUP_ACER_ASPIRE_4930G),
2382 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
2383 ALC882_FIXUP_ACER_ASPIRE_8930G),
2384 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
2385 ALC882_FIXUP_ACER_ASPIRE_8930G),
2386 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
2387 ALC882_FIXUP_ACER_ASPIRE_4930G),
2388 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
2389 ALC882_FIXUP_ACER_ASPIRE_4930G),
2390 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
2391 ALC882_FIXUP_ACER_ASPIRE_4930G),
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002392 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", ALC882_FIXUP_PB_M5210),
Takashi Iwaif5c53d82012-05-07 10:07:33 +02002393 SND_PCI_QUIRK(0x1025, 0x021e, "Acer Aspire 5739G",
2394 ALC882_FIXUP_ACER_ASPIRE_4930G),
Takashi Iwai02a237b2012-02-13 15:25:07 +01002395 SND_PCI_QUIRK(0x1025, 0x0259, "Acer Aspire 5935", ALC889_FIXUP_DAC_ROUTE),
Takashi Iwaife97da12012-04-12 08:00:19 +02002396 SND_PCI_QUIRK(0x1025, 0x026b, "Acer Aspire 8940G", ALC882_FIXUP_ACER_ASPIRE_8930G),
Takashi Iwaiac9b1cd2011-11-09 17:45:55 +01002397 SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", ALC882_FIXUP_ACER_ASPIRE_7736),
Takashi Iwai177943a32011-11-09 12:55:18 +01002398 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_FIXUP_EAPD),
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002399 SND_PCI_QUIRK(0x1043, 0x1873, "ASUS W90V", ALC882_FIXUP_ASUS_W90V),
Takashi Iwai68ef0562011-11-09 18:24:44 +01002400 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_FIXUP_ASUS_W2JC),
Takashi Iwai0e7cc2e2011-11-09 12:42:48 +01002401 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_FIXUP_EEE1601),
Takashi Iwai1f0bbf02013-11-28 15:21:21 +01002402 SND_PCI_QUIRK(0x1043, 0x84bc, "ASUS ET2700", ALC887_FIXUP_ASUS_BASS),
Takashi Iwai85bcf962016-12-06 16:20:36 +01002403 SND_PCI_QUIRK(0x1043, 0x8691, "ASUS ROG Ranger VIII", ALC882_FIXUP_GPIO3),
Takashi Iwaiac9b1cd2011-11-09 17:45:55 +01002404 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT),
Takashi Iwaie427c232012-07-29 10:04:08 +02002405 SND_PCI_QUIRK(0x104d, 0x905a, "Sony Vaio Z", ALC882_FIXUP_NO_PRIMARY_HP),
Sergei A. Trusov3f3c3712017-08-02 20:23:48 +10002406 SND_PCI_QUIRK(0x104d, 0x9060, "Sony Vaio VPCL14M1R", ALC882_FIXUP_NO_PRIMARY_HP),
Fernando Luis Vázquez Cao12e31a72013-02-12 16:47:44 +09002407 SND_PCI_QUIRK(0x104d, 0x9043, "Sony Vaio VGC-LN51JGB", ALC882_FIXUP_NO_PRIMARY_HP),
Takashi Iwaic44d9b12016-02-07 09:38:26 +01002408 SND_PCI_QUIRK(0x104d, 0x9044, "Sony VAIO AiO", ALC882_FIXUP_NO_PRIMARY_HP),
Takashi Iwai56710872011-11-14 17:42:11 +01002409
2410 /* All Apple entries are in codec SSIDs */
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002411 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC889_FIXUP_MBP_VREF),
2412 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC889_FIXUP_MBP_VREF),
2413 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF),
Takashi Iwaic20f31e2014-02-03 11:02:10 +01002414 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC889_FIXUP_MP11_VREF),
Takashi Iwai56710872011-11-14 17:42:11 +01002415 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_FIXUP_MACPRO_GPIO),
2416 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_FIXUP_MACPRO_GPIO),
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002417 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC889_FIXUP_MBP_VREF),
2418 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889_FIXUP_MBP_VREF),
Takashi Iwai56710872011-11-14 17:42:11 +01002419 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_FIXUP_EAPD),
Adrien Vergée7729a42014-01-24 14:56:14 -05002420 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC889_FIXUP_MBA11_VREF),
Takashi Iwai0756f092013-12-04 13:59:45 +01002421 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC889_FIXUP_MBA21_VREF),
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002422 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889_FIXUP_MBP_VREF),
2423 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF),
Takashi Iwai56710872011-11-14 17:42:11 +01002424 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_FIXUP_MACPRO_GPIO),
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002425 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC889_FIXUP_IMAC91_VREF),
2426 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC889_FIXUP_IMAC91_VREF),
2427 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC889_FIXUP_IMAC91_VREF),
Mario Kleiner9f660a12015-12-22 00:45:43 +01002428 SND_PCI_QUIRK(0x106b, 0x4200, "Mac Pro 4,1/5,1", ALC889_FIXUP_MP41_VREF),
Takashi Iwai05193632012-11-12 10:07:36 +01002429 SND_PCI_QUIRK(0x106b, 0x4300, "iMac 9,1", ALC889_FIXUP_IMAC91_VREF),
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002430 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC889_FIXUP_IMAC91_VREF),
2431 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC889_FIXUP_IMAC91_VREF),
Takashi Iwai649ccd02015-07-30 22:30:29 +02002432 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC889_FIXUP_MBA11_VREF),
Takashi Iwai56710872011-11-14 17:42:11 +01002433
Takashi Iwai7a6069b2011-11-09 15:22:01 +01002434 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC882_FIXUP_EAPD),
David Henningssonb2c53e22014-01-01 14:01:34 +01002435 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3/Z87X-UD3H", ALC889_FIXUP_FRONT_HP_NO_PRESENCE),
Takashi Iwai7beb3a62017-04-10 18:05:52 +02002436 SND_PCI_QUIRK(0x1458, 0xa0b8, "Gigabyte AZ370-Gaming", ALC1220_FIXUP_GB_DUAL_CODECS),
Takashi Iwaid2c3b142017-06-01 09:35:30 +02002437 SND_PCI_QUIRK(0x1462, 0x7350, "MSI-7350", ALC889_FIXUP_CD),
Takashi Iwai63691582017-05-22 16:32:46 +02002438 SND_PCI_QUIRK(0x1462, 0xda57, "MSI Z270-Gaming", ALC1220_FIXUP_GB_DUAL_CODECS),
Takashi Iwaid2c3b142017-06-01 09:35:30 +02002439 SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3),
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002440 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX),
Peisen0202f5c2017-10-26 10:35:36 +08002441 SND_PCI_QUIRK(0x1558, 0x9501, "Clevo P950HR", ALC1220_FIXUP_CLEVO_P950),
Takashi Iwaif3d737b2018-07-17 17:08:32 +02002442 SND_PCI_QUIRK(0x1558, 0x95e1, "Clevo P95xER", ALC1220_FIXUP_CLEVO_P950),
Jeremy Soller2f0d5202018-05-07 09:28:45 -06002443 SND_PCI_QUIRK(0x1558, 0x95e2, "Clevo P950ER", ALC1220_FIXUP_CLEVO_P950),
Richard Sailer503d90b2019-06-19 13:33:11 +02002444 SND_PCI_QUIRK(0x1558, 0x96e1, "Clevo P960[ER][CDFN]-K", ALC1220_FIXUP_CLEVO_P950),
2445 SND_PCI_QUIRK(0x1558, 0x97e1, "Clevo P970[ER][CDFN]", ALC1220_FIXUP_CLEVO_P950),
2446 SND_PCI_QUIRK(0x1558, 0x65d1, "Clevo PB51[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
2447 SND_PCI_QUIRK(0x1558, 0x67d1, "Clevo PB71[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
Takashi Iwai7a6069b2011-11-09 15:22:01 +01002448 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD),
2449 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD),
Takashi Iwaiac9b1cd2011-11-09 17:45:55 +01002450 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", ALC882_FIXUP_LENOVO_Y530),
Takashi Iwai68ef0562011-11-09 18:24:44 +01002451 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_FIXUP_COEF),
Takashi Iwai1d045db2011-07-07 18:23:21 +02002452 {}
2453};
2454
Takashi Iwai1727a772013-01-10 09:52:52 +01002455static const struct hda_model_fixup alc882_fixup_models[] = {
Takashi Iwai772c2912018-06-26 17:17:53 +02002456 {.id = ALC882_FIXUP_ABIT_AW9D_MAX, .name = "abit-aw9d"},
2457 {.id = ALC882_FIXUP_LENOVO_Y530, .name = "lenovo-y530"},
2458 {.id = ALC882_FIXUP_ACER_ASPIRE_7736, .name = "acer-aspire-7736"},
2459 {.id = ALC882_FIXUP_ASUS_W90V, .name = "asus-w90v"},
2460 {.id = ALC889_FIXUP_CD, .name = "cd"},
2461 {.id = ALC889_FIXUP_FRONT_HP_NO_PRESENCE, .name = "no-front-hp"},
2462 {.id = ALC889_FIXUP_VAIO_TT, .name = "vaio-tt"},
2463 {.id = ALC888_FIXUP_EEE1601, .name = "eee1601"},
2464 {.id = ALC882_FIXUP_EAPD, .name = "alc882-eapd"},
2465 {.id = ALC883_FIXUP_EAPD, .name = "alc883-eapd"},
2466 {.id = ALC882_FIXUP_GPIO1, .name = "gpio1"},
2467 {.id = ALC882_FIXUP_GPIO2, .name = "gpio2"},
2468 {.id = ALC882_FIXUP_GPIO3, .name = "gpio3"},
2469 {.id = ALC889_FIXUP_COEF, .name = "alc889-coef"},
2470 {.id = ALC882_FIXUP_ASUS_W2JC, .name = "asus-w2jc"},
Takashi Iwai912093b2012-04-11 14:03:41 +02002471 {.id = ALC882_FIXUP_ACER_ASPIRE_4930G, .name = "acer-aspire-4930g"},
2472 {.id = ALC882_FIXUP_ACER_ASPIRE_8930G, .name = "acer-aspire-8930g"},
2473 {.id = ALC883_FIXUP_ACER_EAPD, .name = "acer-aspire"},
Takashi Iwai772c2912018-06-26 17:17:53 +02002474 {.id = ALC885_FIXUP_MACPRO_GPIO, .name = "macpro-gpio"},
2475 {.id = ALC889_FIXUP_DAC_ROUTE, .name = "dac-route"},
2476 {.id = ALC889_FIXUP_MBP_VREF, .name = "mbp-vref"},
2477 {.id = ALC889_FIXUP_IMAC91_VREF, .name = "imac91-vref"},
2478 {.id = ALC889_FIXUP_MBA11_VREF, .name = "mba11-vref"},
2479 {.id = ALC889_FIXUP_MBA21_VREF, .name = "mba21-vref"},
2480 {.id = ALC889_FIXUP_MP11_VREF, .name = "mp11-vref"},
2481 {.id = ALC889_FIXUP_MP41_VREF, .name = "mp41-vref"},
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002482 {.id = ALC882_FIXUP_INV_DMIC, .name = "inv-dmic"},
Takashi Iwaie427c232012-07-29 10:04:08 +02002483 {.id = ALC882_FIXUP_NO_PRIMARY_HP, .name = "no-primary-hp"},
Takashi Iwai772c2912018-06-26 17:17:53 +02002484 {.id = ALC887_FIXUP_ASUS_BASS, .name = "asus-bass"},
Takashi Iwaiba90d6a2017-05-22 16:38:47 +02002485 {.id = ALC1220_FIXUP_GB_DUAL_CODECS, .name = "dual-codecs"},
Takashi Iwai772c2912018-06-26 17:17:53 +02002486 {.id = ALC1220_FIXUP_CLEVO_P950, .name = "clevo-p950"},
Takashi Iwai912093b2012-04-11 14:03:41 +02002487 {}
2488};
2489
Takashi Iwai1d045db2011-07-07 18:23:21 +02002490/*
2491 * BIOS auto configuration
2492 */
2493/* almost identical with ALC880 parser... */
2494static int alc882_parse_auto_config(struct hda_codec *codec)
2495{
Takashi Iwai1d045db2011-07-07 18:23:21 +02002496 static const hda_nid_t alc882_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002497 static const hda_nid_t alc882_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2498 return alc_parse_auto_config(codec, alc882_ignore, alc882_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002499}
2500
Takashi Iwai1d045db2011-07-07 18:23:21 +02002501/*
2502 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002503static int patch_alc882(struct hda_codec *codec)
2504{
2505 struct alc_spec *spec;
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002506 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002507
Takashi Iwai3de95172012-05-07 18:03:15 +02002508 err = alc_alloc_spec(codec, 0x0b);
2509 if (err < 0)
2510 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002511
Takashi Iwai3de95172012-05-07 18:03:15 +02002512 spec = codec->spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002513
Takashi Iwai7639a062015-03-03 10:07:24 +01002514 switch (codec->core.vendor_id) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002515 case 0x10ec0882:
2516 case 0x10ec0885:
Takashi Iwaiacf08082014-09-02 07:21:56 +02002517 case 0x10ec0900:
Kailang Yanga535ad52017-01-16 16:59:26 +08002518 case 0x10ec1220:
Takashi Iwai1d045db2011-07-07 18:23:21 +02002519 break;
2520 default:
2521 /* ALC883 and variants */
2522 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
2523 break;
2524 }
2525
Takashi Iwaic9af7532019-05-10 11:01:43 +02002526 alc_pre_init(codec);
2527
Takashi Iwai1727a772013-01-10 09:52:52 +01002528 snd_hda_pick_fixup(codec, alc882_fixup_models, alc882_fixup_tbl,
Takashi Iwai912093b2012-04-11 14:03:41 +02002529 alc882_fixups);
Takashi Iwai1727a772013-01-10 09:52:52 +01002530 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002531
2532 alc_auto_parse_customize_define(codec);
2533
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002534 if (has_cdefine_beep(codec))
2535 spec->gen.beep_nid = 0x01;
2536
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002537 /* automatic parse from the BIOS config */
2538 err = alc882_parse_auto_config(codec);
2539 if (err < 0)
2540 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002541
Takashi Iwaifea80fa2018-06-20 12:52:46 +02002542 if (!spec->gen.no_analog && spec->gen.beep_nid) {
2543 err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
2544 if (err < 0)
2545 goto error;
2546 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02002547
Takashi Iwai1727a772013-01-10 09:52:52 +01002548 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01002549
Takashi Iwai1d045db2011-07-07 18:23:21 +02002550 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02002551
2552 error:
2553 alc_free(codec);
2554 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002555}
2556
2557
2558/*
2559 * ALC262 support
2560 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002561static int alc262_parse_auto_config(struct hda_codec *codec)
2562{
Takashi Iwai1d045db2011-07-07 18:23:21 +02002563 static const hda_nid_t alc262_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002564 static const hda_nid_t alc262_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2565 return alc_parse_auto_config(codec, alc262_ignore, alc262_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002566}
2567
2568/*
2569 * Pin config fixes
2570 */
2571enum {
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002572 ALC262_FIXUP_FSC_H270,
Takashi Iwai7513e6d2013-01-18 15:41:34 +01002573 ALC262_FIXUP_FSC_S7110,
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002574 ALC262_FIXUP_HP_Z200,
2575 ALC262_FIXUP_TYAN,
Takashi Iwaic4701502011-11-07 14:20:07 +01002576 ALC262_FIXUP_LENOVO_3000,
Takashi Iwaib42590b2011-11-07 14:41:01 +01002577 ALC262_FIXUP_BENQ,
2578 ALC262_FIXUP_BENQ_T31,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002579 ALC262_FIXUP_INV_DMIC,
Mengdong Linb5c66112013-11-29 00:35:35 -05002580 ALC262_FIXUP_INTEL_BAYLEYBAY,
Takashi Iwai1d045db2011-07-07 18:23:21 +02002581};
2582
Takashi Iwai1727a772013-01-10 09:52:52 +01002583static const struct hda_fixup alc262_fixups[] = {
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002584 [ALC262_FIXUP_FSC_H270] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002585 .type = HDA_FIXUP_PINS,
2586 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002587 { 0x14, 0x99130110 }, /* speaker */
2588 { 0x15, 0x0221142f }, /* front HP */
2589 { 0x1b, 0x0121141f }, /* rear HP */
2590 { }
2591 }
2592 },
Takashi Iwai7513e6d2013-01-18 15:41:34 +01002593 [ALC262_FIXUP_FSC_S7110] = {
2594 .type = HDA_FIXUP_PINS,
2595 .v.pins = (const struct hda_pintbl[]) {
2596 { 0x15, 0x90170110 }, /* speaker */
2597 { }
2598 },
2599 .chained = true,
2600 .chain_id = ALC262_FIXUP_BENQ,
2601 },
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002602 [ALC262_FIXUP_HP_Z200] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002603 .type = HDA_FIXUP_PINS,
2604 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002605 { 0x16, 0x99130120 }, /* internal speaker */
2606 { }
2607 }
2608 },
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002609 [ALC262_FIXUP_TYAN] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002610 .type = HDA_FIXUP_PINS,
2611 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002612 { 0x14, 0x1993e1f0 }, /* int AUX */
2613 { }
2614 }
2615 },
Takashi Iwaic4701502011-11-07 14:20:07 +01002616 [ALC262_FIXUP_LENOVO_3000] = {
Takashi Iwaifd108212013-01-10 10:18:14 +01002617 .type = HDA_FIXUP_PINCTLS,
2618 .v.pins = (const struct hda_pintbl[]) {
2619 { 0x19, PIN_VREF50 },
Takashi Iwaib42590b2011-11-07 14:41:01 +01002620 {}
2621 },
2622 .chained = true,
2623 .chain_id = ALC262_FIXUP_BENQ,
2624 },
2625 [ALC262_FIXUP_BENQ] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002626 .type = HDA_FIXUP_VERBS,
Takashi Iwaib42590b2011-11-07 14:41:01 +01002627 .v.verbs = (const struct hda_verb[]) {
Takashi Iwaic4701502011-11-07 14:20:07 +01002628 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2629 { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
2630 {}
2631 }
2632 },
Takashi Iwaib42590b2011-11-07 14:41:01 +01002633 [ALC262_FIXUP_BENQ_T31] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002634 .type = HDA_FIXUP_VERBS,
Takashi Iwaib42590b2011-11-07 14:41:01 +01002635 .v.verbs = (const struct hda_verb[]) {
2636 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2637 { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
2638 {}
2639 }
2640 },
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002641 [ALC262_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002642 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02002643 .v.func = alc_fixup_inv_dmic,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002644 },
Mengdong Linb5c66112013-11-29 00:35:35 -05002645 [ALC262_FIXUP_INTEL_BAYLEYBAY] = {
2646 .type = HDA_FIXUP_FUNC,
2647 .v.func = alc_fixup_no_depop_delay,
2648 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02002649};
2650
2651static const struct snd_pci_quirk alc262_fixup_tbl[] = {
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002652 SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", ALC262_FIXUP_HP_Z200),
Takashi Iwai7513e6d2013-01-18 15:41:34 +01002653 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu Lifebook S7110", ALC262_FIXUP_FSC_S7110),
Takashi Iwai3dcd3be2011-11-07 14:59:40 +01002654 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FIXUP_BENQ),
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002655 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_FIXUP_TYAN),
Takashi Iwai275ec0c2018-06-22 12:17:45 +02002656 SND_PCI_QUIRK(0x1734, 0x1141, "FSC ESPRIMO U9210", ALC262_FIXUP_FSC_H270),
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002657 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", ALC262_FIXUP_FSC_H270),
Takashi Iwaic4701502011-11-07 14:20:07 +01002658 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000", ALC262_FIXUP_LENOVO_3000),
Takashi Iwaib42590b2011-11-07 14:41:01 +01002659 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_FIXUP_BENQ),
2660 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_FIXUP_BENQ_T31),
Mengdong Linb5c66112013-11-29 00:35:35 -05002661 SND_PCI_QUIRK(0x8086, 0x7270, "BayleyBay", ALC262_FIXUP_INTEL_BAYLEYBAY),
Takashi Iwai1d045db2011-07-07 18:23:21 +02002662 {}
2663};
2664
Takashi Iwai1727a772013-01-10 09:52:52 +01002665static const struct hda_model_fixup alc262_fixup_models[] = {
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002666 {.id = ALC262_FIXUP_INV_DMIC, .name = "inv-dmic"},
Takashi Iwaie43c44d2018-06-26 17:02:08 +02002667 {.id = ALC262_FIXUP_FSC_H270, .name = "fsc-h270"},
2668 {.id = ALC262_FIXUP_FSC_S7110, .name = "fsc-s7110"},
2669 {.id = ALC262_FIXUP_HP_Z200, .name = "hp-z200"},
2670 {.id = ALC262_FIXUP_TYAN, .name = "tyan"},
2671 {.id = ALC262_FIXUP_LENOVO_3000, .name = "lenovo-3000"},
2672 {.id = ALC262_FIXUP_BENQ, .name = "benq"},
2673 {.id = ALC262_FIXUP_BENQ_T31, .name = "benq-t31"},
2674 {.id = ALC262_FIXUP_INTEL_BAYLEYBAY, .name = "bayleybay"},
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002675 {}
2676};
Takashi Iwai1d045db2011-07-07 18:23:21 +02002677
Takashi Iwai1d045db2011-07-07 18:23:21 +02002678/*
2679 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002680static int patch_alc262(struct hda_codec *codec)
2681{
2682 struct alc_spec *spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002683 int err;
2684
Takashi Iwai3de95172012-05-07 18:03:15 +02002685 err = alc_alloc_spec(codec, 0x0b);
2686 if (err < 0)
2687 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002688
Takashi Iwai3de95172012-05-07 18:03:15 +02002689 spec = codec->spec;
Takashi Iwai08c189f2012-12-19 15:22:24 +01002690 spec->gen.shared_mic_vref_pin = 0x18;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002691
Takashi Iwai225068a2015-05-29 10:42:14 +02002692 spec->shutup = alc_eapd_shutup;
2693
Takashi Iwai1d045db2011-07-07 18:23:21 +02002694#if 0
2695 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
2696 * under-run
2697 */
Takashi Iwai98b24882014-08-18 13:47:50 +02002698 alc_update_coefex_idx(codec, 0x1a, 7, 0, 0x80);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002699#endif
Takashi Iwai1d045db2011-07-07 18:23:21 +02002700 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
2701
Takashi Iwaic9af7532019-05-10 11:01:43 +02002702 alc_pre_init(codec);
2703
Takashi Iwai1727a772013-01-10 09:52:52 +01002704 snd_hda_pick_fixup(codec, alc262_fixup_models, alc262_fixup_tbl,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002705 alc262_fixups);
Takashi Iwai1727a772013-01-10 09:52:52 +01002706 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002707
Takashi Iwaiaf741c12012-05-07 18:09:48 +02002708 alc_auto_parse_customize_define(codec);
2709
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002710 if (has_cdefine_beep(codec))
2711 spec->gen.beep_nid = 0x01;
2712
Takashi Iwai42399f72011-11-07 17:18:44 +01002713 /* automatic parse from the BIOS config */
2714 err = alc262_parse_auto_config(codec);
2715 if (err < 0)
2716 goto error;
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002717
Takashi Iwaifea80fa2018-06-20 12:52:46 +02002718 if (!spec->gen.no_analog && spec->gen.beep_nid) {
2719 err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
2720 if (err < 0)
2721 goto error;
2722 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02002723
Takashi Iwai1727a772013-01-10 09:52:52 +01002724 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01002725
Takashi Iwai1d045db2011-07-07 18:23:21 +02002726 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02002727
2728 error:
2729 alc_free(codec);
2730 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002731}
2732
2733/*
2734 * ALC268
2735 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002736/* bind Beep switches of both NID 0x0f and 0x10 */
Takashi Iwaia7177772017-05-10 12:04:08 +02002737static int alc268_beep_switch_put(struct snd_kcontrol *kcontrol,
2738 struct snd_ctl_elem_value *ucontrol)
2739{
2740 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2741 unsigned long pval;
2742 int err;
2743
2744 mutex_lock(&codec->control_mutex);
2745 pval = kcontrol->private_value;
2746 kcontrol->private_value = (pval & ~0xff) | 0x0f;
2747 err = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
2748 if (err >= 0) {
2749 kcontrol->private_value = (pval & ~0xff) | 0x10;
2750 err = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
2751 }
2752 kcontrol->private_value = pval;
2753 mutex_unlock(&codec->control_mutex);
2754 return err;
2755}
Takashi Iwai1d045db2011-07-07 18:23:21 +02002756
2757static const struct snd_kcontrol_new alc268_beep_mixer[] = {
2758 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
Takashi Iwaia7177772017-05-10 12:04:08 +02002759 {
2760 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2761 .name = "Beep Playback Switch",
2762 .subdevice = HDA_SUBDEV_AMP_FLAG,
2763 .info = snd_hda_mixer_amp_switch_info,
2764 .get = snd_hda_mixer_amp_switch_get,
2765 .put = alc268_beep_switch_put,
2766 .private_value = HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT)
2767 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02002768};
2769
2770/* set PCBEEP vol = 0, mute connections */
2771static const struct hda_verb alc268_beep_init_verbs[] = {
2772 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2773 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2774 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2775 { }
2776};
2777
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002778enum {
2779 ALC268_FIXUP_INV_DMIC,
Takashi Iwaicb766402012-10-20 10:55:21 +02002780 ALC268_FIXUP_HP_EAPD,
Takashi Iwai24eff322013-11-04 18:21:08 +01002781 ALC268_FIXUP_SPDIF,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002782};
2783
Takashi Iwai1727a772013-01-10 09:52:52 +01002784static const struct hda_fixup alc268_fixups[] = {
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002785 [ALC268_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002786 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02002787 .v.func = alc_fixup_inv_dmic,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002788 },
Takashi Iwaicb766402012-10-20 10:55:21 +02002789 [ALC268_FIXUP_HP_EAPD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002790 .type = HDA_FIXUP_VERBS,
Takashi Iwaicb766402012-10-20 10:55:21 +02002791 .v.verbs = (const struct hda_verb[]) {
2792 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 0},
2793 {}
2794 }
2795 },
Takashi Iwai24eff322013-11-04 18:21:08 +01002796 [ALC268_FIXUP_SPDIF] = {
2797 .type = HDA_FIXUP_PINS,
2798 .v.pins = (const struct hda_pintbl[]) {
2799 { 0x1e, 0x014b1180 }, /* enable SPDIF out */
2800 {}
2801 }
2802 },
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002803};
2804
Takashi Iwai1727a772013-01-10 09:52:52 +01002805static const struct hda_model_fixup alc268_fixup_models[] = {
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002806 {.id = ALC268_FIXUP_INV_DMIC, .name = "inv-dmic"},
Takashi Iwaicb766402012-10-20 10:55:21 +02002807 {.id = ALC268_FIXUP_HP_EAPD, .name = "hp-eapd"},
Takashi Iwai03bf11c2018-06-26 16:56:41 +02002808 {.id = ALC268_FIXUP_SPDIF, .name = "spdif"},
Takashi Iwaicb766402012-10-20 10:55:21 +02002809 {}
2810};
2811
2812static const struct snd_pci_quirk alc268_fixup_tbl[] = {
Takashi Iwai24eff322013-11-04 18:21:08 +01002813 SND_PCI_QUIRK(0x1025, 0x0139, "Acer TravelMate 6293", ALC268_FIXUP_SPDIF),
David Henningssonfcd8f3b2013-01-28 05:45:47 +01002814 SND_PCI_QUIRK(0x1025, 0x015b, "Acer AOA 150 (ZG5)", ALC268_FIXUP_INV_DMIC),
Takashi Iwaicb766402012-10-20 10:55:21 +02002815 /* below is codec SSID since multiple Toshiba laptops have the
2816 * same PCI SSID 1179:ff00
2817 */
2818 SND_PCI_QUIRK(0x1179, 0xff06, "Toshiba P200", ALC268_FIXUP_HP_EAPD),
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002819 {}
2820};
2821
Takashi Iwai1d045db2011-07-07 18:23:21 +02002822/*
2823 * BIOS auto configuration
2824 */
2825static int alc268_parse_auto_config(struct hda_codec *codec)
2826{
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002827 static const hda_nid_t alc268_ssids[] = { 0x15, 0x1b, 0x14, 0 };
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002828 return alc_parse_auto_config(codec, NULL, alc268_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002829}
2830
Takashi Iwai1d045db2011-07-07 18:23:21 +02002831/*
2832 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002833static int patch_alc268(struct hda_codec *codec)
2834{
2835 struct alc_spec *spec;
Takashi Iwaia5cb4632018-06-20 12:50:11 +02002836 int i, err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002837
Takashi Iwai1d045db2011-07-07 18:23:21 +02002838 /* ALC268 has no aa-loopback mixer */
Takashi Iwai3de95172012-05-07 18:03:15 +02002839 err = alc_alloc_spec(codec, 0);
2840 if (err < 0)
2841 return err;
2842
2843 spec = codec->spec;
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002844 spec->gen.beep_nid = 0x01;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002845
Takashi Iwai225068a2015-05-29 10:42:14 +02002846 spec->shutup = alc_eapd_shutup;
2847
Takashi Iwaic9af7532019-05-10 11:01:43 +02002848 alc_pre_init(codec);
2849
Takashi Iwai1727a772013-01-10 09:52:52 +01002850 snd_hda_pick_fixup(codec, alc268_fixup_models, alc268_fixup_tbl, alc268_fixups);
2851 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002852
Takashi Iwai6ebb8052011-08-16 15:15:40 +02002853 /* automatic parse from the BIOS config */
2854 err = alc268_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02002855 if (err < 0)
2856 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002857
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002858 if (err > 0 && !spec->gen.no_analog &&
2859 spec->gen.autocfg.speaker_pins[0] != 0x1d) {
Takashi Iwaia5cb4632018-06-20 12:50:11 +02002860 for (i = 0; i < ARRAY_SIZE(alc268_beep_mixer); i++) {
2861 if (!snd_hda_gen_add_kctl(&spec->gen, NULL,
2862 &alc268_beep_mixer[i])) {
2863 err = -ENOMEM;
2864 goto error;
2865 }
2866 }
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002867 snd_hda_add_verbs(codec, alc268_beep_init_verbs);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002868 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
2869 /* override the amp caps for beep generator */
2870 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
2871 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
2872 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
2873 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
2874 (0 << AC_AMPCAP_MUTE_SHIFT));
2875 }
2876
Takashi Iwai1727a772013-01-10 09:52:52 +01002877 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002878
Takashi Iwai1d045db2011-07-07 18:23:21 +02002879 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02002880
2881 error:
2882 alc_free(codec);
2883 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002884}
2885
2886/*
2887 * ALC269
2888 */
Takashi Iwai08c189f2012-12-19 15:22:24 +01002889
Takashi Iwai1d045db2011-07-07 18:23:21 +02002890static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002891 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002892};
2893
2894static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002895 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002896};
2897
Takashi Iwai1d045db2011-07-07 18:23:21 +02002898/* different alc269-variants */
2899enum {
2900 ALC269_TYPE_ALC269VA,
2901 ALC269_TYPE_ALC269VB,
2902 ALC269_TYPE_ALC269VC,
Kailang Yangadcc70b2012-05-25 08:08:38 +02002903 ALC269_TYPE_ALC269VD,
Kailang Yang065380f2013-01-10 10:25:48 +01002904 ALC269_TYPE_ALC280,
2905 ALC269_TYPE_ALC282,
Kailang Yang2af02be2013-08-22 10:03:50 +02002906 ALC269_TYPE_ALC283,
Kailang Yang065380f2013-01-10 10:25:48 +01002907 ALC269_TYPE_ALC284,
Kailang Yang4731d5d2017-06-30 15:22:57 +08002908 ALC269_TYPE_ALC293,
Kailang Yang7fc7d042013-04-25 11:04:43 +02002909 ALC269_TYPE_ALC286,
Kailang Yang506b62c2014-12-18 17:07:44 +08002910 ALC269_TYPE_ALC298,
Kailang Yang1d04c9d2013-10-24 11:35:18 +02002911 ALC269_TYPE_ALC255,
Kailang Yang4344aec2014-12-17 17:39:05 +08002912 ALC269_TYPE_ALC256,
Kailang Yangf429e7e2017-12-05 15:38:24 +08002913 ALC269_TYPE_ALC257,
Kailang Yang0a6f0602017-06-30 16:00:48 +08002914 ALC269_TYPE_ALC215,
Kailang Yang42314302016-02-03 15:03:50 +08002915 ALC269_TYPE_ALC225,
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08002916 ALC269_TYPE_ALC294,
Kailang Yang1078bef2018-11-08 16:36:15 +08002917 ALC269_TYPE_ALC300,
Kailang Yang6fbae352016-05-30 16:44:20 +08002918 ALC269_TYPE_ALC700,
Takashi Iwai1d045db2011-07-07 18:23:21 +02002919};
2920
2921/*
2922 * BIOS auto configuration
2923 */
2924static int alc269_parse_auto_config(struct hda_codec *codec)
2925{
Takashi Iwai1d045db2011-07-07 18:23:21 +02002926 static const hda_nid_t alc269_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002927 static const hda_nid_t alc269_ssids[] = { 0, 0x1b, 0x14, 0x21 };
2928 static const hda_nid_t alc269va_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2929 struct alc_spec *spec = codec->spec;
Kailang Yangadcc70b2012-05-25 08:08:38 +02002930 const hda_nid_t *ssids;
2931
2932 switch (spec->codec_variant) {
2933 case ALC269_TYPE_ALC269VA:
2934 case ALC269_TYPE_ALC269VC:
Kailang Yang065380f2013-01-10 10:25:48 +01002935 case ALC269_TYPE_ALC280:
2936 case ALC269_TYPE_ALC284:
Kailang Yang4731d5d2017-06-30 15:22:57 +08002937 case ALC269_TYPE_ALC293:
Kailang Yangadcc70b2012-05-25 08:08:38 +02002938 ssids = alc269va_ssids;
2939 break;
2940 case ALC269_TYPE_ALC269VB:
2941 case ALC269_TYPE_ALC269VD:
Kailang Yang065380f2013-01-10 10:25:48 +01002942 case ALC269_TYPE_ALC282:
Kailang Yang2af02be2013-08-22 10:03:50 +02002943 case ALC269_TYPE_ALC283:
Kailang Yang7fc7d042013-04-25 11:04:43 +02002944 case ALC269_TYPE_ALC286:
Kailang Yang506b62c2014-12-18 17:07:44 +08002945 case ALC269_TYPE_ALC298:
Kailang Yang1d04c9d2013-10-24 11:35:18 +02002946 case ALC269_TYPE_ALC255:
Kailang Yang4344aec2014-12-17 17:39:05 +08002947 case ALC269_TYPE_ALC256:
Kailang Yangf429e7e2017-12-05 15:38:24 +08002948 case ALC269_TYPE_ALC257:
Kailang Yang0a6f0602017-06-30 16:00:48 +08002949 case ALC269_TYPE_ALC215:
Kailang Yang42314302016-02-03 15:03:50 +08002950 case ALC269_TYPE_ALC225:
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08002951 case ALC269_TYPE_ALC294:
Kailang Yang1078bef2018-11-08 16:36:15 +08002952 case ALC269_TYPE_ALC300:
Kailang Yang6fbae352016-05-30 16:44:20 +08002953 case ALC269_TYPE_ALC700:
Kailang Yangadcc70b2012-05-25 08:08:38 +02002954 ssids = alc269_ssids;
2955 break;
2956 default:
2957 ssids = alc269_ssids;
2958 break;
2959 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02002960
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002961 return alc_parse_auto_config(codec, alc269_ignore, ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002962}
2963
Kailang Yang1387e2d2012-11-08 10:23:18 +01002964static void alc269vb_toggle_power_output(struct hda_codec *codec, int power_up)
Takashi Iwai1d045db2011-07-07 18:23:21 +02002965{
Takashi Iwai98b24882014-08-18 13:47:50 +02002966 alc_update_coef_idx(codec, 0x04, 1 << 11, power_up ? (1 << 11) : 0);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002967}
2968
2969static void alc269_shutup(struct hda_codec *codec)
2970{
Kailang Yangadcc70b2012-05-25 08:08:38 +02002971 struct alc_spec *spec = codec->spec;
2972
Kailang Yang1387e2d2012-11-08 10:23:18 +01002973 if (spec->codec_variant == ALC269_TYPE_ALC269VB)
2974 alc269vb_toggle_power_output(codec, 0);
2975 if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
2976 (alc_get_coef0(codec) & 0x00ff) == 0x018) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002977 msleep(150);
2978 }
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01002979 alc_shutup_pins(codec);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002980}
2981
Takashi Iwai54db6c32014-08-18 15:11:19 +02002982static struct coef_fw alc282_coefs[] = {
2983 WRITE_COEF(0x03, 0x0002), /* Power Down Control */
Kailang Yang32fa7e42014-10-24 16:26:01 +08002984 UPDATE_COEF(0x05, 0xff3f, 0x0700), /* FIFO and filter clock */
Takashi Iwai54db6c32014-08-18 15:11:19 +02002985 WRITE_COEF(0x07, 0x0200), /* DMIC control */
2986 UPDATE_COEF(0x06, 0x00f0, 0), /* Analog clock */
2987 UPDATE_COEF(0x08, 0xfffc, 0x0c2c), /* JD */
2988 WRITE_COEF(0x0a, 0xcccc), /* JD offset1 */
2989 WRITE_COEF(0x0b, 0xcccc), /* JD offset2 */
2990 WRITE_COEF(0x0e, 0x6e00), /* LDO1/2/3, DAC/ADC */
2991 UPDATE_COEF(0x0f, 0xf800, 0x1000), /* JD */
2992 UPDATE_COEF(0x10, 0xfc00, 0x0c00), /* Capless */
2993 WRITE_COEF(0x6f, 0x0), /* Class D test 4 */
2994 UPDATE_COEF(0x0c, 0xfe00, 0), /* IO power down directly */
2995 WRITE_COEF(0x34, 0xa0c0), /* ANC */
2996 UPDATE_COEF(0x16, 0x0008, 0), /* AGC MUX */
2997 UPDATE_COEF(0x1d, 0x00e0, 0), /* DAC simple content protection */
2998 UPDATE_COEF(0x1f, 0x00e0, 0), /* ADC simple content protection */
2999 WRITE_COEF(0x21, 0x8804), /* DAC ADC Zero Detection */
3000 WRITE_COEF(0x63, 0x2902), /* PLL */
3001 WRITE_COEF(0x68, 0xa080), /* capless control 2 */
3002 WRITE_COEF(0x69, 0x3400), /* capless control 3 */
3003 WRITE_COEF(0x6a, 0x2f3e), /* capless control 4 */
3004 WRITE_COEF(0x6b, 0x0), /* capless control 5 */
3005 UPDATE_COEF(0x6d, 0x0fff, 0x0900), /* class D test 2 */
3006 WRITE_COEF(0x6e, 0x110a), /* class D test 3 */
3007 UPDATE_COEF(0x70, 0x00f8, 0x00d8), /* class D test 5 */
3008 WRITE_COEF(0x71, 0x0014), /* class D test 6 */
3009 WRITE_COEF(0x72, 0xc2ba), /* classD OCP */
3010 UPDATE_COEF(0x77, 0x0f80, 0), /* classD pure DC test */
3011 WRITE_COEF(0x6c, 0xfc06), /* Class D amp control */
3012 {}
3013};
3014
Kailang Yangcb149cb2014-03-18 16:45:32 +08003015static void alc282_restore_default_value(struct hda_codec *codec)
3016{
Takashi Iwai54db6c32014-08-18 15:11:19 +02003017 alc_process_coef_fw(codec, alc282_coefs);
Kailang Yangcb149cb2014-03-18 16:45:32 +08003018}
3019
Kailang Yang7b5c7a02014-03-18 16:15:54 +08003020static void alc282_init(struct hda_codec *codec)
3021{
3022 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003023 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang7b5c7a02014-03-18 16:15:54 +08003024 bool hp_pin_sense;
3025 int coef78;
3026
Kailang Yangcb149cb2014-03-18 16:45:32 +08003027 alc282_restore_default_value(codec);
3028
Kailang Yang7b5c7a02014-03-18 16:15:54 +08003029 if (!hp_pin)
3030 return;
3031 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3032 coef78 = alc_read_coef_idx(codec, 0x78);
3033
3034 /* Index 0x78 Direct Drive HP AMP LPM Control 1 */
3035 /* Headphone capless set to high power mode */
3036 alc_write_coef_idx(codec, 0x78, 0x9004);
3037
3038 if (hp_pin_sense)
3039 msleep(2);
3040
3041 snd_hda_codec_write(codec, hp_pin, 0,
3042 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3043
3044 if (hp_pin_sense)
3045 msleep(85);
3046
3047 snd_hda_codec_write(codec, hp_pin, 0,
3048 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3049
3050 if (hp_pin_sense)
3051 msleep(100);
3052
3053 /* Headphone capless set to normal mode */
3054 alc_write_coef_idx(codec, 0x78, coef78);
3055}
3056
3057static void alc282_shutup(struct hda_codec *codec)
3058{
3059 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003060 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang7b5c7a02014-03-18 16:15:54 +08003061 bool hp_pin_sense;
3062 int coef78;
3063
3064 if (!hp_pin) {
3065 alc269_shutup(codec);
3066 return;
3067 }
3068
3069 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3070 coef78 = alc_read_coef_idx(codec, 0x78);
3071 alc_write_coef_idx(codec, 0x78, 0x9004);
3072
3073 if (hp_pin_sense)
3074 msleep(2);
3075
3076 snd_hda_codec_write(codec, hp_pin, 0,
3077 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3078
3079 if (hp_pin_sense)
3080 msleep(85);
3081
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003082 if (!spec->no_shutup_pins)
3083 snd_hda_codec_write(codec, hp_pin, 0,
3084 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
Kailang Yang7b5c7a02014-03-18 16:15:54 +08003085
3086 if (hp_pin_sense)
3087 msleep(100);
3088
3089 alc_auto_setup_eapd(codec, false);
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003090 alc_shutup_pins(codec);
Kailang Yang7b5c7a02014-03-18 16:15:54 +08003091 alc_write_coef_idx(codec, 0x78, coef78);
3092}
3093
Takashi Iwai54db6c32014-08-18 15:11:19 +02003094static struct coef_fw alc283_coefs[] = {
3095 WRITE_COEF(0x03, 0x0002), /* Power Down Control */
Kailang Yang56779862014-10-24 16:17:51 +08003096 UPDATE_COEF(0x05, 0xff3f, 0x0700), /* FIFO and filter clock */
Takashi Iwai54db6c32014-08-18 15:11:19 +02003097 WRITE_COEF(0x07, 0x0200), /* DMIC control */
3098 UPDATE_COEF(0x06, 0x00f0, 0), /* Analog clock */
3099 UPDATE_COEF(0x08, 0xfffc, 0x0c2c), /* JD */
3100 WRITE_COEF(0x0a, 0xcccc), /* JD offset1 */
3101 WRITE_COEF(0x0b, 0xcccc), /* JD offset2 */
3102 WRITE_COEF(0x0e, 0x6fc0), /* LDO1/2/3, DAC/ADC */
3103 UPDATE_COEF(0x0f, 0xf800, 0x1000), /* JD */
3104 UPDATE_COEF(0x10, 0xfc00, 0x0c00), /* Capless */
3105 WRITE_COEF(0x3a, 0x0), /* Class D test 4 */
3106 UPDATE_COEF(0x0c, 0xfe00, 0x0), /* IO power down directly */
3107 WRITE_COEF(0x22, 0xa0c0), /* ANC */
3108 UPDATE_COEFEX(0x53, 0x01, 0x000f, 0x0008), /* AGC MUX */
3109 UPDATE_COEF(0x1d, 0x00e0, 0), /* DAC simple content protection */
3110 UPDATE_COEF(0x1f, 0x00e0, 0), /* ADC simple content protection */
3111 WRITE_COEF(0x21, 0x8804), /* DAC ADC Zero Detection */
3112 WRITE_COEF(0x2e, 0x2902), /* PLL */
3113 WRITE_COEF(0x33, 0xa080), /* capless control 2 */
3114 WRITE_COEF(0x34, 0x3400), /* capless control 3 */
3115 WRITE_COEF(0x35, 0x2f3e), /* capless control 4 */
3116 WRITE_COEF(0x36, 0x0), /* capless control 5 */
3117 UPDATE_COEF(0x38, 0x0fff, 0x0900), /* class D test 2 */
3118 WRITE_COEF(0x39, 0x110a), /* class D test 3 */
3119 UPDATE_COEF(0x3b, 0x00f8, 0x00d8), /* class D test 5 */
3120 WRITE_COEF(0x3c, 0x0014), /* class D test 6 */
3121 WRITE_COEF(0x3d, 0xc2ba), /* classD OCP */
3122 UPDATE_COEF(0x42, 0x0f80, 0x0), /* classD pure DC test */
3123 WRITE_COEF(0x49, 0x0), /* test mode */
3124 UPDATE_COEF(0x40, 0xf800, 0x9800), /* Class D DC enable */
3125 UPDATE_COEF(0x42, 0xf000, 0x2000), /* DC offset */
3126 WRITE_COEF(0x37, 0xfc06), /* Class D amp control */
Kailang Yang56779862014-10-24 16:17:51 +08003127 UPDATE_COEF(0x1b, 0x8000, 0), /* HP JD control */
Takashi Iwai54db6c32014-08-18 15:11:19 +02003128 {}
3129};
3130
Kailang Yang6bd55b02014-03-17 13:51:27 +08003131static void alc283_restore_default_value(struct hda_codec *codec)
3132{
Takashi Iwai54db6c32014-08-18 15:11:19 +02003133 alc_process_coef_fw(codec, alc283_coefs);
Kailang Yang6bd55b02014-03-17 13:51:27 +08003134}
3135
Kailang Yang2af02be2013-08-22 10:03:50 +02003136static void alc283_init(struct hda_codec *codec)
3137{
3138 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003139 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang2af02be2013-08-22 10:03:50 +02003140 bool hp_pin_sense;
Kailang Yang2af02be2013-08-22 10:03:50 +02003141
Kailang Yang6bd55b02014-03-17 13:51:27 +08003142 alc283_restore_default_value(codec);
3143
Kailang Yang2af02be2013-08-22 10:03:50 +02003144 if (!hp_pin)
3145 return;
Kailang Yanga59d7192015-04-08 16:34:00 +08003146
3147 msleep(30);
Kailang Yang2af02be2013-08-22 10:03:50 +02003148 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3149
3150 /* Index 0x43 Direct Drive HP AMP LPM Control 1 */
3151 /* Headphone capless set to high power mode */
3152 alc_write_coef_idx(codec, 0x43, 0x9004);
3153
3154 snd_hda_codec_write(codec, hp_pin, 0,
3155 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3156
3157 if (hp_pin_sense)
3158 msleep(85);
3159
3160 snd_hda_codec_write(codec, hp_pin, 0,
3161 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3162
3163 if (hp_pin_sense)
3164 msleep(85);
3165 /* Index 0x46 Combo jack auto switch control 2 */
3166 /* 3k pull low control for Headset jack. */
Takashi Iwai98b24882014-08-18 13:47:50 +02003167 alc_update_coef_idx(codec, 0x46, 3 << 12, 0);
Kailang Yang2af02be2013-08-22 10:03:50 +02003168 /* Headphone capless set to normal mode */
3169 alc_write_coef_idx(codec, 0x43, 0x9614);
3170}
3171
3172static void alc283_shutup(struct hda_codec *codec)
3173{
3174 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003175 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang2af02be2013-08-22 10:03:50 +02003176 bool hp_pin_sense;
Kailang Yang2af02be2013-08-22 10:03:50 +02003177
3178 if (!hp_pin) {
3179 alc269_shutup(codec);
3180 return;
3181 }
3182
3183 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3184
3185 alc_write_coef_idx(codec, 0x43, 0x9004);
3186
Harsha Priyab450b172014-10-09 11:04:56 +00003187 /*depop hp during suspend*/
3188 alc_write_coef_idx(codec, 0x06, 0x2100);
3189
Kailang Yang2af02be2013-08-22 10:03:50 +02003190 snd_hda_codec_write(codec, hp_pin, 0,
3191 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3192
3193 if (hp_pin_sense)
Kailang Yang88011c092013-10-24 15:45:24 +02003194 msleep(100);
Kailang Yang2af02be2013-08-22 10:03:50 +02003195
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003196 if (!spec->no_shutup_pins)
3197 snd_hda_codec_write(codec, hp_pin, 0,
3198 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
Kailang Yang2af02be2013-08-22 10:03:50 +02003199
Takashi Iwai98b24882014-08-18 13:47:50 +02003200 alc_update_coef_idx(codec, 0x46, 0, 3 << 12);
Kailang Yang2af02be2013-08-22 10:03:50 +02003201
3202 if (hp_pin_sense)
Kailang Yang88011c092013-10-24 15:45:24 +02003203 msleep(100);
Kailang Yang0435b3f2014-04-08 17:14:14 +08003204 alc_auto_setup_eapd(codec, false);
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003205 alc_shutup_pins(codec);
Kailang Yang2af02be2013-08-22 10:03:50 +02003206 alc_write_coef_idx(codec, 0x43, 0x9614);
3207}
3208
Kailang Yang4a219ef2017-06-16 16:54:35 +08003209static void alc256_init(struct hda_codec *codec)
3210{
3211 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003212 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang4a219ef2017-06-16 16:54:35 +08003213 bool hp_pin_sense;
3214
3215 if (!hp_pin)
Kailang Yang6447c962019-05-08 16:27:03 +08003216 hp_pin = 0x21;
Kailang Yang4a219ef2017-06-16 16:54:35 +08003217
3218 msleep(30);
3219
3220 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3221
3222 if (hp_pin_sense)
3223 msleep(2);
3224
3225 alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */
Kailang Yang6447c962019-05-08 16:27:03 +08003226 if (spec->ultra_low_power) {
3227 alc_update_coef_idx(codec, 0x03, 1<<1, 1<<1);
3228 alc_update_coef_idx(codec, 0x08, 3<<2, 3<<2);
3229 alc_update_coef_idx(codec, 0x08, 7<<4, 0);
3230 alc_update_coef_idx(codec, 0x3b, 1<<15, 0);
3231 alc_update_coef_idx(codec, 0x0e, 7<<6, 7<<6);
3232 msleep(30);
3233 }
Kailang Yang4a219ef2017-06-16 16:54:35 +08003234
3235 snd_hda_codec_write(codec, hp_pin, 0,
3236 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3237
Kailang Yang6447c962019-05-08 16:27:03 +08003238 if (hp_pin_sense || spec->ultra_low_power)
Kailang Yang4a219ef2017-06-16 16:54:35 +08003239 msleep(85);
3240
3241 snd_hda_codec_write(codec, hp_pin, 0,
3242 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3243
Kailang Yang6447c962019-05-08 16:27:03 +08003244 if (hp_pin_sense || spec->ultra_low_power)
Kailang Yang4a219ef2017-06-16 16:54:35 +08003245 msleep(100);
3246
3247 alc_update_coef_idx(codec, 0x46, 3 << 12, 0);
3248 alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x4); /* Hight power */
Kailang Yang88d42b22018-03-14 16:08:57 +08003249 alc_update_coefex_idx(codec, 0x53, 0x02, 0x8000, 1 << 15); /* Clear bit */
3250 alc_update_coefex_idx(codec, 0x53, 0x02, 0x8000, 0 << 15);
Kailang Yangd07a9a42019-07-04 16:02:10 +08003251 alc_update_coef_idx(codec, 0x36, 1 << 13, 1 << 5); /* Switch pcbeep path to Line in path*/
Kailang Yang4a219ef2017-06-16 16:54:35 +08003252}
3253
3254static void alc256_shutup(struct hda_codec *codec)
3255{
3256 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003257 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang4a219ef2017-06-16 16:54:35 +08003258 bool hp_pin_sense;
3259
Kailang Yang6447c962019-05-08 16:27:03 +08003260 if (!hp_pin)
3261 hp_pin = 0x21;
Kailang Yang4a219ef2017-06-16 16:54:35 +08003262
3263 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3264
3265 if (hp_pin_sense)
3266 msleep(2);
3267
3268 snd_hda_codec_write(codec, hp_pin, 0,
3269 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3270
Kailang Yang6447c962019-05-08 16:27:03 +08003271 if (hp_pin_sense || spec->ultra_low_power)
Kailang Yang4a219ef2017-06-16 16:54:35 +08003272 msleep(85);
3273
Takashi Iwai1c9609e2018-01-19 14:18:34 +01003274 /* 3k pull low control for Headset jack. */
3275 /* NOTE: call this before clearing the pin, otherwise codec stalls */
3276 alc_update_coef_idx(codec, 0x46, 0, 3 << 12);
3277
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003278 if (!spec->no_shutup_pins)
3279 snd_hda_codec_write(codec, hp_pin, 0,
3280 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
Kailang Yang4a219ef2017-06-16 16:54:35 +08003281
Kailang Yang6447c962019-05-08 16:27:03 +08003282 if (hp_pin_sense || spec->ultra_low_power)
Kailang Yang4a219ef2017-06-16 16:54:35 +08003283 msleep(100);
3284
3285 alc_auto_setup_eapd(codec, false);
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003286 alc_shutup_pins(codec);
Kailang Yang6447c962019-05-08 16:27:03 +08003287 if (spec->ultra_low_power) {
3288 msleep(50);
3289 alc_update_coef_idx(codec, 0x03, 1<<1, 0);
3290 alc_update_coef_idx(codec, 0x08, 7<<4, 7<<4);
3291 alc_update_coef_idx(codec, 0x08, 3<<2, 0);
3292 alc_update_coef_idx(codec, 0x3b, 1<<15, 1<<15);
3293 alc_update_coef_idx(codec, 0x0e, 7<<6, 0);
3294 msleep(30);
3295 }
Kailang Yang4a219ef2017-06-16 16:54:35 +08003296}
3297
Kailang Yangda911b12018-01-05 16:50:08 +08003298static void alc225_init(struct hda_codec *codec)
3299{
3300 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003301 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yangda911b12018-01-05 16:50:08 +08003302 bool hp1_pin_sense, hp2_pin_sense;
3303
3304 if (!hp_pin)
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003305 hp_pin = 0x21;
Kailang Yangda911b12018-01-05 16:50:08 +08003306 msleep(30);
3307
3308 hp1_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3309 hp2_pin_sense = snd_hda_jack_detect(codec, 0x16);
3310
3311 if (hp1_pin_sense || hp2_pin_sense)
3312 msleep(2);
3313
3314 alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003315 if (spec->ultra_low_power) {
3316 alc_update_coef_idx(codec, 0x08, 0x0f << 2, 3<<2);
3317 alc_update_coef_idx(codec, 0x0e, 7<<6, 7<<6);
3318 alc_update_coef_idx(codec, 0x33, 1<<11, 0);
3319 msleep(30);
3320 }
Kailang Yangda911b12018-01-05 16:50:08 +08003321
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003322 if (hp1_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003323 snd_hda_codec_write(codec, hp_pin, 0,
3324 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3325 if (hp2_pin_sense)
3326 snd_hda_codec_write(codec, 0x16, 0,
3327 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3328
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003329 if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003330 msleep(85);
3331
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003332 if (hp1_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003333 snd_hda_codec_write(codec, hp_pin, 0,
3334 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3335 if (hp2_pin_sense)
3336 snd_hda_codec_write(codec, 0x16, 0,
3337 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3338
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003339 if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003340 msleep(100);
3341
3342 alc_update_coef_idx(codec, 0x4a, 3 << 10, 0);
3343 alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x4); /* Hight power */
3344}
3345
3346static void alc225_shutup(struct hda_codec *codec)
3347{
3348 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003349 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yangda911b12018-01-05 16:50:08 +08003350 bool hp1_pin_sense, hp2_pin_sense;
3351
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003352 if (!hp_pin)
3353 hp_pin = 0x21;
Kailang Yangda911b12018-01-05 16:50:08 +08003354 /* 3k pull low control for Headset jack. */
3355 alc_update_coef_idx(codec, 0x4a, 0, 3 << 10);
3356
3357 hp1_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3358 hp2_pin_sense = snd_hda_jack_detect(codec, 0x16);
3359
3360 if (hp1_pin_sense || hp2_pin_sense)
3361 msleep(2);
3362
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003363 if (hp1_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003364 snd_hda_codec_write(codec, hp_pin, 0,
3365 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3366 if (hp2_pin_sense)
3367 snd_hda_codec_write(codec, 0x16, 0,
3368 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3369
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003370 if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003371 msleep(85);
3372
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003373 if (hp1_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003374 snd_hda_codec_write(codec, hp_pin, 0,
3375 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
3376 if (hp2_pin_sense)
3377 snd_hda_codec_write(codec, 0x16, 0,
3378 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
3379
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003380 if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003381 msleep(100);
3382
3383 alc_auto_setup_eapd(codec, false);
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003384 alc_shutup_pins(codec);
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003385 if (spec->ultra_low_power) {
3386 msleep(50);
3387 alc_update_coef_idx(codec, 0x08, 0x0f << 2, 0x0c << 2);
3388 alc_update_coef_idx(codec, 0x0e, 7<<6, 0);
3389 alc_update_coef_idx(codec, 0x33, 1<<11, 1<<11);
3390 alc_update_coef_idx(codec, 0x4a, 3<<4, 2<<4);
3391 msleep(30);
3392 }
Kailang Yangda911b12018-01-05 16:50:08 +08003393}
3394
Kailang Yangc2d6af52017-06-21 14:50:54 +08003395static void alc_default_init(struct hda_codec *codec)
3396{
3397 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003398 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yangc2d6af52017-06-21 14:50:54 +08003399 bool hp_pin_sense;
3400
3401 if (!hp_pin)
3402 return;
3403
3404 msleep(30);
3405
3406 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3407
3408 if (hp_pin_sense)
3409 msleep(2);
3410
3411 snd_hda_codec_write(codec, hp_pin, 0,
3412 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3413
3414 if (hp_pin_sense)
3415 msleep(85);
3416
3417 snd_hda_codec_write(codec, hp_pin, 0,
3418 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3419
3420 if (hp_pin_sense)
3421 msleep(100);
3422}
3423
3424static void alc_default_shutup(struct hda_codec *codec)
3425{
3426 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003427 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yangc2d6af52017-06-21 14:50:54 +08003428 bool hp_pin_sense;
3429
3430 if (!hp_pin) {
3431 alc269_shutup(codec);
3432 return;
3433 }
3434
3435 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3436
3437 if (hp_pin_sense)
3438 msleep(2);
3439
3440 snd_hda_codec_write(codec, hp_pin, 0,
3441 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3442
3443 if (hp_pin_sense)
3444 msleep(85);
3445
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003446 if (!spec->no_shutup_pins)
3447 snd_hda_codec_write(codec, hp_pin, 0,
3448 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
Kailang Yangc2d6af52017-06-21 14:50:54 +08003449
3450 if (hp_pin_sense)
3451 msleep(100);
3452
3453 alc_auto_setup_eapd(codec, false);
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003454 alc_shutup_pins(codec);
Kailang Yangc2d6af52017-06-21 14:50:54 +08003455}
3456
Kailang Yang693abe12019-01-29 15:38:21 +08003457static void alc294_hp_init(struct hda_codec *codec)
3458{
3459 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003460 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang693abe12019-01-29 15:38:21 +08003461 int i, val;
3462
3463 if (!hp_pin)
3464 return;
3465
3466 snd_hda_codec_write(codec, hp_pin, 0,
3467 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3468
3469 msleep(100);
3470
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003471 if (!spec->no_shutup_pins)
3472 snd_hda_codec_write(codec, hp_pin, 0,
3473 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
Kailang Yang693abe12019-01-29 15:38:21 +08003474
3475 alc_update_coef_idx(codec, 0x6f, 0x000f, 0);/* Set HP depop to manual mode */
3476 alc_update_coefex_idx(codec, 0x58, 0x00, 0x8000, 0x8000); /* HP depop procedure start */
3477
3478 /* Wait for depop procedure finish */
3479 val = alc_read_coefex_idx(codec, 0x58, 0x01);
3480 for (i = 0; i < 20 && val & 0x0080; i++) {
3481 msleep(50);
3482 val = alc_read_coefex_idx(codec, 0x58, 0x01);
3483 }
3484 /* Set HP depop to auto mode */
3485 alc_update_coef_idx(codec, 0x6f, 0x000f, 0x000b);
3486 msleep(50);
3487}
3488
3489static void alc294_init(struct hda_codec *codec)
3490{
3491 struct alc_spec *spec = codec->spec;
3492
Takashi Iwaif6ef4e02019-01-29 14:14:51 +01003493 /* required only at boot or S4 resume time */
3494 if (!spec->done_hp_init ||
3495 codec->core.dev.power.power_state.event == PM_EVENT_RESTORE) {
Kailang Yang693abe12019-01-29 15:38:21 +08003496 alc294_hp_init(codec);
3497 spec->done_hp_init = true;
3498 }
3499 alc_default_init(codec);
3500}
3501
Kailang Yangad60d502013-06-28 12:03:01 +02003502static void alc5505_coef_set(struct hda_codec *codec, unsigned int index_reg,
3503 unsigned int val)
3504{
3505 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_COEF_INDEX, index_reg >> 1);
3506 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_PROC_COEF, val & 0xffff); /* LSB */
3507 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_PROC_COEF, val >> 16); /* MSB */
3508}
3509
3510static int alc5505_coef_get(struct hda_codec *codec, unsigned int index_reg)
3511{
3512 unsigned int val;
3513
3514 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_COEF_INDEX, index_reg >> 1);
3515 val = snd_hda_codec_read(codec, 0x51, 0, AC_VERB_GET_PROC_COEF, 0)
3516 & 0xffff;
3517 val |= snd_hda_codec_read(codec, 0x51, 0, AC_VERB_GET_PROC_COEF, 0)
3518 << 16;
3519 return val;
3520}
3521
3522static void alc5505_dsp_halt(struct hda_codec *codec)
3523{
3524 unsigned int val;
3525
3526 alc5505_coef_set(codec, 0x3000, 0x000c); /* DSP CPU stop */
3527 alc5505_coef_set(codec, 0x880c, 0x0008); /* DDR enter self refresh */
3528 alc5505_coef_set(codec, 0x61c0, 0x11110080); /* Clock control for PLL and CPU */
3529 alc5505_coef_set(codec, 0x6230, 0xfc0d4011); /* Disable Input OP */
3530 alc5505_coef_set(codec, 0x61b4, 0x040a2b03); /* Stop PLL2 */
3531 alc5505_coef_set(codec, 0x61b0, 0x00005b17); /* Stop PLL1 */
3532 alc5505_coef_set(codec, 0x61b8, 0x04133303); /* Stop PLL3 */
3533 val = alc5505_coef_get(codec, 0x6220);
3534 alc5505_coef_set(codec, 0x6220, (val | 0x3000)); /* switch Ringbuffer clock to DBUS clock */
3535}
3536
3537static void alc5505_dsp_back_from_halt(struct hda_codec *codec)
3538{
3539 alc5505_coef_set(codec, 0x61b8, 0x04133302);
3540 alc5505_coef_set(codec, 0x61b0, 0x00005b16);
3541 alc5505_coef_set(codec, 0x61b4, 0x040a2b02);
3542 alc5505_coef_set(codec, 0x6230, 0xf80d4011);
3543 alc5505_coef_set(codec, 0x6220, 0x2002010f);
3544 alc5505_coef_set(codec, 0x880c, 0x00000004);
3545}
3546
3547static void alc5505_dsp_init(struct hda_codec *codec)
3548{
3549 unsigned int val;
3550
3551 alc5505_dsp_halt(codec);
3552 alc5505_dsp_back_from_halt(codec);
3553 alc5505_coef_set(codec, 0x61b0, 0x5b14); /* PLL1 control */
3554 alc5505_coef_set(codec, 0x61b0, 0x5b16);
3555 alc5505_coef_set(codec, 0x61b4, 0x04132b00); /* PLL2 control */
3556 alc5505_coef_set(codec, 0x61b4, 0x04132b02);
3557 alc5505_coef_set(codec, 0x61b8, 0x041f3300); /* PLL3 control*/
3558 alc5505_coef_set(codec, 0x61b8, 0x041f3302);
3559 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_CODEC_RESET, 0); /* Function reset */
3560 alc5505_coef_set(codec, 0x61b8, 0x041b3302);
3561 alc5505_coef_set(codec, 0x61b8, 0x04173302);
3562 alc5505_coef_set(codec, 0x61b8, 0x04163302);
3563 alc5505_coef_set(codec, 0x8800, 0x348b328b); /* DRAM control */
3564 alc5505_coef_set(codec, 0x8808, 0x00020022); /* DRAM control */
3565 alc5505_coef_set(codec, 0x8818, 0x00000400); /* DRAM control */
3566
3567 val = alc5505_coef_get(codec, 0x6200) >> 16; /* Read revision ID */
3568 if (val <= 3)
3569 alc5505_coef_set(codec, 0x6220, 0x2002010f); /* I/O PAD Configuration */
3570 else
3571 alc5505_coef_set(codec, 0x6220, 0x6002018f);
3572
3573 alc5505_coef_set(codec, 0x61ac, 0x055525f0); /**/
3574 alc5505_coef_set(codec, 0x61c0, 0x12230080); /* Clock control */
3575 alc5505_coef_set(codec, 0x61b4, 0x040e2b02); /* PLL2 control */
3576 alc5505_coef_set(codec, 0x61bc, 0x010234f8); /* OSC Control */
3577 alc5505_coef_set(codec, 0x880c, 0x00000004); /* DRAM Function control */
3578 alc5505_coef_set(codec, 0x880c, 0x00000003);
3579 alc5505_coef_set(codec, 0x880c, 0x00000010);
Takashi Iwaicd63a5f2013-07-05 12:13:59 +02003580
3581#ifdef HALT_REALTEK_ALC5505
3582 alc5505_dsp_halt(codec);
3583#endif
Kailang Yangad60d502013-06-28 12:03:01 +02003584}
3585
Takashi Iwaicd63a5f2013-07-05 12:13:59 +02003586#ifdef HALT_REALTEK_ALC5505
3587#define alc5505_dsp_suspend(codec) /* NOP */
3588#define alc5505_dsp_resume(codec) /* NOP */
3589#else
3590#define alc5505_dsp_suspend(codec) alc5505_dsp_halt(codec)
3591#define alc5505_dsp_resume(codec) alc5505_dsp_back_from_halt(codec)
3592#endif
3593
Takashi Iwai2a439522011-07-26 09:52:50 +02003594#ifdef CONFIG_PM
Kailang Yangad60d502013-06-28 12:03:01 +02003595static int alc269_suspend(struct hda_codec *codec)
3596{
3597 struct alc_spec *spec = codec->spec;
3598
3599 if (spec->has_alc5505_dsp)
Takashi Iwaicd63a5f2013-07-05 12:13:59 +02003600 alc5505_dsp_suspend(codec);
Kailang Yangad60d502013-06-28 12:03:01 +02003601 return alc_suspend(codec);
3602}
3603
Takashi Iwai1d045db2011-07-07 18:23:21 +02003604static int alc269_resume(struct hda_codec *codec)
3605{
Kailang Yangadcc70b2012-05-25 08:08:38 +02003606 struct alc_spec *spec = codec->spec;
3607
Kailang Yang1387e2d2012-11-08 10:23:18 +01003608 if (spec->codec_variant == ALC269_TYPE_ALC269VB)
3609 alc269vb_toggle_power_output(codec, 0);
3610 if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
Kailang Yangadcc70b2012-05-25 08:08:38 +02003611 (alc_get_coef0(codec) & 0x00ff) == 0x018) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02003612 msleep(150);
3613 }
3614
3615 codec->patch_ops.init(codec);
3616
Kailang Yang1387e2d2012-11-08 10:23:18 +01003617 if (spec->codec_variant == ALC269_TYPE_ALC269VB)
3618 alc269vb_toggle_power_output(codec, 1);
3619 if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
Kailang Yangadcc70b2012-05-25 08:08:38 +02003620 (alc_get_coef0(codec) & 0x00ff) == 0x017) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02003621 msleep(200);
3622 }
3623
Takashi Iwaieeecd9d2015-02-25 15:18:50 +01003624 regcache_sync(codec->core.regmap);
Takashi Iwai1d045db2011-07-07 18:23:21 +02003625 hda_call_check_power_status(codec, 0x01);
Hui Wangf4753712014-08-19 12:07:03 +08003626
3627 /* on some machine, the BIOS will clear the codec gpio data when enter
3628 * suspend, and won't restore the data after resume, so we restore it
3629 * in the driver.
3630 */
Takashi Iwaid261eec2018-06-19 22:32:29 +02003631 if (spec->gpio_data)
3632 alc_write_gpio_data(codec);
Hui Wangf4753712014-08-19 12:07:03 +08003633
Kailang Yangad60d502013-06-28 12:03:01 +02003634 if (spec->has_alc5505_dsp)
Takashi Iwaicd63a5f2013-07-05 12:13:59 +02003635 alc5505_dsp_resume(codec);
Kailang Yangc5177c82013-07-24 14:39:49 +02003636
Takashi Iwai1d045db2011-07-07 18:23:21 +02003637 return 0;
3638}
Takashi Iwai2a439522011-07-26 09:52:50 +02003639#endif /* CONFIG_PM */
Takashi Iwai1d045db2011-07-07 18:23:21 +02003640
David Henningsson108cc102012-07-20 10:37:25 +02003641static void alc269_fixup_pincfg_no_hp_to_lineout(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003642 const struct hda_fixup *fix, int action)
David Henningsson108cc102012-07-20 10:37:25 +02003643{
3644 struct alc_spec *spec = codec->spec;
3645
Takashi Iwai1727a772013-01-10 09:52:52 +01003646 if (action == HDA_FIXUP_ACT_PRE_PROBE)
David Henningsson108cc102012-07-20 10:37:25 +02003647 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
3648}
3649
Jan-Marek Glogowskifdcc9682018-02-14 11:29:15 +01003650static void alc269_fixup_pincfg_U7x7_headset_mic(struct hda_codec *codec,
3651 const struct hda_fixup *fix,
3652 int action)
3653{
3654 unsigned int cfg_headphone = snd_hda_codec_get_pincfg(codec, 0x21);
3655 unsigned int cfg_headset_mic = snd_hda_codec_get_pincfg(codec, 0x19);
3656
3657 if (cfg_headphone && cfg_headset_mic == 0x411111f0)
3658 snd_hda_codec_set_pincfg(codec, 0x19,
3659 (cfg_headphone & ~AC_DEFCFG_DEVICE) |
3660 (AC_JACK_MIC_IN << AC_DEFCFG_DEVICE_SHIFT));
3661}
3662
Takashi Iwai1d045db2011-07-07 18:23:21 +02003663static void alc269_fixup_hweq(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003664 const struct hda_fixup *fix, int action)
Takashi Iwai1d045db2011-07-07 18:23:21 +02003665{
Takashi Iwai98b24882014-08-18 13:47:50 +02003666 if (action == HDA_FIXUP_ACT_INIT)
3667 alc_update_coef_idx(codec, 0x1e, 0, 0x80);
Takashi Iwai1d045db2011-07-07 18:23:21 +02003668}
3669
David Henningsson7c478f02013-10-11 10:18:46 +02003670static void alc269_fixup_headset_mic(struct hda_codec *codec,
3671 const struct hda_fixup *fix, int action)
3672{
3673 struct alc_spec *spec = codec->spec;
3674
3675 if (action == HDA_FIXUP_ACT_PRE_PROBE)
3676 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
3677}
3678
Takashi Iwai1d045db2011-07-07 18:23:21 +02003679static void alc271_fixup_dmic(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003680 const struct hda_fixup *fix, int action)
Takashi Iwai1d045db2011-07-07 18:23:21 +02003681{
3682 static const struct hda_verb verbs[] = {
3683 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
3684 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
3685 {}
3686 };
3687 unsigned int cfg;
3688
Takashi Iwai7639a062015-03-03 10:07:24 +01003689 if (strcmp(codec->core.chip_name, "ALC271X") &&
3690 strcmp(codec->core.chip_name, "ALC269VB"))
Takashi Iwai1d045db2011-07-07 18:23:21 +02003691 return;
3692 cfg = snd_hda_codec_get_pincfg(codec, 0x12);
3693 if (get_defcfg_connect(cfg) == AC_JACK_PORT_FIXED)
3694 snd_hda_sequence_write(codec, verbs);
3695}
3696
Takashi Iwai017f2a12011-07-09 14:42:25 +02003697static void alc269_fixup_pcm_44k(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003698 const struct hda_fixup *fix, int action)
Takashi Iwai017f2a12011-07-09 14:42:25 +02003699{
3700 struct alc_spec *spec = codec->spec;
3701
Takashi Iwai1727a772013-01-10 09:52:52 +01003702 if (action != HDA_FIXUP_ACT_PROBE)
Takashi Iwai017f2a12011-07-09 14:42:25 +02003703 return;
3704
3705 /* Due to a hardware problem on Lenovo Ideadpad, we need to
3706 * fix the sample rate of analog I/O to 44.1kHz
3707 */
Takashi Iwai08c189f2012-12-19 15:22:24 +01003708 spec->gen.stream_analog_playback = &alc269_44k_pcm_analog_playback;
3709 spec->gen.stream_analog_capture = &alc269_44k_pcm_analog_capture;
Takashi Iwai017f2a12011-07-09 14:42:25 +02003710}
3711
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02003712static void alc269_fixup_stereo_dmic(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003713 const struct hda_fixup *fix, int action)
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02003714{
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02003715 /* The digital-mic unit sends PDM (differential signal) instead of
3716 * the standard PCM, thus you can't record a valid mono stream as is.
3717 * Below is a workaround specific to ALC269 to control the dmic
3718 * signal source as mono.
3719 */
Takashi Iwai98b24882014-08-18 13:47:50 +02003720 if (action == HDA_FIXUP_ACT_INIT)
3721 alc_update_coef_idx(codec, 0x07, 0, 0x80);
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02003722}
3723
Takashi Iwai24519912011-08-16 15:08:49 +02003724static void alc269_quanta_automute(struct hda_codec *codec)
3725{
Takashi Iwai08c189f2012-12-19 15:22:24 +01003726 snd_hda_gen_update_outputs(codec);
Takashi Iwai24519912011-08-16 15:08:49 +02003727
Takashi Iwai1687ccc2014-08-18 13:49:35 +02003728 alc_write_coef_idx(codec, 0x0c, 0x680);
3729 alc_write_coef_idx(codec, 0x0c, 0x480);
Takashi Iwai24519912011-08-16 15:08:49 +02003730}
3731
3732static void alc269_fixup_quanta_mute(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003733 const struct hda_fixup *fix, int action)
Takashi Iwai24519912011-08-16 15:08:49 +02003734{
3735 struct alc_spec *spec = codec->spec;
Takashi Iwai1727a772013-01-10 09:52:52 +01003736 if (action != HDA_FIXUP_ACT_PROBE)
Takashi Iwai24519912011-08-16 15:08:49 +02003737 return;
Takashi Iwai08c189f2012-12-19 15:22:24 +01003738 spec->gen.automute_hook = alc269_quanta_automute;
Takashi Iwai24519912011-08-16 15:08:49 +02003739}
3740
David Henningssond240d1d2013-04-15 12:50:02 +02003741static void alc269_x101_hp_automute_hook(struct hda_codec *codec,
Takashi Iwai1a4f69d2014-09-11 15:22:46 +02003742 struct hda_jack_callback *jack)
David Henningssond240d1d2013-04-15 12:50:02 +02003743{
3744 struct alc_spec *spec = codec->spec;
3745 int vref;
3746 msleep(200);
3747 snd_hda_gen_hp_automute(codec, jack);
3748
3749 vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0;
3750 msleep(100);
3751 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3752 vref);
3753 msleep(500);
3754 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3755 vref);
3756}
3757
3758static void alc269_fixup_x101_headset_mic(struct hda_codec *codec,
3759 const struct hda_fixup *fix, int action)
3760{
3761 struct alc_spec *spec = codec->spec;
3762 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3763 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
3764 spec->gen.hp_automute_hook = alc269_x101_hp_automute_hook;
3765 }
3766}
3767
3768
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003769/* update mute-LED according to the speaker mute state via mic VREF pin */
3770static void alc269_fixup_mic_mute_hook(void *private_data, int enabled)
David Henningsson6d3cd5d2013-01-07 12:03:47 +01003771{
3772 struct hda_codec *codec = private_data;
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003773 struct alc_spec *spec = codec->spec;
3774 unsigned int pinval;
3775
3776 if (spec->mute_led_polarity)
3777 enabled = !enabled;
Takashi Iwai415d5552014-04-03 11:51:21 +02003778 pinval = snd_hda_codec_get_pin_target(codec, spec->mute_led_nid);
3779 pinval &= ~AC_PINCTL_VREFEN;
3780 pinval |= enabled ? AC_PINCTL_VREF_HIZ : AC_PINCTL_VREF_80;
Takashi Iwaie40bdb02018-03-17 22:40:18 +01003781 if (spec->mute_led_nid) {
3782 /* temporarily power up/down for setting VREF */
3783 snd_hda_power_up_pm(codec);
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003784 snd_hda_set_pin_ctl_cache(codec, spec->mute_led_nid, pinval);
Takashi Iwaie40bdb02018-03-17 22:40:18 +01003785 snd_hda_power_down_pm(codec);
3786 }
David Henningsson6d3cd5d2013-01-07 12:03:47 +01003787}
3788
David Henningssond5b6b652013-11-06 10:50:44 +01003789/* Make sure the led works even in runtime suspend */
3790static unsigned int led_power_filter(struct hda_codec *codec,
3791 hda_nid_t nid,
3792 unsigned int power_state)
3793{
3794 struct alc_spec *spec = codec->spec;
3795
Hui Wang50dd9052014-07-08 17:56:15 +08003796 if (power_state != AC_PWRST_D3 || nid == 0 ||
3797 (nid != spec->mute_led_nid && nid != spec->cap_mute_led_nid))
David Henningssond5b6b652013-11-06 10:50:44 +01003798 return power_state;
3799
3800 /* Set pin ctl again, it might have just been set to 0 */
3801 snd_hda_set_pin_ctl(codec, nid,
3802 snd_hda_codec_get_pin_target(codec, nid));
3803
Takashi Iwaicffd3962015-04-09 10:30:25 +02003804 return snd_hda_gen_path_power_filter(codec, nid, power_state);
David Henningssond5b6b652013-11-06 10:50:44 +01003805}
3806
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003807static void alc269_fixup_hp_mute_led(struct hda_codec *codec,
3808 const struct hda_fixup *fix, int action)
David Henningsson6d3cd5d2013-01-07 12:03:47 +01003809{
3810 struct alc_spec *spec = codec->spec;
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003811 const struct dmi_device *dev = NULL;
3812
3813 if (action != HDA_FIXUP_ACT_PRE_PROBE)
3814 return;
3815
3816 while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) {
3817 int pol, pin;
3818 if (sscanf(dev->name, "HP_Mute_LED_%d_%x", &pol, &pin) != 2)
3819 continue;
3820 if (pin < 0x0a || pin >= 0x10)
3821 break;
3822 spec->mute_led_polarity = pol;
3823 spec->mute_led_nid = pin - 0x0a + 0x18;
3824 spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook;
Takashi Iwaifd25a972012-12-20 14:57:18 +01003825 spec->gen.vmaster_mute_enum = 1;
David Henningssond5b6b652013-11-06 10:50:44 +01003826 codec->power_filter = led_power_filter;
Takashi Iwai4e76a882014-02-25 12:21:03 +01003827 codec_dbg(codec,
3828 "Detected mute LED for %x:%d\n", spec->mute_led_nid,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003829 spec->mute_led_polarity);
David Henningsson6d3cd5d2013-01-07 12:03:47 +01003830 break;
3831 }
3832}
3833
Takashi Iwai85c467d2018-05-29 11:38:38 +02003834static void alc269_fixup_hp_mute_led_micx(struct hda_codec *codec,
3835 const struct hda_fixup *fix,
3836 int action, hda_nid_t pin)
David Henningssond06ac142013-02-18 11:41:55 +01003837{
3838 struct alc_spec *spec = codec->spec;
Takashi Iwai85c467d2018-05-29 11:38:38 +02003839
David Henningssond06ac142013-02-18 11:41:55 +01003840 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3841 spec->mute_led_polarity = 0;
Takashi Iwai85c467d2018-05-29 11:38:38 +02003842 spec->mute_led_nid = pin;
David Henningssond06ac142013-02-18 11:41:55 +01003843 spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook;
3844 spec->gen.vmaster_mute_enum = 1;
David Henningssond5b6b652013-11-06 10:50:44 +01003845 codec->power_filter = led_power_filter;
David Henningssond06ac142013-02-18 11:41:55 +01003846 }
3847}
3848
Takashi Iwai85c467d2018-05-29 11:38:38 +02003849static void alc269_fixup_hp_mute_led_mic1(struct hda_codec *codec,
3850 const struct hda_fixup *fix, int action)
3851{
3852 alc269_fixup_hp_mute_led_micx(codec, fix, action, 0x18);
3853}
3854
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003855static void alc269_fixup_hp_mute_led_mic2(struct hda_codec *codec,
3856 const struct hda_fixup *fix, int action)
Takashi Iwai420b0fe2012-03-12 12:35:27 +01003857{
Takashi Iwai85c467d2018-05-29 11:38:38 +02003858 alc269_fixup_hp_mute_led_micx(codec, fix, action, 0x19);
Takashi Iwai420b0fe2012-03-12 12:35:27 +01003859}
3860
Tom Briden7f783bd2017-03-25 10:12:01 +00003861static void alc269_fixup_hp_mute_led_mic3(struct hda_codec *codec,
3862 const struct hda_fixup *fix, int action)
3863{
Takashi Iwai85c467d2018-05-29 11:38:38 +02003864 alc269_fixup_hp_mute_led_micx(codec, fix, action, 0x1b);
Tom Briden7f783bd2017-03-25 10:12:01 +00003865}
3866
Takashi Iwai0f32fd192014-11-19 12:16:14 +01003867/* update LED status via GPIO */
3868static void alc_update_gpio_led(struct hda_codec *codec, unsigned int mask,
3869 bool enabled)
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003870{
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003871 struct alc_spec *spec = codec->spec;
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003872
Takashi Iwai0f32fd192014-11-19 12:16:14 +01003873 if (spec->mute_led_polarity)
3874 enabled = !enabled;
Takashi Iwaid261eec2018-06-19 22:32:29 +02003875 alc_update_gpio_data(codec, mask, !enabled); /* muted -> LED on */
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003876}
3877
Takashi Iwai0f32fd192014-11-19 12:16:14 +01003878/* turn on/off mute LED via GPIO per vmaster hook */
3879static void alc_fixup_gpio_mute_hook(void *private_data, int enabled)
3880{
3881 struct hda_codec *codec = private_data;
3882 struct alc_spec *spec = codec->spec;
3883
3884 alc_update_gpio_led(codec, spec->gpio_mute_led_mask, enabled);
3885}
3886
3887/* turn on/off mic-mute LED via GPIO per capture hook */
Takashi Iwaid03abec2018-06-19 12:29:13 +02003888static void alc_gpio_micmute_update(struct hda_codec *codec)
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003889{
3890 struct alc_spec *spec = codec->spec;
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003891
Takashi Iwaid03abec2018-06-19 12:29:13 +02003892 alc_update_gpio_led(codec, spec->gpio_mic_led_mask,
3893 spec->gen.micmute_led.led_value);
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003894}
3895
Takashi Iwai01e4a272018-06-19 22:47:30 +02003896/* setup mute and mic-mute GPIO bits, add hooks appropriately */
3897static void alc_fixup_hp_gpio_led(struct hda_codec *codec,
3898 int action,
3899 unsigned int mute_mask,
3900 unsigned int micmute_mask)
3901{
3902 struct alc_spec *spec = codec->spec;
3903
3904 alc_fixup_gpio(codec, action, mute_mask | micmute_mask);
3905
3906 if (action != HDA_FIXUP_ACT_PRE_PROBE)
3907 return;
3908 if (mute_mask) {
3909 spec->gpio_mute_led_mask = mute_mask;
3910 spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook;
3911 }
3912 if (micmute_mask) {
3913 spec->gpio_mic_led_mask = micmute_mask;
3914 snd_hda_gen_add_micmute_led(codec, alc_gpio_micmute_update);
3915 }
3916}
3917
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003918static void alc269_fixup_hp_gpio_led(struct hda_codec *codec,
3919 const struct hda_fixup *fix, int action)
3920{
Takashi Iwai01e4a272018-06-19 22:47:30 +02003921 alc_fixup_hp_gpio_led(codec, action, 0x08, 0x10);
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003922}
3923
Kailang Yangeaa8e5e2014-11-21 15:49:11 +08003924static void alc286_fixup_hp_gpio_led(struct hda_codec *codec,
3925 const struct hda_fixup *fix, int action)
3926{
Takashi Iwai01e4a272018-06-19 22:47:30 +02003927 alc_fixup_hp_gpio_led(codec, action, 0x02, 0x20);
Takashi Iwai1d045db2011-07-07 18:23:21 +02003928}
3929
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08003930/* turn on/off mic-mute LED per capture hook */
Takashi Iwaid03abec2018-06-19 12:29:13 +02003931static void alc_cap_micmute_update(struct hda_codec *codec)
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08003932{
3933 struct alc_spec *spec = codec->spec;
Takashi Iwaid03abec2018-06-19 12:29:13 +02003934 unsigned int pinval;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08003935
Takashi Iwaid03abec2018-06-19 12:29:13 +02003936 if (!spec->cap_mute_led_nid)
3937 return;
Hui Wangfc1fad92014-07-08 17:56:14 +08003938 pinval = snd_hda_codec_get_pin_target(codec, spec->cap_mute_led_nid);
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08003939 pinval &= ~AC_PINCTL_VREFEN;
Takashi Iwaid03abec2018-06-19 12:29:13 +02003940 if (spec->gen.micmute_led.led_value)
3941 pinval |= AC_PINCTL_VREF_80;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08003942 else
Takashi Iwaid03abec2018-06-19 12:29:13 +02003943 pinval |= AC_PINCTL_VREF_HIZ;
3944 snd_hda_set_pin_ctl_cache(codec, spec->cap_mute_led_nid, pinval);
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08003945}
3946
3947static void alc269_fixup_hp_gpio_mic1_led(struct hda_codec *codec,
3948 const struct hda_fixup *fix, int action)
3949{
3950 struct alc_spec *spec = codec->spec;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08003951
Takashi Iwai01e4a272018-06-19 22:47:30 +02003952 alc_fixup_hp_gpio_led(codec, action, 0x08, 0);
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08003953 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai01e4a272018-06-19 22:47:30 +02003954 /* Like hp_gpio_mic1_led, but also needs GPIO4 low to
3955 * enable headphone amp
3956 */
3957 spec->gpio_mask |= 0x10;
3958 spec->gpio_dir |= 0x10;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08003959 spec->cap_mute_led_nid = 0x18;
Takashi Iwaid03abec2018-06-19 12:29:13 +02003960 snd_hda_gen_add_micmute_led(codec, alc_cap_micmute_update);
Hui Wang50dd9052014-07-08 17:56:15 +08003961 codec->power_filter = led_power_filter;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08003962 }
3963}
3964
David Henningsson7a5255f2014-10-30 08:26:01 +01003965static void alc280_fixup_hp_gpio4(struct hda_codec *codec,
3966 const struct hda_fixup *fix, int action)
3967{
David Henningsson7a5255f2014-10-30 08:26:01 +01003968 struct alc_spec *spec = codec->spec;
David Henningsson7a5255f2014-10-30 08:26:01 +01003969
Takashi Iwai01e4a272018-06-19 22:47:30 +02003970 alc_fixup_hp_gpio_led(codec, action, 0x08, 0);
David Henningsson7a5255f2014-10-30 08:26:01 +01003971 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
David Henningsson7a5255f2014-10-30 08:26:01 +01003972 spec->cap_mute_led_nid = 0x18;
Takashi Iwaid03abec2018-06-19 12:29:13 +02003973 snd_hda_gen_add_micmute_led(codec, alc_cap_micmute_update);
David Henningsson7a5255f2014-10-30 08:26:01 +01003974 codec->power_filter = led_power_filter;
3975 }
3976}
3977
Takashi Iwai6a30aba2018-04-27 17:17:35 +02003978#if IS_REACHABLE(CONFIG_INPUT)
David Henningsson33f4acd2015-01-07 15:50:13 +01003979static void gpio2_mic_hotkey_event(struct hda_codec *codec,
3980 struct hda_jack_callback *event)
3981{
3982 struct alc_spec *spec = codec->spec;
3983
3984 /* GPIO2 just toggles on a keypress/keyrelease cycle. Therefore
3985 send both key on and key off event for every interrupt. */
Hui Wangc7b60a82015-12-28 11:35:25 +08003986 input_report_key(spec->kb_dev, spec->alc_mute_keycode_map[ALC_KEY_MICMUTE_INDEX], 1);
David Henningsson33f4acd2015-01-07 15:50:13 +01003987 input_sync(spec->kb_dev);
Hui Wangc7b60a82015-12-28 11:35:25 +08003988 input_report_key(spec->kb_dev, spec->alc_mute_keycode_map[ALC_KEY_MICMUTE_INDEX], 0);
David Henningsson33f4acd2015-01-07 15:50:13 +01003989 input_sync(spec->kb_dev);
3990}
David Henningsson33f4acd2015-01-07 15:50:13 +01003991
Kailang3694cb22015-12-28 11:35:24 +08003992static int alc_register_micmute_input_device(struct hda_codec *codec)
3993{
3994 struct alc_spec *spec = codec->spec;
Hui Wangc7b60a82015-12-28 11:35:25 +08003995 int i;
Kailang3694cb22015-12-28 11:35:24 +08003996
3997 spec->kb_dev = input_allocate_device();
3998 if (!spec->kb_dev) {
3999 codec_err(codec, "Out of memory (input_allocate_device)\n");
4000 return -ENOMEM;
4001 }
Hui Wangc7b60a82015-12-28 11:35:25 +08004002
4003 spec->alc_mute_keycode_map[ALC_KEY_MICMUTE_INDEX] = KEY_MICMUTE;
4004
Kailang3694cb22015-12-28 11:35:24 +08004005 spec->kb_dev->name = "Microphone Mute Button";
4006 spec->kb_dev->evbit[0] = BIT_MASK(EV_KEY);
Hui Wangc7b60a82015-12-28 11:35:25 +08004007 spec->kb_dev->keycodesize = sizeof(spec->alc_mute_keycode_map[0]);
4008 spec->kb_dev->keycodemax = ARRAY_SIZE(spec->alc_mute_keycode_map);
4009 spec->kb_dev->keycode = spec->alc_mute_keycode_map;
4010 for (i = 0; i < ARRAY_SIZE(spec->alc_mute_keycode_map); i++)
4011 set_bit(spec->alc_mute_keycode_map[i], spec->kb_dev->keybit);
Kailang3694cb22015-12-28 11:35:24 +08004012
4013 if (input_register_device(spec->kb_dev)) {
4014 codec_err(codec, "input_register_device failed\n");
4015 input_free_device(spec->kb_dev);
4016 spec->kb_dev = NULL;
4017 return -ENOMEM;
4018 }
4019
4020 return 0;
4021}
4022
Takashi Iwai01e4a272018-06-19 22:47:30 +02004023/* GPIO1 = set according to SKU external amp
4024 * GPIO2 = mic mute hotkey
4025 * GPIO3 = mute LED
4026 * GPIO4 = mic mute LED
4027 */
David Henningsson33f4acd2015-01-07 15:50:13 +01004028static void alc280_fixup_hp_gpio2_mic_hotkey(struct hda_codec *codec,
4029 const struct hda_fixup *fix, int action)
4030{
David Henningsson33f4acd2015-01-07 15:50:13 +01004031 struct alc_spec *spec = codec->spec;
4032
Takashi Iwai01e4a272018-06-19 22:47:30 +02004033 alc_fixup_hp_gpio_led(codec, action, 0x08, 0x10);
David Henningsson33f4acd2015-01-07 15:50:13 +01004034 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai1c76aa52018-06-21 16:37:54 +02004035 spec->init_amp = ALC_INIT_DEFAULT;
Kailang3694cb22015-12-28 11:35:24 +08004036 if (alc_register_micmute_input_device(codec) != 0)
David Henningsson33f4acd2015-01-07 15:50:13 +01004037 return;
David Henningsson33f4acd2015-01-07 15:50:13 +01004038
Takashi Iwai01e4a272018-06-19 22:47:30 +02004039 spec->gpio_mask |= 0x06;
4040 spec->gpio_dir |= 0x02;
4041 spec->gpio_data |= 0x02;
Takashi Iwai7639a062015-03-03 10:07:24 +01004042 snd_hda_codec_write_cache(codec, codec->core.afg, 0,
David Henningsson33f4acd2015-01-07 15:50:13 +01004043 AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x04);
Takashi Iwai7639a062015-03-03 10:07:24 +01004044 snd_hda_jack_detect_enable_callback(codec, codec->core.afg,
David Henningsson33f4acd2015-01-07 15:50:13 +01004045 gpio2_mic_hotkey_event);
David Henningsson33f4acd2015-01-07 15:50:13 +01004046 return;
4047 }
4048
4049 if (!spec->kb_dev)
4050 return;
4051
4052 switch (action) {
David Henningsson33f4acd2015-01-07 15:50:13 +01004053 case HDA_FIXUP_ACT_FREE:
4054 input_unregister_device(spec->kb_dev);
David Henningsson33f4acd2015-01-07 15:50:13 +01004055 spec->kb_dev = NULL;
4056 }
David Henningsson33f4acd2015-01-07 15:50:13 +01004057}
4058
Takashi Iwai01e4a272018-06-19 22:47:30 +02004059/* Line2 = mic mute hotkey
4060 * GPIO2 = mic mute LED
4061 */
Kailang3694cb22015-12-28 11:35:24 +08004062static void alc233_fixup_lenovo_line2_mic_hotkey(struct hda_codec *codec,
4063 const struct hda_fixup *fix, int action)
4064{
Kailang3694cb22015-12-28 11:35:24 +08004065 struct alc_spec *spec = codec->spec;
4066
Takashi Iwai01e4a272018-06-19 22:47:30 +02004067 alc_fixup_hp_gpio_led(codec, action, 0, 0x04);
Kailang3694cb22015-12-28 11:35:24 +08004068 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai1c76aa52018-06-21 16:37:54 +02004069 spec->init_amp = ALC_INIT_DEFAULT;
Kailang3694cb22015-12-28 11:35:24 +08004070 if (alc_register_micmute_input_device(codec) != 0)
4071 return;
4072
Kailang3694cb22015-12-28 11:35:24 +08004073 snd_hda_jack_detect_enable_callback(codec, 0x1b,
4074 gpio2_mic_hotkey_event);
Kailang3694cb22015-12-28 11:35:24 +08004075 return;
4076 }
4077
4078 if (!spec->kb_dev)
4079 return;
4080
4081 switch (action) {
Kailang3694cb22015-12-28 11:35:24 +08004082 case HDA_FIXUP_ACT_FREE:
4083 input_unregister_device(spec->kb_dev);
4084 spec->kb_dev = NULL;
4085 }
4086}
Takashi Iwaic4696522018-01-15 10:44:35 +01004087#else /* INPUT */
4088#define alc280_fixup_hp_gpio2_mic_hotkey NULL
4089#define alc233_fixup_lenovo_line2_mic_hotkey NULL
4090#endif /* INPUT */
Kailang3694cb22015-12-28 11:35:24 +08004091
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004092static void alc269_fixup_hp_line1_mic1_led(struct hda_codec *codec,
4093 const struct hda_fixup *fix, int action)
4094{
4095 struct alc_spec *spec = codec->spec;
4096
Takashi Iwai1bce62a2018-06-19 23:15:59 +02004097 alc269_fixup_hp_mute_led_micx(codec, fix, action, 0x1a);
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004098 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004099 spec->cap_mute_led_nid = 0x18;
Takashi Iwaid03abec2018-06-19 12:29:13 +02004100 snd_hda_gen_add_micmute_led(codec, alc_cap_micmute_update);
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004101 }
4102}
4103
Kailang Yang5a367672017-07-21 15:23:53 +08004104static struct coef_fw alc225_pre_hsmode[] = {
4105 UPDATE_COEF(0x4a, 1<<8, 0),
4106 UPDATE_COEFEX(0x57, 0x05, 1<<14, 0),
4107 UPDATE_COEF(0x63, 3<<14, 3<<14),
4108 UPDATE_COEF(0x4a, 3<<4, 2<<4),
4109 UPDATE_COEF(0x4a, 3<<10, 3<<10),
4110 UPDATE_COEF(0x45, 0x3f<<10, 0x34<<10),
4111 UPDATE_COEF(0x4a, 3<<10, 0),
4112 {}
4113};
4114
David Henningsson73bdd592013-04-15 15:44:14 +02004115static void alc_headset_mode_unplugged(struct hda_codec *codec)
4116{
Takashi Iwai54db6c32014-08-18 15:11:19 +02004117 static struct coef_fw coef0255[] = {
Kailang Yang717f43d2019-05-31 17:16:53 +08004118 WRITE_COEF(0x1b, 0x0c0b), /* LDO and MISC control */
Takashi Iwai54db6c32014-08-18 15:11:19 +02004119 WRITE_COEF(0x45, 0xd089), /* UAJ function set to menual mode */
4120 UPDATE_COEFEX(0x57, 0x05, 1<<14, 0), /* Direct Drive HP Amp control(Set to verb control)*/
4121 WRITE_COEF(0x06, 0x6104), /* Set MIC2 Vref gate with HP */
4122 WRITE_COEFEX(0x57, 0x03, 0x8aa6), /* Direct Drive HP Amp control */
4123 {}
4124 };
Kailang Yange69e7e02016-05-30 15:58:28 +08004125 static struct coef_fw coef0256[] = {
4126 WRITE_COEF(0x1b, 0x0c4b), /* LDO and MISC control */
Kailang Yang717f43d2019-05-31 17:16:53 +08004127 WRITE_COEF(0x45, 0xd089), /* UAJ function set to menual mode */
4128 WRITE_COEF(0x06, 0x6104), /* Set MIC2 Vref gate with HP */
4129 WRITE_COEFEX(0x57, 0x03, 0x09a3), /* Direct Drive HP Amp control */
4130 UPDATE_COEFEX(0x57, 0x05, 1<<14, 0), /* Direct Drive HP Amp control(Set to verb control)*/
Kailang Yange69e7e02016-05-30 15:58:28 +08004131 {}
4132 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004133 static struct coef_fw coef0233[] = {
4134 WRITE_COEF(0x1b, 0x0c0b),
4135 WRITE_COEF(0x45, 0xc429),
4136 UPDATE_COEF(0x35, 0x4000, 0),
4137 WRITE_COEF(0x06, 0x2104),
4138 WRITE_COEF(0x1a, 0x0001),
4139 WRITE_COEF(0x26, 0x0004),
4140 WRITE_COEF(0x32, 0x42a3),
4141 {}
4142 };
Kailang Yangf3b70332015-04-08 15:01:17 +08004143 static struct coef_fw coef0288[] = {
4144 UPDATE_COEF(0x4f, 0xfcc0, 0xc400),
4145 UPDATE_COEF(0x50, 0x2000, 0x2000),
4146 UPDATE_COEF(0x56, 0x0006, 0x0006),
4147 UPDATE_COEF(0x66, 0x0008, 0),
4148 UPDATE_COEF(0x67, 0x2000, 0),
4149 {}
4150 };
Kailang Yang89542932017-07-17 15:03:43 +08004151 static struct coef_fw coef0298[] = {
4152 UPDATE_COEF(0x19, 0x1300, 0x0300),
4153 {}
4154 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004155 static struct coef_fw coef0292[] = {
4156 WRITE_COEF(0x76, 0x000e),
4157 WRITE_COEF(0x6c, 0x2400),
4158 WRITE_COEF(0x18, 0x7308),
4159 WRITE_COEF(0x6b, 0xc429),
4160 {}
4161 };
4162 static struct coef_fw coef0293[] = {
4163 UPDATE_COEF(0x10, 7<<8, 6<<8), /* SET Line1 JD to 0 */
4164 UPDATE_COEFEX(0x57, 0x05, 1<<15|1<<13, 0x0), /* SET charge pump by verb */
4165 UPDATE_COEFEX(0x57, 0x03, 1<<10, 1<<10), /* SET EN_OSW to 1 */
4166 UPDATE_COEF(0x1a, 1<<3, 1<<3), /* Combo JD gating with LINE1-VREFO */
4167 WRITE_COEF(0x45, 0xc429), /* Set to TRS type */
4168 UPDATE_COEF(0x4a, 0x000f, 0x000e), /* Combo Jack auto detect */
4169 {}
4170 };
4171 static struct coef_fw coef0668[] = {
4172 WRITE_COEF(0x15, 0x0d40),
4173 WRITE_COEF(0xb7, 0x802b),
4174 {}
4175 };
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004176 static struct coef_fw coef0225[] = {
Kailang Yang5a367672017-07-21 15:23:53 +08004177 UPDATE_COEF(0x63, 3<<14, 0),
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004178 {}
4179 };
Kailang Yang71683c32017-06-20 16:33:50 +08004180 static struct coef_fw coef0274[] = {
4181 UPDATE_COEF(0x4a, 0x0100, 0),
4182 UPDATE_COEFEX(0x57, 0x05, 0x4000, 0),
4183 UPDATE_COEF(0x6b, 0xf000, 0x5000),
4184 UPDATE_COEF(0x4a, 0x0010, 0),
4185 UPDATE_COEF(0x4a, 0x0c00, 0x0c00),
4186 WRITE_COEF(0x45, 0x5289),
4187 UPDATE_COEF(0x4a, 0x0c00, 0),
4188 {}
4189 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004190
Takashi Iwai7639a062015-03-03 10:07:24 +01004191 switch (codec->core.vendor_id) {
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004192 case 0x10ec0255:
Kailang Yange69e7e02016-05-30 15:58:28 +08004193 alc_process_coef_fw(codec, coef0255);
4194 break;
Kailang Yang736f20a2017-10-20 15:06:34 +08004195 case 0x10ec0236:
Kailang Yang7081adf2015-03-30 17:05:37 +08004196 case 0x10ec0256:
Kailang Yange69e7e02016-05-30 15:58:28 +08004197 alc_process_coef_fw(codec, coef0256);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004198 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004199 case 0x10ec0234:
4200 case 0x10ec0274:
4201 case 0x10ec0294:
4202 alc_process_coef_fw(codec, coef0274);
4203 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004204 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004205 case 0x10ec0283:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004206 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02004207 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004208 case 0x10ec0286:
4209 case 0x10ec0288:
Kailang Yang89542932017-07-17 15:03:43 +08004210 alc_process_coef_fw(codec, coef0288);
4211 break;
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004212 case 0x10ec0298:
Kailang Yang89542932017-07-17 15:03:43 +08004213 alc_process_coef_fw(codec, coef0298);
Kailang Yangf3b70332015-04-08 15:01:17 +08004214 alc_process_coef_fw(codec, coef0288);
4215 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004216 case 0x10ec0292:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004217 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02004218 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004219 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004220 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004221 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004222 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004223 alc_process_coef_fw(codec, coef0668);
David Henningsson73bdd592013-04-15 15:44:14 +02004224 break;
Kailang Yangc2b691e2018-01-17 15:22:55 +08004225 case 0x10ec0215:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004226 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004227 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08004228 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004229 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08004230 case 0x10ec0299:
Kailang Yang4d4b0c52019-01-09 16:23:37 +08004231 alc_process_coef_fw(codec, alc225_pre_hsmode);
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004232 alc_process_coef_fw(codec, coef0225);
4233 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08004234 case 0x10ec0867:
4235 alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
4236 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004237 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01004238 codec_dbg(codec, "Headset jack set to unplugged mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02004239}
4240
4241
4242static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin,
4243 hda_nid_t mic_pin)
4244{
Takashi Iwai54db6c32014-08-18 15:11:19 +02004245 static struct coef_fw coef0255[] = {
4246 WRITE_COEFEX(0x57, 0x03, 0x8aa6),
4247 WRITE_COEF(0x06, 0x6100), /* Set MIC2 Vref gate to normal */
4248 {}
4249 };
Kailang Yang717f43d2019-05-31 17:16:53 +08004250 static struct coef_fw coef0256[] = {
4251 UPDATE_COEFEX(0x57, 0x05, 1<<14, 1<<14), /* Direct Drive HP Amp control(Set to verb control)*/
4252 WRITE_COEFEX(0x57, 0x03, 0x09a3),
4253 WRITE_COEF(0x06, 0x6100), /* Set MIC2 Vref gate to normal */
4254 {}
4255 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004256 static struct coef_fw coef0233[] = {
4257 UPDATE_COEF(0x35, 0, 1<<14),
4258 WRITE_COEF(0x06, 0x2100),
4259 WRITE_COEF(0x1a, 0x0021),
4260 WRITE_COEF(0x26, 0x008c),
4261 {}
4262 };
Kailang Yangf3b70332015-04-08 15:01:17 +08004263 static struct coef_fw coef0288[] = {
Kailang Yang89542932017-07-17 15:03:43 +08004264 UPDATE_COEF(0x4f, 0x00c0, 0),
Kailang Yangf3b70332015-04-08 15:01:17 +08004265 UPDATE_COEF(0x50, 0x2000, 0),
4266 UPDATE_COEF(0x56, 0x0006, 0),
4267 UPDATE_COEF(0x4f, 0xfcc0, 0xc400),
4268 UPDATE_COEF(0x66, 0x0008, 0x0008),
4269 UPDATE_COEF(0x67, 0x2000, 0x2000),
4270 {}
4271 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004272 static struct coef_fw coef0292[] = {
4273 WRITE_COEF(0x19, 0xa208),
4274 WRITE_COEF(0x2e, 0xacf0),
4275 {}
4276 };
4277 static struct coef_fw coef0293[] = {
4278 UPDATE_COEFEX(0x57, 0x05, 0, 1<<15|1<<13), /* SET charge pump by verb */
4279 UPDATE_COEFEX(0x57, 0x03, 1<<10, 0), /* SET EN_OSW to 0 */
4280 UPDATE_COEF(0x1a, 1<<3, 0), /* Combo JD gating without LINE1-VREFO */
4281 {}
4282 };
4283 static struct coef_fw coef0688[] = {
4284 WRITE_COEF(0xb7, 0x802b),
4285 WRITE_COEF(0xb5, 0x1040),
4286 UPDATE_COEF(0xc3, 0, 1<<12),
4287 {}
4288 };
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004289 static struct coef_fw coef0225[] = {
4290 UPDATE_COEFEX(0x57, 0x05, 1<<14, 1<<14),
4291 UPDATE_COEF(0x4a, 3<<4, 2<<4),
4292 UPDATE_COEF(0x63, 3<<14, 0),
4293 {}
4294 };
Kailang Yang71683c32017-06-20 16:33:50 +08004295 static struct coef_fw coef0274[] = {
4296 UPDATE_COEFEX(0x57, 0x05, 0x4000, 0x4000),
4297 UPDATE_COEF(0x4a, 0x0010, 0),
4298 UPDATE_COEF(0x6b, 0xf000, 0),
4299 {}
4300 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004301
Takashi Iwai7639a062015-03-03 10:07:24 +01004302 switch (codec->core.vendor_id) {
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004303 case 0x10ec0255:
4304 alc_write_coef_idx(codec, 0x45, 0xc489);
4305 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02004306 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004307 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4308 break;
Kailang Yang717f43d2019-05-31 17:16:53 +08004309 case 0x10ec0236:
4310 case 0x10ec0256:
4311 alc_write_coef_idx(codec, 0x45, 0xc489);
4312 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4313 alc_process_coef_fw(codec, coef0256);
4314 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4315 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004316 case 0x10ec0234:
4317 case 0x10ec0274:
4318 case 0x10ec0294:
4319 alc_write_coef_idx(codec, 0x45, 0x4689);
4320 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4321 alc_process_coef_fw(codec, coef0274);
4322 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4323 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004324 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004325 case 0x10ec0283:
4326 alc_write_coef_idx(codec, 0x45, 0xc429);
4327 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02004328 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02004329 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4330 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004331 case 0x10ec0286:
4332 case 0x10ec0288:
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004333 case 0x10ec0298:
Kailang Yangf3b70332015-04-08 15:01:17 +08004334 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4335 alc_process_coef_fw(codec, coef0288);
4336 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4337 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004338 case 0x10ec0292:
4339 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02004340 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02004341 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004342 case 0x10ec0293:
4343 /* Set to TRS mode */
4344 alc_write_coef_idx(codec, 0x45, 0xc429);
4345 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02004346 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004347 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4348 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08004349 case 0x10ec0867:
4350 alc_update_coefex_idx(codec, 0x57, 0x5, 0, 1<<14);
4351 /* fallthru */
Kailang Yang9eb5d0e2017-01-17 15:40:25 +08004352 case 0x10ec0221:
David Henningsson1f8b46c2015-05-12 14:38:15 +02004353 case 0x10ec0662:
4354 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4355 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4356 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004357 case 0x10ec0668:
4358 alc_write_coef_idx(codec, 0x11, 0x0001);
4359 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02004360 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02004361 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4362 break;
Kailang Yangc2b691e2018-01-17 15:22:55 +08004363 case 0x10ec0215:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004364 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004365 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08004366 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004367 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08004368 case 0x10ec0299:
Kailang Yang5a367672017-07-21 15:23:53 +08004369 alc_process_coef_fw(codec, alc225_pre_hsmode);
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004370 alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x31<<10);
4371 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4372 alc_process_coef_fw(codec, coef0225);
4373 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4374 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004375 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01004376 codec_dbg(codec, "Headset jack set to mic-in mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02004377}
4378
4379static void alc_headset_mode_default(struct hda_codec *codec)
4380{
David Henningsson2ae95572016-02-25 09:37:05 +01004381 static struct coef_fw coef0225[] = {
Kailang Yang5a367672017-07-21 15:23:53 +08004382 UPDATE_COEF(0x45, 0x3f<<10, 0x30<<10),
4383 UPDATE_COEF(0x45, 0x3f<<10, 0x31<<10),
4384 UPDATE_COEF(0x49, 3<<8, 0<<8),
4385 UPDATE_COEF(0x4a, 3<<4, 3<<4),
4386 UPDATE_COEF(0x63, 3<<14, 0),
4387 UPDATE_COEF(0x67, 0xf000, 0x3000),
David Henningsson2ae95572016-02-25 09:37:05 +01004388 {}
4389 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004390 static struct coef_fw coef0255[] = {
4391 WRITE_COEF(0x45, 0xc089),
4392 WRITE_COEF(0x45, 0xc489),
4393 WRITE_COEFEX(0x57, 0x03, 0x8ea6),
4394 WRITE_COEF(0x49, 0x0049),
4395 {}
4396 };
Kailang Yang717f43d2019-05-31 17:16:53 +08004397 static struct coef_fw coef0256[] = {
4398 WRITE_COEF(0x45, 0xc489),
4399 WRITE_COEFEX(0x57, 0x03, 0x0da3),
4400 WRITE_COEF(0x49, 0x0049),
4401 UPDATE_COEFEX(0x57, 0x05, 1<<14, 0), /* Direct Drive HP Amp control(Set to verb control)*/
4402 WRITE_COEF(0x06, 0x6100),
4403 {}
4404 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004405 static struct coef_fw coef0233[] = {
4406 WRITE_COEF(0x06, 0x2100),
4407 WRITE_COEF(0x32, 0x4ea3),
4408 {}
4409 };
Kailang Yangf3b70332015-04-08 15:01:17 +08004410 static struct coef_fw coef0288[] = {
4411 UPDATE_COEF(0x4f, 0xfcc0, 0xc400), /* Set to TRS type */
4412 UPDATE_COEF(0x50, 0x2000, 0x2000),
4413 UPDATE_COEF(0x56, 0x0006, 0x0006),
4414 UPDATE_COEF(0x66, 0x0008, 0),
4415 UPDATE_COEF(0x67, 0x2000, 0),
4416 {}
4417 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004418 static struct coef_fw coef0292[] = {
4419 WRITE_COEF(0x76, 0x000e),
4420 WRITE_COEF(0x6c, 0x2400),
4421 WRITE_COEF(0x6b, 0xc429),
4422 WRITE_COEF(0x18, 0x7308),
4423 {}
4424 };
4425 static struct coef_fw coef0293[] = {
4426 UPDATE_COEF(0x4a, 0x000f, 0x000e), /* Combo Jack auto detect */
4427 WRITE_COEF(0x45, 0xC429), /* Set to TRS type */
4428 UPDATE_COEF(0x1a, 1<<3, 0), /* Combo JD gating without LINE1-VREFO */
4429 {}
4430 };
4431 static struct coef_fw coef0688[] = {
4432 WRITE_COEF(0x11, 0x0041),
4433 WRITE_COEF(0x15, 0x0d40),
4434 WRITE_COEF(0xb7, 0x802b),
4435 {}
4436 };
Kailang Yang71683c32017-06-20 16:33:50 +08004437 static struct coef_fw coef0274[] = {
4438 WRITE_COEF(0x45, 0x4289),
4439 UPDATE_COEF(0x4a, 0x0010, 0x0010),
4440 UPDATE_COEF(0x6b, 0x0f00, 0),
4441 UPDATE_COEF(0x49, 0x0300, 0x0300),
4442 {}
4443 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004444
Takashi Iwai7639a062015-03-03 10:07:24 +01004445 switch (codec->core.vendor_id) {
Kailang Yangc2b691e2018-01-17 15:22:55 +08004446 case 0x10ec0215:
David Henningsson2ae95572016-02-25 09:37:05 +01004447 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004448 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08004449 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004450 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08004451 case 0x10ec0299:
Kailang Yang5a367672017-07-21 15:23:53 +08004452 alc_process_coef_fw(codec, alc225_pre_hsmode);
David Henningsson2ae95572016-02-25 09:37:05 +01004453 alc_process_coef_fw(codec, coef0225);
4454 break;
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004455 case 0x10ec0255:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004456 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004457 break;
Kailang Yang717f43d2019-05-31 17:16:53 +08004458 case 0x10ec0236:
4459 case 0x10ec0256:
4460 alc_write_coef_idx(codec, 0x1b, 0x0e4b);
4461 alc_write_coef_idx(codec, 0x45, 0xc089);
4462 msleep(50);
4463 alc_process_coef_fw(codec, coef0256);
4464 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004465 case 0x10ec0234:
4466 case 0x10ec0274:
4467 case 0x10ec0294:
4468 alc_process_coef_fw(codec, coef0274);
4469 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004470 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004471 case 0x10ec0283:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004472 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02004473 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004474 case 0x10ec0286:
4475 case 0x10ec0288:
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004476 case 0x10ec0298:
Kailang Yangf3b70332015-04-08 15:01:17 +08004477 alc_process_coef_fw(codec, coef0288);
4478 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004479 case 0x10ec0292:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004480 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02004481 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004482 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004483 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004484 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004485 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004486 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02004487 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08004488 case 0x10ec0867:
4489 alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
4490 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004491 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01004492 codec_dbg(codec, "Headset jack set to headphone (default) mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02004493}
4494
4495/* Iphone type */
4496static void alc_headset_mode_ctia(struct hda_codec *codec)
4497{
Kailang Yang89542932017-07-17 15:03:43 +08004498 int val;
4499
Takashi Iwai54db6c32014-08-18 15:11:19 +02004500 static struct coef_fw coef0255[] = {
4501 WRITE_COEF(0x45, 0xd489), /* Set to CTIA type */
4502 WRITE_COEF(0x1b, 0x0c2b),
4503 WRITE_COEFEX(0x57, 0x03, 0x8ea6),
4504 {}
4505 };
Kailang Yange69e7e02016-05-30 15:58:28 +08004506 static struct coef_fw coef0256[] = {
4507 WRITE_COEF(0x45, 0xd489), /* Set to CTIA type */
Kailang Yang717f43d2019-05-31 17:16:53 +08004508 WRITE_COEF(0x1b, 0x0e6b),
Kailang Yange69e7e02016-05-30 15:58:28 +08004509 {}
4510 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004511 static struct coef_fw coef0233[] = {
4512 WRITE_COEF(0x45, 0xd429),
4513 WRITE_COEF(0x1b, 0x0c2b),
4514 WRITE_COEF(0x32, 0x4ea3),
4515 {}
4516 };
Kailang Yangf3b70332015-04-08 15:01:17 +08004517 static struct coef_fw coef0288[] = {
4518 UPDATE_COEF(0x50, 0x2000, 0x2000),
4519 UPDATE_COEF(0x56, 0x0006, 0x0006),
4520 UPDATE_COEF(0x66, 0x0008, 0),
4521 UPDATE_COEF(0x67, 0x2000, 0),
4522 {}
4523 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004524 static struct coef_fw coef0292[] = {
4525 WRITE_COEF(0x6b, 0xd429),
4526 WRITE_COEF(0x76, 0x0008),
4527 WRITE_COEF(0x18, 0x7388),
4528 {}
4529 };
4530 static struct coef_fw coef0293[] = {
4531 WRITE_COEF(0x45, 0xd429), /* Set to ctia type */
4532 UPDATE_COEF(0x10, 7<<8, 7<<8), /* SET Line1 JD to 1 */
4533 {}
4534 };
4535 static struct coef_fw coef0688[] = {
4536 WRITE_COEF(0x11, 0x0001),
4537 WRITE_COEF(0x15, 0x0d60),
4538 WRITE_COEF(0xc3, 0x0000),
4539 {}
4540 };
Kailang Yang5a367672017-07-21 15:23:53 +08004541 static struct coef_fw coef0225_1[] = {
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004542 UPDATE_COEF(0x45, 0x3f<<10, 0x35<<10),
Kailang Yang5a367672017-07-21 15:23:53 +08004543 UPDATE_COEF(0x63, 3<<14, 2<<14),
4544 {}
4545 };
4546 static struct coef_fw coef0225_2[] = {
4547 UPDATE_COEF(0x45, 0x3f<<10, 0x35<<10),
4548 UPDATE_COEF(0x63, 3<<14, 1<<14),
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004549 {}
4550 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004551
Takashi Iwai7639a062015-03-03 10:07:24 +01004552 switch (codec->core.vendor_id) {
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004553 case 0x10ec0255:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004554 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004555 break;
Kailang Yang736f20a2017-10-20 15:06:34 +08004556 case 0x10ec0236:
Kailang Yange69e7e02016-05-30 15:58:28 +08004557 case 0x10ec0256:
4558 alc_process_coef_fw(codec, coef0256);
4559 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004560 case 0x10ec0234:
4561 case 0x10ec0274:
4562 case 0x10ec0294:
4563 alc_write_coef_idx(codec, 0x45, 0xd689);
4564 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004565 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004566 case 0x10ec0283:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004567 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02004568 break;
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004569 case 0x10ec0298:
Kailang Yang89542932017-07-17 15:03:43 +08004570 val = alc_read_coef_idx(codec, 0x50);
4571 if (val & (1 << 12)) {
4572 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0020);
4573 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400);
4574 msleep(300);
4575 } else {
4576 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0010);
4577 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400);
4578 msleep(300);
4579 }
4580 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004581 case 0x10ec0286:
4582 case 0x10ec0288:
4583 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400);
4584 msleep(300);
4585 alc_process_coef_fw(codec, coef0288);
4586 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004587 case 0x10ec0292:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004588 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02004589 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004590 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004591 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004592 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004593 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004594 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02004595 break;
Kailang Yangc2b691e2018-01-17 15:22:55 +08004596 case 0x10ec0215:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004597 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004598 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08004599 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004600 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08004601 case 0x10ec0299:
Kailang Yang5a367672017-07-21 15:23:53 +08004602 val = alc_read_coef_idx(codec, 0x45);
4603 if (val & (1 << 9))
4604 alc_process_coef_fw(codec, coef0225_2);
4605 else
4606 alc_process_coef_fw(codec, coef0225_1);
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004607 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08004608 case 0x10ec0867:
4609 alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
4610 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004611 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01004612 codec_dbg(codec, "Headset jack set to iPhone-style headset mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02004613}
4614
4615/* Nokia type */
4616static void alc_headset_mode_omtp(struct hda_codec *codec)
4617{
Takashi Iwai54db6c32014-08-18 15:11:19 +02004618 static struct coef_fw coef0255[] = {
4619 WRITE_COEF(0x45, 0xe489), /* Set to OMTP Type */
4620 WRITE_COEF(0x1b, 0x0c2b),
4621 WRITE_COEFEX(0x57, 0x03, 0x8ea6),
4622 {}
4623 };
Kailang Yange69e7e02016-05-30 15:58:28 +08004624 static struct coef_fw coef0256[] = {
4625 WRITE_COEF(0x45, 0xe489), /* Set to OMTP Type */
Kailang Yang717f43d2019-05-31 17:16:53 +08004626 WRITE_COEF(0x1b, 0x0e6b),
Kailang Yange69e7e02016-05-30 15:58:28 +08004627 {}
4628 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004629 static struct coef_fw coef0233[] = {
4630 WRITE_COEF(0x45, 0xe429),
4631 WRITE_COEF(0x1b, 0x0c2b),
4632 WRITE_COEF(0x32, 0x4ea3),
4633 {}
4634 };
Kailang Yangf3b70332015-04-08 15:01:17 +08004635 static struct coef_fw coef0288[] = {
4636 UPDATE_COEF(0x50, 0x2000, 0x2000),
4637 UPDATE_COEF(0x56, 0x0006, 0x0006),
4638 UPDATE_COEF(0x66, 0x0008, 0),
4639 UPDATE_COEF(0x67, 0x2000, 0),
4640 {}
4641 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004642 static struct coef_fw coef0292[] = {
4643 WRITE_COEF(0x6b, 0xe429),
4644 WRITE_COEF(0x76, 0x0008),
4645 WRITE_COEF(0x18, 0x7388),
4646 {}
4647 };
4648 static struct coef_fw coef0293[] = {
4649 WRITE_COEF(0x45, 0xe429), /* Set to omtp type */
4650 UPDATE_COEF(0x10, 7<<8, 7<<8), /* SET Line1 JD to 1 */
4651 {}
4652 };
4653 static struct coef_fw coef0688[] = {
4654 WRITE_COEF(0x11, 0x0001),
4655 WRITE_COEF(0x15, 0x0d50),
4656 WRITE_COEF(0xc3, 0x0000),
4657 {}
4658 };
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004659 static struct coef_fw coef0225[] = {
4660 UPDATE_COEF(0x45, 0x3f<<10, 0x39<<10),
Kailang Yang5a367672017-07-21 15:23:53 +08004661 UPDATE_COEF(0x63, 3<<14, 2<<14),
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004662 {}
4663 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004664
Takashi Iwai7639a062015-03-03 10:07:24 +01004665 switch (codec->core.vendor_id) {
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004666 case 0x10ec0255:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004667 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004668 break;
Kailang Yang736f20a2017-10-20 15:06:34 +08004669 case 0x10ec0236:
Kailang Yange69e7e02016-05-30 15:58:28 +08004670 case 0x10ec0256:
4671 alc_process_coef_fw(codec, coef0256);
4672 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004673 case 0x10ec0234:
4674 case 0x10ec0274:
4675 case 0x10ec0294:
4676 alc_write_coef_idx(codec, 0x45, 0xe689);
4677 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004678 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004679 case 0x10ec0283:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004680 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02004681 break;
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004682 case 0x10ec0298:
4683 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0010);/* Headset output enable */
Kailang Yang89542932017-07-17 15:03:43 +08004684 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xe400);
4685 msleep(300);
4686 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004687 case 0x10ec0286:
4688 case 0x10ec0288:
4689 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xe400);
4690 msleep(300);
4691 alc_process_coef_fw(codec, coef0288);
4692 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004693 case 0x10ec0292:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004694 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02004695 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004696 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004697 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004698 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004699 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004700 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02004701 break;
Kailang Yangc2b691e2018-01-17 15:22:55 +08004702 case 0x10ec0215:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004703 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004704 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08004705 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004706 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08004707 case 0x10ec0299:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004708 alc_process_coef_fw(codec, coef0225);
4709 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004710 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01004711 codec_dbg(codec, "Headset jack set to Nokia-style headset mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02004712}
4713
4714static void alc_determine_headset_type(struct hda_codec *codec)
4715{
4716 int val;
4717 bool is_ctia = false;
4718 struct alc_spec *spec = codec->spec;
Takashi Iwai54db6c32014-08-18 15:11:19 +02004719 static struct coef_fw coef0255[] = {
4720 WRITE_COEF(0x45, 0xd089), /* combo jack auto switch control(Check type)*/
4721 WRITE_COEF(0x49, 0x0149), /* combo jack auto switch control(Vref
4722 conteol) */
4723 {}
4724 };
Kailang Yangf3b70332015-04-08 15:01:17 +08004725 static struct coef_fw coef0288[] = {
4726 UPDATE_COEF(0x4f, 0xfcc0, 0xd400), /* Check Type */
4727 {}
4728 };
Kailang Yang89542932017-07-17 15:03:43 +08004729 static struct coef_fw coef0298[] = {
4730 UPDATE_COEF(0x50, 0x2000, 0x2000),
4731 UPDATE_COEF(0x56, 0x0006, 0x0006),
4732 UPDATE_COEF(0x66, 0x0008, 0),
4733 UPDATE_COEF(0x67, 0x2000, 0),
4734 UPDATE_COEF(0x19, 0x1300, 0x1300),
4735 {}
4736 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004737 static struct coef_fw coef0293[] = {
4738 UPDATE_COEF(0x4a, 0x000f, 0x0008), /* Combo Jack auto detect */
4739 WRITE_COEF(0x45, 0xD429), /* Set to ctia type */
4740 {}
4741 };
4742 static struct coef_fw coef0688[] = {
4743 WRITE_COEF(0x11, 0x0001),
4744 WRITE_COEF(0xb7, 0x802b),
4745 WRITE_COEF(0x15, 0x0d60),
4746 WRITE_COEF(0xc3, 0x0c00),
4747 {}
4748 };
Kailang Yang71683c32017-06-20 16:33:50 +08004749 static struct coef_fw coef0274[] = {
4750 UPDATE_COEF(0x4a, 0x0010, 0),
4751 UPDATE_COEF(0x4a, 0x8000, 0),
4752 WRITE_COEF(0x45, 0xd289),
4753 UPDATE_COEF(0x49, 0x0300, 0x0300),
4754 {}
4755 };
David Henningsson73bdd592013-04-15 15:44:14 +02004756
Takashi Iwai7639a062015-03-03 10:07:24 +01004757 switch (codec->core.vendor_id) {
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004758 case 0x10ec0255:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004759 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004760 msleep(300);
4761 val = alc_read_coef_idx(codec, 0x46);
4762 is_ctia = (val & 0x0070) == 0x0070;
4763 break;
Kailang Yang717f43d2019-05-31 17:16:53 +08004764 case 0x10ec0236:
4765 case 0x10ec0256:
4766 alc_write_coef_idx(codec, 0x1b, 0x0e4b);
4767 alc_write_coef_idx(codec, 0x06, 0x6104);
4768 alc_write_coefex_idx(codec, 0x57, 0x3, 0x09a3);
4769
4770 snd_hda_codec_write(codec, 0x21, 0,
4771 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
4772 msleep(80);
4773 snd_hda_codec_write(codec, 0x21, 0,
4774 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
4775
4776 alc_process_coef_fw(codec, coef0255);
4777 msleep(300);
4778 val = alc_read_coef_idx(codec, 0x46);
4779 is_ctia = (val & 0x0070) == 0x0070;
4780
4781 alc_write_coefex_idx(codec, 0x57, 0x3, 0x0da3);
4782 alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
4783
4784 snd_hda_codec_write(codec, 0x21, 0,
4785 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
4786 msleep(80);
4787 snd_hda_codec_write(codec, 0x21, 0,
4788 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
4789 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004790 case 0x10ec0234:
4791 case 0x10ec0274:
4792 case 0x10ec0294:
4793 alc_process_coef_fw(codec, coef0274);
4794 msleep(80);
4795 val = alc_read_coef_idx(codec, 0x46);
4796 is_ctia = (val & 0x00f0) == 0x00f0;
4797 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004798 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004799 case 0x10ec0283:
4800 alc_write_coef_idx(codec, 0x45, 0xd029);
4801 msleep(300);
4802 val = alc_read_coef_idx(codec, 0x46);
4803 is_ctia = (val & 0x0070) == 0x0070;
4804 break;
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004805 case 0x10ec0298:
Kailang Yang89542932017-07-17 15:03:43 +08004806 snd_hda_codec_write(codec, 0x21, 0,
4807 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
4808 msleep(100);
4809 snd_hda_codec_write(codec, 0x21, 0,
4810 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
4811 msleep(200);
4812
4813 val = alc_read_coef_idx(codec, 0x50);
4814 if (val & (1 << 12)) {
4815 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0020);
4816 alc_process_coef_fw(codec, coef0288);
4817 msleep(350);
4818 val = alc_read_coef_idx(codec, 0x50);
4819 is_ctia = (val & 0x0070) == 0x0070;
4820 } else {
4821 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0010);
4822 alc_process_coef_fw(codec, coef0288);
4823 msleep(350);
4824 val = alc_read_coef_idx(codec, 0x50);
4825 is_ctia = (val & 0x0070) == 0x0070;
4826 }
4827 alc_process_coef_fw(codec, coef0298);
4828 snd_hda_codec_write(codec, 0x21, 0,
4829 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP);
4830 msleep(75);
4831 snd_hda_codec_write(codec, 0x21, 0,
4832 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
4833 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004834 case 0x10ec0286:
4835 case 0x10ec0288:
4836 alc_process_coef_fw(codec, coef0288);
4837 msleep(350);
4838 val = alc_read_coef_idx(codec, 0x50);
4839 is_ctia = (val & 0x0070) == 0x0070;
4840 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004841 case 0x10ec0292:
4842 alc_write_coef_idx(codec, 0x6b, 0xd429);
4843 msleep(300);
4844 val = alc_read_coef_idx(codec, 0x6c);
4845 is_ctia = (val & 0x001c) == 0x001c;
4846 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004847 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004848 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004849 msleep(300);
4850 val = alc_read_coef_idx(codec, 0x46);
4851 is_ctia = (val & 0x0070) == 0x0070;
4852 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004853 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004854 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02004855 msleep(300);
4856 val = alc_read_coef_idx(codec, 0xbe);
4857 is_ctia = (val & 0x1c02) == 0x1c02;
4858 break;
Kailang Yangc2b691e2018-01-17 15:22:55 +08004859 case 0x10ec0215:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004860 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004861 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08004862 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004863 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08004864 case 0x10ec0299:
Kailang Yangda911b12018-01-05 16:50:08 +08004865 snd_hda_codec_write(codec, 0x21, 0,
4866 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
4867 msleep(80);
4868 snd_hda_codec_write(codec, 0x21, 0,
4869 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
4870
Kailang Yang5a367672017-07-21 15:23:53 +08004871 alc_process_coef_fw(codec, alc225_pre_hsmode);
4872 alc_update_coef_idx(codec, 0x67, 0xf000, 0x1000);
4873 val = alc_read_coef_idx(codec, 0x45);
4874 if (val & (1 << 9)) {
4875 alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x34<<10);
4876 alc_update_coef_idx(codec, 0x49, 3<<8, 2<<8);
4877 msleep(800);
4878 val = alc_read_coef_idx(codec, 0x46);
4879 is_ctia = (val & 0x00f0) == 0x00f0;
4880 } else {
4881 alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x34<<10);
4882 alc_update_coef_idx(codec, 0x49, 3<<8, 1<<8);
4883 msleep(800);
4884 val = alc_read_coef_idx(codec, 0x46);
4885 is_ctia = (val & 0x00f0) == 0x00f0;
4886 }
4887 alc_update_coef_idx(codec, 0x4a, 7<<6, 7<<6);
4888 alc_update_coef_idx(codec, 0x4a, 3<<4, 3<<4);
4889 alc_update_coef_idx(codec, 0x67, 0xf000, 0x3000);
Kailang Yangda911b12018-01-05 16:50:08 +08004890
4891 snd_hda_codec_write(codec, 0x21, 0,
4892 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
4893 msleep(80);
4894 snd_hda_codec_write(codec, 0x21, 0,
4895 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004896 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08004897 case 0x10ec0867:
4898 is_ctia = true;
4899 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004900 }
4901
Takashi Iwai4e76a882014-02-25 12:21:03 +01004902 codec_dbg(codec, "Headset jack detected iPhone-style headset: %s\n",
David Henningsson73bdd592013-04-15 15:44:14 +02004903 is_ctia ? "yes" : "no");
4904 spec->current_headset_type = is_ctia ? ALC_HEADSET_TYPE_CTIA : ALC_HEADSET_TYPE_OMTP;
4905}
4906
4907static void alc_update_headset_mode(struct hda_codec *codec)
4908{
4909 struct alc_spec *spec = codec->spec;
4910
4911 hda_nid_t mux_pin = spec->gen.imux_pins[spec->gen.cur_mux[0]];
Takashi Iwai35a39f92019-02-01 11:19:50 +01004912 hda_nid_t hp_pin = alc_get_hp_pin(spec);
David Henningsson73bdd592013-04-15 15:44:14 +02004913
4914 int new_headset_mode;
4915
4916 if (!snd_hda_jack_detect(codec, hp_pin))
4917 new_headset_mode = ALC_HEADSET_MODE_UNPLUGGED;
4918 else if (mux_pin == spec->headset_mic_pin)
4919 new_headset_mode = ALC_HEADSET_MODE_HEADSET;
4920 else if (mux_pin == spec->headphone_mic_pin)
4921 new_headset_mode = ALC_HEADSET_MODE_MIC;
4922 else
4923 new_headset_mode = ALC_HEADSET_MODE_HEADPHONE;
4924
David Henningsson5959a6b2013-11-12 11:10:57 +01004925 if (new_headset_mode == spec->current_headset_mode) {
4926 snd_hda_gen_update_outputs(codec);
David Henningsson73bdd592013-04-15 15:44:14 +02004927 return;
David Henningsson5959a6b2013-11-12 11:10:57 +01004928 }
David Henningsson73bdd592013-04-15 15:44:14 +02004929
4930 switch (new_headset_mode) {
4931 case ALC_HEADSET_MODE_UNPLUGGED:
4932 alc_headset_mode_unplugged(codec);
Kailang Yangaeac1a02019-05-16 16:10:44 +08004933 spec->current_headset_mode = ALC_HEADSET_MODE_UNKNOWN;
4934 spec->current_headset_type = ALC_HEADSET_TYPE_UNKNOWN;
David Henningsson73bdd592013-04-15 15:44:14 +02004935 spec->gen.hp_jack_present = false;
4936 break;
4937 case ALC_HEADSET_MODE_HEADSET:
4938 if (spec->current_headset_type == ALC_HEADSET_TYPE_UNKNOWN)
4939 alc_determine_headset_type(codec);
4940 if (spec->current_headset_type == ALC_HEADSET_TYPE_CTIA)
4941 alc_headset_mode_ctia(codec);
4942 else if (spec->current_headset_type == ALC_HEADSET_TYPE_OMTP)
4943 alc_headset_mode_omtp(codec);
4944 spec->gen.hp_jack_present = true;
4945 break;
4946 case ALC_HEADSET_MODE_MIC:
4947 alc_headset_mode_mic_in(codec, hp_pin, spec->headphone_mic_pin);
4948 spec->gen.hp_jack_present = false;
4949 break;
4950 case ALC_HEADSET_MODE_HEADPHONE:
4951 alc_headset_mode_default(codec);
4952 spec->gen.hp_jack_present = true;
4953 break;
4954 }
4955 if (new_headset_mode != ALC_HEADSET_MODE_MIC) {
4956 snd_hda_set_pin_ctl_cache(codec, hp_pin,
4957 AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN);
David Henningsson1f8b46c2015-05-12 14:38:15 +02004958 if (spec->headphone_mic_pin && spec->headphone_mic_pin != hp_pin)
David Henningsson73bdd592013-04-15 15:44:14 +02004959 snd_hda_set_pin_ctl_cache(codec, spec->headphone_mic_pin,
4960 PIN_VREFHIZ);
4961 }
4962 spec->current_headset_mode = new_headset_mode;
4963
4964 snd_hda_gen_update_outputs(codec);
4965}
4966
4967static void alc_update_headset_mode_hook(struct hda_codec *codec,
Takashi Iwai7fe30712014-01-30 17:59:02 +01004968 struct snd_kcontrol *kcontrol,
4969 struct snd_ctl_elem_value *ucontrol)
David Henningsson73bdd592013-04-15 15:44:14 +02004970{
4971 alc_update_headset_mode(codec);
4972}
4973
Takashi Iwai1a4f69d2014-09-11 15:22:46 +02004974static void alc_update_headset_jack_cb(struct hda_codec *codec,
4975 struct hda_jack_callback *jack)
David Henningsson73bdd592013-04-15 15:44:14 +02004976{
David Henningsson73bdd592013-04-15 15:44:14 +02004977 snd_hda_gen_hp_automute(codec, jack);
4978}
4979
4980static void alc_probe_headset_mode(struct hda_codec *codec)
4981{
4982 int i;
4983 struct alc_spec *spec = codec->spec;
4984 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
4985
4986 /* Find mic pins */
4987 for (i = 0; i < cfg->num_inputs; i++) {
4988 if (cfg->inputs[i].is_headset_mic && !spec->headset_mic_pin)
4989 spec->headset_mic_pin = cfg->inputs[i].pin;
4990 if (cfg->inputs[i].is_headphone_mic && !spec->headphone_mic_pin)
4991 spec->headphone_mic_pin = cfg->inputs[i].pin;
4992 }
4993
Takashi Iwai0bed2aa2018-06-19 12:45:53 +02004994 WARN_ON(spec->gen.cap_sync_hook);
David Henningsson73bdd592013-04-15 15:44:14 +02004995 spec->gen.cap_sync_hook = alc_update_headset_mode_hook;
4996 spec->gen.automute_hook = alc_update_headset_mode;
4997 spec->gen.hp_automute_hook = alc_update_headset_jack_cb;
4998}
4999
5000static void alc_fixup_headset_mode(struct hda_codec *codec,
5001 const struct hda_fixup *fix, int action)
5002{
5003 struct alc_spec *spec = codec->spec;
5004
5005 switch (action) {
5006 case HDA_FIXUP_ACT_PRE_PROBE:
5007 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC | HDA_PINCFG_HEADPHONE_MIC;
5008 break;
5009 case HDA_FIXUP_ACT_PROBE:
5010 alc_probe_headset_mode(codec);
5011 break;
5012 case HDA_FIXUP_ACT_INIT:
Kailang Yangaeac1a02019-05-16 16:10:44 +08005013 if (is_s3_resume(codec) || is_s4_resume(codec)) {
5014 spec->current_headset_mode = ALC_HEADSET_MODE_UNKNOWN;
5015 spec->current_headset_type = ALC_HEADSET_TYPE_UNKNOWN;
5016 }
David Henningsson73bdd592013-04-15 15:44:14 +02005017 alc_update_headset_mode(codec);
5018 break;
5019 }
5020}
5021
5022static void alc_fixup_headset_mode_no_hp_mic(struct hda_codec *codec,
5023 const struct hda_fixup *fix, int action)
5024{
5025 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5026 struct alc_spec *spec = codec->spec;
5027 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
5028 }
5029 else
5030 alc_fixup_headset_mode(codec, fix, action);
5031}
5032
Kailang Yang31278992014-03-03 15:27:22 +08005033static void alc255_set_default_jack_type(struct hda_codec *codec)
5034{
5035 /* Set to iphone type */
Kailang Yange69e7e02016-05-30 15:58:28 +08005036 static struct coef_fw alc255fw[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02005037 WRITE_COEF(0x1b, 0x880b),
5038 WRITE_COEF(0x45, 0xd089),
5039 WRITE_COEF(0x1b, 0x080b),
5040 WRITE_COEF(0x46, 0x0004),
5041 WRITE_COEF(0x1b, 0x0c0b),
5042 {}
5043 };
Kailang Yange69e7e02016-05-30 15:58:28 +08005044 static struct coef_fw alc256fw[] = {
5045 WRITE_COEF(0x1b, 0x884b),
5046 WRITE_COEF(0x45, 0xd089),
5047 WRITE_COEF(0x1b, 0x084b),
5048 WRITE_COEF(0x46, 0x0004),
5049 WRITE_COEF(0x1b, 0x0c4b),
5050 {}
5051 };
5052 switch (codec->core.vendor_id) {
5053 case 0x10ec0255:
5054 alc_process_coef_fw(codec, alc255fw);
5055 break;
Kailang Yang736f20a2017-10-20 15:06:34 +08005056 case 0x10ec0236:
Kailang Yange69e7e02016-05-30 15:58:28 +08005057 case 0x10ec0256:
5058 alc_process_coef_fw(codec, alc256fw);
5059 break;
5060 }
Kailang Yang31278992014-03-03 15:27:22 +08005061 msleep(30);
5062}
5063
Kailang Yang9a22a8f52013-11-08 15:54:49 +08005064static void alc_fixup_headset_mode_alc255(struct hda_codec *codec,
5065 const struct hda_fixup *fix, int action)
5066{
5067 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Kailang Yang31278992014-03-03 15:27:22 +08005068 alc255_set_default_jack_type(codec);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08005069 }
5070 alc_fixup_headset_mode(codec, fix, action);
5071}
5072
Kailang Yang31278992014-03-03 15:27:22 +08005073static void alc_fixup_headset_mode_alc255_no_hp_mic(struct hda_codec *codec,
5074 const struct hda_fixup *fix, int action)
5075{
5076 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5077 struct alc_spec *spec = codec->spec;
5078 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
5079 alc255_set_default_jack_type(codec);
5080 }
5081 else
5082 alc_fixup_headset_mode(codec, fix, action);
5083}
5084
Kailang Yange1e62b92015-04-08 16:01:22 +08005085static void alc288_update_headset_jack_cb(struct hda_codec *codec,
5086 struct hda_jack_callback *jack)
5087{
5088 struct alc_spec *spec = codec->spec;
Kailang Yange1e62b92015-04-08 16:01:22 +08005089
5090 alc_update_headset_jack_cb(codec, jack);
5091 /* Headset Mic enable or disable, only for Dell Dino */
Takashi Iwaid44a6862018-06-19 23:04:03 +02005092 alc_update_gpio_data(codec, 0x40, spec->gen.hp_jack_present);
Kailang Yange1e62b92015-04-08 16:01:22 +08005093}
5094
5095static void alc_fixup_headset_mode_dell_alc288(struct hda_codec *codec,
5096 const struct hda_fixup *fix, int action)
5097{
5098 alc_fixup_headset_mode(codec, fix, action);
5099 if (action == HDA_FIXUP_ACT_PROBE) {
5100 struct alc_spec *spec = codec->spec;
Takashi Iwaid44a6862018-06-19 23:04:03 +02005101 /* toggled via hp_automute_hook */
5102 spec->gpio_mask |= 0x40;
5103 spec->gpio_dir |= 0x40;
Kailang Yange1e62b92015-04-08 16:01:22 +08005104 spec->gen.hp_automute_hook = alc288_update_headset_jack_cb;
5105 }
5106}
5107
Hui Wang493a52a2014-01-14 14:07:36 +08005108static void alc_fixup_auto_mute_via_amp(struct hda_codec *codec,
5109 const struct hda_fixup *fix, int action)
5110{
5111 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5112 struct alc_spec *spec = codec->spec;
5113 spec->gen.auto_mute_via_amp = 1;
5114 }
5115}
5116
Takashi Iwai9b745ab2014-03-07 08:37:19 +01005117static void alc_fixup_no_shutup(struct hda_codec *codec,
5118 const struct hda_fixup *fix, int action)
5119{
Takashi Iwaiefe55732018-06-15 11:55:02 +02005120 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai9b745ab2014-03-07 08:37:19 +01005121 struct alc_spec *spec = codec->spec;
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01005122 spec->no_shutup_pins = 1;
Takashi Iwai9b745ab2014-03-07 08:37:19 +01005123 }
5124}
5125
Gabriele Mazzotta5e6db662014-05-20 18:58:26 +02005126static void alc_fixup_disable_aamix(struct hda_codec *codec,
5127 const struct hda_fixup *fix, int action)
5128{
5129 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5130 struct alc_spec *spec = codec->spec;
5131 /* Disable AA-loopback as it causes white noise */
5132 spec->gen.mixer_nid = 0;
5133 }
5134}
5135
Takashi Iwai7f57d802015-09-24 17:36:51 +02005136/* fixup for Thinkpad docks: add dock pins, avoid HP parser fixup */
5137static void alc_fixup_tpt440_dock(struct hda_codec *codec,
5138 const struct hda_fixup *fix, int action)
5139{
5140 static const struct hda_pintbl pincfgs[] = {
5141 { 0x16, 0x21211010 }, /* dock headphone */
5142 { 0x19, 0x21a11010 }, /* dock mic */
5143 { }
5144 };
5145 struct alc_spec *spec = codec->spec;
5146
5147 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Hui Wang871b9062019-08-14 12:09:08 +08005148 spec->reboot_notify = snd_hda_gen_reboot_notify; /* reduce noise */
Takashi Iwai7f57d802015-09-24 17:36:51 +02005149 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
5150 codec->power_save_node = 0; /* avoid click noises */
5151 snd_hda_apply_pincfgs(codec, pincfgs);
5152 }
5153}
5154
Kailang Yang61fcf8e2018-02-02 15:26:46 +08005155static void alc_fixup_tpt470_dock(struct hda_codec *codec,
5156 const struct hda_fixup *fix, int action)
5157{
5158 static const struct hda_pintbl pincfgs[] = {
5159 { 0x17, 0x21211010 }, /* dock headphone */
5160 { 0x19, 0x21a11010 }, /* dock mic */
5161 { }
5162 };
Takashi Iwai54947cd2018-12-03 10:44:15 +01005163 /* Assure the speaker pin to be coupled with DAC NID 0x03; otherwise
5164 * the speaker output becomes too low by some reason on Thinkpads with
5165 * ALC298 codec
5166 */
5167 static hda_nid_t preferred_pairs[] = {
5168 0x14, 0x03, 0x17, 0x02, 0x21, 0x02,
5169 0
5170 };
Kailang Yang61fcf8e2018-02-02 15:26:46 +08005171 struct alc_spec *spec = codec->spec;
5172
5173 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai54947cd2018-12-03 10:44:15 +01005174 spec->gen.preferred_dacs = preferred_pairs;
Kailang Yang61fcf8e2018-02-02 15:26:46 +08005175 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
Takashi Iwai71db96d2018-02-26 15:36:38 +01005176 snd_hda_apply_pincfgs(codec, pincfgs);
5177 } else if (action == HDA_FIXUP_ACT_INIT) {
Kailang Yang61fcf8e2018-02-02 15:26:46 +08005178 /* Enable DOCK device */
5179 snd_hda_codec_write(codec, 0x17, 0,
5180 AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0);
5181 /* Enable DOCK device */
5182 snd_hda_codec_write(codec, 0x19, 0,
5183 AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0);
Kailang Yang61fcf8e2018-02-02 15:26:46 +08005184 }
5185}
5186
Gabriele Mazzotta9476d3692015-04-19 19:00:40 +02005187static void alc_shutup_dell_xps13(struct hda_codec *codec)
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02005188{
5189 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01005190 int hp_pin = alc_get_hp_pin(spec);
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02005191
Gabriele Mazzotta9476d3692015-04-19 19:00:40 +02005192 /* Prevent pop noises when headphones are plugged in */
5193 snd_hda_codec_write(codec, hp_pin, 0,
5194 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
5195 msleep(20);
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02005196}
5197
5198static void alc_fixup_dell_xps13(struct hda_codec *codec,
5199 const struct hda_fixup *fix, int action)
5200{
Takashi Iwai3e1b0c42015-04-27 10:43:22 +02005201 struct alc_spec *spec = codec->spec;
5202 struct hda_input_mux *imux = &spec->gen.input_mux;
5203 int i;
Gabriele Mazzottaf38663a2014-08-08 19:34:40 +02005204
Takashi Iwai3e1b0c42015-04-27 10:43:22 +02005205 switch (action) {
5206 case HDA_FIXUP_ACT_PRE_PROBE:
5207 /* mic pin 0x19 must be initialized with Vref Hi-Z, otherwise
5208 * it causes a click noise at start up
5209 */
5210 snd_hda_codec_set_pin_target(codec, 0x19, PIN_VREFHIZ);
Takashi Iwaiefe55732018-06-15 11:55:02 +02005211 spec->shutup = alc_shutup_dell_xps13;
Takashi Iwai3e1b0c42015-04-27 10:43:22 +02005212 break;
5213 case HDA_FIXUP_ACT_PROBE:
Gabriele Mazzottaf38663a2014-08-08 19:34:40 +02005214 /* Make the internal mic the default input source. */
5215 for (i = 0; i < imux->num_items; i++) {
5216 if (spec->gen.imux_pins[i] == 0x12) {
5217 spec->gen.cur_mux[0] = i;
5218 break;
5219 }
5220 }
Takashi Iwai3e1b0c42015-04-27 10:43:22 +02005221 break;
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02005222 }
5223}
5224
David Henningsson1f8b46c2015-05-12 14:38:15 +02005225static void alc_fixup_headset_mode_alc662(struct hda_codec *codec,
5226 const struct hda_fixup *fix, int action)
5227{
5228 struct alc_spec *spec = codec->spec;
5229
5230 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5231 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
5232 spec->gen.hp_mic = 1; /* Mic-in is same pin as headphone */
David Henningssonb40eda62015-05-28 09:40:23 +02005233
5234 /* Disable boost for mic-in permanently. (This code is only called
5235 from quirks that guarantee that the headphone is at NID 0x1b.) */
5236 snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000);
5237 snd_hda_override_wcaps(codec, 0x1b, get_wcaps(codec, 0x1b) & ~AC_WCAP_IN_AMP);
David Henningsson1f8b46c2015-05-12 14:38:15 +02005238 } else
5239 alc_fixup_headset_mode(codec, fix, action);
5240}
5241
David Henningsson73bdd592013-04-15 15:44:14 +02005242static void alc_fixup_headset_mode_alc668(struct hda_codec *codec,
5243 const struct hda_fixup *fix, int action)
5244{
5245 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
David Henningsson73bdd592013-04-15 15:44:14 +02005246 alc_write_coef_idx(codec, 0xc4, 0x8000);
Takashi Iwai98b24882014-08-18 13:47:50 +02005247 alc_update_coef_idx(codec, 0xc2, ~0xfe, 0);
David Henningsson73bdd592013-04-15 15:44:14 +02005248 snd_hda_set_pin_ctl_cache(codec, 0x18, 0);
5249 }
5250 alc_fixup_headset_mode(codec, fix, action);
5251}
5252
Chih-Chung Changbde7bc62013-08-05 16:38:42 +08005253/* Returns the nid of the external mic input pin, or 0 if it cannot be found. */
5254static int find_ext_mic_pin(struct hda_codec *codec)
5255{
5256 struct alc_spec *spec = codec->spec;
5257 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
5258 hda_nid_t nid;
5259 unsigned int defcfg;
5260 int i;
5261
5262 for (i = 0; i < cfg->num_inputs; i++) {
5263 if (cfg->inputs[i].type != AUTO_PIN_MIC)
5264 continue;
5265 nid = cfg->inputs[i].pin;
5266 defcfg = snd_hda_codec_get_pincfg(codec, nid);
5267 if (snd_hda_get_input_pin_attr(defcfg) == INPUT_PIN_ATTR_INT)
5268 continue;
5269 return nid;
5270 }
5271
5272 return 0;
5273}
5274
Dylan Reid08a978d2012-11-18 22:56:40 -08005275static void alc271_hp_gate_mic_jack(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01005276 const struct hda_fixup *fix,
Dylan Reid08a978d2012-11-18 22:56:40 -08005277 int action)
5278{
5279 struct alc_spec *spec = codec->spec;
5280
Takashi Iwai0db75792013-01-23 13:57:20 +01005281 if (action == HDA_FIXUP_ACT_PROBE) {
Chih-Chung Changbde7bc62013-08-05 16:38:42 +08005282 int mic_pin = find_ext_mic_pin(codec);
Takashi Iwai35a39f92019-02-01 11:19:50 +01005283 int hp_pin = alc_get_hp_pin(spec);
Chih-Chung Changbde7bc62013-08-05 16:38:42 +08005284
5285 if (snd_BUG_ON(!mic_pin || !hp_pin))
Takashi Iwai0db75792013-01-23 13:57:20 +01005286 return;
Chih-Chung Changbde7bc62013-08-05 16:38:42 +08005287 snd_hda_jack_set_gating_jack(codec, mic_pin, hp_pin);
Takashi Iwai0db75792013-01-23 13:57:20 +01005288 }
Dylan Reid08a978d2012-11-18 22:56:40 -08005289}
David Henningsson693b6132012-06-22 19:12:10 +02005290
David Henningsson3e0d6112013-04-22 14:30:14 +02005291static void alc269_fixup_limit_int_mic_boost(struct hda_codec *codec,
5292 const struct hda_fixup *fix,
5293 int action)
5294{
5295 struct alc_spec *spec = codec->spec;
5296 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
5297 int i;
5298
5299 /* The mic boosts on level 2 and 3 are too noisy
5300 on the internal mic input.
5301 Therefore limit the boost to 0 or 1. */
5302
5303 if (action != HDA_FIXUP_ACT_PROBE)
5304 return;
5305
5306 for (i = 0; i < cfg->num_inputs; i++) {
5307 hda_nid_t nid = cfg->inputs[i].pin;
5308 unsigned int defcfg;
5309 if (cfg->inputs[i].type != AUTO_PIN_MIC)
5310 continue;
5311 defcfg = snd_hda_codec_get_pincfg(codec, nid);
5312 if (snd_hda_get_input_pin_attr(defcfg) != INPUT_PIN_ATTR_INT)
5313 continue;
5314
5315 snd_hda_override_amp_caps(codec, nid, HDA_INPUT,
5316 (0x00 << AC_AMPCAP_OFFSET_SHIFT) |
5317 (0x01 << AC_AMPCAP_NUM_STEPS_SHIFT) |
5318 (0x2f << AC_AMPCAP_STEP_SIZE_SHIFT) |
5319 (0 << AC_AMPCAP_MUTE_SHIFT));
5320 }
5321}
5322
Kailang Yangcd217a62013-08-22 10:15:24 +02005323static void alc283_hp_automute_hook(struct hda_codec *codec,
Takashi Iwai1a4f69d2014-09-11 15:22:46 +02005324 struct hda_jack_callback *jack)
Kailang Yangcd217a62013-08-22 10:15:24 +02005325{
5326 struct alc_spec *spec = codec->spec;
5327 int vref;
5328
5329 msleep(200);
5330 snd_hda_gen_hp_automute(codec, jack);
5331
5332 vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0;
5333
5334 msleep(600);
5335 snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5336 vref);
5337}
5338
Kailang Yangcd217a62013-08-22 10:15:24 +02005339static void alc283_fixup_chromebook(struct hda_codec *codec,
5340 const struct hda_fixup *fix, int action)
5341{
5342 struct alc_spec *spec = codec->spec;
Kailang Yangcd217a62013-08-22 10:15:24 +02005343
5344 switch (action) {
5345 case HDA_FIXUP_ACT_PRE_PROBE:
Kailang Yang0202e992013-12-02 15:20:15 +08005346 snd_hda_override_wcaps(codec, 0x03, 0);
Takashi Iwaid2e92702013-10-30 07:50:53 +01005347 /* Disable AA-loopback as it causes white noise */
5348 spec->gen.mixer_nid = 0;
Kailang Yang38070212013-11-01 15:57:35 +08005349 break;
5350 case HDA_FIXUP_ACT_INIT:
Kailang Yangde9481c2014-04-07 16:41:52 +08005351 /* MIC2-VREF control */
5352 /* Set to manual mode */
Takashi Iwai98b24882014-08-18 13:47:50 +02005353 alc_update_coef_idx(codec, 0x06, 0x000c, 0);
Kailang Yang0202e992013-12-02 15:20:15 +08005354 /* Enable Line1 input control by verb */
Takashi Iwai98b24882014-08-18 13:47:50 +02005355 alc_update_coef_idx(codec, 0x1a, 0, 1 << 4);
Kailang Yang0202e992013-12-02 15:20:15 +08005356 break;
5357 }
5358}
5359
5360static void alc283_fixup_sense_combo_jack(struct hda_codec *codec,
5361 const struct hda_fixup *fix, int action)
5362{
5363 struct alc_spec *spec = codec->spec;
Kailang Yang0202e992013-12-02 15:20:15 +08005364
5365 switch (action) {
5366 case HDA_FIXUP_ACT_PRE_PROBE:
Kailang Yangcd217a62013-08-22 10:15:24 +02005367 spec->gen.hp_automute_hook = alc283_hp_automute_hook;
5368 break;
5369 case HDA_FIXUP_ACT_INIT:
5370 /* MIC2-VREF control */
5371 /* Set to manual mode */
Takashi Iwai98b24882014-08-18 13:47:50 +02005372 alc_update_coef_idx(codec, 0x06, 0x000c, 0);
Kailang Yangcd217a62013-08-22 10:15:24 +02005373 break;
5374 }
5375}
5376
Takashi Iwai7bba2152013-09-06 15:45:38 +02005377/* mute tablet speaker pin (0x14) via dock plugging in addition */
5378static void asus_tx300_automute(struct hda_codec *codec)
5379{
5380 struct alc_spec *spec = codec->spec;
5381 snd_hda_gen_update_outputs(codec);
5382 if (snd_hda_jack_detect(codec, 0x1b))
5383 spec->gen.mute_bits |= (1ULL << 0x14);
5384}
5385
5386static void alc282_fixup_asus_tx300(struct hda_codec *codec,
5387 const struct hda_fixup *fix, int action)
5388{
5389 struct alc_spec *spec = codec->spec;
Takashi Iwai7bba2152013-09-06 15:45:38 +02005390 static const struct hda_pintbl dock_pins[] = {
5391 { 0x1b, 0x21114000 }, /* dock speaker pin */
5392 {}
5393 };
Takashi Iwai7bba2152013-09-06 15:45:38 +02005394
5395 switch (action) {
5396 case HDA_FIXUP_ACT_PRE_PROBE:
Takashi Iwai1c76aa52018-06-21 16:37:54 +02005397 spec->init_amp = ALC_INIT_DEFAULT;
Takashi Iwaiae065f12018-06-19 23:00:03 +02005398 /* TX300 needs to set up GPIO2 for the speaker amp */
5399 alc_setup_gpio(codec, 0x04);
Takashi Iwai7bba2152013-09-06 15:45:38 +02005400 snd_hda_apply_pincfgs(codec, dock_pins);
5401 spec->gen.auto_mute_via_amp = 1;
5402 spec->gen.automute_hook = asus_tx300_automute;
5403 snd_hda_jack_detect_enable_callback(codec, 0x1b,
Takashi Iwai7bba2152013-09-06 15:45:38 +02005404 snd_hda_gen_hp_automute);
5405 break;
Takashi Iwai5579cd62018-06-19 22:22:41 +02005406 case HDA_FIXUP_ACT_PROBE:
5407 spec->init_amp = ALC_INIT_DEFAULT;
5408 break;
Takashi Iwai7bba2152013-09-06 15:45:38 +02005409 case HDA_FIXUP_ACT_BUILD:
5410 /* this is a bit tricky; give more sane names for the main
5411 * (tablet) speaker and the dock speaker, respectively
5412 */
Takashi Iwai56798e62017-04-11 08:10:52 +02005413 rename_ctl(codec, "Speaker Playback Switch",
5414 "Dock Speaker Playback Switch");
5415 rename_ctl(codec, "Bass Speaker Playback Switch",
5416 "Speaker Playback Switch");
Takashi Iwai7bba2152013-09-06 15:45:38 +02005417 break;
5418 }
5419}
5420
David Henningsson338cae52013-10-07 10:39:59 +02005421static void alc290_fixup_mono_speakers(struct hda_codec *codec,
5422 const struct hda_fixup *fix, int action)
5423{
David Henningsson0f4881d2013-12-20 16:08:13 +01005424 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5425 /* DAC node 0x03 is giving mono output. We therefore want to
5426 make sure 0x14 (front speaker) and 0x15 (headphones) use the
5427 stereo DAC, while leaving 0x17 (bass speaker) for node 0x03. */
5428 hda_nid_t conn1[2] = { 0x0c };
5429 snd_hda_override_conn_list(codec, 0x14, 1, conn1);
5430 snd_hda_override_conn_list(codec, 0x15, 1, conn1);
5431 }
David Henningsson338cae52013-10-07 10:39:59 +02005432}
5433
Hui Wangdd9aa332016-08-01 10:20:32 +08005434static void alc298_fixup_speaker_volume(struct hda_codec *codec,
5435 const struct hda_fixup *fix, int action)
5436{
5437 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5438 /* The speaker is routed to the Node 0x06 by a mistake, as a result
5439 we can't adjust the speaker's volume since this node does not has
5440 Amp-out capability. we change the speaker's route to:
5441 Node 0x02 (Audio Output) -> Node 0x0c (Audio Mixer) -> Node 0x17 (
5442 Pin Complex), since Node 0x02 has Amp-out caps, we can adjust
5443 speaker's volume now. */
5444
5445 hda_nid_t conn1[1] = { 0x0c };
5446 snd_hda_override_conn_list(codec, 0x17, 1, conn1);
5447 }
5448}
5449
Takashi Iwaie312a862018-03-06 12:14:17 +01005450/* disable DAC3 (0x06) selection on NID 0x17 as it has no volume amp control */
5451static void alc295_fixup_disable_dac3(struct hda_codec *codec,
5452 const struct hda_fixup *fix, int action)
5453{
5454 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5455 hda_nid_t conn[2] = { 0x02, 0x03 };
5456 snd_hda_override_conn_list(codec, 0x17, 2, conn);
5457 }
5458}
5459
Keith Packard98973f22015-07-15 12:14:39 -07005460/* Hook to update amp GPIO4 for automute */
5461static void alc280_hp_gpio4_automute_hook(struct hda_codec *codec,
5462 struct hda_jack_callback *jack)
5463{
5464 struct alc_spec *spec = codec->spec;
5465
5466 snd_hda_gen_hp_automute(codec, jack);
5467 /* mute_led_polarity is set to 0, so we pass inverted value here */
5468 alc_update_gpio_led(codec, 0x10, !spec->gen.hp_jack_present);
5469}
5470
5471/* Manage GPIOs for HP EliteBook Folio 9480m.
5472 *
5473 * GPIO4 is the headphone amplifier power control
5474 * GPIO3 is the audio output mute indicator LED
5475 */
5476
5477static void alc280_fixup_hp_9480m(struct hda_codec *codec,
5478 const struct hda_fixup *fix,
5479 int action)
5480{
5481 struct alc_spec *spec = codec->spec;
Keith Packard98973f22015-07-15 12:14:39 -07005482
Takashi Iwai01e4a272018-06-19 22:47:30 +02005483 alc_fixup_hp_gpio_led(codec, action, 0x08, 0);
Keith Packard98973f22015-07-15 12:14:39 -07005484 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai01e4a272018-06-19 22:47:30 +02005485 /* amp at GPIO4; toggled via alc280_hp_gpio4_automute_hook() */
5486 spec->gpio_mask |= 0x10;
5487 spec->gpio_dir |= 0x10;
Keith Packard98973f22015-07-15 12:14:39 -07005488 spec->gen.hp_automute_hook = alc280_hp_gpio4_automute_hook;
Keith Packard98973f22015-07-15 12:14:39 -07005489 }
5490}
5491
Takashi Iwaiae065f12018-06-19 23:00:03 +02005492static void alc275_fixup_gpio4_off(struct hda_codec *codec,
5493 const struct hda_fixup *fix,
5494 int action)
5495{
5496 struct alc_spec *spec = codec->spec;
5497
5498 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5499 spec->gpio_mask |= 0x04;
5500 spec->gpio_dir |= 0x04;
5501 /* set data bit low */
5502 }
5503}
5504
Kailang Yangca169cc2017-04-25 16:17:40 +08005505static void alc233_alc662_fixup_lenovo_dual_codecs(struct hda_codec *codec,
5506 const struct hda_fixup *fix,
5507 int action)
5508{
5509 alc_fixup_dual_codecs(codec, fix, action);
5510 switch (action) {
5511 case HDA_FIXUP_ACT_PRE_PROBE:
5512 /* override card longname to provide a unique UCM profile */
5513 strcpy(codec->card->longname, "HDAudio-Lenovo-DualCodecs");
5514 break;
5515 case HDA_FIXUP_ACT_BUILD:
5516 /* rename Capture controls depending on the codec */
5517 rename_ctl(codec, "Capture Volume",
5518 codec->addr == 0 ?
5519 "Rear-Panel Capture Volume" :
5520 "Front-Panel Capture Volume");
5521 rename_ctl(codec, "Capture Switch",
5522 codec->addr == 0 ?
5523 "Rear-Panel Capture Switch" :
5524 "Front-Panel Capture Switch");
5525 break;
5526 }
5527}
5528
Kailang Yang92266652017-12-14 15:28:58 +08005529/* Forcibly assign NID 0x03 to HP/LO while NID 0x02 to SPK for EQ */
5530static void alc274_fixup_bind_dacs(struct hda_codec *codec,
5531 const struct hda_fixup *fix, int action)
5532{
5533 struct alc_spec *spec = codec->spec;
5534 static hda_nid_t preferred_pairs[] = {
5535 0x21, 0x03, 0x1b, 0x03, 0x16, 0x02,
5536 0
5537 };
5538
5539 if (action != HDA_FIXUP_ACT_PRE_PROBE)
5540 return;
5541
5542 spec->gen.preferred_dacs = preferred_pairs;
Kailang Yang0700d3d2019-04-26 16:13:54 +08005543 spec->gen.auto_mute_via_amp = 1;
5544 codec->power_save_node = 0;
Kailang Yang92266652017-12-14 15:28:58 +08005545}
5546
Hui Wangc4cfcf62018-11-26 14:17:16 +08005547/* The DAC of NID 0x3 will introduce click/pop noise on headphones, so invalidate it */
5548static void alc285_fixup_invalidate_dacs(struct hda_codec *codec,
5549 const struct hda_fixup *fix, int action)
5550{
5551 if (action != HDA_FIXUP_ACT_PRE_PROBE)
5552 return;
5553
5554 snd_hda_override_wcaps(codec, 0x03, 0);
5555}
5556
Kailang Yange8547472018-11-28 15:32:45 +08005557static const struct hda_jack_keymap alc_headset_btn_keymap[] = {
5558 { SND_JACK_BTN_0, KEY_PLAYPAUSE },
5559 { SND_JACK_BTN_1, KEY_VOICECOMMAND },
5560 { SND_JACK_BTN_2, KEY_VOLUMEUP },
5561 { SND_JACK_BTN_3, KEY_VOLUMEDOWN },
5562 {}
5563};
5564
5565static void alc_headset_btn_callback(struct hda_codec *codec,
5566 struct hda_jack_callback *jack)
5567{
5568 int report = 0;
5569
5570 if (jack->unsol_res & (7 << 13))
5571 report |= SND_JACK_BTN_0;
5572
5573 if (jack->unsol_res & (1 << 16 | 3 << 8))
5574 report |= SND_JACK_BTN_1;
5575
5576 /* Volume up key */
5577 if (jack->unsol_res & (7 << 23))
5578 report |= SND_JACK_BTN_2;
5579
5580 /* Volume down key */
5581 if (jack->unsol_res & (7 << 10))
5582 report |= SND_JACK_BTN_3;
5583
5584 jack->jack->button_state = report;
5585}
5586
Kailang Yang8983eb62019-04-03 15:31:49 +08005587static void alc_fixup_headset_jack(struct hda_codec *codec,
Kailang Yange8547472018-11-28 15:32:45 +08005588 const struct hda_fixup *fix, int action)
5589{
5590
5591 switch (action) {
5592 case HDA_FIXUP_ACT_PRE_PROBE:
5593 snd_hda_jack_detect_enable_callback(codec, 0x55,
5594 alc_headset_btn_callback);
5595 snd_hda_jack_add_kctl(codec, 0x55, "Headset Jack", false,
5596 SND_JACK_HEADSET, alc_headset_btn_keymap);
5597 break;
5598 case HDA_FIXUP_ACT_INIT:
5599 switch (codec->core.vendor_id) {
5600 case 0x10ec0225:
5601 case 0x10ec0295:
5602 case 0x10ec0299:
5603 alc_write_coef_idx(codec, 0x48, 0xd011);
5604 alc_update_coef_idx(codec, 0x49, 0x007f, 0x0045);
5605 alc_update_coef_idx(codec, 0x44, 0x007f << 8, 0x0045 << 8);
5606 break;
5607 case 0x10ec0236:
5608 case 0x10ec0256:
5609 alc_write_coef_idx(codec, 0x48, 0xd011);
5610 alc_update_coef_idx(codec, 0x49, 0x007f, 0x0045);
5611 break;
5612 }
5613 break;
5614 }
5615}
5616
Kailang Yang8983eb62019-04-03 15:31:49 +08005617static void alc295_fixup_chromebook(struct hda_codec *codec,
5618 const struct hda_fixup *fix, int action)
5619{
Kailang Yangd3ba58b2019-05-06 15:09:42 +08005620 struct alc_spec *spec = codec->spec;
5621
Kailang Yang8983eb62019-04-03 15:31:49 +08005622 switch (action) {
Kailang Yangd3ba58b2019-05-06 15:09:42 +08005623 case HDA_FIXUP_ACT_PRE_PROBE:
5624 spec->ultra_low_power = true;
5625 break;
Kailang Yang8983eb62019-04-03 15:31:49 +08005626 case HDA_FIXUP_ACT_INIT:
5627 switch (codec->core.vendor_id) {
5628 case 0x10ec0295:
5629 alc_update_coef_idx(codec, 0x4a, 0x8000, 1 << 15); /* Reset HP JD */
5630 alc_update_coef_idx(codec, 0x4a, 0x8000, 0 << 15);
5631 break;
5632 case 0x10ec0236:
5633 alc_update_coef_idx(codec, 0x1b, 0x8000, 1 << 15); /* Reset HP JD */
5634 alc_update_coef_idx(codec, 0x1b, 0x8000, 0 << 15);
5635 break;
5636 }
5637 break;
5638 }
5639}
5640
Kailang Yangd1dd4212019-01-09 17:05:24 +08005641static void alc_fixup_disable_mic_vref(struct hda_codec *codec,
5642 const struct hda_fixup *fix, int action)
5643{
5644 if (action == HDA_FIXUP_ACT_PRE_PROBE)
5645 snd_hda_codec_set_pin_target(codec, 0x19, PIN_VREFHIZ);
5646}
5647
Takashi Iwaib317b032014-01-08 11:44:21 +01005648/* for hda_fixup_thinkpad_acpi() */
5649#include "thinkpad_helper.c"
David Henningssonb67ae3f2013-11-05 13:11:37 +01005650
Takashi Iwaid5a6cab2018-06-13 12:43:10 +02005651static void alc_fixup_thinkpad_acpi(struct hda_codec *codec,
5652 const struct hda_fixup *fix, int action)
5653{
5654 alc_fixup_no_shutup(codec, fix, action); /* reduce click noise */
5655 hda_fixup_thinkpad_acpi(codec, fix, action);
5656}
5657
Tom Bridenbbf8ff62018-05-29 17:34:20 +01005658/* for alc295_fixup_hp_top_speakers */
5659#include "hp_x360_helper.c"
5660
Takashi Iwai1d045db2011-07-07 18:23:21 +02005661enum {
5662 ALC269_FIXUP_SONY_VAIO,
5663 ALC275_FIXUP_SONY_VAIO_GPIO2,
5664 ALC269_FIXUP_DELL_M101Z,
5665 ALC269_FIXUP_SKU_IGNORE,
5666 ALC269_FIXUP_ASUS_G73JW,
5667 ALC269_FIXUP_LENOVO_EAPD,
5668 ALC275_FIXUP_SONY_HWEQ,
Takashi Iwaie9bd7d52014-05-21 11:06:49 +02005669 ALC275_FIXUP_SONY_DISABLE_AAMIX,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005670 ALC271_FIXUP_DMIC,
Takashi Iwai017f2a12011-07-09 14:42:25 +02005671 ALC269_FIXUP_PCM_44K,
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02005672 ALC269_FIXUP_STEREO_DMIC,
David Henningsson7c478f02013-10-11 10:18:46 +02005673 ALC269_FIXUP_HEADSET_MIC,
Takashi Iwai24519912011-08-16 15:08:49 +02005674 ALC269_FIXUP_QUANTA_MUTE,
5675 ALC269_FIXUP_LIFEBOOK,
David Henningsson2041d562014-06-13 11:15:44 +02005676 ALC269_FIXUP_LIFEBOOK_EXTMIC,
Takashi Iwaicc7016a2015-04-08 20:47:55 +02005677 ALC269_FIXUP_LIFEBOOK_HP_PIN,
Takashi Iwai4df3fd12015-06-29 08:38:02 +02005678 ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT,
Jan-Marek Glogowskifdcc9682018-02-14 11:29:15 +01005679 ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC,
Takashi Iwaia4297b52011-08-23 18:40:12 +02005680 ALC269_FIXUP_AMIC,
5681 ALC269_FIXUP_DMIC,
5682 ALC269VB_FIXUP_AMIC,
5683 ALC269VB_FIXUP_DMIC,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01005684 ALC269_FIXUP_HP_MUTE_LED,
David Henningssond06ac142013-02-18 11:41:55 +01005685 ALC269_FIXUP_HP_MUTE_LED_MIC1,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01005686 ALC269_FIXUP_HP_MUTE_LED_MIC2,
Tom Briden7f783bd2017-03-25 10:12:01 +00005687 ALC269_FIXUP_HP_MUTE_LED_MIC3,
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01005688 ALC269_FIXUP_HP_GPIO_LED,
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08005689 ALC269_FIXUP_HP_GPIO_MIC1_LED,
5690 ALC269_FIXUP_HP_LINE1_MIC1_LED,
David Henningsson693b6132012-06-22 19:12:10 +02005691 ALC269_FIXUP_INV_DMIC,
David Henningsson108cc102012-07-20 10:37:25 +02005692 ALC269_FIXUP_LENOVO_DOCK,
Takashi Iwai9b745ab2014-03-07 08:37:19 +01005693 ALC269_FIXUP_NO_SHUTUP,
David Henningsson88cfcf82013-10-11 10:18:45 +02005694 ALC286_FIXUP_SONY_MIC_NO_PRESENCE,
David Henningsson108cc102012-07-20 10:37:25 +02005695 ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT,
David Henningsson73bdd592013-04-15 15:44:14 +02005696 ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
5697 ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
David Henningsson338cae52013-10-07 10:39:59 +02005698 ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
Kailang Yangfcc6c872017-06-29 15:21:27 +08005699 ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
David Henningsson73bdd592013-04-15 15:44:14 +02005700 ALC269_FIXUP_HEADSET_MODE,
5701 ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC,
Takashi Iwai78197172015-06-27 10:21:13 +02005702 ALC269_FIXUP_ASPIRE_HEADSET_MIC,
David Henningssond240d1d2013-04-15 12:50:02 +02005703 ALC269_FIXUP_ASUS_X101_FUNC,
5704 ALC269_FIXUP_ASUS_X101_VERB,
5705 ALC269_FIXUP_ASUS_X101,
Dylan Reid08a978d2012-11-18 22:56:40 -08005706 ALC271_FIXUP_AMIC_MIC2,
5707 ALC271_FIXUP_HP_GATE_MIC_JACK,
Oleksij Rempelb1e89722013-12-04 20:50:53 +01005708 ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572,
Dylan Reid42397002013-04-05 14:58:22 -07005709 ALC269_FIXUP_ACER_AC700,
David Henningsson3e0d6112013-04-22 14:30:14 +02005710 ALC269_FIXUP_LIMIT_INT_MIC_BOOST,
Oleksij Rempel2cede302013-11-27 17:12:03 +01005711 ALC269VB_FIXUP_ASUS_ZENBOOK,
Takashi Iwai23870832013-11-29 14:13:12 +01005712 ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A,
David Henningsson8e35cd42013-11-06 11:20:01 +01005713 ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED,
Anisse Astier02b504d2013-06-03 11:53:10 +02005714 ALC269VB_FIXUP_ORDISSIMO_EVE2,
Kailang Yangcd217a62013-08-22 10:15:24 +02005715 ALC283_FIXUP_CHROME_BOOK,
Kailang Yang0202e992013-12-02 15:20:15 +08005716 ALC283_FIXUP_SENSE_COMBO_JACK,
Takashi Iwai7bba2152013-09-06 15:45:38 +02005717 ALC282_FIXUP_ASUS_TX300,
Kailang Yang1bb3e062013-09-27 13:10:25 +02005718 ALC283_FIXUP_INT_MIC,
David Henningsson338cae52013-10-07 10:39:59 +02005719 ALC290_FIXUP_MONO_SPEAKERS,
David Henningsson0f4881d2013-12-20 16:08:13 +01005720 ALC290_FIXUP_MONO_SPEAKERS_HSJACK,
5721 ALC290_FIXUP_SUBWOOFER,
5722 ALC290_FIXUP_SUBWOOFER_HSJACK,
David Henningssonb67ae3f2013-11-05 13:11:37 +01005723 ALC269_FIXUP_THINKPAD_ACPI,
David Henningsson56f27012016-01-11 09:33:14 +01005724 ALC269_FIXUP_DMIC_THINKPAD_ACPI,
Chris Chiu5824ce82017-02-28 14:17:11 -06005725 ALC255_FIXUP_ACER_MIC_NO_PRESENCE,
Chris Chiu615966a2017-02-28 14:17:12 -06005726 ALC255_FIXUP_ASUS_MIC_NO_PRESENCE,
Kailang Yang9a22a8f52013-11-08 15:54:49 +08005727 ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Kailang Yang31278992014-03-03 15:27:22 +08005728 ALC255_FIXUP_DELL2_MIC_NO_PRESENCE,
Kailang Yang9a22a8f52013-11-08 15:54:49 +08005729 ALC255_FIXUP_HEADSET_MODE,
Kailang Yang31278992014-03-03 15:27:22 +08005730 ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC,
Kailang Yanga22aa262014-04-23 17:34:28 +08005731 ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
Takashi Iwai1c37c222014-05-06 17:34:42 +02005732 ALC292_FIXUP_TPT440_DOCK,
Takashi Iwai9a811232015-12-09 15:17:43 +01005733 ALC292_FIXUP_TPT440,
Anisse Astierabaa22742016-08-24 09:14:13 +02005734 ALC283_FIXUP_HEADSET_MIC,
Takashi Iwaib3802782018-11-26 17:47:46 +01005735 ALC255_FIXUP_MIC_MUTE_LED,
Takashi Iwai1a22e772014-08-27 08:19:05 +02005736 ALC282_FIXUP_ASPIRE_V5_PINS,
David Henningsson7a5255f2014-10-30 08:26:01 +01005737 ALC280_FIXUP_HP_GPIO4,
Kailang Yangeaa8e5e2014-11-21 15:49:11 +08005738 ALC286_FIXUP_HP_GPIO_LED,
David Henningsson33f4acd2015-01-07 15:50:13 +01005739 ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY,
TienFu Chenb4b33f92015-01-20 15:06:21 +01005740 ALC280_FIXUP_HP_DOCK_PINS,
Jaroslav Kysela04d54662017-03-09 13:29:13 +01005741 ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED,
Keith Packard98973f22015-07-15 12:14:39 -07005742 ALC280_FIXUP_HP_9480M,
Kailang Yange1e62b92015-04-08 16:01:22 +08005743 ALC288_FIXUP_DELL_HEADSET_MODE,
5744 ALC288_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang831bfdf92015-06-26 12:35:17 +08005745 ALC288_FIXUP_DELL_XPS_13,
5746 ALC288_FIXUP_DISABLE_AAMIX,
Takashi Iwai8b99aba2015-06-15 11:59:32 +02005747 ALC292_FIXUP_DELL_E7X,
5748 ALC292_FIXUP_DISABLE_AAMIX,
David Henningssonc04017e2015-12-15 14:44:03 +01005749 ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK,
Kailang Yang977e6272015-05-18 15:31:20 +08005750 ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang2f726ae2017-03-31 10:31:40 +08005751 ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE,
Kailang Yang6ed11312015-10-26 15:37:39 +08005752 ALC275_FIXUP_DELL_XPS,
Hui Wang8c697292015-11-24 11:08:18 +08005753 ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE,
Hui Wang23adc192015-12-08 12:27:18 +08005754 ALC293_FIXUP_LENOVO_SPK_NOISE,
Kailang3694cb22015-12-28 11:35:24 +08005755 ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY,
Kai-Heng Feng3b43b712016-02-25 15:19:38 +08005756 ALC255_FIXUP_DELL_SPK_NOISE,
Kailang Yangd1dd4212019-01-09 17:05:24 +08005757 ALC225_FIXUP_DISABLE_MIC_VREF,
David Henningsson2ae95572016-02-25 09:37:05 +01005758 ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
Takashi Iwaie312a862018-03-06 12:14:17 +01005759 ALC295_FIXUP_DISABLE_DAC3,
Takashi Iwaif8839822016-02-25 14:31:59 +01005760 ALC280_FIXUP_HP_HEADSET_MIC,
Hui Wange549d192016-04-01 11:00:15 +08005761 ALC221_FIXUP_HP_FRONT_MIC,
Sven Eckelmannc636b952016-04-11 16:55:26 +02005762 ALC292_FIXUP_TPT460,
Hui Wangdd9aa332016-08-01 10:20:32 +08005763 ALC298_FIXUP_SPK_VOLUME,
Kai-Heng Fengfd06c772016-08-30 15:36:34 +08005764 ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER,
Gabriele Mazzotta823ff162016-12-24 19:50:01 +01005765 ALC269_FIXUP_ATIV_BOOK_8,
Kailang Yang9eb5d0e2017-01-17 15:40:25 +08005766 ALC221_FIXUP_HP_MIC_NO_PRESENCE,
Chris Chiuc1732ed2017-02-28 14:17:13 -06005767 ALC256_FIXUP_ASUS_HEADSET_MODE,
5768 ALC256_FIXUP_ASUS_MIC,
Chris Chiueeed4cd2017-02-28 14:17:15 -06005769 ALC256_FIXUP_ASUS_AIO_GPIO2,
Chris Chiu216d7ae2017-02-28 14:17:14 -06005770 ALC233_FIXUP_ASUS_MIC_NO_PRESENCE,
5771 ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE,
Kailang Yangca169cc2017-04-25 16:17:40 +08005772 ALC233_FIXUP_LENOVO_MULTI_CODECS,
Jian-Hong Panea5c7eb2019-04-01 11:25:05 +08005773 ALC233_FIXUP_ACER_HEADSET_MIC,
Hui Wangf33f79f2017-07-07 12:08:29 +08005774 ALC294_FIXUP_LENOVO_MIC_LOCATION,
Kailang Yang5f364132017-07-25 16:28:16 +08005775 ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE,
PeiSen Houb84e8432017-09-01 15:11:56 +08005776 ALC700_FIXUP_INTEL_REFERENCE,
Kailang Yang92266652017-12-14 15:28:58 +08005777 ALC274_FIXUP_DELL_BIND_DACS,
5778 ALC274_FIXUP_DELL_AIO_LINEOUT_VERB,
Kailang Yang61fcf8e2018-02-02 15:26:46 +08005779 ALC298_FIXUP_TPT470_DOCK,
Kailang Yangae104a22018-02-05 16:07:20 +08005780 ALC255_FIXUP_DUMMY_LINEOUT_VERB,
Kailang Yangf0ba9d62018-03-16 11:46:08 +08005781 ALC255_FIXUP_DELL_HEADSET_MIC,
Ayman Bagabas0fbf21c2019-05-23 05:30:11 -04005782 ALC256_FIXUP_HUAWEI_MACH_WX9_PINS,
Tom Bridenbbf8ff62018-05-29 17:34:20 +01005783 ALC295_FIXUP_HP_X360,
Kailang Yang8a328ac2018-08-21 16:54:41 +08005784 ALC221_FIXUP_HP_HEADSET_MIC,
Hui Wangc4cfcf62018-11-26 14:17:16 +08005785 ALC285_FIXUP_LENOVO_HEADPHONE_NOISE,
Girija Kumar Kasinadhunie8ed64b2018-11-26 13:40:46 -05005786 ALC295_FIXUP_HP_AUTO_MUTE,
Chris Chiu33aaebd2018-12-05 14:48:53 +08005787 ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE,
Chris Chiud8ae4582018-12-07 17:17:11 +08005788 ALC294_FIXUP_ASUS_MIC,
Jian-Hong Pan4e051102018-12-07 17:17:12 +08005789 ALC294_FIXUP_ASUS_HEADSET_MIC,
5790 ALC294_FIXUP_ASUS_SPK,
Jeremy Soller89e3a562019-01-30 16:12:31 -07005791 ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE,
Hui Wangc8c6ee62019-02-14 11:41:33 +08005792 ALC285_FIXUP_LENOVO_PC_BEEP_IN_NOISE,
Jian-Hong Pancbc05fd2019-03-13 17:33:24 +08005793 ALC255_FIXUP_ACER_HEADSET_MIC,
Kailang Yang10f5b1b2019-02-21 16:10:22 +08005794 ALC295_FIXUP_CHROME_BOOK,
Kailang Yang8983eb62019-04-03 15:31:49 +08005795 ALC225_FIXUP_HEADSET_JACK,
Kailang Yang136824e2019-03-14 16:22:45 +08005796 ALC225_FIXUP_DELL_WYSE_AIO_MIC_NO_PRESENCE,
5797 ALC225_FIXUP_WYSE_AUTO_MUTE,
5798 ALC225_FIXUP_WYSE_DISABLE_MIC_VREF,
Jian-Hong Pan667a8f72019-03-15 17:51:09 +08005799 ALC286_FIXUP_ACER_AIO_HEADSET_MIC,
Jian-Hong Pane1037352019-03-22 11:37:18 +08005800 ALC256_FIXUP_ASUS_MIC_NO_PRESENCE,
Bernhard Rosenkraenzere2a829b2019-03-05 00:38:19 +01005801 ALC299_FIXUP_PREDATOR_SPK,
Jian-Hong Pan60083f92019-09-02 18:00:56 +08005802 ALC294_FIXUP_ASUS_INTSPK_HEADSET_MIC,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005803};
5804
Takashi Iwai1727a772013-01-10 09:52:52 +01005805static const struct hda_fixup alc269_fixups[] = {
Takashi Iwai1d045db2011-07-07 18:23:21 +02005806 [ALC269_FIXUP_SONY_VAIO] = {
Takashi Iwaifd108212013-01-10 10:18:14 +01005807 .type = HDA_FIXUP_PINCTLS,
5808 .v.pins = (const struct hda_pintbl[]) {
5809 {0x19, PIN_VREFGRD},
Takashi Iwai1d045db2011-07-07 18:23:21 +02005810 {}
5811 }
5812 },
5813 [ALC275_FIXUP_SONY_VAIO_GPIO2] = {
Takashi Iwaiae065f12018-06-19 23:00:03 +02005814 .type = HDA_FIXUP_FUNC,
5815 .v.func = alc275_fixup_gpio4_off,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005816 .chained = true,
5817 .chain_id = ALC269_FIXUP_SONY_VAIO
5818 },
5819 [ALC269_FIXUP_DELL_M101Z] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005820 .type = HDA_FIXUP_VERBS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005821 .v.verbs = (const struct hda_verb[]) {
5822 /* Enables internal speaker */
5823 {0x20, AC_VERB_SET_COEF_INDEX, 13},
5824 {0x20, AC_VERB_SET_PROC_COEF, 0x4040},
5825 {}
5826 }
5827 },
5828 [ALC269_FIXUP_SKU_IGNORE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005829 .type = HDA_FIXUP_FUNC,
Takashi Iwai23d30f22012-05-07 17:17:32 +02005830 .v.func = alc_fixup_sku_ignore,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005831 },
5832 [ALC269_FIXUP_ASUS_G73JW] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005833 .type = HDA_FIXUP_PINS,
5834 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02005835 { 0x17, 0x99130111 }, /* subwoofer */
5836 { }
5837 }
5838 },
5839 [ALC269_FIXUP_LENOVO_EAPD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005840 .type = HDA_FIXUP_VERBS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005841 .v.verbs = (const struct hda_verb[]) {
5842 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
5843 {}
5844 }
5845 },
5846 [ALC275_FIXUP_SONY_HWEQ] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005847 .type = HDA_FIXUP_FUNC,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005848 .v.func = alc269_fixup_hweq,
5849 .chained = true,
5850 .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2
5851 },
Takashi Iwaie9bd7d52014-05-21 11:06:49 +02005852 [ALC275_FIXUP_SONY_DISABLE_AAMIX] = {
5853 .type = HDA_FIXUP_FUNC,
5854 .v.func = alc_fixup_disable_aamix,
5855 .chained = true,
5856 .chain_id = ALC269_FIXUP_SONY_VAIO
5857 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02005858 [ALC271_FIXUP_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005859 .type = HDA_FIXUP_FUNC,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005860 .v.func = alc271_fixup_dmic,
5861 },
Takashi Iwai017f2a12011-07-09 14:42:25 +02005862 [ALC269_FIXUP_PCM_44K] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005863 .type = HDA_FIXUP_FUNC,
Takashi Iwai017f2a12011-07-09 14:42:25 +02005864 .v.func = alc269_fixup_pcm_44k,
David Henningsson012e7eb2012-08-08 08:43:37 +02005865 .chained = true,
5866 .chain_id = ALC269_FIXUP_QUANTA_MUTE
Takashi Iwai017f2a12011-07-09 14:42:25 +02005867 },
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02005868 [ALC269_FIXUP_STEREO_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005869 .type = HDA_FIXUP_FUNC,
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02005870 .v.func = alc269_fixup_stereo_dmic,
5871 },
David Henningsson7c478f02013-10-11 10:18:46 +02005872 [ALC269_FIXUP_HEADSET_MIC] = {
5873 .type = HDA_FIXUP_FUNC,
5874 .v.func = alc269_fixup_headset_mic,
5875 },
Takashi Iwai24519912011-08-16 15:08:49 +02005876 [ALC269_FIXUP_QUANTA_MUTE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005877 .type = HDA_FIXUP_FUNC,
Takashi Iwai24519912011-08-16 15:08:49 +02005878 .v.func = alc269_fixup_quanta_mute,
5879 },
5880 [ALC269_FIXUP_LIFEBOOK] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005881 .type = HDA_FIXUP_PINS,
5882 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai24519912011-08-16 15:08:49 +02005883 { 0x1a, 0x2101103f }, /* dock line-out */
5884 { 0x1b, 0x23a11040 }, /* dock mic-in */
5885 { }
5886 },
5887 .chained = true,
5888 .chain_id = ALC269_FIXUP_QUANTA_MUTE
5889 },
David Henningsson2041d562014-06-13 11:15:44 +02005890 [ALC269_FIXUP_LIFEBOOK_EXTMIC] = {
5891 .type = HDA_FIXUP_PINS,
5892 .v.pins = (const struct hda_pintbl[]) {
5893 { 0x19, 0x01a1903c }, /* headset mic, with jack detect */
5894 { }
5895 },
5896 },
Takashi Iwaicc7016a2015-04-08 20:47:55 +02005897 [ALC269_FIXUP_LIFEBOOK_HP_PIN] = {
5898 .type = HDA_FIXUP_PINS,
5899 .v.pins = (const struct hda_pintbl[]) {
5900 { 0x21, 0x0221102f }, /* HP out */
5901 { }
5902 },
5903 },
Takashi Iwai4df3fd12015-06-29 08:38:02 +02005904 [ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT] = {
5905 .type = HDA_FIXUP_FUNC,
5906 .v.func = alc269_fixup_pincfg_no_hp_to_lineout,
5907 },
Jan-Marek Glogowskifdcc9682018-02-14 11:29:15 +01005908 [ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC] = {
5909 .type = HDA_FIXUP_FUNC,
5910 .v.func = alc269_fixup_pincfg_U7x7_headset_mic,
5911 },
Takashi Iwaia4297b52011-08-23 18:40:12 +02005912 [ALC269_FIXUP_AMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005913 .type = HDA_FIXUP_PINS,
5914 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaia4297b52011-08-23 18:40:12 +02005915 { 0x14, 0x99130110 }, /* speaker */
5916 { 0x15, 0x0121401f }, /* HP out */
5917 { 0x18, 0x01a19c20 }, /* mic */
5918 { 0x19, 0x99a3092f }, /* int-mic */
5919 { }
5920 },
5921 },
5922 [ALC269_FIXUP_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005923 .type = HDA_FIXUP_PINS,
5924 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaia4297b52011-08-23 18:40:12 +02005925 { 0x12, 0x99a3092f }, /* int-mic */
5926 { 0x14, 0x99130110 }, /* speaker */
5927 { 0x15, 0x0121401f }, /* HP out */
5928 { 0x18, 0x01a19c20 }, /* mic */
5929 { }
5930 },
5931 },
5932 [ALC269VB_FIXUP_AMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005933 .type = HDA_FIXUP_PINS,
5934 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaia4297b52011-08-23 18:40:12 +02005935 { 0x14, 0x99130110 }, /* speaker */
5936 { 0x18, 0x01a19c20 }, /* mic */
5937 { 0x19, 0x99a3092f }, /* int-mic */
5938 { 0x21, 0x0121401f }, /* HP out */
5939 { }
5940 },
5941 },
David Henningsson2267ea92012-01-03 08:45:56 +01005942 [ALC269VB_FIXUP_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005943 .type = HDA_FIXUP_PINS,
5944 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaia4297b52011-08-23 18:40:12 +02005945 { 0x12, 0x99a3092f }, /* int-mic */
5946 { 0x14, 0x99130110 }, /* speaker */
5947 { 0x18, 0x01a19c20 }, /* mic */
5948 { 0x21, 0x0121401f }, /* HP out */
5949 { }
5950 },
5951 },
Takashi Iwai08fb0d02013-01-10 17:33:58 +01005952 [ALC269_FIXUP_HP_MUTE_LED] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005953 .type = HDA_FIXUP_FUNC,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01005954 .v.func = alc269_fixup_hp_mute_led,
David Henningsson6d3cd5d2013-01-07 12:03:47 +01005955 },
David Henningssond06ac142013-02-18 11:41:55 +01005956 [ALC269_FIXUP_HP_MUTE_LED_MIC1] = {
5957 .type = HDA_FIXUP_FUNC,
5958 .v.func = alc269_fixup_hp_mute_led_mic1,
5959 },
Takashi Iwai08fb0d02013-01-10 17:33:58 +01005960 [ALC269_FIXUP_HP_MUTE_LED_MIC2] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005961 .type = HDA_FIXUP_FUNC,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01005962 .v.func = alc269_fixup_hp_mute_led_mic2,
Takashi Iwai420b0fe2012-03-12 12:35:27 +01005963 },
Tom Briden7f783bd2017-03-25 10:12:01 +00005964 [ALC269_FIXUP_HP_MUTE_LED_MIC3] = {
5965 .type = HDA_FIXUP_FUNC,
5966 .v.func = alc269_fixup_hp_mute_led_mic3,
Girija Kumar Kasinadhunie8ed64b2018-11-26 13:40:46 -05005967 .chained = true,
5968 .chain_id = ALC295_FIXUP_HP_AUTO_MUTE
Tom Briden7f783bd2017-03-25 10:12:01 +00005969 },
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01005970 [ALC269_FIXUP_HP_GPIO_LED] = {
5971 .type = HDA_FIXUP_FUNC,
5972 .v.func = alc269_fixup_hp_gpio_led,
5973 },
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08005974 [ALC269_FIXUP_HP_GPIO_MIC1_LED] = {
5975 .type = HDA_FIXUP_FUNC,
5976 .v.func = alc269_fixup_hp_gpio_mic1_led,
5977 },
5978 [ALC269_FIXUP_HP_LINE1_MIC1_LED] = {
5979 .type = HDA_FIXUP_FUNC,
5980 .v.func = alc269_fixup_hp_line1_mic1_led,
5981 },
David Henningsson693b6132012-06-22 19:12:10 +02005982 [ALC269_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005983 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02005984 .v.func = alc_fixup_inv_dmic,
David Henningsson693b6132012-06-22 19:12:10 +02005985 },
Takashi Iwai9b745ab2014-03-07 08:37:19 +01005986 [ALC269_FIXUP_NO_SHUTUP] = {
5987 .type = HDA_FIXUP_FUNC,
5988 .v.func = alc_fixup_no_shutup,
5989 },
David Henningsson108cc102012-07-20 10:37:25 +02005990 [ALC269_FIXUP_LENOVO_DOCK] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005991 .type = HDA_FIXUP_PINS,
5992 .v.pins = (const struct hda_pintbl[]) {
David Henningsson108cc102012-07-20 10:37:25 +02005993 { 0x19, 0x23a11040 }, /* dock mic */
5994 { 0x1b, 0x2121103f }, /* dock headphone */
5995 { }
5996 },
5997 .chained = true,
5998 .chain_id = ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT
5999 },
6000 [ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006001 .type = HDA_FIXUP_FUNC,
David Henningsson108cc102012-07-20 10:37:25 +02006002 .v.func = alc269_fixup_pincfg_no_hp_to_lineout,
David Henningsson52129002013-11-19 10:25:53 +01006003 .chained = true,
6004 .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
David Henningsson108cc102012-07-20 10:37:25 +02006005 },
David Henningsson73bdd592013-04-15 15:44:14 +02006006 [ALC269_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6007 .type = HDA_FIXUP_PINS,
6008 .v.pins = (const struct hda_pintbl[]) {
6009 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6010 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6011 { }
6012 },
6013 .chained = true,
6014 .chain_id = ALC269_FIXUP_HEADSET_MODE
6015 },
6016 [ALC269_FIXUP_DELL2_MIC_NO_PRESENCE] = {
6017 .type = HDA_FIXUP_PINS,
6018 .v.pins = (const struct hda_pintbl[]) {
6019 { 0x16, 0x21014020 }, /* dock line out */
6020 { 0x19, 0x21a19030 }, /* dock mic */
6021 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6022 { }
6023 },
6024 .chained = true,
6025 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
6026 },
David Henningsson338cae52013-10-07 10:39:59 +02006027 [ALC269_FIXUP_DELL3_MIC_NO_PRESENCE] = {
6028 .type = HDA_FIXUP_PINS,
6029 .v.pins = (const struct hda_pintbl[]) {
6030 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6031 { }
6032 },
6033 .chained = true,
6034 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
6035 },
Kailang Yangfcc6c872017-06-29 15:21:27 +08006036 [ALC269_FIXUP_DELL4_MIC_NO_PRESENCE] = {
6037 .type = HDA_FIXUP_PINS,
6038 .v.pins = (const struct hda_pintbl[]) {
6039 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6040 { 0x1b, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6041 { }
6042 },
6043 .chained = true,
6044 .chain_id = ALC269_FIXUP_HEADSET_MODE
6045 },
David Henningsson73bdd592013-04-15 15:44:14 +02006046 [ALC269_FIXUP_HEADSET_MODE] = {
6047 .type = HDA_FIXUP_FUNC,
6048 .v.func = alc_fixup_headset_mode,
Hui Wang6676f302014-11-18 17:57:41 +08006049 .chained = true,
Takashi Iwaib3802782018-11-26 17:47:46 +01006050 .chain_id = ALC255_FIXUP_MIC_MUTE_LED
David Henningsson73bdd592013-04-15 15:44:14 +02006051 },
6052 [ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC] = {
6053 .type = HDA_FIXUP_FUNC,
6054 .v.func = alc_fixup_headset_mode_no_hp_mic,
6055 },
Takashi Iwai78197172015-06-27 10:21:13 +02006056 [ALC269_FIXUP_ASPIRE_HEADSET_MIC] = {
6057 .type = HDA_FIXUP_PINS,
6058 .v.pins = (const struct hda_pintbl[]) {
6059 { 0x19, 0x01a1913c }, /* headset mic w/o jack detect */
6060 { }
6061 },
6062 .chained = true,
6063 .chain_id = ALC269_FIXUP_HEADSET_MODE,
6064 },
David Henningsson88cfcf82013-10-11 10:18:45 +02006065 [ALC286_FIXUP_SONY_MIC_NO_PRESENCE] = {
6066 .type = HDA_FIXUP_PINS,
6067 .v.pins = (const struct hda_pintbl[]) {
6068 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6069 { }
6070 },
David Henningssonfbc78ad2013-10-11 13:46:04 +02006071 .chained = true,
6072 .chain_id = ALC269_FIXUP_HEADSET_MIC
David Henningsson88cfcf82013-10-11 10:18:45 +02006073 },
Ayman Bagabas0fbf21c2019-05-23 05:30:11 -04006074 [ALC256_FIXUP_HUAWEI_MACH_WX9_PINS] = {
Ayman Bagabas8ac51bb2018-12-12 18:07:57 -05006075 .type = HDA_FIXUP_PINS,
6076 .v.pins = (const struct hda_pintbl[]) {
6077 {0x12, 0x90a60130},
6078 {0x13, 0x40000000},
6079 {0x14, 0x90170110},
6080 {0x18, 0x411111f0},
6081 {0x19, 0x04a11040},
6082 {0x1a, 0x411111f0},
6083 {0x1b, 0x90170112},
6084 {0x1d, 0x40759a05},
6085 {0x1e, 0x411111f0},
6086 {0x21, 0x04211020},
6087 { }
6088 },
Ayman Bagabase2744fd2018-12-12 18:07:59 -05006089 .chained = true,
6090 .chain_id = ALC255_FIXUP_MIC_MUTE_LED
Ayman Bagabas8ac51bb2018-12-12 18:07:57 -05006091 },
David Henningssond240d1d2013-04-15 12:50:02 +02006092 [ALC269_FIXUP_ASUS_X101_FUNC] = {
6093 .type = HDA_FIXUP_FUNC,
6094 .v.func = alc269_fixup_x101_headset_mic,
6095 },
6096 [ALC269_FIXUP_ASUS_X101_VERB] = {
6097 .type = HDA_FIXUP_VERBS,
6098 .v.verbs = (const struct hda_verb[]) {
6099 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6100 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
6101 {0x20, AC_VERB_SET_PROC_COEF, 0x0310},
6102 { }
6103 },
6104 .chained = true,
6105 .chain_id = ALC269_FIXUP_ASUS_X101_FUNC
6106 },
6107 [ALC269_FIXUP_ASUS_X101] = {
6108 .type = HDA_FIXUP_PINS,
6109 .v.pins = (const struct hda_pintbl[]) {
6110 { 0x18, 0x04a1182c }, /* Headset mic */
6111 { }
6112 },
6113 .chained = true,
6114 .chain_id = ALC269_FIXUP_ASUS_X101_VERB
6115 },
Dylan Reid08a978d2012-11-18 22:56:40 -08006116 [ALC271_FIXUP_AMIC_MIC2] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006117 .type = HDA_FIXUP_PINS,
6118 .v.pins = (const struct hda_pintbl[]) {
Dylan Reid08a978d2012-11-18 22:56:40 -08006119 { 0x14, 0x99130110 }, /* speaker */
6120 { 0x19, 0x01a19c20 }, /* mic */
6121 { 0x1b, 0x99a7012f }, /* int-mic */
6122 { 0x21, 0x0121401f }, /* HP out */
6123 { }
6124 },
6125 },
6126 [ALC271_FIXUP_HP_GATE_MIC_JACK] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006127 .type = HDA_FIXUP_FUNC,
Dylan Reid08a978d2012-11-18 22:56:40 -08006128 .v.func = alc271_hp_gate_mic_jack,
6129 .chained = true,
6130 .chain_id = ALC271_FIXUP_AMIC_MIC2,
6131 },
Oleksij Rempelb1e89722013-12-04 20:50:53 +01006132 [ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572] = {
6133 .type = HDA_FIXUP_FUNC,
6134 .v.func = alc269_fixup_limit_int_mic_boost,
6135 .chained = true,
6136 .chain_id = ALC271_FIXUP_HP_GATE_MIC_JACK,
6137 },
Dylan Reid42397002013-04-05 14:58:22 -07006138 [ALC269_FIXUP_ACER_AC700] = {
6139 .type = HDA_FIXUP_PINS,
6140 .v.pins = (const struct hda_pintbl[]) {
6141 { 0x12, 0x99a3092f }, /* int-mic */
6142 { 0x14, 0x99130110 }, /* speaker */
6143 { 0x18, 0x03a11c20 }, /* mic */
6144 { 0x1e, 0x0346101e }, /* SPDIF1 */
6145 { 0x21, 0x0321101f }, /* HP out */
6146 { }
6147 },
6148 .chained = true,
6149 .chain_id = ALC271_FIXUP_DMIC,
6150 },
David Henningsson3e0d6112013-04-22 14:30:14 +02006151 [ALC269_FIXUP_LIMIT_INT_MIC_BOOST] = {
6152 .type = HDA_FIXUP_FUNC,
6153 .v.func = alc269_fixup_limit_int_mic_boost,
David Henningsson27937692013-11-18 11:51:47 +01006154 .chained = true,
6155 .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
David Henningsson3e0d6112013-04-22 14:30:14 +02006156 },
Oleksij Rempel2cede302013-11-27 17:12:03 +01006157 [ALC269VB_FIXUP_ASUS_ZENBOOK] = {
6158 .type = HDA_FIXUP_FUNC,
6159 .v.func = alc269_fixup_limit_int_mic_boost,
6160 .chained = true,
6161 .chain_id = ALC269VB_FIXUP_DMIC,
6162 },
Takashi Iwai23870832013-11-29 14:13:12 +01006163 [ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A] = {
6164 .type = HDA_FIXUP_VERBS,
6165 .v.verbs = (const struct hda_verb[]) {
6166 /* class-D output amp +5dB */
6167 { 0x20, AC_VERB_SET_COEF_INDEX, 0x12 },
6168 { 0x20, AC_VERB_SET_PROC_COEF, 0x2800 },
6169 {}
6170 },
6171 .chained = true,
6172 .chain_id = ALC269VB_FIXUP_ASUS_ZENBOOK,
6173 },
David Henningsson8e35cd42013-11-06 11:20:01 +01006174 [ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED] = {
6175 .type = HDA_FIXUP_FUNC,
6176 .v.func = alc269_fixup_limit_int_mic_boost,
6177 .chained = true,
6178 .chain_id = ALC269_FIXUP_HP_MUTE_LED_MIC1,
6179 },
Anisse Astier02b504d2013-06-03 11:53:10 +02006180 [ALC269VB_FIXUP_ORDISSIMO_EVE2] = {
6181 .type = HDA_FIXUP_PINS,
6182 .v.pins = (const struct hda_pintbl[]) {
6183 { 0x12, 0x99a3092f }, /* int-mic */
6184 { 0x18, 0x03a11d20 }, /* mic */
6185 { 0x19, 0x411111f0 }, /* Unused bogus pin */
6186 { }
6187 },
6188 },
Kailang Yangcd217a62013-08-22 10:15:24 +02006189 [ALC283_FIXUP_CHROME_BOOK] = {
6190 .type = HDA_FIXUP_FUNC,
6191 .v.func = alc283_fixup_chromebook,
6192 },
Kailang Yang0202e992013-12-02 15:20:15 +08006193 [ALC283_FIXUP_SENSE_COMBO_JACK] = {
6194 .type = HDA_FIXUP_FUNC,
6195 .v.func = alc283_fixup_sense_combo_jack,
6196 .chained = true,
6197 .chain_id = ALC283_FIXUP_CHROME_BOOK,
6198 },
Takashi Iwai7bba2152013-09-06 15:45:38 +02006199 [ALC282_FIXUP_ASUS_TX300] = {
6200 .type = HDA_FIXUP_FUNC,
6201 .v.func = alc282_fixup_asus_tx300,
6202 },
Kailang Yang1bb3e062013-09-27 13:10:25 +02006203 [ALC283_FIXUP_INT_MIC] = {
6204 .type = HDA_FIXUP_VERBS,
6205 .v.verbs = (const struct hda_verb[]) {
6206 {0x20, AC_VERB_SET_COEF_INDEX, 0x1a},
6207 {0x20, AC_VERB_SET_PROC_COEF, 0x0011},
6208 { }
6209 },
6210 .chained = true,
6211 .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST
6212 },
David Henningsson0f4881d2013-12-20 16:08:13 +01006213 [ALC290_FIXUP_SUBWOOFER_HSJACK] = {
6214 .type = HDA_FIXUP_PINS,
6215 .v.pins = (const struct hda_pintbl[]) {
6216 { 0x17, 0x90170112 }, /* subwoofer */
6217 { }
6218 },
6219 .chained = true,
6220 .chain_id = ALC290_FIXUP_MONO_SPEAKERS_HSJACK,
6221 },
6222 [ALC290_FIXUP_SUBWOOFER] = {
6223 .type = HDA_FIXUP_PINS,
6224 .v.pins = (const struct hda_pintbl[]) {
6225 { 0x17, 0x90170112 }, /* subwoofer */
6226 { }
6227 },
6228 .chained = true,
6229 .chain_id = ALC290_FIXUP_MONO_SPEAKERS,
6230 },
David Henningsson338cae52013-10-07 10:39:59 +02006231 [ALC290_FIXUP_MONO_SPEAKERS] = {
6232 .type = HDA_FIXUP_FUNC,
6233 .v.func = alc290_fixup_mono_speakers,
David Henningsson0f4881d2013-12-20 16:08:13 +01006234 },
6235 [ALC290_FIXUP_MONO_SPEAKERS_HSJACK] = {
6236 .type = HDA_FIXUP_FUNC,
6237 .v.func = alc290_fixup_mono_speakers,
David Henningsson338cae52013-10-07 10:39:59 +02006238 .chained = true,
6239 .chain_id = ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
6240 },
David Henningssonb67ae3f2013-11-05 13:11:37 +01006241 [ALC269_FIXUP_THINKPAD_ACPI] = {
6242 .type = HDA_FIXUP_FUNC,
Takashi Iwaid5a6cab2018-06-13 12:43:10 +02006243 .v.func = alc_fixup_thinkpad_acpi,
Takashi Iwai09da1112016-09-08 12:15:02 +02006244 .chained = true,
6245 .chain_id = ALC269_FIXUP_SKU_IGNORE,
David Henningssonb67ae3f2013-11-05 13:11:37 +01006246 },
David Henningsson56f27012016-01-11 09:33:14 +01006247 [ALC269_FIXUP_DMIC_THINKPAD_ACPI] = {
6248 .type = HDA_FIXUP_FUNC,
6249 .v.func = alc_fixup_inv_dmic,
6250 .chained = true,
6251 .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
6252 },
Chris Chiu5824ce82017-02-28 14:17:11 -06006253 [ALC255_FIXUP_ACER_MIC_NO_PRESENCE] = {
Hui Wang17d30462019-06-14 16:44:12 +08006254 .type = HDA_FIXUP_PINS,
6255 .v.pins = (const struct hda_pintbl[]) {
6256 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6257 { }
Chris Chiu5824ce82017-02-28 14:17:11 -06006258 },
6259 .chained = true,
Hui Wang17d30462019-06-14 16:44:12 +08006260 .chain_id = ALC255_FIXUP_HEADSET_MODE
Chris Chiu5824ce82017-02-28 14:17:11 -06006261 },
Chris Chiu615966a2017-02-28 14:17:12 -06006262 [ALC255_FIXUP_ASUS_MIC_NO_PRESENCE] = {
6263 .type = HDA_FIXUP_PINS,
6264 .v.pins = (const struct hda_pintbl[]) {
6265 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6266 { }
6267 },
6268 .chained = true,
6269 .chain_id = ALC255_FIXUP_HEADSET_MODE
6270 },
Kailang Yang9a22a8f52013-11-08 15:54:49 +08006271 [ALC255_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6272 .type = HDA_FIXUP_PINS,
6273 .v.pins = (const struct hda_pintbl[]) {
6274 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6275 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6276 { }
6277 },
6278 .chained = true,
6279 .chain_id = ALC255_FIXUP_HEADSET_MODE
6280 },
Kailang Yang31278992014-03-03 15:27:22 +08006281 [ALC255_FIXUP_DELL2_MIC_NO_PRESENCE] = {
6282 .type = HDA_FIXUP_PINS,
6283 .v.pins = (const struct hda_pintbl[]) {
6284 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6285 { }
6286 },
6287 .chained = true,
6288 .chain_id = ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC
6289 },
Kailang Yang9a22a8f52013-11-08 15:54:49 +08006290 [ALC255_FIXUP_HEADSET_MODE] = {
6291 .type = HDA_FIXUP_FUNC,
6292 .v.func = alc_fixup_headset_mode_alc255,
Hui Wang4a83d422014-11-18 17:57:40 +08006293 .chained = true,
Takashi Iwaib3802782018-11-26 17:47:46 +01006294 .chain_id = ALC255_FIXUP_MIC_MUTE_LED
Kailang Yang9a22a8f52013-11-08 15:54:49 +08006295 },
Kailang Yang31278992014-03-03 15:27:22 +08006296 [ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC] = {
6297 .type = HDA_FIXUP_FUNC,
6298 .v.func = alc_fixup_headset_mode_alc255_no_hp_mic,
6299 },
Kailang Yanga22aa262014-04-23 17:34:28 +08006300 [ALC293_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6301 .type = HDA_FIXUP_PINS,
6302 .v.pins = (const struct hda_pintbl[]) {
6303 { 0x18, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6304 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6305 { }
6306 },
6307 .chained = true,
6308 .chain_id = ALC269_FIXUP_HEADSET_MODE
6309 },
Takashi Iwai1c37c222014-05-06 17:34:42 +02006310 [ALC292_FIXUP_TPT440_DOCK] = {
David Henningssonec56af62015-06-24 10:46:33 +02006311 .type = HDA_FIXUP_FUNC,
Takashi Iwai7f57d802015-09-24 17:36:51 +02006312 .v.func = alc_fixup_tpt440_dock,
Takashi Iwai1c37c222014-05-06 17:34:42 +02006313 .chained = true,
6314 .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST
6315 },
Takashi Iwai9a811232015-12-09 15:17:43 +01006316 [ALC292_FIXUP_TPT440] = {
6317 .type = HDA_FIXUP_FUNC,
Takashi Iwai157f0b72015-12-10 23:30:43 +01006318 .v.func = alc_fixup_disable_aamix,
Takashi Iwai9a811232015-12-09 15:17:43 +01006319 .chained = true,
6320 .chain_id = ALC292_FIXUP_TPT440_DOCK,
6321 },
Anisse Astierabaa22742016-08-24 09:14:13 +02006322 [ALC283_FIXUP_HEADSET_MIC] = {
Daniel Drake9dc12862014-07-22 10:58:29 +01006323 .type = HDA_FIXUP_PINS,
6324 .v.pins = (const struct hda_pintbl[]) {
6325 { 0x19, 0x04a110f0 },
6326 { },
6327 },
6328 },
Takashi Iwaib3802782018-11-26 17:47:46 +01006329 [ALC255_FIXUP_MIC_MUTE_LED] = {
Hui Wang00ef9942014-07-31 11:52:38 +08006330 .type = HDA_FIXUP_FUNC,
Takashi Iwaib3802782018-11-26 17:47:46 +01006331 .v.func = snd_hda_gen_fixup_micmute_led,
Hui Wang00ef9942014-07-31 11:52:38 +08006332 },
Takashi Iwai1a22e772014-08-27 08:19:05 +02006333 [ALC282_FIXUP_ASPIRE_V5_PINS] = {
6334 .type = HDA_FIXUP_PINS,
6335 .v.pins = (const struct hda_pintbl[]) {
6336 { 0x12, 0x90a60130 },
6337 { 0x14, 0x90170110 },
6338 { 0x17, 0x40000008 },
6339 { 0x18, 0x411111f0 },
Mateusz Sylwestrzak04206942015-07-19 17:38:56 +02006340 { 0x19, 0x01a1913c },
Takashi Iwai1a22e772014-08-27 08:19:05 +02006341 { 0x1a, 0x411111f0 },
6342 { 0x1b, 0x411111f0 },
6343 { 0x1d, 0x40f89b2d },
6344 { 0x1e, 0x411111f0 },
6345 { 0x21, 0x0321101f },
6346 { },
6347 },
6348 },
David Henningsson7a5255f2014-10-30 08:26:01 +01006349 [ALC280_FIXUP_HP_GPIO4] = {
6350 .type = HDA_FIXUP_FUNC,
6351 .v.func = alc280_fixup_hp_gpio4,
6352 },
Kailang Yangeaa8e5e2014-11-21 15:49:11 +08006353 [ALC286_FIXUP_HP_GPIO_LED] = {
6354 .type = HDA_FIXUP_FUNC,
6355 .v.func = alc286_fixup_hp_gpio_led,
6356 },
David Henningsson33f4acd2015-01-07 15:50:13 +01006357 [ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY] = {
6358 .type = HDA_FIXUP_FUNC,
6359 .v.func = alc280_fixup_hp_gpio2_mic_hotkey,
6360 },
TienFu Chenb4b33f92015-01-20 15:06:21 +01006361 [ALC280_FIXUP_HP_DOCK_PINS] = {
6362 .type = HDA_FIXUP_PINS,
6363 .v.pins = (const struct hda_pintbl[]) {
6364 { 0x1b, 0x21011020 }, /* line-out */
6365 { 0x1a, 0x01a1903c }, /* headset mic */
6366 { 0x18, 0x2181103f }, /* line-in */
6367 { },
6368 },
6369 .chained = true,
6370 .chain_id = ALC280_FIXUP_HP_GPIO4
6371 },
Jaroslav Kysela04d54662017-03-09 13:29:13 +01006372 [ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED] = {
6373 .type = HDA_FIXUP_PINS,
6374 .v.pins = (const struct hda_pintbl[]) {
6375 { 0x1b, 0x21011020 }, /* line-out */
6376 { 0x18, 0x2181103f }, /* line-in */
6377 { },
6378 },
6379 .chained = true,
6380 .chain_id = ALC269_FIXUP_HP_GPIO_MIC1_LED
6381 },
Keith Packard98973f22015-07-15 12:14:39 -07006382 [ALC280_FIXUP_HP_9480M] = {
6383 .type = HDA_FIXUP_FUNC,
6384 .v.func = alc280_fixup_hp_9480m,
6385 },
Kailang Yange1e62b92015-04-08 16:01:22 +08006386 [ALC288_FIXUP_DELL_HEADSET_MODE] = {
6387 .type = HDA_FIXUP_FUNC,
6388 .v.func = alc_fixup_headset_mode_dell_alc288,
6389 .chained = true,
Takashi Iwaib3802782018-11-26 17:47:46 +01006390 .chain_id = ALC255_FIXUP_MIC_MUTE_LED
Kailang Yange1e62b92015-04-08 16:01:22 +08006391 },
6392 [ALC288_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6393 .type = HDA_FIXUP_PINS,
6394 .v.pins = (const struct hda_pintbl[]) {
6395 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6396 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6397 { }
6398 },
6399 .chained = true,
6400 .chain_id = ALC288_FIXUP_DELL_HEADSET_MODE
6401 },
Hui Wang831bfdf92015-06-26 12:35:17 +08006402 [ALC288_FIXUP_DISABLE_AAMIX] = {
6403 .type = HDA_FIXUP_FUNC,
6404 .v.func = alc_fixup_disable_aamix,
6405 .chained = true,
Takashi Iwaid44a6862018-06-19 23:04:03 +02006406 .chain_id = ALC288_FIXUP_DELL1_MIC_NO_PRESENCE
Hui Wang831bfdf92015-06-26 12:35:17 +08006407 },
6408 [ALC288_FIXUP_DELL_XPS_13] = {
6409 .type = HDA_FIXUP_FUNC,
6410 .v.func = alc_fixup_dell_xps13,
6411 .chained = true,
6412 .chain_id = ALC288_FIXUP_DISABLE_AAMIX
6413 },
Takashi Iwai8b99aba2015-06-15 11:59:32 +02006414 [ALC292_FIXUP_DISABLE_AAMIX] = {
6415 .type = HDA_FIXUP_FUNC,
6416 .v.func = alc_fixup_disable_aamix,
Hui Wang831bfdf92015-06-26 12:35:17 +08006417 .chained = true,
6418 .chain_id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE
Takashi Iwai8b99aba2015-06-15 11:59:32 +02006419 },
David Henningssonc04017e2015-12-15 14:44:03 +01006420 [ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK] = {
6421 .type = HDA_FIXUP_FUNC,
6422 .v.func = alc_fixup_disable_aamix,
6423 .chained = true,
6424 .chain_id = ALC293_FIXUP_DELL1_MIC_NO_PRESENCE
6425 },
Takashi Iwai8b99aba2015-06-15 11:59:32 +02006426 [ALC292_FIXUP_DELL_E7X] = {
6427 .type = HDA_FIXUP_FUNC,
6428 .v.func = alc_fixup_dell_xps13,
6429 .chained = true,
6430 .chain_id = ALC292_FIXUP_DISABLE_AAMIX
6431 },
Kailang Yang977e6272015-05-18 15:31:20 +08006432 [ALC298_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6433 .type = HDA_FIXUP_PINS,
6434 .v.pins = (const struct hda_pintbl[]) {
6435 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6436 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6437 { }
6438 },
6439 .chained = true,
6440 .chain_id = ALC269_FIXUP_HEADSET_MODE
6441 },
Hui Wang2f726ae2017-03-31 10:31:40 +08006442 [ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE] = {
6443 .type = HDA_FIXUP_PINS,
6444 .v.pins = (const struct hda_pintbl[]) {
6445 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6446 { }
6447 },
6448 .chained = true,
6449 .chain_id = ALC269_FIXUP_HEADSET_MODE
6450 },
Kailang Yang6ed11312015-10-26 15:37:39 +08006451 [ALC275_FIXUP_DELL_XPS] = {
6452 .type = HDA_FIXUP_VERBS,
6453 .v.verbs = (const struct hda_verb[]) {
6454 /* Enables internal speaker */
6455 {0x20, AC_VERB_SET_COEF_INDEX, 0x1f},
6456 {0x20, AC_VERB_SET_PROC_COEF, 0x00c0},
6457 {0x20, AC_VERB_SET_COEF_INDEX, 0x30},
6458 {0x20, AC_VERB_SET_PROC_COEF, 0x00b1},
6459 {}
6460 }
6461 },
Hui Wang8c697292015-11-24 11:08:18 +08006462 [ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE] = {
6463 .type = HDA_FIXUP_VERBS,
6464 .v.verbs = (const struct hda_verb[]) {
6465 /* Disable pass-through path for FRONT 14h */
6466 {0x20, AC_VERB_SET_COEF_INDEX, 0x36},
6467 {0x20, AC_VERB_SET_PROC_COEF, 0x1737},
6468 {}
6469 },
6470 .chained = true,
6471 .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
6472 },
Hui Wang23adc192015-12-08 12:27:18 +08006473 [ALC293_FIXUP_LENOVO_SPK_NOISE] = {
6474 .type = HDA_FIXUP_FUNC,
6475 .v.func = alc_fixup_disable_aamix,
6476 .chained = true,
6477 .chain_id = ALC269_FIXUP_THINKPAD_ACPI
6478 },
Kailang3694cb22015-12-28 11:35:24 +08006479 [ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY] = {
6480 .type = HDA_FIXUP_FUNC,
6481 .v.func = alc233_fixup_lenovo_line2_mic_hotkey,
6482 },
Kai-Heng Feng3b43b712016-02-25 15:19:38 +08006483 [ALC255_FIXUP_DELL_SPK_NOISE] = {
6484 .type = HDA_FIXUP_FUNC,
6485 .v.func = alc_fixup_disable_aamix,
6486 .chained = true,
6487 .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
6488 },
Kailang Yangd1dd4212019-01-09 17:05:24 +08006489 [ALC225_FIXUP_DISABLE_MIC_VREF] = {
6490 .type = HDA_FIXUP_FUNC,
6491 .v.func = alc_fixup_disable_mic_vref,
6492 .chained = true,
6493 .chain_id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE
6494 },
David Henningsson2ae95572016-02-25 09:37:05 +01006495 [ALC225_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6496 .type = HDA_FIXUP_VERBS,
6497 .v.verbs = (const struct hda_verb[]) {
6498 /* Disable pass-through path for FRONT 14h */
6499 { 0x20, AC_VERB_SET_COEF_INDEX, 0x36 },
6500 { 0x20, AC_VERB_SET_PROC_COEF, 0x57d7 },
6501 {}
6502 },
6503 .chained = true,
Kailang Yangd1dd4212019-01-09 17:05:24 +08006504 .chain_id = ALC225_FIXUP_DISABLE_MIC_VREF
David Henningsson2ae95572016-02-25 09:37:05 +01006505 },
Takashi Iwaif8839822016-02-25 14:31:59 +01006506 [ALC280_FIXUP_HP_HEADSET_MIC] = {
6507 .type = HDA_FIXUP_FUNC,
6508 .v.func = alc_fixup_disable_aamix,
6509 .chained = true,
6510 .chain_id = ALC269_FIXUP_HEADSET_MIC,
6511 },
Hui Wange549d192016-04-01 11:00:15 +08006512 [ALC221_FIXUP_HP_FRONT_MIC] = {
6513 .type = HDA_FIXUP_PINS,
6514 .v.pins = (const struct hda_pintbl[]) {
6515 { 0x19, 0x02a19020 }, /* Front Mic */
6516 { }
6517 },
6518 },
Sven Eckelmannc636b952016-04-11 16:55:26 +02006519 [ALC292_FIXUP_TPT460] = {
6520 .type = HDA_FIXUP_FUNC,
6521 .v.func = alc_fixup_tpt440_dock,
6522 .chained = true,
6523 .chain_id = ALC293_FIXUP_LENOVO_SPK_NOISE,
6524 },
Hui Wangdd9aa332016-08-01 10:20:32 +08006525 [ALC298_FIXUP_SPK_VOLUME] = {
6526 .type = HDA_FIXUP_FUNC,
6527 .v.func = alc298_fixup_speaker_volume,
Hui Wang59ec4b52016-08-04 15:28:04 +08006528 .chained = true,
Hui Wang2f726ae2017-03-31 10:31:40 +08006529 .chain_id = ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE,
Hui Wangdd9aa332016-08-01 10:20:32 +08006530 },
Takashi Iwaie312a862018-03-06 12:14:17 +01006531 [ALC295_FIXUP_DISABLE_DAC3] = {
6532 .type = HDA_FIXUP_FUNC,
6533 .v.func = alc295_fixup_disable_dac3,
6534 },
Kai-Heng Fengfd06c772016-08-30 15:36:34 +08006535 [ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER] = {
6536 .type = HDA_FIXUP_PINS,
6537 .v.pins = (const struct hda_pintbl[]) {
6538 { 0x1b, 0x90170151 },
6539 { }
6540 },
6541 .chained = true,
6542 .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
6543 },
Gabriele Mazzotta823ff162016-12-24 19:50:01 +01006544 [ALC269_FIXUP_ATIV_BOOK_8] = {
6545 .type = HDA_FIXUP_FUNC,
6546 .v.func = alc_fixup_auto_mute_via_amp,
6547 .chained = true,
6548 .chain_id = ALC269_FIXUP_NO_SHUTUP
6549 },
Kailang Yang9eb5d0e2017-01-17 15:40:25 +08006550 [ALC221_FIXUP_HP_MIC_NO_PRESENCE] = {
6551 .type = HDA_FIXUP_PINS,
6552 .v.pins = (const struct hda_pintbl[]) {
6553 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6554 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6555 { }
6556 },
6557 .chained = true,
6558 .chain_id = ALC269_FIXUP_HEADSET_MODE
6559 },
Chris Chiuc1732ed2017-02-28 14:17:13 -06006560 [ALC256_FIXUP_ASUS_HEADSET_MODE] = {
6561 .type = HDA_FIXUP_FUNC,
6562 .v.func = alc_fixup_headset_mode,
6563 },
6564 [ALC256_FIXUP_ASUS_MIC] = {
6565 .type = HDA_FIXUP_PINS,
6566 .v.pins = (const struct hda_pintbl[]) {
6567 { 0x13, 0x90a60160 }, /* use as internal mic */
6568 { 0x19, 0x04a11120 }, /* use as headset mic, without its own jack detect */
6569 { }
6570 },
6571 .chained = true,
6572 .chain_id = ALC256_FIXUP_ASUS_HEADSET_MODE
6573 },
Chris Chiueeed4cd2017-02-28 14:17:15 -06006574 [ALC256_FIXUP_ASUS_AIO_GPIO2] = {
Takashi Iwaiae065f12018-06-19 23:00:03 +02006575 .type = HDA_FIXUP_FUNC,
6576 /* Set up GPIO2 for the speaker amp */
6577 .v.func = alc_fixup_gpio4,
Chris Chiueeed4cd2017-02-28 14:17:15 -06006578 },
Chris Chiu216d7ae2017-02-28 14:17:14 -06006579 [ALC233_FIXUP_ASUS_MIC_NO_PRESENCE] = {
6580 .type = HDA_FIXUP_PINS,
6581 .v.pins = (const struct hda_pintbl[]) {
6582 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6583 { }
6584 },
6585 .chained = true,
6586 .chain_id = ALC269_FIXUP_HEADSET_MIC
6587 },
6588 [ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE] = {
6589 .type = HDA_FIXUP_VERBS,
6590 .v.verbs = (const struct hda_verb[]) {
6591 /* Enables internal speaker */
6592 {0x20, AC_VERB_SET_COEF_INDEX, 0x40},
6593 {0x20, AC_VERB_SET_PROC_COEF, 0x8800},
6594 {}
6595 },
6596 .chained = true,
6597 .chain_id = ALC233_FIXUP_ASUS_MIC_NO_PRESENCE
6598 },
Kailang Yangca169cc2017-04-25 16:17:40 +08006599 [ALC233_FIXUP_LENOVO_MULTI_CODECS] = {
6600 .type = HDA_FIXUP_FUNC,
6601 .v.func = alc233_alc662_fixup_lenovo_dual_codecs,
6602 },
Jian-Hong Panea5c7eb2019-04-01 11:25:05 +08006603 [ALC233_FIXUP_ACER_HEADSET_MIC] = {
6604 .type = HDA_FIXUP_VERBS,
6605 .v.verbs = (const struct hda_verb[]) {
6606 { 0x20, AC_VERB_SET_COEF_INDEX, 0x45 },
6607 { 0x20, AC_VERB_SET_PROC_COEF, 0x5089 },
6608 { }
6609 },
6610 .chained = true,
6611 .chain_id = ALC233_FIXUP_ASUS_MIC_NO_PRESENCE
6612 },
Hui Wangf33f79f2017-07-07 12:08:29 +08006613 [ALC294_FIXUP_LENOVO_MIC_LOCATION] = {
6614 .type = HDA_FIXUP_PINS,
6615 .v.pins = (const struct hda_pintbl[]) {
6616 /* Change the mic location from front to right, otherwise there are
6617 two front mics with the same name, pulseaudio can't handle them.
6618 This is just a temporary workaround, after applying this fixup,
6619 there will be one "Front Mic" and one "Mic" in this machine.
6620 */
6621 { 0x1a, 0x04a19040 },
6622 { }
6623 },
6624 },
Kailang Yang5f364132017-07-25 16:28:16 +08006625 [ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE] = {
6626 .type = HDA_FIXUP_PINS,
6627 .v.pins = (const struct hda_pintbl[]) {
6628 { 0x16, 0x0101102f }, /* Rear Headset HP */
6629 { 0x19, 0x02a1913c }, /* use as Front headset mic, without its own jack detect */
6630 { 0x1a, 0x01a19030 }, /* Rear Headset MIC */
6631 { 0x1b, 0x02011020 },
6632 { }
6633 },
6634 .chained = true,
6635 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
6636 },
PeiSen Houb84e8432017-09-01 15:11:56 +08006637 [ALC700_FIXUP_INTEL_REFERENCE] = {
6638 .type = HDA_FIXUP_VERBS,
6639 .v.verbs = (const struct hda_verb[]) {
6640 /* Enables internal speaker */
6641 {0x20, AC_VERB_SET_COEF_INDEX, 0x45},
6642 {0x20, AC_VERB_SET_PROC_COEF, 0x5289},
6643 {0x20, AC_VERB_SET_COEF_INDEX, 0x4A},
6644 {0x20, AC_VERB_SET_PROC_COEF, 0x001b},
6645 {0x58, AC_VERB_SET_COEF_INDEX, 0x00},
6646 {0x58, AC_VERB_SET_PROC_COEF, 0x3888},
6647 {0x20, AC_VERB_SET_COEF_INDEX, 0x6f},
6648 {0x20, AC_VERB_SET_PROC_COEF, 0x2c0b},
6649 {}
6650 }
6651 },
Kailang Yang92266652017-12-14 15:28:58 +08006652 [ALC274_FIXUP_DELL_BIND_DACS] = {
6653 .type = HDA_FIXUP_FUNC,
6654 .v.func = alc274_fixup_bind_dacs,
6655 .chained = true,
6656 .chain_id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE
6657 },
6658 [ALC274_FIXUP_DELL_AIO_LINEOUT_VERB] = {
6659 .type = HDA_FIXUP_PINS,
6660 .v.pins = (const struct hda_pintbl[]) {
6661 { 0x1b, 0x0401102f },
6662 { }
6663 },
6664 .chained = true,
6665 .chain_id = ALC274_FIXUP_DELL_BIND_DACS
6666 },
Kailang Yang61fcf8e2018-02-02 15:26:46 +08006667 [ALC298_FIXUP_TPT470_DOCK] = {
6668 .type = HDA_FIXUP_FUNC,
6669 .v.func = alc_fixup_tpt470_dock,
6670 .chained = true,
6671 .chain_id = ALC293_FIXUP_LENOVO_SPK_NOISE
6672 },
Kailang Yangae104a22018-02-05 16:07:20 +08006673 [ALC255_FIXUP_DUMMY_LINEOUT_VERB] = {
6674 .type = HDA_FIXUP_PINS,
6675 .v.pins = (const struct hda_pintbl[]) {
6676 { 0x14, 0x0201101f },
6677 { }
6678 },
6679 .chained = true,
6680 .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
6681 },
Kailang Yangf0ba9d62018-03-16 11:46:08 +08006682 [ALC255_FIXUP_DELL_HEADSET_MIC] = {
6683 .type = HDA_FIXUP_PINS,
6684 .v.pins = (const struct hda_pintbl[]) {
6685 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6686 { }
6687 },
Hui Wang3ce0d5a2018-04-19 13:29:04 +08006688 .chained = true,
6689 .chain_id = ALC269_FIXUP_HEADSET_MIC
Kailang Yangf0ba9d62018-03-16 11:46:08 +08006690 },
Tom Bridenbbf8ff62018-05-29 17:34:20 +01006691 [ALC295_FIXUP_HP_X360] = {
6692 .type = HDA_FIXUP_FUNC,
6693 .v.func = alc295_fixup_hp_top_speakers,
6694 .chained = true,
6695 .chain_id = ALC269_FIXUP_HP_MUTE_LED_MIC3
Kailang Yang8a328ac2018-08-21 16:54:41 +08006696 },
6697 [ALC221_FIXUP_HP_HEADSET_MIC] = {
6698 .type = HDA_FIXUP_PINS,
6699 .v.pins = (const struct hda_pintbl[]) {
6700 { 0x19, 0x0181313f},
6701 { }
6702 },
6703 .chained = true,
6704 .chain_id = ALC269_FIXUP_HEADSET_MIC
6705 },
Hui Wangc4cfcf62018-11-26 14:17:16 +08006706 [ALC285_FIXUP_LENOVO_HEADPHONE_NOISE] = {
6707 .type = HDA_FIXUP_FUNC,
6708 .v.func = alc285_fixup_invalidate_dacs,
Hui Wang6ba189c2018-12-09 09:16:43 +08006709 .chained = true,
6710 .chain_id = ALC269_FIXUP_THINKPAD_ACPI
Hui Wangc4cfcf62018-11-26 14:17:16 +08006711 },
Girija Kumar Kasinadhunie8ed64b2018-11-26 13:40:46 -05006712 [ALC295_FIXUP_HP_AUTO_MUTE] = {
6713 .type = HDA_FIXUP_FUNC,
6714 .v.func = alc_fixup_auto_mute_via_amp,
6715 },
Chris Chiu33aaebd2018-12-05 14:48:53 +08006716 [ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE] = {
6717 .type = HDA_FIXUP_PINS,
6718 .v.pins = (const struct hda_pintbl[]) {
6719 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6720 { }
6721 },
6722 .chained = true,
6723 .chain_id = ALC269_FIXUP_HEADSET_MIC
6724 },
Chris Chiud8ae4582018-12-07 17:17:11 +08006725 [ALC294_FIXUP_ASUS_MIC] = {
6726 .type = HDA_FIXUP_PINS,
6727 .v.pins = (const struct hda_pintbl[]) {
6728 { 0x13, 0x90a60160 }, /* use as internal mic */
6729 { 0x19, 0x04a11120 }, /* use as headset mic, without its own jack detect */
6730 { }
6731 },
6732 .chained = true,
6733 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
6734 },
Jian-Hong Pan4e051102018-12-07 17:17:12 +08006735 [ALC294_FIXUP_ASUS_HEADSET_MIC] = {
6736 .type = HDA_FIXUP_PINS,
6737 .v.pins = (const struct hda_pintbl[]) {
Jian-Hong Pan82b01142018-12-27 16:46:31 +08006738 { 0x19, 0x01a1103c }, /* use as headset mic */
Jian-Hong Pan4e051102018-12-07 17:17:12 +08006739 { }
6740 },
6741 .chained = true,
6742 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
6743 },
6744 [ALC294_FIXUP_ASUS_SPK] = {
6745 .type = HDA_FIXUP_VERBS,
6746 .v.verbs = (const struct hda_verb[]) {
6747 /* Set EAPD high */
6748 { 0x20, AC_VERB_SET_COEF_INDEX, 0x40 },
6749 { 0x20, AC_VERB_SET_PROC_COEF, 0x8800 },
6750 { }
6751 },
6752 .chained = true,
6753 .chain_id = ALC294_FIXUP_ASUS_HEADSET_MIC
6754 },
Jaroslav Kyselac8a9afa2019-03-14 09:21:08 +01006755 [ALC295_FIXUP_CHROME_BOOK] = {
Kailang Yange8547472018-11-28 15:32:45 +08006756 .type = HDA_FIXUP_FUNC,
Jaroslav Kyselac8a9afa2019-03-14 09:21:08 +01006757 .v.func = alc295_fixup_chromebook,
Kailang Yang8983eb62019-04-03 15:31:49 +08006758 .chained = true,
6759 .chain_id = ALC225_FIXUP_HEADSET_JACK
6760 },
6761 [ALC225_FIXUP_HEADSET_JACK] = {
6762 .type = HDA_FIXUP_FUNC,
6763 .v.func = alc_fixup_headset_jack,
Kailang Yange8547472018-11-28 15:32:45 +08006764 },
Jeremy Soller89e3a562019-01-30 16:12:31 -07006765 [ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE] = {
6766 .type = HDA_FIXUP_PINS,
6767 .v.pins = (const struct hda_pintbl[]) {
6768 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6769 { }
6770 },
6771 .chained = true,
6772 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
6773 },
Hui Wangc8c6ee62019-02-14 11:41:33 +08006774 [ALC285_FIXUP_LENOVO_PC_BEEP_IN_NOISE] = {
6775 .type = HDA_FIXUP_VERBS,
6776 .v.verbs = (const struct hda_verb[]) {
6777 /* Disable PCBEEP-IN passthrough */
6778 { 0x20, AC_VERB_SET_COEF_INDEX, 0x36 },
6779 { 0x20, AC_VERB_SET_PROC_COEF, 0x57d7 },
6780 { }
6781 },
6782 .chained = true,
6783 .chain_id = ALC285_FIXUP_LENOVO_HEADPHONE_NOISE
6784 },
Jian-Hong Pancbc05fd2019-03-13 17:33:24 +08006785 [ALC255_FIXUP_ACER_HEADSET_MIC] = {
6786 .type = HDA_FIXUP_PINS,
6787 .v.pins = (const struct hda_pintbl[]) {
6788 { 0x19, 0x03a11130 },
6789 { 0x1a, 0x90a60140 }, /* use as internal mic */
6790 { }
6791 },
6792 .chained = true,
6793 .chain_id = ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC
6794 },
Kailang Yang136824e2019-03-14 16:22:45 +08006795 [ALC225_FIXUP_DELL_WYSE_AIO_MIC_NO_PRESENCE] = {
6796 .type = HDA_FIXUP_PINS,
6797 .v.pins = (const struct hda_pintbl[]) {
6798 { 0x16, 0x01011020 }, /* Rear Line out */
6799 { 0x19, 0x01a1913c }, /* use as Front headset mic, without its own jack detect */
6800 { }
6801 },
6802 .chained = true,
6803 .chain_id = ALC225_FIXUP_WYSE_AUTO_MUTE
6804 },
6805 [ALC225_FIXUP_WYSE_AUTO_MUTE] = {
6806 .type = HDA_FIXUP_FUNC,
6807 .v.func = alc_fixup_auto_mute_via_amp,
6808 .chained = true,
6809 .chain_id = ALC225_FIXUP_WYSE_DISABLE_MIC_VREF
6810 },
6811 [ALC225_FIXUP_WYSE_DISABLE_MIC_VREF] = {
6812 .type = HDA_FIXUP_FUNC,
6813 .v.func = alc_fixup_disable_mic_vref,
6814 .chained = true,
6815 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
6816 },
Jian-Hong Pan667a8f72019-03-15 17:51:09 +08006817 [ALC286_FIXUP_ACER_AIO_HEADSET_MIC] = {
6818 .type = HDA_FIXUP_VERBS,
6819 .v.verbs = (const struct hda_verb[]) {
6820 { 0x20, AC_VERB_SET_COEF_INDEX, 0x4f },
6821 { 0x20, AC_VERB_SET_PROC_COEF, 0x5029 },
6822 { }
6823 },
6824 .chained = true,
6825 .chain_id = ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE
6826 },
Jian-Hong Pane1037352019-03-22 11:37:18 +08006827 [ALC256_FIXUP_ASUS_MIC_NO_PRESENCE] = {
6828 .type = HDA_FIXUP_PINS,
6829 .v.pins = (const struct hda_pintbl[]) {
6830 { 0x19, 0x04a11120 }, /* use as headset mic, without its own jack detect */
6831 { }
6832 },
6833 .chained = true,
6834 .chain_id = ALC256_FIXUP_ASUS_HEADSET_MODE
6835 },
Bernhard Rosenkraenzere2a829b2019-03-05 00:38:19 +01006836 [ALC299_FIXUP_PREDATOR_SPK] = {
6837 .type = HDA_FIXUP_PINS,
6838 .v.pins = (const struct hda_pintbl[]) {
6839 { 0x21, 0x90170150 }, /* use as headset mic, without its own jack detect */
6840 { }
6841 }
6842 },
Jian-Hong Pan60083f92019-09-02 18:00:56 +08006843 [ALC294_FIXUP_ASUS_INTSPK_HEADSET_MIC] = {
6844 .type = HDA_FIXUP_PINS,
6845 .v.pins = (const struct hda_pintbl[]) {
6846 { 0x14, 0x411111f0 }, /* disable confusing internal speaker */
6847 { 0x19, 0x04a11150 }, /* use as headset mic, without its own jack detect */
6848 { }
6849 },
6850 .chained = true,
6851 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
6852 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02006853};
6854
6855static const struct snd_pci_quirk alc269_fixup_tbl[] = {
Marius Knausta6b92b62014-03-03 01:48:58 +01006856 SND_PCI_QUIRK(0x1025, 0x0283, "Acer TravelMate 8371", ALC269_FIXUP_INV_DMIC),
David Henningsson693b6132012-06-22 19:12:10 +02006857 SND_PCI_QUIRK(0x1025, 0x029b, "Acer 1810TZ", ALC269_FIXUP_INV_DMIC),
6858 SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC),
David Henningssonaaedfb42013-08-16 14:09:02 +02006859 SND_PCI_QUIRK(0x1025, 0x047c, "Acer AC700", ALC269_FIXUP_ACER_AC700),
Takashi Iwai78197172015-06-27 10:21:13 +02006860 SND_PCI_QUIRK(0x1025, 0x072d, "Acer Aspire V5-571G", ALC269_FIXUP_ASPIRE_HEADSET_MIC),
6861 SND_PCI_QUIRK(0x1025, 0x080d, "Acer Aspire V5-122P", ALC269_FIXUP_ASPIRE_HEADSET_MIC),
David Henningssonaaedfb42013-08-16 14:09:02 +02006862 SND_PCI_QUIRK(0x1025, 0x0740, "Acer AO725", ALC271_FIXUP_HP_GATE_MIC_JACK),
6863 SND_PCI_QUIRK(0x1025, 0x0742, "Acer AO756", ALC271_FIXUP_HP_GATE_MIC_JACK),
Simon South02322ac2016-03-02 23:10:44 -05006864 SND_PCI_QUIRK(0x1025, 0x0762, "Acer Aspire E1-472", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572),
Oleksij Rempelb1e89722013-12-04 20:50:53 +01006865 SND_PCI_QUIRK(0x1025, 0x0775, "Acer Aspire E1-572", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572),
Takashi Iwai1a22e772014-08-27 08:19:05 +02006866 SND_PCI_QUIRK(0x1025, 0x079b, "Acer Aspire V5-573G", ALC282_FIXUP_ASPIRE_V5_PINS),
Chris Chiu705b65f2018-12-05 14:48:54 +08006867 SND_PCI_QUIRK(0x1025, 0x102b, "Acer Aspire C24-860", ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE),
Takashi Iwaib9c2fa52015-11-19 16:39:50 +01006868 SND_PCI_QUIRK(0x1025, 0x106d, "Acer Cloudbook 14", ALC283_FIXUP_CHROME_BOOK),
Chris Chiuc7531e32019-03-21 17:17:31 +08006869 SND_PCI_QUIRK(0x1025, 0x1099, "Acer Aspire E5-523G", ALC255_FIXUP_ACER_MIC_NO_PRESENCE),
6870 SND_PCI_QUIRK(0x1025, 0x110e, "Acer Aspire ES1-432", ALC255_FIXUP_ACER_MIC_NO_PRESENCE),
Bernhard Rosenkraenzere2a829b2019-03-05 00:38:19 +01006871 SND_PCI_QUIRK(0x1025, 0x1246, "Acer Predator Helios 500", ALC299_FIXUP_PREDATOR_SPK),
Jian-Hong Pan667a8f72019-03-15 17:51:09 +08006872 SND_PCI_QUIRK(0x1025, 0x128f, "Acer Veriton Z6860G", ALC286_FIXUP_ACER_AIO_HEADSET_MIC),
6873 SND_PCI_QUIRK(0x1025, 0x1290, "Acer Veriton Z4860G", ALC286_FIXUP_ACER_AIO_HEADSET_MIC),
6874 SND_PCI_QUIRK(0x1025, 0x1291, "Acer Veriton Z4660G", ALC286_FIXUP_ACER_AIO_HEADSET_MIC),
Jian-Hong Pan2733cce2019-03-21 16:39:04 +08006875 SND_PCI_QUIRK(0x1025, 0x1308, "Acer Aspire Z24-890", ALC286_FIXUP_ACER_AIO_HEADSET_MIC),
Jian-Hong Panea5c7eb2019-04-01 11:25:05 +08006876 SND_PCI_QUIRK(0x1025, 0x132a, "Acer TravelMate B114-21", ALC233_FIXUP_ACER_HEADSET_MIC),
Jian-Hong Pancbc05fd2019-03-13 17:33:24 +08006877 SND_PCI_QUIRK(0x1025, 0x1330, "Acer TravelMate X514-51T", ALC255_FIXUP_ACER_HEADSET_MIC),
David Henningssonaaedfb42013-08-16 14:09:02 +02006878 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
Kailang Yang6ed11312015-10-26 15:37:39 +08006879 SND_PCI_QUIRK(0x1028, 0x054b, "Dell XPS one 2710", ALC275_FIXUP_DELL_XPS),
Takashi Iwai86f799b2015-11-14 17:46:31 +01006880 SND_PCI_QUIRK(0x1028, 0x05bd, "Dell Latitude E6440", ALC292_FIXUP_DELL_E7X),
Takashi Iwaicf521032016-01-15 12:59:25 +01006881 SND_PCI_QUIRK(0x1028, 0x05be, "Dell Latitude E6540", ALC292_FIXUP_DELL_E7X),
Takashi Iwai8b99aba2015-06-15 11:59:32 +02006882 SND_PCI_QUIRK(0x1028, 0x05ca, "Dell Latitude E7240", ALC292_FIXUP_DELL_E7X),
6883 SND_PCI_QUIRK(0x1028, 0x05cb, "Dell Latitude E7440", ALC292_FIXUP_DELL_E7X),
David Henningsson0f4881d2013-12-20 16:08:13 +01006884 SND_PCI_QUIRK(0x1028, 0x05da, "Dell Vostro 5460", ALC290_FIXUP_SUBWOOFER),
David Henningsson73bdd592013-04-15 15:44:14 +02006885 SND_PCI_QUIRK(0x1028, 0x05f4, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
6886 SND_PCI_QUIRK(0x1028, 0x05f5, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
6887 SND_PCI_QUIRK(0x1028, 0x05f6, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
David Henningsson0f4881d2013-12-20 16:08:13 +01006888 SND_PCI_QUIRK(0x1028, 0x0615, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK),
6889 SND_PCI_QUIRK(0x1028, 0x0616, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK),
Takashi Iwai98070572016-01-12 21:06:39 +01006890 SND_PCI_QUIRK(0x1028, 0x062c, "Dell Latitude E5550", ALC292_FIXUP_DELL_E7X),
Takashi Iwai42755542015-06-29 10:56:53 +02006891 SND_PCI_QUIRK(0x1028, 0x062e, "Dell Latitude E7450", ALC292_FIXUP_DELL_E7X),
David Henningsson0f4881d2013-12-20 16:08:13 +01006892 SND_PCI_QUIRK(0x1028, 0x0638, "Dell Inspiron 5439", ALC290_FIXUP_MONO_SPEAKERS_HSJACK),
Kailang Yanga22aa262014-04-23 17:34:28 +08006893 SND_PCI_QUIRK(0x1028, 0x064a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
6894 SND_PCI_QUIRK(0x1028, 0x064b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
Hui Wang831bfdf92015-06-26 12:35:17 +08006895 SND_PCI_QUIRK(0x1028, 0x0665, "Dell XPS 13", ALC288_FIXUP_DELL_XPS_13),
Bastien Noceraafecb142016-04-18 11:10:42 +02006896 SND_PCI_QUIRK(0x1028, 0x0669, "Dell Optiplex 9020m", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
Takashi Iwai3a05d122015-07-29 09:04:52 +02006897 SND_PCI_QUIRK(0x1028, 0x069a, "Dell Vostro 5480", ALC290_FIXUP_SUBWOOFER_HSJACK),
Kailang Yang8b724152014-12-17 17:08:59 +08006898 SND_PCI_QUIRK(0x1028, 0x06c7, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
Kailang Yangb7343042014-12-02 14:50:45 +08006899 SND_PCI_QUIRK(0x1028, 0x06d9, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
6900 SND_PCI_QUIRK(0x1028, 0x06da, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
David Henningssonc04017e2015-12-15 14:44:03 +01006901 SND_PCI_QUIRK(0x1028, 0x06db, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
6902 SND_PCI_QUIRK(0x1028, 0x06dd, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
6903 SND_PCI_QUIRK(0x1028, 0x06de, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
6904 SND_PCI_QUIRK(0x1028, 0x06df, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
6905 SND_PCI_QUIRK(0x1028, 0x06e0, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
Kai-Heng Feng423cd782016-05-20 15:47:23 +08006906 SND_PCI_QUIRK(0x1028, 0x0704, "Dell XPS 13 9350", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE),
Kai-Heng Fengfd06c772016-08-30 15:36:34 +08006907 SND_PCI_QUIRK(0x1028, 0x0706, "Dell Inspiron 7559", ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER),
Kai-Heng Feng3b43b712016-02-25 15:19:38 +08006908 SND_PCI_QUIRK(0x1028, 0x0725, "Dell Inspiron 3162", ALC255_FIXUP_DELL_SPK_NOISE),
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01006909 SND_PCI_QUIRK(0x1028, 0x0738, "Dell Precision 5820", ALC269_FIXUP_NO_SHUTUP),
Kai-Heng Feng423cd782016-05-20 15:47:23 +08006910 SND_PCI_QUIRK(0x1028, 0x075b, "Dell XPS 13 9360", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE),
Kai-Heng Feng709ae622018-10-04 11:39:42 +08006911 SND_PCI_QUIRK(0x1028, 0x075c, "Dell XPS 27 7760", ALC298_FIXUP_SPK_VOLUME),
Hui Wangdd9aa332016-08-01 10:20:32 +08006912 SND_PCI_QUIRK(0x1028, 0x075d, "Dell AIO", ALC298_FIXUP_SPK_VOLUME),
Takashi Iwaie312a862018-03-06 12:14:17 +01006913 SND_PCI_QUIRK(0x1028, 0x07b0, "Dell Precision 7520", ALC295_FIXUP_DISABLE_DAC3),
Takashi Iwai493de342017-02-28 17:27:57 +01006914 SND_PCI_QUIRK(0x1028, 0x0798, "Dell Inspiron 17 7000 Gaming", ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER),
Kailang Yang5f364132017-07-25 16:28:16 +08006915 SND_PCI_QUIRK(0x1028, 0x080c, "Dell WYSE", ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE),
Takashi Iwaie4c9fd12018-01-10 08:34:28 +01006916 SND_PCI_QUIRK(0x1028, 0x082a, "Dell XPS 13 9360", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE),
Kailang Yang40e2c4e2018-02-02 15:13:09 +08006917 SND_PCI_QUIRK(0x1028, 0x084b, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB),
6918 SND_PCI_QUIRK(0x1028, 0x084e, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB),
Kailang Yangf0ba9d62018-03-16 11:46:08 +08006919 SND_PCI_QUIRK(0x1028, 0x0871, "Dell Precision 3630", ALC255_FIXUP_DELL_HEADSET_MIC),
6920 SND_PCI_QUIRK(0x1028, 0x0872, "Dell Precision 3630", ALC255_FIXUP_DELL_HEADSET_MIC),
Kailang Yangae104a22018-02-05 16:07:20 +08006921 SND_PCI_QUIRK(0x1028, 0x0873, "Dell Precision 3930", ALC255_FIXUP_DUMMY_LINEOUT_VERB),
Kailang Yang136824e2019-03-14 16:22:45 +08006922 SND_PCI_QUIRK(0x1028, 0x08ad, "Dell WYSE AIO", ALC225_FIXUP_DELL_WYSE_AIO_MIC_NO_PRESENCE),
Kailang Yangda484d02019-03-14 15:50:59 +08006923 SND_PCI_QUIRK(0x1028, 0x08ae, "Dell WYSE NB", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE),
Kailang Yangc2a7c55a2019-01-03 15:53:39 +08006924 SND_PCI_QUIRK(0x1028, 0x0935, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB),
Kailang Yanga22aa262014-04-23 17:34:28 +08006925 SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
6926 SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
Takashi Iwai08fb0d02013-01-10 17:33:58 +01006927 SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01006928 SND_PCI_QUIRK(0x103c, 0x18e6, "HP", ALC269_FIXUP_HP_GPIO_LED),
David Henningsson8e35cd42013-11-06 11:20:01 +01006929 SND_PCI_QUIRK(0x103c, 0x218b, "HP", ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED),
David Henningsson33f4acd2015-01-07 15:50:13 +01006930 SND_PCI_QUIRK(0x103c, 0x225f, "HP", ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY),
Kailang Yangc60666b2014-02-21 16:23:35 +08006931 /* ALC282 */
Hui Wang7976eb42015-02-13 11:14:41 +08006932 SND_PCI_QUIRK(0x103c, 0x21f9, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang8a02b162014-06-13 17:16:31 +08006933 SND_PCI_QUIRK(0x103c, 0x2210, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang8a02b162014-06-13 17:16:31 +08006934 SND_PCI_QUIRK(0x103c, 0x2214, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08006935 SND_PCI_QUIRK(0x103c, 0x2236, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
6936 SND_PCI_QUIRK(0x103c, 0x2237, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
6937 SND_PCI_QUIRK(0x103c, 0x2238, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
6938 SND_PCI_QUIRK(0x103c, 0x2239, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08006939 SND_PCI_QUIRK(0x103c, 0x224b, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
Kailang Yangc60666b2014-02-21 16:23:35 +08006940 SND_PCI_QUIRK(0x103c, 0x2268, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08006941 SND_PCI_QUIRK(0x103c, 0x226a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
6942 SND_PCI_QUIRK(0x103c, 0x226b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang8a02b162014-06-13 17:16:31 +08006943 SND_PCI_QUIRK(0x103c, 0x226e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangeaa8e5e2014-11-21 15:49:11 +08006944 SND_PCI_QUIRK(0x103c, 0x2271, "HP", ALC286_FIXUP_HP_GPIO_LED),
TienFu Chenb4b33f92015-01-20 15:06:21 +01006945 SND_PCI_QUIRK(0x103c, 0x2272, "HP", ALC280_FIXUP_HP_DOCK_PINS),
TienFu Chen3271cb22015-02-10 09:09:41 +01006946 SND_PCI_QUIRK(0x103c, 0x2273, "HP", ALC280_FIXUP_HP_DOCK_PINS),
Kailang Yangc60666b2014-02-21 16:23:35 +08006947 SND_PCI_QUIRK(0x103c, 0x229e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08006948 SND_PCI_QUIRK(0x103c, 0x22b2, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
6949 SND_PCI_QUIRK(0x103c, 0x22b7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
6950 SND_PCI_QUIRK(0x103c, 0x22bf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08006951 SND_PCI_QUIRK(0x103c, 0x22cf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Keith Packard98973f22015-07-15 12:14:39 -07006952 SND_PCI_QUIRK(0x103c, 0x22db, "HP", ALC280_FIXUP_HP_9480M),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08006953 SND_PCI_QUIRK(0x103c, 0x22dc, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
6954 SND_PCI_QUIRK(0x103c, 0x22fb, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yangc60666b2014-02-21 16:23:35 +08006955 /* ALC290 */
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08006956 SND_PCI_QUIRK(0x103c, 0x221b, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08006957 SND_PCI_QUIRK(0x103c, 0x2221, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08006958 SND_PCI_QUIRK(0x103c, 0x2225, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08006959 SND_PCI_QUIRK(0x103c, 0x2253, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
6960 SND_PCI_QUIRK(0x103c, 0x2254, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
6961 SND_PCI_QUIRK(0x103c, 0x2255, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
6962 SND_PCI_QUIRK(0x103c, 0x2256, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
6963 SND_PCI_QUIRK(0x103c, 0x2257, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08006964 SND_PCI_QUIRK(0x103c, 0x2259, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Jaroslav Kysela04d54662017-03-09 13:29:13 +01006965 SND_PCI_QUIRK(0x103c, 0x225a, "HP", ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED),
Kailang Yangc60666b2014-02-21 16:23:35 +08006966 SND_PCI_QUIRK(0x103c, 0x2260, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08006967 SND_PCI_QUIRK(0x103c, 0x2263, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
6968 SND_PCI_QUIRK(0x103c, 0x2264, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
6969 SND_PCI_QUIRK(0x103c, 0x2265, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08006970 SND_PCI_QUIRK(0x103c, 0x2272, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
6971 SND_PCI_QUIRK(0x103c, 0x2273, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08006972 SND_PCI_QUIRK(0x103c, 0x2278, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yangc60666b2014-02-21 16:23:35 +08006973 SND_PCI_QUIRK(0x103c, 0x227f, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08006974 SND_PCI_QUIRK(0x103c, 0x2282, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08006975 SND_PCI_QUIRK(0x103c, 0x228b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08006976 SND_PCI_QUIRK(0x103c, 0x228e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
6977 SND_PCI_QUIRK(0x103c, 0x22c5, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08006978 SND_PCI_QUIRK(0x103c, 0x22c7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
6979 SND_PCI_QUIRK(0x103c, 0x22c8, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08006980 SND_PCI_QUIRK(0x103c, 0x22c4, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang8a02b162014-06-13 17:16:31 +08006981 SND_PCI_QUIRK(0x103c, 0x2334, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
6982 SND_PCI_QUIRK(0x103c, 0x2335, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
6983 SND_PCI_QUIRK(0x103c, 0x2336, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
6984 SND_PCI_QUIRK(0x103c, 0x2337, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Takashi Iwaif8839822016-02-25 14:31:59 +01006985 SND_PCI_QUIRK(0x103c, 0x221c, "HP EliteBook 755 G2", ALC280_FIXUP_HP_HEADSET_MIC),
Jaroslav Kysela167897f2019-03-13 13:40:15 +01006986 SND_PCI_QUIRK(0x103c, 0x802e, "HP Z240 SFF", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
6987 SND_PCI_QUIRK(0x103c, 0x802f, "HP Z240", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
Takashi Iwai563785e2018-11-12 09:43:12 +01006988 SND_PCI_QUIRK(0x103c, 0x820d, "HP Pavilion 15", ALC269_FIXUP_HP_MUTE_LED_MIC3),
Hui Wange549d192016-04-01 11:00:15 +08006989 SND_PCI_QUIRK(0x103c, 0x8256, "HP", ALC221_FIXUP_HP_FRONT_MIC),
Tom Bridenbbf8ff62018-05-29 17:34:20 +01006990 SND_PCI_QUIRK(0x103c, 0x827e, "HP x360", ALC295_FIXUP_HP_X360),
Jaroslav Kysela167897f2019-03-13 13:40:15 +01006991 SND_PCI_QUIRK(0x103c, 0x82bf, "HP G3 mini", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
6992 SND_PCI_QUIRK(0x103c, 0x82c0, "HP G3 mini premium", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
Alexandru Gagniuc56e40eb2018-08-04 11:44:44 -05006993 SND_PCI_QUIRK(0x103c, 0x83b9, "HP Spectre x360", ALC269_FIXUP_HP_MUTE_LED_MIC3),
Takashi Iwai190d0382019-08-13 17:39:56 +02006994 SND_PCI_QUIRK(0x103c, 0x8497, "HP Envy x360", ALC269_FIXUP_HP_MUTE_LED_MIC3),
Sam Bazleyd33cd422019-09-01 03:31:30 +01006995 SND_PCI_QUIRK(0x103c, 0x84e7, "HP Pavilion 15", ALC269_FIXUP_HP_MUTE_LED_MIC3),
Chris Chiuc1732ed2017-02-28 14:17:13 -06006996 SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC),
Takashi Iwai7bba2152013-09-06 15:45:38 +02006997 SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300),
David Henningsson3e0d6112013-04-22 14:30:14 +02006998 SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Wandrille RONCE9cf65332018-12-19 14:52:44 +01006999 SND_PCI_QUIRK(0x1043, 0x10a1, "ASUS UX391UA", ALC294_FIXUP_ASUS_SPK),
Chris Chiuc1732ed2017-02-28 14:17:13 -06007000 SND_PCI_QUIRK(0x1043, 0x10c0, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC),
Takashi Iwai4eab0ea2017-06-06 12:33:17 +02007001 SND_PCI_QUIRK(0x1043, 0x10d0, "ASUS X540LA/X540LJ", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
David Henningsson3e0d6112013-04-22 14:30:14 +02007002 SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Takashi Iwai4eab0ea2017-06-06 12:33:17 +02007003 SND_PCI_QUIRK(0x1043, 0x11c0, "ASUS X556UR", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
7004 SND_PCI_QUIRK(0x1043, 0x1290, "ASUS X441SA", ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE),
7005 SND_PCI_QUIRK(0x1043, 0x12a0, "ASUS X441UV", ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE),
Chris Chiuc1732ed2017-02-28 14:17:13 -06007006 SND_PCI_QUIRK(0x1043, 0x12f0, "ASUS X541UV", ALC256_FIXUP_ASUS_MIC),
7007 SND_PCI_QUIRK(0x1043, 0x12e0, "ASUS X541SA", ALC256_FIXUP_ASUS_MIC),
7008 SND_PCI_QUIRK(0x1043, 0x13b0, "ASUS Z550SA", ALC256_FIXUP_ASUS_MIC),
Oleksij Rempel2cede302013-11-27 17:12:03 +01007009 SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK),
Takashi Iwai23870832013-11-29 14:13:12 +01007010 SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A),
David Henningsson3e0d6112013-04-22 14:30:14 +02007011 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC),
Jian-Hong Pan60083f92019-09-02 18:00:56 +08007012 SND_PCI_QUIRK(0x1043, 0x17d1, "ASUS UX431FL", ALC294_FIXUP_ASUS_INTSPK_HEADSET_MIC),
Takashi Iwai017f2a12011-07-09 14:42:25 +02007013 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
Chris Chiu28e8af82017-06-05 15:05:30 -06007014 SND_PCI_QUIRK(0x1043, 0x1a30, "ASUS X705UD", ALC256_FIXUP_ASUS_MIC),
David Henningsson693b6132012-06-22 19:12:10 +02007015 SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC),
Chris Chiu615966a2017-02-28 14:17:12 -06007016 SND_PCI_QUIRK(0x1043, 0x1bbd, "ASUS Z550MA", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
Takashi Iwai4eab0ea2017-06-06 12:33:17 +02007017 SND_PCI_QUIRK(0x1043, 0x1c23, "Asus X55U", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Chris Chiuc1732ed2017-02-28 14:17:13 -06007018 SND_PCI_QUIRK(0x1043, 0x1ccd, "ASUS X555UB", ALC256_FIXUP_ASUS_MIC),
Chris Chiueeed4cd2017-02-28 14:17:15 -06007019 SND_PCI_QUIRK(0x1043, 0x3030, "ASUS ZN270IE", ALC256_FIXUP_ASUS_AIO_GPIO2),
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02007020 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC),
7021 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC),
7022 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
7023 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
David Henningssond240d1d2013-04-15 12:50:02 +02007024 SND_PCI_QUIRK(0x1043, 0x8516, "ASUS X101CH", ALC269_FIXUP_ASUS_X101),
Takashi Iwaif88abaa2014-02-07 12:07:59 +01007025 SND_PCI_QUIRK(0x104d, 0x90b5, "Sony VAIO Pro 11", ALC286_FIXUP_SONY_MIC_NO_PRESENCE),
David Henningsson88cfcf82013-10-11 10:18:45 +02007026 SND_PCI_QUIRK(0x104d, 0x90b6, "Sony VAIO Pro 13", ALC286_FIXUP_SONY_MIC_NO_PRESENCE),
Takashi Iwai1d045db2011-07-07 18:23:21 +02007027 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
7028 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
7029 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
Takashi Iwaie9bd7d52014-05-21 11:06:49 +02007030 SND_PCI_QUIRK(0x104d, 0x9099, "Sony VAIO S13", ALC275_FIXUP_SONY_DISABLE_AAMIX),
Takashi Iwai24519912011-08-16 15:08:49 +02007031 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook", ALC269_FIXUP_LIFEBOOK),
Takashi Iwai4df3fd12015-06-29 08:38:02 +02007032 SND_PCI_QUIRK(0x10cf, 0x159f, "Lifebook E780", ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT),
Takashi Iwaicc7016a2015-04-08 20:47:55 +02007033 SND_PCI_QUIRK(0x10cf, 0x15dc, "Lifebook T731", ALC269_FIXUP_LIFEBOOK_HP_PIN),
Takashi Iwai88776f32015-05-01 09:20:34 +02007034 SND_PCI_QUIRK(0x10cf, 0x1757, "Lifebook E752", ALC269_FIXUP_LIFEBOOK_HP_PIN),
Jan-Marek Glogowskifdcc9682018-02-14 11:29:15 +01007035 SND_PCI_QUIRK(0x10cf, 0x1629, "Lifebook U7x7", ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC),
David Henningsson2041d562014-06-13 11:15:44 +02007036 SND_PCI_QUIRK(0x10cf, 0x1845, "Lifebook U904", ALC269_FIXUP_LIFEBOOK_EXTMIC),
PeiSen Houb84e8432017-09-01 15:11:56 +08007037 SND_PCI_QUIRK(0x10ec, 0x10f2, "Intel Reference board", ALC700_FIXUP_INTEL_REFERENCE),
YOKOTA Hiroshi0fca97a2018-07-01 18:30:01 +09007038 SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-SZ6", ALC269_FIXUP_HEADSET_MODE),
David Henningssona33cc482014-10-07 10:18:41 +02007039 SND_PCI_QUIRK(0x144d, 0xc109, "Samsung Ativ book 9 (NP900X3G)", ALC269_FIXUP_INV_DMIC),
Gabriele Mazzotta823ff162016-12-24 19:50:01 +01007040 SND_PCI_QUIRK(0x144d, 0xc740, "Samsung Ativ book 8 (NP870Z5G)", ALC269_FIXUP_ATIV_BOOK_8),
Anisse Astierabaa22742016-08-24 09:14:13 +02007041 SND_PCI_QUIRK(0x1458, 0xfa53, "Gigabyte BXBT-2807", ALC283_FIXUP_HEADSET_MIC),
7042 SND_PCI_QUIRK(0x1462, 0xb120, "MSI Cubi MS-B120", ALC283_FIXUP_HEADSET_MIC),
Anisse Astier8cd65272018-11-23 17:59:11 +01007043 SND_PCI_QUIRK(0x1462, 0xb171, "Cubi N 8GL (MS-B171)", ALC283_FIXUP_HEADSET_MIC),
Jeremy Soller89e3a562019-01-30 16:12:31 -07007044 SND_PCI_QUIRK(0x1558, 0x1325, "System76 Darter Pro (darp5)", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
Jeremy Soller80a50522019-05-07 17:11:08 -04007045 SND_PCI_QUIRK(0x1558, 0x8550, "System76 Gazelle (gaze14)", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
Jeremy Soller891afcf2019-05-10 10:15:07 -04007046 SND_PCI_QUIRK(0x1558, 0x8551, "System76 Gazelle (gaze14)", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
7047 SND_PCI_QUIRK(0x1558, 0x8560, "System76 Gazelle (gaze14)", ALC269_FIXUP_HEADSET_MIC),
7048 SND_PCI_QUIRK(0x1558, 0x8561, "System76 Gazelle (gaze14)", ALC269_FIXUP_HEADSET_MIC),
Kailang Yangca169cc2017-04-25 16:17:40 +08007049 SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC233_FIXUP_LENOVO_MULTI_CODECS),
Takashi Iwai1d045db2011-07-07 18:23:21 +02007050 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
7051 SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
7052 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
7053 SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
7054 SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
Takashi Iwai707fba32012-08-02 09:04:39 +02007055 SND_PCI_QUIRK(0x17aa, 0x21f6, "Thinkpad T530", ALC269_FIXUP_LENOVO_DOCK),
Felix Kaechelec8415a42012-08-06 23:02:01 +02007056 SND_PCI_QUIRK(0x17aa, 0x21fa, "Thinkpad X230", ALC269_FIXUP_LENOVO_DOCK),
Stefán Freyr84f98fd2012-10-19 22:46:00 +02007057 SND_PCI_QUIRK(0x17aa, 0x21f3, "Thinkpad T430", ALC269_FIXUP_LENOVO_DOCK),
Philipp A. Mohrenweiser4407be62012-08-06 13:14:18 +02007058 SND_PCI_QUIRK(0x17aa, 0x21fb, "Thinkpad T430s", ALC269_FIXUP_LENOVO_DOCK),
David Henningsson108cc102012-07-20 10:37:25 +02007059 SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK),
David Henningssonaaedfb42013-08-16 14:09:02 +02007060 SND_PCI_QUIRK(0x17aa, 0x2208, "Thinkpad T431s", ALC269_FIXUP_LENOVO_DOCK),
Takashi Iwai9a811232015-12-09 15:17:43 +01007061 SND_PCI_QUIRK(0x17aa, 0x220c, "Thinkpad T440s", ALC292_FIXUP_TPT440),
Takashi Iwai1c37c222014-05-06 17:34:42 +02007062 SND_PCI_QUIRK(0x17aa, 0x220e, "Thinkpad T440p", ALC292_FIXUP_TPT440_DOCK),
Takashi Iwaia12137e2014-06-27 12:14:35 +02007063 SND_PCI_QUIRK(0x17aa, 0x2210, "Thinkpad T540p", ALC292_FIXUP_TPT440_DOCK),
Rick Sherman59a51a62015-08-18 21:04:30 -05007064 SND_PCI_QUIRK(0x17aa, 0x2211, "Thinkpad W541", ALC292_FIXUP_TPT440_DOCK),
Takashi Iwai6d169412014-10-07 17:27:02 +02007065 SND_PCI_QUIRK(0x17aa, 0x2212, "Thinkpad T440", ALC292_FIXUP_TPT440_DOCK),
Lukas Bossard7c215392014-10-29 18:31:07 +01007066 SND_PCI_QUIRK(0x17aa, 0x2214, "Thinkpad X240", ALC292_FIXUP_TPT440_DOCK),
David Henningssona4a9e082013-08-16 14:09:01 +02007067 SND_PCI_QUIRK(0x17aa, 0x2215, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Takashi Iwaib6903c02015-12-10 12:20:20 +01007068 SND_PCI_QUIRK(0x17aa, 0x2218, "Thinkpad X1 Carbon 2nd", ALC292_FIXUP_TPT440_DOCK),
Laura Abbottd05ea7d2015-10-02 11:09:54 -07007069 SND_PCI_QUIRK(0x17aa, 0x2223, "ThinkPad T550", ALC292_FIXUP_TPT440_DOCK),
Yves-Alexis Perezc0278662015-04-11 09:31:35 +02007070 SND_PCI_QUIRK(0x17aa, 0x2226, "ThinkPad X250", ALC292_FIXUP_TPT440_DOCK),
Kailang Yang61fcf8e2018-02-02 15:26:46 +08007071 SND_PCI_QUIRK(0x17aa, 0x222d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7072 SND_PCI_QUIRK(0x17aa, 0x222e, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
Torsten Hilbrichdab38e42016-06-07 13:14:21 +02007073 SND_PCI_QUIRK(0x17aa, 0x2231, "Thinkpad T560", ALC292_FIXUP_TPT460),
Sven Eckelmannc636b952016-04-11 16:55:26 +02007074 SND_PCI_QUIRK(0x17aa, 0x2233, "Thinkpad", ALC292_FIXUP_TPT460),
Kailang Yang61fcf8e2018-02-02 15:26:46 +08007075 SND_PCI_QUIRK(0x17aa, 0x2245, "Thinkpad T470", ALC298_FIXUP_TPT470_DOCK),
7076 SND_PCI_QUIRK(0x17aa, 0x2246, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7077 SND_PCI_QUIRK(0x17aa, 0x2247, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
Dennis Wassenberge4c07b32018-03-08 13:17:54 +01007078 SND_PCI_QUIRK(0x17aa, 0x2249, "Thinkpad", ALC292_FIXUP_TPT460),
Kailang Yang61fcf8e2018-02-02 15:26:46 +08007079 SND_PCI_QUIRK(0x17aa, 0x224b, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7080 SND_PCI_QUIRK(0x17aa, 0x224c, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7081 SND_PCI_QUIRK(0x17aa, 0x224d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
Benjamin Berg85981df2018-02-14 13:29:39 +01007082 SND_PCI_QUIRK(0x17aa, 0x225d, "Thinkpad T480", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Kailang3694cb22015-12-28 11:35:24 +08007083 SND_PCI_QUIRK(0x17aa, 0x30bb, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
Hui Wang6ef2f682016-03-11 12:04:02 +08007084 SND_PCI_QUIRK(0x17aa, 0x30e2, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
Hui Wangf33f79f2017-07-07 12:08:29 +08007085 SND_PCI_QUIRK(0x17aa, 0x310c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
Dennis Wassenbergbef33e12019-06-28 10:54:53 +02007086 SND_PCI_QUIRK(0x17aa, 0x3111, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
Hui Wange41fc8c2018-06-25 14:40:56 +08007087 SND_PCI_QUIRK(0x17aa, 0x312a, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
Kailang Yang65811832018-04-25 17:07:27 +08007088 SND_PCI_QUIRK(0x17aa, 0x312f, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
Hui Wang8da5bbf2017-12-22 11:17:46 +08007089 SND_PCI_QUIRK(0x17aa, 0x313c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
Hui Wang2a36c162019-09-04 13:53:27 +08007090 SND_PCI_QUIRK(0x17aa, 0x3151, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC),
David Henningsson56f27012016-01-11 09:33:14 +01007091 SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
Takashi Iwaifedb2242014-11-13 07:11:38 +01007092 SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC),
Michał Wadowski56df90b2019-05-14 16:58:00 +02007093 SND_PCI_QUIRK(0x17aa, 0x3978, "Lenovo B50-70", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
David Henningssona4a9e082013-08-16 14:09:01 +02007094 SND_PCI_QUIRK(0x17aa, 0x5013, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Kailang Yang1bb3e062013-09-27 13:10:25 +02007095 SND_PCI_QUIRK(0x17aa, 0x501a, "Thinkpad", ALC283_FIXUP_INT_MIC),
Takashi Iwaic497d9f2014-10-08 12:14:40 +02007096 SND_PCI_QUIRK(0x17aa, 0x501e, "Thinkpad L440", ALC292_FIXUP_TPT440_DOCK),
David Henningssoncd5302c2013-08-19 12:22:33 +02007097 SND_PCI_QUIRK(0x17aa, 0x5026, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Jo-Philipp Wichf2aa1112015-04-13 12:47:26 +02007098 SND_PCI_QUIRK(0x17aa, 0x5034, "Thinkpad T450", ALC292_FIXUP_TPT440_DOCK),
Sebastian Wicki80b311d2015-03-23 17:23:11 +01007099 SND_PCI_QUIRK(0x17aa, 0x5036, "Thinkpad T450s", ALC292_FIXUP_TPT440_DOCK),
Ansgar Hegerfeld09ea9972015-05-14 12:31:32 +02007100 SND_PCI_QUIRK(0x17aa, 0x503c, "Thinkpad L450", ALC292_FIXUP_TPT440_DOCK),
Conrad Kostecki037e1192016-04-26 10:08:10 +02007101 SND_PCI_QUIRK(0x17aa, 0x504a, "ThinkPad X260", ALC292_FIXUP_TPT440_DOCK),
Hui Wang23adc192015-12-08 12:27:18 +08007102 SND_PCI_QUIRK(0x17aa, 0x504b, "Thinkpad", ALC293_FIXUP_LENOVO_SPK_NOISE),
Jaroslav Kysela0f087ee2016-06-24 15:13:16 +02007103 SND_PCI_QUIRK(0x17aa, 0x5050, "Thinkpad T560p", ALC292_FIXUP_TPT460),
Torsten Hilbrich9cd25742016-07-05 10:40:22 +02007104 SND_PCI_QUIRK(0x17aa, 0x5051, "Thinkpad L460", ALC292_FIXUP_TPT460),
Jaroslav Kysela0f087ee2016-06-24 15:13:16 +02007105 SND_PCI_QUIRK(0x17aa, 0x5053, "Thinkpad T460", ALC292_FIXUP_TPT460),
Kailang Yang61fcf8e2018-02-02 15:26:46 +08007106 SND_PCI_QUIRK(0x17aa, 0x505d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7107 SND_PCI_QUIRK(0x17aa, 0x505f, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7108 SND_PCI_QUIRK(0x17aa, 0x5062, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
David Henningssoncd5302c2013-08-19 12:22:33 +02007109 SND_PCI_QUIRK(0x17aa, 0x5109, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Kailang Yang61fcf8e2018-02-02 15:26:46 +08007110 SND_PCI_QUIRK(0x17aa, 0x511e, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7111 SND_PCI_QUIRK(0x17aa, 0x511f, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
David Henningsson012e7eb2012-08-08 08:43:37 +02007112 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K),
Takashi Iwai1d045db2011-07-07 18:23:21 +02007113 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
Ayman Bagabas0fbf21c2019-05-23 05:30:11 -04007114 SND_PCI_QUIRK(0x19e5, 0x3204, "Huawei MACH-WX9", ALC256_FIXUP_HUAWEI_MACH_WX9_PINS),
Anisse Astier02b504d2013-06-03 11:53:10 +02007115 SND_PCI_QUIRK(0x1b7d, 0xa831, "Ordissimo EVE2 ", ALC269VB_FIXUP_ORDISSIMO_EVE2), /* Also known as Malata PC-B1303 */
Takashi Iwaia4297b52011-08-23 18:40:12 +02007116
Takashi Iwaia7f3eed2012-02-16 13:03:18 +01007117#if 0
Takashi Iwaia4297b52011-08-23 18:40:12 +02007118 /* Below is a quirk table taken from the old code.
7119 * Basically the device should work as is without the fixup table.
7120 * If BIOS doesn't give a proper info, enable the corresponding
7121 * fixup entry.
Jesper Juhl7d7eb9e2012-04-12 22:11:25 +02007122 */
Takashi Iwaia4297b52011-08-23 18:40:12 +02007123 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
7124 ALC269_FIXUP_AMIC),
7125 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269_FIXUP_AMIC),
Takashi Iwaia4297b52011-08-23 18:40:12 +02007126 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269_FIXUP_AMIC),
7127 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_FIXUP_AMIC),
7128 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269_FIXUP_AMIC),
7129 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269_FIXUP_AMIC),
7130 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269_FIXUP_AMIC),
7131 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269_FIXUP_AMIC),
7132 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_FIXUP_AMIC),
7133 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269_FIXUP_AMIC),
7134 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_FIXUP_AMIC),
7135 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_FIXUP_AMIC),
7136 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_FIXUP_AMIC),
7137 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_FIXUP_AMIC),
7138 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_FIXUP_AMIC),
7139 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_FIXUP_AMIC),
7140 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_FIXUP_AMIC),
7141 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_FIXUP_AMIC),
7142 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_FIXUP_AMIC),
7143 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_FIXUP_AMIC),
7144 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_FIXUP_AMIC),
7145 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_FIXUP_AMIC),
7146 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_FIXUP_AMIC),
7147 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_FIXUP_AMIC),
7148 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_FIXUP_AMIC),
7149 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_FIXUP_AMIC),
7150 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_FIXUP_AMIC),
7151 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_FIXUP_AMIC),
7152 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_FIXUP_AMIC),
7153 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_FIXUP_AMIC),
7154 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_FIXUP_AMIC),
7155 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_FIXUP_AMIC),
7156 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_FIXUP_AMIC),
7157 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_FIXUP_AMIC),
7158 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_FIXUP_AMIC),
7159 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_FIXUP_DMIC),
7160 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_FIXUP_AMIC),
7161 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_AMIC),
7162 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_FIXUP_DMIC),
7163 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_FIXUP_DMIC),
7164#endif
7165 {}
7166};
7167
David Henningsson214eef72014-07-22 14:09:35 +02007168static const struct snd_pci_quirk alc269_fixup_vendor_tbl[] = {
7169 SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC),
7170 SND_PCI_QUIRK_VENDOR(0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED),
7171 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
7172 SND_PCI_QUIRK_VENDOR(0x17aa, "Thinkpad", ALC269_FIXUP_THINKPAD_ACPI),
Ayman Bagabas0fbf21c2019-05-23 05:30:11 -04007173 SND_PCI_QUIRK_VENDOR(0x19e5, "Huawei Matebook", ALC255_FIXUP_MIC_MUTE_LED),
David Henningsson214eef72014-07-22 14:09:35 +02007174 {}
7175};
7176
Takashi Iwai1727a772013-01-10 09:52:52 +01007177static const struct hda_model_fixup alc269_fixup_models[] = {
Takashi Iwaia4297b52011-08-23 18:40:12 +02007178 {.id = ALC269_FIXUP_AMIC, .name = "laptop-amic"},
7179 {.id = ALC269_FIXUP_DMIC, .name = "laptop-dmic"},
Takashi Iwai6e72aa52012-06-25 10:52:25 +02007180 {.id = ALC269_FIXUP_STEREO_DMIC, .name = "alc269-dmic"},
7181 {.id = ALC271_FIXUP_DMIC, .name = "alc271-dmic"},
7182 {.id = ALC269_FIXUP_INV_DMIC, .name = "inv-dmic"},
David Henningsson7c478f02013-10-11 10:18:46 +02007183 {.id = ALC269_FIXUP_HEADSET_MIC, .name = "headset-mic"},
Takashi Iwaib0169512015-05-19 10:20:13 +02007184 {.id = ALC269_FIXUP_HEADSET_MODE, .name = "headset-mode"},
7185 {.id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC, .name = "headset-mode-no-hp-mic"},
David Henningsson108cc102012-07-20 10:37:25 +02007186 {.id = ALC269_FIXUP_LENOVO_DOCK, .name = "lenovo-dock"},
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01007187 {.id = ALC269_FIXUP_HP_GPIO_LED, .name = "hp-gpio-led"},
Jaroslav Kysela04d54662017-03-09 13:29:13 +01007188 {.id = ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED, .name = "hp-dock-gpio-mic1-led"},
David Henningssone32aa852013-06-17 11:04:02 +02007189 {.id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "dell-headset-multi"},
7190 {.id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE, .name = "dell-headset-dock"},
Takashi Iwaia26d96c2018-06-26 15:09:25 +02007191 {.id = ALC269_FIXUP_DELL3_MIC_NO_PRESENCE, .name = "dell-headset3"},
7192 {.id = ALC269_FIXUP_DELL4_MIC_NO_PRESENCE, .name = "dell-headset4"},
Kailang Yangbe8ef162014-04-08 15:19:49 +08007193 {.id = ALC283_FIXUP_CHROME_BOOK, .name = "alc283-dac-wcaps"},
Kailang Yang0202e992013-12-02 15:20:15 +08007194 {.id = ALC283_FIXUP_SENSE_COMBO_JACK, .name = "alc283-sense-combo"},
Takashi Iwai1c37c222014-05-06 17:34:42 +02007195 {.id = ALC292_FIXUP_TPT440_DOCK, .name = "tpt440-dock"},
Takashi Iwai9a811232015-12-09 15:17:43 +01007196 {.id = ALC292_FIXUP_TPT440, .name = "tpt440"},
Sven Eckelmannc636b952016-04-11 16:55:26 +02007197 {.id = ALC292_FIXUP_TPT460, .name = "tpt460"},
Takashi Iwaia26d96c2018-06-26 15:09:25 +02007198 {.id = ALC298_FIXUP_TPT470_DOCK, .name = "tpt470-dock"},
Takashi Iwaiba90d6a2017-05-22 16:38:47 +02007199 {.id = ALC233_FIXUP_LENOVO_MULTI_CODECS, .name = "dual-codecs"},
Takashi Iwai28d1d6d2017-10-18 14:01:58 +02007200 {.id = ALC700_FIXUP_INTEL_REFERENCE, .name = "alc700-ref"},
Takashi Iwaia26d96c2018-06-26 15:09:25 +02007201 {.id = ALC269_FIXUP_SONY_VAIO, .name = "vaio"},
7202 {.id = ALC269_FIXUP_DELL_M101Z, .name = "dell-m101z"},
7203 {.id = ALC269_FIXUP_ASUS_G73JW, .name = "asus-g73jw"},
7204 {.id = ALC269_FIXUP_LENOVO_EAPD, .name = "lenovo-eapd"},
7205 {.id = ALC275_FIXUP_SONY_HWEQ, .name = "sony-hweq"},
7206 {.id = ALC269_FIXUP_PCM_44K, .name = "pcm44k"},
7207 {.id = ALC269_FIXUP_LIFEBOOK, .name = "lifebook"},
7208 {.id = ALC269_FIXUP_LIFEBOOK_EXTMIC, .name = "lifebook-extmic"},
7209 {.id = ALC269_FIXUP_LIFEBOOK_HP_PIN, .name = "lifebook-hp-pin"},
7210 {.id = ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC, .name = "lifebook-u7x7"},
7211 {.id = ALC269VB_FIXUP_AMIC, .name = "alc269vb-amic"},
7212 {.id = ALC269VB_FIXUP_DMIC, .name = "alc269vb-dmic"},
7213 {.id = ALC269_FIXUP_HP_MUTE_LED_MIC1, .name = "hp-mute-led-mic1"},
7214 {.id = ALC269_FIXUP_HP_MUTE_LED_MIC2, .name = "hp-mute-led-mic2"},
7215 {.id = ALC269_FIXUP_HP_MUTE_LED_MIC3, .name = "hp-mute-led-mic3"},
7216 {.id = ALC269_FIXUP_HP_GPIO_MIC1_LED, .name = "hp-gpio-mic1"},
7217 {.id = ALC269_FIXUP_HP_LINE1_MIC1_LED, .name = "hp-line1-mic1"},
7218 {.id = ALC269_FIXUP_NO_SHUTUP, .name = "noshutup"},
7219 {.id = ALC286_FIXUP_SONY_MIC_NO_PRESENCE, .name = "sony-nomic"},
7220 {.id = ALC269_FIXUP_ASPIRE_HEADSET_MIC, .name = "aspire-headset-mic"},
7221 {.id = ALC269_FIXUP_ASUS_X101, .name = "asus-x101"},
7222 {.id = ALC271_FIXUP_HP_GATE_MIC_JACK, .name = "acer-ao7xx"},
7223 {.id = ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572, .name = "acer-aspire-e1"},
7224 {.id = ALC269_FIXUP_ACER_AC700, .name = "acer-ac700"},
7225 {.id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST, .name = "limit-mic-boost"},
7226 {.id = ALC269VB_FIXUP_ASUS_ZENBOOK, .name = "asus-zenbook"},
7227 {.id = ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A, .name = "asus-zenbook-ux31a"},
7228 {.id = ALC269VB_FIXUP_ORDISSIMO_EVE2, .name = "ordissimo"},
7229 {.id = ALC282_FIXUP_ASUS_TX300, .name = "asus-tx300"},
7230 {.id = ALC283_FIXUP_INT_MIC, .name = "alc283-int-mic"},
7231 {.id = ALC290_FIXUP_MONO_SPEAKERS_HSJACK, .name = "mono-speakers"},
7232 {.id = ALC290_FIXUP_SUBWOOFER_HSJACK, .name = "alc290-subwoofer"},
7233 {.id = ALC269_FIXUP_THINKPAD_ACPI, .name = "thinkpad"},
7234 {.id = ALC269_FIXUP_DMIC_THINKPAD_ACPI, .name = "dmic-thinkpad"},
7235 {.id = ALC255_FIXUP_ACER_MIC_NO_PRESENCE, .name = "alc255-acer"},
7236 {.id = ALC255_FIXUP_ASUS_MIC_NO_PRESENCE, .name = "alc255-asus"},
7237 {.id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc255-dell1"},
7238 {.id = ALC255_FIXUP_DELL2_MIC_NO_PRESENCE, .name = "alc255-dell2"},
7239 {.id = ALC293_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc293-dell1"},
7240 {.id = ALC283_FIXUP_HEADSET_MIC, .name = "alc283-headset"},
Takashi Iwaib3802782018-11-26 17:47:46 +01007241 {.id = ALC255_FIXUP_MIC_MUTE_LED, .name = "alc255-dell-mute"},
Takashi Iwaia26d96c2018-06-26 15:09:25 +02007242 {.id = ALC282_FIXUP_ASPIRE_V5_PINS, .name = "aspire-v5"},
7243 {.id = ALC280_FIXUP_HP_GPIO4, .name = "hp-gpio4"},
7244 {.id = ALC286_FIXUP_HP_GPIO_LED, .name = "hp-gpio-led"},
7245 {.id = ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY, .name = "hp-gpio2-hotkey"},
7246 {.id = ALC280_FIXUP_HP_DOCK_PINS, .name = "hp-dock-pins"},
7247 {.id = ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED, .name = "hp-dock-gpio-mic"},
7248 {.id = ALC280_FIXUP_HP_9480M, .name = "hp-9480m"},
7249 {.id = ALC288_FIXUP_DELL_HEADSET_MODE, .name = "alc288-dell-headset"},
7250 {.id = ALC288_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc288-dell1"},
7251 {.id = ALC288_FIXUP_DELL_XPS_13, .name = "alc288-dell-xps13"},
7252 {.id = ALC292_FIXUP_DELL_E7X, .name = "dell-e7x"},
7253 {.id = ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK, .name = "alc293-dell"},
7254 {.id = ALC298_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc298-dell1"},
7255 {.id = ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE, .name = "alc298-dell-aio"},
7256 {.id = ALC275_FIXUP_DELL_XPS, .name = "alc275-dell-xps"},
7257 {.id = ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE, .name = "alc256-dell-xps13"},
7258 {.id = ALC293_FIXUP_LENOVO_SPK_NOISE, .name = "lenovo-spk-noise"},
7259 {.id = ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY, .name = "lenovo-hotkey"},
7260 {.id = ALC255_FIXUP_DELL_SPK_NOISE, .name = "dell-spk-noise"},
Kailang Yang82aa0d72019-01-11 17:15:53 +08007261 {.id = ALC225_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc225-dell1"},
Takashi Iwaia26d96c2018-06-26 15:09:25 +02007262 {.id = ALC295_FIXUP_DISABLE_DAC3, .name = "alc295-disable-dac3"},
7263 {.id = ALC280_FIXUP_HP_HEADSET_MIC, .name = "alc280-hp-headset"},
7264 {.id = ALC221_FIXUP_HP_FRONT_MIC, .name = "alc221-hp-mic"},
7265 {.id = ALC298_FIXUP_SPK_VOLUME, .name = "alc298-spk-volume"},
7266 {.id = ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER, .name = "dell-inspiron-7559"},
7267 {.id = ALC269_FIXUP_ATIV_BOOK_8, .name = "ativ-book"},
7268 {.id = ALC221_FIXUP_HP_MIC_NO_PRESENCE, .name = "alc221-hp-mic"},
7269 {.id = ALC256_FIXUP_ASUS_HEADSET_MODE, .name = "alc256-asus-headset"},
7270 {.id = ALC256_FIXUP_ASUS_MIC, .name = "alc256-asus-mic"},
7271 {.id = ALC256_FIXUP_ASUS_AIO_GPIO2, .name = "alc256-asus-aio"},
7272 {.id = ALC233_FIXUP_ASUS_MIC_NO_PRESENCE, .name = "alc233-asus"},
7273 {.id = ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE, .name = "alc233-eapd"},
7274 {.id = ALC294_FIXUP_LENOVO_MIC_LOCATION, .name = "alc294-lenovo-mic"},
7275 {.id = ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE, .name = "alc225-wyse"},
7276 {.id = ALC274_FIXUP_DELL_AIO_LINEOUT_VERB, .name = "alc274-dell-aio"},
7277 {.id = ALC255_FIXUP_DUMMY_LINEOUT_VERB, .name = "alc255-dummy-lineout"},
7278 {.id = ALC255_FIXUP_DELL_HEADSET_MIC, .name = "alc255-dell-headset"},
7279 {.id = ALC295_FIXUP_HP_X360, .name = "alc295-hp-x360"},
Kailang Yang8983eb62019-04-03 15:31:49 +08007280 {.id = ALC225_FIXUP_HEADSET_JACK, .name = "alc-headset-jack"},
7281 {.id = ALC295_FIXUP_CHROME_BOOK, .name = "alc-chrome-book"},
Bernhard Rosenkraenzere2a829b2019-03-05 00:38:19 +01007282 {.id = ALC299_FIXUP_PREDATOR_SPK, .name = "predator-spk"},
Takashi Iwai1d045db2011-07-07 18:23:21 +02007283 {}
7284};
Kailang Yangcfc5a842016-02-03 15:20:39 +08007285#define ALC225_STANDARD_PINS \
Kailang Yangcfc5a842016-02-03 15:20:39 +08007286 {0x21, 0x04211020}
Takashi Iwai1d045db2011-07-07 18:23:21 +02007287
Hui Wange8191a82015-04-24 13:39:59 +08007288#define ALC256_STANDARD_PINS \
7289 {0x12, 0x90a60140}, \
7290 {0x14, 0x90170110}, \
Hui Wange8191a82015-04-24 13:39:59 +08007291 {0x21, 0x02211020}
7292
David Henningssonfea185e2014-09-03 10:23:04 +02007293#define ALC282_STANDARD_PINS \
Hui Wang11580292015-08-03 11:03:49 +08007294 {0x14, 0x90170110}
Kailang Yange1e62b92015-04-08 16:01:22 +08007295
David Henningssonfea185e2014-09-03 10:23:04 +02007296#define ALC290_STANDARD_PINS \
Hui Wang11580292015-08-03 11:03:49 +08007297 {0x12, 0x99a30130}
David Henningssonfea185e2014-09-03 10:23:04 +02007298
7299#define ALC292_STANDARD_PINS \
7300 {0x14, 0x90170110}, \
Hui Wang11580292015-08-03 11:03:49 +08007301 {0x15, 0x0221401f}
Kailang Yang977e6272015-05-18 15:31:20 +08007302
Hui Wang3f6409702016-09-11 11:26:16 +08007303#define ALC295_STANDARD_PINS \
7304 {0x12, 0xb7a60130}, \
7305 {0x14, 0x90170110}, \
Hui Wang3f6409702016-09-11 11:26:16 +08007306 {0x21, 0x04211020}
7307
Woodrow Shen703867e2015-08-05 12:34:12 +08007308#define ALC298_STANDARD_PINS \
7309 {0x12, 0x90a60130}, \
7310 {0x21, 0x03211020}
7311
Hui Wange1918932014-05-26 16:22:44 +08007312static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
Kailang Yang8a328ac2018-08-21 16:54:41 +08007313 SND_HDA_PIN_QUIRK(0x10ec0221, 0x103c, "HP Workstation", ALC221_FIXUP_HP_HEADSET_MIC,
7314 {0x14, 0x01014020},
7315 {0x17, 0x90170110},
7316 {0x18, 0x02a11030},
7317 {0x19, 0x0181303F},
7318 {0x21, 0x0221102f}),
Chris Chiu5824ce82017-02-28 14:17:11 -06007319 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1025, "Acer", ALC255_FIXUP_ACER_MIC_NO_PRESENCE,
7320 {0x12, 0x90a601c0},
7321 {0x14, 0x90171120},
7322 {0x21, 0x02211030}),
Chris Chiu615966a2017-02-28 14:17:12 -06007323 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1043, "ASUS", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE,
7324 {0x14, 0x90170110},
7325 {0x1b, 0x90a70130},
7326 {0x21, 0x03211020}),
7327 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1043, "ASUS", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE,
7328 {0x1a, 0x90a70130},
7329 {0x1b, 0x90170110},
7330 {0x21, 0x03211020}),
David Henningsson2ae95572016-02-25 09:37:05 +01007331 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
Kailang Yangcfc5a842016-02-03 15:20:39 +08007332 ALC225_STANDARD_PINS,
Hui Wang8a132092016-07-08 14:26:57 +08007333 {0x12, 0xb7a60130},
Kailang Yangcfc5a842016-02-03 15:20:39 +08007334 {0x14, 0x901701a0}),
David Henningsson2ae95572016-02-25 09:37:05 +01007335 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
Kailang Yangcfc5a842016-02-03 15:20:39 +08007336 ALC225_STANDARD_PINS,
Hui Wang8a132092016-07-08 14:26:57 +08007337 {0x12, 0xb7a60130},
Kailang Yangcfc5a842016-02-03 15:20:39 +08007338 {0x14, 0x901701b0}),
Hui Wang8a132092016-07-08 14:26:57 +08007339 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
7340 ALC225_STANDARD_PINS,
7341 {0x12, 0xb7a60150},
7342 {0x14, 0x901701a0}),
7343 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
7344 ALC225_STANDARD_PINS,
7345 {0x12, 0xb7a60150},
7346 {0x14, 0x901701b0}),
7347 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
7348 ALC225_STANDARD_PINS,
7349 {0x12, 0xb7a60130},
7350 {0x1b, 0x90170110}),
Kai-Heng Feng0ce48e12017-11-20 02:29:13 -05007351 SND_HDA_PIN_QUIRK(0x10ec0233, 0x8086, "Intel NUC Skull Canyon", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
7352 {0x1b, 0x01111010},
7353 {0x1e, 0x01451130},
7354 {0x21, 0x02211020}),
Hui Wang986376b2018-05-30 12:33:07 +08007355 SND_HDA_PIN_QUIRK(0x10ec0235, 0x17aa, "Lenovo", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY,
7356 {0x12, 0x90a60140},
7357 {0x14, 0x90170110},
7358 {0x19, 0x02a11030},
7359 {0x21, 0x02211020}),
Hui Wange41fc8c2018-06-25 14:40:56 +08007360 SND_HDA_PIN_QUIRK(0x10ec0235, 0x17aa, "Lenovo", ALC294_FIXUP_LENOVO_MIC_LOCATION,
7361 {0x14, 0x90170110},
7362 {0x19, 0x02a11030},
7363 {0x1a, 0x02a11040},
7364 {0x1b, 0x01014020},
7365 {0x21, 0x0221101f}),
Hui Wangc6b17f12018-07-06 15:14:11 +08007366 SND_HDA_PIN_QUIRK(0x10ec0235, 0x17aa, "Lenovo", ALC294_FIXUP_LENOVO_MIC_LOCATION,
7367 {0x14, 0x90170110},
Hui Wangd06fb562018-10-10 11:57:25 +08007368 {0x19, 0x02a11030},
7369 {0x1a, 0x02a11040},
7370 {0x1b, 0x01011020},
7371 {0x21, 0x0221101f}),
7372 SND_HDA_PIN_QUIRK(0x10ec0235, 0x17aa, "Lenovo", ALC294_FIXUP_LENOVO_MIC_LOCATION,
7373 {0x14, 0x90170110},
Hui Wangc6b17f12018-07-06 15:14:11 +08007374 {0x19, 0x02a11020},
7375 {0x1a, 0x02a11030},
7376 {0x21, 0x0221101f}),
Hui Wangf2657882017-10-24 16:53:34 +08007377 SND_HDA_PIN_QUIRK(0x10ec0236, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7378 {0x12, 0x90a60140},
7379 {0x14, 0x90170110},
7380 {0x21, 0x02211020}),
7381 SND_HDA_PIN_QUIRK(0x10ec0236, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7382 {0x12, 0x90a60140},
7383 {0x14, 0x90170150},
7384 {0x21, 0x02211020}),
Hui Wangb26e36b2019-04-17 16:10:32 +08007385 SND_HDA_PIN_QUIRK(0x10ec0236, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7386 {0x21, 0x02211020}),
Kailang Yang0a29c572019-04-24 16:34:25 +08007387 SND_HDA_PIN_QUIRK(0x10ec0236, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7388 {0x12, 0x40000000},
7389 {0x14, 0x90170110},
7390 {0x21, 0x02211020}),
Hui Wangc77900e2014-09-03 11:31:07 +08007391 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE,
Hui Wangc77900e2014-09-03 11:31:07 +08007392 {0x14, 0x90170110},
Hui Wangc77900e2014-09-03 11:31:07 +08007393 {0x21, 0x02211020}),
David Henningsson76c21322014-06-24 14:46:54 +02007394 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang86c72d12016-05-25 12:12:32 +08007395 {0x14, 0x90170130},
7396 {0x21, 0x02211040}),
7397 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningsson76c21322014-06-24 14:46:54 +02007398 {0x12, 0x90a60140},
7399 {0x14, 0x90170110},
David Henningsson76c21322014-06-24 14:46:54 +02007400 {0x21, 0x02211020}),
7401 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7402 {0x12, 0x90a60160},
7403 {0x14, 0x90170120},
David Henningsson76c21322014-06-24 14:46:54 +02007404 {0x21, 0x02211030}),
7405 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang392c9da2016-09-26 10:59:38 +08007406 {0x14, 0x90170110},
7407 {0x1b, 0x02011020},
7408 {0x21, 0x0221101f}),
7409 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang6aecd872016-10-20 14:03:33 +08007410 {0x14, 0x90170110},
7411 {0x1b, 0x01011020},
7412 {0x21, 0x0221101f}),
7413 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssoncba59972015-07-22 10:00:25 +02007414 {0x14, 0x90170130},
David Henningssoncba59972015-07-22 10:00:25 +02007415 {0x1b, 0x01014020},
David Henningssoncba59972015-07-22 10:00:25 +02007416 {0x21, 0x0221103f}),
7417 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang59ec4b52016-08-04 15:28:04 +08007418 {0x14, 0x90170130},
Hui Wang6aecd872016-10-20 14:03:33 +08007419 {0x1b, 0x01011020},
7420 {0x21, 0x0221103f}),
7421 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7422 {0x14, 0x90170130},
Hui Wang59ec4b52016-08-04 15:28:04 +08007423 {0x1b, 0x02011020},
7424 {0x21, 0x0221103f}),
7425 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Woodrow Shene9c28e12015-07-25 10:36:16 +08007426 {0x14, 0x90170150},
Woodrow Shene9c28e12015-07-25 10:36:16 +08007427 {0x1b, 0x02011020},
Woodrow Shene9c28e12015-07-25 10:36:16 +08007428 {0x21, 0x0221105f}),
7429 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Woodrow Shene9c28e12015-07-25 10:36:16 +08007430 {0x14, 0x90170110},
Woodrow Shene9c28e12015-07-25 10:36:16 +08007431 {0x1b, 0x01014020},
Woodrow Shene9c28e12015-07-25 10:36:16 +08007432 {0x21, 0x0221101f}),
7433 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningsson76c21322014-06-24 14:46:54 +02007434 {0x12, 0x90a60160},
7435 {0x14, 0x90170120},
7436 {0x17, 0x90170140},
David Henningsson76c21322014-06-24 14:46:54 +02007437 {0x21, 0x0321102f}),
7438 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7439 {0x12, 0x90a60160},
7440 {0x14, 0x90170130},
David Henningsson76c21322014-06-24 14:46:54 +02007441 {0x21, 0x02211040}),
7442 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7443 {0x12, 0x90a60160},
7444 {0x14, 0x90170140},
David Henningsson76c21322014-06-24 14:46:54 +02007445 {0x21, 0x02211050}),
7446 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7447 {0x12, 0x90a60170},
7448 {0x14, 0x90170120},
David Henningsson76c21322014-06-24 14:46:54 +02007449 {0x21, 0x02211030}),
7450 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7451 {0x12, 0x90a60170},
7452 {0x14, 0x90170130},
David Henningsson76c21322014-06-24 14:46:54 +02007453 {0x21, 0x02211040}),
Hui Wang70658b92015-03-06 14:03:57 +08007454 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang70658b92015-03-06 14:03:57 +08007455 {0x12, 0x90a60170},
Hui Wang0a1f90a2016-01-13 11:51:38 +08007456 {0x14, 0x90171130},
7457 {0x21, 0x02211040}),
7458 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7459 {0x12, 0x90a60170},
Hui Wang70658b92015-03-06 14:03:57 +08007460 {0x14, 0x90170140},
Hui Wang70658b92015-03-06 14:03:57 +08007461 {0x21, 0x02211050}),
David Henningsson9b5a4e32015-05-11 14:04:14 +02007462 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell Inspiron 5548", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningsson9b5a4e32015-05-11 14:04:14 +02007463 {0x12, 0x90a60180},
7464 {0x14, 0x90170130},
David Henningsson9b5a4e32015-05-11 14:04:14 +02007465 {0x21, 0x02211040}),
AceLan Kaof90d83b2016-06-03 14:45:25 +08007466 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell Inspiron 5565", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7467 {0x12, 0x90a60180},
7468 {0x14, 0x90170120},
7469 {0x21, 0x02211030}),
Hui Wang989dbe42016-11-23 16:05:38 +08007470 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7471 {0x1b, 0x01011020},
7472 {0x21, 0x02211010}),
Kailang Yang7081adf2015-03-30 17:05:37 +08007473 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang285d5dd2017-12-22 11:17:45 +08007474 {0x12, 0x90a60130},
7475 {0x14, 0x90170110},
7476 {0x1b, 0x01011020},
7477 {0x21, 0x0221101f}),
7478 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Kailang Yang81a12312015-05-28 16:48:22 +08007479 {0x12, 0x90a60160},
7480 {0x14, 0x90170120},
Kailang Yang81a12312015-05-28 16:48:22 +08007481 {0x21, 0x02211030}),
7482 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Woodrow Shenf83c3292016-06-24 15:58:34 +08007483 {0x12, 0x90a60170},
7484 {0x14, 0x90170120},
7485 {0x21, 0x02211030}),
Shrirang Bagul311042d2016-08-29 15:19:27 +08007486 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell Inspiron 5468", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7487 {0x12, 0x90a60180},
7488 {0x14, 0x90170120},
7489 {0x21, 0x02211030}),
Woodrow Shenf83c3292016-06-24 15:58:34 +08007490 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang3f6409702016-09-11 11:26:16 +08007491 {0x12, 0xb7a60130},
7492 {0x14, 0x90170110},
7493 {0x21, 0x02211020}),
David Henningssoncf51eb92014-10-30 08:26:02 +01007494 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang3f2f7c52018-01-29 14:23:15 +08007495 {0x12, 0x90a60130},
7496 {0x14, 0x90170110},
7497 {0x14, 0x01011020},
7498 {0x21, 0x0221101f}),
7499 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssoncf51eb92014-10-30 08:26:02 +01007500 ALC256_STANDARD_PINS),
Hui Wangb26e36b2019-04-17 16:10:32 +08007501 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7502 {0x14, 0x90170110},
7503 {0x1b, 0x01011020},
7504 {0x21, 0x0221101f}),
Chris Chiuc1732ed2017-02-28 14:17:13 -06007505 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC,
7506 {0x14, 0x90170110},
7507 {0x1b, 0x90a70130},
7508 {0x21, 0x04211020}),
7509 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC,
7510 {0x14, 0x90170110},
7511 {0x1b, 0x90a70130},
7512 {0x21, 0x03211020}),
Jian-Hong Pane1037352019-03-22 11:37:18 +08007513 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE,
Chris Chiua806ef12019-03-22 11:37:20 +08007514 {0x12, 0x90a60130},
7515 {0x14, 0x90170110},
7516 {0x21, 0x03211020}),
7517 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE,
Jian-Hong Pan6ac371a2019-03-22 11:37:22 +08007518 {0x12, 0x90a60130},
7519 {0x14, 0x90170110},
7520 {0x21, 0x04211020}),
7521 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE,
Jian-Hong Pane1037352019-03-22 11:37:18 +08007522 {0x1a, 0x90a70130},
7523 {0x1b, 0x90170110},
7524 {0x21, 0x03211020}),
Kailang Yang92266652017-12-14 15:28:58 +08007525 SND_HDA_PIN_QUIRK(0x10ec0274, 0x1028, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB,
Hui Wang75ee94b2017-11-09 08:48:08 +08007526 {0x12, 0xb7a60130},
7527 {0x13, 0xb8a61140},
7528 {0x16, 0x90170110},
7529 {0x21, 0x04211020}),
David Henningssoncf51eb92014-10-30 08:26:02 +01007530 SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC280_FIXUP_HP_GPIO4,
7531 {0x12, 0x90a60130},
7532 {0x14, 0x90170110},
7533 {0x15, 0x0421101f},
Hui Wang11580292015-08-03 11:03:49 +08007534 {0x1a, 0x04a11020}),
Hui Wang02796612014-09-03 11:31:11 +08007535 SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED,
7536 {0x12, 0x90a60140},
Hui Wang02796612014-09-03 11:31:11 +08007537 {0x14, 0x90170110},
7538 {0x15, 0x0421101f},
Hui Wang02796612014-09-03 11:31:11 +08007539 {0x18, 0x02811030},
Hui Wang02796612014-09-03 11:31:11 +08007540 {0x1a, 0x04a1103f},
Hui Wang11580292015-08-03 11:03:49 +08007541 {0x1b, 0x02011020}),
David Henningsson42304472014-07-22 11:42:17 +02007542 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP 15 Touchsmart", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007543 ALC282_STANDARD_PINS,
David Henningsson42304472014-07-22 11:42:17 +02007544 {0x12, 0x99a30130},
David Henningsson42304472014-07-22 11:42:17 +02007545 {0x19, 0x03a11020},
David Henningsson42304472014-07-22 11:42:17 +02007546 {0x21, 0x0321101f}),
Hui Wang2c609992014-09-03 11:31:08 +08007547 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007548 ALC282_STANDARD_PINS,
Hui Wang2c609992014-09-03 11:31:08 +08007549 {0x12, 0x99a30130},
Hui Wang2c609992014-09-03 11:31:08 +08007550 {0x19, 0x03a11020},
Hui Wang2c609992014-09-03 11:31:08 +08007551 {0x21, 0x03211040}),
7552 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007553 ALC282_STANDARD_PINS,
Hui Wang2c609992014-09-03 11:31:08 +08007554 {0x12, 0x99a30130},
Hui Wang2c609992014-09-03 11:31:08 +08007555 {0x19, 0x03a11030},
Hui Wang2c609992014-09-03 11:31:08 +08007556 {0x21, 0x03211020}),
7557 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007558 ALC282_STANDARD_PINS,
Hui Wang2c609992014-09-03 11:31:08 +08007559 {0x12, 0x99a30130},
Hui Wang2c609992014-09-03 11:31:08 +08007560 {0x19, 0x04a11020},
Hui Wang2c609992014-09-03 11:31:08 +08007561 {0x21, 0x0421101f}),
Hui Wang200afc02014-09-03 11:31:10 +08007562 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED,
David Henningssonaec856d2014-09-03 10:23:05 +02007563 ALC282_STANDARD_PINS,
Hui Wang200afc02014-09-03 11:31:10 +08007564 {0x12, 0x90a60140},
Hui Wang200afc02014-09-03 11:31:10 +08007565 {0x19, 0x04a11030},
Hui Wang200afc02014-09-03 11:31:10 +08007566 {0x21, 0x04211020}),
David Henningsson76c21322014-06-24 14:46:54 +02007567 SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007568 ALC282_STANDARD_PINS,
David Henningsson76c21322014-06-24 14:46:54 +02007569 {0x12, 0x90a60130},
David Henningsson76c21322014-06-24 14:46:54 +02007570 {0x21, 0x0321101f}),
7571 SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
7572 {0x12, 0x90a60160},
7573 {0x14, 0x90170120},
David Henningsson76c21322014-06-24 14:46:54 +02007574 {0x21, 0x02211030}),
Hui Wangbc262172014-09-03 11:31:05 +08007575 SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007576 ALC282_STANDARD_PINS,
Hui Wangbc262172014-09-03 11:31:05 +08007577 {0x12, 0x90a60130},
Hui Wangbc262172014-09-03 11:31:05 +08007578 {0x19, 0x03a11020},
Hui Wangbc262172014-09-03 11:31:05 +08007579 {0x21, 0x0321101f}),
Hui Wangc8c6ee62019-02-14 11:41:33 +08007580 SND_HDA_PIN_QUIRK(0x10ec0285, 0x17aa, "Lenovo", ALC285_FIXUP_LENOVO_PC_BEEP_IN_NOISE,
Hui Wangc4cfcf62018-11-26 14:17:16 +08007581 {0x12, 0x90a60130},
7582 {0x14, 0x90170110},
7583 {0x19, 0x04a11040},
7584 {0x21, 0x04211020}),
Chris Chiu33aaebd2018-12-05 14:48:53 +08007585 SND_HDA_PIN_QUIRK(0x10ec0286, 0x1025, "Acer", ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE,
7586 {0x12, 0x90a60130},
7587 {0x17, 0x90170110},
7588 {0x21, 0x02211020}),
Takashi Iwaid44a6862018-06-19 23:04:03 +02007589 SND_HDA_PIN_QUIRK(0x10ec0288, 0x1028, "Dell", ALC288_FIXUP_DELL1_MIC_NO_PRESENCE,
Kailang Yange1e62b92015-04-08 16:01:22 +08007590 {0x12, 0x90a60120},
Kailang Yange1e62b92015-04-08 16:01:22 +08007591 {0x14, 0x90170110},
Kailang Yange1e62b92015-04-08 16:01:22 +08007592 {0x21, 0x0321101f}),
Hui Wangd5078192018-03-02 13:05:36 +08007593 SND_HDA_PIN_QUIRK(0x10ec0289, 0x1028, "Dell", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
Hui Wang3f2f7c52018-01-29 14:23:15 +08007594 {0x12, 0xb7a60130},
7595 {0x14, 0x90170110},
7596 {0x21, 0x04211020}),
Hui Wange4442bc2014-09-03 11:31:09 +08007597 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007598 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08007599 {0x15, 0x04211040},
Hui Wange4442bc2014-09-03 11:31:09 +08007600 {0x18, 0x90170112},
Hui Wang11580292015-08-03 11:03:49 +08007601 {0x1a, 0x04a11020}),
Hui Wange4442bc2014-09-03 11:31:09 +08007602 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007603 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08007604 {0x15, 0x04211040},
Hui Wange4442bc2014-09-03 11:31:09 +08007605 {0x18, 0x90170110},
Hui Wang11580292015-08-03 11:03:49 +08007606 {0x1a, 0x04a11020}),
Hui Wange4442bc2014-09-03 11:31:09 +08007607 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007608 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08007609 {0x15, 0x0421101f},
Hui Wang11580292015-08-03 11:03:49 +08007610 {0x1a, 0x04a11020}),
Hui Wange4442bc2014-09-03 11:31:09 +08007611 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007612 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08007613 {0x15, 0x04211020},
Hui Wang11580292015-08-03 11:03:49 +08007614 {0x1a, 0x04a11040}),
Hui Wange4442bc2014-09-03 11:31:09 +08007615 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007616 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08007617 {0x14, 0x90170110},
7618 {0x15, 0x04211020},
Hui Wang11580292015-08-03 11:03:49 +08007619 {0x1a, 0x04a11040}),
Hui Wange4442bc2014-09-03 11:31:09 +08007620 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007621 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08007622 {0x14, 0x90170110},
7623 {0x15, 0x04211020},
Hui Wang11580292015-08-03 11:03:49 +08007624 {0x1a, 0x04a11020}),
Hui Wange4442bc2014-09-03 11:31:09 +08007625 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007626 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08007627 {0x14, 0x90170110},
7628 {0x15, 0x0421101f},
Hui Wang11580292015-08-03 11:03:49 +08007629 {0x1a, 0x04a11020}),
Hui Wange8818fa2014-09-03 11:31:04 +08007630 SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007631 ALC292_STANDARD_PINS,
Hui Wange8818fa2014-09-03 11:31:04 +08007632 {0x12, 0x90a60140},
Hui Wange8818fa2014-09-03 11:31:04 +08007633 {0x16, 0x01014020},
Hui Wang11580292015-08-03 11:03:49 +08007634 {0x19, 0x01a19030}),
Hui Wange8818fa2014-09-03 11:31:04 +08007635 SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007636 ALC292_STANDARD_PINS,
Hui Wange8818fa2014-09-03 11:31:04 +08007637 {0x12, 0x90a60140},
Hui Wange8818fa2014-09-03 11:31:04 +08007638 {0x16, 0x01014020},
7639 {0x18, 0x02a19031},
Hui Wang11580292015-08-03 11:03:49 +08007640 {0x19, 0x01a1903e}),
David Henningsson76c21322014-06-24 14:46:54 +02007641 SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007642 ALC292_STANDARD_PINS,
Hui Wang11580292015-08-03 11:03:49 +08007643 {0x12, 0x90a60140}),
David Henningsson76c21322014-06-24 14:46:54 +02007644 SND_HDA_PIN_QUIRK(0x10ec0293, 0x1028, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007645 ALC292_STANDARD_PINS,
David Henningsson76c21322014-06-24 14:46:54 +02007646 {0x13, 0x90a60140},
David Henningsson76c21322014-06-24 14:46:54 +02007647 {0x16, 0x21014020},
Hui Wang11580292015-08-03 11:03:49 +08007648 {0x19, 0x21a19030}),
David Henningssone03fdbd2014-06-27 08:41:59 +02007649 SND_HDA_PIN_QUIRK(0x10ec0293, 0x1028, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007650 ALC292_STANDARD_PINS,
Hui Wang11580292015-08-03 11:03:49 +08007651 {0x13, 0x90a60140}),
Chris Chiud8ae4582018-12-07 17:17:11 +08007652 SND_HDA_PIN_QUIRK(0x10ec0294, 0x1043, "ASUS", ALC294_FIXUP_ASUS_MIC,
7653 {0x14, 0x90170110},
7654 {0x1b, 0x90a70130},
7655 {0x21, 0x04211020}),
Jian-Hong Pan0bea4cc2018-12-07 17:17:13 +08007656 SND_HDA_PIN_QUIRK(0x10ec0294, 0x1043, "ASUS", ALC294_FIXUP_ASUS_SPK,
7657 {0x12, 0x90a60130},
7658 {0x17, 0x90170110},
Jian-Hong Pan8bb37a22019-02-21 17:00:18 +08007659 {0x21, 0x03211020}),
7660 SND_HDA_PIN_QUIRK(0x10ec0294, 0x1043, "ASUS", ALC294_FIXUP_ASUS_SPK,
7661 {0x12, 0x90a60130},
7662 {0x17, 0x90170110},
Jian-Hong Pan0bea4cc2018-12-07 17:17:13 +08007663 {0x21, 0x04211020}),
Takashi Iwai3887c262019-04-30 15:10:01 +02007664 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1043, "ASUS", ALC294_FIXUP_ASUS_SPK,
7665 {0x12, 0x90a60130},
7666 {0x17, 0x90170110},
7667 {0x21, 0x03211020}),
Kailang Yangfbc57122019-07-15 10:41:50 +08007668 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
Kailang Yang0a29c572019-04-24 16:34:25 +08007669 {0x14, 0x90170110},
7670 {0x21, 0x04211020}),
Kailang Yangfbc57122019-07-15 10:41:50 +08007671 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
7672 {0x14, 0x90170110},
7673 {0x21, 0x04211030}),
Hui Wang3f6409702016-09-11 11:26:16 +08007674 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wangf771d5b2016-10-18 10:59:09 +08007675 ALC295_STANDARD_PINS,
7676 {0x17, 0x21014020},
7677 {0x18, 0x21a19030}),
7678 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
7679 ALC295_STANDARD_PINS,
7680 {0x17, 0x21014040},
7681 {0x18, 0x21a19050}),
Hui Wang3f307832017-03-23 10:00:25 +08007682 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
7683 ALC295_STANDARD_PINS),
Kailang Yang977e6272015-05-18 15:31:20 +08007684 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
Woodrow Shen703867e2015-08-05 12:34:12 +08007685 ALC298_STANDARD_PINS,
Takashi Iwai9f502ff2015-08-05 12:09:45 +02007686 {0x17, 0x90170110}),
7687 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
7688 ALC298_STANDARD_PINS,
Woodrow Shen703867e2015-08-05 12:34:12 +08007689 {0x17, 0x90170140}),
7690 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
7691 ALC298_STANDARD_PINS,
Takashi Iwai9f502ff2015-08-05 12:09:45 +02007692 {0x17, 0x90170150}),
Kai-Heng Feng9f1bc2c42017-02-16 15:26:54 +08007693 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_SPK_VOLUME,
7694 {0x12, 0xb7a60140},
7695 {0x13, 0xb7a60150},
7696 {0x17, 0x90170110},
7697 {0x1a, 0x03011020},
7698 {0x21, 0x03211030}),
Kailang Yangfcc6c872017-06-29 15:21:27 +08007699 SND_HDA_PIN_QUIRK(0x10ec0299, 0x1028, "Dell", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
7700 ALC225_STANDARD_PINS,
7701 {0x12, 0xb7a60130},
Kailang Yangfcc6c872017-06-29 15:21:27 +08007702 {0x17, 0x90170110}),
Hui Wange1918932014-05-26 16:22:44 +08007703 {}
7704};
Takashi Iwai1d045db2011-07-07 18:23:21 +02007705
Takashi Iwai546bb672012-03-07 08:37:19 +01007706static void alc269_fill_coef(struct hda_codec *codec)
Takashi Iwai1d045db2011-07-07 18:23:21 +02007707{
Kailang Yang526af6e2012-03-07 08:25:20 +01007708 struct alc_spec *spec = codec->spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02007709 int val;
7710
Kailang Yang526af6e2012-03-07 08:25:20 +01007711 if (spec->codec_variant != ALC269_TYPE_ALC269VB)
Takashi Iwai546bb672012-03-07 08:37:19 +01007712 return;
Kailang Yang526af6e2012-03-07 08:25:20 +01007713
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007714 if ((alc_get_coef0(codec) & 0x00ff) < 0x015) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02007715 alc_write_coef_idx(codec, 0xf, 0x960b);
7716 alc_write_coef_idx(codec, 0xe, 0x8817);
7717 }
7718
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007719 if ((alc_get_coef0(codec) & 0x00ff) == 0x016) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02007720 alc_write_coef_idx(codec, 0xf, 0x960b);
7721 alc_write_coef_idx(codec, 0xe, 0x8814);
7722 }
7723
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007724 if ((alc_get_coef0(codec) & 0x00ff) == 0x017) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02007725 /* Power up output pin */
Takashi Iwai98b24882014-08-18 13:47:50 +02007726 alc_update_coef_idx(codec, 0x04, 0, 1<<11);
Takashi Iwai1d045db2011-07-07 18:23:21 +02007727 }
7728
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007729 if ((alc_get_coef0(codec) & 0x00ff) == 0x018) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02007730 val = alc_read_coef_idx(codec, 0xd);
Takashi Iwaif3ee07d2014-08-15 17:35:00 +02007731 if (val != -1 && (val & 0x0c00) >> 10 != 0x1) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02007732 /* Capless ramp up clock control */
7733 alc_write_coef_idx(codec, 0xd, val | (1<<10));
7734 }
7735 val = alc_read_coef_idx(codec, 0x17);
Takashi Iwaif3ee07d2014-08-15 17:35:00 +02007736 if (val != -1 && (val & 0x01c0) >> 6 != 0x4) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02007737 /* Class D power on reset */
7738 alc_write_coef_idx(codec, 0x17, val | (1<<7));
7739 }
7740 }
7741
Takashi Iwai98b24882014-08-18 13:47:50 +02007742 /* HP */
7743 alc_update_coef_idx(codec, 0x4, 0, 1<<11);
Takashi Iwai1d045db2011-07-07 18:23:21 +02007744}
7745
7746/*
7747 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02007748static int patch_alc269(struct hda_codec *codec)
7749{
7750 struct alc_spec *spec;
Takashi Iwai3de95172012-05-07 18:03:15 +02007751 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02007752
Takashi Iwai3de95172012-05-07 18:03:15 +02007753 err = alc_alloc_spec(codec, 0x0b);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007754 if (err < 0)
Takashi Iwai3de95172012-05-07 18:03:15 +02007755 return err;
7756
7757 spec = codec->spec;
Takashi Iwai08c189f2012-12-19 15:22:24 +01007758 spec->gen.shared_mic_vref_pin = 0x18;
Kailang Yang317d9312019-05-23 14:43:04 +08007759 codec->power_save_node = 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007760
Takashi Iwai225068a2015-05-29 10:42:14 +02007761#ifdef CONFIG_PM
7762 codec->patch_ops.suspend = alc269_suspend;
7763 codec->patch_ops.resume = alc269_resume;
7764#endif
Kailang Yangc2d6af52017-06-21 14:50:54 +08007765 spec->shutup = alc_default_shutup;
7766 spec->init_hook = alc_default_init;
Takashi Iwai225068a2015-05-29 10:42:14 +02007767
Takashi Iwai7639a062015-03-03 10:07:24 +01007768 switch (codec->core.vendor_id) {
Kailang Yang065380f2013-01-10 10:25:48 +01007769 case 0x10ec0269:
Takashi Iwai1d045db2011-07-07 18:23:21 +02007770 spec->codec_variant = ALC269_TYPE_ALC269VA;
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007771 switch (alc_get_coef0(codec) & 0x00f0) {
7772 case 0x0010:
Takashi Iwai5100cd02014-02-15 10:03:19 +01007773 if (codec->bus->pci &&
7774 codec->bus->pci->subsystem_vendor == 0x1025 &&
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007775 spec->cdefine.platform_type == 1)
Takashi Iwai20ca0c32011-10-17 16:00:35 +02007776 err = alc_codec_rename(codec, "ALC271X");
Takashi Iwai1d045db2011-07-07 18:23:21 +02007777 spec->codec_variant = ALC269_TYPE_ALC269VB;
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007778 break;
7779 case 0x0020:
Takashi Iwai5100cd02014-02-15 10:03:19 +01007780 if (codec->bus->pci &&
7781 codec->bus->pci->subsystem_vendor == 0x17aa &&
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007782 codec->bus->pci->subsystem_device == 0x21f3)
Takashi Iwai20ca0c32011-10-17 16:00:35 +02007783 err = alc_codec_rename(codec, "ALC3202");
Takashi Iwai1d045db2011-07-07 18:23:21 +02007784 spec->codec_variant = ALC269_TYPE_ALC269VC;
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007785 break;
Kailang Yangadcc70b2012-05-25 08:08:38 +02007786 case 0x0030:
7787 spec->codec_variant = ALC269_TYPE_ALC269VD;
7788 break;
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007789 default:
Takashi Iwai1d045db2011-07-07 18:23:21 +02007790 alc_fix_pll_init(codec, 0x20, 0x04, 15);
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007791 }
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007792 if (err < 0)
7793 goto error;
Kailang Yangc2d6af52017-06-21 14:50:54 +08007794 spec->shutup = alc269_shutup;
Takashi Iwai546bb672012-03-07 08:37:19 +01007795 spec->init_hook = alc269_fill_coef;
Takashi Iwai1d045db2011-07-07 18:23:21 +02007796 alc269_fill_coef(codec);
Kailang Yang065380f2013-01-10 10:25:48 +01007797 break;
7798
7799 case 0x10ec0280:
7800 case 0x10ec0290:
7801 spec->codec_variant = ALC269_TYPE_ALC280;
7802 break;
7803 case 0x10ec0282:
Kailang Yang065380f2013-01-10 10:25:48 +01007804 spec->codec_variant = ALC269_TYPE_ALC282;
Kailang Yang7b5c7a02014-03-18 16:15:54 +08007805 spec->shutup = alc282_shutup;
7806 spec->init_hook = alc282_init;
Kailang Yang065380f2013-01-10 10:25:48 +01007807 break;
Kailang Yang2af02be2013-08-22 10:03:50 +02007808 case 0x10ec0233:
7809 case 0x10ec0283:
7810 spec->codec_variant = ALC269_TYPE_ALC283;
7811 spec->shutup = alc283_shutup;
7812 spec->init_hook = alc283_init;
7813 break;
Kailang Yang065380f2013-01-10 10:25:48 +01007814 case 0x10ec0284:
7815 case 0x10ec0292:
7816 spec->codec_variant = ALC269_TYPE_ALC284;
7817 break;
Kailang Yang161ebf22013-10-24 11:36:33 +02007818 case 0x10ec0293:
Kailang Yang4731d5d2017-06-30 15:22:57 +08007819 spec->codec_variant = ALC269_TYPE_ALC293;
Kailang Yang161ebf22013-10-24 11:36:33 +02007820 break;
Kailang Yang7fc7d042013-04-25 11:04:43 +02007821 case 0x10ec0286:
Kailang Yang7c665932014-04-14 15:09:44 +08007822 case 0x10ec0288:
Kailang Yang7fc7d042013-04-25 11:04:43 +02007823 spec->codec_variant = ALC269_TYPE_ALC286;
7824 break;
Kailang Yang506b62c2014-12-18 17:07:44 +08007825 case 0x10ec0298:
7826 spec->codec_variant = ALC269_TYPE_ALC298;
7827 break;
Kailang Yangea04a1d2018-04-25 15:31:52 +08007828 case 0x10ec0235:
Kailang Yang1d04c9d2013-10-24 11:35:18 +02007829 case 0x10ec0255:
7830 spec->codec_variant = ALC269_TYPE_ALC255;
Kailang Yangab3b8e52018-04-25 16:05:27 +08007831 spec->shutup = alc256_shutup;
7832 spec->init_hook = alc256_init;
Kailang Yang1d04c9d2013-10-24 11:35:18 +02007833 break;
Kailang Yang736f20a2017-10-20 15:06:34 +08007834 case 0x10ec0236:
Kailang Yang4344aec2014-12-17 17:39:05 +08007835 case 0x10ec0256:
7836 spec->codec_variant = ALC269_TYPE_ALC256;
Kailang Yang4a219ef2017-06-16 16:54:35 +08007837 spec->shutup = alc256_shutup;
7838 spec->init_hook = alc256_init;
David Henningsson7d1b6e22015-04-21 10:48:46 +02007839 spec->gen.mixer_nid = 0; /* ALC256 does not have any loopback mixer path */
Kailang Yang4344aec2014-12-17 17:39:05 +08007840 break;
Kailang Yangf429e7e2017-12-05 15:38:24 +08007841 case 0x10ec0257:
7842 spec->codec_variant = ALC269_TYPE_ALC257;
Kailang Yang88d42b22018-03-14 16:08:57 +08007843 spec->shutup = alc256_shutup;
7844 spec->init_hook = alc256_init;
Kailang Yangf429e7e2017-12-05 15:38:24 +08007845 spec->gen.mixer_nid = 0;
7846 break;
Kailang Yang0a6f0602017-06-30 16:00:48 +08007847 case 0x10ec0215:
7848 case 0x10ec0285:
7849 case 0x10ec0289:
7850 spec->codec_variant = ALC269_TYPE_ALC215;
Kailang Yang1b6832be2018-01-17 15:32:03 +08007851 spec->shutup = alc225_shutup;
7852 spec->init_hook = alc225_init;
Kailang Yang0a6f0602017-06-30 16:00:48 +08007853 spec->gen.mixer_nid = 0;
7854 break;
Kailang Yang42314302016-02-03 15:03:50 +08007855 case 0x10ec0225:
Kailang Yang7d727862016-05-24 16:46:07 +08007856 case 0x10ec0295:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08007857 case 0x10ec0299:
Kailang Yang42314302016-02-03 15:03:50 +08007858 spec->codec_variant = ALC269_TYPE_ALC225;
Kailang Yangda911b12018-01-05 16:50:08 +08007859 spec->shutup = alc225_shutup;
7860 spec->init_hook = alc225_init;
Takashi Iwaic1350bf2017-12-27 09:03:45 +01007861 spec->gen.mixer_nid = 0; /* no loopback on ALC225, ALC295 and ALC299 */
Kailang Yang42314302016-02-03 15:03:50 +08007862 break;
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08007863 case 0x10ec0234:
7864 case 0x10ec0274:
7865 case 0x10ec0294:
7866 spec->codec_variant = ALC269_TYPE_ALC294;
Hui Wang532a7782017-06-26 12:30:32 +08007867 spec->gen.mixer_nid = 0; /* ALC2x4 does not have any loopback mixer path */
Kailang Yang71683c32017-06-20 16:33:50 +08007868 alc_update_coef_idx(codec, 0x6b, 0x0018, (1<<4) | (1<<3)); /* UAJ MIC Vref control by verb */
Kailang Yang693abe12019-01-29 15:38:21 +08007869 spec->init_hook = alc294_init;
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08007870 break;
Kailang Yang1078bef2018-11-08 16:36:15 +08007871 case 0x10ec0300:
7872 spec->codec_variant = ALC269_TYPE_ALC300;
7873 spec->gen.mixer_nid = 0; /* no loopback on ALC300 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02007874 break;
Kailang Yang6fbae352016-05-30 16:44:20 +08007875 case 0x10ec0700:
7876 case 0x10ec0701:
7877 case 0x10ec0703:
7878 spec->codec_variant = ALC269_TYPE_ALC700;
7879 spec->gen.mixer_nid = 0; /* ALC700 does not have any loopback mixer path */
Kailang Yang2d7fe612017-11-22 15:21:32 +08007880 alc_update_coef_idx(codec, 0x4a, 1 << 15, 0); /* Combo jack auto trigger control */
Kailang Yang693abe12019-01-29 15:38:21 +08007881 spec->init_hook = alc294_init;
Kailang Yang6fbae352016-05-30 16:44:20 +08007882 break;
7883
Takashi Iwai1d045db2011-07-07 18:23:21 +02007884 }
7885
Kailang Yangad60d502013-06-28 12:03:01 +02007886 if (snd_hda_codec_read(codec, 0x51, 0, AC_VERB_PARAMETERS, 0) == 0x10ec5505) {
Kailang Yang97a26572013-11-29 00:35:26 -05007887 spec->has_alc5505_dsp = 1;
Kailang Yangad60d502013-06-28 12:03:01 +02007888 spec->init_hook = alc5505_dsp_init;
7889 }
7890
Takashi Iwaic9af7532019-05-10 11:01:43 +02007891 alc_pre_init(codec);
7892
Takashi Iwaiefe55732018-06-15 11:55:02 +02007893 snd_hda_pick_fixup(codec, alc269_fixup_models,
7894 alc269_fixup_tbl, alc269_fixups);
7895 snd_hda_pick_pin_fixup(codec, alc269_pin_fixup_tbl, alc269_fixups);
7896 snd_hda_pick_fixup(codec, NULL, alc269_fixup_vendor_tbl,
7897 alc269_fixups);
7898 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
7899
7900 alc_auto_parse_customize_define(codec);
7901
7902 if (has_cdefine_beep(codec))
7903 spec->gen.beep_nid = 0x01;
7904
Takashi Iwaia4297b52011-08-23 18:40:12 +02007905 /* automatic parse from the BIOS config */
7906 err = alc269_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007907 if (err < 0)
7908 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02007909
Takashi Iwaifea80fa2018-06-20 12:52:46 +02007910 if (!spec->gen.no_analog && spec->gen.beep_nid && spec->gen.mixer_nid) {
7911 err = set_beep_amp(spec, spec->gen.mixer_nid, 0x04, HDA_INPUT);
7912 if (err < 0)
7913 goto error;
7914 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02007915
Takashi Iwai1727a772013-01-10 09:52:52 +01007916 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01007917
Takashi Iwai1d045db2011-07-07 18:23:21 +02007918 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007919
7920 error:
7921 alc_free(codec);
7922 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02007923}
7924
7925/*
7926 * ALC861
7927 */
7928
Takashi Iwai1d045db2011-07-07 18:23:21 +02007929static int alc861_parse_auto_config(struct hda_codec *codec)
7930{
Takashi Iwai1d045db2011-07-07 18:23:21 +02007931 static const hda_nid_t alc861_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02007932 static const hda_nid_t alc861_ssids[] = { 0x0e, 0x0f, 0x0b, 0 };
7933 return alc_parse_auto_config(codec, alc861_ignore, alc861_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02007934}
7935
Takashi Iwai1d045db2011-07-07 18:23:21 +02007936/* Pin config fixes */
7937enum {
Takashi Iwaie652f4c2012-02-13 11:56:25 +01007938 ALC861_FIXUP_FSC_AMILO_PI1505,
7939 ALC861_FIXUP_AMP_VREF_0F,
7940 ALC861_FIXUP_NO_JACK_DETECT,
7941 ALC861_FIXUP_ASUS_A6RP,
Takashi Iwai6ddf0fd2013-11-29 12:47:34 +01007942 ALC660_FIXUP_ASUS_W7J,
Takashi Iwai1d045db2011-07-07 18:23:21 +02007943};
7944
Takashi Iwai31150f22012-01-30 10:54:08 +01007945/* On some laptops, VREF of pin 0x0f is abused for controlling the main amp */
7946static void alc861_fixup_asus_amp_vref_0f(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01007947 const struct hda_fixup *fix, int action)
Takashi Iwai31150f22012-01-30 10:54:08 +01007948{
7949 struct alc_spec *spec = codec->spec;
7950 unsigned int val;
7951
Takashi Iwai1727a772013-01-10 09:52:52 +01007952 if (action != HDA_FIXUP_ACT_INIT)
Takashi Iwai31150f22012-01-30 10:54:08 +01007953 return;
Takashi Iwaid3f02d62013-01-10 10:12:22 +01007954 val = snd_hda_codec_get_pin_target(codec, 0x0f);
Takashi Iwai31150f22012-01-30 10:54:08 +01007955 if (!(val & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN)))
7956 val |= AC_PINCTL_IN_EN;
7957 val |= AC_PINCTL_VREF_50;
Takashi Iwaicdd03ce2012-04-20 12:34:50 +02007958 snd_hda_set_pin_ctl(codec, 0x0f, val);
Takashi Iwai08c189f2012-12-19 15:22:24 +01007959 spec->gen.keep_vref_in_automute = 1;
Takashi Iwai31150f22012-01-30 10:54:08 +01007960}
7961
Takashi Iwaie652f4c2012-02-13 11:56:25 +01007962/* suppress the jack-detection */
7963static void alc_fixup_no_jack_detect(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01007964 const struct hda_fixup *fix, int action)
Takashi Iwaie652f4c2012-02-13 11:56:25 +01007965{
Takashi Iwai1727a772013-01-10 09:52:52 +01007966 if (action == HDA_FIXUP_ACT_PRE_PROBE)
Takashi Iwaie652f4c2012-02-13 11:56:25 +01007967 codec->no_jack_detect = 1;
Jesper Juhl7d7eb9e2012-04-12 22:11:25 +02007968}
Takashi Iwaie652f4c2012-02-13 11:56:25 +01007969
Takashi Iwai1727a772013-01-10 09:52:52 +01007970static const struct hda_fixup alc861_fixups[] = {
Takashi Iwaie652f4c2012-02-13 11:56:25 +01007971 [ALC861_FIXUP_FSC_AMILO_PI1505] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01007972 .type = HDA_FIXUP_PINS,
7973 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02007974 { 0x0b, 0x0221101f }, /* HP */
7975 { 0x0f, 0x90170310 }, /* speaker */
7976 { }
7977 }
7978 },
Takashi Iwaie652f4c2012-02-13 11:56:25 +01007979 [ALC861_FIXUP_AMP_VREF_0F] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01007980 .type = HDA_FIXUP_FUNC,
Takashi Iwai31150f22012-01-30 10:54:08 +01007981 .v.func = alc861_fixup_asus_amp_vref_0f,
Takashi Iwai3b25eb62012-01-25 09:55:46 +01007982 },
Takashi Iwaie652f4c2012-02-13 11:56:25 +01007983 [ALC861_FIXUP_NO_JACK_DETECT] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01007984 .type = HDA_FIXUP_FUNC,
Takashi Iwaie652f4c2012-02-13 11:56:25 +01007985 .v.func = alc_fixup_no_jack_detect,
7986 },
7987 [ALC861_FIXUP_ASUS_A6RP] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01007988 .type = HDA_FIXUP_FUNC,
Takashi Iwaie652f4c2012-02-13 11:56:25 +01007989 .v.func = alc861_fixup_asus_amp_vref_0f,
7990 .chained = true,
7991 .chain_id = ALC861_FIXUP_NO_JACK_DETECT,
Takashi Iwai6ddf0fd2013-11-29 12:47:34 +01007992 },
7993 [ALC660_FIXUP_ASUS_W7J] = {
7994 .type = HDA_FIXUP_VERBS,
7995 .v.verbs = (const struct hda_verb[]) {
7996 /* ASUS W7J needs a magic pin setup on unused NID 0x10
7997 * for enabling outputs
7998 */
7999 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8000 { }
8001 },
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008002 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02008003};
8004
8005static const struct snd_pci_quirk alc861_fixup_tbl[] = {
Takashi Iwai6ddf0fd2013-11-29 12:47:34 +01008006 SND_PCI_QUIRK(0x1043, 0x1253, "ASUS W7J", ALC660_FIXUP_ASUS_W7J),
Takashi Iwaie7ca2372013-12-02 15:27:19 +01008007 SND_PCI_QUIRK(0x1043, 0x1263, "ASUS Z35HL", ALC660_FIXUP_ASUS_W7J),
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008008 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS A6Rp", ALC861_FIXUP_ASUS_A6RP),
8009 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", ALC861_FIXUP_AMP_VREF_0F),
8010 SND_PCI_QUIRK(0x1462, 0x7254, "HP DX2200", ALC861_FIXUP_NO_JACK_DETECT),
8011 SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", ALC861_FIXUP_AMP_VREF_0F),
8012 SND_PCI_QUIRK(0x1584, 0x0000, "Uniwill ECS M31EI", ALC861_FIXUP_AMP_VREF_0F),
8013 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", ALC861_FIXUP_FSC_AMILO_PI1505),
Takashi Iwai1d045db2011-07-07 18:23:21 +02008014 {}
8015};
8016
8017/*
8018 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02008019static int patch_alc861(struct hda_codec *codec)
8020{
8021 struct alc_spec *spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008022 int err;
8023
Takashi Iwai3de95172012-05-07 18:03:15 +02008024 err = alc_alloc_spec(codec, 0x15);
8025 if (err < 0)
8026 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008027
Takashi Iwai3de95172012-05-07 18:03:15 +02008028 spec = codec->spec;
Takashi Iwai7504b6c2013-03-18 11:25:51 +01008029 spec->gen.beep_nid = 0x23;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008030
Takashi Iwai225068a2015-05-29 10:42:14 +02008031#ifdef CONFIG_PM
8032 spec->power_hook = alc_power_eapd;
8033#endif
8034
Takashi Iwaic9af7532019-05-10 11:01:43 +02008035 alc_pre_init(codec);
8036
Takashi Iwai1727a772013-01-10 09:52:52 +01008037 snd_hda_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
8038 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02008039
Takashi Iwaicb4e4822011-08-23 17:34:25 +02008040 /* automatic parse from the BIOS config */
8041 err = alc861_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008042 if (err < 0)
8043 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008044
Takashi Iwaifea80fa2018-06-20 12:52:46 +02008045 if (!spec->gen.no_analog) {
8046 err = set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
8047 if (err < 0)
8048 goto error;
8049 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02008050
Takashi Iwai1727a772013-01-10 09:52:52 +01008051 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01008052
Takashi Iwai1d045db2011-07-07 18:23:21 +02008053 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008054
8055 error:
8056 alc_free(codec);
8057 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008058}
8059
8060/*
8061 * ALC861-VD support
8062 *
8063 * Based on ALC882
8064 *
8065 * In addition, an independent DAC
8066 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02008067static int alc861vd_parse_auto_config(struct hda_codec *codec)
8068{
Takashi Iwai1d045db2011-07-07 18:23:21 +02008069 static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02008070 static const hda_nid_t alc861vd_ssids[] = { 0x15, 0x1b, 0x14, 0 };
8071 return alc_parse_auto_config(codec, alc861vd_ignore, alc861vd_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02008072}
8073
Takashi Iwai1d045db2011-07-07 18:23:21 +02008074enum {
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008075 ALC660VD_FIX_ASUS_GPIO1,
8076 ALC861VD_FIX_DALLAS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02008077};
8078
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008079/* exclude VREF80 */
8080static void alc861vd_fixup_dallas(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01008081 const struct hda_fixup *fix, int action)
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008082{
Takashi Iwai1727a772013-01-10 09:52:52 +01008083 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwaib78562b2012-12-17 20:06:49 +01008084 snd_hda_override_pin_caps(codec, 0x18, 0x00000734);
8085 snd_hda_override_pin_caps(codec, 0x19, 0x0000073c);
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008086 }
8087}
8088
Takashi Iwaidf73d832018-06-19 23:05:47 +02008089/* reset GPIO1 */
8090static void alc660vd_fixup_asus_gpio1(struct hda_codec *codec,
8091 const struct hda_fixup *fix, int action)
8092{
8093 struct alc_spec *spec = codec->spec;
8094
8095 if (action == HDA_FIXUP_ACT_PRE_PROBE)
8096 spec->gpio_mask |= 0x02;
8097 alc_fixup_gpio(codec, action, 0x01);
8098}
8099
Takashi Iwai1727a772013-01-10 09:52:52 +01008100static const struct hda_fixup alc861vd_fixups[] = {
Takashi Iwai1d045db2011-07-07 18:23:21 +02008101 [ALC660VD_FIX_ASUS_GPIO1] = {
Takashi Iwaidf73d832018-06-19 23:05:47 +02008102 .type = HDA_FIXUP_FUNC,
8103 .v.func = alc660vd_fixup_asus_gpio1,
Takashi Iwai1d045db2011-07-07 18:23:21 +02008104 },
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008105 [ALC861VD_FIX_DALLAS] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008106 .type = HDA_FIXUP_FUNC,
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008107 .v.func = alc861vd_fixup_dallas,
8108 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02008109};
8110
8111static const struct snd_pci_quirk alc861vd_fixup_tbl[] = {
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008112 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_FIX_DALLAS),
Takashi Iwai1d045db2011-07-07 18:23:21 +02008113 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008114 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_FIX_DALLAS),
Takashi Iwai1d045db2011-07-07 18:23:21 +02008115 {}
8116};
8117
Takashi Iwai1d045db2011-07-07 18:23:21 +02008118/*
8119 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02008120static int patch_alc861vd(struct hda_codec *codec)
8121{
8122 struct alc_spec *spec;
Takashi Iwaicb4e4822011-08-23 17:34:25 +02008123 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008124
Takashi Iwai3de95172012-05-07 18:03:15 +02008125 err = alc_alloc_spec(codec, 0x0b);
8126 if (err < 0)
8127 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008128
Takashi Iwai3de95172012-05-07 18:03:15 +02008129 spec = codec->spec;
Takashi Iwai7504b6c2013-03-18 11:25:51 +01008130 spec->gen.beep_nid = 0x23;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008131
Takashi Iwai225068a2015-05-29 10:42:14 +02008132 spec->shutup = alc_eapd_shutup;
8133
Takashi Iwaic9af7532019-05-10 11:01:43 +02008134 alc_pre_init(codec);
8135
Takashi Iwai1727a772013-01-10 09:52:52 +01008136 snd_hda_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
8137 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02008138
Takashi Iwaicb4e4822011-08-23 17:34:25 +02008139 /* automatic parse from the BIOS config */
8140 err = alc861vd_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008141 if (err < 0)
8142 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008143
Takashi Iwaifea80fa2018-06-20 12:52:46 +02008144 if (!spec->gen.no_analog) {
8145 err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
8146 if (err < 0)
8147 goto error;
8148 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02008149
Takashi Iwai1727a772013-01-10 09:52:52 +01008150 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01008151
Takashi Iwai1d045db2011-07-07 18:23:21 +02008152 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008153
8154 error:
8155 alc_free(codec);
8156 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008157}
8158
8159/*
8160 * ALC662 support
8161 *
8162 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
8163 * configuration. Each pin widget can choose any input DACs and a mixer.
8164 * Each ADC is connected from a mixer of all inputs. This makes possible
8165 * 6-channel independent captures.
8166 *
8167 * In addition, an independent DAC for the multi-playback (not used in this
8168 * driver yet).
8169 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02008170
8171/*
8172 * BIOS auto configuration
8173 */
8174
Kailang Yangbc9f98a2007-04-12 13:06:07 +02008175static int alc662_parse_auto_config(struct hda_codec *codec)
8176{
Takashi Iwai4c6d72d2011-05-02 11:30:18 +02008177 static const hda_nid_t alc662_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02008178 static const hda_nid_t alc663_ssids[] = { 0x15, 0x1b, 0x14, 0x21 };
8179 static const hda_nid_t alc662_ssids[] = { 0x15, 0x1b, 0x14, 0 };
8180 const hda_nid_t *ssids;
Takashi Iwaiee979a142008-09-02 15:42:20 +02008181
Takashi Iwai7639a062015-03-03 10:07:24 +01008182 if (codec->core.vendor_id == 0x10ec0272 || codec->core.vendor_id == 0x10ec0663 ||
8183 codec->core.vendor_id == 0x10ec0665 || codec->core.vendor_id == 0x10ec0670 ||
8184 codec->core.vendor_id == 0x10ec0671)
Takashi Iwai3e6179b2011-07-08 16:55:13 +02008185 ssids = alc663_ssids;
Kailang Yang6227cdc2010-02-25 08:36:52 +01008186 else
Takashi Iwai3e6179b2011-07-08 16:55:13 +02008187 ssids = alc662_ssids;
8188 return alc_parse_auto_config(codec, alc662_ignore, ssids);
Kailang Yangbc9f98a2007-04-12 13:06:07 +02008189}
8190
Todd Broch6be79482010-12-07 16:51:05 -08008191static void alc272_fixup_mario(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01008192 const struct hda_fixup *fix, int action)
Takashi Iwai6fc398c2011-01-13 14:36:37 +01008193{
Takashi Iwai9bb1f062013-01-10 17:14:29 +01008194 if (action != HDA_FIXUP_ACT_PRE_PROBE)
Takashi Iwai6fc398c2011-01-13 14:36:37 +01008195 return;
Todd Broch6be79482010-12-07 16:51:05 -08008196 if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT,
8197 (0x3b << AC_AMPCAP_OFFSET_SHIFT) |
8198 (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) |
8199 (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) |
8200 (0 << AC_AMPCAP_MUTE_SHIFT)))
Takashi Iwai4e76a882014-02-25 12:21:03 +01008201 codec_warn(codec, "failed to override amp caps for NID 0x2\n");
Todd Broch6be79482010-12-07 16:51:05 -08008202}
8203
Takashi Iwai8e383952013-10-30 17:41:12 +01008204static const struct snd_pcm_chmap_elem asus_pcm_2_1_chmaps[] = {
8205 { .channels = 2,
8206 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } },
8207 { .channels = 4,
8208 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR,
8209 SNDRV_CHMAP_NA, SNDRV_CHMAP_LFE } }, /* LFE only on right */
8210 { }
8211};
8212
8213/* override the 2.1 chmap */
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01008214static void alc_fixup_bass_chmap(struct hda_codec *codec,
Takashi Iwai8e383952013-10-30 17:41:12 +01008215 const struct hda_fixup *fix, int action)
8216{
8217 if (action == HDA_FIXUP_ACT_BUILD) {
8218 struct alc_spec *spec = codec->spec;
Takashi Iwaibbbc7e82015-02-27 17:43:19 +01008219 spec->gen.pcm_rec[0]->stream[0].chmap = asus_pcm_2_1_chmaps;
Takashi Iwai8e383952013-10-30 17:41:12 +01008220 }
8221}
8222
Takashi Iwaibf686652014-01-13 16:18:25 +01008223/* avoid D3 for keeping GPIO up */
8224static unsigned int gpio_led_power_filter(struct hda_codec *codec,
8225 hda_nid_t nid,
8226 unsigned int power_state)
8227{
8228 struct alc_spec *spec = codec->spec;
Takashi Iwaid261eec2018-06-19 22:32:29 +02008229 if (nid == codec->core.afg && power_state == AC_PWRST_D3 && spec->gpio_data)
Takashi Iwaibf686652014-01-13 16:18:25 +01008230 return AC_PWRST_D0;
8231 return power_state;
8232}
8233
Takashi Iwai3e887f32014-01-10 17:50:58 +01008234static void alc662_fixup_led_gpio1(struct hda_codec *codec,
8235 const struct hda_fixup *fix, int action)
8236{
8237 struct alc_spec *spec = codec->spec;
Takashi Iwai3e887f32014-01-10 17:50:58 +01008238
Takashi Iwai01e4a272018-06-19 22:47:30 +02008239 alc_fixup_hp_gpio_led(codec, action, 0x01, 0);
Takashi Iwai3e887f32014-01-10 17:50:58 +01008240 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai0f32fd192014-11-19 12:16:14 +01008241 spec->mute_led_polarity = 1;
Takashi Iwaibf686652014-01-13 16:18:25 +01008242 codec->power_filter = gpio_led_power_filter;
Takashi Iwai3e887f32014-01-10 17:50:58 +01008243 }
8244}
8245
Kailang Yangc6790c82016-11-25 16:15:17 +08008246static void alc662_usi_automute_hook(struct hda_codec *codec,
8247 struct hda_jack_callback *jack)
8248{
8249 struct alc_spec *spec = codec->spec;
8250 int vref;
8251 msleep(200);
8252 snd_hda_gen_hp_automute(codec, jack);
8253
8254 vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0;
8255 msleep(100);
8256 snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8257 vref);
8258}
8259
8260static void alc662_fixup_usi_headset_mic(struct hda_codec *codec,
8261 const struct hda_fixup *fix, int action)
8262{
8263 struct alc_spec *spec = codec->spec;
8264 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
8265 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
8266 spec->gen.hp_automute_hook = alc662_usi_automute_hook;
8267 }
8268}
8269
Kailang Yangf3f91852014-10-24 15:43:46 +08008270static struct coef_fw alc668_coefs[] = {
8271 WRITE_COEF(0x01, 0xbebe), WRITE_COEF(0x02, 0xaaaa), WRITE_COEF(0x03, 0x0),
8272 WRITE_COEF(0x04, 0x0180), WRITE_COEF(0x06, 0x0), WRITE_COEF(0x07, 0x0f80),
8273 WRITE_COEF(0x08, 0x0031), WRITE_COEF(0x0a, 0x0060), WRITE_COEF(0x0b, 0x0),
8274 WRITE_COEF(0x0c, 0x7cf7), WRITE_COEF(0x0d, 0x1080), WRITE_COEF(0x0e, 0x7f7f),
8275 WRITE_COEF(0x0f, 0xcccc), WRITE_COEF(0x10, 0xddcc), WRITE_COEF(0x11, 0x0001),
8276 WRITE_COEF(0x13, 0x0), WRITE_COEF(0x14, 0x2aa0), WRITE_COEF(0x17, 0xa940),
8277 WRITE_COEF(0x19, 0x0), WRITE_COEF(0x1a, 0x0), WRITE_COEF(0x1b, 0x0),
8278 WRITE_COEF(0x1c, 0x0), WRITE_COEF(0x1d, 0x0), WRITE_COEF(0x1e, 0x7418),
8279 WRITE_COEF(0x1f, 0x0804), WRITE_COEF(0x20, 0x4200), WRITE_COEF(0x21, 0x0468),
8280 WRITE_COEF(0x22, 0x8ccc), WRITE_COEF(0x23, 0x0250), WRITE_COEF(0x24, 0x7418),
8281 WRITE_COEF(0x27, 0x0), WRITE_COEF(0x28, 0x8ccc), WRITE_COEF(0x2a, 0xff00),
8282 WRITE_COEF(0x2b, 0x8000), WRITE_COEF(0xa7, 0xff00), WRITE_COEF(0xa8, 0x8000),
8283 WRITE_COEF(0xaa, 0x2e17), WRITE_COEF(0xab, 0xa0c0), WRITE_COEF(0xac, 0x0),
8284 WRITE_COEF(0xad, 0x0), WRITE_COEF(0xae, 0x2ac6), WRITE_COEF(0xaf, 0xa480),
8285 WRITE_COEF(0xb0, 0x0), WRITE_COEF(0xb1, 0x0), WRITE_COEF(0xb2, 0x0),
8286 WRITE_COEF(0xb3, 0x0), WRITE_COEF(0xb4, 0x0), WRITE_COEF(0xb5, 0x1040),
8287 WRITE_COEF(0xb6, 0xd697), WRITE_COEF(0xb7, 0x902b), WRITE_COEF(0xb8, 0xd697),
8288 WRITE_COEF(0xb9, 0x902b), WRITE_COEF(0xba, 0xb8ba), WRITE_COEF(0xbb, 0xaaab),
8289 WRITE_COEF(0xbc, 0xaaaf), WRITE_COEF(0xbd, 0x6aaa), WRITE_COEF(0xbe, 0x1c02),
8290 WRITE_COEF(0xc0, 0x00ff), WRITE_COEF(0xc1, 0x0fa6),
8291 {}
8292};
8293
8294static void alc668_restore_default_value(struct hda_codec *codec)
8295{
8296 alc_process_coef_fw(codec, alc668_coefs);
8297}
8298
David Henningsson6cb3b702010-09-09 08:51:44 +02008299enum {
Daniel T Chen2df03512010-10-10 22:39:28 -04008300 ALC662_FIXUP_ASPIRE,
Takashi Iwai3e887f32014-01-10 17:50:58 +01008301 ALC662_FIXUP_LED_GPIO1,
David Henningsson6cb3b702010-09-09 08:51:44 +02008302 ALC662_FIXUP_IDEAPAD,
Todd Broch6be79482010-12-07 16:51:05 -08008303 ALC272_FIXUP_MARIO,
Anisse Astierd2ebd472011-01-20 12:36:21 +01008304 ALC662_FIXUP_CZC_P10T,
David Henningsson94024cd2011-04-29 14:10:55 +02008305 ALC662_FIXUP_SKU_IGNORE,
Takashi Iwaie59ea3e2011-06-29 17:21:00 +02008306 ALC662_FIXUP_HP_RP5800,
Takashi Iwai53c334a2011-08-23 18:27:14 +02008307 ALC662_FIXUP_ASUS_MODE1,
8308 ALC662_FIXUP_ASUS_MODE2,
8309 ALC662_FIXUP_ASUS_MODE3,
8310 ALC662_FIXUP_ASUS_MODE4,
8311 ALC662_FIXUP_ASUS_MODE5,
8312 ALC662_FIXUP_ASUS_MODE6,
8313 ALC662_FIXUP_ASUS_MODE7,
8314 ALC662_FIXUP_ASUS_MODE8,
Takashi Iwai1565cc32012-02-13 12:03:25 +01008315 ALC662_FIXUP_NO_JACK_DETECT,
David Henningssonedfe3bf2012-06-12 13:15:12 +02008316 ALC662_FIXUP_ZOTAC_Z68,
Takashi Iwai125821a2012-06-22 14:30:29 +02008317 ALC662_FIXUP_INV_DMIC,
David Henningsson1f8b46c2015-05-12 14:38:15 +02008318 ALC662_FIXUP_DELL_MIC_NO_PRESENCE,
David Henningsson73bdd592013-04-15 15:44:14 +02008319 ALC668_FIXUP_DELL_MIC_NO_PRESENCE,
David Henningsson1f8b46c2015-05-12 14:38:15 +02008320 ALC662_FIXUP_HEADSET_MODE,
David Henningsson73bdd592013-04-15 15:44:14 +02008321 ALC668_FIXUP_HEADSET_MODE,
David Henningsson8e54b4a2014-02-07 09:31:07 +01008322 ALC662_FIXUP_BASS_MODE4_CHMAP,
David Henningsson61a75f12014-02-07 09:31:08 +01008323 ALC662_FIXUP_BASS_16,
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01008324 ALC662_FIXUP_BASS_1A,
David Henningsson8e54b4a2014-02-07 09:31:07 +01008325 ALC662_FIXUP_BASS_CHMAP,
Hui Wang493a52a2014-01-14 14:07:36 +08008326 ALC668_FIXUP_AUTO_MUTE,
Gabriele Mazzotta5e6db662014-05-20 18:58:26 +02008327 ALC668_FIXUP_DELL_DISABLE_AAMIX,
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02008328 ALC668_FIXUP_DELL_XPS13,
Bobi Mihalca9d4dc582016-03-23 13:26:11 +02008329 ALC662_FIXUP_ASUS_Nx50,
Mikhail Paulyshkafc7438b2017-04-21 08:52:42 +02008330 ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE,
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07008331 ALC668_FIXUP_ASUS_Nx51,
Takashi Iwai5b7c5e12018-10-09 14:20:17 +02008332 ALC668_FIXUP_MIC_COEF,
Takashi Iwai11ba6112018-10-07 09:44:17 +02008333 ALC668_FIXUP_ASUS_G751,
Kailang Yang78f4f7c2016-06-07 11:31:34 +08008334 ALC891_FIXUP_HEADSET_MODE,
8335 ALC891_FIXUP_DELL_MIC_NO_PRESENCE,
Shrirang Bagul9b51fe32016-08-01 13:16:17 +08008336 ALC662_FIXUP_ACER_VERITON,
Takashi Iwai1a3f0992016-10-20 12:14:51 +02008337 ALC892_FIXUP_ASROCK_MOBO,
Kailang Yangc6790c82016-11-25 16:15:17 +08008338 ALC662_FIXUP_USI_FUNC,
8339 ALC662_FIXUP_USI_HEADSET_MODE,
Kailang Yangca169cc2017-04-25 16:17:40 +08008340 ALC662_FIXUP_LENOVO_MULTI_CODECS,
David Henningsson6cb3b702010-09-09 08:51:44 +02008341};
8342
Takashi Iwai1727a772013-01-10 09:52:52 +01008343static const struct hda_fixup alc662_fixups[] = {
Daniel T Chen2df03512010-10-10 22:39:28 -04008344 [ALC662_FIXUP_ASPIRE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008345 .type = HDA_FIXUP_PINS,
8346 .v.pins = (const struct hda_pintbl[]) {
Daniel T Chen2df03512010-10-10 22:39:28 -04008347 { 0x15, 0x99130112 }, /* subwoofer */
8348 { }
8349 }
8350 },
Takashi Iwai3e887f32014-01-10 17:50:58 +01008351 [ALC662_FIXUP_LED_GPIO1] = {
8352 .type = HDA_FIXUP_FUNC,
8353 .v.func = alc662_fixup_led_gpio1,
8354 },
David Henningsson6cb3b702010-09-09 08:51:44 +02008355 [ALC662_FIXUP_IDEAPAD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008356 .type = HDA_FIXUP_PINS,
8357 .v.pins = (const struct hda_pintbl[]) {
David Henningsson6cb3b702010-09-09 08:51:44 +02008358 { 0x17, 0x99130112 }, /* subwoofer */
8359 { }
Takashi Iwai3e887f32014-01-10 17:50:58 +01008360 },
8361 .chained = true,
8362 .chain_id = ALC662_FIXUP_LED_GPIO1,
David Henningsson6cb3b702010-09-09 08:51:44 +02008363 },
Todd Broch6be79482010-12-07 16:51:05 -08008364 [ALC272_FIXUP_MARIO] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008365 .type = HDA_FIXUP_FUNC,
Takashi Iwaib5bfbc62011-01-13 14:22:32 +01008366 .v.func = alc272_fixup_mario,
Anisse Astierd2ebd472011-01-20 12:36:21 +01008367 },
8368 [ALC662_FIXUP_CZC_P10T] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008369 .type = HDA_FIXUP_VERBS,
Anisse Astierd2ebd472011-01-20 12:36:21 +01008370 .v.verbs = (const struct hda_verb[]) {
8371 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
8372 {}
8373 }
8374 },
David Henningsson94024cd2011-04-29 14:10:55 +02008375 [ALC662_FIXUP_SKU_IGNORE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008376 .type = HDA_FIXUP_FUNC,
Takashi Iwai23d30f22012-05-07 17:17:32 +02008377 .v.func = alc_fixup_sku_ignore,
Takashi Iwaic6b35872011-03-28 12:05:31 +02008378 },
Takashi Iwaie59ea3e2011-06-29 17:21:00 +02008379 [ALC662_FIXUP_HP_RP5800] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008380 .type = HDA_FIXUP_PINS,
8381 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaie59ea3e2011-06-29 17:21:00 +02008382 { 0x14, 0x0221201f }, /* HP out */
8383 { }
8384 },
8385 .chained = true,
8386 .chain_id = ALC662_FIXUP_SKU_IGNORE
8387 },
Takashi Iwai53c334a2011-08-23 18:27:14 +02008388 [ALC662_FIXUP_ASUS_MODE1] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008389 .type = HDA_FIXUP_PINS,
8390 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008391 { 0x14, 0x99130110 }, /* speaker */
8392 { 0x18, 0x01a19c20 }, /* mic */
8393 { 0x19, 0x99a3092f }, /* int-mic */
8394 { 0x21, 0x0121401f }, /* HP out */
8395 { }
8396 },
8397 .chained = true,
8398 .chain_id = ALC662_FIXUP_SKU_IGNORE
8399 },
8400 [ALC662_FIXUP_ASUS_MODE2] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008401 .type = HDA_FIXUP_PINS,
8402 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai2996bdb2011-08-18 16:02:24 +02008403 { 0x14, 0x99130110 }, /* speaker */
8404 { 0x18, 0x01a19820 }, /* mic */
8405 { 0x19, 0x99a3092f }, /* int-mic */
8406 { 0x1b, 0x0121401f }, /* HP out */
8407 { }
8408 },
Takashi Iwai53c334a2011-08-23 18:27:14 +02008409 .chained = true,
8410 .chain_id = ALC662_FIXUP_SKU_IGNORE
8411 },
8412 [ALC662_FIXUP_ASUS_MODE3] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008413 .type = HDA_FIXUP_PINS,
8414 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008415 { 0x14, 0x99130110 }, /* speaker */
8416 { 0x15, 0x0121441f }, /* HP */
8417 { 0x18, 0x01a19840 }, /* mic */
8418 { 0x19, 0x99a3094f }, /* int-mic */
8419 { 0x21, 0x01211420 }, /* HP2 */
8420 { }
8421 },
8422 .chained = true,
8423 .chain_id = ALC662_FIXUP_SKU_IGNORE
8424 },
8425 [ALC662_FIXUP_ASUS_MODE4] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008426 .type = HDA_FIXUP_PINS,
8427 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008428 { 0x14, 0x99130110 }, /* speaker */
8429 { 0x16, 0x99130111 }, /* speaker */
8430 { 0x18, 0x01a19840 }, /* mic */
8431 { 0x19, 0x99a3094f }, /* int-mic */
8432 { 0x21, 0x0121441f }, /* HP */
8433 { }
8434 },
8435 .chained = true,
8436 .chain_id = ALC662_FIXUP_SKU_IGNORE
8437 },
8438 [ALC662_FIXUP_ASUS_MODE5] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008439 .type = HDA_FIXUP_PINS,
8440 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008441 { 0x14, 0x99130110 }, /* speaker */
8442 { 0x15, 0x0121441f }, /* HP */
8443 { 0x16, 0x99130111 }, /* speaker */
8444 { 0x18, 0x01a19840 }, /* mic */
8445 { 0x19, 0x99a3094f }, /* int-mic */
8446 { }
8447 },
8448 .chained = true,
8449 .chain_id = ALC662_FIXUP_SKU_IGNORE
8450 },
8451 [ALC662_FIXUP_ASUS_MODE6] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008452 .type = HDA_FIXUP_PINS,
8453 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008454 { 0x14, 0x99130110 }, /* speaker */
8455 { 0x15, 0x01211420 }, /* HP2 */
8456 { 0x18, 0x01a19840 }, /* mic */
8457 { 0x19, 0x99a3094f }, /* int-mic */
8458 { 0x1b, 0x0121441f }, /* HP */
8459 { }
8460 },
8461 .chained = true,
8462 .chain_id = ALC662_FIXUP_SKU_IGNORE
8463 },
8464 [ALC662_FIXUP_ASUS_MODE7] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008465 .type = HDA_FIXUP_PINS,
8466 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008467 { 0x14, 0x99130110 }, /* speaker */
8468 { 0x17, 0x99130111 }, /* speaker */
8469 { 0x18, 0x01a19840 }, /* mic */
8470 { 0x19, 0x99a3094f }, /* int-mic */
8471 { 0x1b, 0x01214020 }, /* HP */
8472 { 0x21, 0x0121401f }, /* HP */
8473 { }
8474 },
8475 .chained = true,
8476 .chain_id = ALC662_FIXUP_SKU_IGNORE
8477 },
8478 [ALC662_FIXUP_ASUS_MODE8] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008479 .type = HDA_FIXUP_PINS,
8480 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008481 { 0x14, 0x99130110 }, /* speaker */
8482 { 0x12, 0x99a30970 }, /* int-mic */
8483 { 0x15, 0x01214020 }, /* HP */
8484 { 0x17, 0x99130111 }, /* speaker */
8485 { 0x18, 0x01a19840 }, /* mic */
8486 { 0x21, 0x0121401f }, /* HP */
8487 { }
8488 },
8489 .chained = true,
8490 .chain_id = ALC662_FIXUP_SKU_IGNORE
Takashi Iwai2996bdb2011-08-18 16:02:24 +02008491 },
Takashi Iwai1565cc32012-02-13 12:03:25 +01008492 [ALC662_FIXUP_NO_JACK_DETECT] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008493 .type = HDA_FIXUP_FUNC,
Takashi Iwai1565cc32012-02-13 12:03:25 +01008494 .v.func = alc_fixup_no_jack_detect,
8495 },
David Henningssonedfe3bf2012-06-12 13:15:12 +02008496 [ALC662_FIXUP_ZOTAC_Z68] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008497 .type = HDA_FIXUP_PINS,
8498 .v.pins = (const struct hda_pintbl[]) {
David Henningssonedfe3bf2012-06-12 13:15:12 +02008499 { 0x1b, 0x02214020 }, /* Front HP */
8500 { }
8501 }
8502 },
Takashi Iwai125821a2012-06-22 14:30:29 +02008503 [ALC662_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008504 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02008505 .v.func = alc_fixup_inv_dmic,
Takashi Iwai125821a2012-06-22 14:30:29 +02008506 },
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02008507 [ALC668_FIXUP_DELL_XPS13] = {
8508 .type = HDA_FIXUP_FUNC,
8509 .v.func = alc_fixup_dell_xps13,
8510 .chained = true,
8511 .chain_id = ALC668_FIXUP_DELL_DISABLE_AAMIX
8512 },
Gabriele Mazzotta5e6db662014-05-20 18:58:26 +02008513 [ALC668_FIXUP_DELL_DISABLE_AAMIX] = {
8514 .type = HDA_FIXUP_FUNC,
8515 .v.func = alc_fixup_disable_aamix,
8516 .chained = true,
8517 .chain_id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE
8518 },
Hui Wang493a52a2014-01-14 14:07:36 +08008519 [ALC668_FIXUP_AUTO_MUTE] = {
8520 .type = HDA_FIXUP_FUNC,
8521 .v.func = alc_fixup_auto_mute_via_amp,
8522 .chained = true,
8523 .chain_id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE
8524 },
David Henningsson1f8b46c2015-05-12 14:38:15 +02008525 [ALC662_FIXUP_DELL_MIC_NO_PRESENCE] = {
8526 .type = HDA_FIXUP_PINS,
8527 .v.pins = (const struct hda_pintbl[]) {
8528 { 0x19, 0x03a1113c }, /* use as headset mic, without its own jack detect */
8529 /* headphone mic by setting pin control of 0x1b (headphone out) to in + vref_50 */
8530 { }
8531 },
8532 .chained = true,
8533 .chain_id = ALC662_FIXUP_HEADSET_MODE
8534 },
8535 [ALC662_FIXUP_HEADSET_MODE] = {
8536 .type = HDA_FIXUP_FUNC,
8537 .v.func = alc_fixup_headset_mode_alc662,
8538 },
David Henningsson73bdd592013-04-15 15:44:14 +02008539 [ALC668_FIXUP_DELL_MIC_NO_PRESENCE] = {
8540 .type = HDA_FIXUP_PINS,
8541 .v.pins = (const struct hda_pintbl[]) {
8542 { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
8543 { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */
8544 { }
8545 },
8546 .chained = true,
8547 .chain_id = ALC668_FIXUP_HEADSET_MODE
8548 },
8549 [ALC668_FIXUP_HEADSET_MODE] = {
8550 .type = HDA_FIXUP_FUNC,
8551 .v.func = alc_fixup_headset_mode_alc668,
8552 },
David Henningsson8e54b4a2014-02-07 09:31:07 +01008553 [ALC662_FIXUP_BASS_MODE4_CHMAP] = {
Takashi Iwai8e383952013-10-30 17:41:12 +01008554 .type = HDA_FIXUP_FUNC,
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01008555 .v.func = alc_fixup_bass_chmap,
Takashi Iwai8e383952013-10-30 17:41:12 +01008556 .chained = true,
8557 .chain_id = ALC662_FIXUP_ASUS_MODE4
8558 },
David Henningsson61a75f12014-02-07 09:31:08 +01008559 [ALC662_FIXUP_BASS_16] = {
8560 .type = HDA_FIXUP_PINS,
8561 .v.pins = (const struct hda_pintbl[]) {
8562 {0x16, 0x80106111}, /* bass speaker */
8563 {}
8564 },
8565 .chained = true,
8566 .chain_id = ALC662_FIXUP_BASS_CHMAP,
8567 },
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01008568 [ALC662_FIXUP_BASS_1A] = {
8569 .type = HDA_FIXUP_PINS,
8570 .v.pins = (const struct hda_pintbl[]) {
8571 {0x1a, 0x80106111}, /* bass speaker */
8572 {}
8573 },
David Henningsson8e54b4a2014-02-07 09:31:07 +01008574 .chained = true,
8575 .chain_id = ALC662_FIXUP_BASS_CHMAP,
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01008576 },
David Henningsson8e54b4a2014-02-07 09:31:07 +01008577 [ALC662_FIXUP_BASS_CHMAP] = {
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01008578 .type = HDA_FIXUP_FUNC,
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01008579 .v.func = alc_fixup_bass_chmap,
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01008580 },
Bobi Mihalca9d4dc582016-03-23 13:26:11 +02008581 [ALC662_FIXUP_ASUS_Nx50] = {
8582 .type = HDA_FIXUP_FUNC,
8583 .v.func = alc_fixup_auto_mute_via_amp,
8584 .chained = true,
8585 .chain_id = ALC662_FIXUP_BASS_1A
8586 },
Mikhail Paulyshkafc7438b2017-04-21 08:52:42 +02008587 [ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE] = {
8588 .type = HDA_FIXUP_FUNC,
8589 .v.func = alc_fixup_headset_mode_alc668,
8590 .chain_id = ALC662_FIXUP_BASS_CHMAP
8591 },
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07008592 [ALC668_FIXUP_ASUS_Nx51] = {
8593 .type = HDA_FIXUP_PINS,
8594 .v.pins = (const struct hda_pintbl[]) {
Mikhail Paulyshkafc7438b2017-04-21 08:52:42 +02008595 { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
8596 { 0x1a, 0x90170151 }, /* bass speaker */
8597 { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07008598 {}
8599 },
8600 .chained = true,
Mikhail Paulyshkafc7438b2017-04-21 08:52:42 +02008601 .chain_id = ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE,
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07008602 },
Takashi Iwai5b7c5e12018-10-09 14:20:17 +02008603 [ALC668_FIXUP_MIC_COEF] = {
Takashi Iwai11ba6112018-10-07 09:44:17 +02008604 .type = HDA_FIXUP_VERBS,
8605 .v.verbs = (const struct hda_verb[]) {
8606 { 0x20, AC_VERB_SET_COEF_INDEX, 0xc3 },
8607 { 0x20, AC_VERB_SET_PROC_COEF, 0x4000 },
8608 {}
8609 },
8610 },
Takashi Iwai5b7c5e12018-10-09 14:20:17 +02008611 [ALC668_FIXUP_ASUS_G751] = {
8612 .type = HDA_FIXUP_PINS,
8613 .v.pins = (const struct hda_pintbl[]) {
8614 { 0x16, 0x0421101f }, /* HP */
8615 {}
8616 },
8617 .chained = true,
8618 .chain_id = ALC668_FIXUP_MIC_COEF
8619 },
Kailang Yang78f4f7c2016-06-07 11:31:34 +08008620 [ALC891_FIXUP_HEADSET_MODE] = {
8621 .type = HDA_FIXUP_FUNC,
8622 .v.func = alc_fixup_headset_mode,
8623 },
8624 [ALC891_FIXUP_DELL_MIC_NO_PRESENCE] = {
8625 .type = HDA_FIXUP_PINS,
8626 .v.pins = (const struct hda_pintbl[]) {
8627 { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
8628 { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */
8629 { }
8630 },
8631 .chained = true,
8632 .chain_id = ALC891_FIXUP_HEADSET_MODE
8633 },
Shrirang Bagul9b51fe32016-08-01 13:16:17 +08008634 [ALC662_FIXUP_ACER_VERITON] = {
8635 .type = HDA_FIXUP_PINS,
8636 .v.pins = (const struct hda_pintbl[]) {
8637 { 0x15, 0x50170120 }, /* no internal speaker */
8638 { }
8639 }
8640 },
Takashi Iwai1a3f0992016-10-20 12:14:51 +02008641 [ALC892_FIXUP_ASROCK_MOBO] = {
8642 .type = HDA_FIXUP_PINS,
8643 .v.pins = (const struct hda_pintbl[]) {
8644 { 0x15, 0x40f000f0 }, /* disabled */
8645 { 0x16, 0x40f000f0 }, /* disabled */
Takashi Iwai1a3f0992016-10-20 12:14:51 +02008646 { }
8647 }
8648 },
Kailang Yangc6790c82016-11-25 16:15:17 +08008649 [ALC662_FIXUP_USI_FUNC] = {
8650 .type = HDA_FIXUP_FUNC,
8651 .v.func = alc662_fixup_usi_headset_mic,
8652 },
8653 [ALC662_FIXUP_USI_HEADSET_MODE] = {
8654 .type = HDA_FIXUP_PINS,
8655 .v.pins = (const struct hda_pintbl[]) {
8656 { 0x19, 0x02a1913c }, /* use as headset mic, without its own jack detect */
8657 { 0x18, 0x01a1903d },
8658 { }
8659 },
8660 .chained = true,
8661 .chain_id = ALC662_FIXUP_USI_FUNC
8662 },
Kailang Yangca169cc2017-04-25 16:17:40 +08008663 [ALC662_FIXUP_LENOVO_MULTI_CODECS] = {
8664 .type = HDA_FIXUP_FUNC,
8665 .v.func = alc233_alc662_fixup_lenovo_dual_codecs,
8666 },
David Henningsson6cb3b702010-09-09 08:51:44 +02008667};
8668
Takashi Iwaia9111322011-05-02 11:30:18 +02008669static const struct snd_pci_quirk alc662_fixup_tbl[] = {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008670 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_FIXUP_ASUS_MODE2),
Takashi Iwaid3d38352013-08-19 20:05:50 +02008671 SND_PCI_QUIRK(0x1025, 0x022f, "Acer Aspire One", ALC662_FIXUP_INV_DMIC),
David Henningsson02f6ff92015-12-07 11:29:31 +01008672 SND_PCI_QUIRK(0x1025, 0x0241, "Packard Bell DOTS", ALC662_FIXUP_INV_DMIC),
David Henningssona6c47a82011-02-10 15:39:19 +01008673 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
David Henningsson94024cd2011-04-29 14:10:55 +02008674 SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
Takashi Iwai125821a2012-06-22 14:30:29 +02008675 SND_PCI_QUIRK(0x1025, 0x0349, "eMachines eM250", ALC662_FIXUP_INV_DMIC),
Takashi Iwai18019282013-08-16 08:17:05 +02008676 SND_PCI_QUIRK(0x1025, 0x034a, "Gateway LT27", ALC662_FIXUP_INV_DMIC),
Daniel T Chen2df03512010-10-10 22:39:28 -04008677 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
David Henningsson73bdd592013-04-15 15:44:14 +02008678 SND_PCI_QUIRK(0x1028, 0x05d8, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
8679 SND_PCI_QUIRK(0x1028, 0x05db, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
Takashi Iwaic5d019c2014-07-22 17:33:32 +02008680 SND_PCI_QUIRK(0x1028, 0x05fe, "Dell XPS 15", ALC668_FIXUP_DELL_XPS13),
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02008681 SND_PCI_QUIRK(0x1028, 0x060a, "Dell XPS 13", ALC668_FIXUP_DELL_XPS13),
Niranjan Sivakumar467e1432015-09-05 18:20:35 +02008682 SND_PCI_QUIRK(0x1028, 0x060d, "Dell M3800", ALC668_FIXUP_DELL_XPS13),
David Henningsson09d20142013-11-20 11:43:30 +01008683 SND_PCI_QUIRK(0x1028, 0x0625, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
David Henningssonad8ff99e2013-11-07 09:28:59 +01008684 SND_PCI_QUIRK(0x1028, 0x0626, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
Kailang Yang8dc9abb2014-04-16 15:53:12 +08008685 SND_PCI_QUIRK(0x1028, 0x0696, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
8686 SND_PCI_QUIRK(0x1028, 0x0698, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
Kailang Yang6a98e342014-10-27 16:20:30 +08008687 SND_PCI_QUIRK(0x1028, 0x069f, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
Takashi Iwaie59ea3e2011-06-29 17:21:00 +02008688 SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800),
Kaho Ng2da2dc92016-05-09 00:27:49 +08008689 SND_PCI_QUIRK(0x1043, 0x1080, "Asus UX501VW", ALC668_FIXUP_HEADSET_MODE),
Bobi Mihalca83a9efb2016-03-23 13:32:33 +02008690 SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_ASUS_Nx50),
Takashi Iwaidb8948e2016-01-18 09:17:30 +01008691 SND_PCI_QUIRK(0x1043, 0x13df, "Asus N550JX", ALC662_FIXUP_BASS_1A),
Bobi Mihalca9d4dc582016-03-23 13:26:11 +02008692 SND_PCI_QUIRK(0x1043, 0x129d, "Asus N750", ALC662_FIXUP_ASUS_Nx50),
Takashi Iwai11ba6112018-10-07 09:44:17 +02008693 SND_PCI_QUIRK(0x1043, 0x12ff, "ASUS G751", ALC668_FIXUP_ASUS_G751),
David Henningsson8e54b4a2014-02-07 09:31:07 +01008694 SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
David Henningsson61a75f12014-02-07 09:31:08 +01008695 SND_PCI_QUIRK(0x1043, 0x15a7, "ASUS UX51VZH", ALC662_FIXUP_BASS_16),
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07008696 SND_PCI_QUIRK(0x1043, 0x177d, "ASUS N551", ALC668_FIXUP_ASUS_Nx51),
8697 SND_PCI_QUIRK(0x1043, 0x17bd, "ASUS N751", ALC668_FIXUP_ASUS_Nx51),
Takashi Iwaic7efff92017-01-04 21:38:16 +01008698 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71SL", ALC662_FIXUP_ASUS_MODE8),
David Henningsson61a75f12014-02-07 09:31:08 +01008699 SND_PCI_QUIRK(0x1043, 0x1b73, "ASUS N55SF", ALC662_FIXUP_BASS_16),
David Henningsson8e54b4a2014-02-07 09:31:07 +01008700 SND_PCI_QUIRK(0x1043, 0x1bf3, "ASUS N76VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
Takashi Iwai1565cc32012-02-13 12:03:25 +01008701 SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT),
Takashi Iwai53c334a2011-08-23 18:27:14 +02008702 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2),
Daniel T Chena0e90ac2010-11-20 10:20:35 -05008703 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
Kailang Yangc6790c82016-11-25 16:15:17 +08008704 SND_PCI_QUIRK(0x14cd, 0x5003, "USI", ALC662_FIXUP_USI_HEADSET_MODE),
Kailang Yangca169cc2017-04-25 16:17:40 +08008705 SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC662_FIXUP_LENOVO_MULTI_CODECS),
Valentine Sinitsynd4118582010-10-01 22:24:08 +06008706 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
David Henningsson6cb3b702010-09-09 08:51:44 +02008707 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
Takashi Iwai1a3f0992016-10-20 12:14:51 +02008708 SND_PCI_QUIRK(0x1849, 0x5892, "ASRock B150M", ALC892_FIXUP_ASROCK_MOBO),
David Henningssonedfe3bf2012-06-12 13:15:12 +02008709 SND_PCI_QUIRK(0x19da, 0xa130, "Zotac Z68", ALC662_FIXUP_ZOTAC_Z68),
Shrirang Bagul9b51fe32016-08-01 13:16:17 +08008710 SND_PCI_QUIRK(0x1b0a, 0x01b8, "ACER Veriton", ALC662_FIXUP_ACER_VERITON),
Anisse Astierd2ebd472011-01-20 12:36:21 +01008711 SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
Takashi Iwai53c334a2011-08-23 18:27:14 +02008712
8713#if 0
8714 /* Below is a quirk table taken from the old code.
8715 * Basically the device should work as is without the fixup table.
8716 * If BIOS doesn't give a proper info, enable the corresponding
8717 * fixup entry.
Jesper Juhl7d7eb9e2012-04-12 22:11:25 +02008718 */
Takashi Iwai53c334a2011-08-23 18:27:14 +02008719 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC662_FIXUP_ASUS_MODE1),
8720 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC662_FIXUP_ASUS_MODE3),
8721 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC662_FIXUP_ASUS_MODE1),
8722 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC662_FIXUP_ASUS_MODE3),
8723 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
8724 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8725 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
8726 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC662_FIXUP_ASUS_MODE1),
8727 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC662_FIXUP_ASUS_MODE1),
8728 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8729 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC662_FIXUP_ASUS_MODE7),
8730 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC662_FIXUP_ASUS_MODE7),
8731 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC662_FIXUP_ASUS_MODE8),
8732 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC662_FIXUP_ASUS_MODE3),
8733 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC662_FIXUP_ASUS_MODE1),
8734 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8735 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_FIXUP_ASUS_MODE2),
8736 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC662_FIXUP_ASUS_MODE1),
8737 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8738 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
8739 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
8740 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8741 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC662_FIXUP_ASUS_MODE1),
8742 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC662_FIXUP_ASUS_MODE3),
8743 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_FIXUP_ASUS_MODE2),
8744 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8745 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC662_FIXUP_ASUS_MODE5),
8746 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
8747 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8748 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC662_FIXUP_ASUS_MODE1),
8749 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8750 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8751 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC662_FIXUP_ASUS_MODE3),
8752 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC662_FIXUP_ASUS_MODE3),
8753 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC662_FIXUP_ASUS_MODE1),
8754 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC662_FIXUP_ASUS_MODE1),
8755 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC662_FIXUP_ASUS_MODE1),
8756 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC662_FIXUP_ASUS_MODE1),
8757 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC662_FIXUP_ASUS_MODE1),
8758 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8759 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_FIXUP_ASUS_MODE2),
8760 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC662_FIXUP_ASUS_MODE1),
8761 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
8762 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC662_FIXUP_ASUS_MODE3),
8763 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC662_FIXUP_ASUS_MODE1),
8764 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC662_FIXUP_ASUS_MODE1),
8765 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC662_FIXUP_ASUS_MODE1),
8766 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_FIXUP_ASUS_MODE2),
8767 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
8768 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE4),
8769#endif
David Henningsson6cb3b702010-09-09 08:51:44 +02008770 {}
8771};
8772
Takashi Iwai1727a772013-01-10 09:52:52 +01008773static const struct hda_model_fixup alc662_fixup_models[] = {
Takashi Iwaiaa3841b2018-06-26 07:42:40 +02008774 {.id = ALC662_FIXUP_ASPIRE, .name = "aspire"},
8775 {.id = ALC662_FIXUP_IDEAPAD, .name = "ideapad"},
Todd Broch6be79482010-12-07 16:51:05 -08008776 {.id = ALC272_FIXUP_MARIO, .name = "mario"},
Takashi Iwaiaa3841b2018-06-26 07:42:40 +02008777 {.id = ALC662_FIXUP_HP_RP5800, .name = "hp-rp5800"},
Takashi Iwai53c334a2011-08-23 18:27:14 +02008778 {.id = ALC662_FIXUP_ASUS_MODE1, .name = "asus-mode1"},
8779 {.id = ALC662_FIXUP_ASUS_MODE2, .name = "asus-mode2"},
8780 {.id = ALC662_FIXUP_ASUS_MODE3, .name = "asus-mode3"},
8781 {.id = ALC662_FIXUP_ASUS_MODE4, .name = "asus-mode4"},
8782 {.id = ALC662_FIXUP_ASUS_MODE5, .name = "asus-mode5"},
8783 {.id = ALC662_FIXUP_ASUS_MODE6, .name = "asus-mode6"},
8784 {.id = ALC662_FIXUP_ASUS_MODE7, .name = "asus-mode7"},
8785 {.id = ALC662_FIXUP_ASUS_MODE8, .name = "asus-mode8"},
Takashi Iwaiaa3841b2018-06-26 07:42:40 +02008786 {.id = ALC662_FIXUP_ZOTAC_Z68, .name = "zotac-z68"},
Takashi Iwai6e72aa52012-06-25 10:52:25 +02008787 {.id = ALC662_FIXUP_INV_DMIC, .name = "inv-dmic"},
Takashi Iwaiaa3841b2018-06-26 07:42:40 +02008788 {.id = ALC662_FIXUP_DELL_MIC_NO_PRESENCE, .name = "alc662-headset-multi"},
David Henningssone32aa852013-06-17 11:04:02 +02008789 {.id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE, .name = "dell-headset-multi"},
Takashi Iwaiaa3841b2018-06-26 07:42:40 +02008790 {.id = ALC662_FIXUP_HEADSET_MODE, .name = "alc662-headset"},
8791 {.id = ALC668_FIXUP_HEADSET_MODE, .name = "alc668-headset"},
8792 {.id = ALC662_FIXUP_BASS_16, .name = "bass16"},
8793 {.id = ALC662_FIXUP_BASS_1A, .name = "bass1a"},
8794 {.id = ALC668_FIXUP_AUTO_MUTE, .name = "automute"},
8795 {.id = ALC668_FIXUP_DELL_XPS13, .name = "dell-xps13"},
8796 {.id = ALC662_FIXUP_ASUS_Nx50, .name = "asus-nx50"},
8797 {.id = ALC668_FIXUP_ASUS_Nx51, .name = "asus-nx51"},
Takashi Iwai40c51672018-10-07 09:47:39 +02008798 {.id = ALC668_FIXUP_ASUS_G751, .name = "asus-g751"},
Takashi Iwaiaa3841b2018-06-26 07:42:40 +02008799 {.id = ALC891_FIXUP_HEADSET_MODE, .name = "alc891-headset"},
8800 {.id = ALC891_FIXUP_DELL_MIC_NO_PRESENCE, .name = "alc891-headset-multi"},
8801 {.id = ALC662_FIXUP_ACER_VERITON, .name = "acer-veriton"},
8802 {.id = ALC892_FIXUP_ASROCK_MOBO, .name = "asrock-mobo"},
8803 {.id = ALC662_FIXUP_USI_HEADSET_MODE, .name = "usi-headset"},
Takashi Iwaiba90d6a2017-05-22 16:38:47 +02008804 {.id = ALC662_FIXUP_LENOVO_MULTI_CODECS, .name = "dual-codecs"},
Todd Broch6be79482010-12-07 16:51:05 -08008805 {}
8806};
David Henningsson6cb3b702010-09-09 08:51:44 +02008807
Hui Wang532895c2014-05-29 15:59:19 +08008808static const struct snd_hda_pin_quirk alc662_pin_fixup_tbl[] = {
Kailang Yang78f4f7c2016-06-07 11:31:34 +08008809 SND_HDA_PIN_QUIRK(0x10ec0867, 0x1028, "Dell", ALC891_FIXUP_DELL_MIC_NO_PRESENCE,
8810 {0x17, 0x02211010},
8811 {0x18, 0x01a19030},
8812 {0x1a, 0x01813040},
8813 {0x21, 0x01014020}),
Hui Wang4b4e0e32019-07-16 15:21:34 +08008814 SND_HDA_PIN_QUIRK(0x10ec0867, 0x1028, "Dell", ALC891_FIXUP_DELL_MIC_NO_PRESENCE,
8815 {0x16, 0x01813030},
8816 {0x17, 0x02211010},
8817 {0x18, 0x01a19040},
8818 {0x21, 0x01014020}),
David Henningsson1f8b46c2015-05-12 14:38:15 +02008819 SND_HDA_PIN_QUIRK(0x10ec0662, 0x1028, "Dell", ALC662_FIXUP_DELL_MIC_NO_PRESENCE,
David Henningsson1f8b46c2015-05-12 14:38:15 +02008820 {0x14, 0x01014010},
David Henningsson1f8b46c2015-05-12 14:38:15 +02008821 {0x18, 0x01a19020},
David Henningsson1f8b46c2015-05-12 14:38:15 +02008822 {0x1a, 0x0181302f},
Hui Wang11580292015-08-03 11:03:49 +08008823 {0x1b, 0x0221401f}),
David Henningsson76c21322014-06-24 14:46:54 +02008824 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
8825 {0x12, 0x99a30130},
8826 {0x14, 0x90170110},
8827 {0x15, 0x0321101f},
Hui Wang11580292015-08-03 11:03:49 +08008828 {0x16, 0x03011020}),
David Henningsson76c21322014-06-24 14:46:54 +02008829 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
8830 {0x12, 0x99a30140},
8831 {0x14, 0x90170110},
8832 {0x15, 0x0321101f},
Hui Wang11580292015-08-03 11:03:49 +08008833 {0x16, 0x03011020}),
David Henningsson76c21322014-06-24 14:46:54 +02008834 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
8835 {0x12, 0x99a30150},
8836 {0x14, 0x90170110},
8837 {0x15, 0x0321101f},
Hui Wang11580292015-08-03 11:03:49 +08008838 {0x16, 0x03011020}),
David Henningsson76c21322014-06-24 14:46:54 +02008839 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
David Henningsson76c21322014-06-24 14:46:54 +02008840 {0x14, 0x90170110},
8841 {0x15, 0x0321101f},
Hui Wang11580292015-08-03 11:03:49 +08008842 {0x16, 0x03011020}),
David Henningsson76c21322014-06-24 14:46:54 +02008843 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell XPS 15", ALC668_FIXUP_AUTO_MUTE,
8844 {0x12, 0x90a60130},
8845 {0x14, 0x90170110},
Hui Wang11580292015-08-03 11:03:49 +08008846 {0x15, 0x0321101f}),
Hui Wang532895c2014-05-29 15:59:19 +08008847 {}
8848};
8849
Takashi Iwai1d045db2011-07-07 18:23:21 +02008850/*
8851 */
Kailang Yangbc9f98a2007-04-12 13:06:07 +02008852static int patch_alc662(struct hda_codec *codec)
8853{
8854 struct alc_spec *spec;
Takashi Iwai3de95172012-05-07 18:03:15 +02008855 int err;
Kailang Yangbc9f98a2007-04-12 13:06:07 +02008856
Takashi Iwai3de95172012-05-07 18:03:15 +02008857 err = alc_alloc_spec(codec, 0x0b);
8858 if (err < 0)
8859 return err;
Kailang Yangbc9f98a2007-04-12 13:06:07 +02008860
Takashi Iwai3de95172012-05-07 18:03:15 +02008861 spec = codec->spec;
Takashi Iwai1f0f4b82011-06-27 10:52:59 +02008862
Takashi Iwai225068a2015-05-29 10:42:14 +02008863 spec->shutup = alc_eapd_shutup;
8864
Takashi Iwai53c334a2011-08-23 18:27:14 +02008865 /* handle multiple HPs as is */
8866 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
8867
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +02008868 alc_fix_pll_init(codec, 0x20, 0x04, 15);
8869
Takashi Iwai7639a062015-03-03 10:07:24 +01008870 switch (codec->core.vendor_id) {
Kailang Yangf3f91852014-10-24 15:43:46 +08008871 case 0x10ec0668:
8872 spec->init_hook = alc668_restore_default_value;
8873 break;
Kailang Yangf3f91852014-10-24 15:43:46 +08008874 }
Kailang Yang8663ff72012-06-29 09:35:52 +02008875
Takashi Iwaic9af7532019-05-10 11:01:43 +02008876 alc_pre_init(codec);
8877
Takashi Iwai1727a772013-01-10 09:52:52 +01008878 snd_hda_pick_fixup(codec, alc662_fixup_models,
Takashi Iwai8e5a0502012-06-21 15:49:33 +02008879 alc662_fixup_tbl, alc662_fixups);
Hui Wang532895c2014-05-29 15:59:19 +08008880 snd_hda_pick_pin_fixup(codec, alc662_pin_fixup_tbl, alc662_fixups);
Takashi Iwai1727a772013-01-10 09:52:52 +01008881 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai8e5a0502012-06-21 15:49:33 +02008882
8883 alc_auto_parse_customize_define(codec);
8884
Takashi Iwai7504b6c2013-03-18 11:25:51 +01008885 if (has_cdefine_beep(codec))
8886 spec->gen.beep_nid = 0x01;
8887
Takashi Iwai1bb7e432011-10-17 16:50:59 +02008888 if ((alc_get_coef0(codec) & (1 << 14)) &&
Takashi Iwai5100cd02014-02-15 10:03:19 +01008889 codec->bus->pci && codec->bus->pci->subsystem_vendor == 0x1025 &&
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008890 spec->cdefine.platform_type == 1) {
Wei Yongjun6134b1a2013-04-18 11:12:59 +08008891 err = alc_codec_rename(codec, "ALC272X");
8892 if (err < 0)
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008893 goto error;
Takashi Iwai20ca0c32011-10-17 16:00:35 +02008894 }
Kailang Yang274693f2009-12-03 10:07:50 +01008895
Takashi Iwaib9c51062011-08-24 18:08:07 +02008896 /* automatic parse from the BIOS config */
8897 err = alc662_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008898 if (err < 0)
8899 goto error;
Kailang Yangbc9f98a2007-04-12 13:06:07 +02008900
Takashi Iwai7504b6c2013-03-18 11:25:51 +01008901 if (!spec->gen.no_analog && spec->gen.beep_nid) {
Takashi Iwai7639a062015-03-03 10:07:24 +01008902 switch (codec->core.vendor_id) {
Kailang Yangda00c242010-03-19 11:23:45 +01008903 case 0x10ec0662:
Takashi Iwaifea80fa2018-06-20 12:52:46 +02008904 err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
Kailang Yangda00c242010-03-19 11:23:45 +01008905 break;
8906 case 0x10ec0272:
8907 case 0x10ec0663:
8908 case 0x10ec0665:
Kailang Yang9ad54542013-11-26 15:41:40 +08008909 case 0x10ec0668:
Takashi Iwaifea80fa2018-06-20 12:52:46 +02008910 err = set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
Kailang Yangda00c242010-03-19 11:23:45 +01008911 break;
8912 case 0x10ec0273:
Takashi Iwaifea80fa2018-06-20 12:52:46 +02008913 err = set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
Kailang Yangda00c242010-03-19 11:23:45 +01008914 break;
8915 }
Takashi Iwaifea80fa2018-06-20 12:52:46 +02008916 if (err < 0)
8917 goto error;
Kailang Yangcec27c82010-02-04 14:18:18 +01008918 }
Takashi Iwai2134ea42008-01-10 16:53:55 +01008919
Takashi Iwai1727a772013-01-10 09:52:52 +01008920 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01008921
Kailang Yangbc9f98a2007-04-12 13:06:07 +02008922 return 0;
Kailang Yangbc9f98a2007-04-12 13:06:07 +02008923
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008924 error:
8925 alc_free(codec);
8926 return err;
Kailang Yangb478b992011-05-18 11:51:15 +02008927}
8928
Kailang Yangbc9f98a2007-04-12 13:06:07 +02008929/*
Kailang Yangd1eb57f2010-06-23 16:25:26 +02008930 * ALC680 support
8931 */
Kailang Yangd1eb57f2010-06-23 16:25:26 +02008932
Kailang Yangd1eb57f2010-06-23 16:25:26 +02008933static int alc680_parse_auto_config(struct hda_codec *codec)
8934{
Takashi Iwai3e6179b2011-07-08 16:55:13 +02008935 return alc_parse_auto_config(codec, NULL, NULL);
Kailang Yangd1eb57f2010-06-23 16:25:26 +02008936}
8937
Kailang Yangd1eb57f2010-06-23 16:25:26 +02008938/*
Kailang Yangd1eb57f2010-06-23 16:25:26 +02008939 */
Kailang Yangd1eb57f2010-06-23 16:25:26 +02008940static int patch_alc680(struct hda_codec *codec)
8941{
Kailang Yangd1eb57f2010-06-23 16:25:26 +02008942 int err;
8943
Takashi Iwai1f0f4b82011-06-27 10:52:59 +02008944 /* ALC680 has no aa-loopback mixer */
Takashi Iwai3de95172012-05-07 18:03:15 +02008945 err = alc_alloc_spec(codec, 0);
8946 if (err < 0)
8947 return err;
Takashi Iwai1f0f4b82011-06-27 10:52:59 +02008948
Takashi Iwai1ebec5f2011-08-15 13:21:48 +02008949 /* automatic parse from the BIOS config */
8950 err = alc680_parse_auto_config(codec);
8951 if (err < 0) {
8952 alc_free(codec);
8953 return err;
Kailang Yangd1eb57f2010-06-23 16:25:26 +02008954 }
8955
Kailang Yangd1eb57f2010-06-23 16:25:26 +02008956 return 0;
8957}
8958
8959/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07008960 * patch entries
8961 */
Takashi Iwaib9a94a92015-10-01 16:20:04 +02008962static const struct hda_device_id snd_hda_id_realtek[] = {
Kailang Yang0a6f0602017-06-30 16:00:48 +08008963 HDA_CODEC_ENTRY(0x10ec0215, "ALC215", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02008964 HDA_CODEC_ENTRY(0x10ec0221, "ALC221", patch_alc269),
Hui Wang2a36c162019-09-04 13:53:27 +08008965 HDA_CODEC_ENTRY(0x10ec0222, "ALC222", patch_alc269),
Kailang Yang42314302016-02-03 15:03:50 +08008966 HDA_CODEC_ENTRY(0x10ec0225, "ALC225", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02008967 HDA_CODEC_ENTRY(0x10ec0231, "ALC231", patch_alc269),
8968 HDA_CODEC_ENTRY(0x10ec0233, "ALC233", patch_alc269),
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08008969 HDA_CODEC_ENTRY(0x10ec0234, "ALC234", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02008970 HDA_CODEC_ENTRY(0x10ec0235, "ALC233", patch_alc269),
Kailang Yang736f20a2017-10-20 15:06:34 +08008971 HDA_CODEC_ENTRY(0x10ec0236, "ALC236", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02008972 HDA_CODEC_ENTRY(0x10ec0255, "ALC255", patch_alc269),
8973 HDA_CODEC_ENTRY(0x10ec0256, "ALC256", patch_alc269),
Kailang Yangf429e7e2017-12-05 15:38:24 +08008974 HDA_CODEC_ENTRY(0x10ec0257, "ALC257", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02008975 HDA_CODEC_ENTRY(0x10ec0260, "ALC260", patch_alc260),
8976 HDA_CODEC_ENTRY(0x10ec0262, "ALC262", patch_alc262),
8977 HDA_CODEC_ENTRY(0x10ec0267, "ALC267", patch_alc268),
8978 HDA_CODEC_ENTRY(0x10ec0268, "ALC268", patch_alc268),
8979 HDA_CODEC_ENTRY(0x10ec0269, "ALC269", patch_alc269),
8980 HDA_CODEC_ENTRY(0x10ec0270, "ALC270", patch_alc269),
8981 HDA_CODEC_ENTRY(0x10ec0272, "ALC272", patch_alc662),
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08008982 HDA_CODEC_ENTRY(0x10ec0274, "ALC274", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02008983 HDA_CODEC_ENTRY(0x10ec0275, "ALC275", patch_alc269),
8984 HDA_CODEC_ENTRY(0x10ec0276, "ALC276", patch_alc269),
8985 HDA_CODEC_ENTRY(0x10ec0280, "ALC280", patch_alc269),
8986 HDA_CODEC_ENTRY(0x10ec0282, "ALC282", patch_alc269),
8987 HDA_CODEC_ENTRY(0x10ec0283, "ALC283", patch_alc269),
8988 HDA_CODEC_ENTRY(0x10ec0284, "ALC284", patch_alc269),
Kailang Yang0a6f0602017-06-30 16:00:48 +08008989 HDA_CODEC_ENTRY(0x10ec0285, "ALC285", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02008990 HDA_CODEC_ENTRY(0x10ec0286, "ALC286", patch_alc269),
8991 HDA_CODEC_ENTRY(0x10ec0288, "ALC288", patch_alc269),
Kailang Yang0a6f0602017-06-30 16:00:48 +08008992 HDA_CODEC_ENTRY(0x10ec0289, "ALC289", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02008993 HDA_CODEC_ENTRY(0x10ec0290, "ALC290", patch_alc269),
8994 HDA_CODEC_ENTRY(0x10ec0292, "ALC292", patch_alc269),
8995 HDA_CODEC_ENTRY(0x10ec0293, "ALC293", patch_alc269),
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08008996 HDA_CODEC_ENTRY(0x10ec0294, "ALC294", patch_alc269),
Kailang Yang7d727862016-05-24 16:46:07 +08008997 HDA_CODEC_ENTRY(0x10ec0295, "ALC295", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02008998 HDA_CODEC_ENTRY(0x10ec0298, "ALC298", patch_alc269),
Kailang Yang28f1f9b2017-01-04 14:49:07 +08008999 HDA_CODEC_ENTRY(0x10ec0299, "ALC299", patch_alc269),
Kailang Yang1078bef2018-11-08 16:36:15 +08009000 HDA_CODEC_ENTRY(0x10ec0300, "ALC300", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009001 HDA_CODEC_REV_ENTRY(0x10ec0861, 0x100340, "ALC660", patch_alc861),
9002 HDA_CODEC_ENTRY(0x10ec0660, "ALC660-VD", patch_alc861vd),
9003 HDA_CODEC_ENTRY(0x10ec0861, "ALC861", patch_alc861),
9004 HDA_CODEC_ENTRY(0x10ec0862, "ALC861-VD", patch_alc861vd),
9005 HDA_CODEC_REV_ENTRY(0x10ec0662, 0x100002, "ALC662 rev2", patch_alc882),
9006 HDA_CODEC_REV_ENTRY(0x10ec0662, 0x100101, "ALC662 rev1", patch_alc662),
9007 HDA_CODEC_REV_ENTRY(0x10ec0662, 0x100300, "ALC662 rev3", patch_alc662),
9008 HDA_CODEC_ENTRY(0x10ec0663, "ALC663", patch_alc662),
9009 HDA_CODEC_ENTRY(0x10ec0665, "ALC665", patch_alc662),
9010 HDA_CODEC_ENTRY(0x10ec0667, "ALC667", patch_alc662),
9011 HDA_CODEC_ENTRY(0x10ec0668, "ALC668", patch_alc662),
9012 HDA_CODEC_ENTRY(0x10ec0670, "ALC670", patch_alc662),
9013 HDA_CODEC_ENTRY(0x10ec0671, "ALC671", patch_alc662),
9014 HDA_CODEC_ENTRY(0x10ec0680, "ALC680", patch_alc680),
Kailang Yang6fbae352016-05-30 16:44:20 +08009015 HDA_CODEC_ENTRY(0x10ec0700, "ALC700", patch_alc269),
9016 HDA_CODEC_ENTRY(0x10ec0701, "ALC701", patch_alc269),
9017 HDA_CODEC_ENTRY(0x10ec0703, "ALC703", patch_alc269),
Kailang Yang78f4f7c2016-06-07 11:31:34 +08009018 HDA_CODEC_ENTRY(0x10ec0867, "ALC891", patch_alc662),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009019 HDA_CODEC_ENTRY(0x10ec0880, "ALC880", patch_alc880),
9020 HDA_CODEC_ENTRY(0x10ec0882, "ALC882", patch_alc882),
9021 HDA_CODEC_ENTRY(0x10ec0883, "ALC883", patch_alc882),
9022 HDA_CODEC_REV_ENTRY(0x10ec0885, 0x100101, "ALC889A", patch_alc882),
9023 HDA_CODEC_REV_ENTRY(0x10ec0885, 0x100103, "ALC889A", patch_alc882),
9024 HDA_CODEC_ENTRY(0x10ec0885, "ALC885", patch_alc882),
9025 HDA_CODEC_ENTRY(0x10ec0887, "ALC887", patch_alc882),
9026 HDA_CODEC_REV_ENTRY(0x10ec0888, 0x100101, "ALC1200", patch_alc882),
9027 HDA_CODEC_ENTRY(0x10ec0888, "ALC888", patch_alc882),
9028 HDA_CODEC_ENTRY(0x10ec0889, "ALC889", patch_alc882),
9029 HDA_CODEC_ENTRY(0x10ec0892, "ALC892", patch_alc662),
9030 HDA_CODEC_ENTRY(0x10ec0899, "ALC898", patch_alc882),
9031 HDA_CODEC_ENTRY(0x10ec0900, "ALC1150", patch_alc882),
Kailang Yang65553b12017-07-11 15:15:47 +08009032 HDA_CODEC_ENTRY(0x10ec1168, "ALC1220", patch_alc882),
Kailang Yanga535ad52017-01-16 16:59:26 +08009033 HDA_CODEC_ENTRY(0x10ec1220, "ALC1220", patch_alc882),
Linus Torvalds1da177e2005-04-16 15:20:36 -07009034 {} /* terminator */
9035};
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009036MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_realtek);
Takashi Iwai1289e9e2008-11-27 15:47:11 +01009037
9038MODULE_LICENSE("GPL");
9039MODULE_DESCRIPTION("Realtek HD-audio codec");
9040
Takashi Iwaid8a766a2015-02-17 15:25:37 +01009041static struct hda_codec_driver realtek_driver = {
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009042 .id = snd_hda_id_realtek,
Takashi Iwai1289e9e2008-11-27 15:47:11 +01009043};
9044
Takashi Iwaid8a766a2015-02-17 15:25:37 +01009045module_hda_codec_driver(realtek_driver);