blob: 4c83ed4b0d5c71377ef54ec4ac960d4d438343df [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 Yang83629532019-05-02 16:03:26 +0800396 case 0x10ec0711:
Kailang Yangdcd4f0d2016-05-04 15:50:18 +0800397 alc_update_coef_idx(codec, 0x10, 1<<15, 0);
398 break;
Kailang Yang394c97f2014-11-12 17:38:08 +0800399 case 0x10ec0662:
400 if ((coef & 0x00f0) == 0x0030)
401 alc_update_coef_idx(codec, 0x4, 1<<10, 0); /* EAPD Ctrl */
402 break;
403 case 0x10ec0272:
404 case 0x10ec0273:
405 case 0x10ec0663:
406 case 0x10ec0665:
407 case 0x10ec0670:
408 case 0x10ec0671:
409 case 0x10ec0672:
410 alc_update_coef_idx(codec, 0xd, 0, 1<<14); /* EAPD Ctrl */
411 break;
Kailang Yangf0778872019-10-24 15:13:32 +0800412 case 0x10ec0623:
413 alc_update_coef_idx(codec, 0x19, 1<<13, 0);
414 break;
Kailang Yang394c97f2014-11-12 17:38:08 +0800415 case 0x10ec0668:
416 alc_update_coef_idx(codec, 0x7, 3<<13, 0);
417 break;
418 case 0x10ec0867:
419 alc_update_coef_idx(codec, 0x4, 1<<10, 0);
420 break;
421 case 0x10ec0888:
422 if ((coef & 0x00f0) == 0x0020 || (coef & 0x00f0) == 0x0030)
423 alc_update_coef_idx(codec, 0x7, 1<<5, 0);
424 break;
425 case 0x10ec0892:
426 alc_update_coef_idx(codec, 0x7, 1<<5, 0);
427 break;
428 case 0x10ec0899:
429 case 0x10ec0900:
Kailang Yang65553b12017-07-11 15:15:47 +0800430 case 0x10ec1168:
Kailang Yanga535ad52017-01-16 16:59:26 +0800431 case 0x10ec1220:
Kailang Yang394c97f2014-11-12 17:38:08 +0800432 alc_update_coef_idx(codec, 0x7, 1<<1, 0);
433 break;
434 }
435}
436
Kailang Yangf9423e72008-05-27 12:32:25 +0200437/* additional initialization for ALC888 variants */
438static void alc888_coef_init(struct hda_codec *codec)
439{
Kailang Yang1df88742014-10-29 16:10:13 +0800440 switch (alc_get_coef0(codec) & 0x00f0) {
441 /* alc888-VA */
442 case 0x00:
443 /* alc888-VB */
444 case 0x10:
445 alc_update_coef_idx(codec, 7, 0, 0x2030); /* Turn EAPD to High */
446 break;
447 }
Jaroslav Kysela87a8c372009-07-23 10:58:29 +0200448}
449
Takashi Iwai3fb4a502010-01-19 15:46:37 +0100450/* turn on/off EAPD control (only if available) */
451static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
452{
453 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
454 return;
455 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
456 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
457 on ? 2 : 0);
458}
459
Takashi Iwai691f1fc2011-04-07 10:31:43 +0200460/* turn on/off EAPD controls of the codec */
461static void alc_auto_setup_eapd(struct hda_codec *codec, bool on)
462{
463 /* We currently only handle front, HP */
Takashi Iwai39fa84e2011-06-27 15:28:57 +0200464 static hda_nid_t pins[] = {
Hui Wangaf95b412015-03-26 17:14:55 +0800465 0x0f, 0x10, 0x14, 0x15, 0x17, 0
Takashi Iwai39fa84e2011-06-27 15:28:57 +0200466 };
467 hda_nid_t *p;
468 for (p = pins; *p; p++)
469 set_eapd(codec, *p, on);
Takashi Iwai691f1fc2011-04-07 10:31:43 +0200470}
471
Kailang Yangdad31972019-05-10 16:28:57 +0800472static int find_ext_mic_pin(struct hda_codec *codec);
473
474static void alc_headset_mic_no_shutup(struct hda_codec *codec)
475{
476 const struct hda_pincfg *pin;
477 int mic_pin = find_ext_mic_pin(codec);
478 int i;
479
480 /* don't shut up pins when unloading the driver; otherwise it breaks
481 * the default pin setup at the next load of the driver
482 */
483 if (codec->bus->shutdown)
484 return;
485
486 snd_array_for_each(&codec->init_pins, i, pin) {
487 /* use read here for syncing after issuing each verb */
488 if (pin->nid != mic_pin)
489 snd_hda_codec_read(codec, pin->nid, 0,
490 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
491 }
492
493 codec->pins_shutup = 1;
494}
495
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +0100496static void alc_shutup_pins(struct hda_codec *codec)
497{
498 struct alc_spec *spec = codec->spec;
499
Kailang Yangdad31972019-05-10 16:28:57 +0800500 switch (codec->core.vendor_id) {
501 case 0x10ec0286:
502 case 0x10ec0288:
503 case 0x10ec0298:
504 alc_headset_mic_no_shutup(codec);
505 break;
506 default:
507 if (!spec->no_shutup_pins)
508 snd_hda_shutup_pins(codec);
509 break;
510 }
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +0100511}
512
Takashi Iwai1c7161532011-04-07 10:37:16 +0200513/* generic shutup callback;
Lars-Peter Clausen4ce8e6a2016-11-08 15:48:06 +0100514 * just turning off EAPD and a little pause for avoiding pop-noise
Takashi Iwai1c7161532011-04-07 10:37:16 +0200515 */
516static void alc_eapd_shutup(struct hda_codec *codec)
517{
Kailang Yang97a26572013-11-29 00:35:26 -0500518 struct alc_spec *spec = codec->spec;
519
Takashi Iwai1c7161532011-04-07 10:37:16 +0200520 alc_auto_setup_eapd(codec, false);
Kailang Yang97a26572013-11-29 00:35:26 -0500521 if (!spec->no_depop_delay)
522 msleep(200);
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +0100523 alc_shutup_pins(codec);
Takashi Iwai1c7161532011-04-07 10:37:16 +0200524}
525
Takashi Iwai1d045db2011-07-07 18:23:21 +0200526/* generic EAPD initialization */
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200527static void alc_auto_init_amp(struct hda_codec *codec, int type)
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200528{
Takashi Iwai39fa84e2011-06-27 15:28:57 +0200529 alc_auto_setup_eapd(codec, true);
Takashi Iwai5579cd62018-06-19 22:22:41 +0200530 alc_write_gpio(codec);
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200531 switch (type) {
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200532 case ALC_INIT_DEFAULT:
Takashi Iwai7639a062015-03-03 10:07:24 +0100533 switch (codec->core.vendor_id) {
Kailang Yangc9b58002007-10-16 14:30:01 +0200534 case 0x10ec0260:
Takashi Iwai98b24882014-08-18 13:47:50 +0200535 alc_update_coefex_idx(codec, 0x1a, 7, 0, 0x2010);
Kailang Yangc9b58002007-10-16 14:30:01 +0200536 break;
Kailang Yangc9b58002007-10-16 14:30:01 +0200537 case 0x10ec0880:
538 case 0x10ec0882:
539 case 0x10ec0883:
540 case 0x10ec0885:
Kailang Yang1df88742014-10-29 16:10:13 +0800541 alc_update_coef_idx(codec, 7, 0, 0x2030);
Kailang Yangc9b58002007-10-16 14:30:01 +0200542 break;
Kailang Yangf9423e72008-05-27 12:32:25 +0200543 case 0x10ec0888:
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200544 alc888_coef_init(codec);
Kailang Yangf9423e72008-05-27 12:32:25 +0200545 break;
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200546 }
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200547 break;
548 }
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200549}
Kailang Yangea1fb292008-08-26 12:58:38 +0200550
Takashi Iwai35a39f92019-02-01 11:19:50 +0100551/* get a primary headphone pin if available */
552static hda_nid_t alc_get_hp_pin(struct alc_spec *spec)
553{
554 if (spec->gen.autocfg.hp_pins[0])
555 return spec->gen.autocfg.hp_pins[0];
556 if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
557 return spec->gen.autocfg.line_out_pins[0];
558 return 0;
559}
Takashi Iwai1d045db2011-07-07 18:23:21 +0200560
561/*
562 * Realtek SSID verification
563 */
564
David Henningsson90622912010-10-14 14:50:18 +0200565/* Could be any non-zero and even value. When used as fixup, tells
566 * the driver to ignore any present sku defines.
567 */
568#define ALC_FIXUP_SKU_IGNORE (2)
569
Takashi Iwai23d30f22012-05-07 17:17:32 +0200570static void alc_fixup_sku_ignore(struct hda_codec *codec,
571 const struct hda_fixup *fix, int action)
572{
573 struct alc_spec *spec = codec->spec;
574 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
575 spec->cdefine.fixup = 1;
576 spec->cdefine.sku_cfg = ALC_FIXUP_SKU_IGNORE;
577 }
578}
579
Mengdong Linb5c66112013-11-29 00:35:35 -0500580static void alc_fixup_no_depop_delay(struct hda_codec *codec,
581 const struct hda_fixup *fix, int action)
582{
583 struct alc_spec *spec = codec->spec;
584
Mengdong Lin84d2dc32013-12-02 22:26:03 -0500585 if (action == HDA_FIXUP_ACT_PROBE) {
Mengdong Linb5c66112013-11-29 00:35:35 -0500586 spec->no_depop_delay = 1;
Mengdong Lin84d2dc32013-12-02 22:26:03 -0500587 codec->depop_delay = 0;
588 }
Mengdong Linb5c66112013-11-29 00:35:35 -0500589}
590
Kailang Yangda00c242010-03-19 11:23:45 +0100591static int alc_auto_parse_customize_define(struct hda_codec *codec)
592{
593 unsigned int ass, tmp, i;
Takashi Iwai7fb56222010-03-22 17:09:47 +0100594 unsigned nid = 0;
Kailang Yangda00c242010-03-19 11:23:45 +0100595 struct alc_spec *spec = codec->spec;
596
Takashi Iwaib6cbe512010-07-28 17:43:36 +0200597 spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
598
David Henningsson90622912010-10-14 14:50:18 +0200599 if (spec->cdefine.fixup) {
600 ass = spec->cdefine.sku_cfg;
601 if (ass == ALC_FIXUP_SKU_IGNORE)
602 return -1;
603 goto do_sku;
604 }
605
Takashi Iwai5100cd02014-02-15 10:03:19 +0100606 if (!codec->bus->pci)
607 return -1;
Takashi Iwai7639a062015-03-03 10:07:24 +0100608 ass = codec->core.subsystem_id & 0xffff;
Takashi Iwaib6cbe512010-07-28 17:43:36 +0200609 if (ass != codec->bus->pci->subsystem_device && (ass & 1))
Kailang Yangda00c242010-03-19 11:23:45 +0100610 goto do_sku;
611
612 nid = 0x1d;
Takashi Iwai7639a062015-03-03 10:07:24 +0100613 if (codec->core.vendor_id == 0x10ec0260)
Kailang Yangda00c242010-03-19 11:23:45 +0100614 nid = 0x17;
615 ass = snd_hda_codec_get_pincfg(codec, nid);
616
617 if (!(ass & 1)) {
Takashi Iwai4e76a882014-02-25 12:21:03 +0100618 codec_info(codec, "%s: SKU not ready 0x%08x\n",
Takashi Iwai7639a062015-03-03 10:07:24 +0100619 codec->core.chip_name, ass);
Kailang Yangda00c242010-03-19 11:23:45 +0100620 return -1;
621 }
622
623 /* check sum */
624 tmp = 0;
625 for (i = 1; i < 16; i++) {
626 if ((ass >> i) & 1)
627 tmp++;
628 }
629 if (((ass >> 16) & 0xf) != tmp)
630 return -1;
631
632 spec->cdefine.port_connectivity = ass >> 30;
633 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
634 spec->cdefine.check_sum = (ass >> 16) & 0xf;
635 spec->cdefine.customization = ass >> 8;
636do_sku:
637 spec->cdefine.sku_cfg = ass;
638 spec->cdefine.external_amp = (ass & 0x38) >> 3;
639 spec->cdefine.platform_type = (ass & 0x4) >> 2;
640 spec->cdefine.swap = (ass & 0x2) >> 1;
641 spec->cdefine.override = ass & 0x1;
642
Takashi Iwai4e76a882014-02-25 12:21:03 +0100643 codec_dbg(codec, "SKU: Nid=0x%x sku_cfg=0x%08x\n",
Kailang Yangda00c242010-03-19 11:23:45 +0100644 nid, spec->cdefine.sku_cfg);
Takashi Iwai4e76a882014-02-25 12:21:03 +0100645 codec_dbg(codec, "SKU: port_connectivity=0x%x\n",
Kailang Yangda00c242010-03-19 11:23:45 +0100646 spec->cdefine.port_connectivity);
Takashi Iwai4e76a882014-02-25 12:21:03 +0100647 codec_dbg(codec, "SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
648 codec_dbg(codec, "SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
649 codec_dbg(codec, "SKU: customization=0x%08x\n", spec->cdefine.customization);
650 codec_dbg(codec, "SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
651 codec_dbg(codec, "SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
652 codec_dbg(codec, "SKU: swap=0x%x\n", spec->cdefine.swap);
653 codec_dbg(codec, "SKU: override=0x%x\n", spec->cdefine.override);
Kailang Yangda00c242010-03-19 11:23:45 +0100654
655 return 0;
656}
657
Takashi Iwai08c189f2012-12-19 15:22:24 +0100658/* return the position of NID in the list, or -1 if not found */
659static int find_idx_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
660{
661 int i;
662 for (i = 0; i < nums; i++)
663 if (list[i] == nid)
664 return i;
665 return -1;
666}
Takashi Iwai1d045db2011-07-07 18:23:21 +0200667/* return true if the given NID is found in the list */
Takashi Iwai3af9ee62011-06-27 12:34:01 +0200668static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
669{
Takashi Iwai21268962011-07-07 15:01:13 +0200670 return find_idx_in_nid_list(nid, list, nums) >= 0;
Takashi Iwai3af9ee62011-06-27 12:34:01 +0200671}
672
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200673/* check subsystem ID and set up device-specific initialization;
674 * return 1 if initialized, 0 if invalid SSID
675 */
676/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
677 * 31 ~ 16 : Manufacture ID
678 * 15 ~ 8 : SKU ID
679 * 7 ~ 0 : Assembly ID
680 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
681 */
Takashi Iwai58c57cf2014-01-07 18:22:49 +0100682static int alc_subsystem_id(struct hda_codec *codec, const hda_nid_t *ports)
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200683{
684 unsigned int ass, tmp, i;
685 unsigned nid;
686 struct alc_spec *spec = codec->spec;
687
David Henningsson90622912010-10-14 14:50:18 +0200688 if (spec->cdefine.fixup) {
689 ass = spec->cdefine.sku_cfg;
690 if (ass == ALC_FIXUP_SKU_IGNORE)
691 return 0;
692 goto do_sku;
693 }
694
Takashi Iwai7639a062015-03-03 10:07:24 +0100695 ass = codec->core.subsystem_id & 0xffff;
Takashi Iwai5100cd02014-02-15 10:03:19 +0100696 if (codec->bus->pci &&
697 ass != codec->bus->pci->subsystem_device && (ass & 1))
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200698 goto do_sku;
699
700 /* invalid SSID, check the special NID pin defcfg instead */
701 /*
Sasha Alexandrdef319f2009-06-16 16:00:15 -0400702 * 31~30 : port connectivity
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200703 * 29~21 : reserve
704 * 20 : PCBEEP input
705 * 19~16 : Check sum (15:1)
706 * 15~1 : Custom
707 * 0 : override
708 */
709 nid = 0x1d;
Takashi Iwai7639a062015-03-03 10:07:24 +0100710 if (codec->core.vendor_id == 0x10ec0260)
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200711 nid = 0x17;
712 ass = snd_hda_codec_get_pincfg(codec, nid);
Takashi Iwai4e76a882014-02-25 12:21:03 +0100713 codec_dbg(codec,
714 "realtek: No valid SSID, checking pincfg 0x%08x for NID 0x%x\n",
Takashi Iwaicb6605c2009-04-28 13:03:19 +0200715 ass, nid);
Kailang Yang6227cdc2010-02-25 08:36:52 +0100716 if (!(ass & 1))
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200717 return 0;
718 if ((ass >> 30) != 1) /* no physical connection */
719 return 0;
720
721 /* check sum */
722 tmp = 0;
723 for (i = 1; i < 16; i++) {
724 if ((ass >> i) & 1)
725 tmp++;
726 }
727 if (((ass >> 16) & 0xf) != tmp)
728 return 0;
729do_sku:
Takashi Iwai4e76a882014-02-25 12:21:03 +0100730 codec_dbg(codec, "realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
Takashi Iwai7639a062015-03-03 10:07:24 +0100731 ass & 0xffff, codec->core.vendor_id);
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200732 /*
733 * 0 : override
734 * 1 : Swap Jack
735 * 2 : 0 --> Desktop, 1 --> Laptop
736 * 3~5 : External Amplifier control
737 * 7~6 : Reserved
738 */
739 tmp = (ass & 0x38) >> 3; /* external Amp control */
Takashi Iwai1c76aa52018-06-21 16:37:54 +0200740 if (spec->init_amp == ALC_INIT_UNDEFINED) {
741 switch (tmp) {
742 case 1:
Takashi Iwai5579cd62018-06-19 22:22:41 +0200743 alc_setup_gpio(codec, 0x01);
Takashi Iwai1c76aa52018-06-21 16:37:54 +0200744 break;
745 case 3:
Takashi Iwai5579cd62018-06-19 22:22:41 +0200746 alc_setup_gpio(codec, 0x02);
Takashi Iwai1c76aa52018-06-21 16:37:54 +0200747 break;
748 case 7:
Takashi Iwai5579cd62018-06-19 22:22:41 +0200749 alc_setup_gpio(codec, 0x03);
Takashi Iwai1c76aa52018-06-21 16:37:54 +0200750 break;
751 case 5:
752 default:
753 spec->init_amp = ALC_INIT_DEFAULT;
754 break;
755 }
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200756 }
757
758 /* is laptop or Desktop and enable the function "Mute internal speaker
759 * when the external headphone out jack is plugged"
760 */
761 if (!(ass & 0x8000))
762 return 1;
763 /*
764 * 10~8 : Jack location
765 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
766 * 14~13: Resvered
767 * 15 : 1 --> enable the function "Mute internal speaker
768 * when the external headphone out jack is plugged"
769 */
Takashi Iwai35a39f92019-02-01 11:19:50 +0100770 if (!alc_get_hp_pin(spec)) {
Takashi Iwai01d48252009-10-06 13:21:54 +0200771 hda_nid_t nid;
Kailang Yangc9b58002007-10-16 14:30:01 +0200772 tmp = (ass >> 11) & 0x3; /* HP to chassis */
Takashi Iwai58c57cf2014-01-07 18:22:49 +0100773 nid = ports[tmp];
Takashi Iwai08c189f2012-12-19 15:22:24 +0100774 if (found_in_nid_list(nid, spec->gen.autocfg.line_out_pins,
775 spec->gen.autocfg.line_outs))
Takashi Iwai3af9ee62011-06-27 12:34:01 +0200776 return 1;
Takashi Iwai08c189f2012-12-19 15:22:24 +0100777 spec->gen.autocfg.hp_pins[0] = nid;
Kailang Yangc9b58002007-10-16 14:30:01 +0200778 }
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200779 return 1;
780}
Kailang Yangea1fb292008-08-26 12:58:38 +0200781
Takashi Iwai3e6179b2011-07-08 16:55:13 +0200782/* Check the validity of ALC subsystem-id
783 * ports contains an array of 4 pin NIDs for port-A, E, D and I */
784static void alc_ssid_check(struct hda_codec *codec, const hda_nid_t *ports)
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200785{
Takashi Iwai58c57cf2014-01-07 18:22:49 +0100786 if (!alc_subsystem_id(codec, ports)) {
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200787 struct alc_spec *spec = codec->spec;
Takashi Iwai4e76a882014-02-25 12:21:03 +0100788 codec_dbg(codec,
789 "realtek: Enable default setup for auto mode as fallback\n");
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200790 spec->init_amp = ALC_INIT_DEFAULT;
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200791 }
Takashi Iwai21268962011-07-07 15:01:13 +0200792}
Takashi Iwai1a1455d2011-04-28 17:36:18 +0200793
Takashi Iwai41e41f12005-06-08 14:48:49 +0200794/*
Takashi Iwai1d045db2011-07-07 18:23:21 +0200795 */
796
David Henningsson9d36a7d2014-10-07 10:18:42 +0200797static void alc_fixup_inv_dmic(struct hda_codec *codec,
798 const struct hda_fixup *fix, int action)
Takashi Iwai125821a2012-06-22 14:30:29 +0200799{
800 struct alc_spec *spec = codec->spec;
Takashi Iwai668d1e92012-11-29 14:10:17 +0100801
David Henningsson9d36a7d2014-10-07 10:18:42 +0200802 spec->gen.inv_dmic_split = 1;
Takashi Iwai6e72aa52012-06-25 10:52:25 +0200803}
804
Takashi Iwai603c4012008-07-30 15:01:44 +0200805
Takashi Iwai2eab6942012-12-18 15:30:41 +0100806static int alc_build_controls(struct hda_codec *codec)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700807{
Takashi Iwaia5cb4632018-06-20 12:50:11 +0200808 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700809
Takashi Iwai08c189f2012-12-19 15:22:24 +0100810 err = snd_hda_gen_build_controls(codec);
811 if (err < 0)
812 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700813
Takashi Iwai1727a772013-01-10 09:52:52 +0100814 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_BUILD);
Takashi Iwai420b0fe2012-03-12 12:35:27 +0100815 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700816}
817
Takashi Iwaie9edcee2005-06-13 14:16:38 +0200818
Linus Torvalds1da177e2005-04-16 15:20:36 -0700819/*
Takashi Iwaiae6b8132006-03-03 16:47:17 +0100820 * Common callbacks
Takashi Iwaie9edcee2005-06-13 14:16:38 +0200821 */
Takashi Iwai16ded522005-06-10 19:58:24 +0200822
Takashi Iwaic9af7532019-05-10 11:01:43 +0200823static void alc_pre_init(struct hda_codec *codec)
824{
825 alc_fill_eapd_coef(codec);
826}
827
Kailang Yangaeac1a02019-05-16 16:10:44 +0800828#define is_s3_resume(codec) \
829 ((codec)->core.dev.power.power_state.event == PM_EVENT_RESUME)
Takashi Iwaic9af7532019-05-10 11:01:43 +0200830#define is_s4_resume(codec) \
831 ((codec)->core.dev.power.power_state.event == PM_EVENT_RESTORE)
832
Linus Torvalds1da177e2005-04-16 15:20:36 -0700833static int alc_init(struct hda_codec *codec)
834{
835 struct alc_spec *spec = codec->spec;
Takashi Iwaie9edcee2005-06-13 14:16:38 +0200836
Takashi Iwaic9af7532019-05-10 11:01:43 +0200837 /* hibernation resume needs the full chip initialization */
838 if (is_s4_resume(codec))
839 alc_pre_init(codec);
840
Takashi Iwai546bb672012-03-07 08:37:19 +0100841 if (spec->init_hook)
842 spec->init_hook(codec);
Kailang Yang526af6e2012-03-07 08:25:20 +0100843
Takashi Iwai89781d02019-08-30 12:03:38 +0200844 spec->gen.skip_verbs = 1; /* applied in below */
Kailang Yang607ca3b2019-04-26 16:35:41 +0800845 snd_hda_gen_init(codec);
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200846 alc_fix_pll(codec);
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200847 alc_auto_init_amp(codec, spec->init_amp);
Takashi Iwai89781d02019-08-30 12:03:38 +0200848 snd_hda_apply_verbs(codec); /* apply verbs here after own init */
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200849
Takashi Iwai1727a772013-01-10 09:52:52 +0100850 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_INIT);
Takashi Iwaie08a0072006-09-07 17:52:14 +0200851
Linus Torvalds1da177e2005-04-16 15:20:36 -0700852 return 0;
853}
854
Takashi Iwaia4e09aa2009-12-27 11:22:24 +0100855static inline void alc_shutup(struct hda_codec *codec)
856{
Takashi Iwai1c7161532011-04-07 10:37:16 +0200857 struct alc_spec *spec = codec->spec;
858
Takashi Iwaic7273bd2018-06-12 16:09:57 +0200859 if (!snd_hda_get_bool_hint(codec, "shutup"))
860 return; /* disabled explicitly by hints */
861
Takashi Iwai1c7161532011-04-07 10:37:16 +0200862 if (spec && spec->shutup)
863 spec->shutup(codec);
Takashi Iwai9bfb2842013-07-24 14:31:50 +0200864 else
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +0100865 alc_shutup_pins(codec);
Takashi Iwaia4e09aa2009-12-27 11:22:24 +0100866}
867
Takashi Iwai70a09762015-12-15 14:59:58 +0100868static void alc_reboot_notify(struct hda_codec *codec)
869{
870 struct alc_spec *spec = codec->spec;
871
872 if (spec && spec->reboot_notify)
873 spec->reboot_notify(codec);
874 else
875 alc_shutup(codec);
876}
877
Takashi Iwai8a02c0c2014-02-10 18:09:45 +0100878#define alc_free snd_hda_gen_free
Linus Torvalds1da177e2005-04-16 15:20:36 -0700879
Takashi Iwai83012a72012-08-24 18:38:08 +0200880#ifdef CONFIG_PM
Daniel T Chenc97259d2009-12-27 18:52:08 -0500881static void alc_power_eapd(struct hda_codec *codec)
882{
Takashi Iwai691f1fc2011-04-07 10:31:43 +0200883 alc_auto_setup_eapd(codec, false);
Daniel T Chenc97259d2009-12-27 18:52:08 -0500884}
885
Takashi Iwai68cb2b52012-07-02 15:20:37 +0200886static int alc_suspend(struct hda_codec *codec)
Hector Martinf5de24b2009-12-20 22:51:31 +0100887{
888 struct alc_spec *spec = codec->spec;
Takashi Iwaia4e09aa2009-12-27 11:22:24 +0100889 alc_shutup(codec);
Hector Martinf5de24b2009-12-20 22:51:31 +0100890 if (spec && spec->power_hook)
Daniel T Chenc97259d2009-12-27 18:52:08 -0500891 spec->power_hook(codec);
Hector Martinf5de24b2009-12-20 22:51:31 +0100892 return 0;
893}
894#endif
895
Takashi Iwai2a439522011-07-26 09:52:50 +0200896#ifdef CONFIG_PM
Takashi Iwaie044c392008-10-27 16:56:24 +0100897static int alc_resume(struct hda_codec *codec)
898{
Kailang Yang97a26572013-11-29 00:35:26 -0500899 struct alc_spec *spec = codec->spec;
900
901 if (!spec->no_depop_delay)
902 msleep(150); /* to avoid pop noise */
Takashi Iwaie044c392008-10-27 16:56:24 +0100903 codec->patch_ops.init(codec);
Takashi Iwaieeecd9d2015-02-25 15:18:50 +0100904 regcache_sync(codec->core.regmap);
Takashi Iwai9e5341b2010-09-21 09:57:06 +0200905 hda_call_check_power_status(codec, 0x01);
Takashi Iwaie044c392008-10-27 16:56:24 +0100906 return 0;
907}
Takashi Iwaie044c392008-10-27 16:56:24 +0100908#endif
909
Linus Torvalds1da177e2005-04-16 15:20:36 -0700910/*
911 */
Takashi Iwaia9111322011-05-02 11:30:18 +0200912static const struct hda_codec_ops alc_patch_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700913 .build_controls = alc_build_controls,
Takashi Iwai08c189f2012-12-19 15:22:24 +0100914 .build_pcms = snd_hda_gen_build_pcms,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700915 .init = alc_init,
916 .free = alc_free,
David Henningsson29adc4b2012-09-25 11:31:00 +0200917 .unsol_event = snd_hda_jack_unsol_event,
Takashi Iwai2a439522011-07-26 09:52:50 +0200918#ifdef CONFIG_PM
Takashi Iwaie044c392008-10-27 16:56:24 +0100919 .resume = alc_resume,
Hector Martinf5de24b2009-12-20 22:51:31 +0100920 .suspend = alc_suspend,
Takashi Iwaifce52a32013-01-07 12:42:48 +0100921 .check_power_status = snd_hda_gen_check_power_status,
Takashi Iwaicb53c622007-08-10 17:21:45 +0200922#endif
Takashi Iwai70a09762015-12-15 14:59:58 +0100923 .reboot_notify = alc_reboot_notify,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700924};
925
David Henningsson29adc4b2012-09-25 11:31:00 +0200926
Takashi Iwaided255b2015-10-01 17:59:43 +0200927#define alc_codec_rename(codec, name) snd_hda_codec_set_name(codec, name)
Kailang Yangc027ddc2010-03-19 11:33:06 +0100928
Takashi Iwai2fa522b2005-05-12 14:51:12 +0200929/*
Kailang Yang4b016932013-11-28 11:55:09 +0100930 * Rename codecs appropriately from COEF value or subvendor id
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200931 */
932struct alc_codec_rename_table {
933 unsigned int vendor_id;
934 unsigned short coef_mask;
935 unsigned short coef_bits;
936 const char *name;
937};
938
Kailang Yang4b016932013-11-28 11:55:09 +0100939struct alc_codec_rename_pci_table {
940 unsigned int codec_vendor_id;
941 unsigned short pci_subvendor;
942 unsigned short pci_subdevice;
943 const char *name;
944};
945
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200946static struct alc_codec_rename_table rename_tbl[] = {
Kailang Yange6e5f7a2014-06-06 16:46:43 +0800947 { 0x10ec0221, 0xf00f, 0x1003, "ALC231" },
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200948 { 0x10ec0269, 0xfff0, 0x3010, "ALC277" },
949 { 0x10ec0269, 0xf0f0, 0x2010, "ALC259" },
950 { 0x10ec0269, 0xf0f0, 0x3010, "ALC258" },
951 { 0x10ec0269, 0x00f0, 0x0010, "ALC269VB" },
952 { 0x10ec0269, 0xffff, 0xa023, "ALC259" },
953 { 0x10ec0269, 0xffff, 0x6023, "ALC281X" },
954 { 0x10ec0269, 0x00f0, 0x0020, "ALC269VC" },
Kailang Yangadcc70b2012-05-25 08:08:38 +0200955 { 0x10ec0269, 0x00f0, 0x0030, "ALC269VD" },
Kailang Yange6e5f7a2014-06-06 16:46:43 +0800956 { 0x10ec0662, 0xffff, 0x4020, "ALC656" },
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200957 { 0x10ec0887, 0x00f0, 0x0030, "ALC887-VD" },
958 { 0x10ec0888, 0x00f0, 0x0030, "ALC888-VD" },
959 { 0x10ec0888, 0xf0f0, 0x3020, "ALC886" },
960 { 0x10ec0899, 0x2000, 0x2000, "ALC899" },
961 { 0x10ec0892, 0xffff, 0x8020, "ALC661" },
962 { 0x10ec0892, 0xffff, 0x8011, "ALC661" },
963 { 0x10ec0892, 0xffff, 0x4011, "ALC656" },
964 { } /* terminator */
965};
966
Kailang Yang4b016932013-11-28 11:55:09 +0100967static struct alc_codec_rename_pci_table rename_pci_tbl[] = {
968 { 0x10ec0280, 0x1028, 0, "ALC3220" },
969 { 0x10ec0282, 0x1028, 0, "ALC3221" },
970 { 0x10ec0283, 0x1028, 0, "ALC3223" },
Kailang Yang193177d2014-04-23 16:06:13 +0800971 { 0x10ec0288, 0x1028, 0, "ALC3263" },
Kailang Yang4b016932013-11-28 11:55:09 +0100972 { 0x10ec0292, 0x1028, 0, "ALC3226" },
Kailang Yang193177d2014-04-23 16:06:13 +0800973 { 0x10ec0293, 0x1028, 0, "ALC3235" },
Kailang Yang4b016932013-11-28 11:55:09 +0100974 { 0x10ec0255, 0x1028, 0, "ALC3234" },
975 { 0x10ec0668, 0x1028, 0, "ALC3661" },
Kailang Yange6e5f7a2014-06-06 16:46:43 +0800976 { 0x10ec0275, 0x1028, 0, "ALC3260" },
977 { 0x10ec0899, 0x1028, 0, "ALC3861" },
Kailang Yang2c674fa2015-05-05 15:02:42 +0800978 { 0x10ec0298, 0x1028, 0, "ALC3266" },
Kailang Yang736f20a2017-10-20 15:06:34 +0800979 { 0x10ec0236, 0x1028, 0, "ALC3204" },
Kailang Yang82324502015-05-25 17:16:49 +0800980 { 0x10ec0256, 0x1028, 0, "ALC3246" },
Kailang Yang42314302016-02-03 15:03:50 +0800981 { 0x10ec0225, 0x1028, 0, "ALC3253" },
Kailang Yang7d727862016-05-24 16:46:07 +0800982 { 0x10ec0295, 0x1028, 0, "ALC3254" },
Kailang Yang28f1f9b2017-01-04 14:49:07 +0800983 { 0x10ec0299, 0x1028, 0, "ALC3271" },
Kailang Yange6e5f7a2014-06-06 16:46:43 +0800984 { 0x10ec0670, 0x1025, 0, "ALC669X" },
985 { 0x10ec0676, 0x1025, 0, "ALC679X" },
986 { 0x10ec0282, 0x1043, 0, "ALC3229" },
987 { 0x10ec0233, 0x1043, 0, "ALC3236" },
988 { 0x10ec0280, 0x103c, 0, "ALC3228" },
989 { 0x10ec0282, 0x103c, 0, "ALC3227" },
990 { 0x10ec0286, 0x103c, 0, "ALC3242" },
991 { 0x10ec0290, 0x103c, 0, "ALC3241" },
992 { 0x10ec0668, 0x103c, 0, "ALC3662" },
993 { 0x10ec0283, 0x17aa, 0, "ALC3239" },
994 { 0x10ec0292, 0x17aa, 0, "ALC3232" },
Kailang Yang4b016932013-11-28 11:55:09 +0100995 { } /* terminator */
996};
997
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200998static int alc_codec_rename_from_preset(struct hda_codec *codec)
999{
1000 const struct alc_codec_rename_table *p;
Kailang Yang4b016932013-11-28 11:55:09 +01001001 const struct alc_codec_rename_pci_table *q;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02001002
1003 for (p = rename_tbl; p->vendor_id; p++) {
Takashi Iwai7639a062015-03-03 10:07:24 +01001004 if (p->vendor_id != codec->core.vendor_id)
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02001005 continue;
Takashi Iwai1bb7e432011-10-17 16:50:59 +02001006 if ((alc_get_coef0(codec) & p->coef_mask) == p->coef_bits)
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02001007 return alc_codec_rename(codec, p->name);
1008 }
Kailang Yang4b016932013-11-28 11:55:09 +01001009
Takashi Iwai5100cd02014-02-15 10:03:19 +01001010 if (!codec->bus->pci)
1011 return 0;
Kailang Yang4b016932013-11-28 11:55:09 +01001012 for (q = rename_pci_tbl; q->codec_vendor_id; q++) {
Takashi Iwai7639a062015-03-03 10:07:24 +01001013 if (q->codec_vendor_id != codec->core.vendor_id)
Kailang Yang4b016932013-11-28 11:55:09 +01001014 continue;
1015 if (q->pci_subvendor != codec->bus->pci->subsystem_vendor)
1016 continue;
1017 if (!q->pci_subdevice ||
1018 q->pci_subdevice == codec->bus->pci->subsystem_device)
1019 return alc_codec_rename(codec, q->name);
1020 }
1021
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02001022 return 0;
1023}
1024
Takashi Iwaie4770622011-07-08 11:11:35 +02001025
1026/*
Takashi Iwai1d045db2011-07-07 18:23:21 +02001027 * Digital-beep handlers
1028 */
1029#ifdef CONFIG_SND_HDA_INPUT_BEEP
Takashi Iwaifea80fa2018-06-20 12:52:46 +02001030
1031/* additional beep mixers; private_value will be overwritten */
1032static const struct snd_kcontrol_new alc_beep_mixer[] = {
1033 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
1034 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
1035};
1036
1037/* set up and create beep controls */
1038static int set_beep_amp(struct alc_spec *spec, hda_nid_t nid,
1039 int idx, int dir)
1040{
1041 struct snd_kcontrol_new *knew;
1042 unsigned int beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir);
1043 int i;
1044
1045 for (i = 0; i < ARRAY_SIZE(alc_beep_mixer); i++) {
1046 knew = snd_hda_gen_add_kctl(&spec->gen, NULL,
1047 &alc_beep_mixer[i]);
1048 if (!knew)
1049 return -ENOMEM;
1050 knew->private_value = beep_amp;
1051 }
1052 return 0;
1053}
Takashi Iwai1d045db2011-07-07 18:23:21 +02001054
1055static const struct snd_pci_quirk beep_white_list[] = {
Duncan Roe71100052012-10-10 14:19:50 +02001056 SND_PCI_QUIRK(0x1043, 0x103c, "ASUS", 1),
W. Trevor Kinga4b7f21d2014-03-29 17:47:24 -07001057 SND_PCI_QUIRK(0x1043, 0x115d, "ASUS", 1),
Takashi Iwai1d045db2011-07-07 18:23:21 +02001058 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
Takashi Iwai8554ee42013-02-25 09:54:43 +01001059 SND_PCI_QUIRK(0x1043, 0x8376, "EeePC", 1),
Takashi Iwai1d045db2011-07-07 18:23:21 +02001060 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
1061 SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1),
1062 SND_PCI_QUIRK(0x1043, 0x834a, "EeePC", 1),
Takashi Iwai78f8baf2012-03-06 14:02:32 +01001063 SND_PCI_QUIRK(0x1458, 0xa002, "GA-MA790X", 1),
Takashi Iwai1d045db2011-07-07 18:23:21 +02001064 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
Takashi Iwai051c78a2019-08-22 09:58:07 +02001065 /* blacklist -- no beep available */
1066 SND_PCI_QUIRK(0x17aa, 0x309e, "Lenovo ThinkCentre M73", 0),
1067 SND_PCI_QUIRK(0x17aa, 0x30a3, "Lenovo ThinkCentre M93", 0),
Takashi Iwai1d045db2011-07-07 18:23:21 +02001068 {}
1069};
1070
1071static inline int has_cdefine_beep(struct hda_codec *codec)
1072{
1073 struct alc_spec *spec = codec->spec;
1074 const struct snd_pci_quirk *q;
1075 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
1076 if (q)
1077 return q->value;
1078 return spec->cdefine.enable_pcbeep;
1079}
1080#else
Takashi Iwaifea80fa2018-06-20 12:52:46 +02001081#define set_beep_amp(spec, nid, idx, dir) 0
Takashi Iwai1d045db2011-07-07 18:23:21 +02001082#define has_cdefine_beep(codec) 0
1083#endif
1084
1085/* parse the BIOS configuration and set up the alc_spec */
1086/* return 1 if successful, 0 if the proper config is not found,
1087 * or a negative error code
1088 */
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001089static int alc_parse_auto_config(struct hda_codec *codec,
1090 const hda_nid_t *ignore_nids,
1091 const hda_nid_t *ssid_nids)
Takashi Iwai1d045db2011-07-07 18:23:21 +02001092{
1093 struct alc_spec *spec = codec->spec;
Takashi Iwai08c189f2012-12-19 15:22:24 +01001094 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001095 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001096
Takashi Iwai53c334a2011-08-23 18:27:14 +02001097 err = snd_hda_parse_pin_defcfg(codec, cfg, ignore_nids,
1098 spec->parse_flags);
Takashi Iwai1d045db2011-07-07 18:23:21 +02001099 if (err < 0)
1100 return err;
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001101
1102 if (ssid_nids)
1103 alc_ssid_check(codec, ssid_nids);
1104
Takashi Iwai08c189f2012-12-19 15:22:24 +01001105 err = snd_hda_gen_parse_auto_config(codec, cfg);
1106 if (err < 0)
1107 return err;
Takashi Iwai070cff42012-02-21 12:54:17 +01001108
Takashi Iwai1d045db2011-07-07 18:23:21 +02001109 return 1;
1110}
1111
Takashi Iwai3de95172012-05-07 18:03:15 +02001112/* common preparation job for alc_spec */
1113static int alc_alloc_spec(struct hda_codec *codec, hda_nid_t mixer_nid)
1114{
1115 struct alc_spec *spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1116 int err;
1117
1118 if (!spec)
1119 return -ENOMEM;
1120 codec->spec = spec;
Takashi Iwai08c189f2012-12-19 15:22:24 +01001121 snd_hda_gen_spec_init(&spec->gen);
1122 spec->gen.mixer_nid = mixer_nid;
1123 spec->gen.own_eapd_ctl = 1;
Takashi Iwai1098b7c2012-12-17 20:03:15 +01001124 codec->single_adc_amp = 1;
Takashi Iwai08c189f2012-12-19 15:22:24 +01001125 /* FIXME: do we need this for all Realtek codec models? */
1126 codec->spdif_status_reset = 1;
Takashi Iwai225068a2015-05-29 10:42:14 +02001127 codec->patch_ops = alc_patch_ops;
Takashi Iwai3de95172012-05-07 18:03:15 +02001128
1129 err = alc_codec_rename_from_preset(codec);
1130 if (err < 0) {
1131 kfree(spec);
1132 return err;
1133 }
1134 return 0;
1135}
1136
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001137static int alc880_parse_auto_config(struct hda_codec *codec)
1138{
1139 static const hda_nid_t alc880_ignore[] = { 0x1d, 0 };
Jesper Juhl7d7eb9e2012-04-12 22:11:25 +02001140 static const hda_nid_t alc880_ssids[] = { 0x15, 0x1b, 0x14, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001141 return alc_parse_auto_config(codec, alc880_ignore, alc880_ssids);
1142}
1143
Takashi Iwai1d045db2011-07-07 18:23:21 +02001144/*
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001145 * ALC880 fix-ups
1146 */
1147enum {
Takashi Iwai411225a2012-02-20 17:48:19 +01001148 ALC880_FIXUP_GPIO1,
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001149 ALC880_FIXUP_GPIO2,
1150 ALC880_FIXUP_MEDION_RIM,
Takashi Iwaidc6af522012-02-17 16:18:59 +01001151 ALC880_FIXUP_LG,
Takashi Iwaidb8a38e2013-08-09 12:34:42 +02001152 ALC880_FIXUP_LG_LW25,
Takashi Iwaif02aab52012-02-17 16:33:56 +01001153 ALC880_FIXUP_W810,
Takashi Iwai27e917f2012-02-17 17:49:54 +01001154 ALC880_FIXUP_EAPD_COEF,
Takashi Iwaib9368f52012-02-17 17:54:44 +01001155 ALC880_FIXUP_TCL_S700,
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001156 ALC880_FIXUP_VOL_KNOB,
1157 ALC880_FIXUP_FUJITSU,
Takashi Iwaiba533812012-02-20 16:36:52 +01001158 ALC880_FIXUP_F1734,
Takashi Iwai817de922012-02-20 17:20:48 +01001159 ALC880_FIXUP_UNIWILL,
Takashi Iwai967b88c2012-02-20 17:31:02 +01001160 ALC880_FIXUP_UNIWILL_DIG,
Takashi Iwai96e225f2012-02-20 17:41:51 +01001161 ALC880_FIXUP_Z71V,
Takashi Iwai487a5882013-11-07 07:29:30 +01001162 ALC880_FIXUP_ASUS_W5A,
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001163 ALC880_FIXUP_3ST_BASE,
1164 ALC880_FIXUP_3ST,
1165 ALC880_FIXUP_3ST_DIG,
1166 ALC880_FIXUP_5ST_BASE,
1167 ALC880_FIXUP_5ST,
1168 ALC880_FIXUP_5ST_DIG,
1169 ALC880_FIXUP_6ST_BASE,
1170 ALC880_FIXUP_6ST,
1171 ALC880_FIXUP_6ST_DIG,
Takashi Iwai53971452013-01-23 18:21:37 +01001172 ALC880_FIXUP_6ST_AUTOMUTE,
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001173};
1174
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001175/* enable the volume-knob widget support on NID 0x21 */
1176static void alc880_fixup_vol_knob(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001177 const struct hda_fixup *fix, int action)
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001178{
Takashi Iwai1727a772013-01-10 09:52:52 +01001179 if (action == HDA_FIXUP_ACT_PROBE)
Takashi Iwai62f949b2014-09-11 14:06:53 +02001180 snd_hda_jack_detect_enable_callback(codec, 0x21,
1181 alc_update_knob_master);
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001182}
1183
Takashi Iwai1727a772013-01-10 09:52:52 +01001184static const struct hda_fixup alc880_fixups[] = {
Takashi Iwai411225a2012-02-20 17:48:19 +01001185 [ALC880_FIXUP_GPIO1] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02001186 .type = HDA_FIXUP_FUNC,
1187 .v.func = alc_fixup_gpio1,
Takashi Iwai411225a2012-02-20 17:48:19 +01001188 },
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001189 [ALC880_FIXUP_GPIO2] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02001190 .type = HDA_FIXUP_FUNC,
1191 .v.func = alc_fixup_gpio2,
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001192 },
1193 [ALC880_FIXUP_MEDION_RIM] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001194 .type = HDA_FIXUP_VERBS,
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001195 .v.verbs = (const struct hda_verb[]) {
1196 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
1197 { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
1198 { }
1199 },
1200 .chained = true,
1201 .chain_id = ALC880_FIXUP_GPIO2,
1202 },
Takashi Iwaidc6af522012-02-17 16:18:59 +01001203 [ALC880_FIXUP_LG] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001204 .type = HDA_FIXUP_PINS,
1205 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaidc6af522012-02-17 16:18:59 +01001206 /* disable bogus unused pins */
1207 { 0x16, 0x411111f0 },
1208 { 0x18, 0x411111f0 },
1209 { 0x1a, 0x411111f0 },
1210 { }
1211 }
1212 },
Takashi Iwaidb8a38e2013-08-09 12:34:42 +02001213 [ALC880_FIXUP_LG_LW25] = {
1214 .type = HDA_FIXUP_PINS,
1215 .v.pins = (const struct hda_pintbl[]) {
1216 { 0x1a, 0x0181344f }, /* line-in */
1217 { 0x1b, 0x0321403f }, /* headphone */
1218 { }
1219 }
1220 },
Takashi Iwaif02aab52012-02-17 16:33:56 +01001221 [ALC880_FIXUP_W810] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001222 .type = HDA_FIXUP_PINS,
1223 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaif02aab52012-02-17 16:33:56 +01001224 /* disable bogus unused pins */
1225 { 0x17, 0x411111f0 },
1226 { }
1227 },
1228 .chained = true,
1229 .chain_id = ALC880_FIXUP_GPIO2,
1230 },
Takashi Iwai27e917f2012-02-17 17:49:54 +01001231 [ALC880_FIXUP_EAPD_COEF] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001232 .type = HDA_FIXUP_VERBS,
Takashi Iwai27e917f2012-02-17 17:49:54 +01001233 .v.verbs = (const struct hda_verb[]) {
1234 /* change to EAPD mode */
1235 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
1236 { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
1237 {}
1238 },
1239 },
Takashi Iwaib9368f52012-02-17 17:54:44 +01001240 [ALC880_FIXUP_TCL_S700] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001241 .type = HDA_FIXUP_VERBS,
Takashi Iwaib9368f52012-02-17 17:54:44 +01001242 .v.verbs = (const struct hda_verb[]) {
1243 /* change to EAPD mode */
1244 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
1245 { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
1246 {}
1247 },
1248 .chained = true,
1249 .chain_id = ALC880_FIXUP_GPIO2,
1250 },
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001251 [ALC880_FIXUP_VOL_KNOB] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001252 .type = HDA_FIXUP_FUNC,
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001253 .v.func = alc880_fixup_vol_knob,
1254 },
1255 [ALC880_FIXUP_FUJITSU] = {
1256 /* override all pins as BIOS on old Amilo is broken */
Takashi Iwai1727a772013-01-10 09:52:52 +01001257 .type = HDA_FIXUP_PINS,
1258 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaibb148bd2015-08-13 18:02:39 +02001259 { 0x14, 0x0121401f }, /* HP */
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001260 { 0x15, 0x99030120 }, /* speaker */
1261 { 0x16, 0x99030130 }, /* bass speaker */
1262 { 0x17, 0x411111f0 }, /* N/A */
1263 { 0x18, 0x411111f0 }, /* N/A */
1264 { 0x19, 0x01a19950 }, /* mic-in */
1265 { 0x1a, 0x411111f0 }, /* N/A */
1266 { 0x1b, 0x411111f0 }, /* N/A */
1267 { 0x1c, 0x411111f0 }, /* N/A */
1268 { 0x1d, 0x411111f0 }, /* N/A */
1269 { 0x1e, 0x01454140 }, /* SPDIF out */
1270 { }
1271 },
1272 .chained = true,
1273 .chain_id = ALC880_FIXUP_VOL_KNOB,
1274 },
Takashi Iwaiba533812012-02-20 16:36:52 +01001275 [ALC880_FIXUP_F1734] = {
1276 /* almost compatible with FUJITSU, but no bass and SPDIF */
Takashi Iwai1727a772013-01-10 09:52:52 +01001277 .type = HDA_FIXUP_PINS,
1278 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaibb148bd2015-08-13 18:02:39 +02001279 { 0x14, 0x0121401f }, /* HP */
Takashi Iwaiba533812012-02-20 16:36:52 +01001280 { 0x15, 0x99030120 }, /* speaker */
1281 { 0x16, 0x411111f0 }, /* N/A */
1282 { 0x17, 0x411111f0 }, /* N/A */
1283 { 0x18, 0x411111f0 }, /* N/A */
1284 { 0x19, 0x01a19950 }, /* mic-in */
1285 { 0x1a, 0x411111f0 }, /* N/A */
1286 { 0x1b, 0x411111f0 }, /* N/A */
1287 { 0x1c, 0x411111f0 }, /* N/A */
1288 { 0x1d, 0x411111f0 }, /* N/A */
1289 { 0x1e, 0x411111f0 }, /* N/A */
1290 { }
1291 },
1292 .chained = true,
1293 .chain_id = ALC880_FIXUP_VOL_KNOB,
1294 },
Takashi Iwai817de922012-02-20 17:20:48 +01001295 [ALC880_FIXUP_UNIWILL] = {
1296 /* need to fix HP and speaker pins to be parsed correctly */
Takashi Iwai1727a772013-01-10 09:52:52 +01001297 .type = HDA_FIXUP_PINS,
1298 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai817de922012-02-20 17:20:48 +01001299 { 0x14, 0x0121411f }, /* HP */
1300 { 0x15, 0x99030120 }, /* speaker */
1301 { 0x16, 0x99030130 }, /* bass speaker */
1302 { }
1303 },
1304 },
Takashi Iwai967b88c2012-02-20 17:31:02 +01001305 [ALC880_FIXUP_UNIWILL_DIG] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001306 .type = HDA_FIXUP_PINS,
1307 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai967b88c2012-02-20 17:31:02 +01001308 /* disable bogus unused pins */
1309 { 0x17, 0x411111f0 },
1310 { 0x19, 0x411111f0 },
1311 { 0x1b, 0x411111f0 },
1312 { 0x1f, 0x411111f0 },
1313 { }
1314 }
1315 },
Takashi Iwai96e225f2012-02-20 17:41:51 +01001316 [ALC880_FIXUP_Z71V] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001317 .type = HDA_FIXUP_PINS,
1318 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai96e225f2012-02-20 17:41:51 +01001319 /* set up the whole pins as BIOS is utterly broken */
1320 { 0x14, 0x99030120 }, /* speaker */
1321 { 0x15, 0x0121411f }, /* HP */
1322 { 0x16, 0x411111f0 }, /* N/A */
1323 { 0x17, 0x411111f0 }, /* N/A */
1324 { 0x18, 0x01a19950 }, /* mic-in */
1325 { 0x19, 0x411111f0 }, /* N/A */
1326 { 0x1a, 0x01813031 }, /* line-in */
1327 { 0x1b, 0x411111f0 }, /* N/A */
1328 { 0x1c, 0x411111f0 }, /* N/A */
1329 { 0x1d, 0x411111f0 }, /* N/A */
1330 { 0x1e, 0x0144111e }, /* SPDIF */
1331 { }
1332 }
1333 },
Takashi Iwai487a5882013-11-07 07:29:30 +01001334 [ALC880_FIXUP_ASUS_W5A] = {
1335 .type = HDA_FIXUP_PINS,
1336 .v.pins = (const struct hda_pintbl[]) {
1337 /* set up the whole pins as BIOS is utterly broken */
1338 { 0x14, 0x0121411f }, /* HP */
1339 { 0x15, 0x411111f0 }, /* N/A */
1340 { 0x16, 0x411111f0 }, /* N/A */
1341 { 0x17, 0x411111f0 }, /* N/A */
1342 { 0x18, 0x90a60160 }, /* mic */
1343 { 0x19, 0x411111f0 }, /* N/A */
1344 { 0x1a, 0x411111f0 }, /* N/A */
1345 { 0x1b, 0x411111f0 }, /* N/A */
1346 { 0x1c, 0x411111f0 }, /* N/A */
1347 { 0x1d, 0x411111f0 }, /* N/A */
1348 { 0x1e, 0xb743111e }, /* SPDIF out */
1349 { }
1350 },
1351 .chained = true,
1352 .chain_id = ALC880_FIXUP_GPIO1,
1353 },
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001354 [ALC880_FIXUP_3ST_BASE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001355 .type = HDA_FIXUP_PINS,
1356 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001357 { 0x14, 0x01014010 }, /* line-out */
1358 { 0x15, 0x411111f0 }, /* N/A */
1359 { 0x16, 0x411111f0 }, /* N/A */
1360 { 0x17, 0x411111f0 }, /* N/A */
1361 { 0x18, 0x01a19c30 }, /* mic-in */
1362 { 0x19, 0x0121411f }, /* HP */
1363 { 0x1a, 0x01813031 }, /* line-in */
1364 { 0x1b, 0x02a19c40 }, /* front-mic */
1365 { 0x1c, 0x411111f0 }, /* N/A */
1366 { 0x1d, 0x411111f0 }, /* N/A */
1367 /* 0x1e is filled in below */
1368 { 0x1f, 0x411111f0 }, /* N/A */
1369 { }
1370 }
1371 },
1372 [ALC880_FIXUP_3ST] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001373 .type = HDA_FIXUP_PINS,
1374 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001375 { 0x1e, 0x411111f0 }, /* N/A */
1376 { }
1377 },
1378 .chained = true,
1379 .chain_id = ALC880_FIXUP_3ST_BASE,
1380 },
1381 [ALC880_FIXUP_3ST_DIG] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001382 .type = HDA_FIXUP_PINS,
1383 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001384 { 0x1e, 0x0144111e }, /* SPDIF */
1385 { }
1386 },
1387 .chained = true,
1388 .chain_id = ALC880_FIXUP_3ST_BASE,
1389 },
1390 [ALC880_FIXUP_5ST_BASE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001391 .type = HDA_FIXUP_PINS,
1392 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001393 { 0x14, 0x01014010 }, /* front */
1394 { 0x15, 0x411111f0 }, /* N/A */
1395 { 0x16, 0x01011411 }, /* CLFE */
1396 { 0x17, 0x01016412 }, /* surr */
1397 { 0x18, 0x01a19c30 }, /* mic-in */
1398 { 0x19, 0x0121411f }, /* HP */
1399 { 0x1a, 0x01813031 }, /* line-in */
1400 { 0x1b, 0x02a19c40 }, /* front-mic */
1401 { 0x1c, 0x411111f0 }, /* N/A */
1402 { 0x1d, 0x411111f0 }, /* N/A */
1403 /* 0x1e is filled in below */
1404 { 0x1f, 0x411111f0 }, /* N/A */
1405 { }
1406 }
1407 },
1408 [ALC880_FIXUP_5ST] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001409 .type = HDA_FIXUP_PINS,
1410 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001411 { 0x1e, 0x411111f0 }, /* N/A */
1412 { }
1413 },
1414 .chained = true,
1415 .chain_id = ALC880_FIXUP_5ST_BASE,
1416 },
1417 [ALC880_FIXUP_5ST_DIG] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001418 .type = HDA_FIXUP_PINS,
1419 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001420 { 0x1e, 0x0144111e }, /* SPDIF */
1421 { }
1422 },
1423 .chained = true,
1424 .chain_id = ALC880_FIXUP_5ST_BASE,
1425 },
1426 [ALC880_FIXUP_6ST_BASE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001427 .type = HDA_FIXUP_PINS,
1428 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001429 { 0x14, 0x01014010 }, /* front */
1430 { 0x15, 0x01016412 }, /* surr */
1431 { 0x16, 0x01011411 }, /* CLFE */
1432 { 0x17, 0x01012414 }, /* side */
1433 { 0x18, 0x01a19c30 }, /* mic-in */
1434 { 0x19, 0x02a19c40 }, /* front-mic */
1435 { 0x1a, 0x01813031 }, /* line-in */
1436 { 0x1b, 0x0121411f }, /* HP */
1437 { 0x1c, 0x411111f0 }, /* N/A */
1438 { 0x1d, 0x411111f0 }, /* N/A */
1439 /* 0x1e is filled in below */
1440 { 0x1f, 0x411111f0 }, /* N/A */
1441 { }
1442 }
1443 },
1444 [ALC880_FIXUP_6ST] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001445 .type = HDA_FIXUP_PINS,
1446 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001447 { 0x1e, 0x411111f0 }, /* N/A */
1448 { }
1449 },
1450 .chained = true,
1451 .chain_id = ALC880_FIXUP_6ST_BASE,
1452 },
1453 [ALC880_FIXUP_6ST_DIG] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001454 .type = HDA_FIXUP_PINS,
1455 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001456 { 0x1e, 0x0144111e }, /* SPDIF */
1457 { }
1458 },
1459 .chained = true,
1460 .chain_id = ALC880_FIXUP_6ST_BASE,
1461 },
Takashi Iwai53971452013-01-23 18:21:37 +01001462 [ALC880_FIXUP_6ST_AUTOMUTE] = {
1463 .type = HDA_FIXUP_PINS,
1464 .v.pins = (const struct hda_pintbl[]) {
1465 { 0x1b, 0x0121401f }, /* HP with jack detect */
1466 { }
1467 },
1468 .chained_before = true,
1469 .chain_id = ALC880_FIXUP_6ST_BASE,
1470 },
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001471};
1472
1473static const struct snd_pci_quirk alc880_fixup_tbl[] = {
Takashi Iwaif02aab52012-02-17 16:33:56 +01001474 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_FIXUP_W810),
Takashi Iwai487a5882013-11-07 07:29:30 +01001475 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS W5A", ALC880_FIXUP_ASUS_W5A),
Takashi Iwai96e225f2012-02-20 17:41:51 +01001476 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_FIXUP_Z71V),
Takashi Iwai29e3fdc2012-02-20 17:56:57 +01001477 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_FIXUP_GPIO1),
David Henningsson6538de02014-06-10 10:52:50 +02001478 SND_PCI_QUIRK(0x147b, 0x1045, "ABit AA8XE", ALC880_FIXUP_6ST_AUTOMUTE),
Takashi Iwai29e3fdc2012-02-20 17:56:57 +01001479 SND_PCI_QUIRK(0x1558, 0x5401, "Clevo GPIO2", ALC880_FIXUP_GPIO2),
Takashi Iwai27e917f2012-02-17 17:49:54 +01001480 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo", ALC880_FIXUP_EAPD_COEF),
Takashi Iwai967b88c2012-02-20 17:31:02 +01001481 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_FIXUP_UNIWILL_DIG),
Takashi Iwaiba533812012-02-20 16:36:52 +01001482 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_FIXUP_F1734),
Takashi Iwai817de922012-02-20 17:20:48 +01001483 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_FIXUP_UNIWILL),
Takashi Iwai7833c7e2012-02-20 17:11:38 +01001484 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_FIXUP_VOL_KNOB),
Takashi Iwaif02aab52012-02-17 16:33:56 +01001485 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_FIXUP_W810),
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001486 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_FIXUP_MEDION_RIM),
Takashi Iwai53971452013-01-23 18:21:37 +01001487 SND_PCI_QUIRK(0x1631, 0xe011, "PB 13201056", ALC880_FIXUP_6ST_AUTOMUTE),
Takashi Iwaia1615742015-08-13 18:05:06 +02001488 SND_PCI_QUIRK(0x1734, 0x107c, "FSC Amilo M1437", ALC880_FIXUP_FUJITSU),
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001489 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FIXUP_FUJITSU),
Takashi Iwaiba533812012-02-20 16:36:52 +01001490 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_FIXUP_F1734),
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001491 SND_PCI_QUIRK(0x1734, 0x10b0, "FSC Amilo Pi1556", ALC880_FIXUP_FUJITSU),
Takashi Iwaidc6af522012-02-17 16:18:59 +01001492 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_FIXUP_LG),
1493 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_FIXUP_LG),
1494 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_FIXUP_LG),
Takashi Iwaidb8a38e2013-08-09 12:34:42 +02001495 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_FIXUP_LG_LW25),
Takashi Iwaib9368f52012-02-17 17:54:44 +01001496 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_FIXUP_TCL_S700),
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001497
1498 /* Below is the copied entries from alc880_quirks.c.
1499 * It's not quite sure whether BIOS sets the correct pin-config table
1500 * on these machines, thus they are kept to be compatible with
1501 * the old static quirks. Once when it's confirmed to work without
1502 * these overrides, it'd be better to remove.
1503 */
1504 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_FIXUP_5ST_DIG),
1505 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_FIXUP_6ST),
1506 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_FIXUP_3ST_DIG),
1507 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_FIXUP_6ST_DIG),
1508 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_FIXUP_6ST_DIG),
1509 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_FIXUP_6ST_DIG),
1510 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_FIXUP_3ST_DIG),
1511 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_FIXUP_3ST),
1512 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_FIXUP_6ST_DIG),
1513 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_FIXUP_3ST),
1514 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_FIXUP_3ST),
1515 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_FIXUP_5ST),
1516 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_FIXUP_5ST),
1517 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_FIXUP_5ST),
1518 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_FIXUP_6ST_DIG),
1519 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_FIXUP_6ST_DIG),
1520 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_FIXUP_6ST_DIG),
1521 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_FIXUP_6ST_DIG),
1522 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_FIXUP_5ST_DIG),
1523 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_FIXUP_5ST_DIG),
1524 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_FIXUP_5ST_DIG),
1525 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_FIXUP_6ST_DIG), /* broken BIOS */
1526 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_FIXUP_6ST_DIG),
1527 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1528 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1529 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1530 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_FIXUP_3ST_DIG),
1531 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1532 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_FIXUP_3ST_DIG),
1533 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_FIXUP_3ST_DIG),
1534 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1535 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1536 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1537 /* default Intel */
1538 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_FIXUP_3ST),
1539 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_FIXUP_5ST_DIG),
1540 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_FIXUP_6ST_DIG),
1541 {}
1542};
1543
Takashi Iwai1727a772013-01-10 09:52:52 +01001544static const struct hda_model_fixup alc880_fixup_models[] = {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001545 {.id = ALC880_FIXUP_3ST, .name = "3stack"},
1546 {.id = ALC880_FIXUP_3ST_DIG, .name = "3stack-digout"},
1547 {.id = ALC880_FIXUP_5ST, .name = "5stack"},
1548 {.id = ALC880_FIXUP_5ST_DIG, .name = "5stack-digout"},
1549 {.id = ALC880_FIXUP_6ST, .name = "6stack"},
1550 {.id = ALC880_FIXUP_6ST_DIG, .name = "6stack-digout"},
Takashi Iwai53971452013-01-23 18:21:37 +01001551 {.id = ALC880_FIXUP_6ST_AUTOMUTE, .name = "6stack-automute"},
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001552 {}
1553};
1554
1555
1556/*
Takashi Iwai1d045db2011-07-07 18:23:21 +02001557 * OK, here we have finally the patch for ALC880
1558 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02001559static int patch_alc880(struct hda_codec *codec)
1560{
1561 struct alc_spec *spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001562 int err;
1563
Takashi Iwai3de95172012-05-07 18:03:15 +02001564 err = alc_alloc_spec(codec, 0x0b);
1565 if (err < 0)
1566 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001567
Takashi Iwai3de95172012-05-07 18:03:15 +02001568 spec = codec->spec;
Takashi Iwai08c189f2012-12-19 15:22:24 +01001569 spec->gen.need_dac_fix = 1;
Takashi Iwai7504b6c2013-03-18 11:25:51 +01001570 spec->gen.beep_nid = 0x01;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001571
Takashi Iwai225068a2015-05-29 10:42:14 +02001572 codec->patch_ops.unsol_event = alc880_unsol_event;
1573
Takashi Iwaic9af7532019-05-10 11:01:43 +02001574 alc_pre_init(codec);
1575
Takashi Iwai1727a772013-01-10 09:52:52 +01001576 snd_hda_pick_fixup(codec, alc880_fixup_models, alc880_fixup_tbl,
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001577 alc880_fixups);
Takashi Iwai1727a772013-01-10 09:52:52 +01001578 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02001579
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001580 /* automatic parse from the BIOS config */
1581 err = alc880_parse_auto_config(codec);
1582 if (err < 0)
1583 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001584
Takashi Iwaifea80fa2018-06-20 12:52:46 +02001585 if (!spec->gen.no_analog) {
1586 err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
1587 if (err < 0)
1588 goto error;
1589 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02001590
Takashi Iwai1727a772013-01-10 09:52:52 +01001591 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01001592
Takashi Iwai1d045db2011-07-07 18:23:21 +02001593 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02001594
1595 error:
1596 alc_free(codec);
1597 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001598}
1599
1600
1601/*
1602 * ALC260 support
1603 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02001604static int alc260_parse_auto_config(struct hda_codec *codec)
1605{
Takashi Iwai1d045db2011-07-07 18:23:21 +02001606 static const hda_nid_t alc260_ignore[] = { 0x17, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001607 static const hda_nid_t alc260_ssids[] = { 0x10, 0x15, 0x0f, 0 };
1608 return alc_parse_auto_config(codec, alc260_ignore, alc260_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02001609}
1610
Takashi Iwai1d045db2011-07-07 18:23:21 +02001611/*
1612 * Pin config fixes
1613 */
1614enum {
Takashi Iwaica8f0422012-02-16 11:51:19 +01001615 ALC260_FIXUP_HP_DC5750,
1616 ALC260_FIXUP_HP_PIN_0F,
1617 ALC260_FIXUP_COEF,
Takashi Iwai15317ab2012-02-16 12:02:53 +01001618 ALC260_FIXUP_GPIO1,
Takashi Iwai20f7d922012-02-16 12:35:16 +01001619 ALC260_FIXUP_GPIO1_TOGGLE,
1620 ALC260_FIXUP_REPLACER,
Takashi Iwai0a1c4fa2012-02-16 12:42:30 +01001621 ALC260_FIXUP_HP_B1900,
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001622 ALC260_FIXUP_KN1,
Takashi Iwai39aedee2013-01-10 17:10:40 +01001623 ALC260_FIXUP_FSC_S7020,
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001624 ALC260_FIXUP_FSC_S7020_JWSE,
Takashi Iwaid08c5ef2013-11-22 08:06:36 +01001625 ALC260_FIXUP_VAIO_PINS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02001626};
1627
Takashi Iwai20f7d922012-02-16 12:35:16 +01001628static void alc260_gpio1_automute(struct hda_codec *codec)
1629{
1630 struct alc_spec *spec = codec->spec;
Takashi Iwaiaaf312d2018-06-19 22:28:22 +02001631
1632 alc_update_gpio_data(codec, 0x01, spec->gen.hp_jack_present);
Takashi Iwai20f7d922012-02-16 12:35:16 +01001633}
1634
1635static void alc260_fixup_gpio1_toggle(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001636 const struct hda_fixup *fix, int action)
Takashi Iwai20f7d922012-02-16 12:35:16 +01001637{
1638 struct alc_spec *spec = codec->spec;
Takashi Iwai1727a772013-01-10 09:52:52 +01001639 if (action == HDA_FIXUP_ACT_PROBE) {
Takashi Iwai20f7d922012-02-16 12:35:16 +01001640 /* although the machine has only one output pin, we need to
1641 * toggle GPIO1 according to the jack state
1642 */
Takashi Iwai08c189f2012-12-19 15:22:24 +01001643 spec->gen.automute_hook = alc260_gpio1_automute;
1644 spec->gen.detect_hp = 1;
1645 spec->gen.automute_speaker = 1;
1646 spec->gen.autocfg.hp_pins[0] = 0x0f; /* copy it for automute */
Takashi Iwai62f949b2014-09-11 14:06:53 +02001647 snd_hda_jack_detect_enable_callback(codec, 0x0f,
Takashi Iwai08c189f2012-12-19 15:22:24 +01001648 snd_hda_gen_hp_automute);
Takashi Iwai5579cd62018-06-19 22:22:41 +02001649 alc_setup_gpio(codec, 0x01);
Takashi Iwai20f7d922012-02-16 12:35:16 +01001650 }
1651}
1652
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001653static void alc260_fixup_kn1(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001654 const struct hda_fixup *fix, int action)
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001655{
1656 struct alc_spec *spec = codec->spec;
Takashi Iwai1727a772013-01-10 09:52:52 +01001657 static const struct hda_pintbl pincfgs[] = {
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001658 { 0x0f, 0x02214000 }, /* HP/speaker */
1659 { 0x12, 0x90a60160 }, /* int mic */
1660 { 0x13, 0x02a19000 }, /* ext mic */
1661 { 0x18, 0x01446000 }, /* SPDIF out */
1662 /* disable bogus I/O pins */
1663 { 0x10, 0x411111f0 },
1664 { 0x11, 0x411111f0 },
1665 { 0x14, 0x411111f0 },
1666 { 0x15, 0x411111f0 },
1667 { 0x16, 0x411111f0 },
1668 { 0x17, 0x411111f0 },
1669 { 0x19, 0x411111f0 },
1670 { }
1671 };
1672
1673 switch (action) {
Takashi Iwai1727a772013-01-10 09:52:52 +01001674 case HDA_FIXUP_ACT_PRE_PROBE:
1675 snd_hda_apply_pincfgs(codec, pincfgs);
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001676 spec->init_amp = ALC_INIT_NONE;
1677 break;
1678 }
1679}
1680
Takashi Iwai39aedee2013-01-10 17:10:40 +01001681static void alc260_fixup_fsc_s7020(struct hda_codec *codec,
1682 const struct hda_fixup *fix, int action)
1683{
1684 struct alc_spec *spec = codec->spec;
Takashi Iwai1c76aa52018-06-21 16:37:54 +02001685 if (action == HDA_FIXUP_ACT_PRE_PROBE)
Takashi Iwaie6e0ee52013-02-18 17:04:20 +01001686 spec->init_amp = ALC_INIT_NONE;
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001687}
1688
1689static void alc260_fixup_fsc_s7020_jwse(struct hda_codec *codec,
1690 const struct hda_fixup *fix, int action)
1691{
1692 struct alc_spec *spec = codec->spec;
1693 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwaif811c3c2013-03-07 18:32:59 +01001694 spec->gen.add_jack_modes = 1;
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001695 spec->gen.hp_mic = 1;
Takashi Iwaie6e0ee52013-02-18 17:04:20 +01001696 }
Takashi Iwai39aedee2013-01-10 17:10:40 +01001697}
1698
Takashi Iwai1727a772013-01-10 09:52:52 +01001699static const struct hda_fixup alc260_fixups[] = {
Takashi Iwaica8f0422012-02-16 11:51:19 +01001700 [ALC260_FIXUP_HP_DC5750] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001701 .type = HDA_FIXUP_PINS,
1702 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02001703 { 0x11, 0x90130110 }, /* speaker */
1704 { }
1705 }
1706 },
Takashi Iwaica8f0422012-02-16 11:51:19 +01001707 [ALC260_FIXUP_HP_PIN_0F] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001708 .type = HDA_FIXUP_PINS,
1709 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaica8f0422012-02-16 11:51:19 +01001710 { 0x0f, 0x01214000 }, /* HP */
1711 { }
1712 }
1713 },
1714 [ALC260_FIXUP_COEF] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001715 .type = HDA_FIXUP_VERBS,
Takashi Iwaica8f0422012-02-16 11:51:19 +01001716 .v.verbs = (const struct hda_verb[]) {
Ronan Marquete30cf2d2014-06-01 18:38:53 +02001717 { 0x1a, AC_VERB_SET_COEF_INDEX, 0x07 },
1718 { 0x1a, AC_VERB_SET_PROC_COEF, 0x3040 },
Takashi Iwaica8f0422012-02-16 11:51:19 +01001719 { }
1720 },
Takashi Iwaica8f0422012-02-16 11:51:19 +01001721 },
Takashi Iwai15317ab2012-02-16 12:02:53 +01001722 [ALC260_FIXUP_GPIO1] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02001723 .type = HDA_FIXUP_FUNC,
1724 .v.func = alc_fixup_gpio1,
Takashi Iwai15317ab2012-02-16 12:02:53 +01001725 },
Takashi Iwai20f7d922012-02-16 12:35:16 +01001726 [ALC260_FIXUP_GPIO1_TOGGLE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001727 .type = HDA_FIXUP_FUNC,
Takashi Iwai20f7d922012-02-16 12:35:16 +01001728 .v.func = alc260_fixup_gpio1_toggle,
1729 .chained = true,
1730 .chain_id = ALC260_FIXUP_HP_PIN_0F,
1731 },
1732 [ALC260_FIXUP_REPLACER] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001733 .type = HDA_FIXUP_VERBS,
Takashi Iwai20f7d922012-02-16 12:35:16 +01001734 .v.verbs = (const struct hda_verb[]) {
Takashi Iwai192a98e2014-06-02 15:16:07 +02001735 { 0x1a, AC_VERB_SET_COEF_INDEX, 0x07 },
1736 { 0x1a, AC_VERB_SET_PROC_COEF, 0x3050 },
Takashi Iwai20f7d922012-02-16 12:35:16 +01001737 { }
1738 },
1739 .chained = true,
1740 .chain_id = ALC260_FIXUP_GPIO1_TOGGLE,
1741 },
Takashi Iwai0a1c4fa2012-02-16 12:42:30 +01001742 [ALC260_FIXUP_HP_B1900] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001743 .type = HDA_FIXUP_FUNC,
Takashi Iwai0a1c4fa2012-02-16 12:42:30 +01001744 .v.func = alc260_fixup_gpio1_toggle,
1745 .chained = true,
1746 .chain_id = ALC260_FIXUP_COEF,
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001747 },
1748 [ALC260_FIXUP_KN1] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001749 .type = HDA_FIXUP_FUNC,
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001750 .v.func = alc260_fixup_kn1,
1751 },
Takashi Iwai39aedee2013-01-10 17:10:40 +01001752 [ALC260_FIXUP_FSC_S7020] = {
1753 .type = HDA_FIXUP_FUNC,
1754 .v.func = alc260_fixup_fsc_s7020,
1755 },
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001756 [ALC260_FIXUP_FSC_S7020_JWSE] = {
1757 .type = HDA_FIXUP_FUNC,
1758 .v.func = alc260_fixup_fsc_s7020_jwse,
1759 .chained = true,
1760 .chain_id = ALC260_FIXUP_FSC_S7020,
1761 },
Takashi Iwaid08c5ef2013-11-22 08:06:36 +01001762 [ALC260_FIXUP_VAIO_PINS] = {
1763 .type = HDA_FIXUP_PINS,
1764 .v.pins = (const struct hda_pintbl[]) {
1765 /* Pin configs are missing completely on some VAIOs */
1766 { 0x0f, 0x01211020 },
1767 { 0x10, 0x0001003f },
1768 { 0x11, 0x411111f0 },
1769 { 0x12, 0x01a15930 },
1770 { 0x13, 0x411111f0 },
1771 { 0x14, 0x411111f0 },
1772 { 0x15, 0x411111f0 },
1773 { 0x16, 0x411111f0 },
1774 { 0x17, 0x411111f0 },
1775 { 0x18, 0x411111f0 },
1776 { 0x19, 0x411111f0 },
1777 { }
1778 }
1779 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02001780};
1781
1782static const struct snd_pci_quirk alc260_fixup_tbl[] = {
Takashi Iwai15317ab2012-02-16 12:02:53 +01001783 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_FIXUP_GPIO1),
Takashi Iwaica8f0422012-02-16 11:51:19 +01001784 SND_PCI_QUIRK(0x1025, 0x007f, "Acer Aspire 9500", ALC260_FIXUP_COEF),
Takashi Iwai15317ab2012-02-16 12:02:53 +01001785 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_FIXUP_GPIO1),
Takashi Iwaica8f0422012-02-16 11:51:19 +01001786 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", ALC260_FIXUP_HP_DC5750),
Takashi Iwai0a1c4fa2012-02-16 12:42:30 +01001787 SND_PCI_QUIRK(0x103c, 0x30ba, "HP Presario B1900", ALC260_FIXUP_HP_B1900),
Takashi Iwaid08c5ef2013-11-22 08:06:36 +01001788 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_FIXUP_VAIO_PINS),
Takashi Iwai0f5a5b82013-11-21 09:12:52 +01001789 SND_PCI_QUIRK(0x104d, 0x81e2, "Sony VAIO TX", ALC260_FIXUP_HP_PIN_0F),
Takashi Iwai39aedee2013-01-10 17:10:40 +01001790 SND_PCI_QUIRK(0x10cf, 0x1326, "FSC LifeBook S7020", ALC260_FIXUP_FSC_S7020),
Takashi Iwaib1f58082012-02-16 12:45:03 +01001791 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FIXUP_GPIO1),
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001792 SND_PCI_QUIRK(0x152d, 0x0729, "Quanta KN1", ALC260_FIXUP_KN1),
Takashi Iwai20f7d922012-02-16 12:35:16 +01001793 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_FIXUP_REPLACER),
Takashi Iwaica8f0422012-02-16 11:51:19 +01001794 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_FIXUP_COEF),
Takashi Iwai1d045db2011-07-07 18:23:21 +02001795 {}
1796};
1797
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001798static const struct hda_model_fixup alc260_fixup_models[] = {
1799 {.id = ALC260_FIXUP_GPIO1, .name = "gpio1"},
1800 {.id = ALC260_FIXUP_COEF, .name = "coef"},
1801 {.id = ALC260_FIXUP_FSC_S7020, .name = "fujitsu"},
1802 {.id = ALC260_FIXUP_FSC_S7020_JWSE, .name = "fujitsu-jwse"},
1803 {}
1804};
1805
Takashi Iwai1d045db2011-07-07 18:23:21 +02001806/*
1807 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02001808static int patch_alc260(struct hda_codec *codec)
1809{
1810 struct alc_spec *spec;
Takashi Iwaic3c2c9e2012-02-16 12:59:55 +01001811 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001812
Takashi Iwai3de95172012-05-07 18:03:15 +02001813 err = alc_alloc_spec(codec, 0x07);
1814 if (err < 0)
1815 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001816
Takashi Iwai3de95172012-05-07 18:03:15 +02001817 spec = codec->spec;
Takashi Iwaiea46c3c2013-01-15 18:45:53 +01001818 /* as quite a few machines require HP amp for speaker outputs,
1819 * it's easier to enable it unconditionally; even if it's unneeded,
1820 * it's almost harmless.
1821 */
1822 spec->gen.prefer_hp_amp = 1;
Takashi Iwai7504b6c2013-03-18 11:25:51 +01001823 spec->gen.beep_nid = 0x01;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001824
Takashi Iwai225068a2015-05-29 10:42:14 +02001825 spec->shutup = alc_eapd_shutup;
1826
Takashi Iwaic9af7532019-05-10 11:01:43 +02001827 alc_pre_init(codec);
1828
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001829 snd_hda_pick_fixup(codec, alc260_fixup_models, alc260_fixup_tbl,
1830 alc260_fixups);
Takashi Iwai1727a772013-01-10 09:52:52 +01001831 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02001832
Takashi Iwaic3c2c9e2012-02-16 12:59:55 +01001833 /* automatic parse from the BIOS config */
1834 err = alc260_parse_auto_config(codec);
1835 if (err < 0)
1836 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001837
Takashi Iwaifea80fa2018-06-20 12:52:46 +02001838 if (!spec->gen.no_analog) {
1839 err = set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
1840 if (err < 0)
1841 goto error;
1842 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02001843
Takashi Iwai1727a772013-01-10 09:52:52 +01001844 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01001845
Takashi Iwai1d045db2011-07-07 18:23:21 +02001846 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02001847
1848 error:
1849 alc_free(codec);
1850 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001851}
1852
1853
1854/*
1855 * ALC882/883/885/888/889 support
1856 *
1857 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
1858 * configuration. Each pin widget can choose any input DACs and a mixer.
1859 * Each ADC is connected from a mixer of all inputs. This makes possible
1860 * 6-channel independent captures.
1861 *
1862 * In addition, an independent DAC for the multi-playback (not used in this
1863 * driver yet).
1864 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02001865
1866/*
1867 * Pin config fixes
1868 */
1869enum {
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01001870 ALC882_FIXUP_ABIT_AW9D_MAX,
1871 ALC882_FIXUP_LENOVO_Y530,
1872 ALC882_FIXUP_PB_M5210,
1873 ALC882_FIXUP_ACER_ASPIRE_7736,
1874 ALC882_FIXUP_ASUS_W90V,
Marton Balint8f239212012-03-05 21:33:23 +01001875 ALC889_FIXUP_CD,
David Henningssonb2c53e22014-01-01 14:01:34 +01001876 ALC889_FIXUP_FRONT_HP_NO_PRESENCE,
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01001877 ALC889_FIXUP_VAIO_TT,
Takashi Iwai0e7cc2e2011-11-09 12:42:48 +01001878 ALC888_FIXUP_EEE1601,
Takashi Iwai177943a32011-11-09 12:55:18 +01001879 ALC882_FIXUP_EAPD,
Takashi Iwai7a6069b2011-11-09 15:22:01 +01001880 ALC883_FIXUP_EAPD,
Takashi Iwai8812c4f2011-11-09 17:39:15 +01001881 ALC883_FIXUP_ACER_EAPD,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001882 ALC882_FIXUP_GPIO1,
1883 ALC882_FIXUP_GPIO2,
Takashi Iwaieb844d52011-11-09 18:03:07 +01001884 ALC882_FIXUP_GPIO3,
Takashi Iwai68ef0562011-11-09 18:24:44 +01001885 ALC889_FIXUP_COEF,
1886 ALC882_FIXUP_ASUS_W2JC,
Takashi Iwaic3e837b2011-11-10 16:01:47 +01001887 ALC882_FIXUP_ACER_ASPIRE_4930G,
1888 ALC882_FIXUP_ACER_ASPIRE_8930G,
1889 ALC882_FIXUP_ASPIRE_8930G_VERBS,
Takashi Iwai56710872011-11-14 17:42:11 +01001890 ALC885_FIXUP_MACPRO_GPIO,
Takashi Iwai02a237b2012-02-13 15:25:07 +01001891 ALC889_FIXUP_DAC_ROUTE,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001892 ALC889_FIXUP_MBP_VREF,
1893 ALC889_FIXUP_IMAC91_VREF,
Adrien Vergée7729a42014-01-24 14:56:14 -05001894 ALC889_FIXUP_MBA11_VREF,
Takashi Iwai0756f092013-12-04 13:59:45 +01001895 ALC889_FIXUP_MBA21_VREF,
Takashi Iwaic20f31e2014-02-03 11:02:10 +01001896 ALC889_FIXUP_MP11_VREF,
Mario Kleiner9f660a12015-12-22 00:45:43 +01001897 ALC889_FIXUP_MP41_VREF,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02001898 ALC882_FIXUP_INV_DMIC,
Takashi Iwaie427c232012-07-29 10:04:08 +02001899 ALC882_FIXUP_NO_PRIMARY_HP,
Takashi Iwai1f0bbf02013-11-28 15:21:21 +01001900 ALC887_FIXUP_ASUS_BASS,
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01001901 ALC887_FIXUP_BASS_CHMAP,
Takashi Iwai7beb3a62017-04-10 18:05:52 +02001902 ALC1220_FIXUP_GB_DUAL_CODECS,
Peisen0202f5c2017-10-26 10:35:36 +08001903 ALC1220_FIXUP_CLEVO_P950,
Richard Sailer80690a22019-04-02 15:52:04 +02001904 ALC1220_FIXUP_CLEVO_PB51ED,
1905 ALC1220_FIXUP_CLEVO_PB51ED_PINS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02001906};
1907
Takashi Iwai68ef0562011-11-09 18:24:44 +01001908static void alc889_fixup_coef(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001909 const struct hda_fixup *fix, int action)
Takashi Iwai68ef0562011-11-09 18:24:44 +01001910{
Takashi Iwai1727a772013-01-10 09:52:52 +01001911 if (action != HDA_FIXUP_ACT_INIT)
Takashi Iwai68ef0562011-11-09 18:24:44 +01001912 return;
Kailang Yang1df88742014-10-29 16:10:13 +08001913 alc_update_coef_idx(codec, 7, 0, 0x2030);
Takashi Iwai68ef0562011-11-09 18:24:44 +01001914}
1915
Takashi Iwai56710872011-11-14 17:42:11 +01001916/* set up GPIO at initialization */
1917static void alc885_fixup_macpro_gpio(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001918 const struct hda_fixup *fix, int action)
Takashi Iwai56710872011-11-14 17:42:11 +01001919{
Takashi Iwai215c8502018-06-19 22:34:26 +02001920 struct alc_spec *spec = codec->spec;
1921
1922 spec->gpio_write_delay = true;
1923 alc_fixup_gpio3(codec, fix, action);
Takashi Iwai56710872011-11-14 17:42:11 +01001924}
1925
Takashi Iwai02a237b2012-02-13 15:25:07 +01001926/* Fix the connection of some pins for ALC889:
1927 * At least, Acer Aspire 5935 shows the connections to DAC3/4 don't
1928 * work correctly (bko#42740)
1929 */
1930static void alc889_fixup_dac_route(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001931 const struct hda_fixup *fix, int action)
Takashi Iwai02a237b2012-02-13 15:25:07 +01001932{
Takashi Iwai1727a772013-01-10 09:52:52 +01001933 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwaief8d60f2012-02-17 10:12:38 +01001934 /* fake the connections during parsing the tree */
Takashi Iwai02a237b2012-02-13 15:25:07 +01001935 hda_nid_t conn1[2] = { 0x0c, 0x0d };
1936 hda_nid_t conn2[2] = { 0x0e, 0x0f };
1937 snd_hda_override_conn_list(codec, 0x14, 2, conn1);
1938 snd_hda_override_conn_list(codec, 0x15, 2, conn1);
1939 snd_hda_override_conn_list(codec, 0x18, 2, conn2);
1940 snd_hda_override_conn_list(codec, 0x1a, 2, conn2);
Takashi Iwai1727a772013-01-10 09:52:52 +01001941 } else if (action == HDA_FIXUP_ACT_PROBE) {
Takashi Iwaief8d60f2012-02-17 10:12:38 +01001942 /* restore the connections */
1943 hda_nid_t conn[5] = { 0x0c, 0x0d, 0x0e, 0x0f, 0x26 };
1944 snd_hda_override_conn_list(codec, 0x14, 5, conn);
1945 snd_hda_override_conn_list(codec, 0x15, 5, conn);
1946 snd_hda_override_conn_list(codec, 0x18, 5, conn);
1947 snd_hda_override_conn_list(codec, 0x1a, 5, conn);
Takashi Iwai02a237b2012-02-13 15:25:07 +01001948 }
1949}
1950
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001951/* Set VREF on HP pin */
1952static void alc889_fixup_mbp_vref(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001953 const struct hda_fixup *fix, int action)
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001954{
1955 struct alc_spec *spec = codec->spec;
Mario Kleiner9f660a12015-12-22 00:45:43 +01001956 static hda_nid_t nids[3] = { 0x14, 0x15, 0x19 };
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001957 int i;
1958
Takashi Iwai1727a772013-01-10 09:52:52 +01001959 if (action != HDA_FIXUP_ACT_INIT)
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001960 return;
1961 for (i = 0; i < ARRAY_SIZE(nids); i++) {
1962 unsigned int val = snd_hda_codec_get_pincfg(codec, nids[i]);
1963 if (get_defcfg_device(val) != AC_JACK_HP_OUT)
1964 continue;
Takashi Iwaid3f02d62013-01-10 10:12:22 +01001965 val = snd_hda_codec_get_pin_target(codec, nids[i]);
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001966 val |= AC_PINCTL_VREF_80;
Takashi Iwaicdd03ce2012-04-20 12:34:50 +02001967 snd_hda_set_pin_ctl(codec, nids[i], val);
Takashi Iwai08c189f2012-12-19 15:22:24 +01001968 spec->gen.keep_vref_in_automute = 1;
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001969 break;
1970 }
1971}
1972
Takashi Iwai0756f092013-12-04 13:59:45 +01001973static void alc889_fixup_mac_pins(struct hda_codec *codec,
1974 const hda_nid_t *nids, int num_nids)
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001975{
1976 struct alc_spec *spec = codec->spec;
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001977 int i;
1978
Takashi Iwai0756f092013-12-04 13:59:45 +01001979 for (i = 0; i < num_nids; i++) {
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001980 unsigned int val;
Takashi Iwaid3f02d62013-01-10 10:12:22 +01001981 val = snd_hda_codec_get_pin_target(codec, nids[i]);
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001982 val |= AC_PINCTL_VREF_50;
Takashi Iwaicdd03ce2012-04-20 12:34:50 +02001983 snd_hda_set_pin_ctl(codec, nids[i], val);
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001984 }
Takashi Iwai08c189f2012-12-19 15:22:24 +01001985 spec->gen.keep_vref_in_automute = 1;
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001986}
1987
Takashi Iwai0756f092013-12-04 13:59:45 +01001988/* Set VREF on speaker pins on imac91 */
1989static void alc889_fixup_imac91_vref(struct hda_codec *codec,
1990 const struct hda_fixup *fix, int action)
1991{
1992 static hda_nid_t nids[2] = { 0x18, 0x1a };
1993
1994 if (action == HDA_FIXUP_ACT_INIT)
1995 alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
1996}
1997
Adrien Vergée7729a42014-01-24 14:56:14 -05001998/* Set VREF on speaker pins on mba11 */
1999static void alc889_fixup_mba11_vref(struct hda_codec *codec,
2000 const struct hda_fixup *fix, int action)
2001{
2002 static hda_nid_t nids[1] = { 0x18 };
2003
2004 if (action == HDA_FIXUP_ACT_INIT)
2005 alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
2006}
2007
Takashi Iwai0756f092013-12-04 13:59:45 +01002008/* Set VREF on speaker pins on mba21 */
2009static void alc889_fixup_mba21_vref(struct hda_codec *codec,
2010 const struct hda_fixup *fix, int action)
2011{
2012 static hda_nid_t nids[2] = { 0x18, 0x19 };
2013
2014 if (action == HDA_FIXUP_ACT_INIT)
2015 alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
2016}
2017
Takashi Iwaie427c232012-07-29 10:04:08 +02002018/* Don't take HP output as primary
Fernando Luis Vázquez Caod9111492013-02-12 16:49:46 +09002019 * Strangely, the speaker output doesn't work on Vaio Z and some Vaio
2020 * all-in-one desktop PCs (for example VGC-LN51JGB) through DAC 0x05
Takashi Iwaie427c232012-07-29 10:04:08 +02002021 */
2022static void alc882_fixup_no_primary_hp(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01002023 const struct hda_fixup *fix, int action)
Takashi Iwaie427c232012-07-29 10:04:08 +02002024{
2025 struct alc_spec *spec = codec->spec;
Takashi Iwaida96fb52013-07-29 16:54:36 +02002026 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai08c189f2012-12-19 15:22:24 +01002027 spec->gen.no_primary_hp = 1;
Takashi Iwaida96fb52013-07-29 16:54:36 +02002028 spec->gen.no_multi_io = 1;
2029 }
Takashi Iwaie427c232012-07-29 10:04:08 +02002030}
2031
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01002032static void alc_fixup_bass_chmap(struct hda_codec *codec,
2033 const struct hda_fixup *fix, int action);
2034
Takashi Iwai7beb3a62017-04-10 18:05:52 +02002035/* For dual-codec configuration, we need to disable some features to avoid
2036 * conflicts of kctls and PCM streams
2037 */
2038static void alc_fixup_dual_codecs(struct hda_codec *codec,
2039 const struct hda_fixup *fix, int action)
2040{
2041 struct alc_spec *spec = codec->spec;
2042
2043 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2044 return;
2045 /* disable vmaster */
2046 spec->gen.suppress_vmaster = 1;
2047 /* auto-mute and auto-mic switch don't work with multiple codecs */
2048 spec->gen.suppress_auto_mute = 1;
2049 spec->gen.suppress_auto_mic = 1;
2050 /* disable aamix as well */
2051 spec->gen.mixer_nid = 0;
2052 /* add location prefix to avoid conflicts */
2053 codec->force_pin_prefix = 1;
2054}
2055
2056static void rename_ctl(struct hda_codec *codec, const char *oldname,
2057 const char *newname)
2058{
2059 struct snd_kcontrol *kctl;
2060
2061 kctl = snd_hda_find_mixer_ctl(codec, oldname);
2062 if (kctl)
2063 strcpy(kctl->id.name, newname);
2064}
2065
2066static void alc1220_fixup_gb_dual_codecs(struct hda_codec *codec,
2067 const struct hda_fixup *fix,
2068 int action)
2069{
2070 alc_fixup_dual_codecs(codec, fix, action);
2071 switch (action) {
2072 case HDA_FIXUP_ACT_PRE_PROBE:
2073 /* override card longname to provide a unique UCM profile */
2074 strcpy(codec->card->longname, "HDAudio-Gigabyte-ALC1220DualCodecs");
2075 break;
2076 case HDA_FIXUP_ACT_BUILD:
2077 /* rename Capture controls depending on the codec */
2078 rename_ctl(codec, "Capture Volume",
2079 codec->addr == 0 ?
2080 "Rear-Panel Capture Volume" :
2081 "Front-Panel Capture Volume");
2082 rename_ctl(codec, "Capture Switch",
2083 codec->addr == 0 ?
2084 "Rear-Panel Capture Switch" :
2085 "Front-Panel Capture Switch");
2086 break;
2087 }
2088}
2089
Peisen0202f5c2017-10-26 10:35:36 +08002090static void alc1220_fixup_clevo_p950(struct hda_codec *codec,
2091 const struct hda_fixup *fix,
2092 int action)
2093{
2094 hda_nid_t conn1[1] = { 0x0c };
2095
2096 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2097 return;
2098
2099 alc_update_coef_idx(codec, 0x7, 0, 0x3c3);
2100 /* We therefore want to make sure 0x14 (front headphone) and
2101 * 0x1b (speakers) use the stereo DAC 0x02
2102 */
2103 snd_hda_override_conn_list(codec, 0x14, 1, conn1);
2104 snd_hda_override_conn_list(codec, 0x1b, 1, conn1);
2105}
2106
Jeremy Soller7f665b12019-02-13 10:56:19 -07002107static void alc_fixup_headset_mode_no_hp_mic(struct hda_codec *codec,
2108 const struct hda_fixup *fix, int action);
2109
Richard Sailer80690a22019-04-02 15:52:04 +02002110static void alc1220_fixup_clevo_pb51ed(struct hda_codec *codec,
Jeremy Soller7f665b12019-02-13 10:56:19 -07002111 const struct hda_fixup *fix,
2112 int action)
2113{
2114 alc1220_fixup_clevo_p950(codec, fix, action);
2115 alc_fixup_headset_mode_no_hp_mic(codec, fix, action);
2116}
2117
Takashi Iwai1727a772013-01-10 09:52:52 +01002118static const struct hda_fixup alc882_fixups[] = {
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002119 [ALC882_FIXUP_ABIT_AW9D_MAX] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002120 .type = HDA_FIXUP_PINS,
2121 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002122 { 0x15, 0x01080104 }, /* side */
2123 { 0x16, 0x01011012 }, /* rear */
2124 { 0x17, 0x01016011 }, /* clfe */
2125 { }
2126 }
2127 },
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002128 [ALC882_FIXUP_LENOVO_Y530] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002129 .type = HDA_FIXUP_PINS,
2130 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002131 { 0x15, 0x99130112 }, /* rear int speakers */
2132 { 0x16, 0x99130111 }, /* subwoofer */
2133 { }
2134 }
2135 },
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002136 [ALC882_FIXUP_PB_M5210] = {
Takashi Iwaifd108212013-01-10 10:18:14 +01002137 .type = HDA_FIXUP_PINCTLS,
2138 .v.pins = (const struct hda_pintbl[]) {
2139 { 0x19, PIN_VREF50 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02002140 {}
2141 }
2142 },
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002143 [ALC882_FIXUP_ACER_ASPIRE_7736] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002144 .type = HDA_FIXUP_FUNC,
Takashi Iwai23d30f22012-05-07 17:17:32 +02002145 .v.func = alc_fixup_sku_ignore,
Takashi Iwai1d045db2011-07-07 18:23:21 +02002146 },
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002147 [ALC882_FIXUP_ASUS_W90V] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002148 .type = HDA_FIXUP_PINS,
2149 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai5cdf7452011-10-26 23:04:08 +02002150 { 0x16, 0x99130110 }, /* fix sequence for CLFE */
2151 { }
2152 }
2153 },
Marton Balint8f239212012-03-05 21:33:23 +01002154 [ALC889_FIXUP_CD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002155 .type = HDA_FIXUP_PINS,
2156 .v.pins = (const struct hda_pintbl[]) {
Marton Balint8f239212012-03-05 21:33:23 +01002157 { 0x1c, 0x993301f0 }, /* CD */
2158 { }
2159 }
2160 },
David Henningssonb2c53e22014-01-01 14:01:34 +01002161 [ALC889_FIXUP_FRONT_HP_NO_PRESENCE] = {
2162 .type = HDA_FIXUP_PINS,
2163 .v.pins = (const struct hda_pintbl[]) {
2164 { 0x1b, 0x02214120 }, /* Front HP jack is flaky, disable jack detect */
2165 { }
2166 },
2167 .chained = true,
2168 .chain_id = ALC889_FIXUP_CD,
2169 },
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002170 [ALC889_FIXUP_VAIO_TT] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002171 .type = HDA_FIXUP_PINS,
2172 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002173 { 0x17, 0x90170111 }, /* hidden surround speaker */
2174 { }
2175 }
2176 },
Takashi Iwai0e7cc2e2011-11-09 12:42:48 +01002177 [ALC888_FIXUP_EEE1601] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002178 .type = HDA_FIXUP_VERBS,
Takashi Iwai0e7cc2e2011-11-09 12:42:48 +01002179 .v.verbs = (const struct hda_verb[]) {
2180 { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b },
2181 { 0x20, AC_VERB_SET_PROC_COEF, 0x0838 },
2182 { }
2183 }
Takashi Iwai177943a32011-11-09 12:55:18 +01002184 },
2185 [ALC882_FIXUP_EAPD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002186 .type = HDA_FIXUP_VERBS,
Takashi Iwai177943a32011-11-09 12:55:18 +01002187 .v.verbs = (const struct hda_verb[]) {
2188 /* change to EAPD mode */
2189 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2190 { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
2191 { }
2192 }
2193 },
Takashi Iwai7a6069b2011-11-09 15:22:01 +01002194 [ALC883_FIXUP_EAPD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002195 .type = HDA_FIXUP_VERBS,
Takashi Iwai7a6069b2011-11-09 15:22:01 +01002196 .v.verbs = (const struct hda_verb[]) {
2197 /* change to EAPD mode */
2198 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2199 { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
2200 { }
2201 }
2202 },
Takashi Iwai8812c4f2011-11-09 17:39:15 +01002203 [ALC883_FIXUP_ACER_EAPD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002204 .type = HDA_FIXUP_VERBS,
Takashi Iwai8812c4f2011-11-09 17:39:15 +01002205 .v.verbs = (const struct hda_verb[]) {
2206 /* eanable EAPD on Acer laptops */
2207 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2208 { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
2209 { }
2210 }
2211 },
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002212 [ALC882_FIXUP_GPIO1] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02002213 .type = HDA_FIXUP_FUNC,
2214 .v.func = alc_fixup_gpio1,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002215 },
2216 [ALC882_FIXUP_GPIO2] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02002217 .type = HDA_FIXUP_FUNC,
2218 .v.func = alc_fixup_gpio2,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002219 },
Takashi Iwaieb844d52011-11-09 18:03:07 +01002220 [ALC882_FIXUP_GPIO3] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02002221 .type = HDA_FIXUP_FUNC,
2222 .v.func = alc_fixup_gpio3,
Takashi Iwaieb844d52011-11-09 18:03:07 +01002223 },
Takashi Iwai68ef0562011-11-09 18:24:44 +01002224 [ALC882_FIXUP_ASUS_W2JC] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02002225 .type = HDA_FIXUP_FUNC,
2226 .v.func = alc_fixup_gpio1,
Takashi Iwai68ef0562011-11-09 18:24:44 +01002227 .chained = true,
2228 .chain_id = ALC882_FIXUP_EAPD,
2229 },
2230 [ALC889_FIXUP_COEF] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002231 .type = HDA_FIXUP_FUNC,
Takashi Iwai68ef0562011-11-09 18:24:44 +01002232 .v.func = alc889_fixup_coef,
2233 },
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002234 [ALC882_FIXUP_ACER_ASPIRE_4930G] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002235 .type = HDA_FIXUP_PINS,
2236 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002237 { 0x16, 0x99130111 }, /* CLFE speaker */
2238 { 0x17, 0x99130112 }, /* surround speaker */
2239 { }
Takashi Iwai038d4fe2012-04-11 17:18:12 +02002240 },
2241 .chained = true,
2242 .chain_id = ALC882_FIXUP_GPIO1,
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002243 },
2244 [ALC882_FIXUP_ACER_ASPIRE_8930G] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002245 .type = HDA_FIXUP_PINS,
2246 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002247 { 0x16, 0x99130111 }, /* CLFE speaker */
2248 { 0x1b, 0x99130112 }, /* surround speaker */
2249 { }
2250 },
2251 .chained = true,
2252 .chain_id = ALC882_FIXUP_ASPIRE_8930G_VERBS,
2253 },
2254 [ALC882_FIXUP_ASPIRE_8930G_VERBS] = {
2255 /* additional init verbs for Acer Aspire 8930G */
Takashi Iwai1727a772013-01-10 09:52:52 +01002256 .type = HDA_FIXUP_VERBS,
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002257 .v.verbs = (const struct hda_verb[]) {
2258 /* Enable all DACs */
2259 /* DAC DISABLE/MUTE 1? */
2260 /* setting bits 1-5 disables DAC nids 0x02-0x06
2261 * apparently. Init=0x38 */
2262 { 0x20, AC_VERB_SET_COEF_INDEX, 0x03 },
2263 { 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
2264 /* DAC DISABLE/MUTE 2? */
2265 /* some bit here disables the other DACs.
2266 * Init=0x4900 */
2267 { 0x20, AC_VERB_SET_COEF_INDEX, 0x08 },
2268 { 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
2269 /* DMIC fix
2270 * This laptop has a stereo digital microphone.
2271 * The mics are only 1cm apart which makes the stereo
2272 * useless. However, either the mic or the ALC889
2273 * makes the signal become a difference/sum signal
2274 * instead of standard stereo, which is annoying.
2275 * So instead we flip this bit which makes the
2276 * codec replicate the sum signal to both channels,
2277 * turning it into a normal mono mic.
2278 */
2279 /* DMIC_CONTROL? Init value = 0x0001 */
2280 { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b },
2281 { 0x20, AC_VERB_SET_PROC_COEF, 0x0003 },
2282 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2283 { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
2284 { }
Takashi Iwai038d4fe2012-04-11 17:18:12 +02002285 },
2286 .chained = true,
2287 .chain_id = ALC882_FIXUP_GPIO1,
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002288 },
Takashi Iwai56710872011-11-14 17:42:11 +01002289 [ALC885_FIXUP_MACPRO_GPIO] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002290 .type = HDA_FIXUP_FUNC,
Takashi Iwai56710872011-11-14 17:42:11 +01002291 .v.func = alc885_fixup_macpro_gpio,
2292 },
Takashi Iwai02a237b2012-02-13 15:25:07 +01002293 [ALC889_FIXUP_DAC_ROUTE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002294 .type = HDA_FIXUP_FUNC,
Takashi Iwai02a237b2012-02-13 15:25:07 +01002295 .v.func = alc889_fixup_dac_route,
2296 },
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002297 [ALC889_FIXUP_MBP_VREF] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002298 .type = HDA_FIXUP_FUNC,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002299 .v.func = alc889_fixup_mbp_vref,
2300 .chained = true,
2301 .chain_id = ALC882_FIXUP_GPIO1,
2302 },
2303 [ALC889_FIXUP_IMAC91_VREF] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002304 .type = HDA_FIXUP_FUNC,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002305 .v.func = alc889_fixup_imac91_vref,
2306 .chained = true,
2307 .chain_id = ALC882_FIXUP_GPIO1,
2308 },
Adrien Vergée7729a42014-01-24 14:56:14 -05002309 [ALC889_FIXUP_MBA11_VREF] = {
2310 .type = HDA_FIXUP_FUNC,
2311 .v.func = alc889_fixup_mba11_vref,
2312 .chained = true,
2313 .chain_id = ALC889_FIXUP_MBP_VREF,
2314 },
Takashi Iwai0756f092013-12-04 13:59:45 +01002315 [ALC889_FIXUP_MBA21_VREF] = {
2316 .type = HDA_FIXUP_FUNC,
2317 .v.func = alc889_fixup_mba21_vref,
2318 .chained = true,
2319 .chain_id = ALC889_FIXUP_MBP_VREF,
2320 },
Takashi Iwaic20f31e2014-02-03 11:02:10 +01002321 [ALC889_FIXUP_MP11_VREF] = {
2322 .type = HDA_FIXUP_FUNC,
2323 .v.func = alc889_fixup_mba11_vref,
2324 .chained = true,
2325 .chain_id = ALC885_FIXUP_MACPRO_GPIO,
2326 },
Mario Kleiner9f660a12015-12-22 00:45:43 +01002327 [ALC889_FIXUP_MP41_VREF] = {
2328 .type = HDA_FIXUP_FUNC,
2329 .v.func = alc889_fixup_mbp_vref,
2330 .chained = true,
2331 .chain_id = ALC885_FIXUP_MACPRO_GPIO,
2332 },
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002333 [ALC882_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002334 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02002335 .v.func = alc_fixup_inv_dmic,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002336 },
Takashi Iwaie427c232012-07-29 10:04:08 +02002337 [ALC882_FIXUP_NO_PRIMARY_HP] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002338 .type = HDA_FIXUP_FUNC,
Takashi Iwaie427c232012-07-29 10:04:08 +02002339 .v.func = alc882_fixup_no_primary_hp,
2340 },
Takashi Iwai1f0bbf02013-11-28 15:21:21 +01002341 [ALC887_FIXUP_ASUS_BASS] = {
2342 .type = HDA_FIXUP_PINS,
2343 .v.pins = (const struct hda_pintbl[]) {
2344 {0x16, 0x99130130}, /* bass speaker */
2345 {}
2346 },
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01002347 .chained = true,
2348 .chain_id = ALC887_FIXUP_BASS_CHMAP,
2349 },
2350 [ALC887_FIXUP_BASS_CHMAP] = {
2351 .type = HDA_FIXUP_FUNC,
2352 .v.func = alc_fixup_bass_chmap,
Takashi Iwai1f0bbf02013-11-28 15:21:21 +01002353 },
Takashi Iwai7beb3a62017-04-10 18:05:52 +02002354 [ALC1220_FIXUP_GB_DUAL_CODECS] = {
2355 .type = HDA_FIXUP_FUNC,
2356 .v.func = alc1220_fixup_gb_dual_codecs,
2357 },
Peisen0202f5c2017-10-26 10:35:36 +08002358 [ALC1220_FIXUP_CLEVO_P950] = {
2359 .type = HDA_FIXUP_FUNC,
2360 .v.func = alc1220_fixup_clevo_p950,
2361 },
Richard Sailer80690a22019-04-02 15:52:04 +02002362 [ALC1220_FIXUP_CLEVO_PB51ED] = {
Jeremy Soller7f665b12019-02-13 10:56:19 -07002363 .type = HDA_FIXUP_FUNC,
Richard Sailer80690a22019-04-02 15:52:04 +02002364 .v.func = alc1220_fixup_clevo_pb51ed,
Jeremy Soller7f665b12019-02-13 10:56:19 -07002365 },
Richard Sailer80690a22019-04-02 15:52:04 +02002366 [ALC1220_FIXUP_CLEVO_PB51ED_PINS] = {
Jeremy Soller7f665b12019-02-13 10:56:19 -07002367 .type = HDA_FIXUP_PINS,
2368 .v.pins = (const struct hda_pintbl[]) {
2369 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
2370 {}
2371 },
2372 .chained = true,
Richard Sailer80690a22019-04-02 15:52:04 +02002373 .chain_id = ALC1220_FIXUP_CLEVO_PB51ED,
Jeremy Soller7f665b12019-02-13 10:56:19 -07002374 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02002375};
2376
2377static const struct snd_pci_quirk alc882_fixup_tbl[] = {
Takashi Iwai8812c4f2011-11-09 17:39:15 +01002378 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_FIXUP_ACER_EAPD),
2379 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
Takashi Iwaib5d724b2015-06-02 19:57:08 +02002380 SND_PCI_QUIRK(0x1025, 0x0107, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
Takashi Iwai8812c4f2011-11-09 17:39:15 +01002381 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_FIXUP_ACER_EAPD),
2382 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
2383 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_FIXUP_ACER_EAPD),
2384 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_FIXUP_ACER_EAPD),
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002385 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
2386 ALC882_FIXUP_ACER_ASPIRE_4930G),
2387 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
2388 ALC882_FIXUP_ACER_ASPIRE_4930G),
2389 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
2390 ALC882_FIXUP_ACER_ASPIRE_8930G),
2391 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
2392 ALC882_FIXUP_ACER_ASPIRE_8930G),
2393 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
2394 ALC882_FIXUP_ACER_ASPIRE_4930G),
2395 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
2396 ALC882_FIXUP_ACER_ASPIRE_4930G),
2397 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
2398 ALC882_FIXUP_ACER_ASPIRE_4930G),
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002399 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", ALC882_FIXUP_PB_M5210),
Takashi Iwaif5c53d82012-05-07 10:07:33 +02002400 SND_PCI_QUIRK(0x1025, 0x021e, "Acer Aspire 5739G",
2401 ALC882_FIXUP_ACER_ASPIRE_4930G),
Takashi Iwai02a237b2012-02-13 15:25:07 +01002402 SND_PCI_QUIRK(0x1025, 0x0259, "Acer Aspire 5935", ALC889_FIXUP_DAC_ROUTE),
Takashi Iwaife97da12012-04-12 08:00:19 +02002403 SND_PCI_QUIRK(0x1025, 0x026b, "Acer Aspire 8940G", ALC882_FIXUP_ACER_ASPIRE_8930G),
Takashi Iwaiac9b1cd2011-11-09 17:45:55 +01002404 SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", ALC882_FIXUP_ACER_ASPIRE_7736),
Takashi Iwai177943a32011-11-09 12:55:18 +01002405 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_FIXUP_EAPD),
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002406 SND_PCI_QUIRK(0x1043, 0x1873, "ASUS W90V", ALC882_FIXUP_ASUS_W90V),
Takashi Iwai68ef0562011-11-09 18:24:44 +01002407 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_FIXUP_ASUS_W2JC),
Takashi Iwai0e7cc2e2011-11-09 12:42:48 +01002408 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_FIXUP_EEE1601),
Takashi Iwai1f0bbf02013-11-28 15:21:21 +01002409 SND_PCI_QUIRK(0x1043, 0x84bc, "ASUS ET2700", ALC887_FIXUP_ASUS_BASS),
Takashi Iwai85bcf962016-12-06 16:20:36 +01002410 SND_PCI_QUIRK(0x1043, 0x8691, "ASUS ROG Ranger VIII", ALC882_FIXUP_GPIO3),
Takashi Iwaiac9b1cd2011-11-09 17:45:55 +01002411 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT),
Takashi Iwaie427c232012-07-29 10:04:08 +02002412 SND_PCI_QUIRK(0x104d, 0x905a, "Sony Vaio Z", ALC882_FIXUP_NO_PRIMARY_HP),
Sergei A. Trusov3f3c3712017-08-02 20:23:48 +10002413 SND_PCI_QUIRK(0x104d, 0x9060, "Sony Vaio VPCL14M1R", ALC882_FIXUP_NO_PRIMARY_HP),
Fernando Luis Vázquez Cao12e31a72013-02-12 16:47:44 +09002414 SND_PCI_QUIRK(0x104d, 0x9043, "Sony Vaio VGC-LN51JGB", ALC882_FIXUP_NO_PRIMARY_HP),
Takashi Iwaic44d9b12016-02-07 09:38:26 +01002415 SND_PCI_QUIRK(0x104d, 0x9044, "Sony VAIO AiO", ALC882_FIXUP_NO_PRIMARY_HP),
Takashi Iwai56710872011-11-14 17:42:11 +01002416
2417 /* All Apple entries are in codec SSIDs */
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002418 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC889_FIXUP_MBP_VREF),
2419 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC889_FIXUP_MBP_VREF),
2420 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF),
Takashi Iwaic20f31e2014-02-03 11:02:10 +01002421 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC889_FIXUP_MP11_VREF),
Takashi Iwai56710872011-11-14 17:42:11 +01002422 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_FIXUP_MACPRO_GPIO),
2423 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_FIXUP_MACPRO_GPIO),
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002424 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC889_FIXUP_MBP_VREF),
2425 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889_FIXUP_MBP_VREF),
Takashi Iwai56710872011-11-14 17:42:11 +01002426 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_FIXUP_EAPD),
Adrien Vergée7729a42014-01-24 14:56:14 -05002427 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC889_FIXUP_MBA11_VREF),
Takashi Iwai0756f092013-12-04 13:59:45 +01002428 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC889_FIXUP_MBA21_VREF),
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002429 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889_FIXUP_MBP_VREF),
2430 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF),
Takashi Iwai56710872011-11-14 17:42:11 +01002431 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_FIXUP_MACPRO_GPIO),
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002432 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC889_FIXUP_IMAC91_VREF),
2433 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC889_FIXUP_IMAC91_VREF),
2434 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC889_FIXUP_IMAC91_VREF),
Mario Kleiner9f660a12015-12-22 00:45:43 +01002435 SND_PCI_QUIRK(0x106b, 0x4200, "Mac Pro 4,1/5,1", ALC889_FIXUP_MP41_VREF),
Takashi Iwai05193632012-11-12 10:07:36 +01002436 SND_PCI_QUIRK(0x106b, 0x4300, "iMac 9,1", ALC889_FIXUP_IMAC91_VREF),
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002437 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC889_FIXUP_IMAC91_VREF),
2438 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC889_FIXUP_IMAC91_VREF),
Takashi Iwai649ccd02015-07-30 22:30:29 +02002439 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC889_FIXUP_MBA11_VREF),
Takashi Iwai56710872011-11-14 17:42:11 +01002440
Takashi Iwai7a6069b2011-11-09 15:22:01 +01002441 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC882_FIXUP_EAPD),
David Henningssonb2c53e22014-01-01 14:01:34 +01002442 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3/Z87X-UD3H", ALC889_FIXUP_FRONT_HP_NO_PRESENCE),
Takashi Iwai7beb3a62017-04-10 18:05:52 +02002443 SND_PCI_QUIRK(0x1458, 0xa0b8, "Gigabyte AZ370-Gaming", ALC1220_FIXUP_GB_DUAL_CODECS),
Takashi Iwaid2c3b142017-06-01 09:35:30 +02002444 SND_PCI_QUIRK(0x1462, 0x7350, "MSI-7350", ALC889_FIXUP_CD),
Takashi Iwai63691582017-05-22 16:32:46 +02002445 SND_PCI_QUIRK(0x1462, 0xda57, "MSI Z270-Gaming", ALC1220_FIXUP_GB_DUAL_CODECS),
Takashi Iwaid2c3b142017-06-01 09:35:30 +02002446 SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3),
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002447 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX),
Peisen0202f5c2017-10-26 10:35:36 +08002448 SND_PCI_QUIRK(0x1558, 0x9501, "Clevo P950HR", ALC1220_FIXUP_CLEVO_P950),
Takashi Iwaif3d737b2018-07-17 17:08:32 +02002449 SND_PCI_QUIRK(0x1558, 0x95e1, "Clevo P95xER", ALC1220_FIXUP_CLEVO_P950),
Jeremy Soller2f0d5202018-05-07 09:28:45 -06002450 SND_PCI_QUIRK(0x1558, 0x95e2, "Clevo P950ER", ALC1220_FIXUP_CLEVO_P950),
Richard Sailer503d90b2019-06-19 13:33:11 +02002451 SND_PCI_QUIRK(0x1558, 0x96e1, "Clevo P960[ER][CDFN]-K", ALC1220_FIXUP_CLEVO_P950),
2452 SND_PCI_QUIRK(0x1558, 0x97e1, "Clevo P970[ER][CDFN]", ALC1220_FIXUP_CLEVO_P950),
2453 SND_PCI_QUIRK(0x1558, 0x65d1, "Clevo PB51[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
2454 SND_PCI_QUIRK(0x1558, 0x67d1, "Clevo PB71[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
Takashi Iwai7a6069b2011-11-09 15:22:01 +01002455 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD),
2456 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD),
Takashi Iwaiac9b1cd2011-11-09 17:45:55 +01002457 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", ALC882_FIXUP_LENOVO_Y530),
Takashi Iwai68ef0562011-11-09 18:24:44 +01002458 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_FIXUP_COEF),
Takashi Iwai1d045db2011-07-07 18:23:21 +02002459 {}
2460};
2461
Takashi Iwai1727a772013-01-10 09:52:52 +01002462static const struct hda_model_fixup alc882_fixup_models[] = {
Takashi Iwai772c2912018-06-26 17:17:53 +02002463 {.id = ALC882_FIXUP_ABIT_AW9D_MAX, .name = "abit-aw9d"},
2464 {.id = ALC882_FIXUP_LENOVO_Y530, .name = "lenovo-y530"},
2465 {.id = ALC882_FIXUP_ACER_ASPIRE_7736, .name = "acer-aspire-7736"},
2466 {.id = ALC882_FIXUP_ASUS_W90V, .name = "asus-w90v"},
2467 {.id = ALC889_FIXUP_CD, .name = "cd"},
2468 {.id = ALC889_FIXUP_FRONT_HP_NO_PRESENCE, .name = "no-front-hp"},
2469 {.id = ALC889_FIXUP_VAIO_TT, .name = "vaio-tt"},
2470 {.id = ALC888_FIXUP_EEE1601, .name = "eee1601"},
2471 {.id = ALC882_FIXUP_EAPD, .name = "alc882-eapd"},
2472 {.id = ALC883_FIXUP_EAPD, .name = "alc883-eapd"},
2473 {.id = ALC882_FIXUP_GPIO1, .name = "gpio1"},
2474 {.id = ALC882_FIXUP_GPIO2, .name = "gpio2"},
2475 {.id = ALC882_FIXUP_GPIO3, .name = "gpio3"},
2476 {.id = ALC889_FIXUP_COEF, .name = "alc889-coef"},
2477 {.id = ALC882_FIXUP_ASUS_W2JC, .name = "asus-w2jc"},
Takashi Iwai912093b2012-04-11 14:03:41 +02002478 {.id = ALC882_FIXUP_ACER_ASPIRE_4930G, .name = "acer-aspire-4930g"},
2479 {.id = ALC882_FIXUP_ACER_ASPIRE_8930G, .name = "acer-aspire-8930g"},
2480 {.id = ALC883_FIXUP_ACER_EAPD, .name = "acer-aspire"},
Takashi Iwai772c2912018-06-26 17:17:53 +02002481 {.id = ALC885_FIXUP_MACPRO_GPIO, .name = "macpro-gpio"},
2482 {.id = ALC889_FIXUP_DAC_ROUTE, .name = "dac-route"},
2483 {.id = ALC889_FIXUP_MBP_VREF, .name = "mbp-vref"},
2484 {.id = ALC889_FIXUP_IMAC91_VREF, .name = "imac91-vref"},
2485 {.id = ALC889_FIXUP_MBA11_VREF, .name = "mba11-vref"},
2486 {.id = ALC889_FIXUP_MBA21_VREF, .name = "mba21-vref"},
2487 {.id = ALC889_FIXUP_MP11_VREF, .name = "mp11-vref"},
2488 {.id = ALC889_FIXUP_MP41_VREF, .name = "mp41-vref"},
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002489 {.id = ALC882_FIXUP_INV_DMIC, .name = "inv-dmic"},
Takashi Iwaie427c232012-07-29 10:04:08 +02002490 {.id = ALC882_FIXUP_NO_PRIMARY_HP, .name = "no-primary-hp"},
Takashi Iwai772c2912018-06-26 17:17:53 +02002491 {.id = ALC887_FIXUP_ASUS_BASS, .name = "asus-bass"},
Takashi Iwaiba90d6a2017-05-22 16:38:47 +02002492 {.id = ALC1220_FIXUP_GB_DUAL_CODECS, .name = "dual-codecs"},
Takashi Iwai772c2912018-06-26 17:17:53 +02002493 {.id = ALC1220_FIXUP_CLEVO_P950, .name = "clevo-p950"},
Takashi Iwai912093b2012-04-11 14:03:41 +02002494 {}
2495};
2496
Takashi Iwai1d045db2011-07-07 18:23:21 +02002497/*
2498 * BIOS auto configuration
2499 */
2500/* almost identical with ALC880 parser... */
2501static int alc882_parse_auto_config(struct hda_codec *codec)
2502{
Takashi Iwai1d045db2011-07-07 18:23:21 +02002503 static const hda_nid_t alc882_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002504 static const hda_nid_t alc882_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2505 return alc_parse_auto_config(codec, alc882_ignore, alc882_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002506}
2507
Takashi Iwai1d045db2011-07-07 18:23:21 +02002508/*
2509 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002510static int patch_alc882(struct hda_codec *codec)
2511{
2512 struct alc_spec *spec;
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002513 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002514
Takashi Iwai3de95172012-05-07 18:03:15 +02002515 err = alc_alloc_spec(codec, 0x0b);
2516 if (err < 0)
2517 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002518
Takashi Iwai3de95172012-05-07 18:03:15 +02002519 spec = codec->spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002520
Takashi Iwai7639a062015-03-03 10:07:24 +01002521 switch (codec->core.vendor_id) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002522 case 0x10ec0882:
2523 case 0x10ec0885:
Takashi Iwaiacf08082014-09-02 07:21:56 +02002524 case 0x10ec0900:
Kailang Yanga535ad52017-01-16 16:59:26 +08002525 case 0x10ec1220:
Takashi Iwai1d045db2011-07-07 18:23:21 +02002526 break;
2527 default:
2528 /* ALC883 and variants */
2529 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
2530 break;
2531 }
2532
Takashi Iwaic9af7532019-05-10 11:01:43 +02002533 alc_pre_init(codec);
2534
Takashi Iwai1727a772013-01-10 09:52:52 +01002535 snd_hda_pick_fixup(codec, alc882_fixup_models, alc882_fixup_tbl,
Takashi Iwai912093b2012-04-11 14:03:41 +02002536 alc882_fixups);
Takashi Iwai1727a772013-01-10 09:52:52 +01002537 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002538
2539 alc_auto_parse_customize_define(codec);
2540
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002541 if (has_cdefine_beep(codec))
2542 spec->gen.beep_nid = 0x01;
2543
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002544 /* automatic parse from the BIOS config */
2545 err = alc882_parse_auto_config(codec);
2546 if (err < 0)
2547 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002548
Takashi Iwaifea80fa2018-06-20 12:52:46 +02002549 if (!spec->gen.no_analog && spec->gen.beep_nid) {
2550 err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
2551 if (err < 0)
2552 goto error;
2553 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02002554
Takashi Iwai1727a772013-01-10 09:52:52 +01002555 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01002556
Takashi Iwai1d045db2011-07-07 18:23:21 +02002557 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02002558
2559 error:
2560 alc_free(codec);
2561 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002562}
2563
2564
2565/*
2566 * ALC262 support
2567 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002568static int alc262_parse_auto_config(struct hda_codec *codec)
2569{
Takashi Iwai1d045db2011-07-07 18:23:21 +02002570 static const hda_nid_t alc262_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002571 static const hda_nid_t alc262_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2572 return alc_parse_auto_config(codec, alc262_ignore, alc262_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002573}
2574
2575/*
2576 * Pin config fixes
2577 */
2578enum {
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002579 ALC262_FIXUP_FSC_H270,
Takashi Iwai7513e6d2013-01-18 15:41:34 +01002580 ALC262_FIXUP_FSC_S7110,
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002581 ALC262_FIXUP_HP_Z200,
2582 ALC262_FIXUP_TYAN,
Takashi Iwaic4701502011-11-07 14:20:07 +01002583 ALC262_FIXUP_LENOVO_3000,
Takashi Iwaib42590b2011-11-07 14:41:01 +01002584 ALC262_FIXUP_BENQ,
2585 ALC262_FIXUP_BENQ_T31,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002586 ALC262_FIXUP_INV_DMIC,
Mengdong Linb5c66112013-11-29 00:35:35 -05002587 ALC262_FIXUP_INTEL_BAYLEYBAY,
Takashi Iwai1d045db2011-07-07 18:23:21 +02002588};
2589
Takashi Iwai1727a772013-01-10 09:52:52 +01002590static const struct hda_fixup alc262_fixups[] = {
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002591 [ALC262_FIXUP_FSC_H270] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002592 .type = HDA_FIXUP_PINS,
2593 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002594 { 0x14, 0x99130110 }, /* speaker */
2595 { 0x15, 0x0221142f }, /* front HP */
2596 { 0x1b, 0x0121141f }, /* rear HP */
2597 { }
2598 }
2599 },
Takashi Iwai7513e6d2013-01-18 15:41:34 +01002600 [ALC262_FIXUP_FSC_S7110] = {
2601 .type = HDA_FIXUP_PINS,
2602 .v.pins = (const struct hda_pintbl[]) {
2603 { 0x15, 0x90170110 }, /* speaker */
2604 { }
2605 },
2606 .chained = true,
2607 .chain_id = ALC262_FIXUP_BENQ,
2608 },
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002609 [ALC262_FIXUP_HP_Z200] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002610 .type = HDA_FIXUP_PINS,
2611 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002612 { 0x16, 0x99130120 }, /* internal speaker */
2613 { }
2614 }
2615 },
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002616 [ALC262_FIXUP_TYAN] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002617 .type = HDA_FIXUP_PINS,
2618 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002619 { 0x14, 0x1993e1f0 }, /* int AUX */
2620 { }
2621 }
2622 },
Takashi Iwaic4701502011-11-07 14:20:07 +01002623 [ALC262_FIXUP_LENOVO_3000] = {
Takashi Iwaifd108212013-01-10 10:18:14 +01002624 .type = HDA_FIXUP_PINCTLS,
2625 .v.pins = (const struct hda_pintbl[]) {
2626 { 0x19, PIN_VREF50 },
Takashi Iwaib42590b2011-11-07 14:41:01 +01002627 {}
2628 },
2629 .chained = true,
2630 .chain_id = ALC262_FIXUP_BENQ,
2631 },
2632 [ALC262_FIXUP_BENQ] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002633 .type = HDA_FIXUP_VERBS,
Takashi Iwaib42590b2011-11-07 14:41:01 +01002634 .v.verbs = (const struct hda_verb[]) {
Takashi Iwaic4701502011-11-07 14:20:07 +01002635 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2636 { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
2637 {}
2638 }
2639 },
Takashi Iwaib42590b2011-11-07 14:41:01 +01002640 [ALC262_FIXUP_BENQ_T31] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002641 .type = HDA_FIXUP_VERBS,
Takashi Iwaib42590b2011-11-07 14:41:01 +01002642 .v.verbs = (const struct hda_verb[]) {
2643 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2644 { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
2645 {}
2646 }
2647 },
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002648 [ALC262_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002649 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02002650 .v.func = alc_fixup_inv_dmic,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002651 },
Mengdong Linb5c66112013-11-29 00:35:35 -05002652 [ALC262_FIXUP_INTEL_BAYLEYBAY] = {
2653 .type = HDA_FIXUP_FUNC,
2654 .v.func = alc_fixup_no_depop_delay,
2655 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02002656};
2657
2658static const struct snd_pci_quirk alc262_fixup_tbl[] = {
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002659 SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", ALC262_FIXUP_HP_Z200),
Takashi Iwai7513e6d2013-01-18 15:41:34 +01002660 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu Lifebook S7110", ALC262_FIXUP_FSC_S7110),
Takashi Iwai3dcd3be2011-11-07 14:59:40 +01002661 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FIXUP_BENQ),
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002662 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_FIXUP_TYAN),
Takashi Iwai275ec0c2018-06-22 12:17:45 +02002663 SND_PCI_QUIRK(0x1734, 0x1141, "FSC ESPRIMO U9210", ALC262_FIXUP_FSC_H270),
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002664 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", ALC262_FIXUP_FSC_H270),
Takashi Iwaic4701502011-11-07 14:20:07 +01002665 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000", ALC262_FIXUP_LENOVO_3000),
Takashi Iwaib42590b2011-11-07 14:41:01 +01002666 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_FIXUP_BENQ),
2667 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_FIXUP_BENQ_T31),
Mengdong Linb5c66112013-11-29 00:35:35 -05002668 SND_PCI_QUIRK(0x8086, 0x7270, "BayleyBay", ALC262_FIXUP_INTEL_BAYLEYBAY),
Takashi Iwai1d045db2011-07-07 18:23:21 +02002669 {}
2670};
2671
Takashi Iwai1727a772013-01-10 09:52:52 +01002672static const struct hda_model_fixup alc262_fixup_models[] = {
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002673 {.id = ALC262_FIXUP_INV_DMIC, .name = "inv-dmic"},
Takashi Iwaie43c44d2018-06-26 17:02:08 +02002674 {.id = ALC262_FIXUP_FSC_H270, .name = "fsc-h270"},
2675 {.id = ALC262_FIXUP_FSC_S7110, .name = "fsc-s7110"},
2676 {.id = ALC262_FIXUP_HP_Z200, .name = "hp-z200"},
2677 {.id = ALC262_FIXUP_TYAN, .name = "tyan"},
2678 {.id = ALC262_FIXUP_LENOVO_3000, .name = "lenovo-3000"},
2679 {.id = ALC262_FIXUP_BENQ, .name = "benq"},
2680 {.id = ALC262_FIXUP_BENQ_T31, .name = "benq-t31"},
2681 {.id = ALC262_FIXUP_INTEL_BAYLEYBAY, .name = "bayleybay"},
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002682 {}
2683};
Takashi Iwai1d045db2011-07-07 18:23:21 +02002684
Takashi Iwai1d045db2011-07-07 18:23:21 +02002685/*
2686 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002687static int patch_alc262(struct hda_codec *codec)
2688{
2689 struct alc_spec *spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002690 int err;
2691
Takashi Iwai3de95172012-05-07 18:03:15 +02002692 err = alc_alloc_spec(codec, 0x0b);
2693 if (err < 0)
2694 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002695
Takashi Iwai3de95172012-05-07 18:03:15 +02002696 spec = codec->spec;
Takashi Iwai08c189f2012-12-19 15:22:24 +01002697 spec->gen.shared_mic_vref_pin = 0x18;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002698
Takashi Iwai225068a2015-05-29 10:42:14 +02002699 spec->shutup = alc_eapd_shutup;
2700
Takashi Iwai1d045db2011-07-07 18:23:21 +02002701#if 0
2702 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
2703 * under-run
2704 */
Takashi Iwai98b24882014-08-18 13:47:50 +02002705 alc_update_coefex_idx(codec, 0x1a, 7, 0, 0x80);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002706#endif
Takashi Iwai1d045db2011-07-07 18:23:21 +02002707 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
2708
Takashi Iwaic9af7532019-05-10 11:01:43 +02002709 alc_pre_init(codec);
2710
Takashi Iwai1727a772013-01-10 09:52:52 +01002711 snd_hda_pick_fixup(codec, alc262_fixup_models, alc262_fixup_tbl,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002712 alc262_fixups);
Takashi Iwai1727a772013-01-10 09:52:52 +01002713 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002714
Takashi Iwaiaf741c12012-05-07 18:09:48 +02002715 alc_auto_parse_customize_define(codec);
2716
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002717 if (has_cdefine_beep(codec))
2718 spec->gen.beep_nid = 0x01;
2719
Takashi Iwai42399f72011-11-07 17:18:44 +01002720 /* automatic parse from the BIOS config */
2721 err = alc262_parse_auto_config(codec);
2722 if (err < 0)
2723 goto error;
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002724
Takashi Iwaifea80fa2018-06-20 12:52:46 +02002725 if (!spec->gen.no_analog && spec->gen.beep_nid) {
2726 err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
2727 if (err < 0)
2728 goto error;
2729 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02002730
Takashi Iwai1727a772013-01-10 09:52:52 +01002731 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01002732
Takashi Iwai1d045db2011-07-07 18:23:21 +02002733 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02002734
2735 error:
2736 alc_free(codec);
2737 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002738}
2739
2740/*
2741 * ALC268
2742 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002743/* bind Beep switches of both NID 0x0f and 0x10 */
Takashi Iwaia7177772017-05-10 12:04:08 +02002744static int alc268_beep_switch_put(struct snd_kcontrol *kcontrol,
2745 struct snd_ctl_elem_value *ucontrol)
2746{
2747 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2748 unsigned long pval;
2749 int err;
2750
2751 mutex_lock(&codec->control_mutex);
2752 pval = kcontrol->private_value;
2753 kcontrol->private_value = (pval & ~0xff) | 0x0f;
2754 err = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
2755 if (err >= 0) {
2756 kcontrol->private_value = (pval & ~0xff) | 0x10;
2757 err = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
2758 }
2759 kcontrol->private_value = pval;
2760 mutex_unlock(&codec->control_mutex);
2761 return err;
2762}
Takashi Iwai1d045db2011-07-07 18:23:21 +02002763
2764static const struct snd_kcontrol_new alc268_beep_mixer[] = {
2765 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
Takashi Iwaia7177772017-05-10 12:04:08 +02002766 {
2767 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2768 .name = "Beep Playback Switch",
2769 .subdevice = HDA_SUBDEV_AMP_FLAG,
2770 .info = snd_hda_mixer_amp_switch_info,
2771 .get = snd_hda_mixer_amp_switch_get,
2772 .put = alc268_beep_switch_put,
2773 .private_value = HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT)
2774 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02002775};
2776
2777/* set PCBEEP vol = 0, mute connections */
2778static const struct hda_verb alc268_beep_init_verbs[] = {
2779 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2780 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2781 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2782 { }
2783};
2784
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002785enum {
2786 ALC268_FIXUP_INV_DMIC,
Takashi Iwaicb766402012-10-20 10:55:21 +02002787 ALC268_FIXUP_HP_EAPD,
Takashi Iwai24eff322013-11-04 18:21:08 +01002788 ALC268_FIXUP_SPDIF,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002789};
2790
Takashi Iwai1727a772013-01-10 09:52:52 +01002791static const struct hda_fixup alc268_fixups[] = {
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002792 [ALC268_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002793 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02002794 .v.func = alc_fixup_inv_dmic,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002795 },
Takashi Iwaicb766402012-10-20 10:55:21 +02002796 [ALC268_FIXUP_HP_EAPD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002797 .type = HDA_FIXUP_VERBS,
Takashi Iwaicb766402012-10-20 10:55:21 +02002798 .v.verbs = (const struct hda_verb[]) {
2799 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 0},
2800 {}
2801 }
2802 },
Takashi Iwai24eff322013-11-04 18:21:08 +01002803 [ALC268_FIXUP_SPDIF] = {
2804 .type = HDA_FIXUP_PINS,
2805 .v.pins = (const struct hda_pintbl[]) {
2806 { 0x1e, 0x014b1180 }, /* enable SPDIF out */
2807 {}
2808 }
2809 },
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002810};
2811
Takashi Iwai1727a772013-01-10 09:52:52 +01002812static const struct hda_model_fixup alc268_fixup_models[] = {
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002813 {.id = ALC268_FIXUP_INV_DMIC, .name = "inv-dmic"},
Takashi Iwaicb766402012-10-20 10:55:21 +02002814 {.id = ALC268_FIXUP_HP_EAPD, .name = "hp-eapd"},
Takashi Iwai03bf11c2018-06-26 16:56:41 +02002815 {.id = ALC268_FIXUP_SPDIF, .name = "spdif"},
Takashi Iwaicb766402012-10-20 10:55:21 +02002816 {}
2817};
2818
2819static const struct snd_pci_quirk alc268_fixup_tbl[] = {
Takashi Iwai24eff322013-11-04 18:21:08 +01002820 SND_PCI_QUIRK(0x1025, 0x0139, "Acer TravelMate 6293", ALC268_FIXUP_SPDIF),
David Henningssonfcd8f3b2013-01-28 05:45:47 +01002821 SND_PCI_QUIRK(0x1025, 0x015b, "Acer AOA 150 (ZG5)", ALC268_FIXUP_INV_DMIC),
Takashi Iwaicb766402012-10-20 10:55:21 +02002822 /* below is codec SSID since multiple Toshiba laptops have the
2823 * same PCI SSID 1179:ff00
2824 */
2825 SND_PCI_QUIRK(0x1179, 0xff06, "Toshiba P200", ALC268_FIXUP_HP_EAPD),
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002826 {}
2827};
2828
Takashi Iwai1d045db2011-07-07 18:23:21 +02002829/*
2830 * BIOS auto configuration
2831 */
2832static int alc268_parse_auto_config(struct hda_codec *codec)
2833{
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002834 static const hda_nid_t alc268_ssids[] = { 0x15, 0x1b, 0x14, 0 };
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002835 return alc_parse_auto_config(codec, NULL, alc268_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002836}
2837
Takashi Iwai1d045db2011-07-07 18:23:21 +02002838/*
2839 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002840static int patch_alc268(struct hda_codec *codec)
2841{
2842 struct alc_spec *spec;
Takashi Iwaia5cb4632018-06-20 12:50:11 +02002843 int i, err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002844
Takashi Iwai1d045db2011-07-07 18:23:21 +02002845 /* ALC268 has no aa-loopback mixer */
Takashi Iwai3de95172012-05-07 18:03:15 +02002846 err = alc_alloc_spec(codec, 0);
2847 if (err < 0)
2848 return err;
2849
2850 spec = codec->spec;
Takashi Iwai2722b532019-08-22 09:55:37 +02002851 if (has_cdefine_beep(codec))
2852 spec->gen.beep_nid = 0x01;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002853
Takashi Iwai225068a2015-05-29 10:42:14 +02002854 spec->shutup = alc_eapd_shutup;
2855
Takashi Iwaic9af7532019-05-10 11:01:43 +02002856 alc_pre_init(codec);
2857
Takashi Iwai1727a772013-01-10 09:52:52 +01002858 snd_hda_pick_fixup(codec, alc268_fixup_models, alc268_fixup_tbl, alc268_fixups);
2859 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002860
Takashi Iwai6ebb8052011-08-16 15:15:40 +02002861 /* automatic parse from the BIOS config */
2862 err = alc268_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02002863 if (err < 0)
2864 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002865
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002866 if (err > 0 && !spec->gen.no_analog &&
2867 spec->gen.autocfg.speaker_pins[0] != 0x1d) {
Takashi Iwaia5cb4632018-06-20 12:50:11 +02002868 for (i = 0; i < ARRAY_SIZE(alc268_beep_mixer); i++) {
2869 if (!snd_hda_gen_add_kctl(&spec->gen, NULL,
2870 &alc268_beep_mixer[i])) {
2871 err = -ENOMEM;
2872 goto error;
2873 }
2874 }
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002875 snd_hda_add_verbs(codec, alc268_beep_init_verbs);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002876 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
2877 /* override the amp caps for beep generator */
2878 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
2879 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
2880 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
2881 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
2882 (0 << AC_AMPCAP_MUTE_SHIFT));
2883 }
2884
Takashi Iwai1727a772013-01-10 09:52:52 +01002885 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002886
Takashi Iwai1d045db2011-07-07 18:23:21 +02002887 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02002888
2889 error:
2890 alc_free(codec);
2891 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002892}
2893
2894/*
2895 * ALC269
2896 */
Takashi Iwai08c189f2012-12-19 15:22:24 +01002897
Takashi Iwai1d045db2011-07-07 18:23:21 +02002898static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002899 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002900};
2901
2902static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002903 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002904};
2905
Takashi Iwai1d045db2011-07-07 18:23:21 +02002906/* different alc269-variants */
2907enum {
2908 ALC269_TYPE_ALC269VA,
2909 ALC269_TYPE_ALC269VB,
2910 ALC269_TYPE_ALC269VC,
Kailang Yangadcc70b2012-05-25 08:08:38 +02002911 ALC269_TYPE_ALC269VD,
Kailang Yang065380f2013-01-10 10:25:48 +01002912 ALC269_TYPE_ALC280,
2913 ALC269_TYPE_ALC282,
Kailang Yang2af02be2013-08-22 10:03:50 +02002914 ALC269_TYPE_ALC283,
Kailang Yang065380f2013-01-10 10:25:48 +01002915 ALC269_TYPE_ALC284,
Kailang Yang4731d5d2017-06-30 15:22:57 +08002916 ALC269_TYPE_ALC293,
Kailang Yang7fc7d042013-04-25 11:04:43 +02002917 ALC269_TYPE_ALC286,
Kailang Yang506b62c2014-12-18 17:07:44 +08002918 ALC269_TYPE_ALC298,
Kailang Yang1d04c9d2013-10-24 11:35:18 +02002919 ALC269_TYPE_ALC255,
Kailang Yang4344aec2014-12-17 17:39:05 +08002920 ALC269_TYPE_ALC256,
Kailang Yangf429e7e2017-12-05 15:38:24 +08002921 ALC269_TYPE_ALC257,
Kailang Yang0a6f0602017-06-30 16:00:48 +08002922 ALC269_TYPE_ALC215,
Kailang Yang42314302016-02-03 15:03:50 +08002923 ALC269_TYPE_ALC225,
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08002924 ALC269_TYPE_ALC294,
Kailang Yang1078bef2018-11-08 16:36:15 +08002925 ALC269_TYPE_ALC300,
Kailang Yangf0778872019-10-24 15:13:32 +08002926 ALC269_TYPE_ALC623,
Kailang Yang6fbae352016-05-30 16:44:20 +08002927 ALC269_TYPE_ALC700,
Takashi Iwai1d045db2011-07-07 18:23:21 +02002928};
2929
2930/*
2931 * BIOS auto configuration
2932 */
2933static int alc269_parse_auto_config(struct hda_codec *codec)
2934{
Takashi Iwai1d045db2011-07-07 18:23:21 +02002935 static const hda_nid_t alc269_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002936 static const hda_nid_t alc269_ssids[] = { 0, 0x1b, 0x14, 0x21 };
2937 static const hda_nid_t alc269va_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2938 struct alc_spec *spec = codec->spec;
Kailang Yangadcc70b2012-05-25 08:08:38 +02002939 const hda_nid_t *ssids;
2940
2941 switch (spec->codec_variant) {
2942 case ALC269_TYPE_ALC269VA:
2943 case ALC269_TYPE_ALC269VC:
Kailang Yang065380f2013-01-10 10:25:48 +01002944 case ALC269_TYPE_ALC280:
2945 case ALC269_TYPE_ALC284:
Kailang Yang4731d5d2017-06-30 15:22:57 +08002946 case ALC269_TYPE_ALC293:
Kailang Yangadcc70b2012-05-25 08:08:38 +02002947 ssids = alc269va_ssids;
2948 break;
2949 case ALC269_TYPE_ALC269VB:
2950 case ALC269_TYPE_ALC269VD:
Kailang Yang065380f2013-01-10 10:25:48 +01002951 case ALC269_TYPE_ALC282:
Kailang Yang2af02be2013-08-22 10:03:50 +02002952 case ALC269_TYPE_ALC283:
Kailang Yang7fc7d042013-04-25 11:04:43 +02002953 case ALC269_TYPE_ALC286:
Kailang Yang506b62c2014-12-18 17:07:44 +08002954 case ALC269_TYPE_ALC298:
Kailang Yang1d04c9d2013-10-24 11:35:18 +02002955 case ALC269_TYPE_ALC255:
Kailang Yang4344aec2014-12-17 17:39:05 +08002956 case ALC269_TYPE_ALC256:
Kailang Yangf429e7e2017-12-05 15:38:24 +08002957 case ALC269_TYPE_ALC257:
Kailang Yang0a6f0602017-06-30 16:00:48 +08002958 case ALC269_TYPE_ALC215:
Kailang Yang42314302016-02-03 15:03:50 +08002959 case ALC269_TYPE_ALC225:
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08002960 case ALC269_TYPE_ALC294:
Kailang Yang1078bef2018-11-08 16:36:15 +08002961 case ALC269_TYPE_ALC300:
Kailang Yangf0778872019-10-24 15:13:32 +08002962 case ALC269_TYPE_ALC623:
Kailang Yang6fbae352016-05-30 16:44:20 +08002963 case ALC269_TYPE_ALC700:
Kailang Yangadcc70b2012-05-25 08:08:38 +02002964 ssids = alc269_ssids;
2965 break;
2966 default:
2967 ssids = alc269_ssids;
2968 break;
2969 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02002970
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002971 return alc_parse_auto_config(codec, alc269_ignore, ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002972}
2973
Kailang Yang1387e2d2012-11-08 10:23:18 +01002974static void alc269vb_toggle_power_output(struct hda_codec *codec, int power_up)
Takashi Iwai1d045db2011-07-07 18:23:21 +02002975{
Takashi Iwai98b24882014-08-18 13:47:50 +02002976 alc_update_coef_idx(codec, 0x04, 1 << 11, power_up ? (1 << 11) : 0);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002977}
2978
2979static void alc269_shutup(struct hda_codec *codec)
2980{
Kailang Yangadcc70b2012-05-25 08:08:38 +02002981 struct alc_spec *spec = codec->spec;
2982
Kailang Yang1387e2d2012-11-08 10:23:18 +01002983 if (spec->codec_variant == ALC269_TYPE_ALC269VB)
2984 alc269vb_toggle_power_output(codec, 0);
2985 if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
2986 (alc_get_coef0(codec) & 0x00ff) == 0x018) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002987 msleep(150);
2988 }
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01002989 alc_shutup_pins(codec);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002990}
2991
Takashi Iwai54db6c32014-08-18 15:11:19 +02002992static struct coef_fw alc282_coefs[] = {
2993 WRITE_COEF(0x03, 0x0002), /* Power Down Control */
Kailang Yang32fa7e42014-10-24 16:26:01 +08002994 UPDATE_COEF(0x05, 0xff3f, 0x0700), /* FIFO and filter clock */
Takashi Iwai54db6c32014-08-18 15:11:19 +02002995 WRITE_COEF(0x07, 0x0200), /* DMIC control */
2996 UPDATE_COEF(0x06, 0x00f0, 0), /* Analog clock */
2997 UPDATE_COEF(0x08, 0xfffc, 0x0c2c), /* JD */
2998 WRITE_COEF(0x0a, 0xcccc), /* JD offset1 */
2999 WRITE_COEF(0x0b, 0xcccc), /* JD offset2 */
3000 WRITE_COEF(0x0e, 0x6e00), /* LDO1/2/3, DAC/ADC */
3001 UPDATE_COEF(0x0f, 0xf800, 0x1000), /* JD */
3002 UPDATE_COEF(0x10, 0xfc00, 0x0c00), /* Capless */
3003 WRITE_COEF(0x6f, 0x0), /* Class D test 4 */
3004 UPDATE_COEF(0x0c, 0xfe00, 0), /* IO power down directly */
3005 WRITE_COEF(0x34, 0xa0c0), /* ANC */
3006 UPDATE_COEF(0x16, 0x0008, 0), /* AGC MUX */
3007 UPDATE_COEF(0x1d, 0x00e0, 0), /* DAC simple content protection */
3008 UPDATE_COEF(0x1f, 0x00e0, 0), /* ADC simple content protection */
3009 WRITE_COEF(0x21, 0x8804), /* DAC ADC Zero Detection */
3010 WRITE_COEF(0x63, 0x2902), /* PLL */
3011 WRITE_COEF(0x68, 0xa080), /* capless control 2 */
3012 WRITE_COEF(0x69, 0x3400), /* capless control 3 */
3013 WRITE_COEF(0x6a, 0x2f3e), /* capless control 4 */
3014 WRITE_COEF(0x6b, 0x0), /* capless control 5 */
3015 UPDATE_COEF(0x6d, 0x0fff, 0x0900), /* class D test 2 */
3016 WRITE_COEF(0x6e, 0x110a), /* class D test 3 */
3017 UPDATE_COEF(0x70, 0x00f8, 0x00d8), /* class D test 5 */
3018 WRITE_COEF(0x71, 0x0014), /* class D test 6 */
3019 WRITE_COEF(0x72, 0xc2ba), /* classD OCP */
3020 UPDATE_COEF(0x77, 0x0f80, 0), /* classD pure DC test */
3021 WRITE_COEF(0x6c, 0xfc06), /* Class D amp control */
3022 {}
3023};
3024
Kailang Yangcb149cb2014-03-18 16:45:32 +08003025static void alc282_restore_default_value(struct hda_codec *codec)
3026{
Takashi Iwai54db6c32014-08-18 15:11:19 +02003027 alc_process_coef_fw(codec, alc282_coefs);
Kailang Yangcb149cb2014-03-18 16:45:32 +08003028}
3029
Kailang Yang7b5c7a02014-03-18 16:15:54 +08003030static void alc282_init(struct hda_codec *codec)
3031{
3032 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003033 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang7b5c7a02014-03-18 16:15:54 +08003034 bool hp_pin_sense;
3035 int coef78;
3036
Kailang Yangcb149cb2014-03-18 16:45:32 +08003037 alc282_restore_default_value(codec);
3038
Kailang Yang7b5c7a02014-03-18 16:15:54 +08003039 if (!hp_pin)
3040 return;
3041 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3042 coef78 = alc_read_coef_idx(codec, 0x78);
3043
3044 /* Index 0x78 Direct Drive HP AMP LPM Control 1 */
3045 /* Headphone capless set to high power mode */
3046 alc_write_coef_idx(codec, 0x78, 0x9004);
3047
3048 if (hp_pin_sense)
3049 msleep(2);
3050
3051 snd_hda_codec_write(codec, hp_pin, 0,
3052 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3053
3054 if (hp_pin_sense)
3055 msleep(85);
3056
3057 snd_hda_codec_write(codec, hp_pin, 0,
3058 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3059
3060 if (hp_pin_sense)
3061 msleep(100);
3062
3063 /* Headphone capless set to normal mode */
3064 alc_write_coef_idx(codec, 0x78, coef78);
3065}
3066
3067static void alc282_shutup(struct hda_codec *codec)
3068{
3069 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003070 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang7b5c7a02014-03-18 16:15:54 +08003071 bool hp_pin_sense;
3072 int coef78;
3073
3074 if (!hp_pin) {
3075 alc269_shutup(codec);
3076 return;
3077 }
3078
3079 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3080 coef78 = alc_read_coef_idx(codec, 0x78);
3081 alc_write_coef_idx(codec, 0x78, 0x9004);
3082
3083 if (hp_pin_sense)
3084 msleep(2);
3085
3086 snd_hda_codec_write(codec, hp_pin, 0,
3087 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3088
3089 if (hp_pin_sense)
3090 msleep(85);
3091
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003092 if (!spec->no_shutup_pins)
3093 snd_hda_codec_write(codec, hp_pin, 0,
3094 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
Kailang Yang7b5c7a02014-03-18 16:15:54 +08003095
3096 if (hp_pin_sense)
3097 msleep(100);
3098
3099 alc_auto_setup_eapd(codec, false);
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003100 alc_shutup_pins(codec);
Kailang Yang7b5c7a02014-03-18 16:15:54 +08003101 alc_write_coef_idx(codec, 0x78, coef78);
3102}
3103
Takashi Iwai54db6c32014-08-18 15:11:19 +02003104static struct coef_fw alc283_coefs[] = {
3105 WRITE_COEF(0x03, 0x0002), /* Power Down Control */
Kailang Yang56779862014-10-24 16:17:51 +08003106 UPDATE_COEF(0x05, 0xff3f, 0x0700), /* FIFO and filter clock */
Takashi Iwai54db6c32014-08-18 15:11:19 +02003107 WRITE_COEF(0x07, 0x0200), /* DMIC control */
3108 UPDATE_COEF(0x06, 0x00f0, 0), /* Analog clock */
3109 UPDATE_COEF(0x08, 0xfffc, 0x0c2c), /* JD */
3110 WRITE_COEF(0x0a, 0xcccc), /* JD offset1 */
3111 WRITE_COEF(0x0b, 0xcccc), /* JD offset2 */
3112 WRITE_COEF(0x0e, 0x6fc0), /* LDO1/2/3, DAC/ADC */
3113 UPDATE_COEF(0x0f, 0xf800, 0x1000), /* JD */
3114 UPDATE_COEF(0x10, 0xfc00, 0x0c00), /* Capless */
3115 WRITE_COEF(0x3a, 0x0), /* Class D test 4 */
3116 UPDATE_COEF(0x0c, 0xfe00, 0x0), /* IO power down directly */
3117 WRITE_COEF(0x22, 0xa0c0), /* ANC */
3118 UPDATE_COEFEX(0x53, 0x01, 0x000f, 0x0008), /* AGC MUX */
3119 UPDATE_COEF(0x1d, 0x00e0, 0), /* DAC simple content protection */
3120 UPDATE_COEF(0x1f, 0x00e0, 0), /* ADC simple content protection */
3121 WRITE_COEF(0x21, 0x8804), /* DAC ADC Zero Detection */
3122 WRITE_COEF(0x2e, 0x2902), /* PLL */
3123 WRITE_COEF(0x33, 0xa080), /* capless control 2 */
3124 WRITE_COEF(0x34, 0x3400), /* capless control 3 */
3125 WRITE_COEF(0x35, 0x2f3e), /* capless control 4 */
3126 WRITE_COEF(0x36, 0x0), /* capless control 5 */
3127 UPDATE_COEF(0x38, 0x0fff, 0x0900), /* class D test 2 */
3128 WRITE_COEF(0x39, 0x110a), /* class D test 3 */
3129 UPDATE_COEF(0x3b, 0x00f8, 0x00d8), /* class D test 5 */
3130 WRITE_COEF(0x3c, 0x0014), /* class D test 6 */
3131 WRITE_COEF(0x3d, 0xc2ba), /* classD OCP */
3132 UPDATE_COEF(0x42, 0x0f80, 0x0), /* classD pure DC test */
3133 WRITE_COEF(0x49, 0x0), /* test mode */
3134 UPDATE_COEF(0x40, 0xf800, 0x9800), /* Class D DC enable */
3135 UPDATE_COEF(0x42, 0xf000, 0x2000), /* DC offset */
3136 WRITE_COEF(0x37, 0xfc06), /* Class D amp control */
Kailang Yang56779862014-10-24 16:17:51 +08003137 UPDATE_COEF(0x1b, 0x8000, 0), /* HP JD control */
Takashi Iwai54db6c32014-08-18 15:11:19 +02003138 {}
3139};
3140
Kailang Yang6bd55b02014-03-17 13:51:27 +08003141static void alc283_restore_default_value(struct hda_codec *codec)
3142{
Takashi Iwai54db6c32014-08-18 15:11:19 +02003143 alc_process_coef_fw(codec, alc283_coefs);
Kailang Yang6bd55b02014-03-17 13:51:27 +08003144}
3145
Kailang Yang2af02be2013-08-22 10:03:50 +02003146static void alc283_init(struct hda_codec *codec)
3147{
3148 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003149 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang2af02be2013-08-22 10:03:50 +02003150 bool hp_pin_sense;
Kailang Yang2af02be2013-08-22 10:03:50 +02003151
Kailang Yang6bd55b02014-03-17 13:51:27 +08003152 alc283_restore_default_value(codec);
3153
Kailang Yang2af02be2013-08-22 10:03:50 +02003154 if (!hp_pin)
3155 return;
Kailang Yanga59d7192015-04-08 16:34:00 +08003156
3157 msleep(30);
Kailang Yang2af02be2013-08-22 10:03:50 +02003158 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3159
3160 /* Index 0x43 Direct Drive HP AMP LPM Control 1 */
3161 /* Headphone capless set to high power mode */
3162 alc_write_coef_idx(codec, 0x43, 0x9004);
3163
3164 snd_hda_codec_write(codec, hp_pin, 0,
3165 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3166
3167 if (hp_pin_sense)
3168 msleep(85);
3169
3170 snd_hda_codec_write(codec, hp_pin, 0,
3171 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3172
3173 if (hp_pin_sense)
3174 msleep(85);
3175 /* Index 0x46 Combo jack auto switch control 2 */
3176 /* 3k pull low control for Headset jack. */
Takashi Iwai98b24882014-08-18 13:47:50 +02003177 alc_update_coef_idx(codec, 0x46, 3 << 12, 0);
Kailang Yang2af02be2013-08-22 10:03:50 +02003178 /* Headphone capless set to normal mode */
3179 alc_write_coef_idx(codec, 0x43, 0x9614);
3180}
3181
3182static void alc283_shutup(struct hda_codec *codec)
3183{
3184 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003185 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang2af02be2013-08-22 10:03:50 +02003186 bool hp_pin_sense;
Kailang Yang2af02be2013-08-22 10:03:50 +02003187
3188 if (!hp_pin) {
3189 alc269_shutup(codec);
3190 return;
3191 }
3192
3193 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3194
3195 alc_write_coef_idx(codec, 0x43, 0x9004);
3196
Harsha Priyab450b172014-10-09 11:04:56 +00003197 /*depop hp during suspend*/
3198 alc_write_coef_idx(codec, 0x06, 0x2100);
3199
Kailang Yang2af02be2013-08-22 10:03:50 +02003200 snd_hda_codec_write(codec, hp_pin, 0,
3201 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3202
3203 if (hp_pin_sense)
Kailang Yang88011c092013-10-24 15:45:24 +02003204 msleep(100);
Kailang Yang2af02be2013-08-22 10:03:50 +02003205
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003206 if (!spec->no_shutup_pins)
3207 snd_hda_codec_write(codec, hp_pin, 0,
3208 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
Kailang Yang2af02be2013-08-22 10:03:50 +02003209
Takashi Iwai98b24882014-08-18 13:47:50 +02003210 alc_update_coef_idx(codec, 0x46, 0, 3 << 12);
Kailang Yang2af02be2013-08-22 10:03:50 +02003211
3212 if (hp_pin_sense)
Kailang Yang88011c092013-10-24 15:45:24 +02003213 msleep(100);
Kailang Yang0435b3f2014-04-08 17:14:14 +08003214 alc_auto_setup_eapd(codec, false);
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003215 alc_shutup_pins(codec);
Kailang Yang2af02be2013-08-22 10:03:50 +02003216 alc_write_coef_idx(codec, 0x43, 0x9614);
3217}
3218
Kailang Yang4a219ef2017-06-16 16:54:35 +08003219static void alc256_init(struct hda_codec *codec)
3220{
3221 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003222 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang4a219ef2017-06-16 16:54:35 +08003223 bool hp_pin_sense;
3224
3225 if (!hp_pin)
Kailang Yang6447c962019-05-08 16:27:03 +08003226 hp_pin = 0x21;
Kailang Yang4a219ef2017-06-16 16:54:35 +08003227
3228 msleep(30);
3229
3230 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3231
3232 if (hp_pin_sense)
3233 msleep(2);
3234
3235 alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */
Kailang Yang6447c962019-05-08 16:27:03 +08003236 if (spec->ultra_low_power) {
3237 alc_update_coef_idx(codec, 0x03, 1<<1, 1<<1);
3238 alc_update_coef_idx(codec, 0x08, 3<<2, 3<<2);
3239 alc_update_coef_idx(codec, 0x08, 7<<4, 0);
3240 alc_update_coef_idx(codec, 0x3b, 1<<15, 0);
3241 alc_update_coef_idx(codec, 0x0e, 7<<6, 7<<6);
3242 msleep(30);
3243 }
Kailang Yang4a219ef2017-06-16 16:54:35 +08003244
3245 snd_hda_codec_write(codec, hp_pin, 0,
3246 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3247
Kailang Yang6447c962019-05-08 16:27:03 +08003248 if (hp_pin_sense || spec->ultra_low_power)
Kailang Yang4a219ef2017-06-16 16:54:35 +08003249 msleep(85);
3250
3251 snd_hda_codec_write(codec, hp_pin, 0,
3252 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3253
Kailang Yang6447c962019-05-08 16:27:03 +08003254 if (hp_pin_sense || spec->ultra_low_power)
Kailang Yang4a219ef2017-06-16 16:54:35 +08003255 msleep(100);
3256
3257 alc_update_coef_idx(codec, 0x46, 3 << 12, 0);
3258 alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x4); /* Hight power */
Kailang Yang88d42b22018-03-14 16:08:57 +08003259 alc_update_coefex_idx(codec, 0x53, 0x02, 0x8000, 1 << 15); /* Clear bit */
3260 alc_update_coefex_idx(codec, 0x53, 0x02, 0x8000, 0 << 15);
Kailang Yangd07a9a42019-07-04 16:02:10 +08003261 alc_update_coef_idx(codec, 0x36, 1 << 13, 1 << 5); /* Switch pcbeep path to Line in path*/
Kailang Yang4a219ef2017-06-16 16:54:35 +08003262}
3263
3264static void alc256_shutup(struct hda_codec *codec)
3265{
3266 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003267 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang4a219ef2017-06-16 16:54:35 +08003268 bool hp_pin_sense;
3269
Kailang Yang6447c962019-05-08 16:27:03 +08003270 if (!hp_pin)
3271 hp_pin = 0x21;
Kailang Yang4a219ef2017-06-16 16:54:35 +08003272
3273 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3274
3275 if (hp_pin_sense)
3276 msleep(2);
3277
3278 snd_hda_codec_write(codec, hp_pin, 0,
3279 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3280
Kailang Yang6447c962019-05-08 16:27:03 +08003281 if (hp_pin_sense || spec->ultra_low_power)
Kailang Yang4a219ef2017-06-16 16:54:35 +08003282 msleep(85);
3283
Takashi Iwai1c9609e2018-01-19 14:18:34 +01003284 /* 3k pull low control for Headset jack. */
3285 /* NOTE: call this before clearing the pin, otherwise codec stalls */
3286 alc_update_coef_idx(codec, 0x46, 0, 3 << 12);
3287
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003288 if (!spec->no_shutup_pins)
3289 snd_hda_codec_write(codec, hp_pin, 0,
3290 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
Kailang Yang4a219ef2017-06-16 16:54:35 +08003291
Kailang Yang6447c962019-05-08 16:27:03 +08003292 if (hp_pin_sense || spec->ultra_low_power)
Kailang Yang4a219ef2017-06-16 16:54:35 +08003293 msleep(100);
3294
3295 alc_auto_setup_eapd(codec, false);
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003296 alc_shutup_pins(codec);
Kailang Yang6447c962019-05-08 16:27:03 +08003297 if (spec->ultra_low_power) {
3298 msleep(50);
3299 alc_update_coef_idx(codec, 0x03, 1<<1, 0);
3300 alc_update_coef_idx(codec, 0x08, 7<<4, 7<<4);
3301 alc_update_coef_idx(codec, 0x08, 3<<2, 0);
3302 alc_update_coef_idx(codec, 0x3b, 1<<15, 1<<15);
3303 alc_update_coef_idx(codec, 0x0e, 7<<6, 0);
3304 msleep(30);
3305 }
Kailang Yang4a219ef2017-06-16 16:54:35 +08003306}
3307
Kailang Yangda911b12018-01-05 16:50:08 +08003308static void alc225_init(struct hda_codec *codec)
3309{
3310 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003311 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yangda911b12018-01-05 16:50:08 +08003312 bool hp1_pin_sense, hp2_pin_sense;
3313
3314 if (!hp_pin)
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003315 hp_pin = 0x21;
Kailang Yangda911b12018-01-05 16:50:08 +08003316 msleep(30);
3317
3318 hp1_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3319 hp2_pin_sense = snd_hda_jack_detect(codec, 0x16);
3320
3321 if (hp1_pin_sense || hp2_pin_sense)
3322 msleep(2);
3323
3324 alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003325 if (spec->ultra_low_power) {
3326 alc_update_coef_idx(codec, 0x08, 0x0f << 2, 3<<2);
3327 alc_update_coef_idx(codec, 0x0e, 7<<6, 7<<6);
3328 alc_update_coef_idx(codec, 0x33, 1<<11, 0);
3329 msleep(30);
3330 }
Kailang Yangda911b12018-01-05 16:50:08 +08003331
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_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3335 if (hp2_pin_sense)
3336 snd_hda_codec_write(codec, 0x16, 0,
3337 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
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(85);
3341
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003342 if (hp1_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003343 snd_hda_codec_write(codec, hp_pin, 0,
3344 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3345 if (hp2_pin_sense)
3346 snd_hda_codec_write(codec, 0x16, 0,
3347 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3348
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003349 if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003350 msleep(100);
3351
3352 alc_update_coef_idx(codec, 0x4a, 3 << 10, 0);
3353 alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x4); /* Hight power */
3354}
3355
3356static void alc225_shutup(struct hda_codec *codec)
3357{
3358 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003359 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yangda911b12018-01-05 16:50:08 +08003360 bool hp1_pin_sense, hp2_pin_sense;
3361
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003362 if (!hp_pin)
3363 hp_pin = 0x21;
Kailang Yangda911b12018-01-05 16:50:08 +08003364 /* 3k pull low control for Headset jack. */
3365 alc_update_coef_idx(codec, 0x4a, 0, 3 << 10);
3366
3367 hp1_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3368 hp2_pin_sense = snd_hda_jack_detect(codec, 0x16);
3369
3370 if (hp1_pin_sense || hp2_pin_sense)
3371 msleep(2);
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_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3376 if (hp2_pin_sense)
3377 snd_hda_codec_write(codec, 0x16, 0,
3378 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
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(85);
3382
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003383 if (hp1_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003384 snd_hda_codec_write(codec, hp_pin, 0,
3385 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
3386 if (hp2_pin_sense)
3387 snd_hda_codec_write(codec, 0x16, 0,
3388 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
3389
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003390 if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003391 msleep(100);
3392
3393 alc_auto_setup_eapd(codec, false);
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003394 alc_shutup_pins(codec);
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003395 if (spec->ultra_low_power) {
3396 msleep(50);
3397 alc_update_coef_idx(codec, 0x08, 0x0f << 2, 0x0c << 2);
3398 alc_update_coef_idx(codec, 0x0e, 7<<6, 0);
3399 alc_update_coef_idx(codec, 0x33, 1<<11, 1<<11);
3400 alc_update_coef_idx(codec, 0x4a, 3<<4, 2<<4);
3401 msleep(30);
3402 }
Kailang Yangda911b12018-01-05 16:50:08 +08003403}
3404
Kailang Yangc2d6af52017-06-21 14:50:54 +08003405static void alc_default_init(struct hda_codec *codec)
3406{
3407 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003408 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yangc2d6af52017-06-21 14:50:54 +08003409 bool hp_pin_sense;
3410
3411 if (!hp_pin)
3412 return;
3413
3414 msleep(30);
3415
3416 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3417
3418 if (hp_pin_sense)
3419 msleep(2);
3420
3421 snd_hda_codec_write(codec, hp_pin, 0,
3422 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3423
3424 if (hp_pin_sense)
3425 msleep(85);
3426
3427 snd_hda_codec_write(codec, hp_pin, 0,
3428 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3429
3430 if (hp_pin_sense)
3431 msleep(100);
3432}
3433
3434static void alc_default_shutup(struct hda_codec *codec)
3435{
3436 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003437 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yangc2d6af52017-06-21 14:50:54 +08003438 bool hp_pin_sense;
3439
3440 if (!hp_pin) {
3441 alc269_shutup(codec);
3442 return;
3443 }
3444
3445 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3446
3447 if (hp_pin_sense)
3448 msleep(2);
3449
3450 snd_hda_codec_write(codec, hp_pin, 0,
3451 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3452
3453 if (hp_pin_sense)
3454 msleep(85);
3455
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003456 if (!spec->no_shutup_pins)
3457 snd_hda_codec_write(codec, hp_pin, 0,
3458 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
Kailang Yangc2d6af52017-06-21 14:50:54 +08003459
3460 if (hp_pin_sense)
3461 msleep(100);
3462
3463 alc_auto_setup_eapd(codec, false);
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003464 alc_shutup_pins(codec);
Kailang Yangc2d6af52017-06-21 14:50:54 +08003465}
3466
Kailang Yang693abe12019-01-29 15:38:21 +08003467static void alc294_hp_init(struct hda_codec *codec)
3468{
3469 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003470 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang693abe12019-01-29 15:38:21 +08003471 int i, val;
3472
3473 if (!hp_pin)
3474 return;
3475
3476 snd_hda_codec_write(codec, hp_pin, 0,
3477 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3478
3479 msleep(100);
3480
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003481 if (!spec->no_shutup_pins)
3482 snd_hda_codec_write(codec, hp_pin, 0,
3483 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
Kailang Yang693abe12019-01-29 15:38:21 +08003484
3485 alc_update_coef_idx(codec, 0x6f, 0x000f, 0);/* Set HP depop to manual mode */
3486 alc_update_coefex_idx(codec, 0x58, 0x00, 0x8000, 0x8000); /* HP depop procedure start */
3487
3488 /* Wait for depop procedure finish */
3489 val = alc_read_coefex_idx(codec, 0x58, 0x01);
3490 for (i = 0; i < 20 && val & 0x0080; i++) {
3491 msleep(50);
3492 val = alc_read_coefex_idx(codec, 0x58, 0x01);
3493 }
3494 /* Set HP depop to auto mode */
3495 alc_update_coef_idx(codec, 0x6f, 0x000f, 0x000b);
3496 msleep(50);
3497}
3498
3499static void alc294_init(struct hda_codec *codec)
3500{
3501 struct alc_spec *spec = codec->spec;
3502
Takashi Iwaif6ef4e02019-01-29 14:14:51 +01003503 /* required only at boot or S4 resume time */
3504 if (!spec->done_hp_init ||
3505 codec->core.dev.power.power_state.event == PM_EVENT_RESTORE) {
Kailang Yang693abe12019-01-29 15:38:21 +08003506 alc294_hp_init(codec);
3507 spec->done_hp_init = true;
3508 }
3509 alc_default_init(codec);
3510}
3511
Kailang Yangad60d502013-06-28 12:03:01 +02003512static void alc5505_coef_set(struct hda_codec *codec, unsigned int index_reg,
3513 unsigned int val)
3514{
3515 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_COEF_INDEX, index_reg >> 1);
3516 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_PROC_COEF, val & 0xffff); /* LSB */
3517 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_PROC_COEF, val >> 16); /* MSB */
3518}
3519
3520static int alc5505_coef_get(struct hda_codec *codec, unsigned int index_reg)
3521{
3522 unsigned int val;
3523
3524 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_COEF_INDEX, index_reg >> 1);
3525 val = snd_hda_codec_read(codec, 0x51, 0, AC_VERB_GET_PROC_COEF, 0)
3526 & 0xffff;
3527 val |= snd_hda_codec_read(codec, 0x51, 0, AC_VERB_GET_PROC_COEF, 0)
3528 << 16;
3529 return val;
3530}
3531
3532static void alc5505_dsp_halt(struct hda_codec *codec)
3533{
3534 unsigned int val;
3535
3536 alc5505_coef_set(codec, 0x3000, 0x000c); /* DSP CPU stop */
3537 alc5505_coef_set(codec, 0x880c, 0x0008); /* DDR enter self refresh */
3538 alc5505_coef_set(codec, 0x61c0, 0x11110080); /* Clock control for PLL and CPU */
3539 alc5505_coef_set(codec, 0x6230, 0xfc0d4011); /* Disable Input OP */
3540 alc5505_coef_set(codec, 0x61b4, 0x040a2b03); /* Stop PLL2 */
3541 alc5505_coef_set(codec, 0x61b0, 0x00005b17); /* Stop PLL1 */
3542 alc5505_coef_set(codec, 0x61b8, 0x04133303); /* Stop PLL3 */
3543 val = alc5505_coef_get(codec, 0x6220);
3544 alc5505_coef_set(codec, 0x6220, (val | 0x3000)); /* switch Ringbuffer clock to DBUS clock */
3545}
3546
3547static void alc5505_dsp_back_from_halt(struct hda_codec *codec)
3548{
3549 alc5505_coef_set(codec, 0x61b8, 0x04133302);
3550 alc5505_coef_set(codec, 0x61b0, 0x00005b16);
3551 alc5505_coef_set(codec, 0x61b4, 0x040a2b02);
3552 alc5505_coef_set(codec, 0x6230, 0xf80d4011);
3553 alc5505_coef_set(codec, 0x6220, 0x2002010f);
3554 alc5505_coef_set(codec, 0x880c, 0x00000004);
3555}
3556
3557static void alc5505_dsp_init(struct hda_codec *codec)
3558{
3559 unsigned int val;
3560
3561 alc5505_dsp_halt(codec);
3562 alc5505_dsp_back_from_halt(codec);
3563 alc5505_coef_set(codec, 0x61b0, 0x5b14); /* PLL1 control */
3564 alc5505_coef_set(codec, 0x61b0, 0x5b16);
3565 alc5505_coef_set(codec, 0x61b4, 0x04132b00); /* PLL2 control */
3566 alc5505_coef_set(codec, 0x61b4, 0x04132b02);
3567 alc5505_coef_set(codec, 0x61b8, 0x041f3300); /* PLL3 control*/
3568 alc5505_coef_set(codec, 0x61b8, 0x041f3302);
3569 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_CODEC_RESET, 0); /* Function reset */
3570 alc5505_coef_set(codec, 0x61b8, 0x041b3302);
3571 alc5505_coef_set(codec, 0x61b8, 0x04173302);
3572 alc5505_coef_set(codec, 0x61b8, 0x04163302);
3573 alc5505_coef_set(codec, 0x8800, 0x348b328b); /* DRAM control */
3574 alc5505_coef_set(codec, 0x8808, 0x00020022); /* DRAM control */
3575 alc5505_coef_set(codec, 0x8818, 0x00000400); /* DRAM control */
3576
3577 val = alc5505_coef_get(codec, 0x6200) >> 16; /* Read revision ID */
3578 if (val <= 3)
3579 alc5505_coef_set(codec, 0x6220, 0x2002010f); /* I/O PAD Configuration */
3580 else
3581 alc5505_coef_set(codec, 0x6220, 0x6002018f);
3582
3583 alc5505_coef_set(codec, 0x61ac, 0x055525f0); /**/
3584 alc5505_coef_set(codec, 0x61c0, 0x12230080); /* Clock control */
3585 alc5505_coef_set(codec, 0x61b4, 0x040e2b02); /* PLL2 control */
3586 alc5505_coef_set(codec, 0x61bc, 0x010234f8); /* OSC Control */
3587 alc5505_coef_set(codec, 0x880c, 0x00000004); /* DRAM Function control */
3588 alc5505_coef_set(codec, 0x880c, 0x00000003);
3589 alc5505_coef_set(codec, 0x880c, 0x00000010);
Takashi Iwaicd63a5f2013-07-05 12:13:59 +02003590
3591#ifdef HALT_REALTEK_ALC5505
3592 alc5505_dsp_halt(codec);
3593#endif
Kailang Yangad60d502013-06-28 12:03:01 +02003594}
3595
Takashi Iwaicd63a5f2013-07-05 12:13:59 +02003596#ifdef HALT_REALTEK_ALC5505
3597#define alc5505_dsp_suspend(codec) /* NOP */
3598#define alc5505_dsp_resume(codec) /* NOP */
3599#else
3600#define alc5505_dsp_suspend(codec) alc5505_dsp_halt(codec)
3601#define alc5505_dsp_resume(codec) alc5505_dsp_back_from_halt(codec)
3602#endif
3603
Takashi Iwai2a439522011-07-26 09:52:50 +02003604#ifdef CONFIG_PM
Kailang Yangad60d502013-06-28 12:03:01 +02003605static int alc269_suspend(struct hda_codec *codec)
3606{
3607 struct alc_spec *spec = codec->spec;
3608
3609 if (spec->has_alc5505_dsp)
Takashi Iwaicd63a5f2013-07-05 12:13:59 +02003610 alc5505_dsp_suspend(codec);
Kailang Yangad60d502013-06-28 12:03:01 +02003611 return alc_suspend(codec);
3612}
3613
Takashi Iwai1d045db2011-07-07 18:23:21 +02003614static int alc269_resume(struct hda_codec *codec)
3615{
Kailang Yangadcc70b2012-05-25 08:08:38 +02003616 struct alc_spec *spec = codec->spec;
3617
Kailang Yang1387e2d2012-11-08 10:23:18 +01003618 if (spec->codec_variant == ALC269_TYPE_ALC269VB)
3619 alc269vb_toggle_power_output(codec, 0);
3620 if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
Kailang Yangadcc70b2012-05-25 08:08:38 +02003621 (alc_get_coef0(codec) & 0x00ff) == 0x018) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02003622 msleep(150);
3623 }
3624
3625 codec->patch_ops.init(codec);
3626
Kailang Yang1387e2d2012-11-08 10:23:18 +01003627 if (spec->codec_variant == ALC269_TYPE_ALC269VB)
3628 alc269vb_toggle_power_output(codec, 1);
3629 if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
Kailang Yangadcc70b2012-05-25 08:08:38 +02003630 (alc_get_coef0(codec) & 0x00ff) == 0x017) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02003631 msleep(200);
3632 }
3633
Takashi Iwaieeecd9d2015-02-25 15:18:50 +01003634 regcache_sync(codec->core.regmap);
Takashi Iwai1d045db2011-07-07 18:23:21 +02003635 hda_call_check_power_status(codec, 0x01);
Hui Wangf4753712014-08-19 12:07:03 +08003636
3637 /* on some machine, the BIOS will clear the codec gpio data when enter
3638 * suspend, and won't restore the data after resume, so we restore it
3639 * in the driver.
3640 */
Takashi Iwaid261eec2018-06-19 22:32:29 +02003641 if (spec->gpio_data)
3642 alc_write_gpio_data(codec);
Hui Wangf4753712014-08-19 12:07:03 +08003643
Kailang Yangad60d502013-06-28 12:03:01 +02003644 if (spec->has_alc5505_dsp)
Takashi Iwaicd63a5f2013-07-05 12:13:59 +02003645 alc5505_dsp_resume(codec);
Kailang Yangc5177c82013-07-24 14:39:49 +02003646
Takashi Iwai1d045db2011-07-07 18:23:21 +02003647 return 0;
3648}
Takashi Iwai2a439522011-07-26 09:52:50 +02003649#endif /* CONFIG_PM */
Takashi Iwai1d045db2011-07-07 18:23:21 +02003650
David Henningsson108cc102012-07-20 10:37:25 +02003651static void alc269_fixup_pincfg_no_hp_to_lineout(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003652 const struct hda_fixup *fix, int action)
David Henningsson108cc102012-07-20 10:37:25 +02003653{
3654 struct alc_spec *spec = codec->spec;
3655
Takashi Iwai1727a772013-01-10 09:52:52 +01003656 if (action == HDA_FIXUP_ACT_PRE_PROBE)
David Henningsson108cc102012-07-20 10:37:25 +02003657 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
3658}
3659
Jan-Marek Glogowskifdcc9682018-02-14 11:29:15 +01003660static void alc269_fixup_pincfg_U7x7_headset_mic(struct hda_codec *codec,
3661 const struct hda_fixup *fix,
3662 int action)
3663{
3664 unsigned int cfg_headphone = snd_hda_codec_get_pincfg(codec, 0x21);
3665 unsigned int cfg_headset_mic = snd_hda_codec_get_pincfg(codec, 0x19);
3666
3667 if (cfg_headphone && cfg_headset_mic == 0x411111f0)
3668 snd_hda_codec_set_pincfg(codec, 0x19,
3669 (cfg_headphone & ~AC_DEFCFG_DEVICE) |
3670 (AC_JACK_MIC_IN << AC_DEFCFG_DEVICE_SHIFT));
3671}
3672
Takashi Iwai1d045db2011-07-07 18:23:21 +02003673static void alc269_fixup_hweq(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003674 const struct hda_fixup *fix, int action)
Takashi Iwai1d045db2011-07-07 18:23:21 +02003675{
Takashi Iwai98b24882014-08-18 13:47:50 +02003676 if (action == HDA_FIXUP_ACT_INIT)
3677 alc_update_coef_idx(codec, 0x1e, 0, 0x80);
Takashi Iwai1d045db2011-07-07 18:23:21 +02003678}
3679
David Henningsson7c478f02013-10-11 10:18:46 +02003680static void alc269_fixup_headset_mic(struct hda_codec *codec,
3681 const struct hda_fixup *fix, int action)
3682{
3683 struct alc_spec *spec = codec->spec;
3684
3685 if (action == HDA_FIXUP_ACT_PRE_PROBE)
3686 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
3687}
3688
Takashi Iwai1d045db2011-07-07 18:23:21 +02003689static void alc271_fixup_dmic(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003690 const struct hda_fixup *fix, int action)
Takashi Iwai1d045db2011-07-07 18:23:21 +02003691{
3692 static const struct hda_verb verbs[] = {
3693 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
3694 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
3695 {}
3696 };
3697 unsigned int cfg;
3698
Takashi Iwai7639a062015-03-03 10:07:24 +01003699 if (strcmp(codec->core.chip_name, "ALC271X") &&
3700 strcmp(codec->core.chip_name, "ALC269VB"))
Takashi Iwai1d045db2011-07-07 18:23:21 +02003701 return;
3702 cfg = snd_hda_codec_get_pincfg(codec, 0x12);
3703 if (get_defcfg_connect(cfg) == AC_JACK_PORT_FIXED)
3704 snd_hda_sequence_write(codec, verbs);
3705}
3706
Takashi Iwai017f2a12011-07-09 14:42:25 +02003707static void alc269_fixup_pcm_44k(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003708 const struct hda_fixup *fix, int action)
Takashi Iwai017f2a12011-07-09 14:42:25 +02003709{
3710 struct alc_spec *spec = codec->spec;
3711
Takashi Iwai1727a772013-01-10 09:52:52 +01003712 if (action != HDA_FIXUP_ACT_PROBE)
Takashi Iwai017f2a12011-07-09 14:42:25 +02003713 return;
3714
3715 /* Due to a hardware problem on Lenovo Ideadpad, we need to
3716 * fix the sample rate of analog I/O to 44.1kHz
3717 */
Takashi Iwai08c189f2012-12-19 15:22:24 +01003718 spec->gen.stream_analog_playback = &alc269_44k_pcm_analog_playback;
3719 spec->gen.stream_analog_capture = &alc269_44k_pcm_analog_capture;
Takashi Iwai017f2a12011-07-09 14:42:25 +02003720}
3721
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02003722static void alc269_fixup_stereo_dmic(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003723 const struct hda_fixup *fix, int action)
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02003724{
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02003725 /* The digital-mic unit sends PDM (differential signal) instead of
3726 * the standard PCM, thus you can't record a valid mono stream as is.
3727 * Below is a workaround specific to ALC269 to control the dmic
3728 * signal source as mono.
3729 */
Takashi Iwai98b24882014-08-18 13:47:50 +02003730 if (action == HDA_FIXUP_ACT_INIT)
3731 alc_update_coef_idx(codec, 0x07, 0, 0x80);
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02003732}
3733
Takashi Iwai24519912011-08-16 15:08:49 +02003734static void alc269_quanta_automute(struct hda_codec *codec)
3735{
Takashi Iwai08c189f2012-12-19 15:22:24 +01003736 snd_hda_gen_update_outputs(codec);
Takashi Iwai24519912011-08-16 15:08:49 +02003737
Takashi Iwai1687ccc2014-08-18 13:49:35 +02003738 alc_write_coef_idx(codec, 0x0c, 0x680);
3739 alc_write_coef_idx(codec, 0x0c, 0x480);
Takashi Iwai24519912011-08-16 15:08:49 +02003740}
3741
3742static void alc269_fixup_quanta_mute(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003743 const struct hda_fixup *fix, int action)
Takashi Iwai24519912011-08-16 15:08:49 +02003744{
3745 struct alc_spec *spec = codec->spec;
Takashi Iwai1727a772013-01-10 09:52:52 +01003746 if (action != HDA_FIXUP_ACT_PROBE)
Takashi Iwai24519912011-08-16 15:08:49 +02003747 return;
Takashi Iwai08c189f2012-12-19 15:22:24 +01003748 spec->gen.automute_hook = alc269_quanta_automute;
Takashi Iwai24519912011-08-16 15:08:49 +02003749}
3750
David Henningssond240d1d2013-04-15 12:50:02 +02003751static void alc269_x101_hp_automute_hook(struct hda_codec *codec,
Takashi Iwai1a4f69d2014-09-11 15:22:46 +02003752 struct hda_jack_callback *jack)
David Henningssond240d1d2013-04-15 12:50:02 +02003753{
3754 struct alc_spec *spec = codec->spec;
3755 int vref;
3756 msleep(200);
3757 snd_hda_gen_hp_automute(codec, jack);
3758
3759 vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0;
3760 msleep(100);
3761 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3762 vref);
3763 msleep(500);
3764 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3765 vref);
3766}
3767
Tomas Espeletaa2ef03f2019-08-09 16:37:54 +02003768/*
3769 * Magic sequence to make Huawei Matebook X right speaker working (bko#197801)
3770 */
3771struct hda_alc298_mbxinit {
3772 unsigned char value_0x23;
3773 unsigned char value_0x25;
3774};
3775
3776static void alc298_huawei_mbx_stereo_seq(struct hda_codec *codec,
3777 const struct hda_alc298_mbxinit *initval,
3778 bool first)
3779{
3780 snd_hda_codec_write(codec, 0x06, 0, AC_VERB_SET_DIGI_CONVERT_3, 0x0);
3781 alc_write_coef_idx(codec, 0x26, 0xb000);
3782
3783 if (first)
3784 snd_hda_codec_write(codec, 0x21, 0, AC_VERB_GET_PIN_SENSE, 0x0);
3785
3786 snd_hda_codec_write(codec, 0x6, 0, AC_VERB_SET_DIGI_CONVERT_3, 0x80);
3787 alc_write_coef_idx(codec, 0x26, 0xf000);
3788 alc_write_coef_idx(codec, 0x23, initval->value_0x23);
3789
3790 if (initval->value_0x23 != 0x1e)
3791 alc_write_coef_idx(codec, 0x25, initval->value_0x25);
3792
3793 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0x26);
3794 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, 0xb010);
3795}
3796
3797static void alc298_fixup_huawei_mbx_stereo(struct hda_codec *codec,
3798 const struct hda_fixup *fix,
3799 int action)
3800{
3801 /* Initialization magic */
3802 static const struct hda_alc298_mbxinit dac_init[] = {
3803 {0x0c, 0x00}, {0x0d, 0x00}, {0x0e, 0x00}, {0x0f, 0x00},
3804 {0x10, 0x00}, {0x1a, 0x40}, {0x1b, 0x82}, {0x1c, 0x00},
3805 {0x1d, 0x00}, {0x1e, 0x00}, {0x1f, 0x00},
3806 {0x20, 0xc2}, {0x21, 0xc8}, {0x22, 0x26}, {0x23, 0x24},
3807 {0x27, 0xff}, {0x28, 0xff}, {0x29, 0xff}, {0x2a, 0x8f},
3808 {0x2b, 0x02}, {0x2c, 0x48}, {0x2d, 0x34}, {0x2e, 0x00},
3809 {0x2f, 0x00},
3810 {0x30, 0x00}, {0x31, 0x00}, {0x32, 0x00}, {0x33, 0x00},
3811 {0x34, 0x00}, {0x35, 0x01}, {0x36, 0x93}, {0x37, 0x0c},
3812 {0x38, 0x00}, {0x39, 0x00}, {0x3a, 0xf8}, {0x38, 0x80},
3813 {}
3814 };
3815 const struct hda_alc298_mbxinit *seq;
3816
3817 if (action != HDA_FIXUP_ACT_INIT)
3818 return;
3819
3820 /* Start */
3821 snd_hda_codec_write(codec, 0x06, 0, AC_VERB_SET_DIGI_CONVERT_3, 0x00);
3822 snd_hda_codec_write(codec, 0x06, 0, AC_VERB_SET_DIGI_CONVERT_3, 0x80);
3823 alc_write_coef_idx(codec, 0x26, 0xf000);
3824 alc_write_coef_idx(codec, 0x22, 0x31);
3825 alc_write_coef_idx(codec, 0x23, 0x0b);
3826 alc_write_coef_idx(codec, 0x25, 0x00);
3827 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0x26);
3828 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, 0xb010);
3829
3830 for (seq = dac_init; seq->value_0x23; seq++)
3831 alc298_huawei_mbx_stereo_seq(codec, seq, seq == dac_init);
3832}
3833
David Henningssond240d1d2013-04-15 12:50:02 +02003834static void alc269_fixup_x101_headset_mic(struct hda_codec *codec,
3835 const struct hda_fixup *fix, int action)
3836{
3837 struct alc_spec *spec = codec->spec;
3838 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3839 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
3840 spec->gen.hp_automute_hook = alc269_x101_hp_automute_hook;
3841 }
3842}
3843
3844
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003845/* update mute-LED according to the speaker mute state via mic VREF pin */
3846static void alc269_fixup_mic_mute_hook(void *private_data, int enabled)
David Henningsson6d3cd5d2013-01-07 12:03:47 +01003847{
3848 struct hda_codec *codec = private_data;
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003849 struct alc_spec *spec = codec->spec;
3850 unsigned int pinval;
3851
3852 if (spec->mute_led_polarity)
3853 enabled = !enabled;
Takashi Iwai415d5552014-04-03 11:51:21 +02003854 pinval = snd_hda_codec_get_pin_target(codec, spec->mute_led_nid);
3855 pinval &= ~AC_PINCTL_VREFEN;
3856 pinval |= enabled ? AC_PINCTL_VREF_HIZ : AC_PINCTL_VREF_80;
Takashi Iwaie40bdb02018-03-17 22:40:18 +01003857 if (spec->mute_led_nid) {
3858 /* temporarily power up/down for setting VREF */
3859 snd_hda_power_up_pm(codec);
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003860 snd_hda_set_pin_ctl_cache(codec, spec->mute_led_nid, pinval);
Takashi Iwaie40bdb02018-03-17 22:40:18 +01003861 snd_hda_power_down_pm(codec);
3862 }
David Henningsson6d3cd5d2013-01-07 12:03:47 +01003863}
3864
David Henningssond5b6b652013-11-06 10:50:44 +01003865/* Make sure the led works even in runtime suspend */
3866static unsigned int led_power_filter(struct hda_codec *codec,
3867 hda_nid_t nid,
3868 unsigned int power_state)
3869{
3870 struct alc_spec *spec = codec->spec;
3871
Hui Wang50dd9052014-07-08 17:56:15 +08003872 if (power_state != AC_PWRST_D3 || nid == 0 ||
3873 (nid != spec->mute_led_nid && nid != spec->cap_mute_led_nid))
David Henningssond5b6b652013-11-06 10:50:44 +01003874 return power_state;
3875
3876 /* Set pin ctl again, it might have just been set to 0 */
3877 snd_hda_set_pin_ctl(codec, nid,
3878 snd_hda_codec_get_pin_target(codec, nid));
3879
Takashi Iwaicffd3962015-04-09 10:30:25 +02003880 return snd_hda_gen_path_power_filter(codec, nid, power_state);
David Henningssond5b6b652013-11-06 10:50:44 +01003881}
3882
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003883static void alc269_fixup_hp_mute_led(struct hda_codec *codec,
3884 const struct hda_fixup *fix, int action)
David Henningsson6d3cd5d2013-01-07 12:03:47 +01003885{
3886 struct alc_spec *spec = codec->spec;
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003887 const struct dmi_device *dev = NULL;
3888
3889 if (action != HDA_FIXUP_ACT_PRE_PROBE)
3890 return;
3891
3892 while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) {
3893 int pol, pin;
3894 if (sscanf(dev->name, "HP_Mute_LED_%d_%x", &pol, &pin) != 2)
3895 continue;
3896 if (pin < 0x0a || pin >= 0x10)
3897 break;
3898 spec->mute_led_polarity = pol;
3899 spec->mute_led_nid = pin - 0x0a + 0x18;
3900 spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook;
Takashi Iwaifd25a972012-12-20 14:57:18 +01003901 spec->gen.vmaster_mute_enum = 1;
David Henningssond5b6b652013-11-06 10:50:44 +01003902 codec->power_filter = led_power_filter;
Takashi Iwai4e76a882014-02-25 12:21:03 +01003903 codec_dbg(codec,
3904 "Detected mute LED for %x:%d\n", spec->mute_led_nid,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003905 spec->mute_led_polarity);
David Henningsson6d3cd5d2013-01-07 12:03:47 +01003906 break;
3907 }
3908}
3909
Takashi Iwai85c467d2018-05-29 11:38:38 +02003910static void alc269_fixup_hp_mute_led_micx(struct hda_codec *codec,
3911 const struct hda_fixup *fix,
3912 int action, hda_nid_t pin)
David Henningssond06ac142013-02-18 11:41:55 +01003913{
3914 struct alc_spec *spec = codec->spec;
Takashi Iwai85c467d2018-05-29 11:38:38 +02003915
David Henningssond06ac142013-02-18 11:41:55 +01003916 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3917 spec->mute_led_polarity = 0;
Takashi Iwai85c467d2018-05-29 11:38:38 +02003918 spec->mute_led_nid = pin;
David Henningssond06ac142013-02-18 11:41:55 +01003919 spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook;
3920 spec->gen.vmaster_mute_enum = 1;
David Henningssond5b6b652013-11-06 10:50:44 +01003921 codec->power_filter = led_power_filter;
David Henningssond06ac142013-02-18 11:41:55 +01003922 }
3923}
3924
Takashi Iwai85c467d2018-05-29 11:38:38 +02003925static void alc269_fixup_hp_mute_led_mic1(struct hda_codec *codec,
3926 const struct hda_fixup *fix, int action)
3927{
3928 alc269_fixup_hp_mute_led_micx(codec, fix, action, 0x18);
3929}
3930
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003931static void alc269_fixup_hp_mute_led_mic2(struct hda_codec *codec,
3932 const struct hda_fixup *fix, int action)
Takashi Iwai420b0fe2012-03-12 12:35:27 +01003933{
Takashi Iwai85c467d2018-05-29 11:38:38 +02003934 alc269_fixup_hp_mute_led_micx(codec, fix, action, 0x19);
Takashi Iwai420b0fe2012-03-12 12:35:27 +01003935}
3936
Tom Briden7f783bd2017-03-25 10:12:01 +00003937static void alc269_fixup_hp_mute_led_mic3(struct hda_codec *codec,
3938 const struct hda_fixup *fix, int action)
3939{
Takashi Iwai85c467d2018-05-29 11:38:38 +02003940 alc269_fixup_hp_mute_led_micx(codec, fix, action, 0x1b);
Tom Briden7f783bd2017-03-25 10:12:01 +00003941}
3942
Takashi Iwai0f32fd192014-11-19 12:16:14 +01003943/* update LED status via GPIO */
3944static void alc_update_gpio_led(struct hda_codec *codec, unsigned int mask,
3945 bool enabled)
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003946{
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003947 struct alc_spec *spec = codec->spec;
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003948
Takashi Iwai0f32fd192014-11-19 12:16:14 +01003949 if (spec->mute_led_polarity)
3950 enabled = !enabled;
Takashi Iwaid261eec2018-06-19 22:32:29 +02003951 alc_update_gpio_data(codec, mask, !enabled); /* muted -> LED on */
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003952}
3953
Takashi Iwai0f32fd192014-11-19 12:16:14 +01003954/* turn on/off mute LED via GPIO per vmaster hook */
3955static void alc_fixup_gpio_mute_hook(void *private_data, int enabled)
3956{
3957 struct hda_codec *codec = private_data;
3958 struct alc_spec *spec = codec->spec;
3959
3960 alc_update_gpio_led(codec, spec->gpio_mute_led_mask, enabled);
3961}
3962
3963/* turn on/off mic-mute LED via GPIO per capture hook */
Takashi Iwaid03abec2018-06-19 12:29:13 +02003964static void alc_gpio_micmute_update(struct hda_codec *codec)
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003965{
3966 struct alc_spec *spec = codec->spec;
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003967
Takashi Iwaid03abec2018-06-19 12:29:13 +02003968 alc_update_gpio_led(codec, spec->gpio_mic_led_mask,
3969 spec->gen.micmute_led.led_value);
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003970}
3971
Takashi Iwai01e4a272018-06-19 22:47:30 +02003972/* setup mute and mic-mute GPIO bits, add hooks appropriately */
3973static void alc_fixup_hp_gpio_led(struct hda_codec *codec,
3974 int action,
3975 unsigned int mute_mask,
3976 unsigned int micmute_mask)
3977{
3978 struct alc_spec *spec = codec->spec;
3979
3980 alc_fixup_gpio(codec, action, mute_mask | micmute_mask);
3981
3982 if (action != HDA_FIXUP_ACT_PRE_PROBE)
3983 return;
3984 if (mute_mask) {
3985 spec->gpio_mute_led_mask = mute_mask;
3986 spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook;
3987 }
3988 if (micmute_mask) {
3989 spec->gpio_mic_led_mask = micmute_mask;
3990 snd_hda_gen_add_micmute_led(codec, alc_gpio_micmute_update);
3991 }
3992}
3993
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003994static void alc269_fixup_hp_gpio_led(struct hda_codec *codec,
3995 const struct hda_fixup *fix, int action)
3996{
Takashi Iwai01e4a272018-06-19 22:47:30 +02003997 alc_fixup_hp_gpio_led(codec, action, 0x08, 0x10);
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003998}
3999
Kailang Yangeaa8e5e2014-11-21 15:49:11 +08004000static void alc286_fixup_hp_gpio_led(struct hda_codec *codec,
4001 const struct hda_fixup *fix, int action)
4002{
Takashi Iwai01e4a272018-06-19 22:47:30 +02004003 alc_fixup_hp_gpio_led(codec, action, 0x02, 0x20);
Takashi Iwai1d045db2011-07-07 18:23:21 +02004004}
4005
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004006/* turn on/off mic-mute LED per capture hook */
Takashi Iwaid03abec2018-06-19 12:29:13 +02004007static void alc_cap_micmute_update(struct hda_codec *codec)
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004008{
4009 struct alc_spec *spec = codec->spec;
Takashi Iwaid03abec2018-06-19 12:29:13 +02004010 unsigned int pinval;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004011
Takashi Iwaid03abec2018-06-19 12:29:13 +02004012 if (!spec->cap_mute_led_nid)
4013 return;
Hui Wangfc1fad92014-07-08 17:56:14 +08004014 pinval = snd_hda_codec_get_pin_target(codec, spec->cap_mute_led_nid);
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004015 pinval &= ~AC_PINCTL_VREFEN;
Takashi Iwaid03abec2018-06-19 12:29:13 +02004016 if (spec->gen.micmute_led.led_value)
4017 pinval |= AC_PINCTL_VREF_80;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004018 else
Takashi Iwaid03abec2018-06-19 12:29:13 +02004019 pinval |= AC_PINCTL_VREF_HIZ;
4020 snd_hda_set_pin_ctl_cache(codec, spec->cap_mute_led_nid, pinval);
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004021}
4022
4023static void alc269_fixup_hp_gpio_mic1_led(struct hda_codec *codec,
4024 const struct hda_fixup *fix, int action)
4025{
4026 struct alc_spec *spec = codec->spec;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004027
Takashi Iwai01e4a272018-06-19 22:47:30 +02004028 alc_fixup_hp_gpio_led(codec, action, 0x08, 0);
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004029 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai01e4a272018-06-19 22:47:30 +02004030 /* Like hp_gpio_mic1_led, but also needs GPIO4 low to
4031 * enable headphone amp
4032 */
4033 spec->gpio_mask |= 0x10;
4034 spec->gpio_dir |= 0x10;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004035 spec->cap_mute_led_nid = 0x18;
Takashi Iwaid03abec2018-06-19 12:29:13 +02004036 snd_hda_gen_add_micmute_led(codec, alc_cap_micmute_update);
Hui Wang50dd9052014-07-08 17:56:15 +08004037 codec->power_filter = led_power_filter;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004038 }
4039}
4040
David Henningsson7a5255f2014-10-30 08:26:01 +01004041static void alc280_fixup_hp_gpio4(struct hda_codec *codec,
4042 const struct hda_fixup *fix, int action)
4043{
David Henningsson7a5255f2014-10-30 08:26:01 +01004044 struct alc_spec *spec = codec->spec;
David Henningsson7a5255f2014-10-30 08:26:01 +01004045
Takashi Iwai01e4a272018-06-19 22:47:30 +02004046 alc_fixup_hp_gpio_led(codec, action, 0x08, 0);
David Henningsson7a5255f2014-10-30 08:26:01 +01004047 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
David Henningsson7a5255f2014-10-30 08:26:01 +01004048 spec->cap_mute_led_nid = 0x18;
Takashi Iwaid03abec2018-06-19 12:29:13 +02004049 snd_hda_gen_add_micmute_led(codec, alc_cap_micmute_update);
David Henningsson7a5255f2014-10-30 08:26:01 +01004050 codec->power_filter = led_power_filter;
4051 }
4052}
4053
Takashi Iwai6a30aba2018-04-27 17:17:35 +02004054#if IS_REACHABLE(CONFIG_INPUT)
David Henningsson33f4acd2015-01-07 15:50:13 +01004055static void gpio2_mic_hotkey_event(struct hda_codec *codec,
4056 struct hda_jack_callback *event)
4057{
4058 struct alc_spec *spec = codec->spec;
4059
4060 /* GPIO2 just toggles on a keypress/keyrelease cycle. Therefore
4061 send both key on and key off event for every interrupt. */
Hui Wangc7b60a82015-12-28 11:35:25 +08004062 input_report_key(spec->kb_dev, spec->alc_mute_keycode_map[ALC_KEY_MICMUTE_INDEX], 1);
David Henningsson33f4acd2015-01-07 15:50:13 +01004063 input_sync(spec->kb_dev);
Hui Wangc7b60a82015-12-28 11:35:25 +08004064 input_report_key(spec->kb_dev, spec->alc_mute_keycode_map[ALC_KEY_MICMUTE_INDEX], 0);
David Henningsson33f4acd2015-01-07 15:50:13 +01004065 input_sync(spec->kb_dev);
4066}
David Henningsson33f4acd2015-01-07 15:50:13 +01004067
Kailang3694cb22015-12-28 11:35:24 +08004068static int alc_register_micmute_input_device(struct hda_codec *codec)
4069{
4070 struct alc_spec *spec = codec->spec;
Hui Wangc7b60a82015-12-28 11:35:25 +08004071 int i;
Kailang3694cb22015-12-28 11:35:24 +08004072
4073 spec->kb_dev = input_allocate_device();
4074 if (!spec->kb_dev) {
4075 codec_err(codec, "Out of memory (input_allocate_device)\n");
4076 return -ENOMEM;
4077 }
Hui Wangc7b60a82015-12-28 11:35:25 +08004078
4079 spec->alc_mute_keycode_map[ALC_KEY_MICMUTE_INDEX] = KEY_MICMUTE;
4080
Kailang3694cb22015-12-28 11:35:24 +08004081 spec->kb_dev->name = "Microphone Mute Button";
4082 spec->kb_dev->evbit[0] = BIT_MASK(EV_KEY);
Hui Wangc7b60a82015-12-28 11:35:25 +08004083 spec->kb_dev->keycodesize = sizeof(spec->alc_mute_keycode_map[0]);
4084 spec->kb_dev->keycodemax = ARRAY_SIZE(spec->alc_mute_keycode_map);
4085 spec->kb_dev->keycode = spec->alc_mute_keycode_map;
4086 for (i = 0; i < ARRAY_SIZE(spec->alc_mute_keycode_map); i++)
4087 set_bit(spec->alc_mute_keycode_map[i], spec->kb_dev->keybit);
Kailang3694cb22015-12-28 11:35:24 +08004088
4089 if (input_register_device(spec->kb_dev)) {
4090 codec_err(codec, "input_register_device failed\n");
4091 input_free_device(spec->kb_dev);
4092 spec->kb_dev = NULL;
4093 return -ENOMEM;
4094 }
4095
4096 return 0;
4097}
4098
Takashi Iwai01e4a272018-06-19 22:47:30 +02004099/* GPIO1 = set according to SKU external amp
4100 * GPIO2 = mic mute hotkey
4101 * GPIO3 = mute LED
4102 * GPIO4 = mic mute LED
4103 */
David Henningsson33f4acd2015-01-07 15:50:13 +01004104static void alc280_fixup_hp_gpio2_mic_hotkey(struct hda_codec *codec,
4105 const struct hda_fixup *fix, int action)
4106{
David Henningsson33f4acd2015-01-07 15:50:13 +01004107 struct alc_spec *spec = codec->spec;
4108
Takashi Iwai01e4a272018-06-19 22:47:30 +02004109 alc_fixup_hp_gpio_led(codec, action, 0x08, 0x10);
David Henningsson33f4acd2015-01-07 15:50:13 +01004110 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai1c76aa52018-06-21 16:37:54 +02004111 spec->init_amp = ALC_INIT_DEFAULT;
Kailang3694cb22015-12-28 11:35:24 +08004112 if (alc_register_micmute_input_device(codec) != 0)
David Henningsson33f4acd2015-01-07 15:50:13 +01004113 return;
David Henningsson33f4acd2015-01-07 15:50:13 +01004114
Takashi Iwai01e4a272018-06-19 22:47:30 +02004115 spec->gpio_mask |= 0x06;
4116 spec->gpio_dir |= 0x02;
4117 spec->gpio_data |= 0x02;
Takashi Iwai7639a062015-03-03 10:07:24 +01004118 snd_hda_codec_write_cache(codec, codec->core.afg, 0,
David Henningsson33f4acd2015-01-07 15:50:13 +01004119 AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x04);
Takashi Iwai7639a062015-03-03 10:07:24 +01004120 snd_hda_jack_detect_enable_callback(codec, codec->core.afg,
David Henningsson33f4acd2015-01-07 15:50:13 +01004121 gpio2_mic_hotkey_event);
David Henningsson33f4acd2015-01-07 15:50:13 +01004122 return;
4123 }
4124
4125 if (!spec->kb_dev)
4126 return;
4127
4128 switch (action) {
David Henningsson33f4acd2015-01-07 15:50:13 +01004129 case HDA_FIXUP_ACT_FREE:
4130 input_unregister_device(spec->kb_dev);
David Henningsson33f4acd2015-01-07 15:50:13 +01004131 spec->kb_dev = NULL;
4132 }
David Henningsson33f4acd2015-01-07 15:50:13 +01004133}
4134
Takashi Iwai01e4a272018-06-19 22:47:30 +02004135/* Line2 = mic mute hotkey
4136 * GPIO2 = mic mute LED
4137 */
Kailang3694cb22015-12-28 11:35:24 +08004138static void alc233_fixup_lenovo_line2_mic_hotkey(struct hda_codec *codec,
4139 const struct hda_fixup *fix, int action)
4140{
Kailang3694cb22015-12-28 11:35:24 +08004141 struct alc_spec *spec = codec->spec;
4142
Takashi Iwai01e4a272018-06-19 22:47:30 +02004143 alc_fixup_hp_gpio_led(codec, action, 0, 0x04);
Kailang3694cb22015-12-28 11:35:24 +08004144 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai1c76aa52018-06-21 16:37:54 +02004145 spec->init_amp = ALC_INIT_DEFAULT;
Kailang3694cb22015-12-28 11:35:24 +08004146 if (alc_register_micmute_input_device(codec) != 0)
4147 return;
4148
Kailang3694cb22015-12-28 11:35:24 +08004149 snd_hda_jack_detect_enable_callback(codec, 0x1b,
4150 gpio2_mic_hotkey_event);
Kailang3694cb22015-12-28 11:35:24 +08004151 return;
4152 }
4153
4154 if (!spec->kb_dev)
4155 return;
4156
4157 switch (action) {
Kailang3694cb22015-12-28 11:35:24 +08004158 case HDA_FIXUP_ACT_FREE:
4159 input_unregister_device(spec->kb_dev);
4160 spec->kb_dev = NULL;
4161 }
4162}
Takashi Iwaic4696522018-01-15 10:44:35 +01004163#else /* INPUT */
4164#define alc280_fixup_hp_gpio2_mic_hotkey NULL
4165#define alc233_fixup_lenovo_line2_mic_hotkey NULL
4166#endif /* INPUT */
Kailang3694cb22015-12-28 11:35:24 +08004167
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004168static void alc269_fixup_hp_line1_mic1_led(struct hda_codec *codec,
4169 const struct hda_fixup *fix, int action)
4170{
4171 struct alc_spec *spec = codec->spec;
4172
Takashi Iwai1bce62a2018-06-19 23:15:59 +02004173 alc269_fixup_hp_mute_led_micx(codec, fix, action, 0x1a);
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004174 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004175 spec->cap_mute_led_nid = 0x18;
Takashi Iwaid03abec2018-06-19 12:29:13 +02004176 snd_hda_gen_add_micmute_led(codec, alc_cap_micmute_update);
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004177 }
4178}
4179
Kailang Yang5a367672017-07-21 15:23:53 +08004180static struct coef_fw alc225_pre_hsmode[] = {
4181 UPDATE_COEF(0x4a, 1<<8, 0),
4182 UPDATE_COEFEX(0x57, 0x05, 1<<14, 0),
4183 UPDATE_COEF(0x63, 3<<14, 3<<14),
4184 UPDATE_COEF(0x4a, 3<<4, 2<<4),
4185 UPDATE_COEF(0x4a, 3<<10, 3<<10),
4186 UPDATE_COEF(0x45, 0x3f<<10, 0x34<<10),
4187 UPDATE_COEF(0x4a, 3<<10, 0),
4188 {}
4189};
4190
David Henningsson73bdd592013-04-15 15:44:14 +02004191static void alc_headset_mode_unplugged(struct hda_codec *codec)
4192{
Takashi Iwai54db6c32014-08-18 15:11:19 +02004193 static struct coef_fw coef0255[] = {
Kailang Yang717f43d2019-05-31 17:16:53 +08004194 WRITE_COEF(0x1b, 0x0c0b), /* LDO and MISC control */
Takashi Iwai54db6c32014-08-18 15:11:19 +02004195 WRITE_COEF(0x45, 0xd089), /* UAJ function set to menual mode */
4196 UPDATE_COEFEX(0x57, 0x05, 1<<14, 0), /* Direct Drive HP Amp control(Set to verb control)*/
4197 WRITE_COEF(0x06, 0x6104), /* Set MIC2 Vref gate with HP */
4198 WRITE_COEFEX(0x57, 0x03, 0x8aa6), /* Direct Drive HP Amp control */
4199 {}
4200 };
Kailang Yange69e7e02016-05-30 15:58:28 +08004201 static struct coef_fw coef0256[] = {
4202 WRITE_COEF(0x1b, 0x0c4b), /* LDO and MISC control */
Kailang Yang717f43d2019-05-31 17:16:53 +08004203 WRITE_COEF(0x45, 0xd089), /* UAJ function set to menual mode */
4204 WRITE_COEF(0x06, 0x6104), /* Set MIC2 Vref gate with HP */
4205 WRITE_COEFEX(0x57, 0x03, 0x09a3), /* Direct Drive HP Amp control */
4206 UPDATE_COEFEX(0x57, 0x05, 1<<14, 0), /* Direct Drive HP Amp control(Set to verb control)*/
Kailang Yange69e7e02016-05-30 15:58:28 +08004207 {}
4208 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004209 static struct coef_fw coef0233[] = {
4210 WRITE_COEF(0x1b, 0x0c0b),
4211 WRITE_COEF(0x45, 0xc429),
4212 UPDATE_COEF(0x35, 0x4000, 0),
4213 WRITE_COEF(0x06, 0x2104),
4214 WRITE_COEF(0x1a, 0x0001),
4215 WRITE_COEF(0x26, 0x0004),
4216 WRITE_COEF(0x32, 0x42a3),
4217 {}
4218 };
Kailang Yangf3b70332015-04-08 15:01:17 +08004219 static struct coef_fw coef0288[] = {
4220 UPDATE_COEF(0x4f, 0xfcc0, 0xc400),
4221 UPDATE_COEF(0x50, 0x2000, 0x2000),
4222 UPDATE_COEF(0x56, 0x0006, 0x0006),
4223 UPDATE_COEF(0x66, 0x0008, 0),
4224 UPDATE_COEF(0x67, 0x2000, 0),
4225 {}
4226 };
Kailang Yang89542932017-07-17 15:03:43 +08004227 static struct coef_fw coef0298[] = {
4228 UPDATE_COEF(0x19, 0x1300, 0x0300),
4229 {}
4230 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004231 static struct coef_fw coef0292[] = {
4232 WRITE_COEF(0x76, 0x000e),
4233 WRITE_COEF(0x6c, 0x2400),
4234 WRITE_COEF(0x18, 0x7308),
4235 WRITE_COEF(0x6b, 0xc429),
4236 {}
4237 };
4238 static struct coef_fw coef0293[] = {
4239 UPDATE_COEF(0x10, 7<<8, 6<<8), /* SET Line1 JD to 0 */
4240 UPDATE_COEFEX(0x57, 0x05, 1<<15|1<<13, 0x0), /* SET charge pump by verb */
4241 UPDATE_COEFEX(0x57, 0x03, 1<<10, 1<<10), /* SET EN_OSW to 1 */
4242 UPDATE_COEF(0x1a, 1<<3, 1<<3), /* Combo JD gating with LINE1-VREFO */
4243 WRITE_COEF(0x45, 0xc429), /* Set to TRS type */
4244 UPDATE_COEF(0x4a, 0x000f, 0x000e), /* Combo Jack auto detect */
4245 {}
4246 };
4247 static struct coef_fw coef0668[] = {
4248 WRITE_COEF(0x15, 0x0d40),
4249 WRITE_COEF(0xb7, 0x802b),
4250 {}
4251 };
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004252 static struct coef_fw coef0225[] = {
Kailang Yang5a367672017-07-21 15:23:53 +08004253 UPDATE_COEF(0x63, 3<<14, 0),
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004254 {}
4255 };
Kailang Yang71683c32017-06-20 16:33:50 +08004256 static struct coef_fw coef0274[] = {
4257 UPDATE_COEF(0x4a, 0x0100, 0),
4258 UPDATE_COEFEX(0x57, 0x05, 0x4000, 0),
4259 UPDATE_COEF(0x6b, 0xf000, 0x5000),
4260 UPDATE_COEF(0x4a, 0x0010, 0),
4261 UPDATE_COEF(0x4a, 0x0c00, 0x0c00),
4262 WRITE_COEF(0x45, 0x5289),
4263 UPDATE_COEF(0x4a, 0x0c00, 0),
4264 {}
4265 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004266
Takashi Iwai7639a062015-03-03 10:07:24 +01004267 switch (codec->core.vendor_id) {
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004268 case 0x10ec0255:
Kailang Yange69e7e02016-05-30 15:58:28 +08004269 alc_process_coef_fw(codec, coef0255);
4270 break;
Kailang Yang736f20a2017-10-20 15:06:34 +08004271 case 0x10ec0236:
Kailang Yang7081adf2015-03-30 17:05:37 +08004272 case 0x10ec0256:
Kailang Yange69e7e02016-05-30 15:58:28 +08004273 alc_process_coef_fw(codec, coef0256);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004274 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004275 case 0x10ec0234:
4276 case 0x10ec0274:
4277 case 0x10ec0294:
4278 alc_process_coef_fw(codec, coef0274);
4279 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004280 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004281 case 0x10ec0283:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004282 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02004283 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004284 case 0x10ec0286:
4285 case 0x10ec0288:
Kailang Yang89542932017-07-17 15:03:43 +08004286 alc_process_coef_fw(codec, coef0288);
4287 break;
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004288 case 0x10ec0298:
Kailang Yang89542932017-07-17 15:03:43 +08004289 alc_process_coef_fw(codec, coef0298);
Kailang Yangf3b70332015-04-08 15:01:17 +08004290 alc_process_coef_fw(codec, coef0288);
4291 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004292 case 0x10ec0292:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004293 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02004294 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004295 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004296 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004297 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004298 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004299 alc_process_coef_fw(codec, coef0668);
David Henningsson73bdd592013-04-15 15:44:14 +02004300 break;
Kailang Yangc2b691e2018-01-17 15:22:55 +08004301 case 0x10ec0215:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004302 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004303 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08004304 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004305 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08004306 case 0x10ec0299:
Kailang Yang4d4b0c52019-01-09 16:23:37 +08004307 alc_process_coef_fw(codec, alc225_pre_hsmode);
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004308 alc_process_coef_fw(codec, coef0225);
4309 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08004310 case 0x10ec0867:
4311 alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
4312 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004313 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01004314 codec_dbg(codec, "Headset jack set to unplugged mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02004315}
4316
4317
4318static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin,
4319 hda_nid_t mic_pin)
4320{
Takashi Iwai54db6c32014-08-18 15:11:19 +02004321 static struct coef_fw coef0255[] = {
4322 WRITE_COEFEX(0x57, 0x03, 0x8aa6),
4323 WRITE_COEF(0x06, 0x6100), /* Set MIC2 Vref gate to normal */
4324 {}
4325 };
Kailang Yang717f43d2019-05-31 17:16:53 +08004326 static struct coef_fw coef0256[] = {
4327 UPDATE_COEFEX(0x57, 0x05, 1<<14, 1<<14), /* Direct Drive HP Amp control(Set to verb control)*/
4328 WRITE_COEFEX(0x57, 0x03, 0x09a3),
4329 WRITE_COEF(0x06, 0x6100), /* Set MIC2 Vref gate to normal */
4330 {}
4331 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004332 static struct coef_fw coef0233[] = {
4333 UPDATE_COEF(0x35, 0, 1<<14),
4334 WRITE_COEF(0x06, 0x2100),
4335 WRITE_COEF(0x1a, 0x0021),
4336 WRITE_COEF(0x26, 0x008c),
4337 {}
4338 };
Kailang Yangf3b70332015-04-08 15:01:17 +08004339 static struct coef_fw coef0288[] = {
Kailang Yang89542932017-07-17 15:03:43 +08004340 UPDATE_COEF(0x4f, 0x00c0, 0),
Kailang Yangf3b70332015-04-08 15:01:17 +08004341 UPDATE_COEF(0x50, 0x2000, 0),
4342 UPDATE_COEF(0x56, 0x0006, 0),
4343 UPDATE_COEF(0x4f, 0xfcc0, 0xc400),
4344 UPDATE_COEF(0x66, 0x0008, 0x0008),
4345 UPDATE_COEF(0x67, 0x2000, 0x2000),
4346 {}
4347 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004348 static struct coef_fw coef0292[] = {
4349 WRITE_COEF(0x19, 0xa208),
4350 WRITE_COEF(0x2e, 0xacf0),
4351 {}
4352 };
4353 static struct coef_fw coef0293[] = {
4354 UPDATE_COEFEX(0x57, 0x05, 0, 1<<15|1<<13), /* SET charge pump by verb */
4355 UPDATE_COEFEX(0x57, 0x03, 1<<10, 0), /* SET EN_OSW to 0 */
4356 UPDATE_COEF(0x1a, 1<<3, 0), /* Combo JD gating without LINE1-VREFO */
4357 {}
4358 };
4359 static struct coef_fw coef0688[] = {
4360 WRITE_COEF(0xb7, 0x802b),
4361 WRITE_COEF(0xb5, 0x1040),
4362 UPDATE_COEF(0xc3, 0, 1<<12),
4363 {}
4364 };
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004365 static struct coef_fw coef0225[] = {
4366 UPDATE_COEFEX(0x57, 0x05, 1<<14, 1<<14),
4367 UPDATE_COEF(0x4a, 3<<4, 2<<4),
4368 UPDATE_COEF(0x63, 3<<14, 0),
4369 {}
4370 };
Kailang Yang71683c32017-06-20 16:33:50 +08004371 static struct coef_fw coef0274[] = {
4372 UPDATE_COEFEX(0x57, 0x05, 0x4000, 0x4000),
4373 UPDATE_COEF(0x4a, 0x0010, 0),
4374 UPDATE_COEF(0x6b, 0xf000, 0),
4375 {}
4376 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004377
Takashi Iwai7639a062015-03-03 10:07:24 +01004378 switch (codec->core.vendor_id) {
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004379 case 0x10ec0255:
4380 alc_write_coef_idx(codec, 0x45, 0xc489);
4381 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02004382 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004383 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4384 break;
Kailang Yang717f43d2019-05-31 17:16:53 +08004385 case 0x10ec0236:
4386 case 0x10ec0256:
4387 alc_write_coef_idx(codec, 0x45, 0xc489);
4388 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4389 alc_process_coef_fw(codec, coef0256);
4390 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4391 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004392 case 0x10ec0234:
4393 case 0x10ec0274:
4394 case 0x10ec0294:
4395 alc_write_coef_idx(codec, 0x45, 0x4689);
4396 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4397 alc_process_coef_fw(codec, coef0274);
4398 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4399 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004400 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004401 case 0x10ec0283:
4402 alc_write_coef_idx(codec, 0x45, 0xc429);
4403 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02004404 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02004405 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4406 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004407 case 0x10ec0286:
4408 case 0x10ec0288:
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004409 case 0x10ec0298:
Kailang Yangf3b70332015-04-08 15:01:17 +08004410 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4411 alc_process_coef_fw(codec, coef0288);
4412 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4413 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004414 case 0x10ec0292:
4415 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02004416 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02004417 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004418 case 0x10ec0293:
4419 /* Set to TRS mode */
4420 alc_write_coef_idx(codec, 0x45, 0xc429);
4421 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02004422 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004423 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4424 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08004425 case 0x10ec0867:
4426 alc_update_coefex_idx(codec, 0x57, 0x5, 0, 1<<14);
4427 /* fallthru */
Kailang Yang9eb5d0e2017-01-17 15:40:25 +08004428 case 0x10ec0221:
David Henningsson1f8b46c2015-05-12 14:38:15 +02004429 case 0x10ec0662:
4430 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4431 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4432 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004433 case 0x10ec0668:
4434 alc_write_coef_idx(codec, 0x11, 0x0001);
4435 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02004436 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02004437 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4438 break;
Kailang Yangc2b691e2018-01-17 15:22:55 +08004439 case 0x10ec0215:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004440 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004441 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08004442 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004443 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08004444 case 0x10ec0299:
Kailang Yang5a367672017-07-21 15:23:53 +08004445 alc_process_coef_fw(codec, alc225_pre_hsmode);
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004446 alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x31<<10);
4447 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4448 alc_process_coef_fw(codec, coef0225);
4449 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4450 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004451 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01004452 codec_dbg(codec, "Headset jack set to mic-in mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02004453}
4454
4455static void alc_headset_mode_default(struct hda_codec *codec)
4456{
David Henningsson2ae95572016-02-25 09:37:05 +01004457 static struct coef_fw coef0225[] = {
Kailang Yang5a367672017-07-21 15:23:53 +08004458 UPDATE_COEF(0x45, 0x3f<<10, 0x30<<10),
4459 UPDATE_COEF(0x45, 0x3f<<10, 0x31<<10),
4460 UPDATE_COEF(0x49, 3<<8, 0<<8),
4461 UPDATE_COEF(0x4a, 3<<4, 3<<4),
4462 UPDATE_COEF(0x63, 3<<14, 0),
4463 UPDATE_COEF(0x67, 0xf000, 0x3000),
David Henningsson2ae95572016-02-25 09:37:05 +01004464 {}
4465 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004466 static struct coef_fw coef0255[] = {
4467 WRITE_COEF(0x45, 0xc089),
4468 WRITE_COEF(0x45, 0xc489),
4469 WRITE_COEFEX(0x57, 0x03, 0x8ea6),
4470 WRITE_COEF(0x49, 0x0049),
4471 {}
4472 };
Kailang Yang717f43d2019-05-31 17:16:53 +08004473 static struct coef_fw coef0256[] = {
4474 WRITE_COEF(0x45, 0xc489),
4475 WRITE_COEFEX(0x57, 0x03, 0x0da3),
4476 WRITE_COEF(0x49, 0x0049),
4477 UPDATE_COEFEX(0x57, 0x05, 1<<14, 0), /* Direct Drive HP Amp control(Set to verb control)*/
4478 WRITE_COEF(0x06, 0x6100),
4479 {}
4480 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004481 static struct coef_fw coef0233[] = {
4482 WRITE_COEF(0x06, 0x2100),
4483 WRITE_COEF(0x32, 0x4ea3),
4484 {}
4485 };
Kailang Yangf3b70332015-04-08 15:01:17 +08004486 static struct coef_fw coef0288[] = {
4487 UPDATE_COEF(0x4f, 0xfcc0, 0xc400), /* Set to TRS type */
4488 UPDATE_COEF(0x50, 0x2000, 0x2000),
4489 UPDATE_COEF(0x56, 0x0006, 0x0006),
4490 UPDATE_COEF(0x66, 0x0008, 0),
4491 UPDATE_COEF(0x67, 0x2000, 0),
4492 {}
4493 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004494 static struct coef_fw coef0292[] = {
4495 WRITE_COEF(0x76, 0x000e),
4496 WRITE_COEF(0x6c, 0x2400),
4497 WRITE_COEF(0x6b, 0xc429),
4498 WRITE_COEF(0x18, 0x7308),
4499 {}
4500 };
4501 static struct coef_fw coef0293[] = {
4502 UPDATE_COEF(0x4a, 0x000f, 0x000e), /* Combo Jack auto detect */
4503 WRITE_COEF(0x45, 0xC429), /* Set to TRS type */
4504 UPDATE_COEF(0x1a, 1<<3, 0), /* Combo JD gating without LINE1-VREFO */
4505 {}
4506 };
4507 static struct coef_fw coef0688[] = {
4508 WRITE_COEF(0x11, 0x0041),
4509 WRITE_COEF(0x15, 0x0d40),
4510 WRITE_COEF(0xb7, 0x802b),
4511 {}
4512 };
Kailang Yang71683c32017-06-20 16:33:50 +08004513 static struct coef_fw coef0274[] = {
4514 WRITE_COEF(0x45, 0x4289),
4515 UPDATE_COEF(0x4a, 0x0010, 0x0010),
4516 UPDATE_COEF(0x6b, 0x0f00, 0),
4517 UPDATE_COEF(0x49, 0x0300, 0x0300),
4518 {}
4519 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004520
Takashi Iwai7639a062015-03-03 10:07:24 +01004521 switch (codec->core.vendor_id) {
Kailang Yangc2b691e2018-01-17 15:22:55 +08004522 case 0x10ec0215:
David Henningsson2ae95572016-02-25 09:37:05 +01004523 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004524 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08004525 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004526 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08004527 case 0x10ec0299:
Kailang Yang5a367672017-07-21 15:23:53 +08004528 alc_process_coef_fw(codec, alc225_pre_hsmode);
David Henningsson2ae95572016-02-25 09:37:05 +01004529 alc_process_coef_fw(codec, coef0225);
4530 break;
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004531 case 0x10ec0255:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004532 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004533 break;
Kailang Yang717f43d2019-05-31 17:16:53 +08004534 case 0x10ec0236:
4535 case 0x10ec0256:
4536 alc_write_coef_idx(codec, 0x1b, 0x0e4b);
4537 alc_write_coef_idx(codec, 0x45, 0xc089);
4538 msleep(50);
4539 alc_process_coef_fw(codec, coef0256);
4540 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004541 case 0x10ec0234:
4542 case 0x10ec0274:
4543 case 0x10ec0294:
4544 alc_process_coef_fw(codec, coef0274);
4545 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004546 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004547 case 0x10ec0283:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004548 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02004549 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004550 case 0x10ec0286:
4551 case 0x10ec0288:
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004552 case 0x10ec0298:
Kailang Yangf3b70332015-04-08 15:01:17 +08004553 alc_process_coef_fw(codec, coef0288);
4554 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004555 case 0x10ec0292:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004556 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02004557 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004558 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004559 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004560 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004561 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004562 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02004563 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08004564 case 0x10ec0867:
4565 alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
4566 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004567 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01004568 codec_dbg(codec, "Headset jack set to headphone (default) mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02004569}
4570
4571/* Iphone type */
4572static void alc_headset_mode_ctia(struct hda_codec *codec)
4573{
Kailang Yang89542932017-07-17 15:03:43 +08004574 int val;
4575
Takashi Iwai54db6c32014-08-18 15:11:19 +02004576 static struct coef_fw coef0255[] = {
4577 WRITE_COEF(0x45, 0xd489), /* Set to CTIA type */
4578 WRITE_COEF(0x1b, 0x0c2b),
4579 WRITE_COEFEX(0x57, 0x03, 0x8ea6),
4580 {}
4581 };
Kailang Yange69e7e02016-05-30 15:58:28 +08004582 static struct coef_fw coef0256[] = {
4583 WRITE_COEF(0x45, 0xd489), /* Set to CTIA type */
Kailang Yang717f43d2019-05-31 17:16:53 +08004584 WRITE_COEF(0x1b, 0x0e6b),
Kailang Yange69e7e02016-05-30 15:58:28 +08004585 {}
4586 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004587 static struct coef_fw coef0233[] = {
4588 WRITE_COEF(0x45, 0xd429),
4589 WRITE_COEF(0x1b, 0x0c2b),
4590 WRITE_COEF(0x32, 0x4ea3),
4591 {}
4592 };
Kailang Yangf3b70332015-04-08 15:01:17 +08004593 static struct coef_fw coef0288[] = {
4594 UPDATE_COEF(0x50, 0x2000, 0x2000),
4595 UPDATE_COEF(0x56, 0x0006, 0x0006),
4596 UPDATE_COEF(0x66, 0x0008, 0),
4597 UPDATE_COEF(0x67, 0x2000, 0),
4598 {}
4599 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004600 static struct coef_fw coef0292[] = {
4601 WRITE_COEF(0x6b, 0xd429),
4602 WRITE_COEF(0x76, 0x0008),
4603 WRITE_COEF(0x18, 0x7388),
4604 {}
4605 };
4606 static struct coef_fw coef0293[] = {
4607 WRITE_COEF(0x45, 0xd429), /* Set to ctia type */
4608 UPDATE_COEF(0x10, 7<<8, 7<<8), /* SET Line1 JD to 1 */
4609 {}
4610 };
4611 static struct coef_fw coef0688[] = {
4612 WRITE_COEF(0x11, 0x0001),
4613 WRITE_COEF(0x15, 0x0d60),
4614 WRITE_COEF(0xc3, 0x0000),
4615 {}
4616 };
Kailang Yang5a367672017-07-21 15:23:53 +08004617 static struct coef_fw coef0225_1[] = {
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004618 UPDATE_COEF(0x45, 0x3f<<10, 0x35<<10),
Kailang Yang5a367672017-07-21 15:23:53 +08004619 UPDATE_COEF(0x63, 3<<14, 2<<14),
4620 {}
4621 };
4622 static struct coef_fw coef0225_2[] = {
4623 UPDATE_COEF(0x45, 0x3f<<10, 0x35<<10),
4624 UPDATE_COEF(0x63, 3<<14, 1<<14),
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004625 {}
4626 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004627
Takashi Iwai7639a062015-03-03 10:07:24 +01004628 switch (codec->core.vendor_id) {
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004629 case 0x10ec0255:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004630 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004631 break;
Kailang Yang736f20a2017-10-20 15:06:34 +08004632 case 0x10ec0236:
Kailang Yange69e7e02016-05-30 15:58:28 +08004633 case 0x10ec0256:
4634 alc_process_coef_fw(codec, coef0256);
4635 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004636 case 0x10ec0234:
4637 case 0x10ec0274:
4638 case 0x10ec0294:
4639 alc_write_coef_idx(codec, 0x45, 0xd689);
4640 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004641 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004642 case 0x10ec0283:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004643 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02004644 break;
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004645 case 0x10ec0298:
Kailang Yang89542932017-07-17 15:03:43 +08004646 val = alc_read_coef_idx(codec, 0x50);
4647 if (val & (1 << 12)) {
4648 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0020);
4649 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400);
4650 msleep(300);
4651 } else {
4652 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0010);
4653 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400);
4654 msleep(300);
4655 }
4656 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004657 case 0x10ec0286:
4658 case 0x10ec0288:
4659 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400);
4660 msleep(300);
4661 alc_process_coef_fw(codec, coef0288);
4662 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004663 case 0x10ec0292:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004664 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02004665 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004666 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004667 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004668 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004669 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004670 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02004671 break;
Kailang Yangc2b691e2018-01-17 15:22:55 +08004672 case 0x10ec0215:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004673 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004674 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08004675 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004676 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08004677 case 0x10ec0299:
Kailang Yang5a367672017-07-21 15:23:53 +08004678 val = alc_read_coef_idx(codec, 0x45);
4679 if (val & (1 << 9))
4680 alc_process_coef_fw(codec, coef0225_2);
4681 else
4682 alc_process_coef_fw(codec, coef0225_1);
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004683 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08004684 case 0x10ec0867:
4685 alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
4686 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004687 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01004688 codec_dbg(codec, "Headset jack set to iPhone-style headset mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02004689}
4690
4691/* Nokia type */
4692static void alc_headset_mode_omtp(struct hda_codec *codec)
4693{
Takashi Iwai54db6c32014-08-18 15:11:19 +02004694 static struct coef_fw coef0255[] = {
4695 WRITE_COEF(0x45, 0xe489), /* Set to OMTP Type */
4696 WRITE_COEF(0x1b, 0x0c2b),
4697 WRITE_COEFEX(0x57, 0x03, 0x8ea6),
4698 {}
4699 };
Kailang Yange69e7e02016-05-30 15:58:28 +08004700 static struct coef_fw coef0256[] = {
4701 WRITE_COEF(0x45, 0xe489), /* Set to OMTP Type */
Kailang Yang717f43d2019-05-31 17:16:53 +08004702 WRITE_COEF(0x1b, 0x0e6b),
Kailang Yange69e7e02016-05-30 15:58:28 +08004703 {}
4704 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004705 static struct coef_fw coef0233[] = {
4706 WRITE_COEF(0x45, 0xe429),
4707 WRITE_COEF(0x1b, 0x0c2b),
4708 WRITE_COEF(0x32, 0x4ea3),
4709 {}
4710 };
Kailang Yangf3b70332015-04-08 15:01:17 +08004711 static struct coef_fw coef0288[] = {
4712 UPDATE_COEF(0x50, 0x2000, 0x2000),
4713 UPDATE_COEF(0x56, 0x0006, 0x0006),
4714 UPDATE_COEF(0x66, 0x0008, 0),
4715 UPDATE_COEF(0x67, 0x2000, 0),
4716 {}
4717 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004718 static struct coef_fw coef0292[] = {
4719 WRITE_COEF(0x6b, 0xe429),
4720 WRITE_COEF(0x76, 0x0008),
4721 WRITE_COEF(0x18, 0x7388),
4722 {}
4723 };
4724 static struct coef_fw coef0293[] = {
4725 WRITE_COEF(0x45, 0xe429), /* Set to omtp type */
4726 UPDATE_COEF(0x10, 7<<8, 7<<8), /* SET Line1 JD to 1 */
4727 {}
4728 };
4729 static struct coef_fw coef0688[] = {
4730 WRITE_COEF(0x11, 0x0001),
4731 WRITE_COEF(0x15, 0x0d50),
4732 WRITE_COEF(0xc3, 0x0000),
4733 {}
4734 };
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004735 static struct coef_fw coef0225[] = {
4736 UPDATE_COEF(0x45, 0x3f<<10, 0x39<<10),
Kailang Yang5a367672017-07-21 15:23:53 +08004737 UPDATE_COEF(0x63, 3<<14, 2<<14),
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004738 {}
4739 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004740
Takashi Iwai7639a062015-03-03 10:07:24 +01004741 switch (codec->core.vendor_id) {
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004742 case 0x10ec0255:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004743 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004744 break;
Kailang Yang736f20a2017-10-20 15:06:34 +08004745 case 0x10ec0236:
Kailang Yange69e7e02016-05-30 15:58:28 +08004746 case 0x10ec0256:
4747 alc_process_coef_fw(codec, coef0256);
4748 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004749 case 0x10ec0234:
4750 case 0x10ec0274:
4751 case 0x10ec0294:
4752 alc_write_coef_idx(codec, 0x45, 0xe689);
4753 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004754 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004755 case 0x10ec0283:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004756 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02004757 break;
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004758 case 0x10ec0298:
4759 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0010);/* Headset output enable */
Kailang Yang89542932017-07-17 15:03:43 +08004760 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xe400);
4761 msleep(300);
4762 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004763 case 0x10ec0286:
4764 case 0x10ec0288:
4765 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xe400);
4766 msleep(300);
4767 alc_process_coef_fw(codec, coef0288);
4768 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004769 case 0x10ec0292:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004770 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02004771 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004772 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004773 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004774 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004775 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004776 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02004777 break;
Kailang Yangc2b691e2018-01-17 15:22:55 +08004778 case 0x10ec0215:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004779 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004780 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08004781 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004782 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08004783 case 0x10ec0299:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004784 alc_process_coef_fw(codec, coef0225);
4785 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004786 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01004787 codec_dbg(codec, "Headset jack set to Nokia-style headset mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02004788}
4789
4790static void alc_determine_headset_type(struct hda_codec *codec)
4791{
4792 int val;
4793 bool is_ctia = false;
4794 struct alc_spec *spec = codec->spec;
Takashi Iwai54db6c32014-08-18 15:11:19 +02004795 static struct coef_fw coef0255[] = {
4796 WRITE_COEF(0x45, 0xd089), /* combo jack auto switch control(Check type)*/
4797 WRITE_COEF(0x49, 0x0149), /* combo jack auto switch control(Vref
4798 conteol) */
4799 {}
4800 };
Kailang Yangf3b70332015-04-08 15:01:17 +08004801 static struct coef_fw coef0288[] = {
4802 UPDATE_COEF(0x4f, 0xfcc0, 0xd400), /* Check Type */
4803 {}
4804 };
Kailang Yang89542932017-07-17 15:03:43 +08004805 static struct coef_fw coef0298[] = {
4806 UPDATE_COEF(0x50, 0x2000, 0x2000),
4807 UPDATE_COEF(0x56, 0x0006, 0x0006),
4808 UPDATE_COEF(0x66, 0x0008, 0),
4809 UPDATE_COEF(0x67, 0x2000, 0),
4810 UPDATE_COEF(0x19, 0x1300, 0x1300),
4811 {}
4812 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004813 static struct coef_fw coef0293[] = {
4814 UPDATE_COEF(0x4a, 0x000f, 0x0008), /* Combo Jack auto detect */
4815 WRITE_COEF(0x45, 0xD429), /* Set to ctia type */
4816 {}
4817 };
4818 static struct coef_fw coef0688[] = {
4819 WRITE_COEF(0x11, 0x0001),
4820 WRITE_COEF(0xb7, 0x802b),
4821 WRITE_COEF(0x15, 0x0d60),
4822 WRITE_COEF(0xc3, 0x0c00),
4823 {}
4824 };
Kailang Yang71683c32017-06-20 16:33:50 +08004825 static struct coef_fw coef0274[] = {
4826 UPDATE_COEF(0x4a, 0x0010, 0),
4827 UPDATE_COEF(0x4a, 0x8000, 0),
4828 WRITE_COEF(0x45, 0xd289),
4829 UPDATE_COEF(0x49, 0x0300, 0x0300),
4830 {}
4831 };
David Henningsson73bdd592013-04-15 15:44:14 +02004832
Takashi Iwai7639a062015-03-03 10:07:24 +01004833 switch (codec->core.vendor_id) {
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004834 case 0x10ec0255:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004835 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004836 msleep(300);
4837 val = alc_read_coef_idx(codec, 0x46);
4838 is_ctia = (val & 0x0070) == 0x0070;
4839 break;
Kailang Yang717f43d2019-05-31 17:16:53 +08004840 case 0x10ec0236:
4841 case 0x10ec0256:
4842 alc_write_coef_idx(codec, 0x1b, 0x0e4b);
4843 alc_write_coef_idx(codec, 0x06, 0x6104);
4844 alc_write_coefex_idx(codec, 0x57, 0x3, 0x09a3);
4845
4846 snd_hda_codec_write(codec, 0x21, 0,
4847 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
4848 msleep(80);
4849 snd_hda_codec_write(codec, 0x21, 0,
4850 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
4851
4852 alc_process_coef_fw(codec, coef0255);
4853 msleep(300);
4854 val = alc_read_coef_idx(codec, 0x46);
4855 is_ctia = (val & 0x0070) == 0x0070;
4856
4857 alc_write_coefex_idx(codec, 0x57, 0x3, 0x0da3);
4858 alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
4859
4860 snd_hda_codec_write(codec, 0x21, 0,
4861 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
4862 msleep(80);
4863 snd_hda_codec_write(codec, 0x21, 0,
4864 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
4865 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004866 case 0x10ec0234:
4867 case 0x10ec0274:
4868 case 0x10ec0294:
4869 alc_process_coef_fw(codec, coef0274);
4870 msleep(80);
4871 val = alc_read_coef_idx(codec, 0x46);
4872 is_ctia = (val & 0x00f0) == 0x00f0;
4873 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004874 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004875 case 0x10ec0283:
4876 alc_write_coef_idx(codec, 0x45, 0xd029);
4877 msleep(300);
4878 val = alc_read_coef_idx(codec, 0x46);
4879 is_ctia = (val & 0x0070) == 0x0070;
4880 break;
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004881 case 0x10ec0298:
Kailang Yang89542932017-07-17 15:03:43 +08004882 snd_hda_codec_write(codec, 0x21, 0,
4883 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
4884 msleep(100);
4885 snd_hda_codec_write(codec, 0x21, 0,
4886 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
4887 msleep(200);
4888
4889 val = alc_read_coef_idx(codec, 0x50);
4890 if (val & (1 << 12)) {
4891 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0020);
4892 alc_process_coef_fw(codec, coef0288);
4893 msleep(350);
4894 val = alc_read_coef_idx(codec, 0x50);
4895 is_ctia = (val & 0x0070) == 0x0070;
4896 } else {
4897 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0010);
4898 alc_process_coef_fw(codec, coef0288);
4899 msleep(350);
4900 val = alc_read_coef_idx(codec, 0x50);
4901 is_ctia = (val & 0x0070) == 0x0070;
4902 }
4903 alc_process_coef_fw(codec, coef0298);
4904 snd_hda_codec_write(codec, 0x21, 0,
4905 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP);
4906 msleep(75);
4907 snd_hda_codec_write(codec, 0x21, 0,
4908 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
4909 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004910 case 0x10ec0286:
4911 case 0x10ec0288:
4912 alc_process_coef_fw(codec, coef0288);
4913 msleep(350);
4914 val = alc_read_coef_idx(codec, 0x50);
4915 is_ctia = (val & 0x0070) == 0x0070;
4916 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004917 case 0x10ec0292:
4918 alc_write_coef_idx(codec, 0x6b, 0xd429);
4919 msleep(300);
4920 val = alc_read_coef_idx(codec, 0x6c);
4921 is_ctia = (val & 0x001c) == 0x001c;
4922 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004923 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004924 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004925 msleep(300);
4926 val = alc_read_coef_idx(codec, 0x46);
4927 is_ctia = (val & 0x0070) == 0x0070;
4928 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004929 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004930 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02004931 msleep(300);
4932 val = alc_read_coef_idx(codec, 0xbe);
4933 is_ctia = (val & 0x1c02) == 0x1c02;
4934 break;
Kailang Yangc2b691e2018-01-17 15:22:55 +08004935 case 0x10ec0215:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004936 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004937 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08004938 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004939 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08004940 case 0x10ec0299:
Kailang Yangda911b12018-01-05 16:50:08 +08004941 snd_hda_codec_write(codec, 0x21, 0,
4942 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
4943 msleep(80);
4944 snd_hda_codec_write(codec, 0x21, 0,
4945 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
4946
Kailang Yang5a367672017-07-21 15:23:53 +08004947 alc_process_coef_fw(codec, alc225_pre_hsmode);
4948 alc_update_coef_idx(codec, 0x67, 0xf000, 0x1000);
4949 val = alc_read_coef_idx(codec, 0x45);
4950 if (val & (1 << 9)) {
4951 alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x34<<10);
4952 alc_update_coef_idx(codec, 0x49, 3<<8, 2<<8);
4953 msleep(800);
4954 val = alc_read_coef_idx(codec, 0x46);
4955 is_ctia = (val & 0x00f0) == 0x00f0;
4956 } else {
4957 alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x34<<10);
4958 alc_update_coef_idx(codec, 0x49, 3<<8, 1<<8);
4959 msleep(800);
4960 val = alc_read_coef_idx(codec, 0x46);
4961 is_ctia = (val & 0x00f0) == 0x00f0;
4962 }
4963 alc_update_coef_idx(codec, 0x4a, 7<<6, 7<<6);
4964 alc_update_coef_idx(codec, 0x4a, 3<<4, 3<<4);
4965 alc_update_coef_idx(codec, 0x67, 0xf000, 0x3000);
Kailang Yangda911b12018-01-05 16:50:08 +08004966
4967 snd_hda_codec_write(codec, 0x21, 0,
4968 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
4969 msleep(80);
4970 snd_hda_codec_write(codec, 0x21, 0,
4971 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004972 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08004973 case 0x10ec0867:
4974 is_ctia = true;
4975 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004976 }
4977
Takashi Iwai4e76a882014-02-25 12:21:03 +01004978 codec_dbg(codec, "Headset jack detected iPhone-style headset: %s\n",
David Henningsson73bdd592013-04-15 15:44:14 +02004979 is_ctia ? "yes" : "no");
4980 spec->current_headset_type = is_ctia ? ALC_HEADSET_TYPE_CTIA : ALC_HEADSET_TYPE_OMTP;
4981}
4982
4983static void alc_update_headset_mode(struct hda_codec *codec)
4984{
4985 struct alc_spec *spec = codec->spec;
4986
4987 hda_nid_t mux_pin = spec->gen.imux_pins[spec->gen.cur_mux[0]];
Takashi Iwai35a39f92019-02-01 11:19:50 +01004988 hda_nid_t hp_pin = alc_get_hp_pin(spec);
David Henningsson73bdd592013-04-15 15:44:14 +02004989
4990 int new_headset_mode;
4991
4992 if (!snd_hda_jack_detect(codec, hp_pin))
4993 new_headset_mode = ALC_HEADSET_MODE_UNPLUGGED;
4994 else if (mux_pin == spec->headset_mic_pin)
4995 new_headset_mode = ALC_HEADSET_MODE_HEADSET;
4996 else if (mux_pin == spec->headphone_mic_pin)
4997 new_headset_mode = ALC_HEADSET_MODE_MIC;
4998 else
4999 new_headset_mode = ALC_HEADSET_MODE_HEADPHONE;
5000
David Henningsson5959a6b2013-11-12 11:10:57 +01005001 if (new_headset_mode == spec->current_headset_mode) {
5002 snd_hda_gen_update_outputs(codec);
David Henningsson73bdd592013-04-15 15:44:14 +02005003 return;
David Henningsson5959a6b2013-11-12 11:10:57 +01005004 }
David Henningsson73bdd592013-04-15 15:44:14 +02005005
5006 switch (new_headset_mode) {
5007 case ALC_HEADSET_MODE_UNPLUGGED:
5008 alc_headset_mode_unplugged(codec);
Kailang Yangaeac1a02019-05-16 16:10:44 +08005009 spec->current_headset_mode = ALC_HEADSET_MODE_UNKNOWN;
5010 spec->current_headset_type = ALC_HEADSET_TYPE_UNKNOWN;
David Henningsson73bdd592013-04-15 15:44:14 +02005011 spec->gen.hp_jack_present = false;
5012 break;
5013 case ALC_HEADSET_MODE_HEADSET:
5014 if (spec->current_headset_type == ALC_HEADSET_TYPE_UNKNOWN)
5015 alc_determine_headset_type(codec);
5016 if (spec->current_headset_type == ALC_HEADSET_TYPE_CTIA)
5017 alc_headset_mode_ctia(codec);
5018 else if (spec->current_headset_type == ALC_HEADSET_TYPE_OMTP)
5019 alc_headset_mode_omtp(codec);
5020 spec->gen.hp_jack_present = true;
5021 break;
5022 case ALC_HEADSET_MODE_MIC:
5023 alc_headset_mode_mic_in(codec, hp_pin, spec->headphone_mic_pin);
5024 spec->gen.hp_jack_present = false;
5025 break;
5026 case ALC_HEADSET_MODE_HEADPHONE:
5027 alc_headset_mode_default(codec);
5028 spec->gen.hp_jack_present = true;
5029 break;
5030 }
5031 if (new_headset_mode != ALC_HEADSET_MODE_MIC) {
5032 snd_hda_set_pin_ctl_cache(codec, hp_pin,
5033 AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN);
David Henningsson1f8b46c2015-05-12 14:38:15 +02005034 if (spec->headphone_mic_pin && spec->headphone_mic_pin != hp_pin)
David Henningsson73bdd592013-04-15 15:44:14 +02005035 snd_hda_set_pin_ctl_cache(codec, spec->headphone_mic_pin,
5036 PIN_VREFHIZ);
5037 }
5038 spec->current_headset_mode = new_headset_mode;
5039
5040 snd_hda_gen_update_outputs(codec);
5041}
5042
5043static void alc_update_headset_mode_hook(struct hda_codec *codec,
Takashi Iwai7fe30712014-01-30 17:59:02 +01005044 struct snd_kcontrol *kcontrol,
5045 struct snd_ctl_elem_value *ucontrol)
David Henningsson73bdd592013-04-15 15:44:14 +02005046{
5047 alc_update_headset_mode(codec);
5048}
5049
Takashi Iwai1a4f69d2014-09-11 15:22:46 +02005050static void alc_update_headset_jack_cb(struct hda_codec *codec,
5051 struct hda_jack_callback *jack)
David Henningsson73bdd592013-04-15 15:44:14 +02005052{
David Henningsson73bdd592013-04-15 15:44:14 +02005053 snd_hda_gen_hp_automute(codec, jack);
5054}
5055
5056static void alc_probe_headset_mode(struct hda_codec *codec)
5057{
5058 int i;
5059 struct alc_spec *spec = codec->spec;
5060 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
5061
5062 /* Find mic pins */
5063 for (i = 0; i < cfg->num_inputs; i++) {
5064 if (cfg->inputs[i].is_headset_mic && !spec->headset_mic_pin)
5065 spec->headset_mic_pin = cfg->inputs[i].pin;
5066 if (cfg->inputs[i].is_headphone_mic && !spec->headphone_mic_pin)
5067 spec->headphone_mic_pin = cfg->inputs[i].pin;
5068 }
5069
Takashi Iwai0bed2aa2018-06-19 12:45:53 +02005070 WARN_ON(spec->gen.cap_sync_hook);
David Henningsson73bdd592013-04-15 15:44:14 +02005071 spec->gen.cap_sync_hook = alc_update_headset_mode_hook;
5072 spec->gen.automute_hook = alc_update_headset_mode;
5073 spec->gen.hp_automute_hook = alc_update_headset_jack_cb;
5074}
5075
5076static void alc_fixup_headset_mode(struct hda_codec *codec,
5077 const struct hda_fixup *fix, int action)
5078{
5079 struct alc_spec *spec = codec->spec;
5080
5081 switch (action) {
5082 case HDA_FIXUP_ACT_PRE_PROBE:
5083 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC | HDA_PINCFG_HEADPHONE_MIC;
5084 break;
5085 case HDA_FIXUP_ACT_PROBE:
5086 alc_probe_headset_mode(codec);
5087 break;
5088 case HDA_FIXUP_ACT_INIT:
Kailang Yangaeac1a02019-05-16 16:10:44 +08005089 if (is_s3_resume(codec) || is_s4_resume(codec)) {
5090 spec->current_headset_mode = ALC_HEADSET_MODE_UNKNOWN;
5091 spec->current_headset_type = ALC_HEADSET_TYPE_UNKNOWN;
5092 }
David Henningsson73bdd592013-04-15 15:44:14 +02005093 alc_update_headset_mode(codec);
5094 break;
5095 }
5096}
5097
5098static void alc_fixup_headset_mode_no_hp_mic(struct hda_codec *codec,
5099 const struct hda_fixup *fix, int action)
5100{
5101 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5102 struct alc_spec *spec = codec->spec;
5103 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
5104 }
5105 else
5106 alc_fixup_headset_mode(codec, fix, action);
5107}
5108
Kailang Yang31278992014-03-03 15:27:22 +08005109static void alc255_set_default_jack_type(struct hda_codec *codec)
5110{
5111 /* Set to iphone type */
Kailang Yange69e7e02016-05-30 15:58:28 +08005112 static struct coef_fw alc255fw[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02005113 WRITE_COEF(0x1b, 0x880b),
5114 WRITE_COEF(0x45, 0xd089),
5115 WRITE_COEF(0x1b, 0x080b),
5116 WRITE_COEF(0x46, 0x0004),
5117 WRITE_COEF(0x1b, 0x0c0b),
5118 {}
5119 };
Kailang Yange69e7e02016-05-30 15:58:28 +08005120 static struct coef_fw alc256fw[] = {
5121 WRITE_COEF(0x1b, 0x884b),
5122 WRITE_COEF(0x45, 0xd089),
5123 WRITE_COEF(0x1b, 0x084b),
5124 WRITE_COEF(0x46, 0x0004),
5125 WRITE_COEF(0x1b, 0x0c4b),
5126 {}
5127 };
5128 switch (codec->core.vendor_id) {
5129 case 0x10ec0255:
5130 alc_process_coef_fw(codec, alc255fw);
5131 break;
Kailang Yang736f20a2017-10-20 15:06:34 +08005132 case 0x10ec0236:
Kailang Yange69e7e02016-05-30 15:58:28 +08005133 case 0x10ec0256:
5134 alc_process_coef_fw(codec, alc256fw);
5135 break;
5136 }
Kailang Yang31278992014-03-03 15:27:22 +08005137 msleep(30);
5138}
5139
Kailang Yang9a22a8f52013-11-08 15:54:49 +08005140static void alc_fixup_headset_mode_alc255(struct hda_codec *codec,
5141 const struct hda_fixup *fix, int action)
5142{
5143 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Kailang Yang31278992014-03-03 15:27:22 +08005144 alc255_set_default_jack_type(codec);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08005145 }
5146 alc_fixup_headset_mode(codec, fix, action);
5147}
5148
Kailang Yang31278992014-03-03 15:27:22 +08005149static void alc_fixup_headset_mode_alc255_no_hp_mic(struct hda_codec *codec,
5150 const struct hda_fixup *fix, int action)
5151{
5152 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5153 struct alc_spec *spec = codec->spec;
5154 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
5155 alc255_set_default_jack_type(codec);
5156 }
5157 else
5158 alc_fixup_headset_mode(codec, fix, action);
5159}
5160
Kailang Yange1e62b92015-04-08 16:01:22 +08005161static void alc288_update_headset_jack_cb(struct hda_codec *codec,
5162 struct hda_jack_callback *jack)
5163{
5164 struct alc_spec *spec = codec->spec;
Kailang Yange1e62b92015-04-08 16:01:22 +08005165
5166 alc_update_headset_jack_cb(codec, jack);
5167 /* Headset Mic enable or disable, only for Dell Dino */
Takashi Iwaid44a6862018-06-19 23:04:03 +02005168 alc_update_gpio_data(codec, 0x40, spec->gen.hp_jack_present);
Kailang Yange1e62b92015-04-08 16:01:22 +08005169}
5170
5171static void alc_fixup_headset_mode_dell_alc288(struct hda_codec *codec,
5172 const struct hda_fixup *fix, int action)
5173{
5174 alc_fixup_headset_mode(codec, fix, action);
5175 if (action == HDA_FIXUP_ACT_PROBE) {
5176 struct alc_spec *spec = codec->spec;
Takashi Iwaid44a6862018-06-19 23:04:03 +02005177 /* toggled via hp_automute_hook */
5178 spec->gpio_mask |= 0x40;
5179 spec->gpio_dir |= 0x40;
Kailang Yange1e62b92015-04-08 16:01:22 +08005180 spec->gen.hp_automute_hook = alc288_update_headset_jack_cb;
5181 }
5182}
5183
Hui Wang493a52a2014-01-14 14:07:36 +08005184static void alc_fixup_auto_mute_via_amp(struct hda_codec *codec,
5185 const struct hda_fixup *fix, int action)
5186{
5187 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5188 struct alc_spec *spec = codec->spec;
5189 spec->gen.auto_mute_via_amp = 1;
5190 }
5191}
5192
Takashi Iwai9b745ab2014-03-07 08:37:19 +01005193static void alc_fixup_no_shutup(struct hda_codec *codec,
5194 const struct hda_fixup *fix, int action)
5195{
Takashi Iwaiefe55732018-06-15 11:55:02 +02005196 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai9b745ab2014-03-07 08:37:19 +01005197 struct alc_spec *spec = codec->spec;
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01005198 spec->no_shutup_pins = 1;
Takashi Iwai9b745ab2014-03-07 08:37:19 +01005199 }
5200}
5201
Gabriele Mazzotta5e6db662014-05-20 18:58:26 +02005202static void alc_fixup_disable_aamix(struct hda_codec *codec,
5203 const struct hda_fixup *fix, int action)
5204{
5205 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5206 struct alc_spec *spec = codec->spec;
5207 /* Disable AA-loopback as it causes white noise */
5208 spec->gen.mixer_nid = 0;
5209 }
5210}
5211
Takashi Iwai7f57d802015-09-24 17:36:51 +02005212/* fixup for Thinkpad docks: add dock pins, avoid HP parser fixup */
5213static void alc_fixup_tpt440_dock(struct hda_codec *codec,
5214 const struct hda_fixup *fix, int action)
5215{
5216 static const struct hda_pintbl pincfgs[] = {
5217 { 0x16, 0x21211010 }, /* dock headphone */
5218 { 0x19, 0x21a11010 }, /* dock mic */
5219 { }
5220 };
5221 struct alc_spec *spec = codec->spec;
5222
5223 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Hui Wang871b9062019-08-14 12:09:08 +08005224 spec->reboot_notify = snd_hda_gen_reboot_notify; /* reduce noise */
Takashi Iwai7f57d802015-09-24 17:36:51 +02005225 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
5226 codec->power_save_node = 0; /* avoid click noises */
5227 snd_hda_apply_pincfgs(codec, pincfgs);
5228 }
5229}
5230
Kailang Yang61fcf8e2018-02-02 15:26:46 +08005231static void alc_fixup_tpt470_dock(struct hda_codec *codec,
5232 const struct hda_fixup *fix, int action)
5233{
5234 static const struct hda_pintbl pincfgs[] = {
5235 { 0x17, 0x21211010 }, /* dock headphone */
5236 { 0x19, 0x21a11010 }, /* dock mic */
5237 { }
5238 };
Takashi Iwai54947cd2018-12-03 10:44:15 +01005239 /* Assure the speaker pin to be coupled with DAC NID 0x03; otherwise
5240 * the speaker output becomes too low by some reason on Thinkpads with
5241 * ALC298 codec
5242 */
5243 static hda_nid_t preferred_pairs[] = {
5244 0x14, 0x03, 0x17, 0x02, 0x21, 0x02,
5245 0
5246 };
Kailang Yang61fcf8e2018-02-02 15:26:46 +08005247 struct alc_spec *spec = codec->spec;
5248
5249 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai54947cd2018-12-03 10:44:15 +01005250 spec->gen.preferred_dacs = preferred_pairs;
Kailang Yang61fcf8e2018-02-02 15:26:46 +08005251 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
Takashi Iwai71db96d2018-02-26 15:36:38 +01005252 snd_hda_apply_pincfgs(codec, pincfgs);
5253 } else if (action == HDA_FIXUP_ACT_INIT) {
Kailang Yang61fcf8e2018-02-02 15:26:46 +08005254 /* Enable DOCK device */
5255 snd_hda_codec_write(codec, 0x17, 0,
5256 AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0);
5257 /* Enable DOCK device */
5258 snd_hda_codec_write(codec, 0x19, 0,
5259 AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0);
Kailang Yang61fcf8e2018-02-02 15:26:46 +08005260 }
5261}
5262
Gabriele Mazzotta9476d3692015-04-19 19:00:40 +02005263static void alc_shutup_dell_xps13(struct hda_codec *codec)
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02005264{
5265 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01005266 int hp_pin = alc_get_hp_pin(spec);
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02005267
Gabriele Mazzotta9476d3692015-04-19 19:00:40 +02005268 /* Prevent pop noises when headphones are plugged in */
5269 snd_hda_codec_write(codec, hp_pin, 0,
5270 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
5271 msleep(20);
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02005272}
5273
5274static void alc_fixup_dell_xps13(struct hda_codec *codec,
5275 const struct hda_fixup *fix, int action)
5276{
Takashi Iwai3e1b0c42015-04-27 10:43:22 +02005277 struct alc_spec *spec = codec->spec;
5278 struct hda_input_mux *imux = &spec->gen.input_mux;
5279 int i;
Gabriele Mazzottaf38663a2014-08-08 19:34:40 +02005280
Takashi Iwai3e1b0c42015-04-27 10:43:22 +02005281 switch (action) {
5282 case HDA_FIXUP_ACT_PRE_PROBE:
5283 /* mic pin 0x19 must be initialized with Vref Hi-Z, otherwise
5284 * it causes a click noise at start up
5285 */
5286 snd_hda_codec_set_pin_target(codec, 0x19, PIN_VREFHIZ);
Takashi Iwaiefe55732018-06-15 11:55:02 +02005287 spec->shutup = alc_shutup_dell_xps13;
Takashi Iwai3e1b0c42015-04-27 10:43:22 +02005288 break;
5289 case HDA_FIXUP_ACT_PROBE:
Gabriele Mazzottaf38663a2014-08-08 19:34:40 +02005290 /* Make the internal mic the default input source. */
5291 for (i = 0; i < imux->num_items; i++) {
5292 if (spec->gen.imux_pins[i] == 0x12) {
5293 spec->gen.cur_mux[0] = i;
5294 break;
5295 }
5296 }
Takashi Iwai3e1b0c42015-04-27 10:43:22 +02005297 break;
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02005298 }
5299}
5300
David Henningsson1f8b46c2015-05-12 14:38:15 +02005301static void alc_fixup_headset_mode_alc662(struct hda_codec *codec,
5302 const struct hda_fixup *fix, int action)
5303{
5304 struct alc_spec *spec = codec->spec;
5305
5306 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5307 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
5308 spec->gen.hp_mic = 1; /* Mic-in is same pin as headphone */
David Henningssonb40eda62015-05-28 09:40:23 +02005309
5310 /* Disable boost for mic-in permanently. (This code is only called
5311 from quirks that guarantee that the headphone is at NID 0x1b.) */
5312 snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000);
5313 snd_hda_override_wcaps(codec, 0x1b, get_wcaps(codec, 0x1b) & ~AC_WCAP_IN_AMP);
David Henningsson1f8b46c2015-05-12 14:38:15 +02005314 } else
5315 alc_fixup_headset_mode(codec, fix, action);
5316}
5317
David Henningsson73bdd592013-04-15 15:44:14 +02005318static void alc_fixup_headset_mode_alc668(struct hda_codec *codec,
5319 const struct hda_fixup *fix, int action)
5320{
5321 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
David Henningsson73bdd592013-04-15 15:44:14 +02005322 alc_write_coef_idx(codec, 0xc4, 0x8000);
Takashi Iwai98b24882014-08-18 13:47:50 +02005323 alc_update_coef_idx(codec, 0xc2, ~0xfe, 0);
David Henningsson73bdd592013-04-15 15:44:14 +02005324 snd_hda_set_pin_ctl_cache(codec, 0x18, 0);
5325 }
5326 alc_fixup_headset_mode(codec, fix, action);
5327}
5328
Chih-Chung Changbde7bc62013-08-05 16:38:42 +08005329/* Returns the nid of the external mic input pin, or 0 if it cannot be found. */
5330static int find_ext_mic_pin(struct hda_codec *codec)
5331{
5332 struct alc_spec *spec = codec->spec;
5333 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
5334 hda_nid_t nid;
5335 unsigned int defcfg;
5336 int i;
5337
5338 for (i = 0; i < cfg->num_inputs; i++) {
5339 if (cfg->inputs[i].type != AUTO_PIN_MIC)
5340 continue;
5341 nid = cfg->inputs[i].pin;
5342 defcfg = snd_hda_codec_get_pincfg(codec, nid);
5343 if (snd_hda_get_input_pin_attr(defcfg) == INPUT_PIN_ATTR_INT)
5344 continue;
5345 return nid;
5346 }
5347
5348 return 0;
5349}
5350
Dylan Reid08a978d2012-11-18 22:56:40 -08005351static void alc271_hp_gate_mic_jack(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01005352 const struct hda_fixup *fix,
Dylan Reid08a978d2012-11-18 22:56:40 -08005353 int action)
5354{
5355 struct alc_spec *spec = codec->spec;
5356
Takashi Iwai0db75792013-01-23 13:57:20 +01005357 if (action == HDA_FIXUP_ACT_PROBE) {
Chih-Chung Changbde7bc62013-08-05 16:38:42 +08005358 int mic_pin = find_ext_mic_pin(codec);
Takashi Iwai35a39f92019-02-01 11:19:50 +01005359 int hp_pin = alc_get_hp_pin(spec);
Chih-Chung Changbde7bc62013-08-05 16:38:42 +08005360
5361 if (snd_BUG_ON(!mic_pin || !hp_pin))
Takashi Iwai0db75792013-01-23 13:57:20 +01005362 return;
Chih-Chung Changbde7bc62013-08-05 16:38:42 +08005363 snd_hda_jack_set_gating_jack(codec, mic_pin, hp_pin);
Takashi Iwai0db75792013-01-23 13:57:20 +01005364 }
Dylan Reid08a978d2012-11-18 22:56:40 -08005365}
David Henningsson693b6132012-06-22 19:12:10 +02005366
Kai-Heng Feng1099f482019-10-03 12:39:19 +08005367static void alc256_fixup_dell_xps_13_headphone_noise2(struct hda_codec *codec,
5368 const struct hda_fixup *fix,
5369 int action)
5370{
5371 if (action != HDA_FIXUP_ACT_PRE_PROBE)
5372 return;
5373
5374 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 0, HDA_AMP_VOLMASK, 1);
5375 snd_hda_override_wcaps(codec, 0x1a, get_wcaps(codec, 0x1a) & ~AC_WCAP_IN_AMP);
5376}
5377
David Henningsson3e0d6112013-04-22 14:30:14 +02005378static void alc269_fixup_limit_int_mic_boost(struct hda_codec *codec,
5379 const struct hda_fixup *fix,
5380 int action)
5381{
5382 struct alc_spec *spec = codec->spec;
5383 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
5384 int i;
5385
5386 /* The mic boosts on level 2 and 3 are too noisy
5387 on the internal mic input.
5388 Therefore limit the boost to 0 or 1. */
5389
5390 if (action != HDA_FIXUP_ACT_PROBE)
5391 return;
5392
5393 for (i = 0; i < cfg->num_inputs; i++) {
5394 hda_nid_t nid = cfg->inputs[i].pin;
5395 unsigned int defcfg;
5396 if (cfg->inputs[i].type != AUTO_PIN_MIC)
5397 continue;
5398 defcfg = snd_hda_codec_get_pincfg(codec, nid);
5399 if (snd_hda_get_input_pin_attr(defcfg) != INPUT_PIN_ATTR_INT)
5400 continue;
5401
5402 snd_hda_override_amp_caps(codec, nid, HDA_INPUT,
5403 (0x00 << AC_AMPCAP_OFFSET_SHIFT) |
5404 (0x01 << AC_AMPCAP_NUM_STEPS_SHIFT) |
5405 (0x2f << AC_AMPCAP_STEP_SIZE_SHIFT) |
5406 (0 << AC_AMPCAP_MUTE_SHIFT));
5407 }
5408}
5409
Kailang Yangcd217a62013-08-22 10:15:24 +02005410static void alc283_hp_automute_hook(struct hda_codec *codec,
Takashi Iwai1a4f69d2014-09-11 15:22:46 +02005411 struct hda_jack_callback *jack)
Kailang Yangcd217a62013-08-22 10:15:24 +02005412{
5413 struct alc_spec *spec = codec->spec;
5414 int vref;
5415
5416 msleep(200);
5417 snd_hda_gen_hp_automute(codec, jack);
5418
5419 vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0;
5420
5421 msleep(600);
5422 snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5423 vref);
5424}
5425
Kailang Yangcd217a62013-08-22 10:15:24 +02005426static void alc283_fixup_chromebook(struct hda_codec *codec,
5427 const struct hda_fixup *fix, int action)
5428{
5429 struct alc_spec *spec = codec->spec;
Kailang Yangcd217a62013-08-22 10:15:24 +02005430
5431 switch (action) {
5432 case HDA_FIXUP_ACT_PRE_PROBE:
Kailang Yang0202e992013-12-02 15:20:15 +08005433 snd_hda_override_wcaps(codec, 0x03, 0);
Takashi Iwaid2e92702013-10-30 07:50:53 +01005434 /* Disable AA-loopback as it causes white noise */
5435 spec->gen.mixer_nid = 0;
Kailang Yang38070212013-11-01 15:57:35 +08005436 break;
5437 case HDA_FIXUP_ACT_INIT:
Kailang Yangde9481c2014-04-07 16:41:52 +08005438 /* MIC2-VREF control */
5439 /* Set to manual mode */
Takashi Iwai98b24882014-08-18 13:47:50 +02005440 alc_update_coef_idx(codec, 0x06, 0x000c, 0);
Kailang Yang0202e992013-12-02 15:20:15 +08005441 /* Enable Line1 input control by verb */
Takashi Iwai98b24882014-08-18 13:47:50 +02005442 alc_update_coef_idx(codec, 0x1a, 0, 1 << 4);
Kailang Yang0202e992013-12-02 15:20:15 +08005443 break;
5444 }
5445}
5446
5447static void alc283_fixup_sense_combo_jack(struct hda_codec *codec,
5448 const struct hda_fixup *fix, int action)
5449{
5450 struct alc_spec *spec = codec->spec;
Kailang Yang0202e992013-12-02 15:20:15 +08005451
5452 switch (action) {
5453 case HDA_FIXUP_ACT_PRE_PROBE:
Kailang Yangcd217a62013-08-22 10:15:24 +02005454 spec->gen.hp_automute_hook = alc283_hp_automute_hook;
5455 break;
5456 case HDA_FIXUP_ACT_INIT:
5457 /* MIC2-VREF control */
5458 /* Set to manual mode */
Takashi Iwai98b24882014-08-18 13:47:50 +02005459 alc_update_coef_idx(codec, 0x06, 0x000c, 0);
Kailang Yangcd217a62013-08-22 10:15:24 +02005460 break;
5461 }
5462}
5463
Takashi Iwai7bba2152013-09-06 15:45:38 +02005464/* mute tablet speaker pin (0x14) via dock plugging in addition */
5465static void asus_tx300_automute(struct hda_codec *codec)
5466{
5467 struct alc_spec *spec = codec->spec;
5468 snd_hda_gen_update_outputs(codec);
5469 if (snd_hda_jack_detect(codec, 0x1b))
5470 spec->gen.mute_bits |= (1ULL << 0x14);
5471}
5472
5473static void alc282_fixup_asus_tx300(struct hda_codec *codec,
5474 const struct hda_fixup *fix, int action)
5475{
5476 struct alc_spec *spec = codec->spec;
Takashi Iwai7bba2152013-09-06 15:45:38 +02005477 static const struct hda_pintbl dock_pins[] = {
5478 { 0x1b, 0x21114000 }, /* dock speaker pin */
5479 {}
5480 };
Takashi Iwai7bba2152013-09-06 15:45:38 +02005481
5482 switch (action) {
5483 case HDA_FIXUP_ACT_PRE_PROBE:
Takashi Iwai1c76aa52018-06-21 16:37:54 +02005484 spec->init_amp = ALC_INIT_DEFAULT;
Takashi Iwaiae065f12018-06-19 23:00:03 +02005485 /* TX300 needs to set up GPIO2 for the speaker amp */
5486 alc_setup_gpio(codec, 0x04);
Takashi Iwai7bba2152013-09-06 15:45:38 +02005487 snd_hda_apply_pincfgs(codec, dock_pins);
5488 spec->gen.auto_mute_via_amp = 1;
5489 spec->gen.automute_hook = asus_tx300_automute;
5490 snd_hda_jack_detect_enable_callback(codec, 0x1b,
Takashi Iwai7bba2152013-09-06 15:45:38 +02005491 snd_hda_gen_hp_automute);
5492 break;
Takashi Iwai5579cd62018-06-19 22:22:41 +02005493 case HDA_FIXUP_ACT_PROBE:
5494 spec->init_amp = ALC_INIT_DEFAULT;
5495 break;
Takashi Iwai7bba2152013-09-06 15:45:38 +02005496 case HDA_FIXUP_ACT_BUILD:
5497 /* this is a bit tricky; give more sane names for the main
5498 * (tablet) speaker and the dock speaker, respectively
5499 */
Takashi Iwai56798e62017-04-11 08:10:52 +02005500 rename_ctl(codec, "Speaker Playback Switch",
5501 "Dock Speaker Playback Switch");
5502 rename_ctl(codec, "Bass Speaker Playback Switch",
5503 "Speaker Playback Switch");
Takashi Iwai7bba2152013-09-06 15:45:38 +02005504 break;
5505 }
5506}
5507
David Henningsson338cae52013-10-07 10:39:59 +02005508static void alc290_fixup_mono_speakers(struct hda_codec *codec,
5509 const struct hda_fixup *fix, int action)
5510{
David Henningsson0f4881d2013-12-20 16:08:13 +01005511 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5512 /* DAC node 0x03 is giving mono output. We therefore want to
5513 make sure 0x14 (front speaker) and 0x15 (headphones) use the
5514 stereo DAC, while leaving 0x17 (bass speaker) for node 0x03. */
5515 hda_nid_t conn1[2] = { 0x0c };
5516 snd_hda_override_conn_list(codec, 0x14, 1, conn1);
5517 snd_hda_override_conn_list(codec, 0x15, 1, conn1);
5518 }
David Henningsson338cae52013-10-07 10:39:59 +02005519}
5520
Hui Wangdd9aa332016-08-01 10:20:32 +08005521static void alc298_fixup_speaker_volume(struct hda_codec *codec,
5522 const struct hda_fixup *fix, int action)
5523{
5524 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5525 /* The speaker is routed to the Node 0x06 by a mistake, as a result
5526 we can't adjust the speaker's volume since this node does not has
5527 Amp-out capability. we change the speaker's route to:
5528 Node 0x02 (Audio Output) -> Node 0x0c (Audio Mixer) -> Node 0x17 (
5529 Pin Complex), since Node 0x02 has Amp-out caps, we can adjust
5530 speaker's volume now. */
5531
5532 hda_nid_t conn1[1] = { 0x0c };
5533 snd_hda_override_conn_list(codec, 0x17, 1, conn1);
5534 }
5535}
5536
Takashi Iwaie312a862018-03-06 12:14:17 +01005537/* disable DAC3 (0x06) selection on NID 0x17 as it has no volume amp control */
5538static void alc295_fixup_disable_dac3(struct hda_codec *codec,
5539 const struct hda_fixup *fix, int action)
5540{
5541 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5542 hda_nid_t conn[2] = { 0x02, 0x03 };
5543 snd_hda_override_conn_list(codec, 0x17, 2, conn);
5544 }
5545}
5546
Keith Packard98973f22015-07-15 12:14:39 -07005547/* Hook to update amp GPIO4 for automute */
5548static void alc280_hp_gpio4_automute_hook(struct hda_codec *codec,
5549 struct hda_jack_callback *jack)
5550{
5551 struct alc_spec *spec = codec->spec;
5552
5553 snd_hda_gen_hp_automute(codec, jack);
5554 /* mute_led_polarity is set to 0, so we pass inverted value here */
5555 alc_update_gpio_led(codec, 0x10, !spec->gen.hp_jack_present);
5556}
5557
5558/* Manage GPIOs for HP EliteBook Folio 9480m.
5559 *
5560 * GPIO4 is the headphone amplifier power control
5561 * GPIO3 is the audio output mute indicator LED
5562 */
5563
5564static void alc280_fixup_hp_9480m(struct hda_codec *codec,
5565 const struct hda_fixup *fix,
5566 int action)
5567{
5568 struct alc_spec *spec = codec->spec;
Keith Packard98973f22015-07-15 12:14:39 -07005569
Takashi Iwai01e4a272018-06-19 22:47:30 +02005570 alc_fixup_hp_gpio_led(codec, action, 0x08, 0);
Keith Packard98973f22015-07-15 12:14:39 -07005571 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai01e4a272018-06-19 22:47:30 +02005572 /* amp at GPIO4; toggled via alc280_hp_gpio4_automute_hook() */
5573 spec->gpio_mask |= 0x10;
5574 spec->gpio_dir |= 0x10;
Keith Packard98973f22015-07-15 12:14:39 -07005575 spec->gen.hp_automute_hook = alc280_hp_gpio4_automute_hook;
Keith Packard98973f22015-07-15 12:14:39 -07005576 }
5577}
5578
Takashi Iwaiae065f12018-06-19 23:00:03 +02005579static void alc275_fixup_gpio4_off(struct hda_codec *codec,
5580 const struct hda_fixup *fix,
5581 int action)
5582{
5583 struct alc_spec *spec = codec->spec;
5584
5585 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5586 spec->gpio_mask |= 0x04;
5587 spec->gpio_dir |= 0x04;
5588 /* set data bit low */
5589 }
5590}
5591
Kailang Yangca169cc2017-04-25 16:17:40 +08005592static void alc233_alc662_fixup_lenovo_dual_codecs(struct hda_codec *codec,
5593 const struct hda_fixup *fix,
5594 int action)
5595{
5596 alc_fixup_dual_codecs(codec, fix, action);
5597 switch (action) {
5598 case HDA_FIXUP_ACT_PRE_PROBE:
5599 /* override card longname to provide a unique UCM profile */
5600 strcpy(codec->card->longname, "HDAudio-Lenovo-DualCodecs");
5601 break;
5602 case HDA_FIXUP_ACT_BUILD:
5603 /* rename Capture controls depending on the codec */
5604 rename_ctl(codec, "Capture Volume",
5605 codec->addr == 0 ?
5606 "Rear-Panel Capture Volume" :
5607 "Front-Panel Capture Volume");
5608 rename_ctl(codec, "Capture Switch",
5609 codec->addr == 0 ?
5610 "Rear-Panel Capture Switch" :
5611 "Front-Panel Capture Switch");
5612 break;
5613 }
5614}
5615
Kailang Yang92266652017-12-14 15:28:58 +08005616/* Forcibly assign NID 0x03 to HP/LO while NID 0x02 to SPK for EQ */
5617static void alc274_fixup_bind_dacs(struct hda_codec *codec,
5618 const struct hda_fixup *fix, int action)
5619{
5620 struct alc_spec *spec = codec->spec;
5621 static hda_nid_t preferred_pairs[] = {
5622 0x21, 0x03, 0x1b, 0x03, 0x16, 0x02,
5623 0
5624 };
5625
5626 if (action != HDA_FIXUP_ACT_PRE_PROBE)
5627 return;
5628
5629 spec->gen.preferred_dacs = preferred_pairs;
Kailang Yang0700d3d2019-04-26 16:13:54 +08005630 spec->gen.auto_mute_via_amp = 1;
5631 codec->power_save_node = 0;
Kailang Yang92266652017-12-14 15:28:58 +08005632}
5633
Hui Wangc4cfcf62018-11-26 14:17:16 +08005634/* The DAC of NID 0x3 will introduce click/pop noise on headphones, so invalidate it */
5635static void alc285_fixup_invalidate_dacs(struct hda_codec *codec,
5636 const struct hda_fixup *fix, int action)
5637{
5638 if (action != HDA_FIXUP_ACT_PRE_PROBE)
5639 return;
5640
5641 snd_hda_override_wcaps(codec, 0x03, 0);
5642}
5643
Kailang Yange8547472018-11-28 15:32:45 +08005644static const struct hda_jack_keymap alc_headset_btn_keymap[] = {
5645 { SND_JACK_BTN_0, KEY_PLAYPAUSE },
5646 { SND_JACK_BTN_1, KEY_VOICECOMMAND },
5647 { SND_JACK_BTN_2, KEY_VOLUMEUP },
5648 { SND_JACK_BTN_3, KEY_VOLUMEDOWN },
5649 {}
5650};
5651
5652static void alc_headset_btn_callback(struct hda_codec *codec,
5653 struct hda_jack_callback *jack)
5654{
5655 int report = 0;
5656
5657 if (jack->unsol_res & (7 << 13))
5658 report |= SND_JACK_BTN_0;
5659
5660 if (jack->unsol_res & (1 << 16 | 3 << 8))
5661 report |= SND_JACK_BTN_1;
5662
5663 /* Volume up key */
5664 if (jack->unsol_res & (7 << 23))
5665 report |= SND_JACK_BTN_2;
5666
5667 /* Volume down key */
5668 if (jack->unsol_res & (7 << 10))
5669 report |= SND_JACK_BTN_3;
5670
5671 jack->jack->button_state = report;
5672}
5673
Kailang Yang8983eb62019-04-03 15:31:49 +08005674static void alc_fixup_headset_jack(struct hda_codec *codec,
Kailang Yange8547472018-11-28 15:32:45 +08005675 const struct hda_fixup *fix, int action)
5676{
5677
5678 switch (action) {
5679 case HDA_FIXUP_ACT_PRE_PROBE:
5680 snd_hda_jack_detect_enable_callback(codec, 0x55,
5681 alc_headset_btn_callback);
5682 snd_hda_jack_add_kctl(codec, 0x55, "Headset Jack", false,
5683 SND_JACK_HEADSET, alc_headset_btn_keymap);
5684 break;
5685 case HDA_FIXUP_ACT_INIT:
5686 switch (codec->core.vendor_id) {
5687 case 0x10ec0225:
5688 case 0x10ec0295:
5689 case 0x10ec0299:
5690 alc_write_coef_idx(codec, 0x48, 0xd011);
5691 alc_update_coef_idx(codec, 0x49, 0x007f, 0x0045);
5692 alc_update_coef_idx(codec, 0x44, 0x007f << 8, 0x0045 << 8);
5693 break;
5694 case 0x10ec0236:
5695 case 0x10ec0256:
5696 alc_write_coef_idx(codec, 0x48, 0xd011);
5697 alc_update_coef_idx(codec, 0x49, 0x007f, 0x0045);
5698 break;
5699 }
5700 break;
5701 }
5702}
5703
Kailang Yang8983eb62019-04-03 15:31:49 +08005704static void alc295_fixup_chromebook(struct hda_codec *codec,
5705 const struct hda_fixup *fix, int action)
5706{
Kailang Yangd3ba58b2019-05-06 15:09:42 +08005707 struct alc_spec *spec = codec->spec;
5708
Kailang Yang8983eb62019-04-03 15:31:49 +08005709 switch (action) {
Kailang Yangd3ba58b2019-05-06 15:09:42 +08005710 case HDA_FIXUP_ACT_PRE_PROBE:
5711 spec->ultra_low_power = true;
5712 break;
Kailang Yang8983eb62019-04-03 15:31:49 +08005713 case HDA_FIXUP_ACT_INIT:
5714 switch (codec->core.vendor_id) {
5715 case 0x10ec0295:
5716 alc_update_coef_idx(codec, 0x4a, 0x8000, 1 << 15); /* Reset HP JD */
5717 alc_update_coef_idx(codec, 0x4a, 0x8000, 0 << 15);
5718 break;
5719 case 0x10ec0236:
5720 alc_update_coef_idx(codec, 0x1b, 0x8000, 1 << 15); /* Reset HP JD */
5721 alc_update_coef_idx(codec, 0x1b, 0x8000, 0 << 15);
5722 break;
5723 }
5724 break;
5725 }
5726}
5727
Kailang Yangd1dd4212019-01-09 17:05:24 +08005728static void alc_fixup_disable_mic_vref(struct hda_codec *codec,
5729 const struct hda_fixup *fix, int action)
5730{
5731 if (action == HDA_FIXUP_ACT_PRE_PROBE)
5732 snd_hda_codec_set_pin_target(codec, 0x19, PIN_VREFHIZ);
5733}
5734
Takashi Iwaib317b032014-01-08 11:44:21 +01005735/* for hda_fixup_thinkpad_acpi() */
5736#include "thinkpad_helper.c"
David Henningssonb67ae3f2013-11-05 13:11:37 +01005737
Takashi Iwaid5a6cab2018-06-13 12:43:10 +02005738static void alc_fixup_thinkpad_acpi(struct hda_codec *codec,
5739 const struct hda_fixup *fix, int action)
5740{
5741 alc_fixup_no_shutup(codec, fix, action); /* reduce click noise */
5742 hda_fixup_thinkpad_acpi(codec, fix, action);
5743}
5744
Tom Bridenbbf8ff62018-05-29 17:34:20 +01005745/* for alc295_fixup_hp_top_speakers */
5746#include "hp_x360_helper.c"
5747
Takashi Iwai1d045db2011-07-07 18:23:21 +02005748enum {
5749 ALC269_FIXUP_SONY_VAIO,
5750 ALC275_FIXUP_SONY_VAIO_GPIO2,
5751 ALC269_FIXUP_DELL_M101Z,
5752 ALC269_FIXUP_SKU_IGNORE,
5753 ALC269_FIXUP_ASUS_G73JW,
5754 ALC269_FIXUP_LENOVO_EAPD,
5755 ALC275_FIXUP_SONY_HWEQ,
Takashi Iwaie9bd7d52014-05-21 11:06:49 +02005756 ALC275_FIXUP_SONY_DISABLE_AAMIX,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005757 ALC271_FIXUP_DMIC,
Takashi Iwai017f2a12011-07-09 14:42:25 +02005758 ALC269_FIXUP_PCM_44K,
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02005759 ALC269_FIXUP_STEREO_DMIC,
David Henningsson7c478f02013-10-11 10:18:46 +02005760 ALC269_FIXUP_HEADSET_MIC,
Takashi Iwai24519912011-08-16 15:08:49 +02005761 ALC269_FIXUP_QUANTA_MUTE,
5762 ALC269_FIXUP_LIFEBOOK,
David Henningsson2041d562014-06-13 11:15:44 +02005763 ALC269_FIXUP_LIFEBOOK_EXTMIC,
Takashi Iwaicc7016a2015-04-08 20:47:55 +02005764 ALC269_FIXUP_LIFEBOOK_HP_PIN,
Takashi Iwai4df3fd12015-06-29 08:38:02 +02005765 ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT,
Jan-Marek Glogowskifdcc9682018-02-14 11:29:15 +01005766 ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC,
Takashi Iwaia4297b52011-08-23 18:40:12 +02005767 ALC269_FIXUP_AMIC,
5768 ALC269_FIXUP_DMIC,
5769 ALC269VB_FIXUP_AMIC,
5770 ALC269VB_FIXUP_DMIC,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01005771 ALC269_FIXUP_HP_MUTE_LED,
David Henningssond06ac142013-02-18 11:41:55 +01005772 ALC269_FIXUP_HP_MUTE_LED_MIC1,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01005773 ALC269_FIXUP_HP_MUTE_LED_MIC2,
Tom Briden7f783bd2017-03-25 10:12:01 +00005774 ALC269_FIXUP_HP_MUTE_LED_MIC3,
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01005775 ALC269_FIXUP_HP_GPIO_LED,
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08005776 ALC269_FIXUP_HP_GPIO_MIC1_LED,
5777 ALC269_FIXUP_HP_LINE1_MIC1_LED,
David Henningsson693b6132012-06-22 19:12:10 +02005778 ALC269_FIXUP_INV_DMIC,
David Henningsson108cc102012-07-20 10:37:25 +02005779 ALC269_FIXUP_LENOVO_DOCK,
Takashi Iwai9b745ab2014-03-07 08:37:19 +01005780 ALC269_FIXUP_NO_SHUTUP,
David Henningsson88cfcf82013-10-11 10:18:45 +02005781 ALC286_FIXUP_SONY_MIC_NO_PRESENCE,
David Henningsson108cc102012-07-20 10:37:25 +02005782 ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT,
David Henningsson73bdd592013-04-15 15:44:14 +02005783 ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
5784 ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
David Henningsson338cae52013-10-07 10:39:59 +02005785 ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
Kailang Yangfcc6c872017-06-29 15:21:27 +08005786 ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
David Henningsson73bdd592013-04-15 15:44:14 +02005787 ALC269_FIXUP_HEADSET_MODE,
5788 ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC,
Takashi Iwai78197172015-06-27 10:21:13 +02005789 ALC269_FIXUP_ASPIRE_HEADSET_MIC,
David Henningssond240d1d2013-04-15 12:50:02 +02005790 ALC269_FIXUP_ASUS_X101_FUNC,
5791 ALC269_FIXUP_ASUS_X101_VERB,
5792 ALC269_FIXUP_ASUS_X101,
Dylan Reid08a978d2012-11-18 22:56:40 -08005793 ALC271_FIXUP_AMIC_MIC2,
5794 ALC271_FIXUP_HP_GATE_MIC_JACK,
Oleksij Rempelb1e89722013-12-04 20:50:53 +01005795 ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572,
Dylan Reid42397002013-04-05 14:58:22 -07005796 ALC269_FIXUP_ACER_AC700,
David Henningsson3e0d6112013-04-22 14:30:14 +02005797 ALC269_FIXUP_LIMIT_INT_MIC_BOOST,
Oleksij Rempel2cede302013-11-27 17:12:03 +01005798 ALC269VB_FIXUP_ASUS_ZENBOOK,
Takashi Iwai23870832013-11-29 14:13:12 +01005799 ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A,
David Henningsson8e35cd42013-11-06 11:20:01 +01005800 ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED,
Anisse Astier02b504d2013-06-03 11:53:10 +02005801 ALC269VB_FIXUP_ORDISSIMO_EVE2,
Kailang Yangcd217a62013-08-22 10:15:24 +02005802 ALC283_FIXUP_CHROME_BOOK,
Kailang Yang0202e992013-12-02 15:20:15 +08005803 ALC283_FIXUP_SENSE_COMBO_JACK,
Takashi Iwai7bba2152013-09-06 15:45:38 +02005804 ALC282_FIXUP_ASUS_TX300,
Kailang Yang1bb3e062013-09-27 13:10:25 +02005805 ALC283_FIXUP_INT_MIC,
David Henningsson338cae52013-10-07 10:39:59 +02005806 ALC290_FIXUP_MONO_SPEAKERS,
David Henningsson0f4881d2013-12-20 16:08:13 +01005807 ALC290_FIXUP_MONO_SPEAKERS_HSJACK,
5808 ALC290_FIXUP_SUBWOOFER,
5809 ALC290_FIXUP_SUBWOOFER_HSJACK,
David Henningssonb67ae3f2013-11-05 13:11:37 +01005810 ALC269_FIXUP_THINKPAD_ACPI,
David Henningsson56f27012016-01-11 09:33:14 +01005811 ALC269_FIXUP_DMIC_THINKPAD_ACPI,
Chris Chiu5824ce82017-02-28 14:17:11 -06005812 ALC255_FIXUP_ACER_MIC_NO_PRESENCE,
Chris Chiu615966a2017-02-28 14:17:12 -06005813 ALC255_FIXUP_ASUS_MIC_NO_PRESENCE,
Kailang Yang9a22a8f52013-11-08 15:54:49 +08005814 ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Kailang Yang31278992014-03-03 15:27:22 +08005815 ALC255_FIXUP_DELL2_MIC_NO_PRESENCE,
Kailang Yang9a22a8f52013-11-08 15:54:49 +08005816 ALC255_FIXUP_HEADSET_MODE,
Kailang Yang31278992014-03-03 15:27:22 +08005817 ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC,
Kailang Yanga22aa262014-04-23 17:34:28 +08005818 ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
Takashi Iwai1c37c222014-05-06 17:34:42 +02005819 ALC292_FIXUP_TPT440_DOCK,
Takashi Iwai9a811232015-12-09 15:17:43 +01005820 ALC292_FIXUP_TPT440,
Anisse Astierabaa22742016-08-24 09:14:13 +02005821 ALC283_FIXUP_HEADSET_MIC,
Takashi Iwaib3802782018-11-26 17:47:46 +01005822 ALC255_FIXUP_MIC_MUTE_LED,
Takashi Iwai1a22e772014-08-27 08:19:05 +02005823 ALC282_FIXUP_ASPIRE_V5_PINS,
David Henningsson7a5255f2014-10-30 08:26:01 +01005824 ALC280_FIXUP_HP_GPIO4,
Kailang Yangeaa8e5e2014-11-21 15:49:11 +08005825 ALC286_FIXUP_HP_GPIO_LED,
David Henningsson33f4acd2015-01-07 15:50:13 +01005826 ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY,
TienFu Chenb4b33f92015-01-20 15:06:21 +01005827 ALC280_FIXUP_HP_DOCK_PINS,
Jaroslav Kysela04d54662017-03-09 13:29:13 +01005828 ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED,
Keith Packard98973f22015-07-15 12:14:39 -07005829 ALC280_FIXUP_HP_9480M,
Kailang Yange1e62b92015-04-08 16:01:22 +08005830 ALC288_FIXUP_DELL_HEADSET_MODE,
5831 ALC288_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang831bfdf92015-06-26 12:35:17 +08005832 ALC288_FIXUP_DELL_XPS_13,
5833 ALC288_FIXUP_DISABLE_AAMIX,
Takashi Iwai8b99aba2015-06-15 11:59:32 +02005834 ALC292_FIXUP_DELL_E7X,
5835 ALC292_FIXUP_DISABLE_AAMIX,
David Henningssonc04017e2015-12-15 14:44:03 +01005836 ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK,
James McDonnell54324222019-09-16 14:53:38 +00005837 ALC298_FIXUP_ALIENWARE_MIC_NO_PRESENCE,
Kailang Yang977e6272015-05-18 15:31:20 +08005838 ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang2f726ae2017-03-31 10:31:40 +08005839 ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE,
Kailang Yang6ed11312015-10-26 15:37:39 +08005840 ALC275_FIXUP_DELL_XPS,
Hui Wang8c697292015-11-24 11:08:18 +08005841 ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE,
Kai-Heng Feng1099f482019-10-03 12:39:19 +08005842 ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE2,
Hui Wang23adc192015-12-08 12:27:18 +08005843 ALC293_FIXUP_LENOVO_SPK_NOISE,
Kailang3694cb22015-12-28 11:35:24 +08005844 ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY,
Kai-Heng Feng3b43b712016-02-25 15:19:38 +08005845 ALC255_FIXUP_DELL_SPK_NOISE,
Kailang Yangd1dd4212019-01-09 17:05:24 +08005846 ALC225_FIXUP_DISABLE_MIC_VREF,
David Henningsson2ae95572016-02-25 09:37:05 +01005847 ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
Takashi Iwaie312a862018-03-06 12:14:17 +01005848 ALC295_FIXUP_DISABLE_DAC3,
Takashi Iwaif8839822016-02-25 14:31:59 +01005849 ALC280_FIXUP_HP_HEADSET_MIC,
Hui Wange549d192016-04-01 11:00:15 +08005850 ALC221_FIXUP_HP_FRONT_MIC,
Sven Eckelmannc636b952016-04-11 16:55:26 +02005851 ALC292_FIXUP_TPT460,
Hui Wangdd9aa332016-08-01 10:20:32 +08005852 ALC298_FIXUP_SPK_VOLUME,
Kai-Heng Fengfd06c772016-08-30 15:36:34 +08005853 ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER,
Gabriele Mazzotta823ff162016-12-24 19:50:01 +01005854 ALC269_FIXUP_ATIV_BOOK_8,
Kailang Yang9eb5d0e2017-01-17 15:40:25 +08005855 ALC221_FIXUP_HP_MIC_NO_PRESENCE,
Chris Chiuc1732ed2017-02-28 14:17:13 -06005856 ALC256_FIXUP_ASUS_HEADSET_MODE,
5857 ALC256_FIXUP_ASUS_MIC,
Chris Chiueeed4cd2017-02-28 14:17:15 -06005858 ALC256_FIXUP_ASUS_AIO_GPIO2,
Chris Chiu216d7ae2017-02-28 14:17:14 -06005859 ALC233_FIXUP_ASUS_MIC_NO_PRESENCE,
5860 ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE,
Kailang Yangca169cc2017-04-25 16:17:40 +08005861 ALC233_FIXUP_LENOVO_MULTI_CODECS,
Jian-Hong Panea5c7eb2019-04-01 11:25:05 +08005862 ALC233_FIXUP_ACER_HEADSET_MIC,
Hui Wangf33f79f2017-07-07 12:08:29 +08005863 ALC294_FIXUP_LENOVO_MIC_LOCATION,
Kailang Yang5f364132017-07-25 16:28:16 +08005864 ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE,
PeiSen Houb84e8432017-09-01 15:11:56 +08005865 ALC700_FIXUP_INTEL_REFERENCE,
Kailang Yang92266652017-12-14 15:28:58 +08005866 ALC274_FIXUP_DELL_BIND_DACS,
5867 ALC274_FIXUP_DELL_AIO_LINEOUT_VERB,
Kailang Yang61fcf8e2018-02-02 15:26:46 +08005868 ALC298_FIXUP_TPT470_DOCK,
Kailang Yangae104a22018-02-05 16:07:20 +08005869 ALC255_FIXUP_DUMMY_LINEOUT_VERB,
Kailang Yangf0ba9d62018-03-16 11:46:08 +08005870 ALC255_FIXUP_DELL_HEADSET_MIC,
Ayman Bagabas0fbf21c2019-05-23 05:30:11 -04005871 ALC256_FIXUP_HUAWEI_MACH_WX9_PINS,
Tomas Espeletaa2ef03f2019-08-09 16:37:54 +02005872 ALC298_FIXUP_HUAWEI_MBX_STEREO,
Tom Bridenbbf8ff62018-05-29 17:34:20 +01005873 ALC295_FIXUP_HP_X360,
Kailang Yang8a328ac2018-08-21 16:54:41 +08005874 ALC221_FIXUP_HP_HEADSET_MIC,
Hui Wangc4cfcf62018-11-26 14:17:16 +08005875 ALC285_FIXUP_LENOVO_HEADPHONE_NOISE,
Girija Kumar Kasinadhunie8ed64b2018-11-26 13:40:46 -05005876 ALC295_FIXUP_HP_AUTO_MUTE,
Chris Chiu33aaebd2018-12-05 14:48:53 +08005877 ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE,
Chris Chiud8ae4582018-12-07 17:17:11 +08005878 ALC294_FIXUP_ASUS_MIC,
Jian-Hong Pan4e051102018-12-07 17:17:12 +08005879 ALC294_FIXUP_ASUS_HEADSET_MIC,
5880 ALC294_FIXUP_ASUS_SPK,
Jeremy Soller89e3a562019-01-30 16:12:31 -07005881 ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE,
Hui Wangc8c6ee62019-02-14 11:41:33 +08005882 ALC285_FIXUP_LENOVO_PC_BEEP_IN_NOISE,
Jian-Hong Pancbc05fd2019-03-13 17:33:24 +08005883 ALC255_FIXUP_ACER_HEADSET_MIC,
Kailang Yang10f5b1b2019-02-21 16:10:22 +08005884 ALC295_FIXUP_CHROME_BOOK,
Kailang Yang8983eb62019-04-03 15:31:49 +08005885 ALC225_FIXUP_HEADSET_JACK,
Kailang Yang136824e2019-03-14 16:22:45 +08005886 ALC225_FIXUP_DELL_WYSE_AIO_MIC_NO_PRESENCE,
5887 ALC225_FIXUP_WYSE_AUTO_MUTE,
5888 ALC225_FIXUP_WYSE_DISABLE_MIC_VREF,
Jian-Hong Pan667a8f72019-03-15 17:51:09 +08005889 ALC286_FIXUP_ACER_AIO_HEADSET_MIC,
Daniel Drake8c8967a2019-10-17 16:15:01 +08005890 ALC256_FIXUP_ASUS_HEADSET_MIC,
Jian-Hong Pane1037352019-03-22 11:37:18 +08005891 ALC256_FIXUP_ASUS_MIC_NO_PRESENCE,
Bernhard Rosenkraenzere2a829b2019-03-05 00:38:19 +01005892 ALC299_FIXUP_PREDATOR_SPK,
Jian-Hong Pan60083f92019-09-02 18:00:56 +08005893 ALC294_FIXUP_ASUS_INTSPK_HEADSET_MIC,
Jan-Marek Glogowskibd9c10b2019-09-15 16:57:28 +02005894 ALC256_FIXUP_MEDION_HEADSET_NO_PRESENCE,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005895};
5896
Takashi Iwai1727a772013-01-10 09:52:52 +01005897static const struct hda_fixup alc269_fixups[] = {
Takashi Iwai1d045db2011-07-07 18:23:21 +02005898 [ALC269_FIXUP_SONY_VAIO] = {
Takashi Iwaifd108212013-01-10 10:18:14 +01005899 .type = HDA_FIXUP_PINCTLS,
5900 .v.pins = (const struct hda_pintbl[]) {
5901 {0x19, PIN_VREFGRD},
Takashi Iwai1d045db2011-07-07 18:23:21 +02005902 {}
5903 }
5904 },
5905 [ALC275_FIXUP_SONY_VAIO_GPIO2] = {
Takashi Iwaiae065f12018-06-19 23:00:03 +02005906 .type = HDA_FIXUP_FUNC,
5907 .v.func = alc275_fixup_gpio4_off,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005908 .chained = true,
5909 .chain_id = ALC269_FIXUP_SONY_VAIO
5910 },
5911 [ALC269_FIXUP_DELL_M101Z] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005912 .type = HDA_FIXUP_VERBS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005913 .v.verbs = (const struct hda_verb[]) {
5914 /* Enables internal speaker */
5915 {0x20, AC_VERB_SET_COEF_INDEX, 13},
5916 {0x20, AC_VERB_SET_PROC_COEF, 0x4040},
5917 {}
5918 }
5919 },
5920 [ALC269_FIXUP_SKU_IGNORE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005921 .type = HDA_FIXUP_FUNC,
Takashi Iwai23d30f22012-05-07 17:17:32 +02005922 .v.func = alc_fixup_sku_ignore,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005923 },
5924 [ALC269_FIXUP_ASUS_G73JW] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005925 .type = HDA_FIXUP_PINS,
5926 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02005927 { 0x17, 0x99130111 }, /* subwoofer */
5928 { }
5929 }
5930 },
5931 [ALC269_FIXUP_LENOVO_EAPD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005932 .type = HDA_FIXUP_VERBS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005933 .v.verbs = (const struct hda_verb[]) {
5934 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
5935 {}
5936 }
5937 },
5938 [ALC275_FIXUP_SONY_HWEQ] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005939 .type = HDA_FIXUP_FUNC,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005940 .v.func = alc269_fixup_hweq,
5941 .chained = true,
5942 .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2
5943 },
Takashi Iwaie9bd7d52014-05-21 11:06:49 +02005944 [ALC275_FIXUP_SONY_DISABLE_AAMIX] = {
5945 .type = HDA_FIXUP_FUNC,
5946 .v.func = alc_fixup_disable_aamix,
5947 .chained = true,
5948 .chain_id = ALC269_FIXUP_SONY_VAIO
5949 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02005950 [ALC271_FIXUP_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005951 .type = HDA_FIXUP_FUNC,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005952 .v.func = alc271_fixup_dmic,
5953 },
Takashi Iwai017f2a12011-07-09 14:42:25 +02005954 [ALC269_FIXUP_PCM_44K] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005955 .type = HDA_FIXUP_FUNC,
Takashi Iwai017f2a12011-07-09 14:42:25 +02005956 .v.func = alc269_fixup_pcm_44k,
David Henningsson012e7eb2012-08-08 08:43:37 +02005957 .chained = true,
5958 .chain_id = ALC269_FIXUP_QUANTA_MUTE
Takashi Iwai017f2a12011-07-09 14:42:25 +02005959 },
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02005960 [ALC269_FIXUP_STEREO_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005961 .type = HDA_FIXUP_FUNC,
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02005962 .v.func = alc269_fixup_stereo_dmic,
5963 },
David Henningsson7c478f02013-10-11 10:18:46 +02005964 [ALC269_FIXUP_HEADSET_MIC] = {
5965 .type = HDA_FIXUP_FUNC,
5966 .v.func = alc269_fixup_headset_mic,
5967 },
Takashi Iwai24519912011-08-16 15:08:49 +02005968 [ALC269_FIXUP_QUANTA_MUTE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005969 .type = HDA_FIXUP_FUNC,
Takashi Iwai24519912011-08-16 15:08:49 +02005970 .v.func = alc269_fixup_quanta_mute,
5971 },
5972 [ALC269_FIXUP_LIFEBOOK] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005973 .type = HDA_FIXUP_PINS,
5974 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai24519912011-08-16 15:08:49 +02005975 { 0x1a, 0x2101103f }, /* dock line-out */
5976 { 0x1b, 0x23a11040 }, /* dock mic-in */
5977 { }
5978 },
5979 .chained = true,
5980 .chain_id = ALC269_FIXUP_QUANTA_MUTE
5981 },
David Henningsson2041d562014-06-13 11:15:44 +02005982 [ALC269_FIXUP_LIFEBOOK_EXTMIC] = {
5983 .type = HDA_FIXUP_PINS,
5984 .v.pins = (const struct hda_pintbl[]) {
5985 { 0x19, 0x01a1903c }, /* headset mic, with jack detect */
5986 { }
5987 },
5988 },
Takashi Iwaicc7016a2015-04-08 20:47:55 +02005989 [ALC269_FIXUP_LIFEBOOK_HP_PIN] = {
5990 .type = HDA_FIXUP_PINS,
5991 .v.pins = (const struct hda_pintbl[]) {
5992 { 0x21, 0x0221102f }, /* HP out */
5993 { }
5994 },
5995 },
Takashi Iwai4df3fd12015-06-29 08:38:02 +02005996 [ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT] = {
5997 .type = HDA_FIXUP_FUNC,
5998 .v.func = alc269_fixup_pincfg_no_hp_to_lineout,
5999 },
Jan-Marek Glogowskifdcc9682018-02-14 11:29:15 +01006000 [ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC] = {
6001 .type = HDA_FIXUP_FUNC,
6002 .v.func = alc269_fixup_pincfg_U7x7_headset_mic,
6003 },
Takashi Iwaia4297b52011-08-23 18:40:12 +02006004 [ALC269_FIXUP_AMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006005 .type = HDA_FIXUP_PINS,
6006 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaia4297b52011-08-23 18:40:12 +02006007 { 0x14, 0x99130110 }, /* speaker */
6008 { 0x15, 0x0121401f }, /* HP out */
6009 { 0x18, 0x01a19c20 }, /* mic */
6010 { 0x19, 0x99a3092f }, /* int-mic */
6011 { }
6012 },
6013 },
6014 [ALC269_FIXUP_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006015 .type = HDA_FIXUP_PINS,
6016 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaia4297b52011-08-23 18:40:12 +02006017 { 0x12, 0x99a3092f }, /* int-mic */
6018 { 0x14, 0x99130110 }, /* speaker */
6019 { 0x15, 0x0121401f }, /* HP out */
6020 { 0x18, 0x01a19c20 }, /* mic */
6021 { }
6022 },
6023 },
6024 [ALC269VB_FIXUP_AMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006025 .type = HDA_FIXUP_PINS,
6026 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaia4297b52011-08-23 18:40:12 +02006027 { 0x14, 0x99130110 }, /* speaker */
6028 { 0x18, 0x01a19c20 }, /* mic */
6029 { 0x19, 0x99a3092f }, /* int-mic */
6030 { 0x21, 0x0121401f }, /* HP out */
6031 { }
6032 },
6033 },
David Henningsson2267ea92012-01-03 08:45:56 +01006034 [ALC269VB_FIXUP_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006035 .type = HDA_FIXUP_PINS,
6036 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaia4297b52011-08-23 18:40:12 +02006037 { 0x12, 0x99a3092f }, /* int-mic */
6038 { 0x14, 0x99130110 }, /* speaker */
6039 { 0x18, 0x01a19c20 }, /* mic */
6040 { 0x21, 0x0121401f }, /* HP out */
6041 { }
6042 },
6043 },
Takashi Iwai08fb0d02013-01-10 17:33:58 +01006044 [ALC269_FIXUP_HP_MUTE_LED] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006045 .type = HDA_FIXUP_FUNC,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01006046 .v.func = alc269_fixup_hp_mute_led,
David Henningsson6d3cd5d2013-01-07 12:03:47 +01006047 },
David Henningssond06ac142013-02-18 11:41:55 +01006048 [ALC269_FIXUP_HP_MUTE_LED_MIC1] = {
6049 .type = HDA_FIXUP_FUNC,
6050 .v.func = alc269_fixup_hp_mute_led_mic1,
6051 },
Takashi Iwai08fb0d02013-01-10 17:33:58 +01006052 [ALC269_FIXUP_HP_MUTE_LED_MIC2] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006053 .type = HDA_FIXUP_FUNC,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01006054 .v.func = alc269_fixup_hp_mute_led_mic2,
Takashi Iwai420b0fe2012-03-12 12:35:27 +01006055 },
Tom Briden7f783bd2017-03-25 10:12:01 +00006056 [ALC269_FIXUP_HP_MUTE_LED_MIC3] = {
6057 .type = HDA_FIXUP_FUNC,
6058 .v.func = alc269_fixup_hp_mute_led_mic3,
Girija Kumar Kasinadhunie8ed64b2018-11-26 13:40:46 -05006059 .chained = true,
6060 .chain_id = ALC295_FIXUP_HP_AUTO_MUTE
Tom Briden7f783bd2017-03-25 10:12:01 +00006061 },
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01006062 [ALC269_FIXUP_HP_GPIO_LED] = {
6063 .type = HDA_FIXUP_FUNC,
6064 .v.func = alc269_fixup_hp_gpio_led,
6065 },
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08006066 [ALC269_FIXUP_HP_GPIO_MIC1_LED] = {
6067 .type = HDA_FIXUP_FUNC,
6068 .v.func = alc269_fixup_hp_gpio_mic1_led,
6069 },
6070 [ALC269_FIXUP_HP_LINE1_MIC1_LED] = {
6071 .type = HDA_FIXUP_FUNC,
6072 .v.func = alc269_fixup_hp_line1_mic1_led,
6073 },
David Henningsson693b6132012-06-22 19:12:10 +02006074 [ALC269_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006075 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02006076 .v.func = alc_fixup_inv_dmic,
David Henningsson693b6132012-06-22 19:12:10 +02006077 },
Takashi Iwai9b745ab2014-03-07 08:37:19 +01006078 [ALC269_FIXUP_NO_SHUTUP] = {
6079 .type = HDA_FIXUP_FUNC,
6080 .v.func = alc_fixup_no_shutup,
6081 },
David Henningsson108cc102012-07-20 10:37:25 +02006082 [ALC269_FIXUP_LENOVO_DOCK] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006083 .type = HDA_FIXUP_PINS,
6084 .v.pins = (const struct hda_pintbl[]) {
David Henningsson108cc102012-07-20 10:37:25 +02006085 { 0x19, 0x23a11040 }, /* dock mic */
6086 { 0x1b, 0x2121103f }, /* dock headphone */
6087 { }
6088 },
6089 .chained = true,
6090 .chain_id = ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT
6091 },
6092 [ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006093 .type = HDA_FIXUP_FUNC,
David Henningsson108cc102012-07-20 10:37:25 +02006094 .v.func = alc269_fixup_pincfg_no_hp_to_lineout,
David Henningsson52129002013-11-19 10:25:53 +01006095 .chained = true,
6096 .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
David Henningsson108cc102012-07-20 10:37:25 +02006097 },
David Henningsson73bdd592013-04-15 15:44:14 +02006098 [ALC269_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6099 .type = HDA_FIXUP_PINS,
6100 .v.pins = (const struct hda_pintbl[]) {
6101 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6102 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6103 { }
6104 },
6105 .chained = true,
6106 .chain_id = ALC269_FIXUP_HEADSET_MODE
6107 },
6108 [ALC269_FIXUP_DELL2_MIC_NO_PRESENCE] = {
6109 .type = HDA_FIXUP_PINS,
6110 .v.pins = (const struct hda_pintbl[]) {
6111 { 0x16, 0x21014020 }, /* dock line out */
6112 { 0x19, 0x21a19030 }, /* dock mic */
6113 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6114 { }
6115 },
6116 .chained = true,
6117 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
6118 },
David Henningsson338cae52013-10-07 10:39:59 +02006119 [ALC269_FIXUP_DELL3_MIC_NO_PRESENCE] = {
6120 .type = HDA_FIXUP_PINS,
6121 .v.pins = (const struct hda_pintbl[]) {
6122 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6123 { }
6124 },
6125 .chained = true,
6126 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
6127 },
Kailang Yangfcc6c872017-06-29 15:21:27 +08006128 [ALC269_FIXUP_DELL4_MIC_NO_PRESENCE] = {
6129 .type = HDA_FIXUP_PINS,
6130 .v.pins = (const struct hda_pintbl[]) {
6131 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6132 { 0x1b, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6133 { }
6134 },
6135 .chained = true,
6136 .chain_id = ALC269_FIXUP_HEADSET_MODE
6137 },
David Henningsson73bdd592013-04-15 15:44:14 +02006138 [ALC269_FIXUP_HEADSET_MODE] = {
6139 .type = HDA_FIXUP_FUNC,
6140 .v.func = alc_fixup_headset_mode,
Hui Wang6676f302014-11-18 17:57:41 +08006141 .chained = true,
Takashi Iwaib3802782018-11-26 17:47:46 +01006142 .chain_id = ALC255_FIXUP_MIC_MUTE_LED
David Henningsson73bdd592013-04-15 15:44:14 +02006143 },
6144 [ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC] = {
6145 .type = HDA_FIXUP_FUNC,
6146 .v.func = alc_fixup_headset_mode_no_hp_mic,
6147 },
Takashi Iwai78197172015-06-27 10:21:13 +02006148 [ALC269_FIXUP_ASPIRE_HEADSET_MIC] = {
6149 .type = HDA_FIXUP_PINS,
6150 .v.pins = (const struct hda_pintbl[]) {
6151 { 0x19, 0x01a1913c }, /* headset mic w/o jack detect */
6152 { }
6153 },
6154 .chained = true,
6155 .chain_id = ALC269_FIXUP_HEADSET_MODE,
6156 },
David Henningsson88cfcf82013-10-11 10:18:45 +02006157 [ALC286_FIXUP_SONY_MIC_NO_PRESENCE] = {
6158 .type = HDA_FIXUP_PINS,
6159 .v.pins = (const struct hda_pintbl[]) {
6160 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6161 { }
6162 },
David Henningssonfbc78ad2013-10-11 13:46:04 +02006163 .chained = true,
6164 .chain_id = ALC269_FIXUP_HEADSET_MIC
David Henningsson88cfcf82013-10-11 10:18:45 +02006165 },
Ayman Bagabas0fbf21c2019-05-23 05:30:11 -04006166 [ALC256_FIXUP_HUAWEI_MACH_WX9_PINS] = {
Ayman Bagabas8ac51bb2018-12-12 18:07:57 -05006167 .type = HDA_FIXUP_PINS,
6168 .v.pins = (const struct hda_pintbl[]) {
6169 {0x12, 0x90a60130},
6170 {0x13, 0x40000000},
6171 {0x14, 0x90170110},
6172 {0x18, 0x411111f0},
6173 {0x19, 0x04a11040},
6174 {0x1a, 0x411111f0},
6175 {0x1b, 0x90170112},
6176 {0x1d, 0x40759a05},
6177 {0x1e, 0x411111f0},
6178 {0x21, 0x04211020},
6179 { }
6180 },
Ayman Bagabase2744fd2018-12-12 18:07:59 -05006181 .chained = true,
6182 .chain_id = ALC255_FIXUP_MIC_MUTE_LED
Ayman Bagabas8ac51bb2018-12-12 18:07:57 -05006183 },
Tomas Espeletaa2ef03f2019-08-09 16:37:54 +02006184 [ALC298_FIXUP_HUAWEI_MBX_STEREO] = {
6185 .type = HDA_FIXUP_FUNC,
6186 .v.func = alc298_fixup_huawei_mbx_stereo,
6187 .chained = true,
6188 .chain_id = ALC255_FIXUP_MIC_MUTE_LED
6189 },
David Henningssond240d1d2013-04-15 12:50:02 +02006190 [ALC269_FIXUP_ASUS_X101_FUNC] = {
6191 .type = HDA_FIXUP_FUNC,
6192 .v.func = alc269_fixup_x101_headset_mic,
6193 },
6194 [ALC269_FIXUP_ASUS_X101_VERB] = {
6195 .type = HDA_FIXUP_VERBS,
6196 .v.verbs = (const struct hda_verb[]) {
6197 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6198 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
6199 {0x20, AC_VERB_SET_PROC_COEF, 0x0310},
6200 { }
6201 },
6202 .chained = true,
6203 .chain_id = ALC269_FIXUP_ASUS_X101_FUNC
6204 },
6205 [ALC269_FIXUP_ASUS_X101] = {
6206 .type = HDA_FIXUP_PINS,
6207 .v.pins = (const struct hda_pintbl[]) {
6208 { 0x18, 0x04a1182c }, /* Headset mic */
6209 { }
6210 },
6211 .chained = true,
6212 .chain_id = ALC269_FIXUP_ASUS_X101_VERB
6213 },
Dylan Reid08a978d2012-11-18 22:56:40 -08006214 [ALC271_FIXUP_AMIC_MIC2] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006215 .type = HDA_FIXUP_PINS,
6216 .v.pins = (const struct hda_pintbl[]) {
Dylan Reid08a978d2012-11-18 22:56:40 -08006217 { 0x14, 0x99130110 }, /* speaker */
6218 { 0x19, 0x01a19c20 }, /* mic */
6219 { 0x1b, 0x99a7012f }, /* int-mic */
6220 { 0x21, 0x0121401f }, /* HP out */
6221 { }
6222 },
6223 },
6224 [ALC271_FIXUP_HP_GATE_MIC_JACK] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006225 .type = HDA_FIXUP_FUNC,
Dylan Reid08a978d2012-11-18 22:56:40 -08006226 .v.func = alc271_hp_gate_mic_jack,
6227 .chained = true,
6228 .chain_id = ALC271_FIXUP_AMIC_MIC2,
6229 },
Oleksij Rempelb1e89722013-12-04 20:50:53 +01006230 [ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572] = {
6231 .type = HDA_FIXUP_FUNC,
6232 .v.func = alc269_fixup_limit_int_mic_boost,
6233 .chained = true,
6234 .chain_id = ALC271_FIXUP_HP_GATE_MIC_JACK,
6235 },
Dylan Reid42397002013-04-05 14:58:22 -07006236 [ALC269_FIXUP_ACER_AC700] = {
6237 .type = HDA_FIXUP_PINS,
6238 .v.pins = (const struct hda_pintbl[]) {
6239 { 0x12, 0x99a3092f }, /* int-mic */
6240 { 0x14, 0x99130110 }, /* speaker */
6241 { 0x18, 0x03a11c20 }, /* mic */
6242 { 0x1e, 0x0346101e }, /* SPDIF1 */
6243 { 0x21, 0x0321101f }, /* HP out */
6244 { }
6245 },
6246 .chained = true,
6247 .chain_id = ALC271_FIXUP_DMIC,
6248 },
David Henningsson3e0d6112013-04-22 14:30:14 +02006249 [ALC269_FIXUP_LIMIT_INT_MIC_BOOST] = {
6250 .type = HDA_FIXUP_FUNC,
6251 .v.func = alc269_fixup_limit_int_mic_boost,
David Henningsson27937692013-11-18 11:51:47 +01006252 .chained = true,
6253 .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
David Henningsson3e0d6112013-04-22 14:30:14 +02006254 },
Oleksij Rempel2cede302013-11-27 17:12:03 +01006255 [ALC269VB_FIXUP_ASUS_ZENBOOK] = {
6256 .type = HDA_FIXUP_FUNC,
6257 .v.func = alc269_fixup_limit_int_mic_boost,
6258 .chained = true,
6259 .chain_id = ALC269VB_FIXUP_DMIC,
6260 },
Takashi Iwai23870832013-11-29 14:13:12 +01006261 [ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A] = {
6262 .type = HDA_FIXUP_VERBS,
6263 .v.verbs = (const struct hda_verb[]) {
6264 /* class-D output amp +5dB */
6265 { 0x20, AC_VERB_SET_COEF_INDEX, 0x12 },
6266 { 0x20, AC_VERB_SET_PROC_COEF, 0x2800 },
6267 {}
6268 },
6269 .chained = true,
6270 .chain_id = ALC269VB_FIXUP_ASUS_ZENBOOK,
6271 },
David Henningsson8e35cd42013-11-06 11:20:01 +01006272 [ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED] = {
6273 .type = HDA_FIXUP_FUNC,
6274 .v.func = alc269_fixup_limit_int_mic_boost,
6275 .chained = true,
6276 .chain_id = ALC269_FIXUP_HP_MUTE_LED_MIC1,
6277 },
Anisse Astier02b504d2013-06-03 11:53:10 +02006278 [ALC269VB_FIXUP_ORDISSIMO_EVE2] = {
6279 .type = HDA_FIXUP_PINS,
6280 .v.pins = (const struct hda_pintbl[]) {
6281 { 0x12, 0x99a3092f }, /* int-mic */
6282 { 0x18, 0x03a11d20 }, /* mic */
6283 { 0x19, 0x411111f0 }, /* Unused bogus pin */
6284 { }
6285 },
6286 },
Kailang Yangcd217a62013-08-22 10:15:24 +02006287 [ALC283_FIXUP_CHROME_BOOK] = {
6288 .type = HDA_FIXUP_FUNC,
6289 .v.func = alc283_fixup_chromebook,
6290 },
Kailang Yang0202e992013-12-02 15:20:15 +08006291 [ALC283_FIXUP_SENSE_COMBO_JACK] = {
6292 .type = HDA_FIXUP_FUNC,
6293 .v.func = alc283_fixup_sense_combo_jack,
6294 .chained = true,
6295 .chain_id = ALC283_FIXUP_CHROME_BOOK,
6296 },
Takashi Iwai7bba2152013-09-06 15:45:38 +02006297 [ALC282_FIXUP_ASUS_TX300] = {
6298 .type = HDA_FIXUP_FUNC,
6299 .v.func = alc282_fixup_asus_tx300,
6300 },
Kailang Yang1bb3e062013-09-27 13:10:25 +02006301 [ALC283_FIXUP_INT_MIC] = {
6302 .type = HDA_FIXUP_VERBS,
6303 .v.verbs = (const struct hda_verb[]) {
6304 {0x20, AC_VERB_SET_COEF_INDEX, 0x1a},
6305 {0x20, AC_VERB_SET_PROC_COEF, 0x0011},
6306 { }
6307 },
6308 .chained = true,
6309 .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST
6310 },
David Henningsson0f4881d2013-12-20 16:08:13 +01006311 [ALC290_FIXUP_SUBWOOFER_HSJACK] = {
6312 .type = HDA_FIXUP_PINS,
6313 .v.pins = (const struct hda_pintbl[]) {
6314 { 0x17, 0x90170112 }, /* subwoofer */
6315 { }
6316 },
6317 .chained = true,
6318 .chain_id = ALC290_FIXUP_MONO_SPEAKERS_HSJACK,
6319 },
6320 [ALC290_FIXUP_SUBWOOFER] = {
6321 .type = HDA_FIXUP_PINS,
6322 .v.pins = (const struct hda_pintbl[]) {
6323 { 0x17, 0x90170112 }, /* subwoofer */
6324 { }
6325 },
6326 .chained = true,
6327 .chain_id = ALC290_FIXUP_MONO_SPEAKERS,
6328 },
David Henningsson338cae52013-10-07 10:39:59 +02006329 [ALC290_FIXUP_MONO_SPEAKERS] = {
6330 .type = HDA_FIXUP_FUNC,
6331 .v.func = alc290_fixup_mono_speakers,
David Henningsson0f4881d2013-12-20 16:08:13 +01006332 },
6333 [ALC290_FIXUP_MONO_SPEAKERS_HSJACK] = {
6334 .type = HDA_FIXUP_FUNC,
6335 .v.func = alc290_fixup_mono_speakers,
David Henningsson338cae52013-10-07 10:39:59 +02006336 .chained = true,
6337 .chain_id = ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
6338 },
David Henningssonb67ae3f2013-11-05 13:11:37 +01006339 [ALC269_FIXUP_THINKPAD_ACPI] = {
6340 .type = HDA_FIXUP_FUNC,
Takashi Iwaid5a6cab2018-06-13 12:43:10 +02006341 .v.func = alc_fixup_thinkpad_acpi,
Takashi Iwai09da1112016-09-08 12:15:02 +02006342 .chained = true,
6343 .chain_id = ALC269_FIXUP_SKU_IGNORE,
David Henningssonb67ae3f2013-11-05 13:11:37 +01006344 },
David Henningsson56f27012016-01-11 09:33:14 +01006345 [ALC269_FIXUP_DMIC_THINKPAD_ACPI] = {
6346 .type = HDA_FIXUP_FUNC,
6347 .v.func = alc_fixup_inv_dmic,
6348 .chained = true,
6349 .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
6350 },
Chris Chiu5824ce82017-02-28 14:17:11 -06006351 [ALC255_FIXUP_ACER_MIC_NO_PRESENCE] = {
Hui Wang17d30462019-06-14 16:44:12 +08006352 .type = HDA_FIXUP_PINS,
6353 .v.pins = (const struct hda_pintbl[]) {
6354 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6355 { }
Chris Chiu5824ce82017-02-28 14:17:11 -06006356 },
6357 .chained = true,
Hui Wang17d30462019-06-14 16:44:12 +08006358 .chain_id = ALC255_FIXUP_HEADSET_MODE
Chris Chiu5824ce82017-02-28 14:17:11 -06006359 },
Chris Chiu615966a2017-02-28 14:17:12 -06006360 [ALC255_FIXUP_ASUS_MIC_NO_PRESENCE] = {
6361 .type = HDA_FIXUP_PINS,
6362 .v.pins = (const struct hda_pintbl[]) {
6363 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6364 { }
6365 },
6366 .chained = true,
6367 .chain_id = ALC255_FIXUP_HEADSET_MODE
6368 },
Kailang Yang9a22a8f52013-11-08 15:54:49 +08006369 [ALC255_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6370 .type = HDA_FIXUP_PINS,
6371 .v.pins = (const struct hda_pintbl[]) {
6372 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6373 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6374 { }
6375 },
6376 .chained = true,
6377 .chain_id = ALC255_FIXUP_HEADSET_MODE
6378 },
Kailang Yang31278992014-03-03 15:27:22 +08006379 [ALC255_FIXUP_DELL2_MIC_NO_PRESENCE] = {
6380 .type = HDA_FIXUP_PINS,
6381 .v.pins = (const struct hda_pintbl[]) {
6382 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6383 { }
6384 },
6385 .chained = true,
6386 .chain_id = ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC
6387 },
Kailang Yang9a22a8f52013-11-08 15:54:49 +08006388 [ALC255_FIXUP_HEADSET_MODE] = {
6389 .type = HDA_FIXUP_FUNC,
6390 .v.func = alc_fixup_headset_mode_alc255,
Hui Wang4a83d422014-11-18 17:57:40 +08006391 .chained = true,
Takashi Iwaib3802782018-11-26 17:47:46 +01006392 .chain_id = ALC255_FIXUP_MIC_MUTE_LED
Kailang Yang9a22a8f52013-11-08 15:54:49 +08006393 },
Kailang Yang31278992014-03-03 15:27:22 +08006394 [ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC] = {
6395 .type = HDA_FIXUP_FUNC,
6396 .v.func = alc_fixup_headset_mode_alc255_no_hp_mic,
6397 },
Kailang Yanga22aa262014-04-23 17:34:28 +08006398 [ALC293_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6399 .type = HDA_FIXUP_PINS,
6400 .v.pins = (const struct hda_pintbl[]) {
6401 { 0x18, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6402 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6403 { }
6404 },
6405 .chained = true,
6406 .chain_id = ALC269_FIXUP_HEADSET_MODE
6407 },
Takashi Iwai1c37c222014-05-06 17:34:42 +02006408 [ALC292_FIXUP_TPT440_DOCK] = {
David Henningssonec56af62015-06-24 10:46:33 +02006409 .type = HDA_FIXUP_FUNC,
Takashi Iwai7f57d802015-09-24 17:36:51 +02006410 .v.func = alc_fixup_tpt440_dock,
Takashi Iwai1c37c222014-05-06 17:34:42 +02006411 .chained = true,
6412 .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST
6413 },
Takashi Iwai9a811232015-12-09 15:17:43 +01006414 [ALC292_FIXUP_TPT440] = {
6415 .type = HDA_FIXUP_FUNC,
Takashi Iwai157f0b72015-12-10 23:30:43 +01006416 .v.func = alc_fixup_disable_aamix,
Takashi Iwai9a811232015-12-09 15:17:43 +01006417 .chained = true,
6418 .chain_id = ALC292_FIXUP_TPT440_DOCK,
6419 },
Anisse Astierabaa22742016-08-24 09:14:13 +02006420 [ALC283_FIXUP_HEADSET_MIC] = {
Daniel Drake9dc12862014-07-22 10:58:29 +01006421 .type = HDA_FIXUP_PINS,
6422 .v.pins = (const struct hda_pintbl[]) {
6423 { 0x19, 0x04a110f0 },
6424 { },
6425 },
6426 },
Takashi Iwaib3802782018-11-26 17:47:46 +01006427 [ALC255_FIXUP_MIC_MUTE_LED] = {
Hui Wang00ef9942014-07-31 11:52:38 +08006428 .type = HDA_FIXUP_FUNC,
Takashi Iwaib3802782018-11-26 17:47:46 +01006429 .v.func = snd_hda_gen_fixup_micmute_led,
Hui Wang00ef9942014-07-31 11:52:38 +08006430 },
Takashi Iwai1a22e772014-08-27 08:19:05 +02006431 [ALC282_FIXUP_ASPIRE_V5_PINS] = {
6432 .type = HDA_FIXUP_PINS,
6433 .v.pins = (const struct hda_pintbl[]) {
6434 { 0x12, 0x90a60130 },
6435 { 0x14, 0x90170110 },
6436 { 0x17, 0x40000008 },
6437 { 0x18, 0x411111f0 },
Mateusz Sylwestrzak04206942015-07-19 17:38:56 +02006438 { 0x19, 0x01a1913c },
Takashi Iwai1a22e772014-08-27 08:19:05 +02006439 { 0x1a, 0x411111f0 },
6440 { 0x1b, 0x411111f0 },
6441 { 0x1d, 0x40f89b2d },
6442 { 0x1e, 0x411111f0 },
6443 { 0x21, 0x0321101f },
6444 { },
6445 },
6446 },
David Henningsson7a5255f2014-10-30 08:26:01 +01006447 [ALC280_FIXUP_HP_GPIO4] = {
6448 .type = HDA_FIXUP_FUNC,
6449 .v.func = alc280_fixup_hp_gpio4,
6450 },
Kailang Yangeaa8e5e2014-11-21 15:49:11 +08006451 [ALC286_FIXUP_HP_GPIO_LED] = {
6452 .type = HDA_FIXUP_FUNC,
6453 .v.func = alc286_fixup_hp_gpio_led,
6454 },
David Henningsson33f4acd2015-01-07 15:50:13 +01006455 [ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY] = {
6456 .type = HDA_FIXUP_FUNC,
6457 .v.func = alc280_fixup_hp_gpio2_mic_hotkey,
6458 },
TienFu Chenb4b33f92015-01-20 15:06:21 +01006459 [ALC280_FIXUP_HP_DOCK_PINS] = {
6460 .type = HDA_FIXUP_PINS,
6461 .v.pins = (const struct hda_pintbl[]) {
6462 { 0x1b, 0x21011020 }, /* line-out */
6463 { 0x1a, 0x01a1903c }, /* headset mic */
6464 { 0x18, 0x2181103f }, /* line-in */
6465 { },
6466 },
6467 .chained = true,
6468 .chain_id = ALC280_FIXUP_HP_GPIO4
6469 },
Jaroslav Kysela04d54662017-03-09 13:29:13 +01006470 [ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED] = {
6471 .type = HDA_FIXUP_PINS,
6472 .v.pins = (const struct hda_pintbl[]) {
6473 { 0x1b, 0x21011020 }, /* line-out */
6474 { 0x18, 0x2181103f }, /* line-in */
6475 { },
6476 },
6477 .chained = true,
6478 .chain_id = ALC269_FIXUP_HP_GPIO_MIC1_LED
6479 },
Keith Packard98973f22015-07-15 12:14:39 -07006480 [ALC280_FIXUP_HP_9480M] = {
6481 .type = HDA_FIXUP_FUNC,
6482 .v.func = alc280_fixup_hp_9480m,
6483 },
Kailang Yange1e62b92015-04-08 16:01:22 +08006484 [ALC288_FIXUP_DELL_HEADSET_MODE] = {
6485 .type = HDA_FIXUP_FUNC,
6486 .v.func = alc_fixup_headset_mode_dell_alc288,
6487 .chained = true,
Takashi Iwaib3802782018-11-26 17:47:46 +01006488 .chain_id = ALC255_FIXUP_MIC_MUTE_LED
Kailang Yange1e62b92015-04-08 16:01:22 +08006489 },
6490 [ALC288_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6491 .type = HDA_FIXUP_PINS,
6492 .v.pins = (const struct hda_pintbl[]) {
6493 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6494 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6495 { }
6496 },
6497 .chained = true,
6498 .chain_id = ALC288_FIXUP_DELL_HEADSET_MODE
6499 },
Hui Wang831bfdf92015-06-26 12:35:17 +08006500 [ALC288_FIXUP_DISABLE_AAMIX] = {
6501 .type = HDA_FIXUP_FUNC,
6502 .v.func = alc_fixup_disable_aamix,
6503 .chained = true,
Takashi Iwaid44a6862018-06-19 23:04:03 +02006504 .chain_id = ALC288_FIXUP_DELL1_MIC_NO_PRESENCE
Hui Wang831bfdf92015-06-26 12:35:17 +08006505 },
6506 [ALC288_FIXUP_DELL_XPS_13] = {
6507 .type = HDA_FIXUP_FUNC,
6508 .v.func = alc_fixup_dell_xps13,
6509 .chained = true,
6510 .chain_id = ALC288_FIXUP_DISABLE_AAMIX
6511 },
Takashi Iwai8b99aba2015-06-15 11:59:32 +02006512 [ALC292_FIXUP_DISABLE_AAMIX] = {
6513 .type = HDA_FIXUP_FUNC,
6514 .v.func = alc_fixup_disable_aamix,
Hui Wang831bfdf92015-06-26 12:35:17 +08006515 .chained = true,
6516 .chain_id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE
Takashi Iwai8b99aba2015-06-15 11:59:32 +02006517 },
David Henningssonc04017e2015-12-15 14:44:03 +01006518 [ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK] = {
6519 .type = HDA_FIXUP_FUNC,
6520 .v.func = alc_fixup_disable_aamix,
6521 .chained = true,
6522 .chain_id = ALC293_FIXUP_DELL1_MIC_NO_PRESENCE
6523 },
Takashi Iwai8b99aba2015-06-15 11:59:32 +02006524 [ALC292_FIXUP_DELL_E7X] = {
6525 .type = HDA_FIXUP_FUNC,
6526 .v.func = alc_fixup_dell_xps13,
6527 .chained = true,
6528 .chain_id = ALC292_FIXUP_DISABLE_AAMIX
6529 },
James McDonnell54324222019-09-16 14:53:38 +00006530 [ALC298_FIXUP_ALIENWARE_MIC_NO_PRESENCE] = {
6531 .type = HDA_FIXUP_PINS,
6532 .v.pins = (const struct hda_pintbl[]) {
6533 { 0x18, 0x01a1913c }, /* headset mic w/o jack detect */
6534 { }
6535 },
6536 .chained_before = true,
6537 .chain_id = ALC269_FIXUP_HEADSET_MODE,
6538 },
Kailang Yang977e6272015-05-18 15:31:20 +08006539 [ALC298_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6540 .type = HDA_FIXUP_PINS,
6541 .v.pins = (const struct hda_pintbl[]) {
6542 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6543 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6544 { }
6545 },
6546 .chained = true,
6547 .chain_id = ALC269_FIXUP_HEADSET_MODE
6548 },
Hui Wang2f726ae2017-03-31 10:31:40 +08006549 [ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE] = {
6550 .type = HDA_FIXUP_PINS,
6551 .v.pins = (const struct hda_pintbl[]) {
6552 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6553 { }
6554 },
6555 .chained = true,
6556 .chain_id = ALC269_FIXUP_HEADSET_MODE
6557 },
Kailang Yang6ed11312015-10-26 15:37:39 +08006558 [ALC275_FIXUP_DELL_XPS] = {
6559 .type = HDA_FIXUP_VERBS,
6560 .v.verbs = (const struct hda_verb[]) {
6561 /* Enables internal speaker */
6562 {0x20, AC_VERB_SET_COEF_INDEX, 0x1f},
6563 {0x20, AC_VERB_SET_PROC_COEF, 0x00c0},
6564 {0x20, AC_VERB_SET_COEF_INDEX, 0x30},
6565 {0x20, AC_VERB_SET_PROC_COEF, 0x00b1},
6566 {}
6567 }
6568 },
Hui Wang8c697292015-11-24 11:08:18 +08006569 [ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE] = {
6570 .type = HDA_FIXUP_VERBS,
6571 .v.verbs = (const struct hda_verb[]) {
6572 /* Disable pass-through path for FRONT 14h */
6573 {0x20, AC_VERB_SET_COEF_INDEX, 0x36},
6574 {0x20, AC_VERB_SET_PROC_COEF, 0x1737},
6575 {}
6576 },
6577 .chained = true,
6578 .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
6579 },
Kai-Heng Feng1099f482019-10-03 12:39:19 +08006580 [ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE2] = {
6581 .type = HDA_FIXUP_FUNC,
6582 .v.func = alc256_fixup_dell_xps_13_headphone_noise2,
6583 .chained = true,
6584 .chain_id = ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE
6585 },
Hui Wang23adc192015-12-08 12:27:18 +08006586 [ALC293_FIXUP_LENOVO_SPK_NOISE] = {
6587 .type = HDA_FIXUP_FUNC,
6588 .v.func = alc_fixup_disable_aamix,
6589 .chained = true,
6590 .chain_id = ALC269_FIXUP_THINKPAD_ACPI
6591 },
Kailang3694cb22015-12-28 11:35:24 +08006592 [ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY] = {
6593 .type = HDA_FIXUP_FUNC,
6594 .v.func = alc233_fixup_lenovo_line2_mic_hotkey,
6595 },
Kai-Heng Feng3b43b712016-02-25 15:19:38 +08006596 [ALC255_FIXUP_DELL_SPK_NOISE] = {
6597 .type = HDA_FIXUP_FUNC,
6598 .v.func = alc_fixup_disable_aamix,
6599 .chained = true,
6600 .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
6601 },
Kailang Yangd1dd4212019-01-09 17:05:24 +08006602 [ALC225_FIXUP_DISABLE_MIC_VREF] = {
6603 .type = HDA_FIXUP_FUNC,
6604 .v.func = alc_fixup_disable_mic_vref,
6605 .chained = true,
6606 .chain_id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE
6607 },
David Henningsson2ae95572016-02-25 09:37:05 +01006608 [ALC225_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6609 .type = HDA_FIXUP_VERBS,
6610 .v.verbs = (const struct hda_verb[]) {
6611 /* Disable pass-through path for FRONT 14h */
6612 { 0x20, AC_VERB_SET_COEF_INDEX, 0x36 },
6613 { 0x20, AC_VERB_SET_PROC_COEF, 0x57d7 },
6614 {}
6615 },
6616 .chained = true,
Kailang Yangd1dd4212019-01-09 17:05:24 +08006617 .chain_id = ALC225_FIXUP_DISABLE_MIC_VREF
David Henningsson2ae95572016-02-25 09:37:05 +01006618 },
Takashi Iwaif8839822016-02-25 14:31:59 +01006619 [ALC280_FIXUP_HP_HEADSET_MIC] = {
6620 .type = HDA_FIXUP_FUNC,
6621 .v.func = alc_fixup_disable_aamix,
6622 .chained = true,
6623 .chain_id = ALC269_FIXUP_HEADSET_MIC,
6624 },
Hui Wange549d192016-04-01 11:00:15 +08006625 [ALC221_FIXUP_HP_FRONT_MIC] = {
6626 .type = HDA_FIXUP_PINS,
6627 .v.pins = (const struct hda_pintbl[]) {
6628 { 0x19, 0x02a19020 }, /* Front Mic */
6629 { }
6630 },
6631 },
Sven Eckelmannc636b952016-04-11 16:55:26 +02006632 [ALC292_FIXUP_TPT460] = {
6633 .type = HDA_FIXUP_FUNC,
6634 .v.func = alc_fixup_tpt440_dock,
6635 .chained = true,
6636 .chain_id = ALC293_FIXUP_LENOVO_SPK_NOISE,
6637 },
Hui Wangdd9aa332016-08-01 10:20:32 +08006638 [ALC298_FIXUP_SPK_VOLUME] = {
6639 .type = HDA_FIXUP_FUNC,
6640 .v.func = alc298_fixup_speaker_volume,
Hui Wang59ec4b52016-08-04 15:28:04 +08006641 .chained = true,
Hui Wang2f726ae2017-03-31 10:31:40 +08006642 .chain_id = ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE,
Hui Wangdd9aa332016-08-01 10:20:32 +08006643 },
Takashi Iwaie312a862018-03-06 12:14:17 +01006644 [ALC295_FIXUP_DISABLE_DAC3] = {
6645 .type = HDA_FIXUP_FUNC,
6646 .v.func = alc295_fixup_disable_dac3,
6647 },
Kai-Heng Fengfd06c772016-08-30 15:36:34 +08006648 [ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER] = {
6649 .type = HDA_FIXUP_PINS,
6650 .v.pins = (const struct hda_pintbl[]) {
6651 { 0x1b, 0x90170151 },
6652 { }
6653 },
6654 .chained = true,
6655 .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
6656 },
Gabriele Mazzotta823ff162016-12-24 19:50:01 +01006657 [ALC269_FIXUP_ATIV_BOOK_8] = {
6658 .type = HDA_FIXUP_FUNC,
6659 .v.func = alc_fixup_auto_mute_via_amp,
6660 .chained = true,
6661 .chain_id = ALC269_FIXUP_NO_SHUTUP
6662 },
Kailang Yang9eb5d0e2017-01-17 15:40:25 +08006663 [ALC221_FIXUP_HP_MIC_NO_PRESENCE] = {
6664 .type = HDA_FIXUP_PINS,
6665 .v.pins = (const struct hda_pintbl[]) {
6666 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6667 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6668 { }
6669 },
6670 .chained = true,
6671 .chain_id = ALC269_FIXUP_HEADSET_MODE
6672 },
Chris Chiuc1732ed2017-02-28 14:17:13 -06006673 [ALC256_FIXUP_ASUS_HEADSET_MODE] = {
6674 .type = HDA_FIXUP_FUNC,
6675 .v.func = alc_fixup_headset_mode,
6676 },
6677 [ALC256_FIXUP_ASUS_MIC] = {
6678 .type = HDA_FIXUP_PINS,
6679 .v.pins = (const struct hda_pintbl[]) {
6680 { 0x13, 0x90a60160 }, /* use as internal mic */
6681 { 0x19, 0x04a11120 }, /* use as headset mic, without its own jack detect */
6682 { }
6683 },
6684 .chained = true,
6685 .chain_id = ALC256_FIXUP_ASUS_HEADSET_MODE
6686 },
Chris Chiueeed4cd2017-02-28 14:17:15 -06006687 [ALC256_FIXUP_ASUS_AIO_GPIO2] = {
Takashi Iwaiae065f12018-06-19 23:00:03 +02006688 .type = HDA_FIXUP_FUNC,
6689 /* Set up GPIO2 for the speaker amp */
6690 .v.func = alc_fixup_gpio4,
Chris Chiueeed4cd2017-02-28 14:17:15 -06006691 },
Chris Chiu216d7ae2017-02-28 14:17:14 -06006692 [ALC233_FIXUP_ASUS_MIC_NO_PRESENCE] = {
6693 .type = HDA_FIXUP_PINS,
6694 .v.pins = (const struct hda_pintbl[]) {
6695 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6696 { }
6697 },
6698 .chained = true,
6699 .chain_id = ALC269_FIXUP_HEADSET_MIC
6700 },
6701 [ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE] = {
6702 .type = HDA_FIXUP_VERBS,
6703 .v.verbs = (const struct hda_verb[]) {
6704 /* Enables internal speaker */
6705 {0x20, AC_VERB_SET_COEF_INDEX, 0x40},
6706 {0x20, AC_VERB_SET_PROC_COEF, 0x8800},
6707 {}
6708 },
6709 .chained = true,
6710 .chain_id = ALC233_FIXUP_ASUS_MIC_NO_PRESENCE
6711 },
Kailang Yangca169cc2017-04-25 16:17:40 +08006712 [ALC233_FIXUP_LENOVO_MULTI_CODECS] = {
6713 .type = HDA_FIXUP_FUNC,
6714 .v.func = alc233_alc662_fixup_lenovo_dual_codecs,
6715 },
Jian-Hong Panea5c7eb2019-04-01 11:25:05 +08006716 [ALC233_FIXUP_ACER_HEADSET_MIC] = {
6717 .type = HDA_FIXUP_VERBS,
6718 .v.verbs = (const struct hda_verb[]) {
6719 { 0x20, AC_VERB_SET_COEF_INDEX, 0x45 },
6720 { 0x20, AC_VERB_SET_PROC_COEF, 0x5089 },
6721 { }
6722 },
6723 .chained = true,
6724 .chain_id = ALC233_FIXUP_ASUS_MIC_NO_PRESENCE
6725 },
Hui Wangf33f79f2017-07-07 12:08:29 +08006726 [ALC294_FIXUP_LENOVO_MIC_LOCATION] = {
6727 .type = HDA_FIXUP_PINS,
6728 .v.pins = (const struct hda_pintbl[]) {
6729 /* Change the mic location from front to right, otherwise there are
6730 two front mics with the same name, pulseaudio can't handle them.
6731 This is just a temporary workaround, after applying this fixup,
6732 there will be one "Front Mic" and one "Mic" in this machine.
6733 */
6734 { 0x1a, 0x04a19040 },
6735 { }
6736 },
6737 },
Kailang Yang5f364132017-07-25 16:28:16 +08006738 [ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE] = {
6739 .type = HDA_FIXUP_PINS,
6740 .v.pins = (const struct hda_pintbl[]) {
6741 { 0x16, 0x0101102f }, /* Rear Headset HP */
6742 { 0x19, 0x02a1913c }, /* use as Front headset mic, without its own jack detect */
6743 { 0x1a, 0x01a19030 }, /* Rear Headset MIC */
6744 { 0x1b, 0x02011020 },
6745 { }
6746 },
6747 .chained = true,
6748 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
6749 },
PeiSen Houb84e8432017-09-01 15:11:56 +08006750 [ALC700_FIXUP_INTEL_REFERENCE] = {
6751 .type = HDA_FIXUP_VERBS,
6752 .v.verbs = (const struct hda_verb[]) {
6753 /* Enables internal speaker */
6754 {0x20, AC_VERB_SET_COEF_INDEX, 0x45},
6755 {0x20, AC_VERB_SET_PROC_COEF, 0x5289},
6756 {0x20, AC_VERB_SET_COEF_INDEX, 0x4A},
6757 {0x20, AC_VERB_SET_PROC_COEF, 0x001b},
6758 {0x58, AC_VERB_SET_COEF_INDEX, 0x00},
6759 {0x58, AC_VERB_SET_PROC_COEF, 0x3888},
6760 {0x20, AC_VERB_SET_COEF_INDEX, 0x6f},
6761 {0x20, AC_VERB_SET_PROC_COEF, 0x2c0b},
6762 {}
6763 }
6764 },
Kailang Yang92266652017-12-14 15:28:58 +08006765 [ALC274_FIXUP_DELL_BIND_DACS] = {
6766 .type = HDA_FIXUP_FUNC,
6767 .v.func = alc274_fixup_bind_dacs,
6768 .chained = true,
6769 .chain_id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE
6770 },
6771 [ALC274_FIXUP_DELL_AIO_LINEOUT_VERB] = {
6772 .type = HDA_FIXUP_PINS,
6773 .v.pins = (const struct hda_pintbl[]) {
6774 { 0x1b, 0x0401102f },
6775 { }
6776 },
6777 .chained = true,
6778 .chain_id = ALC274_FIXUP_DELL_BIND_DACS
6779 },
Kailang Yang61fcf8e2018-02-02 15:26:46 +08006780 [ALC298_FIXUP_TPT470_DOCK] = {
6781 .type = HDA_FIXUP_FUNC,
6782 .v.func = alc_fixup_tpt470_dock,
6783 .chained = true,
6784 .chain_id = ALC293_FIXUP_LENOVO_SPK_NOISE
6785 },
Kailang Yangae104a22018-02-05 16:07:20 +08006786 [ALC255_FIXUP_DUMMY_LINEOUT_VERB] = {
6787 .type = HDA_FIXUP_PINS,
6788 .v.pins = (const struct hda_pintbl[]) {
6789 { 0x14, 0x0201101f },
6790 { }
6791 },
6792 .chained = true,
6793 .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
6794 },
Kailang Yangf0ba9d62018-03-16 11:46:08 +08006795 [ALC255_FIXUP_DELL_HEADSET_MIC] = {
6796 .type = HDA_FIXUP_PINS,
6797 .v.pins = (const struct hda_pintbl[]) {
6798 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6799 { }
6800 },
Hui Wang3ce0d5a2018-04-19 13:29:04 +08006801 .chained = true,
6802 .chain_id = ALC269_FIXUP_HEADSET_MIC
Kailang Yangf0ba9d62018-03-16 11:46:08 +08006803 },
Tom Bridenbbf8ff62018-05-29 17:34:20 +01006804 [ALC295_FIXUP_HP_X360] = {
6805 .type = HDA_FIXUP_FUNC,
6806 .v.func = alc295_fixup_hp_top_speakers,
6807 .chained = true,
6808 .chain_id = ALC269_FIXUP_HP_MUTE_LED_MIC3
Kailang Yang8a328ac2018-08-21 16:54:41 +08006809 },
6810 [ALC221_FIXUP_HP_HEADSET_MIC] = {
6811 .type = HDA_FIXUP_PINS,
6812 .v.pins = (const struct hda_pintbl[]) {
6813 { 0x19, 0x0181313f},
6814 { }
6815 },
6816 .chained = true,
6817 .chain_id = ALC269_FIXUP_HEADSET_MIC
6818 },
Hui Wangc4cfcf62018-11-26 14:17:16 +08006819 [ALC285_FIXUP_LENOVO_HEADPHONE_NOISE] = {
6820 .type = HDA_FIXUP_FUNC,
6821 .v.func = alc285_fixup_invalidate_dacs,
Hui Wang6ba189c2018-12-09 09:16:43 +08006822 .chained = true,
6823 .chain_id = ALC269_FIXUP_THINKPAD_ACPI
Hui Wangc4cfcf62018-11-26 14:17:16 +08006824 },
Girija Kumar Kasinadhunie8ed64b2018-11-26 13:40:46 -05006825 [ALC295_FIXUP_HP_AUTO_MUTE] = {
6826 .type = HDA_FIXUP_FUNC,
6827 .v.func = alc_fixup_auto_mute_via_amp,
6828 },
Chris Chiu33aaebd2018-12-05 14:48:53 +08006829 [ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE] = {
6830 .type = HDA_FIXUP_PINS,
6831 .v.pins = (const struct hda_pintbl[]) {
6832 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6833 { }
6834 },
6835 .chained = true,
6836 .chain_id = ALC269_FIXUP_HEADSET_MIC
6837 },
Chris Chiud8ae4582018-12-07 17:17:11 +08006838 [ALC294_FIXUP_ASUS_MIC] = {
6839 .type = HDA_FIXUP_PINS,
6840 .v.pins = (const struct hda_pintbl[]) {
6841 { 0x13, 0x90a60160 }, /* use as internal mic */
6842 { 0x19, 0x04a11120 }, /* use as headset mic, without its own jack detect */
6843 { }
6844 },
6845 .chained = true,
6846 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
6847 },
Jian-Hong Pan4e051102018-12-07 17:17:12 +08006848 [ALC294_FIXUP_ASUS_HEADSET_MIC] = {
6849 .type = HDA_FIXUP_PINS,
6850 .v.pins = (const struct hda_pintbl[]) {
Jian-Hong Pan82b01142018-12-27 16:46:31 +08006851 { 0x19, 0x01a1103c }, /* use as headset mic */
Jian-Hong Pan4e051102018-12-07 17:17:12 +08006852 { }
6853 },
6854 .chained = true,
6855 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
6856 },
6857 [ALC294_FIXUP_ASUS_SPK] = {
6858 .type = HDA_FIXUP_VERBS,
6859 .v.verbs = (const struct hda_verb[]) {
6860 /* Set EAPD high */
6861 { 0x20, AC_VERB_SET_COEF_INDEX, 0x40 },
6862 { 0x20, AC_VERB_SET_PROC_COEF, 0x8800 },
6863 { }
6864 },
6865 .chained = true,
6866 .chain_id = ALC294_FIXUP_ASUS_HEADSET_MIC
6867 },
Jaroslav Kyselac8a9afa2019-03-14 09:21:08 +01006868 [ALC295_FIXUP_CHROME_BOOK] = {
Kailang Yange8547472018-11-28 15:32:45 +08006869 .type = HDA_FIXUP_FUNC,
Jaroslav Kyselac8a9afa2019-03-14 09:21:08 +01006870 .v.func = alc295_fixup_chromebook,
Kailang Yang8983eb62019-04-03 15:31:49 +08006871 .chained = true,
6872 .chain_id = ALC225_FIXUP_HEADSET_JACK
6873 },
6874 [ALC225_FIXUP_HEADSET_JACK] = {
6875 .type = HDA_FIXUP_FUNC,
6876 .v.func = alc_fixup_headset_jack,
Kailang Yange8547472018-11-28 15:32:45 +08006877 },
Jeremy Soller89e3a562019-01-30 16:12:31 -07006878 [ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE] = {
6879 .type = HDA_FIXUP_PINS,
6880 .v.pins = (const struct hda_pintbl[]) {
6881 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6882 { }
6883 },
6884 .chained = true,
6885 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
6886 },
Hui Wangc8c6ee62019-02-14 11:41:33 +08006887 [ALC285_FIXUP_LENOVO_PC_BEEP_IN_NOISE] = {
6888 .type = HDA_FIXUP_VERBS,
6889 .v.verbs = (const struct hda_verb[]) {
6890 /* Disable PCBEEP-IN passthrough */
6891 { 0x20, AC_VERB_SET_COEF_INDEX, 0x36 },
6892 { 0x20, AC_VERB_SET_PROC_COEF, 0x57d7 },
6893 { }
6894 },
6895 .chained = true,
6896 .chain_id = ALC285_FIXUP_LENOVO_HEADPHONE_NOISE
6897 },
Jian-Hong Pancbc05fd2019-03-13 17:33:24 +08006898 [ALC255_FIXUP_ACER_HEADSET_MIC] = {
6899 .type = HDA_FIXUP_PINS,
6900 .v.pins = (const struct hda_pintbl[]) {
6901 { 0x19, 0x03a11130 },
6902 { 0x1a, 0x90a60140 }, /* use as internal mic */
6903 { }
6904 },
6905 .chained = true,
6906 .chain_id = ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC
6907 },
Kailang Yang136824e2019-03-14 16:22:45 +08006908 [ALC225_FIXUP_DELL_WYSE_AIO_MIC_NO_PRESENCE] = {
6909 .type = HDA_FIXUP_PINS,
6910 .v.pins = (const struct hda_pintbl[]) {
6911 { 0x16, 0x01011020 }, /* Rear Line out */
6912 { 0x19, 0x01a1913c }, /* use as Front headset mic, without its own jack detect */
6913 { }
6914 },
6915 .chained = true,
6916 .chain_id = ALC225_FIXUP_WYSE_AUTO_MUTE
6917 },
6918 [ALC225_FIXUP_WYSE_AUTO_MUTE] = {
6919 .type = HDA_FIXUP_FUNC,
6920 .v.func = alc_fixup_auto_mute_via_amp,
6921 .chained = true,
6922 .chain_id = ALC225_FIXUP_WYSE_DISABLE_MIC_VREF
6923 },
6924 [ALC225_FIXUP_WYSE_DISABLE_MIC_VREF] = {
6925 .type = HDA_FIXUP_FUNC,
6926 .v.func = alc_fixup_disable_mic_vref,
6927 .chained = true,
6928 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
6929 },
Jian-Hong Pan667a8f72019-03-15 17:51:09 +08006930 [ALC286_FIXUP_ACER_AIO_HEADSET_MIC] = {
6931 .type = HDA_FIXUP_VERBS,
6932 .v.verbs = (const struct hda_verb[]) {
6933 { 0x20, AC_VERB_SET_COEF_INDEX, 0x4f },
6934 { 0x20, AC_VERB_SET_PROC_COEF, 0x5029 },
6935 { }
6936 },
6937 .chained = true,
6938 .chain_id = ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE
6939 },
Daniel Drake8c8967a2019-10-17 16:15:01 +08006940 [ALC256_FIXUP_ASUS_HEADSET_MIC] = {
6941 .type = HDA_FIXUP_PINS,
6942 .v.pins = (const struct hda_pintbl[]) {
6943 { 0x19, 0x03a11020 }, /* headset mic with jack detect */
6944 { }
6945 },
6946 .chained = true,
6947 .chain_id = ALC256_FIXUP_ASUS_HEADSET_MODE
6948 },
Jian-Hong Pane1037352019-03-22 11:37:18 +08006949 [ALC256_FIXUP_ASUS_MIC_NO_PRESENCE] = {
6950 .type = HDA_FIXUP_PINS,
6951 .v.pins = (const struct hda_pintbl[]) {
6952 { 0x19, 0x04a11120 }, /* use as headset mic, without its own jack detect */
6953 { }
6954 },
6955 .chained = true,
6956 .chain_id = ALC256_FIXUP_ASUS_HEADSET_MODE
6957 },
Bernhard Rosenkraenzere2a829b2019-03-05 00:38:19 +01006958 [ALC299_FIXUP_PREDATOR_SPK] = {
6959 .type = HDA_FIXUP_PINS,
6960 .v.pins = (const struct hda_pintbl[]) {
6961 { 0x21, 0x90170150 }, /* use as headset mic, without its own jack detect */
6962 { }
6963 }
6964 },
Jian-Hong Pan60083f92019-09-02 18:00:56 +08006965 [ALC294_FIXUP_ASUS_INTSPK_HEADSET_MIC] = {
6966 .type = HDA_FIXUP_PINS,
6967 .v.pins = (const struct hda_pintbl[]) {
6968 { 0x14, 0x411111f0 }, /* disable confusing internal speaker */
6969 { 0x19, 0x04a11150 }, /* use as headset mic, without its own jack detect */
6970 { }
6971 },
6972 .chained = true,
6973 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
6974 },
Jan-Marek Glogowskibd9c10b2019-09-15 16:57:28 +02006975 [ALC256_FIXUP_MEDION_HEADSET_NO_PRESENCE] = {
6976 .type = HDA_FIXUP_PINS,
6977 .v.pins = (const struct hda_pintbl[]) {
6978 { 0x19, 0x04a11040 },
6979 { 0x21, 0x04211020 },
6980 { }
6981 },
6982 .chained = true,
6983 .chain_id = ALC256_FIXUP_ASUS_HEADSET_MODE
6984 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02006985};
6986
6987static const struct snd_pci_quirk alc269_fixup_tbl[] = {
Marius Knausta6b92b62014-03-03 01:48:58 +01006988 SND_PCI_QUIRK(0x1025, 0x0283, "Acer TravelMate 8371", ALC269_FIXUP_INV_DMIC),
David Henningsson693b6132012-06-22 19:12:10 +02006989 SND_PCI_QUIRK(0x1025, 0x029b, "Acer 1810TZ", ALC269_FIXUP_INV_DMIC),
6990 SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC),
David Henningssonaaedfb42013-08-16 14:09:02 +02006991 SND_PCI_QUIRK(0x1025, 0x047c, "Acer AC700", ALC269_FIXUP_ACER_AC700),
Takashi Iwai78197172015-06-27 10:21:13 +02006992 SND_PCI_QUIRK(0x1025, 0x072d, "Acer Aspire V5-571G", ALC269_FIXUP_ASPIRE_HEADSET_MIC),
6993 SND_PCI_QUIRK(0x1025, 0x080d, "Acer Aspire V5-122P", ALC269_FIXUP_ASPIRE_HEADSET_MIC),
David Henningssonaaedfb42013-08-16 14:09:02 +02006994 SND_PCI_QUIRK(0x1025, 0x0740, "Acer AO725", ALC271_FIXUP_HP_GATE_MIC_JACK),
6995 SND_PCI_QUIRK(0x1025, 0x0742, "Acer AO756", ALC271_FIXUP_HP_GATE_MIC_JACK),
Simon South02322ac2016-03-02 23:10:44 -05006996 SND_PCI_QUIRK(0x1025, 0x0762, "Acer Aspire E1-472", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572),
Oleksij Rempelb1e89722013-12-04 20:50:53 +01006997 SND_PCI_QUIRK(0x1025, 0x0775, "Acer Aspire E1-572", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572),
Takashi Iwai1a22e772014-08-27 08:19:05 +02006998 SND_PCI_QUIRK(0x1025, 0x079b, "Acer Aspire V5-573G", ALC282_FIXUP_ASPIRE_V5_PINS),
Chris Chiu705b65f2018-12-05 14:48:54 +08006999 SND_PCI_QUIRK(0x1025, 0x102b, "Acer Aspire C24-860", ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE),
Takashi Iwaib9c2fa52015-11-19 16:39:50 +01007000 SND_PCI_QUIRK(0x1025, 0x106d, "Acer Cloudbook 14", ALC283_FIXUP_CHROME_BOOK),
Chris Chiuc7531e32019-03-21 17:17:31 +08007001 SND_PCI_QUIRK(0x1025, 0x1099, "Acer Aspire E5-523G", ALC255_FIXUP_ACER_MIC_NO_PRESENCE),
7002 SND_PCI_QUIRK(0x1025, 0x110e, "Acer Aspire ES1-432", ALC255_FIXUP_ACER_MIC_NO_PRESENCE),
Bernhard Rosenkraenzere2a829b2019-03-05 00:38:19 +01007003 SND_PCI_QUIRK(0x1025, 0x1246, "Acer Predator Helios 500", ALC299_FIXUP_PREDATOR_SPK),
Jian-Hong Pan667a8f72019-03-15 17:51:09 +08007004 SND_PCI_QUIRK(0x1025, 0x128f, "Acer Veriton Z6860G", ALC286_FIXUP_ACER_AIO_HEADSET_MIC),
7005 SND_PCI_QUIRK(0x1025, 0x1290, "Acer Veriton Z4860G", ALC286_FIXUP_ACER_AIO_HEADSET_MIC),
7006 SND_PCI_QUIRK(0x1025, 0x1291, "Acer Veriton Z4660G", ALC286_FIXUP_ACER_AIO_HEADSET_MIC),
Jian-Hong Pan2733cce2019-03-21 16:39:04 +08007007 SND_PCI_QUIRK(0x1025, 0x1308, "Acer Aspire Z24-890", ALC286_FIXUP_ACER_AIO_HEADSET_MIC),
Jian-Hong Panea5c7eb2019-04-01 11:25:05 +08007008 SND_PCI_QUIRK(0x1025, 0x132a, "Acer TravelMate B114-21", ALC233_FIXUP_ACER_HEADSET_MIC),
Jian-Hong Pancbc05fd2019-03-13 17:33:24 +08007009 SND_PCI_QUIRK(0x1025, 0x1330, "Acer TravelMate X514-51T", ALC255_FIXUP_ACER_HEADSET_MIC),
David Henningssonaaedfb42013-08-16 14:09:02 +02007010 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
Kailang Yang6ed11312015-10-26 15:37:39 +08007011 SND_PCI_QUIRK(0x1028, 0x054b, "Dell XPS one 2710", ALC275_FIXUP_DELL_XPS),
Takashi Iwai86f799b2015-11-14 17:46:31 +01007012 SND_PCI_QUIRK(0x1028, 0x05bd, "Dell Latitude E6440", ALC292_FIXUP_DELL_E7X),
Takashi Iwaicf521032016-01-15 12:59:25 +01007013 SND_PCI_QUIRK(0x1028, 0x05be, "Dell Latitude E6540", ALC292_FIXUP_DELL_E7X),
Takashi Iwai8b99aba2015-06-15 11:59:32 +02007014 SND_PCI_QUIRK(0x1028, 0x05ca, "Dell Latitude E7240", ALC292_FIXUP_DELL_E7X),
7015 SND_PCI_QUIRK(0x1028, 0x05cb, "Dell Latitude E7440", ALC292_FIXUP_DELL_E7X),
David Henningsson0f4881d2013-12-20 16:08:13 +01007016 SND_PCI_QUIRK(0x1028, 0x05da, "Dell Vostro 5460", ALC290_FIXUP_SUBWOOFER),
David Henningsson73bdd592013-04-15 15:44:14 +02007017 SND_PCI_QUIRK(0x1028, 0x05f4, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
7018 SND_PCI_QUIRK(0x1028, 0x05f5, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
7019 SND_PCI_QUIRK(0x1028, 0x05f6, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
David Henningsson0f4881d2013-12-20 16:08:13 +01007020 SND_PCI_QUIRK(0x1028, 0x0615, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK),
7021 SND_PCI_QUIRK(0x1028, 0x0616, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK),
Takashi Iwai98070572016-01-12 21:06:39 +01007022 SND_PCI_QUIRK(0x1028, 0x062c, "Dell Latitude E5550", ALC292_FIXUP_DELL_E7X),
Takashi Iwai42755542015-06-29 10:56:53 +02007023 SND_PCI_QUIRK(0x1028, 0x062e, "Dell Latitude E7450", ALC292_FIXUP_DELL_E7X),
David Henningsson0f4881d2013-12-20 16:08:13 +01007024 SND_PCI_QUIRK(0x1028, 0x0638, "Dell Inspiron 5439", ALC290_FIXUP_MONO_SPEAKERS_HSJACK),
Kailang Yanga22aa262014-04-23 17:34:28 +08007025 SND_PCI_QUIRK(0x1028, 0x064a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
7026 SND_PCI_QUIRK(0x1028, 0x064b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
Hui Wang831bfdf92015-06-26 12:35:17 +08007027 SND_PCI_QUIRK(0x1028, 0x0665, "Dell XPS 13", ALC288_FIXUP_DELL_XPS_13),
Bastien Noceraafecb142016-04-18 11:10:42 +02007028 SND_PCI_QUIRK(0x1028, 0x0669, "Dell Optiplex 9020m", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
Takashi Iwai3a05d122015-07-29 09:04:52 +02007029 SND_PCI_QUIRK(0x1028, 0x069a, "Dell Vostro 5480", ALC290_FIXUP_SUBWOOFER_HSJACK),
Kailang Yang8b724152014-12-17 17:08:59 +08007030 SND_PCI_QUIRK(0x1028, 0x06c7, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
Kailang Yangb7343042014-12-02 14:50:45 +08007031 SND_PCI_QUIRK(0x1028, 0x06d9, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
7032 SND_PCI_QUIRK(0x1028, 0x06da, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
David Henningssonc04017e2015-12-15 14:44:03 +01007033 SND_PCI_QUIRK(0x1028, 0x06db, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
7034 SND_PCI_QUIRK(0x1028, 0x06dd, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
7035 SND_PCI_QUIRK(0x1028, 0x06de, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
7036 SND_PCI_QUIRK(0x1028, 0x06df, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
7037 SND_PCI_QUIRK(0x1028, 0x06e0, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
Kai-Heng Feng1099f482019-10-03 12:39:19 +08007038 SND_PCI_QUIRK(0x1028, 0x0704, "Dell XPS 13 9350", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE2),
Kai-Heng Fengfd06c772016-08-30 15:36:34 +08007039 SND_PCI_QUIRK(0x1028, 0x0706, "Dell Inspiron 7559", ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER),
Kai-Heng Feng3b43b712016-02-25 15:19:38 +08007040 SND_PCI_QUIRK(0x1028, 0x0725, "Dell Inspiron 3162", ALC255_FIXUP_DELL_SPK_NOISE),
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01007041 SND_PCI_QUIRK(0x1028, 0x0738, "Dell Precision 5820", ALC269_FIXUP_NO_SHUTUP),
Kai-Heng Feng1099f482019-10-03 12:39:19 +08007042 SND_PCI_QUIRK(0x1028, 0x075b, "Dell XPS 13 9360", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE2),
Kai-Heng Feng709ae622018-10-04 11:39:42 +08007043 SND_PCI_QUIRK(0x1028, 0x075c, "Dell XPS 27 7760", ALC298_FIXUP_SPK_VOLUME),
Hui Wangdd9aa332016-08-01 10:20:32 +08007044 SND_PCI_QUIRK(0x1028, 0x075d, "Dell AIO", ALC298_FIXUP_SPK_VOLUME),
Takashi Iwaie312a862018-03-06 12:14:17 +01007045 SND_PCI_QUIRK(0x1028, 0x07b0, "Dell Precision 7520", ALC295_FIXUP_DISABLE_DAC3),
Takashi Iwai493de342017-02-28 17:27:57 +01007046 SND_PCI_QUIRK(0x1028, 0x0798, "Dell Inspiron 17 7000 Gaming", ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER),
Kailang Yang5f364132017-07-25 16:28:16 +08007047 SND_PCI_QUIRK(0x1028, 0x080c, "Dell WYSE", ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE),
Kai-Heng Feng1099f482019-10-03 12:39:19 +08007048 SND_PCI_QUIRK(0x1028, 0x082a, "Dell XPS 13 9360", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE2),
Kailang Yang40e2c4e2018-02-02 15:13:09 +08007049 SND_PCI_QUIRK(0x1028, 0x084b, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB),
7050 SND_PCI_QUIRK(0x1028, 0x084e, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB),
Kailang Yangf0ba9d62018-03-16 11:46:08 +08007051 SND_PCI_QUIRK(0x1028, 0x0871, "Dell Precision 3630", ALC255_FIXUP_DELL_HEADSET_MIC),
7052 SND_PCI_QUIRK(0x1028, 0x0872, "Dell Precision 3630", ALC255_FIXUP_DELL_HEADSET_MIC),
Kailang Yangae104a22018-02-05 16:07:20 +08007053 SND_PCI_QUIRK(0x1028, 0x0873, "Dell Precision 3930", ALC255_FIXUP_DUMMY_LINEOUT_VERB),
Kailang Yang136824e2019-03-14 16:22:45 +08007054 SND_PCI_QUIRK(0x1028, 0x08ad, "Dell WYSE AIO", ALC225_FIXUP_DELL_WYSE_AIO_MIC_NO_PRESENCE),
Kailang Yangda484d02019-03-14 15:50:59 +08007055 SND_PCI_QUIRK(0x1028, 0x08ae, "Dell WYSE NB", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE),
Kailang Yangc2a7c55a2019-01-03 15:53:39 +08007056 SND_PCI_QUIRK(0x1028, 0x0935, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB),
Kailang Yanga22aa262014-04-23 17:34:28 +08007057 SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
7058 SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
Takashi Iwai08fb0d02013-01-10 17:33:58 +01007059 SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01007060 SND_PCI_QUIRK(0x103c, 0x18e6, "HP", ALC269_FIXUP_HP_GPIO_LED),
David Henningsson8e35cd42013-11-06 11:20:01 +01007061 SND_PCI_QUIRK(0x103c, 0x218b, "HP", ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED),
David Henningsson33f4acd2015-01-07 15:50:13 +01007062 SND_PCI_QUIRK(0x103c, 0x225f, "HP", ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY),
Kailang Yangc60666b2014-02-21 16:23:35 +08007063 /* ALC282 */
Hui Wang7976eb42015-02-13 11:14:41 +08007064 SND_PCI_QUIRK(0x103c, 0x21f9, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang8a02b162014-06-13 17:16:31 +08007065 SND_PCI_QUIRK(0x103c, 0x2210, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang8a02b162014-06-13 17:16:31 +08007066 SND_PCI_QUIRK(0x103c, 0x2214, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007067 SND_PCI_QUIRK(0x103c, 0x2236, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
7068 SND_PCI_QUIRK(0x103c, 0x2237, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
7069 SND_PCI_QUIRK(0x103c, 0x2238, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
7070 SND_PCI_QUIRK(0x103c, 0x2239, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007071 SND_PCI_QUIRK(0x103c, 0x224b, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
Kailang Yangc60666b2014-02-21 16:23:35 +08007072 SND_PCI_QUIRK(0x103c, 0x2268, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08007073 SND_PCI_QUIRK(0x103c, 0x226a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7074 SND_PCI_QUIRK(0x103c, 0x226b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang8a02b162014-06-13 17:16:31 +08007075 SND_PCI_QUIRK(0x103c, 0x226e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangeaa8e5e2014-11-21 15:49:11 +08007076 SND_PCI_QUIRK(0x103c, 0x2271, "HP", ALC286_FIXUP_HP_GPIO_LED),
TienFu Chenb4b33f92015-01-20 15:06:21 +01007077 SND_PCI_QUIRK(0x103c, 0x2272, "HP", ALC280_FIXUP_HP_DOCK_PINS),
TienFu Chen3271cb22015-02-10 09:09:41 +01007078 SND_PCI_QUIRK(0x103c, 0x2273, "HP", ALC280_FIXUP_HP_DOCK_PINS),
Kailang Yangc60666b2014-02-21 16:23:35 +08007079 SND_PCI_QUIRK(0x103c, 0x229e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08007080 SND_PCI_QUIRK(0x103c, 0x22b2, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7081 SND_PCI_QUIRK(0x103c, 0x22b7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7082 SND_PCI_QUIRK(0x103c, 0x22bf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08007083 SND_PCI_QUIRK(0x103c, 0x22cf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Keith Packard98973f22015-07-15 12:14:39 -07007084 SND_PCI_QUIRK(0x103c, 0x22db, "HP", ALC280_FIXUP_HP_9480M),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007085 SND_PCI_QUIRK(0x103c, 0x22dc, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
7086 SND_PCI_QUIRK(0x103c, 0x22fb, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yangc60666b2014-02-21 16:23:35 +08007087 /* ALC290 */
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007088 SND_PCI_QUIRK(0x103c, 0x221b, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007089 SND_PCI_QUIRK(0x103c, 0x2221, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007090 SND_PCI_QUIRK(0x103c, 0x2225, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007091 SND_PCI_QUIRK(0x103c, 0x2253, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
7092 SND_PCI_QUIRK(0x103c, 0x2254, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
7093 SND_PCI_QUIRK(0x103c, 0x2255, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
7094 SND_PCI_QUIRK(0x103c, 0x2256, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
7095 SND_PCI_QUIRK(0x103c, 0x2257, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007096 SND_PCI_QUIRK(0x103c, 0x2259, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Jaroslav Kysela04d54662017-03-09 13:29:13 +01007097 SND_PCI_QUIRK(0x103c, 0x225a, "HP", ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED),
Kailang Yangc60666b2014-02-21 16:23:35 +08007098 SND_PCI_QUIRK(0x103c, 0x2260, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08007099 SND_PCI_QUIRK(0x103c, 0x2263, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7100 SND_PCI_QUIRK(0x103c, 0x2264, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7101 SND_PCI_QUIRK(0x103c, 0x2265, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007102 SND_PCI_QUIRK(0x103c, 0x2272, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
7103 SND_PCI_QUIRK(0x103c, 0x2273, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007104 SND_PCI_QUIRK(0x103c, 0x2278, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yangc60666b2014-02-21 16:23:35 +08007105 SND_PCI_QUIRK(0x103c, 0x227f, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08007106 SND_PCI_QUIRK(0x103c, 0x2282, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08007107 SND_PCI_QUIRK(0x103c, 0x228b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08007108 SND_PCI_QUIRK(0x103c, 0x228e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7109 SND_PCI_QUIRK(0x103c, 0x22c5, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08007110 SND_PCI_QUIRK(0x103c, 0x22c7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7111 SND_PCI_QUIRK(0x103c, 0x22c8, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08007112 SND_PCI_QUIRK(0x103c, 0x22c4, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang8a02b162014-06-13 17:16:31 +08007113 SND_PCI_QUIRK(0x103c, 0x2334, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7114 SND_PCI_QUIRK(0x103c, 0x2335, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7115 SND_PCI_QUIRK(0x103c, 0x2336, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7116 SND_PCI_QUIRK(0x103c, 0x2337, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Takashi Iwaif8839822016-02-25 14:31:59 +01007117 SND_PCI_QUIRK(0x103c, 0x221c, "HP EliteBook 755 G2", ALC280_FIXUP_HP_HEADSET_MIC),
Jaroslav Kysela167897f2019-03-13 13:40:15 +01007118 SND_PCI_QUIRK(0x103c, 0x802e, "HP Z240 SFF", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
7119 SND_PCI_QUIRK(0x103c, 0x802f, "HP Z240", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
Takashi Iwai563785e2018-11-12 09:43:12 +01007120 SND_PCI_QUIRK(0x103c, 0x820d, "HP Pavilion 15", ALC269_FIXUP_HP_MUTE_LED_MIC3),
Hui Wange549d192016-04-01 11:00:15 +08007121 SND_PCI_QUIRK(0x103c, 0x8256, "HP", ALC221_FIXUP_HP_FRONT_MIC),
Tom Bridenbbf8ff62018-05-29 17:34:20 +01007122 SND_PCI_QUIRK(0x103c, 0x827e, "HP x360", ALC295_FIXUP_HP_X360),
Jaroslav Kysela167897f2019-03-13 13:40:15 +01007123 SND_PCI_QUIRK(0x103c, 0x82bf, "HP G3 mini", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
7124 SND_PCI_QUIRK(0x103c, 0x82c0, "HP G3 mini premium", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
Alexandru Gagniuc56e40eb2018-08-04 11:44:44 -05007125 SND_PCI_QUIRK(0x103c, 0x83b9, "HP Spectre x360", ALC269_FIXUP_HP_MUTE_LED_MIC3),
Takashi Iwai190d0382019-08-13 17:39:56 +02007126 SND_PCI_QUIRK(0x103c, 0x8497, "HP Envy x360", ALC269_FIXUP_HP_MUTE_LED_MIC3),
Sam Bazleyd33cd422019-09-01 03:31:30 +01007127 SND_PCI_QUIRK(0x103c, 0x84e7, "HP Pavilion 15", ALC269_FIXUP_HP_MUTE_LED_MIC3),
Chris Chiuc1732ed2017-02-28 14:17:13 -06007128 SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC),
Takashi Iwai7bba2152013-09-06 15:45:38 +02007129 SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300),
David Henningsson3e0d6112013-04-22 14:30:14 +02007130 SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Wandrille RONCE9cf65332018-12-19 14:52:44 +01007131 SND_PCI_QUIRK(0x1043, 0x10a1, "ASUS UX391UA", ALC294_FIXUP_ASUS_SPK),
Chris Chiuc1732ed2017-02-28 14:17:13 -06007132 SND_PCI_QUIRK(0x1043, 0x10c0, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC),
Takashi Iwai4eab0ea2017-06-06 12:33:17 +02007133 SND_PCI_QUIRK(0x1043, 0x10d0, "ASUS X540LA/X540LJ", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
David Henningsson3e0d6112013-04-22 14:30:14 +02007134 SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Takashi Iwai4eab0ea2017-06-06 12:33:17 +02007135 SND_PCI_QUIRK(0x1043, 0x11c0, "ASUS X556UR", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
7136 SND_PCI_QUIRK(0x1043, 0x1290, "ASUS X441SA", ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE),
7137 SND_PCI_QUIRK(0x1043, 0x12a0, "ASUS X441UV", ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE),
Chris Chiuc1732ed2017-02-28 14:17:13 -06007138 SND_PCI_QUIRK(0x1043, 0x12f0, "ASUS X541UV", ALC256_FIXUP_ASUS_MIC),
7139 SND_PCI_QUIRK(0x1043, 0x12e0, "ASUS X541SA", ALC256_FIXUP_ASUS_MIC),
7140 SND_PCI_QUIRK(0x1043, 0x13b0, "ASUS Z550SA", ALC256_FIXUP_ASUS_MIC),
Oleksij Rempel2cede302013-11-27 17:12:03 +01007141 SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK),
Takashi Iwai23870832013-11-29 14:13:12 +01007142 SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A),
David Henningsson3e0d6112013-04-22 14:30:14 +02007143 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC),
Jian-Hong Pan60083f92019-09-02 18:00:56 +08007144 SND_PCI_QUIRK(0x1043, 0x17d1, "ASUS UX431FL", ALC294_FIXUP_ASUS_INTSPK_HEADSET_MIC),
Daniel Drake8c8967a2019-10-17 16:15:01 +08007145 SND_PCI_QUIRK(0x1043, 0x18b1, "Asus MJ401TA", ALC256_FIXUP_ASUS_HEADSET_MIC),
Takashi Iwai017f2a12011-07-09 14:42:25 +02007146 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
Chris Chiu28e8af82017-06-05 15:05:30 -06007147 SND_PCI_QUIRK(0x1043, 0x1a30, "ASUS X705UD", ALC256_FIXUP_ASUS_MIC),
David Henningsson693b6132012-06-22 19:12:10 +02007148 SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC),
Chris Chiu615966a2017-02-28 14:17:12 -06007149 SND_PCI_QUIRK(0x1043, 0x1bbd, "ASUS Z550MA", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
Takashi Iwai4eab0ea2017-06-06 12:33:17 +02007150 SND_PCI_QUIRK(0x1043, 0x1c23, "Asus X55U", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Chris Chiuc1732ed2017-02-28 14:17:13 -06007151 SND_PCI_QUIRK(0x1043, 0x1ccd, "ASUS X555UB", ALC256_FIXUP_ASUS_MIC),
Chris Chiueeed4cd2017-02-28 14:17:15 -06007152 SND_PCI_QUIRK(0x1043, 0x3030, "ASUS ZN270IE", ALC256_FIXUP_ASUS_AIO_GPIO2),
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02007153 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC),
7154 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC),
7155 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
7156 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
David Henningssond240d1d2013-04-15 12:50:02 +02007157 SND_PCI_QUIRK(0x1043, 0x8516, "ASUS X101CH", ALC269_FIXUP_ASUS_X101),
Takashi Iwaif88abaa2014-02-07 12:07:59 +01007158 SND_PCI_QUIRK(0x104d, 0x90b5, "Sony VAIO Pro 11", ALC286_FIXUP_SONY_MIC_NO_PRESENCE),
David Henningsson88cfcf82013-10-11 10:18:45 +02007159 SND_PCI_QUIRK(0x104d, 0x90b6, "Sony VAIO Pro 13", ALC286_FIXUP_SONY_MIC_NO_PRESENCE),
Takashi Iwai1d045db2011-07-07 18:23:21 +02007160 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
7161 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
7162 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
Takashi Iwaie9bd7d52014-05-21 11:06:49 +02007163 SND_PCI_QUIRK(0x104d, 0x9099, "Sony VAIO S13", ALC275_FIXUP_SONY_DISABLE_AAMIX),
Takashi Iwai24519912011-08-16 15:08:49 +02007164 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook", ALC269_FIXUP_LIFEBOOK),
Takashi Iwai4df3fd12015-06-29 08:38:02 +02007165 SND_PCI_QUIRK(0x10cf, 0x159f, "Lifebook E780", ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT),
Takashi Iwaicc7016a2015-04-08 20:47:55 +02007166 SND_PCI_QUIRK(0x10cf, 0x15dc, "Lifebook T731", ALC269_FIXUP_LIFEBOOK_HP_PIN),
Takashi Iwai88776f32015-05-01 09:20:34 +02007167 SND_PCI_QUIRK(0x10cf, 0x1757, "Lifebook E752", ALC269_FIXUP_LIFEBOOK_HP_PIN),
Jan-Marek Glogowskifdcc9682018-02-14 11:29:15 +01007168 SND_PCI_QUIRK(0x10cf, 0x1629, "Lifebook U7x7", ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC),
David Henningsson2041d562014-06-13 11:15:44 +02007169 SND_PCI_QUIRK(0x10cf, 0x1845, "Lifebook U904", ALC269_FIXUP_LIFEBOOK_EXTMIC),
PeiSen Houb84e8432017-09-01 15:11:56 +08007170 SND_PCI_QUIRK(0x10ec, 0x10f2, "Intel Reference board", ALC700_FIXUP_INTEL_REFERENCE),
YOKOTA Hiroshi0fca97a2018-07-01 18:30:01 +09007171 SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-SZ6", ALC269_FIXUP_HEADSET_MODE),
David Henningssona33cc482014-10-07 10:18:41 +02007172 SND_PCI_QUIRK(0x144d, 0xc109, "Samsung Ativ book 9 (NP900X3G)", ALC269_FIXUP_INV_DMIC),
Gabriele Mazzotta823ff162016-12-24 19:50:01 +01007173 SND_PCI_QUIRK(0x144d, 0xc740, "Samsung Ativ book 8 (NP870Z5G)", ALC269_FIXUP_ATIV_BOOK_8),
Anisse Astierabaa22742016-08-24 09:14:13 +02007174 SND_PCI_QUIRK(0x1458, 0xfa53, "Gigabyte BXBT-2807", ALC283_FIXUP_HEADSET_MIC),
7175 SND_PCI_QUIRK(0x1462, 0xb120, "MSI Cubi MS-B120", ALC283_FIXUP_HEADSET_MIC),
Anisse Astier8cd65272018-11-23 17:59:11 +01007176 SND_PCI_QUIRK(0x1462, 0xb171, "Cubi N 8GL (MS-B171)", ALC283_FIXUP_HEADSET_MIC),
Jeremy Soller89e3a562019-01-30 16:12:31 -07007177 SND_PCI_QUIRK(0x1558, 0x1325, "System76 Darter Pro (darp5)", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
Jeremy Soller80a50522019-05-07 17:11:08 -04007178 SND_PCI_QUIRK(0x1558, 0x8550, "System76 Gazelle (gaze14)", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
Jeremy Soller891afcf2019-05-10 10:15:07 -04007179 SND_PCI_QUIRK(0x1558, 0x8551, "System76 Gazelle (gaze14)", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
7180 SND_PCI_QUIRK(0x1558, 0x8560, "System76 Gazelle (gaze14)", ALC269_FIXUP_HEADSET_MIC),
7181 SND_PCI_QUIRK(0x1558, 0x8561, "System76 Gazelle (gaze14)", ALC269_FIXUP_HEADSET_MIC),
Kailang Yangca169cc2017-04-25 16:17:40 +08007182 SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC233_FIXUP_LENOVO_MULTI_CODECS),
Takashi Iwai1d045db2011-07-07 18:23:21 +02007183 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
7184 SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
7185 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
7186 SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
7187 SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
Takashi Iwai707fba32012-08-02 09:04:39 +02007188 SND_PCI_QUIRK(0x17aa, 0x21f6, "Thinkpad T530", ALC269_FIXUP_LENOVO_DOCK),
Felix Kaechelec8415a42012-08-06 23:02:01 +02007189 SND_PCI_QUIRK(0x17aa, 0x21fa, "Thinkpad X230", ALC269_FIXUP_LENOVO_DOCK),
Stefán Freyr84f98fd2012-10-19 22:46:00 +02007190 SND_PCI_QUIRK(0x17aa, 0x21f3, "Thinkpad T430", ALC269_FIXUP_LENOVO_DOCK),
Philipp A. Mohrenweiser4407be62012-08-06 13:14:18 +02007191 SND_PCI_QUIRK(0x17aa, 0x21fb, "Thinkpad T430s", ALC269_FIXUP_LENOVO_DOCK),
David Henningsson108cc102012-07-20 10:37:25 +02007192 SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK),
David Henningssonaaedfb42013-08-16 14:09:02 +02007193 SND_PCI_QUIRK(0x17aa, 0x2208, "Thinkpad T431s", ALC269_FIXUP_LENOVO_DOCK),
Takashi Iwai9a811232015-12-09 15:17:43 +01007194 SND_PCI_QUIRK(0x17aa, 0x220c, "Thinkpad T440s", ALC292_FIXUP_TPT440),
Takashi Iwai1c37c222014-05-06 17:34:42 +02007195 SND_PCI_QUIRK(0x17aa, 0x220e, "Thinkpad T440p", ALC292_FIXUP_TPT440_DOCK),
Takashi Iwaia12137e2014-06-27 12:14:35 +02007196 SND_PCI_QUIRK(0x17aa, 0x2210, "Thinkpad T540p", ALC292_FIXUP_TPT440_DOCK),
Rick Sherman59a51a62015-08-18 21:04:30 -05007197 SND_PCI_QUIRK(0x17aa, 0x2211, "Thinkpad W541", ALC292_FIXUP_TPT440_DOCK),
Takashi Iwai6d169412014-10-07 17:27:02 +02007198 SND_PCI_QUIRK(0x17aa, 0x2212, "Thinkpad T440", ALC292_FIXUP_TPT440_DOCK),
Lukas Bossard7c215392014-10-29 18:31:07 +01007199 SND_PCI_QUIRK(0x17aa, 0x2214, "Thinkpad X240", ALC292_FIXUP_TPT440_DOCK),
David Henningssona4a9e082013-08-16 14:09:01 +02007200 SND_PCI_QUIRK(0x17aa, 0x2215, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Takashi Iwaib6903c02015-12-10 12:20:20 +01007201 SND_PCI_QUIRK(0x17aa, 0x2218, "Thinkpad X1 Carbon 2nd", ALC292_FIXUP_TPT440_DOCK),
Laura Abbottd05ea7d2015-10-02 11:09:54 -07007202 SND_PCI_QUIRK(0x17aa, 0x2223, "ThinkPad T550", ALC292_FIXUP_TPT440_DOCK),
Yves-Alexis Perezc0278662015-04-11 09:31:35 +02007203 SND_PCI_QUIRK(0x17aa, 0x2226, "ThinkPad X250", ALC292_FIXUP_TPT440_DOCK),
Kailang Yang61fcf8e2018-02-02 15:26:46 +08007204 SND_PCI_QUIRK(0x17aa, 0x222d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7205 SND_PCI_QUIRK(0x17aa, 0x222e, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
Torsten Hilbrichdab38e42016-06-07 13:14:21 +02007206 SND_PCI_QUIRK(0x17aa, 0x2231, "Thinkpad T560", ALC292_FIXUP_TPT460),
Sven Eckelmannc636b952016-04-11 16:55:26 +02007207 SND_PCI_QUIRK(0x17aa, 0x2233, "Thinkpad", ALC292_FIXUP_TPT460),
Kailang Yang61fcf8e2018-02-02 15:26:46 +08007208 SND_PCI_QUIRK(0x17aa, 0x2245, "Thinkpad T470", ALC298_FIXUP_TPT470_DOCK),
7209 SND_PCI_QUIRK(0x17aa, 0x2246, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7210 SND_PCI_QUIRK(0x17aa, 0x2247, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
Dennis Wassenberge4c07b32018-03-08 13:17:54 +01007211 SND_PCI_QUIRK(0x17aa, 0x2249, "Thinkpad", ALC292_FIXUP_TPT460),
Kailang Yang61fcf8e2018-02-02 15:26:46 +08007212 SND_PCI_QUIRK(0x17aa, 0x224b, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7213 SND_PCI_QUIRK(0x17aa, 0x224c, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7214 SND_PCI_QUIRK(0x17aa, 0x224d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
Benjamin Berg85981df2018-02-14 13:29:39 +01007215 SND_PCI_QUIRK(0x17aa, 0x225d, "Thinkpad T480", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Kailang3694cb22015-12-28 11:35:24 +08007216 SND_PCI_QUIRK(0x17aa, 0x30bb, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
Hui Wang6ef2f682016-03-11 12:04:02 +08007217 SND_PCI_QUIRK(0x17aa, 0x30e2, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
Hui Wangf33f79f2017-07-07 12:08:29 +08007218 SND_PCI_QUIRK(0x17aa, 0x310c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
Dennis Wassenbergbef33e12019-06-28 10:54:53 +02007219 SND_PCI_QUIRK(0x17aa, 0x3111, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
Hui Wange41fc8c2018-06-25 14:40:56 +08007220 SND_PCI_QUIRK(0x17aa, 0x312a, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
Kailang Yang65811832018-04-25 17:07:27 +08007221 SND_PCI_QUIRK(0x17aa, 0x312f, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
Hui Wang8da5bbf2017-12-22 11:17:46 +08007222 SND_PCI_QUIRK(0x17aa, 0x313c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
Hui Wang2a36c162019-09-04 13:53:27 +08007223 SND_PCI_QUIRK(0x17aa, 0x3151, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC),
Aaron Ma8a6c55d2019-10-24 19:44:39 +08007224 SND_PCI_QUIRK(0x17aa, 0x3176, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC),
7225 SND_PCI_QUIRK(0x17aa, 0x3178, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC),
David Henningsson56f27012016-01-11 09:33:14 +01007226 SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
Takashi Iwaifedb2242014-11-13 07:11:38 +01007227 SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC),
Michał Wadowski56df90b2019-05-14 16:58:00 +02007228 SND_PCI_QUIRK(0x17aa, 0x3978, "Lenovo B50-70", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
David Henningssona4a9e082013-08-16 14:09:01 +02007229 SND_PCI_QUIRK(0x17aa, 0x5013, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Kailang Yang1bb3e062013-09-27 13:10:25 +02007230 SND_PCI_QUIRK(0x17aa, 0x501a, "Thinkpad", ALC283_FIXUP_INT_MIC),
Takashi Iwaic497d9f2014-10-08 12:14:40 +02007231 SND_PCI_QUIRK(0x17aa, 0x501e, "Thinkpad L440", ALC292_FIXUP_TPT440_DOCK),
David Henningssoncd5302c2013-08-19 12:22:33 +02007232 SND_PCI_QUIRK(0x17aa, 0x5026, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Jo-Philipp Wichf2aa1112015-04-13 12:47:26 +02007233 SND_PCI_QUIRK(0x17aa, 0x5034, "Thinkpad T450", ALC292_FIXUP_TPT440_DOCK),
Sebastian Wicki80b311d2015-03-23 17:23:11 +01007234 SND_PCI_QUIRK(0x17aa, 0x5036, "Thinkpad T450s", ALC292_FIXUP_TPT440_DOCK),
Ansgar Hegerfeld09ea9972015-05-14 12:31:32 +02007235 SND_PCI_QUIRK(0x17aa, 0x503c, "Thinkpad L450", ALC292_FIXUP_TPT440_DOCK),
Conrad Kostecki037e1192016-04-26 10:08:10 +02007236 SND_PCI_QUIRK(0x17aa, 0x504a, "ThinkPad X260", ALC292_FIXUP_TPT440_DOCK),
Hui Wang23adc192015-12-08 12:27:18 +08007237 SND_PCI_QUIRK(0x17aa, 0x504b, "Thinkpad", ALC293_FIXUP_LENOVO_SPK_NOISE),
Jaroslav Kysela0f087ee2016-06-24 15:13:16 +02007238 SND_PCI_QUIRK(0x17aa, 0x5050, "Thinkpad T560p", ALC292_FIXUP_TPT460),
Torsten Hilbrich9cd25742016-07-05 10:40:22 +02007239 SND_PCI_QUIRK(0x17aa, 0x5051, "Thinkpad L460", ALC292_FIXUP_TPT460),
Jaroslav Kysela0f087ee2016-06-24 15:13:16 +02007240 SND_PCI_QUIRK(0x17aa, 0x5053, "Thinkpad T460", ALC292_FIXUP_TPT460),
Kailang Yang61fcf8e2018-02-02 15:26:46 +08007241 SND_PCI_QUIRK(0x17aa, 0x505d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7242 SND_PCI_QUIRK(0x17aa, 0x505f, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7243 SND_PCI_QUIRK(0x17aa, 0x5062, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
David Henningssoncd5302c2013-08-19 12:22:33 +02007244 SND_PCI_QUIRK(0x17aa, 0x5109, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Kailang Yang61fcf8e2018-02-02 15:26:46 +08007245 SND_PCI_QUIRK(0x17aa, 0x511e, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7246 SND_PCI_QUIRK(0x17aa, 0x511f, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
David Henningsson012e7eb2012-08-08 08:43:37 +02007247 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K),
Takashi Iwai1d045db2011-07-07 18:23:21 +02007248 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
Ayman Bagabas0fbf21c2019-05-23 05:30:11 -04007249 SND_PCI_QUIRK(0x19e5, 0x3204, "Huawei MACH-WX9", ALC256_FIXUP_HUAWEI_MACH_WX9_PINS),
Anisse Astier02b504d2013-06-03 11:53:10 +02007250 SND_PCI_QUIRK(0x1b7d, 0xa831, "Ordissimo EVE2 ", ALC269VB_FIXUP_ORDISSIMO_EVE2), /* Also known as Malata PC-B1303 */
Jan-Marek Glogowskibd9c10b2019-09-15 16:57:28 +02007251 SND_PCI_QUIRK(0x10ec, 0x118c, "Medion EE4254 MD62100", ALC256_FIXUP_MEDION_HEADSET_NO_PRESENCE),
Takashi Iwaia4297b52011-08-23 18:40:12 +02007252
Takashi Iwaia7f3eed2012-02-16 13:03:18 +01007253#if 0
Takashi Iwaia4297b52011-08-23 18:40:12 +02007254 /* Below is a quirk table taken from the old code.
7255 * Basically the device should work as is without the fixup table.
7256 * If BIOS doesn't give a proper info, enable the corresponding
7257 * fixup entry.
Jesper Juhl7d7eb9e2012-04-12 22:11:25 +02007258 */
Takashi Iwaia4297b52011-08-23 18:40:12 +02007259 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
7260 ALC269_FIXUP_AMIC),
7261 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269_FIXUP_AMIC),
Takashi Iwaia4297b52011-08-23 18:40:12 +02007262 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269_FIXUP_AMIC),
7263 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_FIXUP_AMIC),
7264 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269_FIXUP_AMIC),
7265 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269_FIXUP_AMIC),
7266 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269_FIXUP_AMIC),
7267 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269_FIXUP_AMIC),
7268 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_FIXUP_AMIC),
7269 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269_FIXUP_AMIC),
7270 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_FIXUP_AMIC),
7271 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_FIXUP_AMIC),
7272 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_FIXUP_AMIC),
7273 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_FIXUP_AMIC),
7274 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_FIXUP_AMIC),
7275 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_FIXUP_AMIC),
7276 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_FIXUP_AMIC),
7277 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_FIXUP_AMIC),
7278 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_FIXUP_AMIC),
7279 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_FIXUP_AMIC),
7280 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_FIXUP_AMIC),
7281 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_FIXUP_AMIC),
7282 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_FIXUP_AMIC),
7283 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_FIXUP_AMIC),
7284 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_FIXUP_AMIC),
7285 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_FIXUP_AMIC),
7286 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_FIXUP_AMIC),
7287 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_FIXUP_AMIC),
7288 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_FIXUP_AMIC),
7289 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_FIXUP_AMIC),
7290 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_FIXUP_AMIC),
7291 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_FIXUP_AMIC),
7292 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_FIXUP_AMIC),
7293 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_FIXUP_AMIC),
7294 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_FIXUP_AMIC),
7295 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_FIXUP_DMIC),
7296 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_FIXUP_AMIC),
7297 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_AMIC),
7298 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_FIXUP_DMIC),
7299 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_FIXUP_DMIC),
7300#endif
7301 {}
7302};
7303
David Henningsson214eef72014-07-22 14:09:35 +02007304static const struct snd_pci_quirk alc269_fixup_vendor_tbl[] = {
7305 SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC),
7306 SND_PCI_QUIRK_VENDOR(0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED),
7307 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
7308 SND_PCI_QUIRK_VENDOR(0x17aa, "Thinkpad", ALC269_FIXUP_THINKPAD_ACPI),
Ayman Bagabas0fbf21c2019-05-23 05:30:11 -04007309 SND_PCI_QUIRK_VENDOR(0x19e5, "Huawei Matebook", ALC255_FIXUP_MIC_MUTE_LED),
David Henningsson214eef72014-07-22 14:09:35 +02007310 {}
7311};
7312
Takashi Iwai1727a772013-01-10 09:52:52 +01007313static const struct hda_model_fixup alc269_fixup_models[] = {
Takashi Iwaia4297b52011-08-23 18:40:12 +02007314 {.id = ALC269_FIXUP_AMIC, .name = "laptop-amic"},
7315 {.id = ALC269_FIXUP_DMIC, .name = "laptop-dmic"},
Takashi Iwai6e72aa52012-06-25 10:52:25 +02007316 {.id = ALC269_FIXUP_STEREO_DMIC, .name = "alc269-dmic"},
7317 {.id = ALC271_FIXUP_DMIC, .name = "alc271-dmic"},
7318 {.id = ALC269_FIXUP_INV_DMIC, .name = "inv-dmic"},
David Henningsson7c478f02013-10-11 10:18:46 +02007319 {.id = ALC269_FIXUP_HEADSET_MIC, .name = "headset-mic"},
Takashi Iwaib0169512015-05-19 10:20:13 +02007320 {.id = ALC269_FIXUP_HEADSET_MODE, .name = "headset-mode"},
7321 {.id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC, .name = "headset-mode-no-hp-mic"},
David Henningsson108cc102012-07-20 10:37:25 +02007322 {.id = ALC269_FIXUP_LENOVO_DOCK, .name = "lenovo-dock"},
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01007323 {.id = ALC269_FIXUP_HP_GPIO_LED, .name = "hp-gpio-led"},
Jaroslav Kysela04d54662017-03-09 13:29:13 +01007324 {.id = ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED, .name = "hp-dock-gpio-mic1-led"},
David Henningssone32aa852013-06-17 11:04:02 +02007325 {.id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "dell-headset-multi"},
7326 {.id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE, .name = "dell-headset-dock"},
Takashi Iwaia26d96c2018-06-26 15:09:25 +02007327 {.id = ALC269_FIXUP_DELL3_MIC_NO_PRESENCE, .name = "dell-headset3"},
7328 {.id = ALC269_FIXUP_DELL4_MIC_NO_PRESENCE, .name = "dell-headset4"},
Kailang Yangbe8ef162014-04-08 15:19:49 +08007329 {.id = ALC283_FIXUP_CHROME_BOOK, .name = "alc283-dac-wcaps"},
Kailang Yang0202e992013-12-02 15:20:15 +08007330 {.id = ALC283_FIXUP_SENSE_COMBO_JACK, .name = "alc283-sense-combo"},
Takashi Iwai1c37c222014-05-06 17:34:42 +02007331 {.id = ALC292_FIXUP_TPT440_DOCK, .name = "tpt440-dock"},
Takashi Iwai9a811232015-12-09 15:17:43 +01007332 {.id = ALC292_FIXUP_TPT440, .name = "tpt440"},
Sven Eckelmannc636b952016-04-11 16:55:26 +02007333 {.id = ALC292_FIXUP_TPT460, .name = "tpt460"},
Takashi Iwaia26d96c2018-06-26 15:09:25 +02007334 {.id = ALC298_FIXUP_TPT470_DOCK, .name = "tpt470-dock"},
Takashi Iwaiba90d6a2017-05-22 16:38:47 +02007335 {.id = ALC233_FIXUP_LENOVO_MULTI_CODECS, .name = "dual-codecs"},
Takashi Iwai28d1d6d2017-10-18 14:01:58 +02007336 {.id = ALC700_FIXUP_INTEL_REFERENCE, .name = "alc700-ref"},
Takashi Iwaia26d96c2018-06-26 15:09:25 +02007337 {.id = ALC269_FIXUP_SONY_VAIO, .name = "vaio"},
7338 {.id = ALC269_FIXUP_DELL_M101Z, .name = "dell-m101z"},
7339 {.id = ALC269_FIXUP_ASUS_G73JW, .name = "asus-g73jw"},
7340 {.id = ALC269_FIXUP_LENOVO_EAPD, .name = "lenovo-eapd"},
7341 {.id = ALC275_FIXUP_SONY_HWEQ, .name = "sony-hweq"},
7342 {.id = ALC269_FIXUP_PCM_44K, .name = "pcm44k"},
7343 {.id = ALC269_FIXUP_LIFEBOOK, .name = "lifebook"},
7344 {.id = ALC269_FIXUP_LIFEBOOK_EXTMIC, .name = "lifebook-extmic"},
7345 {.id = ALC269_FIXUP_LIFEBOOK_HP_PIN, .name = "lifebook-hp-pin"},
7346 {.id = ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC, .name = "lifebook-u7x7"},
7347 {.id = ALC269VB_FIXUP_AMIC, .name = "alc269vb-amic"},
7348 {.id = ALC269VB_FIXUP_DMIC, .name = "alc269vb-dmic"},
7349 {.id = ALC269_FIXUP_HP_MUTE_LED_MIC1, .name = "hp-mute-led-mic1"},
7350 {.id = ALC269_FIXUP_HP_MUTE_LED_MIC2, .name = "hp-mute-led-mic2"},
7351 {.id = ALC269_FIXUP_HP_MUTE_LED_MIC3, .name = "hp-mute-led-mic3"},
7352 {.id = ALC269_FIXUP_HP_GPIO_MIC1_LED, .name = "hp-gpio-mic1"},
7353 {.id = ALC269_FIXUP_HP_LINE1_MIC1_LED, .name = "hp-line1-mic1"},
7354 {.id = ALC269_FIXUP_NO_SHUTUP, .name = "noshutup"},
7355 {.id = ALC286_FIXUP_SONY_MIC_NO_PRESENCE, .name = "sony-nomic"},
7356 {.id = ALC269_FIXUP_ASPIRE_HEADSET_MIC, .name = "aspire-headset-mic"},
7357 {.id = ALC269_FIXUP_ASUS_X101, .name = "asus-x101"},
7358 {.id = ALC271_FIXUP_HP_GATE_MIC_JACK, .name = "acer-ao7xx"},
7359 {.id = ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572, .name = "acer-aspire-e1"},
7360 {.id = ALC269_FIXUP_ACER_AC700, .name = "acer-ac700"},
7361 {.id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST, .name = "limit-mic-boost"},
7362 {.id = ALC269VB_FIXUP_ASUS_ZENBOOK, .name = "asus-zenbook"},
7363 {.id = ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A, .name = "asus-zenbook-ux31a"},
7364 {.id = ALC269VB_FIXUP_ORDISSIMO_EVE2, .name = "ordissimo"},
7365 {.id = ALC282_FIXUP_ASUS_TX300, .name = "asus-tx300"},
7366 {.id = ALC283_FIXUP_INT_MIC, .name = "alc283-int-mic"},
7367 {.id = ALC290_FIXUP_MONO_SPEAKERS_HSJACK, .name = "mono-speakers"},
7368 {.id = ALC290_FIXUP_SUBWOOFER_HSJACK, .name = "alc290-subwoofer"},
7369 {.id = ALC269_FIXUP_THINKPAD_ACPI, .name = "thinkpad"},
7370 {.id = ALC269_FIXUP_DMIC_THINKPAD_ACPI, .name = "dmic-thinkpad"},
7371 {.id = ALC255_FIXUP_ACER_MIC_NO_PRESENCE, .name = "alc255-acer"},
7372 {.id = ALC255_FIXUP_ASUS_MIC_NO_PRESENCE, .name = "alc255-asus"},
7373 {.id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc255-dell1"},
7374 {.id = ALC255_FIXUP_DELL2_MIC_NO_PRESENCE, .name = "alc255-dell2"},
7375 {.id = ALC293_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc293-dell1"},
7376 {.id = ALC283_FIXUP_HEADSET_MIC, .name = "alc283-headset"},
Takashi Iwaib3802782018-11-26 17:47:46 +01007377 {.id = ALC255_FIXUP_MIC_MUTE_LED, .name = "alc255-dell-mute"},
Takashi Iwaia26d96c2018-06-26 15:09:25 +02007378 {.id = ALC282_FIXUP_ASPIRE_V5_PINS, .name = "aspire-v5"},
7379 {.id = ALC280_FIXUP_HP_GPIO4, .name = "hp-gpio4"},
7380 {.id = ALC286_FIXUP_HP_GPIO_LED, .name = "hp-gpio-led"},
7381 {.id = ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY, .name = "hp-gpio2-hotkey"},
7382 {.id = ALC280_FIXUP_HP_DOCK_PINS, .name = "hp-dock-pins"},
7383 {.id = ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED, .name = "hp-dock-gpio-mic"},
7384 {.id = ALC280_FIXUP_HP_9480M, .name = "hp-9480m"},
7385 {.id = ALC288_FIXUP_DELL_HEADSET_MODE, .name = "alc288-dell-headset"},
7386 {.id = ALC288_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc288-dell1"},
7387 {.id = ALC288_FIXUP_DELL_XPS_13, .name = "alc288-dell-xps13"},
7388 {.id = ALC292_FIXUP_DELL_E7X, .name = "dell-e7x"},
7389 {.id = ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK, .name = "alc293-dell"},
7390 {.id = ALC298_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc298-dell1"},
7391 {.id = ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE, .name = "alc298-dell-aio"},
7392 {.id = ALC275_FIXUP_DELL_XPS, .name = "alc275-dell-xps"},
7393 {.id = ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE, .name = "alc256-dell-xps13"},
7394 {.id = ALC293_FIXUP_LENOVO_SPK_NOISE, .name = "lenovo-spk-noise"},
7395 {.id = ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY, .name = "lenovo-hotkey"},
7396 {.id = ALC255_FIXUP_DELL_SPK_NOISE, .name = "dell-spk-noise"},
Kailang Yang82aa0d72019-01-11 17:15:53 +08007397 {.id = ALC225_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc225-dell1"},
Takashi Iwaia26d96c2018-06-26 15:09:25 +02007398 {.id = ALC295_FIXUP_DISABLE_DAC3, .name = "alc295-disable-dac3"},
7399 {.id = ALC280_FIXUP_HP_HEADSET_MIC, .name = "alc280-hp-headset"},
7400 {.id = ALC221_FIXUP_HP_FRONT_MIC, .name = "alc221-hp-mic"},
7401 {.id = ALC298_FIXUP_SPK_VOLUME, .name = "alc298-spk-volume"},
7402 {.id = ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER, .name = "dell-inspiron-7559"},
7403 {.id = ALC269_FIXUP_ATIV_BOOK_8, .name = "ativ-book"},
7404 {.id = ALC221_FIXUP_HP_MIC_NO_PRESENCE, .name = "alc221-hp-mic"},
7405 {.id = ALC256_FIXUP_ASUS_HEADSET_MODE, .name = "alc256-asus-headset"},
7406 {.id = ALC256_FIXUP_ASUS_MIC, .name = "alc256-asus-mic"},
7407 {.id = ALC256_FIXUP_ASUS_AIO_GPIO2, .name = "alc256-asus-aio"},
7408 {.id = ALC233_FIXUP_ASUS_MIC_NO_PRESENCE, .name = "alc233-asus"},
7409 {.id = ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE, .name = "alc233-eapd"},
7410 {.id = ALC294_FIXUP_LENOVO_MIC_LOCATION, .name = "alc294-lenovo-mic"},
7411 {.id = ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE, .name = "alc225-wyse"},
7412 {.id = ALC274_FIXUP_DELL_AIO_LINEOUT_VERB, .name = "alc274-dell-aio"},
7413 {.id = ALC255_FIXUP_DUMMY_LINEOUT_VERB, .name = "alc255-dummy-lineout"},
7414 {.id = ALC255_FIXUP_DELL_HEADSET_MIC, .name = "alc255-dell-headset"},
7415 {.id = ALC295_FIXUP_HP_X360, .name = "alc295-hp-x360"},
Kailang Yang8983eb62019-04-03 15:31:49 +08007416 {.id = ALC225_FIXUP_HEADSET_JACK, .name = "alc-headset-jack"},
7417 {.id = ALC295_FIXUP_CHROME_BOOK, .name = "alc-chrome-book"},
Bernhard Rosenkraenzere2a829b2019-03-05 00:38:19 +01007418 {.id = ALC299_FIXUP_PREDATOR_SPK, .name = "predator-spk"},
Tomas Espeletaa2ef03f2019-08-09 16:37:54 +02007419 {.id = ALC298_FIXUP_HUAWEI_MBX_STEREO, .name = "huawei-mbx-stereo"},
Jan-Marek Glogowskibd9c10b2019-09-15 16:57:28 +02007420 {.id = ALC256_FIXUP_MEDION_HEADSET_NO_PRESENCE, .name = "alc256-medion-headset"},
Takashi Iwai1d045db2011-07-07 18:23:21 +02007421 {}
7422};
Kailang Yangcfc5a842016-02-03 15:20:39 +08007423#define ALC225_STANDARD_PINS \
Kailang Yangcfc5a842016-02-03 15:20:39 +08007424 {0x21, 0x04211020}
Takashi Iwai1d045db2011-07-07 18:23:21 +02007425
Hui Wange8191a82015-04-24 13:39:59 +08007426#define ALC256_STANDARD_PINS \
7427 {0x12, 0x90a60140}, \
7428 {0x14, 0x90170110}, \
Hui Wange8191a82015-04-24 13:39:59 +08007429 {0x21, 0x02211020}
7430
David Henningssonfea185e2014-09-03 10:23:04 +02007431#define ALC282_STANDARD_PINS \
Hui Wang11580292015-08-03 11:03:49 +08007432 {0x14, 0x90170110}
Kailang Yange1e62b92015-04-08 16:01:22 +08007433
David Henningssonfea185e2014-09-03 10:23:04 +02007434#define ALC290_STANDARD_PINS \
Hui Wang11580292015-08-03 11:03:49 +08007435 {0x12, 0x99a30130}
David Henningssonfea185e2014-09-03 10:23:04 +02007436
7437#define ALC292_STANDARD_PINS \
7438 {0x14, 0x90170110}, \
Hui Wang11580292015-08-03 11:03:49 +08007439 {0x15, 0x0221401f}
Kailang Yang977e6272015-05-18 15:31:20 +08007440
Hui Wang3f6409702016-09-11 11:26:16 +08007441#define ALC295_STANDARD_PINS \
7442 {0x12, 0xb7a60130}, \
7443 {0x14, 0x90170110}, \
Hui Wang3f6409702016-09-11 11:26:16 +08007444 {0x21, 0x04211020}
7445
Woodrow Shen703867e2015-08-05 12:34:12 +08007446#define ALC298_STANDARD_PINS \
7447 {0x12, 0x90a60130}, \
7448 {0x21, 0x03211020}
7449
Hui Wange1918932014-05-26 16:22:44 +08007450static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
Kailang Yang8a328ac2018-08-21 16:54:41 +08007451 SND_HDA_PIN_QUIRK(0x10ec0221, 0x103c, "HP Workstation", ALC221_FIXUP_HP_HEADSET_MIC,
7452 {0x14, 0x01014020},
7453 {0x17, 0x90170110},
7454 {0x18, 0x02a11030},
7455 {0x19, 0x0181303F},
7456 {0x21, 0x0221102f}),
Chris Chiu5824ce82017-02-28 14:17:11 -06007457 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1025, "Acer", ALC255_FIXUP_ACER_MIC_NO_PRESENCE,
7458 {0x12, 0x90a601c0},
7459 {0x14, 0x90171120},
7460 {0x21, 0x02211030}),
Chris Chiu615966a2017-02-28 14:17:12 -06007461 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1043, "ASUS", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE,
7462 {0x14, 0x90170110},
7463 {0x1b, 0x90a70130},
7464 {0x21, 0x03211020}),
7465 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1043, "ASUS", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE,
7466 {0x1a, 0x90a70130},
7467 {0x1b, 0x90170110},
7468 {0x21, 0x03211020}),
David Henningsson2ae95572016-02-25 09:37:05 +01007469 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
Kailang Yangcfc5a842016-02-03 15:20:39 +08007470 ALC225_STANDARD_PINS,
Hui Wang8a132092016-07-08 14:26:57 +08007471 {0x12, 0xb7a60130},
Kailang Yangcfc5a842016-02-03 15:20:39 +08007472 {0x14, 0x901701a0}),
David Henningsson2ae95572016-02-25 09:37:05 +01007473 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
Kailang Yangcfc5a842016-02-03 15:20:39 +08007474 ALC225_STANDARD_PINS,
Hui Wang8a132092016-07-08 14:26:57 +08007475 {0x12, 0xb7a60130},
Kailang Yangcfc5a842016-02-03 15:20:39 +08007476 {0x14, 0x901701b0}),
Hui Wang8a132092016-07-08 14:26:57 +08007477 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
7478 ALC225_STANDARD_PINS,
7479 {0x12, 0xb7a60150},
7480 {0x14, 0x901701a0}),
7481 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
7482 ALC225_STANDARD_PINS,
7483 {0x12, 0xb7a60150},
7484 {0x14, 0x901701b0}),
7485 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
7486 ALC225_STANDARD_PINS,
7487 {0x12, 0xb7a60130},
7488 {0x1b, 0x90170110}),
Kai-Heng Feng0ce48e12017-11-20 02:29:13 -05007489 SND_HDA_PIN_QUIRK(0x10ec0233, 0x8086, "Intel NUC Skull Canyon", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
7490 {0x1b, 0x01111010},
7491 {0x1e, 0x01451130},
7492 {0x21, 0x02211020}),
Hui Wang986376b2018-05-30 12:33:07 +08007493 SND_HDA_PIN_QUIRK(0x10ec0235, 0x17aa, "Lenovo", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY,
7494 {0x12, 0x90a60140},
7495 {0x14, 0x90170110},
7496 {0x19, 0x02a11030},
7497 {0x21, 0x02211020}),
Hui Wange41fc8c2018-06-25 14:40:56 +08007498 SND_HDA_PIN_QUIRK(0x10ec0235, 0x17aa, "Lenovo", ALC294_FIXUP_LENOVO_MIC_LOCATION,
7499 {0x14, 0x90170110},
7500 {0x19, 0x02a11030},
7501 {0x1a, 0x02a11040},
7502 {0x1b, 0x01014020},
7503 {0x21, 0x0221101f}),
Hui Wangc6b17f12018-07-06 15:14:11 +08007504 SND_HDA_PIN_QUIRK(0x10ec0235, 0x17aa, "Lenovo", ALC294_FIXUP_LENOVO_MIC_LOCATION,
7505 {0x14, 0x90170110},
Hui Wangd06fb562018-10-10 11:57:25 +08007506 {0x19, 0x02a11030},
7507 {0x1a, 0x02a11040},
7508 {0x1b, 0x01011020},
7509 {0x21, 0x0221101f}),
7510 SND_HDA_PIN_QUIRK(0x10ec0235, 0x17aa, "Lenovo", ALC294_FIXUP_LENOVO_MIC_LOCATION,
7511 {0x14, 0x90170110},
Hui Wangc6b17f12018-07-06 15:14:11 +08007512 {0x19, 0x02a11020},
7513 {0x1a, 0x02a11030},
7514 {0x21, 0x0221101f}),
Hui Wangf2657882017-10-24 16:53:34 +08007515 SND_HDA_PIN_QUIRK(0x10ec0236, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7516 {0x12, 0x90a60140},
7517 {0x14, 0x90170110},
7518 {0x21, 0x02211020}),
7519 SND_HDA_PIN_QUIRK(0x10ec0236, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7520 {0x12, 0x90a60140},
7521 {0x14, 0x90170150},
7522 {0x21, 0x02211020}),
Hui Wangb26e36b2019-04-17 16:10:32 +08007523 SND_HDA_PIN_QUIRK(0x10ec0236, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7524 {0x21, 0x02211020}),
Kailang Yang0a29c572019-04-24 16:34:25 +08007525 SND_HDA_PIN_QUIRK(0x10ec0236, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7526 {0x12, 0x40000000},
7527 {0x14, 0x90170110},
7528 {0x21, 0x02211020}),
Hui Wangc77900e2014-09-03 11:31:07 +08007529 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE,
Hui Wangc77900e2014-09-03 11:31:07 +08007530 {0x14, 0x90170110},
Hui Wangc77900e2014-09-03 11:31:07 +08007531 {0x21, 0x02211020}),
David Henningsson76c21322014-06-24 14:46:54 +02007532 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang86c72d12016-05-25 12:12:32 +08007533 {0x14, 0x90170130},
7534 {0x21, 0x02211040}),
7535 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningsson76c21322014-06-24 14:46:54 +02007536 {0x12, 0x90a60140},
7537 {0x14, 0x90170110},
David Henningsson76c21322014-06-24 14:46:54 +02007538 {0x21, 0x02211020}),
7539 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7540 {0x12, 0x90a60160},
7541 {0x14, 0x90170120},
David Henningsson76c21322014-06-24 14:46:54 +02007542 {0x21, 0x02211030}),
7543 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang392c9da2016-09-26 10:59:38 +08007544 {0x14, 0x90170110},
7545 {0x1b, 0x02011020},
7546 {0x21, 0x0221101f}),
7547 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang6aecd872016-10-20 14:03:33 +08007548 {0x14, 0x90170110},
7549 {0x1b, 0x01011020},
7550 {0x21, 0x0221101f}),
7551 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssoncba59972015-07-22 10:00:25 +02007552 {0x14, 0x90170130},
David Henningssoncba59972015-07-22 10:00:25 +02007553 {0x1b, 0x01014020},
David Henningssoncba59972015-07-22 10:00:25 +02007554 {0x21, 0x0221103f}),
7555 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang59ec4b52016-08-04 15:28:04 +08007556 {0x14, 0x90170130},
Hui Wang6aecd872016-10-20 14:03:33 +08007557 {0x1b, 0x01011020},
7558 {0x21, 0x0221103f}),
7559 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7560 {0x14, 0x90170130},
Hui Wang59ec4b52016-08-04 15:28:04 +08007561 {0x1b, 0x02011020},
7562 {0x21, 0x0221103f}),
7563 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Woodrow Shene9c28e12015-07-25 10:36:16 +08007564 {0x14, 0x90170150},
Woodrow Shene9c28e12015-07-25 10:36:16 +08007565 {0x1b, 0x02011020},
Woodrow Shene9c28e12015-07-25 10:36:16 +08007566 {0x21, 0x0221105f}),
7567 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Woodrow Shene9c28e12015-07-25 10:36:16 +08007568 {0x14, 0x90170110},
Woodrow Shene9c28e12015-07-25 10:36:16 +08007569 {0x1b, 0x01014020},
Woodrow Shene9c28e12015-07-25 10:36:16 +08007570 {0x21, 0x0221101f}),
7571 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningsson76c21322014-06-24 14:46:54 +02007572 {0x12, 0x90a60160},
7573 {0x14, 0x90170120},
7574 {0x17, 0x90170140},
David Henningsson76c21322014-06-24 14:46:54 +02007575 {0x21, 0x0321102f}),
7576 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7577 {0x12, 0x90a60160},
7578 {0x14, 0x90170130},
David Henningsson76c21322014-06-24 14:46:54 +02007579 {0x21, 0x02211040}),
7580 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7581 {0x12, 0x90a60160},
7582 {0x14, 0x90170140},
David Henningsson76c21322014-06-24 14:46:54 +02007583 {0x21, 0x02211050}),
7584 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7585 {0x12, 0x90a60170},
7586 {0x14, 0x90170120},
David Henningsson76c21322014-06-24 14:46:54 +02007587 {0x21, 0x02211030}),
7588 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7589 {0x12, 0x90a60170},
7590 {0x14, 0x90170130},
David Henningsson76c21322014-06-24 14:46:54 +02007591 {0x21, 0x02211040}),
Hui Wang70658b92015-03-06 14:03:57 +08007592 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang70658b92015-03-06 14:03:57 +08007593 {0x12, 0x90a60170},
Hui Wang0a1f90a2016-01-13 11:51:38 +08007594 {0x14, 0x90171130},
7595 {0x21, 0x02211040}),
7596 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7597 {0x12, 0x90a60170},
Hui Wang70658b92015-03-06 14:03:57 +08007598 {0x14, 0x90170140},
Hui Wang70658b92015-03-06 14:03:57 +08007599 {0x21, 0x02211050}),
David Henningsson9b5a4e32015-05-11 14:04:14 +02007600 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell Inspiron 5548", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningsson9b5a4e32015-05-11 14:04:14 +02007601 {0x12, 0x90a60180},
7602 {0x14, 0x90170130},
David Henningsson9b5a4e32015-05-11 14:04:14 +02007603 {0x21, 0x02211040}),
AceLan Kaof90d83b2016-06-03 14:45:25 +08007604 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell Inspiron 5565", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7605 {0x12, 0x90a60180},
7606 {0x14, 0x90170120},
7607 {0x21, 0x02211030}),
Hui Wang989dbe42016-11-23 16:05:38 +08007608 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7609 {0x1b, 0x01011020},
7610 {0x21, 0x02211010}),
Chris Chiuc1732ed2017-02-28 14:17:13 -06007611 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC,
7612 {0x14, 0x90170110},
7613 {0x1b, 0x90a70130},
7614 {0x21, 0x04211020}),
7615 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC,
7616 {0x14, 0x90170110},
7617 {0x1b, 0x90a70130},
7618 {0x21, 0x03211020}),
Jian-Hong Pane1037352019-03-22 11:37:18 +08007619 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE,
Chris Chiua806ef12019-03-22 11:37:20 +08007620 {0x12, 0x90a60130},
7621 {0x14, 0x90170110},
7622 {0x21, 0x03211020}),
7623 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE,
Jian-Hong Pan6ac371a2019-03-22 11:37:22 +08007624 {0x12, 0x90a60130},
7625 {0x14, 0x90170110},
7626 {0x21, 0x04211020}),
7627 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE,
Jian-Hong Pane1037352019-03-22 11:37:18 +08007628 {0x1a, 0x90a70130},
7629 {0x1b, 0x90170110},
7630 {0x21, 0x03211020}),
Kailang Yang92266652017-12-14 15:28:58 +08007631 SND_HDA_PIN_QUIRK(0x10ec0274, 0x1028, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB,
Hui Wang75ee94b2017-11-09 08:48:08 +08007632 {0x12, 0xb7a60130},
7633 {0x13, 0xb8a61140},
7634 {0x16, 0x90170110},
7635 {0x21, 0x04211020}),
David Henningssoncf51eb92014-10-30 08:26:02 +01007636 SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC280_FIXUP_HP_GPIO4,
7637 {0x12, 0x90a60130},
David Henningssoncf51eb92014-10-30 08:26:02 +01007638 {0x14, 0x90170110},
7639 {0x15, 0x0421101f},
Hui Wang11580292015-08-03 11:03:49 +08007640 {0x1a, 0x04a11020}),
Hui Wang02796612014-09-03 11:31:11 +08007641 SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED,
7642 {0x12, 0x90a60140},
Hui Wang02796612014-09-03 11:31:11 +08007643 {0x14, 0x90170110},
7644 {0x15, 0x0421101f},
Hui Wang02796612014-09-03 11:31:11 +08007645 {0x18, 0x02811030},
Hui Wang02796612014-09-03 11:31:11 +08007646 {0x1a, 0x04a1103f},
Hui Wang11580292015-08-03 11:03:49 +08007647 {0x1b, 0x02011020}),
David Henningsson42304472014-07-22 11:42:17 +02007648 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP 15 Touchsmart", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007649 ALC282_STANDARD_PINS,
David Henningsson42304472014-07-22 11:42:17 +02007650 {0x12, 0x99a30130},
David Henningsson42304472014-07-22 11:42:17 +02007651 {0x19, 0x03a11020},
David Henningsson42304472014-07-22 11:42:17 +02007652 {0x21, 0x0321101f}),
Hui Wang2c609992014-09-03 11:31:08 +08007653 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007654 ALC282_STANDARD_PINS,
Hui Wang2c609992014-09-03 11:31:08 +08007655 {0x12, 0x99a30130},
Hui Wang2c609992014-09-03 11:31:08 +08007656 {0x19, 0x03a11020},
Hui Wang2c609992014-09-03 11:31:08 +08007657 {0x21, 0x03211040}),
7658 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007659 ALC282_STANDARD_PINS,
Hui Wang2c609992014-09-03 11:31:08 +08007660 {0x12, 0x99a30130},
Hui Wang2c609992014-09-03 11:31:08 +08007661 {0x19, 0x03a11030},
Hui Wang2c609992014-09-03 11:31:08 +08007662 {0x21, 0x03211020}),
7663 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007664 ALC282_STANDARD_PINS,
Hui Wang2c609992014-09-03 11:31:08 +08007665 {0x12, 0x99a30130},
Hui Wang2c609992014-09-03 11:31:08 +08007666 {0x19, 0x04a11020},
Hui Wang2c609992014-09-03 11:31:08 +08007667 {0x21, 0x0421101f}),
Hui Wang200afc02014-09-03 11:31:10 +08007668 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED,
David Henningssonaec856d2014-09-03 10:23:05 +02007669 ALC282_STANDARD_PINS,
Hui Wang200afc02014-09-03 11:31:10 +08007670 {0x12, 0x90a60140},
Hui Wang200afc02014-09-03 11:31:10 +08007671 {0x19, 0x04a11030},
Hui Wang200afc02014-09-03 11:31:10 +08007672 {0x21, 0x04211020}),
David Henningsson76c21322014-06-24 14:46:54 +02007673 SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007674 ALC282_STANDARD_PINS,
David Henningsson76c21322014-06-24 14:46:54 +02007675 {0x12, 0x90a60130},
David Henningsson76c21322014-06-24 14:46:54 +02007676 {0x21, 0x0321101f}),
7677 SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
7678 {0x12, 0x90a60160},
7679 {0x14, 0x90170120},
David Henningsson76c21322014-06-24 14:46:54 +02007680 {0x21, 0x02211030}),
Hui Wangbc262172014-09-03 11:31:05 +08007681 SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007682 ALC282_STANDARD_PINS,
Hui Wangbc262172014-09-03 11:31:05 +08007683 {0x12, 0x90a60130},
Hui Wangbc262172014-09-03 11:31:05 +08007684 {0x19, 0x03a11020},
Hui Wangbc262172014-09-03 11:31:05 +08007685 {0x21, 0x0321101f}),
Hui Wangc8c6ee62019-02-14 11:41:33 +08007686 SND_HDA_PIN_QUIRK(0x10ec0285, 0x17aa, "Lenovo", ALC285_FIXUP_LENOVO_PC_BEEP_IN_NOISE,
Hui Wangc4cfcf62018-11-26 14:17:16 +08007687 {0x12, 0x90a60130},
7688 {0x14, 0x90170110},
7689 {0x19, 0x04a11040},
7690 {0x21, 0x04211020}),
Chris Chiu33aaebd2018-12-05 14:48:53 +08007691 SND_HDA_PIN_QUIRK(0x10ec0286, 0x1025, "Acer", ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE,
7692 {0x12, 0x90a60130},
7693 {0x17, 0x90170110},
7694 {0x21, 0x02211020}),
Takashi Iwaid44a6862018-06-19 23:04:03 +02007695 SND_HDA_PIN_QUIRK(0x10ec0288, 0x1028, "Dell", ALC288_FIXUP_DELL1_MIC_NO_PRESENCE,
Kailang Yange1e62b92015-04-08 16:01:22 +08007696 {0x12, 0x90a60120},
Kailang Yange1e62b92015-04-08 16:01:22 +08007697 {0x14, 0x90170110},
Kailang Yange1e62b92015-04-08 16:01:22 +08007698 {0x21, 0x0321101f}),
Hui Wange4442bc2014-09-03 11:31:09 +08007699 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007700 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08007701 {0x15, 0x04211040},
Hui Wange4442bc2014-09-03 11:31:09 +08007702 {0x18, 0x90170112},
Hui Wang11580292015-08-03 11:03:49 +08007703 {0x1a, 0x04a11020}),
Hui Wange4442bc2014-09-03 11:31:09 +08007704 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007705 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08007706 {0x15, 0x04211040},
Hui Wange4442bc2014-09-03 11:31:09 +08007707 {0x18, 0x90170110},
Hui Wang11580292015-08-03 11:03:49 +08007708 {0x1a, 0x04a11020}),
Hui Wange4442bc2014-09-03 11:31:09 +08007709 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007710 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08007711 {0x15, 0x0421101f},
Hui Wang11580292015-08-03 11:03:49 +08007712 {0x1a, 0x04a11020}),
Hui Wange4442bc2014-09-03 11:31:09 +08007713 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007714 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08007715 {0x15, 0x04211020},
Hui Wang11580292015-08-03 11:03:49 +08007716 {0x1a, 0x04a11040}),
Hui Wange4442bc2014-09-03 11:31:09 +08007717 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007718 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08007719 {0x14, 0x90170110},
7720 {0x15, 0x04211020},
Hui Wang11580292015-08-03 11:03:49 +08007721 {0x1a, 0x04a11040}),
Hui Wange4442bc2014-09-03 11:31:09 +08007722 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007723 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08007724 {0x14, 0x90170110},
7725 {0x15, 0x04211020},
Hui Wang11580292015-08-03 11:03:49 +08007726 {0x1a, 0x04a11020}),
Hui Wange4442bc2014-09-03 11:31:09 +08007727 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007728 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08007729 {0x14, 0x90170110},
7730 {0x15, 0x0421101f},
Hui Wang11580292015-08-03 11:03:49 +08007731 {0x1a, 0x04a11020}),
Hui Wange8818fa2014-09-03 11:31:04 +08007732 SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007733 ALC292_STANDARD_PINS,
Hui Wange8818fa2014-09-03 11:31:04 +08007734 {0x12, 0x90a60140},
Hui Wange8818fa2014-09-03 11:31:04 +08007735 {0x16, 0x01014020},
Hui Wang11580292015-08-03 11:03:49 +08007736 {0x19, 0x01a19030}),
Hui Wange8818fa2014-09-03 11:31:04 +08007737 SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007738 ALC292_STANDARD_PINS,
Hui Wange8818fa2014-09-03 11:31:04 +08007739 {0x12, 0x90a60140},
Hui Wange8818fa2014-09-03 11:31:04 +08007740 {0x16, 0x01014020},
7741 {0x18, 0x02a19031},
Hui Wang11580292015-08-03 11:03:49 +08007742 {0x19, 0x01a1903e}),
David Henningsson76c21322014-06-24 14:46:54 +02007743 SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007744 ALC292_STANDARD_PINS,
Hui Wang11580292015-08-03 11:03:49 +08007745 {0x12, 0x90a60140}),
David Henningsson76c21322014-06-24 14:46:54 +02007746 SND_HDA_PIN_QUIRK(0x10ec0293, 0x1028, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007747 ALC292_STANDARD_PINS,
David Henningsson76c21322014-06-24 14:46:54 +02007748 {0x13, 0x90a60140},
David Henningsson76c21322014-06-24 14:46:54 +02007749 {0x16, 0x21014020},
Hui Wang11580292015-08-03 11:03:49 +08007750 {0x19, 0x21a19030}),
David Henningssone03fdbd2014-06-27 08:41:59 +02007751 SND_HDA_PIN_QUIRK(0x10ec0293, 0x1028, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007752 ALC292_STANDARD_PINS,
Hui Wang11580292015-08-03 11:03:49 +08007753 {0x13, 0x90a60140}),
Chris Chiud8ae4582018-12-07 17:17:11 +08007754 SND_HDA_PIN_QUIRK(0x10ec0294, 0x1043, "ASUS", ALC294_FIXUP_ASUS_MIC,
7755 {0x14, 0x90170110},
7756 {0x1b, 0x90a70130},
7757 {0x21, 0x04211020}),
Jian-Hong Pan0bea4cc2018-12-07 17:17:13 +08007758 SND_HDA_PIN_QUIRK(0x10ec0294, 0x1043, "ASUS", ALC294_FIXUP_ASUS_SPK,
7759 {0x12, 0x90a60130},
7760 {0x17, 0x90170110},
Jian-Hong Pan8bb37a22019-02-21 17:00:18 +08007761 {0x21, 0x03211020}),
7762 SND_HDA_PIN_QUIRK(0x10ec0294, 0x1043, "ASUS", ALC294_FIXUP_ASUS_SPK,
7763 {0x12, 0x90a60130},
7764 {0x17, 0x90170110},
Jian-Hong Pan0bea4cc2018-12-07 17:17:13 +08007765 {0x21, 0x04211020}),
Takashi Iwai3887c262019-04-30 15:10:01 +02007766 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1043, "ASUS", ALC294_FIXUP_ASUS_SPK,
7767 {0x12, 0x90a60130},
7768 {0x17, 0x90170110},
7769 {0x21, 0x03211020}),
Kailang Yangfbc57122019-07-15 10:41:50 +08007770 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
Kailang Yang0a29c572019-04-24 16:34:25 +08007771 {0x14, 0x90170110},
7772 {0x21, 0x04211020}),
Kailang Yangfbc57122019-07-15 10:41:50 +08007773 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
7774 {0x14, 0x90170110},
7775 {0x21, 0x04211030}),
Hui Wang3f6409702016-09-11 11:26:16 +08007776 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wangf771d5b2016-10-18 10:59:09 +08007777 ALC295_STANDARD_PINS,
7778 {0x17, 0x21014020},
7779 {0x18, 0x21a19030}),
7780 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
7781 ALC295_STANDARD_PINS,
7782 {0x17, 0x21014040},
7783 {0x18, 0x21a19050}),
Hui Wang3f307832017-03-23 10:00:25 +08007784 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
7785 ALC295_STANDARD_PINS),
Kailang Yang977e6272015-05-18 15:31:20 +08007786 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
Woodrow Shen703867e2015-08-05 12:34:12 +08007787 ALC298_STANDARD_PINS,
Takashi Iwai9f502ff2015-08-05 12:09:45 +02007788 {0x17, 0x90170110}),
7789 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
7790 ALC298_STANDARD_PINS,
Woodrow Shen703867e2015-08-05 12:34:12 +08007791 {0x17, 0x90170140}),
7792 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
7793 ALC298_STANDARD_PINS,
Takashi Iwai9f502ff2015-08-05 12:09:45 +02007794 {0x17, 0x90170150}),
Kai-Heng Feng9f1bc2c42017-02-16 15:26:54 +08007795 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_SPK_VOLUME,
7796 {0x12, 0xb7a60140},
7797 {0x13, 0xb7a60150},
7798 {0x17, 0x90170110},
7799 {0x1a, 0x03011020},
7800 {0x21, 0x03211030}),
James McDonnell54324222019-09-16 14:53:38 +00007801 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_ALIENWARE_MIC_NO_PRESENCE,
7802 {0x12, 0xb7a60140},
7803 {0x17, 0x90170110},
7804 {0x1a, 0x03a11030},
7805 {0x21, 0x03211020}),
Kailang Yangfcc6c872017-06-29 15:21:27 +08007806 SND_HDA_PIN_QUIRK(0x10ec0299, 0x1028, "Dell", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
7807 ALC225_STANDARD_PINS,
7808 {0x12, 0xb7a60130},
Kailang Yangfcc6c872017-06-29 15:21:27 +08007809 {0x17, 0x90170110}),
Hui Wange1918932014-05-26 16:22:44 +08007810 {}
7811};
Takashi Iwai1d045db2011-07-07 18:23:21 +02007812
Hui Wang7c0a6932019-08-16 14:27:40 +08007813/* This is the fallback pin_fixup_tbl for alc269 family, to make the tbl match
7814 * more machines, don't need to match all valid pins, just need to match
7815 * all the pins defined in the tbl. Just because of this reason, it is possible
7816 * that a single machine matches multiple tbls, so there is one limitation:
7817 * at most one tbl is allowed to define for the same vendor and same codec
7818 */
7819static const struct snd_hda_pin_quirk alc269_fallback_pin_fixup_tbl[] = {
7820 SND_HDA_PIN_QUIRK(0x10ec0289, 0x1028, "Dell", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
7821 {0x19, 0x40000000},
7822 {0x1b, 0x40000000}),
Hui Wangaed8c7f2019-11-21 10:26:43 +08007823 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7824 {0x19, 0x40000000},
7825 {0x1a, 0x40000000}),
Hui Wang7c0a6932019-08-16 14:27:40 +08007826 {}
7827};
7828
Takashi Iwai546bb672012-03-07 08:37:19 +01007829static void alc269_fill_coef(struct hda_codec *codec)
Takashi Iwai1d045db2011-07-07 18:23:21 +02007830{
Kailang Yang526af6e2012-03-07 08:25:20 +01007831 struct alc_spec *spec = codec->spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02007832 int val;
7833
Kailang Yang526af6e2012-03-07 08:25:20 +01007834 if (spec->codec_variant != ALC269_TYPE_ALC269VB)
Takashi Iwai546bb672012-03-07 08:37:19 +01007835 return;
Kailang Yang526af6e2012-03-07 08:25:20 +01007836
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007837 if ((alc_get_coef0(codec) & 0x00ff) < 0x015) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02007838 alc_write_coef_idx(codec, 0xf, 0x960b);
7839 alc_write_coef_idx(codec, 0xe, 0x8817);
7840 }
7841
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007842 if ((alc_get_coef0(codec) & 0x00ff) == 0x016) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02007843 alc_write_coef_idx(codec, 0xf, 0x960b);
7844 alc_write_coef_idx(codec, 0xe, 0x8814);
7845 }
7846
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007847 if ((alc_get_coef0(codec) & 0x00ff) == 0x017) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02007848 /* Power up output pin */
Takashi Iwai98b24882014-08-18 13:47:50 +02007849 alc_update_coef_idx(codec, 0x04, 0, 1<<11);
Takashi Iwai1d045db2011-07-07 18:23:21 +02007850 }
7851
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007852 if ((alc_get_coef0(codec) & 0x00ff) == 0x018) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02007853 val = alc_read_coef_idx(codec, 0xd);
Takashi Iwaif3ee07d2014-08-15 17:35:00 +02007854 if (val != -1 && (val & 0x0c00) >> 10 != 0x1) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02007855 /* Capless ramp up clock control */
7856 alc_write_coef_idx(codec, 0xd, val | (1<<10));
7857 }
7858 val = alc_read_coef_idx(codec, 0x17);
Takashi Iwaif3ee07d2014-08-15 17:35:00 +02007859 if (val != -1 && (val & 0x01c0) >> 6 != 0x4) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02007860 /* Class D power on reset */
7861 alc_write_coef_idx(codec, 0x17, val | (1<<7));
7862 }
7863 }
7864
Takashi Iwai98b24882014-08-18 13:47:50 +02007865 /* HP */
7866 alc_update_coef_idx(codec, 0x4, 0, 1<<11);
Takashi Iwai1d045db2011-07-07 18:23:21 +02007867}
7868
7869/*
7870 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02007871static int patch_alc269(struct hda_codec *codec)
7872{
7873 struct alc_spec *spec;
Takashi Iwai3de95172012-05-07 18:03:15 +02007874 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02007875
Takashi Iwai3de95172012-05-07 18:03:15 +02007876 err = alc_alloc_spec(codec, 0x0b);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007877 if (err < 0)
Takashi Iwai3de95172012-05-07 18:03:15 +02007878 return err;
7879
7880 spec = codec->spec;
Takashi Iwai08c189f2012-12-19 15:22:24 +01007881 spec->gen.shared_mic_vref_pin = 0x18;
Kailang Yang317d9312019-05-23 14:43:04 +08007882 codec->power_save_node = 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007883
Takashi Iwai225068a2015-05-29 10:42:14 +02007884#ifdef CONFIG_PM
7885 codec->patch_ops.suspend = alc269_suspend;
7886 codec->patch_ops.resume = alc269_resume;
7887#endif
Kailang Yangc2d6af52017-06-21 14:50:54 +08007888 spec->shutup = alc_default_shutup;
7889 spec->init_hook = alc_default_init;
Takashi Iwai225068a2015-05-29 10:42:14 +02007890
Takashi Iwai7639a062015-03-03 10:07:24 +01007891 switch (codec->core.vendor_id) {
Kailang Yang065380f2013-01-10 10:25:48 +01007892 case 0x10ec0269:
Takashi Iwai1d045db2011-07-07 18:23:21 +02007893 spec->codec_variant = ALC269_TYPE_ALC269VA;
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007894 switch (alc_get_coef0(codec) & 0x00f0) {
7895 case 0x0010:
Takashi Iwai5100cd02014-02-15 10:03:19 +01007896 if (codec->bus->pci &&
7897 codec->bus->pci->subsystem_vendor == 0x1025 &&
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007898 spec->cdefine.platform_type == 1)
Takashi Iwai20ca0c32011-10-17 16:00:35 +02007899 err = alc_codec_rename(codec, "ALC271X");
Takashi Iwai1d045db2011-07-07 18:23:21 +02007900 spec->codec_variant = ALC269_TYPE_ALC269VB;
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007901 break;
7902 case 0x0020:
Takashi Iwai5100cd02014-02-15 10:03:19 +01007903 if (codec->bus->pci &&
7904 codec->bus->pci->subsystem_vendor == 0x17aa &&
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007905 codec->bus->pci->subsystem_device == 0x21f3)
Takashi Iwai20ca0c32011-10-17 16:00:35 +02007906 err = alc_codec_rename(codec, "ALC3202");
Takashi Iwai1d045db2011-07-07 18:23:21 +02007907 spec->codec_variant = ALC269_TYPE_ALC269VC;
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007908 break;
Kailang Yangadcc70b2012-05-25 08:08:38 +02007909 case 0x0030:
7910 spec->codec_variant = ALC269_TYPE_ALC269VD;
7911 break;
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007912 default:
Takashi Iwai1d045db2011-07-07 18:23:21 +02007913 alc_fix_pll_init(codec, 0x20, 0x04, 15);
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007914 }
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007915 if (err < 0)
7916 goto error;
Kailang Yangc2d6af52017-06-21 14:50:54 +08007917 spec->shutup = alc269_shutup;
Takashi Iwai546bb672012-03-07 08:37:19 +01007918 spec->init_hook = alc269_fill_coef;
Takashi Iwai1d045db2011-07-07 18:23:21 +02007919 alc269_fill_coef(codec);
Kailang Yang065380f2013-01-10 10:25:48 +01007920 break;
7921
7922 case 0x10ec0280:
7923 case 0x10ec0290:
7924 spec->codec_variant = ALC269_TYPE_ALC280;
7925 break;
7926 case 0x10ec0282:
Kailang Yang065380f2013-01-10 10:25:48 +01007927 spec->codec_variant = ALC269_TYPE_ALC282;
Kailang Yang7b5c7a02014-03-18 16:15:54 +08007928 spec->shutup = alc282_shutup;
7929 spec->init_hook = alc282_init;
Kailang Yang065380f2013-01-10 10:25:48 +01007930 break;
Kailang Yang2af02be2013-08-22 10:03:50 +02007931 case 0x10ec0233:
7932 case 0x10ec0283:
7933 spec->codec_variant = ALC269_TYPE_ALC283;
7934 spec->shutup = alc283_shutup;
7935 spec->init_hook = alc283_init;
7936 break;
Kailang Yang065380f2013-01-10 10:25:48 +01007937 case 0x10ec0284:
7938 case 0x10ec0292:
7939 spec->codec_variant = ALC269_TYPE_ALC284;
7940 break;
Kailang Yang161ebf22013-10-24 11:36:33 +02007941 case 0x10ec0293:
Kailang Yang4731d5d2017-06-30 15:22:57 +08007942 spec->codec_variant = ALC269_TYPE_ALC293;
Kailang Yang161ebf22013-10-24 11:36:33 +02007943 break;
Kailang Yang7fc7d042013-04-25 11:04:43 +02007944 case 0x10ec0286:
Kailang Yang7c665932014-04-14 15:09:44 +08007945 case 0x10ec0288:
Kailang Yang7fc7d042013-04-25 11:04:43 +02007946 spec->codec_variant = ALC269_TYPE_ALC286;
7947 break;
Kailang Yang506b62c2014-12-18 17:07:44 +08007948 case 0x10ec0298:
7949 spec->codec_variant = ALC269_TYPE_ALC298;
7950 break;
Kailang Yangea04a1d2018-04-25 15:31:52 +08007951 case 0x10ec0235:
Kailang Yang1d04c9d2013-10-24 11:35:18 +02007952 case 0x10ec0255:
7953 spec->codec_variant = ALC269_TYPE_ALC255;
Kailang Yangab3b8e52018-04-25 16:05:27 +08007954 spec->shutup = alc256_shutup;
7955 spec->init_hook = alc256_init;
Kailang Yang1d04c9d2013-10-24 11:35:18 +02007956 break;
Kailang Yang736f20a2017-10-20 15:06:34 +08007957 case 0x10ec0236:
Kailang Yang4344aec2014-12-17 17:39:05 +08007958 case 0x10ec0256:
7959 spec->codec_variant = ALC269_TYPE_ALC256;
Kailang Yang4a219ef2017-06-16 16:54:35 +08007960 spec->shutup = alc256_shutup;
7961 spec->init_hook = alc256_init;
David Henningsson7d1b6e22015-04-21 10:48:46 +02007962 spec->gen.mixer_nid = 0; /* ALC256 does not have any loopback mixer path */
Kailang Yang4344aec2014-12-17 17:39:05 +08007963 break;
Kailang Yangf429e7e2017-12-05 15:38:24 +08007964 case 0x10ec0257:
7965 spec->codec_variant = ALC269_TYPE_ALC257;
Kailang Yang88d42b22018-03-14 16:08:57 +08007966 spec->shutup = alc256_shutup;
7967 spec->init_hook = alc256_init;
Kailang Yangf429e7e2017-12-05 15:38:24 +08007968 spec->gen.mixer_nid = 0;
7969 break;
Kailang Yang0a6f0602017-06-30 16:00:48 +08007970 case 0x10ec0215:
7971 case 0x10ec0285:
7972 case 0x10ec0289:
7973 spec->codec_variant = ALC269_TYPE_ALC215;
Kailang Yang1b6832be2018-01-17 15:32:03 +08007974 spec->shutup = alc225_shutup;
7975 spec->init_hook = alc225_init;
Kailang Yang0a6f0602017-06-30 16:00:48 +08007976 spec->gen.mixer_nid = 0;
7977 break;
Kailang Yang42314302016-02-03 15:03:50 +08007978 case 0x10ec0225:
Kailang Yang7d727862016-05-24 16:46:07 +08007979 case 0x10ec0295:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08007980 case 0x10ec0299:
Kailang Yang42314302016-02-03 15:03:50 +08007981 spec->codec_variant = ALC269_TYPE_ALC225;
Kailang Yangda911b12018-01-05 16:50:08 +08007982 spec->shutup = alc225_shutup;
7983 spec->init_hook = alc225_init;
Takashi Iwaic1350bf2017-12-27 09:03:45 +01007984 spec->gen.mixer_nid = 0; /* no loopback on ALC225, ALC295 and ALC299 */
Kailang Yang42314302016-02-03 15:03:50 +08007985 break;
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08007986 case 0x10ec0234:
7987 case 0x10ec0274:
7988 case 0x10ec0294:
7989 spec->codec_variant = ALC269_TYPE_ALC294;
Hui Wang532a7782017-06-26 12:30:32 +08007990 spec->gen.mixer_nid = 0; /* ALC2x4 does not have any loopback mixer path */
Kailang Yang71683c32017-06-20 16:33:50 +08007991 alc_update_coef_idx(codec, 0x6b, 0x0018, (1<<4) | (1<<3)); /* UAJ MIC Vref control by verb */
Kailang Yang693abe12019-01-29 15:38:21 +08007992 spec->init_hook = alc294_init;
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08007993 break;
Kailang Yang1078bef2018-11-08 16:36:15 +08007994 case 0x10ec0300:
7995 spec->codec_variant = ALC269_TYPE_ALC300;
7996 spec->gen.mixer_nid = 0; /* no loopback on ALC300 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02007997 break;
Kailang Yangf0778872019-10-24 15:13:32 +08007998 case 0x10ec0623:
7999 spec->codec_variant = ALC269_TYPE_ALC623;
8000 break;
Kailang Yang6fbae352016-05-30 16:44:20 +08008001 case 0x10ec0700:
8002 case 0x10ec0701:
8003 case 0x10ec0703:
Kailang Yang83629532019-05-02 16:03:26 +08008004 case 0x10ec0711:
Kailang Yang6fbae352016-05-30 16:44:20 +08008005 spec->codec_variant = ALC269_TYPE_ALC700;
8006 spec->gen.mixer_nid = 0; /* ALC700 does not have any loopback mixer path */
Kailang Yang2d7fe612017-11-22 15:21:32 +08008007 alc_update_coef_idx(codec, 0x4a, 1 << 15, 0); /* Combo jack auto trigger control */
Kailang Yang693abe12019-01-29 15:38:21 +08008008 spec->init_hook = alc294_init;
Kailang Yang6fbae352016-05-30 16:44:20 +08008009 break;
8010
Takashi Iwai1d045db2011-07-07 18:23:21 +02008011 }
8012
Kailang Yangad60d502013-06-28 12:03:01 +02008013 if (snd_hda_codec_read(codec, 0x51, 0, AC_VERB_PARAMETERS, 0) == 0x10ec5505) {
Kailang Yang97a26572013-11-29 00:35:26 -05008014 spec->has_alc5505_dsp = 1;
Kailang Yangad60d502013-06-28 12:03:01 +02008015 spec->init_hook = alc5505_dsp_init;
8016 }
8017
Takashi Iwaic9af7532019-05-10 11:01:43 +02008018 alc_pre_init(codec);
8019
Takashi Iwaiefe55732018-06-15 11:55:02 +02008020 snd_hda_pick_fixup(codec, alc269_fixup_models,
8021 alc269_fixup_tbl, alc269_fixups);
Hui Wang0fc1e442019-08-16 14:27:39 +08008022 snd_hda_pick_pin_fixup(codec, alc269_pin_fixup_tbl, alc269_fixups, true);
Hui Wang7c0a6932019-08-16 14:27:40 +08008023 snd_hda_pick_pin_fixup(codec, alc269_fallback_pin_fixup_tbl, alc269_fixups, false);
Takashi Iwaiefe55732018-06-15 11:55:02 +02008024 snd_hda_pick_fixup(codec, NULL, alc269_fixup_vendor_tbl,
8025 alc269_fixups);
8026 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
8027
8028 alc_auto_parse_customize_define(codec);
8029
8030 if (has_cdefine_beep(codec))
8031 spec->gen.beep_nid = 0x01;
8032
Takashi Iwaia4297b52011-08-23 18:40:12 +02008033 /* automatic parse from the BIOS config */
8034 err = alc269_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008035 if (err < 0)
8036 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008037
Takashi Iwaifea80fa2018-06-20 12:52:46 +02008038 if (!spec->gen.no_analog && spec->gen.beep_nid && spec->gen.mixer_nid) {
8039 err = set_beep_amp(spec, spec->gen.mixer_nid, 0x04, HDA_INPUT);
8040 if (err < 0)
8041 goto error;
8042 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02008043
Takashi Iwai1727a772013-01-10 09:52:52 +01008044 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01008045
Takashi Iwai1d045db2011-07-07 18:23:21 +02008046 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008047
8048 error:
8049 alc_free(codec);
8050 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008051}
8052
8053/*
8054 * ALC861
8055 */
8056
Takashi Iwai1d045db2011-07-07 18:23:21 +02008057static int alc861_parse_auto_config(struct hda_codec *codec)
8058{
Takashi Iwai1d045db2011-07-07 18:23:21 +02008059 static const hda_nid_t alc861_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02008060 static const hda_nid_t alc861_ssids[] = { 0x0e, 0x0f, 0x0b, 0 };
8061 return alc_parse_auto_config(codec, alc861_ignore, alc861_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02008062}
8063
Takashi Iwai1d045db2011-07-07 18:23:21 +02008064/* Pin config fixes */
8065enum {
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008066 ALC861_FIXUP_FSC_AMILO_PI1505,
8067 ALC861_FIXUP_AMP_VREF_0F,
8068 ALC861_FIXUP_NO_JACK_DETECT,
8069 ALC861_FIXUP_ASUS_A6RP,
Takashi Iwai6ddf0fd2013-11-29 12:47:34 +01008070 ALC660_FIXUP_ASUS_W7J,
Takashi Iwai1d045db2011-07-07 18:23:21 +02008071};
8072
Takashi Iwai31150f22012-01-30 10:54:08 +01008073/* On some laptops, VREF of pin 0x0f is abused for controlling the main amp */
8074static void alc861_fixup_asus_amp_vref_0f(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01008075 const struct hda_fixup *fix, int action)
Takashi Iwai31150f22012-01-30 10:54:08 +01008076{
8077 struct alc_spec *spec = codec->spec;
8078 unsigned int val;
8079
Takashi Iwai1727a772013-01-10 09:52:52 +01008080 if (action != HDA_FIXUP_ACT_INIT)
Takashi Iwai31150f22012-01-30 10:54:08 +01008081 return;
Takashi Iwaid3f02d62013-01-10 10:12:22 +01008082 val = snd_hda_codec_get_pin_target(codec, 0x0f);
Takashi Iwai31150f22012-01-30 10:54:08 +01008083 if (!(val & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN)))
8084 val |= AC_PINCTL_IN_EN;
8085 val |= AC_PINCTL_VREF_50;
Takashi Iwaicdd03ce2012-04-20 12:34:50 +02008086 snd_hda_set_pin_ctl(codec, 0x0f, val);
Takashi Iwai08c189f2012-12-19 15:22:24 +01008087 spec->gen.keep_vref_in_automute = 1;
Takashi Iwai31150f22012-01-30 10:54:08 +01008088}
8089
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008090/* suppress the jack-detection */
8091static void alc_fixup_no_jack_detect(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01008092 const struct hda_fixup *fix, int action)
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008093{
Takashi Iwai1727a772013-01-10 09:52:52 +01008094 if (action == HDA_FIXUP_ACT_PRE_PROBE)
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008095 codec->no_jack_detect = 1;
Jesper Juhl7d7eb9e2012-04-12 22:11:25 +02008096}
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008097
Takashi Iwai1727a772013-01-10 09:52:52 +01008098static const struct hda_fixup alc861_fixups[] = {
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008099 [ALC861_FIXUP_FSC_AMILO_PI1505] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008100 .type = HDA_FIXUP_PINS,
8101 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02008102 { 0x0b, 0x0221101f }, /* HP */
8103 { 0x0f, 0x90170310 }, /* speaker */
8104 { }
8105 }
8106 },
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008107 [ALC861_FIXUP_AMP_VREF_0F] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008108 .type = HDA_FIXUP_FUNC,
Takashi Iwai31150f22012-01-30 10:54:08 +01008109 .v.func = alc861_fixup_asus_amp_vref_0f,
Takashi Iwai3b25eb62012-01-25 09:55:46 +01008110 },
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008111 [ALC861_FIXUP_NO_JACK_DETECT] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008112 .type = HDA_FIXUP_FUNC,
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008113 .v.func = alc_fixup_no_jack_detect,
8114 },
8115 [ALC861_FIXUP_ASUS_A6RP] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008116 .type = HDA_FIXUP_FUNC,
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008117 .v.func = alc861_fixup_asus_amp_vref_0f,
8118 .chained = true,
8119 .chain_id = ALC861_FIXUP_NO_JACK_DETECT,
Takashi Iwai6ddf0fd2013-11-29 12:47:34 +01008120 },
8121 [ALC660_FIXUP_ASUS_W7J] = {
8122 .type = HDA_FIXUP_VERBS,
8123 .v.verbs = (const struct hda_verb[]) {
8124 /* ASUS W7J needs a magic pin setup on unused NID 0x10
8125 * for enabling outputs
8126 */
8127 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8128 { }
8129 },
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008130 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02008131};
8132
8133static const struct snd_pci_quirk alc861_fixup_tbl[] = {
Takashi Iwai6ddf0fd2013-11-29 12:47:34 +01008134 SND_PCI_QUIRK(0x1043, 0x1253, "ASUS W7J", ALC660_FIXUP_ASUS_W7J),
Takashi Iwaie7ca2372013-12-02 15:27:19 +01008135 SND_PCI_QUIRK(0x1043, 0x1263, "ASUS Z35HL", ALC660_FIXUP_ASUS_W7J),
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008136 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS A6Rp", ALC861_FIXUP_ASUS_A6RP),
8137 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", ALC861_FIXUP_AMP_VREF_0F),
8138 SND_PCI_QUIRK(0x1462, 0x7254, "HP DX2200", ALC861_FIXUP_NO_JACK_DETECT),
8139 SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", ALC861_FIXUP_AMP_VREF_0F),
8140 SND_PCI_QUIRK(0x1584, 0x0000, "Uniwill ECS M31EI", ALC861_FIXUP_AMP_VREF_0F),
8141 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", ALC861_FIXUP_FSC_AMILO_PI1505),
Takashi Iwai1d045db2011-07-07 18:23:21 +02008142 {}
8143};
8144
8145/*
8146 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02008147static int patch_alc861(struct hda_codec *codec)
8148{
8149 struct alc_spec *spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008150 int err;
8151
Takashi Iwai3de95172012-05-07 18:03:15 +02008152 err = alc_alloc_spec(codec, 0x15);
8153 if (err < 0)
8154 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008155
Takashi Iwai3de95172012-05-07 18:03:15 +02008156 spec = codec->spec;
Takashi Iwai2722b532019-08-22 09:55:37 +02008157 if (has_cdefine_beep(codec))
8158 spec->gen.beep_nid = 0x23;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008159
Takashi Iwai225068a2015-05-29 10:42:14 +02008160#ifdef CONFIG_PM
8161 spec->power_hook = alc_power_eapd;
8162#endif
8163
Takashi Iwaic9af7532019-05-10 11:01:43 +02008164 alc_pre_init(codec);
8165
Takashi Iwai1727a772013-01-10 09:52:52 +01008166 snd_hda_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
8167 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02008168
Takashi Iwaicb4e4822011-08-23 17:34:25 +02008169 /* automatic parse from the BIOS config */
8170 err = alc861_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008171 if (err < 0)
8172 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008173
Takashi Iwaifea80fa2018-06-20 12:52:46 +02008174 if (!spec->gen.no_analog) {
8175 err = set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
8176 if (err < 0)
8177 goto error;
8178 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02008179
Takashi Iwai1727a772013-01-10 09:52:52 +01008180 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01008181
Takashi Iwai1d045db2011-07-07 18:23:21 +02008182 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008183
8184 error:
8185 alc_free(codec);
8186 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008187}
8188
8189/*
8190 * ALC861-VD support
8191 *
8192 * Based on ALC882
8193 *
8194 * In addition, an independent DAC
8195 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02008196static int alc861vd_parse_auto_config(struct hda_codec *codec)
8197{
Takashi Iwai1d045db2011-07-07 18:23:21 +02008198 static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02008199 static const hda_nid_t alc861vd_ssids[] = { 0x15, 0x1b, 0x14, 0 };
8200 return alc_parse_auto_config(codec, alc861vd_ignore, alc861vd_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02008201}
8202
Takashi Iwai1d045db2011-07-07 18:23:21 +02008203enum {
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008204 ALC660VD_FIX_ASUS_GPIO1,
8205 ALC861VD_FIX_DALLAS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02008206};
8207
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008208/* exclude VREF80 */
8209static void alc861vd_fixup_dallas(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01008210 const struct hda_fixup *fix, int action)
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008211{
Takashi Iwai1727a772013-01-10 09:52:52 +01008212 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwaib78562b2012-12-17 20:06:49 +01008213 snd_hda_override_pin_caps(codec, 0x18, 0x00000734);
8214 snd_hda_override_pin_caps(codec, 0x19, 0x0000073c);
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008215 }
8216}
8217
Takashi Iwaidf73d832018-06-19 23:05:47 +02008218/* reset GPIO1 */
8219static void alc660vd_fixup_asus_gpio1(struct hda_codec *codec,
8220 const struct hda_fixup *fix, int action)
8221{
8222 struct alc_spec *spec = codec->spec;
8223
8224 if (action == HDA_FIXUP_ACT_PRE_PROBE)
8225 spec->gpio_mask |= 0x02;
8226 alc_fixup_gpio(codec, action, 0x01);
8227}
8228
Takashi Iwai1727a772013-01-10 09:52:52 +01008229static const struct hda_fixup alc861vd_fixups[] = {
Takashi Iwai1d045db2011-07-07 18:23:21 +02008230 [ALC660VD_FIX_ASUS_GPIO1] = {
Takashi Iwaidf73d832018-06-19 23:05:47 +02008231 .type = HDA_FIXUP_FUNC,
8232 .v.func = alc660vd_fixup_asus_gpio1,
Takashi Iwai1d045db2011-07-07 18:23:21 +02008233 },
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008234 [ALC861VD_FIX_DALLAS] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008235 .type = HDA_FIXUP_FUNC,
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008236 .v.func = alc861vd_fixup_dallas,
8237 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02008238};
8239
8240static const struct snd_pci_quirk alc861vd_fixup_tbl[] = {
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008241 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_FIX_DALLAS),
Takashi Iwai1d045db2011-07-07 18:23:21 +02008242 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008243 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_FIX_DALLAS),
Takashi Iwai1d045db2011-07-07 18:23:21 +02008244 {}
8245};
8246
Takashi Iwai1d045db2011-07-07 18:23:21 +02008247/*
8248 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02008249static int patch_alc861vd(struct hda_codec *codec)
8250{
8251 struct alc_spec *spec;
Takashi Iwaicb4e4822011-08-23 17:34:25 +02008252 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008253
Takashi Iwai3de95172012-05-07 18:03:15 +02008254 err = alc_alloc_spec(codec, 0x0b);
8255 if (err < 0)
8256 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008257
Takashi Iwai3de95172012-05-07 18:03:15 +02008258 spec = codec->spec;
Takashi Iwai2722b532019-08-22 09:55:37 +02008259 if (has_cdefine_beep(codec))
8260 spec->gen.beep_nid = 0x23;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008261
Takashi Iwai225068a2015-05-29 10:42:14 +02008262 spec->shutup = alc_eapd_shutup;
8263
Takashi Iwaic9af7532019-05-10 11:01:43 +02008264 alc_pre_init(codec);
8265
Takashi Iwai1727a772013-01-10 09:52:52 +01008266 snd_hda_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
8267 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02008268
Takashi Iwaicb4e4822011-08-23 17:34:25 +02008269 /* automatic parse from the BIOS config */
8270 err = alc861vd_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008271 if (err < 0)
8272 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008273
Takashi Iwaifea80fa2018-06-20 12:52:46 +02008274 if (!spec->gen.no_analog) {
8275 err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
8276 if (err < 0)
8277 goto error;
8278 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02008279
Takashi Iwai1727a772013-01-10 09:52:52 +01008280 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01008281
Takashi Iwai1d045db2011-07-07 18:23:21 +02008282 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008283
8284 error:
8285 alc_free(codec);
8286 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008287}
8288
8289/*
8290 * ALC662 support
8291 *
8292 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
8293 * configuration. Each pin widget can choose any input DACs and a mixer.
8294 * Each ADC is connected from a mixer of all inputs. This makes possible
8295 * 6-channel independent captures.
8296 *
8297 * In addition, an independent DAC for the multi-playback (not used in this
8298 * driver yet).
8299 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02008300
8301/*
8302 * BIOS auto configuration
8303 */
8304
Kailang Yangbc9f98a2007-04-12 13:06:07 +02008305static int alc662_parse_auto_config(struct hda_codec *codec)
8306{
Takashi Iwai4c6d72d2011-05-02 11:30:18 +02008307 static const hda_nid_t alc662_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02008308 static const hda_nid_t alc663_ssids[] = { 0x15, 0x1b, 0x14, 0x21 };
8309 static const hda_nid_t alc662_ssids[] = { 0x15, 0x1b, 0x14, 0 };
8310 const hda_nid_t *ssids;
Takashi Iwaiee979a142008-09-02 15:42:20 +02008311
Takashi Iwai7639a062015-03-03 10:07:24 +01008312 if (codec->core.vendor_id == 0x10ec0272 || codec->core.vendor_id == 0x10ec0663 ||
8313 codec->core.vendor_id == 0x10ec0665 || codec->core.vendor_id == 0x10ec0670 ||
8314 codec->core.vendor_id == 0x10ec0671)
Takashi Iwai3e6179b2011-07-08 16:55:13 +02008315 ssids = alc663_ssids;
Kailang Yang6227cdc2010-02-25 08:36:52 +01008316 else
Takashi Iwai3e6179b2011-07-08 16:55:13 +02008317 ssids = alc662_ssids;
8318 return alc_parse_auto_config(codec, alc662_ignore, ssids);
Kailang Yangbc9f98a2007-04-12 13:06:07 +02008319}
8320
Todd Broch6be79482010-12-07 16:51:05 -08008321static void alc272_fixup_mario(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01008322 const struct hda_fixup *fix, int action)
Takashi Iwai6fc398c2011-01-13 14:36:37 +01008323{
Takashi Iwai9bb1f062013-01-10 17:14:29 +01008324 if (action != HDA_FIXUP_ACT_PRE_PROBE)
Takashi Iwai6fc398c2011-01-13 14:36:37 +01008325 return;
Todd Broch6be79482010-12-07 16:51:05 -08008326 if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT,
8327 (0x3b << AC_AMPCAP_OFFSET_SHIFT) |
8328 (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) |
8329 (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) |
8330 (0 << AC_AMPCAP_MUTE_SHIFT)))
Takashi Iwai4e76a882014-02-25 12:21:03 +01008331 codec_warn(codec, "failed to override amp caps for NID 0x2\n");
Todd Broch6be79482010-12-07 16:51:05 -08008332}
8333
Takashi Iwai8e383952013-10-30 17:41:12 +01008334static const struct snd_pcm_chmap_elem asus_pcm_2_1_chmaps[] = {
8335 { .channels = 2,
8336 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } },
8337 { .channels = 4,
8338 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR,
8339 SNDRV_CHMAP_NA, SNDRV_CHMAP_LFE } }, /* LFE only on right */
8340 { }
8341};
8342
8343/* override the 2.1 chmap */
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01008344static void alc_fixup_bass_chmap(struct hda_codec *codec,
Takashi Iwai8e383952013-10-30 17:41:12 +01008345 const struct hda_fixup *fix, int action)
8346{
8347 if (action == HDA_FIXUP_ACT_BUILD) {
8348 struct alc_spec *spec = codec->spec;
Takashi Iwaibbbc7e82015-02-27 17:43:19 +01008349 spec->gen.pcm_rec[0]->stream[0].chmap = asus_pcm_2_1_chmaps;
Takashi Iwai8e383952013-10-30 17:41:12 +01008350 }
8351}
8352
Takashi Iwaibf686652014-01-13 16:18:25 +01008353/* avoid D3 for keeping GPIO up */
8354static unsigned int gpio_led_power_filter(struct hda_codec *codec,
8355 hda_nid_t nid,
8356 unsigned int power_state)
8357{
8358 struct alc_spec *spec = codec->spec;
Takashi Iwaid261eec2018-06-19 22:32:29 +02008359 if (nid == codec->core.afg && power_state == AC_PWRST_D3 && spec->gpio_data)
Takashi Iwaibf686652014-01-13 16:18:25 +01008360 return AC_PWRST_D0;
8361 return power_state;
8362}
8363
Takashi Iwai3e887f32014-01-10 17:50:58 +01008364static void alc662_fixup_led_gpio1(struct hda_codec *codec,
8365 const struct hda_fixup *fix, int action)
8366{
8367 struct alc_spec *spec = codec->spec;
Takashi Iwai3e887f32014-01-10 17:50:58 +01008368
Takashi Iwai01e4a272018-06-19 22:47:30 +02008369 alc_fixup_hp_gpio_led(codec, action, 0x01, 0);
Takashi Iwai3e887f32014-01-10 17:50:58 +01008370 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai0f32fd192014-11-19 12:16:14 +01008371 spec->mute_led_polarity = 1;
Takashi Iwaibf686652014-01-13 16:18:25 +01008372 codec->power_filter = gpio_led_power_filter;
Takashi Iwai3e887f32014-01-10 17:50:58 +01008373 }
8374}
8375
Kailang Yangc6790c82016-11-25 16:15:17 +08008376static void alc662_usi_automute_hook(struct hda_codec *codec,
8377 struct hda_jack_callback *jack)
8378{
8379 struct alc_spec *spec = codec->spec;
8380 int vref;
8381 msleep(200);
8382 snd_hda_gen_hp_automute(codec, jack);
8383
8384 vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0;
8385 msleep(100);
8386 snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8387 vref);
8388}
8389
8390static void alc662_fixup_usi_headset_mic(struct hda_codec *codec,
8391 const struct hda_fixup *fix, int action)
8392{
8393 struct alc_spec *spec = codec->spec;
8394 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
8395 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
8396 spec->gen.hp_automute_hook = alc662_usi_automute_hook;
8397 }
8398}
8399
Sergey Bostandzhyan00066e92019-09-06 11:33:43 +02008400static void alc662_aspire_ethos_mute_speakers(struct hda_codec *codec,
8401 struct hda_jack_callback *cb)
8402{
8403 /* surround speakers at 0x1b already get muted automatically when
8404 * headphones are plugged in, but we have to mute/unmute the remaining
8405 * channels manually:
8406 * 0x15 - front left/front right
8407 * 0x18 - front center/ LFE
8408 */
8409 if (snd_hda_jack_detect_state(codec, 0x1b) == HDA_JACK_PRESENT) {
8410 snd_hda_set_pin_ctl_cache(codec, 0x15, 0);
8411 snd_hda_set_pin_ctl_cache(codec, 0x18, 0);
8412 } else {
8413 snd_hda_set_pin_ctl_cache(codec, 0x15, PIN_OUT);
8414 snd_hda_set_pin_ctl_cache(codec, 0x18, PIN_OUT);
8415 }
8416}
8417
8418static void alc662_fixup_aspire_ethos_hp(struct hda_codec *codec,
8419 const struct hda_fixup *fix, int action)
8420{
8421 /* Pin 0x1b: shared headphones jack and surround speakers */
8422 if (!is_jack_detectable(codec, 0x1b))
8423 return;
8424
8425 switch (action) {
8426 case HDA_FIXUP_ACT_PRE_PROBE:
8427 snd_hda_jack_detect_enable_callback(codec, 0x1b,
8428 alc662_aspire_ethos_mute_speakers);
8429 break;
8430 case HDA_FIXUP_ACT_INIT:
8431 /* Make sure to start in a correct state, i.e. if
8432 * headphones have been plugged in before powering up the system
8433 */
8434 alc662_aspire_ethos_mute_speakers(codec, NULL);
8435 break;
8436 }
8437}
8438
Kailang Yangf3f91852014-10-24 15:43:46 +08008439static struct coef_fw alc668_coefs[] = {
8440 WRITE_COEF(0x01, 0xbebe), WRITE_COEF(0x02, 0xaaaa), WRITE_COEF(0x03, 0x0),
8441 WRITE_COEF(0x04, 0x0180), WRITE_COEF(0x06, 0x0), WRITE_COEF(0x07, 0x0f80),
8442 WRITE_COEF(0x08, 0x0031), WRITE_COEF(0x0a, 0x0060), WRITE_COEF(0x0b, 0x0),
8443 WRITE_COEF(0x0c, 0x7cf7), WRITE_COEF(0x0d, 0x1080), WRITE_COEF(0x0e, 0x7f7f),
8444 WRITE_COEF(0x0f, 0xcccc), WRITE_COEF(0x10, 0xddcc), WRITE_COEF(0x11, 0x0001),
8445 WRITE_COEF(0x13, 0x0), WRITE_COEF(0x14, 0x2aa0), WRITE_COEF(0x17, 0xa940),
8446 WRITE_COEF(0x19, 0x0), WRITE_COEF(0x1a, 0x0), WRITE_COEF(0x1b, 0x0),
8447 WRITE_COEF(0x1c, 0x0), WRITE_COEF(0x1d, 0x0), WRITE_COEF(0x1e, 0x7418),
8448 WRITE_COEF(0x1f, 0x0804), WRITE_COEF(0x20, 0x4200), WRITE_COEF(0x21, 0x0468),
8449 WRITE_COEF(0x22, 0x8ccc), WRITE_COEF(0x23, 0x0250), WRITE_COEF(0x24, 0x7418),
8450 WRITE_COEF(0x27, 0x0), WRITE_COEF(0x28, 0x8ccc), WRITE_COEF(0x2a, 0xff00),
8451 WRITE_COEF(0x2b, 0x8000), WRITE_COEF(0xa7, 0xff00), WRITE_COEF(0xa8, 0x8000),
8452 WRITE_COEF(0xaa, 0x2e17), WRITE_COEF(0xab, 0xa0c0), WRITE_COEF(0xac, 0x0),
8453 WRITE_COEF(0xad, 0x0), WRITE_COEF(0xae, 0x2ac6), WRITE_COEF(0xaf, 0xa480),
8454 WRITE_COEF(0xb0, 0x0), WRITE_COEF(0xb1, 0x0), WRITE_COEF(0xb2, 0x0),
8455 WRITE_COEF(0xb3, 0x0), WRITE_COEF(0xb4, 0x0), WRITE_COEF(0xb5, 0x1040),
8456 WRITE_COEF(0xb6, 0xd697), WRITE_COEF(0xb7, 0x902b), WRITE_COEF(0xb8, 0xd697),
8457 WRITE_COEF(0xb9, 0x902b), WRITE_COEF(0xba, 0xb8ba), WRITE_COEF(0xbb, 0xaaab),
8458 WRITE_COEF(0xbc, 0xaaaf), WRITE_COEF(0xbd, 0x6aaa), WRITE_COEF(0xbe, 0x1c02),
8459 WRITE_COEF(0xc0, 0x00ff), WRITE_COEF(0xc1, 0x0fa6),
8460 {}
8461};
8462
8463static void alc668_restore_default_value(struct hda_codec *codec)
8464{
8465 alc_process_coef_fw(codec, alc668_coefs);
8466}
8467
David Henningsson6cb3b702010-09-09 08:51:44 +02008468enum {
Daniel T Chen2df03512010-10-10 22:39:28 -04008469 ALC662_FIXUP_ASPIRE,
Takashi Iwai3e887f32014-01-10 17:50:58 +01008470 ALC662_FIXUP_LED_GPIO1,
David Henningsson6cb3b702010-09-09 08:51:44 +02008471 ALC662_FIXUP_IDEAPAD,
Todd Broch6be79482010-12-07 16:51:05 -08008472 ALC272_FIXUP_MARIO,
Anisse Astierd2ebd472011-01-20 12:36:21 +01008473 ALC662_FIXUP_CZC_P10T,
David Henningsson94024cd2011-04-29 14:10:55 +02008474 ALC662_FIXUP_SKU_IGNORE,
Takashi Iwaie59ea3e2011-06-29 17:21:00 +02008475 ALC662_FIXUP_HP_RP5800,
Takashi Iwai53c334a2011-08-23 18:27:14 +02008476 ALC662_FIXUP_ASUS_MODE1,
8477 ALC662_FIXUP_ASUS_MODE2,
8478 ALC662_FIXUP_ASUS_MODE3,
8479 ALC662_FIXUP_ASUS_MODE4,
8480 ALC662_FIXUP_ASUS_MODE5,
8481 ALC662_FIXUP_ASUS_MODE6,
8482 ALC662_FIXUP_ASUS_MODE7,
8483 ALC662_FIXUP_ASUS_MODE8,
Takashi Iwai1565cc32012-02-13 12:03:25 +01008484 ALC662_FIXUP_NO_JACK_DETECT,
David Henningssonedfe3bf2012-06-12 13:15:12 +02008485 ALC662_FIXUP_ZOTAC_Z68,
Takashi Iwai125821a2012-06-22 14:30:29 +02008486 ALC662_FIXUP_INV_DMIC,
David Henningsson1f8b46c2015-05-12 14:38:15 +02008487 ALC662_FIXUP_DELL_MIC_NO_PRESENCE,
David Henningsson73bdd592013-04-15 15:44:14 +02008488 ALC668_FIXUP_DELL_MIC_NO_PRESENCE,
David Henningsson1f8b46c2015-05-12 14:38:15 +02008489 ALC662_FIXUP_HEADSET_MODE,
David Henningsson73bdd592013-04-15 15:44:14 +02008490 ALC668_FIXUP_HEADSET_MODE,
David Henningsson8e54b4a2014-02-07 09:31:07 +01008491 ALC662_FIXUP_BASS_MODE4_CHMAP,
David Henningsson61a75f12014-02-07 09:31:08 +01008492 ALC662_FIXUP_BASS_16,
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01008493 ALC662_FIXUP_BASS_1A,
David Henningsson8e54b4a2014-02-07 09:31:07 +01008494 ALC662_FIXUP_BASS_CHMAP,
Hui Wang493a52a2014-01-14 14:07:36 +08008495 ALC668_FIXUP_AUTO_MUTE,
Gabriele Mazzotta5e6db662014-05-20 18:58:26 +02008496 ALC668_FIXUP_DELL_DISABLE_AAMIX,
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02008497 ALC668_FIXUP_DELL_XPS13,
Bobi Mihalca9d4dc582016-03-23 13:26:11 +02008498 ALC662_FIXUP_ASUS_Nx50,
Mikhail Paulyshkafc7438b2017-04-21 08:52:42 +02008499 ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE,
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07008500 ALC668_FIXUP_ASUS_Nx51,
Takashi Iwai5b7c5e12018-10-09 14:20:17 +02008501 ALC668_FIXUP_MIC_COEF,
Takashi Iwai11ba6112018-10-07 09:44:17 +02008502 ALC668_FIXUP_ASUS_G751,
Kailang Yang78f4f7c2016-06-07 11:31:34 +08008503 ALC891_FIXUP_HEADSET_MODE,
8504 ALC891_FIXUP_DELL_MIC_NO_PRESENCE,
Shrirang Bagul9b51fe32016-08-01 13:16:17 +08008505 ALC662_FIXUP_ACER_VERITON,
Takashi Iwai1a3f0992016-10-20 12:14:51 +02008506 ALC892_FIXUP_ASROCK_MOBO,
Kailang Yangc6790c82016-11-25 16:15:17 +08008507 ALC662_FIXUP_USI_FUNC,
8508 ALC662_FIXUP_USI_HEADSET_MODE,
Kailang Yangca169cc2017-04-25 16:17:40 +08008509 ALC662_FIXUP_LENOVO_MULTI_CODECS,
Sergey Bostandzhyan00066e92019-09-06 11:33:43 +02008510 ALC669_FIXUP_ACER_ASPIRE_ETHOS,
8511 ALC669_FIXUP_ACER_ASPIRE_ETHOS_SUBWOOFER,
8512 ALC669_FIXUP_ACER_ASPIRE_ETHOS_HEADSET,
David Henningsson6cb3b702010-09-09 08:51:44 +02008513};
8514
Takashi Iwai1727a772013-01-10 09:52:52 +01008515static const struct hda_fixup alc662_fixups[] = {
Daniel T Chen2df03512010-10-10 22:39:28 -04008516 [ALC662_FIXUP_ASPIRE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008517 .type = HDA_FIXUP_PINS,
8518 .v.pins = (const struct hda_pintbl[]) {
Daniel T Chen2df03512010-10-10 22:39:28 -04008519 { 0x15, 0x99130112 }, /* subwoofer */
8520 { }
8521 }
8522 },
Takashi Iwai3e887f32014-01-10 17:50:58 +01008523 [ALC662_FIXUP_LED_GPIO1] = {
8524 .type = HDA_FIXUP_FUNC,
8525 .v.func = alc662_fixup_led_gpio1,
8526 },
David Henningsson6cb3b702010-09-09 08:51:44 +02008527 [ALC662_FIXUP_IDEAPAD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008528 .type = HDA_FIXUP_PINS,
8529 .v.pins = (const struct hda_pintbl[]) {
David Henningsson6cb3b702010-09-09 08:51:44 +02008530 { 0x17, 0x99130112 }, /* subwoofer */
8531 { }
Takashi Iwai3e887f32014-01-10 17:50:58 +01008532 },
8533 .chained = true,
8534 .chain_id = ALC662_FIXUP_LED_GPIO1,
David Henningsson6cb3b702010-09-09 08:51:44 +02008535 },
Todd Broch6be79482010-12-07 16:51:05 -08008536 [ALC272_FIXUP_MARIO] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008537 .type = HDA_FIXUP_FUNC,
Takashi Iwaib5bfbc62011-01-13 14:22:32 +01008538 .v.func = alc272_fixup_mario,
Anisse Astierd2ebd472011-01-20 12:36:21 +01008539 },
8540 [ALC662_FIXUP_CZC_P10T] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008541 .type = HDA_FIXUP_VERBS,
Anisse Astierd2ebd472011-01-20 12:36:21 +01008542 .v.verbs = (const struct hda_verb[]) {
8543 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
8544 {}
8545 }
8546 },
David Henningsson94024cd2011-04-29 14:10:55 +02008547 [ALC662_FIXUP_SKU_IGNORE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008548 .type = HDA_FIXUP_FUNC,
Takashi Iwai23d30f22012-05-07 17:17:32 +02008549 .v.func = alc_fixup_sku_ignore,
Takashi Iwaic6b35872011-03-28 12:05:31 +02008550 },
Takashi Iwaie59ea3e2011-06-29 17:21:00 +02008551 [ALC662_FIXUP_HP_RP5800] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008552 .type = HDA_FIXUP_PINS,
8553 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaie59ea3e2011-06-29 17:21:00 +02008554 { 0x14, 0x0221201f }, /* HP out */
8555 { }
8556 },
8557 .chained = true,
8558 .chain_id = ALC662_FIXUP_SKU_IGNORE
8559 },
Takashi Iwai53c334a2011-08-23 18:27:14 +02008560 [ALC662_FIXUP_ASUS_MODE1] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008561 .type = HDA_FIXUP_PINS,
8562 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008563 { 0x14, 0x99130110 }, /* speaker */
8564 { 0x18, 0x01a19c20 }, /* mic */
8565 { 0x19, 0x99a3092f }, /* int-mic */
8566 { 0x21, 0x0121401f }, /* HP out */
8567 { }
8568 },
8569 .chained = true,
8570 .chain_id = ALC662_FIXUP_SKU_IGNORE
8571 },
8572 [ALC662_FIXUP_ASUS_MODE2] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008573 .type = HDA_FIXUP_PINS,
8574 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai2996bdb2011-08-18 16:02:24 +02008575 { 0x14, 0x99130110 }, /* speaker */
8576 { 0x18, 0x01a19820 }, /* mic */
8577 { 0x19, 0x99a3092f }, /* int-mic */
8578 { 0x1b, 0x0121401f }, /* HP out */
8579 { }
8580 },
Takashi Iwai53c334a2011-08-23 18:27:14 +02008581 .chained = true,
8582 .chain_id = ALC662_FIXUP_SKU_IGNORE
8583 },
8584 [ALC662_FIXUP_ASUS_MODE3] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008585 .type = HDA_FIXUP_PINS,
8586 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008587 { 0x14, 0x99130110 }, /* speaker */
8588 { 0x15, 0x0121441f }, /* HP */
8589 { 0x18, 0x01a19840 }, /* mic */
8590 { 0x19, 0x99a3094f }, /* int-mic */
8591 { 0x21, 0x01211420 }, /* HP2 */
8592 { }
8593 },
8594 .chained = true,
8595 .chain_id = ALC662_FIXUP_SKU_IGNORE
8596 },
8597 [ALC662_FIXUP_ASUS_MODE4] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008598 .type = HDA_FIXUP_PINS,
8599 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008600 { 0x14, 0x99130110 }, /* speaker */
8601 { 0x16, 0x99130111 }, /* speaker */
8602 { 0x18, 0x01a19840 }, /* mic */
8603 { 0x19, 0x99a3094f }, /* int-mic */
8604 { 0x21, 0x0121441f }, /* HP */
8605 { }
8606 },
8607 .chained = true,
8608 .chain_id = ALC662_FIXUP_SKU_IGNORE
8609 },
8610 [ALC662_FIXUP_ASUS_MODE5] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008611 .type = HDA_FIXUP_PINS,
8612 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008613 { 0x14, 0x99130110 }, /* speaker */
8614 { 0x15, 0x0121441f }, /* HP */
8615 { 0x16, 0x99130111 }, /* speaker */
8616 { 0x18, 0x01a19840 }, /* mic */
8617 { 0x19, 0x99a3094f }, /* int-mic */
8618 { }
8619 },
8620 .chained = true,
8621 .chain_id = ALC662_FIXUP_SKU_IGNORE
8622 },
8623 [ALC662_FIXUP_ASUS_MODE6] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008624 .type = HDA_FIXUP_PINS,
8625 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008626 { 0x14, 0x99130110 }, /* speaker */
8627 { 0x15, 0x01211420 }, /* HP2 */
8628 { 0x18, 0x01a19840 }, /* mic */
8629 { 0x19, 0x99a3094f }, /* int-mic */
8630 { 0x1b, 0x0121441f }, /* HP */
8631 { }
8632 },
8633 .chained = true,
8634 .chain_id = ALC662_FIXUP_SKU_IGNORE
8635 },
8636 [ALC662_FIXUP_ASUS_MODE7] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008637 .type = HDA_FIXUP_PINS,
8638 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008639 { 0x14, 0x99130110 }, /* speaker */
8640 { 0x17, 0x99130111 }, /* speaker */
8641 { 0x18, 0x01a19840 }, /* mic */
8642 { 0x19, 0x99a3094f }, /* int-mic */
8643 { 0x1b, 0x01214020 }, /* HP */
8644 { 0x21, 0x0121401f }, /* HP */
8645 { }
8646 },
8647 .chained = true,
8648 .chain_id = ALC662_FIXUP_SKU_IGNORE
8649 },
8650 [ALC662_FIXUP_ASUS_MODE8] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008651 .type = HDA_FIXUP_PINS,
8652 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008653 { 0x14, 0x99130110 }, /* speaker */
8654 { 0x12, 0x99a30970 }, /* int-mic */
8655 { 0x15, 0x01214020 }, /* HP */
8656 { 0x17, 0x99130111 }, /* speaker */
8657 { 0x18, 0x01a19840 }, /* mic */
8658 { 0x21, 0x0121401f }, /* HP */
8659 { }
8660 },
8661 .chained = true,
8662 .chain_id = ALC662_FIXUP_SKU_IGNORE
Takashi Iwai2996bdb2011-08-18 16:02:24 +02008663 },
Takashi Iwai1565cc32012-02-13 12:03:25 +01008664 [ALC662_FIXUP_NO_JACK_DETECT] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008665 .type = HDA_FIXUP_FUNC,
Takashi Iwai1565cc32012-02-13 12:03:25 +01008666 .v.func = alc_fixup_no_jack_detect,
8667 },
David Henningssonedfe3bf2012-06-12 13:15:12 +02008668 [ALC662_FIXUP_ZOTAC_Z68] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008669 .type = HDA_FIXUP_PINS,
8670 .v.pins = (const struct hda_pintbl[]) {
David Henningssonedfe3bf2012-06-12 13:15:12 +02008671 { 0x1b, 0x02214020 }, /* Front HP */
8672 { }
8673 }
8674 },
Takashi Iwai125821a2012-06-22 14:30:29 +02008675 [ALC662_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008676 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02008677 .v.func = alc_fixup_inv_dmic,
Takashi Iwai125821a2012-06-22 14:30:29 +02008678 },
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02008679 [ALC668_FIXUP_DELL_XPS13] = {
8680 .type = HDA_FIXUP_FUNC,
8681 .v.func = alc_fixup_dell_xps13,
8682 .chained = true,
8683 .chain_id = ALC668_FIXUP_DELL_DISABLE_AAMIX
8684 },
Gabriele Mazzotta5e6db662014-05-20 18:58:26 +02008685 [ALC668_FIXUP_DELL_DISABLE_AAMIX] = {
8686 .type = HDA_FIXUP_FUNC,
8687 .v.func = alc_fixup_disable_aamix,
8688 .chained = true,
8689 .chain_id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE
8690 },
Hui Wang493a52a2014-01-14 14:07:36 +08008691 [ALC668_FIXUP_AUTO_MUTE] = {
8692 .type = HDA_FIXUP_FUNC,
8693 .v.func = alc_fixup_auto_mute_via_amp,
8694 .chained = true,
8695 .chain_id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE
8696 },
David Henningsson1f8b46c2015-05-12 14:38:15 +02008697 [ALC662_FIXUP_DELL_MIC_NO_PRESENCE] = {
8698 .type = HDA_FIXUP_PINS,
8699 .v.pins = (const struct hda_pintbl[]) {
8700 { 0x19, 0x03a1113c }, /* use as headset mic, without its own jack detect */
8701 /* headphone mic by setting pin control of 0x1b (headphone out) to in + vref_50 */
8702 { }
8703 },
8704 .chained = true,
8705 .chain_id = ALC662_FIXUP_HEADSET_MODE
8706 },
8707 [ALC662_FIXUP_HEADSET_MODE] = {
8708 .type = HDA_FIXUP_FUNC,
8709 .v.func = alc_fixup_headset_mode_alc662,
8710 },
David Henningsson73bdd592013-04-15 15:44:14 +02008711 [ALC668_FIXUP_DELL_MIC_NO_PRESENCE] = {
8712 .type = HDA_FIXUP_PINS,
8713 .v.pins = (const struct hda_pintbl[]) {
8714 { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
8715 { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */
8716 { }
8717 },
8718 .chained = true,
8719 .chain_id = ALC668_FIXUP_HEADSET_MODE
8720 },
8721 [ALC668_FIXUP_HEADSET_MODE] = {
8722 .type = HDA_FIXUP_FUNC,
8723 .v.func = alc_fixup_headset_mode_alc668,
8724 },
David Henningsson8e54b4a2014-02-07 09:31:07 +01008725 [ALC662_FIXUP_BASS_MODE4_CHMAP] = {
Takashi Iwai8e383952013-10-30 17:41:12 +01008726 .type = HDA_FIXUP_FUNC,
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01008727 .v.func = alc_fixup_bass_chmap,
Takashi Iwai8e383952013-10-30 17:41:12 +01008728 .chained = true,
8729 .chain_id = ALC662_FIXUP_ASUS_MODE4
8730 },
David Henningsson61a75f12014-02-07 09:31:08 +01008731 [ALC662_FIXUP_BASS_16] = {
8732 .type = HDA_FIXUP_PINS,
8733 .v.pins = (const struct hda_pintbl[]) {
8734 {0x16, 0x80106111}, /* bass speaker */
8735 {}
8736 },
8737 .chained = true,
8738 .chain_id = ALC662_FIXUP_BASS_CHMAP,
8739 },
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01008740 [ALC662_FIXUP_BASS_1A] = {
8741 .type = HDA_FIXUP_PINS,
8742 .v.pins = (const struct hda_pintbl[]) {
8743 {0x1a, 0x80106111}, /* bass speaker */
8744 {}
8745 },
David Henningsson8e54b4a2014-02-07 09:31:07 +01008746 .chained = true,
8747 .chain_id = ALC662_FIXUP_BASS_CHMAP,
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01008748 },
David Henningsson8e54b4a2014-02-07 09:31:07 +01008749 [ALC662_FIXUP_BASS_CHMAP] = {
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01008750 .type = HDA_FIXUP_FUNC,
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01008751 .v.func = alc_fixup_bass_chmap,
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01008752 },
Bobi Mihalca9d4dc582016-03-23 13:26:11 +02008753 [ALC662_FIXUP_ASUS_Nx50] = {
8754 .type = HDA_FIXUP_FUNC,
8755 .v.func = alc_fixup_auto_mute_via_amp,
8756 .chained = true,
8757 .chain_id = ALC662_FIXUP_BASS_1A
8758 },
Mikhail Paulyshkafc7438b2017-04-21 08:52:42 +02008759 [ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE] = {
8760 .type = HDA_FIXUP_FUNC,
8761 .v.func = alc_fixup_headset_mode_alc668,
8762 .chain_id = ALC662_FIXUP_BASS_CHMAP
8763 },
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07008764 [ALC668_FIXUP_ASUS_Nx51] = {
8765 .type = HDA_FIXUP_PINS,
8766 .v.pins = (const struct hda_pintbl[]) {
Mikhail Paulyshkafc7438b2017-04-21 08:52:42 +02008767 { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
8768 { 0x1a, 0x90170151 }, /* bass speaker */
8769 { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07008770 {}
8771 },
8772 .chained = true,
Mikhail Paulyshkafc7438b2017-04-21 08:52:42 +02008773 .chain_id = ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE,
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07008774 },
Takashi Iwai5b7c5e12018-10-09 14:20:17 +02008775 [ALC668_FIXUP_MIC_COEF] = {
Takashi Iwai11ba6112018-10-07 09:44:17 +02008776 .type = HDA_FIXUP_VERBS,
8777 .v.verbs = (const struct hda_verb[]) {
8778 { 0x20, AC_VERB_SET_COEF_INDEX, 0xc3 },
8779 { 0x20, AC_VERB_SET_PROC_COEF, 0x4000 },
8780 {}
8781 },
8782 },
Takashi Iwai5b7c5e12018-10-09 14:20:17 +02008783 [ALC668_FIXUP_ASUS_G751] = {
8784 .type = HDA_FIXUP_PINS,
8785 .v.pins = (const struct hda_pintbl[]) {
8786 { 0x16, 0x0421101f }, /* HP */
8787 {}
8788 },
8789 .chained = true,
8790 .chain_id = ALC668_FIXUP_MIC_COEF
8791 },
Kailang Yang78f4f7c2016-06-07 11:31:34 +08008792 [ALC891_FIXUP_HEADSET_MODE] = {
8793 .type = HDA_FIXUP_FUNC,
8794 .v.func = alc_fixup_headset_mode,
8795 },
8796 [ALC891_FIXUP_DELL_MIC_NO_PRESENCE] = {
8797 .type = HDA_FIXUP_PINS,
8798 .v.pins = (const struct hda_pintbl[]) {
8799 { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
8800 { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */
8801 { }
8802 },
8803 .chained = true,
8804 .chain_id = ALC891_FIXUP_HEADSET_MODE
8805 },
Shrirang Bagul9b51fe32016-08-01 13:16:17 +08008806 [ALC662_FIXUP_ACER_VERITON] = {
8807 .type = HDA_FIXUP_PINS,
8808 .v.pins = (const struct hda_pintbl[]) {
8809 { 0x15, 0x50170120 }, /* no internal speaker */
8810 { }
8811 }
8812 },
Takashi Iwai1a3f0992016-10-20 12:14:51 +02008813 [ALC892_FIXUP_ASROCK_MOBO] = {
8814 .type = HDA_FIXUP_PINS,
8815 .v.pins = (const struct hda_pintbl[]) {
8816 { 0x15, 0x40f000f0 }, /* disabled */
8817 { 0x16, 0x40f000f0 }, /* disabled */
Takashi Iwai1a3f0992016-10-20 12:14:51 +02008818 { }
8819 }
8820 },
Kailang Yangc6790c82016-11-25 16:15:17 +08008821 [ALC662_FIXUP_USI_FUNC] = {
8822 .type = HDA_FIXUP_FUNC,
8823 .v.func = alc662_fixup_usi_headset_mic,
8824 },
8825 [ALC662_FIXUP_USI_HEADSET_MODE] = {
8826 .type = HDA_FIXUP_PINS,
8827 .v.pins = (const struct hda_pintbl[]) {
8828 { 0x19, 0x02a1913c }, /* use as headset mic, without its own jack detect */
8829 { 0x18, 0x01a1903d },
8830 { }
8831 },
8832 .chained = true,
8833 .chain_id = ALC662_FIXUP_USI_FUNC
8834 },
Kailang Yangca169cc2017-04-25 16:17:40 +08008835 [ALC662_FIXUP_LENOVO_MULTI_CODECS] = {
8836 .type = HDA_FIXUP_FUNC,
8837 .v.func = alc233_alc662_fixup_lenovo_dual_codecs,
8838 },
Sergey Bostandzhyan00066e92019-09-06 11:33:43 +02008839 [ALC669_FIXUP_ACER_ASPIRE_ETHOS_HEADSET] = {
8840 .type = HDA_FIXUP_FUNC,
8841 .v.func = alc662_fixup_aspire_ethos_hp,
8842 },
8843 [ALC669_FIXUP_ACER_ASPIRE_ETHOS_SUBWOOFER] = {
8844 .type = HDA_FIXUP_VERBS,
8845 /* subwoofer needs an extra GPIO setting to become audible */
8846 .v.verbs = (const struct hda_verb[]) {
8847 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
8848 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
8849 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
8850 { }
8851 },
8852 .chained = true,
8853 .chain_id = ALC669_FIXUP_ACER_ASPIRE_ETHOS_HEADSET
8854 },
8855 [ALC669_FIXUP_ACER_ASPIRE_ETHOS] = {
8856 .type = HDA_FIXUP_PINS,
8857 .v.pins = (const struct hda_pintbl[]) {
8858 { 0x15, 0x92130110 }, /* front speakers */
8859 { 0x18, 0x99130111 }, /* center/subwoofer */
8860 { 0x1b, 0x11130012 }, /* surround plus jack for HP */
8861 { }
8862 },
8863 .chained = true,
8864 .chain_id = ALC669_FIXUP_ACER_ASPIRE_ETHOS_SUBWOOFER
8865 },
David Henningsson6cb3b702010-09-09 08:51:44 +02008866};
8867
Takashi Iwaia9111322011-05-02 11:30:18 +02008868static const struct snd_pci_quirk alc662_fixup_tbl[] = {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008869 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_FIXUP_ASUS_MODE2),
Takashi Iwaid3d38352013-08-19 20:05:50 +02008870 SND_PCI_QUIRK(0x1025, 0x022f, "Acer Aspire One", ALC662_FIXUP_INV_DMIC),
David Henningsson02f6ff92015-12-07 11:29:31 +01008871 SND_PCI_QUIRK(0x1025, 0x0241, "Packard Bell DOTS", ALC662_FIXUP_INV_DMIC),
David Henningssona6c47a82011-02-10 15:39:19 +01008872 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
David Henningsson94024cd2011-04-29 14:10:55 +02008873 SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
Takashi Iwai125821a2012-06-22 14:30:29 +02008874 SND_PCI_QUIRK(0x1025, 0x0349, "eMachines eM250", ALC662_FIXUP_INV_DMIC),
Takashi Iwai18019282013-08-16 08:17:05 +02008875 SND_PCI_QUIRK(0x1025, 0x034a, "Gateway LT27", ALC662_FIXUP_INV_DMIC),
Daniel T Chen2df03512010-10-10 22:39:28 -04008876 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
David Henningsson73bdd592013-04-15 15:44:14 +02008877 SND_PCI_QUIRK(0x1028, 0x05d8, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
8878 SND_PCI_QUIRK(0x1028, 0x05db, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
Takashi Iwaic5d019c2014-07-22 17:33:32 +02008879 SND_PCI_QUIRK(0x1028, 0x05fe, "Dell XPS 15", ALC668_FIXUP_DELL_XPS13),
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02008880 SND_PCI_QUIRK(0x1028, 0x060a, "Dell XPS 13", ALC668_FIXUP_DELL_XPS13),
Niranjan Sivakumar467e1432015-09-05 18:20:35 +02008881 SND_PCI_QUIRK(0x1028, 0x060d, "Dell M3800", ALC668_FIXUP_DELL_XPS13),
David Henningsson09d20142013-11-20 11:43:30 +01008882 SND_PCI_QUIRK(0x1028, 0x0625, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
David Henningssonad8ff99e2013-11-07 09:28:59 +01008883 SND_PCI_QUIRK(0x1028, 0x0626, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
Kailang Yang8dc9abb2014-04-16 15:53:12 +08008884 SND_PCI_QUIRK(0x1028, 0x0696, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
8885 SND_PCI_QUIRK(0x1028, 0x0698, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
Kailang Yang6a98e342014-10-27 16:20:30 +08008886 SND_PCI_QUIRK(0x1028, 0x069f, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
Takashi Iwaie59ea3e2011-06-29 17:21:00 +02008887 SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800),
Kaho Ng2da2dc92016-05-09 00:27:49 +08008888 SND_PCI_QUIRK(0x1043, 0x1080, "Asus UX501VW", ALC668_FIXUP_HEADSET_MODE),
Bobi Mihalca83a9efb2016-03-23 13:32:33 +02008889 SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_ASUS_Nx50),
Takashi Iwaidb8948e2016-01-18 09:17:30 +01008890 SND_PCI_QUIRK(0x1043, 0x13df, "Asus N550JX", ALC662_FIXUP_BASS_1A),
Bobi Mihalca9d4dc582016-03-23 13:26:11 +02008891 SND_PCI_QUIRK(0x1043, 0x129d, "Asus N750", ALC662_FIXUP_ASUS_Nx50),
Takashi Iwai11ba6112018-10-07 09:44:17 +02008892 SND_PCI_QUIRK(0x1043, 0x12ff, "ASUS G751", ALC668_FIXUP_ASUS_G751),
David Henningsson8e54b4a2014-02-07 09:31:07 +01008893 SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
David Henningsson61a75f12014-02-07 09:31:08 +01008894 SND_PCI_QUIRK(0x1043, 0x15a7, "ASUS UX51VZH", ALC662_FIXUP_BASS_16),
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07008895 SND_PCI_QUIRK(0x1043, 0x177d, "ASUS N551", ALC668_FIXUP_ASUS_Nx51),
8896 SND_PCI_QUIRK(0x1043, 0x17bd, "ASUS N751", ALC668_FIXUP_ASUS_Nx51),
Takashi Iwaic7efff92017-01-04 21:38:16 +01008897 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71SL", ALC662_FIXUP_ASUS_MODE8),
David Henningsson61a75f12014-02-07 09:31:08 +01008898 SND_PCI_QUIRK(0x1043, 0x1b73, "ASUS N55SF", ALC662_FIXUP_BASS_16),
David Henningsson8e54b4a2014-02-07 09:31:07 +01008899 SND_PCI_QUIRK(0x1043, 0x1bf3, "ASUS N76VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
Takashi Iwai1565cc32012-02-13 12:03:25 +01008900 SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT),
Takashi Iwai53c334a2011-08-23 18:27:14 +02008901 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2),
Daniel T Chena0e90ac2010-11-20 10:20:35 -05008902 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
Kailang Yangc6790c82016-11-25 16:15:17 +08008903 SND_PCI_QUIRK(0x14cd, 0x5003, "USI", ALC662_FIXUP_USI_HEADSET_MODE),
Kailang Yangca169cc2017-04-25 16:17:40 +08008904 SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC662_FIXUP_LENOVO_MULTI_CODECS),
Valentine Sinitsynd4118582010-10-01 22:24:08 +06008905 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
David Henningsson6cb3b702010-09-09 08:51:44 +02008906 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
Takashi Iwai1a3f0992016-10-20 12:14:51 +02008907 SND_PCI_QUIRK(0x1849, 0x5892, "ASRock B150M", ALC892_FIXUP_ASROCK_MOBO),
David Henningssonedfe3bf2012-06-12 13:15:12 +02008908 SND_PCI_QUIRK(0x19da, 0xa130, "Zotac Z68", ALC662_FIXUP_ZOTAC_Z68),
Shrirang Bagul9b51fe32016-08-01 13:16:17 +08008909 SND_PCI_QUIRK(0x1b0a, 0x01b8, "ACER Veriton", ALC662_FIXUP_ACER_VERITON),
Anisse Astierd2ebd472011-01-20 12:36:21 +01008910 SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
Sergey Bostandzhyan00066e92019-09-06 11:33:43 +02008911 SND_PCI_QUIRK(0x1025, 0x0566, "Acer Aspire Ethos 8951G", ALC669_FIXUP_ACER_ASPIRE_ETHOS),
Takashi Iwai53c334a2011-08-23 18:27:14 +02008912
8913#if 0
8914 /* Below is a quirk table taken from the old code.
8915 * Basically the device should work as is without the fixup table.
8916 * If BIOS doesn't give a proper info, enable the corresponding
8917 * fixup entry.
Jesper Juhl7d7eb9e2012-04-12 22:11:25 +02008918 */
Takashi Iwai53c334a2011-08-23 18:27:14 +02008919 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC662_FIXUP_ASUS_MODE1),
8920 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC662_FIXUP_ASUS_MODE3),
8921 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC662_FIXUP_ASUS_MODE1),
8922 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC662_FIXUP_ASUS_MODE3),
8923 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
8924 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8925 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
8926 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC662_FIXUP_ASUS_MODE1),
8927 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC662_FIXUP_ASUS_MODE1),
8928 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8929 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC662_FIXUP_ASUS_MODE7),
8930 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC662_FIXUP_ASUS_MODE7),
8931 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC662_FIXUP_ASUS_MODE8),
8932 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC662_FIXUP_ASUS_MODE3),
8933 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC662_FIXUP_ASUS_MODE1),
8934 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8935 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_FIXUP_ASUS_MODE2),
8936 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC662_FIXUP_ASUS_MODE1),
8937 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8938 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
8939 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
8940 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8941 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC662_FIXUP_ASUS_MODE1),
8942 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC662_FIXUP_ASUS_MODE3),
8943 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_FIXUP_ASUS_MODE2),
8944 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8945 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC662_FIXUP_ASUS_MODE5),
8946 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
8947 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8948 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC662_FIXUP_ASUS_MODE1),
8949 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8950 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8951 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC662_FIXUP_ASUS_MODE3),
8952 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC662_FIXUP_ASUS_MODE3),
8953 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC662_FIXUP_ASUS_MODE1),
8954 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC662_FIXUP_ASUS_MODE1),
8955 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC662_FIXUP_ASUS_MODE1),
8956 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC662_FIXUP_ASUS_MODE1),
8957 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC662_FIXUP_ASUS_MODE1),
8958 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8959 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_FIXUP_ASUS_MODE2),
8960 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC662_FIXUP_ASUS_MODE1),
8961 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
8962 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC662_FIXUP_ASUS_MODE3),
8963 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC662_FIXUP_ASUS_MODE1),
8964 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC662_FIXUP_ASUS_MODE1),
8965 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC662_FIXUP_ASUS_MODE1),
8966 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_FIXUP_ASUS_MODE2),
8967 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
8968 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE4),
8969#endif
David Henningsson6cb3b702010-09-09 08:51:44 +02008970 {}
8971};
8972
Takashi Iwai1727a772013-01-10 09:52:52 +01008973static const struct hda_model_fixup alc662_fixup_models[] = {
Takashi Iwaiaa3841b2018-06-26 07:42:40 +02008974 {.id = ALC662_FIXUP_ASPIRE, .name = "aspire"},
8975 {.id = ALC662_FIXUP_IDEAPAD, .name = "ideapad"},
Todd Broch6be79482010-12-07 16:51:05 -08008976 {.id = ALC272_FIXUP_MARIO, .name = "mario"},
Takashi Iwaiaa3841b2018-06-26 07:42:40 +02008977 {.id = ALC662_FIXUP_HP_RP5800, .name = "hp-rp5800"},
Takashi Iwai53c334a2011-08-23 18:27:14 +02008978 {.id = ALC662_FIXUP_ASUS_MODE1, .name = "asus-mode1"},
8979 {.id = ALC662_FIXUP_ASUS_MODE2, .name = "asus-mode2"},
8980 {.id = ALC662_FIXUP_ASUS_MODE3, .name = "asus-mode3"},
8981 {.id = ALC662_FIXUP_ASUS_MODE4, .name = "asus-mode4"},
8982 {.id = ALC662_FIXUP_ASUS_MODE5, .name = "asus-mode5"},
8983 {.id = ALC662_FIXUP_ASUS_MODE6, .name = "asus-mode6"},
8984 {.id = ALC662_FIXUP_ASUS_MODE7, .name = "asus-mode7"},
8985 {.id = ALC662_FIXUP_ASUS_MODE8, .name = "asus-mode8"},
Takashi Iwaiaa3841b2018-06-26 07:42:40 +02008986 {.id = ALC662_FIXUP_ZOTAC_Z68, .name = "zotac-z68"},
Takashi Iwai6e72aa52012-06-25 10:52:25 +02008987 {.id = ALC662_FIXUP_INV_DMIC, .name = "inv-dmic"},
Takashi Iwaiaa3841b2018-06-26 07:42:40 +02008988 {.id = ALC662_FIXUP_DELL_MIC_NO_PRESENCE, .name = "alc662-headset-multi"},
David Henningssone32aa852013-06-17 11:04:02 +02008989 {.id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE, .name = "dell-headset-multi"},
Takashi Iwaiaa3841b2018-06-26 07:42:40 +02008990 {.id = ALC662_FIXUP_HEADSET_MODE, .name = "alc662-headset"},
8991 {.id = ALC668_FIXUP_HEADSET_MODE, .name = "alc668-headset"},
8992 {.id = ALC662_FIXUP_BASS_16, .name = "bass16"},
8993 {.id = ALC662_FIXUP_BASS_1A, .name = "bass1a"},
8994 {.id = ALC668_FIXUP_AUTO_MUTE, .name = "automute"},
8995 {.id = ALC668_FIXUP_DELL_XPS13, .name = "dell-xps13"},
8996 {.id = ALC662_FIXUP_ASUS_Nx50, .name = "asus-nx50"},
8997 {.id = ALC668_FIXUP_ASUS_Nx51, .name = "asus-nx51"},
Takashi Iwai40c51672018-10-07 09:47:39 +02008998 {.id = ALC668_FIXUP_ASUS_G751, .name = "asus-g751"},
Takashi Iwaiaa3841b2018-06-26 07:42:40 +02008999 {.id = ALC891_FIXUP_HEADSET_MODE, .name = "alc891-headset"},
9000 {.id = ALC891_FIXUP_DELL_MIC_NO_PRESENCE, .name = "alc891-headset-multi"},
9001 {.id = ALC662_FIXUP_ACER_VERITON, .name = "acer-veriton"},
9002 {.id = ALC892_FIXUP_ASROCK_MOBO, .name = "asrock-mobo"},
9003 {.id = ALC662_FIXUP_USI_HEADSET_MODE, .name = "usi-headset"},
Takashi Iwaiba90d6a2017-05-22 16:38:47 +02009004 {.id = ALC662_FIXUP_LENOVO_MULTI_CODECS, .name = "dual-codecs"},
Sergey Bostandzhyan00066e92019-09-06 11:33:43 +02009005 {.id = ALC669_FIXUP_ACER_ASPIRE_ETHOS, .name = "aspire-ethos"},
Todd Broch6be79482010-12-07 16:51:05 -08009006 {}
9007};
David Henningsson6cb3b702010-09-09 08:51:44 +02009008
Hui Wang532895c2014-05-29 15:59:19 +08009009static const struct snd_hda_pin_quirk alc662_pin_fixup_tbl[] = {
Kailang Yang78f4f7c2016-06-07 11:31:34 +08009010 SND_HDA_PIN_QUIRK(0x10ec0867, 0x1028, "Dell", ALC891_FIXUP_DELL_MIC_NO_PRESENCE,
9011 {0x17, 0x02211010},
9012 {0x18, 0x01a19030},
9013 {0x1a, 0x01813040},
9014 {0x21, 0x01014020}),
Hui Wang4b4e0e32019-07-16 15:21:34 +08009015 SND_HDA_PIN_QUIRK(0x10ec0867, 0x1028, "Dell", ALC891_FIXUP_DELL_MIC_NO_PRESENCE,
9016 {0x16, 0x01813030},
9017 {0x17, 0x02211010},
9018 {0x18, 0x01a19040},
9019 {0x21, 0x01014020}),
David Henningsson1f8b46c2015-05-12 14:38:15 +02009020 SND_HDA_PIN_QUIRK(0x10ec0662, 0x1028, "Dell", ALC662_FIXUP_DELL_MIC_NO_PRESENCE,
David Henningsson1f8b46c2015-05-12 14:38:15 +02009021 {0x14, 0x01014010},
David Henningsson1f8b46c2015-05-12 14:38:15 +02009022 {0x18, 0x01a19020},
David Henningsson1f8b46c2015-05-12 14:38:15 +02009023 {0x1a, 0x0181302f},
Hui Wang11580292015-08-03 11:03:49 +08009024 {0x1b, 0x0221401f}),
David Henningsson76c21322014-06-24 14:46:54 +02009025 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
9026 {0x12, 0x99a30130},
9027 {0x14, 0x90170110},
9028 {0x15, 0x0321101f},
Hui Wang11580292015-08-03 11:03:49 +08009029 {0x16, 0x03011020}),
David Henningsson76c21322014-06-24 14:46:54 +02009030 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
9031 {0x12, 0x99a30140},
9032 {0x14, 0x90170110},
9033 {0x15, 0x0321101f},
Hui Wang11580292015-08-03 11:03:49 +08009034 {0x16, 0x03011020}),
David Henningsson76c21322014-06-24 14:46:54 +02009035 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
9036 {0x12, 0x99a30150},
9037 {0x14, 0x90170110},
9038 {0x15, 0x0321101f},
Hui Wang11580292015-08-03 11:03:49 +08009039 {0x16, 0x03011020}),
David Henningsson76c21322014-06-24 14:46:54 +02009040 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
David Henningsson76c21322014-06-24 14:46:54 +02009041 {0x14, 0x90170110},
9042 {0x15, 0x0321101f},
Hui Wang11580292015-08-03 11:03:49 +08009043 {0x16, 0x03011020}),
David Henningsson76c21322014-06-24 14:46:54 +02009044 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell XPS 15", ALC668_FIXUP_AUTO_MUTE,
9045 {0x12, 0x90a60130},
9046 {0x14, 0x90170110},
Hui Wang11580292015-08-03 11:03:49 +08009047 {0x15, 0x0321101f}),
Hui Wang532895c2014-05-29 15:59:19 +08009048 {}
9049};
9050
Takashi Iwai1d045db2011-07-07 18:23:21 +02009051/*
9052 */
Kailang Yangbc9f98a2007-04-12 13:06:07 +02009053static int patch_alc662(struct hda_codec *codec)
9054{
9055 struct alc_spec *spec;
Takashi Iwai3de95172012-05-07 18:03:15 +02009056 int err;
Kailang Yangbc9f98a2007-04-12 13:06:07 +02009057
Takashi Iwai3de95172012-05-07 18:03:15 +02009058 err = alc_alloc_spec(codec, 0x0b);
9059 if (err < 0)
9060 return err;
Kailang Yangbc9f98a2007-04-12 13:06:07 +02009061
Takashi Iwai3de95172012-05-07 18:03:15 +02009062 spec = codec->spec;
Takashi Iwai1f0f4b82011-06-27 10:52:59 +02009063
Takashi Iwai225068a2015-05-29 10:42:14 +02009064 spec->shutup = alc_eapd_shutup;
9065
Takashi Iwai53c334a2011-08-23 18:27:14 +02009066 /* handle multiple HPs as is */
9067 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
9068
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +02009069 alc_fix_pll_init(codec, 0x20, 0x04, 15);
9070
Takashi Iwai7639a062015-03-03 10:07:24 +01009071 switch (codec->core.vendor_id) {
Kailang Yangf3f91852014-10-24 15:43:46 +08009072 case 0x10ec0668:
9073 spec->init_hook = alc668_restore_default_value;
9074 break;
Kailang Yangf3f91852014-10-24 15:43:46 +08009075 }
Kailang Yang8663ff72012-06-29 09:35:52 +02009076
Takashi Iwaic9af7532019-05-10 11:01:43 +02009077 alc_pre_init(codec);
9078
Takashi Iwai1727a772013-01-10 09:52:52 +01009079 snd_hda_pick_fixup(codec, alc662_fixup_models,
Takashi Iwai8e5a0502012-06-21 15:49:33 +02009080 alc662_fixup_tbl, alc662_fixups);
Hui Wang0fc1e442019-08-16 14:27:39 +08009081 snd_hda_pick_pin_fixup(codec, alc662_pin_fixup_tbl, alc662_fixups, true);
Takashi Iwai1727a772013-01-10 09:52:52 +01009082 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai8e5a0502012-06-21 15:49:33 +02009083
9084 alc_auto_parse_customize_define(codec);
9085
Takashi Iwai7504b6c2013-03-18 11:25:51 +01009086 if (has_cdefine_beep(codec))
9087 spec->gen.beep_nid = 0x01;
9088
Takashi Iwai1bb7e432011-10-17 16:50:59 +02009089 if ((alc_get_coef0(codec) & (1 << 14)) &&
Takashi Iwai5100cd02014-02-15 10:03:19 +01009090 codec->bus->pci && codec->bus->pci->subsystem_vendor == 0x1025 &&
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02009091 spec->cdefine.platform_type == 1) {
Wei Yongjun6134b1a2013-04-18 11:12:59 +08009092 err = alc_codec_rename(codec, "ALC272X");
9093 if (err < 0)
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02009094 goto error;
Takashi Iwai20ca0c32011-10-17 16:00:35 +02009095 }
Kailang Yang274693f2009-12-03 10:07:50 +01009096
Takashi Iwaib9c51062011-08-24 18:08:07 +02009097 /* automatic parse from the BIOS config */
9098 err = alc662_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02009099 if (err < 0)
9100 goto error;
Kailang Yangbc9f98a2007-04-12 13:06:07 +02009101
Takashi Iwai7504b6c2013-03-18 11:25:51 +01009102 if (!spec->gen.no_analog && spec->gen.beep_nid) {
Takashi Iwai7639a062015-03-03 10:07:24 +01009103 switch (codec->core.vendor_id) {
Kailang Yangda00c242010-03-19 11:23:45 +01009104 case 0x10ec0662:
Takashi Iwaifea80fa2018-06-20 12:52:46 +02009105 err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
Kailang Yangda00c242010-03-19 11:23:45 +01009106 break;
9107 case 0x10ec0272:
9108 case 0x10ec0663:
9109 case 0x10ec0665:
Kailang Yang9ad54542013-11-26 15:41:40 +08009110 case 0x10ec0668:
Takashi Iwaifea80fa2018-06-20 12:52:46 +02009111 err = set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
Kailang Yangda00c242010-03-19 11:23:45 +01009112 break;
9113 case 0x10ec0273:
Takashi Iwaifea80fa2018-06-20 12:52:46 +02009114 err = set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
Kailang Yangda00c242010-03-19 11:23:45 +01009115 break;
9116 }
Takashi Iwaifea80fa2018-06-20 12:52:46 +02009117 if (err < 0)
9118 goto error;
Kailang Yangcec27c82010-02-04 14:18:18 +01009119 }
Takashi Iwai2134ea42008-01-10 16:53:55 +01009120
Takashi Iwai1727a772013-01-10 09:52:52 +01009121 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01009122
Kailang Yangbc9f98a2007-04-12 13:06:07 +02009123 return 0;
Kailang Yangbc9f98a2007-04-12 13:06:07 +02009124
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02009125 error:
9126 alc_free(codec);
9127 return err;
Kailang Yangb478b992011-05-18 11:51:15 +02009128}
9129
Kailang Yangbc9f98a2007-04-12 13:06:07 +02009130/*
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009131 * ALC680 support
9132 */
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009133
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009134static int alc680_parse_auto_config(struct hda_codec *codec)
9135{
Takashi Iwai3e6179b2011-07-08 16:55:13 +02009136 return alc_parse_auto_config(codec, NULL, NULL);
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009137}
9138
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009139/*
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009140 */
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009141static int patch_alc680(struct hda_codec *codec)
9142{
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009143 int err;
9144
Takashi Iwai1f0f4b82011-06-27 10:52:59 +02009145 /* ALC680 has no aa-loopback mixer */
Takashi Iwai3de95172012-05-07 18:03:15 +02009146 err = alc_alloc_spec(codec, 0);
9147 if (err < 0)
9148 return err;
Takashi Iwai1f0f4b82011-06-27 10:52:59 +02009149
Takashi Iwai1ebec5f2011-08-15 13:21:48 +02009150 /* automatic parse from the BIOS config */
9151 err = alc680_parse_auto_config(codec);
9152 if (err < 0) {
9153 alc_free(codec);
9154 return err;
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009155 }
9156
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009157 return 0;
9158}
9159
9160/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07009161 * patch entries
9162 */
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009163static const struct hda_device_id snd_hda_id_realtek[] = {
Kailang Yang0a6f0602017-06-30 16:00:48 +08009164 HDA_CODEC_ENTRY(0x10ec0215, "ALC215", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009165 HDA_CODEC_ENTRY(0x10ec0221, "ALC221", patch_alc269),
Hui Wang2a36c162019-09-04 13:53:27 +08009166 HDA_CODEC_ENTRY(0x10ec0222, "ALC222", patch_alc269),
Kailang Yang42314302016-02-03 15:03:50 +08009167 HDA_CODEC_ENTRY(0x10ec0225, "ALC225", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009168 HDA_CODEC_ENTRY(0x10ec0231, "ALC231", patch_alc269),
9169 HDA_CODEC_ENTRY(0x10ec0233, "ALC233", patch_alc269),
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08009170 HDA_CODEC_ENTRY(0x10ec0234, "ALC234", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009171 HDA_CODEC_ENTRY(0x10ec0235, "ALC233", patch_alc269),
Kailang Yang736f20a2017-10-20 15:06:34 +08009172 HDA_CODEC_ENTRY(0x10ec0236, "ALC236", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009173 HDA_CODEC_ENTRY(0x10ec0255, "ALC255", patch_alc269),
9174 HDA_CODEC_ENTRY(0x10ec0256, "ALC256", patch_alc269),
Kailang Yangf429e7e2017-12-05 15:38:24 +08009175 HDA_CODEC_ENTRY(0x10ec0257, "ALC257", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009176 HDA_CODEC_ENTRY(0x10ec0260, "ALC260", patch_alc260),
9177 HDA_CODEC_ENTRY(0x10ec0262, "ALC262", patch_alc262),
9178 HDA_CODEC_ENTRY(0x10ec0267, "ALC267", patch_alc268),
9179 HDA_CODEC_ENTRY(0x10ec0268, "ALC268", patch_alc268),
9180 HDA_CODEC_ENTRY(0x10ec0269, "ALC269", patch_alc269),
9181 HDA_CODEC_ENTRY(0x10ec0270, "ALC270", patch_alc269),
9182 HDA_CODEC_ENTRY(0x10ec0272, "ALC272", patch_alc662),
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08009183 HDA_CODEC_ENTRY(0x10ec0274, "ALC274", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009184 HDA_CODEC_ENTRY(0x10ec0275, "ALC275", patch_alc269),
9185 HDA_CODEC_ENTRY(0x10ec0276, "ALC276", patch_alc269),
9186 HDA_CODEC_ENTRY(0x10ec0280, "ALC280", patch_alc269),
9187 HDA_CODEC_ENTRY(0x10ec0282, "ALC282", patch_alc269),
9188 HDA_CODEC_ENTRY(0x10ec0283, "ALC283", patch_alc269),
9189 HDA_CODEC_ENTRY(0x10ec0284, "ALC284", patch_alc269),
Kailang Yang0a6f0602017-06-30 16:00:48 +08009190 HDA_CODEC_ENTRY(0x10ec0285, "ALC285", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009191 HDA_CODEC_ENTRY(0x10ec0286, "ALC286", patch_alc269),
9192 HDA_CODEC_ENTRY(0x10ec0288, "ALC288", patch_alc269),
Kailang Yang0a6f0602017-06-30 16:00:48 +08009193 HDA_CODEC_ENTRY(0x10ec0289, "ALC289", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009194 HDA_CODEC_ENTRY(0x10ec0290, "ALC290", patch_alc269),
9195 HDA_CODEC_ENTRY(0x10ec0292, "ALC292", patch_alc269),
9196 HDA_CODEC_ENTRY(0x10ec0293, "ALC293", patch_alc269),
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08009197 HDA_CODEC_ENTRY(0x10ec0294, "ALC294", patch_alc269),
Kailang Yang7d727862016-05-24 16:46:07 +08009198 HDA_CODEC_ENTRY(0x10ec0295, "ALC295", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009199 HDA_CODEC_ENTRY(0x10ec0298, "ALC298", patch_alc269),
Kailang Yang28f1f9b2017-01-04 14:49:07 +08009200 HDA_CODEC_ENTRY(0x10ec0299, "ALC299", patch_alc269),
Kailang Yang1078bef2018-11-08 16:36:15 +08009201 HDA_CODEC_ENTRY(0x10ec0300, "ALC300", patch_alc269),
Kailang Yangf0778872019-10-24 15:13:32 +08009202 HDA_CODEC_ENTRY(0x10ec0623, "ALC623", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009203 HDA_CODEC_REV_ENTRY(0x10ec0861, 0x100340, "ALC660", patch_alc861),
9204 HDA_CODEC_ENTRY(0x10ec0660, "ALC660-VD", patch_alc861vd),
9205 HDA_CODEC_ENTRY(0x10ec0861, "ALC861", patch_alc861),
9206 HDA_CODEC_ENTRY(0x10ec0862, "ALC861-VD", patch_alc861vd),
9207 HDA_CODEC_REV_ENTRY(0x10ec0662, 0x100002, "ALC662 rev2", patch_alc882),
9208 HDA_CODEC_REV_ENTRY(0x10ec0662, 0x100101, "ALC662 rev1", patch_alc662),
9209 HDA_CODEC_REV_ENTRY(0x10ec0662, 0x100300, "ALC662 rev3", patch_alc662),
9210 HDA_CODEC_ENTRY(0x10ec0663, "ALC663", patch_alc662),
9211 HDA_CODEC_ENTRY(0x10ec0665, "ALC665", patch_alc662),
9212 HDA_CODEC_ENTRY(0x10ec0667, "ALC667", patch_alc662),
9213 HDA_CODEC_ENTRY(0x10ec0668, "ALC668", patch_alc662),
9214 HDA_CODEC_ENTRY(0x10ec0670, "ALC670", patch_alc662),
9215 HDA_CODEC_ENTRY(0x10ec0671, "ALC671", patch_alc662),
9216 HDA_CODEC_ENTRY(0x10ec0680, "ALC680", patch_alc680),
Kailang Yang6fbae352016-05-30 16:44:20 +08009217 HDA_CODEC_ENTRY(0x10ec0700, "ALC700", patch_alc269),
9218 HDA_CODEC_ENTRY(0x10ec0701, "ALC701", patch_alc269),
9219 HDA_CODEC_ENTRY(0x10ec0703, "ALC703", patch_alc269),
Kailang Yang83629532019-05-02 16:03:26 +08009220 HDA_CODEC_ENTRY(0x10ec0711, "ALC711", patch_alc269),
Kailang Yang78f4f7c2016-06-07 11:31:34 +08009221 HDA_CODEC_ENTRY(0x10ec0867, "ALC891", patch_alc662),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009222 HDA_CODEC_ENTRY(0x10ec0880, "ALC880", patch_alc880),
9223 HDA_CODEC_ENTRY(0x10ec0882, "ALC882", patch_alc882),
9224 HDA_CODEC_ENTRY(0x10ec0883, "ALC883", patch_alc882),
9225 HDA_CODEC_REV_ENTRY(0x10ec0885, 0x100101, "ALC889A", patch_alc882),
9226 HDA_CODEC_REV_ENTRY(0x10ec0885, 0x100103, "ALC889A", patch_alc882),
9227 HDA_CODEC_ENTRY(0x10ec0885, "ALC885", patch_alc882),
9228 HDA_CODEC_ENTRY(0x10ec0887, "ALC887", patch_alc882),
9229 HDA_CODEC_REV_ENTRY(0x10ec0888, 0x100101, "ALC1200", patch_alc882),
9230 HDA_CODEC_ENTRY(0x10ec0888, "ALC888", patch_alc882),
9231 HDA_CODEC_ENTRY(0x10ec0889, "ALC889", patch_alc882),
9232 HDA_CODEC_ENTRY(0x10ec0892, "ALC892", patch_alc662),
9233 HDA_CODEC_ENTRY(0x10ec0899, "ALC898", patch_alc882),
9234 HDA_CODEC_ENTRY(0x10ec0900, "ALC1150", patch_alc882),
Kailang Yang65553b12017-07-11 15:15:47 +08009235 HDA_CODEC_ENTRY(0x10ec1168, "ALC1220", patch_alc882),
Kailang Yanga535ad52017-01-16 16:59:26 +08009236 HDA_CODEC_ENTRY(0x10ec1220, "ALC1220", patch_alc882),
Linus Torvalds1da177e2005-04-16 15:20:36 -07009237 {} /* terminator */
9238};
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009239MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_realtek);
Takashi Iwai1289e9e2008-11-27 15:47:11 +01009240
9241MODULE_LICENSE("GPL");
9242MODULE_DESCRIPTION("Realtek HD-audio codec");
9243
Takashi Iwaid8a766a2015-02-17 15:25:37 +01009244static struct hda_codec_driver realtek_driver = {
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009245 .id = snd_hda_id_realtek,
Takashi Iwai1289e9e2008-11-27 15:47:11 +01009246};
9247
Takashi Iwaid8a766a2015-02-17 15:25:37 +01009248module_hda_codec_driver(realtek_driver);