blob: 2ee703c2da78f7e8ec94b300fccfe413ea96bd4a [file] [log] [blame]
Thomas Gleixnerd0fa1172019-05-20 19:07:57 +02001// SPDX-License-Identifier: GPL-2.0-or-later
Linus Torvalds1da177e2005-04-16 15:20:36 -07002/*
3 * Universal Interface for Intel High Definition Audio Codec
4 *
Takashi Iwai1d045db2011-07-07 18:23:21 +02005 * HD audio interface patch for Realtek ALC codecs
Linus Torvalds1da177e2005-04-16 15:20:36 -07006 *
Kailang Yangdf694da2005-12-05 19:42:22 +01007 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
8 * PeiSen Hou <pshou@realtek.com.tw>
Linus Torvalds1da177e2005-04-16 15:20:36 -07009 * Takashi Iwai <tiwai@suse.de>
Jonathan Woithe409a3e92012-03-27 13:01:01 +103010 * Jonathan Woithe <jwoithe@just42.net>
Linus Torvalds1da177e2005-04-16 15:20:36 -070011 */
12
Linus Torvalds1da177e2005-04-16 15:20:36 -070013#include <linux/init.h>
14#include <linux/delay.h>
15#include <linux/slab.h>
16#include <linux/pci.h>
Takashi Iwai08fb0d02013-01-10 17:33:58 +010017#include <linux/dmi.h>
Paul Gortmakerda155d52011-07-15 12:38:28 -040018#include <linux/module.h>
David Henningsson33f4acd2015-01-07 15:50:13 +010019#include <linux/input.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070020#include <sound/core.h>
Kailang Yang9ad0e492010-09-14 23:22:00 +020021#include <sound/jack.h>
Pierre-Louis Bossartbe57bff2018-08-22 15:24:57 -050022#include <sound/hda_codec.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070023#include "hda_local.h"
Takashi Iwai23d30f22012-05-07 17:17:32 +020024#include "hda_auto_parser.h"
Takashi Iwai1835a0f2011-10-27 22:12:46 +020025#include "hda_jack.h"
Takashi Iwai08c189f2012-12-19 15:22:24 +010026#include "hda_generic.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070027
Takashi Iwaicd63a5f2013-07-05 12:13:59 +020028/* keep halting ALC5505 DSP, for power saving */
29#define HALT_REALTEK_ALC5505
30
Takashi Iwai4a79ba32009-04-22 16:31:35 +020031/* extra amp-initialization sequence types */
32enum {
Takashi Iwai1c76aa52018-06-21 16:37:54 +020033 ALC_INIT_UNDEFINED,
Takashi Iwai4a79ba32009-04-22 16:31:35 +020034 ALC_INIT_NONE,
35 ALC_INIT_DEFAULT,
Takashi Iwai4a79ba32009-04-22 16:31:35 +020036};
37
David Henningsson73bdd592013-04-15 15:44:14 +020038enum {
39 ALC_HEADSET_MODE_UNKNOWN,
40 ALC_HEADSET_MODE_UNPLUGGED,
41 ALC_HEADSET_MODE_HEADSET,
42 ALC_HEADSET_MODE_MIC,
43 ALC_HEADSET_MODE_HEADPHONE,
44};
45
46enum {
47 ALC_HEADSET_TYPE_UNKNOWN,
48 ALC_HEADSET_TYPE_CTIA,
49 ALC_HEADSET_TYPE_OMTP,
50};
51
Hui Wangc7b60a82015-12-28 11:35:25 +080052enum {
53 ALC_KEY_MICMUTE_INDEX,
54};
55
Kailang Yangda00c242010-03-19 11:23:45 +010056struct alc_customize_define {
57 unsigned int sku_cfg;
58 unsigned char port_connectivity;
59 unsigned char check_sum;
60 unsigned char customization;
61 unsigned char external_amp;
62 unsigned int enable_pcbeep:1;
63 unsigned int platform_type:1;
64 unsigned int swap:1;
65 unsigned int override:1;
David Henningsson90622912010-10-14 14:50:18 +020066 unsigned int fixup:1; /* Means that this sku is set by driver, not read from hw */
Kailang Yangda00c242010-03-19 11:23:45 +010067};
68
Linus Torvalds1da177e2005-04-16 15:20:36 -070069struct alc_spec {
Takashi Iwai08c189f2012-12-19 15:22:24 +010070 struct hda_gen_spec gen; /* must be at head */
Takashi Iwai23d30f22012-05-07 17:17:32 +020071
Linus Torvalds1da177e2005-04-16 15:20:36 -070072 /* codec parameterization */
Kailang Yangda00c242010-03-19 11:23:45 +010073 struct alc_customize_define cdefine;
Takashi Iwai08c189f2012-12-19 15:22:24 +010074 unsigned int parse_flags; /* flag for snd_hda_parse_pin_defcfg() */
75
Takashi Iwai5579cd62018-06-19 22:22:41 +020076 /* GPIO bits */
77 unsigned int gpio_mask;
78 unsigned int gpio_dir;
79 unsigned int gpio_data;
Takashi Iwai215c8502018-06-19 22:34:26 +020080 bool gpio_write_delay; /* add a delay before writing gpio_data */
Takashi Iwai5579cd62018-06-19 22:22:41 +020081
Takashi Iwai08fb0d02013-01-10 17:33:58 +010082 /* mute LED for HP laptops, see alc269_fixup_mic_mute_hook() */
83 int mute_led_polarity;
84 hda_nid_t mute_led_nid;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +080085 hda_nid_t cap_mute_led_nid;
Takashi Iwai08fb0d02013-01-10 17:33:58 +010086
Takashi Iwai0f32fd192014-11-19 12:16:14 +010087 unsigned int gpio_mute_led_mask;
88 unsigned int gpio_mic_led_mask;
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +010089
David Henningsson73bdd592013-04-15 15:44:14 +020090 hda_nid_t headset_mic_pin;
91 hda_nid_t headphone_mic_pin;
92 int current_headset_mode;
93 int current_headset_type;
94
Takashi Iwaiae6b8132006-03-03 16:47:17 +010095 /* hooks */
96 void (*init_hook)(struct hda_codec *codec);
Takashi Iwai83012a72012-08-24 18:38:08 +020097#ifdef CONFIG_PM
Daniel T Chenc97259d2009-12-27 18:52:08 -050098 void (*power_hook)(struct hda_codec *codec);
Hector Martinf5de24b2009-12-20 22:51:31 +010099#endif
Takashi Iwai1c7161532011-04-07 10:37:16 +0200100 void (*shutup)(struct hda_codec *codec);
Takashi Iwai70a09762015-12-15 14:59:58 +0100101 void (*reboot_notify)(struct hda_codec *codec);
Takashi Iwaid922b512011-04-28 12:18:53 +0200102
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200103 int init_amp;
Takashi Iwaid433a672010-09-20 15:11:54 +0200104 int codec_variant; /* flag for other variants */
Kailang Yang97a26572013-11-29 00:35:26 -0500105 unsigned int has_alc5505_dsp:1;
106 unsigned int no_depop_delay:1;
Kailang Yang693abe12019-01-29 15:38:21 +0800107 unsigned int done_hp_init:1;
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +0100108 unsigned int no_shutup_pins:1;
Kailang Yangd3ba58b2019-05-06 15:09:42 +0800109 unsigned int ultra_low_power:1;
Takashi Iwaie64f14f2009-01-20 18:32:55 +0100110
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200111 /* for PLL fix */
112 hda_nid_t pll_nid;
113 unsigned int pll_coef_idx, pll_coef_bit;
Takashi Iwai1bb7e432011-10-17 16:50:59 +0200114 unsigned int coef0;
David Henningsson33f4acd2015-01-07 15:50:13 +0100115 struct input_dev *kb_dev;
Hui Wangc7b60a82015-12-28 11:35:25 +0800116 u8 alc_mute_keycode_map[1];
Kailang Yangdf694da2005-12-05 19:42:22 +0100117};
118
Takashi Iwai23f0c042009-02-26 13:03:58 +0100119/*
Takashi Iwaif2a227c2014-08-18 13:35:22 +0200120 * COEF access helper functions
121 */
122
123static int alc_read_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
124 unsigned int coef_idx)
125{
126 unsigned int val;
127
128 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, coef_idx);
129 val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PROC_COEF, 0);
130 return val;
131}
132
133#define alc_read_coef_idx(codec, coef_idx) \
134 alc_read_coefex_idx(codec, 0x20, coef_idx)
135
136static void alc_write_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
137 unsigned int coef_idx, unsigned int coef_val)
138{
139 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, coef_idx);
140 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PROC_COEF, coef_val);
141}
142
143#define alc_write_coef_idx(codec, coef_idx, coef_val) \
144 alc_write_coefex_idx(codec, 0x20, coef_idx, coef_val)
145
Takashi Iwai98b24882014-08-18 13:47:50 +0200146static void alc_update_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
147 unsigned int coef_idx, unsigned int mask,
148 unsigned int bits_set)
149{
150 unsigned int val = alc_read_coefex_idx(codec, nid, coef_idx);
151
152 if (val != -1)
153 alc_write_coefex_idx(codec, nid, coef_idx,
154 (val & ~mask) | bits_set);
155}
156
157#define alc_update_coef_idx(codec, coef_idx, mask, bits_set) \
158 alc_update_coefex_idx(codec, 0x20, coef_idx, mask, bits_set)
159
Takashi Iwaif2a227c2014-08-18 13:35:22 +0200160/* a special bypass for COEF 0; read the cached value at the second time */
161static unsigned int alc_get_coef0(struct hda_codec *codec)
162{
163 struct alc_spec *spec = codec->spec;
164
165 if (!spec->coef0)
166 spec->coef0 = alc_read_coef_idx(codec, 0);
167 return spec->coef0;
168}
169
Takashi Iwai54db6c32014-08-18 15:11:19 +0200170/* coef writes/updates batch */
171struct coef_fw {
172 unsigned char nid;
173 unsigned char idx;
174 unsigned short mask;
175 unsigned short val;
176};
177
178#define UPDATE_COEFEX(_nid, _idx, _mask, _val) \
179 { .nid = (_nid), .idx = (_idx), .mask = (_mask), .val = (_val) }
180#define WRITE_COEFEX(_nid, _idx, _val) UPDATE_COEFEX(_nid, _idx, -1, _val)
181#define WRITE_COEF(_idx, _val) WRITE_COEFEX(0x20, _idx, _val)
182#define UPDATE_COEF(_idx, _mask, _val) UPDATE_COEFEX(0x20, _idx, _mask, _val)
183
184static void alc_process_coef_fw(struct hda_codec *codec,
185 const struct coef_fw *fw)
186{
187 for (; fw->nid; fw++) {
188 if (fw->mask == (unsigned short)-1)
189 alc_write_coefex_idx(codec, fw->nid, fw->idx, fw->val);
190 else
191 alc_update_coefex_idx(codec, fw->nid, fw->idx,
192 fw->mask, fw->val);
193 }
194}
195
Takashi Iwaif2a227c2014-08-18 13:35:22 +0200196/*
Takashi Iwai1d045db2011-07-07 18:23:21 +0200197 * GPIO setup tables, used in initialization
Kailang Yangdf694da2005-12-05 19:42:22 +0100198 */
Takashi Iwai5579cd62018-06-19 22:22:41 +0200199
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200200/* Enable GPIO mask and set output */
Takashi Iwai5579cd62018-06-19 22:22:41 +0200201static void alc_setup_gpio(struct hda_codec *codec, unsigned int mask)
202{
203 struct alc_spec *spec = codec->spec;
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200204
Takashi Iwai5579cd62018-06-19 22:22:41 +0200205 spec->gpio_mask |= mask;
206 spec->gpio_dir |= mask;
207 spec->gpio_data |= mask;
208}
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200209
Takashi Iwai5579cd62018-06-19 22:22:41 +0200210static void alc_write_gpio_data(struct hda_codec *codec)
211{
212 struct alc_spec *spec = codec->spec;
213
214 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
215 spec->gpio_data);
216}
217
Takashi Iwaiaaf312d2018-06-19 22:28:22 +0200218static void alc_update_gpio_data(struct hda_codec *codec, unsigned int mask,
219 bool on)
220{
221 struct alc_spec *spec = codec->spec;
222 unsigned int oldval = spec->gpio_data;
223
224 if (on)
225 spec->gpio_data |= mask;
226 else
227 spec->gpio_data &= ~mask;
228 if (oldval != spec->gpio_data)
229 alc_write_gpio_data(codec);
230}
231
Takashi Iwai5579cd62018-06-19 22:22:41 +0200232static void alc_write_gpio(struct hda_codec *codec)
233{
234 struct alc_spec *spec = codec->spec;
235
236 if (!spec->gpio_mask)
237 return;
238
239 snd_hda_codec_write(codec, codec->core.afg, 0,
240 AC_VERB_SET_GPIO_MASK, spec->gpio_mask);
241 snd_hda_codec_write(codec, codec->core.afg, 0,
242 AC_VERB_SET_GPIO_DIRECTION, spec->gpio_dir);
Takashi Iwai215c8502018-06-19 22:34:26 +0200243 if (spec->gpio_write_delay)
244 msleep(1);
Takashi Iwai5579cd62018-06-19 22:22:41 +0200245 alc_write_gpio_data(codec);
246}
247
248static void alc_fixup_gpio(struct hda_codec *codec, int action,
249 unsigned int mask)
250{
251 if (action == HDA_FIXUP_ACT_PRE_PROBE)
252 alc_setup_gpio(codec, mask);
253}
254
255static void alc_fixup_gpio1(struct hda_codec *codec,
256 const struct hda_fixup *fix, int action)
257{
258 alc_fixup_gpio(codec, action, 0x01);
259}
260
261static void alc_fixup_gpio2(struct hda_codec *codec,
262 const struct hda_fixup *fix, int action)
263{
264 alc_fixup_gpio(codec, action, 0x02);
265}
266
267static void alc_fixup_gpio3(struct hda_codec *codec,
268 const struct hda_fixup *fix, int action)
269{
270 alc_fixup_gpio(codec, action, 0x03);
271}
Kailang Yangbdd148a2007-05-08 15:19:08 +0200272
Takashi Iwaiae065f12018-06-19 23:00:03 +0200273static void alc_fixup_gpio4(struct hda_codec *codec,
274 const struct hda_fixup *fix, int action)
275{
276 alc_fixup_gpio(codec, action, 0x04);
277}
278
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200279/*
280 * Fix hardware PLL issue
281 * On some codecs, the analog PLL gating control must be off while
282 * the default value is 1.
283 */
284static void alc_fix_pll(struct hda_codec *codec)
285{
286 struct alc_spec *spec = codec->spec;
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200287
Takashi Iwai98b24882014-08-18 13:47:50 +0200288 if (spec->pll_nid)
289 alc_update_coefex_idx(codec, spec->pll_nid, spec->pll_coef_idx,
290 1 << spec->pll_coef_bit, 0);
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200291}
292
293static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
294 unsigned int coef_idx, unsigned int coef_bit)
295{
296 struct alc_spec *spec = codec->spec;
297 spec->pll_nid = nid;
298 spec->pll_coef_idx = coef_idx;
299 spec->pll_coef_bit = coef_bit;
300 alc_fix_pll(codec);
301}
302
Takashi Iwaicf5a2272012-02-20 16:31:07 +0100303/* update the master volume per volume-knob's unsol event */
Takashi Iwai1a4f69d2014-09-11 15:22:46 +0200304static void alc_update_knob_master(struct hda_codec *codec,
305 struct hda_jack_callback *jack)
Takashi Iwaicf5a2272012-02-20 16:31:07 +0100306{
307 unsigned int val;
308 struct snd_kcontrol *kctl;
309 struct snd_ctl_elem_value *uctl;
310
311 kctl = snd_hda_find_mixer_ctl(codec, "Master Playback Volume");
312 if (!kctl)
313 return;
314 uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
315 if (!uctl)
316 return;
Takashi Iwai2ebab402016-02-09 10:23:52 +0100317 val = snd_hda_codec_read(codec, jack->nid, 0,
Takashi Iwaicf5a2272012-02-20 16:31:07 +0100318 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
319 val &= HDA_AMP_VOLMASK;
320 uctl->value.integer.value[0] = val;
321 uctl->value.integer.value[1] = val;
322 kctl->put(kctl, uctl);
323 kfree(uctl);
324}
325
David Henningsson29adc4b2012-09-25 11:31:00 +0200326static void alc880_unsol_event(struct hda_codec *codec, unsigned int res)
Takashi Iwaif21d78e2012-01-19 12:10:29 +0100327{
David Henningsson29adc4b2012-09-25 11:31:00 +0200328 /* For some reason, the res given from ALC880 is broken.
329 Here we adjust it properly. */
330 snd_hda_jack_unsol_event(codec, res >> 2);
Takashi Iwaif21d78e2012-01-19 12:10:29 +0100331}
332
Kailang Yang394c97f2014-11-12 17:38:08 +0800333/* Change EAPD to verb control */
334static void alc_fill_eapd_coef(struct hda_codec *codec)
335{
336 int coef;
337
338 coef = alc_get_coef0(codec);
339
Takashi Iwai7639a062015-03-03 10:07:24 +0100340 switch (codec->core.vendor_id) {
Kailang Yang394c97f2014-11-12 17:38:08 +0800341 case 0x10ec0262:
342 alc_update_coef_idx(codec, 0x7, 0, 1<<5);
343 break;
344 case 0x10ec0267:
345 case 0x10ec0268:
346 alc_update_coef_idx(codec, 0x7, 0, 1<<13);
347 break;
348 case 0x10ec0269:
349 if ((coef & 0x00f0) == 0x0010)
350 alc_update_coef_idx(codec, 0xd, 0, 1<<14);
351 if ((coef & 0x00f0) == 0x0020)
352 alc_update_coef_idx(codec, 0x4, 1<<15, 0);
353 if ((coef & 0x00f0) == 0x0030)
354 alc_update_coef_idx(codec, 0x10, 1<<9, 0);
355 break;
356 case 0x10ec0280:
357 case 0x10ec0284:
358 case 0x10ec0290:
359 case 0x10ec0292:
360 alc_update_coef_idx(codec, 0x4, 1<<15, 0);
361 break;
Kailang Yang42314302016-02-03 15:03:50 +0800362 case 0x10ec0225:
Takashi Iwai44be77c2017-12-27 08:53:59 +0100363 case 0x10ec0295:
364 case 0x10ec0299:
365 alc_update_coef_idx(codec, 0x67, 0xf000, 0x3000);
366 /* fallthrough */
367 case 0x10ec0215:
Kailang Yang394c97f2014-11-12 17:38:08 +0800368 case 0x10ec0233:
Kailang Yangea04a1d2018-04-25 15:31:52 +0800369 case 0x10ec0235:
Kailang Yang394c97f2014-11-12 17:38:08 +0800370 case 0x10ec0255:
Kailang Yangf429e7e2017-12-05 15:38:24 +0800371 case 0x10ec0257:
Kailang Yang394c97f2014-11-12 17:38:08 +0800372 case 0x10ec0282:
373 case 0x10ec0283:
374 case 0x10ec0286:
375 case 0x10ec0288:
Kailang Yang0a6f0602017-06-30 16:00:48 +0800376 case 0x10ec0285:
Kailang Yang506b62c2014-12-18 17:07:44 +0800377 case 0x10ec0298:
Kailang Yang0a6f0602017-06-30 16:00:48 +0800378 case 0x10ec0289:
Kailang Yang1078bef2018-11-08 16:36:15 +0800379 case 0x10ec0300:
Kailang Yang394c97f2014-11-12 17:38:08 +0800380 alc_update_coef_idx(codec, 0x10, 1<<9, 0);
381 break;
Kailang Yange1e8c1f2019-11-26 17:04:23 +0800382 case 0x10ec0236:
383 case 0x10ec0256:
384 alc_write_coef_idx(codec, 0x36, 0x5757);
385 alc_update_coef_idx(codec, 0x10, 1<<9, 0);
386 break;
Kailang Yang3aabf942017-11-08 15:28:33 +0800387 case 0x10ec0275:
388 alc_update_coef_idx(codec, 0xe, 0, 1<<0);
389 break;
Kailang Yang394c97f2014-11-12 17:38:08 +0800390 case 0x10ec0293:
391 alc_update_coef_idx(codec, 0xa, 1<<13, 0);
392 break;
Kailang Yangdcd4f0d2016-05-04 15:50:18 +0800393 case 0x10ec0234:
394 case 0x10ec0274:
395 case 0x10ec0294:
Kailang Yang6fbae352016-05-30 16:44:20 +0800396 case 0x10ec0700:
397 case 0x10ec0701:
398 case 0x10ec0703:
Kailang Yang83629532019-05-02 16:03:26 +0800399 case 0x10ec0711:
Kailang Yangdcd4f0d2016-05-04 15:50:18 +0800400 alc_update_coef_idx(codec, 0x10, 1<<15, 0);
401 break;
Kailang Yang394c97f2014-11-12 17:38:08 +0800402 case 0x10ec0662:
403 if ((coef & 0x00f0) == 0x0030)
404 alc_update_coef_idx(codec, 0x4, 1<<10, 0); /* EAPD Ctrl */
405 break;
406 case 0x10ec0272:
407 case 0x10ec0273:
408 case 0x10ec0663:
409 case 0x10ec0665:
410 case 0x10ec0670:
411 case 0x10ec0671:
412 case 0x10ec0672:
413 alc_update_coef_idx(codec, 0xd, 0, 1<<14); /* EAPD Ctrl */
414 break;
Kailang Yangf0778872019-10-24 15:13:32 +0800415 case 0x10ec0623:
416 alc_update_coef_idx(codec, 0x19, 1<<13, 0);
417 break;
Kailang Yang394c97f2014-11-12 17:38:08 +0800418 case 0x10ec0668:
419 alc_update_coef_idx(codec, 0x7, 3<<13, 0);
420 break;
421 case 0x10ec0867:
422 alc_update_coef_idx(codec, 0x4, 1<<10, 0);
423 break;
424 case 0x10ec0888:
425 if ((coef & 0x00f0) == 0x0020 || (coef & 0x00f0) == 0x0030)
426 alc_update_coef_idx(codec, 0x7, 1<<5, 0);
427 break;
428 case 0x10ec0892:
429 alc_update_coef_idx(codec, 0x7, 1<<5, 0);
430 break;
431 case 0x10ec0899:
432 case 0x10ec0900:
Kailang Yang65553b12017-07-11 15:15:47 +0800433 case 0x10ec1168:
Kailang Yanga535ad52017-01-16 16:59:26 +0800434 case 0x10ec1220:
Kailang Yang394c97f2014-11-12 17:38:08 +0800435 alc_update_coef_idx(codec, 0x7, 1<<1, 0);
436 break;
437 }
438}
439
Kailang Yangf9423e72008-05-27 12:32:25 +0200440/* additional initialization for ALC888 variants */
441static void alc888_coef_init(struct hda_codec *codec)
442{
Kailang Yang1df88742014-10-29 16:10:13 +0800443 switch (alc_get_coef0(codec) & 0x00f0) {
444 /* alc888-VA */
445 case 0x00:
446 /* alc888-VB */
447 case 0x10:
448 alc_update_coef_idx(codec, 7, 0, 0x2030); /* Turn EAPD to High */
449 break;
450 }
Jaroslav Kysela87a8c372009-07-23 10:58:29 +0200451}
452
Takashi Iwai3fb4a502010-01-19 15:46:37 +0100453/* turn on/off EAPD control (only if available) */
454static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
455{
456 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
457 return;
458 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
459 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
460 on ? 2 : 0);
461}
462
Takashi Iwai691f1fc2011-04-07 10:31:43 +0200463/* turn on/off EAPD controls of the codec */
464static void alc_auto_setup_eapd(struct hda_codec *codec, bool on)
465{
466 /* We currently only handle front, HP */
Takashi Iwai39fa84e2011-06-27 15:28:57 +0200467 static hda_nid_t pins[] = {
Hui Wangaf95b412015-03-26 17:14:55 +0800468 0x0f, 0x10, 0x14, 0x15, 0x17, 0
Takashi Iwai39fa84e2011-06-27 15:28:57 +0200469 };
470 hda_nid_t *p;
471 for (p = pins; *p; p++)
472 set_eapd(codec, *p, on);
Takashi Iwai691f1fc2011-04-07 10:31:43 +0200473}
474
Kailang Yangdad31972019-05-10 16:28:57 +0800475static int find_ext_mic_pin(struct hda_codec *codec);
476
477static void alc_headset_mic_no_shutup(struct hda_codec *codec)
478{
479 const struct hda_pincfg *pin;
480 int mic_pin = find_ext_mic_pin(codec);
481 int i;
482
483 /* don't shut up pins when unloading the driver; otherwise it breaks
484 * the default pin setup at the next load of the driver
485 */
486 if (codec->bus->shutdown)
487 return;
488
489 snd_array_for_each(&codec->init_pins, i, pin) {
490 /* use read here for syncing after issuing each verb */
491 if (pin->nid != mic_pin)
492 snd_hda_codec_read(codec, pin->nid, 0,
493 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
494 }
495
496 codec->pins_shutup = 1;
497}
498
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +0100499static void alc_shutup_pins(struct hda_codec *codec)
500{
501 struct alc_spec *spec = codec->spec;
502
Kailang Yangdad31972019-05-10 16:28:57 +0800503 switch (codec->core.vendor_id) {
Kailang Yang66c5d712019-12-09 15:56:15 +0800504 case 0x10ec0283:
Kailang Yangdad31972019-05-10 16:28:57 +0800505 case 0x10ec0286:
506 case 0x10ec0288:
507 case 0x10ec0298:
508 alc_headset_mic_no_shutup(codec);
509 break;
510 default:
511 if (!spec->no_shutup_pins)
512 snd_hda_shutup_pins(codec);
513 break;
514 }
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +0100515}
516
Takashi Iwai1c7161532011-04-07 10:37:16 +0200517/* generic shutup callback;
Lars-Peter Clausen4ce8e6a2016-11-08 15:48:06 +0100518 * just turning off EAPD and a little pause for avoiding pop-noise
Takashi Iwai1c7161532011-04-07 10:37:16 +0200519 */
520static void alc_eapd_shutup(struct hda_codec *codec)
521{
Kailang Yang97a26572013-11-29 00:35:26 -0500522 struct alc_spec *spec = codec->spec;
523
Takashi Iwai1c7161532011-04-07 10:37:16 +0200524 alc_auto_setup_eapd(codec, false);
Kailang Yang97a26572013-11-29 00:35:26 -0500525 if (!spec->no_depop_delay)
526 msleep(200);
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +0100527 alc_shutup_pins(codec);
Takashi Iwai1c7161532011-04-07 10:37:16 +0200528}
529
Takashi Iwai1d045db2011-07-07 18:23:21 +0200530/* generic EAPD initialization */
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200531static void alc_auto_init_amp(struct hda_codec *codec, int type)
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200532{
Takashi Iwai39fa84e2011-06-27 15:28:57 +0200533 alc_auto_setup_eapd(codec, true);
Takashi Iwai5579cd62018-06-19 22:22:41 +0200534 alc_write_gpio(codec);
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200535 switch (type) {
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200536 case ALC_INIT_DEFAULT:
Takashi Iwai7639a062015-03-03 10:07:24 +0100537 switch (codec->core.vendor_id) {
Kailang Yangc9b58002007-10-16 14:30:01 +0200538 case 0x10ec0260:
Takashi Iwai98b24882014-08-18 13:47:50 +0200539 alc_update_coefex_idx(codec, 0x1a, 7, 0, 0x2010);
Kailang Yangc9b58002007-10-16 14:30:01 +0200540 break;
Kailang Yangc9b58002007-10-16 14:30:01 +0200541 case 0x10ec0880:
542 case 0x10ec0882:
543 case 0x10ec0883:
544 case 0x10ec0885:
Kailang Yang1df88742014-10-29 16:10:13 +0800545 alc_update_coef_idx(codec, 7, 0, 0x2030);
Kailang Yangc9b58002007-10-16 14:30:01 +0200546 break;
Kailang Yangf9423e72008-05-27 12:32:25 +0200547 case 0x10ec0888:
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200548 alc888_coef_init(codec);
Kailang Yangf9423e72008-05-27 12:32:25 +0200549 break;
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200550 }
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200551 break;
552 }
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200553}
Kailang Yangea1fb292008-08-26 12:58:38 +0200554
Takashi Iwai35a39f92019-02-01 11:19:50 +0100555/* get a primary headphone pin if available */
556static hda_nid_t alc_get_hp_pin(struct alc_spec *spec)
557{
558 if (spec->gen.autocfg.hp_pins[0])
559 return spec->gen.autocfg.hp_pins[0];
560 if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
561 return spec->gen.autocfg.line_out_pins[0];
562 return 0;
563}
Takashi Iwai1d045db2011-07-07 18:23:21 +0200564
565/*
566 * Realtek SSID verification
567 */
568
David Henningsson90622912010-10-14 14:50:18 +0200569/* Could be any non-zero and even value. When used as fixup, tells
570 * the driver to ignore any present sku defines.
571 */
572#define ALC_FIXUP_SKU_IGNORE (2)
573
Takashi Iwai23d30f22012-05-07 17:17:32 +0200574static void alc_fixup_sku_ignore(struct hda_codec *codec,
575 const struct hda_fixup *fix, int action)
576{
577 struct alc_spec *spec = codec->spec;
578 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
579 spec->cdefine.fixup = 1;
580 spec->cdefine.sku_cfg = ALC_FIXUP_SKU_IGNORE;
581 }
582}
583
Mengdong Linb5c66112013-11-29 00:35:35 -0500584static void alc_fixup_no_depop_delay(struct hda_codec *codec,
585 const struct hda_fixup *fix, int action)
586{
587 struct alc_spec *spec = codec->spec;
588
Mengdong Lin84d2dc32013-12-02 22:26:03 -0500589 if (action == HDA_FIXUP_ACT_PROBE) {
Mengdong Linb5c66112013-11-29 00:35:35 -0500590 spec->no_depop_delay = 1;
Mengdong Lin84d2dc32013-12-02 22:26:03 -0500591 codec->depop_delay = 0;
592 }
Mengdong Linb5c66112013-11-29 00:35:35 -0500593}
594
Kailang Yangda00c242010-03-19 11:23:45 +0100595static int alc_auto_parse_customize_define(struct hda_codec *codec)
596{
597 unsigned int ass, tmp, i;
Takashi Iwai7fb56222010-03-22 17:09:47 +0100598 unsigned nid = 0;
Kailang Yangda00c242010-03-19 11:23:45 +0100599 struct alc_spec *spec = codec->spec;
600
Takashi Iwaib6cbe512010-07-28 17:43:36 +0200601 spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
602
David Henningsson90622912010-10-14 14:50:18 +0200603 if (spec->cdefine.fixup) {
604 ass = spec->cdefine.sku_cfg;
605 if (ass == ALC_FIXUP_SKU_IGNORE)
606 return -1;
607 goto do_sku;
608 }
609
Takashi Iwai5100cd02014-02-15 10:03:19 +0100610 if (!codec->bus->pci)
611 return -1;
Takashi Iwai7639a062015-03-03 10:07:24 +0100612 ass = codec->core.subsystem_id & 0xffff;
Takashi Iwaib6cbe512010-07-28 17:43:36 +0200613 if (ass != codec->bus->pci->subsystem_device && (ass & 1))
Kailang Yangda00c242010-03-19 11:23:45 +0100614 goto do_sku;
615
616 nid = 0x1d;
Takashi Iwai7639a062015-03-03 10:07:24 +0100617 if (codec->core.vendor_id == 0x10ec0260)
Kailang Yangda00c242010-03-19 11:23:45 +0100618 nid = 0x17;
619 ass = snd_hda_codec_get_pincfg(codec, nid);
620
621 if (!(ass & 1)) {
Takashi Iwai4e76a882014-02-25 12:21:03 +0100622 codec_info(codec, "%s: SKU not ready 0x%08x\n",
Takashi Iwai7639a062015-03-03 10:07:24 +0100623 codec->core.chip_name, ass);
Kailang Yangda00c242010-03-19 11:23:45 +0100624 return -1;
625 }
626
627 /* check sum */
628 tmp = 0;
629 for (i = 1; i < 16; i++) {
630 if ((ass >> i) & 1)
631 tmp++;
632 }
633 if (((ass >> 16) & 0xf) != tmp)
634 return -1;
635
636 spec->cdefine.port_connectivity = ass >> 30;
637 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
638 spec->cdefine.check_sum = (ass >> 16) & 0xf;
639 spec->cdefine.customization = ass >> 8;
640do_sku:
641 spec->cdefine.sku_cfg = ass;
642 spec->cdefine.external_amp = (ass & 0x38) >> 3;
643 spec->cdefine.platform_type = (ass & 0x4) >> 2;
644 spec->cdefine.swap = (ass & 0x2) >> 1;
645 spec->cdefine.override = ass & 0x1;
646
Takashi Iwai4e76a882014-02-25 12:21:03 +0100647 codec_dbg(codec, "SKU: Nid=0x%x sku_cfg=0x%08x\n",
Kailang Yangda00c242010-03-19 11:23:45 +0100648 nid, spec->cdefine.sku_cfg);
Takashi Iwai4e76a882014-02-25 12:21:03 +0100649 codec_dbg(codec, "SKU: port_connectivity=0x%x\n",
Kailang Yangda00c242010-03-19 11:23:45 +0100650 spec->cdefine.port_connectivity);
Takashi Iwai4e76a882014-02-25 12:21:03 +0100651 codec_dbg(codec, "SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
652 codec_dbg(codec, "SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
653 codec_dbg(codec, "SKU: customization=0x%08x\n", spec->cdefine.customization);
654 codec_dbg(codec, "SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
655 codec_dbg(codec, "SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
656 codec_dbg(codec, "SKU: swap=0x%x\n", spec->cdefine.swap);
657 codec_dbg(codec, "SKU: override=0x%x\n", spec->cdefine.override);
Kailang Yangda00c242010-03-19 11:23:45 +0100658
659 return 0;
660}
661
Takashi Iwai08c189f2012-12-19 15:22:24 +0100662/* return the position of NID in the list, or -1 if not found */
663static int find_idx_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
664{
665 int i;
666 for (i = 0; i < nums; i++)
667 if (list[i] == nid)
668 return i;
669 return -1;
670}
Takashi Iwai1d045db2011-07-07 18:23:21 +0200671/* return true if the given NID is found in the list */
Takashi Iwai3af9ee62011-06-27 12:34:01 +0200672static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
673{
Takashi Iwai21268962011-07-07 15:01:13 +0200674 return find_idx_in_nid_list(nid, list, nums) >= 0;
Takashi Iwai3af9ee62011-06-27 12:34:01 +0200675}
676
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200677/* check subsystem ID and set up device-specific initialization;
678 * return 1 if initialized, 0 if invalid SSID
679 */
680/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
681 * 31 ~ 16 : Manufacture ID
682 * 15 ~ 8 : SKU ID
683 * 7 ~ 0 : Assembly ID
684 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
685 */
Takashi Iwai58c57cf2014-01-07 18:22:49 +0100686static int alc_subsystem_id(struct hda_codec *codec, const hda_nid_t *ports)
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200687{
688 unsigned int ass, tmp, i;
689 unsigned nid;
690 struct alc_spec *spec = codec->spec;
691
David Henningsson90622912010-10-14 14:50:18 +0200692 if (spec->cdefine.fixup) {
693 ass = spec->cdefine.sku_cfg;
694 if (ass == ALC_FIXUP_SKU_IGNORE)
695 return 0;
696 goto do_sku;
697 }
698
Takashi Iwai7639a062015-03-03 10:07:24 +0100699 ass = codec->core.subsystem_id & 0xffff;
Takashi Iwai5100cd02014-02-15 10:03:19 +0100700 if (codec->bus->pci &&
701 ass != codec->bus->pci->subsystem_device && (ass & 1))
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200702 goto do_sku;
703
704 /* invalid SSID, check the special NID pin defcfg instead */
705 /*
Sasha Alexandrdef319f2009-06-16 16:00:15 -0400706 * 31~30 : port connectivity
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200707 * 29~21 : reserve
708 * 20 : PCBEEP input
709 * 19~16 : Check sum (15:1)
710 * 15~1 : Custom
711 * 0 : override
712 */
713 nid = 0x1d;
Takashi Iwai7639a062015-03-03 10:07:24 +0100714 if (codec->core.vendor_id == 0x10ec0260)
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200715 nid = 0x17;
716 ass = snd_hda_codec_get_pincfg(codec, nid);
Takashi Iwai4e76a882014-02-25 12:21:03 +0100717 codec_dbg(codec,
718 "realtek: No valid SSID, checking pincfg 0x%08x for NID 0x%x\n",
Takashi Iwaicb6605c2009-04-28 13:03:19 +0200719 ass, nid);
Kailang Yang6227cdc2010-02-25 08:36:52 +0100720 if (!(ass & 1))
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200721 return 0;
722 if ((ass >> 30) != 1) /* no physical connection */
723 return 0;
724
725 /* check sum */
726 tmp = 0;
727 for (i = 1; i < 16; i++) {
728 if ((ass >> i) & 1)
729 tmp++;
730 }
731 if (((ass >> 16) & 0xf) != tmp)
732 return 0;
733do_sku:
Takashi Iwai4e76a882014-02-25 12:21:03 +0100734 codec_dbg(codec, "realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
Takashi Iwai7639a062015-03-03 10:07:24 +0100735 ass & 0xffff, codec->core.vendor_id);
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200736 /*
737 * 0 : override
738 * 1 : Swap Jack
739 * 2 : 0 --> Desktop, 1 --> Laptop
740 * 3~5 : External Amplifier control
741 * 7~6 : Reserved
742 */
743 tmp = (ass & 0x38) >> 3; /* external Amp control */
Takashi Iwai1c76aa52018-06-21 16:37:54 +0200744 if (spec->init_amp == ALC_INIT_UNDEFINED) {
745 switch (tmp) {
746 case 1:
Takashi Iwai5579cd62018-06-19 22:22:41 +0200747 alc_setup_gpio(codec, 0x01);
Takashi Iwai1c76aa52018-06-21 16:37:54 +0200748 break;
749 case 3:
Takashi Iwai5579cd62018-06-19 22:22:41 +0200750 alc_setup_gpio(codec, 0x02);
Takashi Iwai1c76aa52018-06-21 16:37:54 +0200751 break;
752 case 7:
Takashi Iwai5579cd62018-06-19 22:22:41 +0200753 alc_setup_gpio(codec, 0x03);
Takashi Iwai1c76aa52018-06-21 16:37:54 +0200754 break;
755 case 5:
756 default:
757 spec->init_amp = ALC_INIT_DEFAULT;
758 break;
759 }
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200760 }
761
762 /* is laptop or Desktop and enable the function "Mute internal speaker
763 * when the external headphone out jack is plugged"
764 */
765 if (!(ass & 0x8000))
766 return 1;
767 /*
768 * 10~8 : Jack location
769 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
770 * 14~13: Resvered
771 * 15 : 1 --> enable the function "Mute internal speaker
772 * when the external headphone out jack is plugged"
773 */
Takashi Iwai35a39f92019-02-01 11:19:50 +0100774 if (!alc_get_hp_pin(spec)) {
Takashi Iwai01d48252009-10-06 13:21:54 +0200775 hda_nid_t nid;
Kailang Yangc9b58002007-10-16 14:30:01 +0200776 tmp = (ass >> 11) & 0x3; /* HP to chassis */
Takashi Iwai58c57cf2014-01-07 18:22:49 +0100777 nid = ports[tmp];
Takashi Iwai08c189f2012-12-19 15:22:24 +0100778 if (found_in_nid_list(nid, spec->gen.autocfg.line_out_pins,
779 spec->gen.autocfg.line_outs))
Takashi Iwai3af9ee62011-06-27 12:34:01 +0200780 return 1;
Takashi Iwai08c189f2012-12-19 15:22:24 +0100781 spec->gen.autocfg.hp_pins[0] = nid;
Kailang Yangc9b58002007-10-16 14:30:01 +0200782 }
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200783 return 1;
784}
Kailang Yangea1fb292008-08-26 12:58:38 +0200785
Takashi Iwai3e6179b2011-07-08 16:55:13 +0200786/* Check the validity of ALC subsystem-id
787 * ports contains an array of 4 pin NIDs for port-A, E, D and I */
788static void alc_ssid_check(struct hda_codec *codec, const hda_nid_t *ports)
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200789{
Takashi Iwai58c57cf2014-01-07 18:22:49 +0100790 if (!alc_subsystem_id(codec, ports)) {
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200791 struct alc_spec *spec = codec->spec;
Takashi Iwai4e76a882014-02-25 12:21:03 +0100792 codec_dbg(codec,
793 "realtek: Enable default setup for auto mode as fallback\n");
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200794 spec->init_amp = ALC_INIT_DEFAULT;
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200795 }
Takashi Iwai21268962011-07-07 15:01:13 +0200796}
Takashi Iwai1a1455d2011-04-28 17:36:18 +0200797
Takashi Iwai41e41f12005-06-08 14:48:49 +0200798/*
Takashi Iwai1d045db2011-07-07 18:23:21 +0200799 */
800
David Henningsson9d36a7d2014-10-07 10:18:42 +0200801static void alc_fixup_inv_dmic(struct hda_codec *codec,
802 const struct hda_fixup *fix, int action)
Takashi Iwai125821a2012-06-22 14:30:29 +0200803{
804 struct alc_spec *spec = codec->spec;
Takashi Iwai668d1e92012-11-29 14:10:17 +0100805
David Henningsson9d36a7d2014-10-07 10:18:42 +0200806 spec->gen.inv_dmic_split = 1;
Takashi Iwai6e72aa52012-06-25 10:52:25 +0200807}
808
Takashi Iwai603c4012008-07-30 15:01:44 +0200809
Takashi Iwai2eab6942012-12-18 15:30:41 +0100810static int alc_build_controls(struct hda_codec *codec)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700811{
Takashi Iwaia5cb4632018-06-20 12:50:11 +0200812 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700813
Takashi Iwai08c189f2012-12-19 15:22:24 +0100814 err = snd_hda_gen_build_controls(codec);
815 if (err < 0)
816 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700817
Takashi Iwai1727a772013-01-10 09:52:52 +0100818 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_BUILD);
Takashi Iwai420b0fe2012-03-12 12:35:27 +0100819 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700820}
821
Takashi Iwaie9edcee2005-06-13 14:16:38 +0200822
Linus Torvalds1da177e2005-04-16 15:20:36 -0700823/*
Takashi Iwaiae6b8132006-03-03 16:47:17 +0100824 * Common callbacks
Takashi Iwaie9edcee2005-06-13 14:16:38 +0200825 */
Takashi Iwai16ded522005-06-10 19:58:24 +0200826
Takashi Iwaic9af7532019-05-10 11:01:43 +0200827static void alc_pre_init(struct hda_codec *codec)
828{
829 alc_fill_eapd_coef(codec);
830}
831
Kailang Yangaeac1a02019-05-16 16:10:44 +0800832#define is_s3_resume(codec) \
833 ((codec)->core.dev.power.power_state.event == PM_EVENT_RESUME)
Takashi Iwaic9af7532019-05-10 11:01:43 +0200834#define is_s4_resume(codec) \
835 ((codec)->core.dev.power.power_state.event == PM_EVENT_RESTORE)
836
Linus Torvalds1da177e2005-04-16 15:20:36 -0700837static int alc_init(struct hda_codec *codec)
838{
839 struct alc_spec *spec = codec->spec;
Takashi Iwaie9edcee2005-06-13 14:16:38 +0200840
Takashi Iwaic9af7532019-05-10 11:01:43 +0200841 /* hibernation resume needs the full chip initialization */
842 if (is_s4_resume(codec))
843 alc_pre_init(codec);
844
Takashi Iwai546bb672012-03-07 08:37:19 +0100845 if (spec->init_hook)
846 spec->init_hook(codec);
Kailang Yang526af6e2012-03-07 08:25:20 +0100847
Takashi Iwai89781d02019-08-30 12:03:38 +0200848 spec->gen.skip_verbs = 1; /* applied in below */
Kailang Yang607ca3b2019-04-26 16:35:41 +0800849 snd_hda_gen_init(codec);
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200850 alc_fix_pll(codec);
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200851 alc_auto_init_amp(codec, spec->init_amp);
Takashi Iwai89781d02019-08-30 12:03:38 +0200852 snd_hda_apply_verbs(codec); /* apply verbs here after own init */
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200853
Takashi Iwai1727a772013-01-10 09:52:52 +0100854 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_INIT);
Takashi Iwaie08a0072006-09-07 17:52:14 +0200855
Linus Torvalds1da177e2005-04-16 15:20:36 -0700856 return 0;
857}
858
Takashi Iwaia4e09aa2009-12-27 11:22:24 +0100859static inline void alc_shutup(struct hda_codec *codec)
860{
Takashi Iwai1c7161532011-04-07 10:37:16 +0200861 struct alc_spec *spec = codec->spec;
862
Takashi Iwaic7273bd2018-06-12 16:09:57 +0200863 if (!snd_hda_get_bool_hint(codec, "shutup"))
864 return; /* disabled explicitly by hints */
865
Takashi Iwai1c7161532011-04-07 10:37:16 +0200866 if (spec && spec->shutup)
867 spec->shutup(codec);
Takashi Iwai9bfb2842013-07-24 14:31:50 +0200868 else
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +0100869 alc_shutup_pins(codec);
Takashi Iwaia4e09aa2009-12-27 11:22:24 +0100870}
871
Takashi Iwai70a09762015-12-15 14:59:58 +0100872static void alc_reboot_notify(struct hda_codec *codec)
873{
874 struct alc_spec *spec = codec->spec;
875
876 if (spec && spec->reboot_notify)
877 spec->reboot_notify(codec);
878 else
879 alc_shutup(codec);
880}
881
Takashi Iwai8a02c0c2014-02-10 18:09:45 +0100882#define alc_free snd_hda_gen_free
Linus Torvalds1da177e2005-04-16 15:20:36 -0700883
Takashi Iwai83012a72012-08-24 18:38:08 +0200884#ifdef CONFIG_PM
Daniel T Chenc97259d2009-12-27 18:52:08 -0500885static void alc_power_eapd(struct hda_codec *codec)
886{
Takashi Iwai691f1fc2011-04-07 10:31:43 +0200887 alc_auto_setup_eapd(codec, false);
Daniel T Chenc97259d2009-12-27 18:52:08 -0500888}
889
Takashi Iwai68cb2b52012-07-02 15:20:37 +0200890static int alc_suspend(struct hda_codec *codec)
Hector Martinf5de24b2009-12-20 22:51:31 +0100891{
892 struct alc_spec *spec = codec->spec;
Takashi Iwaia4e09aa2009-12-27 11:22:24 +0100893 alc_shutup(codec);
Hector Martinf5de24b2009-12-20 22:51:31 +0100894 if (spec && spec->power_hook)
Daniel T Chenc97259d2009-12-27 18:52:08 -0500895 spec->power_hook(codec);
Hector Martinf5de24b2009-12-20 22:51:31 +0100896 return 0;
897}
898#endif
899
Takashi Iwai2a439522011-07-26 09:52:50 +0200900#ifdef CONFIG_PM
Takashi Iwaie044c392008-10-27 16:56:24 +0100901static int alc_resume(struct hda_codec *codec)
902{
Kailang Yang97a26572013-11-29 00:35:26 -0500903 struct alc_spec *spec = codec->spec;
904
905 if (!spec->no_depop_delay)
906 msleep(150); /* to avoid pop noise */
Takashi Iwaie044c392008-10-27 16:56:24 +0100907 codec->patch_ops.init(codec);
Takashi Iwaieeecd9d2015-02-25 15:18:50 +0100908 regcache_sync(codec->core.regmap);
Takashi Iwai9e5341b2010-09-21 09:57:06 +0200909 hda_call_check_power_status(codec, 0x01);
Takashi Iwaie044c392008-10-27 16:56:24 +0100910 return 0;
911}
Takashi Iwaie044c392008-10-27 16:56:24 +0100912#endif
913
Linus Torvalds1da177e2005-04-16 15:20:36 -0700914/*
915 */
Takashi Iwaia9111322011-05-02 11:30:18 +0200916static const struct hda_codec_ops alc_patch_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700917 .build_controls = alc_build_controls,
Takashi Iwai08c189f2012-12-19 15:22:24 +0100918 .build_pcms = snd_hda_gen_build_pcms,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700919 .init = alc_init,
920 .free = alc_free,
David Henningsson29adc4b2012-09-25 11:31:00 +0200921 .unsol_event = snd_hda_jack_unsol_event,
Takashi Iwai2a439522011-07-26 09:52:50 +0200922#ifdef CONFIG_PM
Takashi Iwaie044c392008-10-27 16:56:24 +0100923 .resume = alc_resume,
Hector Martinf5de24b2009-12-20 22:51:31 +0100924 .suspend = alc_suspend,
Takashi Iwaifce52a32013-01-07 12:42:48 +0100925 .check_power_status = snd_hda_gen_check_power_status,
Takashi Iwaicb53c622007-08-10 17:21:45 +0200926#endif
Takashi Iwai70a09762015-12-15 14:59:58 +0100927 .reboot_notify = alc_reboot_notify,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700928};
929
David Henningsson29adc4b2012-09-25 11:31:00 +0200930
Takashi Iwaided255b2015-10-01 17:59:43 +0200931#define alc_codec_rename(codec, name) snd_hda_codec_set_name(codec, name)
Kailang Yangc027ddc2010-03-19 11:33:06 +0100932
Takashi Iwai2fa522b2005-05-12 14:51:12 +0200933/*
Kailang Yang4b016932013-11-28 11:55:09 +0100934 * Rename codecs appropriately from COEF value or subvendor id
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200935 */
936struct alc_codec_rename_table {
937 unsigned int vendor_id;
938 unsigned short coef_mask;
939 unsigned short coef_bits;
940 const char *name;
941};
942
Kailang Yang4b016932013-11-28 11:55:09 +0100943struct alc_codec_rename_pci_table {
944 unsigned int codec_vendor_id;
945 unsigned short pci_subvendor;
946 unsigned short pci_subdevice;
947 const char *name;
948};
949
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200950static struct alc_codec_rename_table rename_tbl[] = {
Kailang Yange6e5f7a2014-06-06 16:46:43 +0800951 { 0x10ec0221, 0xf00f, 0x1003, "ALC231" },
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200952 { 0x10ec0269, 0xfff0, 0x3010, "ALC277" },
953 { 0x10ec0269, 0xf0f0, 0x2010, "ALC259" },
954 { 0x10ec0269, 0xf0f0, 0x3010, "ALC258" },
955 { 0x10ec0269, 0x00f0, 0x0010, "ALC269VB" },
956 { 0x10ec0269, 0xffff, 0xa023, "ALC259" },
957 { 0x10ec0269, 0xffff, 0x6023, "ALC281X" },
958 { 0x10ec0269, 0x00f0, 0x0020, "ALC269VC" },
Kailang Yangadcc70b2012-05-25 08:08:38 +0200959 { 0x10ec0269, 0x00f0, 0x0030, "ALC269VD" },
Kailang Yange6e5f7a2014-06-06 16:46:43 +0800960 { 0x10ec0662, 0xffff, 0x4020, "ALC656" },
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200961 { 0x10ec0887, 0x00f0, 0x0030, "ALC887-VD" },
962 { 0x10ec0888, 0x00f0, 0x0030, "ALC888-VD" },
963 { 0x10ec0888, 0xf0f0, 0x3020, "ALC886" },
964 { 0x10ec0899, 0x2000, 0x2000, "ALC899" },
965 { 0x10ec0892, 0xffff, 0x8020, "ALC661" },
966 { 0x10ec0892, 0xffff, 0x8011, "ALC661" },
967 { 0x10ec0892, 0xffff, 0x4011, "ALC656" },
968 { } /* terminator */
969};
970
Kailang Yang4b016932013-11-28 11:55:09 +0100971static struct alc_codec_rename_pci_table rename_pci_tbl[] = {
972 { 0x10ec0280, 0x1028, 0, "ALC3220" },
973 { 0x10ec0282, 0x1028, 0, "ALC3221" },
974 { 0x10ec0283, 0x1028, 0, "ALC3223" },
Kailang Yang193177d2014-04-23 16:06:13 +0800975 { 0x10ec0288, 0x1028, 0, "ALC3263" },
Kailang Yang4b016932013-11-28 11:55:09 +0100976 { 0x10ec0292, 0x1028, 0, "ALC3226" },
Kailang Yang193177d2014-04-23 16:06:13 +0800977 { 0x10ec0293, 0x1028, 0, "ALC3235" },
Kailang Yang4b016932013-11-28 11:55:09 +0100978 { 0x10ec0255, 0x1028, 0, "ALC3234" },
979 { 0x10ec0668, 0x1028, 0, "ALC3661" },
Kailang Yange6e5f7a2014-06-06 16:46:43 +0800980 { 0x10ec0275, 0x1028, 0, "ALC3260" },
981 { 0x10ec0899, 0x1028, 0, "ALC3861" },
Kailang Yang2c674fa2015-05-05 15:02:42 +0800982 { 0x10ec0298, 0x1028, 0, "ALC3266" },
Kailang Yang736f20a2017-10-20 15:06:34 +0800983 { 0x10ec0236, 0x1028, 0, "ALC3204" },
Kailang Yang82324502015-05-25 17:16:49 +0800984 { 0x10ec0256, 0x1028, 0, "ALC3246" },
Kailang Yang42314302016-02-03 15:03:50 +0800985 { 0x10ec0225, 0x1028, 0, "ALC3253" },
Kailang Yang7d727862016-05-24 16:46:07 +0800986 { 0x10ec0295, 0x1028, 0, "ALC3254" },
Kailang Yang28f1f9b2017-01-04 14:49:07 +0800987 { 0x10ec0299, 0x1028, 0, "ALC3271" },
Kailang Yange6e5f7a2014-06-06 16:46:43 +0800988 { 0x10ec0670, 0x1025, 0, "ALC669X" },
989 { 0x10ec0676, 0x1025, 0, "ALC679X" },
990 { 0x10ec0282, 0x1043, 0, "ALC3229" },
991 { 0x10ec0233, 0x1043, 0, "ALC3236" },
992 { 0x10ec0280, 0x103c, 0, "ALC3228" },
993 { 0x10ec0282, 0x103c, 0, "ALC3227" },
994 { 0x10ec0286, 0x103c, 0, "ALC3242" },
995 { 0x10ec0290, 0x103c, 0, "ALC3241" },
996 { 0x10ec0668, 0x103c, 0, "ALC3662" },
997 { 0x10ec0283, 0x17aa, 0, "ALC3239" },
998 { 0x10ec0292, 0x17aa, 0, "ALC3232" },
Kailang Yang4b016932013-11-28 11:55:09 +0100999 { } /* terminator */
1000};
1001
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02001002static int alc_codec_rename_from_preset(struct hda_codec *codec)
1003{
1004 const struct alc_codec_rename_table *p;
Kailang Yang4b016932013-11-28 11:55:09 +01001005 const struct alc_codec_rename_pci_table *q;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02001006
1007 for (p = rename_tbl; p->vendor_id; p++) {
Takashi Iwai7639a062015-03-03 10:07:24 +01001008 if (p->vendor_id != codec->core.vendor_id)
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02001009 continue;
Takashi Iwai1bb7e432011-10-17 16:50:59 +02001010 if ((alc_get_coef0(codec) & p->coef_mask) == p->coef_bits)
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02001011 return alc_codec_rename(codec, p->name);
1012 }
Kailang Yang4b016932013-11-28 11:55:09 +01001013
Takashi Iwai5100cd02014-02-15 10:03:19 +01001014 if (!codec->bus->pci)
1015 return 0;
Kailang Yang4b016932013-11-28 11:55:09 +01001016 for (q = rename_pci_tbl; q->codec_vendor_id; q++) {
Takashi Iwai7639a062015-03-03 10:07:24 +01001017 if (q->codec_vendor_id != codec->core.vendor_id)
Kailang Yang4b016932013-11-28 11:55:09 +01001018 continue;
1019 if (q->pci_subvendor != codec->bus->pci->subsystem_vendor)
1020 continue;
1021 if (!q->pci_subdevice ||
1022 q->pci_subdevice == codec->bus->pci->subsystem_device)
1023 return alc_codec_rename(codec, q->name);
1024 }
1025
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02001026 return 0;
1027}
1028
Takashi Iwaie4770622011-07-08 11:11:35 +02001029
1030/*
Takashi Iwai1d045db2011-07-07 18:23:21 +02001031 * Digital-beep handlers
1032 */
1033#ifdef CONFIG_SND_HDA_INPUT_BEEP
Takashi Iwaifea80fa2018-06-20 12:52:46 +02001034
1035/* additional beep mixers; private_value will be overwritten */
1036static const struct snd_kcontrol_new alc_beep_mixer[] = {
1037 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
1038 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
1039};
1040
1041/* set up and create beep controls */
1042static int set_beep_amp(struct alc_spec *spec, hda_nid_t nid,
1043 int idx, int dir)
1044{
1045 struct snd_kcontrol_new *knew;
1046 unsigned int beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir);
1047 int i;
1048
1049 for (i = 0; i < ARRAY_SIZE(alc_beep_mixer); i++) {
1050 knew = snd_hda_gen_add_kctl(&spec->gen, NULL,
1051 &alc_beep_mixer[i]);
1052 if (!knew)
1053 return -ENOMEM;
1054 knew->private_value = beep_amp;
1055 }
1056 return 0;
1057}
Takashi Iwai1d045db2011-07-07 18:23:21 +02001058
1059static const struct snd_pci_quirk beep_white_list[] = {
Duncan Roe71100052012-10-10 14:19:50 +02001060 SND_PCI_QUIRK(0x1043, 0x103c, "ASUS", 1),
W. Trevor Kinga4b7f21d2014-03-29 17:47:24 -07001061 SND_PCI_QUIRK(0x1043, 0x115d, "ASUS", 1),
Takashi Iwai1d045db2011-07-07 18:23:21 +02001062 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
Takashi Iwai8554ee42013-02-25 09:54:43 +01001063 SND_PCI_QUIRK(0x1043, 0x8376, "EeePC", 1),
Takashi Iwai1d045db2011-07-07 18:23:21 +02001064 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
1065 SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1),
1066 SND_PCI_QUIRK(0x1043, 0x834a, "EeePC", 1),
Takashi Iwai78f8baf2012-03-06 14:02:32 +01001067 SND_PCI_QUIRK(0x1458, 0xa002, "GA-MA790X", 1),
Takashi Iwai1d045db2011-07-07 18:23:21 +02001068 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
Takashi Iwai051c78a2019-08-22 09:58:07 +02001069 /* blacklist -- no beep available */
1070 SND_PCI_QUIRK(0x17aa, 0x309e, "Lenovo ThinkCentre M73", 0),
1071 SND_PCI_QUIRK(0x17aa, 0x30a3, "Lenovo ThinkCentre M93", 0),
Takashi Iwai1d045db2011-07-07 18:23:21 +02001072 {}
1073};
1074
1075static inline int has_cdefine_beep(struct hda_codec *codec)
1076{
1077 struct alc_spec *spec = codec->spec;
1078 const struct snd_pci_quirk *q;
1079 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
1080 if (q)
1081 return q->value;
1082 return spec->cdefine.enable_pcbeep;
1083}
1084#else
Takashi Iwaifea80fa2018-06-20 12:52:46 +02001085#define set_beep_amp(spec, nid, idx, dir) 0
Takashi Iwai1d045db2011-07-07 18:23:21 +02001086#define has_cdefine_beep(codec) 0
1087#endif
1088
1089/* parse the BIOS configuration and set up the alc_spec */
1090/* return 1 if successful, 0 if the proper config is not found,
1091 * or a negative error code
1092 */
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001093static int alc_parse_auto_config(struct hda_codec *codec,
1094 const hda_nid_t *ignore_nids,
1095 const hda_nid_t *ssid_nids)
Takashi Iwai1d045db2011-07-07 18:23:21 +02001096{
1097 struct alc_spec *spec = codec->spec;
Takashi Iwai08c189f2012-12-19 15:22:24 +01001098 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001099 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001100
Takashi Iwai53c334a2011-08-23 18:27:14 +02001101 err = snd_hda_parse_pin_defcfg(codec, cfg, ignore_nids,
1102 spec->parse_flags);
Takashi Iwai1d045db2011-07-07 18:23:21 +02001103 if (err < 0)
1104 return err;
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001105
1106 if (ssid_nids)
1107 alc_ssid_check(codec, ssid_nids);
1108
Takashi Iwai08c189f2012-12-19 15:22:24 +01001109 err = snd_hda_gen_parse_auto_config(codec, cfg);
1110 if (err < 0)
1111 return err;
Takashi Iwai070cff42012-02-21 12:54:17 +01001112
Takashi Iwai1d045db2011-07-07 18:23:21 +02001113 return 1;
1114}
1115
Takashi Iwai3de95172012-05-07 18:03:15 +02001116/* common preparation job for alc_spec */
1117static int alc_alloc_spec(struct hda_codec *codec, hda_nid_t mixer_nid)
1118{
1119 struct alc_spec *spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1120 int err;
1121
1122 if (!spec)
1123 return -ENOMEM;
1124 codec->spec = spec;
Takashi Iwai08c189f2012-12-19 15:22:24 +01001125 snd_hda_gen_spec_init(&spec->gen);
1126 spec->gen.mixer_nid = mixer_nid;
1127 spec->gen.own_eapd_ctl = 1;
Takashi Iwai1098b7c2012-12-17 20:03:15 +01001128 codec->single_adc_amp = 1;
Takashi Iwai08c189f2012-12-19 15:22:24 +01001129 /* FIXME: do we need this for all Realtek codec models? */
1130 codec->spdif_status_reset = 1;
Takashi Iwai225068a2015-05-29 10:42:14 +02001131 codec->patch_ops = alc_patch_ops;
Takashi Iwai3de95172012-05-07 18:03:15 +02001132
1133 err = alc_codec_rename_from_preset(codec);
1134 if (err < 0) {
1135 kfree(spec);
1136 return err;
1137 }
1138 return 0;
1139}
1140
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001141static int alc880_parse_auto_config(struct hda_codec *codec)
1142{
1143 static const hda_nid_t alc880_ignore[] = { 0x1d, 0 };
Jesper Juhl7d7eb9e2012-04-12 22:11:25 +02001144 static const hda_nid_t alc880_ssids[] = { 0x15, 0x1b, 0x14, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001145 return alc_parse_auto_config(codec, alc880_ignore, alc880_ssids);
1146}
1147
Takashi Iwai1d045db2011-07-07 18:23:21 +02001148/*
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001149 * ALC880 fix-ups
1150 */
1151enum {
Takashi Iwai411225a2012-02-20 17:48:19 +01001152 ALC880_FIXUP_GPIO1,
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001153 ALC880_FIXUP_GPIO2,
1154 ALC880_FIXUP_MEDION_RIM,
Takashi Iwaidc6af522012-02-17 16:18:59 +01001155 ALC880_FIXUP_LG,
Takashi Iwaidb8a38e2013-08-09 12:34:42 +02001156 ALC880_FIXUP_LG_LW25,
Takashi Iwaif02aab52012-02-17 16:33:56 +01001157 ALC880_FIXUP_W810,
Takashi Iwai27e917f2012-02-17 17:49:54 +01001158 ALC880_FIXUP_EAPD_COEF,
Takashi Iwaib9368f52012-02-17 17:54:44 +01001159 ALC880_FIXUP_TCL_S700,
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001160 ALC880_FIXUP_VOL_KNOB,
1161 ALC880_FIXUP_FUJITSU,
Takashi Iwaiba533812012-02-20 16:36:52 +01001162 ALC880_FIXUP_F1734,
Takashi Iwai817de922012-02-20 17:20:48 +01001163 ALC880_FIXUP_UNIWILL,
Takashi Iwai967b88c2012-02-20 17:31:02 +01001164 ALC880_FIXUP_UNIWILL_DIG,
Takashi Iwai96e225f2012-02-20 17:41:51 +01001165 ALC880_FIXUP_Z71V,
Takashi Iwai487a5882013-11-07 07:29:30 +01001166 ALC880_FIXUP_ASUS_W5A,
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001167 ALC880_FIXUP_3ST_BASE,
1168 ALC880_FIXUP_3ST,
1169 ALC880_FIXUP_3ST_DIG,
1170 ALC880_FIXUP_5ST_BASE,
1171 ALC880_FIXUP_5ST,
1172 ALC880_FIXUP_5ST_DIG,
1173 ALC880_FIXUP_6ST_BASE,
1174 ALC880_FIXUP_6ST,
1175 ALC880_FIXUP_6ST_DIG,
Takashi Iwai53971452013-01-23 18:21:37 +01001176 ALC880_FIXUP_6ST_AUTOMUTE,
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001177};
1178
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001179/* enable the volume-knob widget support on NID 0x21 */
1180static void alc880_fixup_vol_knob(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001181 const struct hda_fixup *fix, int action)
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001182{
Takashi Iwai1727a772013-01-10 09:52:52 +01001183 if (action == HDA_FIXUP_ACT_PROBE)
Takashi Iwai62f949b2014-09-11 14:06:53 +02001184 snd_hda_jack_detect_enable_callback(codec, 0x21,
1185 alc_update_knob_master);
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001186}
1187
Takashi Iwai1727a772013-01-10 09:52:52 +01001188static const struct hda_fixup alc880_fixups[] = {
Takashi Iwai411225a2012-02-20 17:48:19 +01001189 [ALC880_FIXUP_GPIO1] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02001190 .type = HDA_FIXUP_FUNC,
1191 .v.func = alc_fixup_gpio1,
Takashi Iwai411225a2012-02-20 17:48:19 +01001192 },
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001193 [ALC880_FIXUP_GPIO2] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02001194 .type = HDA_FIXUP_FUNC,
1195 .v.func = alc_fixup_gpio2,
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001196 },
1197 [ALC880_FIXUP_MEDION_RIM] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001198 .type = HDA_FIXUP_VERBS,
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001199 .v.verbs = (const struct hda_verb[]) {
1200 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
1201 { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
1202 { }
1203 },
1204 .chained = true,
1205 .chain_id = ALC880_FIXUP_GPIO2,
1206 },
Takashi Iwaidc6af522012-02-17 16:18:59 +01001207 [ALC880_FIXUP_LG] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001208 .type = HDA_FIXUP_PINS,
1209 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaidc6af522012-02-17 16:18:59 +01001210 /* disable bogus unused pins */
1211 { 0x16, 0x411111f0 },
1212 { 0x18, 0x411111f0 },
1213 { 0x1a, 0x411111f0 },
1214 { }
1215 }
1216 },
Takashi Iwaidb8a38e2013-08-09 12:34:42 +02001217 [ALC880_FIXUP_LG_LW25] = {
1218 .type = HDA_FIXUP_PINS,
1219 .v.pins = (const struct hda_pintbl[]) {
1220 { 0x1a, 0x0181344f }, /* line-in */
1221 { 0x1b, 0x0321403f }, /* headphone */
1222 { }
1223 }
1224 },
Takashi Iwaif02aab52012-02-17 16:33:56 +01001225 [ALC880_FIXUP_W810] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001226 .type = HDA_FIXUP_PINS,
1227 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaif02aab52012-02-17 16:33:56 +01001228 /* disable bogus unused pins */
1229 { 0x17, 0x411111f0 },
1230 { }
1231 },
1232 .chained = true,
1233 .chain_id = ALC880_FIXUP_GPIO2,
1234 },
Takashi Iwai27e917f2012-02-17 17:49:54 +01001235 [ALC880_FIXUP_EAPD_COEF] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001236 .type = HDA_FIXUP_VERBS,
Takashi Iwai27e917f2012-02-17 17:49:54 +01001237 .v.verbs = (const struct hda_verb[]) {
1238 /* change to EAPD mode */
1239 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
1240 { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
1241 {}
1242 },
1243 },
Takashi Iwaib9368f52012-02-17 17:54:44 +01001244 [ALC880_FIXUP_TCL_S700] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001245 .type = HDA_FIXUP_VERBS,
Takashi Iwaib9368f52012-02-17 17:54:44 +01001246 .v.verbs = (const struct hda_verb[]) {
1247 /* change to EAPD mode */
1248 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
1249 { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
1250 {}
1251 },
1252 .chained = true,
1253 .chain_id = ALC880_FIXUP_GPIO2,
1254 },
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001255 [ALC880_FIXUP_VOL_KNOB] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001256 .type = HDA_FIXUP_FUNC,
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001257 .v.func = alc880_fixup_vol_knob,
1258 },
1259 [ALC880_FIXUP_FUJITSU] = {
1260 /* override all pins as BIOS on old Amilo is broken */
Takashi Iwai1727a772013-01-10 09:52:52 +01001261 .type = HDA_FIXUP_PINS,
1262 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaibb148bd2015-08-13 18:02:39 +02001263 { 0x14, 0x0121401f }, /* HP */
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001264 { 0x15, 0x99030120 }, /* speaker */
1265 { 0x16, 0x99030130 }, /* bass speaker */
1266 { 0x17, 0x411111f0 }, /* N/A */
1267 { 0x18, 0x411111f0 }, /* N/A */
1268 { 0x19, 0x01a19950 }, /* mic-in */
1269 { 0x1a, 0x411111f0 }, /* N/A */
1270 { 0x1b, 0x411111f0 }, /* N/A */
1271 { 0x1c, 0x411111f0 }, /* N/A */
1272 { 0x1d, 0x411111f0 }, /* N/A */
1273 { 0x1e, 0x01454140 }, /* SPDIF out */
1274 { }
1275 },
1276 .chained = true,
1277 .chain_id = ALC880_FIXUP_VOL_KNOB,
1278 },
Takashi Iwaiba533812012-02-20 16:36:52 +01001279 [ALC880_FIXUP_F1734] = {
1280 /* almost compatible with FUJITSU, but no bass and SPDIF */
Takashi Iwai1727a772013-01-10 09:52:52 +01001281 .type = HDA_FIXUP_PINS,
1282 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaibb148bd2015-08-13 18:02:39 +02001283 { 0x14, 0x0121401f }, /* HP */
Takashi Iwaiba533812012-02-20 16:36:52 +01001284 { 0x15, 0x99030120 }, /* speaker */
1285 { 0x16, 0x411111f0 }, /* N/A */
1286 { 0x17, 0x411111f0 }, /* N/A */
1287 { 0x18, 0x411111f0 }, /* N/A */
1288 { 0x19, 0x01a19950 }, /* mic-in */
1289 { 0x1a, 0x411111f0 }, /* N/A */
1290 { 0x1b, 0x411111f0 }, /* N/A */
1291 { 0x1c, 0x411111f0 }, /* N/A */
1292 { 0x1d, 0x411111f0 }, /* N/A */
1293 { 0x1e, 0x411111f0 }, /* N/A */
1294 { }
1295 },
1296 .chained = true,
1297 .chain_id = ALC880_FIXUP_VOL_KNOB,
1298 },
Takashi Iwai817de922012-02-20 17:20:48 +01001299 [ALC880_FIXUP_UNIWILL] = {
1300 /* need to fix HP and speaker pins to be parsed correctly */
Takashi Iwai1727a772013-01-10 09:52:52 +01001301 .type = HDA_FIXUP_PINS,
1302 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai817de922012-02-20 17:20:48 +01001303 { 0x14, 0x0121411f }, /* HP */
1304 { 0x15, 0x99030120 }, /* speaker */
1305 { 0x16, 0x99030130 }, /* bass speaker */
1306 { }
1307 },
1308 },
Takashi Iwai967b88c2012-02-20 17:31:02 +01001309 [ALC880_FIXUP_UNIWILL_DIG] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001310 .type = HDA_FIXUP_PINS,
1311 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai967b88c2012-02-20 17:31:02 +01001312 /* disable bogus unused pins */
1313 { 0x17, 0x411111f0 },
1314 { 0x19, 0x411111f0 },
1315 { 0x1b, 0x411111f0 },
1316 { 0x1f, 0x411111f0 },
1317 { }
1318 }
1319 },
Takashi Iwai96e225f2012-02-20 17:41:51 +01001320 [ALC880_FIXUP_Z71V] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001321 .type = HDA_FIXUP_PINS,
1322 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai96e225f2012-02-20 17:41:51 +01001323 /* set up the whole pins as BIOS is utterly broken */
1324 { 0x14, 0x99030120 }, /* speaker */
1325 { 0x15, 0x0121411f }, /* HP */
1326 { 0x16, 0x411111f0 }, /* N/A */
1327 { 0x17, 0x411111f0 }, /* N/A */
1328 { 0x18, 0x01a19950 }, /* mic-in */
1329 { 0x19, 0x411111f0 }, /* N/A */
1330 { 0x1a, 0x01813031 }, /* line-in */
1331 { 0x1b, 0x411111f0 }, /* N/A */
1332 { 0x1c, 0x411111f0 }, /* N/A */
1333 { 0x1d, 0x411111f0 }, /* N/A */
1334 { 0x1e, 0x0144111e }, /* SPDIF */
1335 { }
1336 }
1337 },
Takashi Iwai487a5882013-11-07 07:29:30 +01001338 [ALC880_FIXUP_ASUS_W5A] = {
1339 .type = HDA_FIXUP_PINS,
1340 .v.pins = (const struct hda_pintbl[]) {
1341 /* set up the whole pins as BIOS is utterly broken */
1342 { 0x14, 0x0121411f }, /* HP */
1343 { 0x15, 0x411111f0 }, /* N/A */
1344 { 0x16, 0x411111f0 }, /* N/A */
1345 { 0x17, 0x411111f0 }, /* N/A */
1346 { 0x18, 0x90a60160 }, /* mic */
1347 { 0x19, 0x411111f0 }, /* N/A */
1348 { 0x1a, 0x411111f0 }, /* N/A */
1349 { 0x1b, 0x411111f0 }, /* N/A */
1350 { 0x1c, 0x411111f0 }, /* N/A */
1351 { 0x1d, 0x411111f0 }, /* N/A */
1352 { 0x1e, 0xb743111e }, /* SPDIF out */
1353 { }
1354 },
1355 .chained = true,
1356 .chain_id = ALC880_FIXUP_GPIO1,
1357 },
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001358 [ALC880_FIXUP_3ST_BASE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001359 .type = HDA_FIXUP_PINS,
1360 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001361 { 0x14, 0x01014010 }, /* line-out */
1362 { 0x15, 0x411111f0 }, /* N/A */
1363 { 0x16, 0x411111f0 }, /* N/A */
1364 { 0x17, 0x411111f0 }, /* N/A */
1365 { 0x18, 0x01a19c30 }, /* mic-in */
1366 { 0x19, 0x0121411f }, /* HP */
1367 { 0x1a, 0x01813031 }, /* line-in */
1368 { 0x1b, 0x02a19c40 }, /* front-mic */
1369 { 0x1c, 0x411111f0 }, /* N/A */
1370 { 0x1d, 0x411111f0 }, /* N/A */
1371 /* 0x1e is filled in below */
1372 { 0x1f, 0x411111f0 }, /* N/A */
1373 { }
1374 }
1375 },
1376 [ALC880_FIXUP_3ST] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001377 .type = HDA_FIXUP_PINS,
1378 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001379 { 0x1e, 0x411111f0 }, /* N/A */
1380 { }
1381 },
1382 .chained = true,
1383 .chain_id = ALC880_FIXUP_3ST_BASE,
1384 },
1385 [ALC880_FIXUP_3ST_DIG] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001386 .type = HDA_FIXUP_PINS,
1387 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001388 { 0x1e, 0x0144111e }, /* SPDIF */
1389 { }
1390 },
1391 .chained = true,
1392 .chain_id = ALC880_FIXUP_3ST_BASE,
1393 },
1394 [ALC880_FIXUP_5ST_BASE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001395 .type = HDA_FIXUP_PINS,
1396 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001397 { 0x14, 0x01014010 }, /* front */
1398 { 0x15, 0x411111f0 }, /* N/A */
1399 { 0x16, 0x01011411 }, /* CLFE */
1400 { 0x17, 0x01016412 }, /* surr */
1401 { 0x18, 0x01a19c30 }, /* mic-in */
1402 { 0x19, 0x0121411f }, /* HP */
1403 { 0x1a, 0x01813031 }, /* line-in */
1404 { 0x1b, 0x02a19c40 }, /* front-mic */
1405 { 0x1c, 0x411111f0 }, /* N/A */
1406 { 0x1d, 0x411111f0 }, /* N/A */
1407 /* 0x1e is filled in below */
1408 { 0x1f, 0x411111f0 }, /* N/A */
1409 { }
1410 }
1411 },
1412 [ALC880_FIXUP_5ST] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001413 .type = HDA_FIXUP_PINS,
1414 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001415 { 0x1e, 0x411111f0 }, /* N/A */
1416 { }
1417 },
1418 .chained = true,
1419 .chain_id = ALC880_FIXUP_5ST_BASE,
1420 },
1421 [ALC880_FIXUP_5ST_DIG] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001422 .type = HDA_FIXUP_PINS,
1423 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001424 { 0x1e, 0x0144111e }, /* SPDIF */
1425 { }
1426 },
1427 .chained = true,
1428 .chain_id = ALC880_FIXUP_5ST_BASE,
1429 },
1430 [ALC880_FIXUP_6ST_BASE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001431 .type = HDA_FIXUP_PINS,
1432 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001433 { 0x14, 0x01014010 }, /* front */
1434 { 0x15, 0x01016412 }, /* surr */
1435 { 0x16, 0x01011411 }, /* CLFE */
1436 { 0x17, 0x01012414 }, /* side */
1437 { 0x18, 0x01a19c30 }, /* mic-in */
1438 { 0x19, 0x02a19c40 }, /* front-mic */
1439 { 0x1a, 0x01813031 }, /* line-in */
1440 { 0x1b, 0x0121411f }, /* HP */
1441 { 0x1c, 0x411111f0 }, /* N/A */
1442 { 0x1d, 0x411111f0 }, /* N/A */
1443 /* 0x1e is filled in below */
1444 { 0x1f, 0x411111f0 }, /* N/A */
1445 { }
1446 }
1447 },
1448 [ALC880_FIXUP_6ST] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001449 .type = HDA_FIXUP_PINS,
1450 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001451 { 0x1e, 0x411111f0 }, /* N/A */
1452 { }
1453 },
1454 .chained = true,
1455 .chain_id = ALC880_FIXUP_6ST_BASE,
1456 },
1457 [ALC880_FIXUP_6ST_DIG] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001458 .type = HDA_FIXUP_PINS,
1459 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001460 { 0x1e, 0x0144111e }, /* SPDIF */
1461 { }
1462 },
1463 .chained = true,
1464 .chain_id = ALC880_FIXUP_6ST_BASE,
1465 },
Takashi Iwai53971452013-01-23 18:21:37 +01001466 [ALC880_FIXUP_6ST_AUTOMUTE] = {
1467 .type = HDA_FIXUP_PINS,
1468 .v.pins = (const struct hda_pintbl[]) {
1469 { 0x1b, 0x0121401f }, /* HP with jack detect */
1470 { }
1471 },
1472 .chained_before = true,
1473 .chain_id = ALC880_FIXUP_6ST_BASE,
1474 },
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001475};
1476
1477static const struct snd_pci_quirk alc880_fixup_tbl[] = {
Takashi Iwaif02aab52012-02-17 16:33:56 +01001478 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_FIXUP_W810),
Takashi Iwai487a5882013-11-07 07:29:30 +01001479 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS W5A", ALC880_FIXUP_ASUS_W5A),
Takashi Iwai96e225f2012-02-20 17:41:51 +01001480 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_FIXUP_Z71V),
Takashi Iwai29e3fdc2012-02-20 17:56:57 +01001481 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_FIXUP_GPIO1),
David Henningsson6538de02014-06-10 10:52:50 +02001482 SND_PCI_QUIRK(0x147b, 0x1045, "ABit AA8XE", ALC880_FIXUP_6ST_AUTOMUTE),
Takashi Iwai29e3fdc2012-02-20 17:56:57 +01001483 SND_PCI_QUIRK(0x1558, 0x5401, "Clevo GPIO2", ALC880_FIXUP_GPIO2),
Takashi Iwai27e917f2012-02-17 17:49:54 +01001484 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo", ALC880_FIXUP_EAPD_COEF),
Takashi Iwai967b88c2012-02-20 17:31:02 +01001485 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_FIXUP_UNIWILL_DIG),
Takashi Iwaiba533812012-02-20 16:36:52 +01001486 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_FIXUP_F1734),
Takashi Iwai817de922012-02-20 17:20:48 +01001487 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_FIXUP_UNIWILL),
Takashi Iwai7833c7e2012-02-20 17:11:38 +01001488 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_FIXUP_VOL_KNOB),
Takashi Iwaif02aab52012-02-17 16:33:56 +01001489 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_FIXUP_W810),
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001490 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_FIXUP_MEDION_RIM),
Takashi Iwai53971452013-01-23 18:21:37 +01001491 SND_PCI_QUIRK(0x1631, 0xe011, "PB 13201056", ALC880_FIXUP_6ST_AUTOMUTE),
Takashi Iwaia1615742015-08-13 18:05:06 +02001492 SND_PCI_QUIRK(0x1734, 0x107c, "FSC Amilo M1437", ALC880_FIXUP_FUJITSU),
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001493 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FIXUP_FUJITSU),
Takashi Iwaiba533812012-02-20 16:36:52 +01001494 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_FIXUP_F1734),
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001495 SND_PCI_QUIRK(0x1734, 0x10b0, "FSC Amilo Pi1556", ALC880_FIXUP_FUJITSU),
Takashi Iwaidc6af522012-02-17 16:18:59 +01001496 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_FIXUP_LG),
1497 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_FIXUP_LG),
1498 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_FIXUP_LG),
Takashi Iwaidb8a38e2013-08-09 12:34:42 +02001499 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_FIXUP_LG_LW25),
Takashi Iwaib9368f52012-02-17 17:54:44 +01001500 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_FIXUP_TCL_S700),
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001501
1502 /* Below is the copied entries from alc880_quirks.c.
1503 * It's not quite sure whether BIOS sets the correct pin-config table
1504 * on these machines, thus they are kept to be compatible with
1505 * the old static quirks. Once when it's confirmed to work without
1506 * these overrides, it'd be better to remove.
1507 */
1508 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_FIXUP_5ST_DIG),
1509 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_FIXUP_6ST),
1510 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_FIXUP_3ST_DIG),
1511 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_FIXUP_6ST_DIG),
1512 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_FIXUP_6ST_DIG),
1513 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_FIXUP_6ST_DIG),
1514 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_FIXUP_3ST_DIG),
1515 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_FIXUP_3ST),
1516 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_FIXUP_6ST_DIG),
1517 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_FIXUP_3ST),
1518 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_FIXUP_3ST),
1519 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_FIXUP_5ST),
1520 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_FIXUP_5ST),
1521 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_FIXUP_5ST),
1522 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_FIXUP_6ST_DIG),
1523 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_FIXUP_6ST_DIG),
1524 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_FIXUP_6ST_DIG),
1525 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_FIXUP_6ST_DIG),
1526 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_FIXUP_5ST_DIG),
1527 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_FIXUP_5ST_DIG),
1528 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_FIXUP_5ST_DIG),
1529 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_FIXUP_6ST_DIG), /* broken BIOS */
1530 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_FIXUP_6ST_DIG),
1531 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1532 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1533 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1534 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_FIXUP_3ST_DIG),
1535 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1536 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_FIXUP_3ST_DIG),
1537 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_FIXUP_3ST_DIG),
1538 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1539 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1540 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1541 /* default Intel */
1542 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_FIXUP_3ST),
1543 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_FIXUP_5ST_DIG),
1544 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_FIXUP_6ST_DIG),
1545 {}
1546};
1547
Takashi Iwai1727a772013-01-10 09:52:52 +01001548static const struct hda_model_fixup alc880_fixup_models[] = {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001549 {.id = ALC880_FIXUP_3ST, .name = "3stack"},
1550 {.id = ALC880_FIXUP_3ST_DIG, .name = "3stack-digout"},
1551 {.id = ALC880_FIXUP_5ST, .name = "5stack"},
1552 {.id = ALC880_FIXUP_5ST_DIG, .name = "5stack-digout"},
1553 {.id = ALC880_FIXUP_6ST, .name = "6stack"},
1554 {.id = ALC880_FIXUP_6ST_DIG, .name = "6stack-digout"},
Takashi Iwai53971452013-01-23 18:21:37 +01001555 {.id = ALC880_FIXUP_6ST_AUTOMUTE, .name = "6stack-automute"},
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001556 {}
1557};
1558
1559
1560/*
Takashi Iwai1d045db2011-07-07 18:23:21 +02001561 * OK, here we have finally the patch for ALC880
1562 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02001563static int patch_alc880(struct hda_codec *codec)
1564{
1565 struct alc_spec *spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001566 int err;
1567
Takashi Iwai3de95172012-05-07 18:03:15 +02001568 err = alc_alloc_spec(codec, 0x0b);
1569 if (err < 0)
1570 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001571
Takashi Iwai3de95172012-05-07 18:03:15 +02001572 spec = codec->spec;
Takashi Iwai08c189f2012-12-19 15:22:24 +01001573 spec->gen.need_dac_fix = 1;
Takashi Iwai7504b6c2013-03-18 11:25:51 +01001574 spec->gen.beep_nid = 0x01;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001575
Takashi Iwai225068a2015-05-29 10:42:14 +02001576 codec->patch_ops.unsol_event = alc880_unsol_event;
1577
Takashi Iwaic9af7532019-05-10 11:01:43 +02001578 alc_pre_init(codec);
1579
Takashi Iwai1727a772013-01-10 09:52:52 +01001580 snd_hda_pick_fixup(codec, alc880_fixup_models, alc880_fixup_tbl,
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001581 alc880_fixups);
Takashi Iwai1727a772013-01-10 09:52:52 +01001582 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02001583
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001584 /* automatic parse from the BIOS config */
1585 err = alc880_parse_auto_config(codec);
1586 if (err < 0)
1587 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001588
Takashi Iwaifea80fa2018-06-20 12:52:46 +02001589 if (!spec->gen.no_analog) {
1590 err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
1591 if (err < 0)
1592 goto error;
1593 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02001594
Takashi Iwai1727a772013-01-10 09:52:52 +01001595 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01001596
Takashi Iwai1d045db2011-07-07 18:23:21 +02001597 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02001598
1599 error:
1600 alc_free(codec);
1601 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001602}
1603
1604
1605/*
1606 * ALC260 support
1607 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02001608static int alc260_parse_auto_config(struct hda_codec *codec)
1609{
Takashi Iwai1d045db2011-07-07 18:23:21 +02001610 static const hda_nid_t alc260_ignore[] = { 0x17, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001611 static const hda_nid_t alc260_ssids[] = { 0x10, 0x15, 0x0f, 0 };
1612 return alc_parse_auto_config(codec, alc260_ignore, alc260_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02001613}
1614
Takashi Iwai1d045db2011-07-07 18:23:21 +02001615/*
1616 * Pin config fixes
1617 */
1618enum {
Takashi Iwaica8f0422012-02-16 11:51:19 +01001619 ALC260_FIXUP_HP_DC5750,
1620 ALC260_FIXUP_HP_PIN_0F,
1621 ALC260_FIXUP_COEF,
Takashi Iwai15317ab2012-02-16 12:02:53 +01001622 ALC260_FIXUP_GPIO1,
Takashi Iwai20f7d922012-02-16 12:35:16 +01001623 ALC260_FIXUP_GPIO1_TOGGLE,
1624 ALC260_FIXUP_REPLACER,
Takashi Iwai0a1c4fa2012-02-16 12:42:30 +01001625 ALC260_FIXUP_HP_B1900,
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001626 ALC260_FIXUP_KN1,
Takashi Iwai39aedee2013-01-10 17:10:40 +01001627 ALC260_FIXUP_FSC_S7020,
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001628 ALC260_FIXUP_FSC_S7020_JWSE,
Takashi Iwaid08c5ef2013-11-22 08:06:36 +01001629 ALC260_FIXUP_VAIO_PINS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02001630};
1631
Takashi Iwai20f7d922012-02-16 12:35:16 +01001632static void alc260_gpio1_automute(struct hda_codec *codec)
1633{
1634 struct alc_spec *spec = codec->spec;
Takashi Iwaiaaf312d2018-06-19 22:28:22 +02001635
1636 alc_update_gpio_data(codec, 0x01, spec->gen.hp_jack_present);
Takashi Iwai20f7d922012-02-16 12:35:16 +01001637}
1638
1639static void alc260_fixup_gpio1_toggle(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001640 const struct hda_fixup *fix, int action)
Takashi Iwai20f7d922012-02-16 12:35:16 +01001641{
1642 struct alc_spec *spec = codec->spec;
Takashi Iwai1727a772013-01-10 09:52:52 +01001643 if (action == HDA_FIXUP_ACT_PROBE) {
Takashi Iwai20f7d922012-02-16 12:35:16 +01001644 /* although the machine has only one output pin, we need to
1645 * toggle GPIO1 according to the jack state
1646 */
Takashi Iwai08c189f2012-12-19 15:22:24 +01001647 spec->gen.automute_hook = alc260_gpio1_automute;
1648 spec->gen.detect_hp = 1;
1649 spec->gen.automute_speaker = 1;
1650 spec->gen.autocfg.hp_pins[0] = 0x0f; /* copy it for automute */
Takashi Iwai62f949b2014-09-11 14:06:53 +02001651 snd_hda_jack_detect_enable_callback(codec, 0x0f,
Takashi Iwai08c189f2012-12-19 15:22:24 +01001652 snd_hda_gen_hp_automute);
Takashi Iwai5579cd62018-06-19 22:22:41 +02001653 alc_setup_gpio(codec, 0x01);
Takashi Iwai20f7d922012-02-16 12:35:16 +01001654 }
1655}
1656
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001657static void alc260_fixup_kn1(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001658 const struct hda_fixup *fix, int action)
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001659{
1660 struct alc_spec *spec = codec->spec;
Takashi Iwai1727a772013-01-10 09:52:52 +01001661 static const struct hda_pintbl pincfgs[] = {
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001662 { 0x0f, 0x02214000 }, /* HP/speaker */
1663 { 0x12, 0x90a60160 }, /* int mic */
1664 { 0x13, 0x02a19000 }, /* ext mic */
1665 { 0x18, 0x01446000 }, /* SPDIF out */
1666 /* disable bogus I/O pins */
1667 { 0x10, 0x411111f0 },
1668 { 0x11, 0x411111f0 },
1669 { 0x14, 0x411111f0 },
1670 { 0x15, 0x411111f0 },
1671 { 0x16, 0x411111f0 },
1672 { 0x17, 0x411111f0 },
1673 { 0x19, 0x411111f0 },
1674 { }
1675 };
1676
1677 switch (action) {
Takashi Iwai1727a772013-01-10 09:52:52 +01001678 case HDA_FIXUP_ACT_PRE_PROBE:
1679 snd_hda_apply_pincfgs(codec, pincfgs);
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001680 spec->init_amp = ALC_INIT_NONE;
1681 break;
1682 }
1683}
1684
Takashi Iwai39aedee2013-01-10 17:10:40 +01001685static void alc260_fixup_fsc_s7020(struct hda_codec *codec,
1686 const struct hda_fixup *fix, int action)
1687{
1688 struct alc_spec *spec = codec->spec;
Takashi Iwai1c76aa52018-06-21 16:37:54 +02001689 if (action == HDA_FIXUP_ACT_PRE_PROBE)
Takashi Iwaie6e0ee52013-02-18 17:04:20 +01001690 spec->init_amp = ALC_INIT_NONE;
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001691}
1692
1693static void alc260_fixup_fsc_s7020_jwse(struct hda_codec *codec,
1694 const struct hda_fixup *fix, int action)
1695{
1696 struct alc_spec *spec = codec->spec;
1697 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwaif811c3c2013-03-07 18:32:59 +01001698 spec->gen.add_jack_modes = 1;
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001699 spec->gen.hp_mic = 1;
Takashi Iwaie6e0ee52013-02-18 17:04:20 +01001700 }
Takashi Iwai39aedee2013-01-10 17:10:40 +01001701}
1702
Takashi Iwai1727a772013-01-10 09:52:52 +01001703static const struct hda_fixup alc260_fixups[] = {
Takashi Iwaica8f0422012-02-16 11:51:19 +01001704 [ALC260_FIXUP_HP_DC5750] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001705 .type = HDA_FIXUP_PINS,
1706 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02001707 { 0x11, 0x90130110 }, /* speaker */
1708 { }
1709 }
1710 },
Takashi Iwaica8f0422012-02-16 11:51:19 +01001711 [ALC260_FIXUP_HP_PIN_0F] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001712 .type = HDA_FIXUP_PINS,
1713 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaica8f0422012-02-16 11:51:19 +01001714 { 0x0f, 0x01214000 }, /* HP */
1715 { }
1716 }
1717 },
1718 [ALC260_FIXUP_COEF] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001719 .type = HDA_FIXUP_VERBS,
Takashi Iwaica8f0422012-02-16 11:51:19 +01001720 .v.verbs = (const struct hda_verb[]) {
Ronan Marquete30cf2d2014-06-01 18:38:53 +02001721 { 0x1a, AC_VERB_SET_COEF_INDEX, 0x07 },
1722 { 0x1a, AC_VERB_SET_PROC_COEF, 0x3040 },
Takashi Iwaica8f0422012-02-16 11:51:19 +01001723 { }
1724 },
Takashi Iwaica8f0422012-02-16 11:51:19 +01001725 },
Takashi Iwai15317ab2012-02-16 12:02:53 +01001726 [ALC260_FIXUP_GPIO1] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02001727 .type = HDA_FIXUP_FUNC,
1728 .v.func = alc_fixup_gpio1,
Takashi Iwai15317ab2012-02-16 12:02:53 +01001729 },
Takashi Iwai20f7d922012-02-16 12:35:16 +01001730 [ALC260_FIXUP_GPIO1_TOGGLE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001731 .type = HDA_FIXUP_FUNC,
Takashi Iwai20f7d922012-02-16 12:35:16 +01001732 .v.func = alc260_fixup_gpio1_toggle,
1733 .chained = true,
1734 .chain_id = ALC260_FIXUP_HP_PIN_0F,
1735 },
1736 [ALC260_FIXUP_REPLACER] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001737 .type = HDA_FIXUP_VERBS,
Takashi Iwai20f7d922012-02-16 12:35:16 +01001738 .v.verbs = (const struct hda_verb[]) {
Takashi Iwai192a98e2014-06-02 15:16:07 +02001739 { 0x1a, AC_VERB_SET_COEF_INDEX, 0x07 },
1740 { 0x1a, AC_VERB_SET_PROC_COEF, 0x3050 },
Takashi Iwai20f7d922012-02-16 12:35:16 +01001741 { }
1742 },
1743 .chained = true,
1744 .chain_id = ALC260_FIXUP_GPIO1_TOGGLE,
1745 },
Takashi Iwai0a1c4fa2012-02-16 12:42:30 +01001746 [ALC260_FIXUP_HP_B1900] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001747 .type = HDA_FIXUP_FUNC,
Takashi Iwai0a1c4fa2012-02-16 12:42:30 +01001748 .v.func = alc260_fixup_gpio1_toggle,
1749 .chained = true,
1750 .chain_id = ALC260_FIXUP_COEF,
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001751 },
1752 [ALC260_FIXUP_KN1] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001753 .type = HDA_FIXUP_FUNC,
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001754 .v.func = alc260_fixup_kn1,
1755 },
Takashi Iwai39aedee2013-01-10 17:10:40 +01001756 [ALC260_FIXUP_FSC_S7020] = {
1757 .type = HDA_FIXUP_FUNC,
1758 .v.func = alc260_fixup_fsc_s7020,
1759 },
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001760 [ALC260_FIXUP_FSC_S7020_JWSE] = {
1761 .type = HDA_FIXUP_FUNC,
1762 .v.func = alc260_fixup_fsc_s7020_jwse,
1763 .chained = true,
1764 .chain_id = ALC260_FIXUP_FSC_S7020,
1765 },
Takashi Iwaid08c5ef2013-11-22 08:06:36 +01001766 [ALC260_FIXUP_VAIO_PINS] = {
1767 .type = HDA_FIXUP_PINS,
1768 .v.pins = (const struct hda_pintbl[]) {
1769 /* Pin configs are missing completely on some VAIOs */
1770 { 0x0f, 0x01211020 },
1771 { 0x10, 0x0001003f },
1772 { 0x11, 0x411111f0 },
1773 { 0x12, 0x01a15930 },
1774 { 0x13, 0x411111f0 },
1775 { 0x14, 0x411111f0 },
1776 { 0x15, 0x411111f0 },
1777 { 0x16, 0x411111f0 },
1778 { 0x17, 0x411111f0 },
1779 { 0x18, 0x411111f0 },
1780 { 0x19, 0x411111f0 },
1781 { }
1782 }
1783 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02001784};
1785
1786static const struct snd_pci_quirk alc260_fixup_tbl[] = {
Takashi Iwai15317ab2012-02-16 12:02:53 +01001787 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_FIXUP_GPIO1),
Takashi Iwaica8f0422012-02-16 11:51:19 +01001788 SND_PCI_QUIRK(0x1025, 0x007f, "Acer Aspire 9500", ALC260_FIXUP_COEF),
Takashi Iwai15317ab2012-02-16 12:02:53 +01001789 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_FIXUP_GPIO1),
Takashi Iwaica8f0422012-02-16 11:51:19 +01001790 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", ALC260_FIXUP_HP_DC5750),
Takashi Iwai0a1c4fa2012-02-16 12:42:30 +01001791 SND_PCI_QUIRK(0x103c, 0x30ba, "HP Presario B1900", ALC260_FIXUP_HP_B1900),
Takashi Iwaid08c5ef2013-11-22 08:06:36 +01001792 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_FIXUP_VAIO_PINS),
Takashi Iwai0f5a5b82013-11-21 09:12:52 +01001793 SND_PCI_QUIRK(0x104d, 0x81e2, "Sony VAIO TX", ALC260_FIXUP_HP_PIN_0F),
Takashi Iwai39aedee2013-01-10 17:10:40 +01001794 SND_PCI_QUIRK(0x10cf, 0x1326, "FSC LifeBook S7020", ALC260_FIXUP_FSC_S7020),
Takashi Iwaib1f58082012-02-16 12:45:03 +01001795 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FIXUP_GPIO1),
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001796 SND_PCI_QUIRK(0x152d, 0x0729, "Quanta KN1", ALC260_FIXUP_KN1),
Takashi Iwai20f7d922012-02-16 12:35:16 +01001797 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_FIXUP_REPLACER),
Takashi Iwaica8f0422012-02-16 11:51:19 +01001798 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_FIXUP_COEF),
Takashi Iwai1d045db2011-07-07 18:23:21 +02001799 {}
1800};
1801
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001802static const struct hda_model_fixup alc260_fixup_models[] = {
1803 {.id = ALC260_FIXUP_GPIO1, .name = "gpio1"},
1804 {.id = ALC260_FIXUP_COEF, .name = "coef"},
1805 {.id = ALC260_FIXUP_FSC_S7020, .name = "fujitsu"},
1806 {.id = ALC260_FIXUP_FSC_S7020_JWSE, .name = "fujitsu-jwse"},
1807 {}
1808};
1809
Takashi Iwai1d045db2011-07-07 18:23:21 +02001810/*
1811 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02001812static int patch_alc260(struct hda_codec *codec)
1813{
1814 struct alc_spec *spec;
Takashi Iwaic3c2c9e2012-02-16 12:59:55 +01001815 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001816
Takashi Iwai3de95172012-05-07 18:03:15 +02001817 err = alc_alloc_spec(codec, 0x07);
1818 if (err < 0)
1819 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001820
Takashi Iwai3de95172012-05-07 18:03:15 +02001821 spec = codec->spec;
Takashi Iwaiea46c3c2013-01-15 18:45:53 +01001822 /* as quite a few machines require HP amp for speaker outputs,
1823 * it's easier to enable it unconditionally; even if it's unneeded,
1824 * it's almost harmless.
1825 */
1826 spec->gen.prefer_hp_amp = 1;
Takashi Iwai7504b6c2013-03-18 11:25:51 +01001827 spec->gen.beep_nid = 0x01;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001828
Takashi Iwai225068a2015-05-29 10:42:14 +02001829 spec->shutup = alc_eapd_shutup;
1830
Takashi Iwaic9af7532019-05-10 11:01:43 +02001831 alc_pre_init(codec);
1832
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001833 snd_hda_pick_fixup(codec, alc260_fixup_models, alc260_fixup_tbl,
1834 alc260_fixups);
Takashi Iwai1727a772013-01-10 09:52:52 +01001835 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02001836
Takashi Iwaic3c2c9e2012-02-16 12:59:55 +01001837 /* automatic parse from the BIOS config */
1838 err = alc260_parse_auto_config(codec);
1839 if (err < 0)
1840 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001841
Takashi Iwaifea80fa2018-06-20 12:52:46 +02001842 if (!spec->gen.no_analog) {
1843 err = set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
1844 if (err < 0)
1845 goto error;
1846 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02001847
Takashi Iwai1727a772013-01-10 09:52:52 +01001848 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01001849
Takashi Iwai1d045db2011-07-07 18:23:21 +02001850 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02001851
1852 error:
1853 alc_free(codec);
1854 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001855}
1856
1857
1858/*
1859 * ALC882/883/885/888/889 support
1860 *
1861 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
1862 * configuration. Each pin widget can choose any input DACs and a mixer.
1863 * Each ADC is connected from a mixer of all inputs. This makes possible
1864 * 6-channel independent captures.
1865 *
1866 * In addition, an independent DAC for the multi-playback (not used in this
1867 * driver yet).
1868 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02001869
1870/*
1871 * Pin config fixes
1872 */
1873enum {
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01001874 ALC882_FIXUP_ABIT_AW9D_MAX,
1875 ALC882_FIXUP_LENOVO_Y530,
1876 ALC882_FIXUP_PB_M5210,
1877 ALC882_FIXUP_ACER_ASPIRE_7736,
1878 ALC882_FIXUP_ASUS_W90V,
Marton Balint8f239212012-03-05 21:33:23 +01001879 ALC889_FIXUP_CD,
David Henningssonb2c53e22014-01-01 14:01:34 +01001880 ALC889_FIXUP_FRONT_HP_NO_PRESENCE,
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01001881 ALC889_FIXUP_VAIO_TT,
Takashi Iwai0e7cc2e2011-11-09 12:42:48 +01001882 ALC888_FIXUP_EEE1601,
Takashi Iwai177943a32011-11-09 12:55:18 +01001883 ALC882_FIXUP_EAPD,
Takashi Iwai7a6069b2011-11-09 15:22:01 +01001884 ALC883_FIXUP_EAPD,
Takashi Iwai8812c4f2011-11-09 17:39:15 +01001885 ALC883_FIXUP_ACER_EAPD,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001886 ALC882_FIXUP_GPIO1,
1887 ALC882_FIXUP_GPIO2,
Takashi Iwaieb844d52011-11-09 18:03:07 +01001888 ALC882_FIXUP_GPIO3,
Takashi Iwai68ef0562011-11-09 18:24:44 +01001889 ALC889_FIXUP_COEF,
1890 ALC882_FIXUP_ASUS_W2JC,
Takashi Iwaic3e837b2011-11-10 16:01:47 +01001891 ALC882_FIXUP_ACER_ASPIRE_4930G,
1892 ALC882_FIXUP_ACER_ASPIRE_8930G,
1893 ALC882_FIXUP_ASPIRE_8930G_VERBS,
Takashi Iwai56710872011-11-14 17:42:11 +01001894 ALC885_FIXUP_MACPRO_GPIO,
Takashi Iwai02a237b2012-02-13 15:25:07 +01001895 ALC889_FIXUP_DAC_ROUTE,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001896 ALC889_FIXUP_MBP_VREF,
1897 ALC889_FIXUP_IMAC91_VREF,
Adrien Vergée7729a42014-01-24 14:56:14 -05001898 ALC889_FIXUP_MBA11_VREF,
Takashi Iwai0756f092013-12-04 13:59:45 +01001899 ALC889_FIXUP_MBA21_VREF,
Takashi Iwaic20f31e2014-02-03 11:02:10 +01001900 ALC889_FIXUP_MP11_VREF,
Mario Kleiner9f660a12015-12-22 00:45:43 +01001901 ALC889_FIXUP_MP41_VREF,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02001902 ALC882_FIXUP_INV_DMIC,
Takashi Iwaie427c232012-07-29 10:04:08 +02001903 ALC882_FIXUP_NO_PRIMARY_HP,
Takashi Iwai1f0bbf02013-11-28 15:21:21 +01001904 ALC887_FIXUP_ASUS_BASS,
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01001905 ALC887_FIXUP_BASS_CHMAP,
Takashi Iwai7beb3a62017-04-10 18:05:52 +02001906 ALC1220_FIXUP_GB_DUAL_CODECS,
Peisen0202f5c2017-10-26 10:35:36 +08001907 ALC1220_FIXUP_CLEVO_P950,
Richard Sailer80690a22019-04-02 15:52:04 +02001908 ALC1220_FIXUP_CLEVO_PB51ED,
1909 ALC1220_FIXUP_CLEVO_PB51ED_PINS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02001910};
1911
Takashi Iwai68ef0562011-11-09 18:24:44 +01001912static void alc889_fixup_coef(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001913 const struct hda_fixup *fix, int action)
Takashi Iwai68ef0562011-11-09 18:24:44 +01001914{
Takashi Iwai1727a772013-01-10 09:52:52 +01001915 if (action != HDA_FIXUP_ACT_INIT)
Takashi Iwai68ef0562011-11-09 18:24:44 +01001916 return;
Kailang Yang1df88742014-10-29 16:10:13 +08001917 alc_update_coef_idx(codec, 7, 0, 0x2030);
Takashi Iwai68ef0562011-11-09 18:24:44 +01001918}
1919
Takashi Iwai56710872011-11-14 17:42:11 +01001920/* set up GPIO at initialization */
1921static void alc885_fixup_macpro_gpio(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001922 const struct hda_fixup *fix, int action)
Takashi Iwai56710872011-11-14 17:42:11 +01001923{
Takashi Iwai215c8502018-06-19 22:34:26 +02001924 struct alc_spec *spec = codec->spec;
1925
1926 spec->gpio_write_delay = true;
1927 alc_fixup_gpio3(codec, fix, action);
Takashi Iwai56710872011-11-14 17:42:11 +01001928}
1929
Takashi Iwai02a237b2012-02-13 15:25:07 +01001930/* Fix the connection of some pins for ALC889:
1931 * At least, Acer Aspire 5935 shows the connections to DAC3/4 don't
1932 * work correctly (bko#42740)
1933 */
1934static void alc889_fixup_dac_route(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001935 const struct hda_fixup *fix, int action)
Takashi Iwai02a237b2012-02-13 15:25:07 +01001936{
Takashi Iwai1727a772013-01-10 09:52:52 +01001937 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwaief8d60f2012-02-17 10:12:38 +01001938 /* fake the connections during parsing the tree */
Takashi Iwai02a237b2012-02-13 15:25:07 +01001939 hda_nid_t conn1[2] = { 0x0c, 0x0d };
1940 hda_nid_t conn2[2] = { 0x0e, 0x0f };
1941 snd_hda_override_conn_list(codec, 0x14, 2, conn1);
1942 snd_hda_override_conn_list(codec, 0x15, 2, conn1);
1943 snd_hda_override_conn_list(codec, 0x18, 2, conn2);
1944 snd_hda_override_conn_list(codec, 0x1a, 2, conn2);
Takashi Iwai1727a772013-01-10 09:52:52 +01001945 } else if (action == HDA_FIXUP_ACT_PROBE) {
Takashi Iwaief8d60f2012-02-17 10:12:38 +01001946 /* restore the connections */
1947 hda_nid_t conn[5] = { 0x0c, 0x0d, 0x0e, 0x0f, 0x26 };
1948 snd_hda_override_conn_list(codec, 0x14, 5, conn);
1949 snd_hda_override_conn_list(codec, 0x15, 5, conn);
1950 snd_hda_override_conn_list(codec, 0x18, 5, conn);
1951 snd_hda_override_conn_list(codec, 0x1a, 5, conn);
Takashi Iwai02a237b2012-02-13 15:25:07 +01001952 }
1953}
1954
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001955/* Set VREF on HP pin */
1956static void alc889_fixup_mbp_vref(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001957 const struct hda_fixup *fix, int action)
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001958{
1959 struct alc_spec *spec = codec->spec;
Mario Kleiner9f660a12015-12-22 00:45:43 +01001960 static hda_nid_t nids[3] = { 0x14, 0x15, 0x19 };
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001961 int i;
1962
Takashi Iwai1727a772013-01-10 09:52:52 +01001963 if (action != HDA_FIXUP_ACT_INIT)
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001964 return;
1965 for (i = 0; i < ARRAY_SIZE(nids); i++) {
1966 unsigned int val = snd_hda_codec_get_pincfg(codec, nids[i]);
1967 if (get_defcfg_device(val) != AC_JACK_HP_OUT)
1968 continue;
Takashi Iwaid3f02d62013-01-10 10:12:22 +01001969 val = snd_hda_codec_get_pin_target(codec, nids[i]);
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001970 val |= AC_PINCTL_VREF_80;
Takashi Iwaicdd03ce2012-04-20 12:34:50 +02001971 snd_hda_set_pin_ctl(codec, nids[i], val);
Takashi Iwai08c189f2012-12-19 15:22:24 +01001972 spec->gen.keep_vref_in_automute = 1;
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001973 break;
1974 }
1975}
1976
Takashi Iwai0756f092013-12-04 13:59:45 +01001977static void alc889_fixup_mac_pins(struct hda_codec *codec,
1978 const hda_nid_t *nids, int num_nids)
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001979{
1980 struct alc_spec *spec = codec->spec;
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001981 int i;
1982
Takashi Iwai0756f092013-12-04 13:59:45 +01001983 for (i = 0; i < num_nids; i++) {
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001984 unsigned int val;
Takashi Iwaid3f02d62013-01-10 10:12:22 +01001985 val = snd_hda_codec_get_pin_target(codec, nids[i]);
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001986 val |= AC_PINCTL_VREF_50;
Takashi Iwaicdd03ce2012-04-20 12:34:50 +02001987 snd_hda_set_pin_ctl(codec, nids[i], val);
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001988 }
Takashi Iwai08c189f2012-12-19 15:22:24 +01001989 spec->gen.keep_vref_in_automute = 1;
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001990}
1991
Takashi Iwai0756f092013-12-04 13:59:45 +01001992/* Set VREF on speaker pins on imac91 */
1993static void alc889_fixup_imac91_vref(struct hda_codec *codec,
1994 const struct hda_fixup *fix, int action)
1995{
1996 static hda_nid_t nids[2] = { 0x18, 0x1a };
1997
1998 if (action == HDA_FIXUP_ACT_INIT)
1999 alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
2000}
2001
Adrien Vergée7729a42014-01-24 14:56:14 -05002002/* Set VREF on speaker pins on mba11 */
2003static void alc889_fixup_mba11_vref(struct hda_codec *codec,
2004 const struct hda_fixup *fix, int action)
2005{
2006 static hda_nid_t nids[1] = { 0x18 };
2007
2008 if (action == HDA_FIXUP_ACT_INIT)
2009 alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
2010}
2011
Takashi Iwai0756f092013-12-04 13:59:45 +01002012/* Set VREF on speaker pins on mba21 */
2013static void alc889_fixup_mba21_vref(struct hda_codec *codec,
2014 const struct hda_fixup *fix, int action)
2015{
2016 static hda_nid_t nids[2] = { 0x18, 0x19 };
2017
2018 if (action == HDA_FIXUP_ACT_INIT)
2019 alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
2020}
2021
Takashi Iwaie427c232012-07-29 10:04:08 +02002022/* Don't take HP output as primary
Fernando Luis Vázquez Caod9111492013-02-12 16:49:46 +09002023 * Strangely, the speaker output doesn't work on Vaio Z and some Vaio
2024 * all-in-one desktop PCs (for example VGC-LN51JGB) through DAC 0x05
Takashi Iwaie427c232012-07-29 10:04:08 +02002025 */
2026static void alc882_fixup_no_primary_hp(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01002027 const struct hda_fixup *fix, int action)
Takashi Iwaie427c232012-07-29 10:04:08 +02002028{
2029 struct alc_spec *spec = codec->spec;
Takashi Iwaida96fb52013-07-29 16:54:36 +02002030 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai08c189f2012-12-19 15:22:24 +01002031 spec->gen.no_primary_hp = 1;
Takashi Iwaida96fb52013-07-29 16:54:36 +02002032 spec->gen.no_multi_io = 1;
2033 }
Takashi Iwaie427c232012-07-29 10:04:08 +02002034}
2035
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01002036static void alc_fixup_bass_chmap(struct hda_codec *codec,
2037 const struct hda_fixup *fix, int action);
2038
Takashi Iwai7beb3a62017-04-10 18:05:52 +02002039/* For dual-codec configuration, we need to disable some features to avoid
2040 * conflicts of kctls and PCM streams
2041 */
2042static void alc_fixup_dual_codecs(struct hda_codec *codec,
2043 const struct hda_fixup *fix, int action)
2044{
2045 struct alc_spec *spec = codec->spec;
2046
2047 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2048 return;
2049 /* disable vmaster */
2050 spec->gen.suppress_vmaster = 1;
2051 /* auto-mute and auto-mic switch don't work with multiple codecs */
2052 spec->gen.suppress_auto_mute = 1;
2053 spec->gen.suppress_auto_mic = 1;
2054 /* disable aamix as well */
2055 spec->gen.mixer_nid = 0;
2056 /* add location prefix to avoid conflicts */
2057 codec->force_pin_prefix = 1;
2058}
2059
2060static void rename_ctl(struct hda_codec *codec, const char *oldname,
2061 const char *newname)
2062{
2063 struct snd_kcontrol *kctl;
2064
2065 kctl = snd_hda_find_mixer_ctl(codec, oldname);
2066 if (kctl)
2067 strcpy(kctl->id.name, newname);
2068}
2069
2070static void alc1220_fixup_gb_dual_codecs(struct hda_codec *codec,
2071 const struct hda_fixup *fix,
2072 int action)
2073{
2074 alc_fixup_dual_codecs(codec, fix, action);
2075 switch (action) {
2076 case HDA_FIXUP_ACT_PRE_PROBE:
2077 /* override card longname to provide a unique UCM profile */
2078 strcpy(codec->card->longname, "HDAudio-Gigabyte-ALC1220DualCodecs");
2079 break;
2080 case HDA_FIXUP_ACT_BUILD:
2081 /* rename Capture controls depending on the codec */
2082 rename_ctl(codec, "Capture Volume",
2083 codec->addr == 0 ?
2084 "Rear-Panel Capture Volume" :
2085 "Front-Panel Capture Volume");
2086 rename_ctl(codec, "Capture Switch",
2087 codec->addr == 0 ?
2088 "Rear-Panel Capture Switch" :
2089 "Front-Panel Capture Switch");
2090 break;
2091 }
2092}
2093
Peisen0202f5c2017-10-26 10:35:36 +08002094static void alc1220_fixup_clevo_p950(struct hda_codec *codec,
2095 const struct hda_fixup *fix,
2096 int action)
2097{
2098 hda_nid_t conn1[1] = { 0x0c };
2099
2100 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2101 return;
2102
2103 alc_update_coef_idx(codec, 0x7, 0, 0x3c3);
2104 /* We therefore want to make sure 0x14 (front headphone) and
2105 * 0x1b (speakers) use the stereo DAC 0x02
2106 */
2107 snd_hda_override_conn_list(codec, 0x14, 1, conn1);
2108 snd_hda_override_conn_list(codec, 0x1b, 1, conn1);
2109}
2110
Jeremy Soller7f665b12019-02-13 10:56:19 -07002111static void alc_fixup_headset_mode_no_hp_mic(struct hda_codec *codec,
2112 const struct hda_fixup *fix, int action);
2113
Richard Sailer80690a22019-04-02 15:52:04 +02002114static void alc1220_fixup_clevo_pb51ed(struct hda_codec *codec,
Jeremy Soller7f665b12019-02-13 10:56:19 -07002115 const struct hda_fixup *fix,
2116 int action)
2117{
2118 alc1220_fixup_clevo_p950(codec, fix, action);
2119 alc_fixup_headset_mode_no_hp_mic(codec, fix, action);
2120}
2121
Takashi Iwai1727a772013-01-10 09:52:52 +01002122static const struct hda_fixup alc882_fixups[] = {
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002123 [ALC882_FIXUP_ABIT_AW9D_MAX] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002124 .type = HDA_FIXUP_PINS,
2125 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002126 { 0x15, 0x01080104 }, /* side */
2127 { 0x16, 0x01011012 }, /* rear */
2128 { 0x17, 0x01016011 }, /* clfe */
2129 { }
2130 }
2131 },
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002132 [ALC882_FIXUP_LENOVO_Y530] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002133 .type = HDA_FIXUP_PINS,
2134 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002135 { 0x15, 0x99130112 }, /* rear int speakers */
2136 { 0x16, 0x99130111 }, /* subwoofer */
2137 { }
2138 }
2139 },
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002140 [ALC882_FIXUP_PB_M5210] = {
Takashi Iwaifd108212013-01-10 10:18:14 +01002141 .type = HDA_FIXUP_PINCTLS,
2142 .v.pins = (const struct hda_pintbl[]) {
2143 { 0x19, PIN_VREF50 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02002144 {}
2145 }
2146 },
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002147 [ALC882_FIXUP_ACER_ASPIRE_7736] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002148 .type = HDA_FIXUP_FUNC,
Takashi Iwai23d30f22012-05-07 17:17:32 +02002149 .v.func = alc_fixup_sku_ignore,
Takashi Iwai1d045db2011-07-07 18:23:21 +02002150 },
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002151 [ALC882_FIXUP_ASUS_W90V] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002152 .type = HDA_FIXUP_PINS,
2153 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai5cdf7452011-10-26 23:04:08 +02002154 { 0x16, 0x99130110 }, /* fix sequence for CLFE */
2155 { }
2156 }
2157 },
Marton Balint8f239212012-03-05 21:33:23 +01002158 [ALC889_FIXUP_CD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002159 .type = HDA_FIXUP_PINS,
2160 .v.pins = (const struct hda_pintbl[]) {
Marton Balint8f239212012-03-05 21:33:23 +01002161 { 0x1c, 0x993301f0 }, /* CD */
2162 { }
2163 }
2164 },
David Henningssonb2c53e22014-01-01 14:01:34 +01002165 [ALC889_FIXUP_FRONT_HP_NO_PRESENCE] = {
2166 .type = HDA_FIXUP_PINS,
2167 .v.pins = (const struct hda_pintbl[]) {
2168 { 0x1b, 0x02214120 }, /* Front HP jack is flaky, disable jack detect */
2169 { }
2170 },
2171 .chained = true,
2172 .chain_id = ALC889_FIXUP_CD,
2173 },
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002174 [ALC889_FIXUP_VAIO_TT] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002175 .type = HDA_FIXUP_PINS,
2176 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002177 { 0x17, 0x90170111 }, /* hidden surround speaker */
2178 { }
2179 }
2180 },
Takashi Iwai0e7cc2e2011-11-09 12:42:48 +01002181 [ALC888_FIXUP_EEE1601] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002182 .type = HDA_FIXUP_VERBS,
Takashi Iwai0e7cc2e2011-11-09 12:42:48 +01002183 .v.verbs = (const struct hda_verb[]) {
2184 { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b },
2185 { 0x20, AC_VERB_SET_PROC_COEF, 0x0838 },
2186 { }
2187 }
Takashi Iwai177943a32011-11-09 12:55:18 +01002188 },
2189 [ALC882_FIXUP_EAPD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002190 .type = HDA_FIXUP_VERBS,
Takashi Iwai177943a32011-11-09 12:55:18 +01002191 .v.verbs = (const struct hda_verb[]) {
2192 /* change to EAPD mode */
2193 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2194 { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
2195 { }
2196 }
2197 },
Takashi Iwai7a6069b2011-11-09 15:22:01 +01002198 [ALC883_FIXUP_EAPD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002199 .type = HDA_FIXUP_VERBS,
Takashi Iwai7a6069b2011-11-09 15:22:01 +01002200 .v.verbs = (const struct hda_verb[]) {
2201 /* change to EAPD mode */
2202 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2203 { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
2204 { }
2205 }
2206 },
Takashi Iwai8812c4f2011-11-09 17:39:15 +01002207 [ALC883_FIXUP_ACER_EAPD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002208 .type = HDA_FIXUP_VERBS,
Takashi Iwai8812c4f2011-11-09 17:39:15 +01002209 .v.verbs = (const struct hda_verb[]) {
2210 /* eanable EAPD on Acer laptops */
2211 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2212 { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
2213 { }
2214 }
2215 },
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002216 [ALC882_FIXUP_GPIO1] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02002217 .type = HDA_FIXUP_FUNC,
2218 .v.func = alc_fixup_gpio1,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002219 },
2220 [ALC882_FIXUP_GPIO2] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02002221 .type = HDA_FIXUP_FUNC,
2222 .v.func = alc_fixup_gpio2,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002223 },
Takashi Iwaieb844d52011-11-09 18:03:07 +01002224 [ALC882_FIXUP_GPIO3] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02002225 .type = HDA_FIXUP_FUNC,
2226 .v.func = alc_fixup_gpio3,
Takashi Iwaieb844d52011-11-09 18:03:07 +01002227 },
Takashi Iwai68ef0562011-11-09 18:24:44 +01002228 [ALC882_FIXUP_ASUS_W2JC] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02002229 .type = HDA_FIXUP_FUNC,
2230 .v.func = alc_fixup_gpio1,
Takashi Iwai68ef0562011-11-09 18:24:44 +01002231 .chained = true,
2232 .chain_id = ALC882_FIXUP_EAPD,
2233 },
2234 [ALC889_FIXUP_COEF] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002235 .type = HDA_FIXUP_FUNC,
Takashi Iwai68ef0562011-11-09 18:24:44 +01002236 .v.func = alc889_fixup_coef,
2237 },
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002238 [ALC882_FIXUP_ACER_ASPIRE_4930G] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002239 .type = HDA_FIXUP_PINS,
2240 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002241 { 0x16, 0x99130111 }, /* CLFE speaker */
2242 { 0x17, 0x99130112 }, /* surround speaker */
2243 { }
Takashi Iwai038d4fe2012-04-11 17:18:12 +02002244 },
2245 .chained = true,
2246 .chain_id = ALC882_FIXUP_GPIO1,
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002247 },
2248 [ALC882_FIXUP_ACER_ASPIRE_8930G] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002249 .type = HDA_FIXUP_PINS,
2250 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002251 { 0x16, 0x99130111 }, /* CLFE speaker */
2252 { 0x1b, 0x99130112 }, /* surround speaker */
2253 { }
2254 },
2255 .chained = true,
2256 .chain_id = ALC882_FIXUP_ASPIRE_8930G_VERBS,
2257 },
2258 [ALC882_FIXUP_ASPIRE_8930G_VERBS] = {
2259 /* additional init verbs for Acer Aspire 8930G */
Takashi Iwai1727a772013-01-10 09:52:52 +01002260 .type = HDA_FIXUP_VERBS,
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002261 .v.verbs = (const struct hda_verb[]) {
2262 /* Enable all DACs */
2263 /* DAC DISABLE/MUTE 1? */
2264 /* setting bits 1-5 disables DAC nids 0x02-0x06
2265 * apparently. Init=0x38 */
2266 { 0x20, AC_VERB_SET_COEF_INDEX, 0x03 },
2267 { 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
2268 /* DAC DISABLE/MUTE 2? */
2269 /* some bit here disables the other DACs.
2270 * Init=0x4900 */
2271 { 0x20, AC_VERB_SET_COEF_INDEX, 0x08 },
2272 { 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
2273 /* DMIC fix
2274 * This laptop has a stereo digital microphone.
2275 * The mics are only 1cm apart which makes the stereo
2276 * useless. However, either the mic or the ALC889
2277 * makes the signal become a difference/sum signal
2278 * instead of standard stereo, which is annoying.
2279 * So instead we flip this bit which makes the
2280 * codec replicate the sum signal to both channels,
2281 * turning it into a normal mono mic.
2282 */
2283 /* DMIC_CONTROL? Init value = 0x0001 */
2284 { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b },
2285 { 0x20, AC_VERB_SET_PROC_COEF, 0x0003 },
2286 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2287 { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
2288 { }
Takashi Iwai038d4fe2012-04-11 17:18:12 +02002289 },
2290 .chained = true,
2291 .chain_id = ALC882_FIXUP_GPIO1,
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002292 },
Takashi Iwai56710872011-11-14 17:42:11 +01002293 [ALC885_FIXUP_MACPRO_GPIO] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002294 .type = HDA_FIXUP_FUNC,
Takashi Iwai56710872011-11-14 17:42:11 +01002295 .v.func = alc885_fixup_macpro_gpio,
2296 },
Takashi Iwai02a237b2012-02-13 15:25:07 +01002297 [ALC889_FIXUP_DAC_ROUTE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002298 .type = HDA_FIXUP_FUNC,
Takashi Iwai02a237b2012-02-13 15:25:07 +01002299 .v.func = alc889_fixup_dac_route,
2300 },
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002301 [ALC889_FIXUP_MBP_VREF] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002302 .type = HDA_FIXUP_FUNC,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002303 .v.func = alc889_fixup_mbp_vref,
2304 .chained = true,
2305 .chain_id = ALC882_FIXUP_GPIO1,
2306 },
2307 [ALC889_FIXUP_IMAC91_VREF] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002308 .type = HDA_FIXUP_FUNC,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002309 .v.func = alc889_fixup_imac91_vref,
2310 .chained = true,
2311 .chain_id = ALC882_FIXUP_GPIO1,
2312 },
Adrien Vergée7729a42014-01-24 14:56:14 -05002313 [ALC889_FIXUP_MBA11_VREF] = {
2314 .type = HDA_FIXUP_FUNC,
2315 .v.func = alc889_fixup_mba11_vref,
2316 .chained = true,
2317 .chain_id = ALC889_FIXUP_MBP_VREF,
2318 },
Takashi Iwai0756f092013-12-04 13:59:45 +01002319 [ALC889_FIXUP_MBA21_VREF] = {
2320 .type = HDA_FIXUP_FUNC,
2321 .v.func = alc889_fixup_mba21_vref,
2322 .chained = true,
2323 .chain_id = ALC889_FIXUP_MBP_VREF,
2324 },
Takashi Iwaic20f31e2014-02-03 11:02:10 +01002325 [ALC889_FIXUP_MP11_VREF] = {
2326 .type = HDA_FIXUP_FUNC,
2327 .v.func = alc889_fixup_mba11_vref,
2328 .chained = true,
2329 .chain_id = ALC885_FIXUP_MACPRO_GPIO,
2330 },
Mario Kleiner9f660a12015-12-22 00:45:43 +01002331 [ALC889_FIXUP_MP41_VREF] = {
2332 .type = HDA_FIXUP_FUNC,
2333 .v.func = alc889_fixup_mbp_vref,
2334 .chained = true,
2335 .chain_id = ALC885_FIXUP_MACPRO_GPIO,
2336 },
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002337 [ALC882_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002338 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02002339 .v.func = alc_fixup_inv_dmic,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002340 },
Takashi Iwaie427c232012-07-29 10:04:08 +02002341 [ALC882_FIXUP_NO_PRIMARY_HP] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002342 .type = HDA_FIXUP_FUNC,
Takashi Iwaie427c232012-07-29 10:04:08 +02002343 .v.func = alc882_fixup_no_primary_hp,
2344 },
Takashi Iwai1f0bbf02013-11-28 15:21:21 +01002345 [ALC887_FIXUP_ASUS_BASS] = {
2346 .type = HDA_FIXUP_PINS,
2347 .v.pins = (const struct hda_pintbl[]) {
2348 {0x16, 0x99130130}, /* bass speaker */
2349 {}
2350 },
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01002351 .chained = true,
2352 .chain_id = ALC887_FIXUP_BASS_CHMAP,
2353 },
2354 [ALC887_FIXUP_BASS_CHMAP] = {
2355 .type = HDA_FIXUP_FUNC,
2356 .v.func = alc_fixup_bass_chmap,
Takashi Iwai1f0bbf02013-11-28 15:21:21 +01002357 },
Takashi Iwai7beb3a62017-04-10 18:05:52 +02002358 [ALC1220_FIXUP_GB_DUAL_CODECS] = {
2359 .type = HDA_FIXUP_FUNC,
2360 .v.func = alc1220_fixup_gb_dual_codecs,
2361 },
Peisen0202f5c2017-10-26 10:35:36 +08002362 [ALC1220_FIXUP_CLEVO_P950] = {
2363 .type = HDA_FIXUP_FUNC,
2364 .v.func = alc1220_fixup_clevo_p950,
2365 },
Richard Sailer80690a22019-04-02 15:52:04 +02002366 [ALC1220_FIXUP_CLEVO_PB51ED] = {
Jeremy Soller7f665b12019-02-13 10:56:19 -07002367 .type = HDA_FIXUP_FUNC,
Richard Sailer80690a22019-04-02 15:52:04 +02002368 .v.func = alc1220_fixup_clevo_pb51ed,
Jeremy Soller7f665b12019-02-13 10:56:19 -07002369 },
Richard Sailer80690a22019-04-02 15:52:04 +02002370 [ALC1220_FIXUP_CLEVO_PB51ED_PINS] = {
Jeremy Soller7f665b12019-02-13 10:56:19 -07002371 .type = HDA_FIXUP_PINS,
2372 .v.pins = (const struct hda_pintbl[]) {
2373 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
2374 {}
2375 },
2376 .chained = true,
Richard Sailer80690a22019-04-02 15:52:04 +02002377 .chain_id = ALC1220_FIXUP_CLEVO_PB51ED,
Jeremy Soller7f665b12019-02-13 10:56:19 -07002378 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02002379};
2380
2381static const struct snd_pci_quirk alc882_fixup_tbl[] = {
Takashi Iwai8812c4f2011-11-09 17:39:15 +01002382 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_FIXUP_ACER_EAPD),
2383 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
Takashi Iwaib5d724b2015-06-02 19:57:08 +02002384 SND_PCI_QUIRK(0x1025, 0x0107, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
Takashi Iwai8812c4f2011-11-09 17:39:15 +01002385 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_FIXUP_ACER_EAPD),
2386 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
2387 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_FIXUP_ACER_EAPD),
2388 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_FIXUP_ACER_EAPD),
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002389 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
2390 ALC882_FIXUP_ACER_ASPIRE_4930G),
2391 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
2392 ALC882_FIXUP_ACER_ASPIRE_4930G),
2393 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
2394 ALC882_FIXUP_ACER_ASPIRE_8930G),
2395 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
2396 ALC882_FIXUP_ACER_ASPIRE_8930G),
2397 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
2398 ALC882_FIXUP_ACER_ASPIRE_4930G),
2399 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
2400 ALC882_FIXUP_ACER_ASPIRE_4930G),
2401 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
2402 ALC882_FIXUP_ACER_ASPIRE_4930G),
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002403 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", ALC882_FIXUP_PB_M5210),
Takashi Iwaif5c53d82012-05-07 10:07:33 +02002404 SND_PCI_QUIRK(0x1025, 0x021e, "Acer Aspire 5739G",
2405 ALC882_FIXUP_ACER_ASPIRE_4930G),
Takashi Iwai02a237b2012-02-13 15:25:07 +01002406 SND_PCI_QUIRK(0x1025, 0x0259, "Acer Aspire 5935", ALC889_FIXUP_DAC_ROUTE),
Takashi Iwaife97da12012-04-12 08:00:19 +02002407 SND_PCI_QUIRK(0x1025, 0x026b, "Acer Aspire 8940G", ALC882_FIXUP_ACER_ASPIRE_8930G),
Takashi Iwaiac9b1cd2011-11-09 17:45:55 +01002408 SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", ALC882_FIXUP_ACER_ASPIRE_7736),
Takashi Iwai177943a32011-11-09 12:55:18 +01002409 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_FIXUP_EAPD),
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002410 SND_PCI_QUIRK(0x1043, 0x1873, "ASUS W90V", ALC882_FIXUP_ASUS_W90V),
Takashi Iwai68ef0562011-11-09 18:24:44 +01002411 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_FIXUP_ASUS_W2JC),
Takashi Iwai0e7cc2e2011-11-09 12:42:48 +01002412 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_FIXUP_EEE1601),
Takashi Iwai1f0bbf02013-11-28 15:21:21 +01002413 SND_PCI_QUIRK(0x1043, 0x84bc, "ASUS ET2700", ALC887_FIXUP_ASUS_BASS),
Takashi Iwai85bcf962016-12-06 16:20:36 +01002414 SND_PCI_QUIRK(0x1043, 0x8691, "ASUS ROG Ranger VIII", ALC882_FIXUP_GPIO3),
Takashi Iwaiac9b1cd2011-11-09 17:45:55 +01002415 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT),
Takashi Iwaie427c232012-07-29 10:04:08 +02002416 SND_PCI_QUIRK(0x104d, 0x905a, "Sony Vaio Z", ALC882_FIXUP_NO_PRIMARY_HP),
Sergei A. Trusov3f3c3712017-08-02 20:23:48 +10002417 SND_PCI_QUIRK(0x104d, 0x9060, "Sony Vaio VPCL14M1R", ALC882_FIXUP_NO_PRIMARY_HP),
Fernando Luis Vázquez Cao12e31a72013-02-12 16:47:44 +09002418 SND_PCI_QUIRK(0x104d, 0x9043, "Sony Vaio VGC-LN51JGB", ALC882_FIXUP_NO_PRIMARY_HP),
Takashi Iwaic44d9b12016-02-07 09:38:26 +01002419 SND_PCI_QUIRK(0x104d, 0x9044, "Sony VAIO AiO", ALC882_FIXUP_NO_PRIMARY_HP),
Takashi Iwai56710872011-11-14 17:42:11 +01002420
2421 /* All Apple entries are in codec SSIDs */
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002422 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC889_FIXUP_MBP_VREF),
2423 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC889_FIXUP_MBP_VREF),
2424 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF),
Takashi Iwaic20f31e2014-02-03 11:02:10 +01002425 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC889_FIXUP_MP11_VREF),
Takashi Iwai56710872011-11-14 17:42:11 +01002426 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_FIXUP_MACPRO_GPIO),
2427 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_FIXUP_MACPRO_GPIO),
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002428 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC889_FIXUP_MBP_VREF),
2429 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889_FIXUP_MBP_VREF),
Takashi Iwai56710872011-11-14 17:42:11 +01002430 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_FIXUP_EAPD),
Adrien Vergée7729a42014-01-24 14:56:14 -05002431 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC889_FIXUP_MBA11_VREF),
Takashi Iwai0756f092013-12-04 13:59:45 +01002432 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC889_FIXUP_MBA21_VREF),
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002433 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889_FIXUP_MBP_VREF),
2434 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF),
Takashi Iwai56710872011-11-14 17:42:11 +01002435 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_FIXUP_MACPRO_GPIO),
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002436 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC889_FIXUP_IMAC91_VREF),
2437 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC889_FIXUP_IMAC91_VREF),
2438 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC889_FIXUP_IMAC91_VREF),
Mario Kleiner9f660a12015-12-22 00:45:43 +01002439 SND_PCI_QUIRK(0x106b, 0x4200, "Mac Pro 4,1/5,1", ALC889_FIXUP_MP41_VREF),
Takashi Iwai05193632012-11-12 10:07:36 +01002440 SND_PCI_QUIRK(0x106b, 0x4300, "iMac 9,1", ALC889_FIXUP_IMAC91_VREF),
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002441 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC889_FIXUP_IMAC91_VREF),
2442 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC889_FIXUP_IMAC91_VREF),
Takashi Iwai649ccd02015-07-30 22:30:29 +02002443 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC889_FIXUP_MBA11_VREF),
Takashi Iwai56710872011-11-14 17:42:11 +01002444
Takashi Iwai7a6069b2011-11-09 15:22:01 +01002445 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC882_FIXUP_EAPD),
David Henningssonb2c53e22014-01-01 14:01:34 +01002446 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3/Z87X-UD3H", ALC889_FIXUP_FRONT_HP_NO_PRESENCE),
Takashi Iwai7beb3a62017-04-10 18:05:52 +02002447 SND_PCI_QUIRK(0x1458, 0xa0b8, "Gigabyte AZ370-Gaming", ALC1220_FIXUP_GB_DUAL_CODECS),
Takashi Iwaid2c3b142017-06-01 09:35:30 +02002448 SND_PCI_QUIRK(0x1462, 0x7350, "MSI-7350", ALC889_FIXUP_CD),
Takashi Iwai63691582017-05-22 16:32:46 +02002449 SND_PCI_QUIRK(0x1462, 0xda57, "MSI Z270-Gaming", ALC1220_FIXUP_GB_DUAL_CODECS),
Takashi Iwaid2c3b142017-06-01 09:35:30 +02002450 SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3),
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002451 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX),
Peisen0202f5c2017-10-26 10:35:36 +08002452 SND_PCI_QUIRK(0x1558, 0x9501, "Clevo P950HR", ALC1220_FIXUP_CLEVO_P950),
Takashi Iwaif3d737b2018-07-17 17:08:32 +02002453 SND_PCI_QUIRK(0x1558, 0x95e1, "Clevo P95xER", ALC1220_FIXUP_CLEVO_P950),
Jeremy Soller2f0d5202018-05-07 09:28:45 -06002454 SND_PCI_QUIRK(0x1558, 0x95e2, "Clevo P950ER", ALC1220_FIXUP_CLEVO_P950),
Richard Sailer503d90b2019-06-19 13:33:11 +02002455 SND_PCI_QUIRK(0x1558, 0x96e1, "Clevo P960[ER][CDFN]-K", ALC1220_FIXUP_CLEVO_P950),
2456 SND_PCI_QUIRK(0x1558, 0x97e1, "Clevo P970[ER][CDFN]", ALC1220_FIXUP_CLEVO_P950),
2457 SND_PCI_QUIRK(0x1558, 0x65d1, "Clevo PB51[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
2458 SND_PCI_QUIRK(0x1558, 0x67d1, "Clevo PB71[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
Takashi Iwai7a6069b2011-11-09 15:22:01 +01002459 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD),
2460 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD),
Takashi Iwaiac9b1cd2011-11-09 17:45:55 +01002461 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", ALC882_FIXUP_LENOVO_Y530),
Takashi Iwai68ef0562011-11-09 18:24:44 +01002462 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_FIXUP_COEF),
Takashi Iwai1d045db2011-07-07 18:23:21 +02002463 {}
2464};
2465
Takashi Iwai1727a772013-01-10 09:52:52 +01002466static const struct hda_model_fixup alc882_fixup_models[] = {
Takashi Iwai772c2912018-06-26 17:17:53 +02002467 {.id = ALC882_FIXUP_ABIT_AW9D_MAX, .name = "abit-aw9d"},
2468 {.id = ALC882_FIXUP_LENOVO_Y530, .name = "lenovo-y530"},
2469 {.id = ALC882_FIXUP_ACER_ASPIRE_7736, .name = "acer-aspire-7736"},
2470 {.id = ALC882_FIXUP_ASUS_W90V, .name = "asus-w90v"},
2471 {.id = ALC889_FIXUP_CD, .name = "cd"},
2472 {.id = ALC889_FIXUP_FRONT_HP_NO_PRESENCE, .name = "no-front-hp"},
2473 {.id = ALC889_FIXUP_VAIO_TT, .name = "vaio-tt"},
2474 {.id = ALC888_FIXUP_EEE1601, .name = "eee1601"},
2475 {.id = ALC882_FIXUP_EAPD, .name = "alc882-eapd"},
2476 {.id = ALC883_FIXUP_EAPD, .name = "alc883-eapd"},
2477 {.id = ALC882_FIXUP_GPIO1, .name = "gpio1"},
2478 {.id = ALC882_FIXUP_GPIO2, .name = "gpio2"},
2479 {.id = ALC882_FIXUP_GPIO3, .name = "gpio3"},
2480 {.id = ALC889_FIXUP_COEF, .name = "alc889-coef"},
2481 {.id = ALC882_FIXUP_ASUS_W2JC, .name = "asus-w2jc"},
Takashi Iwai912093b2012-04-11 14:03:41 +02002482 {.id = ALC882_FIXUP_ACER_ASPIRE_4930G, .name = "acer-aspire-4930g"},
2483 {.id = ALC882_FIXUP_ACER_ASPIRE_8930G, .name = "acer-aspire-8930g"},
2484 {.id = ALC883_FIXUP_ACER_EAPD, .name = "acer-aspire"},
Takashi Iwai772c2912018-06-26 17:17:53 +02002485 {.id = ALC885_FIXUP_MACPRO_GPIO, .name = "macpro-gpio"},
2486 {.id = ALC889_FIXUP_DAC_ROUTE, .name = "dac-route"},
2487 {.id = ALC889_FIXUP_MBP_VREF, .name = "mbp-vref"},
2488 {.id = ALC889_FIXUP_IMAC91_VREF, .name = "imac91-vref"},
2489 {.id = ALC889_FIXUP_MBA11_VREF, .name = "mba11-vref"},
2490 {.id = ALC889_FIXUP_MBA21_VREF, .name = "mba21-vref"},
2491 {.id = ALC889_FIXUP_MP11_VREF, .name = "mp11-vref"},
2492 {.id = ALC889_FIXUP_MP41_VREF, .name = "mp41-vref"},
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002493 {.id = ALC882_FIXUP_INV_DMIC, .name = "inv-dmic"},
Takashi Iwaie427c232012-07-29 10:04:08 +02002494 {.id = ALC882_FIXUP_NO_PRIMARY_HP, .name = "no-primary-hp"},
Takashi Iwai772c2912018-06-26 17:17:53 +02002495 {.id = ALC887_FIXUP_ASUS_BASS, .name = "asus-bass"},
Takashi Iwaiba90d6a2017-05-22 16:38:47 +02002496 {.id = ALC1220_FIXUP_GB_DUAL_CODECS, .name = "dual-codecs"},
Takashi Iwai772c2912018-06-26 17:17:53 +02002497 {.id = ALC1220_FIXUP_CLEVO_P950, .name = "clevo-p950"},
Takashi Iwai912093b2012-04-11 14:03:41 +02002498 {}
2499};
2500
Takashi Iwai1d045db2011-07-07 18:23:21 +02002501/*
2502 * BIOS auto configuration
2503 */
2504/* almost identical with ALC880 parser... */
2505static int alc882_parse_auto_config(struct hda_codec *codec)
2506{
Takashi Iwai1d045db2011-07-07 18:23:21 +02002507 static const hda_nid_t alc882_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002508 static const hda_nid_t alc882_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2509 return alc_parse_auto_config(codec, alc882_ignore, alc882_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002510}
2511
Takashi Iwai1d045db2011-07-07 18:23:21 +02002512/*
2513 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002514static int patch_alc882(struct hda_codec *codec)
2515{
2516 struct alc_spec *spec;
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002517 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002518
Takashi Iwai3de95172012-05-07 18:03:15 +02002519 err = alc_alloc_spec(codec, 0x0b);
2520 if (err < 0)
2521 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002522
Takashi Iwai3de95172012-05-07 18:03:15 +02002523 spec = codec->spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002524
Takashi Iwai7639a062015-03-03 10:07:24 +01002525 switch (codec->core.vendor_id) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002526 case 0x10ec0882:
2527 case 0x10ec0885:
Takashi Iwaiacf08082014-09-02 07:21:56 +02002528 case 0x10ec0900:
Kailang Yanga535ad52017-01-16 16:59:26 +08002529 case 0x10ec1220:
Takashi Iwai1d045db2011-07-07 18:23:21 +02002530 break;
2531 default:
2532 /* ALC883 and variants */
2533 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
2534 break;
2535 }
2536
Takashi Iwaic9af7532019-05-10 11:01:43 +02002537 alc_pre_init(codec);
2538
Takashi Iwai1727a772013-01-10 09:52:52 +01002539 snd_hda_pick_fixup(codec, alc882_fixup_models, alc882_fixup_tbl,
Takashi Iwai912093b2012-04-11 14:03:41 +02002540 alc882_fixups);
Takashi Iwai1727a772013-01-10 09:52:52 +01002541 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002542
2543 alc_auto_parse_customize_define(codec);
2544
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002545 if (has_cdefine_beep(codec))
2546 spec->gen.beep_nid = 0x01;
2547
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002548 /* automatic parse from the BIOS config */
2549 err = alc882_parse_auto_config(codec);
2550 if (err < 0)
2551 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002552
Takashi Iwaifea80fa2018-06-20 12:52:46 +02002553 if (!spec->gen.no_analog && spec->gen.beep_nid) {
2554 err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
2555 if (err < 0)
2556 goto error;
2557 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02002558
Takashi Iwai1727a772013-01-10 09:52:52 +01002559 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01002560
Takashi Iwai1d045db2011-07-07 18:23:21 +02002561 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02002562
2563 error:
2564 alc_free(codec);
2565 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002566}
2567
2568
2569/*
2570 * ALC262 support
2571 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002572static int alc262_parse_auto_config(struct hda_codec *codec)
2573{
Takashi Iwai1d045db2011-07-07 18:23:21 +02002574 static const hda_nid_t alc262_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002575 static const hda_nid_t alc262_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2576 return alc_parse_auto_config(codec, alc262_ignore, alc262_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002577}
2578
2579/*
2580 * Pin config fixes
2581 */
2582enum {
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002583 ALC262_FIXUP_FSC_H270,
Takashi Iwai7513e6d2013-01-18 15:41:34 +01002584 ALC262_FIXUP_FSC_S7110,
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002585 ALC262_FIXUP_HP_Z200,
2586 ALC262_FIXUP_TYAN,
Takashi Iwaic4701502011-11-07 14:20:07 +01002587 ALC262_FIXUP_LENOVO_3000,
Takashi Iwaib42590b2011-11-07 14:41:01 +01002588 ALC262_FIXUP_BENQ,
2589 ALC262_FIXUP_BENQ_T31,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002590 ALC262_FIXUP_INV_DMIC,
Mengdong Linb5c66112013-11-29 00:35:35 -05002591 ALC262_FIXUP_INTEL_BAYLEYBAY,
Takashi Iwai1d045db2011-07-07 18:23:21 +02002592};
2593
Takashi Iwai1727a772013-01-10 09:52:52 +01002594static const struct hda_fixup alc262_fixups[] = {
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002595 [ALC262_FIXUP_FSC_H270] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002596 .type = HDA_FIXUP_PINS,
2597 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002598 { 0x14, 0x99130110 }, /* speaker */
2599 { 0x15, 0x0221142f }, /* front HP */
2600 { 0x1b, 0x0121141f }, /* rear HP */
2601 { }
2602 }
2603 },
Takashi Iwai7513e6d2013-01-18 15:41:34 +01002604 [ALC262_FIXUP_FSC_S7110] = {
2605 .type = HDA_FIXUP_PINS,
2606 .v.pins = (const struct hda_pintbl[]) {
2607 { 0x15, 0x90170110 }, /* speaker */
2608 { }
2609 },
2610 .chained = true,
2611 .chain_id = ALC262_FIXUP_BENQ,
2612 },
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002613 [ALC262_FIXUP_HP_Z200] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002614 .type = HDA_FIXUP_PINS,
2615 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002616 { 0x16, 0x99130120 }, /* internal speaker */
2617 { }
2618 }
2619 },
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002620 [ALC262_FIXUP_TYAN] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002621 .type = HDA_FIXUP_PINS,
2622 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002623 { 0x14, 0x1993e1f0 }, /* int AUX */
2624 { }
2625 }
2626 },
Takashi Iwaic4701502011-11-07 14:20:07 +01002627 [ALC262_FIXUP_LENOVO_3000] = {
Takashi Iwaifd108212013-01-10 10:18:14 +01002628 .type = HDA_FIXUP_PINCTLS,
2629 .v.pins = (const struct hda_pintbl[]) {
2630 { 0x19, PIN_VREF50 },
Takashi Iwaib42590b2011-11-07 14:41:01 +01002631 {}
2632 },
2633 .chained = true,
2634 .chain_id = ALC262_FIXUP_BENQ,
2635 },
2636 [ALC262_FIXUP_BENQ] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002637 .type = HDA_FIXUP_VERBS,
Takashi Iwaib42590b2011-11-07 14:41:01 +01002638 .v.verbs = (const struct hda_verb[]) {
Takashi Iwaic4701502011-11-07 14:20:07 +01002639 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2640 { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
2641 {}
2642 }
2643 },
Takashi Iwaib42590b2011-11-07 14:41:01 +01002644 [ALC262_FIXUP_BENQ_T31] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002645 .type = HDA_FIXUP_VERBS,
Takashi Iwaib42590b2011-11-07 14:41:01 +01002646 .v.verbs = (const struct hda_verb[]) {
2647 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2648 { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
2649 {}
2650 }
2651 },
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002652 [ALC262_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002653 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02002654 .v.func = alc_fixup_inv_dmic,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002655 },
Mengdong Linb5c66112013-11-29 00:35:35 -05002656 [ALC262_FIXUP_INTEL_BAYLEYBAY] = {
2657 .type = HDA_FIXUP_FUNC,
2658 .v.func = alc_fixup_no_depop_delay,
2659 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02002660};
2661
2662static const struct snd_pci_quirk alc262_fixup_tbl[] = {
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002663 SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", ALC262_FIXUP_HP_Z200),
Takashi Iwai7513e6d2013-01-18 15:41:34 +01002664 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu Lifebook S7110", ALC262_FIXUP_FSC_S7110),
Takashi Iwai3dcd3be2011-11-07 14:59:40 +01002665 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FIXUP_BENQ),
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002666 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_FIXUP_TYAN),
Takashi Iwai275ec0c2018-06-22 12:17:45 +02002667 SND_PCI_QUIRK(0x1734, 0x1141, "FSC ESPRIMO U9210", ALC262_FIXUP_FSC_H270),
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002668 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", ALC262_FIXUP_FSC_H270),
Takashi Iwaic4701502011-11-07 14:20:07 +01002669 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000", ALC262_FIXUP_LENOVO_3000),
Takashi Iwaib42590b2011-11-07 14:41:01 +01002670 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_FIXUP_BENQ),
2671 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_FIXUP_BENQ_T31),
Mengdong Linb5c66112013-11-29 00:35:35 -05002672 SND_PCI_QUIRK(0x8086, 0x7270, "BayleyBay", ALC262_FIXUP_INTEL_BAYLEYBAY),
Takashi Iwai1d045db2011-07-07 18:23:21 +02002673 {}
2674};
2675
Takashi Iwai1727a772013-01-10 09:52:52 +01002676static const struct hda_model_fixup alc262_fixup_models[] = {
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002677 {.id = ALC262_FIXUP_INV_DMIC, .name = "inv-dmic"},
Takashi Iwaie43c44d2018-06-26 17:02:08 +02002678 {.id = ALC262_FIXUP_FSC_H270, .name = "fsc-h270"},
2679 {.id = ALC262_FIXUP_FSC_S7110, .name = "fsc-s7110"},
2680 {.id = ALC262_FIXUP_HP_Z200, .name = "hp-z200"},
2681 {.id = ALC262_FIXUP_TYAN, .name = "tyan"},
2682 {.id = ALC262_FIXUP_LENOVO_3000, .name = "lenovo-3000"},
2683 {.id = ALC262_FIXUP_BENQ, .name = "benq"},
2684 {.id = ALC262_FIXUP_BENQ_T31, .name = "benq-t31"},
2685 {.id = ALC262_FIXUP_INTEL_BAYLEYBAY, .name = "bayleybay"},
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002686 {}
2687};
Takashi Iwai1d045db2011-07-07 18:23:21 +02002688
Takashi Iwai1d045db2011-07-07 18:23:21 +02002689/*
2690 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002691static int patch_alc262(struct hda_codec *codec)
2692{
2693 struct alc_spec *spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002694 int err;
2695
Takashi Iwai3de95172012-05-07 18:03:15 +02002696 err = alc_alloc_spec(codec, 0x0b);
2697 if (err < 0)
2698 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002699
Takashi Iwai3de95172012-05-07 18:03:15 +02002700 spec = codec->spec;
Takashi Iwai08c189f2012-12-19 15:22:24 +01002701 spec->gen.shared_mic_vref_pin = 0x18;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002702
Takashi Iwai225068a2015-05-29 10:42:14 +02002703 spec->shutup = alc_eapd_shutup;
2704
Takashi Iwai1d045db2011-07-07 18:23:21 +02002705#if 0
2706 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
2707 * under-run
2708 */
Takashi Iwai98b24882014-08-18 13:47:50 +02002709 alc_update_coefex_idx(codec, 0x1a, 7, 0, 0x80);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002710#endif
Takashi Iwai1d045db2011-07-07 18:23:21 +02002711 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
2712
Takashi Iwaic9af7532019-05-10 11:01:43 +02002713 alc_pre_init(codec);
2714
Takashi Iwai1727a772013-01-10 09:52:52 +01002715 snd_hda_pick_fixup(codec, alc262_fixup_models, alc262_fixup_tbl,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002716 alc262_fixups);
Takashi Iwai1727a772013-01-10 09:52:52 +01002717 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002718
Takashi Iwaiaf741c12012-05-07 18:09:48 +02002719 alc_auto_parse_customize_define(codec);
2720
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002721 if (has_cdefine_beep(codec))
2722 spec->gen.beep_nid = 0x01;
2723
Takashi Iwai42399f72011-11-07 17:18:44 +01002724 /* automatic parse from the BIOS config */
2725 err = alc262_parse_auto_config(codec);
2726 if (err < 0)
2727 goto error;
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002728
Takashi Iwaifea80fa2018-06-20 12:52:46 +02002729 if (!spec->gen.no_analog && spec->gen.beep_nid) {
2730 err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
2731 if (err < 0)
2732 goto error;
2733 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02002734
Takashi Iwai1727a772013-01-10 09:52:52 +01002735 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01002736
Takashi Iwai1d045db2011-07-07 18:23:21 +02002737 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02002738
2739 error:
2740 alc_free(codec);
2741 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002742}
2743
2744/*
2745 * ALC268
2746 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002747/* bind Beep switches of both NID 0x0f and 0x10 */
Takashi Iwaia7177772017-05-10 12:04:08 +02002748static int alc268_beep_switch_put(struct snd_kcontrol *kcontrol,
2749 struct snd_ctl_elem_value *ucontrol)
2750{
2751 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2752 unsigned long pval;
2753 int err;
2754
2755 mutex_lock(&codec->control_mutex);
2756 pval = kcontrol->private_value;
2757 kcontrol->private_value = (pval & ~0xff) | 0x0f;
2758 err = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
2759 if (err >= 0) {
2760 kcontrol->private_value = (pval & ~0xff) | 0x10;
2761 err = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
2762 }
2763 kcontrol->private_value = pval;
2764 mutex_unlock(&codec->control_mutex);
2765 return err;
2766}
Takashi Iwai1d045db2011-07-07 18:23:21 +02002767
2768static const struct snd_kcontrol_new alc268_beep_mixer[] = {
2769 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
Takashi Iwaia7177772017-05-10 12:04:08 +02002770 {
2771 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2772 .name = "Beep Playback Switch",
2773 .subdevice = HDA_SUBDEV_AMP_FLAG,
2774 .info = snd_hda_mixer_amp_switch_info,
2775 .get = snd_hda_mixer_amp_switch_get,
2776 .put = alc268_beep_switch_put,
2777 .private_value = HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT)
2778 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02002779};
2780
2781/* set PCBEEP vol = 0, mute connections */
2782static const struct hda_verb alc268_beep_init_verbs[] = {
2783 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2784 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2785 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2786 { }
2787};
2788
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002789enum {
2790 ALC268_FIXUP_INV_DMIC,
Takashi Iwaicb766402012-10-20 10:55:21 +02002791 ALC268_FIXUP_HP_EAPD,
Takashi Iwai24eff322013-11-04 18:21:08 +01002792 ALC268_FIXUP_SPDIF,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002793};
2794
Takashi Iwai1727a772013-01-10 09:52:52 +01002795static const struct hda_fixup alc268_fixups[] = {
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002796 [ALC268_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002797 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02002798 .v.func = alc_fixup_inv_dmic,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002799 },
Takashi Iwaicb766402012-10-20 10:55:21 +02002800 [ALC268_FIXUP_HP_EAPD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002801 .type = HDA_FIXUP_VERBS,
Takashi Iwaicb766402012-10-20 10:55:21 +02002802 .v.verbs = (const struct hda_verb[]) {
2803 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 0},
2804 {}
2805 }
2806 },
Takashi Iwai24eff322013-11-04 18:21:08 +01002807 [ALC268_FIXUP_SPDIF] = {
2808 .type = HDA_FIXUP_PINS,
2809 .v.pins = (const struct hda_pintbl[]) {
2810 { 0x1e, 0x014b1180 }, /* enable SPDIF out */
2811 {}
2812 }
2813 },
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002814};
2815
Takashi Iwai1727a772013-01-10 09:52:52 +01002816static const struct hda_model_fixup alc268_fixup_models[] = {
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002817 {.id = ALC268_FIXUP_INV_DMIC, .name = "inv-dmic"},
Takashi Iwaicb766402012-10-20 10:55:21 +02002818 {.id = ALC268_FIXUP_HP_EAPD, .name = "hp-eapd"},
Takashi Iwai03bf11c2018-06-26 16:56:41 +02002819 {.id = ALC268_FIXUP_SPDIF, .name = "spdif"},
Takashi Iwaicb766402012-10-20 10:55:21 +02002820 {}
2821};
2822
2823static const struct snd_pci_quirk alc268_fixup_tbl[] = {
Takashi Iwai24eff322013-11-04 18:21:08 +01002824 SND_PCI_QUIRK(0x1025, 0x0139, "Acer TravelMate 6293", ALC268_FIXUP_SPDIF),
David Henningssonfcd8f3b2013-01-28 05:45:47 +01002825 SND_PCI_QUIRK(0x1025, 0x015b, "Acer AOA 150 (ZG5)", ALC268_FIXUP_INV_DMIC),
Takashi Iwaicb766402012-10-20 10:55:21 +02002826 /* below is codec SSID since multiple Toshiba laptops have the
2827 * same PCI SSID 1179:ff00
2828 */
2829 SND_PCI_QUIRK(0x1179, 0xff06, "Toshiba P200", ALC268_FIXUP_HP_EAPD),
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002830 {}
2831};
2832
Takashi Iwai1d045db2011-07-07 18:23:21 +02002833/*
2834 * BIOS auto configuration
2835 */
2836static int alc268_parse_auto_config(struct hda_codec *codec)
2837{
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002838 static const hda_nid_t alc268_ssids[] = { 0x15, 0x1b, 0x14, 0 };
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002839 return alc_parse_auto_config(codec, NULL, alc268_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002840}
2841
Takashi Iwai1d045db2011-07-07 18:23:21 +02002842/*
2843 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002844static int patch_alc268(struct hda_codec *codec)
2845{
2846 struct alc_spec *spec;
Takashi Iwaia5cb4632018-06-20 12:50:11 +02002847 int i, err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002848
Takashi Iwai1d045db2011-07-07 18:23:21 +02002849 /* ALC268 has no aa-loopback mixer */
Takashi Iwai3de95172012-05-07 18:03:15 +02002850 err = alc_alloc_spec(codec, 0);
2851 if (err < 0)
2852 return err;
2853
2854 spec = codec->spec;
Takashi Iwai2722b532019-08-22 09:55:37 +02002855 if (has_cdefine_beep(codec))
2856 spec->gen.beep_nid = 0x01;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002857
Takashi Iwai225068a2015-05-29 10:42:14 +02002858 spec->shutup = alc_eapd_shutup;
2859
Takashi Iwaic9af7532019-05-10 11:01:43 +02002860 alc_pre_init(codec);
2861
Takashi Iwai1727a772013-01-10 09:52:52 +01002862 snd_hda_pick_fixup(codec, alc268_fixup_models, alc268_fixup_tbl, alc268_fixups);
2863 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002864
Takashi Iwai6ebb8052011-08-16 15:15:40 +02002865 /* automatic parse from the BIOS config */
2866 err = alc268_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02002867 if (err < 0)
2868 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002869
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002870 if (err > 0 && !spec->gen.no_analog &&
2871 spec->gen.autocfg.speaker_pins[0] != 0x1d) {
Takashi Iwaia5cb4632018-06-20 12:50:11 +02002872 for (i = 0; i < ARRAY_SIZE(alc268_beep_mixer); i++) {
2873 if (!snd_hda_gen_add_kctl(&spec->gen, NULL,
2874 &alc268_beep_mixer[i])) {
2875 err = -ENOMEM;
2876 goto error;
2877 }
2878 }
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002879 snd_hda_add_verbs(codec, alc268_beep_init_verbs);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002880 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
2881 /* override the amp caps for beep generator */
2882 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
2883 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
2884 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
2885 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
2886 (0 << AC_AMPCAP_MUTE_SHIFT));
2887 }
2888
Takashi Iwai1727a772013-01-10 09:52:52 +01002889 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002890
Takashi Iwai1d045db2011-07-07 18:23:21 +02002891 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02002892
2893 error:
2894 alc_free(codec);
2895 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002896}
2897
2898/*
2899 * ALC269
2900 */
Takashi Iwai08c189f2012-12-19 15:22:24 +01002901
Takashi Iwai1d045db2011-07-07 18:23:21 +02002902static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002903 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002904};
2905
2906static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002907 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002908};
2909
Takashi Iwai1d045db2011-07-07 18:23:21 +02002910/* different alc269-variants */
2911enum {
2912 ALC269_TYPE_ALC269VA,
2913 ALC269_TYPE_ALC269VB,
2914 ALC269_TYPE_ALC269VC,
Kailang Yangadcc70b2012-05-25 08:08:38 +02002915 ALC269_TYPE_ALC269VD,
Kailang Yang065380f2013-01-10 10:25:48 +01002916 ALC269_TYPE_ALC280,
2917 ALC269_TYPE_ALC282,
Kailang Yang2af02be2013-08-22 10:03:50 +02002918 ALC269_TYPE_ALC283,
Kailang Yang065380f2013-01-10 10:25:48 +01002919 ALC269_TYPE_ALC284,
Kailang Yang4731d5d2017-06-30 15:22:57 +08002920 ALC269_TYPE_ALC293,
Kailang Yang7fc7d042013-04-25 11:04:43 +02002921 ALC269_TYPE_ALC286,
Kailang Yang506b62c2014-12-18 17:07:44 +08002922 ALC269_TYPE_ALC298,
Kailang Yang1d04c9d2013-10-24 11:35:18 +02002923 ALC269_TYPE_ALC255,
Kailang Yang4344aec2014-12-17 17:39:05 +08002924 ALC269_TYPE_ALC256,
Kailang Yangf429e7e2017-12-05 15:38:24 +08002925 ALC269_TYPE_ALC257,
Kailang Yang0a6f0602017-06-30 16:00:48 +08002926 ALC269_TYPE_ALC215,
Kailang Yang42314302016-02-03 15:03:50 +08002927 ALC269_TYPE_ALC225,
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08002928 ALC269_TYPE_ALC294,
Kailang Yang1078bef2018-11-08 16:36:15 +08002929 ALC269_TYPE_ALC300,
Kailang Yangf0778872019-10-24 15:13:32 +08002930 ALC269_TYPE_ALC623,
Kailang Yang6fbae352016-05-30 16:44:20 +08002931 ALC269_TYPE_ALC700,
Takashi Iwai1d045db2011-07-07 18:23:21 +02002932};
2933
2934/*
2935 * BIOS auto configuration
2936 */
2937static int alc269_parse_auto_config(struct hda_codec *codec)
2938{
Takashi Iwai1d045db2011-07-07 18:23:21 +02002939 static const hda_nid_t alc269_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002940 static const hda_nid_t alc269_ssids[] = { 0, 0x1b, 0x14, 0x21 };
2941 static const hda_nid_t alc269va_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2942 struct alc_spec *spec = codec->spec;
Kailang Yangadcc70b2012-05-25 08:08:38 +02002943 const hda_nid_t *ssids;
2944
2945 switch (spec->codec_variant) {
2946 case ALC269_TYPE_ALC269VA:
2947 case ALC269_TYPE_ALC269VC:
Kailang Yang065380f2013-01-10 10:25:48 +01002948 case ALC269_TYPE_ALC280:
2949 case ALC269_TYPE_ALC284:
Kailang Yang4731d5d2017-06-30 15:22:57 +08002950 case ALC269_TYPE_ALC293:
Kailang Yangadcc70b2012-05-25 08:08:38 +02002951 ssids = alc269va_ssids;
2952 break;
2953 case ALC269_TYPE_ALC269VB:
2954 case ALC269_TYPE_ALC269VD:
Kailang Yang065380f2013-01-10 10:25:48 +01002955 case ALC269_TYPE_ALC282:
Kailang Yang2af02be2013-08-22 10:03:50 +02002956 case ALC269_TYPE_ALC283:
Kailang Yang7fc7d042013-04-25 11:04:43 +02002957 case ALC269_TYPE_ALC286:
Kailang Yang506b62c2014-12-18 17:07:44 +08002958 case ALC269_TYPE_ALC298:
Kailang Yang1d04c9d2013-10-24 11:35:18 +02002959 case ALC269_TYPE_ALC255:
Kailang Yang4344aec2014-12-17 17:39:05 +08002960 case ALC269_TYPE_ALC256:
Kailang Yangf429e7e2017-12-05 15:38:24 +08002961 case ALC269_TYPE_ALC257:
Kailang Yang0a6f0602017-06-30 16:00:48 +08002962 case ALC269_TYPE_ALC215:
Kailang Yang42314302016-02-03 15:03:50 +08002963 case ALC269_TYPE_ALC225:
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08002964 case ALC269_TYPE_ALC294:
Kailang Yang1078bef2018-11-08 16:36:15 +08002965 case ALC269_TYPE_ALC300:
Kailang Yangf0778872019-10-24 15:13:32 +08002966 case ALC269_TYPE_ALC623:
Kailang Yang6fbae352016-05-30 16:44:20 +08002967 case ALC269_TYPE_ALC700:
Kailang Yangadcc70b2012-05-25 08:08:38 +02002968 ssids = alc269_ssids;
2969 break;
2970 default:
2971 ssids = alc269_ssids;
2972 break;
2973 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02002974
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002975 return alc_parse_auto_config(codec, alc269_ignore, ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002976}
2977
Kailang Yang1387e2d2012-11-08 10:23:18 +01002978static void alc269vb_toggle_power_output(struct hda_codec *codec, int power_up)
Takashi Iwai1d045db2011-07-07 18:23:21 +02002979{
Takashi Iwai98b24882014-08-18 13:47:50 +02002980 alc_update_coef_idx(codec, 0x04, 1 << 11, power_up ? (1 << 11) : 0);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002981}
2982
2983static void alc269_shutup(struct hda_codec *codec)
2984{
Kailang Yangadcc70b2012-05-25 08:08:38 +02002985 struct alc_spec *spec = codec->spec;
2986
Kailang Yang1387e2d2012-11-08 10:23:18 +01002987 if (spec->codec_variant == ALC269_TYPE_ALC269VB)
2988 alc269vb_toggle_power_output(codec, 0);
2989 if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
2990 (alc_get_coef0(codec) & 0x00ff) == 0x018) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002991 msleep(150);
2992 }
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01002993 alc_shutup_pins(codec);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002994}
2995
Takashi Iwai54db6c32014-08-18 15:11:19 +02002996static struct coef_fw alc282_coefs[] = {
2997 WRITE_COEF(0x03, 0x0002), /* Power Down Control */
Kailang Yang32fa7e42014-10-24 16:26:01 +08002998 UPDATE_COEF(0x05, 0xff3f, 0x0700), /* FIFO and filter clock */
Takashi Iwai54db6c32014-08-18 15:11:19 +02002999 WRITE_COEF(0x07, 0x0200), /* DMIC control */
3000 UPDATE_COEF(0x06, 0x00f0, 0), /* Analog clock */
3001 UPDATE_COEF(0x08, 0xfffc, 0x0c2c), /* JD */
3002 WRITE_COEF(0x0a, 0xcccc), /* JD offset1 */
3003 WRITE_COEF(0x0b, 0xcccc), /* JD offset2 */
3004 WRITE_COEF(0x0e, 0x6e00), /* LDO1/2/3, DAC/ADC */
3005 UPDATE_COEF(0x0f, 0xf800, 0x1000), /* JD */
3006 UPDATE_COEF(0x10, 0xfc00, 0x0c00), /* Capless */
3007 WRITE_COEF(0x6f, 0x0), /* Class D test 4 */
3008 UPDATE_COEF(0x0c, 0xfe00, 0), /* IO power down directly */
3009 WRITE_COEF(0x34, 0xa0c0), /* ANC */
3010 UPDATE_COEF(0x16, 0x0008, 0), /* AGC MUX */
3011 UPDATE_COEF(0x1d, 0x00e0, 0), /* DAC simple content protection */
3012 UPDATE_COEF(0x1f, 0x00e0, 0), /* ADC simple content protection */
3013 WRITE_COEF(0x21, 0x8804), /* DAC ADC Zero Detection */
3014 WRITE_COEF(0x63, 0x2902), /* PLL */
3015 WRITE_COEF(0x68, 0xa080), /* capless control 2 */
3016 WRITE_COEF(0x69, 0x3400), /* capless control 3 */
3017 WRITE_COEF(0x6a, 0x2f3e), /* capless control 4 */
3018 WRITE_COEF(0x6b, 0x0), /* capless control 5 */
3019 UPDATE_COEF(0x6d, 0x0fff, 0x0900), /* class D test 2 */
3020 WRITE_COEF(0x6e, 0x110a), /* class D test 3 */
3021 UPDATE_COEF(0x70, 0x00f8, 0x00d8), /* class D test 5 */
3022 WRITE_COEF(0x71, 0x0014), /* class D test 6 */
3023 WRITE_COEF(0x72, 0xc2ba), /* classD OCP */
3024 UPDATE_COEF(0x77, 0x0f80, 0), /* classD pure DC test */
3025 WRITE_COEF(0x6c, 0xfc06), /* Class D amp control */
3026 {}
3027};
3028
Kailang Yangcb149cb2014-03-18 16:45:32 +08003029static void alc282_restore_default_value(struct hda_codec *codec)
3030{
Takashi Iwai54db6c32014-08-18 15:11:19 +02003031 alc_process_coef_fw(codec, alc282_coefs);
Kailang Yangcb149cb2014-03-18 16:45:32 +08003032}
3033
Kailang Yang7b5c7a02014-03-18 16:15:54 +08003034static void alc282_init(struct hda_codec *codec)
3035{
3036 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003037 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang7b5c7a02014-03-18 16:15:54 +08003038 bool hp_pin_sense;
3039 int coef78;
3040
Kailang Yangcb149cb2014-03-18 16:45:32 +08003041 alc282_restore_default_value(codec);
3042
Kailang Yang7b5c7a02014-03-18 16:15:54 +08003043 if (!hp_pin)
3044 return;
3045 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3046 coef78 = alc_read_coef_idx(codec, 0x78);
3047
3048 /* Index 0x78 Direct Drive HP AMP LPM Control 1 */
3049 /* Headphone capless set to high power mode */
3050 alc_write_coef_idx(codec, 0x78, 0x9004);
3051
3052 if (hp_pin_sense)
3053 msleep(2);
3054
3055 snd_hda_codec_write(codec, hp_pin, 0,
3056 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3057
3058 if (hp_pin_sense)
3059 msleep(85);
3060
3061 snd_hda_codec_write(codec, hp_pin, 0,
3062 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3063
3064 if (hp_pin_sense)
3065 msleep(100);
3066
3067 /* Headphone capless set to normal mode */
3068 alc_write_coef_idx(codec, 0x78, coef78);
3069}
3070
3071static void alc282_shutup(struct hda_codec *codec)
3072{
3073 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003074 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang7b5c7a02014-03-18 16:15:54 +08003075 bool hp_pin_sense;
3076 int coef78;
3077
3078 if (!hp_pin) {
3079 alc269_shutup(codec);
3080 return;
3081 }
3082
3083 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3084 coef78 = alc_read_coef_idx(codec, 0x78);
3085 alc_write_coef_idx(codec, 0x78, 0x9004);
3086
3087 if (hp_pin_sense)
3088 msleep(2);
3089
3090 snd_hda_codec_write(codec, hp_pin, 0,
3091 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3092
3093 if (hp_pin_sense)
3094 msleep(85);
3095
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003096 if (!spec->no_shutup_pins)
3097 snd_hda_codec_write(codec, hp_pin, 0,
3098 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
Kailang Yang7b5c7a02014-03-18 16:15:54 +08003099
3100 if (hp_pin_sense)
3101 msleep(100);
3102
3103 alc_auto_setup_eapd(codec, false);
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003104 alc_shutup_pins(codec);
Kailang Yang7b5c7a02014-03-18 16:15:54 +08003105 alc_write_coef_idx(codec, 0x78, coef78);
3106}
3107
Takashi Iwai54db6c32014-08-18 15:11:19 +02003108static struct coef_fw alc283_coefs[] = {
3109 WRITE_COEF(0x03, 0x0002), /* Power Down Control */
Kailang Yang56779862014-10-24 16:17:51 +08003110 UPDATE_COEF(0x05, 0xff3f, 0x0700), /* FIFO and filter clock */
Takashi Iwai54db6c32014-08-18 15:11:19 +02003111 WRITE_COEF(0x07, 0x0200), /* DMIC control */
3112 UPDATE_COEF(0x06, 0x00f0, 0), /* Analog clock */
3113 UPDATE_COEF(0x08, 0xfffc, 0x0c2c), /* JD */
3114 WRITE_COEF(0x0a, 0xcccc), /* JD offset1 */
3115 WRITE_COEF(0x0b, 0xcccc), /* JD offset2 */
3116 WRITE_COEF(0x0e, 0x6fc0), /* LDO1/2/3, DAC/ADC */
3117 UPDATE_COEF(0x0f, 0xf800, 0x1000), /* JD */
3118 UPDATE_COEF(0x10, 0xfc00, 0x0c00), /* Capless */
3119 WRITE_COEF(0x3a, 0x0), /* Class D test 4 */
3120 UPDATE_COEF(0x0c, 0xfe00, 0x0), /* IO power down directly */
3121 WRITE_COEF(0x22, 0xa0c0), /* ANC */
3122 UPDATE_COEFEX(0x53, 0x01, 0x000f, 0x0008), /* AGC MUX */
3123 UPDATE_COEF(0x1d, 0x00e0, 0), /* DAC simple content protection */
3124 UPDATE_COEF(0x1f, 0x00e0, 0), /* ADC simple content protection */
3125 WRITE_COEF(0x21, 0x8804), /* DAC ADC Zero Detection */
3126 WRITE_COEF(0x2e, 0x2902), /* PLL */
3127 WRITE_COEF(0x33, 0xa080), /* capless control 2 */
3128 WRITE_COEF(0x34, 0x3400), /* capless control 3 */
3129 WRITE_COEF(0x35, 0x2f3e), /* capless control 4 */
3130 WRITE_COEF(0x36, 0x0), /* capless control 5 */
3131 UPDATE_COEF(0x38, 0x0fff, 0x0900), /* class D test 2 */
3132 WRITE_COEF(0x39, 0x110a), /* class D test 3 */
3133 UPDATE_COEF(0x3b, 0x00f8, 0x00d8), /* class D test 5 */
3134 WRITE_COEF(0x3c, 0x0014), /* class D test 6 */
3135 WRITE_COEF(0x3d, 0xc2ba), /* classD OCP */
3136 UPDATE_COEF(0x42, 0x0f80, 0x0), /* classD pure DC test */
3137 WRITE_COEF(0x49, 0x0), /* test mode */
3138 UPDATE_COEF(0x40, 0xf800, 0x9800), /* Class D DC enable */
3139 UPDATE_COEF(0x42, 0xf000, 0x2000), /* DC offset */
3140 WRITE_COEF(0x37, 0xfc06), /* Class D amp control */
Kailang Yang56779862014-10-24 16:17:51 +08003141 UPDATE_COEF(0x1b, 0x8000, 0), /* HP JD control */
Takashi Iwai54db6c32014-08-18 15:11:19 +02003142 {}
3143};
3144
Kailang Yang6bd55b02014-03-17 13:51:27 +08003145static void alc283_restore_default_value(struct hda_codec *codec)
3146{
Takashi Iwai54db6c32014-08-18 15:11:19 +02003147 alc_process_coef_fw(codec, alc283_coefs);
Kailang Yang6bd55b02014-03-17 13:51:27 +08003148}
3149
Kailang Yang2af02be2013-08-22 10:03:50 +02003150static void alc283_init(struct hda_codec *codec)
3151{
3152 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003153 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang2af02be2013-08-22 10:03:50 +02003154 bool hp_pin_sense;
Kailang Yang2af02be2013-08-22 10:03:50 +02003155
Kailang Yang6bd55b02014-03-17 13:51:27 +08003156 alc283_restore_default_value(codec);
3157
Kailang Yang2af02be2013-08-22 10:03:50 +02003158 if (!hp_pin)
3159 return;
Kailang Yanga59d7192015-04-08 16:34:00 +08003160
3161 msleep(30);
Kailang Yang2af02be2013-08-22 10:03:50 +02003162 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3163
3164 /* Index 0x43 Direct Drive HP AMP LPM Control 1 */
3165 /* Headphone capless set to high power mode */
3166 alc_write_coef_idx(codec, 0x43, 0x9004);
3167
3168 snd_hda_codec_write(codec, hp_pin, 0,
3169 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3170
3171 if (hp_pin_sense)
3172 msleep(85);
3173
3174 snd_hda_codec_write(codec, hp_pin, 0,
3175 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3176
3177 if (hp_pin_sense)
3178 msleep(85);
3179 /* Index 0x46 Combo jack auto switch control 2 */
3180 /* 3k pull low control for Headset jack. */
Takashi Iwai98b24882014-08-18 13:47:50 +02003181 alc_update_coef_idx(codec, 0x46, 3 << 12, 0);
Kailang Yang2af02be2013-08-22 10:03:50 +02003182 /* Headphone capless set to normal mode */
3183 alc_write_coef_idx(codec, 0x43, 0x9614);
3184}
3185
3186static void alc283_shutup(struct hda_codec *codec)
3187{
3188 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003189 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang2af02be2013-08-22 10:03:50 +02003190 bool hp_pin_sense;
Kailang Yang2af02be2013-08-22 10:03:50 +02003191
3192 if (!hp_pin) {
3193 alc269_shutup(codec);
3194 return;
3195 }
3196
3197 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3198
3199 alc_write_coef_idx(codec, 0x43, 0x9004);
3200
Harsha Priyab450b172014-10-09 11:04:56 +00003201 /*depop hp during suspend*/
3202 alc_write_coef_idx(codec, 0x06, 0x2100);
3203
Kailang Yang2af02be2013-08-22 10:03:50 +02003204 snd_hda_codec_write(codec, hp_pin, 0,
3205 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3206
3207 if (hp_pin_sense)
Kailang Yang88011c092013-10-24 15:45:24 +02003208 msleep(100);
Kailang Yang2af02be2013-08-22 10:03:50 +02003209
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003210 if (!spec->no_shutup_pins)
3211 snd_hda_codec_write(codec, hp_pin, 0,
3212 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
Kailang Yang2af02be2013-08-22 10:03:50 +02003213
Takashi Iwai98b24882014-08-18 13:47:50 +02003214 alc_update_coef_idx(codec, 0x46, 0, 3 << 12);
Kailang Yang2af02be2013-08-22 10:03:50 +02003215
3216 if (hp_pin_sense)
Kailang Yang88011c092013-10-24 15:45:24 +02003217 msleep(100);
Kailang Yang0435b3f2014-04-08 17:14:14 +08003218 alc_auto_setup_eapd(codec, false);
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003219 alc_shutup_pins(codec);
Kailang Yang2af02be2013-08-22 10:03:50 +02003220 alc_write_coef_idx(codec, 0x43, 0x9614);
3221}
3222
Kailang Yang4a219ef2017-06-16 16:54:35 +08003223static void alc256_init(struct hda_codec *codec)
3224{
3225 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003226 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang4a219ef2017-06-16 16:54:35 +08003227 bool hp_pin_sense;
3228
3229 if (!hp_pin)
Kailang Yang6447c962019-05-08 16:27:03 +08003230 hp_pin = 0x21;
Kailang Yang4a219ef2017-06-16 16:54:35 +08003231
3232 msleep(30);
3233
3234 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3235
3236 if (hp_pin_sense)
3237 msleep(2);
3238
3239 alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */
Kailang Yang6447c962019-05-08 16:27:03 +08003240 if (spec->ultra_low_power) {
3241 alc_update_coef_idx(codec, 0x03, 1<<1, 1<<1);
3242 alc_update_coef_idx(codec, 0x08, 3<<2, 3<<2);
3243 alc_update_coef_idx(codec, 0x08, 7<<4, 0);
3244 alc_update_coef_idx(codec, 0x3b, 1<<15, 0);
3245 alc_update_coef_idx(codec, 0x0e, 7<<6, 7<<6);
3246 msleep(30);
3247 }
Kailang Yang4a219ef2017-06-16 16:54:35 +08003248
3249 snd_hda_codec_write(codec, hp_pin, 0,
3250 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3251
Kailang Yang6447c962019-05-08 16:27:03 +08003252 if (hp_pin_sense || spec->ultra_low_power)
Kailang Yang4a219ef2017-06-16 16:54:35 +08003253 msleep(85);
3254
3255 snd_hda_codec_write(codec, hp_pin, 0,
3256 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3257
Kailang Yang6447c962019-05-08 16:27:03 +08003258 if (hp_pin_sense || spec->ultra_low_power)
Kailang Yang4a219ef2017-06-16 16:54:35 +08003259 msleep(100);
3260
3261 alc_update_coef_idx(codec, 0x46, 3 << 12, 0);
3262 alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x4); /* Hight power */
Kailang Yang88d42b22018-03-14 16:08:57 +08003263 alc_update_coefex_idx(codec, 0x53, 0x02, 0x8000, 1 << 15); /* Clear bit */
3264 alc_update_coefex_idx(codec, 0x53, 0x02, 0x8000, 0 << 15);
Kailang Yangd07a9a42019-07-04 16:02:10 +08003265 alc_update_coef_idx(codec, 0x36, 1 << 13, 1 << 5); /* Switch pcbeep path to Line in path*/
Kailang Yang4a219ef2017-06-16 16:54:35 +08003266}
3267
3268static void alc256_shutup(struct hda_codec *codec)
3269{
3270 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003271 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang4a219ef2017-06-16 16:54:35 +08003272 bool hp_pin_sense;
3273
Kailang Yang6447c962019-05-08 16:27:03 +08003274 if (!hp_pin)
3275 hp_pin = 0x21;
Kailang Yang4a219ef2017-06-16 16:54:35 +08003276
3277 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3278
3279 if (hp_pin_sense)
3280 msleep(2);
3281
3282 snd_hda_codec_write(codec, hp_pin, 0,
3283 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3284
Kailang Yang6447c962019-05-08 16:27:03 +08003285 if (hp_pin_sense || spec->ultra_low_power)
Kailang Yang4a219ef2017-06-16 16:54:35 +08003286 msleep(85);
3287
Takashi Iwai1c9609e2018-01-19 14:18:34 +01003288 /* 3k pull low control for Headset jack. */
3289 /* NOTE: call this before clearing the pin, otherwise codec stalls */
3290 alc_update_coef_idx(codec, 0x46, 0, 3 << 12);
3291
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003292 if (!spec->no_shutup_pins)
3293 snd_hda_codec_write(codec, hp_pin, 0,
3294 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
Kailang Yang4a219ef2017-06-16 16:54:35 +08003295
Kailang Yang6447c962019-05-08 16:27:03 +08003296 if (hp_pin_sense || spec->ultra_low_power)
Kailang Yang4a219ef2017-06-16 16:54:35 +08003297 msleep(100);
3298
3299 alc_auto_setup_eapd(codec, false);
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003300 alc_shutup_pins(codec);
Kailang Yang6447c962019-05-08 16:27:03 +08003301 if (spec->ultra_low_power) {
3302 msleep(50);
3303 alc_update_coef_idx(codec, 0x03, 1<<1, 0);
3304 alc_update_coef_idx(codec, 0x08, 7<<4, 7<<4);
3305 alc_update_coef_idx(codec, 0x08, 3<<2, 0);
3306 alc_update_coef_idx(codec, 0x3b, 1<<15, 1<<15);
3307 alc_update_coef_idx(codec, 0x0e, 7<<6, 0);
3308 msleep(30);
3309 }
Kailang Yang4a219ef2017-06-16 16:54:35 +08003310}
3311
Kailang Yangda911b12018-01-05 16:50:08 +08003312static void alc225_init(struct hda_codec *codec)
3313{
3314 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003315 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yangda911b12018-01-05 16:50:08 +08003316 bool hp1_pin_sense, hp2_pin_sense;
3317
3318 if (!hp_pin)
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003319 hp_pin = 0x21;
Kailang Yangda911b12018-01-05 16:50:08 +08003320 msleep(30);
3321
3322 hp1_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3323 hp2_pin_sense = snd_hda_jack_detect(codec, 0x16);
3324
3325 if (hp1_pin_sense || hp2_pin_sense)
3326 msleep(2);
3327
3328 alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003329 if (spec->ultra_low_power) {
3330 alc_update_coef_idx(codec, 0x08, 0x0f << 2, 3<<2);
3331 alc_update_coef_idx(codec, 0x0e, 7<<6, 7<<6);
3332 alc_update_coef_idx(codec, 0x33, 1<<11, 0);
3333 msleep(30);
3334 }
Kailang Yangda911b12018-01-05 16:50:08 +08003335
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003336 if (hp1_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003337 snd_hda_codec_write(codec, hp_pin, 0,
3338 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3339 if (hp2_pin_sense)
3340 snd_hda_codec_write(codec, 0x16, 0,
3341 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3342
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003343 if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003344 msleep(85);
3345
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003346 if (hp1_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003347 snd_hda_codec_write(codec, hp_pin, 0,
3348 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3349 if (hp2_pin_sense)
3350 snd_hda_codec_write(codec, 0x16, 0,
3351 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3352
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003353 if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003354 msleep(100);
3355
3356 alc_update_coef_idx(codec, 0x4a, 3 << 10, 0);
3357 alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x4); /* Hight power */
3358}
3359
3360static void alc225_shutup(struct hda_codec *codec)
3361{
3362 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003363 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yangda911b12018-01-05 16:50:08 +08003364 bool hp1_pin_sense, hp2_pin_sense;
3365
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003366 if (!hp_pin)
3367 hp_pin = 0x21;
Kailang Yangda911b12018-01-05 16:50:08 +08003368 /* 3k pull low control for Headset jack. */
3369 alc_update_coef_idx(codec, 0x4a, 0, 3 << 10);
3370
3371 hp1_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3372 hp2_pin_sense = snd_hda_jack_detect(codec, 0x16);
3373
3374 if (hp1_pin_sense || hp2_pin_sense)
3375 msleep(2);
3376
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003377 if (hp1_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003378 snd_hda_codec_write(codec, hp_pin, 0,
3379 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3380 if (hp2_pin_sense)
3381 snd_hda_codec_write(codec, 0x16, 0,
3382 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3383
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003384 if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003385 msleep(85);
3386
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003387 if (hp1_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003388 snd_hda_codec_write(codec, hp_pin, 0,
3389 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
3390 if (hp2_pin_sense)
3391 snd_hda_codec_write(codec, 0x16, 0,
3392 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
3393
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003394 if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003395 msleep(100);
3396
3397 alc_auto_setup_eapd(codec, false);
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003398 alc_shutup_pins(codec);
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003399 if (spec->ultra_low_power) {
3400 msleep(50);
3401 alc_update_coef_idx(codec, 0x08, 0x0f << 2, 0x0c << 2);
3402 alc_update_coef_idx(codec, 0x0e, 7<<6, 0);
3403 alc_update_coef_idx(codec, 0x33, 1<<11, 1<<11);
3404 alc_update_coef_idx(codec, 0x4a, 3<<4, 2<<4);
3405 msleep(30);
3406 }
Kailang Yangda911b12018-01-05 16:50:08 +08003407}
3408
Kailang Yangc2d6af52017-06-21 14:50:54 +08003409static void alc_default_init(struct hda_codec *codec)
3410{
3411 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003412 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yangc2d6af52017-06-21 14:50:54 +08003413 bool hp_pin_sense;
3414
3415 if (!hp_pin)
3416 return;
3417
3418 msleep(30);
3419
3420 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3421
3422 if (hp_pin_sense)
3423 msleep(2);
3424
3425 snd_hda_codec_write(codec, hp_pin, 0,
3426 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3427
3428 if (hp_pin_sense)
3429 msleep(85);
3430
3431 snd_hda_codec_write(codec, hp_pin, 0,
3432 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3433
3434 if (hp_pin_sense)
3435 msleep(100);
3436}
3437
3438static void alc_default_shutup(struct hda_codec *codec)
3439{
3440 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003441 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yangc2d6af52017-06-21 14:50:54 +08003442 bool hp_pin_sense;
3443
3444 if (!hp_pin) {
3445 alc269_shutup(codec);
3446 return;
3447 }
3448
3449 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3450
3451 if (hp_pin_sense)
3452 msleep(2);
3453
3454 snd_hda_codec_write(codec, hp_pin, 0,
3455 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3456
3457 if (hp_pin_sense)
3458 msleep(85);
3459
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003460 if (!spec->no_shutup_pins)
3461 snd_hda_codec_write(codec, hp_pin, 0,
3462 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
Kailang Yangc2d6af52017-06-21 14:50:54 +08003463
3464 if (hp_pin_sense)
3465 msleep(100);
3466
3467 alc_auto_setup_eapd(codec, false);
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003468 alc_shutup_pins(codec);
Kailang Yangc2d6af52017-06-21 14:50:54 +08003469}
3470
Kailang Yang693abe12019-01-29 15:38:21 +08003471static void alc294_hp_init(struct hda_codec *codec)
3472{
3473 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003474 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang693abe12019-01-29 15:38:21 +08003475 int i, val;
3476
3477 if (!hp_pin)
3478 return;
3479
3480 snd_hda_codec_write(codec, hp_pin, 0,
3481 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3482
3483 msleep(100);
3484
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003485 if (!spec->no_shutup_pins)
3486 snd_hda_codec_write(codec, hp_pin, 0,
3487 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
Kailang Yang693abe12019-01-29 15:38:21 +08003488
3489 alc_update_coef_idx(codec, 0x6f, 0x000f, 0);/* Set HP depop to manual mode */
3490 alc_update_coefex_idx(codec, 0x58, 0x00, 0x8000, 0x8000); /* HP depop procedure start */
3491
3492 /* Wait for depop procedure finish */
3493 val = alc_read_coefex_idx(codec, 0x58, 0x01);
3494 for (i = 0; i < 20 && val & 0x0080; i++) {
3495 msleep(50);
3496 val = alc_read_coefex_idx(codec, 0x58, 0x01);
3497 }
3498 /* Set HP depop to auto mode */
3499 alc_update_coef_idx(codec, 0x6f, 0x000f, 0x000b);
3500 msleep(50);
3501}
3502
3503static void alc294_init(struct hda_codec *codec)
3504{
3505 struct alc_spec *spec = codec->spec;
3506
Takashi Iwaif6ef4e02019-01-29 14:14:51 +01003507 /* required only at boot or S4 resume time */
3508 if (!spec->done_hp_init ||
3509 codec->core.dev.power.power_state.event == PM_EVENT_RESTORE) {
Kailang Yang693abe12019-01-29 15:38:21 +08003510 alc294_hp_init(codec);
3511 spec->done_hp_init = true;
3512 }
3513 alc_default_init(codec);
3514}
3515
Kailang Yangad60d502013-06-28 12:03:01 +02003516static void alc5505_coef_set(struct hda_codec *codec, unsigned int index_reg,
3517 unsigned int val)
3518{
3519 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_COEF_INDEX, index_reg >> 1);
3520 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_PROC_COEF, val & 0xffff); /* LSB */
3521 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_PROC_COEF, val >> 16); /* MSB */
3522}
3523
3524static int alc5505_coef_get(struct hda_codec *codec, unsigned int index_reg)
3525{
3526 unsigned int val;
3527
3528 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_COEF_INDEX, index_reg >> 1);
3529 val = snd_hda_codec_read(codec, 0x51, 0, AC_VERB_GET_PROC_COEF, 0)
3530 & 0xffff;
3531 val |= snd_hda_codec_read(codec, 0x51, 0, AC_VERB_GET_PROC_COEF, 0)
3532 << 16;
3533 return val;
3534}
3535
3536static void alc5505_dsp_halt(struct hda_codec *codec)
3537{
3538 unsigned int val;
3539
3540 alc5505_coef_set(codec, 0x3000, 0x000c); /* DSP CPU stop */
3541 alc5505_coef_set(codec, 0x880c, 0x0008); /* DDR enter self refresh */
3542 alc5505_coef_set(codec, 0x61c0, 0x11110080); /* Clock control for PLL and CPU */
3543 alc5505_coef_set(codec, 0x6230, 0xfc0d4011); /* Disable Input OP */
3544 alc5505_coef_set(codec, 0x61b4, 0x040a2b03); /* Stop PLL2 */
3545 alc5505_coef_set(codec, 0x61b0, 0x00005b17); /* Stop PLL1 */
3546 alc5505_coef_set(codec, 0x61b8, 0x04133303); /* Stop PLL3 */
3547 val = alc5505_coef_get(codec, 0x6220);
3548 alc5505_coef_set(codec, 0x6220, (val | 0x3000)); /* switch Ringbuffer clock to DBUS clock */
3549}
3550
3551static void alc5505_dsp_back_from_halt(struct hda_codec *codec)
3552{
3553 alc5505_coef_set(codec, 0x61b8, 0x04133302);
3554 alc5505_coef_set(codec, 0x61b0, 0x00005b16);
3555 alc5505_coef_set(codec, 0x61b4, 0x040a2b02);
3556 alc5505_coef_set(codec, 0x6230, 0xf80d4011);
3557 alc5505_coef_set(codec, 0x6220, 0x2002010f);
3558 alc5505_coef_set(codec, 0x880c, 0x00000004);
3559}
3560
3561static void alc5505_dsp_init(struct hda_codec *codec)
3562{
3563 unsigned int val;
3564
3565 alc5505_dsp_halt(codec);
3566 alc5505_dsp_back_from_halt(codec);
3567 alc5505_coef_set(codec, 0x61b0, 0x5b14); /* PLL1 control */
3568 alc5505_coef_set(codec, 0x61b0, 0x5b16);
3569 alc5505_coef_set(codec, 0x61b4, 0x04132b00); /* PLL2 control */
3570 alc5505_coef_set(codec, 0x61b4, 0x04132b02);
3571 alc5505_coef_set(codec, 0x61b8, 0x041f3300); /* PLL3 control*/
3572 alc5505_coef_set(codec, 0x61b8, 0x041f3302);
3573 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_CODEC_RESET, 0); /* Function reset */
3574 alc5505_coef_set(codec, 0x61b8, 0x041b3302);
3575 alc5505_coef_set(codec, 0x61b8, 0x04173302);
3576 alc5505_coef_set(codec, 0x61b8, 0x04163302);
3577 alc5505_coef_set(codec, 0x8800, 0x348b328b); /* DRAM control */
3578 alc5505_coef_set(codec, 0x8808, 0x00020022); /* DRAM control */
3579 alc5505_coef_set(codec, 0x8818, 0x00000400); /* DRAM control */
3580
3581 val = alc5505_coef_get(codec, 0x6200) >> 16; /* Read revision ID */
3582 if (val <= 3)
3583 alc5505_coef_set(codec, 0x6220, 0x2002010f); /* I/O PAD Configuration */
3584 else
3585 alc5505_coef_set(codec, 0x6220, 0x6002018f);
3586
3587 alc5505_coef_set(codec, 0x61ac, 0x055525f0); /**/
3588 alc5505_coef_set(codec, 0x61c0, 0x12230080); /* Clock control */
3589 alc5505_coef_set(codec, 0x61b4, 0x040e2b02); /* PLL2 control */
3590 alc5505_coef_set(codec, 0x61bc, 0x010234f8); /* OSC Control */
3591 alc5505_coef_set(codec, 0x880c, 0x00000004); /* DRAM Function control */
3592 alc5505_coef_set(codec, 0x880c, 0x00000003);
3593 alc5505_coef_set(codec, 0x880c, 0x00000010);
Takashi Iwaicd63a5f2013-07-05 12:13:59 +02003594
3595#ifdef HALT_REALTEK_ALC5505
3596 alc5505_dsp_halt(codec);
3597#endif
Kailang Yangad60d502013-06-28 12:03:01 +02003598}
3599
Takashi Iwaicd63a5f2013-07-05 12:13:59 +02003600#ifdef HALT_REALTEK_ALC5505
3601#define alc5505_dsp_suspend(codec) /* NOP */
3602#define alc5505_dsp_resume(codec) /* NOP */
3603#else
3604#define alc5505_dsp_suspend(codec) alc5505_dsp_halt(codec)
3605#define alc5505_dsp_resume(codec) alc5505_dsp_back_from_halt(codec)
3606#endif
3607
Takashi Iwai2a439522011-07-26 09:52:50 +02003608#ifdef CONFIG_PM
Kailang Yangad60d502013-06-28 12:03:01 +02003609static int alc269_suspend(struct hda_codec *codec)
3610{
3611 struct alc_spec *spec = codec->spec;
3612
3613 if (spec->has_alc5505_dsp)
Takashi Iwaicd63a5f2013-07-05 12:13:59 +02003614 alc5505_dsp_suspend(codec);
Kailang Yangad60d502013-06-28 12:03:01 +02003615 return alc_suspend(codec);
3616}
3617
Takashi Iwai1d045db2011-07-07 18:23:21 +02003618static int alc269_resume(struct hda_codec *codec)
3619{
Kailang Yangadcc70b2012-05-25 08:08:38 +02003620 struct alc_spec *spec = codec->spec;
3621
Kailang Yang1387e2d2012-11-08 10:23:18 +01003622 if (spec->codec_variant == ALC269_TYPE_ALC269VB)
3623 alc269vb_toggle_power_output(codec, 0);
3624 if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
Kailang Yangadcc70b2012-05-25 08:08:38 +02003625 (alc_get_coef0(codec) & 0x00ff) == 0x018) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02003626 msleep(150);
3627 }
3628
3629 codec->patch_ops.init(codec);
3630
Kailang Yang1387e2d2012-11-08 10:23:18 +01003631 if (spec->codec_variant == ALC269_TYPE_ALC269VB)
3632 alc269vb_toggle_power_output(codec, 1);
3633 if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
Kailang Yangadcc70b2012-05-25 08:08:38 +02003634 (alc_get_coef0(codec) & 0x00ff) == 0x017) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02003635 msleep(200);
3636 }
3637
Takashi Iwaieeecd9d2015-02-25 15:18:50 +01003638 regcache_sync(codec->core.regmap);
Takashi Iwai1d045db2011-07-07 18:23:21 +02003639 hda_call_check_power_status(codec, 0x01);
Hui Wangf4753712014-08-19 12:07:03 +08003640
3641 /* on some machine, the BIOS will clear the codec gpio data when enter
3642 * suspend, and won't restore the data after resume, so we restore it
3643 * in the driver.
3644 */
Takashi Iwaid261eec2018-06-19 22:32:29 +02003645 if (spec->gpio_data)
3646 alc_write_gpio_data(codec);
Hui Wangf4753712014-08-19 12:07:03 +08003647
Kailang Yangad60d502013-06-28 12:03:01 +02003648 if (spec->has_alc5505_dsp)
Takashi Iwaicd63a5f2013-07-05 12:13:59 +02003649 alc5505_dsp_resume(codec);
Kailang Yangc5177c82013-07-24 14:39:49 +02003650
Takashi Iwai1d045db2011-07-07 18:23:21 +02003651 return 0;
3652}
Takashi Iwai2a439522011-07-26 09:52:50 +02003653#endif /* CONFIG_PM */
Takashi Iwai1d045db2011-07-07 18:23:21 +02003654
David Henningsson108cc102012-07-20 10:37:25 +02003655static void alc269_fixup_pincfg_no_hp_to_lineout(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003656 const struct hda_fixup *fix, int action)
David Henningsson108cc102012-07-20 10:37:25 +02003657{
3658 struct alc_spec *spec = codec->spec;
3659
Takashi Iwai1727a772013-01-10 09:52:52 +01003660 if (action == HDA_FIXUP_ACT_PRE_PROBE)
David Henningsson108cc102012-07-20 10:37:25 +02003661 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
3662}
3663
Jan-Marek Glogowskifdcc9682018-02-14 11:29:15 +01003664static void alc269_fixup_pincfg_U7x7_headset_mic(struct hda_codec *codec,
3665 const struct hda_fixup *fix,
3666 int action)
3667{
3668 unsigned int cfg_headphone = snd_hda_codec_get_pincfg(codec, 0x21);
3669 unsigned int cfg_headset_mic = snd_hda_codec_get_pincfg(codec, 0x19);
3670
3671 if (cfg_headphone && cfg_headset_mic == 0x411111f0)
3672 snd_hda_codec_set_pincfg(codec, 0x19,
3673 (cfg_headphone & ~AC_DEFCFG_DEVICE) |
3674 (AC_JACK_MIC_IN << AC_DEFCFG_DEVICE_SHIFT));
3675}
3676
Takashi Iwai1d045db2011-07-07 18:23:21 +02003677static void alc269_fixup_hweq(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003678 const struct hda_fixup *fix, int action)
Takashi Iwai1d045db2011-07-07 18:23:21 +02003679{
Takashi Iwai98b24882014-08-18 13:47:50 +02003680 if (action == HDA_FIXUP_ACT_INIT)
3681 alc_update_coef_idx(codec, 0x1e, 0, 0x80);
Takashi Iwai1d045db2011-07-07 18:23:21 +02003682}
3683
David Henningsson7c478f02013-10-11 10:18:46 +02003684static void alc269_fixup_headset_mic(struct hda_codec *codec,
3685 const struct hda_fixup *fix, int action)
3686{
3687 struct alc_spec *spec = codec->spec;
3688
3689 if (action == HDA_FIXUP_ACT_PRE_PROBE)
3690 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
3691}
3692
Takashi Iwai1d045db2011-07-07 18:23:21 +02003693static void alc271_fixup_dmic(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003694 const struct hda_fixup *fix, int action)
Takashi Iwai1d045db2011-07-07 18:23:21 +02003695{
3696 static const struct hda_verb verbs[] = {
3697 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
3698 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
3699 {}
3700 };
3701 unsigned int cfg;
3702
Takashi Iwai7639a062015-03-03 10:07:24 +01003703 if (strcmp(codec->core.chip_name, "ALC271X") &&
3704 strcmp(codec->core.chip_name, "ALC269VB"))
Takashi Iwai1d045db2011-07-07 18:23:21 +02003705 return;
3706 cfg = snd_hda_codec_get_pincfg(codec, 0x12);
3707 if (get_defcfg_connect(cfg) == AC_JACK_PORT_FIXED)
3708 snd_hda_sequence_write(codec, verbs);
3709}
3710
Takashi Iwai017f2a12011-07-09 14:42:25 +02003711static void alc269_fixup_pcm_44k(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003712 const struct hda_fixup *fix, int action)
Takashi Iwai017f2a12011-07-09 14:42:25 +02003713{
3714 struct alc_spec *spec = codec->spec;
3715
Takashi Iwai1727a772013-01-10 09:52:52 +01003716 if (action != HDA_FIXUP_ACT_PROBE)
Takashi Iwai017f2a12011-07-09 14:42:25 +02003717 return;
3718
3719 /* Due to a hardware problem on Lenovo Ideadpad, we need to
3720 * fix the sample rate of analog I/O to 44.1kHz
3721 */
Takashi Iwai08c189f2012-12-19 15:22:24 +01003722 spec->gen.stream_analog_playback = &alc269_44k_pcm_analog_playback;
3723 spec->gen.stream_analog_capture = &alc269_44k_pcm_analog_capture;
Takashi Iwai017f2a12011-07-09 14:42:25 +02003724}
3725
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02003726static void alc269_fixup_stereo_dmic(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003727 const struct hda_fixup *fix, int action)
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02003728{
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02003729 /* The digital-mic unit sends PDM (differential signal) instead of
3730 * the standard PCM, thus you can't record a valid mono stream as is.
3731 * Below is a workaround specific to ALC269 to control the dmic
3732 * signal source as mono.
3733 */
Takashi Iwai98b24882014-08-18 13:47:50 +02003734 if (action == HDA_FIXUP_ACT_INIT)
3735 alc_update_coef_idx(codec, 0x07, 0, 0x80);
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02003736}
3737
Takashi Iwai24519912011-08-16 15:08:49 +02003738static void alc269_quanta_automute(struct hda_codec *codec)
3739{
Takashi Iwai08c189f2012-12-19 15:22:24 +01003740 snd_hda_gen_update_outputs(codec);
Takashi Iwai24519912011-08-16 15:08:49 +02003741
Takashi Iwai1687ccc2014-08-18 13:49:35 +02003742 alc_write_coef_idx(codec, 0x0c, 0x680);
3743 alc_write_coef_idx(codec, 0x0c, 0x480);
Takashi Iwai24519912011-08-16 15:08:49 +02003744}
3745
3746static void alc269_fixup_quanta_mute(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003747 const struct hda_fixup *fix, int action)
Takashi Iwai24519912011-08-16 15:08:49 +02003748{
3749 struct alc_spec *spec = codec->spec;
Takashi Iwai1727a772013-01-10 09:52:52 +01003750 if (action != HDA_FIXUP_ACT_PROBE)
Takashi Iwai24519912011-08-16 15:08:49 +02003751 return;
Takashi Iwai08c189f2012-12-19 15:22:24 +01003752 spec->gen.automute_hook = alc269_quanta_automute;
Takashi Iwai24519912011-08-16 15:08:49 +02003753}
3754
David Henningssond240d1d2013-04-15 12:50:02 +02003755static void alc269_x101_hp_automute_hook(struct hda_codec *codec,
Takashi Iwai1a4f69d2014-09-11 15:22:46 +02003756 struct hda_jack_callback *jack)
David Henningssond240d1d2013-04-15 12:50:02 +02003757{
3758 struct alc_spec *spec = codec->spec;
3759 int vref;
3760 msleep(200);
3761 snd_hda_gen_hp_automute(codec, jack);
3762
3763 vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0;
3764 msleep(100);
3765 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3766 vref);
3767 msleep(500);
3768 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3769 vref);
3770}
3771
Tomas Espeletaa2ef03f2019-08-09 16:37:54 +02003772/*
3773 * Magic sequence to make Huawei Matebook X right speaker working (bko#197801)
3774 */
3775struct hda_alc298_mbxinit {
3776 unsigned char value_0x23;
3777 unsigned char value_0x25;
3778};
3779
3780static void alc298_huawei_mbx_stereo_seq(struct hda_codec *codec,
3781 const struct hda_alc298_mbxinit *initval,
3782 bool first)
3783{
3784 snd_hda_codec_write(codec, 0x06, 0, AC_VERB_SET_DIGI_CONVERT_3, 0x0);
3785 alc_write_coef_idx(codec, 0x26, 0xb000);
3786
3787 if (first)
3788 snd_hda_codec_write(codec, 0x21, 0, AC_VERB_GET_PIN_SENSE, 0x0);
3789
3790 snd_hda_codec_write(codec, 0x6, 0, AC_VERB_SET_DIGI_CONVERT_3, 0x80);
3791 alc_write_coef_idx(codec, 0x26, 0xf000);
3792 alc_write_coef_idx(codec, 0x23, initval->value_0x23);
3793
3794 if (initval->value_0x23 != 0x1e)
3795 alc_write_coef_idx(codec, 0x25, initval->value_0x25);
3796
3797 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0x26);
3798 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, 0xb010);
3799}
3800
3801static void alc298_fixup_huawei_mbx_stereo(struct hda_codec *codec,
3802 const struct hda_fixup *fix,
3803 int action)
3804{
3805 /* Initialization magic */
3806 static const struct hda_alc298_mbxinit dac_init[] = {
3807 {0x0c, 0x00}, {0x0d, 0x00}, {0x0e, 0x00}, {0x0f, 0x00},
3808 {0x10, 0x00}, {0x1a, 0x40}, {0x1b, 0x82}, {0x1c, 0x00},
3809 {0x1d, 0x00}, {0x1e, 0x00}, {0x1f, 0x00},
3810 {0x20, 0xc2}, {0x21, 0xc8}, {0x22, 0x26}, {0x23, 0x24},
3811 {0x27, 0xff}, {0x28, 0xff}, {0x29, 0xff}, {0x2a, 0x8f},
3812 {0x2b, 0x02}, {0x2c, 0x48}, {0x2d, 0x34}, {0x2e, 0x00},
3813 {0x2f, 0x00},
3814 {0x30, 0x00}, {0x31, 0x00}, {0x32, 0x00}, {0x33, 0x00},
3815 {0x34, 0x00}, {0x35, 0x01}, {0x36, 0x93}, {0x37, 0x0c},
3816 {0x38, 0x00}, {0x39, 0x00}, {0x3a, 0xf8}, {0x38, 0x80},
3817 {}
3818 };
3819 const struct hda_alc298_mbxinit *seq;
3820
3821 if (action != HDA_FIXUP_ACT_INIT)
3822 return;
3823
3824 /* Start */
3825 snd_hda_codec_write(codec, 0x06, 0, AC_VERB_SET_DIGI_CONVERT_3, 0x00);
3826 snd_hda_codec_write(codec, 0x06, 0, AC_VERB_SET_DIGI_CONVERT_3, 0x80);
3827 alc_write_coef_idx(codec, 0x26, 0xf000);
3828 alc_write_coef_idx(codec, 0x22, 0x31);
3829 alc_write_coef_idx(codec, 0x23, 0x0b);
3830 alc_write_coef_idx(codec, 0x25, 0x00);
3831 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0x26);
3832 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, 0xb010);
3833
3834 for (seq = dac_init; seq->value_0x23; seq++)
3835 alc298_huawei_mbx_stereo_seq(codec, seq, seq == dac_init);
3836}
3837
David Henningssond240d1d2013-04-15 12:50:02 +02003838static void alc269_fixup_x101_headset_mic(struct hda_codec *codec,
3839 const struct hda_fixup *fix, int action)
3840{
3841 struct alc_spec *spec = codec->spec;
3842 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3843 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
3844 spec->gen.hp_automute_hook = alc269_x101_hp_automute_hook;
3845 }
3846}
3847
3848
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003849/* update mute-LED according to the speaker mute state via mic VREF pin */
3850static void alc269_fixup_mic_mute_hook(void *private_data, int enabled)
David Henningsson6d3cd5d2013-01-07 12:03:47 +01003851{
3852 struct hda_codec *codec = private_data;
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003853 struct alc_spec *spec = codec->spec;
3854 unsigned int pinval;
3855
3856 if (spec->mute_led_polarity)
3857 enabled = !enabled;
Takashi Iwai415d5552014-04-03 11:51:21 +02003858 pinval = snd_hda_codec_get_pin_target(codec, spec->mute_led_nid);
3859 pinval &= ~AC_PINCTL_VREFEN;
3860 pinval |= enabled ? AC_PINCTL_VREF_HIZ : AC_PINCTL_VREF_80;
Takashi Iwaie40bdb02018-03-17 22:40:18 +01003861 if (spec->mute_led_nid) {
3862 /* temporarily power up/down for setting VREF */
3863 snd_hda_power_up_pm(codec);
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003864 snd_hda_set_pin_ctl_cache(codec, spec->mute_led_nid, pinval);
Takashi Iwaie40bdb02018-03-17 22:40:18 +01003865 snd_hda_power_down_pm(codec);
3866 }
David Henningsson6d3cd5d2013-01-07 12:03:47 +01003867}
3868
David Henningssond5b6b652013-11-06 10:50:44 +01003869/* Make sure the led works even in runtime suspend */
3870static unsigned int led_power_filter(struct hda_codec *codec,
3871 hda_nid_t nid,
3872 unsigned int power_state)
3873{
3874 struct alc_spec *spec = codec->spec;
3875
Hui Wang50dd9052014-07-08 17:56:15 +08003876 if (power_state != AC_PWRST_D3 || nid == 0 ||
3877 (nid != spec->mute_led_nid && nid != spec->cap_mute_led_nid))
David Henningssond5b6b652013-11-06 10:50:44 +01003878 return power_state;
3879
3880 /* Set pin ctl again, it might have just been set to 0 */
3881 snd_hda_set_pin_ctl(codec, nid,
3882 snd_hda_codec_get_pin_target(codec, nid));
3883
Takashi Iwaicffd3962015-04-09 10:30:25 +02003884 return snd_hda_gen_path_power_filter(codec, nid, power_state);
David Henningssond5b6b652013-11-06 10:50:44 +01003885}
3886
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003887static void alc269_fixup_hp_mute_led(struct hda_codec *codec,
3888 const struct hda_fixup *fix, int action)
David Henningsson6d3cd5d2013-01-07 12:03:47 +01003889{
3890 struct alc_spec *spec = codec->spec;
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003891 const struct dmi_device *dev = NULL;
3892
3893 if (action != HDA_FIXUP_ACT_PRE_PROBE)
3894 return;
3895
3896 while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) {
3897 int pol, pin;
3898 if (sscanf(dev->name, "HP_Mute_LED_%d_%x", &pol, &pin) != 2)
3899 continue;
3900 if (pin < 0x0a || pin >= 0x10)
3901 break;
3902 spec->mute_led_polarity = pol;
3903 spec->mute_led_nid = pin - 0x0a + 0x18;
3904 spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook;
Takashi Iwaifd25a972012-12-20 14:57:18 +01003905 spec->gen.vmaster_mute_enum = 1;
David Henningssond5b6b652013-11-06 10:50:44 +01003906 codec->power_filter = led_power_filter;
Takashi Iwai4e76a882014-02-25 12:21:03 +01003907 codec_dbg(codec,
3908 "Detected mute LED for %x:%d\n", spec->mute_led_nid,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003909 spec->mute_led_polarity);
David Henningsson6d3cd5d2013-01-07 12:03:47 +01003910 break;
3911 }
3912}
3913
Takashi Iwai85c467d2018-05-29 11:38:38 +02003914static void alc269_fixup_hp_mute_led_micx(struct hda_codec *codec,
3915 const struct hda_fixup *fix,
3916 int action, hda_nid_t pin)
David Henningssond06ac142013-02-18 11:41:55 +01003917{
3918 struct alc_spec *spec = codec->spec;
Takashi Iwai85c467d2018-05-29 11:38:38 +02003919
David Henningssond06ac142013-02-18 11:41:55 +01003920 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3921 spec->mute_led_polarity = 0;
Takashi Iwai85c467d2018-05-29 11:38:38 +02003922 spec->mute_led_nid = pin;
David Henningssond06ac142013-02-18 11:41:55 +01003923 spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook;
3924 spec->gen.vmaster_mute_enum = 1;
David Henningssond5b6b652013-11-06 10:50:44 +01003925 codec->power_filter = led_power_filter;
David Henningssond06ac142013-02-18 11:41:55 +01003926 }
3927}
3928
Takashi Iwai85c467d2018-05-29 11:38:38 +02003929static void alc269_fixup_hp_mute_led_mic1(struct hda_codec *codec,
3930 const struct hda_fixup *fix, int action)
3931{
3932 alc269_fixup_hp_mute_led_micx(codec, fix, action, 0x18);
3933}
3934
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003935static void alc269_fixup_hp_mute_led_mic2(struct hda_codec *codec,
3936 const struct hda_fixup *fix, int action)
Takashi Iwai420b0fe2012-03-12 12:35:27 +01003937{
Takashi Iwai85c467d2018-05-29 11:38:38 +02003938 alc269_fixup_hp_mute_led_micx(codec, fix, action, 0x19);
Takashi Iwai420b0fe2012-03-12 12:35:27 +01003939}
3940
Tom Briden7f783bd2017-03-25 10:12:01 +00003941static void alc269_fixup_hp_mute_led_mic3(struct hda_codec *codec,
3942 const struct hda_fixup *fix, int action)
3943{
Takashi Iwai85c467d2018-05-29 11:38:38 +02003944 alc269_fixup_hp_mute_led_micx(codec, fix, action, 0x1b);
Tom Briden7f783bd2017-03-25 10:12:01 +00003945}
3946
Takashi Iwai0f32fd192014-11-19 12:16:14 +01003947/* update LED status via GPIO */
3948static void alc_update_gpio_led(struct hda_codec *codec, unsigned int mask,
3949 bool enabled)
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003950{
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003951 struct alc_spec *spec = codec->spec;
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003952
Takashi Iwai0f32fd192014-11-19 12:16:14 +01003953 if (spec->mute_led_polarity)
3954 enabled = !enabled;
Takashi Iwaid261eec2018-06-19 22:32:29 +02003955 alc_update_gpio_data(codec, mask, !enabled); /* muted -> LED on */
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003956}
3957
Takashi Iwai0f32fd192014-11-19 12:16:14 +01003958/* turn on/off mute LED via GPIO per vmaster hook */
3959static void alc_fixup_gpio_mute_hook(void *private_data, int enabled)
3960{
3961 struct hda_codec *codec = private_data;
3962 struct alc_spec *spec = codec->spec;
3963
3964 alc_update_gpio_led(codec, spec->gpio_mute_led_mask, enabled);
3965}
3966
3967/* turn on/off mic-mute LED via GPIO per capture hook */
Takashi Iwaid03abec2018-06-19 12:29:13 +02003968static void alc_gpio_micmute_update(struct hda_codec *codec)
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003969{
3970 struct alc_spec *spec = codec->spec;
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003971
Takashi Iwaid03abec2018-06-19 12:29:13 +02003972 alc_update_gpio_led(codec, spec->gpio_mic_led_mask,
3973 spec->gen.micmute_led.led_value);
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003974}
3975
Takashi Iwai01e4a272018-06-19 22:47:30 +02003976/* setup mute and mic-mute GPIO bits, add hooks appropriately */
3977static void alc_fixup_hp_gpio_led(struct hda_codec *codec,
3978 int action,
3979 unsigned int mute_mask,
3980 unsigned int micmute_mask)
3981{
3982 struct alc_spec *spec = codec->spec;
3983
3984 alc_fixup_gpio(codec, action, mute_mask | micmute_mask);
3985
3986 if (action != HDA_FIXUP_ACT_PRE_PROBE)
3987 return;
3988 if (mute_mask) {
3989 spec->gpio_mute_led_mask = mute_mask;
3990 spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook;
3991 }
3992 if (micmute_mask) {
3993 spec->gpio_mic_led_mask = micmute_mask;
3994 snd_hda_gen_add_micmute_led(codec, alc_gpio_micmute_update);
3995 }
3996}
3997
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003998static void alc269_fixup_hp_gpio_led(struct hda_codec *codec,
3999 const struct hda_fixup *fix, int action)
4000{
Takashi Iwai01e4a272018-06-19 22:47:30 +02004001 alc_fixup_hp_gpio_led(codec, action, 0x08, 0x10);
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01004002}
4003
Kailang Yangeaa8e5e2014-11-21 15:49:11 +08004004static void alc286_fixup_hp_gpio_led(struct hda_codec *codec,
4005 const struct hda_fixup *fix, int action)
4006{
Takashi Iwai01e4a272018-06-19 22:47:30 +02004007 alc_fixup_hp_gpio_led(codec, action, 0x02, 0x20);
Takashi Iwai1d045db2011-07-07 18:23:21 +02004008}
4009
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004010/* turn on/off mic-mute LED per capture hook */
Takashi Iwaid03abec2018-06-19 12:29:13 +02004011static void alc_cap_micmute_update(struct hda_codec *codec)
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004012{
4013 struct alc_spec *spec = codec->spec;
Takashi Iwaid03abec2018-06-19 12:29:13 +02004014 unsigned int pinval;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004015
Takashi Iwaid03abec2018-06-19 12:29:13 +02004016 if (!spec->cap_mute_led_nid)
4017 return;
Hui Wangfc1fad92014-07-08 17:56:14 +08004018 pinval = snd_hda_codec_get_pin_target(codec, spec->cap_mute_led_nid);
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004019 pinval &= ~AC_PINCTL_VREFEN;
Takashi Iwaid03abec2018-06-19 12:29:13 +02004020 if (spec->gen.micmute_led.led_value)
4021 pinval |= AC_PINCTL_VREF_80;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004022 else
Takashi Iwaid03abec2018-06-19 12:29:13 +02004023 pinval |= AC_PINCTL_VREF_HIZ;
4024 snd_hda_set_pin_ctl_cache(codec, spec->cap_mute_led_nid, pinval);
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004025}
4026
4027static void alc269_fixup_hp_gpio_mic1_led(struct hda_codec *codec,
4028 const struct hda_fixup *fix, int action)
4029{
4030 struct alc_spec *spec = codec->spec;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004031
Takashi Iwai01e4a272018-06-19 22:47:30 +02004032 alc_fixup_hp_gpio_led(codec, action, 0x08, 0);
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004033 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai01e4a272018-06-19 22:47:30 +02004034 /* Like hp_gpio_mic1_led, but also needs GPIO4 low to
4035 * enable headphone amp
4036 */
4037 spec->gpio_mask |= 0x10;
4038 spec->gpio_dir |= 0x10;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004039 spec->cap_mute_led_nid = 0x18;
Takashi Iwaid03abec2018-06-19 12:29:13 +02004040 snd_hda_gen_add_micmute_led(codec, alc_cap_micmute_update);
Hui Wang50dd9052014-07-08 17:56:15 +08004041 codec->power_filter = led_power_filter;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004042 }
4043}
4044
David Henningsson7a5255f2014-10-30 08:26:01 +01004045static void alc280_fixup_hp_gpio4(struct hda_codec *codec,
4046 const struct hda_fixup *fix, int action)
4047{
David Henningsson7a5255f2014-10-30 08:26:01 +01004048 struct alc_spec *spec = codec->spec;
David Henningsson7a5255f2014-10-30 08:26:01 +01004049
Takashi Iwai01e4a272018-06-19 22:47:30 +02004050 alc_fixup_hp_gpio_led(codec, action, 0x08, 0);
David Henningsson7a5255f2014-10-30 08:26:01 +01004051 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
David Henningsson7a5255f2014-10-30 08:26:01 +01004052 spec->cap_mute_led_nid = 0x18;
Takashi Iwaid03abec2018-06-19 12:29:13 +02004053 snd_hda_gen_add_micmute_led(codec, alc_cap_micmute_update);
David Henningsson7a5255f2014-10-30 08:26:01 +01004054 codec->power_filter = led_power_filter;
4055 }
4056}
4057
Takashi Iwai6a30aba2018-04-27 17:17:35 +02004058#if IS_REACHABLE(CONFIG_INPUT)
David Henningsson33f4acd2015-01-07 15:50:13 +01004059static void gpio2_mic_hotkey_event(struct hda_codec *codec,
4060 struct hda_jack_callback *event)
4061{
4062 struct alc_spec *spec = codec->spec;
4063
4064 /* GPIO2 just toggles on a keypress/keyrelease cycle. Therefore
4065 send both key on and key off event for every interrupt. */
Hui Wangc7b60a82015-12-28 11:35:25 +08004066 input_report_key(spec->kb_dev, spec->alc_mute_keycode_map[ALC_KEY_MICMUTE_INDEX], 1);
David Henningsson33f4acd2015-01-07 15:50:13 +01004067 input_sync(spec->kb_dev);
Hui Wangc7b60a82015-12-28 11:35:25 +08004068 input_report_key(spec->kb_dev, spec->alc_mute_keycode_map[ALC_KEY_MICMUTE_INDEX], 0);
David Henningsson33f4acd2015-01-07 15:50:13 +01004069 input_sync(spec->kb_dev);
4070}
David Henningsson33f4acd2015-01-07 15:50:13 +01004071
Kailang3694cb22015-12-28 11:35:24 +08004072static int alc_register_micmute_input_device(struct hda_codec *codec)
4073{
4074 struct alc_spec *spec = codec->spec;
Hui Wangc7b60a82015-12-28 11:35:25 +08004075 int i;
Kailang3694cb22015-12-28 11:35:24 +08004076
4077 spec->kb_dev = input_allocate_device();
4078 if (!spec->kb_dev) {
4079 codec_err(codec, "Out of memory (input_allocate_device)\n");
4080 return -ENOMEM;
4081 }
Hui Wangc7b60a82015-12-28 11:35:25 +08004082
4083 spec->alc_mute_keycode_map[ALC_KEY_MICMUTE_INDEX] = KEY_MICMUTE;
4084
Kailang3694cb22015-12-28 11:35:24 +08004085 spec->kb_dev->name = "Microphone Mute Button";
4086 spec->kb_dev->evbit[0] = BIT_MASK(EV_KEY);
Hui Wangc7b60a82015-12-28 11:35:25 +08004087 spec->kb_dev->keycodesize = sizeof(spec->alc_mute_keycode_map[0]);
4088 spec->kb_dev->keycodemax = ARRAY_SIZE(spec->alc_mute_keycode_map);
4089 spec->kb_dev->keycode = spec->alc_mute_keycode_map;
4090 for (i = 0; i < ARRAY_SIZE(spec->alc_mute_keycode_map); i++)
4091 set_bit(spec->alc_mute_keycode_map[i], spec->kb_dev->keybit);
Kailang3694cb22015-12-28 11:35:24 +08004092
4093 if (input_register_device(spec->kb_dev)) {
4094 codec_err(codec, "input_register_device failed\n");
4095 input_free_device(spec->kb_dev);
4096 spec->kb_dev = NULL;
4097 return -ENOMEM;
4098 }
4099
4100 return 0;
4101}
4102
Takashi Iwai01e4a272018-06-19 22:47:30 +02004103/* GPIO1 = set according to SKU external amp
4104 * GPIO2 = mic mute hotkey
4105 * GPIO3 = mute LED
4106 * GPIO4 = mic mute LED
4107 */
David Henningsson33f4acd2015-01-07 15:50:13 +01004108static void alc280_fixup_hp_gpio2_mic_hotkey(struct hda_codec *codec,
4109 const struct hda_fixup *fix, int action)
4110{
David Henningsson33f4acd2015-01-07 15:50:13 +01004111 struct alc_spec *spec = codec->spec;
4112
Takashi Iwai01e4a272018-06-19 22:47:30 +02004113 alc_fixup_hp_gpio_led(codec, action, 0x08, 0x10);
David Henningsson33f4acd2015-01-07 15:50:13 +01004114 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai1c76aa52018-06-21 16:37:54 +02004115 spec->init_amp = ALC_INIT_DEFAULT;
Kailang3694cb22015-12-28 11:35:24 +08004116 if (alc_register_micmute_input_device(codec) != 0)
David Henningsson33f4acd2015-01-07 15:50:13 +01004117 return;
David Henningsson33f4acd2015-01-07 15:50:13 +01004118
Takashi Iwai01e4a272018-06-19 22:47:30 +02004119 spec->gpio_mask |= 0x06;
4120 spec->gpio_dir |= 0x02;
4121 spec->gpio_data |= 0x02;
Takashi Iwai7639a062015-03-03 10:07:24 +01004122 snd_hda_codec_write_cache(codec, codec->core.afg, 0,
David Henningsson33f4acd2015-01-07 15:50:13 +01004123 AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x04);
Takashi Iwai7639a062015-03-03 10:07:24 +01004124 snd_hda_jack_detect_enable_callback(codec, codec->core.afg,
David Henningsson33f4acd2015-01-07 15:50:13 +01004125 gpio2_mic_hotkey_event);
David Henningsson33f4acd2015-01-07 15:50:13 +01004126 return;
4127 }
4128
4129 if (!spec->kb_dev)
4130 return;
4131
4132 switch (action) {
David Henningsson33f4acd2015-01-07 15:50:13 +01004133 case HDA_FIXUP_ACT_FREE:
4134 input_unregister_device(spec->kb_dev);
David Henningsson33f4acd2015-01-07 15:50:13 +01004135 spec->kb_dev = NULL;
4136 }
David Henningsson33f4acd2015-01-07 15:50:13 +01004137}
4138
Takashi Iwai01e4a272018-06-19 22:47:30 +02004139/* Line2 = mic mute hotkey
4140 * GPIO2 = mic mute LED
4141 */
Kailang3694cb22015-12-28 11:35:24 +08004142static void alc233_fixup_lenovo_line2_mic_hotkey(struct hda_codec *codec,
4143 const struct hda_fixup *fix, int action)
4144{
Kailang3694cb22015-12-28 11:35:24 +08004145 struct alc_spec *spec = codec->spec;
4146
Takashi Iwai01e4a272018-06-19 22:47:30 +02004147 alc_fixup_hp_gpio_led(codec, action, 0, 0x04);
Kailang3694cb22015-12-28 11:35:24 +08004148 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai1c76aa52018-06-21 16:37:54 +02004149 spec->init_amp = ALC_INIT_DEFAULT;
Kailang3694cb22015-12-28 11:35:24 +08004150 if (alc_register_micmute_input_device(codec) != 0)
4151 return;
4152
Kailang3694cb22015-12-28 11:35:24 +08004153 snd_hda_jack_detect_enable_callback(codec, 0x1b,
4154 gpio2_mic_hotkey_event);
Kailang3694cb22015-12-28 11:35:24 +08004155 return;
4156 }
4157
4158 if (!spec->kb_dev)
4159 return;
4160
4161 switch (action) {
Kailang3694cb22015-12-28 11:35:24 +08004162 case HDA_FIXUP_ACT_FREE:
4163 input_unregister_device(spec->kb_dev);
4164 spec->kb_dev = NULL;
4165 }
4166}
Takashi Iwaic4696522018-01-15 10:44:35 +01004167#else /* INPUT */
4168#define alc280_fixup_hp_gpio2_mic_hotkey NULL
4169#define alc233_fixup_lenovo_line2_mic_hotkey NULL
4170#endif /* INPUT */
Kailang3694cb22015-12-28 11:35:24 +08004171
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004172static void alc269_fixup_hp_line1_mic1_led(struct hda_codec *codec,
4173 const struct hda_fixup *fix, int action)
4174{
4175 struct alc_spec *spec = codec->spec;
4176
Takashi Iwai1bce62a2018-06-19 23:15:59 +02004177 alc269_fixup_hp_mute_led_micx(codec, fix, action, 0x1a);
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004178 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004179 spec->cap_mute_led_nid = 0x18;
Takashi Iwaid03abec2018-06-19 12:29:13 +02004180 snd_hda_gen_add_micmute_led(codec, alc_cap_micmute_update);
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004181 }
4182}
4183
Kailang Yang5a367672017-07-21 15:23:53 +08004184static struct coef_fw alc225_pre_hsmode[] = {
4185 UPDATE_COEF(0x4a, 1<<8, 0),
4186 UPDATE_COEFEX(0x57, 0x05, 1<<14, 0),
4187 UPDATE_COEF(0x63, 3<<14, 3<<14),
4188 UPDATE_COEF(0x4a, 3<<4, 2<<4),
4189 UPDATE_COEF(0x4a, 3<<10, 3<<10),
4190 UPDATE_COEF(0x45, 0x3f<<10, 0x34<<10),
4191 UPDATE_COEF(0x4a, 3<<10, 0),
4192 {}
4193};
4194
David Henningsson73bdd592013-04-15 15:44:14 +02004195static void alc_headset_mode_unplugged(struct hda_codec *codec)
4196{
Takashi Iwai54db6c32014-08-18 15:11:19 +02004197 static struct coef_fw coef0255[] = {
Kailang Yang717f43d2019-05-31 17:16:53 +08004198 WRITE_COEF(0x1b, 0x0c0b), /* LDO and MISC control */
Takashi Iwai54db6c32014-08-18 15:11:19 +02004199 WRITE_COEF(0x45, 0xd089), /* UAJ function set to menual mode */
4200 UPDATE_COEFEX(0x57, 0x05, 1<<14, 0), /* Direct Drive HP Amp control(Set to verb control)*/
4201 WRITE_COEF(0x06, 0x6104), /* Set MIC2 Vref gate with HP */
4202 WRITE_COEFEX(0x57, 0x03, 0x8aa6), /* Direct Drive HP Amp control */
4203 {}
4204 };
Kailang Yange69e7e02016-05-30 15:58:28 +08004205 static struct coef_fw coef0256[] = {
4206 WRITE_COEF(0x1b, 0x0c4b), /* LDO and MISC control */
Kailang Yang717f43d2019-05-31 17:16:53 +08004207 WRITE_COEF(0x45, 0xd089), /* UAJ function set to menual mode */
4208 WRITE_COEF(0x06, 0x6104), /* Set MIC2 Vref gate with HP */
4209 WRITE_COEFEX(0x57, 0x03, 0x09a3), /* Direct Drive HP Amp control */
4210 UPDATE_COEFEX(0x57, 0x05, 1<<14, 0), /* Direct Drive HP Amp control(Set to verb control)*/
Kailang Yange69e7e02016-05-30 15:58:28 +08004211 {}
4212 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004213 static struct coef_fw coef0233[] = {
4214 WRITE_COEF(0x1b, 0x0c0b),
4215 WRITE_COEF(0x45, 0xc429),
4216 UPDATE_COEF(0x35, 0x4000, 0),
4217 WRITE_COEF(0x06, 0x2104),
4218 WRITE_COEF(0x1a, 0x0001),
4219 WRITE_COEF(0x26, 0x0004),
4220 WRITE_COEF(0x32, 0x42a3),
4221 {}
4222 };
Kailang Yangf3b70332015-04-08 15:01:17 +08004223 static struct coef_fw coef0288[] = {
4224 UPDATE_COEF(0x4f, 0xfcc0, 0xc400),
4225 UPDATE_COEF(0x50, 0x2000, 0x2000),
4226 UPDATE_COEF(0x56, 0x0006, 0x0006),
4227 UPDATE_COEF(0x66, 0x0008, 0),
4228 UPDATE_COEF(0x67, 0x2000, 0),
4229 {}
4230 };
Kailang Yang89542932017-07-17 15:03:43 +08004231 static struct coef_fw coef0298[] = {
4232 UPDATE_COEF(0x19, 0x1300, 0x0300),
4233 {}
4234 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004235 static struct coef_fw coef0292[] = {
4236 WRITE_COEF(0x76, 0x000e),
4237 WRITE_COEF(0x6c, 0x2400),
4238 WRITE_COEF(0x18, 0x7308),
4239 WRITE_COEF(0x6b, 0xc429),
4240 {}
4241 };
4242 static struct coef_fw coef0293[] = {
4243 UPDATE_COEF(0x10, 7<<8, 6<<8), /* SET Line1 JD to 0 */
4244 UPDATE_COEFEX(0x57, 0x05, 1<<15|1<<13, 0x0), /* SET charge pump by verb */
4245 UPDATE_COEFEX(0x57, 0x03, 1<<10, 1<<10), /* SET EN_OSW to 1 */
4246 UPDATE_COEF(0x1a, 1<<3, 1<<3), /* Combo JD gating with LINE1-VREFO */
4247 WRITE_COEF(0x45, 0xc429), /* Set to TRS type */
4248 UPDATE_COEF(0x4a, 0x000f, 0x000e), /* Combo Jack auto detect */
4249 {}
4250 };
4251 static struct coef_fw coef0668[] = {
4252 WRITE_COEF(0x15, 0x0d40),
4253 WRITE_COEF(0xb7, 0x802b),
4254 {}
4255 };
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004256 static struct coef_fw coef0225[] = {
Kailang Yang5a367672017-07-21 15:23:53 +08004257 UPDATE_COEF(0x63, 3<<14, 0),
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004258 {}
4259 };
Kailang Yang71683c32017-06-20 16:33:50 +08004260 static struct coef_fw coef0274[] = {
4261 UPDATE_COEF(0x4a, 0x0100, 0),
4262 UPDATE_COEFEX(0x57, 0x05, 0x4000, 0),
4263 UPDATE_COEF(0x6b, 0xf000, 0x5000),
4264 UPDATE_COEF(0x4a, 0x0010, 0),
4265 UPDATE_COEF(0x4a, 0x0c00, 0x0c00),
4266 WRITE_COEF(0x45, 0x5289),
4267 UPDATE_COEF(0x4a, 0x0c00, 0),
4268 {}
4269 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004270
Takashi Iwai7639a062015-03-03 10:07:24 +01004271 switch (codec->core.vendor_id) {
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004272 case 0x10ec0255:
Kailang Yange69e7e02016-05-30 15:58:28 +08004273 alc_process_coef_fw(codec, coef0255);
4274 break;
Kailang Yang736f20a2017-10-20 15:06:34 +08004275 case 0x10ec0236:
Kailang Yang7081adf2015-03-30 17:05:37 +08004276 case 0x10ec0256:
Kailang Yange69e7e02016-05-30 15:58:28 +08004277 alc_process_coef_fw(codec, coef0256);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004278 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004279 case 0x10ec0234:
4280 case 0x10ec0274:
4281 case 0x10ec0294:
4282 alc_process_coef_fw(codec, coef0274);
4283 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004284 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004285 case 0x10ec0283:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004286 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02004287 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004288 case 0x10ec0286:
4289 case 0x10ec0288:
Kailang Yang89542932017-07-17 15:03:43 +08004290 alc_process_coef_fw(codec, coef0288);
4291 break;
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004292 case 0x10ec0298:
Kailang Yang89542932017-07-17 15:03:43 +08004293 alc_process_coef_fw(codec, coef0298);
Kailang Yangf3b70332015-04-08 15:01:17 +08004294 alc_process_coef_fw(codec, coef0288);
4295 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004296 case 0x10ec0292:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004297 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02004298 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004299 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004300 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004301 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004302 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004303 alc_process_coef_fw(codec, coef0668);
David Henningsson73bdd592013-04-15 15:44:14 +02004304 break;
Kailang Yangc2b691e2018-01-17 15:22:55 +08004305 case 0x10ec0215:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004306 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004307 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08004308 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004309 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08004310 case 0x10ec0299:
Kailang Yang4d4b0c52019-01-09 16:23:37 +08004311 alc_process_coef_fw(codec, alc225_pre_hsmode);
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004312 alc_process_coef_fw(codec, coef0225);
4313 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08004314 case 0x10ec0867:
4315 alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
4316 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004317 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01004318 codec_dbg(codec, "Headset jack set to unplugged mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02004319}
4320
4321
4322static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin,
4323 hda_nid_t mic_pin)
4324{
Takashi Iwai54db6c32014-08-18 15:11:19 +02004325 static struct coef_fw coef0255[] = {
4326 WRITE_COEFEX(0x57, 0x03, 0x8aa6),
4327 WRITE_COEF(0x06, 0x6100), /* Set MIC2 Vref gate to normal */
4328 {}
4329 };
Kailang Yang717f43d2019-05-31 17:16:53 +08004330 static struct coef_fw coef0256[] = {
4331 UPDATE_COEFEX(0x57, 0x05, 1<<14, 1<<14), /* Direct Drive HP Amp control(Set to verb control)*/
4332 WRITE_COEFEX(0x57, 0x03, 0x09a3),
4333 WRITE_COEF(0x06, 0x6100), /* Set MIC2 Vref gate to normal */
4334 {}
4335 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004336 static struct coef_fw coef0233[] = {
4337 UPDATE_COEF(0x35, 0, 1<<14),
4338 WRITE_COEF(0x06, 0x2100),
4339 WRITE_COEF(0x1a, 0x0021),
4340 WRITE_COEF(0x26, 0x008c),
4341 {}
4342 };
Kailang Yangf3b70332015-04-08 15:01:17 +08004343 static struct coef_fw coef0288[] = {
Kailang Yang89542932017-07-17 15:03:43 +08004344 UPDATE_COEF(0x4f, 0x00c0, 0),
Kailang Yangf3b70332015-04-08 15:01:17 +08004345 UPDATE_COEF(0x50, 0x2000, 0),
4346 UPDATE_COEF(0x56, 0x0006, 0),
4347 UPDATE_COEF(0x4f, 0xfcc0, 0xc400),
4348 UPDATE_COEF(0x66, 0x0008, 0x0008),
4349 UPDATE_COEF(0x67, 0x2000, 0x2000),
4350 {}
4351 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004352 static struct coef_fw coef0292[] = {
4353 WRITE_COEF(0x19, 0xa208),
4354 WRITE_COEF(0x2e, 0xacf0),
4355 {}
4356 };
4357 static struct coef_fw coef0293[] = {
4358 UPDATE_COEFEX(0x57, 0x05, 0, 1<<15|1<<13), /* SET charge pump by verb */
4359 UPDATE_COEFEX(0x57, 0x03, 1<<10, 0), /* SET EN_OSW to 0 */
4360 UPDATE_COEF(0x1a, 1<<3, 0), /* Combo JD gating without LINE1-VREFO */
4361 {}
4362 };
4363 static struct coef_fw coef0688[] = {
4364 WRITE_COEF(0xb7, 0x802b),
4365 WRITE_COEF(0xb5, 0x1040),
4366 UPDATE_COEF(0xc3, 0, 1<<12),
4367 {}
4368 };
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004369 static struct coef_fw coef0225[] = {
4370 UPDATE_COEFEX(0x57, 0x05, 1<<14, 1<<14),
4371 UPDATE_COEF(0x4a, 3<<4, 2<<4),
4372 UPDATE_COEF(0x63, 3<<14, 0),
4373 {}
4374 };
Kailang Yang71683c32017-06-20 16:33:50 +08004375 static struct coef_fw coef0274[] = {
4376 UPDATE_COEFEX(0x57, 0x05, 0x4000, 0x4000),
4377 UPDATE_COEF(0x4a, 0x0010, 0),
4378 UPDATE_COEF(0x6b, 0xf000, 0),
4379 {}
4380 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004381
Takashi Iwai7639a062015-03-03 10:07:24 +01004382 switch (codec->core.vendor_id) {
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004383 case 0x10ec0255:
4384 alc_write_coef_idx(codec, 0x45, 0xc489);
4385 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02004386 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004387 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4388 break;
Kailang Yang717f43d2019-05-31 17:16:53 +08004389 case 0x10ec0236:
4390 case 0x10ec0256:
4391 alc_write_coef_idx(codec, 0x45, 0xc489);
4392 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4393 alc_process_coef_fw(codec, coef0256);
4394 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4395 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004396 case 0x10ec0234:
4397 case 0x10ec0274:
4398 case 0x10ec0294:
4399 alc_write_coef_idx(codec, 0x45, 0x4689);
4400 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4401 alc_process_coef_fw(codec, coef0274);
4402 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4403 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004404 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004405 case 0x10ec0283:
4406 alc_write_coef_idx(codec, 0x45, 0xc429);
4407 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02004408 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02004409 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4410 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004411 case 0x10ec0286:
4412 case 0x10ec0288:
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004413 case 0x10ec0298:
Kailang Yangf3b70332015-04-08 15:01:17 +08004414 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4415 alc_process_coef_fw(codec, coef0288);
4416 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4417 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004418 case 0x10ec0292:
4419 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02004420 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02004421 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004422 case 0x10ec0293:
4423 /* Set to TRS mode */
4424 alc_write_coef_idx(codec, 0x45, 0xc429);
4425 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02004426 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004427 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4428 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08004429 case 0x10ec0867:
4430 alc_update_coefex_idx(codec, 0x57, 0x5, 0, 1<<14);
4431 /* fallthru */
Kailang Yang9eb5d0e2017-01-17 15:40:25 +08004432 case 0x10ec0221:
David Henningsson1f8b46c2015-05-12 14:38:15 +02004433 case 0x10ec0662:
4434 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4435 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4436 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004437 case 0x10ec0668:
4438 alc_write_coef_idx(codec, 0x11, 0x0001);
4439 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02004440 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02004441 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4442 break;
Kailang Yangc2b691e2018-01-17 15:22:55 +08004443 case 0x10ec0215:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004444 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004445 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08004446 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004447 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08004448 case 0x10ec0299:
Kailang Yang5a367672017-07-21 15:23:53 +08004449 alc_process_coef_fw(codec, alc225_pre_hsmode);
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004450 alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x31<<10);
4451 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4452 alc_process_coef_fw(codec, coef0225);
4453 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4454 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004455 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01004456 codec_dbg(codec, "Headset jack set to mic-in mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02004457}
4458
4459static void alc_headset_mode_default(struct hda_codec *codec)
4460{
David Henningsson2ae95572016-02-25 09:37:05 +01004461 static struct coef_fw coef0225[] = {
Kailang Yang5a367672017-07-21 15:23:53 +08004462 UPDATE_COEF(0x45, 0x3f<<10, 0x30<<10),
4463 UPDATE_COEF(0x45, 0x3f<<10, 0x31<<10),
4464 UPDATE_COEF(0x49, 3<<8, 0<<8),
4465 UPDATE_COEF(0x4a, 3<<4, 3<<4),
4466 UPDATE_COEF(0x63, 3<<14, 0),
4467 UPDATE_COEF(0x67, 0xf000, 0x3000),
David Henningsson2ae95572016-02-25 09:37:05 +01004468 {}
4469 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004470 static struct coef_fw coef0255[] = {
4471 WRITE_COEF(0x45, 0xc089),
4472 WRITE_COEF(0x45, 0xc489),
4473 WRITE_COEFEX(0x57, 0x03, 0x8ea6),
4474 WRITE_COEF(0x49, 0x0049),
4475 {}
4476 };
Kailang Yang717f43d2019-05-31 17:16:53 +08004477 static struct coef_fw coef0256[] = {
4478 WRITE_COEF(0x45, 0xc489),
4479 WRITE_COEFEX(0x57, 0x03, 0x0da3),
4480 WRITE_COEF(0x49, 0x0049),
4481 UPDATE_COEFEX(0x57, 0x05, 1<<14, 0), /* Direct Drive HP Amp control(Set to verb control)*/
4482 WRITE_COEF(0x06, 0x6100),
4483 {}
4484 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004485 static struct coef_fw coef0233[] = {
4486 WRITE_COEF(0x06, 0x2100),
4487 WRITE_COEF(0x32, 0x4ea3),
4488 {}
4489 };
Kailang Yangf3b70332015-04-08 15:01:17 +08004490 static struct coef_fw coef0288[] = {
4491 UPDATE_COEF(0x4f, 0xfcc0, 0xc400), /* Set to TRS type */
4492 UPDATE_COEF(0x50, 0x2000, 0x2000),
4493 UPDATE_COEF(0x56, 0x0006, 0x0006),
4494 UPDATE_COEF(0x66, 0x0008, 0),
4495 UPDATE_COEF(0x67, 0x2000, 0),
4496 {}
4497 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004498 static struct coef_fw coef0292[] = {
4499 WRITE_COEF(0x76, 0x000e),
4500 WRITE_COEF(0x6c, 0x2400),
4501 WRITE_COEF(0x6b, 0xc429),
4502 WRITE_COEF(0x18, 0x7308),
4503 {}
4504 };
4505 static struct coef_fw coef0293[] = {
4506 UPDATE_COEF(0x4a, 0x000f, 0x000e), /* Combo Jack auto detect */
4507 WRITE_COEF(0x45, 0xC429), /* Set to TRS type */
4508 UPDATE_COEF(0x1a, 1<<3, 0), /* Combo JD gating without LINE1-VREFO */
4509 {}
4510 };
4511 static struct coef_fw coef0688[] = {
4512 WRITE_COEF(0x11, 0x0041),
4513 WRITE_COEF(0x15, 0x0d40),
4514 WRITE_COEF(0xb7, 0x802b),
4515 {}
4516 };
Kailang Yang71683c32017-06-20 16:33:50 +08004517 static struct coef_fw coef0274[] = {
4518 WRITE_COEF(0x45, 0x4289),
4519 UPDATE_COEF(0x4a, 0x0010, 0x0010),
4520 UPDATE_COEF(0x6b, 0x0f00, 0),
4521 UPDATE_COEF(0x49, 0x0300, 0x0300),
4522 {}
4523 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004524
Takashi Iwai7639a062015-03-03 10:07:24 +01004525 switch (codec->core.vendor_id) {
Kailang Yangc2b691e2018-01-17 15:22:55 +08004526 case 0x10ec0215:
David Henningsson2ae95572016-02-25 09:37:05 +01004527 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004528 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08004529 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004530 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08004531 case 0x10ec0299:
Kailang Yang5a367672017-07-21 15:23:53 +08004532 alc_process_coef_fw(codec, alc225_pre_hsmode);
David Henningsson2ae95572016-02-25 09:37:05 +01004533 alc_process_coef_fw(codec, coef0225);
4534 break;
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004535 case 0x10ec0255:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004536 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004537 break;
Kailang Yang717f43d2019-05-31 17:16:53 +08004538 case 0x10ec0236:
4539 case 0x10ec0256:
4540 alc_write_coef_idx(codec, 0x1b, 0x0e4b);
4541 alc_write_coef_idx(codec, 0x45, 0xc089);
4542 msleep(50);
4543 alc_process_coef_fw(codec, coef0256);
4544 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004545 case 0x10ec0234:
4546 case 0x10ec0274:
4547 case 0x10ec0294:
4548 alc_process_coef_fw(codec, coef0274);
4549 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004550 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004551 case 0x10ec0283:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004552 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02004553 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004554 case 0x10ec0286:
4555 case 0x10ec0288:
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004556 case 0x10ec0298:
Kailang Yangf3b70332015-04-08 15:01:17 +08004557 alc_process_coef_fw(codec, coef0288);
4558 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004559 case 0x10ec0292:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004560 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02004561 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004562 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004563 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004564 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004565 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004566 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02004567 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08004568 case 0x10ec0867:
4569 alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
4570 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004571 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01004572 codec_dbg(codec, "Headset jack set to headphone (default) mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02004573}
4574
4575/* Iphone type */
4576static void alc_headset_mode_ctia(struct hda_codec *codec)
4577{
Kailang Yang89542932017-07-17 15:03:43 +08004578 int val;
4579
Takashi Iwai54db6c32014-08-18 15:11:19 +02004580 static struct coef_fw coef0255[] = {
4581 WRITE_COEF(0x45, 0xd489), /* Set to CTIA type */
4582 WRITE_COEF(0x1b, 0x0c2b),
4583 WRITE_COEFEX(0x57, 0x03, 0x8ea6),
4584 {}
4585 };
Kailang Yange69e7e02016-05-30 15:58:28 +08004586 static struct coef_fw coef0256[] = {
4587 WRITE_COEF(0x45, 0xd489), /* Set to CTIA type */
Kailang Yang717f43d2019-05-31 17:16:53 +08004588 WRITE_COEF(0x1b, 0x0e6b),
Kailang Yange69e7e02016-05-30 15:58:28 +08004589 {}
4590 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004591 static struct coef_fw coef0233[] = {
4592 WRITE_COEF(0x45, 0xd429),
4593 WRITE_COEF(0x1b, 0x0c2b),
4594 WRITE_COEF(0x32, 0x4ea3),
4595 {}
4596 };
Kailang Yangf3b70332015-04-08 15:01:17 +08004597 static struct coef_fw coef0288[] = {
4598 UPDATE_COEF(0x50, 0x2000, 0x2000),
4599 UPDATE_COEF(0x56, 0x0006, 0x0006),
4600 UPDATE_COEF(0x66, 0x0008, 0),
4601 UPDATE_COEF(0x67, 0x2000, 0),
4602 {}
4603 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004604 static struct coef_fw coef0292[] = {
4605 WRITE_COEF(0x6b, 0xd429),
4606 WRITE_COEF(0x76, 0x0008),
4607 WRITE_COEF(0x18, 0x7388),
4608 {}
4609 };
4610 static struct coef_fw coef0293[] = {
4611 WRITE_COEF(0x45, 0xd429), /* Set to ctia type */
4612 UPDATE_COEF(0x10, 7<<8, 7<<8), /* SET Line1 JD to 1 */
4613 {}
4614 };
4615 static struct coef_fw coef0688[] = {
4616 WRITE_COEF(0x11, 0x0001),
4617 WRITE_COEF(0x15, 0x0d60),
4618 WRITE_COEF(0xc3, 0x0000),
4619 {}
4620 };
Kailang Yang5a367672017-07-21 15:23:53 +08004621 static struct coef_fw coef0225_1[] = {
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004622 UPDATE_COEF(0x45, 0x3f<<10, 0x35<<10),
Kailang Yang5a367672017-07-21 15:23:53 +08004623 UPDATE_COEF(0x63, 3<<14, 2<<14),
4624 {}
4625 };
4626 static struct coef_fw coef0225_2[] = {
4627 UPDATE_COEF(0x45, 0x3f<<10, 0x35<<10),
4628 UPDATE_COEF(0x63, 3<<14, 1<<14),
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004629 {}
4630 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004631
Takashi Iwai7639a062015-03-03 10:07:24 +01004632 switch (codec->core.vendor_id) {
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004633 case 0x10ec0255:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004634 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004635 break;
Kailang Yang736f20a2017-10-20 15:06:34 +08004636 case 0x10ec0236:
Kailang Yange69e7e02016-05-30 15:58:28 +08004637 case 0x10ec0256:
4638 alc_process_coef_fw(codec, coef0256);
4639 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004640 case 0x10ec0234:
4641 case 0x10ec0274:
4642 case 0x10ec0294:
4643 alc_write_coef_idx(codec, 0x45, 0xd689);
4644 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004645 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004646 case 0x10ec0283:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004647 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02004648 break;
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004649 case 0x10ec0298:
Kailang Yang89542932017-07-17 15:03:43 +08004650 val = alc_read_coef_idx(codec, 0x50);
4651 if (val & (1 << 12)) {
4652 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0020);
4653 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400);
4654 msleep(300);
4655 } else {
4656 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0010);
4657 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400);
4658 msleep(300);
4659 }
4660 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004661 case 0x10ec0286:
4662 case 0x10ec0288:
4663 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400);
4664 msleep(300);
4665 alc_process_coef_fw(codec, coef0288);
4666 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004667 case 0x10ec0292:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004668 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02004669 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004670 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004671 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004672 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004673 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004674 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02004675 break;
Kailang Yangc2b691e2018-01-17 15:22:55 +08004676 case 0x10ec0215:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004677 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004678 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08004679 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004680 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08004681 case 0x10ec0299:
Kailang Yang5a367672017-07-21 15:23:53 +08004682 val = alc_read_coef_idx(codec, 0x45);
4683 if (val & (1 << 9))
4684 alc_process_coef_fw(codec, coef0225_2);
4685 else
4686 alc_process_coef_fw(codec, coef0225_1);
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004687 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08004688 case 0x10ec0867:
4689 alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
4690 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004691 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01004692 codec_dbg(codec, "Headset jack set to iPhone-style headset mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02004693}
4694
4695/* Nokia type */
4696static void alc_headset_mode_omtp(struct hda_codec *codec)
4697{
Takashi Iwai54db6c32014-08-18 15:11:19 +02004698 static struct coef_fw coef0255[] = {
4699 WRITE_COEF(0x45, 0xe489), /* Set to OMTP Type */
4700 WRITE_COEF(0x1b, 0x0c2b),
4701 WRITE_COEFEX(0x57, 0x03, 0x8ea6),
4702 {}
4703 };
Kailang Yange69e7e02016-05-30 15:58:28 +08004704 static struct coef_fw coef0256[] = {
4705 WRITE_COEF(0x45, 0xe489), /* Set to OMTP Type */
Kailang Yang717f43d2019-05-31 17:16:53 +08004706 WRITE_COEF(0x1b, 0x0e6b),
Kailang Yange69e7e02016-05-30 15:58:28 +08004707 {}
4708 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004709 static struct coef_fw coef0233[] = {
4710 WRITE_COEF(0x45, 0xe429),
4711 WRITE_COEF(0x1b, 0x0c2b),
4712 WRITE_COEF(0x32, 0x4ea3),
4713 {}
4714 };
Kailang Yangf3b70332015-04-08 15:01:17 +08004715 static struct coef_fw coef0288[] = {
4716 UPDATE_COEF(0x50, 0x2000, 0x2000),
4717 UPDATE_COEF(0x56, 0x0006, 0x0006),
4718 UPDATE_COEF(0x66, 0x0008, 0),
4719 UPDATE_COEF(0x67, 0x2000, 0),
4720 {}
4721 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004722 static struct coef_fw coef0292[] = {
4723 WRITE_COEF(0x6b, 0xe429),
4724 WRITE_COEF(0x76, 0x0008),
4725 WRITE_COEF(0x18, 0x7388),
4726 {}
4727 };
4728 static struct coef_fw coef0293[] = {
4729 WRITE_COEF(0x45, 0xe429), /* Set to omtp type */
4730 UPDATE_COEF(0x10, 7<<8, 7<<8), /* SET Line1 JD to 1 */
4731 {}
4732 };
4733 static struct coef_fw coef0688[] = {
4734 WRITE_COEF(0x11, 0x0001),
4735 WRITE_COEF(0x15, 0x0d50),
4736 WRITE_COEF(0xc3, 0x0000),
4737 {}
4738 };
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004739 static struct coef_fw coef0225[] = {
4740 UPDATE_COEF(0x45, 0x3f<<10, 0x39<<10),
Kailang Yang5a367672017-07-21 15:23:53 +08004741 UPDATE_COEF(0x63, 3<<14, 2<<14),
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004742 {}
4743 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004744
Takashi Iwai7639a062015-03-03 10:07:24 +01004745 switch (codec->core.vendor_id) {
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004746 case 0x10ec0255:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004747 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004748 break;
Kailang Yang736f20a2017-10-20 15:06:34 +08004749 case 0x10ec0236:
Kailang Yange69e7e02016-05-30 15:58:28 +08004750 case 0x10ec0256:
4751 alc_process_coef_fw(codec, coef0256);
4752 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004753 case 0x10ec0234:
4754 case 0x10ec0274:
4755 case 0x10ec0294:
4756 alc_write_coef_idx(codec, 0x45, 0xe689);
4757 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004758 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004759 case 0x10ec0283:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004760 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02004761 break;
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004762 case 0x10ec0298:
4763 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0010);/* Headset output enable */
Kailang Yang89542932017-07-17 15:03:43 +08004764 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xe400);
4765 msleep(300);
4766 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004767 case 0x10ec0286:
4768 case 0x10ec0288:
4769 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xe400);
4770 msleep(300);
4771 alc_process_coef_fw(codec, coef0288);
4772 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004773 case 0x10ec0292:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004774 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02004775 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004776 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004777 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004778 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004779 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004780 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02004781 break;
Kailang Yangc2b691e2018-01-17 15:22:55 +08004782 case 0x10ec0215:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004783 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004784 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08004785 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004786 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08004787 case 0x10ec0299:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004788 alc_process_coef_fw(codec, coef0225);
4789 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004790 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01004791 codec_dbg(codec, "Headset jack set to Nokia-style headset mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02004792}
4793
4794static void alc_determine_headset_type(struct hda_codec *codec)
4795{
4796 int val;
4797 bool is_ctia = false;
4798 struct alc_spec *spec = codec->spec;
Takashi Iwai54db6c32014-08-18 15:11:19 +02004799 static struct coef_fw coef0255[] = {
4800 WRITE_COEF(0x45, 0xd089), /* combo jack auto switch control(Check type)*/
4801 WRITE_COEF(0x49, 0x0149), /* combo jack auto switch control(Vref
4802 conteol) */
4803 {}
4804 };
Kailang Yangf3b70332015-04-08 15:01:17 +08004805 static struct coef_fw coef0288[] = {
4806 UPDATE_COEF(0x4f, 0xfcc0, 0xd400), /* Check Type */
4807 {}
4808 };
Kailang Yang89542932017-07-17 15:03:43 +08004809 static struct coef_fw coef0298[] = {
4810 UPDATE_COEF(0x50, 0x2000, 0x2000),
4811 UPDATE_COEF(0x56, 0x0006, 0x0006),
4812 UPDATE_COEF(0x66, 0x0008, 0),
4813 UPDATE_COEF(0x67, 0x2000, 0),
4814 UPDATE_COEF(0x19, 0x1300, 0x1300),
4815 {}
4816 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004817 static struct coef_fw coef0293[] = {
4818 UPDATE_COEF(0x4a, 0x000f, 0x0008), /* Combo Jack auto detect */
4819 WRITE_COEF(0x45, 0xD429), /* Set to ctia type */
4820 {}
4821 };
4822 static struct coef_fw coef0688[] = {
4823 WRITE_COEF(0x11, 0x0001),
4824 WRITE_COEF(0xb7, 0x802b),
4825 WRITE_COEF(0x15, 0x0d60),
4826 WRITE_COEF(0xc3, 0x0c00),
4827 {}
4828 };
Kailang Yang71683c32017-06-20 16:33:50 +08004829 static struct coef_fw coef0274[] = {
4830 UPDATE_COEF(0x4a, 0x0010, 0),
4831 UPDATE_COEF(0x4a, 0x8000, 0),
4832 WRITE_COEF(0x45, 0xd289),
4833 UPDATE_COEF(0x49, 0x0300, 0x0300),
4834 {}
4835 };
David Henningsson73bdd592013-04-15 15:44:14 +02004836
Takashi Iwai7639a062015-03-03 10:07:24 +01004837 switch (codec->core.vendor_id) {
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004838 case 0x10ec0255:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004839 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004840 msleep(300);
4841 val = alc_read_coef_idx(codec, 0x46);
4842 is_ctia = (val & 0x0070) == 0x0070;
4843 break;
Kailang Yang717f43d2019-05-31 17:16:53 +08004844 case 0x10ec0236:
4845 case 0x10ec0256:
4846 alc_write_coef_idx(codec, 0x1b, 0x0e4b);
4847 alc_write_coef_idx(codec, 0x06, 0x6104);
4848 alc_write_coefex_idx(codec, 0x57, 0x3, 0x09a3);
4849
4850 snd_hda_codec_write(codec, 0x21, 0,
4851 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
4852 msleep(80);
4853 snd_hda_codec_write(codec, 0x21, 0,
4854 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
4855
4856 alc_process_coef_fw(codec, coef0255);
4857 msleep(300);
4858 val = alc_read_coef_idx(codec, 0x46);
4859 is_ctia = (val & 0x0070) == 0x0070;
4860
4861 alc_write_coefex_idx(codec, 0x57, 0x3, 0x0da3);
4862 alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
4863
4864 snd_hda_codec_write(codec, 0x21, 0,
4865 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
4866 msleep(80);
4867 snd_hda_codec_write(codec, 0x21, 0,
4868 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
4869 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004870 case 0x10ec0234:
4871 case 0x10ec0274:
4872 case 0x10ec0294:
4873 alc_process_coef_fw(codec, coef0274);
4874 msleep(80);
4875 val = alc_read_coef_idx(codec, 0x46);
4876 is_ctia = (val & 0x00f0) == 0x00f0;
4877 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004878 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004879 case 0x10ec0283:
4880 alc_write_coef_idx(codec, 0x45, 0xd029);
4881 msleep(300);
4882 val = alc_read_coef_idx(codec, 0x46);
4883 is_ctia = (val & 0x0070) == 0x0070;
4884 break;
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004885 case 0x10ec0298:
Kailang Yang89542932017-07-17 15:03:43 +08004886 snd_hda_codec_write(codec, 0x21, 0,
4887 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
4888 msleep(100);
4889 snd_hda_codec_write(codec, 0x21, 0,
4890 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
4891 msleep(200);
4892
4893 val = alc_read_coef_idx(codec, 0x50);
4894 if (val & (1 << 12)) {
4895 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0020);
4896 alc_process_coef_fw(codec, coef0288);
4897 msleep(350);
4898 val = alc_read_coef_idx(codec, 0x50);
4899 is_ctia = (val & 0x0070) == 0x0070;
4900 } else {
4901 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0010);
4902 alc_process_coef_fw(codec, coef0288);
4903 msleep(350);
4904 val = alc_read_coef_idx(codec, 0x50);
4905 is_ctia = (val & 0x0070) == 0x0070;
4906 }
4907 alc_process_coef_fw(codec, coef0298);
4908 snd_hda_codec_write(codec, 0x21, 0,
4909 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP);
4910 msleep(75);
4911 snd_hda_codec_write(codec, 0x21, 0,
4912 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
4913 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004914 case 0x10ec0286:
4915 case 0x10ec0288:
4916 alc_process_coef_fw(codec, coef0288);
4917 msleep(350);
4918 val = alc_read_coef_idx(codec, 0x50);
4919 is_ctia = (val & 0x0070) == 0x0070;
4920 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004921 case 0x10ec0292:
4922 alc_write_coef_idx(codec, 0x6b, 0xd429);
4923 msleep(300);
4924 val = alc_read_coef_idx(codec, 0x6c);
4925 is_ctia = (val & 0x001c) == 0x001c;
4926 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004927 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004928 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004929 msleep(300);
4930 val = alc_read_coef_idx(codec, 0x46);
4931 is_ctia = (val & 0x0070) == 0x0070;
4932 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004933 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004934 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02004935 msleep(300);
4936 val = alc_read_coef_idx(codec, 0xbe);
4937 is_ctia = (val & 0x1c02) == 0x1c02;
4938 break;
Kailang Yangc2b691e2018-01-17 15:22:55 +08004939 case 0x10ec0215:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004940 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004941 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08004942 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004943 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08004944 case 0x10ec0299:
Kailang Yangda911b12018-01-05 16:50:08 +08004945 snd_hda_codec_write(codec, 0x21, 0,
4946 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
4947 msleep(80);
4948 snd_hda_codec_write(codec, 0x21, 0,
4949 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
4950
Kailang Yang5a367672017-07-21 15:23:53 +08004951 alc_process_coef_fw(codec, alc225_pre_hsmode);
4952 alc_update_coef_idx(codec, 0x67, 0xf000, 0x1000);
4953 val = alc_read_coef_idx(codec, 0x45);
4954 if (val & (1 << 9)) {
4955 alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x34<<10);
4956 alc_update_coef_idx(codec, 0x49, 3<<8, 2<<8);
4957 msleep(800);
4958 val = alc_read_coef_idx(codec, 0x46);
4959 is_ctia = (val & 0x00f0) == 0x00f0;
4960 } else {
4961 alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x34<<10);
4962 alc_update_coef_idx(codec, 0x49, 3<<8, 1<<8);
4963 msleep(800);
4964 val = alc_read_coef_idx(codec, 0x46);
4965 is_ctia = (val & 0x00f0) == 0x00f0;
4966 }
4967 alc_update_coef_idx(codec, 0x4a, 7<<6, 7<<6);
4968 alc_update_coef_idx(codec, 0x4a, 3<<4, 3<<4);
4969 alc_update_coef_idx(codec, 0x67, 0xf000, 0x3000);
Kailang Yangda911b12018-01-05 16:50:08 +08004970
4971 snd_hda_codec_write(codec, 0x21, 0,
4972 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
4973 msleep(80);
4974 snd_hda_codec_write(codec, 0x21, 0,
4975 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004976 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08004977 case 0x10ec0867:
4978 is_ctia = true;
4979 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004980 }
4981
Takashi Iwai4e76a882014-02-25 12:21:03 +01004982 codec_dbg(codec, "Headset jack detected iPhone-style headset: %s\n",
David Henningsson73bdd592013-04-15 15:44:14 +02004983 is_ctia ? "yes" : "no");
4984 spec->current_headset_type = is_ctia ? ALC_HEADSET_TYPE_CTIA : ALC_HEADSET_TYPE_OMTP;
4985}
4986
4987static void alc_update_headset_mode(struct hda_codec *codec)
4988{
4989 struct alc_spec *spec = codec->spec;
4990
4991 hda_nid_t mux_pin = spec->gen.imux_pins[spec->gen.cur_mux[0]];
Takashi Iwai35a39f92019-02-01 11:19:50 +01004992 hda_nid_t hp_pin = alc_get_hp_pin(spec);
David Henningsson73bdd592013-04-15 15:44:14 +02004993
4994 int new_headset_mode;
4995
4996 if (!snd_hda_jack_detect(codec, hp_pin))
4997 new_headset_mode = ALC_HEADSET_MODE_UNPLUGGED;
4998 else if (mux_pin == spec->headset_mic_pin)
4999 new_headset_mode = ALC_HEADSET_MODE_HEADSET;
5000 else if (mux_pin == spec->headphone_mic_pin)
5001 new_headset_mode = ALC_HEADSET_MODE_MIC;
5002 else
5003 new_headset_mode = ALC_HEADSET_MODE_HEADPHONE;
5004
David Henningsson5959a6b2013-11-12 11:10:57 +01005005 if (new_headset_mode == spec->current_headset_mode) {
5006 snd_hda_gen_update_outputs(codec);
David Henningsson73bdd592013-04-15 15:44:14 +02005007 return;
David Henningsson5959a6b2013-11-12 11:10:57 +01005008 }
David Henningsson73bdd592013-04-15 15:44:14 +02005009
5010 switch (new_headset_mode) {
5011 case ALC_HEADSET_MODE_UNPLUGGED:
5012 alc_headset_mode_unplugged(codec);
Kailang Yangaeac1a02019-05-16 16:10:44 +08005013 spec->current_headset_mode = ALC_HEADSET_MODE_UNKNOWN;
5014 spec->current_headset_type = ALC_HEADSET_TYPE_UNKNOWN;
David Henningsson73bdd592013-04-15 15:44:14 +02005015 spec->gen.hp_jack_present = false;
5016 break;
5017 case ALC_HEADSET_MODE_HEADSET:
5018 if (spec->current_headset_type == ALC_HEADSET_TYPE_UNKNOWN)
5019 alc_determine_headset_type(codec);
5020 if (spec->current_headset_type == ALC_HEADSET_TYPE_CTIA)
5021 alc_headset_mode_ctia(codec);
5022 else if (spec->current_headset_type == ALC_HEADSET_TYPE_OMTP)
5023 alc_headset_mode_omtp(codec);
5024 spec->gen.hp_jack_present = true;
5025 break;
5026 case ALC_HEADSET_MODE_MIC:
5027 alc_headset_mode_mic_in(codec, hp_pin, spec->headphone_mic_pin);
5028 spec->gen.hp_jack_present = false;
5029 break;
5030 case ALC_HEADSET_MODE_HEADPHONE:
5031 alc_headset_mode_default(codec);
5032 spec->gen.hp_jack_present = true;
5033 break;
5034 }
5035 if (new_headset_mode != ALC_HEADSET_MODE_MIC) {
5036 snd_hda_set_pin_ctl_cache(codec, hp_pin,
5037 AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN);
David Henningsson1f8b46c2015-05-12 14:38:15 +02005038 if (spec->headphone_mic_pin && spec->headphone_mic_pin != hp_pin)
David Henningsson73bdd592013-04-15 15:44:14 +02005039 snd_hda_set_pin_ctl_cache(codec, spec->headphone_mic_pin,
5040 PIN_VREFHIZ);
5041 }
5042 spec->current_headset_mode = new_headset_mode;
5043
5044 snd_hda_gen_update_outputs(codec);
5045}
5046
5047static void alc_update_headset_mode_hook(struct hda_codec *codec,
Takashi Iwai7fe30712014-01-30 17:59:02 +01005048 struct snd_kcontrol *kcontrol,
5049 struct snd_ctl_elem_value *ucontrol)
David Henningsson73bdd592013-04-15 15:44:14 +02005050{
5051 alc_update_headset_mode(codec);
5052}
5053
Takashi Iwai1a4f69d2014-09-11 15:22:46 +02005054static void alc_update_headset_jack_cb(struct hda_codec *codec,
5055 struct hda_jack_callback *jack)
David Henningsson73bdd592013-04-15 15:44:14 +02005056{
David Henningsson73bdd592013-04-15 15:44:14 +02005057 snd_hda_gen_hp_automute(codec, jack);
5058}
5059
5060static void alc_probe_headset_mode(struct hda_codec *codec)
5061{
5062 int i;
5063 struct alc_spec *spec = codec->spec;
5064 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
5065
5066 /* Find mic pins */
5067 for (i = 0; i < cfg->num_inputs; i++) {
5068 if (cfg->inputs[i].is_headset_mic && !spec->headset_mic_pin)
5069 spec->headset_mic_pin = cfg->inputs[i].pin;
5070 if (cfg->inputs[i].is_headphone_mic && !spec->headphone_mic_pin)
5071 spec->headphone_mic_pin = cfg->inputs[i].pin;
5072 }
5073
Takashi Iwai0bed2aa2018-06-19 12:45:53 +02005074 WARN_ON(spec->gen.cap_sync_hook);
David Henningsson73bdd592013-04-15 15:44:14 +02005075 spec->gen.cap_sync_hook = alc_update_headset_mode_hook;
5076 spec->gen.automute_hook = alc_update_headset_mode;
5077 spec->gen.hp_automute_hook = alc_update_headset_jack_cb;
5078}
5079
5080static void alc_fixup_headset_mode(struct hda_codec *codec,
5081 const struct hda_fixup *fix, int action)
5082{
5083 struct alc_spec *spec = codec->spec;
5084
5085 switch (action) {
5086 case HDA_FIXUP_ACT_PRE_PROBE:
5087 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC | HDA_PINCFG_HEADPHONE_MIC;
5088 break;
5089 case HDA_FIXUP_ACT_PROBE:
5090 alc_probe_headset_mode(codec);
5091 break;
5092 case HDA_FIXUP_ACT_INIT:
Kailang Yangaeac1a02019-05-16 16:10:44 +08005093 if (is_s3_resume(codec) || is_s4_resume(codec)) {
5094 spec->current_headset_mode = ALC_HEADSET_MODE_UNKNOWN;
5095 spec->current_headset_type = ALC_HEADSET_TYPE_UNKNOWN;
5096 }
David Henningsson73bdd592013-04-15 15:44:14 +02005097 alc_update_headset_mode(codec);
5098 break;
5099 }
5100}
5101
5102static void alc_fixup_headset_mode_no_hp_mic(struct hda_codec *codec,
5103 const struct hda_fixup *fix, int action)
5104{
5105 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5106 struct alc_spec *spec = codec->spec;
5107 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
5108 }
5109 else
5110 alc_fixup_headset_mode(codec, fix, action);
5111}
5112
Kailang Yang31278992014-03-03 15:27:22 +08005113static void alc255_set_default_jack_type(struct hda_codec *codec)
5114{
5115 /* Set to iphone type */
Kailang Yange69e7e02016-05-30 15:58:28 +08005116 static struct coef_fw alc255fw[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02005117 WRITE_COEF(0x1b, 0x880b),
5118 WRITE_COEF(0x45, 0xd089),
5119 WRITE_COEF(0x1b, 0x080b),
5120 WRITE_COEF(0x46, 0x0004),
5121 WRITE_COEF(0x1b, 0x0c0b),
5122 {}
5123 };
Kailang Yange69e7e02016-05-30 15:58:28 +08005124 static struct coef_fw alc256fw[] = {
5125 WRITE_COEF(0x1b, 0x884b),
5126 WRITE_COEF(0x45, 0xd089),
5127 WRITE_COEF(0x1b, 0x084b),
5128 WRITE_COEF(0x46, 0x0004),
5129 WRITE_COEF(0x1b, 0x0c4b),
5130 {}
5131 };
5132 switch (codec->core.vendor_id) {
5133 case 0x10ec0255:
5134 alc_process_coef_fw(codec, alc255fw);
5135 break;
Kailang Yang736f20a2017-10-20 15:06:34 +08005136 case 0x10ec0236:
Kailang Yange69e7e02016-05-30 15:58:28 +08005137 case 0x10ec0256:
5138 alc_process_coef_fw(codec, alc256fw);
5139 break;
5140 }
Kailang Yang31278992014-03-03 15:27:22 +08005141 msleep(30);
5142}
5143
Kailang Yang9a22a8f52013-11-08 15:54:49 +08005144static void alc_fixup_headset_mode_alc255(struct hda_codec *codec,
5145 const struct hda_fixup *fix, int action)
5146{
5147 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Kailang Yang31278992014-03-03 15:27:22 +08005148 alc255_set_default_jack_type(codec);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08005149 }
5150 alc_fixup_headset_mode(codec, fix, action);
5151}
5152
Kailang Yang31278992014-03-03 15:27:22 +08005153static void alc_fixup_headset_mode_alc255_no_hp_mic(struct hda_codec *codec,
5154 const struct hda_fixup *fix, int action)
5155{
5156 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5157 struct alc_spec *spec = codec->spec;
5158 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
5159 alc255_set_default_jack_type(codec);
5160 }
5161 else
5162 alc_fixup_headset_mode(codec, fix, action);
5163}
5164
Kailang Yange1e62b92015-04-08 16:01:22 +08005165static void alc288_update_headset_jack_cb(struct hda_codec *codec,
5166 struct hda_jack_callback *jack)
5167{
5168 struct alc_spec *spec = codec->spec;
Kailang Yange1e62b92015-04-08 16:01:22 +08005169
5170 alc_update_headset_jack_cb(codec, jack);
5171 /* Headset Mic enable or disable, only for Dell Dino */
Takashi Iwaid44a6862018-06-19 23:04:03 +02005172 alc_update_gpio_data(codec, 0x40, spec->gen.hp_jack_present);
Kailang Yange1e62b92015-04-08 16:01:22 +08005173}
5174
5175static void alc_fixup_headset_mode_dell_alc288(struct hda_codec *codec,
5176 const struct hda_fixup *fix, int action)
5177{
5178 alc_fixup_headset_mode(codec, fix, action);
5179 if (action == HDA_FIXUP_ACT_PROBE) {
5180 struct alc_spec *spec = codec->spec;
Takashi Iwaid44a6862018-06-19 23:04:03 +02005181 /* toggled via hp_automute_hook */
5182 spec->gpio_mask |= 0x40;
5183 spec->gpio_dir |= 0x40;
Kailang Yange1e62b92015-04-08 16:01:22 +08005184 spec->gen.hp_automute_hook = alc288_update_headset_jack_cb;
5185 }
5186}
5187
Hui Wang493a52a2014-01-14 14:07:36 +08005188static void alc_fixup_auto_mute_via_amp(struct hda_codec *codec,
5189 const struct hda_fixup *fix, int action)
5190{
5191 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5192 struct alc_spec *spec = codec->spec;
5193 spec->gen.auto_mute_via_amp = 1;
5194 }
5195}
5196
Takashi Iwai9b745ab2014-03-07 08:37:19 +01005197static void alc_fixup_no_shutup(struct hda_codec *codec,
5198 const struct hda_fixup *fix, int action)
5199{
Takashi Iwaiefe55732018-06-15 11:55:02 +02005200 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai9b745ab2014-03-07 08:37:19 +01005201 struct alc_spec *spec = codec->spec;
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01005202 spec->no_shutup_pins = 1;
Takashi Iwai9b745ab2014-03-07 08:37:19 +01005203 }
5204}
5205
Gabriele Mazzotta5e6db662014-05-20 18:58:26 +02005206static void alc_fixup_disable_aamix(struct hda_codec *codec,
5207 const struct hda_fixup *fix, int action)
5208{
5209 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5210 struct alc_spec *spec = codec->spec;
5211 /* Disable AA-loopback as it causes white noise */
5212 spec->gen.mixer_nid = 0;
5213 }
5214}
5215
Takashi Iwai7f57d802015-09-24 17:36:51 +02005216/* fixup for Thinkpad docks: add dock pins, avoid HP parser fixup */
5217static void alc_fixup_tpt440_dock(struct hda_codec *codec,
5218 const struct hda_fixup *fix, int action)
5219{
5220 static const struct hda_pintbl pincfgs[] = {
5221 { 0x16, 0x21211010 }, /* dock headphone */
5222 { 0x19, 0x21a11010 }, /* dock mic */
5223 { }
5224 };
5225 struct alc_spec *spec = codec->spec;
5226
5227 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Hui Wang871b9062019-08-14 12:09:08 +08005228 spec->reboot_notify = snd_hda_gen_reboot_notify; /* reduce noise */
Takashi Iwai7f57d802015-09-24 17:36:51 +02005229 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
5230 codec->power_save_node = 0; /* avoid click noises */
5231 snd_hda_apply_pincfgs(codec, pincfgs);
5232 }
5233}
5234
Kailang Yang61fcf8e2018-02-02 15:26:46 +08005235static void alc_fixup_tpt470_dock(struct hda_codec *codec,
5236 const struct hda_fixup *fix, int action)
5237{
5238 static const struct hda_pintbl pincfgs[] = {
5239 { 0x17, 0x21211010 }, /* dock headphone */
5240 { 0x19, 0x21a11010 }, /* dock mic */
5241 { }
5242 };
Takashi Iwai54947cd2018-12-03 10:44:15 +01005243 /* Assure the speaker pin to be coupled with DAC NID 0x03; otherwise
5244 * the speaker output becomes too low by some reason on Thinkpads with
5245 * ALC298 codec
5246 */
5247 static hda_nid_t preferred_pairs[] = {
5248 0x14, 0x03, 0x17, 0x02, 0x21, 0x02,
5249 0
5250 };
Kailang Yang61fcf8e2018-02-02 15:26:46 +08005251 struct alc_spec *spec = codec->spec;
5252
5253 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai54947cd2018-12-03 10:44:15 +01005254 spec->gen.preferred_dacs = preferred_pairs;
Kailang Yang61fcf8e2018-02-02 15:26:46 +08005255 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
Takashi Iwai71db96d2018-02-26 15:36:38 +01005256 snd_hda_apply_pincfgs(codec, pincfgs);
5257 } else if (action == HDA_FIXUP_ACT_INIT) {
Kailang Yang61fcf8e2018-02-02 15:26:46 +08005258 /* Enable DOCK device */
5259 snd_hda_codec_write(codec, 0x17, 0,
5260 AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0);
5261 /* Enable DOCK device */
5262 snd_hda_codec_write(codec, 0x19, 0,
5263 AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0);
Kailang Yang61fcf8e2018-02-02 15:26:46 +08005264 }
5265}
5266
Gabriele Mazzotta9476d3692015-04-19 19:00:40 +02005267static void alc_shutup_dell_xps13(struct hda_codec *codec)
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02005268{
5269 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01005270 int hp_pin = alc_get_hp_pin(spec);
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02005271
Gabriele Mazzotta9476d3692015-04-19 19:00:40 +02005272 /* Prevent pop noises when headphones are plugged in */
5273 snd_hda_codec_write(codec, hp_pin, 0,
5274 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
5275 msleep(20);
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02005276}
5277
5278static void alc_fixup_dell_xps13(struct hda_codec *codec,
5279 const struct hda_fixup *fix, int action)
5280{
Takashi Iwai3e1b0c42015-04-27 10:43:22 +02005281 struct alc_spec *spec = codec->spec;
5282 struct hda_input_mux *imux = &spec->gen.input_mux;
5283 int i;
Gabriele Mazzottaf38663a2014-08-08 19:34:40 +02005284
Takashi Iwai3e1b0c42015-04-27 10:43:22 +02005285 switch (action) {
5286 case HDA_FIXUP_ACT_PRE_PROBE:
5287 /* mic pin 0x19 must be initialized with Vref Hi-Z, otherwise
5288 * it causes a click noise at start up
5289 */
5290 snd_hda_codec_set_pin_target(codec, 0x19, PIN_VREFHIZ);
Takashi Iwaiefe55732018-06-15 11:55:02 +02005291 spec->shutup = alc_shutup_dell_xps13;
Takashi Iwai3e1b0c42015-04-27 10:43:22 +02005292 break;
5293 case HDA_FIXUP_ACT_PROBE:
Gabriele Mazzottaf38663a2014-08-08 19:34:40 +02005294 /* Make the internal mic the default input source. */
5295 for (i = 0; i < imux->num_items; i++) {
5296 if (spec->gen.imux_pins[i] == 0x12) {
5297 spec->gen.cur_mux[0] = i;
5298 break;
5299 }
5300 }
Takashi Iwai3e1b0c42015-04-27 10:43:22 +02005301 break;
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02005302 }
5303}
5304
David Henningsson1f8b46c2015-05-12 14:38:15 +02005305static void alc_fixup_headset_mode_alc662(struct hda_codec *codec,
5306 const struct hda_fixup *fix, int action)
5307{
5308 struct alc_spec *spec = codec->spec;
5309
5310 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5311 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
5312 spec->gen.hp_mic = 1; /* Mic-in is same pin as headphone */
David Henningssonb40eda62015-05-28 09:40:23 +02005313
5314 /* Disable boost for mic-in permanently. (This code is only called
5315 from quirks that guarantee that the headphone is at NID 0x1b.) */
5316 snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000);
5317 snd_hda_override_wcaps(codec, 0x1b, get_wcaps(codec, 0x1b) & ~AC_WCAP_IN_AMP);
David Henningsson1f8b46c2015-05-12 14:38:15 +02005318 } else
5319 alc_fixup_headset_mode(codec, fix, action);
5320}
5321
David Henningsson73bdd592013-04-15 15:44:14 +02005322static void alc_fixup_headset_mode_alc668(struct hda_codec *codec,
5323 const struct hda_fixup *fix, int action)
5324{
5325 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
David Henningsson73bdd592013-04-15 15:44:14 +02005326 alc_write_coef_idx(codec, 0xc4, 0x8000);
Takashi Iwai98b24882014-08-18 13:47:50 +02005327 alc_update_coef_idx(codec, 0xc2, ~0xfe, 0);
David Henningsson73bdd592013-04-15 15:44:14 +02005328 snd_hda_set_pin_ctl_cache(codec, 0x18, 0);
5329 }
5330 alc_fixup_headset_mode(codec, fix, action);
5331}
5332
Chih-Chung Changbde7bc62013-08-05 16:38:42 +08005333/* Returns the nid of the external mic input pin, or 0 if it cannot be found. */
5334static int find_ext_mic_pin(struct hda_codec *codec)
5335{
5336 struct alc_spec *spec = codec->spec;
5337 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
5338 hda_nid_t nid;
5339 unsigned int defcfg;
5340 int i;
5341
5342 for (i = 0; i < cfg->num_inputs; i++) {
5343 if (cfg->inputs[i].type != AUTO_PIN_MIC)
5344 continue;
5345 nid = cfg->inputs[i].pin;
5346 defcfg = snd_hda_codec_get_pincfg(codec, nid);
5347 if (snd_hda_get_input_pin_attr(defcfg) == INPUT_PIN_ATTR_INT)
5348 continue;
5349 return nid;
5350 }
5351
5352 return 0;
5353}
5354
Dylan Reid08a978d2012-11-18 22:56:40 -08005355static void alc271_hp_gate_mic_jack(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01005356 const struct hda_fixup *fix,
Dylan Reid08a978d2012-11-18 22:56:40 -08005357 int action)
5358{
5359 struct alc_spec *spec = codec->spec;
5360
Takashi Iwai0db75792013-01-23 13:57:20 +01005361 if (action == HDA_FIXUP_ACT_PROBE) {
Chih-Chung Changbde7bc62013-08-05 16:38:42 +08005362 int mic_pin = find_ext_mic_pin(codec);
Takashi Iwai35a39f92019-02-01 11:19:50 +01005363 int hp_pin = alc_get_hp_pin(spec);
Chih-Chung Changbde7bc62013-08-05 16:38:42 +08005364
5365 if (snd_BUG_ON(!mic_pin || !hp_pin))
Takashi Iwai0db75792013-01-23 13:57:20 +01005366 return;
Chih-Chung Changbde7bc62013-08-05 16:38:42 +08005367 snd_hda_jack_set_gating_jack(codec, mic_pin, hp_pin);
Takashi Iwai0db75792013-01-23 13:57:20 +01005368 }
Dylan Reid08a978d2012-11-18 22:56:40 -08005369}
David Henningsson693b6132012-06-22 19:12:10 +02005370
Kai-Heng Feng1099f482019-10-03 12:39:19 +08005371static void alc256_fixup_dell_xps_13_headphone_noise2(struct hda_codec *codec,
5372 const struct hda_fixup *fix,
5373 int action)
5374{
5375 if (action != HDA_FIXUP_ACT_PRE_PROBE)
5376 return;
5377
5378 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 0, HDA_AMP_VOLMASK, 1);
5379 snd_hda_override_wcaps(codec, 0x1a, get_wcaps(codec, 0x1a) & ~AC_WCAP_IN_AMP);
5380}
5381
David Henningsson3e0d6112013-04-22 14:30:14 +02005382static void alc269_fixup_limit_int_mic_boost(struct hda_codec *codec,
5383 const struct hda_fixup *fix,
5384 int action)
5385{
5386 struct alc_spec *spec = codec->spec;
5387 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
5388 int i;
5389
5390 /* The mic boosts on level 2 and 3 are too noisy
5391 on the internal mic input.
5392 Therefore limit the boost to 0 or 1. */
5393
5394 if (action != HDA_FIXUP_ACT_PROBE)
5395 return;
5396
5397 for (i = 0; i < cfg->num_inputs; i++) {
5398 hda_nid_t nid = cfg->inputs[i].pin;
5399 unsigned int defcfg;
5400 if (cfg->inputs[i].type != AUTO_PIN_MIC)
5401 continue;
5402 defcfg = snd_hda_codec_get_pincfg(codec, nid);
5403 if (snd_hda_get_input_pin_attr(defcfg) != INPUT_PIN_ATTR_INT)
5404 continue;
5405
5406 snd_hda_override_amp_caps(codec, nid, HDA_INPUT,
5407 (0x00 << AC_AMPCAP_OFFSET_SHIFT) |
5408 (0x01 << AC_AMPCAP_NUM_STEPS_SHIFT) |
5409 (0x2f << AC_AMPCAP_STEP_SIZE_SHIFT) |
5410 (0 << AC_AMPCAP_MUTE_SHIFT));
5411 }
5412}
5413
Kailang Yangcd217a62013-08-22 10:15:24 +02005414static void alc283_hp_automute_hook(struct hda_codec *codec,
Takashi Iwai1a4f69d2014-09-11 15:22:46 +02005415 struct hda_jack_callback *jack)
Kailang Yangcd217a62013-08-22 10:15:24 +02005416{
5417 struct alc_spec *spec = codec->spec;
5418 int vref;
5419
5420 msleep(200);
5421 snd_hda_gen_hp_automute(codec, jack);
5422
5423 vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0;
5424
5425 msleep(600);
5426 snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5427 vref);
5428}
5429
Kailang Yangcd217a62013-08-22 10:15:24 +02005430static void alc283_fixup_chromebook(struct hda_codec *codec,
5431 const struct hda_fixup *fix, int action)
5432{
5433 struct alc_spec *spec = codec->spec;
Kailang Yangcd217a62013-08-22 10:15:24 +02005434
5435 switch (action) {
5436 case HDA_FIXUP_ACT_PRE_PROBE:
Kailang Yang0202e992013-12-02 15:20:15 +08005437 snd_hda_override_wcaps(codec, 0x03, 0);
Takashi Iwaid2e92702013-10-30 07:50:53 +01005438 /* Disable AA-loopback as it causes white noise */
5439 spec->gen.mixer_nid = 0;
Kailang Yang38070212013-11-01 15:57:35 +08005440 break;
5441 case HDA_FIXUP_ACT_INIT:
Kailang Yangde9481c2014-04-07 16:41:52 +08005442 /* MIC2-VREF control */
5443 /* Set to manual mode */
Takashi Iwai98b24882014-08-18 13:47:50 +02005444 alc_update_coef_idx(codec, 0x06, 0x000c, 0);
Kailang Yang0202e992013-12-02 15:20:15 +08005445 /* Enable Line1 input control by verb */
Takashi Iwai98b24882014-08-18 13:47:50 +02005446 alc_update_coef_idx(codec, 0x1a, 0, 1 << 4);
Kailang Yang0202e992013-12-02 15:20:15 +08005447 break;
5448 }
5449}
5450
5451static void alc283_fixup_sense_combo_jack(struct hda_codec *codec,
5452 const struct hda_fixup *fix, int action)
5453{
5454 struct alc_spec *spec = codec->spec;
Kailang Yang0202e992013-12-02 15:20:15 +08005455
5456 switch (action) {
5457 case HDA_FIXUP_ACT_PRE_PROBE:
Kailang Yangcd217a62013-08-22 10:15:24 +02005458 spec->gen.hp_automute_hook = alc283_hp_automute_hook;
5459 break;
5460 case HDA_FIXUP_ACT_INIT:
5461 /* MIC2-VREF control */
5462 /* Set to manual mode */
Takashi Iwai98b24882014-08-18 13:47:50 +02005463 alc_update_coef_idx(codec, 0x06, 0x000c, 0);
Kailang Yangcd217a62013-08-22 10:15:24 +02005464 break;
5465 }
5466}
5467
Takashi Iwai7bba2152013-09-06 15:45:38 +02005468/* mute tablet speaker pin (0x14) via dock plugging in addition */
5469static void asus_tx300_automute(struct hda_codec *codec)
5470{
5471 struct alc_spec *spec = codec->spec;
5472 snd_hda_gen_update_outputs(codec);
5473 if (snd_hda_jack_detect(codec, 0x1b))
5474 spec->gen.mute_bits |= (1ULL << 0x14);
5475}
5476
5477static void alc282_fixup_asus_tx300(struct hda_codec *codec,
5478 const struct hda_fixup *fix, int action)
5479{
5480 struct alc_spec *spec = codec->spec;
Takashi Iwai7bba2152013-09-06 15:45:38 +02005481 static const struct hda_pintbl dock_pins[] = {
5482 { 0x1b, 0x21114000 }, /* dock speaker pin */
5483 {}
5484 };
Takashi Iwai7bba2152013-09-06 15:45:38 +02005485
5486 switch (action) {
5487 case HDA_FIXUP_ACT_PRE_PROBE:
Takashi Iwai1c76aa52018-06-21 16:37:54 +02005488 spec->init_amp = ALC_INIT_DEFAULT;
Takashi Iwaiae065f12018-06-19 23:00:03 +02005489 /* TX300 needs to set up GPIO2 for the speaker amp */
5490 alc_setup_gpio(codec, 0x04);
Takashi Iwai7bba2152013-09-06 15:45:38 +02005491 snd_hda_apply_pincfgs(codec, dock_pins);
5492 spec->gen.auto_mute_via_amp = 1;
5493 spec->gen.automute_hook = asus_tx300_automute;
5494 snd_hda_jack_detect_enable_callback(codec, 0x1b,
Takashi Iwai7bba2152013-09-06 15:45:38 +02005495 snd_hda_gen_hp_automute);
5496 break;
Takashi Iwai5579cd62018-06-19 22:22:41 +02005497 case HDA_FIXUP_ACT_PROBE:
5498 spec->init_amp = ALC_INIT_DEFAULT;
5499 break;
Takashi Iwai7bba2152013-09-06 15:45:38 +02005500 case HDA_FIXUP_ACT_BUILD:
5501 /* this is a bit tricky; give more sane names for the main
5502 * (tablet) speaker and the dock speaker, respectively
5503 */
Takashi Iwai56798e62017-04-11 08:10:52 +02005504 rename_ctl(codec, "Speaker Playback Switch",
5505 "Dock Speaker Playback Switch");
5506 rename_ctl(codec, "Bass Speaker Playback Switch",
5507 "Speaker Playback Switch");
Takashi Iwai7bba2152013-09-06 15:45:38 +02005508 break;
5509 }
5510}
5511
David Henningsson338cae52013-10-07 10:39:59 +02005512static void alc290_fixup_mono_speakers(struct hda_codec *codec,
5513 const struct hda_fixup *fix, int action)
5514{
David Henningsson0f4881d2013-12-20 16:08:13 +01005515 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5516 /* DAC node 0x03 is giving mono output. We therefore want to
5517 make sure 0x14 (front speaker) and 0x15 (headphones) use the
5518 stereo DAC, while leaving 0x17 (bass speaker) for node 0x03. */
5519 hda_nid_t conn1[2] = { 0x0c };
5520 snd_hda_override_conn_list(codec, 0x14, 1, conn1);
5521 snd_hda_override_conn_list(codec, 0x15, 1, conn1);
5522 }
David Henningsson338cae52013-10-07 10:39:59 +02005523}
5524
Hui Wangdd9aa332016-08-01 10:20:32 +08005525static void alc298_fixup_speaker_volume(struct hda_codec *codec,
5526 const struct hda_fixup *fix, int action)
5527{
5528 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5529 /* The speaker is routed to the Node 0x06 by a mistake, as a result
5530 we can't adjust the speaker's volume since this node does not has
5531 Amp-out capability. we change the speaker's route to:
5532 Node 0x02 (Audio Output) -> Node 0x0c (Audio Mixer) -> Node 0x17 (
5533 Pin Complex), since Node 0x02 has Amp-out caps, we can adjust
5534 speaker's volume now. */
5535
5536 hda_nid_t conn1[1] = { 0x0c };
5537 snd_hda_override_conn_list(codec, 0x17, 1, conn1);
5538 }
5539}
5540
Takashi Iwaie312a862018-03-06 12:14:17 +01005541/* disable DAC3 (0x06) selection on NID 0x17 as it has no volume amp control */
5542static void alc295_fixup_disable_dac3(struct hda_codec *codec,
5543 const struct hda_fixup *fix, int action)
5544{
5545 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5546 hda_nid_t conn[2] = { 0x02, 0x03 };
5547 snd_hda_override_conn_list(codec, 0x17, 2, conn);
5548 }
5549}
5550
Jaroslav Kyselad2cd7952019-11-29 15:40:27 +01005551/* force NID 0x17 (Bass Speaker) to DAC1 to share it with the main speaker */
5552static void alc285_fixup_speaker2_to_dac1(struct hda_codec *codec,
5553 const struct hda_fixup *fix, int action)
5554{
5555 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5556 hda_nid_t conn[1] = { 0x02 };
5557 snd_hda_override_conn_list(codec, 0x17, 1, conn);
5558 }
5559}
5560
Keith Packard98973f22015-07-15 12:14:39 -07005561/* Hook to update amp GPIO4 for automute */
5562static void alc280_hp_gpio4_automute_hook(struct hda_codec *codec,
5563 struct hda_jack_callback *jack)
5564{
5565 struct alc_spec *spec = codec->spec;
5566
5567 snd_hda_gen_hp_automute(codec, jack);
5568 /* mute_led_polarity is set to 0, so we pass inverted value here */
5569 alc_update_gpio_led(codec, 0x10, !spec->gen.hp_jack_present);
5570}
5571
5572/* Manage GPIOs for HP EliteBook Folio 9480m.
5573 *
5574 * GPIO4 is the headphone amplifier power control
5575 * GPIO3 is the audio output mute indicator LED
5576 */
5577
5578static void alc280_fixup_hp_9480m(struct hda_codec *codec,
5579 const struct hda_fixup *fix,
5580 int action)
5581{
5582 struct alc_spec *spec = codec->spec;
Keith Packard98973f22015-07-15 12:14:39 -07005583
Takashi Iwai01e4a272018-06-19 22:47:30 +02005584 alc_fixup_hp_gpio_led(codec, action, 0x08, 0);
Keith Packard98973f22015-07-15 12:14:39 -07005585 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai01e4a272018-06-19 22:47:30 +02005586 /* amp at GPIO4; toggled via alc280_hp_gpio4_automute_hook() */
5587 spec->gpio_mask |= 0x10;
5588 spec->gpio_dir |= 0x10;
Keith Packard98973f22015-07-15 12:14:39 -07005589 spec->gen.hp_automute_hook = alc280_hp_gpio4_automute_hook;
Keith Packard98973f22015-07-15 12:14:39 -07005590 }
5591}
5592
Takashi Iwaiae065f12018-06-19 23:00:03 +02005593static void alc275_fixup_gpio4_off(struct hda_codec *codec,
5594 const struct hda_fixup *fix,
5595 int action)
5596{
5597 struct alc_spec *spec = codec->spec;
5598
5599 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5600 spec->gpio_mask |= 0x04;
5601 spec->gpio_dir |= 0x04;
5602 /* set data bit low */
5603 }
5604}
5605
Kailang Yangca169cc2017-04-25 16:17:40 +08005606static void alc233_alc662_fixup_lenovo_dual_codecs(struct hda_codec *codec,
5607 const struct hda_fixup *fix,
5608 int action)
5609{
5610 alc_fixup_dual_codecs(codec, fix, action);
5611 switch (action) {
5612 case HDA_FIXUP_ACT_PRE_PROBE:
5613 /* override card longname to provide a unique UCM profile */
5614 strcpy(codec->card->longname, "HDAudio-Lenovo-DualCodecs");
5615 break;
5616 case HDA_FIXUP_ACT_BUILD:
5617 /* rename Capture controls depending on the codec */
5618 rename_ctl(codec, "Capture Volume",
5619 codec->addr == 0 ?
5620 "Rear-Panel Capture Volume" :
5621 "Front-Panel Capture Volume");
5622 rename_ctl(codec, "Capture Switch",
5623 codec->addr == 0 ?
5624 "Rear-Panel Capture Switch" :
5625 "Front-Panel Capture Switch");
5626 break;
5627 }
5628}
5629
Kailang Yang92266652017-12-14 15:28:58 +08005630/* Forcibly assign NID 0x03 to HP/LO while NID 0x02 to SPK for EQ */
5631static void alc274_fixup_bind_dacs(struct hda_codec *codec,
5632 const struct hda_fixup *fix, int action)
5633{
5634 struct alc_spec *spec = codec->spec;
5635 static hda_nid_t preferred_pairs[] = {
5636 0x21, 0x03, 0x1b, 0x03, 0x16, 0x02,
5637 0
5638 };
5639
5640 if (action != HDA_FIXUP_ACT_PRE_PROBE)
5641 return;
5642
5643 spec->gen.preferred_dacs = preferred_pairs;
Kailang Yang0700d3d2019-04-26 16:13:54 +08005644 spec->gen.auto_mute_via_amp = 1;
5645 codec->power_save_node = 0;
Kailang Yang92266652017-12-14 15:28:58 +08005646}
5647
Hui Wangc4cfcf62018-11-26 14:17:16 +08005648/* The DAC of NID 0x3 will introduce click/pop noise on headphones, so invalidate it */
5649static void alc285_fixup_invalidate_dacs(struct hda_codec *codec,
5650 const struct hda_fixup *fix, int action)
5651{
5652 if (action != HDA_FIXUP_ACT_PRE_PROBE)
5653 return;
5654
5655 snd_hda_override_wcaps(codec, 0x03, 0);
5656}
5657
Kailang Yange8547472018-11-28 15:32:45 +08005658static const struct hda_jack_keymap alc_headset_btn_keymap[] = {
5659 { SND_JACK_BTN_0, KEY_PLAYPAUSE },
5660 { SND_JACK_BTN_1, KEY_VOICECOMMAND },
5661 { SND_JACK_BTN_2, KEY_VOLUMEUP },
5662 { SND_JACK_BTN_3, KEY_VOLUMEDOWN },
5663 {}
5664};
5665
5666static void alc_headset_btn_callback(struct hda_codec *codec,
5667 struct hda_jack_callback *jack)
5668{
5669 int report = 0;
5670
5671 if (jack->unsol_res & (7 << 13))
5672 report |= SND_JACK_BTN_0;
5673
5674 if (jack->unsol_res & (1 << 16 | 3 << 8))
5675 report |= SND_JACK_BTN_1;
5676
5677 /* Volume up key */
5678 if (jack->unsol_res & (7 << 23))
5679 report |= SND_JACK_BTN_2;
5680
5681 /* Volume down key */
5682 if (jack->unsol_res & (7 << 10))
5683 report |= SND_JACK_BTN_3;
5684
5685 jack->jack->button_state = report;
5686}
5687
Kailang Yang8983eb62019-04-03 15:31:49 +08005688static void alc_fixup_headset_jack(struct hda_codec *codec,
Kailang Yange8547472018-11-28 15:32:45 +08005689 const struct hda_fixup *fix, int action)
5690{
5691
5692 switch (action) {
5693 case HDA_FIXUP_ACT_PRE_PROBE:
5694 snd_hda_jack_detect_enable_callback(codec, 0x55,
5695 alc_headset_btn_callback);
5696 snd_hda_jack_add_kctl(codec, 0x55, "Headset Jack", false,
5697 SND_JACK_HEADSET, alc_headset_btn_keymap);
5698 break;
5699 case HDA_FIXUP_ACT_INIT:
5700 switch (codec->core.vendor_id) {
5701 case 0x10ec0225:
5702 case 0x10ec0295:
5703 case 0x10ec0299:
5704 alc_write_coef_idx(codec, 0x48, 0xd011);
5705 alc_update_coef_idx(codec, 0x49, 0x007f, 0x0045);
5706 alc_update_coef_idx(codec, 0x44, 0x007f << 8, 0x0045 << 8);
5707 break;
5708 case 0x10ec0236:
5709 case 0x10ec0256:
5710 alc_write_coef_idx(codec, 0x48, 0xd011);
5711 alc_update_coef_idx(codec, 0x49, 0x007f, 0x0045);
5712 break;
5713 }
5714 break;
5715 }
5716}
5717
Kailang Yang8983eb62019-04-03 15:31:49 +08005718static void alc295_fixup_chromebook(struct hda_codec *codec,
5719 const struct hda_fixup *fix, int action)
5720{
Kailang Yangd3ba58b2019-05-06 15:09:42 +08005721 struct alc_spec *spec = codec->spec;
5722
Kailang Yang8983eb62019-04-03 15:31:49 +08005723 switch (action) {
Kailang Yangd3ba58b2019-05-06 15:09:42 +08005724 case HDA_FIXUP_ACT_PRE_PROBE:
5725 spec->ultra_low_power = true;
5726 break;
Kailang Yang8983eb62019-04-03 15:31:49 +08005727 case HDA_FIXUP_ACT_INIT:
5728 switch (codec->core.vendor_id) {
5729 case 0x10ec0295:
5730 alc_update_coef_idx(codec, 0x4a, 0x8000, 1 << 15); /* Reset HP JD */
5731 alc_update_coef_idx(codec, 0x4a, 0x8000, 0 << 15);
5732 break;
5733 case 0x10ec0236:
5734 alc_update_coef_idx(codec, 0x1b, 0x8000, 1 << 15); /* Reset HP JD */
5735 alc_update_coef_idx(codec, 0x1b, 0x8000, 0 << 15);
5736 break;
5737 }
5738 break;
5739 }
5740}
5741
Kailang Yangd1dd4212019-01-09 17:05:24 +08005742static void alc_fixup_disable_mic_vref(struct hda_codec *codec,
5743 const struct hda_fixup *fix, int action)
5744{
5745 if (action == HDA_FIXUP_ACT_PRE_PROBE)
5746 snd_hda_codec_set_pin_target(codec, 0x19, PIN_VREFHIZ);
5747}
5748
Takashi Iwaib317b032014-01-08 11:44:21 +01005749/* for hda_fixup_thinkpad_acpi() */
5750#include "thinkpad_helper.c"
David Henningssonb67ae3f2013-11-05 13:11:37 +01005751
Takashi Iwaid5a6cab2018-06-13 12:43:10 +02005752static void alc_fixup_thinkpad_acpi(struct hda_codec *codec,
5753 const struct hda_fixup *fix, int action)
5754{
5755 alc_fixup_no_shutup(codec, fix, action); /* reduce click noise */
5756 hda_fixup_thinkpad_acpi(codec, fix, action);
5757}
5758
Tom Bridenbbf8ff62018-05-29 17:34:20 +01005759/* for alc295_fixup_hp_top_speakers */
5760#include "hp_x360_helper.c"
5761
Takashi Iwai1d045db2011-07-07 18:23:21 +02005762enum {
5763 ALC269_FIXUP_SONY_VAIO,
5764 ALC275_FIXUP_SONY_VAIO_GPIO2,
5765 ALC269_FIXUP_DELL_M101Z,
5766 ALC269_FIXUP_SKU_IGNORE,
5767 ALC269_FIXUP_ASUS_G73JW,
5768 ALC269_FIXUP_LENOVO_EAPD,
5769 ALC275_FIXUP_SONY_HWEQ,
Takashi Iwaie9bd7d52014-05-21 11:06:49 +02005770 ALC275_FIXUP_SONY_DISABLE_AAMIX,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005771 ALC271_FIXUP_DMIC,
Takashi Iwai017f2a12011-07-09 14:42:25 +02005772 ALC269_FIXUP_PCM_44K,
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02005773 ALC269_FIXUP_STEREO_DMIC,
David Henningsson7c478f02013-10-11 10:18:46 +02005774 ALC269_FIXUP_HEADSET_MIC,
Takashi Iwai24519912011-08-16 15:08:49 +02005775 ALC269_FIXUP_QUANTA_MUTE,
5776 ALC269_FIXUP_LIFEBOOK,
David Henningsson2041d562014-06-13 11:15:44 +02005777 ALC269_FIXUP_LIFEBOOK_EXTMIC,
Takashi Iwaicc7016a2015-04-08 20:47:55 +02005778 ALC269_FIXUP_LIFEBOOK_HP_PIN,
Takashi Iwai4df3fd12015-06-29 08:38:02 +02005779 ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT,
Jan-Marek Glogowskifdcc9682018-02-14 11:29:15 +01005780 ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC,
Takashi Iwaia4297b52011-08-23 18:40:12 +02005781 ALC269_FIXUP_AMIC,
5782 ALC269_FIXUP_DMIC,
5783 ALC269VB_FIXUP_AMIC,
5784 ALC269VB_FIXUP_DMIC,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01005785 ALC269_FIXUP_HP_MUTE_LED,
David Henningssond06ac142013-02-18 11:41:55 +01005786 ALC269_FIXUP_HP_MUTE_LED_MIC1,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01005787 ALC269_FIXUP_HP_MUTE_LED_MIC2,
Tom Briden7f783bd2017-03-25 10:12:01 +00005788 ALC269_FIXUP_HP_MUTE_LED_MIC3,
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01005789 ALC269_FIXUP_HP_GPIO_LED,
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08005790 ALC269_FIXUP_HP_GPIO_MIC1_LED,
5791 ALC269_FIXUP_HP_LINE1_MIC1_LED,
David Henningsson693b6132012-06-22 19:12:10 +02005792 ALC269_FIXUP_INV_DMIC,
David Henningsson108cc102012-07-20 10:37:25 +02005793 ALC269_FIXUP_LENOVO_DOCK,
Takashi Iwai9b745ab2014-03-07 08:37:19 +01005794 ALC269_FIXUP_NO_SHUTUP,
David Henningsson88cfcf82013-10-11 10:18:45 +02005795 ALC286_FIXUP_SONY_MIC_NO_PRESENCE,
David Henningsson108cc102012-07-20 10:37:25 +02005796 ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT,
David Henningsson73bdd592013-04-15 15:44:14 +02005797 ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
5798 ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
David Henningsson338cae52013-10-07 10:39:59 +02005799 ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
Kailang Yangfcc6c872017-06-29 15:21:27 +08005800 ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
David Henningsson73bdd592013-04-15 15:44:14 +02005801 ALC269_FIXUP_HEADSET_MODE,
5802 ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC,
Takashi Iwai78197172015-06-27 10:21:13 +02005803 ALC269_FIXUP_ASPIRE_HEADSET_MIC,
David Henningssond240d1d2013-04-15 12:50:02 +02005804 ALC269_FIXUP_ASUS_X101_FUNC,
5805 ALC269_FIXUP_ASUS_X101_VERB,
5806 ALC269_FIXUP_ASUS_X101,
Dylan Reid08a978d2012-11-18 22:56:40 -08005807 ALC271_FIXUP_AMIC_MIC2,
5808 ALC271_FIXUP_HP_GATE_MIC_JACK,
Oleksij Rempelb1e89722013-12-04 20:50:53 +01005809 ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572,
Dylan Reid42397002013-04-05 14:58:22 -07005810 ALC269_FIXUP_ACER_AC700,
David Henningsson3e0d6112013-04-22 14:30:14 +02005811 ALC269_FIXUP_LIMIT_INT_MIC_BOOST,
Oleksij Rempel2cede302013-11-27 17:12:03 +01005812 ALC269VB_FIXUP_ASUS_ZENBOOK,
Takashi Iwai23870832013-11-29 14:13:12 +01005813 ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A,
David Henningsson8e35cd42013-11-06 11:20:01 +01005814 ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED,
Anisse Astier02b504d2013-06-03 11:53:10 +02005815 ALC269VB_FIXUP_ORDISSIMO_EVE2,
Kailang Yangcd217a62013-08-22 10:15:24 +02005816 ALC283_FIXUP_CHROME_BOOK,
Kailang Yang0202e992013-12-02 15:20:15 +08005817 ALC283_FIXUP_SENSE_COMBO_JACK,
Takashi Iwai7bba2152013-09-06 15:45:38 +02005818 ALC282_FIXUP_ASUS_TX300,
Kailang Yang1bb3e062013-09-27 13:10:25 +02005819 ALC283_FIXUP_INT_MIC,
David Henningsson338cae52013-10-07 10:39:59 +02005820 ALC290_FIXUP_MONO_SPEAKERS,
David Henningsson0f4881d2013-12-20 16:08:13 +01005821 ALC290_FIXUP_MONO_SPEAKERS_HSJACK,
5822 ALC290_FIXUP_SUBWOOFER,
5823 ALC290_FIXUP_SUBWOOFER_HSJACK,
David Henningssonb67ae3f2013-11-05 13:11:37 +01005824 ALC269_FIXUP_THINKPAD_ACPI,
David Henningsson56f27012016-01-11 09:33:14 +01005825 ALC269_FIXUP_DMIC_THINKPAD_ACPI,
Chris Chiu5824ce82017-02-28 14:17:11 -06005826 ALC255_FIXUP_ACER_MIC_NO_PRESENCE,
Chris Chiu615966a2017-02-28 14:17:12 -06005827 ALC255_FIXUP_ASUS_MIC_NO_PRESENCE,
Kailang Yang9a22a8f52013-11-08 15:54:49 +08005828 ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Kailang Yang31278992014-03-03 15:27:22 +08005829 ALC255_FIXUP_DELL2_MIC_NO_PRESENCE,
Kailang Yang9a22a8f52013-11-08 15:54:49 +08005830 ALC255_FIXUP_HEADSET_MODE,
Kailang Yang31278992014-03-03 15:27:22 +08005831 ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC,
Kailang Yanga22aa262014-04-23 17:34:28 +08005832 ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
Takashi Iwai1c37c222014-05-06 17:34:42 +02005833 ALC292_FIXUP_TPT440_DOCK,
Takashi Iwai9a811232015-12-09 15:17:43 +01005834 ALC292_FIXUP_TPT440,
Anisse Astierabaa22742016-08-24 09:14:13 +02005835 ALC283_FIXUP_HEADSET_MIC,
Takashi Iwaib3802782018-11-26 17:47:46 +01005836 ALC255_FIXUP_MIC_MUTE_LED,
Takashi Iwai1a22e772014-08-27 08:19:05 +02005837 ALC282_FIXUP_ASPIRE_V5_PINS,
David Henningsson7a5255f2014-10-30 08:26:01 +01005838 ALC280_FIXUP_HP_GPIO4,
Kailang Yangeaa8e5e2014-11-21 15:49:11 +08005839 ALC286_FIXUP_HP_GPIO_LED,
David Henningsson33f4acd2015-01-07 15:50:13 +01005840 ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY,
TienFu Chenb4b33f92015-01-20 15:06:21 +01005841 ALC280_FIXUP_HP_DOCK_PINS,
Jaroslav Kysela04d54662017-03-09 13:29:13 +01005842 ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED,
Keith Packard98973f22015-07-15 12:14:39 -07005843 ALC280_FIXUP_HP_9480M,
Kailang Yange1e62b92015-04-08 16:01:22 +08005844 ALC288_FIXUP_DELL_HEADSET_MODE,
5845 ALC288_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang831bfdf92015-06-26 12:35:17 +08005846 ALC288_FIXUP_DELL_XPS_13,
5847 ALC288_FIXUP_DISABLE_AAMIX,
Takashi Iwai8b99aba2015-06-15 11:59:32 +02005848 ALC292_FIXUP_DELL_E7X,
5849 ALC292_FIXUP_DISABLE_AAMIX,
David Henningssonc04017e2015-12-15 14:44:03 +01005850 ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK,
James McDonnell54324222019-09-16 14:53:38 +00005851 ALC298_FIXUP_ALIENWARE_MIC_NO_PRESENCE,
Kailang Yang977e6272015-05-18 15:31:20 +08005852 ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang2f726ae2017-03-31 10:31:40 +08005853 ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE,
Kailang Yang6ed11312015-10-26 15:37:39 +08005854 ALC275_FIXUP_DELL_XPS,
Hui Wang8c697292015-11-24 11:08:18 +08005855 ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE,
Kai-Heng Feng1099f482019-10-03 12:39:19 +08005856 ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE2,
Hui Wang23adc192015-12-08 12:27:18 +08005857 ALC293_FIXUP_LENOVO_SPK_NOISE,
Kailang3694cb22015-12-28 11:35:24 +08005858 ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY,
Kai-Heng Feng3b43b712016-02-25 15:19:38 +08005859 ALC255_FIXUP_DELL_SPK_NOISE,
Kailang Yangd1dd4212019-01-09 17:05:24 +08005860 ALC225_FIXUP_DISABLE_MIC_VREF,
David Henningsson2ae95572016-02-25 09:37:05 +01005861 ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
Takashi Iwaie312a862018-03-06 12:14:17 +01005862 ALC295_FIXUP_DISABLE_DAC3,
Jaroslav Kyselad2cd7952019-11-29 15:40:27 +01005863 ALC285_FIXUP_SPEAKER2_TO_DAC1,
Takashi Iwaif8839822016-02-25 14:31:59 +01005864 ALC280_FIXUP_HP_HEADSET_MIC,
Hui Wange549d192016-04-01 11:00:15 +08005865 ALC221_FIXUP_HP_FRONT_MIC,
Sven Eckelmannc636b952016-04-11 16:55:26 +02005866 ALC292_FIXUP_TPT460,
Hui Wangdd9aa332016-08-01 10:20:32 +08005867 ALC298_FIXUP_SPK_VOLUME,
Kai-Heng Fengfd06c772016-08-30 15:36:34 +08005868 ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER,
Gabriele Mazzotta823ff162016-12-24 19:50:01 +01005869 ALC269_FIXUP_ATIV_BOOK_8,
Kailang Yang9eb5d0e2017-01-17 15:40:25 +08005870 ALC221_FIXUP_HP_MIC_NO_PRESENCE,
Chris Chiuc1732ed2017-02-28 14:17:13 -06005871 ALC256_FIXUP_ASUS_HEADSET_MODE,
5872 ALC256_FIXUP_ASUS_MIC,
Chris Chiueeed4cd2017-02-28 14:17:15 -06005873 ALC256_FIXUP_ASUS_AIO_GPIO2,
Chris Chiu216d7ae2017-02-28 14:17:14 -06005874 ALC233_FIXUP_ASUS_MIC_NO_PRESENCE,
5875 ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE,
Kailang Yangca169cc2017-04-25 16:17:40 +08005876 ALC233_FIXUP_LENOVO_MULTI_CODECS,
Jian-Hong Panea5c7eb2019-04-01 11:25:05 +08005877 ALC233_FIXUP_ACER_HEADSET_MIC,
Hui Wangf33f79f2017-07-07 12:08:29 +08005878 ALC294_FIXUP_LENOVO_MIC_LOCATION,
Kailang Yang5f364132017-07-25 16:28:16 +08005879 ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE,
PeiSen Houb84e8432017-09-01 15:11:56 +08005880 ALC700_FIXUP_INTEL_REFERENCE,
Kailang Yang92266652017-12-14 15:28:58 +08005881 ALC274_FIXUP_DELL_BIND_DACS,
5882 ALC274_FIXUP_DELL_AIO_LINEOUT_VERB,
Kailang Yang61fcf8e2018-02-02 15:26:46 +08005883 ALC298_FIXUP_TPT470_DOCK,
Kailang Yangae104a22018-02-05 16:07:20 +08005884 ALC255_FIXUP_DUMMY_LINEOUT_VERB,
Kailang Yangf0ba9d62018-03-16 11:46:08 +08005885 ALC255_FIXUP_DELL_HEADSET_MIC,
Ayman Bagabas0fbf21c2019-05-23 05:30:11 -04005886 ALC256_FIXUP_HUAWEI_MACH_WX9_PINS,
Tomas Espeletaa2ef03f2019-08-09 16:37:54 +02005887 ALC298_FIXUP_HUAWEI_MBX_STEREO,
Tom Bridenbbf8ff62018-05-29 17:34:20 +01005888 ALC295_FIXUP_HP_X360,
Kailang Yang8a328ac2018-08-21 16:54:41 +08005889 ALC221_FIXUP_HP_HEADSET_MIC,
Hui Wangc4cfcf62018-11-26 14:17:16 +08005890 ALC285_FIXUP_LENOVO_HEADPHONE_NOISE,
Girija Kumar Kasinadhunie8ed64b2018-11-26 13:40:46 -05005891 ALC295_FIXUP_HP_AUTO_MUTE,
Chris Chiu33aaebd2018-12-05 14:48:53 +08005892 ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE,
Chris Chiud8ae4582018-12-07 17:17:11 +08005893 ALC294_FIXUP_ASUS_MIC,
Jian-Hong Pan4e051102018-12-07 17:17:12 +08005894 ALC294_FIXUP_ASUS_HEADSET_MIC,
5895 ALC294_FIXUP_ASUS_SPK,
Jeremy Soller89e3a562019-01-30 16:12:31 -07005896 ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE,
Hui Wangc8c6ee62019-02-14 11:41:33 +08005897 ALC285_FIXUP_LENOVO_PC_BEEP_IN_NOISE,
Jian-Hong Pancbc05fd2019-03-13 17:33:24 +08005898 ALC255_FIXUP_ACER_HEADSET_MIC,
Kailang Yang10f5b1b2019-02-21 16:10:22 +08005899 ALC295_FIXUP_CHROME_BOOK,
Kailang Yang8983eb62019-04-03 15:31:49 +08005900 ALC225_FIXUP_HEADSET_JACK,
Kailang Yang136824e2019-03-14 16:22:45 +08005901 ALC225_FIXUP_DELL_WYSE_AIO_MIC_NO_PRESENCE,
5902 ALC225_FIXUP_WYSE_AUTO_MUTE,
5903 ALC225_FIXUP_WYSE_DISABLE_MIC_VREF,
Jian-Hong Pan667a8f72019-03-15 17:51:09 +08005904 ALC286_FIXUP_ACER_AIO_HEADSET_MIC,
Daniel Drake8c8967a2019-10-17 16:15:01 +08005905 ALC256_FIXUP_ASUS_HEADSET_MIC,
Jian-Hong Pane1037352019-03-22 11:37:18 +08005906 ALC256_FIXUP_ASUS_MIC_NO_PRESENCE,
Bernhard Rosenkraenzere2a829b2019-03-05 00:38:19 +01005907 ALC299_FIXUP_PREDATOR_SPK,
Jian-Hong Pan60083f92019-09-02 18:00:56 +08005908 ALC294_FIXUP_ASUS_INTSPK_HEADSET_MIC,
Jan-Marek Glogowskibd9c10b2019-09-15 16:57:28 +02005909 ALC256_FIXUP_MEDION_HEADSET_NO_PRESENCE,
Jian-Hong Pan436e2552019-11-25 17:34:06 +08005910 ALC294_FIXUP_ASUS_INTSPK_GPIO,
Kailang Yange79c2262019-12-19 14:12:15 +08005911 ALC289_FIXUP_DELL_SPK2,
5912 ALC289_FIXUP_DUAL_SPK,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005913};
5914
Takashi Iwai1727a772013-01-10 09:52:52 +01005915static const struct hda_fixup alc269_fixups[] = {
Takashi Iwai1d045db2011-07-07 18:23:21 +02005916 [ALC269_FIXUP_SONY_VAIO] = {
Takashi Iwaifd108212013-01-10 10:18:14 +01005917 .type = HDA_FIXUP_PINCTLS,
5918 .v.pins = (const struct hda_pintbl[]) {
5919 {0x19, PIN_VREFGRD},
Takashi Iwai1d045db2011-07-07 18:23:21 +02005920 {}
5921 }
5922 },
5923 [ALC275_FIXUP_SONY_VAIO_GPIO2] = {
Takashi Iwaiae065f12018-06-19 23:00:03 +02005924 .type = HDA_FIXUP_FUNC,
5925 .v.func = alc275_fixup_gpio4_off,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005926 .chained = true,
5927 .chain_id = ALC269_FIXUP_SONY_VAIO
5928 },
5929 [ALC269_FIXUP_DELL_M101Z] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005930 .type = HDA_FIXUP_VERBS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005931 .v.verbs = (const struct hda_verb[]) {
5932 /* Enables internal speaker */
5933 {0x20, AC_VERB_SET_COEF_INDEX, 13},
5934 {0x20, AC_VERB_SET_PROC_COEF, 0x4040},
5935 {}
5936 }
5937 },
5938 [ALC269_FIXUP_SKU_IGNORE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005939 .type = HDA_FIXUP_FUNC,
Takashi Iwai23d30f22012-05-07 17:17:32 +02005940 .v.func = alc_fixup_sku_ignore,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005941 },
5942 [ALC269_FIXUP_ASUS_G73JW] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005943 .type = HDA_FIXUP_PINS,
5944 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02005945 { 0x17, 0x99130111 }, /* subwoofer */
5946 { }
5947 }
5948 },
5949 [ALC269_FIXUP_LENOVO_EAPD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005950 .type = HDA_FIXUP_VERBS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005951 .v.verbs = (const struct hda_verb[]) {
5952 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
5953 {}
5954 }
5955 },
5956 [ALC275_FIXUP_SONY_HWEQ] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005957 .type = HDA_FIXUP_FUNC,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005958 .v.func = alc269_fixup_hweq,
5959 .chained = true,
5960 .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2
5961 },
Takashi Iwaie9bd7d52014-05-21 11:06:49 +02005962 [ALC275_FIXUP_SONY_DISABLE_AAMIX] = {
5963 .type = HDA_FIXUP_FUNC,
5964 .v.func = alc_fixup_disable_aamix,
5965 .chained = true,
5966 .chain_id = ALC269_FIXUP_SONY_VAIO
5967 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02005968 [ALC271_FIXUP_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005969 .type = HDA_FIXUP_FUNC,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005970 .v.func = alc271_fixup_dmic,
5971 },
Takashi Iwai017f2a12011-07-09 14:42:25 +02005972 [ALC269_FIXUP_PCM_44K] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005973 .type = HDA_FIXUP_FUNC,
Takashi Iwai017f2a12011-07-09 14:42:25 +02005974 .v.func = alc269_fixup_pcm_44k,
David Henningsson012e7eb2012-08-08 08:43:37 +02005975 .chained = true,
5976 .chain_id = ALC269_FIXUP_QUANTA_MUTE
Takashi Iwai017f2a12011-07-09 14:42:25 +02005977 },
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02005978 [ALC269_FIXUP_STEREO_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005979 .type = HDA_FIXUP_FUNC,
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02005980 .v.func = alc269_fixup_stereo_dmic,
5981 },
David Henningsson7c478f02013-10-11 10:18:46 +02005982 [ALC269_FIXUP_HEADSET_MIC] = {
5983 .type = HDA_FIXUP_FUNC,
5984 .v.func = alc269_fixup_headset_mic,
5985 },
Takashi Iwai24519912011-08-16 15:08:49 +02005986 [ALC269_FIXUP_QUANTA_MUTE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005987 .type = HDA_FIXUP_FUNC,
Takashi Iwai24519912011-08-16 15:08:49 +02005988 .v.func = alc269_fixup_quanta_mute,
5989 },
5990 [ALC269_FIXUP_LIFEBOOK] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005991 .type = HDA_FIXUP_PINS,
5992 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai24519912011-08-16 15:08:49 +02005993 { 0x1a, 0x2101103f }, /* dock line-out */
5994 { 0x1b, 0x23a11040 }, /* dock mic-in */
5995 { }
5996 },
5997 .chained = true,
5998 .chain_id = ALC269_FIXUP_QUANTA_MUTE
5999 },
David Henningsson2041d562014-06-13 11:15:44 +02006000 [ALC269_FIXUP_LIFEBOOK_EXTMIC] = {
6001 .type = HDA_FIXUP_PINS,
6002 .v.pins = (const struct hda_pintbl[]) {
6003 { 0x19, 0x01a1903c }, /* headset mic, with jack detect */
6004 { }
6005 },
6006 },
Takashi Iwaicc7016a2015-04-08 20:47:55 +02006007 [ALC269_FIXUP_LIFEBOOK_HP_PIN] = {
6008 .type = HDA_FIXUP_PINS,
6009 .v.pins = (const struct hda_pintbl[]) {
6010 { 0x21, 0x0221102f }, /* HP out */
6011 { }
6012 },
6013 },
Takashi Iwai4df3fd12015-06-29 08:38:02 +02006014 [ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT] = {
6015 .type = HDA_FIXUP_FUNC,
6016 .v.func = alc269_fixup_pincfg_no_hp_to_lineout,
6017 },
Jan-Marek Glogowskifdcc9682018-02-14 11:29:15 +01006018 [ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC] = {
6019 .type = HDA_FIXUP_FUNC,
6020 .v.func = alc269_fixup_pincfg_U7x7_headset_mic,
6021 },
Takashi Iwaia4297b52011-08-23 18:40:12 +02006022 [ALC269_FIXUP_AMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006023 .type = HDA_FIXUP_PINS,
6024 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaia4297b52011-08-23 18:40:12 +02006025 { 0x14, 0x99130110 }, /* speaker */
6026 { 0x15, 0x0121401f }, /* HP out */
6027 { 0x18, 0x01a19c20 }, /* mic */
6028 { 0x19, 0x99a3092f }, /* int-mic */
6029 { }
6030 },
6031 },
6032 [ALC269_FIXUP_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006033 .type = HDA_FIXUP_PINS,
6034 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaia4297b52011-08-23 18:40:12 +02006035 { 0x12, 0x99a3092f }, /* int-mic */
6036 { 0x14, 0x99130110 }, /* speaker */
6037 { 0x15, 0x0121401f }, /* HP out */
6038 { 0x18, 0x01a19c20 }, /* mic */
6039 { }
6040 },
6041 },
6042 [ALC269VB_FIXUP_AMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006043 .type = HDA_FIXUP_PINS,
6044 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaia4297b52011-08-23 18:40:12 +02006045 { 0x14, 0x99130110 }, /* speaker */
6046 { 0x18, 0x01a19c20 }, /* mic */
6047 { 0x19, 0x99a3092f }, /* int-mic */
6048 { 0x21, 0x0121401f }, /* HP out */
6049 { }
6050 },
6051 },
David Henningsson2267ea92012-01-03 08:45:56 +01006052 [ALC269VB_FIXUP_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006053 .type = HDA_FIXUP_PINS,
6054 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaia4297b52011-08-23 18:40:12 +02006055 { 0x12, 0x99a3092f }, /* int-mic */
6056 { 0x14, 0x99130110 }, /* speaker */
6057 { 0x18, 0x01a19c20 }, /* mic */
6058 { 0x21, 0x0121401f }, /* HP out */
6059 { }
6060 },
6061 },
Takashi Iwai08fb0d02013-01-10 17:33:58 +01006062 [ALC269_FIXUP_HP_MUTE_LED] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006063 .type = HDA_FIXUP_FUNC,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01006064 .v.func = alc269_fixup_hp_mute_led,
David Henningsson6d3cd5d2013-01-07 12:03:47 +01006065 },
David Henningssond06ac142013-02-18 11:41:55 +01006066 [ALC269_FIXUP_HP_MUTE_LED_MIC1] = {
6067 .type = HDA_FIXUP_FUNC,
6068 .v.func = alc269_fixup_hp_mute_led_mic1,
6069 },
Takashi Iwai08fb0d02013-01-10 17:33:58 +01006070 [ALC269_FIXUP_HP_MUTE_LED_MIC2] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006071 .type = HDA_FIXUP_FUNC,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01006072 .v.func = alc269_fixup_hp_mute_led_mic2,
Takashi Iwai420b0fe2012-03-12 12:35:27 +01006073 },
Tom Briden7f783bd2017-03-25 10:12:01 +00006074 [ALC269_FIXUP_HP_MUTE_LED_MIC3] = {
6075 .type = HDA_FIXUP_FUNC,
6076 .v.func = alc269_fixup_hp_mute_led_mic3,
Girija Kumar Kasinadhunie8ed64b2018-11-26 13:40:46 -05006077 .chained = true,
6078 .chain_id = ALC295_FIXUP_HP_AUTO_MUTE
Tom Briden7f783bd2017-03-25 10:12:01 +00006079 },
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01006080 [ALC269_FIXUP_HP_GPIO_LED] = {
6081 .type = HDA_FIXUP_FUNC,
6082 .v.func = alc269_fixup_hp_gpio_led,
6083 },
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08006084 [ALC269_FIXUP_HP_GPIO_MIC1_LED] = {
6085 .type = HDA_FIXUP_FUNC,
6086 .v.func = alc269_fixup_hp_gpio_mic1_led,
6087 },
6088 [ALC269_FIXUP_HP_LINE1_MIC1_LED] = {
6089 .type = HDA_FIXUP_FUNC,
6090 .v.func = alc269_fixup_hp_line1_mic1_led,
6091 },
David Henningsson693b6132012-06-22 19:12:10 +02006092 [ALC269_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006093 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02006094 .v.func = alc_fixup_inv_dmic,
David Henningsson693b6132012-06-22 19:12:10 +02006095 },
Takashi Iwai9b745ab2014-03-07 08:37:19 +01006096 [ALC269_FIXUP_NO_SHUTUP] = {
6097 .type = HDA_FIXUP_FUNC,
6098 .v.func = alc_fixup_no_shutup,
6099 },
David Henningsson108cc102012-07-20 10:37:25 +02006100 [ALC269_FIXUP_LENOVO_DOCK] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006101 .type = HDA_FIXUP_PINS,
6102 .v.pins = (const struct hda_pintbl[]) {
David Henningsson108cc102012-07-20 10:37:25 +02006103 { 0x19, 0x23a11040 }, /* dock mic */
6104 { 0x1b, 0x2121103f }, /* dock headphone */
6105 { }
6106 },
6107 .chained = true,
6108 .chain_id = ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT
6109 },
6110 [ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006111 .type = HDA_FIXUP_FUNC,
David Henningsson108cc102012-07-20 10:37:25 +02006112 .v.func = alc269_fixup_pincfg_no_hp_to_lineout,
David Henningsson52129002013-11-19 10:25:53 +01006113 .chained = true,
6114 .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
David Henningsson108cc102012-07-20 10:37:25 +02006115 },
David Henningsson73bdd592013-04-15 15:44:14 +02006116 [ALC269_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6117 .type = HDA_FIXUP_PINS,
6118 .v.pins = (const struct hda_pintbl[]) {
6119 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6120 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6121 { }
6122 },
6123 .chained = true,
6124 .chain_id = ALC269_FIXUP_HEADSET_MODE
6125 },
6126 [ALC269_FIXUP_DELL2_MIC_NO_PRESENCE] = {
6127 .type = HDA_FIXUP_PINS,
6128 .v.pins = (const struct hda_pintbl[]) {
6129 { 0x16, 0x21014020 }, /* dock line out */
6130 { 0x19, 0x21a19030 }, /* dock mic */
6131 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6132 { }
6133 },
6134 .chained = true,
6135 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
6136 },
David Henningsson338cae52013-10-07 10:39:59 +02006137 [ALC269_FIXUP_DELL3_MIC_NO_PRESENCE] = {
6138 .type = HDA_FIXUP_PINS,
6139 .v.pins = (const struct hda_pintbl[]) {
6140 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6141 { }
6142 },
6143 .chained = true,
6144 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
6145 },
Kailang Yangfcc6c872017-06-29 15:21:27 +08006146 [ALC269_FIXUP_DELL4_MIC_NO_PRESENCE] = {
6147 .type = HDA_FIXUP_PINS,
6148 .v.pins = (const struct hda_pintbl[]) {
6149 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6150 { 0x1b, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6151 { }
6152 },
6153 .chained = true,
6154 .chain_id = ALC269_FIXUP_HEADSET_MODE
6155 },
David Henningsson73bdd592013-04-15 15:44:14 +02006156 [ALC269_FIXUP_HEADSET_MODE] = {
6157 .type = HDA_FIXUP_FUNC,
6158 .v.func = alc_fixup_headset_mode,
Hui Wang6676f302014-11-18 17:57:41 +08006159 .chained = true,
Takashi Iwaib3802782018-11-26 17:47:46 +01006160 .chain_id = ALC255_FIXUP_MIC_MUTE_LED
David Henningsson73bdd592013-04-15 15:44:14 +02006161 },
6162 [ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC] = {
6163 .type = HDA_FIXUP_FUNC,
6164 .v.func = alc_fixup_headset_mode_no_hp_mic,
6165 },
Takashi Iwai78197172015-06-27 10:21:13 +02006166 [ALC269_FIXUP_ASPIRE_HEADSET_MIC] = {
6167 .type = HDA_FIXUP_PINS,
6168 .v.pins = (const struct hda_pintbl[]) {
6169 { 0x19, 0x01a1913c }, /* headset mic w/o jack detect */
6170 { }
6171 },
6172 .chained = true,
6173 .chain_id = ALC269_FIXUP_HEADSET_MODE,
6174 },
David Henningsson88cfcf82013-10-11 10:18:45 +02006175 [ALC286_FIXUP_SONY_MIC_NO_PRESENCE] = {
6176 .type = HDA_FIXUP_PINS,
6177 .v.pins = (const struct hda_pintbl[]) {
6178 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6179 { }
6180 },
David Henningssonfbc78ad2013-10-11 13:46:04 +02006181 .chained = true,
6182 .chain_id = ALC269_FIXUP_HEADSET_MIC
David Henningsson88cfcf82013-10-11 10:18:45 +02006183 },
Ayman Bagabas0fbf21c2019-05-23 05:30:11 -04006184 [ALC256_FIXUP_HUAWEI_MACH_WX9_PINS] = {
Ayman Bagabas8ac51bb2018-12-12 18:07:57 -05006185 .type = HDA_FIXUP_PINS,
6186 .v.pins = (const struct hda_pintbl[]) {
6187 {0x12, 0x90a60130},
6188 {0x13, 0x40000000},
6189 {0x14, 0x90170110},
6190 {0x18, 0x411111f0},
6191 {0x19, 0x04a11040},
6192 {0x1a, 0x411111f0},
6193 {0x1b, 0x90170112},
6194 {0x1d, 0x40759a05},
6195 {0x1e, 0x411111f0},
6196 {0x21, 0x04211020},
6197 { }
6198 },
Ayman Bagabase2744fd2018-12-12 18:07:59 -05006199 .chained = true,
6200 .chain_id = ALC255_FIXUP_MIC_MUTE_LED
Ayman Bagabas8ac51bb2018-12-12 18:07:57 -05006201 },
Tomas Espeletaa2ef03f2019-08-09 16:37:54 +02006202 [ALC298_FIXUP_HUAWEI_MBX_STEREO] = {
6203 .type = HDA_FIXUP_FUNC,
6204 .v.func = alc298_fixup_huawei_mbx_stereo,
6205 .chained = true,
6206 .chain_id = ALC255_FIXUP_MIC_MUTE_LED
6207 },
David Henningssond240d1d2013-04-15 12:50:02 +02006208 [ALC269_FIXUP_ASUS_X101_FUNC] = {
6209 .type = HDA_FIXUP_FUNC,
6210 .v.func = alc269_fixup_x101_headset_mic,
6211 },
6212 [ALC269_FIXUP_ASUS_X101_VERB] = {
6213 .type = HDA_FIXUP_VERBS,
6214 .v.verbs = (const struct hda_verb[]) {
6215 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6216 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
6217 {0x20, AC_VERB_SET_PROC_COEF, 0x0310},
6218 { }
6219 },
6220 .chained = true,
6221 .chain_id = ALC269_FIXUP_ASUS_X101_FUNC
6222 },
6223 [ALC269_FIXUP_ASUS_X101] = {
6224 .type = HDA_FIXUP_PINS,
6225 .v.pins = (const struct hda_pintbl[]) {
6226 { 0x18, 0x04a1182c }, /* Headset mic */
6227 { }
6228 },
6229 .chained = true,
6230 .chain_id = ALC269_FIXUP_ASUS_X101_VERB
6231 },
Dylan Reid08a978d2012-11-18 22:56:40 -08006232 [ALC271_FIXUP_AMIC_MIC2] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006233 .type = HDA_FIXUP_PINS,
6234 .v.pins = (const struct hda_pintbl[]) {
Dylan Reid08a978d2012-11-18 22:56:40 -08006235 { 0x14, 0x99130110 }, /* speaker */
6236 { 0x19, 0x01a19c20 }, /* mic */
6237 { 0x1b, 0x99a7012f }, /* int-mic */
6238 { 0x21, 0x0121401f }, /* HP out */
6239 { }
6240 },
6241 },
6242 [ALC271_FIXUP_HP_GATE_MIC_JACK] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006243 .type = HDA_FIXUP_FUNC,
Dylan Reid08a978d2012-11-18 22:56:40 -08006244 .v.func = alc271_hp_gate_mic_jack,
6245 .chained = true,
6246 .chain_id = ALC271_FIXUP_AMIC_MIC2,
6247 },
Oleksij Rempelb1e89722013-12-04 20:50:53 +01006248 [ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572] = {
6249 .type = HDA_FIXUP_FUNC,
6250 .v.func = alc269_fixup_limit_int_mic_boost,
6251 .chained = true,
6252 .chain_id = ALC271_FIXUP_HP_GATE_MIC_JACK,
6253 },
Dylan Reid42397002013-04-05 14:58:22 -07006254 [ALC269_FIXUP_ACER_AC700] = {
6255 .type = HDA_FIXUP_PINS,
6256 .v.pins = (const struct hda_pintbl[]) {
6257 { 0x12, 0x99a3092f }, /* int-mic */
6258 { 0x14, 0x99130110 }, /* speaker */
6259 { 0x18, 0x03a11c20 }, /* mic */
6260 { 0x1e, 0x0346101e }, /* SPDIF1 */
6261 { 0x21, 0x0321101f }, /* HP out */
6262 { }
6263 },
6264 .chained = true,
6265 .chain_id = ALC271_FIXUP_DMIC,
6266 },
David Henningsson3e0d6112013-04-22 14:30:14 +02006267 [ALC269_FIXUP_LIMIT_INT_MIC_BOOST] = {
6268 .type = HDA_FIXUP_FUNC,
6269 .v.func = alc269_fixup_limit_int_mic_boost,
David Henningsson27937692013-11-18 11:51:47 +01006270 .chained = true,
6271 .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
David Henningsson3e0d6112013-04-22 14:30:14 +02006272 },
Oleksij Rempel2cede302013-11-27 17:12:03 +01006273 [ALC269VB_FIXUP_ASUS_ZENBOOK] = {
6274 .type = HDA_FIXUP_FUNC,
6275 .v.func = alc269_fixup_limit_int_mic_boost,
6276 .chained = true,
6277 .chain_id = ALC269VB_FIXUP_DMIC,
6278 },
Takashi Iwai23870832013-11-29 14:13:12 +01006279 [ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A] = {
6280 .type = HDA_FIXUP_VERBS,
6281 .v.verbs = (const struct hda_verb[]) {
6282 /* class-D output amp +5dB */
6283 { 0x20, AC_VERB_SET_COEF_INDEX, 0x12 },
6284 { 0x20, AC_VERB_SET_PROC_COEF, 0x2800 },
6285 {}
6286 },
6287 .chained = true,
6288 .chain_id = ALC269VB_FIXUP_ASUS_ZENBOOK,
6289 },
David Henningsson8e35cd42013-11-06 11:20:01 +01006290 [ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED] = {
6291 .type = HDA_FIXUP_FUNC,
6292 .v.func = alc269_fixup_limit_int_mic_boost,
6293 .chained = true,
6294 .chain_id = ALC269_FIXUP_HP_MUTE_LED_MIC1,
6295 },
Anisse Astier02b504d2013-06-03 11:53:10 +02006296 [ALC269VB_FIXUP_ORDISSIMO_EVE2] = {
6297 .type = HDA_FIXUP_PINS,
6298 .v.pins = (const struct hda_pintbl[]) {
6299 { 0x12, 0x99a3092f }, /* int-mic */
6300 { 0x18, 0x03a11d20 }, /* mic */
6301 { 0x19, 0x411111f0 }, /* Unused bogus pin */
6302 { }
6303 },
6304 },
Kailang Yangcd217a62013-08-22 10:15:24 +02006305 [ALC283_FIXUP_CHROME_BOOK] = {
6306 .type = HDA_FIXUP_FUNC,
6307 .v.func = alc283_fixup_chromebook,
6308 },
Kailang Yang0202e992013-12-02 15:20:15 +08006309 [ALC283_FIXUP_SENSE_COMBO_JACK] = {
6310 .type = HDA_FIXUP_FUNC,
6311 .v.func = alc283_fixup_sense_combo_jack,
6312 .chained = true,
6313 .chain_id = ALC283_FIXUP_CHROME_BOOK,
6314 },
Takashi Iwai7bba2152013-09-06 15:45:38 +02006315 [ALC282_FIXUP_ASUS_TX300] = {
6316 .type = HDA_FIXUP_FUNC,
6317 .v.func = alc282_fixup_asus_tx300,
6318 },
Kailang Yang1bb3e062013-09-27 13:10:25 +02006319 [ALC283_FIXUP_INT_MIC] = {
6320 .type = HDA_FIXUP_VERBS,
6321 .v.verbs = (const struct hda_verb[]) {
6322 {0x20, AC_VERB_SET_COEF_INDEX, 0x1a},
6323 {0x20, AC_VERB_SET_PROC_COEF, 0x0011},
6324 { }
6325 },
6326 .chained = true,
6327 .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST
6328 },
David Henningsson0f4881d2013-12-20 16:08:13 +01006329 [ALC290_FIXUP_SUBWOOFER_HSJACK] = {
6330 .type = HDA_FIXUP_PINS,
6331 .v.pins = (const struct hda_pintbl[]) {
6332 { 0x17, 0x90170112 }, /* subwoofer */
6333 { }
6334 },
6335 .chained = true,
6336 .chain_id = ALC290_FIXUP_MONO_SPEAKERS_HSJACK,
6337 },
6338 [ALC290_FIXUP_SUBWOOFER] = {
6339 .type = HDA_FIXUP_PINS,
6340 .v.pins = (const struct hda_pintbl[]) {
6341 { 0x17, 0x90170112 }, /* subwoofer */
6342 { }
6343 },
6344 .chained = true,
6345 .chain_id = ALC290_FIXUP_MONO_SPEAKERS,
6346 },
David Henningsson338cae52013-10-07 10:39:59 +02006347 [ALC290_FIXUP_MONO_SPEAKERS] = {
6348 .type = HDA_FIXUP_FUNC,
6349 .v.func = alc290_fixup_mono_speakers,
David Henningsson0f4881d2013-12-20 16:08:13 +01006350 },
6351 [ALC290_FIXUP_MONO_SPEAKERS_HSJACK] = {
6352 .type = HDA_FIXUP_FUNC,
6353 .v.func = alc290_fixup_mono_speakers,
David Henningsson338cae52013-10-07 10:39:59 +02006354 .chained = true,
6355 .chain_id = ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
6356 },
David Henningssonb67ae3f2013-11-05 13:11:37 +01006357 [ALC269_FIXUP_THINKPAD_ACPI] = {
6358 .type = HDA_FIXUP_FUNC,
Takashi Iwaid5a6cab2018-06-13 12:43:10 +02006359 .v.func = alc_fixup_thinkpad_acpi,
Takashi Iwai09da1112016-09-08 12:15:02 +02006360 .chained = true,
6361 .chain_id = ALC269_FIXUP_SKU_IGNORE,
David Henningssonb67ae3f2013-11-05 13:11:37 +01006362 },
David Henningsson56f27012016-01-11 09:33:14 +01006363 [ALC269_FIXUP_DMIC_THINKPAD_ACPI] = {
6364 .type = HDA_FIXUP_FUNC,
6365 .v.func = alc_fixup_inv_dmic,
6366 .chained = true,
6367 .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
6368 },
Chris Chiu5824ce82017-02-28 14:17:11 -06006369 [ALC255_FIXUP_ACER_MIC_NO_PRESENCE] = {
Hui Wang17d30462019-06-14 16:44:12 +08006370 .type = HDA_FIXUP_PINS,
6371 .v.pins = (const struct hda_pintbl[]) {
6372 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6373 { }
Chris Chiu5824ce82017-02-28 14:17:11 -06006374 },
6375 .chained = true,
Hui Wang17d30462019-06-14 16:44:12 +08006376 .chain_id = ALC255_FIXUP_HEADSET_MODE
Chris Chiu5824ce82017-02-28 14:17:11 -06006377 },
Chris Chiu615966a2017-02-28 14:17:12 -06006378 [ALC255_FIXUP_ASUS_MIC_NO_PRESENCE] = {
6379 .type = HDA_FIXUP_PINS,
6380 .v.pins = (const struct hda_pintbl[]) {
6381 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6382 { }
6383 },
6384 .chained = true,
6385 .chain_id = ALC255_FIXUP_HEADSET_MODE
6386 },
Kailang Yang9a22a8f52013-11-08 15:54:49 +08006387 [ALC255_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6388 .type = HDA_FIXUP_PINS,
6389 .v.pins = (const struct hda_pintbl[]) {
6390 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6391 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6392 { }
6393 },
6394 .chained = true,
6395 .chain_id = ALC255_FIXUP_HEADSET_MODE
6396 },
Kailang Yang31278992014-03-03 15:27:22 +08006397 [ALC255_FIXUP_DELL2_MIC_NO_PRESENCE] = {
6398 .type = HDA_FIXUP_PINS,
6399 .v.pins = (const struct hda_pintbl[]) {
6400 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6401 { }
6402 },
6403 .chained = true,
6404 .chain_id = ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC
6405 },
Kailang Yang9a22a8f52013-11-08 15:54:49 +08006406 [ALC255_FIXUP_HEADSET_MODE] = {
6407 .type = HDA_FIXUP_FUNC,
6408 .v.func = alc_fixup_headset_mode_alc255,
Hui Wang4a83d422014-11-18 17:57:40 +08006409 .chained = true,
Takashi Iwaib3802782018-11-26 17:47:46 +01006410 .chain_id = ALC255_FIXUP_MIC_MUTE_LED
Kailang Yang9a22a8f52013-11-08 15:54:49 +08006411 },
Kailang Yang31278992014-03-03 15:27:22 +08006412 [ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC] = {
6413 .type = HDA_FIXUP_FUNC,
6414 .v.func = alc_fixup_headset_mode_alc255_no_hp_mic,
6415 },
Kailang Yanga22aa262014-04-23 17:34:28 +08006416 [ALC293_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6417 .type = HDA_FIXUP_PINS,
6418 .v.pins = (const struct hda_pintbl[]) {
6419 { 0x18, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6420 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6421 { }
6422 },
6423 .chained = true,
6424 .chain_id = ALC269_FIXUP_HEADSET_MODE
6425 },
Takashi Iwai1c37c222014-05-06 17:34:42 +02006426 [ALC292_FIXUP_TPT440_DOCK] = {
David Henningssonec56af62015-06-24 10:46:33 +02006427 .type = HDA_FIXUP_FUNC,
Takashi Iwai7f57d802015-09-24 17:36:51 +02006428 .v.func = alc_fixup_tpt440_dock,
Takashi Iwai1c37c222014-05-06 17:34:42 +02006429 .chained = true,
6430 .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST
6431 },
Takashi Iwai9a811232015-12-09 15:17:43 +01006432 [ALC292_FIXUP_TPT440] = {
6433 .type = HDA_FIXUP_FUNC,
Takashi Iwai157f0b72015-12-10 23:30:43 +01006434 .v.func = alc_fixup_disable_aamix,
Takashi Iwai9a811232015-12-09 15:17:43 +01006435 .chained = true,
6436 .chain_id = ALC292_FIXUP_TPT440_DOCK,
6437 },
Anisse Astierabaa22742016-08-24 09:14:13 +02006438 [ALC283_FIXUP_HEADSET_MIC] = {
Daniel Drake9dc12862014-07-22 10:58:29 +01006439 .type = HDA_FIXUP_PINS,
6440 .v.pins = (const struct hda_pintbl[]) {
6441 { 0x19, 0x04a110f0 },
6442 { },
6443 },
6444 },
Takashi Iwaib3802782018-11-26 17:47:46 +01006445 [ALC255_FIXUP_MIC_MUTE_LED] = {
Hui Wang00ef9942014-07-31 11:52:38 +08006446 .type = HDA_FIXUP_FUNC,
Takashi Iwaib3802782018-11-26 17:47:46 +01006447 .v.func = snd_hda_gen_fixup_micmute_led,
Hui Wang00ef9942014-07-31 11:52:38 +08006448 },
Takashi Iwai1a22e772014-08-27 08:19:05 +02006449 [ALC282_FIXUP_ASPIRE_V5_PINS] = {
6450 .type = HDA_FIXUP_PINS,
6451 .v.pins = (const struct hda_pintbl[]) {
6452 { 0x12, 0x90a60130 },
6453 { 0x14, 0x90170110 },
6454 { 0x17, 0x40000008 },
6455 { 0x18, 0x411111f0 },
Mateusz Sylwestrzak04206942015-07-19 17:38:56 +02006456 { 0x19, 0x01a1913c },
Takashi Iwai1a22e772014-08-27 08:19:05 +02006457 { 0x1a, 0x411111f0 },
6458 { 0x1b, 0x411111f0 },
6459 { 0x1d, 0x40f89b2d },
6460 { 0x1e, 0x411111f0 },
6461 { 0x21, 0x0321101f },
6462 { },
6463 },
6464 },
David Henningsson7a5255f2014-10-30 08:26:01 +01006465 [ALC280_FIXUP_HP_GPIO4] = {
6466 .type = HDA_FIXUP_FUNC,
6467 .v.func = alc280_fixup_hp_gpio4,
6468 },
Kailang Yangeaa8e5e2014-11-21 15:49:11 +08006469 [ALC286_FIXUP_HP_GPIO_LED] = {
6470 .type = HDA_FIXUP_FUNC,
6471 .v.func = alc286_fixup_hp_gpio_led,
6472 },
David Henningsson33f4acd2015-01-07 15:50:13 +01006473 [ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY] = {
6474 .type = HDA_FIXUP_FUNC,
6475 .v.func = alc280_fixup_hp_gpio2_mic_hotkey,
6476 },
TienFu Chenb4b33f92015-01-20 15:06:21 +01006477 [ALC280_FIXUP_HP_DOCK_PINS] = {
6478 .type = HDA_FIXUP_PINS,
6479 .v.pins = (const struct hda_pintbl[]) {
6480 { 0x1b, 0x21011020 }, /* line-out */
6481 { 0x1a, 0x01a1903c }, /* headset mic */
6482 { 0x18, 0x2181103f }, /* line-in */
6483 { },
6484 },
6485 .chained = true,
6486 .chain_id = ALC280_FIXUP_HP_GPIO4
6487 },
Jaroslav Kysela04d54662017-03-09 13:29:13 +01006488 [ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED] = {
6489 .type = HDA_FIXUP_PINS,
6490 .v.pins = (const struct hda_pintbl[]) {
6491 { 0x1b, 0x21011020 }, /* line-out */
6492 { 0x18, 0x2181103f }, /* line-in */
6493 { },
6494 },
6495 .chained = true,
6496 .chain_id = ALC269_FIXUP_HP_GPIO_MIC1_LED
6497 },
Keith Packard98973f22015-07-15 12:14:39 -07006498 [ALC280_FIXUP_HP_9480M] = {
6499 .type = HDA_FIXUP_FUNC,
6500 .v.func = alc280_fixup_hp_9480m,
6501 },
Kailang Yange1e62b92015-04-08 16:01:22 +08006502 [ALC288_FIXUP_DELL_HEADSET_MODE] = {
6503 .type = HDA_FIXUP_FUNC,
6504 .v.func = alc_fixup_headset_mode_dell_alc288,
6505 .chained = true,
Takashi Iwaib3802782018-11-26 17:47:46 +01006506 .chain_id = ALC255_FIXUP_MIC_MUTE_LED
Kailang Yange1e62b92015-04-08 16:01:22 +08006507 },
6508 [ALC288_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6509 .type = HDA_FIXUP_PINS,
6510 .v.pins = (const struct hda_pintbl[]) {
6511 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6512 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6513 { }
6514 },
6515 .chained = true,
6516 .chain_id = ALC288_FIXUP_DELL_HEADSET_MODE
6517 },
Hui Wang831bfdf92015-06-26 12:35:17 +08006518 [ALC288_FIXUP_DISABLE_AAMIX] = {
6519 .type = HDA_FIXUP_FUNC,
6520 .v.func = alc_fixup_disable_aamix,
6521 .chained = true,
Takashi Iwaid44a6862018-06-19 23:04:03 +02006522 .chain_id = ALC288_FIXUP_DELL1_MIC_NO_PRESENCE
Hui Wang831bfdf92015-06-26 12:35:17 +08006523 },
6524 [ALC288_FIXUP_DELL_XPS_13] = {
6525 .type = HDA_FIXUP_FUNC,
6526 .v.func = alc_fixup_dell_xps13,
6527 .chained = true,
6528 .chain_id = ALC288_FIXUP_DISABLE_AAMIX
6529 },
Takashi Iwai8b99aba2015-06-15 11:59:32 +02006530 [ALC292_FIXUP_DISABLE_AAMIX] = {
6531 .type = HDA_FIXUP_FUNC,
6532 .v.func = alc_fixup_disable_aamix,
Hui Wang831bfdf92015-06-26 12:35:17 +08006533 .chained = true,
6534 .chain_id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE
Takashi Iwai8b99aba2015-06-15 11:59:32 +02006535 },
David Henningssonc04017e2015-12-15 14:44:03 +01006536 [ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK] = {
6537 .type = HDA_FIXUP_FUNC,
6538 .v.func = alc_fixup_disable_aamix,
6539 .chained = true,
6540 .chain_id = ALC293_FIXUP_DELL1_MIC_NO_PRESENCE
6541 },
Takashi Iwai8b99aba2015-06-15 11:59:32 +02006542 [ALC292_FIXUP_DELL_E7X] = {
6543 .type = HDA_FIXUP_FUNC,
6544 .v.func = alc_fixup_dell_xps13,
6545 .chained = true,
6546 .chain_id = ALC292_FIXUP_DISABLE_AAMIX
6547 },
James McDonnell54324222019-09-16 14:53:38 +00006548 [ALC298_FIXUP_ALIENWARE_MIC_NO_PRESENCE] = {
6549 .type = HDA_FIXUP_PINS,
6550 .v.pins = (const struct hda_pintbl[]) {
6551 { 0x18, 0x01a1913c }, /* headset mic w/o jack detect */
6552 { }
6553 },
6554 .chained_before = true,
6555 .chain_id = ALC269_FIXUP_HEADSET_MODE,
6556 },
Kailang Yang977e6272015-05-18 15:31:20 +08006557 [ALC298_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6558 .type = HDA_FIXUP_PINS,
6559 .v.pins = (const struct hda_pintbl[]) {
6560 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6561 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6562 { }
6563 },
6564 .chained = true,
6565 .chain_id = ALC269_FIXUP_HEADSET_MODE
6566 },
Hui Wang2f726ae2017-03-31 10:31:40 +08006567 [ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE] = {
6568 .type = HDA_FIXUP_PINS,
6569 .v.pins = (const struct hda_pintbl[]) {
6570 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6571 { }
6572 },
6573 .chained = true,
6574 .chain_id = ALC269_FIXUP_HEADSET_MODE
6575 },
Kailang Yang6ed11312015-10-26 15:37:39 +08006576 [ALC275_FIXUP_DELL_XPS] = {
6577 .type = HDA_FIXUP_VERBS,
6578 .v.verbs = (const struct hda_verb[]) {
6579 /* Enables internal speaker */
6580 {0x20, AC_VERB_SET_COEF_INDEX, 0x1f},
6581 {0x20, AC_VERB_SET_PROC_COEF, 0x00c0},
6582 {0x20, AC_VERB_SET_COEF_INDEX, 0x30},
6583 {0x20, AC_VERB_SET_PROC_COEF, 0x00b1},
6584 {}
6585 }
6586 },
Hui Wang8c697292015-11-24 11:08:18 +08006587 [ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE] = {
6588 .type = HDA_FIXUP_VERBS,
6589 .v.verbs = (const struct hda_verb[]) {
6590 /* Disable pass-through path for FRONT 14h */
6591 {0x20, AC_VERB_SET_COEF_INDEX, 0x36},
6592 {0x20, AC_VERB_SET_PROC_COEF, 0x1737},
6593 {}
6594 },
6595 .chained = true,
6596 .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
6597 },
Kai-Heng Feng1099f482019-10-03 12:39:19 +08006598 [ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE2] = {
6599 .type = HDA_FIXUP_FUNC,
6600 .v.func = alc256_fixup_dell_xps_13_headphone_noise2,
6601 .chained = true,
6602 .chain_id = ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE
6603 },
Hui Wang23adc192015-12-08 12:27:18 +08006604 [ALC293_FIXUP_LENOVO_SPK_NOISE] = {
6605 .type = HDA_FIXUP_FUNC,
6606 .v.func = alc_fixup_disable_aamix,
6607 .chained = true,
6608 .chain_id = ALC269_FIXUP_THINKPAD_ACPI
6609 },
Kailang3694cb22015-12-28 11:35:24 +08006610 [ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY] = {
6611 .type = HDA_FIXUP_FUNC,
6612 .v.func = alc233_fixup_lenovo_line2_mic_hotkey,
6613 },
Kai-Heng Feng3b43b712016-02-25 15:19:38 +08006614 [ALC255_FIXUP_DELL_SPK_NOISE] = {
6615 .type = HDA_FIXUP_FUNC,
6616 .v.func = alc_fixup_disable_aamix,
6617 .chained = true,
6618 .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
6619 },
Kailang Yangd1dd4212019-01-09 17:05:24 +08006620 [ALC225_FIXUP_DISABLE_MIC_VREF] = {
6621 .type = HDA_FIXUP_FUNC,
6622 .v.func = alc_fixup_disable_mic_vref,
6623 .chained = true,
6624 .chain_id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE
6625 },
David Henningsson2ae95572016-02-25 09:37:05 +01006626 [ALC225_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6627 .type = HDA_FIXUP_VERBS,
6628 .v.verbs = (const struct hda_verb[]) {
6629 /* Disable pass-through path for FRONT 14h */
6630 { 0x20, AC_VERB_SET_COEF_INDEX, 0x36 },
6631 { 0x20, AC_VERB_SET_PROC_COEF, 0x57d7 },
6632 {}
6633 },
6634 .chained = true,
Kailang Yangd1dd4212019-01-09 17:05:24 +08006635 .chain_id = ALC225_FIXUP_DISABLE_MIC_VREF
David Henningsson2ae95572016-02-25 09:37:05 +01006636 },
Takashi Iwaif8839822016-02-25 14:31:59 +01006637 [ALC280_FIXUP_HP_HEADSET_MIC] = {
6638 .type = HDA_FIXUP_FUNC,
6639 .v.func = alc_fixup_disable_aamix,
6640 .chained = true,
6641 .chain_id = ALC269_FIXUP_HEADSET_MIC,
6642 },
Hui Wange549d192016-04-01 11:00:15 +08006643 [ALC221_FIXUP_HP_FRONT_MIC] = {
6644 .type = HDA_FIXUP_PINS,
6645 .v.pins = (const struct hda_pintbl[]) {
6646 { 0x19, 0x02a19020 }, /* Front Mic */
6647 { }
6648 },
6649 },
Sven Eckelmannc636b952016-04-11 16:55:26 +02006650 [ALC292_FIXUP_TPT460] = {
6651 .type = HDA_FIXUP_FUNC,
6652 .v.func = alc_fixup_tpt440_dock,
6653 .chained = true,
6654 .chain_id = ALC293_FIXUP_LENOVO_SPK_NOISE,
6655 },
Hui Wangdd9aa332016-08-01 10:20:32 +08006656 [ALC298_FIXUP_SPK_VOLUME] = {
6657 .type = HDA_FIXUP_FUNC,
6658 .v.func = alc298_fixup_speaker_volume,
Hui Wang59ec4b52016-08-04 15:28:04 +08006659 .chained = true,
Hui Wang2f726ae2017-03-31 10:31:40 +08006660 .chain_id = ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE,
Hui Wangdd9aa332016-08-01 10:20:32 +08006661 },
Takashi Iwaie312a862018-03-06 12:14:17 +01006662 [ALC295_FIXUP_DISABLE_DAC3] = {
6663 .type = HDA_FIXUP_FUNC,
6664 .v.func = alc295_fixup_disable_dac3,
6665 },
Jaroslav Kyselad2cd7952019-11-29 15:40:27 +01006666 [ALC285_FIXUP_SPEAKER2_TO_DAC1] = {
6667 .type = HDA_FIXUP_FUNC,
6668 .v.func = alc285_fixup_speaker2_to_dac1,
6669 },
Kai-Heng Fengfd06c772016-08-30 15:36:34 +08006670 [ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER] = {
6671 .type = HDA_FIXUP_PINS,
6672 .v.pins = (const struct hda_pintbl[]) {
6673 { 0x1b, 0x90170151 },
6674 { }
6675 },
6676 .chained = true,
6677 .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
6678 },
Gabriele Mazzotta823ff162016-12-24 19:50:01 +01006679 [ALC269_FIXUP_ATIV_BOOK_8] = {
6680 .type = HDA_FIXUP_FUNC,
6681 .v.func = alc_fixup_auto_mute_via_amp,
6682 .chained = true,
6683 .chain_id = ALC269_FIXUP_NO_SHUTUP
6684 },
Kailang Yang9eb5d0e2017-01-17 15:40:25 +08006685 [ALC221_FIXUP_HP_MIC_NO_PRESENCE] = {
6686 .type = HDA_FIXUP_PINS,
6687 .v.pins = (const struct hda_pintbl[]) {
6688 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6689 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6690 { }
6691 },
6692 .chained = true,
6693 .chain_id = ALC269_FIXUP_HEADSET_MODE
6694 },
Chris Chiuc1732ed2017-02-28 14:17:13 -06006695 [ALC256_FIXUP_ASUS_HEADSET_MODE] = {
6696 .type = HDA_FIXUP_FUNC,
6697 .v.func = alc_fixup_headset_mode,
6698 },
6699 [ALC256_FIXUP_ASUS_MIC] = {
6700 .type = HDA_FIXUP_PINS,
6701 .v.pins = (const struct hda_pintbl[]) {
6702 { 0x13, 0x90a60160 }, /* use as internal mic */
6703 { 0x19, 0x04a11120 }, /* use as headset mic, without its own jack detect */
6704 { }
6705 },
6706 .chained = true,
6707 .chain_id = ALC256_FIXUP_ASUS_HEADSET_MODE
6708 },
Chris Chiueeed4cd2017-02-28 14:17:15 -06006709 [ALC256_FIXUP_ASUS_AIO_GPIO2] = {
Takashi Iwaiae065f12018-06-19 23:00:03 +02006710 .type = HDA_FIXUP_FUNC,
6711 /* Set up GPIO2 for the speaker amp */
6712 .v.func = alc_fixup_gpio4,
Chris Chiueeed4cd2017-02-28 14:17:15 -06006713 },
Chris Chiu216d7ae2017-02-28 14:17:14 -06006714 [ALC233_FIXUP_ASUS_MIC_NO_PRESENCE] = {
6715 .type = HDA_FIXUP_PINS,
6716 .v.pins = (const struct hda_pintbl[]) {
6717 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6718 { }
6719 },
6720 .chained = true,
6721 .chain_id = ALC269_FIXUP_HEADSET_MIC
6722 },
6723 [ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE] = {
6724 .type = HDA_FIXUP_VERBS,
6725 .v.verbs = (const struct hda_verb[]) {
6726 /* Enables internal speaker */
6727 {0x20, AC_VERB_SET_COEF_INDEX, 0x40},
6728 {0x20, AC_VERB_SET_PROC_COEF, 0x8800},
6729 {}
6730 },
6731 .chained = true,
6732 .chain_id = ALC233_FIXUP_ASUS_MIC_NO_PRESENCE
6733 },
Kailang Yangca169cc2017-04-25 16:17:40 +08006734 [ALC233_FIXUP_LENOVO_MULTI_CODECS] = {
6735 .type = HDA_FIXUP_FUNC,
6736 .v.func = alc233_alc662_fixup_lenovo_dual_codecs,
6737 },
Jian-Hong Panea5c7eb2019-04-01 11:25:05 +08006738 [ALC233_FIXUP_ACER_HEADSET_MIC] = {
6739 .type = HDA_FIXUP_VERBS,
6740 .v.verbs = (const struct hda_verb[]) {
6741 { 0x20, AC_VERB_SET_COEF_INDEX, 0x45 },
6742 { 0x20, AC_VERB_SET_PROC_COEF, 0x5089 },
6743 { }
6744 },
6745 .chained = true,
6746 .chain_id = ALC233_FIXUP_ASUS_MIC_NO_PRESENCE
6747 },
Hui Wangf33f79f2017-07-07 12:08:29 +08006748 [ALC294_FIXUP_LENOVO_MIC_LOCATION] = {
6749 .type = HDA_FIXUP_PINS,
6750 .v.pins = (const struct hda_pintbl[]) {
6751 /* Change the mic location from front to right, otherwise there are
6752 two front mics with the same name, pulseaudio can't handle them.
6753 This is just a temporary workaround, after applying this fixup,
6754 there will be one "Front Mic" and one "Mic" in this machine.
6755 */
6756 { 0x1a, 0x04a19040 },
6757 { }
6758 },
6759 },
Kailang Yang5f364132017-07-25 16:28:16 +08006760 [ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE] = {
6761 .type = HDA_FIXUP_PINS,
6762 .v.pins = (const struct hda_pintbl[]) {
6763 { 0x16, 0x0101102f }, /* Rear Headset HP */
6764 { 0x19, 0x02a1913c }, /* use as Front headset mic, without its own jack detect */
6765 { 0x1a, 0x01a19030 }, /* Rear Headset MIC */
6766 { 0x1b, 0x02011020 },
6767 { }
6768 },
6769 .chained = true,
6770 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
6771 },
PeiSen Houb84e8432017-09-01 15:11:56 +08006772 [ALC700_FIXUP_INTEL_REFERENCE] = {
6773 .type = HDA_FIXUP_VERBS,
6774 .v.verbs = (const struct hda_verb[]) {
6775 /* Enables internal speaker */
6776 {0x20, AC_VERB_SET_COEF_INDEX, 0x45},
6777 {0x20, AC_VERB_SET_PROC_COEF, 0x5289},
6778 {0x20, AC_VERB_SET_COEF_INDEX, 0x4A},
6779 {0x20, AC_VERB_SET_PROC_COEF, 0x001b},
6780 {0x58, AC_VERB_SET_COEF_INDEX, 0x00},
6781 {0x58, AC_VERB_SET_PROC_COEF, 0x3888},
6782 {0x20, AC_VERB_SET_COEF_INDEX, 0x6f},
6783 {0x20, AC_VERB_SET_PROC_COEF, 0x2c0b},
6784 {}
6785 }
6786 },
Kailang Yang92266652017-12-14 15:28:58 +08006787 [ALC274_FIXUP_DELL_BIND_DACS] = {
6788 .type = HDA_FIXUP_FUNC,
6789 .v.func = alc274_fixup_bind_dacs,
6790 .chained = true,
6791 .chain_id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE
6792 },
6793 [ALC274_FIXUP_DELL_AIO_LINEOUT_VERB] = {
6794 .type = HDA_FIXUP_PINS,
6795 .v.pins = (const struct hda_pintbl[]) {
6796 { 0x1b, 0x0401102f },
6797 { }
6798 },
6799 .chained = true,
6800 .chain_id = ALC274_FIXUP_DELL_BIND_DACS
6801 },
Kailang Yang61fcf8e2018-02-02 15:26:46 +08006802 [ALC298_FIXUP_TPT470_DOCK] = {
6803 .type = HDA_FIXUP_FUNC,
6804 .v.func = alc_fixup_tpt470_dock,
6805 .chained = true,
6806 .chain_id = ALC293_FIXUP_LENOVO_SPK_NOISE
6807 },
Kailang Yangae104a22018-02-05 16:07:20 +08006808 [ALC255_FIXUP_DUMMY_LINEOUT_VERB] = {
6809 .type = HDA_FIXUP_PINS,
6810 .v.pins = (const struct hda_pintbl[]) {
6811 { 0x14, 0x0201101f },
6812 { }
6813 },
6814 .chained = true,
6815 .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
6816 },
Kailang Yangf0ba9d62018-03-16 11:46:08 +08006817 [ALC255_FIXUP_DELL_HEADSET_MIC] = {
6818 .type = HDA_FIXUP_PINS,
6819 .v.pins = (const struct hda_pintbl[]) {
6820 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6821 { }
6822 },
Hui Wang3ce0d5a2018-04-19 13:29:04 +08006823 .chained = true,
6824 .chain_id = ALC269_FIXUP_HEADSET_MIC
Kailang Yangf0ba9d62018-03-16 11:46:08 +08006825 },
Tom Bridenbbf8ff62018-05-29 17:34:20 +01006826 [ALC295_FIXUP_HP_X360] = {
6827 .type = HDA_FIXUP_FUNC,
6828 .v.func = alc295_fixup_hp_top_speakers,
6829 .chained = true,
6830 .chain_id = ALC269_FIXUP_HP_MUTE_LED_MIC3
Kailang Yang8a328ac2018-08-21 16:54:41 +08006831 },
6832 [ALC221_FIXUP_HP_HEADSET_MIC] = {
6833 .type = HDA_FIXUP_PINS,
6834 .v.pins = (const struct hda_pintbl[]) {
6835 { 0x19, 0x0181313f},
6836 { }
6837 },
6838 .chained = true,
6839 .chain_id = ALC269_FIXUP_HEADSET_MIC
6840 },
Hui Wangc4cfcf62018-11-26 14:17:16 +08006841 [ALC285_FIXUP_LENOVO_HEADPHONE_NOISE] = {
6842 .type = HDA_FIXUP_FUNC,
6843 .v.func = alc285_fixup_invalidate_dacs,
Hui Wang6ba189c2018-12-09 09:16:43 +08006844 .chained = true,
6845 .chain_id = ALC269_FIXUP_THINKPAD_ACPI
Hui Wangc4cfcf62018-11-26 14:17:16 +08006846 },
Girija Kumar Kasinadhunie8ed64b2018-11-26 13:40:46 -05006847 [ALC295_FIXUP_HP_AUTO_MUTE] = {
6848 .type = HDA_FIXUP_FUNC,
6849 .v.func = alc_fixup_auto_mute_via_amp,
6850 },
Chris Chiu33aaebd2018-12-05 14:48:53 +08006851 [ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE] = {
6852 .type = HDA_FIXUP_PINS,
6853 .v.pins = (const struct hda_pintbl[]) {
6854 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6855 { }
6856 },
6857 .chained = true,
6858 .chain_id = ALC269_FIXUP_HEADSET_MIC
6859 },
Chris Chiud8ae4582018-12-07 17:17:11 +08006860 [ALC294_FIXUP_ASUS_MIC] = {
6861 .type = HDA_FIXUP_PINS,
6862 .v.pins = (const struct hda_pintbl[]) {
6863 { 0x13, 0x90a60160 }, /* use as internal mic */
6864 { 0x19, 0x04a11120 }, /* use as headset mic, without its own jack detect */
6865 { }
6866 },
6867 .chained = true,
6868 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
6869 },
Jian-Hong Pan4e051102018-12-07 17:17:12 +08006870 [ALC294_FIXUP_ASUS_HEADSET_MIC] = {
6871 .type = HDA_FIXUP_PINS,
6872 .v.pins = (const struct hda_pintbl[]) {
Jian-Hong Pan82b01142018-12-27 16:46:31 +08006873 { 0x19, 0x01a1103c }, /* use as headset mic */
Jian-Hong Pan4e051102018-12-07 17:17:12 +08006874 { }
6875 },
6876 .chained = true,
6877 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
6878 },
6879 [ALC294_FIXUP_ASUS_SPK] = {
6880 .type = HDA_FIXUP_VERBS,
6881 .v.verbs = (const struct hda_verb[]) {
6882 /* Set EAPD high */
6883 { 0x20, AC_VERB_SET_COEF_INDEX, 0x40 },
6884 { 0x20, AC_VERB_SET_PROC_COEF, 0x8800 },
6885 { }
6886 },
6887 .chained = true,
6888 .chain_id = ALC294_FIXUP_ASUS_HEADSET_MIC
6889 },
Jaroslav Kyselac8a9afa2019-03-14 09:21:08 +01006890 [ALC295_FIXUP_CHROME_BOOK] = {
Kailang Yange8547472018-11-28 15:32:45 +08006891 .type = HDA_FIXUP_FUNC,
Jaroslav Kyselac8a9afa2019-03-14 09:21:08 +01006892 .v.func = alc295_fixup_chromebook,
Kailang Yang8983eb62019-04-03 15:31:49 +08006893 .chained = true,
6894 .chain_id = ALC225_FIXUP_HEADSET_JACK
6895 },
6896 [ALC225_FIXUP_HEADSET_JACK] = {
6897 .type = HDA_FIXUP_FUNC,
6898 .v.func = alc_fixup_headset_jack,
Kailang Yange8547472018-11-28 15:32:45 +08006899 },
Jeremy Soller89e3a562019-01-30 16:12:31 -07006900 [ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE] = {
6901 .type = HDA_FIXUP_PINS,
6902 .v.pins = (const struct hda_pintbl[]) {
6903 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6904 { }
6905 },
6906 .chained = true,
6907 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
6908 },
Hui Wangc8c6ee62019-02-14 11:41:33 +08006909 [ALC285_FIXUP_LENOVO_PC_BEEP_IN_NOISE] = {
6910 .type = HDA_FIXUP_VERBS,
6911 .v.verbs = (const struct hda_verb[]) {
6912 /* Disable PCBEEP-IN passthrough */
6913 { 0x20, AC_VERB_SET_COEF_INDEX, 0x36 },
6914 { 0x20, AC_VERB_SET_PROC_COEF, 0x57d7 },
6915 { }
6916 },
6917 .chained = true,
6918 .chain_id = ALC285_FIXUP_LENOVO_HEADPHONE_NOISE
6919 },
Jian-Hong Pancbc05fd2019-03-13 17:33:24 +08006920 [ALC255_FIXUP_ACER_HEADSET_MIC] = {
6921 .type = HDA_FIXUP_PINS,
6922 .v.pins = (const struct hda_pintbl[]) {
6923 { 0x19, 0x03a11130 },
6924 { 0x1a, 0x90a60140 }, /* use as internal mic */
6925 { }
6926 },
6927 .chained = true,
6928 .chain_id = ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC
6929 },
Kailang Yang136824e2019-03-14 16:22:45 +08006930 [ALC225_FIXUP_DELL_WYSE_AIO_MIC_NO_PRESENCE] = {
6931 .type = HDA_FIXUP_PINS,
6932 .v.pins = (const struct hda_pintbl[]) {
6933 { 0x16, 0x01011020 }, /* Rear Line out */
6934 { 0x19, 0x01a1913c }, /* use as Front headset mic, without its own jack detect */
6935 { }
6936 },
6937 .chained = true,
6938 .chain_id = ALC225_FIXUP_WYSE_AUTO_MUTE
6939 },
6940 [ALC225_FIXUP_WYSE_AUTO_MUTE] = {
6941 .type = HDA_FIXUP_FUNC,
6942 .v.func = alc_fixup_auto_mute_via_amp,
6943 .chained = true,
6944 .chain_id = ALC225_FIXUP_WYSE_DISABLE_MIC_VREF
6945 },
6946 [ALC225_FIXUP_WYSE_DISABLE_MIC_VREF] = {
6947 .type = HDA_FIXUP_FUNC,
6948 .v.func = alc_fixup_disable_mic_vref,
6949 .chained = true,
6950 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
6951 },
Jian-Hong Pan667a8f72019-03-15 17:51:09 +08006952 [ALC286_FIXUP_ACER_AIO_HEADSET_MIC] = {
6953 .type = HDA_FIXUP_VERBS,
6954 .v.verbs = (const struct hda_verb[]) {
6955 { 0x20, AC_VERB_SET_COEF_INDEX, 0x4f },
6956 { 0x20, AC_VERB_SET_PROC_COEF, 0x5029 },
6957 { }
6958 },
6959 .chained = true,
6960 .chain_id = ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE
6961 },
Daniel Drake8c8967a2019-10-17 16:15:01 +08006962 [ALC256_FIXUP_ASUS_HEADSET_MIC] = {
6963 .type = HDA_FIXUP_PINS,
6964 .v.pins = (const struct hda_pintbl[]) {
6965 { 0x19, 0x03a11020 }, /* headset mic with jack detect */
6966 { }
6967 },
6968 .chained = true,
6969 .chain_id = ALC256_FIXUP_ASUS_HEADSET_MODE
6970 },
Jian-Hong Pane1037352019-03-22 11:37:18 +08006971 [ALC256_FIXUP_ASUS_MIC_NO_PRESENCE] = {
6972 .type = HDA_FIXUP_PINS,
6973 .v.pins = (const struct hda_pintbl[]) {
6974 { 0x19, 0x04a11120 }, /* use as headset mic, without its own jack detect */
6975 { }
6976 },
6977 .chained = true,
6978 .chain_id = ALC256_FIXUP_ASUS_HEADSET_MODE
6979 },
Bernhard Rosenkraenzere2a829b2019-03-05 00:38:19 +01006980 [ALC299_FIXUP_PREDATOR_SPK] = {
6981 .type = HDA_FIXUP_PINS,
6982 .v.pins = (const struct hda_pintbl[]) {
6983 { 0x21, 0x90170150 }, /* use as headset mic, without its own jack detect */
6984 { }
6985 }
6986 },
Jian-Hong Pan60083f92019-09-02 18:00:56 +08006987 [ALC294_FIXUP_ASUS_INTSPK_HEADSET_MIC] = {
6988 .type = HDA_FIXUP_PINS,
6989 .v.pins = (const struct hda_pintbl[]) {
6990 { 0x14, 0x411111f0 }, /* disable confusing internal speaker */
6991 { 0x19, 0x04a11150 }, /* use as headset mic, without its own jack detect */
6992 { }
6993 },
6994 .chained = true,
6995 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
6996 },
Jan-Marek Glogowskibd9c10b2019-09-15 16:57:28 +02006997 [ALC256_FIXUP_MEDION_HEADSET_NO_PRESENCE] = {
6998 .type = HDA_FIXUP_PINS,
6999 .v.pins = (const struct hda_pintbl[]) {
7000 { 0x19, 0x04a11040 },
7001 { 0x21, 0x04211020 },
7002 { }
7003 },
7004 .chained = true,
7005 .chain_id = ALC256_FIXUP_ASUS_HEADSET_MODE
7006 },
Jian-Hong Pan436e2552019-11-25 17:34:06 +08007007 [ALC294_FIXUP_ASUS_INTSPK_GPIO] = {
7008 .type = HDA_FIXUP_FUNC,
7009 /* The GPIO must be pulled to initialize the AMP */
7010 .v.func = alc_fixup_gpio4,
7011 .chained = true,
7012 .chain_id = ALC294_FIXUP_ASUS_INTSPK_HEADSET_MIC
7013 },
Kailang Yange79c2262019-12-19 14:12:15 +08007014 [ALC289_FIXUP_DELL_SPK2] = {
7015 .type = HDA_FIXUP_PINS,
7016 .v.pins = (const struct hda_pintbl[]) {
7017 { 0x17, 0x90170130 }, /* bass spk */
7018 { }
7019 },
7020 .chained = true,
7021 .chain_id = ALC269_FIXUP_DELL4_MIC_NO_PRESENCE
7022 },
7023 [ALC289_FIXUP_DUAL_SPK] = {
7024 .type = HDA_FIXUP_FUNC,
7025 .v.func = alc285_fixup_speaker2_to_dac1,
7026 .chained = true,
7027 .chain_id = ALC289_FIXUP_DELL_SPK2
7028 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02007029};
7030
7031static const struct snd_pci_quirk alc269_fixup_tbl[] = {
Marius Knausta6b92b62014-03-03 01:48:58 +01007032 SND_PCI_QUIRK(0x1025, 0x0283, "Acer TravelMate 8371", ALC269_FIXUP_INV_DMIC),
David Henningsson693b6132012-06-22 19:12:10 +02007033 SND_PCI_QUIRK(0x1025, 0x029b, "Acer 1810TZ", ALC269_FIXUP_INV_DMIC),
7034 SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC),
David Henningssonaaedfb42013-08-16 14:09:02 +02007035 SND_PCI_QUIRK(0x1025, 0x047c, "Acer AC700", ALC269_FIXUP_ACER_AC700),
Takashi Iwai78197172015-06-27 10:21:13 +02007036 SND_PCI_QUIRK(0x1025, 0x072d, "Acer Aspire V5-571G", ALC269_FIXUP_ASPIRE_HEADSET_MIC),
7037 SND_PCI_QUIRK(0x1025, 0x080d, "Acer Aspire V5-122P", ALC269_FIXUP_ASPIRE_HEADSET_MIC),
David Henningssonaaedfb42013-08-16 14:09:02 +02007038 SND_PCI_QUIRK(0x1025, 0x0740, "Acer AO725", ALC271_FIXUP_HP_GATE_MIC_JACK),
7039 SND_PCI_QUIRK(0x1025, 0x0742, "Acer AO756", ALC271_FIXUP_HP_GATE_MIC_JACK),
Simon South02322ac2016-03-02 23:10:44 -05007040 SND_PCI_QUIRK(0x1025, 0x0762, "Acer Aspire E1-472", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572),
Oleksij Rempelb1e89722013-12-04 20:50:53 +01007041 SND_PCI_QUIRK(0x1025, 0x0775, "Acer Aspire E1-572", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572),
Takashi Iwai1a22e772014-08-27 08:19:05 +02007042 SND_PCI_QUIRK(0x1025, 0x079b, "Acer Aspire V5-573G", ALC282_FIXUP_ASPIRE_V5_PINS),
Chris Chiu705b65f2018-12-05 14:48:54 +08007043 SND_PCI_QUIRK(0x1025, 0x102b, "Acer Aspire C24-860", ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE),
Takashi Iwaib9c2fa52015-11-19 16:39:50 +01007044 SND_PCI_QUIRK(0x1025, 0x106d, "Acer Cloudbook 14", ALC283_FIXUP_CHROME_BOOK),
Chris Chiuc7531e32019-03-21 17:17:31 +08007045 SND_PCI_QUIRK(0x1025, 0x1099, "Acer Aspire E5-523G", ALC255_FIXUP_ACER_MIC_NO_PRESENCE),
7046 SND_PCI_QUIRK(0x1025, 0x110e, "Acer Aspire ES1-432", ALC255_FIXUP_ACER_MIC_NO_PRESENCE),
Bernhard Rosenkraenzere2a829b2019-03-05 00:38:19 +01007047 SND_PCI_QUIRK(0x1025, 0x1246, "Acer Predator Helios 500", ALC299_FIXUP_PREDATOR_SPK),
Jian-Hong Pan667a8f72019-03-15 17:51:09 +08007048 SND_PCI_QUIRK(0x1025, 0x128f, "Acer Veriton Z6860G", ALC286_FIXUP_ACER_AIO_HEADSET_MIC),
7049 SND_PCI_QUIRK(0x1025, 0x1290, "Acer Veriton Z4860G", ALC286_FIXUP_ACER_AIO_HEADSET_MIC),
7050 SND_PCI_QUIRK(0x1025, 0x1291, "Acer Veriton Z4660G", ALC286_FIXUP_ACER_AIO_HEADSET_MIC),
Jian-Hong Pan2733cce2019-03-21 16:39:04 +08007051 SND_PCI_QUIRK(0x1025, 0x1308, "Acer Aspire Z24-890", ALC286_FIXUP_ACER_AIO_HEADSET_MIC),
Jian-Hong Panea5c7eb2019-04-01 11:25:05 +08007052 SND_PCI_QUIRK(0x1025, 0x132a, "Acer TravelMate B114-21", ALC233_FIXUP_ACER_HEADSET_MIC),
Jian-Hong Pancbc05fd2019-03-13 17:33:24 +08007053 SND_PCI_QUIRK(0x1025, 0x1330, "Acer TravelMate X514-51T", ALC255_FIXUP_ACER_HEADSET_MIC),
David Henningssonaaedfb42013-08-16 14:09:02 +02007054 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
Kailang Yang6ed11312015-10-26 15:37:39 +08007055 SND_PCI_QUIRK(0x1028, 0x054b, "Dell XPS one 2710", ALC275_FIXUP_DELL_XPS),
Takashi Iwai86f799b2015-11-14 17:46:31 +01007056 SND_PCI_QUIRK(0x1028, 0x05bd, "Dell Latitude E6440", ALC292_FIXUP_DELL_E7X),
Takashi Iwaicf521032016-01-15 12:59:25 +01007057 SND_PCI_QUIRK(0x1028, 0x05be, "Dell Latitude E6540", ALC292_FIXUP_DELL_E7X),
Takashi Iwai8b99aba2015-06-15 11:59:32 +02007058 SND_PCI_QUIRK(0x1028, 0x05ca, "Dell Latitude E7240", ALC292_FIXUP_DELL_E7X),
7059 SND_PCI_QUIRK(0x1028, 0x05cb, "Dell Latitude E7440", ALC292_FIXUP_DELL_E7X),
David Henningsson0f4881d2013-12-20 16:08:13 +01007060 SND_PCI_QUIRK(0x1028, 0x05da, "Dell Vostro 5460", ALC290_FIXUP_SUBWOOFER),
David Henningsson73bdd592013-04-15 15:44:14 +02007061 SND_PCI_QUIRK(0x1028, 0x05f4, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
7062 SND_PCI_QUIRK(0x1028, 0x05f5, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
7063 SND_PCI_QUIRK(0x1028, 0x05f6, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
David Henningsson0f4881d2013-12-20 16:08:13 +01007064 SND_PCI_QUIRK(0x1028, 0x0615, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK),
7065 SND_PCI_QUIRK(0x1028, 0x0616, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK),
Takashi Iwai98070572016-01-12 21:06:39 +01007066 SND_PCI_QUIRK(0x1028, 0x062c, "Dell Latitude E5550", ALC292_FIXUP_DELL_E7X),
Takashi Iwai42755542015-06-29 10:56:53 +02007067 SND_PCI_QUIRK(0x1028, 0x062e, "Dell Latitude E7450", ALC292_FIXUP_DELL_E7X),
David Henningsson0f4881d2013-12-20 16:08:13 +01007068 SND_PCI_QUIRK(0x1028, 0x0638, "Dell Inspiron 5439", ALC290_FIXUP_MONO_SPEAKERS_HSJACK),
Kailang Yanga22aa262014-04-23 17:34:28 +08007069 SND_PCI_QUIRK(0x1028, 0x064a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
7070 SND_PCI_QUIRK(0x1028, 0x064b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
Hui Wang831bfdf92015-06-26 12:35:17 +08007071 SND_PCI_QUIRK(0x1028, 0x0665, "Dell XPS 13", ALC288_FIXUP_DELL_XPS_13),
Bastien Noceraafecb142016-04-18 11:10:42 +02007072 SND_PCI_QUIRK(0x1028, 0x0669, "Dell Optiplex 9020m", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
Takashi Iwai3a05d122015-07-29 09:04:52 +02007073 SND_PCI_QUIRK(0x1028, 0x069a, "Dell Vostro 5480", ALC290_FIXUP_SUBWOOFER_HSJACK),
Kailang Yang8b724152014-12-17 17:08:59 +08007074 SND_PCI_QUIRK(0x1028, 0x06c7, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
Kailang Yangb7343042014-12-02 14:50:45 +08007075 SND_PCI_QUIRK(0x1028, 0x06d9, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
7076 SND_PCI_QUIRK(0x1028, 0x06da, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
David Henningssonc04017e2015-12-15 14:44:03 +01007077 SND_PCI_QUIRK(0x1028, 0x06db, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
7078 SND_PCI_QUIRK(0x1028, 0x06dd, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
7079 SND_PCI_QUIRK(0x1028, 0x06de, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
7080 SND_PCI_QUIRK(0x1028, 0x06df, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
7081 SND_PCI_QUIRK(0x1028, 0x06e0, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
Kai-Heng Feng1099f482019-10-03 12:39:19 +08007082 SND_PCI_QUIRK(0x1028, 0x0704, "Dell XPS 13 9350", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE2),
Kai-Heng Fengfd06c772016-08-30 15:36:34 +08007083 SND_PCI_QUIRK(0x1028, 0x0706, "Dell Inspiron 7559", ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER),
Kai-Heng Feng3b43b712016-02-25 15:19:38 +08007084 SND_PCI_QUIRK(0x1028, 0x0725, "Dell Inspiron 3162", ALC255_FIXUP_DELL_SPK_NOISE),
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01007085 SND_PCI_QUIRK(0x1028, 0x0738, "Dell Precision 5820", ALC269_FIXUP_NO_SHUTUP),
Kai-Heng Feng1099f482019-10-03 12:39:19 +08007086 SND_PCI_QUIRK(0x1028, 0x075b, "Dell XPS 13 9360", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE2),
Kai-Heng Feng709ae622018-10-04 11:39:42 +08007087 SND_PCI_QUIRK(0x1028, 0x075c, "Dell XPS 27 7760", ALC298_FIXUP_SPK_VOLUME),
Hui Wangdd9aa332016-08-01 10:20:32 +08007088 SND_PCI_QUIRK(0x1028, 0x075d, "Dell AIO", ALC298_FIXUP_SPK_VOLUME),
Takashi Iwaie312a862018-03-06 12:14:17 +01007089 SND_PCI_QUIRK(0x1028, 0x07b0, "Dell Precision 7520", ALC295_FIXUP_DISABLE_DAC3),
Takashi Iwai493de342017-02-28 17:27:57 +01007090 SND_PCI_QUIRK(0x1028, 0x0798, "Dell Inspiron 17 7000 Gaming", ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER),
Kailang Yang5f364132017-07-25 16:28:16 +08007091 SND_PCI_QUIRK(0x1028, 0x080c, "Dell WYSE", ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE),
Kai-Heng Feng1099f482019-10-03 12:39:19 +08007092 SND_PCI_QUIRK(0x1028, 0x082a, "Dell XPS 13 9360", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE2),
Kailang Yang40e2c4e2018-02-02 15:13:09 +08007093 SND_PCI_QUIRK(0x1028, 0x084b, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB),
7094 SND_PCI_QUIRK(0x1028, 0x084e, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB),
Kailang Yangf0ba9d62018-03-16 11:46:08 +08007095 SND_PCI_QUIRK(0x1028, 0x0871, "Dell Precision 3630", ALC255_FIXUP_DELL_HEADSET_MIC),
7096 SND_PCI_QUIRK(0x1028, 0x0872, "Dell Precision 3630", ALC255_FIXUP_DELL_HEADSET_MIC),
Kailang Yangae104a22018-02-05 16:07:20 +08007097 SND_PCI_QUIRK(0x1028, 0x0873, "Dell Precision 3930", ALC255_FIXUP_DUMMY_LINEOUT_VERB),
Kailang Yang136824e2019-03-14 16:22:45 +08007098 SND_PCI_QUIRK(0x1028, 0x08ad, "Dell WYSE AIO", ALC225_FIXUP_DELL_WYSE_AIO_MIC_NO_PRESENCE),
Kailang Yangda484d02019-03-14 15:50:59 +08007099 SND_PCI_QUIRK(0x1028, 0x08ae, "Dell WYSE NB", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE),
Kailang Yangc2a7c55a2019-01-03 15:53:39 +08007100 SND_PCI_QUIRK(0x1028, 0x0935, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB),
Kailang Yange79c2262019-12-19 14:12:15 +08007101 SND_PCI_QUIRK(0x1028, 0x097e, "Dell Precision", ALC289_FIXUP_DUAL_SPK),
7102 SND_PCI_QUIRK(0x1028, 0x097d, "Dell Precision", ALC289_FIXUP_DUAL_SPK),
Kailang Yanga22aa262014-04-23 17:34:28 +08007103 SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
7104 SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
Takashi Iwai08fb0d02013-01-10 17:33:58 +01007105 SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01007106 SND_PCI_QUIRK(0x103c, 0x18e6, "HP", ALC269_FIXUP_HP_GPIO_LED),
David Henningsson8e35cd42013-11-06 11:20:01 +01007107 SND_PCI_QUIRK(0x103c, 0x218b, "HP", ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED),
David Henningsson33f4acd2015-01-07 15:50:13 +01007108 SND_PCI_QUIRK(0x103c, 0x225f, "HP", ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY),
Kailang Yangc60666b2014-02-21 16:23:35 +08007109 /* ALC282 */
Hui Wang7976eb42015-02-13 11:14:41 +08007110 SND_PCI_QUIRK(0x103c, 0x21f9, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang8a02b162014-06-13 17:16:31 +08007111 SND_PCI_QUIRK(0x103c, 0x2210, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang8a02b162014-06-13 17:16:31 +08007112 SND_PCI_QUIRK(0x103c, 0x2214, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007113 SND_PCI_QUIRK(0x103c, 0x2236, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
7114 SND_PCI_QUIRK(0x103c, 0x2237, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
7115 SND_PCI_QUIRK(0x103c, 0x2238, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
7116 SND_PCI_QUIRK(0x103c, 0x2239, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007117 SND_PCI_QUIRK(0x103c, 0x224b, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
Kailang Yangc60666b2014-02-21 16:23:35 +08007118 SND_PCI_QUIRK(0x103c, 0x2268, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08007119 SND_PCI_QUIRK(0x103c, 0x226a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7120 SND_PCI_QUIRK(0x103c, 0x226b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang8a02b162014-06-13 17:16:31 +08007121 SND_PCI_QUIRK(0x103c, 0x226e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangeaa8e5e2014-11-21 15:49:11 +08007122 SND_PCI_QUIRK(0x103c, 0x2271, "HP", ALC286_FIXUP_HP_GPIO_LED),
TienFu Chenb4b33f92015-01-20 15:06:21 +01007123 SND_PCI_QUIRK(0x103c, 0x2272, "HP", ALC280_FIXUP_HP_DOCK_PINS),
TienFu Chen3271cb22015-02-10 09:09:41 +01007124 SND_PCI_QUIRK(0x103c, 0x2273, "HP", ALC280_FIXUP_HP_DOCK_PINS),
Kailang Yangc60666b2014-02-21 16:23:35 +08007125 SND_PCI_QUIRK(0x103c, 0x229e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08007126 SND_PCI_QUIRK(0x103c, 0x22b2, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7127 SND_PCI_QUIRK(0x103c, 0x22b7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7128 SND_PCI_QUIRK(0x103c, 0x22bf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08007129 SND_PCI_QUIRK(0x103c, 0x22cf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Keith Packard98973f22015-07-15 12:14:39 -07007130 SND_PCI_QUIRK(0x103c, 0x22db, "HP", ALC280_FIXUP_HP_9480M),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007131 SND_PCI_QUIRK(0x103c, 0x22dc, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
7132 SND_PCI_QUIRK(0x103c, 0x22fb, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yangc60666b2014-02-21 16:23:35 +08007133 /* ALC290 */
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007134 SND_PCI_QUIRK(0x103c, 0x221b, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007135 SND_PCI_QUIRK(0x103c, 0x2221, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007136 SND_PCI_QUIRK(0x103c, 0x2225, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007137 SND_PCI_QUIRK(0x103c, 0x2253, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
7138 SND_PCI_QUIRK(0x103c, 0x2254, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
7139 SND_PCI_QUIRK(0x103c, 0x2255, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
7140 SND_PCI_QUIRK(0x103c, 0x2256, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
7141 SND_PCI_QUIRK(0x103c, 0x2257, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007142 SND_PCI_QUIRK(0x103c, 0x2259, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Jaroslav Kysela04d54662017-03-09 13:29:13 +01007143 SND_PCI_QUIRK(0x103c, 0x225a, "HP", ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED),
Kailang Yangc60666b2014-02-21 16:23:35 +08007144 SND_PCI_QUIRK(0x103c, 0x2260, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08007145 SND_PCI_QUIRK(0x103c, 0x2263, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7146 SND_PCI_QUIRK(0x103c, 0x2264, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7147 SND_PCI_QUIRK(0x103c, 0x2265, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007148 SND_PCI_QUIRK(0x103c, 0x2272, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
7149 SND_PCI_QUIRK(0x103c, 0x2273, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08007150 SND_PCI_QUIRK(0x103c, 0x2278, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yangc60666b2014-02-21 16:23:35 +08007151 SND_PCI_QUIRK(0x103c, 0x227f, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08007152 SND_PCI_QUIRK(0x103c, 0x2282, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08007153 SND_PCI_QUIRK(0x103c, 0x228b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08007154 SND_PCI_QUIRK(0x103c, 0x228e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7155 SND_PCI_QUIRK(0x103c, 0x22c5, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08007156 SND_PCI_QUIRK(0x103c, 0x22c7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7157 SND_PCI_QUIRK(0x103c, 0x22c8, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08007158 SND_PCI_QUIRK(0x103c, 0x22c4, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang8a02b162014-06-13 17:16:31 +08007159 SND_PCI_QUIRK(0x103c, 0x2334, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7160 SND_PCI_QUIRK(0x103c, 0x2335, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7161 SND_PCI_QUIRK(0x103c, 0x2336, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
7162 SND_PCI_QUIRK(0x103c, 0x2337, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Takashi Iwaif8839822016-02-25 14:31:59 +01007163 SND_PCI_QUIRK(0x103c, 0x221c, "HP EliteBook 755 G2", ALC280_FIXUP_HP_HEADSET_MIC),
Jaroslav Kysela167897f2019-03-13 13:40:15 +01007164 SND_PCI_QUIRK(0x103c, 0x802e, "HP Z240 SFF", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
7165 SND_PCI_QUIRK(0x103c, 0x802f, "HP Z240", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
Takashi Iwai563785e2018-11-12 09:43:12 +01007166 SND_PCI_QUIRK(0x103c, 0x820d, "HP Pavilion 15", ALC269_FIXUP_HP_MUTE_LED_MIC3),
Hui Wange549d192016-04-01 11:00:15 +08007167 SND_PCI_QUIRK(0x103c, 0x8256, "HP", ALC221_FIXUP_HP_FRONT_MIC),
Tom Bridenbbf8ff62018-05-29 17:34:20 +01007168 SND_PCI_QUIRK(0x103c, 0x827e, "HP x360", ALC295_FIXUP_HP_X360),
Jaroslav Kysela167897f2019-03-13 13:40:15 +01007169 SND_PCI_QUIRK(0x103c, 0x82bf, "HP G3 mini", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
7170 SND_PCI_QUIRK(0x103c, 0x82c0, "HP G3 mini premium", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
Alexandru Gagniuc56e40eb2018-08-04 11:44:44 -05007171 SND_PCI_QUIRK(0x103c, 0x83b9, "HP Spectre x360", ALC269_FIXUP_HP_MUTE_LED_MIC3),
Takashi Iwai190d0382019-08-13 17:39:56 +02007172 SND_PCI_QUIRK(0x103c, 0x8497, "HP Envy x360", ALC269_FIXUP_HP_MUTE_LED_MIC3),
Sam Bazleyd33cd422019-09-01 03:31:30 +01007173 SND_PCI_QUIRK(0x103c, 0x84e7, "HP Pavilion 15", ALC269_FIXUP_HP_MUTE_LED_MIC3),
Chris Chiuc1732ed2017-02-28 14:17:13 -06007174 SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC),
Takashi Iwai7bba2152013-09-06 15:45:38 +02007175 SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300),
David Henningsson3e0d6112013-04-22 14:30:14 +02007176 SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Wandrille RONCE9cf65332018-12-19 14:52:44 +01007177 SND_PCI_QUIRK(0x1043, 0x10a1, "ASUS UX391UA", ALC294_FIXUP_ASUS_SPK),
Chris Chiuc1732ed2017-02-28 14:17:13 -06007178 SND_PCI_QUIRK(0x1043, 0x10c0, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC),
Takashi Iwai4eab0ea2017-06-06 12:33:17 +02007179 SND_PCI_QUIRK(0x1043, 0x10d0, "ASUS X540LA/X540LJ", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
David Henningsson3e0d6112013-04-22 14:30:14 +02007180 SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Takashi Iwai4eab0ea2017-06-06 12:33:17 +02007181 SND_PCI_QUIRK(0x1043, 0x11c0, "ASUS X556UR", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
7182 SND_PCI_QUIRK(0x1043, 0x1290, "ASUS X441SA", ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE),
7183 SND_PCI_QUIRK(0x1043, 0x12a0, "ASUS X441UV", ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE),
Chris Chiuc1732ed2017-02-28 14:17:13 -06007184 SND_PCI_QUIRK(0x1043, 0x12f0, "ASUS X541UV", ALC256_FIXUP_ASUS_MIC),
7185 SND_PCI_QUIRK(0x1043, 0x12e0, "ASUS X541SA", ALC256_FIXUP_ASUS_MIC),
7186 SND_PCI_QUIRK(0x1043, 0x13b0, "ASUS Z550SA", ALC256_FIXUP_ASUS_MIC),
Oleksij Rempel2cede302013-11-27 17:12:03 +01007187 SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK),
Takashi Iwai23870832013-11-29 14:13:12 +01007188 SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A),
David Henningsson3e0d6112013-04-22 14:30:14 +02007189 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC),
Jian-Hong Pan436e2552019-11-25 17:34:06 +08007190 SND_PCI_QUIRK(0x1043, 0x17d1, "ASUS UX431FL", ALC294_FIXUP_ASUS_INTSPK_GPIO),
Daniel Drake8c8967a2019-10-17 16:15:01 +08007191 SND_PCI_QUIRK(0x1043, 0x18b1, "Asus MJ401TA", ALC256_FIXUP_ASUS_HEADSET_MIC),
Takashi Iwai017f2a12011-07-09 14:42:25 +02007192 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
Chris Chiu28e8af82017-06-05 15:05:30 -06007193 SND_PCI_QUIRK(0x1043, 0x1a30, "ASUS X705UD", ALC256_FIXUP_ASUS_MIC),
David Henningsson693b6132012-06-22 19:12:10 +02007194 SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC),
Chris Chiu615966a2017-02-28 14:17:12 -06007195 SND_PCI_QUIRK(0x1043, 0x1bbd, "ASUS Z550MA", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
Takashi Iwai4eab0ea2017-06-06 12:33:17 +02007196 SND_PCI_QUIRK(0x1043, 0x1c23, "Asus X55U", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Chris Chiuc1732ed2017-02-28 14:17:13 -06007197 SND_PCI_QUIRK(0x1043, 0x1ccd, "ASUS X555UB", ALC256_FIXUP_ASUS_MIC),
Chris Chiueeed4cd2017-02-28 14:17:15 -06007198 SND_PCI_QUIRK(0x1043, 0x3030, "ASUS ZN270IE", ALC256_FIXUP_ASUS_AIO_GPIO2),
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02007199 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC),
7200 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC),
7201 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
7202 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
David Henningssond240d1d2013-04-15 12:50:02 +02007203 SND_PCI_QUIRK(0x1043, 0x8516, "ASUS X101CH", ALC269_FIXUP_ASUS_X101),
Takashi Iwaif88abaa2014-02-07 12:07:59 +01007204 SND_PCI_QUIRK(0x104d, 0x90b5, "Sony VAIO Pro 11", ALC286_FIXUP_SONY_MIC_NO_PRESENCE),
David Henningsson88cfcf82013-10-11 10:18:45 +02007205 SND_PCI_QUIRK(0x104d, 0x90b6, "Sony VAIO Pro 13", ALC286_FIXUP_SONY_MIC_NO_PRESENCE),
Takashi Iwai1d045db2011-07-07 18:23:21 +02007206 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
7207 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
7208 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
Takashi Iwaie9bd7d52014-05-21 11:06:49 +02007209 SND_PCI_QUIRK(0x104d, 0x9099, "Sony VAIO S13", ALC275_FIXUP_SONY_DISABLE_AAMIX),
Takashi Iwai24519912011-08-16 15:08:49 +02007210 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook", ALC269_FIXUP_LIFEBOOK),
Takashi Iwai4df3fd12015-06-29 08:38:02 +02007211 SND_PCI_QUIRK(0x10cf, 0x159f, "Lifebook E780", ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT),
Takashi Iwaicc7016a2015-04-08 20:47:55 +02007212 SND_PCI_QUIRK(0x10cf, 0x15dc, "Lifebook T731", ALC269_FIXUP_LIFEBOOK_HP_PIN),
Takashi Iwai88776f32015-05-01 09:20:34 +02007213 SND_PCI_QUIRK(0x10cf, 0x1757, "Lifebook E752", ALC269_FIXUP_LIFEBOOK_HP_PIN),
Jan-Marek Glogowskifdcc9682018-02-14 11:29:15 +01007214 SND_PCI_QUIRK(0x10cf, 0x1629, "Lifebook U7x7", ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC),
David Henningsson2041d562014-06-13 11:15:44 +02007215 SND_PCI_QUIRK(0x10cf, 0x1845, "Lifebook U904", ALC269_FIXUP_LIFEBOOK_EXTMIC),
PeiSen Houb84e8432017-09-01 15:11:56 +08007216 SND_PCI_QUIRK(0x10ec, 0x10f2, "Intel Reference board", ALC700_FIXUP_INTEL_REFERENCE),
YOKOTA Hiroshi0fca97a2018-07-01 18:30:01 +09007217 SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-SZ6", ALC269_FIXUP_HEADSET_MODE),
David Henningssona33cc482014-10-07 10:18:41 +02007218 SND_PCI_QUIRK(0x144d, 0xc109, "Samsung Ativ book 9 (NP900X3G)", ALC269_FIXUP_INV_DMIC),
Gabriele Mazzotta823ff162016-12-24 19:50:01 +01007219 SND_PCI_QUIRK(0x144d, 0xc740, "Samsung Ativ book 8 (NP870Z5G)", ALC269_FIXUP_ATIV_BOOK_8),
Anisse Astierabaa22742016-08-24 09:14:13 +02007220 SND_PCI_QUIRK(0x1458, 0xfa53, "Gigabyte BXBT-2807", ALC283_FIXUP_HEADSET_MIC),
7221 SND_PCI_QUIRK(0x1462, 0xb120, "MSI Cubi MS-B120", ALC283_FIXUP_HEADSET_MIC),
Anisse Astier8cd65272018-11-23 17:59:11 +01007222 SND_PCI_QUIRK(0x1462, 0xb171, "Cubi N 8GL (MS-B171)", ALC283_FIXUP_HEADSET_MIC),
Jeremy Soller89e3a562019-01-30 16:12:31 -07007223 SND_PCI_QUIRK(0x1558, 0x1325, "System76 Darter Pro (darp5)", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
Jeremy Soller80a50522019-05-07 17:11:08 -04007224 SND_PCI_QUIRK(0x1558, 0x8550, "System76 Gazelle (gaze14)", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
Jeremy Soller891afcf2019-05-10 10:15:07 -04007225 SND_PCI_QUIRK(0x1558, 0x8551, "System76 Gazelle (gaze14)", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
7226 SND_PCI_QUIRK(0x1558, 0x8560, "System76 Gazelle (gaze14)", ALC269_FIXUP_HEADSET_MIC),
7227 SND_PCI_QUIRK(0x1558, 0x8561, "System76 Gazelle (gaze14)", ALC269_FIXUP_HEADSET_MIC),
Kailang Yangca169cc2017-04-25 16:17:40 +08007228 SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC233_FIXUP_LENOVO_MULTI_CODECS),
Takashi Iwai1d045db2011-07-07 18:23:21 +02007229 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
7230 SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
7231 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
7232 SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
7233 SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
Takashi Iwai707fba32012-08-02 09:04:39 +02007234 SND_PCI_QUIRK(0x17aa, 0x21f6, "Thinkpad T530", ALC269_FIXUP_LENOVO_DOCK),
Felix Kaechelec8415a42012-08-06 23:02:01 +02007235 SND_PCI_QUIRK(0x17aa, 0x21fa, "Thinkpad X230", ALC269_FIXUP_LENOVO_DOCK),
Stefán Freyr84f98fd2012-10-19 22:46:00 +02007236 SND_PCI_QUIRK(0x17aa, 0x21f3, "Thinkpad T430", ALC269_FIXUP_LENOVO_DOCK),
Philipp A. Mohrenweiser4407be62012-08-06 13:14:18 +02007237 SND_PCI_QUIRK(0x17aa, 0x21fb, "Thinkpad T430s", ALC269_FIXUP_LENOVO_DOCK),
David Henningsson108cc102012-07-20 10:37:25 +02007238 SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK),
David Henningssonaaedfb42013-08-16 14:09:02 +02007239 SND_PCI_QUIRK(0x17aa, 0x2208, "Thinkpad T431s", ALC269_FIXUP_LENOVO_DOCK),
Takashi Iwai9a811232015-12-09 15:17:43 +01007240 SND_PCI_QUIRK(0x17aa, 0x220c, "Thinkpad T440s", ALC292_FIXUP_TPT440),
Takashi Iwai1c37c222014-05-06 17:34:42 +02007241 SND_PCI_QUIRK(0x17aa, 0x220e, "Thinkpad T440p", ALC292_FIXUP_TPT440_DOCK),
Takashi Iwaia12137e2014-06-27 12:14:35 +02007242 SND_PCI_QUIRK(0x17aa, 0x2210, "Thinkpad T540p", ALC292_FIXUP_TPT440_DOCK),
Rick Sherman59a51a62015-08-18 21:04:30 -05007243 SND_PCI_QUIRK(0x17aa, 0x2211, "Thinkpad W541", ALC292_FIXUP_TPT440_DOCK),
Takashi Iwai6d169412014-10-07 17:27:02 +02007244 SND_PCI_QUIRK(0x17aa, 0x2212, "Thinkpad T440", ALC292_FIXUP_TPT440_DOCK),
Lukas Bossard7c215392014-10-29 18:31:07 +01007245 SND_PCI_QUIRK(0x17aa, 0x2214, "Thinkpad X240", ALC292_FIXUP_TPT440_DOCK),
David Henningssona4a9e082013-08-16 14:09:01 +02007246 SND_PCI_QUIRK(0x17aa, 0x2215, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Takashi Iwaib6903c02015-12-10 12:20:20 +01007247 SND_PCI_QUIRK(0x17aa, 0x2218, "Thinkpad X1 Carbon 2nd", ALC292_FIXUP_TPT440_DOCK),
Laura Abbottd05ea7d2015-10-02 11:09:54 -07007248 SND_PCI_QUIRK(0x17aa, 0x2223, "ThinkPad T550", ALC292_FIXUP_TPT440_DOCK),
Yves-Alexis Perezc0278662015-04-11 09:31:35 +02007249 SND_PCI_QUIRK(0x17aa, 0x2226, "ThinkPad X250", ALC292_FIXUP_TPT440_DOCK),
Kailang Yang61fcf8e2018-02-02 15:26:46 +08007250 SND_PCI_QUIRK(0x17aa, 0x222d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7251 SND_PCI_QUIRK(0x17aa, 0x222e, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
Torsten Hilbrichdab38e42016-06-07 13:14:21 +02007252 SND_PCI_QUIRK(0x17aa, 0x2231, "Thinkpad T560", ALC292_FIXUP_TPT460),
Sven Eckelmannc636b952016-04-11 16:55:26 +02007253 SND_PCI_QUIRK(0x17aa, 0x2233, "Thinkpad", ALC292_FIXUP_TPT460),
Kailang Yang61fcf8e2018-02-02 15:26:46 +08007254 SND_PCI_QUIRK(0x17aa, 0x2245, "Thinkpad T470", ALC298_FIXUP_TPT470_DOCK),
7255 SND_PCI_QUIRK(0x17aa, 0x2246, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7256 SND_PCI_QUIRK(0x17aa, 0x2247, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
Dennis Wassenberge4c07b32018-03-08 13:17:54 +01007257 SND_PCI_QUIRK(0x17aa, 0x2249, "Thinkpad", ALC292_FIXUP_TPT460),
Kailang Yang61fcf8e2018-02-02 15:26:46 +08007258 SND_PCI_QUIRK(0x17aa, 0x224b, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7259 SND_PCI_QUIRK(0x17aa, 0x224c, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7260 SND_PCI_QUIRK(0x17aa, 0x224d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
Benjamin Berg85981df2018-02-14 13:29:39 +01007261 SND_PCI_QUIRK(0x17aa, 0x225d, "Thinkpad T480", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Jaroslav Kyselad2cd7952019-11-29 15:40:27 +01007262 SND_PCI_QUIRK(0x17aa, 0x2293, "Thinkpad X1 Carbon 7th", ALC285_FIXUP_SPEAKER2_TO_DAC1),
Kailang3694cb22015-12-28 11:35:24 +08007263 SND_PCI_QUIRK(0x17aa, 0x30bb, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
Hui Wang6ef2f682016-03-11 12:04:02 +08007264 SND_PCI_QUIRK(0x17aa, 0x30e2, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
Hui Wangf33f79f2017-07-07 12:08:29 +08007265 SND_PCI_QUIRK(0x17aa, 0x310c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
Dennis Wassenbergbef33e12019-06-28 10:54:53 +02007266 SND_PCI_QUIRK(0x17aa, 0x3111, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
Hui Wange41fc8c2018-06-25 14:40:56 +08007267 SND_PCI_QUIRK(0x17aa, 0x312a, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
Kailang Yang65811832018-04-25 17:07:27 +08007268 SND_PCI_QUIRK(0x17aa, 0x312f, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
Hui Wang8da5bbf2017-12-22 11:17:46 +08007269 SND_PCI_QUIRK(0x17aa, 0x313c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
Hui Wang2a36c162019-09-04 13:53:27 +08007270 SND_PCI_QUIRK(0x17aa, 0x3151, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC),
Aaron Ma8a6c55d2019-10-24 19:44:39 +08007271 SND_PCI_QUIRK(0x17aa, 0x3176, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC),
7272 SND_PCI_QUIRK(0x17aa, 0x3178, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC),
David Henningsson56f27012016-01-11 09:33:14 +01007273 SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
Takashi Iwaifedb2242014-11-13 07:11:38 +01007274 SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC),
Michał Wadowski56df90b2019-05-14 16:58:00 +02007275 SND_PCI_QUIRK(0x17aa, 0x3978, "Lenovo B50-70", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
David Henningssona4a9e082013-08-16 14:09:01 +02007276 SND_PCI_QUIRK(0x17aa, 0x5013, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Kailang Yang1bb3e062013-09-27 13:10:25 +02007277 SND_PCI_QUIRK(0x17aa, 0x501a, "Thinkpad", ALC283_FIXUP_INT_MIC),
Takashi Iwaic497d9f2014-10-08 12:14:40 +02007278 SND_PCI_QUIRK(0x17aa, 0x501e, "Thinkpad L440", ALC292_FIXUP_TPT440_DOCK),
David Henningssoncd5302c2013-08-19 12:22:33 +02007279 SND_PCI_QUIRK(0x17aa, 0x5026, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Jo-Philipp Wichf2aa1112015-04-13 12:47:26 +02007280 SND_PCI_QUIRK(0x17aa, 0x5034, "Thinkpad T450", ALC292_FIXUP_TPT440_DOCK),
Sebastian Wicki80b311d2015-03-23 17:23:11 +01007281 SND_PCI_QUIRK(0x17aa, 0x5036, "Thinkpad T450s", ALC292_FIXUP_TPT440_DOCK),
Ansgar Hegerfeld09ea9972015-05-14 12:31:32 +02007282 SND_PCI_QUIRK(0x17aa, 0x503c, "Thinkpad L450", ALC292_FIXUP_TPT440_DOCK),
Conrad Kostecki037e1192016-04-26 10:08:10 +02007283 SND_PCI_QUIRK(0x17aa, 0x504a, "ThinkPad X260", ALC292_FIXUP_TPT440_DOCK),
Hui Wang23adc192015-12-08 12:27:18 +08007284 SND_PCI_QUIRK(0x17aa, 0x504b, "Thinkpad", ALC293_FIXUP_LENOVO_SPK_NOISE),
Jaroslav Kysela0f087ee2016-06-24 15:13:16 +02007285 SND_PCI_QUIRK(0x17aa, 0x5050, "Thinkpad T560p", ALC292_FIXUP_TPT460),
Torsten Hilbrich9cd25742016-07-05 10:40:22 +02007286 SND_PCI_QUIRK(0x17aa, 0x5051, "Thinkpad L460", ALC292_FIXUP_TPT460),
Jaroslav Kysela0f087ee2016-06-24 15:13:16 +02007287 SND_PCI_QUIRK(0x17aa, 0x5053, "Thinkpad T460", ALC292_FIXUP_TPT460),
Kailang Yang61fcf8e2018-02-02 15:26:46 +08007288 SND_PCI_QUIRK(0x17aa, 0x505d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7289 SND_PCI_QUIRK(0x17aa, 0x505f, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7290 SND_PCI_QUIRK(0x17aa, 0x5062, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
David Henningssoncd5302c2013-08-19 12:22:33 +02007291 SND_PCI_QUIRK(0x17aa, 0x5109, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Kailang Yang61fcf8e2018-02-02 15:26:46 +08007292 SND_PCI_QUIRK(0x17aa, 0x511e, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7293 SND_PCI_QUIRK(0x17aa, 0x511f, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
David Henningsson012e7eb2012-08-08 08:43:37 +02007294 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K),
Takashi Iwai1d045db2011-07-07 18:23:21 +02007295 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
Ayman Bagabas0fbf21c2019-05-23 05:30:11 -04007296 SND_PCI_QUIRK(0x19e5, 0x3204, "Huawei MACH-WX9", ALC256_FIXUP_HUAWEI_MACH_WX9_PINS),
Anisse Astier02b504d2013-06-03 11:53:10 +02007297 SND_PCI_QUIRK(0x1b7d, 0xa831, "Ordissimo EVE2 ", ALC269VB_FIXUP_ORDISSIMO_EVE2), /* Also known as Malata PC-B1303 */
Hui Wang695d1ec2019-11-21 10:54:27 +08007298 SND_PCI_QUIRK(0x1d72, 0x1901, "RedmiBook 14", ALC256_FIXUP_ASUS_HEADSET_MIC),
Jan-Marek Glogowskibd9c10b2019-09-15 16:57:28 +02007299 SND_PCI_QUIRK(0x10ec, 0x118c, "Medion EE4254 MD62100", ALC256_FIXUP_MEDION_HEADSET_NO_PRESENCE),
Takashi Iwaia4297b52011-08-23 18:40:12 +02007300
Takashi Iwaia7f3eed2012-02-16 13:03:18 +01007301#if 0
Takashi Iwaia4297b52011-08-23 18:40:12 +02007302 /* Below is a quirk table taken from the old code.
7303 * Basically the device should work as is without the fixup table.
7304 * If BIOS doesn't give a proper info, enable the corresponding
7305 * fixup entry.
Jesper Juhl7d7eb9e2012-04-12 22:11:25 +02007306 */
Takashi Iwaia4297b52011-08-23 18:40:12 +02007307 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
7308 ALC269_FIXUP_AMIC),
7309 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269_FIXUP_AMIC),
Takashi Iwaia4297b52011-08-23 18:40:12 +02007310 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269_FIXUP_AMIC),
7311 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_FIXUP_AMIC),
7312 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269_FIXUP_AMIC),
7313 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269_FIXUP_AMIC),
7314 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269_FIXUP_AMIC),
7315 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269_FIXUP_AMIC),
7316 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_FIXUP_AMIC),
7317 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269_FIXUP_AMIC),
7318 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_FIXUP_AMIC),
7319 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_FIXUP_AMIC),
7320 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_FIXUP_AMIC),
7321 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_FIXUP_AMIC),
7322 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_FIXUP_AMIC),
7323 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_FIXUP_AMIC),
7324 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_FIXUP_AMIC),
7325 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_FIXUP_AMIC),
7326 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_FIXUP_AMIC),
7327 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_FIXUP_AMIC),
7328 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_FIXUP_AMIC),
7329 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_FIXUP_AMIC),
7330 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_FIXUP_AMIC),
7331 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_FIXUP_AMIC),
7332 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_FIXUP_AMIC),
7333 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_FIXUP_AMIC),
7334 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_FIXUP_AMIC),
7335 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_FIXUP_AMIC),
7336 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_FIXUP_AMIC),
7337 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_FIXUP_AMIC),
7338 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_FIXUP_AMIC),
7339 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_FIXUP_AMIC),
7340 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_FIXUP_AMIC),
7341 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_FIXUP_AMIC),
7342 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_FIXUP_AMIC),
7343 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_FIXUP_DMIC),
7344 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_FIXUP_AMIC),
7345 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_AMIC),
7346 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_FIXUP_DMIC),
7347 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_FIXUP_DMIC),
7348#endif
7349 {}
7350};
7351
David Henningsson214eef72014-07-22 14:09:35 +02007352static const struct snd_pci_quirk alc269_fixup_vendor_tbl[] = {
7353 SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC),
7354 SND_PCI_QUIRK_VENDOR(0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED),
7355 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
7356 SND_PCI_QUIRK_VENDOR(0x17aa, "Thinkpad", ALC269_FIXUP_THINKPAD_ACPI),
Ayman Bagabas0fbf21c2019-05-23 05:30:11 -04007357 SND_PCI_QUIRK_VENDOR(0x19e5, "Huawei Matebook", ALC255_FIXUP_MIC_MUTE_LED),
David Henningsson214eef72014-07-22 14:09:35 +02007358 {}
7359};
7360
Takashi Iwai1727a772013-01-10 09:52:52 +01007361static const struct hda_model_fixup alc269_fixup_models[] = {
Takashi Iwaia4297b52011-08-23 18:40:12 +02007362 {.id = ALC269_FIXUP_AMIC, .name = "laptop-amic"},
7363 {.id = ALC269_FIXUP_DMIC, .name = "laptop-dmic"},
Takashi Iwai6e72aa52012-06-25 10:52:25 +02007364 {.id = ALC269_FIXUP_STEREO_DMIC, .name = "alc269-dmic"},
7365 {.id = ALC271_FIXUP_DMIC, .name = "alc271-dmic"},
7366 {.id = ALC269_FIXUP_INV_DMIC, .name = "inv-dmic"},
David Henningsson7c478f02013-10-11 10:18:46 +02007367 {.id = ALC269_FIXUP_HEADSET_MIC, .name = "headset-mic"},
Takashi Iwaib0169512015-05-19 10:20:13 +02007368 {.id = ALC269_FIXUP_HEADSET_MODE, .name = "headset-mode"},
7369 {.id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC, .name = "headset-mode-no-hp-mic"},
David Henningsson108cc102012-07-20 10:37:25 +02007370 {.id = ALC269_FIXUP_LENOVO_DOCK, .name = "lenovo-dock"},
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01007371 {.id = ALC269_FIXUP_HP_GPIO_LED, .name = "hp-gpio-led"},
Jaroslav Kysela04d54662017-03-09 13:29:13 +01007372 {.id = ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED, .name = "hp-dock-gpio-mic1-led"},
David Henningssone32aa852013-06-17 11:04:02 +02007373 {.id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "dell-headset-multi"},
7374 {.id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE, .name = "dell-headset-dock"},
Takashi Iwaia26d96c2018-06-26 15:09:25 +02007375 {.id = ALC269_FIXUP_DELL3_MIC_NO_PRESENCE, .name = "dell-headset3"},
7376 {.id = ALC269_FIXUP_DELL4_MIC_NO_PRESENCE, .name = "dell-headset4"},
Kailang Yangbe8ef162014-04-08 15:19:49 +08007377 {.id = ALC283_FIXUP_CHROME_BOOK, .name = "alc283-dac-wcaps"},
Kailang Yang0202e992013-12-02 15:20:15 +08007378 {.id = ALC283_FIXUP_SENSE_COMBO_JACK, .name = "alc283-sense-combo"},
Takashi Iwai1c37c222014-05-06 17:34:42 +02007379 {.id = ALC292_FIXUP_TPT440_DOCK, .name = "tpt440-dock"},
Takashi Iwai9a811232015-12-09 15:17:43 +01007380 {.id = ALC292_FIXUP_TPT440, .name = "tpt440"},
Sven Eckelmannc636b952016-04-11 16:55:26 +02007381 {.id = ALC292_FIXUP_TPT460, .name = "tpt460"},
Takashi Iwaia26d96c2018-06-26 15:09:25 +02007382 {.id = ALC298_FIXUP_TPT470_DOCK, .name = "tpt470-dock"},
Takashi Iwaiba90d6a2017-05-22 16:38:47 +02007383 {.id = ALC233_FIXUP_LENOVO_MULTI_CODECS, .name = "dual-codecs"},
Takashi Iwai28d1d6d2017-10-18 14:01:58 +02007384 {.id = ALC700_FIXUP_INTEL_REFERENCE, .name = "alc700-ref"},
Takashi Iwaia26d96c2018-06-26 15:09:25 +02007385 {.id = ALC269_FIXUP_SONY_VAIO, .name = "vaio"},
7386 {.id = ALC269_FIXUP_DELL_M101Z, .name = "dell-m101z"},
7387 {.id = ALC269_FIXUP_ASUS_G73JW, .name = "asus-g73jw"},
7388 {.id = ALC269_FIXUP_LENOVO_EAPD, .name = "lenovo-eapd"},
7389 {.id = ALC275_FIXUP_SONY_HWEQ, .name = "sony-hweq"},
7390 {.id = ALC269_FIXUP_PCM_44K, .name = "pcm44k"},
7391 {.id = ALC269_FIXUP_LIFEBOOK, .name = "lifebook"},
7392 {.id = ALC269_FIXUP_LIFEBOOK_EXTMIC, .name = "lifebook-extmic"},
7393 {.id = ALC269_FIXUP_LIFEBOOK_HP_PIN, .name = "lifebook-hp-pin"},
7394 {.id = ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC, .name = "lifebook-u7x7"},
7395 {.id = ALC269VB_FIXUP_AMIC, .name = "alc269vb-amic"},
7396 {.id = ALC269VB_FIXUP_DMIC, .name = "alc269vb-dmic"},
7397 {.id = ALC269_FIXUP_HP_MUTE_LED_MIC1, .name = "hp-mute-led-mic1"},
7398 {.id = ALC269_FIXUP_HP_MUTE_LED_MIC2, .name = "hp-mute-led-mic2"},
7399 {.id = ALC269_FIXUP_HP_MUTE_LED_MIC3, .name = "hp-mute-led-mic3"},
7400 {.id = ALC269_FIXUP_HP_GPIO_MIC1_LED, .name = "hp-gpio-mic1"},
7401 {.id = ALC269_FIXUP_HP_LINE1_MIC1_LED, .name = "hp-line1-mic1"},
7402 {.id = ALC269_FIXUP_NO_SHUTUP, .name = "noshutup"},
7403 {.id = ALC286_FIXUP_SONY_MIC_NO_PRESENCE, .name = "sony-nomic"},
7404 {.id = ALC269_FIXUP_ASPIRE_HEADSET_MIC, .name = "aspire-headset-mic"},
7405 {.id = ALC269_FIXUP_ASUS_X101, .name = "asus-x101"},
7406 {.id = ALC271_FIXUP_HP_GATE_MIC_JACK, .name = "acer-ao7xx"},
7407 {.id = ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572, .name = "acer-aspire-e1"},
7408 {.id = ALC269_FIXUP_ACER_AC700, .name = "acer-ac700"},
7409 {.id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST, .name = "limit-mic-boost"},
7410 {.id = ALC269VB_FIXUP_ASUS_ZENBOOK, .name = "asus-zenbook"},
7411 {.id = ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A, .name = "asus-zenbook-ux31a"},
7412 {.id = ALC269VB_FIXUP_ORDISSIMO_EVE2, .name = "ordissimo"},
7413 {.id = ALC282_FIXUP_ASUS_TX300, .name = "asus-tx300"},
7414 {.id = ALC283_FIXUP_INT_MIC, .name = "alc283-int-mic"},
7415 {.id = ALC290_FIXUP_MONO_SPEAKERS_HSJACK, .name = "mono-speakers"},
7416 {.id = ALC290_FIXUP_SUBWOOFER_HSJACK, .name = "alc290-subwoofer"},
7417 {.id = ALC269_FIXUP_THINKPAD_ACPI, .name = "thinkpad"},
7418 {.id = ALC269_FIXUP_DMIC_THINKPAD_ACPI, .name = "dmic-thinkpad"},
7419 {.id = ALC255_FIXUP_ACER_MIC_NO_PRESENCE, .name = "alc255-acer"},
7420 {.id = ALC255_FIXUP_ASUS_MIC_NO_PRESENCE, .name = "alc255-asus"},
7421 {.id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc255-dell1"},
7422 {.id = ALC255_FIXUP_DELL2_MIC_NO_PRESENCE, .name = "alc255-dell2"},
7423 {.id = ALC293_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc293-dell1"},
7424 {.id = ALC283_FIXUP_HEADSET_MIC, .name = "alc283-headset"},
Takashi Iwaib3802782018-11-26 17:47:46 +01007425 {.id = ALC255_FIXUP_MIC_MUTE_LED, .name = "alc255-dell-mute"},
Takashi Iwaia26d96c2018-06-26 15:09:25 +02007426 {.id = ALC282_FIXUP_ASPIRE_V5_PINS, .name = "aspire-v5"},
7427 {.id = ALC280_FIXUP_HP_GPIO4, .name = "hp-gpio4"},
7428 {.id = ALC286_FIXUP_HP_GPIO_LED, .name = "hp-gpio-led"},
7429 {.id = ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY, .name = "hp-gpio2-hotkey"},
7430 {.id = ALC280_FIXUP_HP_DOCK_PINS, .name = "hp-dock-pins"},
7431 {.id = ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED, .name = "hp-dock-gpio-mic"},
7432 {.id = ALC280_FIXUP_HP_9480M, .name = "hp-9480m"},
7433 {.id = ALC288_FIXUP_DELL_HEADSET_MODE, .name = "alc288-dell-headset"},
7434 {.id = ALC288_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc288-dell1"},
7435 {.id = ALC288_FIXUP_DELL_XPS_13, .name = "alc288-dell-xps13"},
7436 {.id = ALC292_FIXUP_DELL_E7X, .name = "dell-e7x"},
7437 {.id = ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK, .name = "alc293-dell"},
7438 {.id = ALC298_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc298-dell1"},
7439 {.id = ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE, .name = "alc298-dell-aio"},
7440 {.id = ALC275_FIXUP_DELL_XPS, .name = "alc275-dell-xps"},
7441 {.id = ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE, .name = "alc256-dell-xps13"},
7442 {.id = ALC293_FIXUP_LENOVO_SPK_NOISE, .name = "lenovo-spk-noise"},
7443 {.id = ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY, .name = "lenovo-hotkey"},
7444 {.id = ALC255_FIXUP_DELL_SPK_NOISE, .name = "dell-spk-noise"},
Kailang Yang82aa0d72019-01-11 17:15:53 +08007445 {.id = ALC225_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc225-dell1"},
Takashi Iwaia26d96c2018-06-26 15:09:25 +02007446 {.id = ALC295_FIXUP_DISABLE_DAC3, .name = "alc295-disable-dac3"},
Jaroslav Kyselad2cd7952019-11-29 15:40:27 +01007447 {.id = ALC285_FIXUP_SPEAKER2_TO_DAC1, .name = "alc285-speaker2-to-dac1"},
Takashi Iwaia26d96c2018-06-26 15:09:25 +02007448 {.id = ALC280_FIXUP_HP_HEADSET_MIC, .name = "alc280-hp-headset"},
7449 {.id = ALC221_FIXUP_HP_FRONT_MIC, .name = "alc221-hp-mic"},
7450 {.id = ALC298_FIXUP_SPK_VOLUME, .name = "alc298-spk-volume"},
7451 {.id = ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER, .name = "dell-inspiron-7559"},
7452 {.id = ALC269_FIXUP_ATIV_BOOK_8, .name = "ativ-book"},
7453 {.id = ALC221_FIXUP_HP_MIC_NO_PRESENCE, .name = "alc221-hp-mic"},
7454 {.id = ALC256_FIXUP_ASUS_HEADSET_MODE, .name = "alc256-asus-headset"},
7455 {.id = ALC256_FIXUP_ASUS_MIC, .name = "alc256-asus-mic"},
7456 {.id = ALC256_FIXUP_ASUS_AIO_GPIO2, .name = "alc256-asus-aio"},
7457 {.id = ALC233_FIXUP_ASUS_MIC_NO_PRESENCE, .name = "alc233-asus"},
7458 {.id = ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE, .name = "alc233-eapd"},
7459 {.id = ALC294_FIXUP_LENOVO_MIC_LOCATION, .name = "alc294-lenovo-mic"},
7460 {.id = ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE, .name = "alc225-wyse"},
7461 {.id = ALC274_FIXUP_DELL_AIO_LINEOUT_VERB, .name = "alc274-dell-aio"},
7462 {.id = ALC255_FIXUP_DUMMY_LINEOUT_VERB, .name = "alc255-dummy-lineout"},
7463 {.id = ALC255_FIXUP_DELL_HEADSET_MIC, .name = "alc255-dell-headset"},
7464 {.id = ALC295_FIXUP_HP_X360, .name = "alc295-hp-x360"},
Kailang Yang8983eb62019-04-03 15:31:49 +08007465 {.id = ALC225_FIXUP_HEADSET_JACK, .name = "alc-headset-jack"},
7466 {.id = ALC295_FIXUP_CHROME_BOOK, .name = "alc-chrome-book"},
Bernhard Rosenkraenzere2a829b2019-03-05 00:38:19 +01007467 {.id = ALC299_FIXUP_PREDATOR_SPK, .name = "predator-spk"},
Tomas Espeletaa2ef03f2019-08-09 16:37:54 +02007468 {.id = ALC298_FIXUP_HUAWEI_MBX_STEREO, .name = "huawei-mbx-stereo"},
Jan-Marek Glogowskibd9c10b2019-09-15 16:57:28 +02007469 {.id = ALC256_FIXUP_MEDION_HEADSET_NO_PRESENCE, .name = "alc256-medion-headset"},
Takashi Iwai1d045db2011-07-07 18:23:21 +02007470 {}
7471};
Kailang Yangcfc5a842016-02-03 15:20:39 +08007472#define ALC225_STANDARD_PINS \
Kailang Yangcfc5a842016-02-03 15:20:39 +08007473 {0x21, 0x04211020}
Takashi Iwai1d045db2011-07-07 18:23:21 +02007474
Hui Wange8191a82015-04-24 13:39:59 +08007475#define ALC256_STANDARD_PINS \
7476 {0x12, 0x90a60140}, \
7477 {0x14, 0x90170110}, \
Hui Wange8191a82015-04-24 13:39:59 +08007478 {0x21, 0x02211020}
7479
David Henningssonfea185e2014-09-03 10:23:04 +02007480#define ALC282_STANDARD_PINS \
Hui Wang11580292015-08-03 11:03:49 +08007481 {0x14, 0x90170110}
Kailang Yange1e62b92015-04-08 16:01:22 +08007482
David Henningssonfea185e2014-09-03 10:23:04 +02007483#define ALC290_STANDARD_PINS \
Hui Wang11580292015-08-03 11:03:49 +08007484 {0x12, 0x99a30130}
David Henningssonfea185e2014-09-03 10:23:04 +02007485
7486#define ALC292_STANDARD_PINS \
7487 {0x14, 0x90170110}, \
Hui Wang11580292015-08-03 11:03:49 +08007488 {0x15, 0x0221401f}
Kailang Yang977e6272015-05-18 15:31:20 +08007489
Hui Wang3f6409702016-09-11 11:26:16 +08007490#define ALC295_STANDARD_PINS \
7491 {0x12, 0xb7a60130}, \
7492 {0x14, 0x90170110}, \
Hui Wang3f6409702016-09-11 11:26:16 +08007493 {0x21, 0x04211020}
7494
Woodrow Shen703867e2015-08-05 12:34:12 +08007495#define ALC298_STANDARD_PINS \
7496 {0x12, 0x90a60130}, \
7497 {0x21, 0x03211020}
7498
Hui Wange1918932014-05-26 16:22:44 +08007499static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
Kailang Yang8a328ac2018-08-21 16:54:41 +08007500 SND_HDA_PIN_QUIRK(0x10ec0221, 0x103c, "HP Workstation", ALC221_FIXUP_HP_HEADSET_MIC,
7501 {0x14, 0x01014020},
7502 {0x17, 0x90170110},
7503 {0x18, 0x02a11030},
7504 {0x19, 0x0181303F},
7505 {0x21, 0x0221102f}),
Chris Chiu5824ce82017-02-28 14:17:11 -06007506 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1025, "Acer", ALC255_FIXUP_ACER_MIC_NO_PRESENCE,
7507 {0x12, 0x90a601c0},
7508 {0x14, 0x90171120},
7509 {0x21, 0x02211030}),
Chris Chiu615966a2017-02-28 14:17:12 -06007510 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1043, "ASUS", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE,
7511 {0x14, 0x90170110},
7512 {0x1b, 0x90a70130},
7513 {0x21, 0x03211020}),
7514 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1043, "ASUS", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE,
7515 {0x1a, 0x90a70130},
7516 {0x1b, 0x90170110},
7517 {0x21, 0x03211020}),
David Henningsson2ae95572016-02-25 09:37:05 +01007518 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
Kailang Yangcfc5a842016-02-03 15:20:39 +08007519 ALC225_STANDARD_PINS,
Hui Wang8a132092016-07-08 14:26:57 +08007520 {0x12, 0xb7a60130},
Kailang Yangcfc5a842016-02-03 15:20:39 +08007521 {0x14, 0x901701a0}),
David Henningsson2ae95572016-02-25 09:37:05 +01007522 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
Kailang Yangcfc5a842016-02-03 15:20:39 +08007523 ALC225_STANDARD_PINS,
Hui Wang8a132092016-07-08 14:26:57 +08007524 {0x12, 0xb7a60130},
Kailang Yangcfc5a842016-02-03 15:20:39 +08007525 {0x14, 0x901701b0}),
Hui Wang8a132092016-07-08 14:26:57 +08007526 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
7527 ALC225_STANDARD_PINS,
7528 {0x12, 0xb7a60150},
7529 {0x14, 0x901701a0}),
7530 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
7531 ALC225_STANDARD_PINS,
7532 {0x12, 0xb7a60150},
7533 {0x14, 0x901701b0}),
7534 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
7535 ALC225_STANDARD_PINS,
7536 {0x12, 0xb7a60130},
7537 {0x1b, 0x90170110}),
Kai-Heng Feng0ce48e12017-11-20 02:29:13 -05007538 SND_HDA_PIN_QUIRK(0x10ec0233, 0x8086, "Intel NUC Skull Canyon", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
7539 {0x1b, 0x01111010},
7540 {0x1e, 0x01451130},
7541 {0x21, 0x02211020}),
Hui Wang986376b2018-05-30 12:33:07 +08007542 SND_HDA_PIN_QUIRK(0x10ec0235, 0x17aa, "Lenovo", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY,
7543 {0x12, 0x90a60140},
7544 {0x14, 0x90170110},
7545 {0x19, 0x02a11030},
7546 {0x21, 0x02211020}),
Hui Wange41fc8c2018-06-25 14:40:56 +08007547 SND_HDA_PIN_QUIRK(0x10ec0235, 0x17aa, "Lenovo", ALC294_FIXUP_LENOVO_MIC_LOCATION,
7548 {0x14, 0x90170110},
7549 {0x19, 0x02a11030},
7550 {0x1a, 0x02a11040},
7551 {0x1b, 0x01014020},
7552 {0x21, 0x0221101f}),
Hui Wangc6b17f12018-07-06 15:14:11 +08007553 SND_HDA_PIN_QUIRK(0x10ec0235, 0x17aa, "Lenovo", ALC294_FIXUP_LENOVO_MIC_LOCATION,
7554 {0x14, 0x90170110},
Hui Wangd06fb562018-10-10 11:57:25 +08007555 {0x19, 0x02a11030},
7556 {0x1a, 0x02a11040},
7557 {0x1b, 0x01011020},
7558 {0x21, 0x0221101f}),
7559 SND_HDA_PIN_QUIRK(0x10ec0235, 0x17aa, "Lenovo", ALC294_FIXUP_LENOVO_MIC_LOCATION,
7560 {0x14, 0x90170110},
Hui Wangc6b17f12018-07-06 15:14:11 +08007561 {0x19, 0x02a11020},
7562 {0x1a, 0x02a11030},
7563 {0x21, 0x0221101f}),
Hui Wangc77900e2014-09-03 11:31:07 +08007564 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE,
Hui Wangc77900e2014-09-03 11:31:07 +08007565 {0x14, 0x90170110},
Hui Wangc77900e2014-09-03 11:31:07 +08007566 {0x21, 0x02211020}),
David Henningsson76c21322014-06-24 14:46:54 +02007567 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang86c72d12016-05-25 12:12:32 +08007568 {0x14, 0x90170130},
7569 {0x21, 0x02211040}),
7570 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningsson76c21322014-06-24 14:46:54 +02007571 {0x12, 0x90a60140},
7572 {0x14, 0x90170110},
David Henningsson76c21322014-06-24 14:46:54 +02007573 {0x21, 0x02211020}),
7574 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7575 {0x12, 0x90a60160},
7576 {0x14, 0x90170120},
David Henningsson76c21322014-06-24 14:46:54 +02007577 {0x21, 0x02211030}),
7578 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang392c9da2016-09-26 10:59:38 +08007579 {0x14, 0x90170110},
7580 {0x1b, 0x02011020},
7581 {0x21, 0x0221101f}),
7582 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang6aecd872016-10-20 14:03:33 +08007583 {0x14, 0x90170110},
7584 {0x1b, 0x01011020},
7585 {0x21, 0x0221101f}),
7586 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssoncba59972015-07-22 10:00:25 +02007587 {0x14, 0x90170130},
David Henningssoncba59972015-07-22 10:00:25 +02007588 {0x1b, 0x01014020},
David Henningssoncba59972015-07-22 10:00:25 +02007589 {0x21, 0x0221103f}),
7590 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang59ec4b52016-08-04 15:28:04 +08007591 {0x14, 0x90170130},
Hui Wang6aecd872016-10-20 14:03:33 +08007592 {0x1b, 0x01011020},
7593 {0x21, 0x0221103f}),
7594 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7595 {0x14, 0x90170130},
Hui Wang59ec4b52016-08-04 15:28:04 +08007596 {0x1b, 0x02011020},
7597 {0x21, 0x0221103f}),
7598 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Woodrow Shene9c28e12015-07-25 10:36:16 +08007599 {0x14, 0x90170150},
Woodrow Shene9c28e12015-07-25 10:36:16 +08007600 {0x1b, 0x02011020},
Woodrow Shene9c28e12015-07-25 10:36:16 +08007601 {0x21, 0x0221105f}),
7602 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Woodrow Shene9c28e12015-07-25 10:36:16 +08007603 {0x14, 0x90170110},
Woodrow Shene9c28e12015-07-25 10:36:16 +08007604 {0x1b, 0x01014020},
Woodrow Shene9c28e12015-07-25 10:36:16 +08007605 {0x21, 0x0221101f}),
7606 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningsson76c21322014-06-24 14:46:54 +02007607 {0x12, 0x90a60160},
7608 {0x14, 0x90170120},
7609 {0x17, 0x90170140},
David Henningsson76c21322014-06-24 14:46:54 +02007610 {0x21, 0x0321102f}),
7611 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7612 {0x12, 0x90a60160},
7613 {0x14, 0x90170130},
David Henningsson76c21322014-06-24 14:46:54 +02007614 {0x21, 0x02211040}),
7615 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7616 {0x12, 0x90a60160},
7617 {0x14, 0x90170140},
David Henningsson76c21322014-06-24 14:46:54 +02007618 {0x21, 0x02211050}),
7619 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7620 {0x12, 0x90a60170},
7621 {0x14, 0x90170120},
David Henningsson76c21322014-06-24 14:46:54 +02007622 {0x21, 0x02211030}),
7623 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7624 {0x12, 0x90a60170},
7625 {0x14, 0x90170130},
David Henningsson76c21322014-06-24 14:46:54 +02007626 {0x21, 0x02211040}),
Hui Wang70658b92015-03-06 14:03:57 +08007627 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang70658b92015-03-06 14:03:57 +08007628 {0x12, 0x90a60170},
Hui Wang0a1f90a2016-01-13 11:51:38 +08007629 {0x14, 0x90171130},
7630 {0x21, 0x02211040}),
7631 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7632 {0x12, 0x90a60170},
Hui Wang70658b92015-03-06 14:03:57 +08007633 {0x14, 0x90170140},
Hui Wang70658b92015-03-06 14:03:57 +08007634 {0x21, 0x02211050}),
David Henningsson9b5a4e32015-05-11 14:04:14 +02007635 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell Inspiron 5548", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningsson9b5a4e32015-05-11 14:04:14 +02007636 {0x12, 0x90a60180},
7637 {0x14, 0x90170130},
David Henningsson9b5a4e32015-05-11 14:04:14 +02007638 {0x21, 0x02211040}),
AceLan Kaof90d83b2016-06-03 14:45:25 +08007639 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell Inspiron 5565", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7640 {0x12, 0x90a60180},
7641 {0x14, 0x90170120},
7642 {0x21, 0x02211030}),
Hui Wang989dbe42016-11-23 16:05:38 +08007643 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7644 {0x1b, 0x01011020},
7645 {0x21, 0x02211010}),
Chris Chiuc1732ed2017-02-28 14:17:13 -06007646 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC,
7647 {0x14, 0x90170110},
7648 {0x1b, 0x90a70130},
7649 {0x21, 0x04211020}),
7650 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC,
7651 {0x14, 0x90170110},
7652 {0x1b, 0x90a70130},
7653 {0x21, 0x03211020}),
Jian-Hong Pane1037352019-03-22 11:37:18 +08007654 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE,
Chris Chiua806ef12019-03-22 11:37:20 +08007655 {0x12, 0x90a60130},
7656 {0x14, 0x90170110},
7657 {0x21, 0x03211020}),
7658 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE,
Jian-Hong Pan6ac371a2019-03-22 11:37:22 +08007659 {0x12, 0x90a60130},
7660 {0x14, 0x90170110},
7661 {0x21, 0x04211020}),
7662 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE,
Jian-Hong Pane1037352019-03-22 11:37:18 +08007663 {0x1a, 0x90a70130},
7664 {0x1b, 0x90170110},
7665 {0x21, 0x03211020}),
David Henningssoncf51eb92014-10-30 08:26:02 +01007666 SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC280_FIXUP_HP_GPIO4,
7667 {0x12, 0x90a60130},
David Henningssoncf51eb92014-10-30 08:26:02 +01007668 {0x14, 0x90170110},
7669 {0x15, 0x0421101f},
Hui Wang11580292015-08-03 11:03:49 +08007670 {0x1a, 0x04a11020}),
Hui Wang02796612014-09-03 11:31:11 +08007671 SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED,
7672 {0x12, 0x90a60140},
Hui Wang02796612014-09-03 11:31:11 +08007673 {0x14, 0x90170110},
7674 {0x15, 0x0421101f},
Hui Wang02796612014-09-03 11:31:11 +08007675 {0x18, 0x02811030},
Hui Wang02796612014-09-03 11:31:11 +08007676 {0x1a, 0x04a1103f},
Hui Wang11580292015-08-03 11:03:49 +08007677 {0x1b, 0x02011020}),
David Henningsson42304472014-07-22 11:42:17 +02007678 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP 15 Touchsmart", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007679 ALC282_STANDARD_PINS,
David Henningsson42304472014-07-22 11:42:17 +02007680 {0x12, 0x99a30130},
David Henningsson42304472014-07-22 11:42:17 +02007681 {0x19, 0x03a11020},
David Henningsson42304472014-07-22 11:42:17 +02007682 {0x21, 0x0321101f}),
Hui Wang2c609992014-09-03 11:31:08 +08007683 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007684 ALC282_STANDARD_PINS,
Hui Wang2c609992014-09-03 11:31:08 +08007685 {0x12, 0x99a30130},
Hui Wang2c609992014-09-03 11:31:08 +08007686 {0x19, 0x03a11020},
Hui Wang2c609992014-09-03 11:31:08 +08007687 {0x21, 0x03211040}),
7688 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007689 ALC282_STANDARD_PINS,
Hui Wang2c609992014-09-03 11:31:08 +08007690 {0x12, 0x99a30130},
Hui Wang2c609992014-09-03 11:31:08 +08007691 {0x19, 0x03a11030},
Hui Wang2c609992014-09-03 11:31:08 +08007692 {0x21, 0x03211020}),
7693 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007694 ALC282_STANDARD_PINS,
Hui Wang2c609992014-09-03 11:31:08 +08007695 {0x12, 0x99a30130},
Hui Wang2c609992014-09-03 11:31:08 +08007696 {0x19, 0x04a11020},
Hui Wang2c609992014-09-03 11:31:08 +08007697 {0x21, 0x0421101f}),
Hui Wang200afc02014-09-03 11:31:10 +08007698 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED,
David Henningssonaec856d2014-09-03 10:23:05 +02007699 ALC282_STANDARD_PINS,
Hui Wang200afc02014-09-03 11:31:10 +08007700 {0x12, 0x90a60140},
Hui Wang200afc02014-09-03 11:31:10 +08007701 {0x19, 0x04a11030},
Hui Wang200afc02014-09-03 11:31:10 +08007702 {0x21, 0x04211020}),
David Henningsson76c21322014-06-24 14:46:54 +02007703 SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007704 ALC282_STANDARD_PINS,
David Henningsson76c21322014-06-24 14:46:54 +02007705 {0x12, 0x90a60130},
David Henningsson76c21322014-06-24 14:46:54 +02007706 {0x21, 0x0321101f}),
7707 SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
7708 {0x12, 0x90a60160},
7709 {0x14, 0x90170120},
David Henningsson76c21322014-06-24 14:46:54 +02007710 {0x21, 0x02211030}),
Hui Wangbc262172014-09-03 11:31:05 +08007711 SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007712 ALC282_STANDARD_PINS,
Hui Wangbc262172014-09-03 11:31:05 +08007713 {0x12, 0x90a60130},
Hui Wangbc262172014-09-03 11:31:05 +08007714 {0x19, 0x03a11020},
Hui Wangbc262172014-09-03 11:31:05 +08007715 {0x21, 0x0321101f}),
Hui Wangc8c6ee62019-02-14 11:41:33 +08007716 SND_HDA_PIN_QUIRK(0x10ec0285, 0x17aa, "Lenovo", ALC285_FIXUP_LENOVO_PC_BEEP_IN_NOISE,
Hui Wangc4cfcf62018-11-26 14:17:16 +08007717 {0x12, 0x90a60130},
7718 {0x14, 0x90170110},
7719 {0x19, 0x04a11040},
7720 {0x21, 0x04211020}),
Chris Chiu33aaebd2018-12-05 14:48:53 +08007721 SND_HDA_PIN_QUIRK(0x10ec0286, 0x1025, "Acer", ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE,
7722 {0x12, 0x90a60130},
7723 {0x17, 0x90170110},
7724 {0x21, 0x02211020}),
Takashi Iwaid44a6862018-06-19 23:04:03 +02007725 SND_HDA_PIN_QUIRK(0x10ec0288, 0x1028, "Dell", ALC288_FIXUP_DELL1_MIC_NO_PRESENCE,
Kailang Yange1e62b92015-04-08 16:01:22 +08007726 {0x12, 0x90a60120},
Kailang Yange1e62b92015-04-08 16:01:22 +08007727 {0x14, 0x90170110},
Kailang Yange1e62b92015-04-08 16:01:22 +08007728 {0x21, 0x0321101f}),
Hui Wange4442bc2014-09-03 11:31:09 +08007729 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007730 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08007731 {0x15, 0x04211040},
Hui Wange4442bc2014-09-03 11:31:09 +08007732 {0x18, 0x90170112},
Hui Wang11580292015-08-03 11:03:49 +08007733 {0x1a, 0x04a11020}),
Hui Wange4442bc2014-09-03 11:31:09 +08007734 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007735 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08007736 {0x15, 0x04211040},
Hui Wange4442bc2014-09-03 11:31:09 +08007737 {0x18, 0x90170110},
Hui Wang11580292015-08-03 11:03:49 +08007738 {0x1a, 0x04a11020}),
Hui Wange4442bc2014-09-03 11:31:09 +08007739 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007740 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08007741 {0x15, 0x0421101f},
Hui Wang11580292015-08-03 11:03:49 +08007742 {0x1a, 0x04a11020}),
Hui Wange4442bc2014-09-03 11:31:09 +08007743 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007744 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08007745 {0x15, 0x04211020},
Hui Wang11580292015-08-03 11:03:49 +08007746 {0x1a, 0x04a11040}),
Hui Wange4442bc2014-09-03 11:31:09 +08007747 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007748 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08007749 {0x14, 0x90170110},
7750 {0x15, 0x04211020},
Hui Wang11580292015-08-03 11:03:49 +08007751 {0x1a, 0x04a11040}),
Hui Wange4442bc2014-09-03 11:31:09 +08007752 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007753 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08007754 {0x14, 0x90170110},
7755 {0x15, 0x04211020},
Hui Wang11580292015-08-03 11:03:49 +08007756 {0x1a, 0x04a11020}),
Hui Wange4442bc2014-09-03 11:31:09 +08007757 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007758 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08007759 {0x14, 0x90170110},
7760 {0x15, 0x0421101f},
Hui Wang11580292015-08-03 11:03:49 +08007761 {0x1a, 0x04a11020}),
Hui Wange8818fa2014-09-03 11:31:04 +08007762 SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007763 ALC292_STANDARD_PINS,
Hui Wange8818fa2014-09-03 11:31:04 +08007764 {0x12, 0x90a60140},
Hui Wange8818fa2014-09-03 11:31:04 +08007765 {0x16, 0x01014020},
Hui Wang11580292015-08-03 11:03:49 +08007766 {0x19, 0x01a19030}),
Hui Wange8818fa2014-09-03 11:31:04 +08007767 SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007768 ALC292_STANDARD_PINS,
Hui Wange8818fa2014-09-03 11:31:04 +08007769 {0x12, 0x90a60140},
Hui Wange8818fa2014-09-03 11:31:04 +08007770 {0x16, 0x01014020},
7771 {0x18, 0x02a19031},
Hui Wang11580292015-08-03 11:03:49 +08007772 {0x19, 0x01a1903e}),
David Henningsson76c21322014-06-24 14:46:54 +02007773 SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007774 ALC292_STANDARD_PINS,
Hui Wang11580292015-08-03 11:03:49 +08007775 {0x12, 0x90a60140}),
David Henningsson76c21322014-06-24 14:46:54 +02007776 SND_HDA_PIN_QUIRK(0x10ec0293, 0x1028, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007777 ALC292_STANDARD_PINS,
David Henningsson76c21322014-06-24 14:46:54 +02007778 {0x13, 0x90a60140},
David Henningsson76c21322014-06-24 14:46:54 +02007779 {0x16, 0x21014020},
Hui Wang11580292015-08-03 11:03:49 +08007780 {0x19, 0x21a19030}),
David Henningssone03fdbd2014-06-27 08:41:59 +02007781 SND_HDA_PIN_QUIRK(0x10ec0293, 0x1028, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007782 ALC292_STANDARD_PINS,
Hui Wang11580292015-08-03 11:03:49 +08007783 {0x13, 0x90a60140}),
Chris Chiud8ae4582018-12-07 17:17:11 +08007784 SND_HDA_PIN_QUIRK(0x10ec0294, 0x1043, "ASUS", ALC294_FIXUP_ASUS_MIC,
7785 {0x14, 0x90170110},
7786 {0x1b, 0x90a70130},
7787 {0x21, 0x04211020}),
Jian-Hong Pan0bea4cc2018-12-07 17:17:13 +08007788 SND_HDA_PIN_QUIRK(0x10ec0294, 0x1043, "ASUS", ALC294_FIXUP_ASUS_SPK,
7789 {0x12, 0x90a60130},
7790 {0x17, 0x90170110},
Jian-Hong Pan8bb37a22019-02-21 17:00:18 +08007791 {0x21, 0x03211020}),
7792 SND_HDA_PIN_QUIRK(0x10ec0294, 0x1043, "ASUS", ALC294_FIXUP_ASUS_SPK,
7793 {0x12, 0x90a60130},
7794 {0x17, 0x90170110},
Jian-Hong Pan0bea4cc2018-12-07 17:17:13 +08007795 {0x21, 0x04211020}),
Takashi Iwai3887c262019-04-30 15:10:01 +02007796 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1043, "ASUS", ALC294_FIXUP_ASUS_SPK,
7797 {0x12, 0x90a60130},
7798 {0x17, 0x90170110},
7799 {0x21, 0x03211020}),
Kailang Yangfbc57122019-07-15 10:41:50 +08007800 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
Kailang Yang0a29c572019-04-24 16:34:25 +08007801 {0x14, 0x90170110},
7802 {0x21, 0x04211020}),
Kailang Yangfbc57122019-07-15 10:41:50 +08007803 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
7804 {0x14, 0x90170110},
7805 {0x21, 0x04211030}),
Hui Wang3f6409702016-09-11 11:26:16 +08007806 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wangf771d5b2016-10-18 10:59:09 +08007807 ALC295_STANDARD_PINS,
7808 {0x17, 0x21014020},
7809 {0x18, 0x21a19030}),
7810 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
7811 ALC295_STANDARD_PINS,
7812 {0x17, 0x21014040},
7813 {0x18, 0x21a19050}),
Hui Wang3f307832017-03-23 10:00:25 +08007814 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
7815 ALC295_STANDARD_PINS),
Kailang Yang977e6272015-05-18 15:31:20 +08007816 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
Woodrow Shen703867e2015-08-05 12:34:12 +08007817 ALC298_STANDARD_PINS,
Takashi Iwai9f502ff2015-08-05 12:09:45 +02007818 {0x17, 0x90170110}),
7819 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
7820 ALC298_STANDARD_PINS,
Woodrow Shen703867e2015-08-05 12:34:12 +08007821 {0x17, 0x90170140}),
7822 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
7823 ALC298_STANDARD_PINS,
Takashi Iwai9f502ff2015-08-05 12:09:45 +02007824 {0x17, 0x90170150}),
Kai-Heng Feng9f1bc2c42017-02-16 15:26:54 +08007825 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_SPK_VOLUME,
7826 {0x12, 0xb7a60140},
7827 {0x13, 0xb7a60150},
7828 {0x17, 0x90170110},
7829 {0x1a, 0x03011020},
7830 {0x21, 0x03211030}),
James McDonnell54324222019-09-16 14:53:38 +00007831 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_ALIENWARE_MIC_NO_PRESENCE,
7832 {0x12, 0xb7a60140},
7833 {0x17, 0x90170110},
7834 {0x1a, 0x03a11030},
7835 {0x21, 0x03211020}),
Kailang Yangfcc6c872017-06-29 15:21:27 +08007836 SND_HDA_PIN_QUIRK(0x10ec0299, 0x1028, "Dell", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
7837 ALC225_STANDARD_PINS,
7838 {0x12, 0xb7a60130},
Kailang Yangfcc6c872017-06-29 15:21:27 +08007839 {0x17, 0x90170110}),
Hui Wange1918932014-05-26 16:22:44 +08007840 {}
7841};
Takashi Iwai1d045db2011-07-07 18:23:21 +02007842
Hui Wang7c0a6932019-08-16 14:27:40 +08007843/* This is the fallback pin_fixup_tbl for alc269 family, to make the tbl match
7844 * more machines, don't need to match all valid pins, just need to match
7845 * all the pins defined in the tbl. Just because of this reason, it is possible
7846 * that a single machine matches multiple tbls, so there is one limitation:
7847 * at most one tbl is allowed to define for the same vendor and same codec
7848 */
7849static const struct snd_hda_pin_quirk alc269_fallback_pin_fixup_tbl[] = {
7850 SND_HDA_PIN_QUIRK(0x10ec0289, 0x1028, "Dell", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
7851 {0x19, 0x40000000},
7852 {0x1b, 0x40000000}),
Hui Wangaed8c7f2019-11-21 10:26:43 +08007853 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7854 {0x19, 0x40000000},
7855 {0x1a, 0x40000000}),
Hui Wangd64ebdb2019-11-21 10:26:44 +08007856 SND_HDA_PIN_QUIRK(0x10ec0236, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7857 {0x19, 0x40000000},
7858 {0x1a, 0x40000000}),
Hui Wang5815bdf2019-12-11 13:13:21 +08007859 SND_HDA_PIN_QUIRK(0x10ec0274, 0x1028, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB,
7860 {0x19, 0x40000000},
7861 {0x1a, 0x40000000}),
Hui Wang7c0a6932019-08-16 14:27:40 +08007862 {}
7863};
7864
Takashi Iwai546bb672012-03-07 08:37:19 +01007865static void alc269_fill_coef(struct hda_codec *codec)
Takashi Iwai1d045db2011-07-07 18:23:21 +02007866{
Kailang Yang526af6e2012-03-07 08:25:20 +01007867 struct alc_spec *spec = codec->spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02007868 int val;
7869
Kailang Yang526af6e2012-03-07 08:25:20 +01007870 if (spec->codec_variant != ALC269_TYPE_ALC269VB)
Takashi Iwai546bb672012-03-07 08:37:19 +01007871 return;
Kailang Yang526af6e2012-03-07 08:25:20 +01007872
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007873 if ((alc_get_coef0(codec) & 0x00ff) < 0x015) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02007874 alc_write_coef_idx(codec, 0xf, 0x960b);
7875 alc_write_coef_idx(codec, 0xe, 0x8817);
7876 }
7877
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007878 if ((alc_get_coef0(codec) & 0x00ff) == 0x016) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02007879 alc_write_coef_idx(codec, 0xf, 0x960b);
7880 alc_write_coef_idx(codec, 0xe, 0x8814);
7881 }
7882
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007883 if ((alc_get_coef0(codec) & 0x00ff) == 0x017) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02007884 /* Power up output pin */
Takashi Iwai98b24882014-08-18 13:47:50 +02007885 alc_update_coef_idx(codec, 0x04, 0, 1<<11);
Takashi Iwai1d045db2011-07-07 18:23:21 +02007886 }
7887
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007888 if ((alc_get_coef0(codec) & 0x00ff) == 0x018) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02007889 val = alc_read_coef_idx(codec, 0xd);
Takashi Iwaif3ee07d2014-08-15 17:35:00 +02007890 if (val != -1 && (val & 0x0c00) >> 10 != 0x1) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02007891 /* Capless ramp up clock control */
7892 alc_write_coef_idx(codec, 0xd, val | (1<<10));
7893 }
7894 val = alc_read_coef_idx(codec, 0x17);
Takashi Iwaif3ee07d2014-08-15 17:35:00 +02007895 if (val != -1 && (val & 0x01c0) >> 6 != 0x4) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02007896 /* Class D power on reset */
7897 alc_write_coef_idx(codec, 0x17, val | (1<<7));
7898 }
7899 }
7900
Takashi Iwai98b24882014-08-18 13:47:50 +02007901 /* HP */
7902 alc_update_coef_idx(codec, 0x4, 0, 1<<11);
Takashi Iwai1d045db2011-07-07 18:23:21 +02007903}
7904
7905/*
7906 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02007907static int patch_alc269(struct hda_codec *codec)
7908{
7909 struct alc_spec *spec;
Takashi Iwai3de95172012-05-07 18:03:15 +02007910 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02007911
Takashi Iwai3de95172012-05-07 18:03:15 +02007912 err = alc_alloc_spec(codec, 0x0b);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007913 if (err < 0)
Takashi Iwai3de95172012-05-07 18:03:15 +02007914 return err;
7915
7916 spec = codec->spec;
Takashi Iwai08c189f2012-12-19 15:22:24 +01007917 spec->gen.shared_mic_vref_pin = 0x18;
Kailang Yang317d9312019-05-23 14:43:04 +08007918 codec->power_save_node = 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007919
Takashi Iwai225068a2015-05-29 10:42:14 +02007920#ifdef CONFIG_PM
7921 codec->patch_ops.suspend = alc269_suspend;
7922 codec->patch_ops.resume = alc269_resume;
7923#endif
Kailang Yangc2d6af52017-06-21 14:50:54 +08007924 spec->shutup = alc_default_shutup;
7925 spec->init_hook = alc_default_init;
Takashi Iwai225068a2015-05-29 10:42:14 +02007926
Takashi Iwai7639a062015-03-03 10:07:24 +01007927 switch (codec->core.vendor_id) {
Kailang Yang065380f2013-01-10 10:25:48 +01007928 case 0x10ec0269:
Takashi Iwai1d045db2011-07-07 18:23:21 +02007929 spec->codec_variant = ALC269_TYPE_ALC269VA;
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007930 switch (alc_get_coef0(codec) & 0x00f0) {
7931 case 0x0010:
Takashi Iwai5100cd02014-02-15 10:03:19 +01007932 if (codec->bus->pci &&
7933 codec->bus->pci->subsystem_vendor == 0x1025 &&
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007934 spec->cdefine.platform_type == 1)
Takashi Iwai20ca0c32011-10-17 16:00:35 +02007935 err = alc_codec_rename(codec, "ALC271X");
Takashi Iwai1d045db2011-07-07 18:23:21 +02007936 spec->codec_variant = ALC269_TYPE_ALC269VB;
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007937 break;
7938 case 0x0020:
Takashi Iwai5100cd02014-02-15 10:03:19 +01007939 if (codec->bus->pci &&
7940 codec->bus->pci->subsystem_vendor == 0x17aa &&
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007941 codec->bus->pci->subsystem_device == 0x21f3)
Takashi Iwai20ca0c32011-10-17 16:00:35 +02007942 err = alc_codec_rename(codec, "ALC3202");
Takashi Iwai1d045db2011-07-07 18:23:21 +02007943 spec->codec_variant = ALC269_TYPE_ALC269VC;
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007944 break;
Kailang Yangadcc70b2012-05-25 08:08:38 +02007945 case 0x0030:
7946 spec->codec_variant = ALC269_TYPE_ALC269VD;
7947 break;
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007948 default:
Takashi Iwai1d045db2011-07-07 18:23:21 +02007949 alc_fix_pll_init(codec, 0x20, 0x04, 15);
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007950 }
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007951 if (err < 0)
7952 goto error;
Kailang Yangc2d6af52017-06-21 14:50:54 +08007953 spec->shutup = alc269_shutup;
Takashi Iwai546bb672012-03-07 08:37:19 +01007954 spec->init_hook = alc269_fill_coef;
Takashi Iwai1d045db2011-07-07 18:23:21 +02007955 alc269_fill_coef(codec);
Kailang Yang065380f2013-01-10 10:25:48 +01007956 break;
7957
7958 case 0x10ec0280:
7959 case 0x10ec0290:
7960 spec->codec_variant = ALC269_TYPE_ALC280;
7961 break;
7962 case 0x10ec0282:
Kailang Yang065380f2013-01-10 10:25:48 +01007963 spec->codec_variant = ALC269_TYPE_ALC282;
Kailang Yang7b5c7a02014-03-18 16:15:54 +08007964 spec->shutup = alc282_shutup;
7965 spec->init_hook = alc282_init;
Kailang Yang065380f2013-01-10 10:25:48 +01007966 break;
Kailang Yang2af02be2013-08-22 10:03:50 +02007967 case 0x10ec0233:
7968 case 0x10ec0283:
7969 spec->codec_variant = ALC269_TYPE_ALC283;
7970 spec->shutup = alc283_shutup;
7971 spec->init_hook = alc283_init;
7972 break;
Kailang Yang065380f2013-01-10 10:25:48 +01007973 case 0x10ec0284:
7974 case 0x10ec0292:
7975 spec->codec_variant = ALC269_TYPE_ALC284;
7976 break;
Kailang Yang161ebf22013-10-24 11:36:33 +02007977 case 0x10ec0293:
Kailang Yang4731d5d2017-06-30 15:22:57 +08007978 spec->codec_variant = ALC269_TYPE_ALC293;
Kailang Yang161ebf22013-10-24 11:36:33 +02007979 break;
Kailang Yang7fc7d042013-04-25 11:04:43 +02007980 case 0x10ec0286:
Kailang Yang7c665932014-04-14 15:09:44 +08007981 case 0x10ec0288:
Kailang Yang7fc7d042013-04-25 11:04:43 +02007982 spec->codec_variant = ALC269_TYPE_ALC286;
7983 break;
Kailang Yang506b62c2014-12-18 17:07:44 +08007984 case 0x10ec0298:
7985 spec->codec_variant = ALC269_TYPE_ALC298;
7986 break;
Kailang Yangea04a1d2018-04-25 15:31:52 +08007987 case 0x10ec0235:
Kailang Yang1d04c9d2013-10-24 11:35:18 +02007988 case 0x10ec0255:
7989 spec->codec_variant = ALC269_TYPE_ALC255;
Kailang Yangab3b8e52018-04-25 16:05:27 +08007990 spec->shutup = alc256_shutup;
7991 spec->init_hook = alc256_init;
Kailang Yang1d04c9d2013-10-24 11:35:18 +02007992 break;
Kailang Yang736f20a2017-10-20 15:06:34 +08007993 case 0x10ec0236:
Kailang Yang4344aec2014-12-17 17:39:05 +08007994 case 0x10ec0256:
7995 spec->codec_variant = ALC269_TYPE_ALC256;
Kailang Yang4a219ef2017-06-16 16:54:35 +08007996 spec->shutup = alc256_shutup;
7997 spec->init_hook = alc256_init;
David Henningsson7d1b6e22015-04-21 10:48:46 +02007998 spec->gen.mixer_nid = 0; /* ALC256 does not have any loopback mixer path */
Kailang Yang4344aec2014-12-17 17:39:05 +08007999 break;
Kailang Yangf429e7e2017-12-05 15:38:24 +08008000 case 0x10ec0257:
8001 spec->codec_variant = ALC269_TYPE_ALC257;
Kailang Yang88d42b22018-03-14 16:08:57 +08008002 spec->shutup = alc256_shutup;
8003 spec->init_hook = alc256_init;
Kailang Yangf429e7e2017-12-05 15:38:24 +08008004 spec->gen.mixer_nid = 0;
8005 break;
Kailang Yang0a6f0602017-06-30 16:00:48 +08008006 case 0x10ec0215:
8007 case 0x10ec0285:
8008 case 0x10ec0289:
8009 spec->codec_variant = ALC269_TYPE_ALC215;
Kailang Yang1b6832be2018-01-17 15:32:03 +08008010 spec->shutup = alc225_shutup;
8011 spec->init_hook = alc225_init;
Kailang Yang0a6f0602017-06-30 16:00:48 +08008012 spec->gen.mixer_nid = 0;
8013 break;
Kailang Yang42314302016-02-03 15:03:50 +08008014 case 0x10ec0225:
Kailang Yang7d727862016-05-24 16:46:07 +08008015 case 0x10ec0295:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08008016 case 0x10ec0299:
Kailang Yang42314302016-02-03 15:03:50 +08008017 spec->codec_variant = ALC269_TYPE_ALC225;
Kailang Yangda911b12018-01-05 16:50:08 +08008018 spec->shutup = alc225_shutup;
8019 spec->init_hook = alc225_init;
Takashi Iwaic1350bf2017-12-27 09:03:45 +01008020 spec->gen.mixer_nid = 0; /* no loopback on ALC225, ALC295 and ALC299 */
Kailang Yang42314302016-02-03 15:03:50 +08008021 break;
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08008022 case 0x10ec0234:
8023 case 0x10ec0274:
8024 case 0x10ec0294:
8025 spec->codec_variant = ALC269_TYPE_ALC294;
Hui Wang532a7782017-06-26 12:30:32 +08008026 spec->gen.mixer_nid = 0; /* ALC2x4 does not have any loopback mixer path */
Kailang Yang71683c32017-06-20 16:33:50 +08008027 alc_update_coef_idx(codec, 0x6b, 0x0018, (1<<4) | (1<<3)); /* UAJ MIC Vref control by verb */
Kailang Yang693abe12019-01-29 15:38:21 +08008028 spec->init_hook = alc294_init;
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08008029 break;
Kailang Yang1078bef2018-11-08 16:36:15 +08008030 case 0x10ec0300:
8031 spec->codec_variant = ALC269_TYPE_ALC300;
8032 spec->gen.mixer_nid = 0; /* no loopback on ALC300 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02008033 break;
Kailang Yangf0778872019-10-24 15:13:32 +08008034 case 0x10ec0623:
8035 spec->codec_variant = ALC269_TYPE_ALC623;
8036 break;
Kailang Yang6fbae352016-05-30 16:44:20 +08008037 case 0x10ec0700:
8038 case 0x10ec0701:
8039 case 0x10ec0703:
Kailang Yang83629532019-05-02 16:03:26 +08008040 case 0x10ec0711:
Kailang Yang6fbae352016-05-30 16:44:20 +08008041 spec->codec_variant = ALC269_TYPE_ALC700;
8042 spec->gen.mixer_nid = 0; /* ALC700 does not have any loopback mixer path */
Kailang Yang2d7fe612017-11-22 15:21:32 +08008043 alc_update_coef_idx(codec, 0x4a, 1 << 15, 0); /* Combo jack auto trigger control */
Kailang Yang693abe12019-01-29 15:38:21 +08008044 spec->init_hook = alc294_init;
Kailang Yang6fbae352016-05-30 16:44:20 +08008045 break;
8046
Takashi Iwai1d045db2011-07-07 18:23:21 +02008047 }
8048
Kailang Yangad60d502013-06-28 12:03:01 +02008049 if (snd_hda_codec_read(codec, 0x51, 0, AC_VERB_PARAMETERS, 0) == 0x10ec5505) {
Kailang Yang97a26572013-11-29 00:35:26 -05008050 spec->has_alc5505_dsp = 1;
Kailang Yangad60d502013-06-28 12:03:01 +02008051 spec->init_hook = alc5505_dsp_init;
8052 }
8053
Takashi Iwaic9af7532019-05-10 11:01:43 +02008054 alc_pre_init(codec);
8055
Takashi Iwaiefe55732018-06-15 11:55:02 +02008056 snd_hda_pick_fixup(codec, alc269_fixup_models,
8057 alc269_fixup_tbl, alc269_fixups);
Hui Wang0fc1e442019-08-16 14:27:39 +08008058 snd_hda_pick_pin_fixup(codec, alc269_pin_fixup_tbl, alc269_fixups, true);
Hui Wang7c0a6932019-08-16 14:27:40 +08008059 snd_hda_pick_pin_fixup(codec, alc269_fallback_pin_fixup_tbl, alc269_fixups, false);
Takashi Iwaiefe55732018-06-15 11:55:02 +02008060 snd_hda_pick_fixup(codec, NULL, alc269_fixup_vendor_tbl,
8061 alc269_fixups);
8062 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
8063
8064 alc_auto_parse_customize_define(codec);
8065
8066 if (has_cdefine_beep(codec))
8067 spec->gen.beep_nid = 0x01;
8068
Takashi Iwaia4297b52011-08-23 18:40:12 +02008069 /* automatic parse from the BIOS config */
8070 err = alc269_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008071 if (err < 0)
8072 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008073
Takashi Iwaifea80fa2018-06-20 12:52:46 +02008074 if (!spec->gen.no_analog && spec->gen.beep_nid && spec->gen.mixer_nid) {
8075 err = set_beep_amp(spec, spec->gen.mixer_nid, 0x04, HDA_INPUT);
8076 if (err < 0)
8077 goto error;
8078 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02008079
Takashi Iwai1727a772013-01-10 09:52:52 +01008080 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01008081
Takashi Iwai1d045db2011-07-07 18:23:21 +02008082 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008083
8084 error:
8085 alc_free(codec);
8086 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008087}
8088
8089/*
8090 * ALC861
8091 */
8092
Takashi Iwai1d045db2011-07-07 18:23:21 +02008093static int alc861_parse_auto_config(struct hda_codec *codec)
8094{
Takashi Iwai1d045db2011-07-07 18:23:21 +02008095 static const hda_nid_t alc861_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02008096 static const hda_nid_t alc861_ssids[] = { 0x0e, 0x0f, 0x0b, 0 };
8097 return alc_parse_auto_config(codec, alc861_ignore, alc861_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02008098}
8099
Takashi Iwai1d045db2011-07-07 18:23:21 +02008100/* Pin config fixes */
8101enum {
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008102 ALC861_FIXUP_FSC_AMILO_PI1505,
8103 ALC861_FIXUP_AMP_VREF_0F,
8104 ALC861_FIXUP_NO_JACK_DETECT,
8105 ALC861_FIXUP_ASUS_A6RP,
Takashi Iwai6ddf0fd2013-11-29 12:47:34 +01008106 ALC660_FIXUP_ASUS_W7J,
Takashi Iwai1d045db2011-07-07 18:23:21 +02008107};
8108
Takashi Iwai31150f22012-01-30 10:54:08 +01008109/* On some laptops, VREF of pin 0x0f is abused for controlling the main amp */
8110static void alc861_fixup_asus_amp_vref_0f(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01008111 const struct hda_fixup *fix, int action)
Takashi Iwai31150f22012-01-30 10:54:08 +01008112{
8113 struct alc_spec *spec = codec->spec;
8114 unsigned int val;
8115
Takashi Iwai1727a772013-01-10 09:52:52 +01008116 if (action != HDA_FIXUP_ACT_INIT)
Takashi Iwai31150f22012-01-30 10:54:08 +01008117 return;
Takashi Iwaid3f02d62013-01-10 10:12:22 +01008118 val = snd_hda_codec_get_pin_target(codec, 0x0f);
Takashi Iwai31150f22012-01-30 10:54:08 +01008119 if (!(val & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN)))
8120 val |= AC_PINCTL_IN_EN;
8121 val |= AC_PINCTL_VREF_50;
Takashi Iwaicdd03ce2012-04-20 12:34:50 +02008122 snd_hda_set_pin_ctl(codec, 0x0f, val);
Takashi Iwai08c189f2012-12-19 15:22:24 +01008123 spec->gen.keep_vref_in_automute = 1;
Takashi Iwai31150f22012-01-30 10:54:08 +01008124}
8125
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008126/* suppress the jack-detection */
8127static void alc_fixup_no_jack_detect(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01008128 const struct hda_fixup *fix, int action)
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008129{
Takashi Iwai1727a772013-01-10 09:52:52 +01008130 if (action == HDA_FIXUP_ACT_PRE_PROBE)
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008131 codec->no_jack_detect = 1;
Jesper Juhl7d7eb9e2012-04-12 22:11:25 +02008132}
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008133
Takashi Iwai1727a772013-01-10 09:52:52 +01008134static const struct hda_fixup alc861_fixups[] = {
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008135 [ALC861_FIXUP_FSC_AMILO_PI1505] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008136 .type = HDA_FIXUP_PINS,
8137 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02008138 { 0x0b, 0x0221101f }, /* HP */
8139 { 0x0f, 0x90170310 }, /* speaker */
8140 { }
8141 }
8142 },
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008143 [ALC861_FIXUP_AMP_VREF_0F] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008144 .type = HDA_FIXUP_FUNC,
Takashi Iwai31150f22012-01-30 10:54:08 +01008145 .v.func = alc861_fixup_asus_amp_vref_0f,
Takashi Iwai3b25eb62012-01-25 09:55:46 +01008146 },
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008147 [ALC861_FIXUP_NO_JACK_DETECT] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008148 .type = HDA_FIXUP_FUNC,
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008149 .v.func = alc_fixup_no_jack_detect,
8150 },
8151 [ALC861_FIXUP_ASUS_A6RP] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008152 .type = HDA_FIXUP_FUNC,
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008153 .v.func = alc861_fixup_asus_amp_vref_0f,
8154 .chained = true,
8155 .chain_id = ALC861_FIXUP_NO_JACK_DETECT,
Takashi Iwai6ddf0fd2013-11-29 12:47:34 +01008156 },
8157 [ALC660_FIXUP_ASUS_W7J] = {
8158 .type = HDA_FIXUP_VERBS,
8159 .v.verbs = (const struct hda_verb[]) {
8160 /* ASUS W7J needs a magic pin setup on unused NID 0x10
8161 * for enabling outputs
8162 */
8163 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8164 { }
8165 },
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008166 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02008167};
8168
8169static const struct snd_pci_quirk alc861_fixup_tbl[] = {
Takashi Iwai6ddf0fd2013-11-29 12:47:34 +01008170 SND_PCI_QUIRK(0x1043, 0x1253, "ASUS W7J", ALC660_FIXUP_ASUS_W7J),
Takashi Iwaie7ca2372013-12-02 15:27:19 +01008171 SND_PCI_QUIRK(0x1043, 0x1263, "ASUS Z35HL", ALC660_FIXUP_ASUS_W7J),
Takashi Iwaie652f4c2012-02-13 11:56:25 +01008172 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS A6Rp", ALC861_FIXUP_ASUS_A6RP),
8173 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", ALC861_FIXUP_AMP_VREF_0F),
8174 SND_PCI_QUIRK(0x1462, 0x7254, "HP DX2200", ALC861_FIXUP_NO_JACK_DETECT),
8175 SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", ALC861_FIXUP_AMP_VREF_0F),
8176 SND_PCI_QUIRK(0x1584, 0x0000, "Uniwill ECS M31EI", ALC861_FIXUP_AMP_VREF_0F),
8177 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", ALC861_FIXUP_FSC_AMILO_PI1505),
Takashi Iwai1d045db2011-07-07 18:23:21 +02008178 {}
8179};
8180
8181/*
8182 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02008183static int patch_alc861(struct hda_codec *codec)
8184{
8185 struct alc_spec *spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008186 int err;
8187
Takashi Iwai3de95172012-05-07 18:03:15 +02008188 err = alc_alloc_spec(codec, 0x15);
8189 if (err < 0)
8190 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008191
Takashi Iwai3de95172012-05-07 18:03:15 +02008192 spec = codec->spec;
Takashi Iwai2722b532019-08-22 09:55:37 +02008193 if (has_cdefine_beep(codec))
8194 spec->gen.beep_nid = 0x23;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008195
Takashi Iwai225068a2015-05-29 10:42:14 +02008196#ifdef CONFIG_PM
8197 spec->power_hook = alc_power_eapd;
8198#endif
8199
Takashi Iwaic9af7532019-05-10 11:01:43 +02008200 alc_pre_init(codec);
8201
Takashi Iwai1727a772013-01-10 09:52:52 +01008202 snd_hda_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
8203 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02008204
Takashi Iwaicb4e4822011-08-23 17:34:25 +02008205 /* automatic parse from the BIOS config */
8206 err = alc861_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008207 if (err < 0)
8208 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008209
Takashi Iwaifea80fa2018-06-20 12:52:46 +02008210 if (!spec->gen.no_analog) {
8211 err = set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
8212 if (err < 0)
8213 goto error;
8214 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02008215
Takashi Iwai1727a772013-01-10 09:52:52 +01008216 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01008217
Takashi Iwai1d045db2011-07-07 18:23:21 +02008218 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008219
8220 error:
8221 alc_free(codec);
8222 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008223}
8224
8225/*
8226 * ALC861-VD support
8227 *
8228 * Based on ALC882
8229 *
8230 * In addition, an independent DAC
8231 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02008232static int alc861vd_parse_auto_config(struct hda_codec *codec)
8233{
Takashi Iwai1d045db2011-07-07 18:23:21 +02008234 static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02008235 static const hda_nid_t alc861vd_ssids[] = { 0x15, 0x1b, 0x14, 0 };
8236 return alc_parse_auto_config(codec, alc861vd_ignore, alc861vd_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02008237}
8238
Takashi Iwai1d045db2011-07-07 18:23:21 +02008239enum {
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008240 ALC660VD_FIX_ASUS_GPIO1,
8241 ALC861VD_FIX_DALLAS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02008242};
8243
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008244/* exclude VREF80 */
8245static void alc861vd_fixup_dallas(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01008246 const struct hda_fixup *fix, int action)
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008247{
Takashi Iwai1727a772013-01-10 09:52:52 +01008248 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwaib78562b2012-12-17 20:06:49 +01008249 snd_hda_override_pin_caps(codec, 0x18, 0x00000734);
8250 snd_hda_override_pin_caps(codec, 0x19, 0x0000073c);
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008251 }
8252}
8253
Takashi Iwaidf73d832018-06-19 23:05:47 +02008254/* reset GPIO1 */
8255static void alc660vd_fixup_asus_gpio1(struct hda_codec *codec,
8256 const struct hda_fixup *fix, int action)
8257{
8258 struct alc_spec *spec = codec->spec;
8259
8260 if (action == HDA_FIXUP_ACT_PRE_PROBE)
8261 spec->gpio_mask |= 0x02;
8262 alc_fixup_gpio(codec, action, 0x01);
8263}
8264
Takashi Iwai1727a772013-01-10 09:52:52 +01008265static const struct hda_fixup alc861vd_fixups[] = {
Takashi Iwai1d045db2011-07-07 18:23:21 +02008266 [ALC660VD_FIX_ASUS_GPIO1] = {
Takashi Iwaidf73d832018-06-19 23:05:47 +02008267 .type = HDA_FIXUP_FUNC,
8268 .v.func = alc660vd_fixup_asus_gpio1,
Takashi Iwai1d045db2011-07-07 18:23:21 +02008269 },
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008270 [ALC861VD_FIX_DALLAS] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008271 .type = HDA_FIXUP_FUNC,
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008272 .v.func = alc861vd_fixup_dallas,
8273 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02008274};
8275
8276static const struct snd_pci_quirk alc861vd_fixup_tbl[] = {
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008277 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_FIX_DALLAS),
Takashi Iwai1d045db2011-07-07 18:23:21 +02008278 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008279 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_FIX_DALLAS),
Takashi Iwai1d045db2011-07-07 18:23:21 +02008280 {}
8281};
8282
Takashi Iwai1d045db2011-07-07 18:23:21 +02008283/*
8284 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02008285static int patch_alc861vd(struct hda_codec *codec)
8286{
8287 struct alc_spec *spec;
Takashi Iwaicb4e4822011-08-23 17:34:25 +02008288 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008289
Takashi Iwai3de95172012-05-07 18:03:15 +02008290 err = alc_alloc_spec(codec, 0x0b);
8291 if (err < 0)
8292 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008293
Takashi Iwai3de95172012-05-07 18:03:15 +02008294 spec = codec->spec;
Takashi Iwai2722b532019-08-22 09:55:37 +02008295 if (has_cdefine_beep(codec))
8296 spec->gen.beep_nid = 0x23;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008297
Takashi Iwai225068a2015-05-29 10:42:14 +02008298 spec->shutup = alc_eapd_shutup;
8299
Takashi Iwaic9af7532019-05-10 11:01:43 +02008300 alc_pre_init(codec);
8301
Takashi Iwai1727a772013-01-10 09:52:52 +01008302 snd_hda_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
8303 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02008304
Takashi Iwaicb4e4822011-08-23 17:34:25 +02008305 /* automatic parse from the BIOS config */
8306 err = alc861vd_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008307 if (err < 0)
8308 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008309
Takashi Iwaifea80fa2018-06-20 12:52:46 +02008310 if (!spec->gen.no_analog) {
8311 err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
8312 if (err < 0)
8313 goto error;
8314 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02008315
Takashi Iwai1727a772013-01-10 09:52:52 +01008316 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01008317
Takashi Iwai1d045db2011-07-07 18:23:21 +02008318 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008319
8320 error:
8321 alc_free(codec);
8322 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008323}
8324
8325/*
8326 * ALC662 support
8327 *
8328 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
8329 * configuration. Each pin widget can choose any input DACs and a mixer.
8330 * Each ADC is connected from a mixer of all inputs. This makes possible
8331 * 6-channel independent captures.
8332 *
8333 * In addition, an independent DAC for the multi-playback (not used in this
8334 * driver yet).
8335 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02008336
8337/*
8338 * BIOS auto configuration
8339 */
8340
Kailang Yangbc9f98a2007-04-12 13:06:07 +02008341static int alc662_parse_auto_config(struct hda_codec *codec)
8342{
Takashi Iwai4c6d72d2011-05-02 11:30:18 +02008343 static const hda_nid_t alc662_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02008344 static const hda_nid_t alc663_ssids[] = { 0x15, 0x1b, 0x14, 0x21 };
8345 static const hda_nid_t alc662_ssids[] = { 0x15, 0x1b, 0x14, 0 };
8346 const hda_nid_t *ssids;
Takashi Iwaiee979a142008-09-02 15:42:20 +02008347
Takashi Iwai7639a062015-03-03 10:07:24 +01008348 if (codec->core.vendor_id == 0x10ec0272 || codec->core.vendor_id == 0x10ec0663 ||
8349 codec->core.vendor_id == 0x10ec0665 || codec->core.vendor_id == 0x10ec0670 ||
8350 codec->core.vendor_id == 0x10ec0671)
Takashi Iwai3e6179b2011-07-08 16:55:13 +02008351 ssids = alc663_ssids;
Kailang Yang6227cdc2010-02-25 08:36:52 +01008352 else
Takashi Iwai3e6179b2011-07-08 16:55:13 +02008353 ssids = alc662_ssids;
8354 return alc_parse_auto_config(codec, alc662_ignore, ssids);
Kailang Yangbc9f98a2007-04-12 13:06:07 +02008355}
8356
Todd Broch6be79482010-12-07 16:51:05 -08008357static void alc272_fixup_mario(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01008358 const struct hda_fixup *fix, int action)
Takashi Iwai6fc398c2011-01-13 14:36:37 +01008359{
Takashi Iwai9bb1f062013-01-10 17:14:29 +01008360 if (action != HDA_FIXUP_ACT_PRE_PROBE)
Takashi Iwai6fc398c2011-01-13 14:36:37 +01008361 return;
Todd Broch6be79482010-12-07 16:51:05 -08008362 if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT,
8363 (0x3b << AC_AMPCAP_OFFSET_SHIFT) |
8364 (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) |
8365 (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) |
8366 (0 << AC_AMPCAP_MUTE_SHIFT)))
Takashi Iwai4e76a882014-02-25 12:21:03 +01008367 codec_warn(codec, "failed to override amp caps for NID 0x2\n");
Todd Broch6be79482010-12-07 16:51:05 -08008368}
8369
Takashi Iwai8e383952013-10-30 17:41:12 +01008370static const struct snd_pcm_chmap_elem asus_pcm_2_1_chmaps[] = {
8371 { .channels = 2,
8372 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } },
8373 { .channels = 4,
8374 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR,
8375 SNDRV_CHMAP_NA, SNDRV_CHMAP_LFE } }, /* LFE only on right */
8376 { }
8377};
8378
8379/* override the 2.1 chmap */
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01008380static void alc_fixup_bass_chmap(struct hda_codec *codec,
Takashi Iwai8e383952013-10-30 17:41:12 +01008381 const struct hda_fixup *fix, int action)
8382{
8383 if (action == HDA_FIXUP_ACT_BUILD) {
8384 struct alc_spec *spec = codec->spec;
Takashi Iwaibbbc7e82015-02-27 17:43:19 +01008385 spec->gen.pcm_rec[0]->stream[0].chmap = asus_pcm_2_1_chmaps;
Takashi Iwai8e383952013-10-30 17:41:12 +01008386 }
8387}
8388
Takashi Iwaibf686652014-01-13 16:18:25 +01008389/* avoid D3 for keeping GPIO up */
8390static unsigned int gpio_led_power_filter(struct hda_codec *codec,
8391 hda_nid_t nid,
8392 unsigned int power_state)
8393{
8394 struct alc_spec *spec = codec->spec;
Takashi Iwaid261eec2018-06-19 22:32:29 +02008395 if (nid == codec->core.afg && power_state == AC_PWRST_D3 && spec->gpio_data)
Takashi Iwaibf686652014-01-13 16:18:25 +01008396 return AC_PWRST_D0;
8397 return power_state;
8398}
8399
Takashi Iwai3e887f32014-01-10 17:50:58 +01008400static void alc662_fixup_led_gpio1(struct hda_codec *codec,
8401 const struct hda_fixup *fix, int action)
8402{
8403 struct alc_spec *spec = codec->spec;
Takashi Iwai3e887f32014-01-10 17:50:58 +01008404
Takashi Iwai01e4a272018-06-19 22:47:30 +02008405 alc_fixup_hp_gpio_led(codec, action, 0x01, 0);
Takashi Iwai3e887f32014-01-10 17:50:58 +01008406 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai0f32fd192014-11-19 12:16:14 +01008407 spec->mute_led_polarity = 1;
Takashi Iwaibf686652014-01-13 16:18:25 +01008408 codec->power_filter = gpio_led_power_filter;
Takashi Iwai3e887f32014-01-10 17:50:58 +01008409 }
8410}
8411
Kailang Yangc6790c82016-11-25 16:15:17 +08008412static void alc662_usi_automute_hook(struct hda_codec *codec,
8413 struct hda_jack_callback *jack)
8414{
8415 struct alc_spec *spec = codec->spec;
8416 int vref;
8417 msleep(200);
8418 snd_hda_gen_hp_automute(codec, jack);
8419
8420 vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0;
8421 msleep(100);
8422 snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8423 vref);
8424}
8425
8426static void alc662_fixup_usi_headset_mic(struct hda_codec *codec,
8427 const struct hda_fixup *fix, int action)
8428{
8429 struct alc_spec *spec = codec->spec;
8430 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
8431 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
8432 spec->gen.hp_automute_hook = alc662_usi_automute_hook;
8433 }
8434}
8435
Sergey Bostandzhyan00066e92019-09-06 11:33:43 +02008436static void alc662_aspire_ethos_mute_speakers(struct hda_codec *codec,
8437 struct hda_jack_callback *cb)
8438{
8439 /* surround speakers at 0x1b already get muted automatically when
8440 * headphones are plugged in, but we have to mute/unmute the remaining
8441 * channels manually:
8442 * 0x15 - front left/front right
8443 * 0x18 - front center/ LFE
8444 */
8445 if (snd_hda_jack_detect_state(codec, 0x1b) == HDA_JACK_PRESENT) {
8446 snd_hda_set_pin_ctl_cache(codec, 0x15, 0);
8447 snd_hda_set_pin_ctl_cache(codec, 0x18, 0);
8448 } else {
8449 snd_hda_set_pin_ctl_cache(codec, 0x15, PIN_OUT);
8450 snd_hda_set_pin_ctl_cache(codec, 0x18, PIN_OUT);
8451 }
8452}
8453
8454static void alc662_fixup_aspire_ethos_hp(struct hda_codec *codec,
8455 const struct hda_fixup *fix, int action)
8456{
8457 /* Pin 0x1b: shared headphones jack and surround speakers */
8458 if (!is_jack_detectable(codec, 0x1b))
8459 return;
8460
8461 switch (action) {
8462 case HDA_FIXUP_ACT_PRE_PROBE:
8463 snd_hda_jack_detect_enable_callback(codec, 0x1b,
8464 alc662_aspire_ethos_mute_speakers);
Takashi Iwai336820c2019-11-28 21:26:30 +01008465 /* subwoofer needs an extra GPIO setting to become audible */
8466 alc_setup_gpio(codec, 0x02);
Sergey Bostandzhyan00066e92019-09-06 11:33:43 +02008467 break;
8468 case HDA_FIXUP_ACT_INIT:
8469 /* Make sure to start in a correct state, i.e. if
8470 * headphones have been plugged in before powering up the system
8471 */
8472 alc662_aspire_ethos_mute_speakers(codec, NULL);
8473 break;
8474 }
8475}
8476
Kailang Yangf3f91852014-10-24 15:43:46 +08008477static struct coef_fw alc668_coefs[] = {
8478 WRITE_COEF(0x01, 0xbebe), WRITE_COEF(0x02, 0xaaaa), WRITE_COEF(0x03, 0x0),
8479 WRITE_COEF(0x04, 0x0180), WRITE_COEF(0x06, 0x0), WRITE_COEF(0x07, 0x0f80),
8480 WRITE_COEF(0x08, 0x0031), WRITE_COEF(0x0a, 0x0060), WRITE_COEF(0x0b, 0x0),
8481 WRITE_COEF(0x0c, 0x7cf7), WRITE_COEF(0x0d, 0x1080), WRITE_COEF(0x0e, 0x7f7f),
8482 WRITE_COEF(0x0f, 0xcccc), WRITE_COEF(0x10, 0xddcc), WRITE_COEF(0x11, 0x0001),
8483 WRITE_COEF(0x13, 0x0), WRITE_COEF(0x14, 0x2aa0), WRITE_COEF(0x17, 0xa940),
8484 WRITE_COEF(0x19, 0x0), WRITE_COEF(0x1a, 0x0), WRITE_COEF(0x1b, 0x0),
8485 WRITE_COEF(0x1c, 0x0), WRITE_COEF(0x1d, 0x0), WRITE_COEF(0x1e, 0x7418),
8486 WRITE_COEF(0x1f, 0x0804), WRITE_COEF(0x20, 0x4200), WRITE_COEF(0x21, 0x0468),
8487 WRITE_COEF(0x22, 0x8ccc), WRITE_COEF(0x23, 0x0250), WRITE_COEF(0x24, 0x7418),
8488 WRITE_COEF(0x27, 0x0), WRITE_COEF(0x28, 0x8ccc), WRITE_COEF(0x2a, 0xff00),
8489 WRITE_COEF(0x2b, 0x8000), WRITE_COEF(0xa7, 0xff00), WRITE_COEF(0xa8, 0x8000),
8490 WRITE_COEF(0xaa, 0x2e17), WRITE_COEF(0xab, 0xa0c0), WRITE_COEF(0xac, 0x0),
8491 WRITE_COEF(0xad, 0x0), WRITE_COEF(0xae, 0x2ac6), WRITE_COEF(0xaf, 0xa480),
8492 WRITE_COEF(0xb0, 0x0), WRITE_COEF(0xb1, 0x0), WRITE_COEF(0xb2, 0x0),
8493 WRITE_COEF(0xb3, 0x0), WRITE_COEF(0xb4, 0x0), WRITE_COEF(0xb5, 0x1040),
8494 WRITE_COEF(0xb6, 0xd697), WRITE_COEF(0xb7, 0x902b), WRITE_COEF(0xb8, 0xd697),
8495 WRITE_COEF(0xb9, 0x902b), WRITE_COEF(0xba, 0xb8ba), WRITE_COEF(0xbb, 0xaaab),
8496 WRITE_COEF(0xbc, 0xaaaf), WRITE_COEF(0xbd, 0x6aaa), WRITE_COEF(0xbe, 0x1c02),
8497 WRITE_COEF(0xc0, 0x00ff), WRITE_COEF(0xc1, 0x0fa6),
8498 {}
8499};
8500
8501static void alc668_restore_default_value(struct hda_codec *codec)
8502{
8503 alc_process_coef_fw(codec, alc668_coefs);
8504}
8505
David Henningsson6cb3b702010-09-09 08:51:44 +02008506enum {
Daniel T Chen2df03512010-10-10 22:39:28 -04008507 ALC662_FIXUP_ASPIRE,
Takashi Iwai3e887f32014-01-10 17:50:58 +01008508 ALC662_FIXUP_LED_GPIO1,
David Henningsson6cb3b702010-09-09 08:51:44 +02008509 ALC662_FIXUP_IDEAPAD,
Todd Broch6be79482010-12-07 16:51:05 -08008510 ALC272_FIXUP_MARIO,
Anisse Astierd2ebd472011-01-20 12:36:21 +01008511 ALC662_FIXUP_CZC_P10T,
David Henningsson94024cd2011-04-29 14:10:55 +02008512 ALC662_FIXUP_SKU_IGNORE,
Takashi Iwaie59ea3e2011-06-29 17:21:00 +02008513 ALC662_FIXUP_HP_RP5800,
Takashi Iwai53c334a2011-08-23 18:27:14 +02008514 ALC662_FIXUP_ASUS_MODE1,
8515 ALC662_FIXUP_ASUS_MODE2,
8516 ALC662_FIXUP_ASUS_MODE3,
8517 ALC662_FIXUP_ASUS_MODE4,
8518 ALC662_FIXUP_ASUS_MODE5,
8519 ALC662_FIXUP_ASUS_MODE6,
8520 ALC662_FIXUP_ASUS_MODE7,
8521 ALC662_FIXUP_ASUS_MODE8,
Takashi Iwai1565cc32012-02-13 12:03:25 +01008522 ALC662_FIXUP_NO_JACK_DETECT,
David Henningssonedfe3bf2012-06-12 13:15:12 +02008523 ALC662_FIXUP_ZOTAC_Z68,
Takashi Iwai125821a2012-06-22 14:30:29 +02008524 ALC662_FIXUP_INV_DMIC,
David Henningsson1f8b46c2015-05-12 14:38:15 +02008525 ALC662_FIXUP_DELL_MIC_NO_PRESENCE,
David Henningsson73bdd592013-04-15 15:44:14 +02008526 ALC668_FIXUP_DELL_MIC_NO_PRESENCE,
David Henningsson1f8b46c2015-05-12 14:38:15 +02008527 ALC662_FIXUP_HEADSET_MODE,
David Henningsson73bdd592013-04-15 15:44:14 +02008528 ALC668_FIXUP_HEADSET_MODE,
David Henningsson8e54b4a2014-02-07 09:31:07 +01008529 ALC662_FIXUP_BASS_MODE4_CHMAP,
David Henningsson61a75f12014-02-07 09:31:08 +01008530 ALC662_FIXUP_BASS_16,
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01008531 ALC662_FIXUP_BASS_1A,
David Henningsson8e54b4a2014-02-07 09:31:07 +01008532 ALC662_FIXUP_BASS_CHMAP,
Hui Wang493a52a2014-01-14 14:07:36 +08008533 ALC668_FIXUP_AUTO_MUTE,
Gabriele Mazzotta5e6db662014-05-20 18:58:26 +02008534 ALC668_FIXUP_DELL_DISABLE_AAMIX,
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02008535 ALC668_FIXUP_DELL_XPS13,
Bobi Mihalca9d4dc582016-03-23 13:26:11 +02008536 ALC662_FIXUP_ASUS_Nx50,
Mikhail Paulyshkafc7438b2017-04-21 08:52:42 +02008537 ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE,
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07008538 ALC668_FIXUP_ASUS_Nx51,
Takashi Iwai5b7c5e12018-10-09 14:20:17 +02008539 ALC668_FIXUP_MIC_COEF,
Takashi Iwai11ba6112018-10-07 09:44:17 +02008540 ALC668_FIXUP_ASUS_G751,
Kailang Yang78f4f7c2016-06-07 11:31:34 +08008541 ALC891_FIXUP_HEADSET_MODE,
8542 ALC891_FIXUP_DELL_MIC_NO_PRESENCE,
Shrirang Bagul9b51fe32016-08-01 13:16:17 +08008543 ALC662_FIXUP_ACER_VERITON,
Takashi Iwai1a3f0992016-10-20 12:14:51 +02008544 ALC892_FIXUP_ASROCK_MOBO,
Kailang Yangc6790c82016-11-25 16:15:17 +08008545 ALC662_FIXUP_USI_FUNC,
8546 ALC662_FIXUP_USI_HEADSET_MODE,
Kailang Yangca169cc2017-04-25 16:17:40 +08008547 ALC662_FIXUP_LENOVO_MULTI_CODECS,
Sergey Bostandzhyan00066e92019-09-06 11:33:43 +02008548 ALC669_FIXUP_ACER_ASPIRE_ETHOS,
Sergey Bostandzhyan00066e92019-09-06 11:33:43 +02008549 ALC669_FIXUP_ACER_ASPIRE_ETHOS_HEADSET,
David Henningsson6cb3b702010-09-09 08:51:44 +02008550};
8551
Takashi Iwai1727a772013-01-10 09:52:52 +01008552static const struct hda_fixup alc662_fixups[] = {
Daniel T Chen2df03512010-10-10 22:39:28 -04008553 [ALC662_FIXUP_ASPIRE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008554 .type = HDA_FIXUP_PINS,
8555 .v.pins = (const struct hda_pintbl[]) {
Daniel T Chen2df03512010-10-10 22:39:28 -04008556 { 0x15, 0x99130112 }, /* subwoofer */
8557 { }
8558 }
8559 },
Takashi Iwai3e887f32014-01-10 17:50:58 +01008560 [ALC662_FIXUP_LED_GPIO1] = {
8561 .type = HDA_FIXUP_FUNC,
8562 .v.func = alc662_fixup_led_gpio1,
8563 },
David Henningsson6cb3b702010-09-09 08:51:44 +02008564 [ALC662_FIXUP_IDEAPAD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008565 .type = HDA_FIXUP_PINS,
8566 .v.pins = (const struct hda_pintbl[]) {
David Henningsson6cb3b702010-09-09 08:51:44 +02008567 { 0x17, 0x99130112 }, /* subwoofer */
8568 { }
Takashi Iwai3e887f32014-01-10 17:50:58 +01008569 },
8570 .chained = true,
8571 .chain_id = ALC662_FIXUP_LED_GPIO1,
David Henningsson6cb3b702010-09-09 08:51:44 +02008572 },
Todd Broch6be79482010-12-07 16:51:05 -08008573 [ALC272_FIXUP_MARIO] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008574 .type = HDA_FIXUP_FUNC,
Takashi Iwaib5bfbc62011-01-13 14:22:32 +01008575 .v.func = alc272_fixup_mario,
Anisse Astierd2ebd472011-01-20 12:36:21 +01008576 },
8577 [ALC662_FIXUP_CZC_P10T] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008578 .type = HDA_FIXUP_VERBS,
Anisse Astierd2ebd472011-01-20 12:36:21 +01008579 .v.verbs = (const struct hda_verb[]) {
8580 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
8581 {}
8582 }
8583 },
David Henningsson94024cd2011-04-29 14:10:55 +02008584 [ALC662_FIXUP_SKU_IGNORE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008585 .type = HDA_FIXUP_FUNC,
Takashi Iwai23d30f22012-05-07 17:17:32 +02008586 .v.func = alc_fixup_sku_ignore,
Takashi Iwaic6b35872011-03-28 12:05:31 +02008587 },
Takashi Iwaie59ea3e2011-06-29 17:21:00 +02008588 [ALC662_FIXUP_HP_RP5800] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008589 .type = HDA_FIXUP_PINS,
8590 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaie59ea3e2011-06-29 17:21:00 +02008591 { 0x14, 0x0221201f }, /* HP out */
8592 { }
8593 },
8594 .chained = true,
8595 .chain_id = ALC662_FIXUP_SKU_IGNORE
8596 },
Takashi Iwai53c334a2011-08-23 18:27:14 +02008597 [ALC662_FIXUP_ASUS_MODE1] = {
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 { 0x18, 0x01a19c20 }, /* mic */
8602 { 0x19, 0x99a3092f }, /* int-mic */
8603 { 0x21, 0x0121401f }, /* HP out */
8604 { }
8605 },
8606 .chained = true,
8607 .chain_id = ALC662_FIXUP_SKU_IGNORE
8608 },
8609 [ALC662_FIXUP_ASUS_MODE2] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008610 .type = HDA_FIXUP_PINS,
8611 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai2996bdb2011-08-18 16:02:24 +02008612 { 0x14, 0x99130110 }, /* speaker */
8613 { 0x18, 0x01a19820 }, /* mic */
8614 { 0x19, 0x99a3092f }, /* int-mic */
8615 { 0x1b, 0x0121401f }, /* HP out */
8616 { }
8617 },
Takashi Iwai53c334a2011-08-23 18:27:14 +02008618 .chained = true,
8619 .chain_id = ALC662_FIXUP_SKU_IGNORE
8620 },
8621 [ALC662_FIXUP_ASUS_MODE3] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008622 .type = HDA_FIXUP_PINS,
8623 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008624 { 0x14, 0x99130110 }, /* speaker */
8625 { 0x15, 0x0121441f }, /* HP */
8626 { 0x18, 0x01a19840 }, /* mic */
8627 { 0x19, 0x99a3094f }, /* int-mic */
8628 { 0x21, 0x01211420 }, /* HP2 */
8629 { }
8630 },
8631 .chained = true,
8632 .chain_id = ALC662_FIXUP_SKU_IGNORE
8633 },
8634 [ALC662_FIXUP_ASUS_MODE4] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008635 .type = HDA_FIXUP_PINS,
8636 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008637 { 0x14, 0x99130110 }, /* speaker */
8638 { 0x16, 0x99130111 }, /* speaker */
8639 { 0x18, 0x01a19840 }, /* mic */
8640 { 0x19, 0x99a3094f }, /* int-mic */
8641 { 0x21, 0x0121441f }, /* HP */
8642 { }
8643 },
8644 .chained = true,
8645 .chain_id = ALC662_FIXUP_SKU_IGNORE
8646 },
8647 [ALC662_FIXUP_ASUS_MODE5] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008648 .type = HDA_FIXUP_PINS,
8649 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008650 { 0x14, 0x99130110 }, /* speaker */
8651 { 0x15, 0x0121441f }, /* HP */
8652 { 0x16, 0x99130111 }, /* speaker */
8653 { 0x18, 0x01a19840 }, /* mic */
8654 { 0x19, 0x99a3094f }, /* int-mic */
8655 { }
8656 },
8657 .chained = true,
8658 .chain_id = ALC662_FIXUP_SKU_IGNORE
8659 },
8660 [ALC662_FIXUP_ASUS_MODE6] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008661 .type = HDA_FIXUP_PINS,
8662 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008663 { 0x14, 0x99130110 }, /* speaker */
8664 { 0x15, 0x01211420 }, /* HP2 */
8665 { 0x18, 0x01a19840 }, /* mic */
8666 { 0x19, 0x99a3094f }, /* int-mic */
8667 { 0x1b, 0x0121441f }, /* HP */
8668 { }
8669 },
8670 .chained = true,
8671 .chain_id = ALC662_FIXUP_SKU_IGNORE
8672 },
8673 [ALC662_FIXUP_ASUS_MODE7] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008674 .type = HDA_FIXUP_PINS,
8675 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008676 { 0x14, 0x99130110 }, /* speaker */
8677 { 0x17, 0x99130111 }, /* speaker */
8678 { 0x18, 0x01a19840 }, /* mic */
8679 { 0x19, 0x99a3094f }, /* int-mic */
8680 { 0x1b, 0x01214020 }, /* HP */
8681 { 0x21, 0x0121401f }, /* HP */
8682 { }
8683 },
8684 .chained = true,
8685 .chain_id = ALC662_FIXUP_SKU_IGNORE
8686 },
8687 [ALC662_FIXUP_ASUS_MODE8] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008688 .type = HDA_FIXUP_PINS,
8689 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008690 { 0x14, 0x99130110 }, /* speaker */
8691 { 0x12, 0x99a30970 }, /* int-mic */
8692 { 0x15, 0x01214020 }, /* HP */
8693 { 0x17, 0x99130111 }, /* speaker */
8694 { 0x18, 0x01a19840 }, /* mic */
8695 { 0x21, 0x0121401f }, /* HP */
8696 { }
8697 },
8698 .chained = true,
8699 .chain_id = ALC662_FIXUP_SKU_IGNORE
Takashi Iwai2996bdb2011-08-18 16:02:24 +02008700 },
Takashi Iwai1565cc32012-02-13 12:03:25 +01008701 [ALC662_FIXUP_NO_JACK_DETECT] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008702 .type = HDA_FIXUP_FUNC,
Takashi Iwai1565cc32012-02-13 12:03:25 +01008703 .v.func = alc_fixup_no_jack_detect,
8704 },
David Henningssonedfe3bf2012-06-12 13:15:12 +02008705 [ALC662_FIXUP_ZOTAC_Z68] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008706 .type = HDA_FIXUP_PINS,
8707 .v.pins = (const struct hda_pintbl[]) {
David Henningssonedfe3bf2012-06-12 13:15:12 +02008708 { 0x1b, 0x02214020 }, /* Front HP */
8709 { }
8710 }
8711 },
Takashi Iwai125821a2012-06-22 14:30:29 +02008712 [ALC662_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008713 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02008714 .v.func = alc_fixup_inv_dmic,
Takashi Iwai125821a2012-06-22 14:30:29 +02008715 },
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02008716 [ALC668_FIXUP_DELL_XPS13] = {
8717 .type = HDA_FIXUP_FUNC,
8718 .v.func = alc_fixup_dell_xps13,
8719 .chained = true,
8720 .chain_id = ALC668_FIXUP_DELL_DISABLE_AAMIX
8721 },
Gabriele Mazzotta5e6db662014-05-20 18:58:26 +02008722 [ALC668_FIXUP_DELL_DISABLE_AAMIX] = {
8723 .type = HDA_FIXUP_FUNC,
8724 .v.func = alc_fixup_disable_aamix,
8725 .chained = true,
8726 .chain_id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE
8727 },
Hui Wang493a52a2014-01-14 14:07:36 +08008728 [ALC668_FIXUP_AUTO_MUTE] = {
8729 .type = HDA_FIXUP_FUNC,
8730 .v.func = alc_fixup_auto_mute_via_amp,
8731 .chained = true,
8732 .chain_id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE
8733 },
David Henningsson1f8b46c2015-05-12 14:38:15 +02008734 [ALC662_FIXUP_DELL_MIC_NO_PRESENCE] = {
8735 .type = HDA_FIXUP_PINS,
8736 .v.pins = (const struct hda_pintbl[]) {
8737 { 0x19, 0x03a1113c }, /* use as headset mic, without its own jack detect */
8738 /* headphone mic by setting pin control of 0x1b (headphone out) to in + vref_50 */
8739 { }
8740 },
8741 .chained = true,
8742 .chain_id = ALC662_FIXUP_HEADSET_MODE
8743 },
8744 [ALC662_FIXUP_HEADSET_MODE] = {
8745 .type = HDA_FIXUP_FUNC,
8746 .v.func = alc_fixup_headset_mode_alc662,
8747 },
David Henningsson73bdd592013-04-15 15:44:14 +02008748 [ALC668_FIXUP_DELL_MIC_NO_PRESENCE] = {
8749 .type = HDA_FIXUP_PINS,
8750 .v.pins = (const struct hda_pintbl[]) {
8751 { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
8752 { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */
8753 { }
8754 },
8755 .chained = true,
8756 .chain_id = ALC668_FIXUP_HEADSET_MODE
8757 },
8758 [ALC668_FIXUP_HEADSET_MODE] = {
8759 .type = HDA_FIXUP_FUNC,
8760 .v.func = alc_fixup_headset_mode_alc668,
8761 },
David Henningsson8e54b4a2014-02-07 09:31:07 +01008762 [ALC662_FIXUP_BASS_MODE4_CHMAP] = {
Takashi Iwai8e383952013-10-30 17:41:12 +01008763 .type = HDA_FIXUP_FUNC,
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01008764 .v.func = alc_fixup_bass_chmap,
Takashi Iwai8e383952013-10-30 17:41:12 +01008765 .chained = true,
8766 .chain_id = ALC662_FIXUP_ASUS_MODE4
8767 },
David Henningsson61a75f12014-02-07 09:31:08 +01008768 [ALC662_FIXUP_BASS_16] = {
8769 .type = HDA_FIXUP_PINS,
8770 .v.pins = (const struct hda_pintbl[]) {
8771 {0x16, 0x80106111}, /* bass speaker */
8772 {}
8773 },
8774 .chained = true,
8775 .chain_id = ALC662_FIXUP_BASS_CHMAP,
8776 },
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01008777 [ALC662_FIXUP_BASS_1A] = {
8778 .type = HDA_FIXUP_PINS,
8779 .v.pins = (const struct hda_pintbl[]) {
8780 {0x1a, 0x80106111}, /* bass speaker */
8781 {}
8782 },
David Henningsson8e54b4a2014-02-07 09:31:07 +01008783 .chained = true,
8784 .chain_id = ALC662_FIXUP_BASS_CHMAP,
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01008785 },
David Henningsson8e54b4a2014-02-07 09:31:07 +01008786 [ALC662_FIXUP_BASS_CHMAP] = {
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01008787 .type = HDA_FIXUP_FUNC,
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01008788 .v.func = alc_fixup_bass_chmap,
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01008789 },
Bobi Mihalca9d4dc582016-03-23 13:26:11 +02008790 [ALC662_FIXUP_ASUS_Nx50] = {
8791 .type = HDA_FIXUP_FUNC,
8792 .v.func = alc_fixup_auto_mute_via_amp,
8793 .chained = true,
8794 .chain_id = ALC662_FIXUP_BASS_1A
8795 },
Mikhail Paulyshkafc7438b2017-04-21 08:52:42 +02008796 [ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE] = {
8797 .type = HDA_FIXUP_FUNC,
8798 .v.func = alc_fixup_headset_mode_alc668,
8799 .chain_id = ALC662_FIXUP_BASS_CHMAP
8800 },
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07008801 [ALC668_FIXUP_ASUS_Nx51] = {
8802 .type = HDA_FIXUP_PINS,
8803 .v.pins = (const struct hda_pintbl[]) {
Mikhail Paulyshkafc7438b2017-04-21 08:52:42 +02008804 { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
8805 { 0x1a, 0x90170151 }, /* bass speaker */
8806 { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07008807 {}
8808 },
8809 .chained = true,
Mikhail Paulyshkafc7438b2017-04-21 08:52:42 +02008810 .chain_id = ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE,
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07008811 },
Takashi Iwai5b7c5e12018-10-09 14:20:17 +02008812 [ALC668_FIXUP_MIC_COEF] = {
Takashi Iwai11ba6112018-10-07 09:44:17 +02008813 .type = HDA_FIXUP_VERBS,
8814 .v.verbs = (const struct hda_verb[]) {
8815 { 0x20, AC_VERB_SET_COEF_INDEX, 0xc3 },
8816 { 0x20, AC_VERB_SET_PROC_COEF, 0x4000 },
8817 {}
8818 },
8819 },
Takashi Iwai5b7c5e12018-10-09 14:20:17 +02008820 [ALC668_FIXUP_ASUS_G751] = {
8821 .type = HDA_FIXUP_PINS,
8822 .v.pins = (const struct hda_pintbl[]) {
8823 { 0x16, 0x0421101f }, /* HP */
8824 {}
8825 },
8826 .chained = true,
8827 .chain_id = ALC668_FIXUP_MIC_COEF
8828 },
Kailang Yang78f4f7c2016-06-07 11:31:34 +08008829 [ALC891_FIXUP_HEADSET_MODE] = {
8830 .type = HDA_FIXUP_FUNC,
8831 .v.func = alc_fixup_headset_mode,
8832 },
8833 [ALC891_FIXUP_DELL_MIC_NO_PRESENCE] = {
8834 .type = HDA_FIXUP_PINS,
8835 .v.pins = (const struct hda_pintbl[]) {
8836 { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
8837 { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */
8838 { }
8839 },
8840 .chained = true,
8841 .chain_id = ALC891_FIXUP_HEADSET_MODE
8842 },
Shrirang Bagul9b51fe32016-08-01 13:16:17 +08008843 [ALC662_FIXUP_ACER_VERITON] = {
8844 .type = HDA_FIXUP_PINS,
8845 .v.pins = (const struct hda_pintbl[]) {
8846 { 0x15, 0x50170120 }, /* no internal speaker */
8847 { }
8848 }
8849 },
Takashi Iwai1a3f0992016-10-20 12:14:51 +02008850 [ALC892_FIXUP_ASROCK_MOBO] = {
8851 .type = HDA_FIXUP_PINS,
8852 .v.pins = (const struct hda_pintbl[]) {
8853 { 0x15, 0x40f000f0 }, /* disabled */
8854 { 0x16, 0x40f000f0 }, /* disabled */
Takashi Iwai1a3f0992016-10-20 12:14:51 +02008855 { }
8856 }
8857 },
Kailang Yangc6790c82016-11-25 16:15:17 +08008858 [ALC662_FIXUP_USI_FUNC] = {
8859 .type = HDA_FIXUP_FUNC,
8860 .v.func = alc662_fixup_usi_headset_mic,
8861 },
8862 [ALC662_FIXUP_USI_HEADSET_MODE] = {
8863 .type = HDA_FIXUP_PINS,
8864 .v.pins = (const struct hda_pintbl[]) {
8865 { 0x19, 0x02a1913c }, /* use as headset mic, without its own jack detect */
8866 { 0x18, 0x01a1903d },
8867 { }
8868 },
8869 .chained = true,
8870 .chain_id = ALC662_FIXUP_USI_FUNC
8871 },
Kailang Yangca169cc2017-04-25 16:17:40 +08008872 [ALC662_FIXUP_LENOVO_MULTI_CODECS] = {
8873 .type = HDA_FIXUP_FUNC,
8874 .v.func = alc233_alc662_fixup_lenovo_dual_codecs,
8875 },
Sergey Bostandzhyan00066e92019-09-06 11:33:43 +02008876 [ALC669_FIXUP_ACER_ASPIRE_ETHOS_HEADSET] = {
8877 .type = HDA_FIXUP_FUNC,
8878 .v.func = alc662_fixup_aspire_ethos_hp,
8879 },
Sergey Bostandzhyan00066e92019-09-06 11:33:43 +02008880 [ALC669_FIXUP_ACER_ASPIRE_ETHOS] = {
8881 .type = HDA_FIXUP_PINS,
8882 .v.pins = (const struct hda_pintbl[]) {
8883 { 0x15, 0x92130110 }, /* front speakers */
8884 { 0x18, 0x99130111 }, /* center/subwoofer */
8885 { 0x1b, 0x11130012 }, /* surround plus jack for HP */
8886 { }
8887 },
8888 .chained = true,
Takashi Iwai336820c2019-11-28 21:26:30 +01008889 .chain_id = ALC669_FIXUP_ACER_ASPIRE_ETHOS_HEADSET
Sergey Bostandzhyan00066e92019-09-06 11:33:43 +02008890 },
David Henningsson6cb3b702010-09-09 08:51:44 +02008891};
8892
Takashi Iwaia9111322011-05-02 11:30:18 +02008893static const struct snd_pci_quirk alc662_fixup_tbl[] = {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008894 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_FIXUP_ASUS_MODE2),
Takashi Iwaid3d38352013-08-19 20:05:50 +02008895 SND_PCI_QUIRK(0x1025, 0x022f, "Acer Aspire One", ALC662_FIXUP_INV_DMIC),
David Henningsson02f6ff92015-12-07 11:29:31 +01008896 SND_PCI_QUIRK(0x1025, 0x0241, "Packard Bell DOTS", ALC662_FIXUP_INV_DMIC),
David Henningssona6c47a82011-02-10 15:39:19 +01008897 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
David Henningsson94024cd2011-04-29 14:10:55 +02008898 SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
Takashi Iwai125821a2012-06-22 14:30:29 +02008899 SND_PCI_QUIRK(0x1025, 0x0349, "eMachines eM250", ALC662_FIXUP_INV_DMIC),
Takashi Iwai18019282013-08-16 08:17:05 +02008900 SND_PCI_QUIRK(0x1025, 0x034a, "Gateway LT27", ALC662_FIXUP_INV_DMIC),
Daniel T Chen2df03512010-10-10 22:39:28 -04008901 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
David Henningsson73bdd592013-04-15 15:44:14 +02008902 SND_PCI_QUIRK(0x1028, 0x05d8, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
8903 SND_PCI_QUIRK(0x1028, 0x05db, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
Takashi Iwaic5d019c2014-07-22 17:33:32 +02008904 SND_PCI_QUIRK(0x1028, 0x05fe, "Dell XPS 15", ALC668_FIXUP_DELL_XPS13),
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02008905 SND_PCI_QUIRK(0x1028, 0x060a, "Dell XPS 13", ALC668_FIXUP_DELL_XPS13),
Niranjan Sivakumar467e1432015-09-05 18:20:35 +02008906 SND_PCI_QUIRK(0x1028, 0x060d, "Dell M3800", ALC668_FIXUP_DELL_XPS13),
David Henningsson09d20142013-11-20 11:43:30 +01008907 SND_PCI_QUIRK(0x1028, 0x0625, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
David Henningssonad8ff99e2013-11-07 09:28:59 +01008908 SND_PCI_QUIRK(0x1028, 0x0626, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
Kailang Yang8dc9abb2014-04-16 15:53:12 +08008909 SND_PCI_QUIRK(0x1028, 0x0696, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
8910 SND_PCI_QUIRK(0x1028, 0x0698, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
Kailang Yang6a98e342014-10-27 16:20:30 +08008911 SND_PCI_QUIRK(0x1028, 0x069f, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
Takashi Iwaie59ea3e2011-06-29 17:21:00 +02008912 SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800),
Kaho Ng2da2dc92016-05-09 00:27:49 +08008913 SND_PCI_QUIRK(0x1043, 0x1080, "Asus UX501VW", ALC668_FIXUP_HEADSET_MODE),
Bobi Mihalca83a9efb2016-03-23 13:32:33 +02008914 SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_ASUS_Nx50),
Takashi Iwaidb8948e2016-01-18 09:17:30 +01008915 SND_PCI_QUIRK(0x1043, 0x13df, "Asus N550JX", ALC662_FIXUP_BASS_1A),
Bobi Mihalca9d4dc582016-03-23 13:26:11 +02008916 SND_PCI_QUIRK(0x1043, 0x129d, "Asus N750", ALC662_FIXUP_ASUS_Nx50),
Takashi Iwai11ba6112018-10-07 09:44:17 +02008917 SND_PCI_QUIRK(0x1043, 0x12ff, "ASUS G751", ALC668_FIXUP_ASUS_G751),
David Henningsson8e54b4a2014-02-07 09:31:07 +01008918 SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
David Henningsson61a75f12014-02-07 09:31:08 +01008919 SND_PCI_QUIRK(0x1043, 0x15a7, "ASUS UX51VZH", ALC662_FIXUP_BASS_16),
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07008920 SND_PCI_QUIRK(0x1043, 0x177d, "ASUS N551", ALC668_FIXUP_ASUS_Nx51),
8921 SND_PCI_QUIRK(0x1043, 0x17bd, "ASUS N751", ALC668_FIXUP_ASUS_Nx51),
Takashi Iwaic7efff92017-01-04 21:38:16 +01008922 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71SL", ALC662_FIXUP_ASUS_MODE8),
David Henningsson61a75f12014-02-07 09:31:08 +01008923 SND_PCI_QUIRK(0x1043, 0x1b73, "ASUS N55SF", ALC662_FIXUP_BASS_16),
David Henningsson8e54b4a2014-02-07 09:31:07 +01008924 SND_PCI_QUIRK(0x1043, 0x1bf3, "ASUS N76VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
Takashi Iwai1565cc32012-02-13 12:03:25 +01008925 SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT),
Takashi Iwai53c334a2011-08-23 18:27:14 +02008926 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2),
Daniel T Chena0e90ac2010-11-20 10:20:35 -05008927 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
Kailang Yangc6790c82016-11-25 16:15:17 +08008928 SND_PCI_QUIRK(0x14cd, 0x5003, "USI", ALC662_FIXUP_USI_HEADSET_MODE),
Kailang Yangca169cc2017-04-25 16:17:40 +08008929 SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC662_FIXUP_LENOVO_MULTI_CODECS),
Valentine Sinitsynd4118582010-10-01 22:24:08 +06008930 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
David Henningsson6cb3b702010-09-09 08:51:44 +02008931 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
Takashi Iwai1a3f0992016-10-20 12:14:51 +02008932 SND_PCI_QUIRK(0x1849, 0x5892, "ASRock B150M", ALC892_FIXUP_ASROCK_MOBO),
David Henningssonedfe3bf2012-06-12 13:15:12 +02008933 SND_PCI_QUIRK(0x19da, 0xa130, "Zotac Z68", ALC662_FIXUP_ZOTAC_Z68),
Shrirang Bagul9b51fe32016-08-01 13:16:17 +08008934 SND_PCI_QUIRK(0x1b0a, 0x01b8, "ACER Veriton", ALC662_FIXUP_ACER_VERITON),
Anisse Astierd2ebd472011-01-20 12:36:21 +01008935 SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
Sergey Bostandzhyan00066e92019-09-06 11:33:43 +02008936 SND_PCI_QUIRK(0x1025, 0x0566, "Acer Aspire Ethos 8951G", ALC669_FIXUP_ACER_ASPIRE_ETHOS),
Takashi Iwai53c334a2011-08-23 18:27:14 +02008937
8938#if 0
8939 /* Below is a quirk table taken from the old code.
8940 * Basically the device should work as is without the fixup table.
8941 * If BIOS doesn't give a proper info, enable the corresponding
8942 * fixup entry.
Jesper Juhl7d7eb9e2012-04-12 22:11:25 +02008943 */
Takashi Iwai53c334a2011-08-23 18:27:14 +02008944 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC662_FIXUP_ASUS_MODE1),
8945 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC662_FIXUP_ASUS_MODE3),
8946 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC662_FIXUP_ASUS_MODE1),
8947 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC662_FIXUP_ASUS_MODE3),
8948 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
8949 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8950 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
8951 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC662_FIXUP_ASUS_MODE1),
8952 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC662_FIXUP_ASUS_MODE1),
8953 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8954 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC662_FIXUP_ASUS_MODE7),
8955 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC662_FIXUP_ASUS_MODE7),
8956 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC662_FIXUP_ASUS_MODE8),
8957 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC662_FIXUP_ASUS_MODE3),
8958 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC662_FIXUP_ASUS_MODE1),
8959 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8960 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_FIXUP_ASUS_MODE2),
8961 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC662_FIXUP_ASUS_MODE1),
8962 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8963 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
8964 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
8965 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8966 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC662_FIXUP_ASUS_MODE1),
8967 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC662_FIXUP_ASUS_MODE3),
8968 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_FIXUP_ASUS_MODE2),
8969 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8970 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC662_FIXUP_ASUS_MODE5),
8971 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
8972 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8973 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC662_FIXUP_ASUS_MODE1),
8974 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8975 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8976 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC662_FIXUP_ASUS_MODE3),
8977 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC662_FIXUP_ASUS_MODE3),
8978 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC662_FIXUP_ASUS_MODE1),
8979 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC662_FIXUP_ASUS_MODE1),
8980 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC662_FIXUP_ASUS_MODE1),
8981 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC662_FIXUP_ASUS_MODE1),
8982 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC662_FIXUP_ASUS_MODE1),
8983 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8984 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_FIXUP_ASUS_MODE2),
8985 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC662_FIXUP_ASUS_MODE1),
8986 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
8987 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC662_FIXUP_ASUS_MODE3),
8988 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC662_FIXUP_ASUS_MODE1),
8989 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC662_FIXUP_ASUS_MODE1),
8990 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC662_FIXUP_ASUS_MODE1),
8991 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_FIXUP_ASUS_MODE2),
8992 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
8993 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE4),
8994#endif
David Henningsson6cb3b702010-09-09 08:51:44 +02008995 {}
8996};
8997
Takashi Iwai1727a772013-01-10 09:52:52 +01008998static const struct hda_model_fixup alc662_fixup_models[] = {
Takashi Iwaiaa3841b2018-06-26 07:42:40 +02008999 {.id = ALC662_FIXUP_ASPIRE, .name = "aspire"},
9000 {.id = ALC662_FIXUP_IDEAPAD, .name = "ideapad"},
Todd Broch6be79482010-12-07 16:51:05 -08009001 {.id = ALC272_FIXUP_MARIO, .name = "mario"},
Takashi Iwaiaa3841b2018-06-26 07:42:40 +02009002 {.id = ALC662_FIXUP_HP_RP5800, .name = "hp-rp5800"},
Takashi Iwai53c334a2011-08-23 18:27:14 +02009003 {.id = ALC662_FIXUP_ASUS_MODE1, .name = "asus-mode1"},
9004 {.id = ALC662_FIXUP_ASUS_MODE2, .name = "asus-mode2"},
9005 {.id = ALC662_FIXUP_ASUS_MODE3, .name = "asus-mode3"},
9006 {.id = ALC662_FIXUP_ASUS_MODE4, .name = "asus-mode4"},
9007 {.id = ALC662_FIXUP_ASUS_MODE5, .name = "asus-mode5"},
9008 {.id = ALC662_FIXUP_ASUS_MODE6, .name = "asus-mode6"},
9009 {.id = ALC662_FIXUP_ASUS_MODE7, .name = "asus-mode7"},
9010 {.id = ALC662_FIXUP_ASUS_MODE8, .name = "asus-mode8"},
Takashi Iwaiaa3841b2018-06-26 07:42:40 +02009011 {.id = ALC662_FIXUP_ZOTAC_Z68, .name = "zotac-z68"},
Takashi Iwai6e72aa52012-06-25 10:52:25 +02009012 {.id = ALC662_FIXUP_INV_DMIC, .name = "inv-dmic"},
Takashi Iwaiaa3841b2018-06-26 07:42:40 +02009013 {.id = ALC662_FIXUP_DELL_MIC_NO_PRESENCE, .name = "alc662-headset-multi"},
David Henningssone32aa852013-06-17 11:04:02 +02009014 {.id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE, .name = "dell-headset-multi"},
Takashi Iwaiaa3841b2018-06-26 07:42:40 +02009015 {.id = ALC662_FIXUP_HEADSET_MODE, .name = "alc662-headset"},
9016 {.id = ALC668_FIXUP_HEADSET_MODE, .name = "alc668-headset"},
9017 {.id = ALC662_FIXUP_BASS_16, .name = "bass16"},
9018 {.id = ALC662_FIXUP_BASS_1A, .name = "bass1a"},
9019 {.id = ALC668_FIXUP_AUTO_MUTE, .name = "automute"},
9020 {.id = ALC668_FIXUP_DELL_XPS13, .name = "dell-xps13"},
9021 {.id = ALC662_FIXUP_ASUS_Nx50, .name = "asus-nx50"},
9022 {.id = ALC668_FIXUP_ASUS_Nx51, .name = "asus-nx51"},
Takashi Iwai40c51672018-10-07 09:47:39 +02009023 {.id = ALC668_FIXUP_ASUS_G751, .name = "asus-g751"},
Takashi Iwaiaa3841b2018-06-26 07:42:40 +02009024 {.id = ALC891_FIXUP_HEADSET_MODE, .name = "alc891-headset"},
9025 {.id = ALC891_FIXUP_DELL_MIC_NO_PRESENCE, .name = "alc891-headset-multi"},
9026 {.id = ALC662_FIXUP_ACER_VERITON, .name = "acer-veriton"},
9027 {.id = ALC892_FIXUP_ASROCK_MOBO, .name = "asrock-mobo"},
9028 {.id = ALC662_FIXUP_USI_HEADSET_MODE, .name = "usi-headset"},
Takashi Iwaiba90d6a2017-05-22 16:38:47 +02009029 {.id = ALC662_FIXUP_LENOVO_MULTI_CODECS, .name = "dual-codecs"},
Sergey Bostandzhyan00066e92019-09-06 11:33:43 +02009030 {.id = ALC669_FIXUP_ACER_ASPIRE_ETHOS, .name = "aspire-ethos"},
Todd Broch6be79482010-12-07 16:51:05 -08009031 {}
9032};
David Henningsson6cb3b702010-09-09 08:51:44 +02009033
Hui Wang532895c2014-05-29 15:59:19 +08009034static const struct snd_hda_pin_quirk alc662_pin_fixup_tbl[] = {
Kailang Yang78f4f7c2016-06-07 11:31:34 +08009035 SND_HDA_PIN_QUIRK(0x10ec0867, 0x1028, "Dell", ALC891_FIXUP_DELL_MIC_NO_PRESENCE,
9036 {0x17, 0x02211010},
9037 {0x18, 0x01a19030},
9038 {0x1a, 0x01813040},
9039 {0x21, 0x01014020}),
Hui Wang4b4e0e32019-07-16 15:21:34 +08009040 SND_HDA_PIN_QUIRK(0x10ec0867, 0x1028, "Dell", ALC891_FIXUP_DELL_MIC_NO_PRESENCE,
9041 {0x16, 0x01813030},
9042 {0x17, 0x02211010},
9043 {0x18, 0x01a19040},
9044 {0x21, 0x01014020}),
David Henningsson1f8b46c2015-05-12 14:38:15 +02009045 SND_HDA_PIN_QUIRK(0x10ec0662, 0x1028, "Dell", ALC662_FIXUP_DELL_MIC_NO_PRESENCE,
David Henningsson1f8b46c2015-05-12 14:38:15 +02009046 {0x14, 0x01014010},
David Henningsson1f8b46c2015-05-12 14:38:15 +02009047 {0x18, 0x01a19020},
David Henningsson1f8b46c2015-05-12 14:38:15 +02009048 {0x1a, 0x0181302f},
Hui Wang11580292015-08-03 11:03:49 +08009049 {0x1b, 0x0221401f}),
David Henningsson76c21322014-06-24 14:46:54 +02009050 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
9051 {0x12, 0x99a30130},
9052 {0x14, 0x90170110},
9053 {0x15, 0x0321101f},
Hui Wang11580292015-08-03 11:03:49 +08009054 {0x16, 0x03011020}),
David Henningsson76c21322014-06-24 14:46:54 +02009055 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
9056 {0x12, 0x99a30140},
9057 {0x14, 0x90170110},
9058 {0x15, 0x0321101f},
Hui Wang11580292015-08-03 11:03:49 +08009059 {0x16, 0x03011020}),
David Henningsson76c21322014-06-24 14:46:54 +02009060 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
9061 {0x12, 0x99a30150},
9062 {0x14, 0x90170110},
9063 {0x15, 0x0321101f},
Hui Wang11580292015-08-03 11:03:49 +08009064 {0x16, 0x03011020}),
David Henningsson76c21322014-06-24 14:46:54 +02009065 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
David Henningsson76c21322014-06-24 14:46:54 +02009066 {0x14, 0x90170110},
9067 {0x15, 0x0321101f},
Hui Wang11580292015-08-03 11:03:49 +08009068 {0x16, 0x03011020}),
David Henningsson76c21322014-06-24 14:46:54 +02009069 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell XPS 15", ALC668_FIXUP_AUTO_MUTE,
9070 {0x12, 0x90a60130},
9071 {0x14, 0x90170110},
Hui Wang11580292015-08-03 11:03:49 +08009072 {0x15, 0x0321101f}),
Hui Wang532895c2014-05-29 15:59:19 +08009073 {}
9074};
9075
Takashi Iwai1d045db2011-07-07 18:23:21 +02009076/*
9077 */
Kailang Yangbc9f98a2007-04-12 13:06:07 +02009078static int patch_alc662(struct hda_codec *codec)
9079{
9080 struct alc_spec *spec;
Takashi Iwai3de95172012-05-07 18:03:15 +02009081 int err;
Kailang Yangbc9f98a2007-04-12 13:06:07 +02009082
Takashi Iwai3de95172012-05-07 18:03:15 +02009083 err = alc_alloc_spec(codec, 0x0b);
9084 if (err < 0)
9085 return err;
Kailang Yangbc9f98a2007-04-12 13:06:07 +02009086
Takashi Iwai3de95172012-05-07 18:03:15 +02009087 spec = codec->spec;
Takashi Iwai1f0f4b82011-06-27 10:52:59 +02009088
Takashi Iwai225068a2015-05-29 10:42:14 +02009089 spec->shutup = alc_eapd_shutup;
9090
Takashi Iwai53c334a2011-08-23 18:27:14 +02009091 /* handle multiple HPs as is */
9092 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
9093
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +02009094 alc_fix_pll_init(codec, 0x20, 0x04, 15);
9095
Takashi Iwai7639a062015-03-03 10:07:24 +01009096 switch (codec->core.vendor_id) {
Kailang Yangf3f91852014-10-24 15:43:46 +08009097 case 0x10ec0668:
9098 spec->init_hook = alc668_restore_default_value;
9099 break;
Kailang Yangf3f91852014-10-24 15:43:46 +08009100 }
Kailang Yang8663ff72012-06-29 09:35:52 +02009101
Takashi Iwaic9af7532019-05-10 11:01:43 +02009102 alc_pre_init(codec);
9103
Takashi Iwai1727a772013-01-10 09:52:52 +01009104 snd_hda_pick_fixup(codec, alc662_fixup_models,
Takashi Iwai8e5a0502012-06-21 15:49:33 +02009105 alc662_fixup_tbl, alc662_fixups);
Hui Wang0fc1e442019-08-16 14:27:39 +08009106 snd_hda_pick_pin_fixup(codec, alc662_pin_fixup_tbl, alc662_fixups, true);
Takashi Iwai1727a772013-01-10 09:52:52 +01009107 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai8e5a0502012-06-21 15:49:33 +02009108
9109 alc_auto_parse_customize_define(codec);
9110
Takashi Iwai7504b6c2013-03-18 11:25:51 +01009111 if (has_cdefine_beep(codec))
9112 spec->gen.beep_nid = 0x01;
9113
Takashi Iwai1bb7e432011-10-17 16:50:59 +02009114 if ((alc_get_coef0(codec) & (1 << 14)) &&
Takashi Iwai5100cd02014-02-15 10:03:19 +01009115 codec->bus->pci && codec->bus->pci->subsystem_vendor == 0x1025 &&
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02009116 spec->cdefine.platform_type == 1) {
Wei Yongjun6134b1a2013-04-18 11:12:59 +08009117 err = alc_codec_rename(codec, "ALC272X");
9118 if (err < 0)
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02009119 goto error;
Takashi Iwai20ca0c32011-10-17 16:00:35 +02009120 }
Kailang Yang274693f2009-12-03 10:07:50 +01009121
Takashi Iwaib9c51062011-08-24 18:08:07 +02009122 /* automatic parse from the BIOS config */
9123 err = alc662_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02009124 if (err < 0)
9125 goto error;
Kailang Yangbc9f98a2007-04-12 13:06:07 +02009126
Takashi Iwai7504b6c2013-03-18 11:25:51 +01009127 if (!spec->gen.no_analog && spec->gen.beep_nid) {
Takashi Iwai7639a062015-03-03 10:07:24 +01009128 switch (codec->core.vendor_id) {
Kailang Yangda00c242010-03-19 11:23:45 +01009129 case 0x10ec0662:
Takashi Iwaifea80fa2018-06-20 12:52:46 +02009130 err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
Kailang Yangda00c242010-03-19 11:23:45 +01009131 break;
9132 case 0x10ec0272:
9133 case 0x10ec0663:
9134 case 0x10ec0665:
Kailang Yang9ad54542013-11-26 15:41:40 +08009135 case 0x10ec0668:
Takashi Iwaifea80fa2018-06-20 12:52:46 +02009136 err = set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
Kailang Yangda00c242010-03-19 11:23:45 +01009137 break;
9138 case 0x10ec0273:
Takashi Iwaifea80fa2018-06-20 12:52:46 +02009139 err = set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
Kailang Yangda00c242010-03-19 11:23:45 +01009140 break;
9141 }
Takashi Iwaifea80fa2018-06-20 12:52:46 +02009142 if (err < 0)
9143 goto error;
Kailang Yangcec27c82010-02-04 14:18:18 +01009144 }
Takashi Iwai2134ea42008-01-10 16:53:55 +01009145
Takashi Iwai1727a772013-01-10 09:52:52 +01009146 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01009147
Kailang Yangbc9f98a2007-04-12 13:06:07 +02009148 return 0;
Kailang Yangbc9f98a2007-04-12 13:06:07 +02009149
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02009150 error:
9151 alc_free(codec);
9152 return err;
Kailang Yangb478b992011-05-18 11:51:15 +02009153}
9154
Kailang Yangbc9f98a2007-04-12 13:06:07 +02009155/*
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009156 * ALC680 support
9157 */
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009158
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009159static int alc680_parse_auto_config(struct hda_codec *codec)
9160{
Takashi Iwai3e6179b2011-07-08 16:55:13 +02009161 return alc_parse_auto_config(codec, NULL, NULL);
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009162}
9163
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009164/*
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009165 */
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009166static int patch_alc680(struct hda_codec *codec)
9167{
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009168 int err;
9169
Takashi Iwai1f0f4b82011-06-27 10:52:59 +02009170 /* ALC680 has no aa-loopback mixer */
Takashi Iwai3de95172012-05-07 18:03:15 +02009171 err = alc_alloc_spec(codec, 0);
9172 if (err < 0)
9173 return err;
Takashi Iwai1f0f4b82011-06-27 10:52:59 +02009174
Takashi Iwai1ebec5f2011-08-15 13:21:48 +02009175 /* automatic parse from the BIOS config */
9176 err = alc680_parse_auto_config(codec);
9177 if (err < 0) {
9178 alc_free(codec);
9179 return err;
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009180 }
9181
Kailang Yangd1eb57f2010-06-23 16:25:26 +02009182 return 0;
9183}
9184
9185/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07009186 * patch entries
9187 */
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009188static const struct hda_device_id snd_hda_id_realtek[] = {
Kailang Yang0a6f0602017-06-30 16:00:48 +08009189 HDA_CODEC_ENTRY(0x10ec0215, "ALC215", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009190 HDA_CODEC_ENTRY(0x10ec0221, "ALC221", patch_alc269),
Hui Wang2a36c162019-09-04 13:53:27 +08009191 HDA_CODEC_ENTRY(0x10ec0222, "ALC222", patch_alc269),
Kailang Yang42314302016-02-03 15:03:50 +08009192 HDA_CODEC_ENTRY(0x10ec0225, "ALC225", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009193 HDA_CODEC_ENTRY(0x10ec0231, "ALC231", patch_alc269),
9194 HDA_CODEC_ENTRY(0x10ec0233, "ALC233", patch_alc269),
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08009195 HDA_CODEC_ENTRY(0x10ec0234, "ALC234", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009196 HDA_CODEC_ENTRY(0x10ec0235, "ALC233", patch_alc269),
Kailang Yang736f20a2017-10-20 15:06:34 +08009197 HDA_CODEC_ENTRY(0x10ec0236, "ALC236", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009198 HDA_CODEC_ENTRY(0x10ec0255, "ALC255", patch_alc269),
9199 HDA_CODEC_ENTRY(0x10ec0256, "ALC256", patch_alc269),
Kailang Yangf429e7e2017-12-05 15:38:24 +08009200 HDA_CODEC_ENTRY(0x10ec0257, "ALC257", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009201 HDA_CODEC_ENTRY(0x10ec0260, "ALC260", patch_alc260),
9202 HDA_CODEC_ENTRY(0x10ec0262, "ALC262", patch_alc262),
9203 HDA_CODEC_ENTRY(0x10ec0267, "ALC267", patch_alc268),
9204 HDA_CODEC_ENTRY(0x10ec0268, "ALC268", patch_alc268),
9205 HDA_CODEC_ENTRY(0x10ec0269, "ALC269", patch_alc269),
9206 HDA_CODEC_ENTRY(0x10ec0270, "ALC270", patch_alc269),
9207 HDA_CODEC_ENTRY(0x10ec0272, "ALC272", patch_alc662),
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08009208 HDA_CODEC_ENTRY(0x10ec0274, "ALC274", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009209 HDA_CODEC_ENTRY(0x10ec0275, "ALC275", patch_alc269),
9210 HDA_CODEC_ENTRY(0x10ec0276, "ALC276", patch_alc269),
9211 HDA_CODEC_ENTRY(0x10ec0280, "ALC280", patch_alc269),
9212 HDA_CODEC_ENTRY(0x10ec0282, "ALC282", patch_alc269),
9213 HDA_CODEC_ENTRY(0x10ec0283, "ALC283", patch_alc269),
9214 HDA_CODEC_ENTRY(0x10ec0284, "ALC284", patch_alc269),
Kailang Yang0a6f0602017-06-30 16:00:48 +08009215 HDA_CODEC_ENTRY(0x10ec0285, "ALC285", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009216 HDA_CODEC_ENTRY(0x10ec0286, "ALC286", patch_alc269),
9217 HDA_CODEC_ENTRY(0x10ec0288, "ALC288", patch_alc269),
Kailang Yang0a6f0602017-06-30 16:00:48 +08009218 HDA_CODEC_ENTRY(0x10ec0289, "ALC289", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009219 HDA_CODEC_ENTRY(0x10ec0290, "ALC290", patch_alc269),
9220 HDA_CODEC_ENTRY(0x10ec0292, "ALC292", patch_alc269),
9221 HDA_CODEC_ENTRY(0x10ec0293, "ALC293", patch_alc269),
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08009222 HDA_CODEC_ENTRY(0x10ec0294, "ALC294", patch_alc269),
Kailang Yang7d727862016-05-24 16:46:07 +08009223 HDA_CODEC_ENTRY(0x10ec0295, "ALC295", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009224 HDA_CODEC_ENTRY(0x10ec0298, "ALC298", patch_alc269),
Kailang Yang28f1f9b2017-01-04 14:49:07 +08009225 HDA_CODEC_ENTRY(0x10ec0299, "ALC299", patch_alc269),
Kailang Yang1078bef2018-11-08 16:36:15 +08009226 HDA_CODEC_ENTRY(0x10ec0300, "ALC300", patch_alc269),
Kailang Yangf0778872019-10-24 15:13:32 +08009227 HDA_CODEC_ENTRY(0x10ec0623, "ALC623", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009228 HDA_CODEC_REV_ENTRY(0x10ec0861, 0x100340, "ALC660", patch_alc861),
9229 HDA_CODEC_ENTRY(0x10ec0660, "ALC660-VD", patch_alc861vd),
9230 HDA_CODEC_ENTRY(0x10ec0861, "ALC861", patch_alc861),
9231 HDA_CODEC_ENTRY(0x10ec0862, "ALC861-VD", patch_alc861vd),
9232 HDA_CODEC_REV_ENTRY(0x10ec0662, 0x100002, "ALC662 rev2", patch_alc882),
9233 HDA_CODEC_REV_ENTRY(0x10ec0662, 0x100101, "ALC662 rev1", patch_alc662),
9234 HDA_CODEC_REV_ENTRY(0x10ec0662, 0x100300, "ALC662 rev3", patch_alc662),
9235 HDA_CODEC_ENTRY(0x10ec0663, "ALC663", patch_alc662),
9236 HDA_CODEC_ENTRY(0x10ec0665, "ALC665", patch_alc662),
9237 HDA_CODEC_ENTRY(0x10ec0667, "ALC667", patch_alc662),
9238 HDA_CODEC_ENTRY(0x10ec0668, "ALC668", patch_alc662),
9239 HDA_CODEC_ENTRY(0x10ec0670, "ALC670", patch_alc662),
9240 HDA_CODEC_ENTRY(0x10ec0671, "ALC671", patch_alc662),
9241 HDA_CODEC_ENTRY(0x10ec0680, "ALC680", patch_alc680),
Kailang Yang6fbae352016-05-30 16:44:20 +08009242 HDA_CODEC_ENTRY(0x10ec0700, "ALC700", patch_alc269),
9243 HDA_CODEC_ENTRY(0x10ec0701, "ALC701", patch_alc269),
9244 HDA_CODEC_ENTRY(0x10ec0703, "ALC703", patch_alc269),
Kailang Yang83629532019-05-02 16:03:26 +08009245 HDA_CODEC_ENTRY(0x10ec0711, "ALC711", patch_alc269),
Kailang Yang78f4f7c2016-06-07 11:31:34 +08009246 HDA_CODEC_ENTRY(0x10ec0867, "ALC891", patch_alc662),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009247 HDA_CODEC_ENTRY(0x10ec0880, "ALC880", patch_alc880),
9248 HDA_CODEC_ENTRY(0x10ec0882, "ALC882", patch_alc882),
9249 HDA_CODEC_ENTRY(0x10ec0883, "ALC883", patch_alc882),
9250 HDA_CODEC_REV_ENTRY(0x10ec0885, 0x100101, "ALC889A", patch_alc882),
9251 HDA_CODEC_REV_ENTRY(0x10ec0885, 0x100103, "ALC889A", patch_alc882),
9252 HDA_CODEC_ENTRY(0x10ec0885, "ALC885", patch_alc882),
9253 HDA_CODEC_ENTRY(0x10ec0887, "ALC887", patch_alc882),
9254 HDA_CODEC_REV_ENTRY(0x10ec0888, 0x100101, "ALC1200", patch_alc882),
9255 HDA_CODEC_ENTRY(0x10ec0888, "ALC888", patch_alc882),
9256 HDA_CODEC_ENTRY(0x10ec0889, "ALC889", patch_alc882),
9257 HDA_CODEC_ENTRY(0x10ec0892, "ALC892", patch_alc662),
9258 HDA_CODEC_ENTRY(0x10ec0899, "ALC898", patch_alc882),
9259 HDA_CODEC_ENTRY(0x10ec0900, "ALC1150", patch_alc882),
Kailang Yang65553b12017-07-11 15:15:47 +08009260 HDA_CODEC_ENTRY(0x10ec1168, "ALC1220", patch_alc882),
Kailang Yanga535ad52017-01-16 16:59:26 +08009261 HDA_CODEC_ENTRY(0x10ec1220, "ALC1220", patch_alc882),
Linus Torvalds1da177e2005-04-16 15:20:36 -07009262 {} /* terminator */
9263};
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009264MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_realtek);
Takashi Iwai1289e9e2008-11-27 15:47:11 +01009265
9266MODULE_LICENSE("GPL");
9267MODULE_DESCRIPTION("Realtek HD-audio codec");
9268
Takashi Iwaid8a766a2015-02-17 15:25:37 +01009269static struct hda_codec_driver realtek_driver = {
Takashi Iwaib9a94a92015-10-01 16:20:04 +02009270 .id = snd_hda_id_realtek,
Takashi Iwai1289e9e2008-11-27 15:47:11 +01009271};
9272
Takashi Iwaid8a766a2015-02-17 15:25:37 +01009273module_hda_codec_driver(realtek_driver);