blob: e733d323f1a7c4a60a74cac437cd2c704fde0ef9 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * Universal Interface for Intel High Definition Audio Codec
3 *
Takashi Iwai1d045db2011-07-07 18:23:21 +02004 * HD audio interface patch for Realtek ALC codecs
Linus Torvalds1da177e2005-04-16 15:20:36 -07005 *
Kailang Yangdf694da2005-12-05 19:42:22 +01006 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7 * PeiSen Hou <pshou@realtek.com.tw>
Linus Torvalds1da177e2005-04-16 15:20:36 -07008 * Takashi Iwai <tiwai@suse.de>
Jonathan Woithe409a3e92012-03-27 13:01:01 +10309 * Jonathan Woithe <jwoithe@just42.net>
Linus Torvalds1da177e2005-04-16 15:20:36 -070010 *
11 * This driver is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This driver is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */
25
Linus Torvalds1da177e2005-04-16 15:20:36 -070026#include <linux/init.h>
27#include <linux/delay.h>
28#include <linux/slab.h>
29#include <linux/pci.h>
Takashi Iwai08fb0d02013-01-10 17:33:58 +010030#include <linux/dmi.h>
Paul Gortmakerda155d52011-07-15 12:38:28 -040031#include <linux/module.h>
David Henningsson33f4acd2015-01-07 15:50:13 +010032#include <linux/input.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070033#include <sound/core.h>
Kailang Yang9ad0e492010-09-14 23:22:00 +020034#include <sound/jack.h>
Pierre-Louis Bossartbe57bff2018-08-22 15:24:57 -050035#include <sound/hda_codec.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070036#include "hda_local.h"
Takashi Iwai23d30f22012-05-07 17:17:32 +020037#include "hda_auto_parser.h"
Takashi Iwai1835a0f2011-10-27 22:12:46 +020038#include "hda_jack.h"
Takashi Iwai08c189f2012-12-19 15:22:24 +010039#include "hda_generic.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070040
Takashi Iwaicd63a5f2013-07-05 12:13:59 +020041/* keep halting ALC5505 DSP, for power saving */
42#define HALT_REALTEK_ALC5505
43
Takashi Iwai4a79ba32009-04-22 16:31:35 +020044/* extra amp-initialization sequence types */
45enum {
Takashi Iwai1c76aa52018-06-21 16:37:54 +020046 ALC_INIT_UNDEFINED,
Takashi Iwai4a79ba32009-04-22 16:31:35 +020047 ALC_INIT_NONE,
48 ALC_INIT_DEFAULT,
Takashi Iwai4a79ba32009-04-22 16:31:35 +020049};
50
David Henningsson73bdd592013-04-15 15:44:14 +020051enum {
52 ALC_HEADSET_MODE_UNKNOWN,
53 ALC_HEADSET_MODE_UNPLUGGED,
54 ALC_HEADSET_MODE_HEADSET,
55 ALC_HEADSET_MODE_MIC,
56 ALC_HEADSET_MODE_HEADPHONE,
57};
58
59enum {
60 ALC_HEADSET_TYPE_UNKNOWN,
61 ALC_HEADSET_TYPE_CTIA,
62 ALC_HEADSET_TYPE_OMTP,
63};
64
Hui Wangc7b60a82015-12-28 11:35:25 +080065enum {
66 ALC_KEY_MICMUTE_INDEX,
67};
68
Kailang Yangda00c242010-03-19 11:23:45 +010069struct alc_customize_define {
70 unsigned int sku_cfg;
71 unsigned char port_connectivity;
72 unsigned char check_sum;
73 unsigned char customization;
74 unsigned char external_amp;
75 unsigned int enable_pcbeep:1;
76 unsigned int platform_type:1;
77 unsigned int swap:1;
78 unsigned int override:1;
David Henningsson90622912010-10-14 14:50:18 +020079 unsigned int fixup:1; /* Means that this sku is set by driver, not read from hw */
Kailang Yangda00c242010-03-19 11:23:45 +010080};
81
Linus Torvalds1da177e2005-04-16 15:20:36 -070082struct alc_spec {
Takashi Iwai08c189f2012-12-19 15:22:24 +010083 struct hda_gen_spec gen; /* must be at head */
Takashi Iwai23d30f22012-05-07 17:17:32 +020084
Linus Torvalds1da177e2005-04-16 15:20:36 -070085 /* codec parameterization */
Kailang Yangda00c242010-03-19 11:23:45 +010086 struct alc_customize_define cdefine;
Takashi Iwai08c189f2012-12-19 15:22:24 +010087 unsigned int parse_flags; /* flag for snd_hda_parse_pin_defcfg() */
88
Takashi Iwai5579cd62018-06-19 22:22:41 +020089 /* GPIO bits */
90 unsigned int gpio_mask;
91 unsigned int gpio_dir;
92 unsigned int gpio_data;
Takashi Iwai215c8502018-06-19 22:34:26 +020093 bool gpio_write_delay; /* add a delay before writing gpio_data */
Takashi Iwai5579cd62018-06-19 22:22:41 +020094
Takashi Iwai08fb0d02013-01-10 17:33:58 +010095 /* mute LED for HP laptops, see alc269_fixup_mic_mute_hook() */
96 int mute_led_polarity;
97 hda_nid_t mute_led_nid;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +080098 hda_nid_t cap_mute_led_nid;
Takashi Iwai08fb0d02013-01-10 17:33:58 +010099
Takashi Iwai0f32fd192014-11-19 12:16:14 +0100100 unsigned int gpio_mute_led_mask;
101 unsigned int gpio_mic_led_mask;
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +0100102
David Henningsson73bdd592013-04-15 15:44:14 +0200103 hda_nid_t headset_mic_pin;
104 hda_nid_t headphone_mic_pin;
105 int current_headset_mode;
106 int current_headset_type;
107
Takashi Iwaiae6b8132006-03-03 16:47:17 +0100108 /* hooks */
109 void (*init_hook)(struct hda_codec *codec);
Takashi Iwai83012a72012-08-24 18:38:08 +0200110#ifdef CONFIG_PM
Daniel T Chenc97259d2009-12-27 18:52:08 -0500111 void (*power_hook)(struct hda_codec *codec);
Hector Martinf5de24b2009-12-20 22:51:31 +0100112#endif
Takashi Iwai1c7161532011-04-07 10:37:16 +0200113 void (*shutup)(struct hda_codec *codec);
Takashi Iwai70a09762015-12-15 14:59:58 +0100114 void (*reboot_notify)(struct hda_codec *codec);
Takashi Iwaid922b512011-04-28 12:18:53 +0200115
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200116 int init_amp;
Takashi Iwaid433a672010-09-20 15:11:54 +0200117 int codec_variant; /* flag for other variants */
Kailang Yang97a26572013-11-29 00:35:26 -0500118 unsigned int has_alc5505_dsp:1;
119 unsigned int no_depop_delay:1;
Kailang Yang693abe12019-01-29 15:38:21 +0800120 unsigned int done_hp_init:1;
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +0100121 unsigned int no_shutup_pins:1;
Kailang Yangd3ba58b2019-05-06 15:09:42 +0800122 unsigned int ultra_low_power:1;
Takashi Iwaie64f14f2009-01-20 18:32:55 +0100123
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200124 /* for PLL fix */
125 hda_nid_t pll_nid;
126 unsigned int pll_coef_idx, pll_coef_bit;
Takashi Iwai1bb7e432011-10-17 16:50:59 +0200127 unsigned int coef0;
David Henningsson33f4acd2015-01-07 15:50:13 +0100128 struct input_dev *kb_dev;
Hui Wangc7b60a82015-12-28 11:35:25 +0800129 u8 alc_mute_keycode_map[1];
Kailang Yangdf694da2005-12-05 19:42:22 +0100130};
131
Takashi Iwai23f0c042009-02-26 13:03:58 +0100132/*
Takashi Iwaif2a227c2014-08-18 13:35:22 +0200133 * COEF access helper functions
134 */
135
136static int alc_read_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
137 unsigned int coef_idx)
138{
139 unsigned int val;
140
141 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, coef_idx);
142 val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PROC_COEF, 0);
143 return val;
144}
145
146#define alc_read_coef_idx(codec, coef_idx) \
147 alc_read_coefex_idx(codec, 0x20, coef_idx)
148
149static void alc_write_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
150 unsigned int coef_idx, unsigned int coef_val)
151{
152 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, coef_idx);
153 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PROC_COEF, coef_val);
154}
155
156#define alc_write_coef_idx(codec, coef_idx, coef_val) \
157 alc_write_coefex_idx(codec, 0x20, coef_idx, coef_val)
158
Takashi Iwai98b24882014-08-18 13:47:50 +0200159static void alc_update_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
160 unsigned int coef_idx, unsigned int mask,
161 unsigned int bits_set)
162{
163 unsigned int val = alc_read_coefex_idx(codec, nid, coef_idx);
164
165 if (val != -1)
166 alc_write_coefex_idx(codec, nid, coef_idx,
167 (val & ~mask) | bits_set);
168}
169
170#define alc_update_coef_idx(codec, coef_idx, mask, bits_set) \
171 alc_update_coefex_idx(codec, 0x20, coef_idx, mask, bits_set)
172
Takashi Iwaif2a227c2014-08-18 13:35:22 +0200173/* a special bypass for COEF 0; read the cached value at the second time */
174static unsigned int alc_get_coef0(struct hda_codec *codec)
175{
176 struct alc_spec *spec = codec->spec;
177
178 if (!spec->coef0)
179 spec->coef0 = alc_read_coef_idx(codec, 0);
180 return spec->coef0;
181}
182
Takashi Iwai54db6c32014-08-18 15:11:19 +0200183/* coef writes/updates batch */
184struct coef_fw {
185 unsigned char nid;
186 unsigned char idx;
187 unsigned short mask;
188 unsigned short val;
189};
190
191#define UPDATE_COEFEX(_nid, _idx, _mask, _val) \
192 { .nid = (_nid), .idx = (_idx), .mask = (_mask), .val = (_val) }
193#define WRITE_COEFEX(_nid, _idx, _val) UPDATE_COEFEX(_nid, _idx, -1, _val)
194#define WRITE_COEF(_idx, _val) WRITE_COEFEX(0x20, _idx, _val)
195#define UPDATE_COEF(_idx, _mask, _val) UPDATE_COEFEX(0x20, _idx, _mask, _val)
196
197static void alc_process_coef_fw(struct hda_codec *codec,
198 const struct coef_fw *fw)
199{
200 for (; fw->nid; fw++) {
201 if (fw->mask == (unsigned short)-1)
202 alc_write_coefex_idx(codec, fw->nid, fw->idx, fw->val);
203 else
204 alc_update_coefex_idx(codec, fw->nid, fw->idx,
205 fw->mask, fw->val);
206 }
207}
208
Takashi Iwaif2a227c2014-08-18 13:35:22 +0200209/*
Takashi Iwai1d045db2011-07-07 18:23:21 +0200210 * GPIO setup tables, used in initialization
Kailang Yangdf694da2005-12-05 19:42:22 +0100211 */
Takashi Iwai5579cd62018-06-19 22:22:41 +0200212
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200213/* Enable GPIO mask and set output */
Takashi Iwai5579cd62018-06-19 22:22:41 +0200214static void alc_setup_gpio(struct hda_codec *codec, unsigned int mask)
215{
216 struct alc_spec *spec = codec->spec;
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200217
Takashi Iwai5579cd62018-06-19 22:22:41 +0200218 spec->gpio_mask |= mask;
219 spec->gpio_dir |= mask;
220 spec->gpio_data |= mask;
221}
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200222
Takashi Iwai5579cd62018-06-19 22:22:41 +0200223static void alc_write_gpio_data(struct hda_codec *codec)
224{
225 struct alc_spec *spec = codec->spec;
226
227 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
228 spec->gpio_data);
229}
230
Takashi Iwaiaaf312d2018-06-19 22:28:22 +0200231static void alc_update_gpio_data(struct hda_codec *codec, unsigned int mask,
232 bool on)
233{
234 struct alc_spec *spec = codec->spec;
235 unsigned int oldval = spec->gpio_data;
236
237 if (on)
238 spec->gpio_data |= mask;
239 else
240 spec->gpio_data &= ~mask;
241 if (oldval != spec->gpio_data)
242 alc_write_gpio_data(codec);
243}
244
Takashi Iwai5579cd62018-06-19 22:22:41 +0200245static void alc_write_gpio(struct hda_codec *codec)
246{
247 struct alc_spec *spec = codec->spec;
248
249 if (!spec->gpio_mask)
250 return;
251
252 snd_hda_codec_write(codec, codec->core.afg, 0,
253 AC_VERB_SET_GPIO_MASK, spec->gpio_mask);
254 snd_hda_codec_write(codec, codec->core.afg, 0,
255 AC_VERB_SET_GPIO_DIRECTION, spec->gpio_dir);
Takashi Iwai215c8502018-06-19 22:34:26 +0200256 if (spec->gpio_write_delay)
257 msleep(1);
Takashi Iwai5579cd62018-06-19 22:22:41 +0200258 alc_write_gpio_data(codec);
259}
260
261static void alc_fixup_gpio(struct hda_codec *codec, int action,
262 unsigned int mask)
263{
264 if (action == HDA_FIXUP_ACT_PRE_PROBE)
265 alc_setup_gpio(codec, mask);
266}
267
268static void alc_fixup_gpio1(struct hda_codec *codec,
269 const struct hda_fixup *fix, int action)
270{
271 alc_fixup_gpio(codec, action, 0x01);
272}
273
274static void alc_fixup_gpio2(struct hda_codec *codec,
275 const struct hda_fixup *fix, int action)
276{
277 alc_fixup_gpio(codec, action, 0x02);
278}
279
280static void alc_fixup_gpio3(struct hda_codec *codec,
281 const struct hda_fixup *fix, int action)
282{
283 alc_fixup_gpio(codec, action, 0x03);
284}
Kailang Yangbdd148a2007-05-08 15:19:08 +0200285
Takashi Iwaiae065f12018-06-19 23:00:03 +0200286static void alc_fixup_gpio4(struct hda_codec *codec,
287 const struct hda_fixup *fix, int action)
288{
289 alc_fixup_gpio(codec, action, 0x04);
290}
291
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200292/*
293 * Fix hardware PLL issue
294 * On some codecs, the analog PLL gating control must be off while
295 * the default value is 1.
296 */
297static void alc_fix_pll(struct hda_codec *codec)
298{
299 struct alc_spec *spec = codec->spec;
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200300
Takashi Iwai98b24882014-08-18 13:47:50 +0200301 if (spec->pll_nid)
302 alc_update_coefex_idx(codec, spec->pll_nid, spec->pll_coef_idx,
303 1 << spec->pll_coef_bit, 0);
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200304}
305
306static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
307 unsigned int coef_idx, unsigned int coef_bit)
308{
309 struct alc_spec *spec = codec->spec;
310 spec->pll_nid = nid;
311 spec->pll_coef_idx = coef_idx;
312 spec->pll_coef_bit = coef_bit;
313 alc_fix_pll(codec);
314}
315
Takashi Iwaicf5a2272012-02-20 16:31:07 +0100316/* update the master volume per volume-knob's unsol event */
Takashi Iwai1a4f69d2014-09-11 15:22:46 +0200317static void alc_update_knob_master(struct hda_codec *codec,
318 struct hda_jack_callback *jack)
Takashi Iwaicf5a2272012-02-20 16:31:07 +0100319{
320 unsigned int val;
321 struct snd_kcontrol *kctl;
322 struct snd_ctl_elem_value *uctl;
323
324 kctl = snd_hda_find_mixer_ctl(codec, "Master Playback Volume");
325 if (!kctl)
326 return;
327 uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
328 if (!uctl)
329 return;
Takashi Iwai2ebab402016-02-09 10:23:52 +0100330 val = snd_hda_codec_read(codec, jack->nid, 0,
Takashi Iwaicf5a2272012-02-20 16:31:07 +0100331 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
332 val &= HDA_AMP_VOLMASK;
333 uctl->value.integer.value[0] = val;
334 uctl->value.integer.value[1] = val;
335 kctl->put(kctl, uctl);
336 kfree(uctl);
337}
338
David Henningsson29adc4b2012-09-25 11:31:00 +0200339static void alc880_unsol_event(struct hda_codec *codec, unsigned int res)
Takashi Iwaif21d78e2012-01-19 12:10:29 +0100340{
David Henningsson29adc4b2012-09-25 11:31:00 +0200341 /* For some reason, the res given from ALC880 is broken.
342 Here we adjust it properly. */
343 snd_hda_jack_unsol_event(codec, res >> 2);
Takashi Iwaif21d78e2012-01-19 12:10:29 +0100344}
345
Kailang Yang394c97f2014-11-12 17:38:08 +0800346/* Change EAPD to verb control */
347static void alc_fill_eapd_coef(struct hda_codec *codec)
348{
349 int coef;
350
351 coef = alc_get_coef0(codec);
352
Takashi Iwai7639a062015-03-03 10:07:24 +0100353 switch (codec->core.vendor_id) {
Kailang Yang394c97f2014-11-12 17:38:08 +0800354 case 0x10ec0262:
355 alc_update_coef_idx(codec, 0x7, 0, 1<<5);
356 break;
357 case 0x10ec0267:
358 case 0x10ec0268:
359 alc_update_coef_idx(codec, 0x7, 0, 1<<13);
360 break;
361 case 0x10ec0269:
362 if ((coef & 0x00f0) == 0x0010)
363 alc_update_coef_idx(codec, 0xd, 0, 1<<14);
364 if ((coef & 0x00f0) == 0x0020)
365 alc_update_coef_idx(codec, 0x4, 1<<15, 0);
366 if ((coef & 0x00f0) == 0x0030)
367 alc_update_coef_idx(codec, 0x10, 1<<9, 0);
368 break;
369 case 0x10ec0280:
370 case 0x10ec0284:
371 case 0x10ec0290:
372 case 0x10ec0292:
373 alc_update_coef_idx(codec, 0x4, 1<<15, 0);
374 break;
Kailang Yang42314302016-02-03 15:03:50 +0800375 case 0x10ec0225:
Takashi Iwai44be77c2017-12-27 08:53:59 +0100376 case 0x10ec0295:
377 case 0x10ec0299:
378 alc_update_coef_idx(codec, 0x67, 0xf000, 0x3000);
379 /* fallthrough */
380 case 0x10ec0215:
Kailang Yang394c97f2014-11-12 17:38:08 +0800381 case 0x10ec0233:
Kailang Yangea04a1d2018-04-25 15:31:52 +0800382 case 0x10ec0235:
Kailang Yang736f20a2017-10-20 15:06:34 +0800383 case 0x10ec0236:
Kailang Yang394c97f2014-11-12 17:38:08 +0800384 case 0x10ec0255:
Kailang Yang4344aec2014-12-17 17:39:05 +0800385 case 0x10ec0256:
Kailang Yangf429e7e2017-12-05 15:38:24 +0800386 case 0x10ec0257:
Kailang Yang394c97f2014-11-12 17:38:08 +0800387 case 0x10ec0282:
388 case 0x10ec0283:
389 case 0x10ec0286:
390 case 0x10ec0288:
Kailang Yang0a6f0602017-06-30 16:00:48 +0800391 case 0x10ec0285:
Kailang Yang506b62c2014-12-18 17:07:44 +0800392 case 0x10ec0298:
Kailang Yang0a6f0602017-06-30 16:00:48 +0800393 case 0x10ec0289:
Kailang Yang1078bef2018-11-08 16:36:15 +0800394 case 0x10ec0300:
Kailang Yang394c97f2014-11-12 17:38:08 +0800395 alc_update_coef_idx(codec, 0x10, 1<<9, 0);
396 break;
Kailang Yang3aabf942017-11-08 15:28:33 +0800397 case 0x10ec0275:
398 alc_update_coef_idx(codec, 0xe, 0, 1<<0);
399 break;
Kailang Yang394c97f2014-11-12 17:38:08 +0800400 case 0x10ec0293:
401 alc_update_coef_idx(codec, 0xa, 1<<13, 0);
402 break;
Kailang Yangdcd4f0d2016-05-04 15:50:18 +0800403 case 0x10ec0234:
404 case 0x10ec0274:
405 case 0x10ec0294:
Kailang Yang6fbae352016-05-30 16:44:20 +0800406 case 0x10ec0700:
407 case 0x10ec0701:
408 case 0x10ec0703:
Kailang Yangdcd4f0d2016-05-04 15:50:18 +0800409 alc_update_coef_idx(codec, 0x10, 1<<15, 0);
410 break;
Kailang Yang394c97f2014-11-12 17:38:08 +0800411 case 0x10ec0662:
412 if ((coef & 0x00f0) == 0x0030)
413 alc_update_coef_idx(codec, 0x4, 1<<10, 0); /* EAPD Ctrl */
414 break;
415 case 0x10ec0272:
416 case 0x10ec0273:
417 case 0x10ec0663:
418 case 0x10ec0665:
419 case 0x10ec0670:
420 case 0x10ec0671:
421 case 0x10ec0672:
422 alc_update_coef_idx(codec, 0xd, 0, 1<<14); /* EAPD Ctrl */
423 break;
424 case 0x10ec0668:
425 alc_update_coef_idx(codec, 0x7, 3<<13, 0);
426 break;
427 case 0x10ec0867:
428 alc_update_coef_idx(codec, 0x4, 1<<10, 0);
429 break;
430 case 0x10ec0888:
431 if ((coef & 0x00f0) == 0x0020 || (coef & 0x00f0) == 0x0030)
432 alc_update_coef_idx(codec, 0x7, 1<<5, 0);
433 break;
434 case 0x10ec0892:
435 alc_update_coef_idx(codec, 0x7, 1<<5, 0);
436 break;
437 case 0x10ec0899:
438 case 0x10ec0900:
Kailang Yang65553b12017-07-11 15:15:47 +0800439 case 0x10ec1168:
Kailang Yanga535ad52017-01-16 16:59:26 +0800440 case 0x10ec1220:
Kailang Yang394c97f2014-11-12 17:38:08 +0800441 alc_update_coef_idx(codec, 0x7, 1<<1, 0);
442 break;
443 }
444}
445
Kailang Yangf9423e72008-05-27 12:32:25 +0200446/* additional initialization for ALC888 variants */
447static void alc888_coef_init(struct hda_codec *codec)
448{
Kailang Yang1df88742014-10-29 16:10:13 +0800449 switch (alc_get_coef0(codec) & 0x00f0) {
450 /* alc888-VA */
451 case 0x00:
452 /* alc888-VB */
453 case 0x10:
454 alc_update_coef_idx(codec, 7, 0, 0x2030); /* Turn EAPD to High */
455 break;
456 }
Jaroslav Kysela87a8c372009-07-23 10:58:29 +0200457}
458
Takashi Iwai3fb4a502010-01-19 15:46:37 +0100459/* turn on/off EAPD control (only if available) */
460static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
461{
462 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
463 return;
464 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
465 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
466 on ? 2 : 0);
467}
468
Takashi Iwai691f1fc2011-04-07 10:31:43 +0200469/* turn on/off EAPD controls of the codec */
470static void alc_auto_setup_eapd(struct hda_codec *codec, bool on)
471{
472 /* We currently only handle front, HP */
Takashi Iwai39fa84e2011-06-27 15:28:57 +0200473 static hda_nid_t pins[] = {
Hui Wangaf95b412015-03-26 17:14:55 +0800474 0x0f, 0x10, 0x14, 0x15, 0x17, 0
Takashi Iwai39fa84e2011-06-27 15:28:57 +0200475 };
476 hda_nid_t *p;
477 for (p = pins; *p; p++)
478 set_eapd(codec, *p, on);
Takashi Iwai691f1fc2011-04-07 10:31:43 +0200479}
480
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +0100481static void alc_shutup_pins(struct hda_codec *codec)
482{
483 struct alc_spec *spec = codec->spec;
484
485 if (!spec->no_shutup_pins)
486 snd_hda_shutup_pins(codec);
487}
488
Takashi Iwai1c7161532011-04-07 10:37:16 +0200489/* generic shutup callback;
Lars-Peter Clausen4ce8e6a2016-11-08 15:48:06 +0100490 * just turning off EAPD and a little pause for avoiding pop-noise
Takashi Iwai1c7161532011-04-07 10:37:16 +0200491 */
492static void alc_eapd_shutup(struct hda_codec *codec)
493{
Kailang Yang97a26572013-11-29 00:35:26 -0500494 struct alc_spec *spec = codec->spec;
495
Takashi Iwai1c7161532011-04-07 10:37:16 +0200496 alc_auto_setup_eapd(codec, false);
Kailang Yang97a26572013-11-29 00:35:26 -0500497 if (!spec->no_depop_delay)
498 msleep(200);
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +0100499 alc_shutup_pins(codec);
Takashi Iwai1c7161532011-04-07 10:37:16 +0200500}
501
Takashi Iwai1d045db2011-07-07 18:23:21 +0200502/* generic EAPD initialization */
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200503static void alc_auto_init_amp(struct hda_codec *codec, int type)
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200504{
Kailang Yang394c97f2014-11-12 17:38:08 +0800505 alc_fill_eapd_coef(codec);
Takashi Iwai39fa84e2011-06-27 15:28:57 +0200506 alc_auto_setup_eapd(codec, true);
Takashi Iwai5579cd62018-06-19 22:22:41 +0200507 alc_write_gpio(codec);
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200508 switch (type) {
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200509 case ALC_INIT_DEFAULT:
Takashi Iwai7639a062015-03-03 10:07:24 +0100510 switch (codec->core.vendor_id) {
Kailang Yangc9b58002007-10-16 14:30:01 +0200511 case 0x10ec0260:
Takashi Iwai98b24882014-08-18 13:47:50 +0200512 alc_update_coefex_idx(codec, 0x1a, 7, 0, 0x2010);
Kailang Yangc9b58002007-10-16 14:30:01 +0200513 break;
Kailang Yangc9b58002007-10-16 14:30:01 +0200514 case 0x10ec0880:
515 case 0x10ec0882:
516 case 0x10ec0883:
517 case 0x10ec0885:
Kailang Yang1df88742014-10-29 16:10:13 +0800518 alc_update_coef_idx(codec, 7, 0, 0x2030);
Kailang Yangc9b58002007-10-16 14:30:01 +0200519 break;
Kailang Yangf9423e72008-05-27 12:32:25 +0200520 case 0x10ec0888:
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200521 alc888_coef_init(codec);
Kailang Yangf9423e72008-05-27 12:32:25 +0200522 break;
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200523 }
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200524 break;
525 }
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200526}
Kailang Yangea1fb292008-08-26 12:58:38 +0200527
Takashi Iwai35a39f92019-02-01 11:19:50 +0100528/* get a primary headphone pin if available */
529static hda_nid_t alc_get_hp_pin(struct alc_spec *spec)
530{
531 if (spec->gen.autocfg.hp_pins[0])
532 return spec->gen.autocfg.hp_pins[0];
533 if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
534 return spec->gen.autocfg.line_out_pins[0];
535 return 0;
536}
Takashi Iwai1d045db2011-07-07 18:23:21 +0200537
538/*
539 * Realtek SSID verification
540 */
541
David Henningsson90622912010-10-14 14:50:18 +0200542/* Could be any non-zero and even value. When used as fixup, tells
543 * the driver to ignore any present sku defines.
544 */
545#define ALC_FIXUP_SKU_IGNORE (2)
546
Takashi Iwai23d30f22012-05-07 17:17:32 +0200547static void alc_fixup_sku_ignore(struct hda_codec *codec,
548 const struct hda_fixup *fix, int action)
549{
550 struct alc_spec *spec = codec->spec;
551 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
552 spec->cdefine.fixup = 1;
553 spec->cdefine.sku_cfg = ALC_FIXUP_SKU_IGNORE;
554 }
555}
556
Mengdong Linb5c66112013-11-29 00:35:35 -0500557static void alc_fixup_no_depop_delay(struct hda_codec *codec,
558 const struct hda_fixup *fix, int action)
559{
560 struct alc_spec *spec = codec->spec;
561
Mengdong Lin84d2dc32013-12-02 22:26:03 -0500562 if (action == HDA_FIXUP_ACT_PROBE) {
Mengdong Linb5c66112013-11-29 00:35:35 -0500563 spec->no_depop_delay = 1;
Mengdong Lin84d2dc32013-12-02 22:26:03 -0500564 codec->depop_delay = 0;
565 }
Mengdong Linb5c66112013-11-29 00:35:35 -0500566}
567
Kailang Yangda00c242010-03-19 11:23:45 +0100568static int alc_auto_parse_customize_define(struct hda_codec *codec)
569{
570 unsigned int ass, tmp, i;
Takashi Iwai7fb56222010-03-22 17:09:47 +0100571 unsigned nid = 0;
Kailang Yangda00c242010-03-19 11:23:45 +0100572 struct alc_spec *spec = codec->spec;
573
Takashi Iwaib6cbe512010-07-28 17:43:36 +0200574 spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
575
David Henningsson90622912010-10-14 14:50:18 +0200576 if (spec->cdefine.fixup) {
577 ass = spec->cdefine.sku_cfg;
578 if (ass == ALC_FIXUP_SKU_IGNORE)
579 return -1;
580 goto do_sku;
581 }
582
Takashi Iwai5100cd02014-02-15 10:03:19 +0100583 if (!codec->bus->pci)
584 return -1;
Takashi Iwai7639a062015-03-03 10:07:24 +0100585 ass = codec->core.subsystem_id & 0xffff;
Takashi Iwaib6cbe512010-07-28 17:43:36 +0200586 if (ass != codec->bus->pci->subsystem_device && (ass & 1))
Kailang Yangda00c242010-03-19 11:23:45 +0100587 goto do_sku;
588
589 nid = 0x1d;
Takashi Iwai7639a062015-03-03 10:07:24 +0100590 if (codec->core.vendor_id == 0x10ec0260)
Kailang Yangda00c242010-03-19 11:23:45 +0100591 nid = 0x17;
592 ass = snd_hda_codec_get_pincfg(codec, nid);
593
594 if (!(ass & 1)) {
Takashi Iwai4e76a882014-02-25 12:21:03 +0100595 codec_info(codec, "%s: SKU not ready 0x%08x\n",
Takashi Iwai7639a062015-03-03 10:07:24 +0100596 codec->core.chip_name, ass);
Kailang Yangda00c242010-03-19 11:23:45 +0100597 return -1;
598 }
599
600 /* check sum */
601 tmp = 0;
602 for (i = 1; i < 16; i++) {
603 if ((ass >> i) & 1)
604 tmp++;
605 }
606 if (((ass >> 16) & 0xf) != tmp)
607 return -1;
608
609 spec->cdefine.port_connectivity = ass >> 30;
610 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
611 spec->cdefine.check_sum = (ass >> 16) & 0xf;
612 spec->cdefine.customization = ass >> 8;
613do_sku:
614 spec->cdefine.sku_cfg = ass;
615 spec->cdefine.external_amp = (ass & 0x38) >> 3;
616 spec->cdefine.platform_type = (ass & 0x4) >> 2;
617 spec->cdefine.swap = (ass & 0x2) >> 1;
618 spec->cdefine.override = ass & 0x1;
619
Takashi Iwai4e76a882014-02-25 12:21:03 +0100620 codec_dbg(codec, "SKU: Nid=0x%x sku_cfg=0x%08x\n",
Kailang Yangda00c242010-03-19 11:23:45 +0100621 nid, spec->cdefine.sku_cfg);
Takashi Iwai4e76a882014-02-25 12:21:03 +0100622 codec_dbg(codec, "SKU: port_connectivity=0x%x\n",
Kailang Yangda00c242010-03-19 11:23:45 +0100623 spec->cdefine.port_connectivity);
Takashi Iwai4e76a882014-02-25 12:21:03 +0100624 codec_dbg(codec, "SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
625 codec_dbg(codec, "SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
626 codec_dbg(codec, "SKU: customization=0x%08x\n", spec->cdefine.customization);
627 codec_dbg(codec, "SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
628 codec_dbg(codec, "SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
629 codec_dbg(codec, "SKU: swap=0x%x\n", spec->cdefine.swap);
630 codec_dbg(codec, "SKU: override=0x%x\n", spec->cdefine.override);
Kailang Yangda00c242010-03-19 11:23:45 +0100631
632 return 0;
633}
634
Takashi Iwai08c189f2012-12-19 15:22:24 +0100635/* return the position of NID in the list, or -1 if not found */
636static int find_idx_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
637{
638 int i;
639 for (i = 0; i < nums; i++)
640 if (list[i] == nid)
641 return i;
642 return -1;
643}
Takashi Iwai1d045db2011-07-07 18:23:21 +0200644/* return true if the given NID is found in the list */
Takashi Iwai3af9ee62011-06-27 12:34:01 +0200645static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
646{
Takashi Iwai21268962011-07-07 15:01:13 +0200647 return find_idx_in_nid_list(nid, list, nums) >= 0;
Takashi Iwai3af9ee62011-06-27 12:34:01 +0200648}
649
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200650/* check subsystem ID and set up device-specific initialization;
651 * return 1 if initialized, 0 if invalid SSID
652 */
653/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
654 * 31 ~ 16 : Manufacture ID
655 * 15 ~ 8 : SKU ID
656 * 7 ~ 0 : Assembly ID
657 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
658 */
Takashi Iwai58c57cf2014-01-07 18:22:49 +0100659static int alc_subsystem_id(struct hda_codec *codec, const hda_nid_t *ports)
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200660{
661 unsigned int ass, tmp, i;
662 unsigned nid;
663 struct alc_spec *spec = codec->spec;
664
David Henningsson90622912010-10-14 14:50:18 +0200665 if (spec->cdefine.fixup) {
666 ass = spec->cdefine.sku_cfg;
667 if (ass == ALC_FIXUP_SKU_IGNORE)
668 return 0;
669 goto do_sku;
670 }
671
Takashi Iwai7639a062015-03-03 10:07:24 +0100672 ass = codec->core.subsystem_id & 0xffff;
Takashi Iwai5100cd02014-02-15 10:03:19 +0100673 if (codec->bus->pci &&
674 ass != codec->bus->pci->subsystem_device && (ass & 1))
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200675 goto do_sku;
676
677 /* invalid SSID, check the special NID pin defcfg instead */
678 /*
Sasha Alexandrdef319f2009-06-16 16:00:15 -0400679 * 31~30 : port connectivity
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200680 * 29~21 : reserve
681 * 20 : PCBEEP input
682 * 19~16 : Check sum (15:1)
683 * 15~1 : Custom
684 * 0 : override
685 */
686 nid = 0x1d;
Takashi Iwai7639a062015-03-03 10:07:24 +0100687 if (codec->core.vendor_id == 0x10ec0260)
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200688 nid = 0x17;
689 ass = snd_hda_codec_get_pincfg(codec, nid);
Takashi Iwai4e76a882014-02-25 12:21:03 +0100690 codec_dbg(codec,
691 "realtek: No valid SSID, checking pincfg 0x%08x for NID 0x%x\n",
Takashi Iwaicb6605c2009-04-28 13:03:19 +0200692 ass, nid);
Kailang Yang6227cdc2010-02-25 08:36:52 +0100693 if (!(ass & 1))
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200694 return 0;
695 if ((ass >> 30) != 1) /* no physical connection */
696 return 0;
697
698 /* check sum */
699 tmp = 0;
700 for (i = 1; i < 16; i++) {
701 if ((ass >> i) & 1)
702 tmp++;
703 }
704 if (((ass >> 16) & 0xf) != tmp)
705 return 0;
706do_sku:
Takashi Iwai4e76a882014-02-25 12:21:03 +0100707 codec_dbg(codec, "realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
Takashi Iwai7639a062015-03-03 10:07:24 +0100708 ass & 0xffff, codec->core.vendor_id);
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200709 /*
710 * 0 : override
711 * 1 : Swap Jack
712 * 2 : 0 --> Desktop, 1 --> Laptop
713 * 3~5 : External Amplifier control
714 * 7~6 : Reserved
715 */
716 tmp = (ass & 0x38) >> 3; /* external Amp control */
Takashi Iwai1c76aa52018-06-21 16:37:54 +0200717 if (spec->init_amp == ALC_INIT_UNDEFINED) {
718 switch (tmp) {
719 case 1:
Takashi Iwai5579cd62018-06-19 22:22:41 +0200720 alc_setup_gpio(codec, 0x01);
Takashi Iwai1c76aa52018-06-21 16:37:54 +0200721 break;
722 case 3:
Takashi Iwai5579cd62018-06-19 22:22:41 +0200723 alc_setup_gpio(codec, 0x02);
Takashi Iwai1c76aa52018-06-21 16:37:54 +0200724 break;
725 case 7:
Takashi Iwai5579cd62018-06-19 22:22:41 +0200726 alc_setup_gpio(codec, 0x03);
Takashi Iwai1c76aa52018-06-21 16:37:54 +0200727 break;
728 case 5:
729 default:
730 spec->init_amp = ALC_INIT_DEFAULT;
731 break;
732 }
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200733 }
734
735 /* is laptop or Desktop and enable the function "Mute internal speaker
736 * when the external headphone out jack is plugged"
737 */
738 if (!(ass & 0x8000))
739 return 1;
740 /*
741 * 10~8 : Jack location
742 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
743 * 14~13: Resvered
744 * 15 : 1 --> enable the function "Mute internal speaker
745 * when the external headphone out jack is plugged"
746 */
Takashi Iwai35a39f92019-02-01 11:19:50 +0100747 if (!alc_get_hp_pin(spec)) {
Takashi Iwai01d48252009-10-06 13:21:54 +0200748 hda_nid_t nid;
Kailang Yangc9b58002007-10-16 14:30:01 +0200749 tmp = (ass >> 11) & 0x3; /* HP to chassis */
Takashi Iwai58c57cf2014-01-07 18:22:49 +0100750 nid = ports[tmp];
Takashi Iwai08c189f2012-12-19 15:22:24 +0100751 if (found_in_nid_list(nid, spec->gen.autocfg.line_out_pins,
752 spec->gen.autocfg.line_outs))
Takashi Iwai3af9ee62011-06-27 12:34:01 +0200753 return 1;
Takashi Iwai08c189f2012-12-19 15:22:24 +0100754 spec->gen.autocfg.hp_pins[0] = nid;
Kailang Yangc9b58002007-10-16 14:30:01 +0200755 }
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200756 return 1;
757}
Kailang Yangea1fb292008-08-26 12:58:38 +0200758
Takashi Iwai3e6179b2011-07-08 16:55:13 +0200759/* Check the validity of ALC subsystem-id
760 * ports contains an array of 4 pin NIDs for port-A, E, D and I */
761static void alc_ssid_check(struct hda_codec *codec, const hda_nid_t *ports)
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200762{
Takashi Iwai58c57cf2014-01-07 18:22:49 +0100763 if (!alc_subsystem_id(codec, ports)) {
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200764 struct alc_spec *spec = codec->spec;
Takashi Iwai4e76a882014-02-25 12:21:03 +0100765 codec_dbg(codec,
766 "realtek: Enable default setup for auto mode as fallback\n");
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200767 spec->init_amp = ALC_INIT_DEFAULT;
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200768 }
Takashi Iwai21268962011-07-07 15:01:13 +0200769}
Takashi Iwai1a1455d2011-04-28 17:36:18 +0200770
Takashi Iwai41e41f12005-06-08 14:48:49 +0200771/*
Takashi Iwai1d045db2011-07-07 18:23:21 +0200772 */
773
David Henningsson9d36a7d2014-10-07 10:18:42 +0200774static void alc_fixup_inv_dmic(struct hda_codec *codec,
775 const struct hda_fixup *fix, int action)
Takashi Iwai125821a2012-06-22 14:30:29 +0200776{
777 struct alc_spec *spec = codec->spec;
Takashi Iwai668d1e92012-11-29 14:10:17 +0100778
David Henningsson9d36a7d2014-10-07 10:18:42 +0200779 spec->gen.inv_dmic_split = 1;
Takashi Iwai6e72aa52012-06-25 10:52:25 +0200780}
781
Takashi Iwai603c4012008-07-30 15:01:44 +0200782
Takashi Iwai2eab6942012-12-18 15:30:41 +0100783static int alc_build_controls(struct hda_codec *codec)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700784{
Takashi Iwaia5cb4632018-06-20 12:50:11 +0200785 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700786
Takashi Iwai08c189f2012-12-19 15:22:24 +0100787 err = snd_hda_gen_build_controls(codec);
788 if (err < 0)
789 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700790
Takashi Iwai1727a772013-01-10 09:52:52 +0100791 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_BUILD);
Takashi Iwai420b0fe2012-03-12 12:35:27 +0100792 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700793}
794
Takashi Iwaie9edcee2005-06-13 14:16:38 +0200795
Linus Torvalds1da177e2005-04-16 15:20:36 -0700796/*
Takashi Iwaiae6b8132006-03-03 16:47:17 +0100797 * Common callbacks
Takashi Iwaie9edcee2005-06-13 14:16:38 +0200798 */
Takashi Iwai16ded522005-06-10 19:58:24 +0200799
Linus Torvalds1da177e2005-04-16 15:20:36 -0700800static int alc_init(struct hda_codec *codec)
801{
802 struct alc_spec *spec = codec->spec;
Takashi Iwaie9edcee2005-06-13 14:16:38 +0200803
Takashi Iwai546bb672012-03-07 08:37:19 +0100804 if (spec->init_hook)
805 spec->init_hook(codec);
Kailang Yang526af6e2012-03-07 08:25:20 +0100806
Kailang Yang607ca3b2019-04-26 16:35:41 +0800807 snd_hda_gen_init(codec);
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200808 alc_fix_pll(codec);
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200809 alc_auto_init_amp(codec, spec->init_amp);
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200810
Takashi Iwai1727a772013-01-10 09:52:52 +0100811 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_INIT);
Takashi Iwaie08a0072006-09-07 17:52:14 +0200812
Linus Torvalds1da177e2005-04-16 15:20:36 -0700813 return 0;
814}
815
Takashi Iwaia4e09aa2009-12-27 11:22:24 +0100816static inline void alc_shutup(struct hda_codec *codec)
817{
Takashi Iwai1c7161532011-04-07 10:37:16 +0200818 struct alc_spec *spec = codec->spec;
819
Takashi Iwaic7273bd2018-06-12 16:09:57 +0200820 if (!snd_hda_get_bool_hint(codec, "shutup"))
821 return; /* disabled explicitly by hints */
822
Takashi Iwai1c7161532011-04-07 10:37:16 +0200823 if (spec && spec->shutup)
824 spec->shutup(codec);
Takashi Iwai9bfb2842013-07-24 14:31:50 +0200825 else
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +0100826 alc_shutup_pins(codec);
Takashi Iwaia4e09aa2009-12-27 11:22:24 +0100827}
828
Takashi Iwai70a09762015-12-15 14:59:58 +0100829static void alc_reboot_notify(struct hda_codec *codec)
830{
831 struct alc_spec *spec = codec->spec;
832
833 if (spec && spec->reboot_notify)
834 spec->reboot_notify(codec);
835 else
836 alc_shutup(codec);
837}
838
839/* power down codec to D3 at reboot/shutdown; set as reboot_notify ops */
840static void alc_d3_at_reboot(struct hda_codec *codec)
841{
842 snd_hda_codec_set_power_to_all(codec, codec->core.afg, AC_PWRST_D3);
843 snd_hda_codec_write(codec, codec->core.afg, 0,
844 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
845 msleep(10);
846}
847
Takashi Iwai8a02c0c2014-02-10 18:09:45 +0100848#define alc_free snd_hda_gen_free
Linus Torvalds1da177e2005-04-16 15:20:36 -0700849
Takashi Iwai83012a72012-08-24 18:38:08 +0200850#ifdef CONFIG_PM
Daniel T Chenc97259d2009-12-27 18:52:08 -0500851static void alc_power_eapd(struct hda_codec *codec)
852{
Takashi Iwai691f1fc2011-04-07 10:31:43 +0200853 alc_auto_setup_eapd(codec, false);
Daniel T Chenc97259d2009-12-27 18:52:08 -0500854}
855
Takashi Iwai68cb2b52012-07-02 15:20:37 +0200856static int alc_suspend(struct hda_codec *codec)
Hector Martinf5de24b2009-12-20 22:51:31 +0100857{
858 struct alc_spec *spec = codec->spec;
Takashi Iwaia4e09aa2009-12-27 11:22:24 +0100859 alc_shutup(codec);
Hector Martinf5de24b2009-12-20 22:51:31 +0100860 if (spec && spec->power_hook)
Daniel T Chenc97259d2009-12-27 18:52:08 -0500861 spec->power_hook(codec);
Hector Martinf5de24b2009-12-20 22:51:31 +0100862 return 0;
863}
864#endif
865
Takashi Iwai2a439522011-07-26 09:52:50 +0200866#ifdef CONFIG_PM
Takashi Iwaie044c392008-10-27 16:56:24 +0100867static int alc_resume(struct hda_codec *codec)
868{
Kailang Yang97a26572013-11-29 00:35:26 -0500869 struct alc_spec *spec = codec->spec;
870
871 if (!spec->no_depop_delay)
872 msleep(150); /* to avoid pop noise */
Takashi Iwaie044c392008-10-27 16:56:24 +0100873 codec->patch_ops.init(codec);
Takashi Iwaieeecd9d2015-02-25 15:18:50 +0100874 regcache_sync(codec->core.regmap);
Takashi Iwai9e5341b2010-09-21 09:57:06 +0200875 hda_call_check_power_status(codec, 0x01);
Takashi Iwaie044c392008-10-27 16:56:24 +0100876 return 0;
877}
Takashi Iwaie044c392008-10-27 16:56:24 +0100878#endif
879
Linus Torvalds1da177e2005-04-16 15:20:36 -0700880/*
881 */
Takashi Iwaia9111322011-05-02 11:30:18 +0200882static const struct hda_codec_ops alc_patch_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700883 .build_controls = alc_build_controls,
Takashi Iwai08c189f2012-12-19 15:22:24 +0100884 .build_pcms = snd_hda_gen_build_pcms,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700885 .init = alc_init,
886 .free = alc_free,
David Henningsson29adc4b2012-09-25 11:31:00 +0200887 .unsol_event = snd_hda_jack_unsol_event,
Takashi Iwai2a439522011-07-26 09:52:50 +0200888#ifdef CONFIG_PM
Takashi Iwaie044c392008-10-27 16:56:24 +0100889 .resume = alc_resume,
Hector Martinf5de24b2009-12-20 22:51:31 +0100890 .suspend = alc_suspend,
Takashi Iwaifce52a32013-01-07 12:42:48 +0100891 .check_power_status = snd_hda_gen_check_power_status,
Takashi Iwaicb53c622007-08-10 17:21:45 +0200892#endif
Takashi Iwai70a09762015-12-15 14:59:58 +0100893 .reboot_notify = alc_reboot_notify,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700894};
895
David Henningsson29adc4b2012-09-25 11:31:00 +0200896
Takashi Iwaided255b2015-10-01 17:59:43 +0200897#define alc_codec_rename(codec, name) snd_hda_codec_set_name(codec, name)
Kailang Yangc027ddc2010-03-19 11:33:06 +0100898
Takashi Iwai2fa522b2005-05-12 14:51:12 +0200899/*
Kailang Yang4b016932013-11-28 11:55:09 +0100900 * Rename codecs appropriately from COEF value or subvendor id
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200901 */
902struct alc_codec_rename_table {
903 unsigned int vendor_id;
904 unsigned short coef_mask;
905 unsigned short coef_bits;
906 const char *name;
907};
908
Kailang Yang4b016932013-11-28 11:55:09 +0100909struct alc_codec_rename_pci_table {
910 unsigned int codec_vendor_id;
911 unsigned short pci_subvendor;
912 unsigned short pci_subdevice;
913 const char *name;
914};
915
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200916static struct alc_codec_rename_table rename_tbl[] = {
Kailang Yange6e5f7a2014-06-06 16:46:43 +0800917 { 0x10ec0221, 0xf00f, 0x1003, "ALC231" },
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200918 { 0x10ec0269, 0xfff0, 0x3010, "ALC277" },
919 { 0x10ec0269, 0xf0f0, 0x2010, "ALC259" },
920 { 0x10ec0269, 0xf0f0, 0x3010, "ALC258" },
921 { 0x10ec0269, 0x00f0, 0x0010, "ALC269VB" },
922 { 0x10ec0269, 0xffff, 0xa023, "ALC259" },
923 { 0x10ec0269, 0xffff, 0x6023, "ALC281X" },
924 { 0x10ec0269, 0x00f0, 0x0020, "ALC269VC" },
Kailang Yangadcc70b2012-05-25 08:08:38 +0200925 { 0x10ec0269, 0x00f0, 0x0030, "ALC269VD" },
Kailang Yange6e5f7a2014-06-06 16:46:43 +0800926 { 0x10ec0662, 0xffff, 0x4020, "ALC656" },
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200927 { 0x10ec0887, 0x00f0, 0x0030, "ALC887-VD" },
928 { 0x10ec0888, 0x00f0, 0x0030, "ALC888-VD" },
929 { 0x10ec0888, 0xf0f0, 0x3020, "ALC886" },
930 { 0x10ec0899, 0x2000, 0x2000, "ALC899" },
931 { 0x10ec0892, 0xffff, 0x8020, "ALC661" },
932 { 0x10ec0892, 0xffff, 0x8011, "ALC661" },
933 { 0x10ec0892, 0xffff, 0x4011, "ALC656" },
934 { } /* terminator */
935};
936
Kailang Yang4b016932013-11-28 11:55:09 +0100937static struct alc_codec_rename_pci_table rename_pci_tbl[] = {
938 { 0x10ec0280, 0x1028, 0, "ALC3220" },
939 { 0x10ec0282, 0x1028, 0, "ALC3221" },
940 { 0x10ec0283, 0x1028, 0, "ALC3223" },
Kailang Yang193177d2014-04-23 16:06:13 +0800941 { 0x10ec0288, 0x1028, 0, "ALC3263" },
Kailang Yang4b016932013-11-28 11:55:09 +0100942 { 0x10ec0292, 0x1028, 0, "ALC3226" },
Kailang Yang193177d2014-04-23 16:06:13 +0800943 { 0x10ec0293, 0x1028, 0, "ALC3235" },
Kailang Yang4b016932013-11-28 11:55:09 +0100944 { 0x10ec0255, 0x1028, 0, "ALC3234" },
945 { 0x10ec0668, 0x1028, 0, "ALC3661" },
Kailang Yange6e5f7a2014-06-06 16:46:43 +0800946 { 0x10ec0275, 0x1028, 0, "ALC3260" },
947 { 0x10ec0899, 0x1028, 0, "ALC3861" },
Kailang Yang2c674fa2015-05-05 15:02:42 +0800948 { 0x10ec0298, 0x1028, 0, "ALC3266" },
Kailang Yang736f20a2017-10-20 15:06:34 +0800949 { 0x10ec0236, 0x1028, 0, "ALC3204" },
Kailang Yang82324502015-05-25 17:16:49 +0800950 { 0x10ec0256, 0x1028, 0, "ALC3246" },
Kailang Yang42314302016-02-03 15:03:50 +0800951 { 0x10ec0225, 0x1028, 0, "ALC3253" },
Kailang Yang7d727862016-05-24 16:46:07 +0800952 { 0x10ec0295, 0x1028, 0, "ALC3254" },
Kailang Yang28f1f9b2017-01-04 14:49:07 +0800953 { 0x10ec0299, 0x1028, 0, "ALC3271" },
Kailang Yange6e5f7a2014-06-06 16:46:43 +0800954 { 0x10ec0670, 0x1025, 0, "ALC669X" },
955 { 0x10ec0676, 0x1025, 0, "ALC679X" },
956 { 0x10ec0282, 0x1043, 0, "ALC3229" },
957 { 0x10ec0233, 0x1043, 0, "ALC3236" },
958 { 0x10ec0280, 0x103c, 0, "ALC3228" },
959 { 0x10ec0282, 0x103c, 0, "ALC3227" },
960 { 0x10ec0286, 0x103c, 0, "ALC3242" },
961 { 0x10ec0290, 0x103c, 0, "ALC3241" },
962 { 0x10ec0668, 0x103c, 0, "ALC3662" },
963 { 0x10ec0283, 0x17aa, 0, "ALC3239" },
964 { 0x10ec0292, 0x17aa, 0, "ALC3232" },
Kailang Yang4b016932013-11-28 11:55:09 +0100965 { } /* terminator */
966};
967
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200968static int alc_codec_rename_from_preset(struct hda_codec *codec)
969{
970 const struct alc_codec_rename_table *p;
Kailang Yang4b016932013-11-28 11:55:09 +0100971 const struct alc_codec_rename_pci_table *q;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200972
973 for (p = rename_tbl; p->vendor_id; p++) {
Takashi Iwai7639a062015-03-03 10:07:24 +0100974 if (p->vendor_id != codec->core.vendor_id)
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200975 continue;
Takashi Iwai1bb7e432011-10-17 16:50:59 +0200976 if ((alc_get_coef0(codec) & p->coef_mask) == p->coef_bits)
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200977 return alc_codec_rename(codec, p->name);
978 }
Kailang Yang4b016932013-11-28 11:55:09 +0100979
Takashi Iwai5100cd02014-02-15 10:03:19 +0100980 if (!codec->bus->pci)
981 return 0;
Kailang Yang4b016932013-11-28 11:55:09 +0100982 for (q = rename_pci_tbl; q->codec_vendor_id; q++) {
Takashi Iwai7639a062015-03-03 10:07:24 +0100983 if (q->codec_vendor_id != codec->core.vendor_id)
Kailang Yang4b016932013-11-28 11:55:09 +0100984 continue;
985 if (q->pci_subvendor != codec->bus->pci->subsystem_vendor)
986 continue;
987 if (!q->pci_subdevice ||
988 q->pci_subdevice == codec->bus->pci->subsystem_device)
989 return alc_codec_rename(codec, q->name);
990 }
991
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200992 return 0;
993}
994
Takashi Iwaie4770622011-07-08 11:11:35 +0200995
996/*
Takashi Iwai1d045db2011-07-07 18:23:21 +0200997 * Digital-beep handlers
998 */
999#ifdef CONFIG_SND_HDA_INPUT_BEEP
Takashi Iwaifea80fa2018-06-20 12:52:46 +02001000
1001/* additional beep mixers; private_value will be overwritten */
1002static const struct snd_kcontrol_new alc_beep_mixer[] = {
1003 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
1004 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
1005};
1006
1007/* set up and create beep controls */
1008static int set_beep_amp(struct alc_spec *spec, hda_nid_t nid,
1009 int idx, int dir)
1010{
1011 struct snd_kcontrol_new *knew;
1012 unsigned int beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir);
1013 int i;
1014
1015 for (i = 0; i < ARRAY_SIZE(alc_beep_mixer); i++) {
1016 knew = snd_hda_gen_add_kctl(&spec->gen, NULL,
1017 &alc_beep_mixer[i]);
1018 if (!knew)
1019 return -ENOMEM;
1020 knew->private_value = beep_amp;
1021 }
1022 return 0;
1023}
Takashi Iwai1d045db2011-07-07 18:23:21 +02001024
1025static const struct snd_pci_quirk beep_white_list[] = {
Duncan Roe71100052012-10-10 14:19:50 +02001026 SND_PCI_QUIRK(0x1043, 0x103c, "ASUS", 1),
W. Trevor Kinga4b7f21d2014-03-29 17:47:24 -07001027 SND_PCI_QUIRK(0x1043, 0x115d, "ASUS", 1),
Takashi Iwai1d045db2011-07-07 18:23:21 +02001028 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
Takashi Iwai8554ee42013-02-25 09:54:43 +01001029 SND_PCI_QUIRK(0x1043, 0x8376, "EeePC", 1),
Takashi Iwai1d045db2011-07-07 18:23:21 +02001030 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
1031 SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1),
1032 SND_PCI_QUIRK(0x1043, 0x834a, "EeePC", 1),
Takashi Iwai78f8baf2012-03-06 14:02:32 +01001033 SND_PCI_QUIRK(0x1458, 0xa002, "GA-MA790X", 1),
Takashi Iwai1d045db2011-07-07 18:23:21 +02001034 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
1035 {}
1036};
1037
1038static inline int has_cdefine_beep(struct hda_codec *codec)
1039{
1040 struct alc_spec *spec = codec->spec;
1041 const struct snd_pci_quirk *q;
1042 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
1043 if (q)
1044 return q->value;
1045 return spec->cdefine.enable_pcbeep;
1046}
1047#else
Takashi Iwaifea80fa2018-06-20 12:52:46 +02001048#define set_beep_amp(spec, nid, idx, dir) 0
Takashi Iwai1d045db2011-07-07 18:23:21 +02001049#define has_cdefine_beep(codec) 0
1050#endif
1051
1052/* parse the BIOS configuration and set up the alc_spec */
1053/* return 1 if successful, 0 if the proper config is not found,
1054 * or a negative error code
1055 */
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001056static int alc_parse_auto_config(struct hda_codec *codec,
1057 const hda_nid_t *ignore_nids,
1058 const hda_nid_t *ssid_nids)
Takashi Iwai1d045db2011-07-07 18:23:21 +02001059{
1060 struct alc_spec *spec = codec->spec;
Takashi Iwai08c189f2012-12-19 15:22:24 +01001061 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001062 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001063
Takashi Iwai53c334a2011-08-23 18:27:14 +02001064 err = snd_hda_parse_pin_defcfg(codec, cfg, ignore_nids,
1065 spec->parse_flags);
Takashi Iwai1d045db2011-07-07 18:23:21 +02001066 if (err < 0)
1067 return err;
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001068
1069 if (ssid_nids)
1070 alc_ssid_check(codec, ssid_nids);
1071
Takashi Iwai08c189f2012-12-19 15:22:24 +01001072 err = snd_hda_gen_parse_auto_config(codec, cfg);
1073 if (err < 0)
1074 return err;
Takashi Iwai070cff42012-02-21 12:54:17 +01001075
Takashi Iwai1d045db2011-07-07 18:23:21 +02001076 return 1;
1077}
1078
Takashi Iwai3de95172012-05-07 18:03:15 +02001079/* common preparation job for alc_spec */
1080static int alc_alloc_spec(struct hda_codec *codec, hda_nid_t mixer_nid)
1081{
1082 struct alc_spec *spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1083 int err;
1084
1085 if (!spec)
1086 return -ENOMEM;
1087 codec->spec = spec;
Takashi Iwai08c189f2012-12-19 15:22:24 +01001088 snd_hda_gen_spec_init(&spec->gen);
1089 spec->gen.mixer_nid = mixer_nid;
1090 spec->gen.own_eapd_ctl = 1;
Takashi Iwai1098b7c2012-12-17 20:03:15 +01001091 codec->single_adc_amp = 1;
Takashi Iwai08c189f2012-12-19 15:22:24 +01001092 /* FIXME: do we need this for all Realtek codec models? */
1093 codec->spdif_status_reset = 1;
Takashi Iwai225068a2015-05-29 10:42:14 +02001094 codec->patch_ops = alc_patch_ops;
Takashi Iwai3de95172012-05-07 18:03:15 +02001095
1096 err = alc_codec_rename_from_preset(codec);
1097 if (err < 0) {
1098 kfree(spec);
1099 return err;
1100 }
1101 return 0;
1102}
1103
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001104static int alc880_parse_auto_config(struct hda_codec *codec)
1105{
1106 static const hda_nid_t alc880_ignore[] = { 0x1d, 0 };
Jesper Juhl7d7eb9e2012-04-12 22:11:25 +02001107 static const hda_nid_t alc880_ssids[] = { 0x15, 0x1b, 0x14, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001108 return alc_parse_auto_config(codec, alc880_ignore, alc880_ssids);
1109}
1110
Takashi Iwai1d045db2011-07-07 18:23:21 +02001111/*
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001112 * ALC880 fix-ups
1113 */
1114enum {
Takashi Iwai411225a2012-02-20 17:48:19 +01001115 ALC880_FIXUP_GPIO1,
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001116 ALC880_FIXUP_GPIO2,
1117 ALC880_FIXUP_MEDION_RIM,
Takashi Iwaidc6af522012-02-17 16:18:59 +01001118 ALC880_FIXUP_LG,
Takashi Iwaidb8a38e2013-08-09 12:34:42 +02001119 ALC880_FIXUP_LG_LW25,
Takashi Iwaif02aab52012-02-17 16:33:56 +01001120 ALC880_FIXUP_W810,
Takashi Iwai27e917f2012-02-17 17:49:54 +01001121 ALC880_FIXUP_EAPD_COEF,
Takashi Iwaib9368f52012-02-17 17:54:44 +01001122 ALC880_FIXUP_TCL_S700,
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001123 ALC880_FIXUP_VOL_KNOB,
1124 ALC880_FIXUP_FUJITSU,
Takashi Iwaiba533812012-02-20 16:36:52 +01001125 ALC880_FIXUP_F1734,
Takashi Iwai817de922012-02-20 17:20:48 +01001126 ALC880_FIXUP_UNIWILL,
Takashi Iwai967b88c2012-02-20 17:31:02 +01001127 ALC880_FIXUP_UNIWILL_DIG,
Takashi Iwai96e225f2012-02-20 17:41:51 +01001128 ALC880_FIXUP_Z71V,
Takashi Iwai487a5882013-11-07 07:29:30 +01001129 ALC880_FIXUP_ASUS_W5A,
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001130 ALC880_FIXUP_3ST_BASE,
1131 ALC880_FIXUP_3ST,
1132 ALC880_FIXUP_3ST_DIG,
1133 ALC880_FIXUP_5ST_BASE,
1134 ALC880_FIXUP_5ST,
1135 ALC880_FIXUP_5ST_DIG,
1136 ALC880_FIXUP_6ST_BASE,
1137 ALC880_FIXUP_6ST,
1138 ALC880_FIXUP_6ST_DIG,
Takashi Iwai53971452013-01-23 18:21:37 +01001139 ALC880_FIXUP_6ST_AUTOMUTE,
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001140};
1141
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001142/* enable the volume-knob widget support on NID 0x21 */
1143static void alc880_fixup_vol_knob(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001144 const struct hda_fixup *fix, int action)
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001145{
Takashi Iwai1727a772013-01-10 09:52:52 +01001146 if (action == HDA_FIXUP_ACT_PROBE)
Takashi Iwai62f949b2014-09-11 14:06:53 +02001147 snd_hda_jack_detect_enable_callback(codec, 0x21,
1148 alc_update_knob_master);
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001149}
1150
Takashi Iwai1727a772013-01-10 09:52:52 +01001151static const struct hda_fixup alc880_fixups[] = {
Takashi Iwai411225a2012-02-20 17:48:19 +01001152 [ALC880_FIXUP_GPIO1] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02001153 .type = HDA_FIXUP_FUNC,
1154 .v.func = alc_fixup_gpio1,
Takashi Iwai411225a2012-02-20 17:48:19 +01001155 },
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001156 [ALC880_FIXUP_GPIO2] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02001157 .type = HDA_FIXUP_FUNC,
1158 .v.func = alc_fixup_gpio2,
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001159 },
1160 [ALC880_FIXUP_MEDION_RIM] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001161 .type = HDA_FIXUP_VERBS,
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001162 .v.verbs = (const struct hda_verb[]) {
1163 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
1164 { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
1165 { }
1166 },
1167 .chained = true,
1168 .chain_id = ALC880_FIXUP_GPIO2,
1169 },
Takashi Iwaidc6af522012-02-17 16:18:59 +01001170 [ALC880_FIXUP_LG] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001171 .type = HDA_FIXUP_PINS,
1172 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaidc6af522012-02-17 16:18:59 +01001173 /* disable bogus unused pins */
1174 { 0x16, 0x411111f0 },
1175 { 0x18, 0x411111f0 },
1176 { 0x1a, 0x411111f0 },
1177 { }
1178 }
1179 },
Takashi Iwaidb8a38e2013-08-09 12:34:42 +02001180 [ALC880_FIXUP_LG_LW25] = {
1181 .type = HDA_FIXUP_PINS,
1182 .v.pins = (const struct hda_pintbl[]) {
1183 { 0x1a, 0x0181344f }, /* line-in */
1184 { 0x1b, 0x0321403f }, /* headphone */
1185 { }
1186 }
1187 },
Takashi Iwaif02aab52012-02-17 16:33:56 +01001188 [ALC880_FIXUP_W810] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001189 .type = HDA_FIXUP_PINS,
1190 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaif02aab52012-02-17 16:33:56 +01001191 /* disable bogus unused pins */
1192 { 0x17, 0x411111f0 },
1193 { }
1194 },
1195 .chained = true,
1196 .chain_id = ALC880_FIXUP_GPIO2,
1197 },
Takashi Iwai27e917f2012-02-17 17:49:54 +01001198 [ALC880_FIXUP_EAPD_COEF] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001199 .type = HDA_FIXUP_VERBS,
Takashi Iwai27e917f2012-02-17 17:49:54 +01001200 .v.verbs = (const struct hda_verb[]) {
1201 /* change to EAPD mode */
1202 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
1203 { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
1204 {}
1205 },
1206 },
Takashi Iwaib9368f52012-02-17 17:54:44 +01001207 [ALC880_FIXUP_TCL_S700] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001208 .type = HDA_FIXUP_VERBS,
Takashi Iwaib9368f52012-02-17 17:54:44 +01001209 .v.verbs = (const struct hda_verb[]) {
1210 /* change to EAPD mode */
1211 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
1212 { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
1213 {}
1214 },
1215 .chained = true,
1216 .chain_id = ALC880_FIXUP_GPIO2,
1217 },
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001218 [ALC880_FIXUP_VOL_KNOB] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001219 .type = HDA_FIXUP_FUNC,
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001220 .v.func = alc880_fixup_vol_knob,
1221 },
1222 [ALC880_FIXUP_FUJITSU] = {
1223 /* override all pins as BIOS on old Amilo is broken */
Takashi Iwai1727a772013-01-10 09:52:52 +01001224 .type = HDA_FIXUP_PINS,
1225 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaibb148bd2015-08-13 18:02:39 +02001226 { 0x14, 0x0121401f }, /* HP */
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001227 { 0x15, 0x99030120 }, /* speaker */
1228 { 0x16, 0x99030130 }, /* bass speaker */
1229 { 0x17, 0x411111f0 }, /* N/A */
1230 { 0x18, 0x411111f0 }, /* N/A */
1231 { 0x19, 0x01a19950 }, /* mic-in */
1232 { 0x1a, 0x411111f0 }, /* N/A */
1233 { 0x1b, 0x411111f0 }, /* N/A */
1234 { 0x1c, 0x411111f0 }, /* N/A */
1235 { 0x1d, 0x411111f0 }, /* N/A */
1236 { 0x1e, 0x01454140 }, /* SPDIF out */
1237 { }
1238 },
1239 .chained = true,
1240 .chain_id = ALC880_FIXUP_VOL_KNOB,
1241 },
Takashi Iwaiba533812012-02-20 16:36:52 +01001242 [ALC880_FIXUP_F1734] = {
1243 /* almost compatible with FUJITSU, but no bass and SPDIF */
Takashi Iwai1727a772013-01-10 09:52:52 +01001244 .type = HDA_FIXUP_PINS,
1245 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaibb148bd2015-08-13 18:02:39 +02001246 { 0x14, 0x0121401f }, /* HP */
Takashi Iwaiba533812012-02-20 16:36:52 +01001247 { 0x15, 0x99030120 }, /* speaker */
1248 { 0x16, 0x411111f0 }, /* N/A */
1249 { 0x17, 0x411111f0 }, /* N/A */
1250 { 0x18, 0x411111f0 }, /* N/A */
1251 { 0x19, 0x01a19950 }, /* mic-in */
1252 { 0x1a, 0x411111f0 }, /* N/A */
1253 { 0x1b, 0x411111f0 }, /* N/A */
1254 { 0x1c, 0x411111f0 }, /* N/A */
1255 { 0x1d, 0x411111f0 }, /* N/A */
1256 { 0x1e, 0x411111f0 }, /* N/A */
1257 { }
1258 },
1259 .chained = true,
1260 .chain_id = ALC880_FIXUP_VOL_KNOB,
1261 },
Takashi Iwai817de922012-02-20 17:20:48 +01001262 [ALC880_FIXUP_UNIWILL] = {
1263 /* need to fix HP and speaker pins to be parsed correctly */
Takashi Iwai1727a772013-01-10 09:52:52 +01001264 .type = HDA_FIXUP_PINS,
1265 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai817de922012-02-20 17:20:48 +01001266 { 0x14, 0x0121411f }, /* HP */
1267 { 0x15, 0x99030120 }, /* speaker */
1268 { 0x16, 0x99030130 }, /* bass speaker */
1269 { }
1270 },
1271 },
Takashi Iwai967b88c2012-02-20 17:31:02 +01001272 [ALC880_FIXUP_UNIWILL_DIG] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001273 .type = HDA_FIXUP_PINS,
1274 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai967b88c2012-02-20 17:31:02 +01001275 /* disable bogus unused pins */
1276 { 0x17, 0x411111f0 },
1277 { 0x19, 0x411111f0 },
1278 { 0x1b, 0x411111f0 },
1279 { 0x1f, 0x411111f0 },
1280 { }
1281 }
1282 },
Takashi Iwai96e225f2012-02-20 17:41:51 +01001283 [ALC880_FIXUP_Z71V] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001284 .type = HDA_FIXUP_PINS,
1285 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai96e225f2012-02-20 17:41:51 +01001286 /* set up the whole pins as BIOS is utterly broken */
1287 { 0x14, 0x99030120 }, /* speaker */
1288 { 0x15, 0x0121411f }, /* HP */
1289 { 0x16, 0x411111f0 }, /* N/A */
1290 { 0x17, 0x411111f0 }, /* N/A */
1291 { 0x18, 0x01a19950 }, /* mic-in */
1292 { 0x19, 0x411111f0 }, /* N/A */
1293 { 0x1a, 0x01813031 }, /* line-in */
1294 { 0x1b, 0x411111f0 }, /* N/A */
1295 { 0x1c, 0x411111f0 }, /* N/A */
1296 { 0x1d, 0x411111f0 }, /* N/A */
1297 { 0x1e, 0x0144111e }, /* SPDIF */
1298 { }
1299 }
1300 },
Takashi Iwai487a5882013-11-07 07:29:30 +01001301 [ALC880_FIXUP_ASUS_W5A] = {
1302 .type = HDA_FIXUP_PINS,
1303 .v.pins = (const struct hda_pintbl[]) {
1304 /* set up the whole pins as BIOS is utterly broken */
1305 { 0x14, 0x0121411f }, /* HP */
1306 { 0x15, 0x411111f0 }, /* N/A */
1307 { 0x16, 0x411111f0 }, /* N/A */
1308 { 0x17, 0x411111f0 }, /* N/A */
1309 { 0x18, 0x90a60160 }, /* mic */
1310 { 0x19, 0x411111f0 }, /* N/A */
1311 { 0x1a, 0x411111f0 }, /* N/A */
1312 { 0x1b, 0x411111f0 }, /* N/A */
1313 { 0x1c, 0x411111f0 }, /* N/A */
1314 { 0x1d, 0x411111f0 }, /* N/A */
1315 { 0x1e, 0xb743111e }, /* SPDIF out */
1316 { }
1317 },
1318 .chained = true,
1319 .chain_id = ALC880_FIXUP_GPIO1,
1320 },
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001321 [ALC880_FIXUP_3ST_BASE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001322 .type = HDA_FIXUP_PINS,
1323 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001324 { 0x14, 0x01014010 }, /* line-out */
1325 { 0x15, 0x411111f0 }, /* N/A */
1326 { 0x16, 0x411111f0 }, /* N/A */
1327 { 0x17, 0x411111f0 }, /* N/A */
1328 { 0x18, 0x01a19c30 }, /* mic-in */
1329 { 0x19, 0x0121411f }, /* HP */
1330 { 0x1a, 0x01813031 }, /* line-in */
1331 { 0x1b, 0x02a19c40 }, /* front-mic */
1332 { 0x1c, 0x411111f0 }, /* N/A */
1333 { 0x1d, 0x411111f0 }, /* N/A */
1334 /* 0x1e is filled in below */
1335 { 0x1f, 0x411111f0 }, /* N/A */
1336 { }
1337 }
1338 },
1339 [ALC880_FIXUP_3ST] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001340 .type = HDA_FIXUP_PINS,
1341 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001342 { 0x1e, 0x411111f0 }, /* N/A */
1343 { }
1344 },
1345 .chained = true,
1346 .chain_id = ALC880_FIXUP_3ST_BASE,
1347 },
1348 [ALC880_FIXUP_3ST_DIG] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001349 .type = HDA_FIXUP_PINS,
1350 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001351 { 0x1e, 0x0144111e }, /* SPDIF */
1352 { }
1353 },
1354 .chained = true,
1355 .chain_id = ALC880_FIXUP_3ST_BASE,
1356 },
1357 [ALC880_FIXUP_5ST_BASE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001358 .type = HDA_FIXUP_PINS,
1359 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001360 { 0x14, 0x01014010 }, /* front */
1361 { 0x15, 0x411111f0 }, /* N/A */
1362 { 0x16, 0x01011411 }, /* CLFE */
1363 { 0x17, 0x01016412 }, /* surr */
1364 { 0x18, 0x01a19c30 }, /* mic-in */
1365 { 0x19, 0x0121411f }, /* HP */
1366 { 0x1a, 0x01813031 }, /* line-in */
1367 { 0x1b, 0x02a19c40 }, /* front-mic */
1368 { 0x1c, 0x411111f0 }, /* N/A */
1369 { 0x1d, 0x411111f0 }, /* N/A */
1370 /* 0x1e is filled in below */
1371 { 0x1f, 0x411111f0 }, /* N/A */
1372 { }
1373 }
1374 },
1375 [ALC880_FIXUP_5ST] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001376 .type = HDA_FIXUP_PINS,
1377 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001378 { 0x1e, 0x411111f0 }, /* N/A */
1379 { }
1380 },
1381 .chained = true,
1382 .chain_id = ALC880_FIXUP_5ST_BASE,
1383 },
1384 [ALC880_FIXUP_5ST_DIG] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001385 .type = HDA_FIXUP_PINS,
1386 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001387 { 0x1e, 0x0144111e }, /* SPDIF */
1388 { }
1389 },
1390 .chained = true,
1391 .chain_id = ALC880_FIXUP_5ST_BASE,
1392 },
1393 [ALC880_FIXUP_6ST_BASE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001394 .type = HDA_FIXUP_PINS,
1395 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001396 { 0x14, 0x01014010 }, /* front */
1397 { 0x15, 0x01016412 }, /* surr */
1398 { 0x16, 0x01011411 }, /* CLFE */
1399 { 0x17, 0x01012414 }, /* side */
1400 { 0x18, 0x01a19c30 }, /* mic-in */
1401 { 0x19, 0x02a19c40 }, /* front-mic */
1402 { 0x1a, 0x01813031 }, /* line-in */
1403 { 0x1b, 0x0121411f }, /* HP */
1404 { 0x1c, 0x411111f0 }, /* N/A */
1405 { 0x1d, 0x411111f0 }, /* N/A */
1406 /* 0x1e is filled in below */
1407 { 0x1f, 0x411111f0 }, /* N/A */
1408 { }
1409 }
1410 },
1411 [ALC880_FIXUP_6ST] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001412 .type = HDA_FIXUP_PINS,
1413 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001414 { 0x1e, 0x411111f0 }, /* N/A */
1415 { }
1416 },
1417 .chained = true,
1418 .chain_id = ALC880_FIXUP_6ST_BASE,
1419 },
1420 [ALC880_FIXUP_6ST_DIG] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001421 .type = HDA_FIXUP_PINS,
1422 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001423 { 0x1e, 0x0144111e }, /* SPDIF */
1424 { }
1425 },
1426 .chained = true,
1427 .chain_id = ALC880_FIXUP_6ST_BASE,
1428 },
Takashi Iwai53971452013-01-23 18:21:37 +01001429 [ALC880_FIXUP_6ST_AUTOMUTE] = {
1430 .type = HDA_FIXUP_PINS,
1431 .v.pins = (const struct hda_pintbl[]) {
1432 { 0x1b, 0x0121401f }, /* HP with jack detect */
1433 { }
1434 },
1435 .chained_before = true,
1436 .chain_id = ALC880_FIXUP_6ST_BASE,
1437 },
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001438};
1439
1440static const struct snd_pci_quirk alc880_fixup_tbl[] = {
Takashi Iwaif02aab52012-02-17 16:33:56 +01001441 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_FIXUP_W810),
Takashi Iwai487a5882013-11-07 07:29:30 +01001442 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS W5A", ALC880_FIXUP_ASUS_W5A),
Takashi Iwai96e225f2012-02-20 17:41:51 +01001443 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_FIXUP_Z71V),
Takashi Iwai29e3fdc2012-02-20 17:56:57 +01001444 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_FIXUP_GPIO1),
David Henningsson6538de02014-06-10 10:52:50 +02001445 SND_PCI_QUIRK(0x147b, 0x1045, "ABit AA8XE", ALC880_FIXUP_6ST_AUTOMUTE),
Takashi Iwai29e3fdc2012-02-20 17:56:57 +01001446 SND_PCI_QUIRK(0x1558, 0x5401, "Clevo GPIO2", ALC880_FIXUP_GPIO2),
Takashi Iwai27e917f2012-02-17 17:49:54 +01001447 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo", ALC880_FIXUP_EAPD_COEF),
Takashi Iwai967b88c2012-02-20 17:31:02 +01001448 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_FIXUP_UNIWILL_DIG),
Takashi Iwaiba533812012-02-20 16:36:52 +01001449 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_FIXUP_F1734),
Takashi Iwai817de922012-02-20 17:20:48 +01001450 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_FIXUP_UNIWILL),
Takashi Iwai7833c7e2012-02-20 17:11:38 +01001451 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_FIXUP_VOL_KNOB),
Takashi Iwaif02aab52012-02-17 16:33:56 +01001452 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_FIXUP_W810),
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001453 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_FIXUP_MEDION_RIM),
Takashi Iwai53971452013-01-23 18:21:37 +01001454 SND_PCI_QUIRK(0x1631, 0xe011, "PB 13201056", ALC880_FIXUP_6ST_AUTOMUTE),
Takashi Iwaia1615742015-08-13 18:05:06 +02001455 SND_PCI_QUIRK(0x1734, 0x107c, "FSC Amilo M1437", ALC880_FIXUP_FUJITSU),
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001456 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FIXUP_FUJITSU),
Takashi Iwaiba533812012-02-20 16:36:52 +01001457 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_FIXUP_F1734),
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001458 SND_PCI_QUIRK(0x1734, 0x10b0, "FSC Amilo Pi1556", ALC880_FIXUP_FUJITSU),
Takashi Iwaidc6af522012-02-17 16:18:59 +01001459 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_FIXUP_LG),
1460 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_FIXUP_LG),
1461 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_FIXUP_LG),
Takashi Iwaidb8a38e2013-08-09 12:34:42 +02001462 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_FIXUP_LG_LW25),
Takashi Iwaib9368f52012-02-17 17:54:44 +01001463 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_FIXUP_TCL_S700),
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001464
1465 /* Below is the copied entries from alc880_quirks.c.
1466 * It's not quite sure whether BIOS sets the correct pin-config table
1467 * on these machines, thus they are kept to be compatible with
1468 * the old static quirks. Once when it's confirmed to work without
1469 * these overrides, it'd be better to remove.
1470 */
1471 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_FIXUP_5ST_DIG),
1472 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_FIXUP_6ST),
1473 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_FIXUP_3ST_DIG),
1474 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_FIXUP_6ST_DIG),
1475 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_FIXUP_6ST_DIG),
1476 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_FIXUP_6ST_DIG),
1477 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_FIXUP_3ST_DIG),
1478 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_FIXUP_3ST),
1479 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_FIXUP_6ST_DIG),
1480 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_FIXUP_3ST),
1481 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_FIXUP_3ST),
1482 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_FIXUP_5ST),
1483 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_FIXUP_5ST),
1484 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_FIXUP_5ST),
1485 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_FIXUP_6ST_DIG),
1486 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_FIXUP_6ST_DIG),
1487 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_FIXUP_6ST_DIG),
1488 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_FIXUP_6ST_DIG),
1489 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_FIXUP_5ST_DIG),
1490 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_FIXUP_5ST_DIG),
1491 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_FIXUP_5ST_DIG),
1492 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_FIXUP_6ST_DIG), /* broken BIOS */
1493 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_FIXUP_6ST_DIG),
1494 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1495 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1496 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1497 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_FIXUP_3ST_DIG),
1498 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1499 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_FIXUP_3ST_DIG),
1500 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_FIXUP_3ST_DIG),
1501 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1502 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1503 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1504 /* default Intel */
1505 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_FIXUP_3ST),
1506 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_FIXUP_5ST_DIG),
1507 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_FIXUP_6ST_DIG),
1508 {}
1509};
1510
Takashi Iwai1727a772013-01-10 09:52:52 +01001511static const struct hda_model_fixup alc880_fixup_models[] = {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001512 {.id = ALC880_FIXUP_3ST, .name = "3stack"},
1513 {.id = ALC880_FIXUP_3ST_DIG, .name = "3stack-digout"},
1514 {.id = ALC880_FIXUP_5ST, .name = "5stack"},
1515 {.id = ALC880_FIXUP_5ST_DIG, .name = "5stack-digout"},
1516 {.id = ALC880_FIXUP_6ST, .name = "6stack"},
1517 {.id = ALC880_FIXUP_6ST_DIG, .name = "6stack-digout"},
Takashi Iwai53971452013-01-23 18:21:37 +01001518 {.id = ALC880_FIXUP_6ST_AUTOMUTE, .name = "6stack-automute"},
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001519 {}
1520};
1521
1522
1523/*
Takashi Iwai1d045db2011-07-07 18:23:21 +02001524 * OK, here we have finally the patch for ALC880
1525 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02001526static int patch_alc880(struct hda_codec *codec)
1527{
1528 struct alc_spec *spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001529 int err;
1530
Takashi Iwai3de95172012-05-07 18:03:15 +02001531 err = alc_alloc_spec(codec, 0x0b);
1532 if (err < 0)
1533 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001534
Takashi Iwai3de95172012-05-07 18:03:15 +02001535 spec = codec->spec;
Takashi Iwai08c189f2012-12-19 15:22:24 +01001536 spec->gen.need_dac_fix = 1;
Takashi Iwai7504b6c2013-03-18 11:25:51 +01001537 spec->gen.beep_nid = 0x01;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001538
Takashi Iwai225068a2015-05-29 10:42:14 +02001539 codec->patch_ops.unsol_event = alc880_unsol_event;
1540
Takashi Iwai1727a772013-01-10 09:52:52 +01001541 snd_hda_pick_fixup(codec, alc880_fixup_models, alc880_fixup_tbl,
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001542 alc880_fixups);
Takashi Iwai1727a772013-01-10 09:52:52 +01001543 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02001544
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001545 /* automatic parse from the BIOS config */
1546 err = alc880_parse_auto_config(codec);
1547 if (err < 0)
1548 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001549
Takashi Iwaifea80fa2018-06-20 12:52:46 +02001550 if (!spec->gen.no_analog) {
1551 err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
1552 if (err < 0)
1553 goto error;
1554 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02001555
Takashi Iwai1727a772013-01-10 09:52:52 +01001556 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01001557
Takashi Iwai1d045db2011-07-07 18:23:21 +02001558 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02001559
1560 error:
1561 alc_free(codec);
1562 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001563}
1564
1565
1566/*
1567 * ALC260 support
1568 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02001569static int alc260_parse_auto_config(struct hda_codec *codec)
1570{
Takashi Iwai1d045db2011-07-07 18:23:21 +02001571 static const hda_nid_t alc260_ignore[] = { 0x17, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001572 static const hda_nid_t alc260_ssids[] = { 0x10, 0x15, 0x0f, 0 };
1573 return alc_parse_auto_config(codec, alc260_ignore, alc260_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02001574}
1575
Takashi Iwai1d045db2011-07-07 18:23:21 +02001576/*
1577 * Pin config fixes
1578 */
1579enum {
Takashi Iwaica8f0422012-02-16 11:51:19 +01001580 ALC260_FIXUP_HP_DC5750,
1581 ALC260_FIXUP_HP_PIN_0F,
1582 ALC260_FIXUP_COEF,
Takashi Iwai15317ab2012-02-16 12:02:53 +01001583 ALC260_FIXUP_GPIO1,
Takashi Iwai20f7d922012-02-16 12:35:16 +01001584 ALC260_FIXUP_GPIO1_TOGGLE,
1585 ALC260_FIXUP_REPLACER,
Takashi Iwai0a1c4fa2012-02-16 12:42:30 +01001586 ALC260_FIXUP_HP_B1900,
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001587 ALC260_FIXUP_KN1,
Takashi Iwai39aedee2013-01-10 17:10:40 +01001588 ALC260_FIXUP_FSC_S7020,
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001589 ALC260_FIXUP_FSC_S7020_JWSE,
Takashi Iwaid08c5ef2013-11-22 08:06:36 +01001590 ALC260_FIXUP_VAIO_PINS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02001591};
1592
Takashi Iwai20f7d922012-02-16 12:35:16 +01001593static void alc260_gpio1_automute(struct hda_codec *codec)
1594{
1595 struct alc_spec *spec = codec->spec;
Takashi Iwaiaaf312d2018-06-19 22:28:22 +02001596
1597 alc_update_gpio_data(codec, 0x01, spec->gen.hp_jack_present);
Takashi Iwai20f7d922012-02-16 12:35:16 +01001598}
1599
1600static void alc260_fixup_gpio1_toggle(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001601 const struct hda_fixup *fix, int action)
Takashi Iwai20f7d922012-02-16 12:35:16 +01001602{
1603 struct alc_spec *spec = codec->spec;
Takashi Iwai1727a772013-01-10 09:52:52 +01001604 if (action == HDA_FIXUP_ACT_PROBE) {
Takashi Iwai20f7d922012-02-16 12:35:16 +01001605 /* although the machine has only one output pin, we need to
1606 * toggle GPIO1 according to the jack state
1607 */
Takashi Iwai08c189f2012-12-19 15:22:24 +01001608 spec->gen.automute_hook = alc260_gpio1_automute;
1609 spec->gen.detect_hp = 1;
1610 spec->gen.automute_speaker = 1;
1611 spec->gen.autocfg.hp_pins[0] = 0x0f; /* copy it for automute */
Takashi Iwai62f949b2014-09-11 14:06:53 +02001612 snd_hda_jack_detect_enable_callback(codec, 0x0f,
Takashi Iwai08c189f2012-12-19 15:22:24 +01001613 snd_hda_gen_hp_automute);
Takashi Iwai5579cd62018-06-19 22:22:41 +02001614 alc_setup_gpio(codec, 0x01);
Takashi Iwai20f7d922012-02-16 12:35:16 +01001615 }
1616}
1617
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001618static void alc260_fixup_kn1(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001619 const struct hda_fixup *fix, int action)
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001620{
1621 struct alc_spec *spec = codec->spec;
Takashi Iwai1727a772013-01-10 09:52:52 +01001622 static const struct hda_pintbl pincfgs[] = {
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001623 { 0x0f, 0x02214000 }, /* HP/speaker */
1624 { 0x12, 0x90a60160 }, /* int mic */
1625 { 0x13, 0x02a19000 }, /* ext mic */
1626 { 0x18, 0x01446000 }, /* SPDIF out */
1627 /* disable bogus I/O pins */
1628 { 0x10, 0x411111f0 },
1629 { 0x11, 0x411111f0 },
1630 { 0x14, 0x411111f0 },
1631 { 0x15, 0x411111f0 },
1632 { 0x16, 0x411111f0 },
1633 { 0x17, 0x411111f0 },
1634 { 0x19, 0x411111f0 },
1635 { }
1636 };
1637
1638 switch (action) {
Takashi Iwai1727a772013-01-10 09:52:52 +01001639 case HDA_FIXUP_ACT_PRE_PROBE:
1640 snd_hda_apply_pincfgs(codec, pincfgs);
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001641 spec->init_amp = ALC_INIT_NONE;
1642 break;
1643 }
1644}
1645
Takashi Iwai39aedee2013-01-10 17:10:40 +01001646static void alc260_fixup_fsc_s7020(struct hda_codec *codec,
1647 const struct hda_fixup *fix, int action)
1648{
1649 struct alc_spec *spec = codec->spec;
Takashi Iwai1c76aa52018-06-21 16:37:54 +02001650 if (action == HDA_FIXUP_ACT_PRE_PROBE)
Takashi Iwaie6e0ee52013-02-18 17:04:20 +01001651 spec->init_amp = ALC_INIT_NONE;
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001652}
1653
1654static void alc260_fixup_fsc_s7020_jwse(struct hda_codec *codec,
1655 const struct hda_fixup *fix, int action)
1656{
1657 struct alc_spec *spec = codec->spec;
1658 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwaif811c3c2013-03-07 18:32:59 +01001659 spec->gen.add_jack_modes = 1;
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001660 spec->gen.hp_mic = 1;
Takashi Iwaie6e0ee52013-02-18 17:04:20 +01001661 }
Takashi Iwai39aedee2013-01-10 17:10:40 +01001662}
1663
Takashi Iwai1727a772013-01-10 09:52:52 +01001664static const struct hda_fixup alc260_fixups[] = {
Takashi Iwaica8f0422012-02-16 11:51:19 +01001665 [ALC260_FIXUP_HP_DC5750] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001666 .type = HDA_FIXUP_PINS,
1667 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02001668 { 0x11, 0x90130110 }, /* speaker */
1669 { }
1670 }
1671 },
Takashi Iwaica8f0422012-02-16 11:51:19 +01001672 [ALC260_FIXUP_HP_PIN_0F] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001673 .type = HDA_FIXUP_PINS,
1674 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaica8f0422012-02-16 11:51:19 +01001675 { 0x0f, 0x01214000 }, /* HP */
1676 { }
1677 }
1678 },
1679 [ALC260_FIXUP_COEF] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001680 .type = HDA_FIXUP_VERBS,
Takashi Iwaica8f0422012-02-16 11:51:19 +01001681 .v.verbs = (const struct hda_verb[]) {
Ronan Marquete30cf2d2014-06-01 18:38:53 +02001682 { 0x1a, AC_VERB_SET_COEF_INDEX, 0x07 },
1683 { 0x1a, AC_VERB_SET_PROC_COEF, 0x3040 },
Takashi Iwaica8f0422012-02-16 11:51:19 +01001684 { }
1685 },
Takashi Iwaica8f0422012-02-16 11:51:19 +01001686 },
Takashi Iwai15317ab2012-02-16 12:02:53 +01001687 [ALC260_FIXUP_GPIO1] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02001688 .type = HDA_FIXUP_FUNC,
1689 .v.func = alc_fixup_gpio1,
Takashi Iwai15317ab2012-02-16 12:02:53 +01001690 },
Takashi Iwai20f7d922012-02-16 12:35:16 +01001691 [ALC260_FIXUP_GPIO1_TOGGLE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001692 .type = HDA_FIXUP_FUNC,
Takashi Iwai20f7d922012-02-16 12:35:16 +01001693 .v.func = alc260_fixup_gpio1_toggle,
1694 .chained = true,
1695 .chain_id = ALC260_FIXUP_HP_PIN_0F,
1696 },
1697 [ALC260_FIXUP_REPLACER] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001698 .type = HDA_FIXUP_VERBS,
Takashi Iwai20f7d922012-02-16 12:35:16 +01001699 .v.verbs = (const struct hda_verb[]) {
Takashi Iwai192a98e2014-06-02 15:16:07 +02001700 { 0x1a, AC_VERB_SET_COEF_INDEX, 0x07 },
1701 { 0x1a, AC_VERB_SET_PROC_COEF, 0x3050 },
Takashi Iwai20f7d922012-02-16 12:35:16 +01001702 { }
1703 },
1704 .chained = true,
1705 .chain_id = ALC260_FIXUP_GPIO1_TOGGLE,
1706 },
Takashi Iwai0a1c4fa2012-02-16 12:42:30 +01001707 [ALC260_FIXUP_HP_B1900] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001708 .type = HDA_FIXUP_FUNC,
Takashi Iwai0a1c4fa2012-02-16 12:42:30 +01001709 .v.func = alc260_fixup_gpio1_toggle,
1710 .chained = true,
1711 .chain_id = ALC260_FIXUP_COEF,
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001712 },
1713 [ALC260_FIXUP_KN1] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001714 .type = HDA_FIXUP_FUNC,
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001715 .v.func = alc260_fixup_kn1,
1716 },
Takashi Iwai39aedee2013-01-10 17:10:40 +01001717 [ALC260_FIXUP_FSC_S7020] = {
1718 .type = HDA_FIXUP_FUNC,
1719 .v.func = alc260_fixup_fsc_s7020,
1720 },
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001721 [ALC260_FIXUP_FSC_S7020_JWSE] = {
1722 .type = HDA_FIXUP_FUNC,
1723 .v.func = alc260_fixup_fsc_s7020_jwse,
1724 .chained = true,
1725 .chain_id = ALC260_FIXUP_FSC_S7020,
1726 },
Takashi Iwaid08c5ef2013-11-22 08:06:36 +01001727 [ALC260_FIXUP_VAIO_PINS] = {
1728 .type = HDA_FIXUP_PINS,
1729 .v.pins = (const struct hda_pintbl[]) {
1730 /* Pin configs are missing completely on some VAIOs */
1731 { 0x0f, 0x01211020 },
1732 { 0x10, 0x0001003f },
1733 { 0x11, 0x411111f0 },
1734 { 0x12, 0x01a15930 },
1735 { 0x13, 0x411111f0 },
1736 { 0x14, 0x411111f0 },
1737 { 0x15, 0x411111f0 },
1738 { 0x16, 0x411111f0 },
1739 { 0x17, 0x411111f0 },
1740 { 0x18, 0x411111f0 },
1741 { 0x19, 0x411111f0 },
1742 { }
1743 }
1744 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02001745};
1746
1747static const struct snd_pci_quirk alc260_fixup_tbl[] = {
Takashi Iwai15317ab2012-02-16 12:02:53 +01001748 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_FIXUP_GPIO1),
Takashi Iwaica8f0422012-02-16 11:51:19 +01001749 SND_PCI_QUIRK(0x1025, 0x007f, "Acer Aspire 9500", ALC260_FIXUP_COEF),
Takashi Iwai15317ab2012-02-16 12:02:53 +01001750 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_FIXUP_GPIO1),
Takashi Iwaica8f0422012-02-16 11:51:19 +01001751 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", ALC260_FIXUP_HP_DC5750),
Takashi Iwai0a1c4fa2012-02-16 12:42:30 +01001752 SND_PCI_QUIRK(0x103c, 0x30ba, "HP Presario B1900", ALC260_FIXUP_HP_B1900),
Takashi Iwaid08c5ef2013-11-22 08:06:36 +01001753 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_FIXUP_VAIO_PINS),
Takashi Iwai0f5a5b82013-11-21 09:12:52 +01001754 SND_PCI_QUIRK(0x104d, 0x81e2, "Sony VAIO TX", ALC260_FIXUP_HP_PIN_0F),
Takashi Iwai39aedee2013-01-10 17:10:40 +01001755 SND_PCI_QUIRK(0x10cf, 0x1326, "FSC LifeBook S7020", ALC260_FIXUP_FSC_S7020),
Takashi Iwaib1f58082012-02-16 12:45:03 +01001756 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FIXUP_GPIO1),
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001757 SND_PCI_QUIRK(0x152d, 0x0729, "Quanta KN1", ALC260_FIXUP_KN1),
Takashi Iwai20f7d922012-02-16 12:35:16 +01001758 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_FIXUP_REPLACER),
Takashi Iwaica8f0422012-02-16 11:51:19 +01001759 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_FIXUP_COEF),
Takashi Iwai1d045db2011-07-07 18:23:21 +02001760 {}
1761};
1762
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001763static const struct hda_model_fixup alc260_fixup_models[] = {
1764 {.id = ALC260_FIXUP_GPIO1, .name = "gpio1"},
1765 {.id = ALC260_FIXUP_COEF, .name = "coef"},
1766 {.id = ALC260_FIXUP_FSC_S7020, .name = "fujitsu"},
1767 {.id = ALC260_FIXUP_FSC_S7020_JWSE, .name = "fujitsu-jwse"},
1768 {}
1769};
1770
Takashi Iwai1d045db2011-07-07 18:23:21 +02001771/*
1772 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02001773static int patch_alc260(struct hda_codec *codec)
1774{
1775 struct alc_spec *spec;
Takashi Iwaic3c2c9e2012-02-16 12:59:55 +01001776 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001777
Takashi Iwai3de95172012-05-07 18:03:15 +02001778 err = alc_alloc_spec(codec, 0x07);
1779 if (err < 0)
1780 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001781
Takashi Iwai3de95172012-05-07 18:03:15 +02001782 spec = codec->spec;
Takashi Iwaiea46c3c2013-01-15 18:45:53 +01001783 /* as quite a few machines require HP amp for speaker outputs,
1784 * it's easier to enable it unconditionally; even if it's unneeded,
1785 * it's almost harmless.
1786 */
1787 spec->gen.prefer_hp_amp = 1;
Takashi Iwai7504b6c2013-03-18 11:25:51 +01001788 spec->gen.beep_nid = 0x01;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001789
Takashi Iwai225068a2015-05-29 10:42:14 +02001790 spec->shutup = alc_eapd_shutup;
1791
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001792 snd_hda_pick_fixup(codec, alc260_fixup_models, alc260_fixup_tbl,
1793 alc260_fixups);
Takashi Iwai1727a772013-01-10 09:52:52 +01001794 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02001795
Takashi Iwaic3c2c9e2012-02-16 12:59:55 +01001796 /* automatic parse from the BIOS config */
1797 err = alc260_parse_auto_config(codec);
1798 if (err < 0)
1799 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001800
Takashi Iwaifea80fa2018-06-20 12:52:46 +02001801 if (!spec->gen.no_analog) {
1802 err = set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
1803 if (err < 0)
1804 goto error;
1805 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02001806
Takashi Iwai1727a772013-01-10 09:52:52 +01001807 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01001808
Takashi Iwai1d045db2011-07-07 18:23:21 +02001809 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02001810
1811 error:
1812 alc_free(codec);
1813 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001814}
1815
1816
1817/*
1818 * ALC882/883/885/888/889 support
1819 *
1820 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
1821 * configuration. Each pin widget can choose any input DACs and a mixer.
1822 * Each ADC is connected from a mixer of all inputs. This makes possible
1823 * 6-channel independent captures.
1824 *
1825 * In addition, an independent DAC for the multi-playback (not used in this
1826 * driver yet).
1827 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02001828
1829/*
1830 * Pin config fixes
1831 */
1832enum {
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01001833 ALC882_FIXUP_ABIT_AW9D_MAX,
1834 ALC882_FIXUP_LENOVO_Y530,
1835 ALC882_FIXUP_PB_M5210,
1836 ALC882_FIXUP_ACER_ASPIRE_7736,
1837 ALC882_FIXUP_ASUS_W90V,
Marton Balint8f239212012-03-05 21:33:23 +01001838 ALC889_FIXUP_CD,
David Henningssonb2c53e22014-01-01 14:01:34 +01001839 ALC889_FIXUP_FRONT_HP_NO_PRESENCE,
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01001840 ALC889_FIXUP_VAIO_TT,
Takashi Iwai0e7cc2e2011-11-09 12:42:48 +01001841 ALC888_FIXUP_EEE1601,
Takashi Iwai177943a2011-11-09 12:55:18 +01001842 ALC882_FIXUP_EAPD,
Takashi Iwai7a6069b2011-11-09 15:22:01 +01001843 ALC883_FIXUP_EAPD,
Takashi Iwai8812c4f2011-11-09 17:39:15 +01001844 ALC883_FIXUP_ACER_EAPD,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001845 ALC882_FIXUP_GPIO1,
1846 ALC882_FIXUP_GPIO2,
Takashi Iwaieb844d52011-11-09 18:03:07 +01001847 ALC882_FIXUP_GPIO3,
Takashi Iwai68ef0562011-11-09 18:24:44 +01001848 ALC889_FIXUP_COEF,
1849 ALC882_FIXUP_ASUS_W2JC,
Takashi Iwaic3e837b2011-11-10 16:01:47 +01001850 ALC882_FIXUP_ACER_ASPIRE_4930G,
1851 ALC882_FIXUP_ACER_ASPIRE_8930G,
1852 ALC882_FIXUP_ASPIRE_8930G_VERBS,
Takashi Iwai56710872011-11-14 17:42:11 +01001853 ALC885_FIXUP_MACPRO_GPIO,
Takashi Iwai02a237b2012-02-13 15:25:07 +01001854 ALC889_FIXUP_DAC_ROUTE,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001855 ALC889_FIXUP_MBP_VREF,
1856 ALC889_FIXUP_IMAC91_VREF,
Adrien Vergée7729a42014-01-24 14:56:14 -05001857 ALC889_FIXUP_MBA11_VREF,
Takashi Iwai0756f092013-12-04 13:59:45 +01001858 ALC889_FIXUP_MBA21_VREF,
Takashi Iwaic20f31e2014-02-03 11:02:10 +01001859 ALC889_FIXUP_MP11_VREF,
Mario Kleiner9f660a12015-12-22 00:45:43 +01001860 ALC889_FIXUP_MP41_VREF,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02001861 ALC882_FIXUP_INV_DMIC,
Takashi Iwaie427c232012-07-29 10:04:08 +02001862 ALC882_FIXUP_NO_PRIMARY_HP,
Takashi Iwai1f0bbf02013-11-28 15:21:21 +01001863 ALC887_FIXUP_ASUS_BASS,
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01001864 ALC887_FIXUP_BASS_CHMAP,
Takashi Iwai7beb3a62017-04-10 18:05:52 +02001865 ALC1220_FIXUP_GB_DUAL_CODECS,
Peisen0202f5c2017-10-26 10:35:36 +08001866 ALC1220_FIXUP_CLEVO_P950,
Richard Sailer80690a22019-04-02 15:52:04 +02001867 ALC1220_FIXUP_CLEVO_PB51ED,
1868 ALC1220_FIXUP_CLEVO_PB51ED_PINS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02001869};
1870
Takashi Iwai68ef0562011-11-09 18:24:44 +01001871static void alc889_fixup_coef(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001872 const struct hda_fixup *fix, int action)
Takashi Iwai68ef0562011-11-09 18:24:44 +01001873{
Takashi Iwai1727a772013-01-10 09:52:52 +01001874 if (action != HDA_FIXUP_ACT_INIT)
Takashi Iwai68ef0562011-11-09 18:24:44 +01001875 return;
Kailang Yang1df88742014-10-29 16:10:13 +08001876 alc_update_coef_idx(codec, 7, 0, 0x2030);
Takashi Iwai68ef0562011-11-09 18:24:44 +01001877}
1878
Takashi Iwai56710872011-11-14 17:42:11 +01001879/* set up GPIO at initialization */
1880static void alc885_fixup_macpro_gpio(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001881 const struct hda_fixup *fix, int action)
Takashi Iwai56710872011-11-14 17:42:11 +01001882{
Takashi Iwai215c8502018-06-19 22:34:26 +02001883 struct alc_spec *spec = codec->spec;
1884
1885 spec->gpio_write_delay = true;
1886 alc_fixup_gpio3(codec, fix, action);
Takashi Iwai56710872011-11-14 17:42:11 +01001887}
1888
Takashi Iwai02a237b2012-02-13 15:25:07 +01001889/* Fix the connection of some pins for ALC889:
1890 * At least, Acer Aspire 5935 shows the connections to DAC3/4 don't
1891 * work correctly (bko#42740)
1892 */
1893static void alc889_fixup_dac_route(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001894 const struct hda_fixup *fix, int action)
Takashi Iwai02a237b2012-02-13 15:25:07 +01001895{
Takashi Iwai1727a772013-01-10 09:52:52 +01001896 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwaief8d60f2012-02-17 10:12:38 +01001897 /* fake the connections during parsing the tree */
Takashi Iwai02a237b2012-02-13 15:25:07 +01001898 hda_nid_t conn1[2] = { 0x0c, 0x0d };
1899 hda_nid_t conn2[2] = { 0x0e, 0x0f };
1900 snd_hda_override_conn_list(codec, 0x14, 2, conn1);
1901 snd_hda_override_conn_list(codec, 0x15, 2, conn1);
1902 snd_hda_override_conn_list(codec, 0x18, 2, conn2);
1903 snd_hda_override_conn_list(codec, 0x1a, 2, conn2);
Takashi Iwai1727a772013-01-10 09:52:52 +01001904 } else if (action == HDA_FIXUP_ACT_PROBE) {
Takashi Iwaief8d60f2012-02-17 10:12:38 +01001905 /* restore the connections */
1906 hda_nid_t conn[5] = { 0x0c, 0x0d, 0x0e, 0x0f, 0x26 };
1907 snd_hda_override_conn_list(codec, 0x14, 5, conn);
1908 snd_hda_override_conn_list(codec, 0x15, 5, conn);
1909 snd_hda_override_conn_list(codec, 0x18, 5, conn);
1910 snd_hda_override_conn_list(codec, 0x1a, 5, conn);
Takashi Iwai02a237b2012-02-13 15:25:07 +01001911 }
1912}
1913
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001914/* Set VREF on HP pin */
1915static void alc889_fixup_mbp_vref(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001916 const struct hda_fixup *fix, int action)
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001917{
1918 struct alc_spec *spec = codec->spec;
Mario Kleiner9f660a12015-12-22 00:45:43 +01001919 static hda_nid_t nids[3] = { 0x14, 0x15, 0x19 };
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001920 int i;
1921
Takashi Iwai1727a772013-01-10 09:52:52 +01001922 if (action != HDA_FIXUP_ACT_INIT)
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001923 return;
1924 for (i = 0; i < ARRAY_SIZE(nids); i++) {
1925 unsigned int val = snd_hda_codec_get_pincfg(codec, nids[i]);
1926 if (get_defcfg_device(val) != AC_JACK_HP_OUT)
1927 continue;
Takashi Iwaid3f02d62013-01-10 10:12:22 +01001928 val = snd_hda_codec_get_pin_target(codec, nids[i]);
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001929 val |= AC_PINCTL_VREF_80;
Takashi Iwaicdd03ce2012-04-20 12:34:50 +02001930 snd_hda_set_pin_ctl(codec, nids[i], val);
Takashi Iwai08c189f2012-12-19 15:22:24 +01001931 spec->gen.keep_vref_in_automute = 1;
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001932 break;
1933 }
1934}
1935
Takashi Iwai0756f092013-12-04 13:59:45 +01001936static void alc889_fixup_mac_pins(struct hda_codec *codec,
1937 const hda_nid_t *nids, int num_nids)
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001938{
1939 struct alc_spec *spec = codec->spec;
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001940 int i;
1941
Takashi Iwai0756f092013-12-04 13:59:45 +01001942 for (i = 0; i < num_nids; i++) {
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001943 unsigned int val;
Takashi Iwaid3f02d62013-01-10 10:12:22 +01001944 val = snd_hda_codec_get_pin_target(codec, nids[i]);
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001945 val |= AC_PINCTL_VREF_50;
Takashi Iwaicdd03ce2012-04-20 12:34:50 +02001946 snd_hda_set_pin_ctl(codec, nids[i], val);
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001947 }
Takashi Iwai08c189f2012-12-19 15:22:24 +01001948 spec->gen.keep_vref_in_automute = 1;
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001949}
1950
Takashi Iwai0756f092013-12-04 13:59:45 +01001951/* Set VREF on speaker pins on imac91 */
1952static void alc889_fixup_imac91_vref(struct hda_codec *codec,
1953 const struct hda_fixup *fix, int action)
1954{
1955 static hda_nid_t nids[2] = { 0x18, 0x1a };
1956
1957 if (action == HDA_FIXUP_ACT_INIT)
1958 alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
1959}
1960
Adrien Vergée7729a42014-01-24 14:56:14 -05001961/* Set VREF on speaker pins on mba11 */
1962static void alc889_fixup_mba11_vref(struct hda_codec *codec,
1963 const struct hda_fixup *fix, int action)
1964{
1965 static hda_nid_t nids[1] = { 0x18 };
1966
1967 if (action == HDA_FIXUP_ACT_INIT)
1968 alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
1969}
1970
Takashi Iwai0756f092013-12-04 13:59:45 +01001971/* Set VREF on speaker pins on mba21 */
1972static void alc889_fixup_mba21_vref(struct hda_codec *codec,
1973 const struct hda_fixup *fix, int action)
1974{
1975 static hda_nid_t nids[2] = { 0x18, 0x19 };
1976
1977 if (action == HDA_FIXUP_ACT_INIT)
1978 alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
1979}
1980
Takashi Iwaie427c232012-07-29 10:04:08 +02001981/* Don't take HP output as primary
Fernando Luis Vázquez Caod9111492013-02-12 16:49:46 +09001982 * Strangely, the speaker output doesn't work on Vaio Z and some Vaio
1983 * all-in-one desktop PCs (for example VGC-LN51JGB) through DAC 0x05
Takashi Iwaie427c232012-07-29 10:04:08 +02001984 */
1985static void alc882_fixup_no_primary_hp(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001986 const struct hda_fixup *fix, int action)
Takashi Iwaie427c232012-07-29 10:04:08 +02001987{
1988 struct alc_spec *spec = codec->spec;
Takashi Iwaida96fb52013-07-29 16:54:36 +02001989 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai08c189f2012-12-19 15:22:24 +01001990 spec->gen.no_primary_hp = 1;
Takashi Iwaida96fb52013-07-29 16:54:36 +02001991 spec->gen.no_multi_io = 1;
1992 }
Takashi Iwaie427c232012-07-29 10:04:08 +02001993}
1994
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01001995static void alc_fixup_bass_chmap(struct hda_codec *codec,
1996 const struct hda_fixup *fix, int action);
1997
Takashi Iwai7beb3a62017-04-10 18:05:52 +02001998/* For dual-codec configuration, we need to disable some features to avoid
1999 * conflicts of kctls and PCM streams
2000 */
2001static void alc_fixup_dual_codecs(struct hda_codec *codec,
2002 const struct hda_fixup *fix, int action)
2003{
2004 struct alc_spec *spec = codec->spec;
2005
2006 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2007 return;
2008 /* disable vmaster */
2009 spec->gen.suppress_vmaster = 1;
2010 /* auto-mute and auto-mic switch don't work with multiple codecs */
2011 spec->gen.suppress_auto_mute = 1;
2012 spec->gen.suppress_auto_mic = 1;
2013 /* disable aamix as well */
2014 spec->gen.mixer_nid = 0;
2015 /* add location prefix to avoid conflicts */
2016 codec->force_pin_prefix = 1;
2017}
2018
2019static void rename_ctl(struct hda_codec *codec, const char *oldname,
2020 const char *newname)
2021{
2022 struct snd_kcontrol *kctl;
2023
2024 kctl = snd_hda_find_mixer_ctl(codec, oldname);
2025 if (kctl)
2026 strcpy(kctl->id.name, newname);
2027}
2028
2029static void alc1220_fixup_gb_dual_codecs(struct hda_codec *codec,
2030 const struct hda_fixup *fix,
2031 int action)
2032{
2033 alc_fixup_dual_codecs(codec, fix, action);
2034 switch (action) {
2035 case HDA_FIXUP_ACT_PRE_PROBE:
2036 /* override card longname to provide a unique UCM profile */
2037 strcpy(codec->card->longname, "HDAudio-Gigabyte-ALC1220DualCodecs");
2038 break;
2039 case HDA_FIXUP_ACT_BUILD:
2040 /* rename Capture controls depending on the codec */
2041 rename_ctl(codec, "Capture Volume",
2042 codec->addr == 0 ?
2043 "Rear-Panel Capture Volume" :
2044 "Front-Panel Capture Volume");
2045 rename_ctl(codec, "Capture Switch",
2046 codec->addr == 0 ?
2047 "Rear-Panel Capture Switch" :
2048 "Front-Panel Capture Switch");
2049 break;
2050 }
2051}
2052
Peisen0202f5c2017-10-26 10:35:36 +08002053static void alc1220_fixup_clevo_p950(struct hda_codec *codec,
2054 const struct hda_fixup *fix,
2055 int action)
2056{
2057 hda_nid_t conn1[1] = { 0x0c };
2058
2059 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2060 return;
2061
2062 alc_update_coef_idx(codec, 0x7, 0, 0x3c3);
2063 /* We therefore want to make sure 0x14 (front headphone) and
2064 * 0x1b (speakers) use the stereo DAC 0x02
2065 */
2066 snd_hda_override_conn_list(codec, 0x14, 1, conn1);
2067 snd_hda_override_conn_list(codec, 0x1b, 1, conn1);
2068}
2069
Jeremy Soller7f665b12019-02-13 10:56:19 -07002070static void alc_fixup_headset_mode_no_hp_mic(struct hda_codec *codec,
2071 const struct hda_fixup *fix, int action);
2072
Richard Sailer80690a22019-04-02 15:52:04 +02002073static void alc1220_fixup_clevo_pb51ed(struct hda_codec *codec,
Jeremy Soller7f665b12019-02-13 10:56:19 -07002074 const struct hda_fixup *fix,
2075 int action)
2076{
2077 alc1220_fixup_clevo_p950(codec, fix, action);
2078 alc_fixup_headset_mode_no_hp_mic(codec, fix, action);
2079}
2080
Takashi Iwai1727a772013-01-10 09:52:52 +01002081static const struct hda_fixup alc882_fixups[] = {
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002082 [ALC882_FIXUP_ABIT_AW9D_MAX] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002083 .type = HDA_FIXUP_PINS,
2084 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002085 { 0x15, 0x01080104 }, /* side */
2086 { 0x16, 0x01011012 }, /* rear */
2087 { 0x17, 0x01016011 }, /* clfe */
2088 { }
2089 }
2090 },
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002091 [ALC882_FIXUP_LENOVO_Y530] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002092 .type = HDA_FIXUP_PINS,
2093 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002094 { 0x15, 0x99130112 }, /* rear int speakers */
2095 { 0x16, 0x99130111 }, /* subwoofer */
2096 { }
2097 }
2098 },
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002099 [ALC882_FIXUP_PB_M5210] = {
Takashi Iwaifd108212013-01-10 10:18:14 +01002100 .type = HDA_FIXUP_PINCTLS,
2101 .v.pins = (const struct hda_pintbl[]) {
2102 { 0x19, PIN_VREF50 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02002103 {}
2104 }
2105 },
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002106 [ALC882_FIXUP_ACER_ASPIRE_7736] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002107 .type = HDA_FIXUP_FUNC,
Takashi Iwai23d30f22012-05-07 17:17:32 +02002108 .v.func = alc_fixup_sku_ignore,
Takashi Iwai1d045db2011-07-07 18:23:21 +02002109 },
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002110 [ALC882_FIXUP_ASUS_W90V] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002111 .type = HDA_FIXUP_PINS,
2112 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai5cdf7452011-10-26 23:04:08 +02002113 { 0x16, 0x99130110 }, /* fix sequence for CLFE */
2114 { }
2115 }
2116 },
Marton Balint8f239212012-03-05 21:33:23 +01002117 [ALC889_FIXUP_CD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002118 .type = HDA_FIXUP_PINS,
2119 .v.pins = (const struct hda_pintbl[]) {
Marton Balint8f239212012-03-05 21:33:23 +01002120 { 0x1c, 0x993301f0 }, /* CD */
2121 { }
2122 }
2123 },
David Henningssonb2c53e22014-01-01 14:01:34 +01002124 [ALC889_FIXUP_FRONT_HP_NO_PRESENCE] = {
2125 .type = HDA_FIXUP_PINS,
2126 .v.pins = (const struct hda_pintbl[]) {
2127 { 0x1b, 0x02214120 }, /* Front HP jack is flaky, disable jack detect */
2128 { }
2129 },
2130 .chained = true,
2131 .chain_id = ALC889_FIXUP_CD,
2132 },
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002133 [ALC889_FIXUP_VAIO_TT] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002134 .type = HDA_FIXUP_PINS,
2135 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002136 { 0x17, 0x90170111 }, /* hidden surround speaker */
2137 { }
2138 }
2139 },
Takashi Iwai0e7cc2e2011-11-09 12:42:48 +01002140 [ALC888_FIXUP_EEE1601] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002141 .type = HDA_FIXUP_VERBS,
Takashi Iwai0e7cc2e2011-11-09 12:42:48 +01002142 .v.verbs = (const struct hda_verb[]) {
2143 { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b },
2144 { 0x20, AC_VERB_SET_PROC_COEF, 0x0838 },
2145 { }
2146 }
Takashi Iwai177943a2011-11-09 12:55:18 +01002147 },
2148 [ALC882_FIXUP_EAPD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002149 .type = HDA_FIXUP_VERBS,
Takashi Iwai177943a2011-11-09 12:55:18 +01002150 .v.verbs = (const struct hda_verb[]) {
2151 /* change to EAPD mode */
2152 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2153 { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
2154 { }
2155 }
2156 },
Takashi Iwai7a6069b2011-11-09 15:22:01 +01002157 [ALC883_FIXUP_EAPD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002158 .type = HDA_FIXUP_VERBS,
Takashi Iwai7a6069b2011-11-09 15:22:01 +01002159 .v.verbs = (const struct hda_verb[]) {
2160 /* change to EAPD mode */
2161 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2162 { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
2163 { }
2164 }
2165 },
Takashi Iwai8812c4f2011-11-09 17:39:15 +01002166 [ALC883_FIXUP_ACER_EAPD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002167 .type = HDA_FIXUP_VERBS,
Takashi Iwai8812c4f2011-11-09 17:39:15 +01002168 .v.verbs = (const struct hda_verb[]) {
2169 /* eanable EAPD on Acer laptops */
2170 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2171 { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
2172 { }
2173 }
2174 },
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002175 [ALC882_FIXUP_GPIO1] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02002176 .type = HDA_FIXUP_FUNC,
2177 .v.func = alc_fixup_gpio1,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002178 },
2179 [ALC882_FIXUP_GPIO2] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02002180 .type = HDA_FIXUP_FUNC,
2181 .v.func = alc_fixup_gpio2,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002182 },
Takashi Iwaieb844d52011-11-09 18:03:07 +01002183 [ALC882_FIXUP_GPIO3] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02002184 .type = HDA_FIXUP_FUNC,
2185 .v.func = alc_fixup_gpio3,
Takashi Iwaieb844d52011-11-09 18:03:07 +01002186 },
Takashi Iwai68ef0562011-11-09 18:24:44 +01002187 [ALC882_FIXUP_ASUS_W2JC] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02002188 .type = HDA_FIXUP_FUNC,
2189 .v.func = alc_fixup_gpio1,
Takashi Iwai68ef0562011-11-09 18:24:44 +01002190 .chained = true,
2191 .chain_id = ALC882_FIXUP_EAPD,
2192 },
2193 [ALC889_FIXUP_COEF] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002194 .type = HDA_FIXUP_FUNC,
Takashi Iwai68ef0562011-11-09 18:24:44 +01002195 .v.func = alc889_fixup_coef,
2196 },
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002197 [ALC882_FIXUP_ACER_ASPIRE_4930G] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002198 .type = HDA_FIXUP_PINS,
2199 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002200 { 0x16, 0x99130111 }, /* CLFE speaker */
2201 { 0x17, 0x99130112 }, /* surround speaker */
2202 { }
Takashi Iwai038d4fe2012-04-11 17:18:12 +02002203 },
2204 .chained = true,
2205 .chain_id = ALC882_FIXUP_GPIO1,
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002206 },
2207 [ALC882_FIXUP_ACER_ASPIRE_8930G] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002208 .type = HDA_FIXUP_PINS,
2209 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002210 { 0x16, 0x99130111 }, /* CLFE speaker */
2211 { 0x1b, 0x99130112 }, /* surround speaker */
2212 { }
2213 },
2214 .chained = true,
2215 .chain_id = ALC882_FIXUP_ASPIRE_8930G_VERBS,
2216 },
2217 [ALC882_FIXUP_ASPIRE_8930G_VERBS] = {
2218 /* additional init verbs for Acer Aspire 8930G */
Takashi Iwai1727a772013-01-10 09:52:52 +01002219 .type = HDA_FIXUP_VERBS,
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002220 .v.verbs = (const struct hda_verb[]) {
2221 /* Enable all DACs */
2222 /* DAC DISABLE/MUTE 1? */
2223 /* setting bits 1-5 disables DAC nids 0x02-0x06
2224 * apparently. Init=0x38 */
2225 { 0x20, AC_VERB_SET_COEF_INDEX, 0x03 },
2226 { 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
2227 /* DAC DISABLE/MUTE 2? */
2228 /* some bit here disables the other DACs.
2229 * Init=0x4900 */
2230 { 0x20, AC_VERB_SET_COEF_INDEX, 0x08 },
2231 { 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
2232 /* DMIC fix
2233 * This laptop has a stereo digital microphone.
2234 * The mics are only 1cm apart which makes the stereo
2235 * useless. However, either the mic or the ALC889
2236 * makes the signal become a difference/sum signal
2237 * instead of standard stereo, which is annoying.
2238 * So instead we flip this bit which makes the
2239 * codec replicate the sum signal to both channels,
2240 * turning it into a normal mono mic.
2241 */
2242 /* DMIC_CONTROL? Init value = 0x0001 */
2243 { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b },
2244 { 0x20, AC_VERB_SET_PROC_COEF, 0x0003 },
2245 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2246 { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
2247 { }
Takashi Iwai038d4fe2012-04-11 17:18:12 +02002248 },
2249 .chained = true,
2250 .chain_id = ALC882_FIXUP_GPIO1,
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002251 },
Takashi Iwai56710872011-11-14 17:42:11 +01002252 [ALC885_FIXUP_MACPRO_GPIO] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002253 .type = HDA_FIXUP_FUNC,
Takashi Iwai56710872011-11-14 17:42:11 +01002254 .v.func = alc885_fixup_macpro_gpio,
2255 },
Takashi Iwai02a237b2012-02-13 15:25:07 +01002256 [ALC889_FIXUP_DAC_ROUTE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002257 .type = HDA_FIXUP_FUNC,
Takashi Iwai02a237b2012-02-13 15:25:07 +01002258 .v.func = alc889_fixup_dac_route,
2259 },
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002260 [ALC889_FIXUP_MBP_VREF] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002261 .type = HDA_FIXUP_FUNC,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002262 .v.func = alc889_fixup_mbp_vref,
2263 .chained = true,
2264 .chain_id = ALC882_FIXUP_GPIO1,
2265 },
2266 [ALC889_FIXUP_IMAC91_VREF] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002267 .type = HDA_FIXUP_FUNC,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002268 .v.func = alc889_fixup_imac91_vref,
2269 .chained = true,
2270 .chain_id = ALC882_FIXUP_GPIO1,
2271 },
Adrien Vergée7729a42014-01-24 14:56:14 -05002272 [ALC889_FIXUP_MBA11_VREF] = {
2273 .type = HDA_FIXUP_FUNC,
2274 .v.func = alc889_fixup_mba11_vref,
2275 .chained = true,
2276 .chain_id = ALC889_FIXUP_MBP_VREF,
2277 },
Takashi Iwai0756f092013-12-04 13:59:45 +01002278 [ALC889_FIXUP_MBA21_VREF] = {
2279 .type = HDA_FIXUP_FUNC,
2280 .v.func = alc889_fixup_mba21_vref,
2281 .chained = true,
2282 .chain_id = ALC889_FIXUP_MBP_VREF,
2283 },
Takashi Iwaic20f31e2014-02-03 11:02:10 +01002284 [ALC889_FIXUP_MP11_VREF] = {
2285 .type = HDA_FIXUP_FUNC,
2286 .v.func = alc889_fixup_mba11_vref,
2287 .chained = true,
2288 .chain_id = ALC885_FIXUP_MACPRO_GPIO,
2289 },
Mario Kleiner9f660a12015-12-22 00:45:43 +01002290 [ALC889_FIXUP_MP41_VREF] = {
2291 .type = HDA_FIXUP_FUNC,
2292 .v.func = alc889_fixup_mbp_vref,
2293 .chained = true,
2294 .chain_id = ALC885_FIXUP_MACPRO_GPIO,
2295 },
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002296 [ALC882_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002297 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02002298 .v.func = alc_fixup_inv_dmic,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002299 },
Takashi Iwaie427c232012-07-29 10:04:08 +02002300 [ALC882_FIXUP_NO_PRIMARY_HP] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002301 .type = HDA_FIXUP_FUNC,
Takashi Iwaie427c232012-07-29 10:04:08 +02002302 .v.func = alc882_fixup_no_primary_hp,
2303 },
Takashi Iwai1f0bbf02013-11-28 15:21:21 +01002304 [ALC887_FIXUP_ASUS_BASS] = {
2305 .type = HDA_FIXUP_PINS,
2306 .v.pins = (const struct hda_pintbl[]) {
2307 {0x16, 0x99130130}, /* bass speaker */
2308 {}
2309 },
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01002310 .chained = true,
2311 .chain_id = ALC887_FIXUP_BASS_CHMAP,
2312 },
2313 [ALC887_FIXUP_BASS_CHMAP] = {
2314 .type = HDA_FIXUP_FUNC,
2315 .v.func = alc_fixup_bass_chmap,
Takashi Iwai1f0bbf02013-11-28 15:21:21 +01002316 },
Takashi Iwai7beb3a62017-04-10 18:05:52 +02002317 [ALC1220_FIXUP_GB_DUAL_CODECS] = {
2318 .type = HDA_FIXUP_FUNC,
2319 .v.func = alc1220_fixup_gb_dual_codecs,
2320 },
Peisen0202f5c2017-10-26 10:35:36 +08002321 [ALC1220_FIXUP_CLEVO_P950] = {
2322 .type = HDA_FIXUP_FUNC,
2323 .v.func = alc1220_fixup_clevo_p950,
2324 },
Richard Sailer80690a22019-04-02 15:52:04 +02002325 [ALC1220_FIXUP_CLEVO_PB51ED] = {
Jeremy Soller7f665b12019-02-13 10:56:19 -07002326 .type = HDA_FIXUP_FUNC,
Richard Sailer80690a22019-04-02 15:52:04 +02002327 .v.func = alc1220_fixup_clevo_pb51ed,
Jeremy Soller7f665b12019-02-13 10:56:19 -07002328 },
Richard Sailer80690a22019-04-02 15:52:04 +02002329 [ALC1220_FIXUP_CLEVO_PB51ED_PINS] = {
Jeremy Soller7f665b12019-02-13 10:56:19 -07002330 .type = HDA_FIXUP_PINS,
2331 .v.pins = (const struct hda_pintbl[]) {
2332 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
2333 {}
2334 },
2335 .chained = true,
Richard Sailer80690a22019-04-02 15:52:04 +02002336 .chain_id = ALC1220_FIXUP_CLEVO_PB51ED,
Jeremy Soller7f665b12019-02-13 10:56:19 -07002337 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02002338};
2339
2340static const struct snd_pci_quirk alc882_fixup_tbl[] = {
Takashi Iwai8812c4f2011-11-09 17:39:15 +01002341 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_FIXUP_ACER_EAPD),
2342 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
Takashi Iwaib5d724b2015-06-02 19:57:08 +02002343 SND_PCI_QUIRK(0x1025, 0x0107, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
Takashi Iwai8812c4f2011-11-09 17:39:15 +01002344 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_FIXUP_ACER_EAPD),
2345 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
2346 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_FIXUP_ACER_EAPD),
2347 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_FIXUP_ACER_EAPD),
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002348 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
2349 ALC882_FIXUP_ACER_ASPIRE_4930G),
2350 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
2351 ALC882_FIXUP_ACER_ASPIRE_4930G),
2352 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
2353 ALC882_FIXUP_ACER_ASPIRE_8930G),
2354 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
2355 ALC882_FIXUP_ACER_ASPIRE_8930G),
2356 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
2357 ALC882_FIXUP_ACER_ASPIRE_4930G),
2358 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
2359 ALC882_FIXUP_ACER_ASPIRE_4930G),
2360 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
2361 ALC882_FIXUP_ACER_ASPIRE_4930G),
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002362 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", ALC882_FIXUP_PB_M5210),
Takashi Iwaif5c53d82012-05-07 10:07:33 +02002363 SND_PCI_QUIRK(0x1025, 0x021e, "Acer Aspire 5739G",
2364 ALC882_FIXUP_ACER_ASPIRE_4930G),
Takashi Iwai02a237b2012-02-13 15:25:07 +01002365 SND_PCI_QUIRK(0x1025, 0x0259, "Acer Aspire 5935", ALC889_FIXUP_DAC_ROUTE),
Takashi Iwaife97da12012-04-12 08:00:19 +02002366 SND_PCI_QUIRK(0x1025, 0x026b, "Acer Aspire 8940G", ALC882_FIXUP_ACER_ASPIRE_8930G),
Takashi Iwaiac9b1cd2011-11-09 17:45:55 +01002367 SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", ALC882_FIXUP_ACER_ASPIRE_7736),
Takashi Iwai177943a2011-11-09 12:55:18 +01002368 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_FIXUP_EAPD),
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002369 SND_PCI_QUIRK(0x1043, 0x1873, "ASUS W90V", ALC882_FIXUP_ASUS_W90V),
Takashi Iwai68ef0562011-11-09 18:24:44 +01002370 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_FIXUP_ASUS_W2JC),
Takashi Iwai0e7cc2e2011-11-09 12:42:48 +01002371 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_FIXUP_EEE1601),
Takashi Iwai1f0bbf02013-11-28 15:21:21 +01002372 SND_PCI_QUIRK(0x1043, 0x84bc, "ASUS ET2700", ALC887_FIXUP_ASUS_BASS),
Takashi Iwai85bcf962016-12-06 16:20:36 +01002373 SND_PCI_QUIRK(0x1043, 0x8691, "ASUS ROG Ranger VIII", ALC882_FIXUP_GPIO3),
Takashi Iwaiac9b1cd2011-11-09 17:45:55 +01002374 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT),
Takashi Iwaie427c232012-07-29 10:04:08 +02002375 SND_PCI_QUIRK(0x104d, 0x905a, "Sony Vaio Z", ALC882_FIXUP_NO_PRIMARY_HP),
Sergei A. Trusov3f3c3712017-08-02 20:23:48 +10002376 SND_PCI_QUIRK(0x104d, 0x9060, "Sony Vaio VPCL14M1R", ALC882_FIXUP_NO_PRIMARY_HP),
Fernando Luis Vázquez Cao12e31a72013-02-12 16:47:44 +09002377 SND_PCI_QUIRK(0x104d, 0x9043, "Sony Vaio VGC-LN51JGB", ALC882_FIXUP_NO_PRIMARY_HP),
Takashi Iwaic44d9b12016-02-07 09:38:26 +01002378 SND_PCI_QUIRK(0x104d, 0x9044, "Sony VAIO AiO", ALC882_FIXUP_NO_PRIMARY_HP),
Takashi Iwai56710872011-11-14 17:42:11 +01002379
2380 /* All Apple entries are in codec SSIDs */
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002381 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC889_FIXUP_MBP_VREF),
2382 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC889_FIXUP_MBP_VREF),
2383 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF),
Takashi Iwaic20f31e2014-02-03 11:02:10 +01002384 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC889_FIXUP_MP11_VREF),
Takashi Iwai56710872011-11-14 17:42:11 +01002385 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_FIXUP_MACPRO_GPIO),
2386 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_FIXUP_MACPRO_GPIO),
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002387 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC889_FIXUP_MBP_VREF),
2388 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889_FIXUP_MBP_VREF),
Takashi Iwai56710872011-11-14 17:42:11 +01002389 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_FIXUP_EAPD),
Adrien Vergée7729a42014-01-24 14:56:14 -05002390 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC889_FIXUP_MBA11_VREF),
Takashi Iwai0756f092013-12-04 13:59:45 +01002391 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC889_FIXUP_MBA21_VREF),
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002392 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889_FIXUP_MBP_VREF),
2393 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF),
Takashi Iwai56710872011-11-14 17:42:11 +01002394 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_FIXUP_MACPRO_GPIO),
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002395 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC889_FIXUP_IMAC91_VREF),
2396 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC889_FIXUP_IMAC91_VREF),
2397 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC889_FIXUP_IMAC91_VREF),
Mario Kleiner9f660a12015-12-22 00:45:43 +01002398 SND_PCI_QUIRK(0x106b, 0x4200, "Mac Pro 4,1/5,1", ALC889_FIXUP_MP41_VREF),
Takashi Iwai05193632012-11-12 10:07:36 +01002399 SND_PCI_QUIRK(0x106b, 0x4300, "iMac 9,1", ALC889_FIXUP_IMAC91_VREF),
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002400 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC889_FIXUP_IMAC91_VREF),
2401 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC889_FIXUP_IMAC91_VREF),
Takashi Iwai649ccd02015-07-30 22:30:29 +02002402 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC889_FIXUP_MBA11_VREF),
Takashi Iwai56710872011-11-14 17:42:11 +01002403
Takashi Iwai7a6069b2011-11-09 15:22:01 +01002404 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC882_FIXUP_EAPD),
David Henningssonb2c53e22014-01-01 14:01:34 +01002405 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3/Z87X-UD3H", ALC889_FIXUP_FRONT_HP_NO_PRESENCE),
Takashi Iwai7beb3a62017-04-10 18:05:52 +02002406 SND_PCI_QUIRK(0x1458, 0xa0b8, "Gigabyte AZ370-Gaming", ALC1220_FIXUP_GB_DUAL_CODECS),
Takashi Iwaid2c3b142017-06-01 09:35:30 +02002407 SND_PCI_QUIRK(0x1462, 0x7350, "MSI-7350", ALC889_FIXUP_CD),
Takashi Iwai63691582017-05-22 16:32:46 +02002408 SND_PCI_QUIRK(0x1462, 0xda57, "MSI Z270-Gaming", ALC1220_FIXUP_GB_DUAL_CODECS),
Takashi Iwaid2c3b142017-06-01 09:35:30 +02002409 SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3),
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002410 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX),
Peisen0202f5c2017-10-26 10:35:36 +08002411 SND_PCI_QUIRK(0x1558, 0x9501, "Clevo P950HR", ALC1220_FIXUP_CLEVO_P950),
Takashi Iwaif3d737b2018-07-17 17:08:32 +02002412 SND_PCI_QUIRK(0x1558, 0x95e1, "Clevo P95xER", ALC1220_FIXUP_CLEVO_P950),
Jeremy Soller2f0d5202018-05-07 09:28:45 -06002413 SND_PCI_QUIRK(0x1558, 0x95e2, "Clevo P950ER", ALC1220_FIXUP_CLEVO_P950),
Richard Sailer80690a22019-04-02 15:52:04 +02002414 SND_PCI_QUIRK(0x1558, 0x96e1, "System76 Oryx Pro (oryp5)", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
2415 SND_PCI_QUIRK(0x1558, 0x97e1, "System76 Oryx Pro (oryp5)", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
2416 SND_PCI_QUIRK(0x1558, 0x65d1, "Tuxedo Book XC1509", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
Takashi Iwai7a6069b2011-11-09 15:22:01 +01002417 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD),
2418 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD),
Takashi Iwaiac9b1cd2011-11-09 17:45:55 +01002419 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", ALC882_FIXUP_LENOVO_Y530),
Takashi Iwai68ef0562011-11-09 18:24:44 +01002420 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_FIXUP_COEF),
Takashi Iwai1d045db2011-07-07 18:23:21 +02002421 {}
2422};
2423
Takashi Iwai1727a772013-01-10 09:52:52 +01002424static const struct hda_model_fixup alc882_fixup_models[] = {
Takashi Iwai772c2912018-06-26 17:17:53 +02002425 {.id = ALC882_FIXUP_ABIT_AW9D_MAX, .name = "abit-aw9d"},
2426 {.id = ALC882_FIXUP_LENOVO_Y530, .name = "lenovo-y530"},
2427 {.id = ALC882_FIXUP_ACER_ASPIRE_7736, .name = "acer-aspire-7736"},
2428 {.id = ALC882_FIXUP_ASUS_W90V, .name = "asus-w90v"},
2429 {.id = ALC889_FIXUP_CD, .name = "cd"},
2430 {.id = ALC889_FIXUP_FRONT_HP_NO_PRESENCE, .name = "no-front-hp"},
2431 {.id = ALC889_FIXUP_VAIO_TT, .name = "vaio-tt"},
2432 {.id = ALC888_FIXUP_EEE1601, .name = "eee1601"},
2433 {.id = ALC882_FIXUP_EAPD, .name = "alc882-eapd"},
2434 {.id = ALC883_FIXUP_EAPD, .name = "alc883-eapd"},
2435 {.id = ALC882_FIXUP_GPIO1, .name = "gpio1"},
2436 {.id = ALC882_FIXUP_GPIO2, .name = "gpio2"},
2437 {.id = ALC882_FIXUP_GPIO3, .name = "gpio3"},
2438 {.id = ALC889_FIXUP_COEF, .name = "alc889-coef"},
2439 {.id = ALC882_FIXUP_ASUS_W2JC, .name = "asus-w2jc"},
Takashi Iwai912093b2012-04-11 14:03:41 +02002440 {.id = ALC882_FIXUP_ACER_ASPIRE_4930G, .name = "acer-aspire-4930g"},
2441 {.id = ALC882_FIXUP_ACER_ASPIRE_8930G, .name = "acer-aspire-8930g"},
2442 {.id = ALC883_FIXUP_ACER_EAPD, .name = "acer-aspire"},
Takashi Iwai772c2912018-06-26 17:17:53 +02002443 {.id = ALC885_FIXUP_MACPRO_GPIO, .name = "macpro-gpio"},
2444 {.id = ALC889_FIXUP_DAC_ROUTE, .name = "dac-route"},
2445 {.id = ALC889_FIXUP_MBP_VREF, .name = "mbp-vref"},
2446 {.id = ALC889_FIXUP_IMAC91_VREF, .name = "imac91-vref"},
2447 {.id = ALC889_FIXUP_MBA11_VREF, .name = "mba11-vref"},
2448 {.id = ALC889_FIXUP_MBA21_VREF, .name = "mba21-vref"},
2449 {.id = ALC889_FIXUP_MP11_VREF, .name = "mp11-vref"},
2450 {.id = ALC889_FIXUP_MP41_VREF, .name = "mp41-vref"},
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002451 {.id = ALC882_FIXUP_INV_DMIC, .name = "inv-dmic"},
Takashi Iwaie427c232012-07-29 10:04:08 +02002452 {.id = ALC882_FIXUP_NO_PRIMARY_HP, .name = "no-primary-hp"},
Takashi Iwai772c2912018-06-26 17:17:53 +02002453 {.id = ALC887_FIXUP_ASUS_BASS, .name = "asus-bass"},
Takashi Iwaiba90d6a2017-05-22 16:38:47 +02002454 {.id = ALC1220_FIXUP_GB_DUAL_CODECS, .name = "dual-codecs"},
Takashi Iwai772c2912018-06-26 17:17:53 +02002455 {.id = ALC1220_FIXUP_CLEVO_P950, .name = "clevo-p950"},
Takashi Iwai912093b2012-04-11 14:03:41 +02002456 {}
2457};
2458
Takashi Iwai1d045db2011-07-07 18:23:21 +02002459/*
2460 * BIOS auto configuration
2461 */
2462/* almost identical with ALC880 parser... */
2463static int alc882_parse_auto_config(struct hda_codec *codec)
2464{
Takashi Iwai1d045db2011-07-07 18:23:21 +02002465 static const hda_nid_t alc882_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002466 static const hda_nid_t alc882_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2467 return alc_parse_auto_config(codec, alc882_ignore, alc882_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002468}
2469
Takashi Iwai1d045db2011-07-07 18:23:21 +02002470/*
2471 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002472static int patch_alc882(struct hda_codec *codec)
2473{
2474 struct alc_spec *spec;
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002475 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002476
Takashi Iwai3de95172012-05-07 18:03:15 +02002477 err = alc_alloc_spec(codec, 0x0b);
2478 if (err < 0)
2479 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002480
Takashi Iwai3de95172012-05-07 18:03:15 +02002481 spec = codec->spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002482
Takashi Iwai7639a062015-03-03 10:07:24 +01002483 switch (codec->core.vendor_id) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002484 case 0x10ec0882:
2485 case 0x10ec0885:
Takashi Iwaiacf08082014-09-02 07:21:56 +02002486 case 0x10ec0900:
Kailang Yanga535ad52017-01-16 16:59:26 +08002487 case 0x10ec1220:
Takashi Iwai1d045db2011-07-07 18:23:21 +02002488 break;
2489 default:
2490 /* ALC883 and variants */
2491 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
2492 break;
2493 }
2494
Takashi Iwai1727a772013-01-10 09:52:52 +01002495 snd_hda_pick_fixup(codec, alc882_fixup_models, alc882_fixup_tbl,
Takashi Iwai912093b2012-04-11 14:03:41 +02002496 alc882_fixups);
Takashi Iwai1727a772013-01-10 09:52:52 +01002497 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002498
2499 alc_auto_parse_customize_define(codec);
2500
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002501 if (has_cdefine_beep(codec))
2502 spec->gen.beep_nid = 0x01;
2503
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002504 /* automatic parse from the BIOS config */
2505 err = alc882_parse_auto_config(codec);
2506 if (err < 0)
2507 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002508
Takashi Iwaifea80fa2018-06-20 12:52:46 +02002509 if (!spec->gen.no_analog && spec->gen.beep_nid) {
2510 err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
2511 if (err < 0)
2512 goto error;
2513 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02002514
Takashi Iwai1727a772013-01-10 09:52:52 +01002515 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01002516
Takashi Iwai1d045db2011-07-07 18:23:21 +02002517 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02002518
2519 error:
2520 alc_free(codec);
2521 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002522}
2523
2524
2525/*
2526 * ALC262 support
2527 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002528static int alc262_parse_auto_config(struct hda_codec *codec)
2529{
Takashi Iwai1d045db2011-07-07 18:23:21 +02002530 static const hda_nid_t alc262_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002531 static const hda_nid_t alc262_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2532 return alc_parse_auto_config(codec, alc262_ignore, alc262_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002533}
2534
2535/*
2536 * Pin config fixes
2537 */
2538enum {
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002539 ALC262_FIXUP_FSC_H270,
Takashi Iwai7513e6d2013-01-18 15:41:34 +01002540 ALC262_FIXUP_FSC_S7110,
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002541 ALC262_FIXUP_HP_Z200,
2542 ALC262_FIXUP_TYAN,
Takashi Iwaic4701502011-11-07 14:20:07 +01002543 ALC262_FIXUP_LENOVO_3000,
Takashi Iwaib42590b2011-11-07 14:41:01 +01002544 ALC262_FIXUP_BENQ,
2545 ALC262_FIXUP_BENQ_T31,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002546 ALC262_FIXUP_INV_DMIC,
Mengdong Linb5c66112013-11-29 00:35:35 -05002547 ALC262_FIXUP_INTEL_BAYLEYBAY,
Takashi Iwai1d045db2011-07-07 18:23:21 +02002548};
2549
Takashi Iwai1727a772013-01-10 09:52:52 +01002550static const struct hda_fixup alc262_fixups[] = {
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002551 [ALC262_FIXUP_FSC_H270] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002552 .type = HDA_FIXUP_PINS,
2553 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002554 { 0x14, 0x99130110 }, /* speaker */
2555 { 0x15, 0x0221142f }, /* front HP */
2556 { 0x1b, 0x0121141f }, /* rear HP */
2557 { }
2558 }
2559 },
Takashi Iwai7513e6d2013-01-18 15:41:34 +01002560 [ALC262_FIXUP_FSC_S7110] = {
2561 .type = HDA_FIXUP_PINS,
2562 .v.pins = (const struct hda_pintbl[]) {
2563 { 0x15, 0x90170110 }, /* speaker */
2564 { }
2565 },
2566 .chained = true,
2567 .chain_id = ALC262_FIXUP_BENQ,
2568 },
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002569 [ALC262_FIXUP_HP_Z200] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002570 .type = HDA_FIXUP_PINS,
2571 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002572 { 0x16, 0x99130120 }, /* internal speaker */
2573 { }
2574 }
2575 },
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002576 [ALC262_FIXUP_TYAN] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002577 .type = HDA_FIXUP_PINS,
2578 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002579 { 0x14, 0x1993e1f0 }, /* int AUX */
2580 { }
2581 }
2582 },
Takashi Iwaic4701502011-11-07 14:20:07 +01002583 [ALC262_FIXUP_LENOVO_3000] = {
Takashi Iwaifd108212013-01-10 10:18:14 +01002584 .type = HDA_FIXUP_PINCTLS,
2585 .v.pins = (const struct hda_pintbl[]) {
2586 { 0x19, PIN_VREF50 },
Takashi Iwaib42590b2011-11-07 14:41:01 +01002587 {}
2588 },
2589 .chained = true,
2590 .chain_id = ALC262_FIXUP_BENQ,
2591 },
2592 [ALC262_FIXUP_BENQ] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002593 .type = HDA_FIXUP_VERBS,
Takashi Iwaib42590b2011-11-07 14:41:01 +01002594 .v.verbs = (const struct hda_verb[]) {
Takashi Iwaic4701502011-11-07 14:20:07 +01002595 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2596 { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
2597 {}
2598 }
2599 },
Takashi Iwaib42590b2011-11-07 14:41:01 +01002600 [ALC262_FIXUP_BENQ_T31] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002601 .type = HDA_FIXUP_VERBS,
Takashi Iwaib42590b2011-11-07 14:41:01 +01002602 .v.verbs = (const struct hda_verb[]) {
2603 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2604 { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
2605 {}
2606 }
2607 },
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002608 [ALC262_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002609 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02002610 .v.func = alc_fixup_inv_dmic,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002611 },
Mengdong Linb5c66112013-11-29 00:35:35 -05002612 [ALC262_FIXUP_INTEL_BAYLEYBAY] = {
2613 .type = HDA_FIXUP_FUNC,
2614 .v.func = alc_fixup_no_depop_delay,
2615 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02002616};
2617
2618static const struct snd_pci_quirk alc262_fixup_tbl[] = {
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002619 SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", ALC262_FIXUP_HP_Z200),
Takashi Iwai7513e6d2013-01-18 15:41:34 +01002620 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu Lifebook S7110", ALC262_FIXUP_FSC_S7110),
Takashi Iwai3dcd3be2011-11-07 14:59:40 +01002621 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FIXUP_BENQ),
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002622 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_FIXUP_TYAN),
Takashi Iwai275ec0c2018-06-22 12:17:45 +02002623 SND_PCI_QUIRK(0x1734, 0x1141, "FSC ESPRIMO U9210", ALC262_FIXUP_FSC_H270),
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002624 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", ALC262_FIXUP_FSC_H270),
Takashi Iwaic4701502011-11-07 14:20:07 +01002625 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000", ALC262_FIXUP_LENOVO_3000),
Takashi Iwaib42590b2011-11-07 14:41:01 +01002626 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_FIXUP_BENQ),
2627 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_FIXUP_BENQ_T31),
Mengdong Linb5c66112013-11-29 00:35:35 -05002628 SND_PCI_QUIRK(0x8086, 0x7270, "BayleyBay", ALC262_FIXUP_INTEL_BAYLEYBAY),
Takashi Iwai1d045db2011-07-07 18:23:21 +02002629 {}
2630};
2631
Takashi Iwai1727a772013-01-10 09:52:52 +01002632static const struct hda_model_fixup alc262_fixup_models[] = {
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002633 {.id = ALC262_FIXUP_INV_DMIC, .name = "inv-dmic"},
Takashi Iwaie43c44d2018-06-26 17:02:08 +02002634 {.id = ALC262_FIXUP_FSC_H270, .name = "fsc-h270"},
2635 {.id = ALC262_FIXUP_FSC_S7110, .name = "fsc-s7110"},
2636 {.id = ALC262_FIXUP_HP_Z200, .name = "hp-z200"},
2637 {.id = ALC262_FIXUP_TYAN, .name = "tyan"},
2638 {.id = ALC262_FIXUP_LENOVO_3000, .name = "lenovo-3000"},
2639 {.id = ALC262_FIXUP_BENQ, .name = "benq"},
2640 {.id = ALC262_FIXUP_BENQ_T31, .name = "benq-t31"},
2641 {.id = ALC262_FIXUP_INTEL_BAYLEYBAY, .name = "bayleybay"},
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002642 {}
2643};
Takashi Iwai1d045db2011-07-07 18:23:21 +02002644
Takashi Iwai1d045db2011-07-07 18:23:21 +02002645/*
2646 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002647static int patch_alc262(struct hda_codec *codec)
2648{
2649 struct alc_spec *spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002650 int err;
2651
Takashi Iwai3de95172012-05-07 18:03:15 +02002652 err = alc_alloc_spec(codec, 0x0b);
2653 if (err < 0)
2654 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002655
Takashi Iwai3de95172012-05-07 18:03:15 +02002656 spec = codec->spec;
Takashi Iwai08c189f2012-12-19 15:22:24 +01002657 spec->gen.shared_mic_vref_pin = 0x18;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002658
Takashi Iwai225068a2015-05-29 10:42:14 +02002659 spec->shutup = alc_eapd_shutup;
2660
Takashi Iwai1d045db2011-07-07 18:23:21 +02002661#if 0
2662 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
2663 * under-run
2664 */
Takashi Iwai98b24882014-08-18 13:47:50 +02002665 alc_update_coefex_idx(codec, 0x1a, 7, 0, 0x80);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002666#endif
Takashi Iwai1d045db2011-07-07 18:23:21 +02002667 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
2668
Takashi Iwai1727a772013-01-10 09:52:52 +01002669 snd_hda_pick_fixup(codec, alc262_fixup_models, alc262_fixup_tbl,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002670 alc262_fixups);
Takashi Iwai1727a772013-01-10 09:52:52 +01002671 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002672
Takashi Iwaiaf741c12012-05-07 18:09:48 +02002673 alc_auto_parse_customize_define(codec);
2674
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002675 if (has_cdefine_beep(codec))
2676 spec->gen.beep_nid = 0x01;
2677
Takashi Iwai42399f72011-11-07 17:18:44 +01002678 /* automatic parse from the BIOS config */
2679 err = alc262_parse_auto_config(codec);
2680 if (err < 0)
2681 goto error;
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002682
Takashi Iwaifea80fa2018-06-20 12:52:46 +02002683 if (!spec->gen.no_analog && spec->gen.beep_nid) {
2684 err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
2685 if (err < 0)
2686 goto error;
2687 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02002688
Takashi Iwai1727a772013-01-10 09:52:52 +01002689 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01002690
Takashi Iwai1d045db2011-07-07 18:23:21 +02002691 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02002692
2693 error:
2694 alc_free(codec);
2695 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002696}
2697
2698/*
2699 * ALC268
2700 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002701/* bind Beep switches of both NID 0x0f and 0x10 */
Takashi Iwaia7177772017-05-10 12:04:08 +02002702static int alc268_beep_switch_put(struct snd_kcontrol *kcontrol,
2703 struct snd_ctl_elem_value *ucontrol)
2704{
2705 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2706 unsigned long pval;
2707 int err;
2708
2709 mutex_lock(&codec->control_mutex);
2710 pval = kcontrol->private_value;
2711 kcontrol->private_value = (pval & ~0xff) | 0x0f;
2712 err = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
2713 if (err >= 0) {
2714 kcontrol->private_value = (pval & ~0xff) | 0x10;
2715 err = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
2716 }
2717 kcontrol->private_value = pval;
2718 mutex_unlock(&codec->control_mutex);
2719 return err;
2720}
Takashi Iwai1d045db2011-07-07 18:23:21 +02002721
2722static const struct snd_kcontrol_new alc268_beep_mixer[] = {
2723 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
Takashi Iwaia7177772017-05-10 12:04:08 +02002724 {
2725 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2726 .name = "Beep Playback Switch",
2727 .subdevice = HDA_SUBDEV_AMP_FLAG,
2728 .info = snd_hda_mixer_amp_switch_info,
2729 .get = snd_hda_mixer_amp_switch_get,
2730 .put = alc268_beep_switch_put,
2731 .private_value = HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT)
2732 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02002733};
2734
2735/* set PCBEEP vol = 0, mute connections */
2736static const struct hda_verb alc268_beep_init_verbs[] = {
2737 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2738 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2739 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2740 { }
2741};
2742
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002743enum {
2744 ALC268_FIXUP_INV_DMIC,
Takashi Iwaicb766402012-10-20 10:55:21 +02002745 ALC268_FIXUP_HP_EAPD,
Takashi Iwai24eff322013-11-04 18:21:08 +01002746 ALC268_FIXUP_SPDIF,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002747};
2748
Takashi Iwai1727a772013-01-10 09:52:52 +01002749static const struct hda_fixup alc268_fixups[] = {
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002750 [ALC268_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002751 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02002752 .v.func = alc_fixup_inv_dmic,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002753 },
Takashi Iwaicb766402012-10-20 10:55:21 +02002754 [ALC268_FIXUP_HP_EAPD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002755 .type = HDA_FIXUP_VERBS,
Takashi Iwaicb766402012-10-20 10:55:21 +02002756 .v.verbs = (const struct hda_verb[]) {
2757 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 0},
2758 {}
2759 }
2760 },
Takashi Iwai24eff322013-11-04 18:21:08 +01002761 [ALC268_FIXUP_SPDIF] = {
2762 .type = HDA_FIXUP_PINS,
2763 .v.pins = (const struct hda_pintbl[]) {
2764 { 0x1e, 0x014b1180 }, /* enable SPDIF out */
2765 {}
2766 }
2767 },
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002768};
2769
Takashi Iwai1727a772013-01-10 09:52:52 +01002770static const struct hda_model_fixup alc268_fixup_models[] = {
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002771 {.id = ALC268_FIXUP_INV_DMIC, .name = "inv-dmic"},
Takashi Iwaicb766402012-10-20 10:55:21 +02002772 {.id = ALC268_FIXUP_HP_EAPD, .name = "hp-eapd"},
Takashi Iwai03bf11c2018-06-26 16:56:41 +02002773 {.id = ALC268_FIXUP_SPDIF, .name = "spdif"},
Takashi Iwaicb766402012-10-20 10:55:21 +02002774 {}
2775};
2776
2777static const struct snd_pci_quirk alc268_fixup_tbl[] = {
Takashi Iwai24eff322013-11-04 18:21:08 +01002778 SND_PCI_QUIRK(0x1025, 0x0139, "Acer TravelMate 6293", ALC268_FIXUP_SPDIF),
David Henningssonfcd8f3b2013-01-28 05:45:47 +01002779 SND_PCI_QUIRK(0x1025, 0x015b, "Acer AOA 150 (ZG5)", ALC268_FIXUP_INV_DMIC),
Takashi Iwaicb766402012-10-20 10:55:21 +02002780 /* below is codec SSID since multiple Toshiba laptops have the
2781 * same PCI SSID 1179:ff00
2782 */
2783 SND_PCI_QUIRK(0x1179, 0xff06, "Toshiba P200", ALC268_FIXUP_HP_EAPD),
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002784 {}
2785};
2786
Takashi Iwai1d045db2011-07-07 18:23:21 +02002787/*
2788 * BIOS auto configuration
2789 */
2790static int alc268_parse_auto_config(struct hda_codec *codec)
2791{
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002792 static const hda_nid_t alc268_ssids[] = { 0x15, 0x1b, 0x14, 0 };
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002793 return alc_parse_auto_config(codec, NULL, alc268_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002794}
2795
Takashi Iwai1d045db2011-07-07 18:23:21 +02002796/*
2797 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002798static int patch_alc268(struct hda_codec *codec)
2799{
2800 struct alc_spec *spec;
Takashi Iwaia5cb4632018-06-20 12:50:11 +02002801 int i, err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002802
Takashi Iwai1d045db2011-07-07 18:23:21 +02002803 /* ALC268 has no aa-loopback mixer */
Takashi Iwai3de95172012-05-07 18:03:15 +02002804 err = alc_alloc_spec(codec, 0);
2805 if (err < 0)
2806 return err;
2807
2808 spec = codec->spec;
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002809 spec->gen.beep_nid = 0x01;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002810
Takashi Iwai225068a2015-05-29 10:42:14 +02002811 spec->shutup = alc_eapd_shutup;
2812
Takashi Iwai1727a772013-01-10 09:52:52 +01002813 snd_hda_pick_fixup(codec, alc268_fixup_models, alc268_fixup_tbl, alc268_fixups);
2814 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002815
Takashi Iwai6ebb8052011-08-16 15:15:40 +02002816 /* automatic parse from the BIOS config */
2817 err = alc268_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02002818 if (err < 0)
2819 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002820
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002821 if (err > 0 && !spec->gen.no_analog &&
2822 spec->gen.autocfg.speaker_pins[0] != 0x1d) {
Takashi Iwaia5cb4632018-06-20 12:50:11 +02002823 for (i = 0; i < ARRAY_SIZE(alc268_beep_mixer); i++) {
2824 if (!snd_hda_gen_add_kctl(&spec->gen, NULL,
2825 &alc268_beep_mixer[i])) {
2826 err = -ENOMEM;
2827 goto error;
2828 }
2829 }
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002830 snd_hda_add_verbs(codec, alc268_beep_init_verbs);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002831 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
2832 /* override the amp caps for beep generator */
2833 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
2834 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
2835 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
2836 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
2837 (0 << AC_AMPCAP_MUTE_SHIFT));
2838 }
2839
Takashi Iwai1727a772013-01-10 09:52:52 +01002840 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002841
Takashi Iwai1d045db2011-07-07 18:23:21 +02002842 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02002843
2844 error:
2845 alc_free(codec);
2846 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002847}
2848
2849/*
2850 * ALC269
2851 */
Takashi Iwai08c189f2012-12-19 15:22:24 +01002852
Takashi Iwai1d045db2011-07-07 18:23:21 +02002853static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002854 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002855};
2856
2857static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002858 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002859};
2860
Takashi Iwai1d045db2011-07-07 18:23:21 +02002861/* different alc269-variants */
2862enum {
2863 ALC269_TYPE_ALC269VA,
2864 ALC269_TYPE_ALC269VB,
2865 ALC269_TYPE_ALC269VC,
Kailang Yangadcc70b2012-05-25 08:08:38 +02002866 ALC269_TYPE_ALC269VD,
Kailang Yang065380f2013-01-10 10:25:48 +01002867 ALC269_TYPE_ALC280,
2868 ALC269_TYPE_ALC282,
Kailang Yang2af02be2013-08-22 10:03:50 +02002869 ALC269_TYPE_ALC283,
Kailang Yang065380f2013-01-10 10:25:48 +01002870 ALC269_TYPE_ALC284,
Kailang Yang4731d5d2017-06-30 15:22:57 +08002871 ALC269_TYPE_ALC293,
Kailang Yang7fc7d042013-04-25 11:04:43 +02002872 ALC269_TYPE_ALC286,
Kailang Yang506b62c2014-12-18 17:07:44 +08002873 ALC269_TYPE_ALC298,
Kailang Yang1d04c9d2013-10-24 11:35:18 +02002874 ALC269_TYPE_ALC255,
Kailang Yang4344aec2014-12-17 17:39:05 +08002875 ALC269_TYPE_ALC256,
Kailang Yangf429e7e2017-12-05 15:38:24 +08002876 ALC269_TYPE_ALC257,
Kailang Yang0a6f0602017-06-30 16:00:48 +08002877 ALC269_TYPE_ALC215,
Kailang Yang42314302016-02-03 15:03:50 +08002878 ALC269_TYPE_ALC225,
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08002879 ALC269_TYPE_ALC294,
Kailang Yang1078bef2018-11-08 16:36:15 +08002880 ALC269_TYPE_ALC300,
Kailang Yang6fbae352016-05-30 16:44:20 +08002881 ALC269_TYPE_ALC700,
Takashi Iwai1d045db2011-07-07 18:23:21 +02002882};
2883
2884/*
2885 * BIOS auto configuration
2886 */
2887static int alc269_parse_auto_config(struct hda_codec *codec)
2888{
Takashi Iwai1d045db2011-07-07 18:23:21 +02002889 static const hda_nid_t alc269_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002890 static const hda_nid_t alc269_ssids[] = { 0, 0x1b, 0x14, 0x21 };
2891 static const hda_nid_t alc269va_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2892 struct alc_spec *spec = codec->spec;
Kailang Yangadcc70b2012-05-25 08:08:38 +02002893 const hda_nid_t *ssids;
2894
2895 switch (spec->codec_variant) {
2896 case ALC269_TYPE_ALC269VA:
2897 case ALC269_TYPE_ALC269VC:
Kailang Yang065380f2013-01-10 10:25:48 +01002898 case ALC269_TYPE_ALC280:
2899 case ALC269_TYPE_ALC284:
Kailang Yang4731d5d2017-06-30 15:22:57 +08002900 case ALC269_TYPE_ALC293:
Kailang Yangadcc70b2012-05-25 08:08:38 +02002901 ssids = alc269va_ssids;
2902 break;
2903 case ALC269_TYPE_ALC269VB:
2904 case ALC269_TYPE_ALC269VD:
Kailang Yang065380f2013-01-10 10:25:48 +01002905 case ALC269_TYPE_ALC282:
Kailang Yang2af02be2013-08-22 10:03:50 +02002906 case ALC269_TYPE_ALC283:
Kailang Yang7fc7d042013-04-25 11:04:43 +02002907 case ALC269_TYPE_ALC286:
Kailang Yang506b62c2014-12-18 17:07:44 +08002908 case ALC269_TYPE_ALC298:
Kailang Yang1d04c9d2013-10-24 11:35:18 +02002909 case ALC269_TYPE_ALC255:
Kailang Yang4344aec2014-12-17 17:39:05 +08002910 case ALC269_TYPE_ALC256:
Kailang Yangf429e7e2017-12-05 15:38:24 +08002911 case ALC269_TYPE_ALC257:
Kailang Yang0a6f0602017-06-30 16:00:48 +08002912 case ALC269_TYPE_ALC215:
Kailang Yang42314302016-02-03 15:03:50 +08002913 case ALC269_TYPE_ALC225:
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08002914 case ALC269_TYPE_ALC294:
Kailang Yang1078bef2018-11-08 16:36:15 +08002915 case ALC269_TYPE_ALC300:
Kailang Yang6fbae352016-05-30 16:44:20 +08002916 case ALC269_TYPE_ALC700:
Kailang Yangadcc70b2012-05-25 08:08:38 +02002917 ssids = alc269_ssids;
2918 break;
2919 default:
2920 ssids = alc269_ssids;
2921 break;
2922 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02002923
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002924 return alc_parse_auto_config(codec, alc269_ignore, ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002925}
2926
Kailang Yangf7ae9ba2014-06-30 16:10:37 +08002927static int find_ext_mic_pin(struct hda_codec *codec);
2928
2929static void alc286_shutup(struct hda_codec *codec)
2930{
Takashi Iwaia9c2dfc2018-04-23 17:24:56 +02002931 const struct hda_pincfg *pin;
Kailang Yangf7ae9ba2014-06-30 16:10:37 +08002932 int i;
2933 int mic_pin = find_ext_mic_pin(codec);
2934 /* don't shut up pins when unloading the driver; otherwise it breaks
2935 * the default pin setup at the next load of the driver
2936 */
2937 if (codec->bus->shutdown)
2938 return;
Takashi Iwaia9c2dfc2018-04-23 17:24:56 +02002939 snd_array_for_each(&codec->init_pins, i, pin) {
Kailang Yangf7ae9ba2014-06-30 16:10:37 +08002940 /* use read here for syncing after issuing each verb */
2941 if (pin->nid != mic_pin)
2942 snd_hda_codec_read(codec, pin->nid, 0,
2943 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
2944 }
2945 codec->pins_shutup = 1;
2946}
2947
Kailang Yang1387e2d2012-11-08 10:23:18 +01002948static void alc269vb_toggle_power_output(struct hda_codec *codec, int power_up)
Takashi Iwai1d045db2011-07-07 18:23:21 +02002949{
Takashi Iwai98b24882014-08-18 13:47:50 +02002950 alc_update_coef_idx(codec, 0x04, 1 << 11, power_up ? (1 << 11) : 0);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002951}
2952
2953static void alc269_shutup(struct hda_codec *codec)
2954{
Kailang Yangadcc70b2012-05-25 08:08:38 +02002955 struct alc_spec *spec = codec->spec;
2956
Kailang Yang1387e2d2012-11-08 10:23:18 +01002957 if (spec->codec_variant == ALC269_TYPE_ALC269VB)
2958 alc269vb_toggle_power_output(codec, 0);
2959 if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
2960 (alc_get_coef0(codec) & 0x00ff) == 0x018) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002961 msleep(150);
2962 }
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01002963 alc_shutup_pins(codec);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002964}
2965
Takashi Iwai54db6c32014-08-18 15:11:19 +02002966static struct coef_fw alc282_coefs[] = {
2967 WRITE_COEF(0x03, 0x0002), /* Power Down Control */
Kailang Yang32fa7e42014-10-24 16:26:01 +08002968 UPDATE_COEF(0x05, 0xff3f, 0x0700), /* FIFO and filter clock */
Takashi Iwai54db6c32014-08-18 15:11:19 +02002969 WRITE_COEF(0x07, 0x0200), /* DMIC control */
2970 UPDATE_COEF(0x06, 0x00f0, 0), /* Analog clock */
2971 UPDATE_COEF(0x08, 0xfffc, 0x0c2c), /* JD */
2972 WRITE_COEF(0x0a, 0xcccc), /* JD offset1 */
2973 WRITE_COEF(0x0b, 0xcccc), /* JD offset2 */
2974 WRITE_COEF(0x0e, 0x6e00), /* LDO1/2/3, DAC/ADC */
2975 UPDATE_COEF(0x0f, 0xf800, 0x1000), /* JD */
2976 UPDATE_COEF(0x10, 0xfc00, 0x0c00), /* Capless */
2977 WRITE_COEF(0x6f, 0x0), /* Class D test 4 */
2978 UPDATE_COEF(0x0c, 0xfe00, 0), /* IO power down directly */
2979 WRITE_COEF(0x34, 0xa0c0), /* ANC */
2980 UPDATE_COEF(0x16, 0x0008, 0), /* AGC MUX */
2981 UPDATE_COEF(0x1d, 0x00e0, 0), /* DAC simple content protection */
2982 UPDATE_COEF(0x1f, 0x00e0, 0), /* ADC simple content protection */
2983 WRITE_COEF(0x21, 0x8804), /* DAC ADC Zero Detection */
2984 WRITE_COEF(0x63, 0x2902), /* PLL */
2985 WRITE_COEF(0x68, 0xa080), /* capless control 2 */
2986 WRITE_COEF(0x69, 0x3400), /* capless control 3 */
2987 WRITE_COEF(0x6a, 0x2f3e), /* capless control 4 */
2988 WRITE_COEF(0x6b, 0x0), /* capless control 5 */
2989 UPDATE_COEF(0x6d, 0x0fff, 0x0900), /* class D test 2 */
2990 WRITE_COEF(0x6e, 0x110a), /* class D test 3 */
2991 UPDATE_COEF(0x70, 0x00f8, 0x00d8), /* class D test 5 */
2992 WRITE_COEF(0x71, 0x0014), /* class D test 6 */
2993 WRITE_COEF(0x72, 0xc2ba), /* classD OCP */
2994 UPDATE_COEF(0x77, 0x0f80, 0), /* classD pure DC test */
2995 WRITE_COEF(0x6c, 0xfc06), /* Class D amp control */
2996 {}
2997};
2998
Kailang Yangcb149cb2014-03-18 16:45:32 +08002999static void alc282_restore_default_value(struct hda_codec *codec)
3000{
Takashi Iwai54db6c32014-08-18 15:11:19 +02003001 alc_process_coef_fw(codec, alc282_coefs);
Kailang Yangcb149cb2014-03-18 16:45:32 +08003002}
3003
Kailang Yang7b5c7a02014-03-18 16:15:54 +08003004static void alc282_init(struct hda_codec *codec)
3005{
3006 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003007 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang7b5c7a02014-03-18 16:15:54 +08003008 bool hp_pin_sense;
3009 int coef78;
3010
Kailang Yangcb149cb2014-03-18 16:45:32 +08003011 alc282_restore_default_value(codec);
3012
Kailang Yang7b5c7a02014-03-18 16:15:54 +08003013 if (!hp_pin)
3014 return;
3015 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3016 coef78 = alc_read_coef_idx(codec, 0x78);
3017
3018 /* Index 0x78 Direct Drive HP AMP LPM Control 1 */
3019 /* Headphone capless set to high power mode */
3020 alc_write_coef_idx(codec, 0x78, 0x9004);
3021
3022 if (hp_pin_sense)
3023 msleep(2);
3024
3025 snd_hda_codec_write(codec, hp_pin, 0,
3026 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3027
3028 if (hp_pin_sense)
3029 msleep(85);
3030
3031 snd_hda_codec_write(codec, hp_pin, 0,
3032 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3033
3034 if (hp_pin_sense)
3035 msleep(100);
3036
3037 /* Headphone capless set to normal mode */
3038 alc_write_coef_idx(codec, 0x78, coef78);
3039}
3040
3041static void alc282_shutup(struct hda_codec *codec)
3042{
3043 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003044 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang7b5c7a02014-03-18 16:15:54 +08003045 bool hp_pin_sense;
3046 int coef78;
3047
3048 if (!hp_pin) {
3049 alc269_shutup(codec);
3050 return;
3051 }
3052
3053 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3054 coef78 = alc_read_coef_idx(codec, 0x78);
3055 alc_write_coef_idx(codec, 0x78, 0x9004);
3056
3057 if (hp_pin_sense)
3058 msleep(2);
3059
3060 snd_hda_codec_write(codec, hp_pin, 0,
3061 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3062
3063 if (hp_pin_sense)
3064 msleep(85);
3065
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003066 if (!spec->no_shutup_pins)
3067 snd_hda_codec_write(codec, hp_pin, 0,
3068 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
Kailang Yang7b5c7a02014-03-18 16:15:54 +08003069
3070 if (hp_pin_sense)
3071 msleep(100);
3072
3073 alc_auto_setup_eapd(codec, false);
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003074 alc_shutup_pins(codec);
Kailang Yang7b5c7a02014-03-18 16:15:54 +08003075 alc_write_coef_idx(codec, 0x78, coef78);
3076}
3077
Takashi Iwai54db6c32014-08-18 15:11:19 +02003078static struct coef_fw alc283_coefs[] = {
3079 WRITE_COEF(0x03, 0x0002), /* Power Down Control */
Kailang Yang56779862014-10-24 16:17:51 +08003080 UPDATE_COEF(0x05, 0xff3f, 0x0700), /* FIFO and filter clock */
Takashi Iwai54db6c32014-08-18 15:11:19 +02003081 WRITE_COEF(0x07, 0x0200), /* DMIC control */
3082 UPDATE_COEF(0x06, 0x00f0, 0), /* Analog clock */
3083 UPDATE_COEF(0x08, 0xfffc, 0x0c2c), /* JD */
3084 WRITE_COEF(0x0a, 0xcccc), /* JD offset1 */
3085 WRITE_COEF(0x0b, 0xcccc), /* JD offset2 */
3086 WRITE_COEF(0x0e, 0x6fc0), /* LDO1/2/3, DAC/ADC */
3087 UPDATE_COEF(0x0f, 0xf800, 0x1000), /* JD */
3088 UPDATE_COEF(0x10, 0xfc00, 0x0c00), /* Capless */
3089 WRITE_COEF(0x3a, 0x0), /* Class D test 4 */
3090 UPDATE_COEF(0x0c, 0xfe00, 0x0), /* IO power down directly */
3091 WRITE_COEF(0x22, 0xa0c0), /* ANC */
3092 UPDATE_COEFEX(0x53, 0x01, 0x000f, 0x0008), /* AGC MUX */
3093 UPDATE_COEF(0x1d, 0x00e0, 0), /* DAC simple content protection */
3094 UPDATE_COEF(0x1f, 0x00e0, 0), /* ADC simple content protection */
3095 WRITE_COEF(0x21, 0x8804), /* DAC ADC Zero Detection */
3096 WRITE_COEF(0x2e, 0x2902), /* PLL */
3097 WRITE_COEF(0x33, 0xa080), /* capless control 2 */
3098 WRITE_COEF(0x34, 0x3400), /* capless control 3 */
3099 WRITE_COEF(0x35, 0x2f3e), /* capless control 4 */
3100 WRITE_COEF(0x36, 0x0), /* capless control 5 */
3101 UPDATE_COEF(0x38, 0x0fff, 0x0900), /* class D test 2 */
3102 WRITE_COEF(0x39, 0x110a), /* class D test 3 */
3103 UPDATE_COEF(0x3b, 0x00f8, 0x00d8), /* class D test 5 */
3104 WRITE_COEF(0x3c, 0x0014), /* class D test 6 */
3105 WRITE_COEF(0x3d, 0xc2ba), /* classD OCP */
3106 UPDATE_COEF(0x42, 0x0f80, 0x0), /* classD pure DC test */
3107 WRITE_COEF(0x49, 0x0), /* test mode */
3108 UPDATE_COEF(0x40, 0xf800, 0x9800), /* Class D DC enable */
3109 UPDATE_COEF(0x42, 0xf000, 0x2000), /* DC offset */
3110 WRITE_COEF(0x37, 0xfc06), /* Class D amp control */
Kailang Yang56779862014-10-24 16:17:51 +08003111 UPDATE_COEF(0x1b, 0x8000, 0), /* HP JD control */
Takashi Iwai54db6c32014-08-18 15:11:19 +02003112 {}
3113};
3114
Kailang Yang6bd55b02014-03-17 13:51:27 +08003115static void alc283_restore_default_value(struct hda_codec *codec)
3116{
Takashi Iwai54db6c32014-08-18 15:11:19 +02003117 alc_process_coef_fw(codec, alc283_coefs);
Kailang Yang6bd55b02014-03-17 13:51:27 +08003118}
3119
Kailang Yang2af02be2013-08-22 10:03:50 +02003120static void alc283_init(struct hda_codec *codec)
3121{
3122 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003123 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang2af02be2013-08-22 10:03:50 +02003124 bool hp_pin_sense;
Kailang Yang2af02be2013-08-22 10:03:50 +02003125
Kailang Yang6bd55b02014-03-17 13:51:27 +08003126 alc283_restore_default_value(codec);
3127
Kailang Yang2af02be2013-08-22 10:03:50 +02003128 if (!hp_pin)
3129 return;
Kailang Yanga59d7192015-04-08 16:34:00 +08003130
3131 msleep(30);
Kailang Yang2af02be2013-08-22 10:03:50 +02003132 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3133
3134 /* Index 0x43 Direct Drive HP AMP LPM Control 1 */
3135 /* Headphone capless set to high power mode */
3136 alc_write_coef_idx(codec, 0x43, 0x9004);
3137
3138 snd_hda_codec_write(codec, hp_pin, 0,
3139 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3140
3141 if (hp_pin_sense)
3142 msleep(85);
3143
3144 snd_hda_codec_write(codec, hp_pin, 0,
3145 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3146
3147 if (hp_pin_sense)
3148 msleep(85);
3149 /* Index 0x46 Combo jack auto switch control 2 */
3150 /* 3k pull low control for Headset jack. */
Takashi Iwai98b24882014-08-18 13:47:50 +02003151 alc_update_coef_idx(codec, 0x46, 3 << 12, 0);
Kailang Yang2af02be2013-08-22 10:03:50 +02003152 /* Headphone capless set to normal mode */
3153 alc_write_coef_idx(codec, 0x43, 0x9614);
3154}
3155
3156static void alc283_shutup(struct hda_codec *codec)
3157{
3158 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003159 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang2af02be2013-08-22 10:03:50 +02003160 bool hp_pin_sense;
Kailang Yang2af02be2013-08-22 10:03:50 +02003161
3162 if (!hp_pin) {
3163 alc269_shutup(codec);
3164 return;
3165 }
3166
3167 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3168
3169 alc_write_coef_idx(codec, 0x43, 0x9004);
3170
Harsha Priyab450b172014-10-09 11:04:56 +00003171 /*depop hp during suspend*/
3172 alc_write_coef_idx(codec, 0x06, 0x2100);
3173
Kailang Yang2af02be2013-08-22 10:03:50 +02003174 snd_hda_codec_write(codec, hp_pin, 0,
3175 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3176
3177 if (hp_pin_sense)
Kailang Yang88011c092013-10-24 15:45:24 +02003178 msleep(100);
Kailang Yang2af02be2013-08-22 10:03:50 +02003179
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003180 if (!spec->no_shutup_pins)
3181 snd_hda_codec_write(codec, hp_pin, 0,
3182 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
Kailang Yang2af02be2013-08-22 10:03:50 +02003183
Takashi Iwai98b24882014-08-18 13:47:50 +02003184 alc_update_coef_idx(codec, 0x46, 0, 3 << 12);
Kailang Yang2af02be2013-08-22 10:03:50 +02003185
3186 if (hp_pin_sense)
Kailang Yang88011c092013-10-24 15:45:24 +02003187 msleep(100);
Kailang Yang0435b3f2014-04-08 17:14:14 +08003188 alc_auto_setup_eapd(codec, false);
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003189 alc_shutup_pins(codec);
Kailang Yang2af02be2013-08-22 10:03:50 +02003190 alc_write_coef_idx(codec, 0x43, 0x9614);
3191}
3192
Kailang Yang4a219ef2017-06-16 16:54:35 +08003193static void alc256_init(struct hda_codec *codec)
3194{
3195 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003196 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang4a219ef2017-06-16 16:54:35 +08003197 bool hp_pin_sense;
3198
3199 if (!hp_pin)
3200 return;
3201
3202 msleep(30);
3203
3204 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3205
3206 if (hp_pin_sense)
3207 msleep(2);
3208
3209 alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */
3210
3211 snd_hda_codec_write(codec, hp_pin, 0,
3212 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3213
3214 if (hp_pin_sense)
3215 msleep(85);
3216
3217 snd_hda_codec_write(codec, hp_pin, 0,
3218 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3219
3220 if (hp_pin_sense)
3221 msleep(100);
3222
3223 alc_update_coef_idx(codec, 0x46, 3 << 12, 0);
3224 alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x4); /* Hight power */
Kailang Yang88d42b22018-03-14 16:08:57 +08003225 alc_update_coefex_idx(codec, 0x53, 0x02, 0x8000, 1 << 15); /* Clear bit */
3226 alc_update_coefex_idx(codec, 0x53, 0x02, 0x8000, 0 << 15);
Kailang Yang4a219ef2017-06-16 16:54:35 +08003227}
3228
3229static void alc256_shutup(struct hda_codec *codec)
3230{
3231 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003232 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang4a219ef2017-06-16 16:54:35 +08003233 bool hp_pin_sense;
3234
3235 if (!hp_pin) {
3236 alc269_shutup(codec);
3237 return;
3238 }
3239
3240 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3241
3242 if (hp_pin_sense)
3243 msleep(2);
3244
3245 snd_hda_codec_write(codec, hp_pin, 0,
3246 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3247
3248 if (hp_pin_sense)
3249 msleep(85);
3250
Takashi Iwai1c9609e2018-01-19 14:18:34 +01003251 /* 3k pull low control for Headset jack. */
3252 /* NOTE: call this before clearing the pin, otherwise codec stalls */
3253 alc_update_coef_idx(codec, 0x46, 0, 3 << 12);
3254
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003255 if (!spec->no_shutup_pins)
3256 snd_hda_codec_write(codec, hp_pin, 0,
3257 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
Kailang Yang4a219ef2017-06-16 16:54:35 +08003258
Kailang Yang4a219ef2017-06-16 16:54:35 +08003259 if (hp_pin_sense)
3260 msleep(100);
3261
3262 alc_auto_setup_eapd(codec, false);
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003263 alc_shutup_pins(codec);
Kailang Yang4a219ef2017-06-16 16:54:35 +08003264}
3265
Kailang Yangda911b12018-01-05 16:50:08 +08003266static void alc225_init(struct hda_codec *codec)
3267{
3268 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003269 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yangda911b12018-01-05 16:50:08 +08003270 bool hp1_pin_sense, hp2_pin_sense;
3271
3272 if (!hp_pin)
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003273 hp_pin = 0x21;
Kailang Yangda911b12018-01-05 16:50:08 +08003274 msleep(30);
3275
3276 hp1_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3277 hp2_pin_sense = snd_hda_jack_detect(codec, 0x16);
3278
3279 if (hp1_pin_sense || hp2_pin_sense)
3280 msleep(2);
3281
3282 alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003283 if (spec->ultra_low_power) {
3284 alc_update_coef_idx(codec, 0x08, 0x0f << 2, 3<<2);
3285 alc_update_coef_idx(codec, 0x0e, 7<<6, 7<<6);
3286 alc_update_coef_idx(codec, 0x33, 1<<11, 0);
3287 msleep(30);
3288 }
Kailang Yangda911b12018-01-05 16:50:08 +08003289
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003290 if (hp1_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003291 snd_hda_codec_write(codec, hp_pin, 0,
3292 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3293 if (hp2_pin_sense)
3294 snd_hda_codec_write(codec, 0x16, 0,
3295 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3296
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003297 if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003298 msleep(85);
3299
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003300 if (hp1_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003301 snd_hda_codec_write(codec, hp_pin, 0,
3302 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3303 if (hp2_pin_sense)
3304 snd_hda_codec_write(codec, 0x16, 0,
3305 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3306
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003307 if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003308 msleep(100);
3309
3310 alc_update_coef_idx(codec, 0x4a, 3 << 10, 0);
3311 alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x4); /* Hight power */
3312}
3313
3314static void alc225_shutup(struct hda_codec *codec)
3315{
3316 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003317 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yangda911b12018-01-05 16:50:08 +08003318 bool hp1_pin_sense, hp2_pin_sense;
3319
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003320 if (!hp_pin)
3321 hp_pin = 0x21;
Kailang Yangda911b12018-01-05 16:50:08 +08003322 /* 3k pull low control for Headset jack. */
3323 alc_update_coef_idx(codec, 0x4a, 0, 3 << 10);
3324
3325 hp1_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3326 hp2_pin_sense = snd_hda_jack_detect(codec, 0x16);
3327
3328 if (hp1_pin_sense || hp2_pin_sense)
3329 msleep(2);
3330
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003331 if (hp1_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003332 snd_hda_codec_write(codec, hp_pin, 0,
3333 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3334 if (hp2_pin_sense)
3335 snd_hda_codec_write(codec, 0x16, 0,
3336 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3337
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003338 if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003339 msleep(85);
3340
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003341 if (hp1_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003342 snd_hda_codec_write(codec, hp_pin, 0,
3343 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
3344 if (hp2_pin_sense)
3345 snd_hda_codec_write(codec, 0x16, 0,
3346 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
3347
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003348 if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power)
Kailang Yangda911b12018-01-05 16:50:08 +08003349 msleep(100);
3350
3351 alc_auto_setup_eapd(codec, false);
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003352 alc_shutup_pins(codec);
Kailang Yangd3ba58b2019-05-06 15:09:42 +08003353 if (spec->ultra_low_power) {
3354 msleep(50);
3355 alc_update_coef_idx(codec, 0x08, 0x0f << 2, 0x0c << 2);
3356 alc_update_coef_idx(codec, 0x0e, 7<<6, 0);
3357 alc_update_coef_idx(codec, 0x33, 1<<11, 1<<11);
3358 alc_update_coef_idx(codec, 0x4a, 3<<4, 2<<4);
3359 msleep(30);
3360 }
Kailang Yangda911b12018-01-05 16:50:08 +08003361}
3362
Kailang Yangc2d6af52017-06-21 14:50:54 +08003363static void alc_default_init(struct hda_codec *codec)
3364{
3365 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003366 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yangc2d6af52017-06-21 14:50:54 +08003367 bool hp_pin_sense;
3368
3369 if (!hp_pin)
3370 return;
3371
3372 msleep(30);
3373
3374 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3375
3376 if (hp_pin_sense)
3377 msleep(2);
3378
3379 snd_hda_codec_write(codec, hp_pin, 0,
3380 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3381
3382 if (hp_pin_sense)
3383 msleep(85);
3384
3385 snd_hda_codec_write(codec, hp_pin, 0,
3386 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3387
3388 if (hp_pin_sense)
3389 msleep(100);
3390}
3391
3392static void alc_default_shutup(struct hda_codec *codec)
3393{
3394 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003395 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yangc2d6af52017-06-21 14:50:54 +08003396 bool hp_pin_sense;
3397
3398 if (!hp_pin) {
3399 alc269_shutup(codec);
3400 return;
3401 }
3402
3403 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3404
3405 if (hp_pin_sense)
3406 msleep(2);
3407
3408 snd_hda_codec_write(codec, hp_pin, 0,
3409 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3410
3411 if (hp_pin_sense)
3412 msleep(85);
3413
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003414 if (!spec->no_shutup_pins)
3415 snd_hda_codec_write(codec, hp_pin, 0,
3416 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
Kailang Yangc2d6af52017-06-21 14:50:54 +08003417
3418 if (hp_pin_sense)
3419 msleep(100);
3420
3421 alc_auto_setup_eapd(codec, false);
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003422 alc_shutup_pins(codec);
Kailang Yangc2d6af52017-06-21 14:50:54 +08003423}
3424
Kailang Yang693abe12019-01-29 15:38:21 +08003425static void alc294_hp_init(struct hda_codec *codec)
3426{
3427 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01003428 hda_nid_t hp_pin = alc_get_hp_pin(spec);
Kailang Yang693abe12019-01-29 15:38:21 +08003429 int i, val;
3430
3431 if (!hp_pin)
3432 return;
3433
3434 snd_hda_codec_write(codec, hp_pin, 0,
3435 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3436
3437 msleep(100);
3438
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01003439 if (!spec->no_shutup_pins)
3440 snd_hda_codec_write(codec, hp_pin, 0,
3441 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
Kailang Yang693abe12019-01-29 15:38:21 +08003442
3443 alc_update_coef_idx(codec, 0x6f, 0x000f, 0);/* Set HP depop to manual mode */
3444 alc_update_coefex_idx(codec, 0x58, 0x00, 0x8000, 0x8000); /* HP depop procedure start */
3445
3446 /* Wait for depop procedure finish */
3447 val = alc_read_coefex_idx(codec, 0x58, 0x01);
3448 for (i = 0; i < 20 && val & 0x0080; i++) {
3449 msleep(50);
3450 val = alc_read_coefex_idx(codec, 0x58, 0x01);
3451 }
3452 /* Set HP depop to auto mode */
3453 alc_update_coef_idx(codec, 0x6f, 0x000f, 0x000b);
3454 msleep(50);
3455}
3456
3457static void alc294_init(struct hda_codec *codec)
3458{
3459 struct alc_spec *spec = codec->spec;
3460
Takashi Iwaif6ef4e02019-01-29 14:14:51 +01003461 /* required only at boot or S4 resume time */
3462 if (!spec->done_hp_init ||
3463 codec->core.dev.power.power_state.event == PM_EVENT_RESTORE) {
Kailang Yang693abe12019-01-29 15:38:21 +08003464 alc294_hp_init(codec);
3465 spec->done_hp_init = true;
3466 }
3467 alc_default_init(codec);
3468}
3469
Kailang Yangad60d502013-06-28 12:03:01 +02003470static void alc5505_coef_set(struct hda_codec *codec, unsigned int index_reg,
3471 unsigned int val)
3472{
3473 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_COEF_INDEX, index_reg >> 1);
3474 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_PROC_COEF, val & 0xffff); /* LSB */
3475 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_PROC_COEF, val >> 16); /* MSB */
3476}
3477
3478static int alc5505_coef_get(struct hda_codec *codec, unsigned int index_reg)
3479{
3480 unsigned int val;
3481
3482 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_COEF_INDEX, index_reg >> 1);
3483 val = snd_hda_codec_read(codec, 0x51, 0, AC_VERB_GET_PROC_COEF, 0)
3484 & 0xffff;
3485 val |= snd_hda_codec_read(codec, 0x51, 0, AC_VERB_GET_PROC_COEF, 0)
3486 << 16;
3487 return val;
3488}
3489
3490static void alc5505_dsp_halt(struct hda_codec *codec)
3491{
3492 unsigned int val;
3493
3494 alc5505_coef_set(codec, 0x3000, 0x000c); /* DSP CPU stop */
3495 alc5505_coef_set(codec, 0x880c, 0x0008); /* DDR enter self refresh */
3496 alc5505_coef_set(codec, 0x61c0, 0x11110080); /* Clock control for PLL and CPU */
3497 alc5505_coef_set(codec, 0x6230, 0xfc0d4011); /* Disable Input OP */
3498 alc5505_coef_set(codec, 0x61b4, 0x040a2b03); /* Stop PLL2 */
3499 alc5505_coef_set(codec, 0x61b0, 0x00005b17); /* Stop PLL1 */
3500 alc5505_coef_set(codec, 0x61b8, 0x04133303); /* Stop PLL3 */
3501 val = alc5505_coef_get(codec, 0x6220);
3502 alc5505_coef_set(codec, 0x6220, (val | 0x3000)); /* switch Ringbuffer clock to DBUS clock */
3503}
3504
3505static void alc5505_dsp_back_from_halt(struct hda_codec *codec)
3506{
3507 alc5505_coef_set(codec, 0x61b8, 0x04133302);
3508 alc5505_coef_set(codec, 0x61b0, 0x00005b16);
3509 alc5505_coef_set(codec, 0x61b4, 0x040a2b02);
3510 alc5505_coef_set(codec, 0x6230, 0xf80d4011);
3511 alc5505_coef_set(codec, 0x6220, 0x2002010f);
3512 alc5505_coef_set(codec, 0x880c, 0x00000004);
3513}
3514
3515static void alc5505_dsp_init(struct hda_codec *codec)
3516{
3517 unsigned int val;
3518
3519 alc5505_dsp_halt(codec);
3520 alc5505_dsp_back_from_halt(codec);
3521 alc5505_coef_set(codec, 0x61b0, 0x5b14); /* PLL1 control */
3522 alc5505_coef_set(codec, 0x61b0, 0x5b16);
3523 alc5505_coef_set(codec, 0x61b4, 0x04132b00); /* PLL2 control */
3524 alc5505_coef_set(codec, 0x61b4, 0x04132b02);
3525 alc5505_coef_set(codec, 0x61b8, 0x041f3300); /* PLL3 control*/
3526 alc5505_coef_set(codec, 0x61b8, 0x041f3302);
3527 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_CODEC_RESET, 0); /* Function reset */
3528 alc5505_coef_set(codec, 0x61b8, 0x041b3302);
3529 alc5505_coef_set(codec, 0x61b8, 0x04173302);
3530 alc5505_coef_set(codec, 0x61b8, 0x04163302);
3531 alc5505_coef_set(codec, 0x8800, 0x348b328b); /* DRAM control */
3532 alc5505_coef_set(codec, 0x8808, 0x00020022); /* DRAM control */
3533 alc5505_coef_set(codec, 0x8818, 0x00000400); /* DRAM control */
3534
3535 val = alc5505_coef_get(codec, 0x6200) >> 16; /* Read revision ID */
3536 if (val <= 3)
3537 alc5505_coef_set(codec, 0x6220, 0x2002010f); /* I/O PAD Configuration */
3538 else
3539 alc5505_coef_set(codec, 0x6220, 0x6002018f);
3540
3541 alc5505_coef_set(codec, 0x61ac, 0x055525f0); /**/
3542 alc5505_coef_set(codec, 0x61c0, 0x12230080); /* Clock control */
3543 alc5505_coef_set(codec, 0x61b4, 0x040e2b02); /* PLL2 control */
3544 alc5505_coef_set(codec, 0x61bc, 0x010234f8); /* OSC Control */
3545 alc5505_coef_set(codec, 0x880c, 0x00000004); /* DRAM Function control */
3546 alc5505_coef_set(codec, 0x880c, 0x00000003);
3547 alc5505_coef_set(codec, 0x880c, 0x00000010);
Takashi Iwaicd63a5f2013-07-05 12:13:59 +02003548
3549#ifdef HALT_REALTEK_ALC5505
3550 alc5505_dsp_halt(codec);
3551#endif
Kailang Yangad60d502013-06-28 12:03:01 +02003552}
3553
Takashi Iwaicd63a5f2013-07-05 12:13:59 +02003554#ifdef HALT_REALTEK_ALC5505
3555#define alc5505_dsp_suspend(codec) /* NOP */
3556#define alc5505_dsp_resume(codec) /* NOP */
3557#else
3558#define alc5505_dsp_suspend(codec) alc5505_dsp_halt(codec)
3559#define alc5505_dsp_resume(codec) alc5505_dsp_back_from_halt(codec)
3560#endif
3561
Takashi Iwai2a439522011-07-26 09:52:50 +02003562#ifdef CONFIG_PM
Kailang Yangad60d502013-06-28 12:03:01 +02003563static int alc269_suspend(struct hda_codec *codec)
3564{
3565 struct alc_spec *spec = codec->spec;
3566
3567 if (spec->has_alc5505_dsp)
Takashi Iwaicd63a5f2013-07-05 12:13:59 +02003568 alc5505_dsp_suspend(codec);
Kailang Yangad60d502013-06-28 12:03:01 +02003569 return alc_suspend(codec);
3570}
3571
Takashi Iwai1d045db2011-07-07 18:23:21 +02003572static int alc269_resume(struct hda_codec *codec)
3573{
Kailang Yangadcc70b2012-05-25 08:08:38 +02003574 struct alc_spec *spec = codec->spec;
3575
Kailang Yang1387e2d2012-11-08 10:23:18 +01003576 if (spec->codec_variant == ALC269_TYPE_ALC269VB)
3577 alc269vb_toggle_power_output(codec, 0);
3578 if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
Kailang Yangadcc70b2012-05-25 08:08:38 +02003579 (alc_get_coef0(codec) & 0x00ff) == 0x018) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02003580 msleep(150);
3581 }
3582
3583 codec->patch_ops.init(codec);
3584
Kailang Yang1387e2d2012-11-08 10:23:18 +01003585 if (spec->codec_variant == ALC269_TYPE_ALC269VB)
3586 alc269vb_toggle_power_output(codec, 1);
3587 if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
Kailang Yangadcc70b2012-05-25 08:08:38 +02003588 (alc_get_coef0(codec) & 0x00ff) == 0x017) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02003589 msleep(200);
3590 }
3591
Takashi Iwaieeecd9d2015-02-25 15:18:50 +01003592 regcache_sync(codec->core.regmap);
Takashi Iwai1d045db2011-07-07 18:23:21 +02003593 hda_call_check_power_status(codec, 0x01);
Hui Wangf4753712014-08-19 12:07:03 +08003594
3595 /* on some machine, the BIOS will clear the codec gpio data when enter
3596 * suspend, and won't restore the data after resume, so we restore it
3597 * in the driver.
3598 */
Takashi Iwaid261eec2018-06-19 22:32:29 +02003599 if (spec->gpio_data)
3600 alc_write_gpio_data(codec);
Hui Wangf4753712014-08-19 12:07:03 +08003601
Kailang Yangad60d502013-06-28 12:03:01 +02003602 if (spec->has_alc5505_dsp)
Takashi Iwaicd63a5f2013-07-05 12:13:59 +02003603 alc5505_dsp_resume(codec);
Kailang Yangc5177c82013-07-24 14:39:49 +02003604
Takashi Iwai1d045db2011-07-07 18:23:21 +02003605 return 0;
3606}
Takashi Iwai2a439522011-07-26 09:52:50 +02003607#endif /* CONFIG_PM */
Takashi Iwai1d045db2011-07-07 18:23:21 +02003608
David Henningsson108cc102012-07-20 10:37:25 +02003609static void alc269_fixup_pincfg_no_hp_to_lineout(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003610 const struct hda_fixup *fix, int action)
David Henningsson108cc102012-07-20 10:37:25 +02003611{
3612 struct alc_spec *spec = codec->spec;
3613
Takashi Iwai1727a772013-01-10 09:52:52 +01003614 if (action == HDA_FIXUP_ACT_PRE_PROBE)
David Henningsson108cc102012-07-20 10:37:25 +02003615 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
3616}
3617
Jan-Marek Glogowskifdcc9682018-02-14 11:29:15 +01003618static void alc269_fixup_pincfg_U7x7_headset_mic(struct hda_codec *codec,
3619 const struct hda_fixup *fix,
3620 int action)
3621{
3622 unsigned int cfg_headphone = snd_hda_codec_get_pincfg(codec, 0x21);
3623 unsigned int cfg_headset_mic = snd_hda_codec_get_pincfg(codec, 0x19);
3624
3625 if (cfg_headphone && cfg_headset_mic == 0x411111f0)
3626 snd_hda_codec_set_pincfg(codec, 0x19,
3627 (cfg_headphone & ~AC_DEFCFG_DEVICE) |
3628 (AC_JACK_MIC_IN << AC_DEFCFG_DEVICE_SHIFT));
3629}
3630
Takashi Iwai1d045db2011-07-07 18:23:21 +02003631static void alc269_fixup_hweq(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003632 const struct hda_fixup *fix, int action)
Takashi Iwai1d045db2011-07-07 18:23:21 +02003633{
Takashi Iwai98b24882014-08-18 13:47:50 +02003634 if (action == HDA_FIXUP_ACT_INIT)
3635 alc_update_coef_idx(codec, 0x1e, 0, 0x80);
Takashi Iwai1d045db2011-07-07 18:23:21 +02003636}
3637
David Henningsson7c478f02013-10-11 10:18:46 +02003638static void alc269_fixup_headset_mic(struct hda_codec *codec,
3639 const struct hda_fixup *fix, int action)
3640{
3641 struct alc_spec *spec = codec->spec;
3642
3643 if (action == HDA_FIXUP_ACT_PRE_PROBE)
3644 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
3645}
3646
Takashi Iwai1d045db2011-07-07 18:23:21 +02003647static void alc271_fixup_dmic(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003648 const struct hda_fixup *fix, int action)
Takashi Iwai1d045db2011-07-07 18:23:21 +02003649{
3650 static const struct hda_verb verbs[] = {
3651 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
3652 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
3653 {}
3654 };
3655 unsigned int cfg;
3656
Takashi Iwai7639a062015-03-03 10:07:24 +01003657 if (strcmp(codec->core.chip_name, "ALC271X") &&
3658 strcmp(codec->core.chip_name, "ALC269VB"))
Takashi Iwai1d045db2011-07-07 18:23:21 +02003659 return;
3660 cfg = snd_hda_codec_get_pincfg(codec, 0x12);
3661 if (get_defcfg_connect(cfg) == AC_JACK_PORT_FIXED)
3662 snd_hda_sequence_write(codec, verbs);
3663}
3664
Takashi Iwai017f2a12011-07-09 14:42:25 +02003665static void alc269_fixup_pcm_44k(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003666 const struct hda_fixup *fix, int action)
Takashi Iwai017f2a12011-07-09 14:42:25 +02003667{
3668 struct alc_spec *spec = codec->spec;
3669
Takashi Iwai1727a772013-01-10 09:52:52 +01003670 if (action != HDA_FIXUP_ACT_PROBE)
Takashi Iwai017f2a12011-07-09 14:42:25 +02003671 return;
3672
3673 /* Due to a hardware problem on Lenovo Ideadpad, we need to
3674 * fix the sample rate of analog I/O to 44.1kHz
3675 */
Takashi Iwai08c189f2012-12-19 15:22:24 +01003676 spec->gen.stream_analog_playback = &alc269_44k_pcm_analog_playback;
3677 spec->gen.stream_analog_capture = &alc269_44k_pcm_analog_capture;
Takashi Iwai017f2a12011-07-09 14:42:25 +02003678}
3679
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02003680static void alc269_fixup_stereo_dmic(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003681 const struct hda_fixup *fix, int action)
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02003682{
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02003683 /* The digital-mic unit sends PDM (differential signal) instead of
3684 * the standard PCM, thus you can't record a valid mono stream as is.
3685 * Below is a workaround specific to ALC269 to control the dmic
3686 * signal source as mono.
3687 */
Takashi Iwai98b24882014-08-18 13:47:50 +02003688 if (action == HDA_FIXUP_ACT_INIT)
3689 alc_update_coef_idx(codec, 0x07, 0, 0x80);
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02003690}
3691
Takashi Iwai24519912011-08-16 15:08:49 +02003692static void alc269_quanta_automute(struct hda_codec *codec)
3693{
Takashi Iwai08c189f2012-12-19 15:22:24 +01003694 snd_hda_gen_update_outputs(codec);
Takashi Iwai24519912011-08-16 15:08:49 +02003695
Takashi Iwai1687ccc2014-08-18 13:49:35 +02003696 alc_write_coef_idx(codec, 0x0c, 0x680);
3697 alc_write_coef_idx(codec, 0x0c, 0x480);
Takashi Iwai24519912011-08-16 15:08:49 +02003698}
3699
3700static void alc269_fixup_quanta_mute(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003701 const struct hda_fixup *fix, int action)
Takashi Iwai24519912011-08-16 15:08:49 +02003702{
3703 struct alc_spec *spec = codec->spec;
Takashi Iwai1727a772013-01-10 09:52:52 +01003704 if (action != HDA_FIXUP_ACT_PROBE)
Takashi Iwai24519912011-08-16 15:08:49 +02003705 return;
Takashi Iwai08c189f2012-12-19 15:22:24 +01003706 spec->gen.automute_hook = alc269_quanta_automute;
Takashi Iwai24519912011-08-16 15:08:49 +02003707}
3708
David Henningssond240d1d2013-04-15 12:50:02 +02003709static void alc269_x101_hp_automute_hook(struct hda_codec *codec,
Takashi Iwai1a4f69d2014-09-11 15:22:46 +02003710 struct hda_jack_callback *jack)
David Henningssond240d1d2013-04-15 12:50:02 +02003711{
3712 struct alc_spec *spec = codec->spec;
3713 int vref;
3714 msleep(200);
3715 snd_hda_gen_hp_automute(codec, jack);
3716
3717 vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0;
3718 msleep(100);
3719 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3720 vref);
3721 msleep(500);
3722 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3723 vref);
3724}
3725
3726static void alc269_fixup_x101_headset_mic(struct hda_codec *codec,
3727 const struct hda_fixup *fix, int action)
3728{
3729 struct alc_spec *spec = codec->spec;
3730 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3731 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
3732 spec->gen.hp_automute_hook = alc269_x101_hp_automute_hook;
3733 }
3734}
3735
3736
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003737/* update mute-LED according to the speaker mute state via mic VREF pin */
3738static void alc269_fixup_mic_mute_hook(void *private_data, int enabled)
David Henningsson6d3cd5d2013-01-07 12:03:47 +01003739{
3740 struct hda_codec *codec = private_data;
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003741 struct alc_spec *spec = codec->spec;
3742 unsigned int pinval;
3743
3744 if (spec->mute_led_polarity)
3745 enabled = !enabled;
Takashi Iwai415d5552014-04-03 11:51:21 +02003746 pinval = snd_hda_codec_get_pin_target(codec, spec->mute_led_nid);
3747 pinval &= ~AC_PINCTL_VREFEN;
3748 pinval |= enabled ? AC_PINCTL_VREF_HIZ : AC_PINCTL_VREF_80;
Takashi Iwaie40bdb02018-03-17 22:40:18 +01003749 if (spec->mute_led_nid) {
3750 /* temporarily power up/down for setting VREF */
3751 snd_hda_power_up_pm(codec);
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003752 snd_hda_set_pin_ctl_cache(codec, spec->mute_led_nid, pinval);
Takashi Iwaie40bdb02018-03-17 22:40:18 +01003753 snd_hda_power_down_pm(codec);
3754 }
David Henningsson6d3cd5d2013-01-07 12:03:47 +01003755}
3756
David Henningssond5b6b652013-11-06 10:50:44 +01003757/* Make sure the led works even in runtime suspend */
3758static unsigned int led_power_filter(struct hda_codec *codec,
3759 hda_nid_t nid,
3760 unsigned int power_state)
3761{
3762 struct alc_spec *spec = codec->spec;
3763
Hui Wang50dd9052014-07-08 17:56:15 +08003764 if (power_state != AC_PWRST_D3 || nid == 0 ||
3765 (nid != spec->mute_led_nid && nid != spec->cap_mute_led_nid))
David Henningssond5b6b652013-11-06 10:50:44 +01003766 return power_state;
3767
3768 /* Set pin ctl again, it might have just been set to 0 */
3769 snd_hda_set_pin_ctl(codec, nid,
3770 snd_hda_codec_get_pin_target(codec, nid));
3771
Takashi Iwaicffd3962015-04-09 10:30:25 +02003772 return snd_hda_gen_path_power_filter(codec, nid, power_state);
David Henningssond5b6b652013-11-06 10:50:44 +01003773}
3774
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003775static void alc269_fixup_hp_mute_led(struct hda_codec *codec,
3776 const struct hda_fixup *fix, int action)
David Henningsson6d3cd5d2013-01-07 12:03:47 +01003777{
3778 struct alc_spec *spec = codec->spec;
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003779 const struct dmi_device *dev = NULL;
3780
3781 if (action != HDA_FIXUP_ACT_PRE_PROBE)
3782 return;
3783
3784 while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) {
3785 int pol, pin;
3786 if (sscanf(dev->name, "HP_Mute_LED_%d_%x", &pol, &pin) != 2)
3787 continue;
3788 if (pin < 0x0a || pin >= 0x10)
3789 break;
3790 spec->mute_led_polarity = pol;
3791 spec->mute_led_nid = pin - 0x0a + 0x18;
3792 spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook;
Takashi Iwaifd25a972012-12-20 14:57:18 +01003793 spec->gen.vmaster_mute_enum = 1;
David Henningssond5b6b652013-11-06 10:50:44 +01003794 codec->power_filter = led_power_filter;
Takashi Iwai4e76a882014-02-25 12:21:03 +01003795 codec_dbg(codec,
3796 "Detected mute LED for %x:%d\n", spec->mute_led_nid,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003797 spec->mute_led_polarity);
David Henningsson6d3cd5d2013-01-07 12:03:47 +01003798 break;
3799 }
3800}
3801
Takashi Iwai85c467d2018-05-29 11:38:38 +02003802static void alc269_fixup_hp_mute_led_micx(struct hda_codec *codec,
3803 const struct hda_fixup *fix,
3804 int action, hda_nid_t pin)
David Henningssond06ac142013-02-18 11:41:55 +01003805{
3806 struct alc_spec *spec = codec->spec;
Takashi Iwai85c467d2018-05-29 11:38:38 +02003807
David Henningssond06ac142013-02-18 11:41:55 +01003808 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3809 spec->mute_led_polarity = 0;
Takashi Iwai85c467d2018-05-29 11:38:38 +02003810 spec->mute_led_nid = pin;
David Henningssond06ac142013-02-18 11:41:55 +01003811 spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook;
3812 spec->gen.vmaster_mute_enum = 1;
David Henningssond5b6b652013-11-06 10:50:44 +01003813 codec->power_filter = led_power_filter;
David Henningssond06ac142013-02-18 11:41:55 +01003814 }
3815}
3816
Takashi Iwai85c467d2018-05-29 11:38:38 +02003817static void alc269_fixup_hp_mute_led_mic1(struct hda_codec *codec,
3818 const struct hda_fixup *fix, int action)
3819{
3820 alc269_fixup_hp_mute_led_micx(codec, fix, action, 0x18);
3821}
3822
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003823static void alc269_fixup_hp_mute_led_mic2(struct hda_codec *codec,
3824 const struct hda_fixup *fix, int action)
Takashi Iwai420b0fe2012-03-12 12:35:27 +01003825{
Takashi Iwai85c467d2018-05-29 11:38:38 +02003826 alc269_fixup_hp_mute_led_micx(codec, fix, action, 0x19);
Takashi Iwai420b0fe2012-03-12 12:35:27 +01003827}
3828
Tom Briden7f783bd2017-03-25 10:12:01 +00003829static void alc269_fixup_hp_mute_led_mic3(struct hda_codec *codec,
3830 const struct hda_fixup *fix, int action)
3831{
Takashi Iwai85c467d2018-05-29 11:38:38 +02003832 alc269_fixup_hp_mute_led_micx(codec, fix, action, 0x1b);
Tom Briden7f783bd2017-03-25 10:12:01 +00003833}
3834
Takashi Iwai0f32fd192014-11-19 12:16:14 +01003835/* update LED status via GPIO */
3836static void alc_update_gpio_led(struct hda_codec *codec, unsigned int mask,
3837 bool enabled)
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003838{
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003839 struct alc_spec *spec = codec->spec;
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003840
Takashi Iwai0f32fd192014-11-19 12:16:14 +01003841 if (spec->mute_led_polarity)
3842 enabled = !enabled;
Takashi Iwaid261eec2018-06-19 22:32:29 +02003843 alc_update_gpio_data(codec, mask, !enabled); /* muted -> LED on */
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003844}
3845
Takashi Iwai0f32fd192014-11-19 12:16:14 +01003846/* turn on/off mute LED via GPIO per vmaster hook */
3847static void alc_fixup_gpio_mute_hook(void *private_data, int enabled)
3848{
3849 struct hda_codec *codec = private_data;
3850 struct alc_spec *spec = codec->spec;
3851
3852 alc_update_gpio_led(codec, spec->gpio_mute_led_mask, enabled);
3853}
3854
3855/* turn on/off mic-mute LED via GPIO per capture hook */
Takashi Iwaid03abec2018-06-19 12:29:13 +02003856static void alc_gpio_micmute_update(struct hda_codec *codec)
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003857{
3858 struct alc_spec *spec = codec->spec;
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003859
Takashi Iwaid03abec2018-06-19 12:29:13 +02003860 alc_update_gpio_led(codec, spec->gpio_mic_led_mask,
3861 spec->gen.micmute_led.led_value);
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003862}
3863
Takashi Iwai01e4a272018-06-19 22:47:30 +02003864/* setup mute and mic-mute GPIO bits, add hooks appropriately */
3865static void alc_fixup_hp_gpio_led(struct hda_codec *codec,
3866 int action,
3867 unsigned int mute_mask,
3868 unsigned int micmute_mask)
3869{
3870 struct alc_spec *spec = codec->spec;
3871
3872 alc_fixup_gpio(codec, action, mute_mask | micmute_mask);
3873
3874 if (action != HDA_FIXUP_ACT_PRE_PROBE)
3875 return;
3876 if (mute_mask) {
3877 spec->gpio_mute_led_mask = mute_mask;
3878 spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook;
3879 }
3880 if (micmute_mask) {
3881 spec->gpio_mic_led_mask = micmute_mask;
3882 snd_hda_gen_add_micmute_led(codec, alc_gpio_micmute_update);
3883 }
3884}
3885
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003886static void alc269_fixup_hp_gpio_led(struct hda_codec *codec,
3887 const struct hda_fixup *fix, int action)
3888{
Takashi Iwai01e4a272018-06-19 22:47:30 +02003889 alc_fixup_hp_gpio_led(codec, action, 0x08, 0x10);
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003890}
3891
Kailang Yangeaa8e5e2014-11-21 15:49:11 +08003892static void alc286_fixup_hp_gpio_led(struct hda_codec *codec,
3893 const struct hda_fixup *fix, int action)
3894{
Takashi Iwai01e4a272018-06-19 22:47:30 +02003895 alc_fixup_hp_gpio_led(codec, action, 0x02, 0x20);
Takashi Iwai1d045db2011-07-07 18:23:21 +02003896}
3897
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08003898/* turn on/off mic-mute LED per capture hook */
Takashi Iwaid03abec2018-06-19 12:29:13 +02003899static void alc_cap_micmute_update(struct hda_codec *codec)
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08003900{
3901 struct alc_spec *spec = codec->spec;
Takashi Iwaid03abec2018-06-19 12:29:13 +02003902 unsigned int pinval;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08003903
Takashi Iwaid03abec2018-06-19 12:29:13 +02003904 if (!spec->cap_mute_led_nid)
3905 return;
Hui Wangfc1fad92014-07-08 17:56:14 +08003906 pinval = snd_hda_codec_get_pin_target(codec, spec->cap_mute_led_nid);
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08003907 pinval &= ~AC_PINCTL_VREFEN;
Takashi Iwaid03abec2018-06-19 12:29:13 +02003908 if (spec->gen.micmute_led.led_value)
3909 pinval |= AC_PINCTL_VREF_80;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08003910 else
Takashi Iwaid03abec2018-06-19 12:29:13 +02003911 pinval |= AC_PINCTL_VREF_HIZ;
3912 snd_hda_set_pin_ctl_cache(codec, spec->cap_mute_led_nid, pinval);
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08003913}
3914
3915static void alc269_fixup_hp_gpio_mic1_led(struct hda_codec *codec,
3916 const struct hda_fixup *fix, int action)
3917{
3918 struct alc_spec *spec = codec->spec;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08003919
Takashi Iwai01e4a272018-06-19 22:47:30 +02003920 alc_fixup_hp_gpio_led(codec, action, 0x08, 0);
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08003921 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai01e4a272018-06-19 22:47:30 +02003922 /* Like hp_gpio_mic1_led, but also needs GPIO4 low to
3923 * enable headphone amp
3924 */
3925 spec->gpio_mask |= 0x10;
3926 spec->gpio_dir |= 0x10;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08003927 spec->cap_mute_led_nid = 0x18;
Takashi Iwaid03abec2018-06-19 12:29:13 +02003928 snd_hda_gen_add_micmute_led(codec, alc_cap_micmute_update);
Hui Wang50dd9052014-07-08 17:56:15 +08003929 codec->power_filter = led_power_filter;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08003930 }
3931}
3932
David Henningsson7a5255f2014-10-30 08:26:01 +01003933static void alc280_fixup_hp_gpio4(struct hda_codec *codec,
3934 const struct hda_fixup *fix, int action)
3935{
David Henningsson7a5255f2014-10-30 08:26:01 +01003936 struct alc_spec *spec = codec->spec;
David Henningsson7a5255f2014-10-30 08:26:01 +01003937
Takashi Iwai01e4a272018-06-19 22:47:30 +02003938 alc_fixup_hp_gpio_led(codec, action, 0x08, 0);
David Henningsson7a5255f2014-10-30 08:26:01 +01003939 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
David Henningsson7a5255f2014-10-30 08:26:01 +01003940 spec->cap_mute_led_nid = 0x18;
Takashi Iwaid03abec2018-06-19 12:29:13 +02003941 snd_hda_gen_add_micmute_led(codec, alc_cap_micmute_update);
David Henningsson7a5255f2014-10-30 08:26:01 +01003942 codec->power_filter = led_power_filter;
3943 }
3944}
3945
Takashi Iwai6a30aba2018-04-27 17:17:35 +02003946#if IS_REACHABLE(CONFIG_INPUT)
David Henningsson33f4acd2015-01-07 15:50:13 +01003947static void gpio2_mic_hotkey_event(struct hda_codec *codec,
3948 struct hda_jack_callback *event)
3949{
3950 struct alc_spec *spec = codec->spec;
3951
3952 /* GPIO2 just toggles on a keypress/keyrelease cycle. Therefore
3953 send both key on and key off event for every interrupt. */
Hui Wangc7b60a82015-12-28 11:35:25 +08003954 input_report_key(spec->kb_dev, spec->alc_mute_keycode_map[ALC_KEY_MICMUTE_INDEX], 1);
David Henningsson33f4acd2015-01-07 15:50:13 +01003955 input_sync(spec->kb_dev);
Hui Wangc7b60a82015-12-28 11:35:25 +08003956 input_report_key(spec->kb_dev, spec->alc_mute_keycode_map[ALC_KEY_MICMUTE_INDEX], 0);
David Henningsson33f4acd2015-01-07 15:50:13 +01003957 input_sync(spec->kb_dev);
3958}
David Henningsson33f4acd2015-01-07 15:50:13 +01003959
Kailang3694cb22015-12-28 11:35:24 +08003960static int alc_register_micmute_input_device(struct hda_codec *codec)
3961{
3962 struct alc_spec *spec = codec->spec;
Hui Wangc7b60a82015-12-28 11:35:25 +08003963 int i;
Kailang3694cb22015-12-28 11:35:24 +08003964
3965 spec->kb_dev = input_allocate_device();
3966 if (!spec->kb_dev) {
3967 codec_err(codec, "Out of memory (input_allocate_device)\n");
3968 return -ENOMEM;
3969 }
Hui Wangc7b60a82015-12-28 11:35:25 +08003970
3971 spec->alc_mute_keycode_map[ALC_KEY_MICMUTE_INDEX] = KEY_MICMUTE;
3972
Kailang3694cb22015-12-28 11:35:24 +08003973 spec->kb_dev->name = "Microphone Mute Button";
3974 spec->kb_dev->evbit[0] = BIT_MASK(EV_KEY);
Hui Wangc7b60a82015-12-28 11:35:25 +08003975 spec->kb_dev->keycodesize = sizeof(spec->alc_mute_keycode_map[0]);
3976 spec->kb_dev->keycodemax = ARRAY_SIZE(spec->alc_mute_keycode_map);
3977 spec->kb_dev->keycode = spec->alc_mute_keycode_map;
3978 for (i = 0; i < ARRAY_SIZE(spec->alc_mute_keycode_map); i++)
3979 set_bit(spec->alc_mute_keycode_map[i], spec->kb_dev->keybit);
Kailang3694cb22015-12-28 11:35:24 +08003980
3981 if (input_register_device(spec->kb_dev)) {
3982 codec_err(codec, "input_register_device failed\n");
3983 input_free_device(spec->kb_dev);
3984 spec->kb_dev = NULL;
3985 return -ENOMEM;
3986 }
3987
3988 return 0;
3989}
3990
Takashi Iwai01e4a272018-06-19 22:47:30 +02003991/* GPIO1 = set according to SKU external amp
3992 * GPIO2 = mic mute hotkey
3993 * GPIO3 = mute LED
3994 * GPIO4 = mic mute LED
3995 */
David Henningsson33f4acd2015-01-07 15:50:13 +01003996static void alc280_fixup_hp_gpio2_mic_hotkey(struct hda_codec *codec,
3997 const struct hda_fixup *fix, int action)
3998{
David Henningsson33f4acd2015-01-07 15:50:13 +01003999 struct alc_spec *spec = codec->spec;
4000
Takashi Iwai01e4a272018-06-19 22:47:30 +02004001 alc_fixup_hp_gpio_led(codec, action, 0x08, 0x10);
David Henningsson33f4acd2015-01-07 15:50:13 +01004002 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai1c76aa52018-06-21 16:37:54 +02004003 spec->init_amp = ALC_INIT_DEFAULT;
Kailang3694cb22015-12-28 11:35:24 +08004004 if (alc_register_micmute_input_device(codec) != 0)
David Henningsson33f4acd2015-01-07 15:50:13 +01004005 return;
David Henningsson33f4acd2015-01-07 15:50:13 +01004006
Takashi Iwai01e4a272018-06-19 22:47:30 +02004007 spec->gpio_mask |= 0x06;
4008 spec->gpio_dir |= 0x02;
4009 spec->gpio_data |= 0x02;
Takashi Iwai7639a062015-03-03 10:07:24 +01004010 snd_hda_codec_write_cache(codec, codec->core.afg, 0,
David Henningsson33f4acd2015-01-07 15:50:13 +01004011 AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x04);
Takashi Iwai7639a062015-03-03 10:07:24 +01004012 snd_hda_jack_detect_enable_callback(codec, codec->core.afg,
David Henningsson33f4acd2015-01-07 15:50:13 +01004013 gpio2_mic_hotkey_event);
David Henningsson33f4acd2015-01-07 15:50:13 +01004014 return;
4015 }
4016
4017 if (!spec->kb_dev)
4018 return;
4019
4020 switch (action) {
David Henningsson33f4acd2015-01-07 15:50:13 +01004021 case HDA_FIXUP_ACT_FREE:
4022 input_unregister_device(spec->kb_dev);
David Henningsson33f4acd2015-01-07 15:50:13 +01004023 spec->kb_dev = NULL;
4024 }
David Henningsson33f4acd2015-01-07 15:50:13 +01004025}
4026
Takashi Iwai01e4a272018-06-19 22:47:30 +02004027/* Line2 = mic mute hotkey
4028 * GPIO2 = mic mute LED
4029 */
Kailang3694cb22015-12-28 11:35:24 +08004030static void alc233_fixup_lenovo_line2_mic_hotkey(struct hda_codec *codec,
4031 const struct hda_fixup *fix, int action)
4032{
Kailang3694cb22015-12-28 11:35:24 +08004033 struct alc_spec *spec = codec->spec;
4034
Takashi Iwai01e4a272018-06-19 22:47:30 +02004035 alc_fixup_hp_gpio_led(codec, action, 0, 0x04);
Kailang3694cb22015-12-28 11:35:24 +08004036 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai1c76aa52018-06-21 16:37:54 +02004037 spec->init_amp = ALC_INIT_DEFAULT;
Kailang3694cb22015-12-28 11:35:24 +08004038 if (alc_register_micmute_input_device(codec) != 0)
4039 return;
4040
Kailang3694cb22015-12-28 11:35:24 +08004041 snd_hda_jack_detect_enable_callback(codec, 0x1b,
4042 gpio2_mic_hotkey_event);
Kailang3694cb22015-12-28 11:35:24 +08004043 return;
4044 }
4045
4046 if (!spec->kb_dev)
4047 return;
4048
4049 switch (action) {
Kailang3694cb22015-12-28 11:35:24 +08004050 case HDA_FIXUP_ACT_FREE:
4051 input_unregister_device(spec->kb_dev);
4052 spec->kb_dev = NULL;
4053 }
4054}
Takashi Iwaic4696522018-01-15 10:44:35 +01004055#else /* INPUT */
4056#define alc280_fixup_hp_gpio2_mic_hotkey NULL
4057#define alc233_fixup_lenovo_line2_mic_hotkey NULL
4058#endif /* INPUT */
Kailang3694cb22015-12-28 11:35:24 +08004059
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004060static void alc269_fixup_hp_line1_mic1_led(struct hda_codec *codec,
4061 const struct hda_fixup *fix, int action)
4062{
4063 struct alc_spec *spec = codec->spec;
4064
Takashi Iwai1bce62a2018-06-19 23:15:59 +02004065 alc269_fixup_hp_mute_led_micx(codec, fix, action, 0x1a);
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004066 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004067 spec->cap_mute_led_nid = 0x18;
Takashi Iwaid03abec2018-06-19 12:29:13 +02004068 snd_hda_gen_add_micmute_led(codec, alc_cap_micmute_update);
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004069 }
4070}
4071
Kailang Yang5a367672017-07-21 15:23:53 +08004072static struct coef_fw alc225_pre_hsmode[] = {
4073 UPDATE_COEF(0x4a, 1<<8, 0),
4074 UPDATE_COEFEX(0x57, 0x05, 1<<14, 0),
4075 UPDATE_COEF(0x63, 3<<14, 3<<14),
4076 UPDATE_COEF(0x4a, 3<<4, 2<<4),
4077 UPDATE_COEF(0x4a, 3<<10, 3<<10),
4078 UPDATE_COEF(0x45, 0x3f<<10, 0x34<<10),
4079 UPDATE_COEF(0x4a, 3<<10, 0),
4080 {}
4081};
4082
David Henningsson73bdd592013-04-15 15:44:14 +02004083static void alc_headset_mode_unplugged(struct hda_codec *codec)
4084{
Takashi Iwai54db6c32014-08-18 15:11:19 +02004085 static struct coef_fw coef0255[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004086 WRITE_COEF(0x45, 0xd089), /* UAJ function set to menual mode */
4087 UPDATE_COEFEX(0x57, 0x05, 1<<14, 0), /* Direct Drive HP Amp control(Set to verb control)*/
4088 WRITE_COEF(0x06, 0x6104), /* Set MIC2 Vref gate with HP */
4089 WRITE_COEFEX(0x57, 0x03, 0x8aa6), /* Direct Drive HP Amp control */
4090 {}
4091 };
Kailang Yange69e7e02016-05-30 15:58:28 +08004092 static struct coef_fw coef0255_1[] = {
4093 WRITE_COEF(0x1b, 0x0c0b), /* LDO and MISC control */
4094 {}
4095 };
4096 static struct coef_fw coef0256[] = {
4097 WRITE_COEF(0x1b, 0x0c4b), /* LDO and MISC control */
4098 {}
4099 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004100 static struct coef_fw coef0233[] = {
4101 WRITE_COEF(0x1b, 0x0c0b),
4102 WRITE_COEF(0x45, 0xc429),
4103 UPDATE_COEF(0x35, 0x4000, 0),
4104 WRITE_COEF(0x06, 0x2104),
4105 WRITE_COEF(0x1a, 0x0001),
4106 WRITE_COEF(0x26, 0x0004),
4107 WRITE_COEF(0x32, 0x42a3),
4108 {}
4109 };
Kailang Yangf3b70332015-04-08 15:01:17 +08004110 static struct coef_fw coef0288[] = {
4111 UPDATE_COEF(0x4f, 0xfcc0, 0xc400),
4112 UPDATE_COEF(0x50, 0x2000, 0x2000),
4113 UPDATE_COEF(0x56, 0x0006, 0x0006),
4114 UPDATE_COEF(0x66, 0x0008, 0),
4115 UPDATE_COEF(0x67, 0x2000, 0),
4116 {}
4117 };
Kailang Yang89542932017-07-17 15:03:43 +08004118 static struct coef_fw coef0298[] = {
4119 UPDATE_COEF(0x19, 0x1300, 0x0300),
4120 {}
4121 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004122 static struct coef_fw coef0292[] = {
4123 WRITE_COEF(0x76, 0x000e),
4124 WRITE_COEF(0x6c, 0x2400),
4125 WRITE_COEF(0x18, 0x7308),
4126 WRITE_COEF(0x6b, 0xc429),
4127 {}
4128 };
4129 static struct coef_fw coef0293[] = {
4130 UPDATE_COEF(0x10, 7<<8, 6<<8), /* SET Line1 JD to 0 */
4131 UPDATE_COEFEX(0x57, 0x05, 1<<15|1<<13, 0x0), /* SET charge pump by verb */
4132 UPDATE_COEFEX(0x57, 0x03, 1<<10, 1<<10), /* SET EN_OSW to 1 */
4133 UPDATE_COEF(0x1a, 1<<3, 1<<3), /* Combo JD gating with LINE1-VREFO */
4134 WRITE_COEF(0x45, 0xc429), /* Set to TRS type */
4135 UPDATE_COEF(0x4a, 0x000f, 0x000e), /* Combo Jack auto detect */
4136 {}
4137 };
4138 static struct coef_fw coef0668[] = {
4139 WRITE_COEF(0x15, 0x0d40),
4140 WRITE_COEF(0xb7, 0x802b),
4141 {}
4142 };
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004143 static struct coef_fw coef0225[] = {
Kailang Yang5a367672017-07-21 15:23:53 +08004144 UPDATE_COEF(0x63, 3<<14, 0),
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004145 {}
4146 };
Kailang Yang71683c32017-06-20 16:33:50 +08004147 static struct coef_fw coef0274[] = {
4148 UPDATE_COEF(0x4a, 0x0100, 0),
4149 UPDATE_COEFEX(0x57, 0x05, 0x4000, 0),
4150 UPDATE_COEF(0x6b, 0xf000, 0x5000),
4151 UPDATE_COEF(0x4a, 0x0010, 0),
4152 UPDATE_COEF(0x4a, 0x0c00, 0x0c00),
4153 WRITE_COEF(0x45, 0x5289),
4154 UPDATE_COEF(0x4a, 0x0c00, 0),
4155 {}
4156 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004157
Takashi Iwai7639a062015-03-03 10:07:24 +01004158 switch (codec->core.vendor_id) {
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004159 case 0x10ec0255:
Kailang Yange69e7e02016-05-30 15:58:28 +08004160 alc_process_coef_fw(codec, coef0255_1);
4161 alc_process_coef_fw(codec, coef0255);
4162 break;
Kailang Yang736f20a2017-10-20 15:06:34 +08004163 case 0x10ec0236:
Kailang Yang7081adf2015-03-30 17:05:37 +08004164 case 0x10ec0256:
Kailang Yange69e7e02016-05-30 15:58:28 +08004165 alc_process_coef_fw(codec, coef0256);
Takashi Iwai54db6c32014-08-18 15:11:19 +02004166 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004167 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004168 case 0x10ec0234:
4169 case 0x10ec0274:
4170 case 0x10ec0294:
4171 alc_process_coef_fw(codec, coef0274);
4172 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004173 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004174 case 0x10ec0283:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004175 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02004176 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004177 case 0x10ec0286:
4178 case 0x10ec0288:
Kailang Yang89542932017-07-17 15:03:43 +08004179 alc_process_coef_fw(codec, coef0288);
4180 break;
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004181 case 0x10ec0298:
Kailang Yang89542932017-07-17 15:03:43 +08004182 alc_process_coef_fw(codec, coef0298);
Kailang Yangf3b70332015-04-08 15:01:17 +08004183 alc_process_coef_fw(codec, coef0288);
4184 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004185 case 0x10ec0292:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004186 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02004187 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004188 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004189 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004190 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004191 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004192 alc_process_coef_fw(codec, coef0668);
David Henningsson73bdd592013-04-15 15:44:14 +02004193 break;
Kailang Yangc2b691e2018-01-17 15:22:55 +08004194 case 0x10ec0215:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004195 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004196 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08004197 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004198 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08004199 case 0x10ec0299:
Kailang Yang4d4b0c52019-01-09 16:23:37 +08004200 alc_process_coef_fw(codec, alc225_pre_hsmode);
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004201 alc_process_coef_fw(codec, coef0225);
4202 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08004203 case 0x10ec0867:
4204 alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
4205 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004206 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01004207 codec_dbg(codec, "Headset jack set to unplugged mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02004208}
4209
4210
4211static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin,
4212 hda_nid_t mic_pin)
4213{
Takashi Iwai54db6c32014-08-18 15:11:19 +02004214 static struct coef_fw coef0255[] = {
4215 WRITE_COEFEX(0x57, 0x03, 0x8aa6),
4216 WRITE_COEF(0x06, 0x6100), /* Set MIC2 Vref gate to normal */
4217 {}
4218 };
4219 static struct coef_fw coef0233[] = {
4220 UPDATE_COEF(0x35, 0, 1<<14),
4221 WRITE_COEF(0x06, 0x2100),
4222 WRITE_COEF(0x1a, 0x0021),
4223 WRITE_COEF(0x26, 0x008c),
4224 {}
4225 };
Kailang Yangf3b70332015-04-08 15:01:17 +08004226 static struct coef_fw coef0288[] = {
Kailang Yang89542932017-07-17 15:03:43 +08004227 UPDATE_COEF(0x4f, 0x00c0, 0),
Kailang Yangf3b70332015-04-08 15:01:17 +08004228 UPDATE_COEF(0x50, 0x2000, 0),
4229 UPDATE_COEF(0x56, 0x0006, 0),
4230 UPDATE_COEF(0x4f, 0xfcc0, 0xc400),
4231 UPDATE_COEF(0x66, 0x0008, 0x0008),
4232 UPDATE_COEF(0x67, 0x2000, 0x2000),
4233 {}
4234 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004235 static struct coef_fw coef0292[] = {
4236 WRITE_COEF(0x19, 0xa208),
4237 WRITE_COEF(0x2e, 0xacf0),
4238 {}
4239 };
4240 static struct coef_fw coef0293[] = {
4241 UPDATE_COEFEX(0x57, 0x05, 0, 1<<15|1<<13), /* SET charge pump by verb */
4242 UPDATE_COEFEX(0x57, 0x03, 1<<10, 0), /* SET EN_OSW to 0 */
4243 UPDATE_COEF(0x1a, 1<<3, 0), /* Combo JD gating without LINE1-VREFO */
4244 {}
4245 };
4246 static struct coef_fw coef0688[] = {
4247 WRITE_COEF(0xb7, 0x802b),
4248 WRITE_COEF(0xb5, 0x1040),
4249 UPDATE_COEF(0xc3, 0, 1<<12),
4250 {}
4251 };
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004252 static struct coef_fw coef0225[] = {
4253 UPDATE_COEFEX(0x57, 0x05, 1<<14, 1<<14),
4254 UPDATE_COEF(0x4a, 3<<4, 2<<4),
4255 UPDATE_COEF(0x63, 3<<14, 0),
4256 {}
4257 };
Kailang Yang71683c32017-06-20 16:33:50 +08004258 static struct coef_fw coef0274[] = {
4259 UPDATE_COEFEX(0x57, 0x05, 0x4000, 0x4000),
4260 UPDATE_COEF(0x4a, 0x0010, 0),
4261 UPDATE_COEF(0x6b, 0xf000, 0),
4262 {}
4263 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004264
Takashi Iwai7639a062015-03-03 10:07:24 +01004265 switch (codec->core.vendor_id) {
Kailang Yang736f20a2017-10-20 15:06:34 +08004266 case 0x10ec0236:
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004267 case 0x10ec0255:
Kailang Yang7081adf2015-03-30 17:05:37 +08004268 case 0x10ec0256:
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004269 alc_write_coef_idx(codec, 0x45, 0xc489);
4270 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02004271 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004272 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4273 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004274 case 0x10ec0234:
4275 case 0x10ec0274:
4276 case 0x10ec0294:
4277 alc_write_coef_idx(codec, 0x45, 0x4689);
4278 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4279 alc_process_coef_fw(codec, coef0274);
4280 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4281 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004282 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004283 case 0x10ec0283:
4284 alc_write_coef_idx(codec, 0x45, 0xc429);
4285 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02004286 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02004287 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4288 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004289 case 0x10ec0286:
4290 case 0x10ec0288:
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004291 case 0x10ec0298:
Kailang Yangf3b70332015-04-08 15:01:17 +08004292 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4293 alc_process_coef_fw(codec, coef0288);
4294 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4295 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004296 case 0x10ec0292:
4297 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02004298 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02004299 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004300 case 0x10ec0293:
4301 /* Set to TRS mode */
4302 alc_write_coef_idx(codec, 0x45, 0xc429);
4303 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02004304 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004305 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4306 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08004307 case 0x10ec0867:
4308 alc_update_coefex_idx(codec, 0x57, 0x5, 0, 1<<14);
4309 /* fallthru */
Kailang Yang9eb5d0e2017-01-17 15:40:25 +08004310 case 0x10ec0221:
David Henningsson1f8b46c2015-05-12 14:38:15 +02004311 case 0x10ec0662:
4312 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4313 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4314 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004315 case 0x10ec0668:
4316 alc_write_coef_idx(codec, 0x11, 0x0001);
4317 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02004318 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02004319 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4320 break;
Kailang Yangc2b691e2018-01-17 15:22:55 +08004321 case 0x10ec0215:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004322 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004323 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08004324 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004325 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08004326 case 0x10ec0299:
Kailang Yang5a367672017-07-21 15:23:53 +08004327 alc_process_coef_fw(codec, alc225_pre_hsmode);
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004328 alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x31<<10);
4329 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4330 alc_process_coef_fw(codec, coef0225);
4331 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4332 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004333 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01004334 codec_dbg(codec, "Headset jack set to mic-in mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02004335}
4336
4337static void alc_headset_mode_default(struct hda_codec *codec)
4338{
David Henningsson2ae95572016-02-25 09:37:05 +01004339 static struct coef_fw coef0225[] = {
Kailang Yang5a367672017-07-21 15:23:53 +08004340 UPDATE_COEF(0x45, 0x3f<<10, 0x30<<10),
4341 UPDATE_COEF(0x45, 0x3f<<10, 0x31<<10),
4342 UPDATE_COEF(0x49, 3<<8, 0<<8),
4343 UPDATE_COEF(0x4a, 3<<4, 3<<4),
4344 UPDATE_COEF(0x63, 3<<14, 0),
4345 UPDATE_COEF(0x67, 0xf000, 0x3000),
David Henningsson2ae95572016-02-25 09:37:05 +01004346 {}
4347 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004348 static struct coef_fw coef0255[] = {
4349 WRITE_COEF(0x45, 0xc089),
4350 WRITE_COEF(0x45, 0xc489),
4351 WRITE_COEFEX(0x57, 0x03, 0x8ea6),
4352 WRITE_COEF(0x49, 0x0049),
4353 {}
4354 };
4355 static struct coef_fw coef0233[] = {
4356 WRITE_COEF(0x06, 0x2100),
4357 WRITE_COEF(0x32, 0x4ea3),
4358 {}
4359 };
Kailang Yangf3b70332015-04-08 15:01:17 +08004360 static struct coef_fw coef0288[] = {
4361 UPDATE_COEF(0x4f, 0xfcc0, 0xc400), /* Set to TRS type */
4362 UPDATE_COEF(0x50, 0x2000, 0x2000),
4363 UPDATE_COEF(0x56, 0x0006, 0x0006),
4364 UPDATE_COEF(0x66, 0x0008, 0),
4365 UPDATE_COEF(0x67, 0x2000, 0),
4366 {}
4367 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004368 static struct coef_fw coef0292[] = {
4369 WRITE_COEF(0x76, 0x000e),
4370 WRITE_COEF(0x6c, 0x2400),
4371 WRITE_COEF(0x6b, 0xc429),
4372 WRITE_COEF(0x18, 0x7308),
4373 {}
4374 };
4375 static struct coef_fw coef0293[] = {
4376 UPDATE_COEF(0x4a, 0x000f, 0x000e), /* Combo Jack auto detect */
4377 WRITE_COEF(0x45, 0xC429), /* Set to TRS type */
4378 UPDATE_COEF(0x1a, 1<<3, 0), /* Combo JD gating without LINE1-VREFO */
4379 {}
4380 };
4381 static struct coef_fw coef0688[] = {
4382 WRITE_COEF(0x11, 0x0041),
4383 WRITE_COEF(0x15, 0x0d40),
4384 WRITE_COEF(0xb7, 0x802b),
4385 {}
4386 };
Kailang Yang71683c32017-06-20 16:33:50 +08004387 static struct coef_fw coef0274[] = {
4388 WRITE_COEF(0x45, 0x4289),
4389 UPDATE_COEF(0x4a, 0x0010, 0x0010),
4390 UPDATE_COEF(0x6b, 0x0f00, 0),
4391 UPDATE_COEF(0x49, 0x0300, 0x0300),
4392 {}
4393 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004394
Takashi Iwai7639a062015-03-03 10:07:24 +01004395 switch (codec->core.vendor_id) {
Kailang Yangc2b691e2018-01-17 15:22:55 +08004396 case 0x10ec0215:
David Henningsson2ae95572016-02-25 09:37:05 +01004397 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004398 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08004399 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004400 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08004401 case 0x10ec0299:
Kailang Yang5a367672017-07-21 15:23:53 +08004402 alc_process_coef_fw(codec, alc225_pre_hsmode);
David Henningsson2ae95572016-02-25 09:37:05 +01004403 alc_process_coef_fw(codec, coef0225);
4404 break;
Kailang Yang736f20a2017-10-20 15:06:34 +08004405 case 0x10ec0236:
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004406 case 0x10ec0255:
Kailang Yang7081adf2015-03-30 17:05:37 +08004407 case 0x10ec0256:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004408 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004409 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004410 case 0x10ec0234:
4411 case 0x10ec0274:
4412 case 0x10ec0294:
4413 alc_process_coef_fw(codec, coef0274);
4414 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004415 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004416 case 0x10ec0283:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004417 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02004418 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004419 case 0x10ec0286:
4420 case 0x10ec0288:
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004421 case 0x10ec0298:
Kailang Yangf3b70332015-04-08 15:01:17 +08004422 alc_process_coef_fw(codec, coef0288);
4423 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004424 case 0x10ec0292:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004425 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02004426 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004427 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004428 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004429 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004430 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004431 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02004432 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08004433 case 0x10ec0867:
4434 alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
4435 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004436 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01004437 codec_dbg(codec, "Headset jack set to headphone (default) mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02004438}
4439
4440/* Iphone type */
4441static void alc_headset_mode_ctia(struct hda_codec *codec)
4442{
Kailang Yang89542932017-07-17 15:03:43 +08004443 int val;
4444
Takashi Iwai54db6c32014-08-18 15:11:19 +02004445 static struct coef_fw coef0255[] = {
4446 WRITE_COEF(0x45, 0xd489), /* Set to CTIA type */
4447 WRITE_COEF(0x1b, 0x0c2b),
4448 WRITE_COEFEX(0x57, 0x03, 0x8ea6),
4449 {}
4450 };
Kailang Yange69e7e02016-05-30 15:58:28 +08004451 static struct coef_fw coef0256[] = {
4452 WRITE_COEF(0x45, 0xd489), /* Set to CTIA type */
4453 WRITE_COEF(0x1b, 0x0c6b),
4454 WRITE_COEFEX(0x57, 0x03, 0x8ea6),
4455 {}
4456 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004457 static struct coef_fw coef0233[] = {
4458 WRITE_COEF(0x45, 0xd429),
4459 WRITE_COEF(0x1b, 0x0c2b),
4460 WRITE_COEF(0x32, 0x4ea3),
4461 {}
4462 };
Kailang Yangf3b70332015-04-08 15:01:17 +08004463 static struct coef_fw coef0288[] = {
4464 UPDATE_COEF(0x50, 0x2000, 0x2000),
4465 UPDATE_COEF(0x56, 0x0006, 0x0006),
4466 UPDATE_COEF(0x66, 0x0008, 0),
4467 UPDATE_COEF(0x67, 0x2000, 0),
4468 {}
4469 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004470 static struct coef_fw coef0292[] = {
4471 WRITE_COEF(0x6b, 0xd429),
4472 WRITE_COEF(0x76, 0x0008),
4473 WRITE_COEF(0x18, 0x7388),
4474 {}
4475 };
4476 static struct coef_fw coef0293[] = {
4477 WRITE_COEF(0x45, 0xd429), /* Set to ctia type */
4478 UPDATE_COEF(0x10, 7<<8, 7<<8), /* SET Line1 JD to 1 */
4479 {}
4480 };
4481 static struct coef_fw coef0688[] = {
4482 WRITE_COEF(0x11, 0x0001),
4483 WRITE_COEF(0x15, 0x0d60),
4484 WRITE_COEF(0xc3, 0x0000),
4485 {}
4486 };
Kailang Yang5a367672017-07-21 15:23:53 +08004487 static struct coef_fw coef0225_1[] = {
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004488 UPDATE_COEF(0x45, 0x3f<<10, 0x35<<10),
Kailang Yang5a367672017-07-21 15:23:53 +08004489 UPDATE_COEF(0x63, 3<<14, 2<<14),
4490 {}
4491 };
4492 static struct coef_fw coef0225_2[] = {
4493 UPDATE_COEF(0x45, 0x3f<<10, 0x35<<10),
4494 UPDATE_COEF(0x63, 3<<14, 1<<14),
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004495 {}
4496 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004497
Takashi Iwai7639a062015-03-03 10:07:24 +01004498 switch (codec->core.vendor_id) {
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004499 case 0x10ec0255:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004500 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004501 break;
Kailang Yang736f20a2017-10-20 15:06:34 +08004502 case 0x10ec0236:
Kailang Yange69e7e02016-05-30 15:58:28 +08004503 case 0x10ec0256:
4504 alc_process_coef_fw(codec, coef0256);
4505 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004506 case 0x10ec0234:
4507 case 0x10ec0274:
4508 case 0x10ec0294:
4509 alc_write_coef_idx(codec, 0x45, 0xd689);
4510 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004511 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004512 case 0x10ec0283:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004513 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02004514 break;
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004515 case 0x10ec0298:
Kailang Yang89542932017-07-17 15:03:43 +08004516 val = alc_read_coef_idx(codec, 0x50);
4517 if (val & (1 << 12)) {
4518 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0020);
4519 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400);
4520 msleep(300);
4521 } else {
4522 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0010);
4523 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400);
4524 msleep(300);
4525 }
4526 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004527 case 0x10ec0286:
4528 case 0x10ec0288:
4529 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400);
4530 msleep(300);
4531 alc_process_coef_fw(codec, coef0288);
4532 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004533 case 0x10ec0292:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004534 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02004535 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004536 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004537 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004538 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004539 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004540 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02004541 break;
Kailang Yangc2b691e2018-01-17 15:22:55 +08004542 case 0x10ec0215:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004543 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004544 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08004545 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004546 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08004547 case 0x10ec0299:
Kailang Yang5a367672017-07-21 15:23:53 +08004548 val = alc_read_coef_idx(codec, 0x45);
4549 if (val & (1 << 9))
4550 alc_process_coef_fw(codec, coef0225_2);
4551 else
4552 alc_process_coef_fw(codec, coef0225_1);
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004553 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08004554 case 0x10ec0867:
4555 alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
4556 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004557 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01004558 codec_dbg(codec, "Headset jack set to iPhone-style headset mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02004559}
4560
4561/* Nokia type */
4562static void alc_headset_mode_omtp(struct hda_codec *codec)
4563{
Takashi Iwai54db6c32014-08-18 15:11:19 +02004564 static struct coef_fw coef0255[] = {
4565 WRITE_COEF(0x45, 0xe489), /* Set to OMTP Type */
4566 WRITE_COEF(0x1b, 0x0c2b),
4567 WRITE_COEFEX(0x57, 0x03, 0x8ea6),
4568 {}
4569 };
Kailang Yange69e7e02016-05-30 15:58:28 +08004570 static struct coef_fw coef0256[] = {
4571 WRITE_COEF(0x45, 0xe489), /* Set to OMTP Type */
4572 WRITE_COEF(0x1b, 0x0c6b),
4573 WRITE_COEFEX(0x57, 0x03, 0x8ea6),
4574 {}
4575 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004576 static struct coef_fw coef0233[] = {
4577 WRITE_COEF(0x45, 0xe429),
4578 WRITE_COEF(0x1b, 0x0c2b),
4579 WRITE_COEF(0x32, 0x4ea3),
4580 {}
4581 };
Kailang Yangf3b70332015-04-08 15:01:17 +08004582 static struct coef_fw coef0288[] = {
4583 UPDATE_COEF(0x50, 0x2000, 0x2000),
4584 UPDATE_COEF(0x56, 0x0006, 0x0006),
4585 UPDATE_COEF(0x66, 0x0008, 0),
4586 UPDATE_COEF(0x67, 0x2000, 0),
4587 {}
4588 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004589 static struct coef_fw coef0292[] = {
4590 WRITE_COEF(0x6b, 0xe429),
4591 WRITE_COEF(0x76, 0x0008),
4592 WRITE_COEF(0x18, 0x7388),
4593 {}
4594 };
4595 static struct coef_fw coef0293[] = {
4596 WRITE_COEF(0x45, 0xe429), /* Set to omtp type */
4597 UPDATE_COEF(0x10, 7<<8, 7<<8), /* SET Line1 JD to 1 */
4598 {}
4599 };
4600 static struct coef_fw coef0688[] = {
4601 WRITE_COEF(0x11, 0x0001),
4602 WRITE_COEF(0x15, 0x0d50),
4603 WRITE_COEF(0xc3, 0x0000),
4604 {}
4605 };
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004606 static struct coef_fw coef0225[] = {
4607 UPDATE_COEF(0x45, 0x3f<<10, 0x39<<10),
Kailang Yang5a367672017-07-21 15:23:53 +08004608 UPDATE_COEF(0x63, 3<<14, 2<<14),
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004609 {}
4610 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004611
Takashi Iwai7639a062015-03-03 10:07:24 +01004612 switch (codec->core.vendor_id) {
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004613 case 0x10ec0255:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004614 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004615 break;
Kailang Yang736f20a2017-10-20 15:06:34 +08004616 case 0x10ec0236:
Kailang Yange69e7e02016-05-30 15:58:28 +08004617 case 0x10ec0256:
4618 alc_process_coef_fw(codec, coef0256);
4619 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004620 case 0x10ec0234:
4621 case 0x10ec0274:
4622 case 0x10ec0294:
4623 alc_write_coef_idx(codec, 0x45, 0xe689);
4624 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004625 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004626 case 0x10ec0283:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004627 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02004628 break;
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004629 case 0x10ec0298:
4630 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0010);/* Headset output enable */
Kailang Yang89542932017-07-17 15:03:43 +08004631 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xe400);
4632 msleep(300);
4633 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004634 case 0x10ec0286:
4635 case 0x10ec0288:
4636 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xe400);
4637 msleep(300);
4638 alc_process_coef_fw(codec, coef0288);
4639 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004640 case 0x10ec0292:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004641 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02004642 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004643 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004644 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004645 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004646 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004647 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02004648 break;
Kailang Yangc2b691e2018-01-17 15:22:55 +08004649 case 0x10ec0215:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004650 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004651 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08004652 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004653 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08004654 case 0x10ec0299:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004655 alc_process_coef_fw(codec, coef0225);
4656 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004657 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01004658 codec_dbg(codec, "Headset jack set to Nokia-style headset mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02004659}
4660
4661static void alc_determine_headset_type(struct hda_codec *codec)
4662{
4663 int val;
4664 bool is_ctia = false;
4665 struct alc_spec *spec = codec->spec;
Takashi Iwai54db6c32014-08-18 15:11:19 +02004666 static struct coef_fw coef0255[] = {
4667 WRITE_COEF(0x45, 0xd089), /* combo jack auto switch control(Check type)*/
4668 WRITE_COEF(0x49, 0x0149), /* combo jack auto switch control(Vref
4669 conteol) */
4670 {}
4671 };
Kailang Yangf3b70332015-04-08 15:01:17 +08004672 static struct coef_fw coef0288[] = {
4673 UPDATE_COEF(0x4f, 0xfcc0, 0xd400), /* Check Type */
4674 {}
4675 };
Kailang Yang89542932017-07-17 15:03:43 +08004676 static struct coef_fw coef0298[] = {
4677 UPDATE_COEF(0x50, 0x2000, 0x2000),
4678 UPDATE_COEF(0x56, 0x0006, 0x0006),
4679 UPDATE_COEF(0x66, 0x0008, 0),
4680 UPDATE_COEF(0x67, 0x2000, 0),
4681 UPDATE_COEF(0x19, 0x1300, 0x1300),
4682 {}
4683 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004684 static struct coef_fw coef0293[] = {
4685 UPDATE_COEF(0x4a, 0x000f, 0x0008), /* Combo Jack auto detect */
4686 WRITE_COEF(0x45, 0xD429), /* Set to ctia type */
4687 {}
4688 };
4689 static struct coef_fw coef0688[] = {
4690 WRITE_COEF(0x11, 0x0001),
4691 WRITE_COEF(0xb7, 0x802b),
4692 WRITE_COEF(0x15, 0x0d60),
4693 WRITE_COEF(0xc3, 0x0c00),
4694 {}
4695 };
Kailang Yang71683c32017-06-20 16:33:50 +08004696 static struct coef_fw coef0274[] = {
4697 UPDATE_COEF(0x4a, 0x0010, 0),
4698 UPDATE_COEF(0x4a, 0x8000, 0),
4699 WRITE_COEF(0x45, 0xd289),
4700 UPDATE_COEF(0x49, 0x0300, 0x0300),
4701 {}
4702 };
David Henningsson73bdd592013-04-15 15:44:14 +02004703
Takashi Iwai7639a062015-03-03 10:07:24 +01004704 switch (codec->core.vendor_id) {
Kailang Yang736f20a2017-10-20 15:06:34 +08004705 case 0x10ec0236:
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004706 case 0x10ec0255:
Kailang Yang7081adf2015-03-30 17:05:37 +08004707 case 0x10ec0256:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004708 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004709 msleep(300);
4710 val = alc_read_coef_idx(codec, 0x46);
4711 is_ctia = (val & 0x0070) == 0x0070;
4712 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004713 case 0x10ec0234:
4714 case 0x10ec0274:
4715 case 0x10ec0294:
4716 alc_process_coef_fw(codec, coef0274);
4717 msleep(80);
4718 val = alc_read_coef_idx(codec, 0x46);
4719 is_ctia = (val & 0x00f0) == 0x00f0;
4720 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004721 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004722 case 0x10ec0283:
4723 alc_write_coef_idx(codec, 0x45, 0xd029);
4724 msleep(300);
4725 val = alc_read_coef_idx(codec, 0x46);
4726 is_ctia = (val & 0x0070) == 0x0070;
4727 break;
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004728 case 0x10ec0298:
Kailang Yang89542932017-07-17 15:03:43 +08004729 snd_hda_codec_write(codec, 0x21, 0,
4730 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
4731 msleep(100);
4732 snd_hda_codec_write(codec, 0x21, 0,
4733 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
4734 msleep(200);
4735
4736 val = alc_read_coef_idx(codec, 0x50);
4737 if (val & (1 << 12)) {
4738 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0020);
4739 alc_process_coef_fw(codec, coef0288);
4740 msleep(350);
4741 val = alc_read_coef_idx(codec, 0x50);
4742 is_ctia = (val & 0x0070) == 0x0070;
4743 } else {
4744 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0010);
4745 alc_process_coef_fw(codec, coef0288);
4746 msleep(350);
4747 val = alc_read_coef_idx(codec, 0x50);
4748 is_ctia = (val & 0x0070) == 0x0070;
4749 }
4750 alc_process_coef_fw(codec, coef0298);
4751 snd_hda_codec_write(codec, 0x21, 0,
4752 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP);
4753 msleep(75);
4754 snd_hda_codec_write(codec, 0x21, 0,
4755 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
4756 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004757 case 0x10ec0286:
4758 case 0x10ec0288:
4759 alc_process_coef_fw(codec, coef0288);
4760 msleep(350);
4761 val = alc_read_coef_idx(codec, 0x50);
4762 is_ctia = (val & 0x0070) == 0x0070;
4763 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004764 case 0x10ec0292:
4765 alc_write_coef_idx(codec, 0x6b, 0xd429);
4766 msleep(300);
4767 val = alc_read_coef_idx(codec, 0x6c);
4768 is_ctia = (val & 0x001c) == 0x001c;
4769 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004770 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004771 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004772 msleep(300);
4773 val = alc_read_coef_idx(codec, 0x46);
4774 is_ctia = (val & 0x0070) == 0x0070;
4775 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004776 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004777 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02004778 msleep(300);
4779 val = alc_read_coef_idx(codec, 0xbe);
4780 is_ctia = (val & 0x1c02) == 0x1c02;
4781 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 Yangda911b12018-01-05 16:50:08 +08004788 snd_hda_codec_write(codec, 0x21, 0,
4789 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
4790 msleep(80);
4791 snd_hda_codec_write(codec, 0x21, 0,
4792 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
4793
Kailang Yang5a367672017-07-21 15:23:53 +08004794 alc_process_coef_fw(codec, alc225_pre_hsmode);
4795 alc_update_coef_idx(codec, 0x67, 0xf000, 0x1000);
4796 val = alc_read_coef_idx(codec, 0x45);
4797 if (val & (1 << 9)) {
4798 alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x34<<10);
4799 alc_update_coef_idx(codec, 0x49, 3<<8, 2<<8);
4800 msleep(800);
4801 val = alc_read_coef_idx(codec, 0x46);
4802 is_ctia = (val & 0x00f0) == 0x00f0;
4803 } else {
4804 alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x34<<10);
4805 alc_update_coef_idx(codec, 0x49, 3<<8, 1<<8);
4806 msleep(800);
4807 val = alc_read_coef_idx(codec, 0x46);
4808 is_ctia = (val & 0x00f0) == 0x00f0;
4809 }
4810 alc_update_coef_idx(codec, 0x4a, 7<<6, 7<<6);
4811 alc_update_coef_idx(codec, 0x4a, 3<<4, 3<<4);
4812 alc_update_coef_idx(codec, 0x67, 0xf000, 0x3000);
Kailang Yangda911b12018-01-05 16:50:08 +08004813
4814 snd_hda_codec_write(codec, 0x21, 0,
4815 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
4816 msleep(80);
4817 snd_hda_codec_write(codec, 0x21, 0,
4818 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004819 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08004820 case 0x10ec0867:
4821 is_ctia = true;
4822 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004823 }
4824
Takashi Iwai4e76a882014-02-25 12:21:03 +01004825 codec_dbg(codec, "Headset jack detected iPhone-style headset: %s\n",
David Henningsson73bdd592013-04-15 15:44:14 +02004826 is_ctia ? "yes" : "no");
4827 spec->current_headset_type = is_ctia ? ALC_HEADSET_TYPE_CTIA : ALC_HEADSET_TYPE_OMTP;
4828}
4829
4830static void alc_update_headset_mode(struct hda_codec *codec)
4831{
4832 struct alc_spec *spec = codec->spec;
4833
4834 hda_nid_t mux_pin = spec->gen.imux_pins[spec->gen.cur_mux[0]];
Takashi Iwai35a39f92019-02-01 11:19:50 +01004835 hda_nid_t hp_pin = alc_get_hp_pin(spec);
David Henningsson73bdd592013-04-15 15:44:14 +02004836
4837 int new_headset_mode;
4838
4839 if (!snd_hda_jack_detect(codec, hp_pin))
4840 new_headset_mode = ALC_HEADSET_MODE_UNPLUGGED;
4841 else if (mux_pin == spec->headset_mic_pin)
4842 new_headset_mode = ALC_HEADSET_MODE_HEADSET;
4843 else if (mux_pin == spec->headphone_mic_pin)
4844 new_headset_mode = ALC_HEADSET_MODE_MIC;
4845 else
4846 new_headset_mode = ALC_HEADSET_MODE_HEADPHONE;
4847
David Henningsson5959a6b2013-11-12 11:10:57 +01004848 if (new_headset_mode == spec->current_headset_mode) {
4849 snd_hda_gen_update_outputs(codec);
David Henningsson73bdd592013-04-15 15:44:14 +02004850 return;
David Henningsson5959a6b2013-11-12 11:10:57 +01004851 }
David Henningsson73bdd592013-04-15 15:44:14 +02004852
4853 switch (new_headset_mode) {
4854 case ALC_HEADSET_MODE_UNPLUGGED:
4855 alc_headset_mode_unplugged(codec);
4856 spec->gen.hp_jack_present = false;
4857 break;
4858 case ALC_HEADSET_MODE_HEADSET:
4859 if (spec->current_headset_type == ALC_HEADSET_TYPE_UNKNOWN)
4860 alc_determine_headset_type(codec);
4861 if (spec->current_headset_type == ALC_HEADSET_TYPE_CTIA)
4862 alc_headset_mode_ctia(codec);
4863 else if (spec->current_headset_type == ALC_HEADSET_TYPE_OMTP)
4864 alc_headset_mode_omtp(codec);
4865 spec->gen.hp_jack_present = true;
4866 break;
4867 case ALC_HEADSET_MODE_MIC:
4868 alc_headset_mode_mic_in(codec, hp_pin, spec->headphone_mic_pin);
4869 spec->gen.hp_jack_present = false;
4870 break;
4871 case ALC_HEADSET_MODE_HEADPHONE:
4872 alc_headset_mode_default(codec);
4873 spec->gen.hp_jack_present = true;
4874 break;
4875 }
4876 if (new_headset_mode != ALC_HEADSET_MODE_MIC) {
4877 snd_hda_set_pin_ctl_cache(codec, hp_pin,
4878 AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN);
David Henningsson1f8b46c2015-05-12 14:38:15 +02004879 if (spec->headphone_mic_pin && spec->headphone_mic_pin != hp_pin)
David Henningsson73bdd592013-04-15 15:44:14 +02004880 snd_hda_set_pin_ctl_cache(codec, spec->headphone_mic_pin,
4881 PIN_VREFHIZ);
4882 }
4883 spec->current_headset_mode = new_headset_mode;
4884
4885 snd_hda_gen_update_outputs(codec);
4886}
4887
4888static void alc_update_headset_mode_hook(struct hda_codec *codec,
Takashi Iwai7fe30712014-01-30 17:59:02 +01004889 struct snd_kcontrol *kcontrol,
4890 struct snd_ctl_elem_value *ucontrol)
David Henningsson73bdd592013-04-15 15:44:14 +02004891{
4892 alc_update_headset_mode(codec);
4893}
4894
Takashi Iwai1a4f69d2014-09-11 15:22:46 +02004895static void alc_update_headset_jack_cb(struct hda_codec *codec,
4896 struct hda_jack_callback *jack)
David Henningsson73bdd592013-04-15 15:44:14 +02004897{
4898 struct alc_spec *spec = codec->spec;
David Henningsson5db4d342013-11-22 12:17:06 +01004899 spec->current_headset_type = ALC_HEADSET_TYPE_UNKNOWN;
David Henningsson73bdd592013-04-15 15:44:14 +02004900 snd_hda_gen_hp_automute(codec, jack);
4901}
4902
4903static void alc_probe_headset_mode(struct hda_codec *codec)
4904{
4905 int i;
4906 struct alc_spec *spec = codec->spec;
4907 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
4908
4909 /* Find mic pins */
4910 for (i = 0; i < cfg->num_inputs; i++) {
4911 if (cfg->inputs[i].is_headset_mic && !spec->headset_mic_pin)
4912 spec->headset_mic_pin = cfg->inputs[i].pin;
4913 if (cfg->inputs[i].is_headphone_mic && !spec->headphone_mic_pin)
4914 spec->headphone_mic_pin = cfg->inputs[i].pin;
4915 }
4916
Takashi Iwai0bed2aa2018-06-19 12:45:53 +02004917 WARN_ON(spec->gen.cap_sync_hook);
David Henningsson73bdd592013-04-15 15:44:14 +02004918 spec->gen.cap_sync_hook = alc_update_headset_mode_hook;
4919 spec->gen.automute_hook = alc_update_headset_mode;
4920 spec->gen.hp_automute_hook = alc_update_headset_jack_cb;
4921}
4922
4923static void alc_fixup_headset_mode(struct hda_codec *codec,
4924 const struct hda_fixup *fix, int action)
4925{
4926 struct alc_spec *spec = codec->spec;
4927
4928 switch (action) {
4929 case HDA_FIXUP_ACT_PRE_PROBE:
4930 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC | HDA_PINCFG_HEADPHONE_MIC;
4931 break;
4932 case HDA_FIXUP_ACT_PROBE:
4933 alc_probe_headset_mode(codec);
4934 break;
4935 case HDA_FIXUP_ACT_INIT:
4936 spec->current_headset_mode = 0;
4937 alc_update_headset_mode(codec);
4938 break;
4939 }
4940}
4941
4942static void alc_fixup_headset_mode_no_hp_mic(struct hda_codec *codec,
4943 const struct hda_fixup *fix, int action)
4944{
4945 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4946 struct alc_spec *spec = codec->spec;
4947 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
4948 }
4949 else
4950 alc_fixup_headset_mode(codec, fix, action);
4951}
4952
Kailang Yang31278992014-03-03 15:27:22 +08004953static void alc255_set_default_jack_type(struct hda_codec *codec)
4954{
4955 /* Set to iphone type */
Kailang Yange69e7e02016-05-30 15:58:28 +08004956 static struct coef_fw alc255fw[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004957 WRITE_COEF(0x1b, 0x880b),
4958 WRITE_COEF(0x45, 0xd089),
4959 WRITE_COEF(0x1b, 0x080b),
4960 WRITE_COEF(0x46, 0x0004),
4961 WRITE_COEF(0x1b, 0x0c0b),
4962 {}
4963 };
Kailang Yange69e7e02016-05-30 15:58:28 +08004964 static struct coef_fw alc256fw[] = {
4965 WRITE_COEF(0x1b, 0x884b),
4966 WRITE_COEF(0x45, 0xd089),
4967 WRITE_COEF(0x1b, 0x084b),
4968 WRITE_COEF(0x46, 0x0004),
4969 WRITE_COEF(0x1b, 0x0c4b),
4970 {}
4971 };
4972 switch (codec->core.vendor_id) {
4973 case 0x10ec0255:
4974 alc_process_coef_fw(codec, alc255fw);
4975 break;
Kailang Yang736f20a2017-10-20 15:06:34 +08004976 case 0x10ec0236:
Kailang Yange69e7e02016-05-30 15:58:28 +08004977 case 0x10ec0256:
4978 alc_process_coef_fw(codec, alc256fw);
4979 break;
4980 }
Kailang Yang31278992014-03-03 15:27:22 +08004981 msleep(30);
4982}
4983
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004984static void alc_fixup_headset_mode_alc255(struct hda_codec *codec,
4985 const struct hda_fixup *fix, int action)
4986{
4987 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Kailang Yang31278992014-03-03 15:27:22 +08004988 alc255_set_default_jack_type(codec);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004989 }
4990 alc_fixup_headset_mode(codec, fix, action);
4991}
4992
Kailang Yang31278992014-03-03 15:27:22 +08004993static void alc_fixup_headset_mode_alc255_no_hp_mic(struct hda_codec *codec,
4994 const struct hda_fixup *fix, int action)
4995{
4996 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4997 struct alc_spec *spec = codec->spec;
4998 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
4999 alc255_set_default_jack_type(codec);
5000 }
5001 else
5002 alc_fixup_headset_mode(codec, fix, action);
5003}
5004
Kailang Yange1e62b92015-04-08 16:01:22 +08005005static void alc288_update_headset_jack_cb(struct hda_codec *codec,
5006 struct hda_jack_callback *jack)
5007{
5008 struct alc_spec *spec = codec->spec;
Kailang Yange1e62b92015-04-08 16:01:22 +08005009
5010 alc_update_headset_jack_cb(codec, jack);
5011 /* Headset Mic enable or disable, only for Dell Dino */
Takashi Iwaid44a6862018-06-19 23:04:03 +02005012 alc_update_gpio_data(codec, 0x40, spec->gen.hp_jack_present);
Kailang Yange1e62b92015-04-08 16:01:22 +08005013}
5014
5015static void alc_fixup_headset_mode_dell_alc288(struct hda_codec *codec,
5016 const struct hda_fixup *fix, int action)
5017{
5018 alc_fixup_headset_mode(codec, fix, action);
5019 if (action == HDA_FIXUP_ACT_PROBE) {
5020 struct alc_spec *spec = codec->spec;
Takashi Iwaid44a6862018-06-19 23:04:03 +02005021 /* toggled via hp_automute_hook */
5022 spec->gpio_mask |= 0x40;
5023 spec->gpio_dir |= 0x40;
Kailang Yange1e62b92015-04-08 16:01:22 +08005024 spec->gen.hp_automute_hook = alc288_update_headset_jack_cb;
5025 }
5026}
5027
Hui Wang493a52a2014-01-14 14:07:36 +08005028static void alc_fixup_auto_mute_via_amp(struct hda_codec *codec,
5029 const struct hda_fixup *fix, int action)
5030{
5031 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5032 struct alc_spec *spec = codec->spec;
5033 spec->gen.auto_mute_via_amp = 1;
5034 }
5035}
5036
Takashi Iwai9b745ab2014-03-07 08:37:19 +01005037static void alc_fixup_no_shutup(struct hda_codec *codec,
5038 const struct hda_fixup *fix, int action)
5039{
Takashi Iwaiefe55732018-06-15 11:55:02 +02005040 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai9b745ab2014-03-07 08:37:19 +01005041 struct alc_spec *spec = codec->spec;
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01005042 spec->no_shutup_pins = 1;
Takashi Iwai9b745ab2014-03-07 08:37:19 +01005043 }
5044}
5045
Gabriele Mazzotta5e6db662014-05-20 18:58:26 +02005046static void alc_fixup_disable_aamix(struct hda_codec *codec,
5047 const struct hda_fixup *fix, int action)
5048{
5049 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5050 struct alc_spec *spec = codec->spec;
5051 /* Disable AA-loopback as it causes white noise */
5052 spec->gen.mixer_nid = 0;
5053 }
5054}
5055
Takashi Iwai7f57d802015-09-24 17:36:51 +02005056/* fixup for Thinkpad docks: add dock pins, avoid HP parser fixup */
5057static void alc_fixup_tpt440_dock(struct hda_codec *codec,
5058 const struct hda_fixup *fix, int action)
5059{
5060 static const struct hda_pintbl pincfgs[] = {
5061 { 0x16, 0x21211010 }, /* dock headphone */
5062 { 0x19, 0x21a11010 }, /* dock mic */
5063 { }
5064 };
5065 struct alc_spec *spec = codec->spec;
5066
5067 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai70a09762015-12-15 14:59:58 +01005068 spec->reboot_notify = alc_d3_at_reboot; /* reduce noise */
Takashi Iwai7f57d802015-09-24 17:36:51 +02005069 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
5070 codec->power_save_node = 0; /* avoid click noises */
5071 snd_hda_apply_pincfgs(codec, pincfgs);
5072 }
5073}
5074
Kailang Yang61fcf8e2018-02-02 15:26:46 +08005075static void alc_fixup_tpt470_dock(struct hda_codec *codec,
5076 const struct hda_fixup *fix, int action)
5077{
5078 static const struct hda_pintbl pincfgs[] = {
5079 { 0x17, 0x21211010 }, /* dock headphone */
5080 { 0x19, 0x21a11010 }, /* dock mic */
5081 { }
5082 };
Takashi Iwai54947cd2018-12-03 10:44:15 +01005083 /* Assure the speaker pin to be coupled with DAC NID 0x03; otherwise
5084 * the speaker output becomes too low by some reason on Thinkpads with
5085 * ALC298 codec
5086 */
5087 static hda_nid_t preferred_pairs[] = {
5088 0x14, 0x03, 0x17, 0x02, 0x21, 0x02,
5089 0
5090 };
Kailang Yang61fcf8e2018-02-02 15:26:46 +08005091 struct alc_spec *spec = codec->spec;
5092
5093 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai54947cd2018-12-03 10:44:15 +01005094 spec->gen.preferred_dacs = preferred_pairs;
Kailang Yang61fcf8e2018-02-02 15:26:46 +08005095 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
Takashi Iwai71db96d2018-02-26 15:36:38 +01005096 snd_hda_apply_pincfgs(codec, pincfgs);
5097 } else if (action == HDA_FIXUP_ACT_INIT) {
Kailang Yang61fcf8e2018-02-02 15:26:46 +08005098 /* Enable DOCK device */
5099 snd_hda_codec_write(codec, 0x17, 0,
5100 AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0);
5101 /* Enable DOCK device */
5102 snd_hda_codec_write(codec, 0x19, 0,
5103 AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0);
Kailang Yang61fcf8e2018-02-02 15:26:46 +08005104 }
5105}
5106
Gabriele Mazzotta9476d3692015-04-19 19:00:40 +02005107static void alc_shutup_dell_xps13(struct hda_codec *codec)
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02005108{
5109 struct alc_spec *spec = codec->spec;
Takashi Iwai35a39f92019-02-01 11:19:50 +01005110 int hp_pin = alc_get_hp_pin(spec);
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02005111
Gabriele Mazzotta9476d3692015-04-19 19:00:40 +02005112 /* Prevent pop noises when headphones are plugged in */
5113 snd_hda_codec_write(codec, hp_pin, 0,
5114 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
5115 msleep(20);
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02005116}
5117
5118static void alc_fixup_dell_xps13(struct hda_codec *codec,
5119 const struct hda_fixup *fix, int action)
5120{
Takashi Iwai3e1b0c42015-04-27 10:43:22 +02005121 struct alc_spec *spec = codec->spec;
5122 struct hda_input_mux *imux = &spec->gen.input_mux;
5123 int i;
Gabriele Mazzottaf38663a2014-08-08 19:34:40 +02005124
Takashi Iwai3e1b0c42015-04-27 10:43:22 +02005125 switch (action) {
5126 case HDA_FIXUP_ACT_PRE_PROBE:
5127 /* mic pin 0x19 must be initialized with Vref Hi-Z, otherwise
5128 * it causes a click noise at start up
5129 */
5130 snd_hda_codec_set_pin_target(codec, 0x19, PIN_VREFHIZ);
Takashi Iwaiefe55732018-06-15 11:55:02 +02005131 spec->shutup = alc_shutup_dell_xps13;
Takashi Iwai3e1b0c42015-04-27 10:43:22 +02005132 break;
5133 case HDA_FIXUP_ACT_PROBE:
Gabriele Mazzottaf38663a2014-08-08 19:34:40 +02005134 /* Make the internal mic the default input source. */
5135 for (i = 0; i < imux->num_items; i++) {
5136 if (spec->gen.imux_pins[i] == 0x12) {
5137 spec->gen.cur_mux[0] = i;
5138 break;
5139 }
5140 }
Takashi Iwai3e1b0c42015-04-27 10:43:22 +02005141 break;
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02005142 }
5143}
5144
David Henningsson1f8b46c2015-05-12 14:38:15 +02005145static void alc_fixup_headset_mode_alc662(struct hda_codec *codec,
5146 const struct hda_fixup *fix, int action)
5147{
5148 struct alc_spec *spec = codec->spec;
5149
5150 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5151 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
5152 spec->gen.hp_mic = 1; /* Mic-in is same pin as headphone */
David Henningssonb40eda62015-05-28 09:40:23 +02005153
5154 /* Disable boost for mic-in permanently. (This code is only called
5155 from quirks that guarantee that the headphone is at NID 0x1b.) */
5156 snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000);
5157 snd_hda_override_wcaps(codec, 0x1b, get_wcaps(codec, 0x1b) & ~AC_WCAP_IN_AMP);
David Henningsson1f8b46c2015-05-12 14:38:15 +02005158 } else
5159 alc_fixup_headset_mode(codec, fix, action);
5160}
5161
David Henningsson73bdd592013-04-15 15:44:14 +02005162static void alc_fixup_headset_mode_alc668(struct hda_codec *codec,
5163 const struct hda_fixup *fix, int action)
5164{
5165 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
David Henningsson73bdd592013-04-15 15:44:14 +02005166 alc_write_coef_idx(codec, 0xc4, 0x8000);
Takashi Iwai98b24882014-08-18 13:47:50 +02005167 alc_update_coef_idx(codec, 0xc2, ~0xfe, 0);
David Henningsson73bdd592013-04-15 15:44:14 +02005168 snd_hda_set_pin_ctl_cache(codec, 0x18, 0);
5169 }
5170 alc_fixup_headset_mode(codec, fix, action);
5171}
5172
Chih-Chung Changbde7bc62013-08-05 16:38:42 +08005173/* Returns the nid of the external mic input pin, or 0 if it cannot be found. */
5174static int find_ext_mic_pin(struct hda_codec *codec)
5175{
5176 struct alc_spec *spec = codec->spec;
5177 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
5178 hda_nid_t nid;
5179 unsigned int defcfg;
5180 int i;
5181
5182 for (i = 0; i < cfg->num_inputs; i++) {
5183 if (cfg->inputs[i].type != AUTO_PIN_MIC)
5184 continue;
5185 nid = cfg->inputs[i].pin;
5186 defcfg = snd_hda_codec_get_pincfg(codec, nid);
5187 if (snd_hda_get_input_pin_attr(defcfg) == INPUT_PIN_ATTR_INT)
5188 continue;
5189 return nid;
5190 }
5191
5192 return 0;
5193}
5194
Dylan Reid08a978d2012-11-18 22:56:40 -08005195static void alc271_hp_gate_mic_jack(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01005196 const struct hda_fixup *fix,
Dylan Reid08a978d2012-11-18 22:56:40 -08005197 int action)
5198{
5199 struct alc_spec *spec = codec->spec;
5200
Takashi Iwai0db75792013-01-23 13:57:20 +01005201 if (action == HDA_FIXUP_ACT_PROBE) {
Chih-Chung Changbde7bc62013-08-05 16:38:42 +08005202 int mic_pin = find_ext_mic_pin(codec);
Takashi Iwai35a39f92019-02-01 11:19:50 +01005203 int hp_pin = alc_get_hp_pin(spec);
Chih-Chung Changbde7bc62013-08-05 16:38:42 +08005204
5205 if (snd_BUG_ON(!mic_pin || !hp_pin))
Takashi Iwai0db75792013-01-23 13:57:20 +01005206 return;
Chih-Chung Changbde7bc62013-08-05 16:38:42 +08005207 snd_hda_jack_set_gating_jack(codec, mic_pin, hp_pin);
Takashi Iwai0db75792013-01-23 13:57:20 +01005208 }
Dylan Reid08a978d2012-11-18 22:56:40 -08005209}
David Henningsson693b6132012-06-22 19:12:10 +02005210
David Henningsson3e0d6112013-04-22 14:30:14 +02005211static void alc269_fixup_limit_int_mic_boost(struct hda_codec *codec,
5212 const struct hda_fixup *fix,
5213 int action)
5214{
5215 struct alc_spec *spec = codec->spec;
5216 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
5217 int i;
5218
5219 /* The mic boosts on level 2 and 3 are too noisy
5220 on the internal mic input.
5221 Therefore limit the boost to 0 or 1. */
5222
5223 if (action != HDA_FIXUP_ACT_PROBE)
5224 return;
5225
5226 for (i = 0; i < cfg->num_inputs; i++) {
5227 hda_nid_t nid = cfg->inputs[i].pin;
5228 unsigned int defcfg;
5229 if (cfg->inputs[i].type != AUTO_PIN_MIC)
5230 continue;
5231 defcfg = snd_hda_codec_get_pincfg(codec, nid);
5232 if (snd_hda_get_input_pin_attr(defcfg) != INPUT_PIN_ATTR_INT)
5233 continue;
5234
5235 snd_hda_override_amp_caps(codec, nid, HDA_INPUT,
5236 (0x00 << AC_AMPCAP_OFFSET_SHIFT) |
5237 (0x01 << AC_AMPCAP_NUM_STEPS_SHIFT) |
5238 (0x2f << AC_AMPCAP_STEP_SIZE_SHIFT) |
5239 (0 << AC_AMPCAP_MUTE_SHIFT));
5240 }
5241}
5242
Kailang Yangcd217a62013-08-22 10:15:24 +02005243static void alc283_hp_automute_hook(struct hda_codec *codec,
Takashi Iwai1a4f69d2014-09-11 15:22:46 +02005244 struct hda_jack_callback *jack)
Kailang Yangcd217a62013-08-22 10:15:24 +02005245{
5246 struct alc_spec *spec = codec->spec;
5247 int vref;
5248
5249 msleep(200);
5250 snd_hda_gen_hp_automute(codec, jack);
5251
5252 vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0;
5253
5254 msleep(600);
5255 snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5256 vref);
5257}
5258
Kailang Yangcd217a62013-08-22 10:15:24 +02005259static void alc283_fixup_chromebook(struct hda_codec *codec,
5260 const struct hda_fixup *fix, int action)
5261{
5262 struct alc_spec *spec = codec->spec;
Kailang Yangcd217a62013-08-22 10:15:24 +02005263
5264 switch (action) {
5265 case HDA_FIXUP_ACT_PRE_PROBE:
Kailang Yang0202e992013-12-02 15:20:15 +08005266 snd_hda_override_wcaps(codec, 0x03, 0);
Takashi Iwaid2e92702013-10-30 07:50:53 +01005267 /* Disable AA-loopback as it causes white noise */
5268 spec->gen.mixer_nid = 0;
Kailang Yang38070212013-11-01 15:57:35 +08005269 break;
5270 case HDA_FIXUP_ACT_INIT:
Kailang Yangde9481c2014-04-07 16:41:52 +08005271 /* MIC2-VREF control */
5272 /* Set to manual mode */
Takashi Iwai98b24882014-08-18 13:47:50 +02005273 alc_update_coef_idx(codec, 0x06, 0x000c, 0);
Kailang Yang0202e992013-12-02 15:20:15 +08005274 /* Enable Line1 input control by verb */
Takashi Iwai98b24882014-08-18 13:47:50 +02005275 alc_update_coef_idx(codec, 0x1a, 0, 1 << 4);
Kailang Yang0202e992013-12-02 15:20:15 +08005276 break;
5277 }
5278}
5279
5280static void alc283_fixup_sense_combo_jack(struct hda_codec *codec,
5281 const struct hda_fixup *fix, int action)
5282{
5283 struct alc_spec *spec = codec->spec;
Kailang Yang0202e992013-12-02 15:20:15 +08005284
5285 switch (action) {
5286 case HDA_FIXUP_ACT_PRE_PROBE:
Kailang Yangcd217a62013-08-22 10:15:24 +02005287 spec->gen.hp_automute_hook = alc283_hp_automute_hook;
5288 break;
5289 case HDA_FIXUP_ACT_INIT:
5290 /* MIC2-VREF control */
5291 /* Set to manual mode */
Takashi Iwai98b24882014-08-18 13:47:50 +02005292 alc_update_coef_idx(codec, 0x06, 0x000c, 0);
Kailang Yangcd217a62013-08-22 10:15:24 +02005293 break;
5294 }
5295}
5296
Takashi Iwai7bba2152013-09-06 15:45:38 +02005297/* mute tablet speaker pin (0x14) via dock plugging in addition */
5298static void asus_tx300_automute(struct hda_codec *codec)
5299{
5300 struct alc_spec *spec = codec->spec;
5301 snd_hda_gen_update_outputs(codec);
5302 if (snd_hda_jack_detect(codec, 0x1b))
5303 spec->gen.mute_bits |= (1ULL << 0x14);
5304}
5305
5306static void alc282_fixup_asus_tx300(struct hda_codec *codec,
5307 const struct hda_fixup *fix, int action)
5308{
5309 struct alc_spec *spec = codec->spec;
Takashi Iwai7bba2152013-09-06 15:45:38 +02005310 static const struct hda_pintbl dock_pins[] = {
5311 { 0x1b, 0x21114000 }, /* dock speaker pin */
5312 {}
5313 };
Takashi Iwai7bba2152013-09-06 15:45:38 +02005314
5315 switch (action) {
5316 case HDA_FIXUP_ACT_PRE_PROBE:
Takashi Iwai1c76aa52018-06-21 16:37:54 +02005317 spec->init_amp = ALC_INIT_DEFAULT;
Takashi Iwaiae065f12018-06-19 23:00:03 +02005318 /* TX300 needs to set up GPIO2 for the speaker amp */
5319 alc_setup_gpio(codec, 0x04);
Takashi Iwai7bba2152013-09-06 15:45:38 +02005320 snd_hda_apply_pincfgs(codec, dock_pins);
5321 spec->gen.auto_mute_via_amp = 1;
5322 spec->gen.automute_hook = asus_tx300_automute;
5323 snd_hda_jack_detect_enable_callback(codec, 0x1b,
Takashi Iwai7bba2152013-09-06 15:45:38 +02005324 snd_hda_gen_hp_automute);
5325 break;
Takashi Iwai5579cd62018-06-19 22:22:41 +02005326 case HDA_FIXUP_ACT_PROBE:
5327 spec->init_amp = ALC_INIT_DEFAULT;
5328 break;
Takashi Iwai7bba2152013-09-06 15:45:38 +02005329 case HDA_FIXUP_ACT_BUILD:
5330 /* this is a bit tricky; give more sane names for the main
5331 * (tablet) speaker and the dock speaker, respectively
5332 */
Takashi Iwai56798e62017-04-11 08:10:52 +02005333 rename_ctl(codec, "Speaker Playback Switch",
5334 "Dock Speaker Playback Switch");
5335 rename_ctl(codec, "Bass Speaker Playback Switch",
5336 "Speaker Playback Switch");
Takashi Iwai7bba2152013-09-06 15:45:38 +02005337 break;
5338 }
5339}
5340
David Henningsson338cae52013-10-07 10:39:59 +02005341static void alc290_fixup_mono_speakers(struct hda_codec *codec,
5342 const struct hda_fixup *fix, int action)
5343{
David Henningsson0f4881d2013-12-20 16:08:13 +01005344 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5345 /* DAC node 0x03 is giving mono output. We therefore want to
5346 make sure 0x14 (front speaker) and 0x15 (headphones) use the
5347 stereo DAC, while leaving 0x17 (bass speaker) for node 0x03. */
5348 hda_nid_t conn1[2] = { 0x0c };
5349 snd_hda_override_conn_list(codec, 0x14, 1, conn1);
5350 snd_hda_override_conn_list(codec, 0x15, 1, conn1);
5351 }
David Henningsson338cae52013-10-07 10:39:59 +02005352}
5353
Hui Wangdd9aa332016-08-01 10:20:32 +08005354static void alc298_fixup_speaker_volume(struct hda_codec *codec,
5355 const struct hda_fixup *fix, int action)
5356{
5357 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5358 /* The speaker is routed to the Node 0x06 by a mistake, as a result
5359 we can't adjust the speaker's volume since this node does not has
5360 Amp-out capability. we change the speaker's route to:
5361 Node 0x02 (Audio Output) -> Node 0x0c (Audio Mixer) -> Node 0x17 (
5362 Pin Complex), since Node 0x02 has Amp-out caps, we can adjust
5363 speaker's volume now. */
5364
5365 hda_nid_t conn1[1] = { 0x0c };
5366 snd_hda_override_conn_list(codec, 0x17, 1, conn1);
5367 }
5368}
5369
Takashi Iwaie312a862018-03-06 12:14:17 +01005370/* disable DAC3 (0x06) selection on NID 0x17 as it has no volume amp control */
5371static void alc295_fixup_disable_dac3(struct hda_codec *codec,
5372 const struct hda_fixup *fix, int action)
5373{
5374 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5375 hda_nid_t conn[2] = { 0x02, 0x03 };
5376 snd_hda_override_conn_list(codec, 0x17, 2, conn);
5377 }
5378}
5379
Keith Packard98973f22015-07-15 12:14:39 -07005380/* Hook to update amp GPIO4 for automute */
5381static void alc280_hp_gpio4_automute_hook(struct hda_codec *codec,
5382 struct hda_jack_callback *jack)
5383{
5384 struct alc_spec *spec = codec->spec;
5385
5386 snd_hda_gen_hp_automute(codec, jack);
5387 /* mute_led_polarity is set to 0, so we pass inverted value here */
5388 alc_update_gpio_led(codec, 0x10, !spec->gen.hp_jack_present);
5389}
5390
5391/* Manage GPIOs for HP EliteBook Folio 9480m.
5392 *
5393 * GPIO4 is the headphone amplifier power control
5394 * GPIO3 is the audio output mute indicator LED
5395 */
5396
5397static void alc280_fixup_hp_9480m(struct hda_codec *codec,
5398 const struct hda_fixup *fix,
5399 int action)
5400{
5401 struct alc_spec *spec = codec->spec;
Keith Packard98973f22015-07-15 12:14:39 -07005402
Takashi Iwai01e4a272018-06-19 22:47:30 +02005403 alc_fixup_hp_gpio_led(codec, action, 0x08, 0);
Keith Packard98973f22015-07-15 12:14:39 -07005404 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai01e4a272018-06-19 22:47:30 +02005405 /* amp at GPIO4; toggled via alc280_hp_gpio4_automute_hook() */
5406 spec->gpio_mask |= 0x10;
5407 spec->gpio_dir |= 0x10;
Keith Packard98973f22015-07-15 12:14:39 -07005408 spec->gen.hp_automute_hook = alc280_hp_gpio4_automute_hook;
Keith Packard98973f22015-07-15 12:14:39 -07005409 }
5410}
5411
Takashi Iwaiae065f12018-06-19 23:00:03 +02005412static void alc275_fixup_gpio4_off(struct hda_codec *codec,
5413 const struct hda_fixup *fix,
5414 int action)
5415{
5416 struct alc_spec *spec = codec->spec;
5417
5418 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5419 spec->gpio_mask |= 0x04;
5420 spec->gpio_dir |= 0x04;
5421 /* set data bit low */
5422 }
5423}
5424
Kailang Yangca169cc2017-04-25 16:17:40 +08005425static void alc233_alc662_fixup_lenovo_dual_codecs(struct hda_codec *codec,
5426 const struct hda_fixup *fix,
5427 int action)
5428{
5429 alc_fixup_dual_codecs(codec, fix, action);
5430 switch (action) {
5431 case HDA_FIXUP_ACT_PRE_PROBE:
5432 /* override card longname to provide a unique UCM profile */
5433 strcpy(codec->card->longname, "HDAudio-Lenovo-DualCodecs");
5434 break;
5435 case HDA_FIXUP_ACT_BUILD:
5436 /* rename Capture controls depending on the codec */
5437 rename_ctl(codec, "Capture Volume",
5438 codec->addr == 0 ?
5439 "Rear-Panel Capture Volume" :
5440 "Front-Panel Capture Volume");
5441 rename_ctl(codec, "Capture Switch",
5442 codec->addr == 0 ?
5443 "Rear-Panel Capture Switch" :
5444 "Front-Panel Capture Switch");
5445 break;
5446 }
5447}
5448
Kailang Yang92266652017-12-14 15:28:58 +08005449/* Forcibly assign NID 0x03 to HP/LO while NID 0x02 to SPK for EQ */
5450static void alc274_fixup_bind_dacs(struct hda_codec *codec,
5451 const struct hda_fixup *fix, int action)
5452{
5453 struct alc_spec *spec = codec->spec;
5454 static hda_nid_t preferred_pairs[] = {
5455 0x21, 0x03, 0x1b, 0x03, 0x16, 0x02,
5456 0
5457 };
5458
5459 if (action != HDA_FIXUP_ACT_PRE_PROBE)
5460 return;
5461
5462 spec->gen.preferred_dacs = preferred_pairs;
Kailang Yang0700d3d2019-04-26 16:13:54 +08005463 spec->gen.auto_mute_via_amp = 1;
5464 codec->power_save_node = 0;
Kailang Yang92266652017-12-14 15:28:58 +08005465}
5466
Hui Wangc4cfcf62018-11-26 14:17:16 +08005467/* The DAC of NID 0x3 will introduce click/pop noise on headphones, so invalidate it */
5468static void alc285_fixup_invalidate_dacs(struct hda_codec *codec,
5469 const struct hda_fixup *fix, int action)
5470{
5471 if (action != HDA_FIXUP_ACT_PRE_PROBE)
5472 return;
5473
5474 snd_hda_override_wcaps(codec, 0x03, 0);
5475}
5476
Kailang Yange8547472018-11-28 15:32:45 +08005477static const struct hda_jack_keymap alc_headset_btn_keymap[] = {
5478 { SND_JACK_BTN_0, KEY_PLAYPAUSE },
5479 { SND_JACK_BTN_1, KEY_VOICECOMMAND },
5480 { SND_JACK_BTN_2, KEY_VOLUMEUP },
5481 { SND_JACK_BTN_3, KEY_VOLUMEDOWN },
5482 {}
5483};
5484
5485static void alc_headset_btn_callback(struct hda_codec *codec,
5486 struct hda_jack_callback *jack)
5487{
5488 int report = 0;
5489
5490 if (jack->unsol_res & (7 << 13))
5491 report |= SND_JACK_BTN_0;
5492
5493 if (jack->unsol_res & (1 << 16 | 3 << 8))
5494 report |= SND_JACK_BTN_1;
5495
5496 /* Volume up key */
5497 if (jack->unsol_res & (7 << 23))
5498 report |= SND_JACK_BTN_2;
5499
5500 /* Volume down key */
5501 if (jack->unsol_res & (7 << 10))
5502 report |= SND_JACK_BTN_3;
5503
5504 jack->jack->button_state = report;
5505}
5506
Kailang Yang8983eb62019-04-03 15:31:49 +08005507static void alc_fixup_headset_jack(struct hda_codec *codec,
Kailang Yange8547472018-11-28 15:32:45 +08005508 const struct hda_fixup *fix, int action)
5509{
5510
5511 switch (action) {
5512 case HDA_FIXUP_ACT_PRE_PROBE:
5513 snd_hda_jack_detect_enable_callback(codec, 0x55,
5514 alc_headset_btn_callback);
5515 snd_hda_jack_add_kctl(codec, 0x55, "Headset Jack", false,
5516 SND_JACK_HEADSET, alc_headset_btn_keymap);
5517 break;
5518 case HDA_FIXUP_ACT_INIT:
5519 switch (codec->core.vendor_id) {
5520 case 0x10ec0225:
5521 case 0x10ec0295:
5522 case 0x10ec0299:
5523 alc_write_coef_idx(codec, 0x48, 0xd011);
5524 alc_update_coef_idx(codec, 0x49, 0x007f, 0x0045);
5525 alc_update_coef_idx(codec, 0x44, 0x007f << 8, 0x0045 << 8);
5526 break;
5527 case 0x10ec0236:
5528 case 0x10ec0256:
5529 alc_write_coef_idx(codec, 0x48, 0xd011);
5530 alc_update_coef_idx(codec, 0x49, 0x007f, 0x0045);
5531 break;
5532 }
5533 break;
5534 }
5535}
5536
Kailang Yang8983eb62019-04-03 15:31:49 +08005537static void alc295_fixup_chromebook(struct hda_codec *codec,
5538 const struct hda_fixup *fix, int action)
5539{
Kailang Yangd3ba58b2019-05-06 15:09:42 +08005540 struct alc_spec *spec = codec->spec;
5541
Kailang Yang8983eb62019-04-03 15:31:49 +08005542 switch (action) {
Kailang Yangd3ba58b2019-05-06 15:09:42 +08005543 case HDA_FIXUP_ACT_PRE_PROBE:
5544 spec->ultra_low_power = true;
5545 break;
Kailang Yang8983eb62019-04-03 15:31:49 +08005546 case HDA_FIXUP_ACT_INIT:
5547 switch (codec->core.vendor_id) {
5548 case 0x10ec0295:
5549 alc_update_coef_idx(codec, 0x4a, 0x8000, 1 << 15); /* Reset HP JD */
5550 alc_update_coef_idx(codec, 0x4a, 0x8000, 0 << 15);
5551 break;
5552 case 0x10ec0236:
5553 alc_update_coef_idx(codec, 0x1b, 0x8000, 1 << 15); /* Reset HP JD */
5554 alc_update_coef_idx(codec, 0x1b, 0x8000, 0 << 15);
5555 break;
5556 }
5557 break;
5558 }
5559}
5560
Kailang Yangd1dd4212019-01-09 17:05:24 +08005561static void alc_fixup_disable_mic_vref(struct hda_codec *codec,
5562 const struct hda_fixup *fix, int action)
5563{
5564 if (action == HDA_FIXUP_ACT_PRE_PROBE)
5565 snd_hda_codec_set_pin_target(codec, 0x19, PIN_VREFHIZ);
5566}
5567
Takashi Iwaib317b032014-01-08 11:44:21 +01005568/* for hda_fixup_thinkpad_acpi() */
5569#include "thinkpad_helper.c"
David Henningssonb67ae3f2013-11-05 13:11:37 +01005570
Takashi Iwaid5a6cab2018-06-13 12:43:10 +02005571static void alc_fixup_thinkpad_acpi(struct hda_codec *codec,
5572 const struct hda_fixup *fix, int action)
5573{
5574 alc_fixup_no_shutup(codec, fix, action); /* reduce click noise */
5575 hda_fixup_thinkpad_acpi(codec, fix, action);
5576}
5577
Tom Bridenbbf8ff62018-05-29 17:34:20 +01005578/* for alc295_fixup_hp_top_speakers */
5579#include "hp_x360_helper.c"
5580
Takashi Iwai1d045db2011-07-07 18:23:21 +02005581enum {
5582 ALC269_FIXUP_SONY_VAIO,
5583 ALC275_FIXUP_SONY_VAIO_GPIO2,
5584 ALC269_FIXUP_DELL_M101Z,
5585 ALC269_FIXUP_SKU_IGNORE,
5586 ALC269_FIXUP_ASUS_G73JW,
5587 ALC269_FIXUP_LENOVO_EAPD,
5588 ALC275_FIXUP_SONY_HWEQ,
Takashi Iwaie9bd7d52014-05-21 11:06:49 +02005589 ALC275_FIXUP_SONY_DISABLE_AAMIX,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005590 ALC271_FIXUP_DMIC,
Takashi Iwai017f2a12011-07-09 14:42:25 +02005591 ALC269_FIXUP_PCM_44K,
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02005592 ALC269_FIXUP_STEREO_DMIC,
David Henningsson7c478f02013-10-11 10:18:46 +02005593 ALC269_FIXUP_HEADSET_MIC,
Takashi Iwai24519912011-08-16 15:08:49 +02005594 ALC269_FIXUP_QUANTA_MUTE,
5595 ALC269_FIXUP_LIFEBOOK,
David Henningsson2041d562014-06-13 11:15:44 +02005596 ALC269_FIXUP_LIFEBOOK_EXTMIC,
Takashi Iwaicc7016a2015-04-08 20:47:55 +02005597 ALC269_FIXUP_LIFEBOOK_HP_PIN,
Takashi Iwai4df3fd12015-06-29 08:38:02 +02005598 ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT,
Jan-Marek Glogowskifdcc9682018-02-14 11:29:15 +01005599 ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC,
Takashi Iwaia4297b52011-08-23 18:40:12 +02005600 ALC269_FIXUP_AMIC,
5601 ALC269_FIXUP_DMIC,
5602 ALC269VB_FIXUP_AMIC,
5603 ALC269VB_FIXUP_DMIC,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01005604 ALC269_FIXUP_HP_MUTE_LED,
David Henningssond06ac142013-02-18 11:41:55 +01005605 ALC269_FIXUP_HP_MUTE_LED_MIC1,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01005606 ALC269_FIXUP_HP_MUTE_LED_MIC2,
Tom Briden7f783bd2017-03-25 10:12:01 +00005607 ALC269_FIXUP_HP_MUTE_LED_MIC3,
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01005608 ALC269_FIXUP_HP_GPIO_LED,
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08005609 ALC269_FIXUP_HP_GPIO_MIC1_LED,
5610 ALC269_FIXUP_HP_LINE1_MIC1_LED,
David Henningsson693b6132012-06-22 19:12:10 +02005611 ALC269_FIXUP_INV_DMIC,
David Henningsson108cc102012-07-20 10:37:25 +02005612 ALC269_FIXUP_LENOVO_DOCK,
Takashi Iwai9b745ab2014-03-07 08:37:19 +01005613 ALC269_FIXUP_NO_SHUTUP,
David Henningsson88cfcf82013-10-11 10:18:45 +02005614 ALC286_FIXUP_SONY_MIC_NO_PRESENCE,
David Henningsson108cc102012-07-20 10:37:25 +02005615 ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT,
David Henningsson73bdd592013-04-15 15:44:14 +02005616 ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
5617 ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
David Henningsson338cae52013-10-07 10:39:59 +02005618 ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
Kailang Yangfcc6c872017-06-29 15:21:27 +08005619 ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
David Henningsson73bdd592013-04-15 15:44:14 +02005620 ALC269_FIXUP_HEADSET_MODE,
5621 ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC,
Takashi Iwai78197172015-06-27 10:21:13 +02005622 ALC269_FIXUP_ASPIRE_HEADSET_MIC,
David Henningssond240d1d2013-04-15 12:50:02 +02005623 ALC269_FIXUP_ASUS_X101_FUNC,
5624 ALC269_FIXUP_ASUS_X101_VERB,
5625 ALC269_FIXUP_ASUS_X101,
Dylan Reid08a978d2012-11-18 22:56:40 -08005626 ALC271_FIXUP_AMIC_MIC2,
5627 ALC271_FIXUP_HP_GATE_MIC_JACK,
Oleksij Rempelb1e89722013-12-04 20:50:53 +01005628 ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572,
Dylan Reid42397002013-04-05 14:58:22 -07005629 ALC269_FIXUP_ACER_AC700,
David Henningsson3e0d6112013-04-22 14:30:14 +02005630 ALC269_FIXUP_LIMIT_INT_MIC_BOOST,
Oleksij Rempel2cede302013-11-27 17:12:03 +01005631 ALC269VB_FIXUP_ASUS_ZENBOOK,
Takashi Iwai23870832013-11-29 14:13:12 +01005632 ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A,
David Henningsson8e35cd42013-11-06 11:20:01 +01005633 ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED,
Anisse Astier02b504d2013-06-03 11:53:10 +02005634 ALC269VB_FIXUP_ORDISSIMO_EVE2,
Kailang Yangcd217a62013-08-22 10:15:24 +02005635 ALC283_FIXUP_CHROME_BOOK,
Kailang Yang0202e992013-12-02 15:20:15 +08005636 ALC283_FIXUP_SENSE_COMBO_JACK,
Takashi Iwai7bba2152013-09-06 15:45:38 +02005637 ALC282_FIXUP_ASUS_TX300,
Kailang Yang1bb3e062013-09-27 13:10:25 +02005638 ALC283_FIXUP_INT_MIC,
David Henningsson338cae52013-10-07 10:39:59 +02005639 ALC290_FIXUP_MONO_SPEAKERS,
David Henningsson0f4881d2013-12-20 16:08:13 +01005640 ALC290_FIXUP_MONO_SPEAKERS_HSJACK,
5641 ALC290_FIXUP_SUBWOOFER,
5642 ALC290_FIXUP_SUBWOOFER_HSJACK,
David Henningssonb67ae3f2013-11-05 13:11:37 +01005643 ALC269_FIXUP_THINKPAD_ACPI,
David Henningsson56f27012016-01-11 09:33:14 +01005644 ALC269_FIXUP_DMIC_THINKPAD_ACPI,
Chris Chiu5824ce82017-02-28 14:17:11 -06005645 ALC255_FIXUP_ACER_MIC_NO_PRESENCE,
Chris Chiu615966a2017-02-28 14:17:12 -06005646 ALC255_FIXUP_ASUS_MIC_NO_PRESENCE,
Kailang Yang9a22a8f52013-11-08 15:54:49 +08005647 ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Kailang Yang31278992014-03-03 15:27:22 +08005648 ALC255_FIXUP_DELL2_MIC_NO_PRESENCE,
Kailang Yang9a22a8f52013-11-08 15:54:49 +08005649 ALC255_FIXUP_HEADSET_MODE,
Kailang Yang31278992014-03-03 15:27:22 +08005650 ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC,
Kailang Yanga22aa262014-04-23 17:34:28 +08005651 ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
Takashi Iwai1c37c222014-05-06 17:34:42 +02005652 ALC292_FIXUP_TPT440_DOCK,
Takashi Iwai9a811232015-12-09 15:17:43 +01005653 ALC292_FIXUP_TPT440,
Anisse Astierabaa22742016-08-24 09:14:13 +02005654 ALC283_FIXUP_HEADSET_MIC,
Takashi Iwaib3802782018-11-26 17:47:46 +01005655 ALC255_FIXUP_MIC_MUTE_LED,
Takashi Iwai1a22e772014-08-27 08:19:05 +02005656 ALC282_FIXUP_ASPIRE_V5_PINS,
David Henningsson7a5255f2014-10-30 08:26:01 +01005657 ALC280_FIXUP_HP_GPIO4,
Kailang Yangeaa8e5e2014-11-21 15:49:11 +08005658 ALC286_FIXUP_HP_GPIO_LED,
David Henningsson33f4acd2015-01-07 15:50:13 +01005659 ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY,
TienFu Chenb4b33f92015-01-20 15:06:21 +01005660 ALC280_FIXUP_HP_DOCK_PINS,
Jaroslav Kysela04d54662017-03-09 13:29:13 +01005661 ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED,
Keith Packard98973f22015-07-15 12:14:39 -07005662 ALC280_FIXUP_HP_9480M,
Kailang Yange1e62b92015-04-08 16:01:22 +08005663 ALC288_FIXUP_DELL_HEADSET_MODE,
5664 ALC288_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang831bfdf92015-06-26 12:35:17 +08005665 ALC288_FIXUP_DELL_XPS_13,
5666 ALC288_FIXUP_DISABLE_AAMIX,
Takashi Iwai8b99aba2015-06-15 11:59:32 +02005667 ALC292_FIXUP_DELL_E7X,
5668 ALC292_FIXUP_DISABLE_AAMIX,
David Henningssonc04017e2015-12-15 14:44:03 +01005669 ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK,
Kailang Yang977e6272015-05-18 15:31:20 +08005670 ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang2f726ae2017-03-31 10:31:40 +08005671 ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE,
Kailang Yang6ed11312015-10-26 15:37:39 +08005672 ALC275_FIXUP_DELL_XPS,
Hui Wang8c697292015-11-24 11:08:18 +08005673 ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE,
Hui Wang23adc192015-12-08 12:27:18 +08005674 ALC293_FIXUP_LENOVO_SPK_NOISE,
Kailang3694cb22015-12-28 11:35:24 +08005675 ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY,
Kai-Heng Feng3b43b712016-02-25 15:19:38 +08005676 ALC255_FIXUP_DELL_SPK_NOISE,
Kailang Yangd1dd4212019-01-09 17:05:24 +08005677 ALC225_FIXUP_DISABLE_MIC_VREF,
David Henningsson2ae95572016-02-25 09:37:05 +01005678 ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
Takashi Iwaie312a862018-03-06 12:14:17 +01005679 ALC295_FIXUP_DISABLE_DAC3,
Takashi Iwaif8839822016-02-25 14:31:59 +01005680 ALC280_FIXUP_HP_HEADSET_MIC,
Hui Wange549d192016-04-01 11:00:15 +08005681 ALC221_FIXUP_HP_FRONT_MIC,
Sven Eckelmannc636b952016-04-11 16:55:26 +02005682 ALC292_FIXUP_TPT460,
Hui Wangdd9aa332016-08-01 10:20:32 +08005683 ALC298_FIXUP_SPK_VOLUME,
Kai-Heng Fengfd06c772016-08-30 15:36:34 +08005684 ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER,
Gabriele Mazzotta823ff162016-12-24 19:50:01 +01005685 ALC269_FIXUP_ATIV_BOOK_8,
Kailang Yang9eb5d0e2017-01-17 15:40:25 +08005686 ALC221_FIXUP_HP_MIC_NO_PRESENCE,
Chris Chiuc1732ed2017-02-28 14:17:13 -06005687 ALC256_FIXUP_ASUS_HEADSET_MODE,
5688 ALC256_FIXUP_ASUS_MIC,
Chris Chiueeed4cd2017-02-28 14:17:15 -06005689 ALC256_FIXUP_ASUS_AIO_GPIO2,
Chris Chiu216d7ae2017-02-28 14:17:14 -06005690 ALC233_FIXUP_ASUS_MIC_NO_PRESENCE,
5691 ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE,
Kailang Yangca169cc2017-04-25 16:17:40 +08005692 ALC233_FIXUP_LENOVO_MULTI_CODECS,
Jian-Hong Panea5c7eb2019-04-01 11:25:05 +08005693 ALC233_FIXUP_ACER_HEADSET_MIC,
Hui Wangf33f79f2017-07-07 12:08:29 +08005694 ALC294_FIXUP_LENOVO_MIC_LOCATION,
Kailang Yang5f364132017-07-25 16:28:16 +08005695 ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE,
PeiSen Houb84e8432017-09-01 15:11:56 +08005696 ALC700_FIXUP_INTEL_REFERENCE,
Kailang Yang92266652017-12-14 15:28:58 +08005697 ALC274_FIXUP_DELL_BIND_DACS,
5698 ALC274_FIXUP_DELL_AIO_LINEOUT_VERB,
Kailang Yang61fcf8e2018-02-02 15:26:46 +08005699 ALC298_FIXUP_TPT470_DOCK,
Kailang Yangae104a22018-02-05 16:07:20 +08005700 ALC255_FIXUP_DUMMY_LINEOUT_VERB,
Kailang Yangf0ba9d62018-03-16 11:46:08 +08005701 ALC255_FIXUP_DELL_HEADSET_MIC,
Ayman Bagabas8ac51bb2018-12-12 18:07:57 -05005702 ALC256_FIXUP_HUAWEI_MBXP_PINS,
Tom Bridenbbf8ff62018-05-29 17:34:20 +01005703 ALC295_FIXUP_HP_X360,
Kailang Yang8a328ac2018-08-21 16:54:41 +08005704 ALC221_FIXUP_HP_HEADSET_MIC,
Hui Wangc4cfcf62018-11-26 14:17:16 +08005705 ALC285_FIXUP_LENOVO_HEADPHONE_NOISE,
Girija Kumar Kasinadhunie8ed64b2018-11-26 13:40:46 -05005706 ALC295_FIXUP_HP_AUTO_MUTE,
Chris Chiu33aaebd2018-12-05 14:48:53 +08005707 ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE,
Chris Chiud8ae4582018-12-07 17:17:11 +08005708 ALC294_FIXUP_ASUS_MIC,
Jian-Hong Pan4e051102018-12-07 17:17:12 +08005709 ALC294_FIXUP_ASUS_HEADSET_MIC,
5710 ALC294_FIXUP_ASUS_SPK,
Jeremy Soller89e3a562019-01-30 16:12:31 -07005711 ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE,
Hui Wangc8c6ee62019-02-14 11:41:33 +08005712 ALC285_FIXUP_LENOVO_PC_BEEP_IN_NOISE,
Jian-Hong Pancbc05fd2019-03-13 17:33:24 +08005713 ALC255_FIXUP_ACER_HEADSET_MIC,
Kailang Yang10f5b1b2019-02-21 16:10:22 +08005714 ALC295_FIXUP_CHROME_BOOK,
Kailang Yang8983eb62019-04-03 15:31:49 +08005715 ALC225_FIXUP_HEADSET_JACK,
Kailang Yang136824e2019-03-14 16:22:45 +08005716 ALC225_FIXUP_DELL_WYSE_AIO_MIC_NO_PRESENCE,
5717 ALC225_FIXUP_WYSE_AUTO_MUTE,
5718 ALC225_FIXUP_WYSE_DISABLE_MIC_VREF,
Jian-Hong Pan667a8f72019-03-15 17:51:09 +08005719 ALC286_FIXUP_ACER_AIO_HEADSET_MIC,
Jian-Hong Pane1037352019-03-22 11:37:18 +08005720 ALC256_FIXUP_ASUS_MIC_NO_PRESENCE,
Bernhard Rosenkraenzere2a829b2019-03-05 00:38:19 +01005721 ALC299_FIXUP_PREDATOR_SPK,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005722};
5723
Takashi Iwai1727a772013-01-10 09:52:52 +01005724static const struct hda_fixup alc269_fixups[] = {
Takashi Iwai1d045db2011-07-07 18:23:21 +02005725 [ALC269_FIXUP_SONY_VAIO] = {
Takashi Iwaifd108212013-01-10 10:18:14 +01005726 .type = HDA_FIXUP_PINCTLS,
5727 .v.pins = (const struct hda_pintbl[]) {
5728 {0x19, PIN_VREFGRD},
Takashi Iwai1d045db2011-07-07 18:23:21 +02005729 {}
5730 }
5731 },
5732 [ALC275_FIXUP_SONY_VAIO_GPIO2] = {
Takashi Iwaiae065f12018-06-19 23:00:03 +02005733 .type = HDA_FIXUP_FUNC,
5734 .v.func = alc275_fixup_gpio4_off,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005735 .chained = true,
5736 .chain_id = ALC269_FIXUP_SONY_VAIO
5737 },
5738 [ALC269_FIXUP_DELL_M101Z] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005739 .type = HDA_FIXUP_VERBS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005740 .v.verbs = (const struct hda_verb[]) {
5741 /* Enables internal speaker */
5742 {0x20, AC_VERB_SET_COEF_INDEX, 13},
5743 {0x20, AC_VERB_SET_PROC_COEF, 0x4040},
5744 {}
5745 }
5746 },
5747 [ALC269_FIXUP_SKU_IGNORE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005748 .type = HDA_FIXUP_FUNC,
Takashi Iwai23d30f22012-05-07 17:17:32 +02005749 .v.func = alc_fixup_sku_ignore,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005750 },
5751 [ALC269_FIXUP_ASUS_G73JW] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005752 .type = HDA_FIXUP_PINS,
5753 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02005754 { 0x17, 0x99130111 }, /* subwoofer */
5755 { }
5756 }
5757 },
5758 [ALC269_FIXUP_LENOVO_EAPD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005759 .type = HDA_FIXUP_VERBS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005760 .v.verbs = (const struct hda_verb[]) {
5761 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
5762 {}
5763 }
5764 },
5765 [ALC275_FIXUP_SONY_HWEQ] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005766 .type = HDA_FIXUP_FUNC,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005767 .v.func = alc269_fixup_hweq,
5768 .chained = true,
5769 .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2
5770 },
Takashi Iwaie9bd7d52014-05-21 11:06:49 +02005771 [ALC275_FIXUP_SONY_DISABLE_AAMIX] = {
5772 .type = HDA_FIXUP_FUNC,
5773 .v.func = alc_fixup_disable_aamix,
5774 .chained = true,
5775 .chain_id = ALC269_FIXUP_SONY_VAIO
5776 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02005777 [ALC271_FIXUP_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005778 .type = HDA_FIXUP_FUNC,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005779 .v.func = alc271_fixup_dmic,
5780 },
Takashi Iwai017f2a12011-07-09 14:42:25 +02005781 [ALC269_FIXUP_PCM_44K] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005782 .type = HDA_FIXUP_FUNC,
Takashi Iwai017f2a12011-07-09 14:42:25 +02005783 .v.func = alc269_fixup_pcm_44k,
David Henningsson012e7eb2012-08-08 08:43:37 +02005784 .chained = true,
5785 .chain_id = ALC269_FIXUP_QUANTA_MUTE
Takashi Iwai017f2a12011-07-09 14:42:25 +02005786 },
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02005787 [ALC269_FIXUP_STEREO_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005788 .type = HDA_FIXUP_FUNC,
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02005789 .v.func = alc269_fixup_stereo_dmic,
5790 },
David Henningsson7c478f02013-10-11 10:18:46 +02005791 [ALC269_FIXUP_HEADSET_MIC] = {
5792 .type = HDA_FIXUP_FUNC,
5793 .v.func = alc269_fixup_headset_mic,
5794 },
Takashi Iwai24519912011-08-16 15:08:49 +02005795 [ALC269_FIXUP_QUANTA_MUTE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005796 .type = HDA_FIXUP_FUNC,
Takashi Iwai24519912011-08-16 15:08:49 +02005797 .v.func = alc269_fixup_quanta_mute,
5798 },
5799 [ALC269_FIXUP_LIFEBOOK] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005800 .type = HDA_FIXUP_PINS,
5801 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai24519912011-08-16 15:08:49 +02005802 { 0x1a, 0x2101103f }, /* dock line-out */
5803 { 0x1b, 0x23a11040 }, /* dock mic-in */
5804 { }
5805 },
5806 .chained = true,
5807 .chain_id = ALC269_FIXUP_QUANTA_MUTE
5808 },
David Henningsson2041d562014-06-13 11:15:44 +02005809 [ALC269_FIXUP_LIFEBOOK_EXTMIC] = {
5810 .type = HDA_FIXUP_PINS,
5811 .v.pins = (const struct hda_pintbl[]) {
5812 { 0x19, 0x01a1903c }, /* headset mic, with jack detect */
5813 { }
5814 },
5815 },
Takashi Iwaicc7016a2015-04-08 20:47:55 +02005816 [ALC269_FIXUP_LIFEBOOK_HP_PIN] = {
5817 .type = HDA_FIXUP_PINS,
5818 .v.pins = (const struct hda_pintbl[]) {
5819 { 0x21, 0x0221102f }, /* HP out */
5820 { }
5821 },
5822 },
Takashi Iwai4df3fd12015-06-29 08:38:02 +02005823 [ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT] = {
5824 .type = HDA_FIXUP_FUNC,
5825 .v.func = alc269_fixup_pincfg_no_hp_to_lineout,
5826 },
Jan-Marek Glogowskifdcc9682018-02-14 11:29:15 +01005827 [ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC] = {
5828 .type = HDA_FIXUP_FUNC,
5829 .v.func = alc269_fixup_pincfg_U7x7_headset_mic,
5830 },
Takashi Iwaia4297b52011-08-23 18:40:12 +02005831 [ALC269_FIXUP_AMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005832 .type = HDA_FIXUP_PINS,
5833 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaia4297b52011-08-23 18:40:12 +02005834 { 0x14, 0x99130110 }, /* speaker */
5835 { 0x15, 0x0121401f }, /* HP out */
5836 { 0x18, 0x01a19c20 }, /* mic */
5837 { 0x19, 0x99a3092f }, /* int-mic */
5838 { }
5839 },
5840 },
5841 [ALC269_FIXUP_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005842 .type = HDA_FIXUP_PINS,
5843 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaia4297b52011-08-23 18:40:12 +02005844 { 0x12, 0x99a3092f }, /* int-mic */
5845 { 0x14, 0x99130110 }, /* speaker */
5846 { 0x15, 0x0121401f }, /* HP out */
5847 { 0x18, 0x01a19c20 }, /* mic */
5848 { }
5849 },
5850 },
5851 [ALC269VB_FIXUP_AMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005852 .type = HDA_FIXUP_PINS,
5853 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaia4297b52011-08-23 18:40:12 +02005854 { 0x14, 0x99130110 }, /* speaker */
5855 { 0x18, 0x01a19c20 }, /* mic */
5856 { 0x19, 0x99a3092f }, /* int-mic */
5857 { 0x21, 0x0121401f }, /* HP out */
5858 { }
5859 },
5860 },
David Henningsson2267ea92012-01-03 08:45:56 +01005861 [ALC269VB_FIXUP_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005862 .type = HDA_FIXUP_PINS,
5863 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaia4297b52011-08-23 18:40:12 +02005864 { 0x12, 0x99a3092f }, /* int-mic */
5865 { 0x14, 0x99130110 }, /* speaker */
5866 { 0x18, 0x01a19c20 }, /* mic */
5867 { 0x21, 0x0121401f }, /* HP out */
5868 { }
5869 },
5870 },
Takashi Iwai08fb0d02013-01-10 17:33:58 +01005871 [ALC269_FIXUP_HP_MUTE_LED] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005872 .type = HDA_FIXUP_FUNC,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01005873 .v.func = alc269_fixup_hp_mute_led,
David Henningsson6d3cd5d2013-01-07 12:03:47 +01005874 },
David Henningssond06ac142013-02-18 11:41:55 +01005875 [ALC269_FIXUP_HP_MUTE_LED_MIC1] = {
5876 .type = HDA_FIXUP_FUNC,
5877 .v.func = alc269_fixup_hp_mute_led_mic1,
5878 },
Takashi Iwai08fb0d02013-01-10 17:33:58 +01005879 [ALC269_FIXUP_HP_MUTE_LED_MIC2] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005880 .type = HDA_FIXUP_FUNC,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01005881 .v.func = alc269_fixup_hp_mute_led_mic2,
Takashi Iwai420b0fe2012-03-12 12:35:27 +01005882 },
Tom Briden7f783bd2017-03-25 10:12:01 +00005883 [ALC269_FIXUP_HP_MUTE_LED_MIC3] = {
5884 .type = HDA_FIXUP_FUNC,
5885 .v.func = alc269_fixup_hp_mute_led_mic3,
Girija Kumar Kasinadhunie8ed64b2018-11-26 13:40:46 -05005886 .chained = true,
5887 .chain_id = ALC295_FIXUP_HP_AUTO_MUTE
Tom Briden7f783bd2017-03-25 10:12:01 +00005888 },
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01005889 [ALC269_FIXUP_HP_GPIO_LED] = {
5890 .type = HDA_FIXUP_FUNC,
5891 .v.func = alc269_fixup_hp_gpio_led,
5892 },
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08005893 [ALC269_FIXUP_HP_GPIO_MIC1_LED] = {
5894 .type = HDA_FIXUP_FUNC,
5895 .v.func = alc269_fixup_hp_gpio_mic1_led,
5896 },
5897 [ALC269_FIXUP_HP_LINE1_MIC1_LED] = {
5898 .type = HDA_FIXUP_FUNC,
5899 .v.func = alc269_fixup_hp_line1_mic1_led,
5900 },
David Henningsson693b6132012-06-22 19:12:10 +02005901 [ALC269_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005902 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02005903 .v.func = alc_fixup_inv_dmic,
David Henningsson693b6132012-06-22 19:12:10 +02005904 },
Takashi Iwai9b745ab2014-03-07 08:37:19 +01005905 [ALC269_FIXUP_NO_SHUTUP] = {
5906 .type = HDA_FIXUP_FUNC,
5907 .v.func = alc_fixup_no_shutup,
5908 },
David Henningsson108cc102012-07-20 10:37:25 +02005909 [ALC269_FIXUP_LENOVO_DOCK] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005910 .type = HDA_FIXUP_PINS,
5911 .v.pins = (const struct hda_pintbl[]) {
David Henningsson108cc102012-07-20 10:37:25 +02005912 { 0x19, 0x23a11040 }, /* dock mic */
5913 { 0x1b, 0x2121103f }, /* dock headphone */
5914 { }
5915 },
5916 .chained = true,
5917 .chain_id = ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT
5918 },
5919 [ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005920 .type = HDA_FIXUP_FUNC,
David Henningsson108cc102012-07-20 10:37:25 +02005921 .v.func = alc269_fixup_pincfg_no_hp_to_lineout,
David Henningsson52129002013-11-19 10:25:53 +01005922 .chained = true,
5923 .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
David Henningsson108cc102012-07-20 10:37:25 +02005924 },
David Henningsson73bdd592013-04-15 15:44:14 +02005925 [ALC269_FIXUP_DELL1_MIC_NO_PRESENCE] = {
5926 .type = HDA_FIXUP_PINS,
5927 .v.pins = (const struct hda_pintbl[]) {
5928 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5929 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
5930 { }
5931 },
5932 .chained = true,
5933 .chain_id = ALC269_FIXUP_HEADSET_MODE
5934 },
5935 [ALC269_FIXUP_DELL2_MIC_NO_PRESENCE] = {
5936 .type = HDA_FIXUP_PINS,
5937 .v.pins = (const struct hda_pintbl[]) {
5938 { 0x16, 0x21014020 }, /* dock line out */
5939 { 0x19, 0x21a19030 }, /* dock mic */
5940 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5941 { }
5942 },
5943 .chained = true,
5944 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
5945 },
David Henningsson338cae52013-10-07 10:39:59 +02005946 [ALC269_FIXUP_DELL3_MIC_NO_PRESENCE] = {
5947 .type = HDA_FIXUP_PINS,
5948 .v.pins = (const struct hda_pintbl[]) {
5949 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5950 { }
5951 },
5952 .chained = true,
5953 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
5954 },
Kailang Yangfcc6c872017-06-29 15:21:27 +08005955 [ALC269_FIXUP_DELL4_MIC_NO_PRESENCE] = {
5956 .type = HDA_FIXUP_PINS,
5957 .v.pins = (const struct hda_pintbl[]) {
5958 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5959 { 0x1b, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
5960 { }
5961 },
5962 .chained = true,
5963 .chain_id = ALC269_FIXUP_HEADSET_MODE
5964 },
David Henningsson73bdd592013-04-15 15:44:14 +02005965 [ALC269_FIXUP_HEADSET_MODE] = {
5966 .type = HDA_FIXUP_FUNC,
5967 .v.func = alc_fixup_headset_mode,
Hui Wang6676f302014-11-18 17:57:41 +08005968 .chained = true,
Takashi Iwaib3802782018-11-26 17:47:46 +01005969 .chain_id = ALC255_FIXUP_MIC_MUTE_LED
David Henningsson73bdd592013-04-15 15:44:14 +02005970 },
5971 [ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC] = {
5972 .type = HDA_FIXUP_FUNC,
5973 .v.func = alc_fixup_headset_mode_no_hp_mic,
5974 },
Takashi Iwai78197172015-06-27 10:21:13 +02005975 [ALC269_FIXUP_ASPIRE_HEADSET_MIC] = {
5976 .type = HDA_FIXUP_PINS,
5977 .v.pins = (const struct hda_pintbl[]) {
5978 { 0x19, 0x01a1913c }, /* headset mic w/o jack detect */
5979 { }
5980 },
5981 .chained = true,
5982 .chain_id = ALC269_FIXUP_HEADSET_MODE,
5983 },
David Henningsson88cfcf82013-10-11 10:18:45 +02005984 [ALC286_FIXUP_SONY_MIC_NO_PRESENCE] = {
5985 .type = HDA_FIXUP_PINS,
5986 .v.pins = (const struct hda_pintbl[]) {
5987 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5988 { }
5989 },
David Henningssonfbc78ad2013-10-11 13:46:04 +02005990 .chained = true,
5991 .chain_id = ALC269_FIXUP_HEADSET_MIC
David Henningsson88cfcf82013-10-11 10:18:45 +02005992 },
Ayman Bagabas8ac51bb2018-12-12 18:07:57 -05005993 [ALC256_FIXUP_HUAWEI_MBXP_PINS] = {
5994 .type = HDA_FIXUP_PINS,
5995 .v.pins = (const struct hda_pintbl[]) {
5996 {0x12, 0x90a60130},
5997 {0x13, 0x40000000},
5998 {0x14, 0x90170110},
5999 {0x18, 0x411111f0},
6000 {0x19, 0x04a11040},
6001 {0x1a, 0x411111f0},
6002 {0x1b, 0x90170112},
6003 {0x1d, 0x40759a05},
6004 {0x1e, 0x411111f0},
6005 {0x21, 0x04211020},
6006 { }
6007 },
Ayman Bagabase2744fd2018-12-12 18:07:59 -05006008 .chained = true,
6009 .chain_id = ALC255_FIXUP_MIC_MUTE_LED
Ayman Bagabas8ac51bb2018-12-12 18:07:57 -05006010 },
David Henningssond240d1d2013-04-15 12:50:02 +02006011 [ALC269_FIXUP_ASUS_X101_FUNC] = {
6012 .type = HDA_FIXUP_FUNC,
6013 .v.func = alc269_fixup_x101_headset_mic,
6014 },
6015 [ALC269_FIXUP_ASUS_X101_VERB] = {
6016 .type = HDA_FIXUP_VERBS,
6017 .v.verbs = (const struct hda_verb[]) {
6018 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6019 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
6020 {0x20, AC_VERB_SET_PROC_COEF, 0x0310},
6021 { }
6022 },
6023 .chained = true,
6024 .chain_id = ALC269_FIXUP_ASUS_X101_FUNC
6025 },
6026 [ALC269_FIXUP_ASUS_X101] = {
6027 .type = HDA_FIXUP_PINS,
6028 .v.pins = (const struct hda_pintbl[]) {
6029 { 0x18, 0x04a1182c }, /* Headset mic */
6030 { }
6031 },
6032 .chained = true,
6033 .chain_id = ALC269_FIXUP_ASUS_X101_VERB
6034 },
Dylan Reid08a978d2012-11-18 22:56:40 -08006035 [ALC271_FIXUP_AMIC_MIC2] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006036 .type = HDA_FIXUP_PINS,
6037 .v.pins = (const struct hda_pintbl[]) {
Dylan Reid08a978d2012-11-18 22:56:40 -08006038 { 0x14, 0x99130110 }, /* speaker */
6039 { 0x19, 0x01a19c20 }, /* mic */
6040 { 0x1b, 0x99a7012f }, /* int-mic */
6041 { 0x21, 0x0121401f }, /* HP out */
6042 { }
6043 },
6044 },
6045 [ALC271_FIXUP_HP_GATE_MIC_JACK] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006046 .type = HDA_FIXUP_FUNC,
Dylan Reid08a978d2012-11-18 22:56:40 -08006047 .v.func = alc271_hp_gate_mic_jack,
6048 .chained = true,
6049 .chain_id = ALC271_FIXUP_AMIC_MIC2,
6050 },
Oleksij Rempelb1e89722013-12-04 20:50:53 +01006051 [ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572] = {
6052 .type = HDA_FIXUP_FUNC,
6053 .v.func = alc269_fixup_limit_int_mic_boost,
6054 .chained = true,
6055 .chain_id = ALC271_FIXUP_HP_GATE_MIC_JACK,
6056 },
Dylan Reid42397002013-04-05 14:58:22 -07006057 [ALC269_FIXUP_ACER_AC700] = {
6058 .type = HDA_FIXUP_PINS,
6059 .v.pins = (const struct hda_pintbl[]) {
6060 { 0x12, 0x99a3092f }, /* int-mic */
6061 { 0x14, 0x99130110 }, /* speaker */
6062 { 0x18, 0x03a11c20 }, /* mic */
6063 { 0x1e, 0x0346101e }, /* SPDIF1 */
6064 { 0x21, 0x0321101f }, /* HP out */
6065 { }
6066 },
6067 .chained = true,
6068 .chain_id = ALC271_FIXUP_DMIC,
6069 },
David Henningsson3e0d6112013-04-22 14:30:14 +02006070 [ALC269_FIXUP_LIMIT_INT_MIC_BOOST] = {
6071 .type = HDA_FIXUP_FUNC,
6072 .v.func = alc269_fixup_limit_int_mic_boost,
David Henningsson27937692013-11-18 11:51:47 +01006073 .chained = true,
6074 .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
David Henningsson3e0d6112013-04-22 14:30:14 +02006075 },
Oleksij Rempel2cede302013-11-27 17:12:03 +01006076 [ALC269VB_FIXUP_ASUS_ZENBOOK] = {
6077 .type = HDA_FIXUP_FUNC,
6078 .v.func = alc269_fixup_limit_int_mic_boost,
6079 .chained = true,
6080 .chain_id = ALC269VB_FIXUP_DMIC,
6081 },
Takashi Iwai23870832013-11-29 14:13:12 +01006082 [ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A] = {
6083 .type = HDA_FIXUP_VERBS,
6084 .v.verbs = (const struct hda_verb[]) {
6085 /* class-D output amp +5dB */
6086 { 0x20, AC_VERB_SET_COEF_INDEX, 0x12 },
6087 { 0x20, AC_VERB_SET_PROC_COEF, 0x2800 },
6088 {}
6089 },
6090 .chained = true,
6091 .chain_id = ALC269VB_FIXUP_ASUS_ZENBOOK,
6092 },
David Henningsson8e35cd42013-11-06 11:20:01 +01006093 [ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED] = {
6094 .type = HDA_FIXUP_FUNC,
6095 .v.func = alc269_fixup_limit_int_mic_boost,
6096 .chained = true,
6097 .chain_id = ALC269_FIXUP_HP_MUTE_LED_MIC1,
6098 },
Anisse Astier02b504d2013-06-03 11:53:10 +02006099 [ALC269VB_FIXUP_ORDISSIMO_EVE2] = {
6100 .type = HDA_FIXUP_PINS,
6101 .v.pins = (const struct hda_pintbl[]) {
6102 { 0x12, 0x99a3092f }, /* int-mic */
6103 { 0x18, 0x03a11d20 }, /* mic */
6104 { 0x19, 0x411111f0 }, /* Unused bogus pin */
6105 { }
6106 },
6107 },
Kailang Yangcd217a62013-08-22 10:15:24 +02006108 [ALC283_FIXUP_CHROME_BOOK] = {
6109 .type = HDA_FIXUP_FUNC,
6110 .v.func = alc283_fixup_chromebook,
6111 },
Kailang Yang0202e992013-12-02 15:20:15 +08006112 [ALC283_FIXUP_SENSE_COMBO_JACK] = {
6113 .type = HDA_FIXUP_FUNC,
6114 .v.func = alc283_fixup_sense_combo_jack,
6115 .chained = true,
6116 .chain_id = ALC283_FIXUP_CHROME_BOOK,
6117 },
Takashi Iwai7bba2152013-09-06 15:45:38 +02006118 [ALC282_FIXUP_ASUS_TX300] = {
6119 .type = HDA_FIXUP_FUNC,
6120 .v.func = alc282_fixup_asus_tx300,
6121 },
Kailang Yang1bb3e062013-09-27 13:10:25 +02006122 [ALC283_FIXUP_INT_MIC] = {
6123 .type = HDA_FIXUP_VERBS,
6124 .v.verbs = (const struct hda_verb[]) {
6125 {0x20, AC_VERB_SET_COEF_INDEX, 0x1a},
6126 {0x20, AC_VERB_SET_PROC_COEF, 0x0011},
6127 { }
6128 },
6129 .chained = true,
6130 .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST
6131 },
David Henningsson0f4881d2013-12-20 16:08:13 +01006132 [ALC290_FIXUP_SUBWOOFER_HSJACK] = {
6133 .type = HDA_FIXUP_PINS,
6134 .v.pins = (const struct hda_pintbl[]) {
6135 { 0x17, 0x90170112 }, /* subwoofer */
6136 { }
6137 },
6138 .chained = true,
6139 .chain_id = ALC290_FIXUP_MONO_SPEAKERS_HSJACK,
6140 },
6141 [ALC290_FIXUP_SUBWOOFER] = {
6142 .type = HDA_FIXUP_PINS,
6143 .v.pins = (const struct hda_pintbl[]) {
6144 { 0x17, 0x90170112 }, /* subwoofer */
6145 { }
6146 },
6147 .chained = true,
6148 .chain_id = ALC290_FIXUP_MONO_SPEAKERS,
6149 },
David Henningsson338cae52013-10-07 10:39:59 +02006150 [ALC290_FIXUP_MONO_SPEAKERS] = {
6151 .type = HDA_FIXUP_FUNC,
6152 .v.func = alc290_fixup_mono_speakers,
David Henningsson0f4881d2013-12-20 16:08:13 +01006153 },
6154 [ALC290_FIXUP_MONO_SPEAKERS_HSJACK] = {
6155 .type = HDA_FIXUP_FUNC,
6156 .v.func = alc290_fixup_mono_speakers,
David Henningsson338cae52013-10-07 10:39:59 +02006157 .chained = true,
6158 .chain_id = ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
6159 },
David Henningssonb67ae3f2013-11-05 13:11:37 +01006160 [ALC269_FIXUP_THINKPAD_ACPI] = {
6161 .type = HDA_FIXUP_FUNC,
Takashi Iwaid5a6cab2018-06-13 12:43:10 +02006162 .v.func = alc_fixup_thinkpad_acpi,
Takashi Iwai09da1112016-09-08 12:15:02 +02006163 .chained = true,
6164 .chain_id = ALC269_FIXUP_SKU_IGNORE,
David Henningssonb67ae3f2013-11-05 13:11:37 +01006165 },
David Henningsson56f27012016-01-11 09:33:14 +01006166 [ALC269_FIXUP_DMIC_THINKPAD_ACPI] = {
6167 .type = HDA_FIXUP_FUNC,
6168 .v.func = alc_fixup_inv_dmic,
6169 .chained = true,
6170 .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
6171 },
Chris Chiu5824ce82017-02-28 14:17:11 -06006172 [ALC255_FIXUP_ACER_MIC_NO_PRESENCE] = {
6173 .type = HDA_FIXUP_PINS,
6174 .v.pins = (const struct hda_pintbl[]) {
6175 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6176 { }
6177 },
6178 .chained = true,
6179 .chain_id = ALC255_FIXUP_HEADSET_MODE
6180 },
Chris Chiu615966a2017-02-28 14:17:12 -06006181 [ALC255_FIXUP_ASUS_MIC_NO_PRESENCE] = {
6182 .type = HDA_FIXUP_PINS,
6183 .v.pins = (const struct hda_pintbl[]) {
6184 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6185 { }
6186 },
6187 .chained = true,
6188 .chain_id = ALC255_FIXUP_HEADSET_MODE
6189 },
Kailang Yang9a22a8f52013-11-08 15:54:49 +08006190 [ALC255_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6191 .type = HDA_FIXUP_PINS,
6192 .v.pins = (const struct hda_pintbl[]) {
6193 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6194 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6195 { }
6196 },
6197 .chained = true,
6198 .chain_id = ALC255_FIXUP_HEADSET_MODE
6199 },
Kailang Yang31278992014-03-03 15:27:22 +08006200 [ALC255_FIXUP_DELL2_MIC_NO_PRESENCE] = {
6201 .type = HDA_FIXUP_PINS,
6202 .v.pins = (const struct hda_pintbl[]) {
6203 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6204 { }
6205 },
6206 .chained = true,
6207 .chain_id = ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC
6208 },
Kailang Yang9a22a8f52013-11-08 15:54:49 +08006209 [ALC255_FIXUP_HEADSET_MODE] = {
6210 .type = HDA_FIXUP_FUNC,
6211 .v.func = alc_fixup_headset_mode_alc255,
Hui Wang4a83d422014-11-18 17:57:40 +08006212 .chained = true,
Takashi Iwaib3802782018-11-26 17:47:46 +01006213 .chain_id = ALC255_FIXUP_MIC_MUTE_LED
Kailang Yang9a22a8f52013-11-08 15:54:49 +08006214 },
Kailang Yang31278992014-03-03 15:27:22 +08006215 [ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC] = {
6216 .type = HDA_FIXUP_FUNC,
6217 .v.func = alc_fixup_headset_mode_alc255_no_hp_mic,
6218 },
Kailang Yanga22aa262014-04-23 17:34:28 +08006219 [ALC293_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6220 .type = HDA_FIXUP_PINS,
6221 .v.pins = (const struct hda_pintbl[]) {
6222 { 0x18, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6223 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6224 { }
6225 },
6226 .chained = true,
6227 .chain_id = ALC269_FIXUP_HEADSET_MODE
6228 },
Takashi Iwai1c37c222014-05-06 17:34:42 +02006229 [ALC292_FIXUP_TPT440_DOCK] = {
David Henningssonec56af62015-06-24 10:46:33 +02006230 .type = HDA_FIXUP_FUNC,
Takashi Iwai7f57d802015-09-24 17:36:51 +02006231 .v.func = alc_fixup_tpt440_dock,
Takashi Iwai1c37c222014-05-06 17:34:42 +02006232 .chained = true,
6233 .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST
6234 },
Takashi Iwai9a811232015-12-09 15:17:43 +01006235 [ALC292_FIXUP_TPT440] = {
6236 .type = HDA_FIXUP_FUNC,
Takashi Iwai157f0b72015-12-10 23:30:43 +01006237 .v.func = alc_fixup_disable_aamix,
Takashi Iwai9a811232015-12-09 15:17:43 +01006238 .chained = true,
6239 .chain_id = ALC292_FIXUP_TPT440_DOCK,
6240 },
Anisse Astierabaa22742016-08-24 09:14:13 +02006241 [ALC283_FIXUP_HEADSET_MIC] = {
Daniel Drake9dc12862014-07-22 10:58:29 +01006242 .type = HDA_FIXUP_PINS,
6243 .v.pins = (const struct hda_pintbl[]) {
6244 { 0x19, 0x04a110f0 },
6245 { },
6246 },
6247 },
Takashi Iwaib3802782018-11-26 17:47:46 +01006248 [ALC255_FIXUP_MIC_MUTE_LED] = {
Hui Wang00ef9942014-07-31 11:52:38 +08006249 .type = HDA_FIXUP_FUNC,
Takashi Iwaib3802782018-11-26 17:47:46 +01006250 .v.func = snd_hda_gen_fixup_micmute_led,
Hui Wang00ef9942014-07-31 11:52:38 +08006251 },
Takashi Iwai1a22e772014-08-27 08:19:05 +02006252 [ALC282_FIXUP_ASPIRE_V5_PINS] = {
6253 .type = HDA_FIXUP_PINS,
6254 .v.pins = (const struct hda_pintbl[]) {
6255 { 0x12, 0x90a60130 },
6256 { 0x14, 0x90170110 },
6257 { 0x17, 0x40000008 },
6258 { 0x18, 0x411111f0 },
Mateusz Sylwestrzak04206942015-07-19 17:38:56 +02006259 { 0x19, 0x01a1913c },
Takashi Iwai1a22e772014-08-27 08:19:05 +02006260 { 0x1a, 0x411111f0 },
6261 { 0x1b, 0x411111f0 },
6262 { 0x1d, 0x40f89b2d },
6263 { 0x1e, 0x411111f0 },
6264 { 0x21, 0x0321101f },
6265 { },
6266 },
6267 },
David Henningsson7a5255f2014-10-30 08:26:01 +01006268 [ALC280_FIXUP_HP_GPIO4] = {
6269 .type = HDA_FIXUP_FUNC,
6270 .v.func = alc280_fixup_hp_gpio4,
6271 },
Kailang Yangeaa8e5e2014-11-21 15:49:11 +08006272 [ALC286_FIXUP_HP_GPIO_LED] = {
6273 .type = HDA_FIXUP_FUNC,
6274 .v.func = alc286_fixup_hp_gpio_led,
6275 },
David Henningsson33f4acd2015-01-07 15:50:13 +01006276 [ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY] = {
6277 .type = HDA_FIXUP_FUNC,
6278 .v.func = alc280_fixup_hp_gpio2_mic_hotkey,
6279 },
TienFu Chenb4b33f92015-01-20 15:06:21 +01006280 [ALC280_FIXUP_HP_DOCK_PINS] = {
6281 .type = HDA_FIXUP_PINS,
6282 .v.pins = (const struct hda_pintbl[]) {
6283 { 0x1b, 0x21011020 }, /* line-out */
6284 { 0x1a, 0x01a1903c }, /* headset mic */
6285 { 0x18, 0x2181103f }, /* line-in */
6286 { },
6287 },
6288 .chained = true,
6289 .chain_id = ALC280_FIXUP_HP_GPIO4
6290 },
Jaroslav Kysela04d54662017-03-09 13:29:13 +01006291 [ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED] = {
6292 .type = HDA_FIXUP_PINS,
6293 .v.pins = (const struct hda_pintbl[]) {
6294 { 0x1b, 0x21011020 }, /* line-out */
6295 { 0x18, 0x2181103f }, /* line-in */
6296 { },
6297 },
6298 .chained = true,
6299 .chain_id = ALC269_FIXUP_HP_GPIO_MIC1_LED
6300 },
Keith Packard98973f22015-07-15 12:14:39 -07006301 [ALC280_FIXUP_HP_9480M] = {
6302 .type = HDA_FIXUP_FUNC,
6303 .v.func = alc280_fixup_hp_9480m,
6304 },
Kailang Yange1e62b92015-04-08 16:01:22 +08006305 [ALC288_FIXUP_DELL_HEADSET_MODE] = {
6306 .type = HDA_FIXUP_FUNC,
6307 .v.func = alc_fixup_headset_mode_dell_alc288,
6308 .chained = true,
Takashi Iwaib3802782018-11-26 17:47:46 +01006309 .chain_id = ALC255_FIXUP_MIC_MUTE_LED
Kailang Yange1e62b92015-04-08 16:01:22 +08006310 },
6311 [ALC288_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6312 .type = HDA_FIXUP_PINS,
6313 .v.pins = (const struct hda_pintbl[]) {
6314 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6315 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6316 { }
6317 },
6318 .chained = true,
6319 .chain_id = ALC288_FIXUP_DELL_HEADSET_MODE
6320 },
Hui Wang831bfdf92015-06-26 12:35:17 +08006321 [ALC288_FIXUP_DISABLE_AAMIX] = {
6322 .type = HDA_FIXUP_FUNC,
6323 .v.func = alc_fixup_disable_aamix,
6324 .chained = true,
Takashi Iwaid44a6862018-06-19 23:04:03 +02006325 .chain_id = ALC288_FIXUP_DELL1_MIC_NO_PRESENCE
Hui Wang831bfdf92015-06-26 12:35:17 +08006326 },
6327 [ALC288_FIXUP_DELL_XPS_13] = {
6328 .type = HDA_FIXUP_FUNC,
6329 .v.func = alc_fixup_dell_xps13,
6330 .chained = true,
6331 .chain_id = ALC288_FIXUP_DISABLE_AAMIX
6332 },
Takashi Iwai8b99aba2015-06-15 11:59:32 +02006333 [ALC292_FIXUP_DISABLE_AAMIX] = {
6334 .type = HDA_FIXUP_FUNC,
6335 .v.func = alc_fixup_disable_aamix,
Hui Wang831bfdf92015-06-26 12:35:17 +08006336 .chained = true,
6337 .chain_id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE
Takashi Iwai8b99aba2015-06-15 11:59:32 +02006338 },
David Henningssonc04017e2015-12-15 14:44:03 +01006339 [ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK] = {
6340 .type = HDA_FIXUP_FUNC,
6341 .v.func = alc_fixup_disable_aamix,
6342 .chained = true,
6343 .chain_id = ALC293_FIXUP_DELL1_MIC_NO_PRESENCE
6344 },
Takashi Iwai8b99aba2015-06-15 11:59:32 +02006345 [ALC292_FIXUP_DELL_E7X] = {
6346 .type = HDA_FIXUP_FUNC,
6347 .v.func = alc_fixup_dell_xps13,
6348 .chained = true,
6349 .chain_id = ALC292_FIXUP_DISABLE_AAMIX
6350 },
Kailang Yang977e6272015-05-18 15:31:20 +08006351 [ALC298_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6352 .type = HDA_FIXUP_PINS,
6353 .v.pins = (const struct hda_pintbl[]) {
6354 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6355 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6356 { }
6357 },
6358 .chained = true,
6359 .chain_id = ALC269_FIXUP_HEADSET_MODE
6360 },
Hui Wang2f726ae2017-03-31 10:31:40 +08006361 [ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE] = {
6362 .type = HDA_FIXUP_PINS,
6363 .v.pins = (const struct hda_pintbl[]) {
6364 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6365 { }
6366 },
6367 .chained = true,
6368 .chain_id = ALC269_FIXUP_HEADSET_MODE
6369 },
Kailang Yang6ed11312015-10-26 15:37:39 +08006370 [ALC275_FIXUP_DELL_XPS] = {
6371 .type = HDA_FIXUP_VERBS,
6372 .v.verbs = (const struct hda_verb[]) {
6373 /* Enables internal speaker */
6374 {0x20, AC_VERB_SET_COEF_INDEX, 0x1f},
6375 {0x20, AC_VERB_SET_PROC_COEF, 0x00c0},
6376 {0x20, AC_VERB_SET_COEF_INDEX, 0x30},
6377 {0x20, AC_VERB_SET_PROC_COEF, 0x00b1},
6378 {}
6379 }
6380 },
Hui Wang8c697292015-11-24 11:08:18 +08006381 [ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE] = {
6382 .type = HDA_FIXUP_VERBS,
6383 .v.verbs = (const struct hda_verb[]) {
6384 /* Disable pass-through path for FRONT 14h */
6385 {0x20, AC_VERB_SET_COEF_INDEX, 0x36},
6386 {0x20, AC_VERB_SET_PROC_COEF, 0x1737},
6387 {}
6388 },
6389 .chained = true,
6390 .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
6391 },
Hui Wang23adc192015-12-08 12:27:18 +08006392 [ALC293_FIXUP_LENOVO_SPK_NOISE] = {
6393 .type = HDA_FIXUP_FUNC,
6394 .v.func = alc_fixup_disable_aamix,
6395 .chained = true,
6396 .chain_id = ALC269_FIXUP_THINKPAD_ACPI
6397 },
Kailang3694cb22015-12-28 11:35:24 +08006398 [ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY] = {
6399 .type = HDA_FIXUP_FUNC,
6400 .v.func = alc233_fixup_lenovo_line2_mic_hotkey,
6401 },
Kai-Heng Feng3b43b712016-02-25 15:19:38 +08006402 [ALC255_FIXUP_DELL_SPK_NOISE] = {
6403 .type = HDA_FIXUP_FUNC,
6404 .v.func = alc_fixup_disable_aamix,
6405 .chained = true,
6406 .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
6407 },
Kailang Yangd1dd4212019-01-09 17:05:24 +08006408 [ALC225_FIXUP_DISABLE_MIC_VREF] = {
6409 .type = HDA_FIXUP_FUNC,
6410 .v.func = alc_fixup_disable_mic_vref,
6411 .chained = true,
6412 .chain_id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE
6413 },
David Henningsson2ae95572016-02-25 09:37:05 +01006414 [ALC225_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6415 .type = HDA_FIXUP_VERBS,
6416 .v.verbs = (const struct hda_verb[]) {
6417 /* Disable pass-through path for FRONT 14h */
6418 { 0x20, AC_VERB_SET_COEF_INDEX, 0x36 },
6419 { 0x20, AC_VERB_SET_PROC_COEF, 0x57d7 },
6420 {}
6421 },
6422 .chained = true,
Kailang Yangd1dd4212019-01-09 17:05:24 +08006423 .chain_id = ALC225_FIXUP_DISABLE_MIC_VREF
David Henningsson2ae95572016-02-25 09:37:05 +01006424 },
Takashi Iwaif8839822016-02-25 14:31:59 +01006425 [ALC280_FIXUP_HP_HEADSET_MIC] = {
6426 .type = HDA_FIXUP_FUNC,
6427 .v.func = alc_fixup_disable_aamix,
6428 .chained = true,
6429 .chain_id = ALC269_FIXUP_HEADSET_MIC,
6430 },
Hui Wange549d192016-04-01 11:00:15 +08006431 [ALC221_FIXUP_HP_FRONT_MIC] = {
6432 .type = HDA_FIXUP_PINS,
6433 .v.pins = (const struct hda_pintbl[]) {
6434 { 0x19, 0x02a19020 }, /* Front Mic */
6435 { }
6436 },
6437 },
Sven Eckelmannc636b952016-04-11 16:55:26 +02006438 [ALC292_FIXUP_TPT460] = {
6439 .type = HDA_FIXUP_FUNC,
6440 .v.func = alc_fixup_tpt440_dock,
6441 .chained = true,
6442 .chain_id = ALC293_FIXUP_LENOVO_SPK_NOISE,
6443 },
Hui Wangdd9aa332016-08-01 10:20:32 +08006444 [ALC298_FIXUP_SPK_VOLUME] = {
6445 .type = HDA_FIXUP_FUNC,
6446 .v.func = alc298_fixup_speaker_volume,
Hui Wang59ec4b52016-08-04 15:28:04 +08006447 .chained = true,
Hui Wang2f726ae2017-03-31 10:31:40 +08006448 .chain_id = ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE,
Hui Wangdd9aa332016-08-01 10:20:32 +08006449 },
Takashi Iwaie312a862018-03-06 12:14:17 +01006450 [ALC295_FIXUP_DISABLE_DAC3] = {
6451 .type = HDA_FIXUP_FUNC,
6452 .v.func = alc295_fixup_disable_dac3,
6453 },
Kai-Heng Fengfd06c772016-08-30 15:36:34 +08006454 [ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER] = {
6455 .type = HDA_FIXUP_PINS,
6456 .v.pins = (const struct hda_pintbl[]) {
6457 { 0x1b, 0x90170151 },
6458 { }
6459 },
6460 .chained = true,
6461 .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
6462 },
Gabriele Mazzotta823ff162016-12-24 19:50:01 +01006463 [ALC269_FIXUP_ATIV_BOOK_8] = {
6464 .type = HDA_FIXUP_FUNC,
6465 .v.func = alc_fixup_auto_mute_via_amp,
6466 .chained = true,
6467 .chain_id = ALC269_FIXUP_NO_SHUTUP
6468 },
Kailang Yang9eb5d0e2017-01-17 15:40:25 +08006469 [ALC221_FIXUP_HP_MIC_NO_PRESENCE] = {
6470 .type = HDA_FIXUP_PINS,
6471 .v.pins = (const struct hda_pintbl[]) {
6472 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6473 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6474 { }
6475 },
6476 .chained = true,
6477 .chain_id = ALC269_FIXUP_HEADSET_MODE
6478 },
Chris Chiuc1732ed2017-02-28 14:17:13 -06006479 [ALC256_FIXUP_ASUS_HEADSET_MODE] = {
6480 .type = HDA_FIXUP_FUNC,
6481 .v.func = alc_fixup_headset_mode,
6482 },
6483 [ALC256_FIXUP_ASUS_MIC] = {
6484 .type = HDA_FIXUP_PINS,
6485 .v.pins = (const struct hda_pintbl[]) {
6486 { 0x13, 0x90a60160 }, /* use as internal mic */
6487 { 0x19, 0x04a11120 }, /* use as headset mic, without its own jack detect */
6488 { }
6489 },
6490 .chained = true,
6491 .chain_id = ALC256_FIXUP_ASUS_HEADSET_MODE
6492 },
Chris Chiueeed4cd2017-02-28 14:17:15 -06006493 [ALC256_FIXUP_ASUS_AIO_GPIO2] = {
Takashi Iwaiae065f12018-06-19 23:00:03 +02006494 .type = HDA_FIXUP_FUNC,
6495 /* Set up GPIO2 for the speaker amp */
6496 .v.func = alc_fixup_gpio4,
Chris Chiueeed4cd2017-02-28 14:17:15 -06006497 },
Chris Chiu216d7ae2017-02-28 14:17:14 -06006498 [ALC233_FIXUP_ASUS_MIC_NO_PRESENCE] = {
6499 .type = HDA_FIXUP_PINS,
6500 .v.pins = (const struct hda_pintbl[]) {
6501 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6502 { }
6503 },
6504 .chained = true,
6505 .chain_id = ALC269_FIXUP_HEADSET_MIC
6506 },
6507 [ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE] = {
6508 .type = HDA_FIXUP_VERBS,
6509 .v.verbs = (const struct hda_verb[]) {
6510 /* Enables internal speaker */
6511 {0x20, AC_VERB_SET_COEF_INDEX, 0x40},
6512 {0x20, AC_VERB_SET_PROC_COEF, 0x8800},
6513 {}
6514 },
6515 .chained = true,
6516 .chain_id = ALC233_FIXUP_ASUS_MIC_NO_PRESENCE
6517 },
Kailang Yangca169cc2017-04-25 16:17:40 +08006518 [ALC233_FIXUP_LENOVO_MULTI_CODECS] = {
6519 .type = HDA_FIXUP_FUNC,
6520 .v.func = alc233_alc662_fixup_lenovo_dual_codecs,
6521 },
Jian-Hong Panea5c7eb2019-04-01 11:25:05 +08006522 [ALC233_FIXUP_ACER_HEADSET_MIC] = {
6523 .type = HDA_FIXUP_VERBS,
6524 .v.verbs = (const struct hda_verb[]) {
6525 { 0x20, AC_VERB_SET_COEF_INDEX, 0x45 },
6526 { 0x20, AC_VERB_SET_PROC_COEF, 0x5089 },
6527 { }
6528 },
6529 .chained = true,
6530 .chain_id = ALC233_FIXUP_ASUS_MIC_NO_PRESENCE
6531 },
Hui Wangf33f79f2017-07-07 12:08:29 +08006532 [ALC294_FIXUP_LENOVO_MIC_LOCATION] = {
6533 .type = HDA_FIXUP_PINS,
6534 .v.pins = (const struct hda_pintbl[]) {
6535 /* Change the mic location from front to right, otherwise there are
6536 two front mics with the same name, pulseaudio can't handle them.
6537 This is just a temporary workaround, after applying this fixup,
6538 there will be one "Front Mic" and one "Mic" in this machine.
6539 */
6540 { 0x1a, 0x04a19040 },
6541 { }
6542 },
6543 },
Kailang Yang5f364132017-07-25 16:28:16 +08006544 [ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE] = {
6545 .type = HDA_FIXUP_PINS,
6546 .v.pins = (const struct hda_pintbl[]) {
6547 { 0x16, 0x0101102f }, /* Rear Headset HP */
6548 { 0x19, 0x02a1913c }, /* use as Front headset mic, without its own jack detect */
6549 { 0x1a, 0x01a19030 }, /* Rear Headset MIC */
6550 { 0x1b, 0x02011020 },
6551 { }
6552 },
6553 .chained = true,
6554 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
6555 },
PeiSen Houb84e8432017-09-01 15:11:56 +08006556 [ALC700_FIXUP_INTEL_REFERENCE] = {
6557 .type = HDA_FIXUP_VERBS,
6558 .v.verbs = (const struct hda_verb[]) {
6559 /* Enables internal speaker */
6560 {0x20, AC_VERB_SET_COEF_INDEX, 0x45},
6561 {0x20, AC_VERB_SET_PROC_COEF, 0x5289},
6562 {0x20, AC_VERB_SET_COEF_INDEX, 0x4A},
6563 {0x20, AC_VERB_SET_PROC_COEF, 0x001b},
6564 {0x58, AC_VERB_SET_COEF_INDEX, 0x00},
6565 {0x58, AC_VERB_SET_PROC_COEF, 0x3888},
6566 {0x20, AC_VERB_SET_COEF_INDEX, 0x6f},
6567 {0x20, AC_VERB_SET_PROC_COEF, 0x2c0b},
6568 {}
6569 }
6570 },
Kailang Yang92266652017-12-14 15:28:58 +08006571 [ALC274_FIXUP_DELL_BIND_DACS] = {
6572 .type = HDA_FIXUP_FUNC,
6573 .v.func = alc274_fixup_bind_dacs,
6574 .chained = true,
6575 .chain_id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE
6576 },
6577 [ALC274_FIXUP_DELL_AIO_LINEOUT_VERB] = {
6578 .type = HDA_FIXUP_PINS,
6579 .v.pins = (const struct hda_pintbl[]) {
6580 { 0x1b, 0x0401102f },
6581 { }
6582 },
6583 .chained = true,
6584 .chain_id = ALC274_FIXUP_DELL_BIND_DACS
6585 },
Kailang Yang61fcf8e2018-02-02 15:26:46 +08006586 [ALC298_FIXUP_TPT470_DOCK] = {
6587 .type = HDA_FIXUP_FUNC,
6588 .v.func = alc_fixup_tpt470_dock,
6589 .chained = true,
6590 .chain_id = ALC293_FIXUP_LENOVO_SPK_NOISE
6591 },
Kailang Yangae104a22018-02-05 16:07:20 +08006592 [ALC255_FIXUP_DUMMY_LINEOUT_VERB] = {
6593 .type = HDA_FIXUP_PINS,
6594 .v.pins = (const struct hda_pintbl[]) {
6595 { 0x14, 0x0201101f },
6596 { }
6597 },
6598 .chained = true,
6599 .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
6600 },
Kailang Yangf0ba9d62018-03-16 11:46:08 +08006601 [ALC255_FIXUP_DELL_HEADSET_MIC] = {
6602 .type = HDA_FIXUP_PINS,
6603 .v.pins = (const struct hda_pintbl[]) {
6604 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6605 { }
6606 },
Hui Wang3ce0d5a2018-04-19 13:29:04 +08006607 .chained = true,
6608 .chain_id = ALC269_FIXUP_HEADSET_MIC
Kailang Yangf0ba9d62018-03-16 11:46:08 +08006609 },
Tom Bridenbbf8ff62018-05-29 17:34:20 +01006610 [ALC295_FIXUP_HP_X360] = {
6611 .type = HDA_FIXUP_FUNC,
6612 .v.func = alc295_fixup_hp_top_speakers,
6613 .chained = true,
6614 .chain_id = ALC269_FIXUP_HP_MUTE_LED_MIC3
Kailang Yang8a328ac2018-08-21 16:54:41 +08006615 },
6616 [ALC221_FIXUP_HP_HEADSET_MIC] = {
6617 .type = HDA_FIXUP_PINS,
6618 .v.pins = (const struct hda_pintbl[]) {
6619 { 0x19, 0x0181313f},
6620 { }
6621 },
6622 .chained = true,
6623 .chain_id = ALC269_FIXUP_HEADSET_MIC
6624 },
Hui Wangc4cfcf62018-11-26 14:17:16 +08006625 [ALC285_FIXUP_LENOVO_HEADPHONE_NOISE] = {
6626 .type = HDA_FIXUP_FUNC,
6627 .v.func = alc285_fixup_invalidate_dacs,
Hui Wang6ba189c2018-12-09 09:16:43 +08006628 .chained = true,
6629 .chain_id = ALC269_FIXUP_THINKPAD_ACPI
Hui Wangc4cfcf62018-11-26 14:17:16 +08006630 },
Girija Kumar Kasinadhunie8ed64b2018-11-26 13:40:46 -05006631 [ALC295_FIXUP_HP_AUTO_MUTE] = {
6632 .type = HDA_FIXUP_FUNC,
6633 .v.func = alc_fixup_auto_mute_via_amp,
6634 },
Chris Chiu33aaebd2018-12-05 14:48:53 +08006635 [ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE] = {
6636 .type = HDA_FIXUP_PINS,
6637 .v.pins = (const struct hda_pintbl[]) {
6638 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6639 { }
6640 },
6641 .chained = true,
6642 .chain_id = ALC269_FIXUP_HEADSET_MIC
6643 },
Chris Chiud8ae4582018-12-07 17:17:11 +08006644 [ALC294_FIXUP_ASUS_MIC] = {
6645 .type = HDA_FIXUP_PINS,
6646 .v.pins = (const struct hda_pintbl[]) {
6647 { 0x13, 0x90a60160 }, /* use as internal mic */
6648 { 0x19, 0x04a11120 }, /* use as headset mic, without its own jack detect */
6649 { }
6650 },
6651 .chained = true,
6652 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
6653 },
Jian-Hong Pan4e051102018-12-07 17:17:12 +08006654 [ALC294_FIXUP_ASUS_HEADSET_MIC] = {
6655 .type = HDA_FIXUP_PINS,
6656 .v.pins = (const struct hda_pintbl[]) {
Jian-Hong Pan82b01142018-12-27 16:46:31 +08006657 { 0x19, 0x01a1103c }, /* use as headset mic */
Jian-Hong Pan4e051102018-12-07 17:17:12 +08006658 { }
6659 },
6660 .chained = true,
6661 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
6662 },
6663 [ALC294_FIXUP_ASUS_SPK] = {
6664 .type = HDA_FIXUP_VERBS,
6665 .v.verbs = (const struct hda_verb[]) {
6666 /* Set EAPD high */
6667 { 0x20, AC_VERB_SET_COEF_INDEX, 0x40 },
6668 { 0x20, AC_VERB_SET_PROC_COEF, 0x8800 },
6669 { }
6670 },
6671 .chained = true,
6672 .chain_id = ALC294_FIXUP_ASUS_HEADSET_MIC
6673 },
Jaroslav Kyselac8a9afa2019-03-14 09:21:08 +01006674 [ALC295_FIXUP_CHROME_BOOK] = {
Kailang Yange8547472018-11-28 15:32:45 +08006675 .type = HDA_FIXUP_FUNC,
Jaroslav Kyselac8a9afa2019-03-14 09:21:08 +01006676 .v.func = alc295_fixup_chromebook,
Kailang Yang8983eb62019-04-03 15:31:49 +08006677 .chained = true,
6678 .chain_id = ALC225_FIXUP_HEADSET_JACK
6679 },
6680 [ALC225_FIXUP_HEADSET_JACK] = {
6681 .type = HDA_FIXUP_FUNC,
6682 .v.func = alc_fixup_headset_jack,
Kailang Yange8547472018-11-28 15:32:45 +08006683 },
Jeremy Soller89e3a562019-01-30 16:12:31 -07006684 [ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE] = {
6685 .type = HDA_FIXUP_PINS,
6686 .v.pins = (const struct hda_pintbl[]) {
6687 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6688 { }
6689 },
6690 .chained = true,
6691 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
6692 },
Hui Wangc8c6ee62019-02-14 11:41:33 +08006693 [ALC285_FIXUP_LENOVO_PC_BEEP_IN_NOISE] = {
6694 .type = HDA_FIXUP_VERBS,
6695 .v.verbs = (const struct hda_verb[]) {
6696 /* Disable PCBEEP-IN passthrough */
6697 { 0x20, AC_VERB_SET_COEF_INDEX, 0x36 },
6698 { 0x20, AC_VERB_SET_PROC_COEF, 0x57d7 },
6699 { }
6700 },
6701 .chained = true,
6702 .chain_id = ALC285_FIXUP_LENOVO_HEADPHONE_NOISE
6703 },
Jian-Hong Pancbc05fd2019-03-13 17:33:24 +08006704 [ALC255_FIXUP_ACER_HEADSET_MIC] = {
6705 .type = HDA_FIXUP_PINS,
6706 .v.pins = (const struct hda_pintbl[]) {
6707 { 0x19, 0x03a11130 },
6708 { 0x1a, 0x90a60140 }, /* use as internal mic */
6709 { }
6710 },
6711 .chained = true,
6712 .chain_id = ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC
6713 },
Kailang Yang136824e2019-03-14 16:22:45 +08006714 [ALC225_FIXUP_DELL_WYSE_AIO_MIC_NO_PRESENCE] = {
6715 .type = HDA_FIXUP_PINS,
6716 .v.pins = (const struct hda_pintbl[]) {
6717 { 0x16, 0x01011020 }, /* Rear Line out */
6718 { 0x19, 0x01a1913c }, /* use as Front headset mic, without its own jack detect */
6719 { }
6720 },
6721 .chained = true,
6722 .chain_id = ALC225_FIXUP_WYSE_AUTO_MUTE
6723 },
6724 [ALC225_FIXUP_WYSE_AUTO_MUTE] = {
6725 .type = HDA_FIXUP_FUNC,
6726 .v.func = alc_fixup_auto_mute_via_amp,
6727 .chained = true,
6728 .chain_id = ALC225_FIXUP_WYSE_DISABLE_MIC_VREF
6729 },
6730 [ALC225_FIXUP_WYSE_DISABLE_MIC_VREF] = {
6731 .type = HDA_FIXUP_FUNC,
6732 .v.func = alc_fixup_disable_mic_vref,
6733 .chained = true,
6734 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
6735 },
Jian-Hong Pan667a8f72019-03-15 17:51:09 +08006736 [ALC286_FIXUP_ACER_AIO_HEADSET_MIC] = {
6737 .type = HDA_FIXUP_VERBS,
6738 .v.verbs = (const struct hda_verb[]) {
6739 { 0x20, AC_VERB_SET_COEF_INDEX, 0x4f },
6740 { 0x20, AC_VERB_SET_PROC_COEF, 0x5029 },
6741 { }
6742 },
6743 .chained = true,
6744 .chain_id = ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE
6745 },
Jian-Hong Pane1037352019-03-22 11:37:18 +08006746 [ALC256_FIXUP_ASUS_MIC_NO_PRESENCE] = {
6747 .type = HDA_FIXUP_PINS,
6748 .v.pins = (const struct hda_pintbl[]) {
6749 { 0x19, 0x04a11120 }, /* use as headset mic, without its own jack detect */
6750 { }
6751 },
6752 .chained = true,
6753 .chain_id = ALC256_FIXUP_ASUS_HEADSET_MODE
6754 },
Bernhard Rosenkraenzere2a829b2019-03-05 00:38:19 +01006755 [ALC299_FIXUP_PREDATOR_SPK] = {
6756 .type = HDA_FIXUP_PINS,
6757 .v.pins = (const struct hda_pintbl[]) {
6758 { 0x21, 0x90170150 }, /* use as headset mic, without its own jack detect */
6759 { }
6760 }
6761 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02006762};
6763
6764static const struct snd_pci_quirk alc269_fixup_tbl[] = {
Marius Knausta6b92b62014-03-03 01:48:58 +01006765 SND_PCI_QUIRK(0x1025, 0x0283, "Acer TravelMate 8371", ALC269_FIXUP_INV_DMIC),
David Henningsson693b6132012-06-22 19:12:10 +02006766 SND_PCI_QUIRK(0x1025, 0x029b, "Acer 1810TZ", ALC269_FIXUP_INV_DMIC),
6767 SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC),
David Henningssonaaedfb42013-08-16 14:09:02 +02006768 SND_PCI_QUIRK(0x1025, 0x047c, "Acer AC700", ALC269_FIXUP_ACER_AC700),
Takashi Iwai78197172015-06-27 10:21:13 +02006769 SND_PCI_QUIRK(0x1025, 0x072d, "Acer Aspire V5-571G", ALC269_FIXUP_ASPIRE_HEADSET_MIC),
6770 SND_PCI_QUIRK(0x1025, 0x080d, "Acer Aspire V5-122P", ALC269_FIXUP_ASPIRE_HEADSET_MIC),
David Henningssonaaedfb42013-08-16 14:09:02 +02006771 SND_PCI_QUIRK(0x1025, 0x0740, "Acer AO725", ALC271_FIXUP_HP_GATE_MIC_JACK),
6772 SND_PCI_QUIRK(0x1025, 0x0742, "Acer AO756", ALC271_FIXUP_HP_GATE_MIC_JACK),
Simon South02322ac2016-03-02 23:10:44 -05006773 SND_PCI_QUIRK(0x1025, 0x0762, "Acer Aspire E1-472", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572),
Oleksij Rempelb1e89722013-12-04 20:50:53 +01006774 SND_PCI_QUIRK(0x1025, 0x0775, "Acer Aspire E1-572", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572),
Takashi Iwai1a22e772014-08-27 08:19:05 +02006775 SND_PCI_QUIRK(0x1025, 0x079b, "Acer Aspire V5-573G", ALC282_FIXUP_ASPIRE_V5_PINS),
Chris Chiu705b65f2018-12-05 14:48:54 +08006776 SND_PCI_QUIRK(0x1025, 0x102b, "Acer Aspire C24-860", ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE),
Takashi Iwaib9c2fa52015-11-19 16:39:50 +01006777 SND_PCI_QUIRK(0x1025, 0x106d, "Acer Cloudbook 14", ALC283_FIXUP_CHROME_BOOK),
Chris Chiuc7531e32019-03-21 17:17:31 +08006778 SND_PCI_QUIRK(0x1025, 0x1099, "Acer Aspire E5-523G", ALC255_FIXUP_ACER_MIC_NO_PRESENCE),
6779 SND_PCI_QUIRK(0x1025, 0x110e, "Acer Aspire ES1-432", ALC255_FIXUP_ACER_MIC_NO_PRESENCE),
Bernhard Rosenkraenzere2a829b2019-03-05 00:38:19 +01006780 SND_PCI_QUIRK(0x1025, 0x1246, "Acer Predator Helios 500", ALC299_FIXUP_PREDATOR_SPK),
Jian-Hong Pan667a8f72019-03-15 17:51:09 +08006781 SND_PCI_QUIRK(0x1025, 0x128f, "Acer Veriton Z6860G", ALC286_FIXUP_ACER_AIO_HEADSET_MIC),
6782 SND_PCI_QUIRK(0x1025, 0x1290, "Acer Veriton Z4860G", ALC286_FIXUP_ACER_AIO_HEADSET_MIC),
6783 SND_PCI_QUIRK(0x1025, 0x1291, "Acer Veriton Z4660G", ALC286_FIXUP_ACER_AIO_HEADSET_MIC),
Jian-Hong Pan2733cce2019-03-21 16:39:04 +08006784 SND_PCI_QUIRK(0x1025, 0x1308, "Acer Aspire Z24-890", ALC286_FIXUP_ACER_AIO_HEADSET_MIC),
Jian-Hong Panea5c7eb2019-04-01 11:25:05 +08006785 SND_PCI_QUIRK(0x1025, 0x132a, "Acer TravelMate B114-21", ALC233_FIXUP_ACER_HEADSET_MIC),
Jian-Hong Pancbc05fd2019-03-13 17:33:24 +08006786 SND_PCI_QUIRK(0x1025, 0x1330, "Acer TravelMate X514-51T", ALC255_FIXUP_ACER_HEADSET_MIC),
David Henningssonaaedfb42013-08-16 14:09:02 +02006787 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
Kailang Yang6ed11312015-10-26 15:37:39 +08006788 SND_PCI_QUIRK(0x1028, 0x054b, "Dell XPS one 2710", ALC275_FIXUP_DELL_XPS),
Takashi Iwai86f799b2015-11-14 17:46:31 +01006789 SND_PCI_QUIRK(0x1028, 0x05bd, "Dell Latitude E6440", ALC292_FIXUP_DELL_E7X),
Takashi Iwaicf521032016-01-15 12:59:25 +01006790 SND_PCI_QUIRK(0x1028, 0x05be, "Dell Latitude E6540", ALC292_FIXUP_DELL_E7X),
Takashi Iwai8b99aba2015-06-15 11:59:32 +02006791 SND_PCI_QUIRK(0x1028, 0x05ca, "Dell Latitude E7240", ALC292_FIXUP_DELL_E7X),
6792 SND_PCI_QUIRK(0x1028, 0x05cb, "Dell Latitude E7440", ALC292_FIXUP_DELL_E7X),
David Henningsson0f4881d2013-12-20 16:08:13 +01006793 SND_PCI_QUIRK(0x1028, 0x05da, "Dell Vostro 5460", ALC290_FIXUP_SUBWOOFER),
David Henningsson73bdd592013-04-15 15:44:14 +02006794 SND_PCI_QUIRK(0x1028, 0x05f4, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
6795 SND_PCI_QUIRK(0x1028, 0x05f5, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
6796 SND_PCI_QUIRK(0x1028, 0x05f6, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
David Henningsson0f4881d2013-12-20 16:08:13 +01006797 SND_PCI_QUIRK(0x1028, 0x0615, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK),
6798 SND_PCI_QUIRK(0x1028, 0x0616, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK),
Takashi Iwai98070572016-01-12 21:06:39 +01006799 SND_PCI_QUIRK(0x1028, 0x062c, "Dell Latitude E5550", ALC292_FIXUP_DELL_E7X),
Takashi Iwai42755542015-06-29 10:56:53 +02006800 SND_PCI_QUIRK(0x1028, 0x062e, "Dell Latitude E7450", ALC292_FIXUP_DELL_E7X),
David Henningsson0f4881d2013-12-20 16:08:13 +01006801 SND_PCI_QUIRK(0x1028, 0x0638, "Dell Inspiron 5439", ALC290_FIXUP_MONO_SPEAKERS_HSJACK),
Kailang Yanga22aa262014-04-23 17:34:28 +08006802 SND_PCI_QUIRK(0x1028, 0x064a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
6803 SND_PCI_QUIRK(0x1028, 0x064b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
Hui Wang831bfdf92015-06-26 12:35:17 +08006804 SND_PCI_QUIRK(0x1028, 0x0665, "Dell XPS 13", ALC288_FIXUP_DELL_XPS_13),
Bastien Noceraafecb142016-04-18 11:10:42 +02006805 SND_PCI_QUIRK(0x1028, 0x0669, "Dell Optiplex 9020m", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
Takashi Iwai3a05d122015-07-29 09:04:52 +02006806 SND_PCI_QUIRK(0x1028, 0x069a, "Dell Vostro 5480", ALC290_FIXUP_SUBWOOFER_HSJACK),
Kailang Yang8b724152014-12-17 17:08:59 +08006807 SND_PCI_QUIRK(0x1028, 0x06c7, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
Kailang Yangb7343042014-12-02 14:50:45 +08006808 SND_PCI_QUIRK(0x1028, 0x06d9, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
6809 SND_PCI_QUIRK(0x1028, 0x06da, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
David Henningssonc04017e2015-12-15 14:44:03 +01006810 SND_PCI_QUIRK(0x1028, 0x06db, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
6811 SND_PCI_QUIRK(0x1028, 0x06dd, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
6812 SND_PCI_QUIRK(0x1028, 0x06de, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
6813 SND_PCI_QUIRK(0x1028, 0x06df, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
6814 SND_PCI_QUIRK(0x1028, 0x06e0, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
Kai-Heng Feng423cd782016-05-20 15:47:23 +08006815 SND_PCI_QUIRK(0x1028, 0x0704, "Dell XPS 13 9350", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE),
Kai-Heng Fengfd06c772016-08-30 15:36:34 +08006816 SND_PCI_QUIRK(0x1028, 0x0706, "Dell Inspiron 7559", ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER),
Kai-Heng Feng3b43b712016-02-25 15:19:38 +08006817 SND_PCI_QUIRK(0x1028, 0x0725, "Dell Inspiron 3162", ALC255_FIXUP_DELL_SPK_NOISE),
Takashi Iwaic0ca5ec2019-02-20 16:15:45 +01006818 SND_PCI_QUIRK(0x1028, 0x0738, "Dell Precision 5820", ALC269_FIXUP_NO_SHUTUP),
Kai-Heng Feng423cd782016-05-20 15:47:23 +08006819 SND_PCI_QUIRK(0x1028, 0x075b, "Dell XPS 13 9360", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE),
Kai-Heng Feng709ae622018-10-04 11:39:42 +08006820 SND_PCI_QUIRK(0x1028, 0x075c, "Dell XPS 27 7760", ALC298_FIXUP_SPK_VOLUME),
Hui Wangdd9aa332016-08-01 10:20:32 +08006821 SND_PCI_QUIRK(0x1028, 0x075d, "Dell AIO", ALC298_FIXUP_SPK_VOLUME),
Takashi Iwaie312a862018-03-06 12:14:17 +01006822 SND_PCI_QUIRK(0x1028, 0x07b0, "Dell Precision 7520", ALC295_FIXUP_DISABLE_DAC3),
Takashi Iwai493de342017-02-28 17:27:57 +01006823 SND_PCI_QUIRK(0x1028, 0x0798, "Dell Inspiron 17 7000 Gaming", ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER),
Kailang Yang5f364132017-07-25 16:28:16 +08006824 SND_PCI_QUIRK(0x1028, 0x080c, "Dell WYSE", ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE),
Takashi Iwaie4c9fd12018-01-10 08:34:28 +01006825 SND_PCI_QUIRK(0x1028, 0x082a, "Dell XPS 13 9360", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE),
Kailang Yang40e2c4e2018-02-02 15:13:09 +08006826 SND_PCI_QUIRK(0x1028, 0x084b, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB),
6827 SND_PCI_QUIRK(0x1028, 0x084e, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB),
Kailang Yangf0ba9d62018-03-16 11:46:08 +08006828 SND_PCI_QUIRK(0x1028, 0x0871, "Dell Precision 3630", ALC255_FIXUP_DELL_HEADSET_MIC),
6829 SND_PCI_QUIRK(0x1028, 0x0872, "Dell Precision 3630", ALC255_FIXUP_DELL_HEADSET_MIC),
Kailang Yangae104a22018-02-05 16:07:20 +08006830 SND_PCI_QUIRK(0x1028, 0x0873, "Dell Precision 3930", ALC255_FIXUP_DUMMY_LINEOUT_VERB),
Kailang Yang136824e2019-03-14 16:22:45 +08006831 SND_PCI_QUIRK(0x1028, 0x08ad, "Dell WYSE AIO", ALC225_FIXUP_DELL_WYSE_AIO_MIC_NO_PRESENCE),
Kailang Yangda484d02019-03-14 15:50:59 +08006832 SND_PCI_QUIRK(0x1028, 0x08ae, "Dell WYSE NB", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE),
Kailang Yangc2a7c55a2019-01-03 15:53:39 +08006833 SND_PCI_QUIRK(0x1028, 0x0935, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB),
Kailang Yanga22aa262014-04-23 17:34:28 +08006834 SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
6835 SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
Takashi Iwai08fb0d02013-01-10 17:33:58 +01006836 SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01006837 SND_PCI_QUIRK(0x103c, 0x18e6, "HP", ALC269_FIXUP_HP_GPIO_LED),
David Henningsson8e35cd42013-11-06 11:20:01 +01006838 SND_PCI_QUIRK(0x103c, 0x218b, "HP", ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED),
David Henningsson33f4acd2015-01-07 15:50:13 +01006839 SND_PCI_QUIRK(0x103c, 0x225f, "HP", ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY),
Kailang Yangc60666b2014-02-21 16:23:35 +08006840 /* ALC282 */
Hui Wang7976eb42015-02-13 11:14:41 +08006841 SND_PCI_QUIRK(0x103c, 0x21f9, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang8a02b162014-06-13 17:16:31 +08006842 SND_PCI_QUIRK(0x103c, 0x2210, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang8a02b162014-06-13 17:16:31 +08006843 SND_PCI_QUIRK(0x103c, 0x2214, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08006844 SND_PCI_QUIRK(0x103c, 0x2236, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
6845 SND_PCI_QUIRK(0x103c, 0x2237, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
6846 SND_PCI_QUIRK(0x103c, 0x2238, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
6847 SND_PCI_QUIRK(0x103c, 0x2239, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08006848 SND_PCI_QUIRK(0x103c, 0x224b, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
Kailang Yangc60666b2014-02-21 16:23:35 +08006849 SND_PCI_QUIRK(0x103c, 0x2268, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08006850 SND_PCI_QUIRK(0x103c, 0x226a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
6851 SND_PCI_QUIRK(0x103c, 0x226b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang8a02b162014-06-13 17:16:31 +08006852 SND_PCI_QUIRK(0x103c, 0x226e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangeaa8e5e2014-11-21 15:49:11 +08006853 SND_PCI_QUIRK(0x103c, 0x2271, "HP", ALC286_FIXUP_HP_GPIO_LED),
TienFu Chenb4b33f92015-01-20 15:06:21 +01006854 SND_PCI_QUIRK(0x103c, 0x2272, "HP", ALC280_FIXUP_HP_DOCK_PINS),
TienFu Chen3271cb22015-02-10 09:09:41 +01006855 SND_PCI_QUIRK(0x103c, 0x2273, "HP", ALC280_FIXUP_HP_DOCK_PINS),
Kailang Yangc60666b2014-02-21 16:23:35 +08006856 SND_PCI_QUIRK(0x103c, 0x229e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08006857 SND_PCI_QUIRK(0x103c, 0x22b2, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
6858 SND_PCI_QUIRK(0x103c, 0x22b7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
6859 SND_PCI_QUIRK(0x103c, 0x22bf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08006860 SND_PCI_QUIRK(0x103c, 0x22cf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Keith Packard98973f22015-07-15 12:14:39 -07006861 SND_PCI_QUIRK(0x103c, 0x22db, "HP", ALC280_FIXUP_HP_9480M),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08006862 SND_PCI_QUIRK(0x103c, 0x22dc, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
6863 SND_PCI_QUIRK(0x103c, 0x22fb, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yangc60666b2014-02-21 16:23:35 +08006864 /* ALC290 */
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08006865 SND_PCI_QUIRK(0x103c, 0x221b, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08006866 SND_PCI_QUIRK(0x103c, 0x2221, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08006867 SND_PCI_QUIRK(0x103c, 0x2225, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08006868 SND_PCI_QUIRK(0x103c, 0x2253, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
6869 SND_PCI_QUIRK(0x103c, 0x2254, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
6870 SND_PCI_QUIRK(0x103c, 0x2255, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
6871 SND_PCI_QUIRK(0x103c, 0x2256, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
6872 SND_PCI_QUIRK(0x103c, 0x2257, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08006873 SND_PCI_QUIRK(0x103c, 0x2259, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Jaroslav Kysela04d54662017-03-09 13:29:13 +01006874 SND_PCI_QUIRK(0x103c, 0x225a, "HP", ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED),
Kailang Yangc60666b2014-02-21 16:23:35 +08006875 SND_PCI_QUIRK(0x103c, 0x2260, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08006876 SND_PCI_QUIRK(0x103c, 0x2263, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
6877 SND_PCI_QUIRK(0x103c, 0x2264, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
6878 SND_PCI_QUIRK(0x103c, 0x2265, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08006879 SND_PCI_QUIRK(0x103c, 0x2272, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
6880 SND_PCI_QUIRK(0x103c, 0x2273, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08006881 SND_PCI_QUIRK(0x103c, 0x2278, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yangc60666b2014-02-21 16:23:35 +08006882 SND_PCI_QUIRK(0x103c, 0x227f, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08006883 SND_PCI_QUIRK(0x103c, 0x2282, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08006884 SND_PCI_QUIRK(0x103c, 0x228b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08006885 SND_PCI_QUIRK(0x103c, 0x228e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
6886 SND_PCI_QUIRK(0x103c, 0x22c5, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08006887 SND_PCI_QUIRK(0x103c, 0x22c7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
6888 SND_PCI_QUIRK(0x103c, 0x22c8, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08006889 SND_PCI_QUIRK(0x103c, 0x22c4, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang8a02b162014-06-13 17:16:31 +08006890 SND_PCI_QUIRK(0x103c, 0x2334, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
6891 SND_PCI_QUIRK(0x103c, 0x2335, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
6892 SND_PCI_QUIRK(0x103c, 0x2336, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
6893 SND_PCI_QUIRK(0x103c, 0x2337, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Takashi Iwaif8839822016-02-25 14:31:59 +01006894 SND_PCI_QUIRK(0x103c, 0x221c, "HP EliteBook 755 G2", ALC280_FIXUP_HP_HEADSET_MIC),
Jaroslav Kysela167897f2019-03-13 13:40:15 +01006895 SND_PCI_QUIRK(0x103c, 0x802e, "HP Z240 SFF", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
6896 SND_PCI_QUIRK(0x103c, 0x802f, "HP Z240", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
Takashi Iwai563785e2018-11-12 09:43:12 +01006897 SND_PCI_QUIRK(0x103c, 0x820d, "HP Pavilion 15", ALC269_FIXUP_HP_MUTE_LED_MIC3),
Hui Wange549d192016-04-01 11:00:15 +08006898 SND_PCI_QUIRK(0x103c, 0x8256, "HP", ALC221_FIXUP_HP_FRONT_MIC),
Tom Bridenbbf8ff62018-05-29 17:34:20 +01006899 SND_PCI_QUIRK(0x103c, 0x827e, "HP x360", ALC295_FIXUP_HP_X360),
Jaroslav Kysela167897f2019-03-13 13:40:15 +01006900 SND_PCI_QUIRK(0x103c, 0x82bf, "HP G3 mini", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
6901 SND_PCI_QUIRK(0x103c, 0x82c0, "HP G3 mini premium", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
Alexandru Gagniuc56e40eb2018-08-04 11:44:44 -05006902 SND_PCI_QUIRK(0x103c, 0x83b9, "HP Spectre x360", ALC269_FIXUP_HP_MUTE_LED_MIC3),
Chris Chiuc1732ed2017-02-28 14:17:13 -06006903 SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC),
Takashi Iwai7bba2152013-09-06 15:45:38 +02006904 SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300),
David Henningsson3e0d6112013-04-22 14:30:14 +02006905 SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Wandrille RONCE9cf65332018-12-19 14:52:44 +01006906 SND_PCI_QUIRK(0x1043, 0x10a1, "ASUS UX391UA", ALC294_FIXUP_ASUS_SPK),
Chris Chiuc1732ed2017-02-28 14:17:13 -06006907 SND_PCI_QUIRK(0x1043, 0x10c0, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC),
Takashi Iwai4eab0ea2017-06-06 12:33:17 +02006908 SND_PCI_QUIRK(0x1043, 0x10d0, "ASUS X540LA/X540LJ", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
David Henningsson3e0d6112013-04-22 14:30:14 +02006909 SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Takashi Iwai4eab0ea2017-06-06 12:33:17 +02006910 SND_PCI_QUIRK(0x1043, 0x11c0, "ASUS X556UR", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
6911 SND_PCI_QUIRK(0x1043, 0x1290, "ASUS X441SA", ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE),
6912 SND_PCI_QUIRK(0x1043, 0x12a0, "ASUS X441UV", ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE),
Chris Chiuc1732ed2017-02-28 14:17:13 -06006913 SND_PCI_QUIRK(0x1043, 0x12f0, "ASUS X541UV", ALC256_FIXUP_ASUS_MIC),
6914 SND_PCI_QUIRK(0x1043, 0x12e0, "ASUS X541SA", ALC256_FIXUP_ASUS_MIC),
6915 SND_PCI_QUIRK(0x1043, 0x13b0, "ASUS Z550SA", ALC256_FIXUP_ASUS_MIC),
Oleksij Rempel2cede302013-11-27 17:12:03 +01006916 SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK),
Takashi Iwai23870832013-11-29 14:13:12 +01006917 SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A),
David Henningsson3e0d6112013-04-22 14:30:14 +02006918 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC),
Takashi Iwai017f2a12011-07-09 14:42:25 +02006919 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
Chris Chiu28e8af82017-06-05 15:05:30 -06006920 SND_PCI_QUIRK(0x1043, 0x1a30, "ASUS X705UD", ALC256_FIXUP_ASUS_MIC),
David Henningsson693b6132012-06-22 19:12:10 +02006921 SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC),
Chris Chiu615966a2017-02-28 14:17:12 -06006922 SND_PCI_QUIRK(0x1043, 0x1bbd, "ASUS Z550MA", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
Takashi Iwai4eab0ea2017-06-06 12:33:17 +02006923 SND_PCI_QUIRK(0x1043, 0x1c23, "Asus X55U", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Chris Chiuc1732ed2017-02-28 14:17:13 -06006924 SND_PCI_QUIRK(0x1043, 0x1ccd, "ASUS X555UB", ALC256_FIXUP_ASUS_MIC),
Chris Chiueeed4cd2017-02-28 14:17:15 -06006925 SND_PCI_QUIRK(0x1043, 0x3030, "ASUS ZN270IE", ALC256_FIXUP_ASUS_AIO_GPIO2),
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02006926 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC),
6927 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC),
6928 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
6929 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
David Henningssond240d1d2013-04-15 12:50:02 +02006930 SND_PCI_QUIRK(0x1043, 0x8516, "ASUS X101CH", ALC269_FIXUP_ASUS_X101),
Takashi Iwaif88abaa2014-02-07 12:07:59 +01006931 SND_PCI_QUIRK(0x104d, 0x90b5, "Sony VAIO Pro 11", ALC286_FIXUP_SONY_MIC_NO_PRESENCE),
David Henningsson88cfcf82013-10-11 10:18:45 +02006932 SND_PCI_QUIRK(0x104d, 0x90b6, "Sony VAIO Pro 13", ALC286_FIXUP_SONY_MIC_NO_PRESENCE),
Takashi Iwai1d045db2011-07-07 18:23:21 +02006933 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
6934 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
6935 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
Takashi Iwaie9bd7d52014-05-21 11:06:49 +02006936 SND_PCI_QUIRK(0x104d, 0x9099, "Sony VAIO S13", ALC275_FIXUP_SONY_DISABLE_AAMIX),
Takashi Iwai24519912011-08-16 15:08:49 +02006937 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook", ALC269_FIXUP_LIFEBOOK),
Takashi Iwai4df3fd12015-06-29 08:38:02 +02006938 SND_PCI_QUIRK(0x10cf, 0x159f, "Lifebook E780", ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT),
Takashi Iwaicc7016a2015-04-08 20:47:55 +02006939 SND_PCI_QUIRK(0x10cf, 0x15dc, "Lifebook T731", ALC269_FIXUP_LIFEBOOK_HP_PIN),
Takashi Iwai88776f32015-05-01 09:20:34 +02006940 SND_PCI_QUIRK(0x10cf, 0x1757, "Lifebook E752", ALC269_FIXUP_LIFEBOOK_HP_PIN),
Jan-Marek Glogowskifdcc9682018-02-14 11:29:15 +01006941 SND_PCI_QUIRK(0x10cf, 0x1629, "Lifebook U7x7", ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC),
David Henningsson2041d562014-06-13 11:15:44 +02006942 SND_PCI_QUIRK(0x10cf, 0x1845, "Lifebook U904", ALC269_FIXUP_LIFEBOOK_EXTMIC),
PeiSen Houb84e8432017-09-01 15:11:56 +08006943 SND_PCI_QUIRK(0x10ec, 0x10f2, "Intel Reference board", ALC700_FIXUP_INTEL_REFERENCE),
YOKOTA Hiroshi0fca97a2018-07-01 18:30:01 +09006944 SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-SZ6", ALC269_FIXUP_HEADSET_MODE),
David Henningssona33cc482014-10-07 10:18:41 +02006945 SND_PCI_QUIRK(0x144d, 0xc109, "Samsung Ativ book 9 (NP900X3G)", ALC269_FIXUP_INV_DMIC),
Gabriele Mazzotta823ff162016-12-24 19:50:01 +01006946 SND_PCI_QUIRK(0x144d, 0xc740, "Samsung Ativ book 8 (NP870Z5G)", ALC269_FIXUP_ATIV_BOOK_8),
Anisse Astierabaa22742016-08-24 09:14:13 +02006947 SND_PCI_QUIRK(0x1458, 0xfa53, "Gigabyte BXBT-2807", ALC283_FIXUP_HEADSET_MIC),
6948 SND_PCI_QUIRK(0x1462, 0xb120, "MSI Cubi MS-B120", ALC283_FIXUP_HEADSET_MIC),
Anisse Astier8cd65272018-11-23 17:59:11 +01006949 SND_PCI_QUIRK(0x1462, 0xb171, "Cubi N 8GL (MS-B171)", ALC283_FIXUP_HEADSET_MIC),
Jeremy Soller89e3a562019-01-30 16:12:31 -07006950 SND_PCI_QUIRK(0x1558, 0x1325, "System76 Darter Pro (darp5)", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
Kailang Yangca169cc2017-04-25 16:17:40 +08006951 SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC233_FIXUP_LENOVO_MULTI_CODECS),
Takashi Iwai1d045db2011-07-07 18:23:21 +02006952 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
6953 SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
6954 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
6955 SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
6956 SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
Takashi Iwai707fba32012-08-02 09:04:39 +02006957 SND_PCI_QUIRK(0x17aa, 0x21f6, "Thinkpad T530", ALC269_FIXUP_LENOVO_DOCK),
Felix Kaechelec8415a42012-08-06 23:02:01 +02006958 SND_PCI_QUIRK(0x17aa, 0x21fa, "Thinkpad X230", ALC269_FIXUP_LENOVO_DOCK),
Stefán Freyr84f98fd2012-10-19 22:46:00 +02006959 SND_PCI_QUIRK(0x17aa, 0x21f3, "Thinkpad T430", ALC269_FIXUP_LENOVO_DOCK),
Philipp A. Mohrenweiser4407be62012-08-06 13:14:18 +02006960 SND_PCI_QUIRK(0x17aa, 0x21fb, "Thinkpad T430s", ALC269_FIXUP_LENOVO_DOCK),
David Henningsson108cc102012-07-20 10:37:25 +02006961 SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK),
David Henningssonaaedfb42013-08-16 14:09:02 +02006962 SND_PCI_QUIRK(0x17aa, 0x2208, "Thinkpad T431s", ALC269_FIXUP_LENOVO_DOCK),
Takashi Iwai9a811232015-12-09 15:17:43 +01006963 SND_PCI_QUIRK(0x17aa, 0x220c, "Thinkpad T440s", ALC292_FIXUP_TPT440),
Takashi Iwai1c37c222014-05-06 17:34:42 +02006964 SND_PCI_QUIRK(0x17aa, 0x220e, "Thinkpad T440p", ALC292_FIXUP_TPT440_DOCK),
Takashi Iwaia12137e2014-06-27 12:14:35 +02006965 SND_PCI_QUIRK(0x17aa, 0x2210, "Thinkpad T540p", ALC292_FIXUP_TPT440_DOCK),
Rick Sherman59a51a62015-08-18 21:04:30 -05006966 SND_PCI_QUIRK(0x17aa, 0x2211, "Thinkpad W541", ALC292_FIXUP_TPT440_DOCK),
Takashi Iwai6d169412014-10-07 17:27:02 +02006967 SND_PCI_QUIRK(0x17aa, 0x2212, "Thinkpad T440", ALC292_FIXUP_TPT440_DOCK),
Lukas Bossard7c215392014-10-29 18:31:07 +01006968 SND_PCI_QUIRK(0x17aa, 0x2214, "Thinkpad X240", ALC292_FIXUP_TPT440_DOCK),
David Henningssona4a9e082013-08-16 14:09:01 +02006969 SND_PCI_QUIRK(0x17aa, 0x2215, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Takashi Iwaib6903c02015-12-10 12:20:20 +01006970 SND_PCI_QUIRK(0x17aa, 0x2218, "Thinkpad X1 Carbon 2nd", ALC292_FIXUP_TPT440_DOCK),
Laura Abbottd05ea7d2015-10-02 11:09:54 -07006971 SND_PCI_QUIRK(0x17aa, 0x2223, "ThinkPad T550", ALC292_FIXUP_TPT440_DOCK),
Yves-Alexis Perezc0278662015-04-11 09:31:35 +02006972 SND_PCI_QUIRK(0x17aa, 0x2226, "ThinkPad X250", ALC292_FIXUP_TPT440_DOCK),
Kailang Yang61fcf8e2018-02-02 15:26:46 +08006973 SND_PCI_QUIRK(0x17aa, 0x222d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
6974 SND_PCI_QUIRK(0x17aa, 0x222e, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
Torsten Hilbrichdab38e42016-06-07 13:14:21 +02006975 SND_PCI_QUIRK(0x17aa, 0x2231, "Thinkpad T560", ALC292_FIXUP_TPT460),
Sven Eckelmannc636b952016-04-11 16:55:26 +02006976 SND_PCI_QUIRK(0x17aa, 0x2233, "Thinkpad", ALC292_FIXUP_TPT460),
Kailang Yang61fcf8e2018-02-02 15:26:46 +08006977 SND_PCI_QUIRK(0x17aa, 0x2245, "Thinkpad T470", ALC298_FIXUP_TPT470_DOCK),
6978 SND_PCI_QUIRK(0x17aa, 0x2246, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
6979 SND_PCI_QUIRK(0x17aa, 0x2247, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
Dennis Wassenberge4c07b32018-03-08 13:17:54 +01006980 SND_PCI_QUIRK(0x17aa, 0x2249, "Thinkpad", ALC292_FIXUP_TPT460),
Kailang Yang61fcf8e2018-02-02 15:26:46 +08006981 SND_PCI_QUIRK(0x17aa, 0x224b, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
6982 SND_PCI_QUIRK(0x17aa, 0x224c, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
6983 SND_PCI_QUIRK(0x17aa, 0x224d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
Benjamin Berg85981df2018-02-14 13:29:39 +01006984 SND_PCI_QUIRK(0x17aa, 0x225d, "Thinkpad T480", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Kailang3694cb22015-12-28 11:35:24 +08006985 SND_PCI_QUIRK(0x17aa, 0x30bb, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
Hui Wang6ef2f682016-03-11 12:04:02 +08006986 SND_PCI_QUIRK(0x17aa, 0x30e2, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
Hui Wangf33f79f2017-07-07 12:08:29 +08006987 SND_PCI_QUIRK(0x17aa, 0x310c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
Hui Wange41fc8c2018-06-25 14:40:56 +08006988 SND_PCI_QUIRK(0x17aa, 0x312a, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
Kailang Yang65811832018-04-25 17:07:27 +08006989 SND_PCI_QUIRK(0x17aa, 0x312f, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
Hui Wang8da5bbf2017-12-22 11:17:46 +08006990 SND_PCI_QUIRK(0x17aa, 0x313c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
David Henningsson56f27012016-01-11 09:33:14 +01006991 SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
Takashi Iwaifedb2242014-11-13 07:11:38 +01006992 SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC),
Takashi Iwai9b745ab2014-03-07 08:37:19 +01006993 SND_PCI_QUIRK(0x17aa, 0x3978, "IdeaPad Y410P", ALC269_FIXUP_NO_SHUTUP),
David Henningssona4a9e082013-08-16 14:09:01 +02006994 SND_PCI_QUIRK(0x17aa, 0x5013, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Kailang Yang1bb3e062013-09-27 13:10:25 +02006995 SND_PCI_QUIRK(0x17aa, 0x501a, "Thinkpad", ALC283_FIXUP_INT_MIC),
Takashi Iwaic497d9f2014-10-08 12:14:40 +02006996 SND_PCI_QUIRK(0x17aa, 0x501e, "Thinkpad L440", ALC292_FIXUP_TPT440_DOCK),
David Henningssoncd5302c2013-08-19 12:22:33 +02006997 SND_PCI_QUIRK(0x17aa, 0x5026, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Jo-Philipp Wichf2aa1112015-04-13 12:47:26 +02006998 SND_PCI_QUIRK(0x17aa, 0x5034, "Thinkpad T450", ALC292_FIXUP_TPT440_DOCK),
Sebastian Wicki80b311d2015-03-23 17:23:11 +01006999 SND_PCI_QUIRK(0x17aa, 0x5036, "Thinkpad T450s", ALC292_FIXUP_TPT440_DOCK),
Ansgar Hegerfeld09ea9972015-05-14 12:31:32 +02007000 SND_PCI_QUIRK(0x17aa, 0x503c, "Thinkpad L450", ALC292_FIXUP_TPT440_DOCK),
Conrad Kostecki037e1192016-04-26 10:08:10 +02007001 SND_PCI_QUIRK(0x17aa, 0x504a, "ThinkPad X260", ALC292_FIXUP_TPT440_DOCK),
Hui Wang23adc192015-12-08 12:27:18 +08007002 SND_PCI_QUIRK(0x17aa, 0x504b, "Thinkpad", ALC293_FIXUP_LENOVO_SPK_NOISE),
Jaroslav Kysela0f087ee2016-06-24 15:13:16 +02007003 SND_PCI_QUIRK(0x17aa, 0x5050, "Thinkpad T560p", ALC292_FIXUP_TPT460),
Torsten Hilbrich9cd25742016-07-05 10:40:22 +02007004 SND_PCI_QUIRK(0x17aa, 0x5051, "Thinkpad L460", ALC292_FIXUP_TPT460),
Jaroslav Kysela0f087ee2016-06-24 15:13:16 +02007005 SND_PCI_QUIRK(0x17aa, 0x5053, "Thinkpad T460", ALC292_FIXUP_TPT460),
Kailang Yang61fcf8e2018-02-02 15:26:46 +08007006 SND_PCI_QUIRK(0x17aa, 0x505d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7007 SND_PCI_QUIRK(0x17aa, 0x505f, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7008 SND_PCI_QUIRK(0x17aa, 0x5062, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
David Henningssoncd5302c2013-08-19 12:22:33 +02007009 SND_PCI_QUIRK(0x17aa, 0x5109, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Kailang Yang61fcf8e2018-02-02 15:26:46 +08007010 SND_PCI_QUIRK(0x17aa, 0x511e, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
7011 SND_PCI_QUIRK(0x17aa, 0x511f, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
David Henningsson012e7eb2012-08-08 08:43:37 +02007012 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K),
Takashi Iwai1d045db2011-07-07 18:23:21 +02007013 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
Ayman Bagabase2744fd2018-12-12 18:07:59 -05007014 SND_PCI_QUIRK(0x19e5, 0x3200, "Huawei MBX", ALC255_FIXUP_MIC_MUTE_LED),
7015 SND_PCI_QUIRK(0x19e5, 0x3201, "Huawei MBX", ALC255_FIXUP_MIC_MUTE_LED),
Ayman Bagabas8ac51bb2018-12-12 18:07:57 -05007016 SND_PCI_QUIRK(0x19e5, 0x3204, "Huawei MBXP", ALC256_FIXUP_HUAWEI_MBXP_PINS),
Anisse Astier02b504d2013-06-03 11:53:10 +02007017 SND_PCI_QUIRK(0x1b7d, 0xa831, "Ordissimo EVE2 ", ALC269VB_FIXUP_ORDISSIMO_EVE2), /* Also known as Malata PC-B1303 */
Takashi Iwaia4297b52011-08-23 18:40:12 +02007018
Takashi Iwaia7f3eed2012-02-16 13:03:18 +01007019#if 0
Takashi Iwaia4297b52011-08-23 18:40:12 +02007020 /* Below is a quirk table taken from the old code.
7021 * Basically the device should work as is without the fixup table.
7022 * If BIOS doesn't give a proper info, enable the corresponding
7023 * fixup entry.
Jesper Juhl7d7eb9e2012-04-12 22:11:25 +02007024 */
Takashi Iwaia4297b52011-08-23 18:40:12 +02007025 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
7026 ALC269_FIXUP_AMIC),
7027 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269_FIXUP_AMIC),
Takashi Iwaia4297b52011-08-23 18:40:12 +02007028 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269_FIXUP_AMIC),
7029 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_FIXUP_AMIC),
7030 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269_FIXUP_AMIC),
7031 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269_FIXUP_AMIC),
7032 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269_FIXUP_AMIC),
7033 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269_FIXUP_AMIC),
7034 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_FIXUP_AMIC),
7035 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269_FIXUP_AMIC),
7036 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_FIXUP_AMIC),
7037 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_FIXUP_AMIC),
7038 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_FIXUP_AMIC),
7039 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_FIXUP_AMIC),
7040 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_FIXUP_AMIC),
7041 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_FIXUP_AMIC),
7042 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_FIXUP_AMIC),
7043 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_FIXUP_AMIC),
7044 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_FIXUP_AMIC),
7045 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_FIXUP_AMIC),
7046 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_FIXUP_AMIC),
7047 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_FIXUP_AMIC),
7048 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_FIXUP_AMIC),
7049 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_FIXUP_AMIC),
7050 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_FIXUP_AMIC),
7051 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_FIXUP_AMIC),
7052 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_FIXUP_AMIC),
7053 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_FIXUP_AMIC),
7054 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_FIXUP_AMIC),
7055 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_FIXUP_AMIC),
7056 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_FIXUP_AMIC),
7057 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_FIXUP_AMIC),
7058 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_FIXUP_AMIC),
7059 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_FIXUP_AMIC),
7060 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_FIXUP_AMIC),
7061 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_FIXUP_DMIC),
7062 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_FIXUP_AMIC),
7063 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_AMIC),
7064 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_FIXUP_DMIC),
7065 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_FIXUP_DMIC),
7066#endif
7067 {}
7068};
7069
David Henningsson214eef72014-07-22 14:09:35 +02007070static const struct snd_pci_quirk alc269_fixup_vendor_tbl[] = {
7071 SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC),
7072 SND_PCI_QUIRK_VENDOR(0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED),
7073 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
7074 SND_PCI_QUIRK_VENDOR(0x17aa, "Thinkpad", ALC269_FIXUP_THINKPAD_ACPI),
7075 {}
7076};
7077
Takashi Iwai1727a772013-01-10 09:52:52 +01007078static const struct hda_model_fixup alc269_fixup_models[] = {
Takashi Iwaia4297b52011-08-23 18:40:12 +02007079 {.id = ALC269_FIXUP_AMIC, .name = "laptop-amic"},
7080 {.id = ALC269_FIXUP_DMIC, .name = "laptop-dmic"},
Takashi Iwai6e72aa52012-06-25 10:52:25 +02007081 {.id = ALC269_FIXUP_STEREO_DMIC, .name = "alc269-dmic"},
7082 {.id = ALC271_FIXUP_DMIC, .name = "alc271-dmic"},
7083 {.id = ALC269_FIXUP_INV_DMIC, .name = "inv-dmic"},
David Henningsson7c478f02013-10-11 10:18:46 +02007084 {.id = ALC269_FIXUP_HEADSET_MIC, .name = "headset-mic"},
Takashi Iwaib0169512015-05-19 10:20:13 +02007085 {.id = ALC269_FIXUP_HEADSET_MODE, .name = "headset-mode"},
7086 {.id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC, .name = "headset-mode-no-hp-mic"},
David Henningsson108cc102012-07-20 10:37:25 +02007087 {.id = ALC269_FIXUP_LENOVO_DOCK, .name = "lenovo-dock"},
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01007088 {.id = ALC269_FIXUP_HP_GPIO_LED, .name = "hp-gpio-led"},
Jaroslav Kysela04d54662017-03-09 13:29:13 +01007089 {.id = ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED, .name = "hp-dock-gpio-mic1-led"},
David Henningssone32aa852013-06-17 11:04:02 +02007090 {.id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "dell-headset-multi"},
7091 {.id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE, .name = "dell-headset-dock"},
Takashi Iwaia26d96c2018-06-26 15:09:25 +02007092 {.id = ALC269_FIXUP_DELL3_MIC_NO_PRESENCE, .name = "dell-headset3"},
7093 {.id = ALC269_FIXUP_DELL4_MIC_NO_PRESENCE, .name = "dell-headset4"},
Kailang Yangbe8ef162014-04-08 15:19:49 +08007094 {.id = ALC283_FIXUP_CHROME_BOOK, .name = "alc283-dac-wcaps"},
Kailang Yang0202e992013-12-02 15:20:15 +08007095 {.id = ALC283_FIXUP_SENSE_COMBO_JACK, .name = "alc283-sense-combo"},
Takashi Iwai1c37c222014-05-06 17:34:42 +02007096 {.id = ALC292_FIXUP_TPT440_DOCK, .name = "tpt440-dock"},
Takashi Iwai9a811232015-12-09 15:17:43 +01007097 {.id = ALC292_FIXUP_TPT440, .name = "tpt440"},
Sven Eckelmannc636b952016-04-11 16:55:26 +02007098 {.id = ALC292_FIXUP_TPT460, .name = "tpt460"},
Takashi Iwaia26d96c2018-06-26 15:09:25 +02007099 {.id = ALC298_FIXUP_TPT470_DOCK, .name = "tpt470-dock"},
Takashi Iwaiba90d6a2017-05-22 16:38:47 +02007100 {.id = ALC233_FIXUP_LENOVO_MULTI_CODECS, .name = "dual-codecs"},
Takashi Iwai28d1d6d2017-10-18 14:01:58 +02007101 {.id = ALC700_FIXUP_INTEL_REFERENCE, .name = "alc700-ref"},
Takashi Iwaia26d96c2018-06-26 15:09:25 +02007102 {.id = ALC269_FIXUP_SONY_VAIO, .name = "vaio"},
7103 {.id = ALC269_FIXUP_DELL_M101Z, .name = "dell-m101z"},
7104 {.id = ALC269_FIXUP_ASUS_G73JW, .name = "asus-g73jw"},
7105 {.id = ALC269_FIXUP_LENOVO_EAPD, .name = "lenovo-eapd"},
7106 {.id = ALC275_FIXUP_SONY_HWEQ, .name = "sony-hweq"},
7107 {.id = ALC269_FIXUP_PCM_44K, .name = "pcm44k"},
7108 {.id = ALC269_FIXUP_LIFEBOOK, .name = "lifebook"},
7109 {.id = ALC269_FIXUP_LIFEBOOK_EXTMIC, .name = "lifebook-extmic"},
7110 {.id = ALC269_FIXUP_LIFEBOOK_HP_PIN, .name = "lifebook-hp-pin"},
7111 {.id = ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC, .name = "lifebook-u7x7"},
7112 {.id = ALC269VB_FIXUP_AMIC, .name = "alc269vb-amic"},
7113 {.id = ALC269VB_FIXUP_DMIC, .name = "alc269vb-dmic"},
7114 {.id = ALC269_FIXUP_HP_MUTE_LED_MIC1, .name = "hp-mute-led-mic1"},
7115 {.id = ALC269_FIXUP_HP_MUTE_LED_MIC2, .name = "hp-mute-led-mic2"},
7116 {.id = ALC269_FIXUP_HP_MUTE_LED_MIC3, .name = "hp-mute-led-mic3"},
7117 {.id = ALC269_FIXUP_HP_GPIO_MIC1_LED, .name = "hp-gpio-mic1"},
7118 {.id = ALC269_FIXUP_HP_LINE1_MIC1_LED, .name = "hp-line1-mic1"},
7119 {.id = ALC269_FIXUP_NO_SHUTUP, .name = "noshutup"},
7120 {.id = ALC286_FIXUP_SONY_MIC_NO_PRESENCE, .name = "sony-nomic"},
7121 {.id = ALC269_FIXUP_ASPIRE_HEADSET_MIC, .name = "aspire-headset-mic"},
7122 {.id = ALC269_FIXUP_ASUS_X101, .name = "asus-x101"},
7123 {.id = ALC271_FIXUP_HP_GATE_MIC_JACK, .name = "acer-ao7xx"},
7124 {.id = ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572, .name = "acer-aspire-e1"},
7125 {.id = ALC269_FIXUP_ACER_AC700, .name = "acer-ac700"},
7126 {.id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST, .name = "limit-mic-boost"},
7127 {.id = ALC269VB_FIXUP_ASUS_ZENBOOK, .name = "asus-zenbook"},
7128 {.id = ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A, .name = "asus-zenbook-ux31a"},
7129 {.id = ALC269VB_FIXUP_ORDISSIMO_EVE2, .name = "ordissimo"},
7130 {.id = ALC282_FIXUP_ASUS_TX300, .name = "asus-tx300"},
7131 {.id = ALC283_FIXUP_INT_MIC, .name = "alc283-int-mic"},
7132 {.id = ALC290_FIXUP_MONO_SPEAKERS_HSJACK, .name = "mono-speakers"},
7133 {.id = ALC290_FIXUP_SUBWOOFER_HSJACK, .name = "alc290-subwoofer"},
7134 {.id = ALC269_FIXUP_THINKPAD_ACPI, .name = "thinkpad"},
7135 {.id = ALC269_FIXUP_DMIC_THINKPAD_ACPI, .name = "dmic-thinkpad"},
7136 {.id = ALC255_FIXUP_ACER_MIC_NO_PRESENCE, .name = "alc255-acer"},
7137 {.id = ALC255_FIXUP_ASUS_MIC_NO_PRESENCE, .name = "alc255-asus"},
7138 {.id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc255-dell1"},
7139 {.id = ALC255_FIXUP_DELL2_MIC_NO_PRESENCE, .name = "alc255-dell2"},
7140 {.id = ALC293_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc293-dell1"},
7141 {.id = ALC283_FIXUP_HEADSET_MIC, .name = "alc283-headset"},
Takashi Iwaib3802782018-11-26 17:47:46 +01007142 {.id = ALC255_FIXUP_MIC_MUTE_LED, .name = "alc255-dell-mute"},
Takashi Iwaia26d96c2018-06-26 15:09:25 +02007143 {.id = ALC282_FIXUP_ASPIRE_V5_PINS, .name = "aspire-v5"},
7144 {.id = ALC280_FIXUP_HP_GPIO4, .name = "hp-gpio4"},
7145 {.id = ALC286_FIXUP_HP_GPIO_LED, .name = "hp-gpio-led"},
7146 {.id = ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY, .name = "hp-gpio2-hotkey"},
7147 {.id = ALC280_FIXUP_HP_DOCK_PINS, .name = "hp-dock-pins"},
7148 {.id = ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED, .name = "hp-dock-gpio-mic"},
7149 {.id = ALC280_FIXUP_HP_9480M, .name = "hp-9480m"},
7150 {.id = ALC288_FIXUP_DELL_HEADSET_MODE, .name = "alc288-dell-headset"},
7151 {.id = ALC288_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc288-dell1"},
7152 {.id = ALC288_FIXUP_DELL_XPS_13, .name = "alc288-dell-xps13"},
7153 {.id = ALC292_FIXUP_DELL_E7X, .name = "dell-e7x"},
7154 {.id = ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK, .name = "alc293-dell"},
7155 {.id = ALC298_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc298-dell1"},
7156 {.id = ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE, .name = "alc298-dell-aio"},
7157 {.id = ALC275_FIXUP_DELL_XPS, .name = "alc275-dell-xps"},
7158 {.id = ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE, .name = "alc256-dell-xps13"},
7159 {.id = ALC293_FIXUP_LENOVO_SPK_NOISE, .name = "lenovo-spk-noise"},
7160 {.id = ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY, .name = "lenovo-hotkey"},
7161 {.id = ALC255_FIXUP_DELL_SPK_NOISE, .name = "dell-spk-noise"},
Kailang Yang82aa0d72019-01-11 17:15:53 +08007162 {.id = ALC225_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc225-dell1"},
Takashi Iwaia26d96c2018-06-26 15:09:25 +02007163 {.id = ALC295_FIXUP_DISABLE_DAC3, .name = "alc295-disable-dac3"},
7164 {.id = ALC280_FIXUP_HP_HEADSET_MIC, .name = "alc280-hp-headset"},
7165 {.id = ALC221_FIXUP_HP_FRONT_MIC, .name = "alc221-hp-mic"},
7166 {.id = ALC298_FIXUP_SPK_VOLUME, .name = "alc298-spk-volume"},
7167 {.id = ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER, .name = "dell-inspiron-7559"},
7168 {.id = ALC269_FIXUP_ATIV_BOOK_8, .name = "ativ-book"},
7169 {.id = ALC221_FIXUP_HP_MIC_NO_PRESENCE, .name = "alc221-hp-mic"},
7170 {.id = ALC256_FIXUP_ASUS_HEADSET_MODE, .name = "alc256-asus-headset"},
7171 {.id = ALC256_FIXUP_ASUS_MIC, .name = "alc256-asus-mic"},
7172 {.id = ALC256_FIXUP_ASUS_AIO_GPIO2, .name = "alc256-asus-aio"},
7173 {.id = ALC233_FIXUP_ASUS_MIC_NO_PRESENCE, .name = "alc233-asus"},
7174 {.id = ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE, .name = "alc233-eapd"},
7175 {.id = ALC294_FIXUP_LENOVO_MIC_LOCATION, .name = "alc294-lenovo-mic"},
7176 {.id = ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE, .name = "alc225-wyse"},
7177 {.id = ALC274_FIXUP_DELL_AIO_LINEOUT_VERB, .name = "alc274-dell-aio"},
7178 {.id = ALC255_FIXUP_DUMMY_LINEOUT_VERB, .name = "alc255-dummy-lineout"},
7179 {.id = ALC255_FIXUP_DELL_HEADSET_MIC, .name = "alc255-dell-headset"},
7180 {.id = ALC295_FIXUP_HP_X360, .name = "alc295-hp-x360"},
Kailang Yang8983eb62019-04-03 15:31:49 +08007181 {.id = ALC225_FIXUP_HEADSET_JACK, .name = "alc-headset-jack"},
7182 {.id = ALC295_FIXUP_CHROME_BOOK, .name = "alc-chrome-book"},
Bernhard Rosenkraenzere2a829b2019-03-05 00:38:19 +01007183 {.id = ALC299_FIXUP_PREDATOR_SPK, .name = "predator-spk"},
Takashi Iwai1d045db2011-07-07 18:23:21 +02007184 {}
7185};
Kailang Yangcfc5a842016-02-03 15:20:39 +08007186#define ALC225_STANDARD_PINS \
Kailang Yangcfc5a842016-02-03 15:20:39 +08007187 {0x21, 0x04211020}
Takashi Iwai1d045db2011-07-07 18:23:21 +02007188
Hui Wange8191a82015-04-24 13:39:59 +08007189#define ALC256_STANDARD_PINS \
7190 {0x12, 0x90a60140}, \
7191 {0x14, 0x90170110}, \
Hui Wange8191a82015-04-24 13:39:59 +08007192 {0x21, 0x02211020}
7193
David Henningssonfea185e2014-09-03 10:23:04 +02007194#define ALC282_STANDARD_PINS \
Hui Wang11580292015-08-03 11:03:49 +08007195 {0x14, 0x90170110}
Kailang Yange1e62b92015-04-08 16:01:22 +08007196
David Henningssonfea185e2014-09-03 10:23:04 +02007197#define ALC290_STANDARD_PINS \
Hui Wang11580292015-08-03 11:03:49 +08007198 {0x12, 0x99a30130}
David Henningssonfea185e2014-09-03 10:23:04 +02007199
7200#define ALC292_STANDARD_PINS \
7201 {0x14, 0x90170110}, \
Hui Wang11580292015-08-03 11:03:49 +08007202 {0x15, 0x0221401f}
Kailang Yang977e6272015-05-18 15:31:20 +08007203
Hui Wang3f6409702016-09-11 11:26:16 +08007204#define ALC295_STANDARD_PINS \
7205 {0x12, 0xb7a60130}, \
7206 {0x14, 0x90170110}, \
Hui Wang3f6409702016-09-11 11:26:16 +08007207 {0x21, 0x04211020}
7208
Woodrow Shen703867e2015-08-05 12:34:12 +08007209#define ALC298_STANDARD_PINS \
7210 {0x12, 0x90a60130}, \
7211 {0x21, 0x03211020}
7212
Hui Wange1918932014-05-26 16:22:44 +08007213static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
Kailang Yang8a328ac2018-08-21 16:54:41 +08007214 SND_HDA_PIN_QUIRK(0x10ec0221, 0x103c, "HP Workstation", ALC221_FIXUP_HP_HEADSET_MIC,
7215 {0x14, 0x01014020},
7216 {0x17, 0x90170110},
7217 {0x18, 0x02a11030},
7218 {0x19, 0x0181303F},
7219 {0x21, 0x0221102f}),
Chris Chiu5824ce82017-02-28 14:17:11 -06007220 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1025, "Acer", ALC255_FIXUP_ACER_MIC_NO_PRESENCE,
7221 {0x12, 0x90a601c0},
7222 {0x14, 0x90171120},
7223 {0x21, 0x02211030}),
Chris Chiu615966a2017-02-28 14:17:12 -06007224 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1043, "ASUS", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE,
7225 {0x14, 0x90170110},
7226 {0x1b, 0x90a70130},
7227 {0x21, 0x03211020}),
7228 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1043, "ASUS", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE,
7229 {0x1a, 0x90a70130},
7230 {0x1b, 0x90170110},
7231 {0x21, 0x03211020}),
David Henningsson2ae95572016-02-25 09:37:05 +01007232 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
Kailang Yangcfc5a842016-02-03 15:20:39 +08007233 ALC225_STANDARD_PINS,
Hui Wang8a132092016-07-08 14:26:57 +08007234 {0x12, 0xb7a60130},
Kailang Yangcfc5a842016-02-03 15:20:39 +08007235 {0x14, 0x901701a0}),
David Henningsson2ae95572016-02-25 09:37:05 +01007236 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
Kailang Yangcfc5a842016-02-03 15:20:39 +08007237 ALC225_STANDARD_PINS,
Hui Wang8a132092016-07-08 14:26:57 +08007238 {0x12, 0xb7a60130},
Kailang Yangcfc5a842016-02-03 15:20:39 +08007239 {0x14, 0x901701b0}),
Hui Wang8a132092016-07-08 14:26:57 +08007240 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
7241 ALC225_STANDARD_PINS,
7242 {0x12, 0xb7a60150},
7243 {0x14, 0x901701a0}),
7244 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
7245 ALC225_STANDARD_PINS,
7246 {0x12, 0xb7a60150},
7247 {0x14, 0x901701b0}),
7248 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
7249 ALC225_STANDARD_PINS,
7250 {0x12, 0xb7a60130},
7251 {0x1b, 0x90170110}),
Kai-Heng Feng0ce48e12017-11-20 02:29:13 -05007252 SND_HDA_PIN_QUIRK(0x10ec0233, 0x8086, "Intel NUC Skull Canyon", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
7253 {0x1b, 0x01111010},
7254 {0x1e, 0x01451130},
7255 {0x21, 0x02211020}),
Hui Wang986376b2018-05-30 12:33:07 +08007256 SND_HDA_PIN_QUIRK(0x10ec0235, 0x17aa, "Lenovo", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY,
7257 {0x12, 0x90a60140},
7258 {0x14, 0x90170110},
7259 {0x19, 0x02a11030},
7260 {0x21, 0x02211020}),
Hui Wange41fc8c2018-06-25 14:40:56 +08007261 SND_HDA_PIN_QUIRK(0x10ec0235, 0x17aa, "Lenovo", ALC294_FIXUP_LENOVO_MIC_LOCATION,
7262 {0x14, 0x90170110},
7263 {0x19, 0x02a11030},
7264 {0x1a, 0x02a11040},
7265 {0x1b, 0x01014020},
7266 {0x21, 0x0221101f}),
Hui Wangc6b17f12018-07-06 15:14:11 +08007267 SND_HDA_PIN_QUIRK(0x10ec0235, 0x17aa, "Lenovo", ALC294_FIXUP_LENOVO_MIC_LOCATION,
7268 {0x14, 0x90170110},
Hui Wangd06fb562018-10-10 11:57:25 +08007269 {0x19, 0x02a11030},
7270 {0x1a, 0x02a11040},
7271 {0x1b, 0x01011020},
7272 {0x21, 0x0221101f}),
7273 SND_HDA_PIN_QUIRK(0x10ec0235, 0x17aa, "Lenovo", ALC294_FIXUP_LENOVO_MIC_LOCATION,
7274 {0x14, 0x90170110},
Hui Wangc6b17f12018-07-06 15:14:11 +08007275 {0x19, 0x02a11020},
7276 {0x1a, 0x02a11030},
7277 {0x21, 0x0221101f}),
Hui Wangf2657882017-10-24 16:53:34 +08007278 SND_HDA_PIN_QUIRK(0x10ec0236, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7279 {0x12, 0x90a60140},
7280 {0x14, 0x90170110},
7281 {0x21, 0x02211020}),
7282 SND_HDA_PIN_QUIRK(0x10ec0236, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7283 {0x12, 0x90a60140},
7284 {0x14, 0x90170150},
7285 {0x21, 0x02211020}),
Hui Wangb26e36b2019-04-17 16:10:32 +08007286 SND_HDA_PIN_QUIRK(0x10ec0236, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7287 {0x21, 0x02211020}),
Kailang Yang0a29c572019-04-24 16:34:25 +08007288 SND_HDA_PIN_QUIRK(0x10ec0236, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7289 {0x12, 0x40000000},
7290 {0x14, 0x90170110},
7291 {0x21, 0x02211020}),
Hui Wangc77900e2014-09-03 11:31:07 +08007292 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE,
Hui Wangc77900e2014-09-03 11:31:07 +08007293 {0x14, 0x90170110},
Hui Wangc77900e2014-09-03 11:31:07 +08007294 {0x21, 0x02211020}),
David Henningsson76c21322014-06-24 14:46:54 +02007295 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang86c72d12016-05-25 12:12:32 +08007296 {0x14, 0x90170130},
7297 {0x21, 0x02211040}),
7298 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningsson76c21322014-06-24 14:46:54 +02007299 {0x12, 0x90a60140},
7300 {0x14, 0x90170110},
David Henningsson76c21322014-06-24 14:46:54 +02007301 {0x21, 0x02211020}),
7302 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7303 {0x12, 0x90a60160},
7304 {0x14, 0x90170120},
David Henningsson76c21322014-06-24 14:46:54 +02007305 {0x21, 0x02211030}),
7306 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang392c9da2016-09-26 10:59:38 +08007307 {0x14, 0x90170110},
7308 {0x1b, 0x02011020},
7309 {0x21, 0x0221101f}),
7310 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang6aecd872016-10-20 14:03:33 +08007311 {0x14, 0x90170110},
7312 {0x1b, 0x01011020},
7313 {0x21, 0x0221101f}),
7314 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssoncba59972015-07-22 10:00:25 +02007315 {0x14, 0x90170130},
David Henningssoncba59972015-07-22 10:00:25 +02007316 {0x1b, 0x01014020},
David Henningssoncba59972015-07-22 10:00:25 +02007317 {0x21, 0x0221103f}),
7318 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang59ec4b52016-08-04 15:28:04 +08007319 {0x14, 0x90170130},
Hui Wang6aecd872016-10-20 14:03:33 +08007320 {0x1b, 0x01011020},
7321 {0x21, 0x0221103f}),
7322 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7323 {0x14, 0x90170130},
Hui Wang59ec4b52016-08-04 15:28:04 +08007324 {0x1b, 0x02011020},
7325 {0x21, 0x0221103f}),
7326 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Woodrow Shene9c28e12015-07-25 10:36:16 +08007327 {0x14, 0x90170150},
Woodrow Shene9c28e12015-07-25 10:36:16 +08007328 {0x1b, 0x02011020},
Woodrow Shene9c28e12015-07-25 10:36:16 +08007329 {0x21, 0x0221105f}),
7330 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Woodrow Shene9c28e12015-07-25 10:36:16 +08007331 {0x14, 0x90170110},
Woodrow Shene9c28e12015-07-25 10:36:16 +08007332 {0x1b, 0x01014020},
Woodrow Shene9c28e12015-07-25 10:36:16 +08007333 {0x21, 0x0221101f}),
7334 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningsson76c21322014-06-24 14:46:54 +02007335 {0x12, 0x90a60160},
7336 {0x14, 0x90170120},
7337 {0x17, 0x90170140},
David Henningsson76c21322014-06-24 14:46:54 +02007338 {0x21, 0x0321102f}),
7339 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7340 {0x12, 0x90a60160},
7341 {0x14, 0x90170130},
David Henningsson76c21322014-06-24 14:46:54 +02007342 {0x21, 0x02211040}),
7343 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7344 {0x12, 0x90a60160},
7345 {0x14, 0x90170140},
David Henningsson76c21322014-06-24 14:46:54 +02007346 {0x21, 0x02211050}),
7347 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7348 {0x12, 0x90a60170},
7349 {0x14, 0x90170120},
David Henningsson76c21322014-06-24 14:46:54 +02007350 {0x21, 0x02211030}),
7351 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7352 {0x12, 0x90a60170},
7353 {0x14, 0x90170130},
David Henningsson76c21322014-06-24 14:46:54 +02007354 {0x21, 0x02211040}),
Hui Wang70658b92015-03-06 14:03:57 +08007355 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang70658b92015-03-06 14:03:57 +08007356 {0x12, 0x90a60170},
Hui Wang0a1f90a2016-01-13 11:51:38 +08007357 {0x14, 0x90171130},
7358 {0x21, 0x02211040}),
7359 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7360 {0x12, 0x90a60170},
Hui Wang70658b92015-03-06 14:03:57 +08007361 {0x14, 0x90170140},
Hui Wang70658b92015-03-06 14:03:57 +08007362 {0x21, 0x02211050}),
David Henningsson9b5a4e32015-05-11 14:04:14 +02007363 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell Inspiron 5548", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningsson9b5a4e32015-05-11 14:04:14 +02007364 {0x12, 0x90a60180},
7365 {0x14, 0x90170130},
David Henningsson9b5a4e32015-05-11 14:04:14 +02007366 {0x21, 0x02211040}),
AceLan Kaof90d83b2016-06-03 14:45:25 +08007367 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell Inspiron 5565", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7368 {0x12, 0x90a60180},
7369 {0x14, 0x90170120},
7370 {0x21, 0x02211030}),
Hui Wang989dbe42016-11-23 16:05:38 +08007371 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7372 {0x1b, 0x01011020},
7373 {0x21, 0x02211010}),
Kailang Yang7081adf2015-03-30 17:05:37 +08007374 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang285d5dd2017-12-22 11:17:45 +08007375 {0x12, 0x90a60130},
7376 {0x14, 0x90170110},
7377 {0x1b, 0x01011020},
7378 {0x21, 0x0221101f}),
7379 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Kailang Yang81a12312015-05-28 16:48:22 +08007380 {0x12, 0x90a60160},
7381 {0x14, 0x90170120},
Kailang Yang81a12312015-05-28 16:48:22 +08007382 {0x21, 0x02211030}),
7383 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Woodrow Shenf83c3292016-06-24 15:58:34 +08007384 {0x12, 0x90a60170},
7385 {0x14, 0x90170120},
7386 {0x21, 0x02211030}),
Shrirang Bagul311042d2016-08-29 15:19:27 +08007387 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell Inspiron 5468", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7388 {0x12, 0x90a60180},
7389 {0x14, 0x90170120},
7390 {0x21, 0x02211030}),
Woodrow Shenf83c3292016-06-24 15:58:34 +08007391 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang3f6409702016-09-11 11:26:16 +08007392 {0x12, 0xb7a60130},
7393 {0x14, 0x90170110},
7394 {0x21, 0x02211020}),
David Henningssoncf51eb92014-10-30 08:26:02 +01007395 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang3f2f7c52018-01-29 14:23:15 +08007396 {0x12, 0x90a60130},
7397 {0x14, 0x90170110},
7398 {0x14, 0x01011020},
7399 {0x21, 0x0221101f}),
7400 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssoncf51eb92014-10-30 08:26:02 +01007401 ALC256_STANDARD_PINS),
Hui Wangb26e36b2019-04-17 16:10:32 +08007402 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
7403 {0x14, 0x90170110},
7404 {0x1b, 0x01011020},
7405 {0x21, 0x0221101f}),
Chris Chiuc1732ed2017-02-28 14:17:13 -06007406 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC,
7407 {0x14, 0x90170110},
7408 {0x1b, 0x90a70130},
7409 {0x21, 0x04211020}),
7410 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC,
7411 {0x14, 0x90170110},
7412 {0x1b, 0x90a70130},
7413 {0x21, 0x03211020}),
Jian-Hong Pane1037352019-03-22 11:37:18 +08007414 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE,
Chris Chiua806ef12019-03-22 11:37:20 +08007415 {0x12, 0x90a60130},
7416 {0x14, 0x90170110},
7417 {0x21, 0x03211020}),
7418 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE,
Jian-Hong Pan6ac371a2019-03-22 11:37:22 +08007419 {0x12, 0x90a60130},
7420 {0x14, 0x90170110},
7421 {0x21, 0x04211020}),
7422 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE,
Jian-Hong Pane1037352019-03-22 11:37:18 +08007423 {0x1a, 0x90a70130},
7424 {0x1b, 0x90170110},
7425 {0x21, 0x03211020}),
Kailang Yang92266652017-12-14 15:28:58 +08007426 SND_HDA_PIN_QUIRK(0x10ec0274, 0x1028, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB,
Hui Wang75ee94b2017-11-09 08:48:08 +08007427 {0x12, 0xb7a60130},
7428 {0x13, 0xb8a61140},
7429 {0x16, 0x90170110},
7430 {0x21, 0x04211020}),
David Henningssoncf51eb92014-10-30 08:26:02 +01007431 SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC280_FIXUP_HP_GPIO4,
7432 {0x12, 0x90a60130},
7433 {0x14, 0x90170110},
7434 {0x15, 0x0421101f},
Hui Wang11580292015-08-03 11:03:49 +08007435 {0x1a, 0x04a11020}),
Hui Wang02796612014-09-03 11:31:11 +08007436 SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED,
7437 {0x12, 0x90a60140},
Hui Wang02796612014-09-03 11:31:11 +08007438 {0x14, 0x90170110},
7439 {0x15, 0x0421101f},
Hui Wang02796612014-09-03 11:31:11 +08007440 {0x18, 0x02811030},
Hui Wang02796612014-09-03 11:31:11 +08007441 {0x1a, 0x04a1103f},
Hui Wang11580292015-08-03 11:03:49 +08007442 {0x1b, 0x02011020}),
David Henningsson42304472014-07-22 11:42:17 +02007443 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP 15 Touchsmart", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007444 ALC282_STANDARD_PINS,
David Henningsson42304472014-07-22 11:42:17 +02007445 {0x12, 0x99a30130},
David Henningsson42304472014-07-22 11:42:17 +02007446 {0x19, 0x03a11020},
David Henningsson42304472014-07-22 11:42:17 +02007447 {0x21, 0x0321101f}),
Hui Wang2c609992014-09-03 11:31:08 +08007448 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007449 ALC282_STANDARD_PINS,
Hui Wang2c609992014-09-03 11:31:08 +08007450 {0x12, 0x99a30130},
Hui Wang2c609992014-09-03 11:31:08 +08007451 {0x19, 0x03a11020},
Hui Wang2c609992014-09-03 11:31:08 +08007452 {0x21, 0x03211040}),
7453 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007454 ALC282_STANDARD_PINS,
Hui Wang2c609992014-09-03 11:31:08 +08007455 {0x12, 0x99a30130},
Hui Wang2c609992014-09-03 11:31:08 +08007456 {0x19, 0x03a11030},
Hui Wang2c609992014-09-03 11:31:08 +08007457 {0x21, 0x03211020}),
7458 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007459 ALC282_STANDARD_PINS,
Hui Wang2c609992014-09-03 11:31:08 +08007460 {0x12, 0x99a30130},
Hui Wang2c609992014-09-03 11:31:08 +08007461 {0x19, 0x04a11020},
Hui Wang2c609992014-09-03 11:31:08 +08007462 {0x21, 0x0421101f}),
Hui Wang200afc02014-09-03 11:31:10 +08007463 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED,
David Henningssonaec856d2014-09-03 10:23:05 +02007464 ALC282_STANDARD_PINS,
Hui Wang200afc02014-09-03 11:31:10 +08007465 {0x12, 0x90a60140},
Hui Wang200afc02014-09-03 11:31:10 +08007466 {0x19, 0x04a11030},
Hui Wang200afc02014-09-03 11:31:10 +08007467 {0x21, 0x04211020}),
David Henningsson76c21322014-06-24 14:46:54 +02007468 SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007469 ALC282_STANDARD_PINS,
David Henningsson76c21322014-06-24 14:46:54 +02007470 {0x12, 0x90a60130},
David Henningsson76c21322014-06-24 14:46:54 +02007471 {0x21, 0x0321101f}),
7472 SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
7473 {0x12, 0x90a60160},
7474 {0x14, 0x90170120},
David Henningsson76c21322014-06-24 14:46:54 +02007475 {0x21, 0x02211030}),
Hui Wangbc262172014-09-03 11:31:05 +08007476 SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007477 ALC282_STANDARD_PINS,
Hui Wangbc262172014-09-03 11:31:05 +08007478 {0x12, 0x90a60130},
Hui Wangbc262172014-09-03 11:31:05 +08007479 {0x19, 0x03a11020},
Hui Wangbc262172014-09-03 11:31:05 +08007480 {0x21, 0x0321101f}),
Hui Wangc8c6ee62019-02-14 11:41:33 +08007481 SND_HDA_PIN_QUIRK(0x10ec0285, 0x17aa, "Lenovo", ALC285_FIXUP_LENOVO_PC_BEEP_IN_NOISE,
Hui Wangc4cfcf62018-11-26 14:17:16 +08007482 {0x12, 0x90a60130},
7483 {0x14, 0x90170110},
7484 {0x19, 0x04a11040},
7485 {0x21, 0x04211020}),
Chris Chiu33aaebd2018-12-05 14:48:53 +08007486 SND_HDA_PIN_QUIRK(0x10ec0286, 0x1025, "Acer", ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE,
7487 {0x12, 0x90a60130},
7488 {0x17, 0x90170110},
7489 {0x21, 0x02211020}),
Takashi Iwaid44a6862018-06-19 23:04:03 +02007490 SND_HDA_PIN_QUIRK(0x10ec0288, 0x1028, "Dell", ALC288_FIXUP_DELL1_MIC_NO_PRESENCE,
Kailang Yange1e62b92015-04-08 16:01:22 +08007491 {0x12, 0x90a60120},
Kailang Yange1e62b92015-04-08 16:01:22 +08007492 {0x14, 0x90170110},
Kailang Yange1e62b92015-04-08 16:01:22 +08007493 {0x21, 0x0321101f}),
Hui Wangd5078192018-03-02 13:05:36 +08007494 SND_HDA_PIN_QUIRK(0x10ec0289, 0x1028, "Dell", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
Hui Wang3f2f7c52018-01-29 14:23:15 +08007495 {0x12, 0xb7a60130},
7496 {0x14, 0x90170110},
7497 {0x21, 0x04211020}),
Hui Wange4442bc2014-09-03 11:31:09 +08007498 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007499 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08007500 {0x15, 0x04211040},
Hui Wange4442bc2014-09-03 11:31:09 +08007501 {0x18, 0x90170112},
Hui Wang11580292015-08-03 11:03:49 +08007502 {0x1a, 0x04a11020}),
Hui Wange4442bc2014-09-03 11:31:09 +08007503 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007504 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08007505 {0x15, 0x04211040},
Hui Wange4442bc2014-09-03 11:31:09 +08007506 {0x18, 0x90170110},
Hui Wang11580292015-08-03 11:03:49 +08007507 {0x1a, 0x04a11020}),
Hui Wange4442bc2014-09-03 11:31:09 +08007508 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007509 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08007510 {0x15, 0x0421101f},
Hui Wang11580292015-08-03 11:03:49 +08007511 {0x1a, 0x04a11020}),
Hui Wange4442bc2014-09-03 11:31:09 +08007512 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007513 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08007514 {0x15, 0x04211020},
Hui Wang11580292015-08-03 11:03:49 +08007515 {0x1a, 0x04a11040}),
Hui Wange4442bc2014-09-03 11:31:09 +08007516 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007517 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08007518 {0x14, 0x90170110},
7519 {0x15, 0x04211020},
Hui Wang11580292015-08-03 11:03:49 +08007520 {0x1a, 0x04a11040}),
Hui Wange4442bc2014-09-03 11:31:09 +08007521 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007522 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08007523 {0x14, 0x90170110},
7524 {0x15, 0x04211020},
Hui Wang11580292015-08-03 11:03:49 +08007525 {0x1a, 0x04a11020}),
Hui Wange4442bc2014-09-03 11:31:09 +08007526 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007527 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08007528 {0x14, 0x90170110},
7529 {0x15, 0x0421101f},
Hui Wang11580292015-08-03 11:03:49 +08007530 {0x1a, 0x04a11020}),
Hui Wange8818fa2014-09-03 11:31:04 +08007531 SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007532 ALC292_STANDARD_PINS,
Hui Wange8818fa2014-09-03 11:31:04 +08007533 {0x12, 0x90a60140},
Hui Wange8818fa2014-09-03 11:31:04 +08007534 {0x16, 0x01014020},
Hui Wang11580292015-08-03 11:03:49 +08007535 {0x19, 0x01a19030}),
Hui Wange8818fa2014-09-03 11:31:04 +08007536 SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007537 ALC292_STANDARD_PINS,
Hui Wange8818fa2014-09-03 11:31:04 +08007538 {0x12, 0x90a60140},
Hui Wange8818fa2014-09-03 11:31:04 +08007539 {0x16, 0x01014020},
7540 {0x18, 0x02a19031},
Hui Wang11580292015-08-03 11:03:49 +08007541 {0x19, 0x01a1903e}),
David Henningsson76c21322014-06-24 14:46:54 +02007542 SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007543 ALC292_STANDARD_PINS,
Hui Wang11580292015-08-03 11:03:49 +08007544 {0x12, 0x90a60140}),
David Henningsson76c21322014-06-24 14:46:54 +02007545 SND_HDA_PIN_QUIRK(0x10ec0293, 0x1028, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007546 ALC292_STANDARD_PINS,
David Henningsson76c21322014-06-24 14:46:54 +02007547 {0x13, 0x90a60140},
David Henningsson76c21322014-06-24 14:46:54 +02007548 {0x16, 0x21014020},
Hui Wang11580292015-08-03 11:03:49 +08007549 {0x19, 0x21a19030}),
David Henningssone03fdbd2014-06-27 08:41:59 +02007550 SND_HDA_PIN_QUIRK(0x10ec0293, 0x1028, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007551 ALC292_STANDARD_PINS,
Hui Wang11580292015-08-03 11:03:49 +08007552 {0x13, 0x90a60140}),
Chris Chiud8ae4582018-12-07 17:17:11 +08007553 SND_HDA_PIN_QUIRK(0x10ec0294, 0x1043, "ASUS", ALC294_FIXUP_ASUS_MIC,
7554 {0x14, 0x90170110},
7555 {0x1b, 0x90a70130},
7556 {0x21, 0x04211020}),
Jian-Hong Pan0bea4cc2018-12-07 17:17:13 +08007557 SND_HDA_PIN_QUIRK(0x10ec0294, 0x1043, "ASUS", ALC294_FIXUP_ASUS_SPK,
7558 {0x12, 0x90a60130},
7559 {0x17, 0x90170110},
Jian-Hong Pan8bb37a22019-02-21 17:00:18 +08007560 {0x21, 0x03211020}),
7561 SND_HDA_PIN_QUIRK(0x10ec0294, 0x1043, "ASUS", ALC294_FIXUP_ASUS_SPK,
7562 {0x12, 0x90a60130},
7563 {0x17, 0x90170110},
Jian-Hong Pan0bea4cc2018-12-07 17:17:13 +08007564 {0x21, 0x04211020}),
Takashi Iwai3887c262019-04-30 15:10:01 +02007565 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1043, "ASUS", ALC294_FIXUP_ASUS_SPK,
7566 {0x12, 0x90a60130},
7567 {0x17, 0x90170110},
7568 {0x21, 0x03211020}),
Hui Wang3f6409702016-09-11 11:26:16 +08007569 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
Kailang Yang0a29c572019-04-24 16:34:25 +08007570 {0x14, 0x90170110},
7571 {0x21, 0x04211020}),
Hui Wang3f6409702016-09-11 11:26:16 +08007572 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wangf771d5b2016-10-18 10:59:09 +08007573 ALC295_STANDARD_PINS,
7574 {0x17, 0x21014020},
7575 {0x18, 0x21a19030}),
7576 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
7577 ALC295_STANDARD_PINS,
7578 {0x17, 0x21014040},
7579 {0x18, 0x21a19050}),
Hui Wang3f307832017-03-23 10:00:25 +08007580 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
7581 ALC295_STANDARD_PINS),
Kailang Yang977e6272015-05-18 15:31:20 +08007582 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
Woodrow Shen703867e2015-08-05 12:34:12 +08007583 ALC298_STANDARD_PINS,
Takashi Iwai9f502ff2015-08-05 12:09:45 +02007584 {0x17, 0x90170110}),
7585 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
7586 ALC298_STANDARD_PINS,
Woodrow Shen703867e2015-08-05 12:34:12 +08007587 {0x17, 0x90170140}),
7588 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
7589 ALC298_STANDARD_PINS,
Takashi Iwai9f502ff2015-08-05 12:09:45 +02007590 {0x17, 0x90170150}),
Kai-Heng Feng9f1bc2c42017-02-16 15:26:54 +08007591 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_SPK_VOLUME,
7592 {0x12, 0xb7a60140},
7593 {0x13, 0xb7a60150},
7594 {0x17, 0x90170110},
7595 {0x1a, 0x03011020},
7596 {0x21, 0x03211030}),
Kailang Yangfcc6c872017-06-29 15:21:27 +08007597 SND_HDA_PIN_QUIRK(0x10ec0299, 0x1028, "Dell", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
7598 ALC225_STANDARD_PINS,
7599 {0x12, 0xb7a60130},
Kailang Yangfcc6c872017-06-29 15:21:27 +08007600 {0x17, 0x90170110}),
Hui Wange1918932014-05-26 16:22:44 +08007601 {}
7602};
Takashi Iwai1d045db2011-07-07 18:23:21 +02007603
Takashi Iwai546bb672012-03-07 08:37:19 +01007604static void alc269_fill_coef(struct hda_codec *codec)
Takashi Iwai1d045db2011-07-07 18:23:21 +02007605{
Kailang Yang526af6e2012-03-07 08:25:20 +01007606 struct alc_spec *spec = codec->spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02007607 int val;
7608
Kailang Yang526af6e2012-03-07 08:25:20 +01007609 if (spec->codec_variant != ALC269_TYPE_ALC269VB)
Takashi Iwai546bb672012-03-07 08:37:19 +01007610 return;
Kailang Yang526af6e2012-03-07 08:25:20 +01007611
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007612 if ((alc_get_coef0(codec) & 0x00ff) < 0x015) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02007613 alc_write_coef_idx(codec, 0xf, 0x960b);
7614 alc_write_coef_idx(codec, 0xe, 0x8817);
7615 }
7616
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007617 if ((alc_get_coef0(codec) & 0x00ff) == 0x016) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02007618 alc_write_coef_idx(codec, 0xf, 0x960b);
7619 alc_write_coef_idx(codec, 0xe, 0x8814);
7620 }
7621
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007622 if ((alc_get_coef0(codec) & 0x00ff) == 0x017) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02007623 /* Power up output pin */
Takashi Iwai98b24882014-08-18 13:47:50 +02007624 alc_update_coef_idx(codec, 0x04, 0, 1<<11);
Takashi Iwai1d045db2011-07-07 18:23:21 +02007625 }
7626
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007627 if ((alc_get_coef0(codec) & 0x00ff) == 0x018) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02007628 val = alc_read_coef_idx(codec, 0xd);
Takashi Iwaif3ee07d2014-08-15 17:35:00 +02007629 if (val != -1 && (val & 0x0c00) >> 10 != 0x1) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02007630 /* Capless ramp up clock control */
7631 alc_write_coef_idx(codec, 0xd, val | (1<<10));
7632 }
7633 val = alc_read_coef_idx(codec, 0x17);
Takashi Iwaif3ee07d2014-08-15 17:35:00 +02007634 if (val != -1 && (val & 0x01c0) >> 6 != 0x4) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02007635 /* Class D power on reset */
7636 alc_write_coef_idx(codec, 0x17, val | (1<<7));
7637 }
7638 }
7639
Takashi Iwai98b24882014-08-18 13:47:50 +02007640 /* HP */
7641 alc_update_coef_idx(codec, 0x4, 0, 1<<11);
Takashi Iwai1d045db2011-07-07 18:23:21 +02007642}
7643
7644/*
7645 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02007646static int patch_alc269(struct hda_codec *codec)
7647{
7648 struct alc_spec *spec;
Takashi Iwai3de95172012-05-07 18:03:15 +02007649 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02007650
Takashi Iwai3de95172012-05-07 18:03:15 +02007651 err = alc_alloc_spec(codec, 0x0b);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007652 if (err < 0)
Takashi Iwai3de95172012-05-07 18:03:15 +02007653 return err;
7654
7655 spec = codec->spec;
Takashi Iwai08c189f2012-12-19 15:22:24 +01007656 spec->gen.shared_mic_vref_pin = 0x18;
Takashi Iwai8b99aba2015-06-15 11:59:32 +02007657 codec->power_save_node = 1;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007658
Takashi Iwai225068a2015-05-29 10:42:14 +02007659#ifdef CONFIG_PM
7660 codec->patch_ops.suspend = alc269_suspend;
7661 codec->patch_ops.resume = alc269_resume;
7662#endif
Kailang Yangc2d6af52017-06-21 14:50:54 +08007663 spec->shutup = alc_default_shutup;
7664 spec->init_hook = alc_default_init;
Takashi Iwai225068a2015-05-29 10:42:14 +02007665
Takashi Iwai7639a062015-03-03 10:07:24 +01007666 switch (codec->core.vendor_id) {
Kailang Yang065380f2013-01-10 10:25:48 +01007667 case 0x10ec0269:
Takashi Iwai1d045db2011-07-07 18:23:21 +02007668 spec->codec_variant = ALC269_TYPE_ALC269VA;
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007669 switch (alc_get_coef0(codec) & 0x00f0) {
7670 case 0x0010:
Takashi Iwai5100cd02014-02-15 10:03:19 +01007671 if (codec->bus->pci &&
7672 codec->bus->pci->subsystem_vendor == 0x1025 &&
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007673 spec->cdefine.platform_type == 1)
Takashi Iwai20ca0c32011-10-17 16:00:35 +02007674 err = alc_codec_rename(codec, "ALC271X");
Takashi Iwai1d045db2011-07-07 18:23:21 +02007675 spec->codec_variant = ALC269_TYPE_ALC269VB;
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007676 break;
7677 case 0x0020:
Takashi Iwai5100cd02014-02-15 10:03:19 +01007678 if (codec->bus->pci &&
7679 codec->bus->pci->subsystem_vendor == 0x17aa &&
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007680 codec->bus->pci->subsystem_device == 0x21f3)
Takashi Iwai20ca0c32011-10-17 16:00:35 +02007681 err = alc_codec_rename(codec, "ALC3202");
Takashi Iwai1d045db2011-07-07 18:23:21 +02007682 spec->codec_variant = ALC269_TYPE_ALC269VC;
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007683 break;
Kailang Yangadcc70b2012-05-25 08:08:38 +02007684 case 0x0030:
7685 spec->codec_variant = ALC269_TYPE_ALC269VD;
7686 break;
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007687 default:
Takashi Iwai1d045db2011-07-07 18:23:21 +02007688 alc_fix_pll_init(codec, 0x20, 0x04, 15);
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007689 }
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007690 if (err < 0)
7691 goto error;
Kailang Yangc2d6af52017-06-21 14:50:54 +08007692 spec->shutup = alc269_shutup;
Takashi Iwai546bb672012-03-07 08:37:19 +01007693 spec->init_hook = alc269_fill_coef;
Takashi Iwai1d045db2011-07-07 18:23:21 +02007694 alc269_fill_coef(codec);
Kailang Yang065380f2013-01-10 10:25:48 +01007695 break;
7696
7697 case 0x10ec0280:
7698 case 0x10ec0290:
7699 spec->codec_variant = ALC269_TYPE_ALC280;
7700 break;
7701 case 0x10ec0282:
Kailang Yang065380f2013-01-10 10:25:48 +01007702 spec->codec_variant = ALC269_TYPE_ALC282;
Kailang Yang7b5c7a02014-03-18 16:15:54 +08007703 spec->shutup = alc282_shutup;
7704 spec->init_hook = alc282_init;
Kailang Yang065380f2013-01-10 10:25:48 +01007705 break;
Kailang Yang2af02be2013-08-22 10:03:50 +02007706 case 0x10ec0233:
7707 case 0x10ec0283:
7708 spec->codec_variant = ALC269_TYPE_ALC283;
7709 spec->shutup = alc283_shutup;
7710 spec->init_hook = alc283_init;
7711 break;
Kailang Yang065380f2013-01-10 10:25:48 +01007712 case 0x10ec0284:
7713 case 0x10ec0292:
7714 spec->codec_variant = ALC269_TYPE_ALC284;
7715 break;
Kailang Yang161ebf22013-10-24 11:36:33 +02007716 case 0x10ec0293:
Kailang Yang4731d5d2017-06-30 15:22:57 +08007717 spec->codec_variant = ALC269_TYPE_ALC293;
Kailang Yang161ebf22013-10-24 11:36:33 +02007718 break;
Kailang Yang7fc7d042013-04-25 11:04:43 +02007719 case 0x10ec0286:
Kailang Yang7c665932014-04-14 15:09:44 +08007720 case 0x10ec0288:
Kailang Yang7fc7d042013-04-25 11:04:43 +02007721 spec->codec_variant = ALC269_TYPE_ALC286;
Kailang Yangf7ae9ba2014-06-30 16:10:37 +08007722 spec->shutup = alc286_shutup;
Kailang Yang7fc7d042013-04-25 11:04:43 +02007723 break;
Kailang Yang506b62c2014-12-18 17:07:44 +08007724 case 0x10ec0298:
7725 spec->codec_variant = ALC269_TYPE_ALC298;
7726 break;
Kailang Yangea04a1d2018-04-25 15:31:52 +08007727 case 0x10ec0235:
Kailang Yang1d04c9d2013-10-24 11:35:18 +02007728 case 0x10ec0255:
7729 spec->codec_variant = ALC269_TYPE_ALC255;
Kailang Yangab3b8e52018-04-25 16:05:27 +08007730 spec->shutup = alc256_shutup;
7731 spec->init_hook = alc256_init;
Kailang Yang1d04c9d2013-10-24 11:35:18 +02007732 break;
Kailang Yang736f20a2017-10-20 15:06:34 +08007733 case 0x10ec0236:
Kailang Yang4344aec2014-12-17 17:39:05 +08007734 case 0x10ec0256:
7735 spec->codec_variant = ALC269_TYPE_ALC256;
Kailang Yang4a219ef2017-06-16 16:54:35 +08007736 spec->shutup = alc256_shutup;
7737 spec->init_hook = alc256_init;
David Henningsson7d1b6e22015-04-21 10:48:46 +02007738 spec->gen.mixer_nid = 0; /* ALC256 does not have any loopback mixer path */
Kailang Yangd32b6662015-04-23 15:10:53 +08007739 alc_update_coef_idx(codec, 0x36, 1 << 13, 1 << 5); /* Switch pcbeep path to Line in path*/
Kailang Yang4344aec2014-12-17 17:39:05 +08007740 break;
Kailang Yangf429e7e2017-12-05 15:38:24 +08007741 case 0x10ec0257:
7742 spec->codec_variant = ALC269_TYPE_ALC257;
Kailang Yang88d42b22018-03-14 16:08:57 +08007743 spec->shutup = alc256_shutup;
7744 spec->init_hook = alc256_init;
Kailang Yangf429e7e2017-12-05 15:38:24 +08007745 spec->gen.mixer_nid = 0;
7746 break;
Kailang Yang0a6f0602017-06-30 16:00:48 +08007747 case 0x10ec0215:
7748 case 0x10ec0285:
7749 case 0x10ec0289:
7750 spec->codec_variant = ALC269_TYPE_ALC215;
Kailang Yang1b6832be2018-01-17 15:32:03 +08007751 spec->shutup = alc225_shutup;
7752 spec->init_hook = alc225_init;
Kailang Yang0a6f0602017-06-30 16:00:48 +08007753 spec->gen.mixer_nid = 0;
7754 break;
Kailang Yang42314302016-02-03 15:03:50 +08007755 case 0x10ec0225:
Kailang Yang7d727862016-05-24 16:46:07 +08007756 case 0x10ec0295:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08007757 case 0x10ec0299:
Kailang Yang42314302016-02-03 15:03:50 +08007758 spec->codec_variant = ALC269_TYPE_ALC225;
Kailang Yangda911b12018-01-05 16:50:08 +08007759 spec->shutup = alc225_shutup;
7760 spec->init_hook = alc225_init;
Takashi Iwaic1350bf2017-12-27 09:03:45 +01007761 spec->gen.mixer_nid = 0; /* no loopback on ALC225, ALC295 and ALC299 */
Kailang Yang42314302016-02-03 15:03:50 +08007762 break;
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08007763 case 0x10ec0234:
7764 case 0x10ec0274:
7765 case 0x10ec0294:
7766 spec->codec_variant = ALC269_TYPE_ALC294;
Hui Wang532a7782017-06-26 12:30:32 +08007767 spec->gen.mixer_nid = 0; /* ALC2x4 does not have any loopback mixer path */
Kailang Yang71683c32017-06-20 16:33:50 +08007768 alc_update_coef_idx(codec, 0x6b, 0x0018, (1<<4) | (1<<3)); /* UAJ MIC Vref control by verb */
Kailang Yang693abe12019-01-29 15:38:21 +08007769 spec->init_hook = alc294_init;
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08007770 break;
Kailang Yang1078bef2018-11-08 16:36:15 +08007771 case 0x10ec0300:
7772 spec->codec_variant = ALC269_TYPE_ALC300;
7773 spec->gen.mixer_nid = 0; /* no loopback on ALC300 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02007774 break;
Kailang Yang6fbae352016-05-30 16:44:20 +08007775 case 0x10ec0700:
7776 case 0x10ec0701:
7777 case 0x10ec0703:
7778 spec->codec_variant = ALC269_TYPE_ALC700;
7779 spec->gen.mixer_nid = 0; /* ALC700 does not have any loopback mixer path */
Kailang Yang2d7fe612017-11-22 15:21:32 +08007780 alc_update_coef_idx(codec, 0x4a, 1 << 15, 0); /* Combo jack auto trigger control */
Kailang Yang693abe12019-01-29 15:38:21 +08007781 spec->init_hook = alc294_init;
Kailang Yang6fbae352016-05-30 16:44:20 +08007782 break;
7783
Takashi Iwai1d045db2011-07-07 18:23:21 +02007784 }
7785
Kailang Yangad60d502013-06-28 12:03:01 +02007786 if (snd_hda_codec_read(codec, 0x51, 0, AC_VERB_PARAMETERS, 0) == 0x10ec5505) {
Kailang Yang97a26572013-11-29 00:35:26 -05007787 spec->has_alc5505_dsp = 1;
Kailang Yangad60d502013-06-28 12:03:01 +02007788 spec->init_hook = alc5505_dsp_init;
7789 }
7790
Takashi Iwaiefe55732018-06-15 11:55:02 +02007791 snd_hda_pick_fixup(codec, alc269_fixup_models,
7792 alc269_fixup_tbl, alc269_fixups);
7793 snd_hda_pick_pin_fixup(codec, alc269_pin_fixup_tbl, alc269_fixups);
7794 snd_hda_pick_fixup(codec, NULL, alc269_fixup_vendor_tbl,
7795 alc269_fixups);
7796 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
7797
7798 alc_auto_parse_customize_define(codec);
7799
7800 if (has_cdefine_beep(codec))
7801 spec->gen.beep_nid = 0x01;
7802
Takashi Iwaia4297b52011-08-23 18:40:12 +02007803 /* automatic parse from the BIOS config */
7804 err = alc269_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007805 if (err < 0)
7806 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02007807
Takashi Iwaifea80fa2018-06-20 12:52:46 +02007808 if (!spec->gen.no_analog && spec->gen.beep_nid && spec->gen.mixer_nid) {
7809 err = set_beep_amp(spec, spec->gen.mixer_nid, 0x04, HDA_INPUT);
7810 if (err < 0)
7811 goto error;
7812 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02007813
Takashi Iwai1727a772013-01-10 09:52:52 +01007814 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01007815
Takashi Iwai1d045db2011-07-07 18:23:21 +02007816 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007817
7818 error:
7819 alc_free(codec);
7820 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02007821}
7822
7823/*
7824 * ALC861
7825 */
7826
Takashi Iwai1d045db2011-07-07 18:23:21 +02007827static int alc861_parse_auto_config(struct hda_codec *codec)
7828{
Takashi Iwai1d045db2011-07-07 18:23:21 +02007829 static const hda_nid_t alc861_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02007830 static const hda_nid_t alc861_ssids[] = { 0x0e, 0x0f, 0x0b, 0 };
7831 return alc_parse_auto_config(codec, alc861_ignore, alc861_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02007832}
7833
Takashi Iwai1d045db2011-07-07 18:23:21 +02007834/* Pin config fixes */
7835enum {
Takashi Iwaie652f4c2012-02-13 11:56:25 +01007836 ALC861_FIXUP_FSC_AMILO_PI1505,
7837 ALC861_FIXUP_AMP_VREF_0F,
7838 ALC861_FIXUP_NO_JACK_DETECT,
7839 ALC861_FIXUP_ASUS_A6RP,
Takashi Iwai6ddf0fd2013-11-29 12:47:34 +01007840 ALC660_FIXUP_ASUS_W7J,
Takashi Iwai1d045db2011-07-07 18:23:21 +02007841};
7842
Takashi Iwai31150f22012-01-30 10:54:08 +01007843/* On some laptops, VREF of pin 0x0f is abused for controlling the main amp */
7844static void alc861_fixup_asus_amp_vref_0f(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01007845 const struct hda_fixup *fix, int action)
Takashi Iwai31150f22012-01-30 10:54:08 +01007846{
7847 struct alc_spec *spec = codec->spec;
7848 unsigned int val;
7849
Takashi Iwai1727a772013-01-10 09:52:52 +01007850 if (action != HDA_FIXUP_ACT_INIT)
Takashi Iwai31150f22012-01-30 10:54:08 +01007851 return;
Takashi Iwaid3f02d62013-01-10 10:12:22 +01007852 val = snd_hda_codec_get_pin_target(codec, 0x0f);
Takashi Iwai31150f22012-01-30 10:54:08 +01007853 if (!(val & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN)))
7854 val |= AC_PINCTL_IN_EN;
7855 val |= AC_PINCTL_VREF_50;
Takashi Iwaicdd03ce2012-04-20 12:34:50 +02007856 snd_hda_set_pin_ctl(codec, 0x0f, val);
Takashi Iwai08c189f2012-12-19 15:22:24 +01007857 spec->gen.keep_vref_in_automute = 1;
Takashi Iwai31150f22012-01-30 10:54:08 +01007858}
7859
Takashi Iwaie652f4c2012-02-13 11:56:25 +01007860/* suppress the jack-detection */
7861static void alc_fixup_no_jack_detect(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01007862 const struct hda_fixup *fix, int action)
Takashi Iwaie652f4c2012-02-13 11:56:25 +01007863{
Takashi Iwai1727a772013-01-10 09:52:52 +01007864 if (action == HDA_FIXUP_ACT_PRE_PROBE)
Takashi Iwaie652f4c2012-02-13 11:56:25 +01007865 codec->no_jack_detect = 1;
Jesper Juhl7d7eb9e2012-04-12 22:11:25 +02007866}
Takashi Iwaie652f4c2012-02-13 11:56:25 +01007867
Takashi Iwai1727a772013-01-10 09:52:52 +01007868static const struct hda_fixup alc861_fixups[] = {
Takashi Iwaie652f4c2012-02-13 11:56:25 +01007869 [ALC861_FIXUP_FSC_AMILO_PI1505] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01007870 .type = HDA_FIXUP_PINS,
7871 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02007872 { 0x0b, 0x0221101f }, /* HP */
7873 { 0x0f, 0x90170310 }, /* speaker */
7874 { }
7875 }
7876 },
Takashi Iwaie652f4c2012-02-13 11:56:25 +01007877 [ALC861_FIXUP_AMP_VREF_0F] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01007878 .type = HDA_FIXUP_FUNC,
Takashi Iwai31150f22012-01-30 10:54:08 +01007879 .v.func = alc861_fixup_asus_amp_vref_0f,
Takashi Iwai3b25eb62012-01-25 09:55:46 +01007880 },
Takashi Iwaie652f4c2012-02-13 11:56:25 +01007881 [ALC861_FIXUP_NO_JACK_DETECT] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01007882 .type = HDA_FIXUP_FUNC,
Takashi Iwaie652f4c2012-02-13 11:56:25 +01007883 .v.func = alc_fixup_no_jack_detect,
7884 },
7885 [ALC861_FIXUP_ASUS_A6RP] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01007886 .type = HDA_FIXUP_FUNC,
Takashi Iwaie652f4c2012-02-13 11:56:25 +01007887 .v.func = alc861_fixup_asus_amp_vref_0f,
7888 .chained = true,
7889 .chain_id = ALC861_FIXUP_NO_JACK_DETECT,
Takashi Iwai6ddf0fd2013-11-29 12:47:34 +01007890 },
7891 [ALC660_FIXUP_ASUS_W7J] = {
7892 .type = HDA_FIXUP_VERBS,
7893 .v.verbs = (const struct hda_verb[]) {
7894 /* ASUS W7J needs a magic pin setup on unused NID 0x10
7895 * for enabling outputs
7896 */
7897 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
7898 { }
7899 },
Takashi Iwaie652f4c2012-02-13 11:56:25 +01007900 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02007901};
7902
7903static const struct snd_pci_quirk alc861_fixup_tbl[] = {
Takashi Iwai6ddf0fd2013-11-29 12:47:34 +01007904 SND_PCI_QUIRK(0x1043, 0x1253, "ASUS W7J", ALC660_FIXUP_ASUS_W7J),
Takashi Iwaie7ca2372013-12-02 15:27:19 +01007905 SND_PCI_QUIRK(0x1043, 0x1263, "ASUS Z35HL", ALC660_FIXUP_ASUS_W7J),
Takashi Iwaie652f4c2012-02-13 11:56:25 +01007906 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS A6Rp", ALC861_FIXUP_ASUS_A6RP),
7907 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", ALC861_FIXUP_AMP_VREF_0F),
7908 SND_PCI_QUIRK(0x1462, 0x7254, "HP DX2200", ALC861_FIXUP_NO_JACK_DETECT),
7909 SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", ALC861_FIXUP_AMP_VREF_0F),
7910 SND_PCI_QUIRK(0x1584, 0x0000, "Uniwill ECS M31EI", ALC861_FIXUP_AMP_VREF_0F),
7911 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", ALC861_FIXUP_FSC_AMILO_PI1505),
Takashi Iwai1d045db2011-07-07 18:23:21 +02007912 {}
7913};
7914
7915/*
7916 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02007917static int patch_alc861(struct hda_codec *codec)
7918{
7919 struct alc_spec *spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02007920 int err;
7921
Takashi Iwai3de95172012-05-07 18:03:15 +02007922 err = alc_alloc_spec(codec, 0x15);
7923 if (err < 0)
7924 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02007925
Takashi Iwai3de95172012-05-07 18:03:15 +02007926 spec = codec->spec;
Takashi Iwai7504b6c2013-03-18 11:25:51 +01007927 spec->gen.beep_nid = 0x23;
Takashi Iwai1d045db2011-07-07 18:23:21 +02007928
Takashi Iwai225068a2015-05-29 10:42:14 +02007929#ifdef CONFIG_PM
7930 spec->power_hook = alc_power_eapd;
7931#endif
7932
Takashi Iwai1727a772013-01-10 09:52:52 +01007933 snd_hda_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
7934 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02007935
Takashi Iwaicb4e4822011-08-23 17:34:25 +02007936 /* automatic parse from the BIOS config */
7937 err = alc861_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007938 if (err < 0)
7939 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02007940
Takashi Iwaifea80fa2018-06-20 12:52:46 +02007941 if (!spec->gen.no_analog) {
7942 err = set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
7943 if (err < 0)
7944 goto error;
7945 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02007946
Takashi Iwai1727a772013-01-10 09:52:52 +01007947 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01007948
Takashi Iwai1d045db2011-07-07 18:23:21 +02007949 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007950
7951 error:
7952 alc_free(codec);
7953 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02007954}
7955
7956/*
7957 * ALC861-VD support
7958 *
7959 * Based on ALC882
7960 *
7961 * In addition, an independent DAC
7962 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02007963static int alc861vd_parse_auto_config(struct hda_codec *codec)
7964{
Takashi Iwai1d045db2011-07-07 18:23:21 +02007965 static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02007966 static const hda_nid_t alc861vd_ssids[] = { 0x15, 0x1b, 0x14, 0 };
7967 return alc_parse_auto_config(codec, alc861vd_ignore, alc861vd_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02007968}
7969
Takashi Iwai1d045db2011-07-07 18:23:21 +02007970enum {
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02007971 ALC660VD_FIX_ASUS_GPIO1,
7972 ALC861VD_FIX_DALLAS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02007973};
7974
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02007975/* exclude VREF80 */
7976static void alc861vd_fixup_dallas(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01007977 const struct hda_fixup *fix, int action)
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02007978{
Takashi Iwai1727a772013-01-10 09:52:52 +01007979 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwaib78562b2012-12-17 20:06:49 +01007980 snd_hda_override_pin_caps(codec, 0x18, 0x00000734);
7981 snd_hda_override_pin_caps(codec, 0x19, 0x0000073c);
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02007982 }
7983}
7984
Takashi Iwaidf73d832018-06-19 23:05:47 +02007985/* reset GPIO1 */
7986static void alc660vd_fixup_asus_gpio1(struct hda_codec *codec,
7987 const struct hda_fixup *fix, int action)
7988{
7989 struct alc_spec *spec = codec->spec;
7990
7991 if (action == HDA_FIXUP_ACT_PRE_PROBE)
7992 spec->gpio_mask |= 0x02;
7993 alc_fixup_gpio(codec, action, 0x01);
7994}
7995
Takashi Iwai1727a772013-01-10 09:52:52 +01007996static const struct hda_fixup alc861vd_fixups[] = {
Takashi Iwai1d045db2011-07-07 18:23:21 +02007997 [ALC660VD_FIX_ASUS_GPIO1] = {
Takashi Iwaidf73d832018-06-19 23:05:47 +02007998 .type = HDA_FIXUP_FUNC,
7999 .v.func = alc660vd_fixup_asus_gpio1,
Takashi Iwai1d045db2011-07-07 18:23:21 +02008000 },
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008001 [ALC861VD_FIX_DALLAS] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008002 .type = HDA_FIXUP_FUNC,
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008003 .v.func = alc861vd_fixup_dallas,
8004 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02008005};
8006
8007static const struct snd_pci_quirk alc861vd_fixup_tbl[] = {
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008008 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_FIX_DALLAS),
Takashi Iwai1d045db2011-07-07 18:23:21 +02008009 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02008010 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_FIX_DALLAS),
Takashi Iwai1d045db2011-07-07 18:23:21 +02008011 {}
8012};
8013
Takashi Iwai1d045db2011-07-07 18:23:21 +02008014/*
8015 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02008016static int patch_alc861vd(struct hda_codec *codec)
8017{
8018 struct alc_spec *spec;
Takashi Iwaicb4e4822011-08-23 17:34:25 +02008019 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008020
Takashi Iwai3de95172012-05-07 18:03:15 +02008021 err = alc_alloc_spec(codec, 0x0b);
8022 if (err < 0)
8023 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008024
Takashi Iwai3de95172012-05-07 18:03:15 +02008025 spec = codec->spec;
Takashi Iwai7504b6c2013-03-18 11:25:51 +01008026 spec->gen.beep_nid = 0x23;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008027
Takashi Iwai225068a2015-05-29 10:42:14 +02008028 spec->shutup = alc_eapd_shutup;
8029
Takashi Iwai1727a772013-01-10 09:52:52 +01008030 snd_hda_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
8031 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02008032
Takashi Iwaicb4e4822011-08-23 17:34:25 +02008033 /* automatic parse from the BIOS config */
8034 err = alc861vd_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008035 if (err < 0)
8036 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008037
Takashi Iwaifea80fa2018-06-20 12:52:46 +02008038 if (!spec->gen.no_analog) {
8039 err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
8040 if (err < 0)
8041 goto error;
8042 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02008043
Takashi Iwai1727a772013-01-10 09:52:52 +01008044 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01008045
Takashi Iwai1d045db2011-07-07 18:23:21 +02008046 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008047
8048 error:
8049 alc_free(codec);
8050 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02008051}
8052
8053/*
8054 * ALC662 support
8055 *
8056 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
8057 * configuration. Each pin widget can choose any input DACs and a mixer.
8058 * Each ADC is connected from a mixer of all inputs. This makes possible
8059 * 6-channel independent captures.
8060 *
8061 * In addition, an independent DAC for the multi-playback (not used in this
8062 * driver yet).
8063 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02008064
8065/*
8066 * BIOS auto configuration
8067 */
8068
Kailang Yangbc9f98a2007-04-12 13:06:07 +02008069static int alc662_parse_auto_config(struct hda_codec *codec)
8070{
Takashi Iwai4c6d72d2011-05-02 11:30:18 +02008071 static const hda_nid_t alc662_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02008072 static const hda_nid_t alc663_ssids[] = { 0x15, 0x1b, 0x14, 0x21 };
8073 static const hda_nid_t alc662_ssids[] = { 0x15, 0x1b, 0x14, 0 };
8074 const hda_nid_t *ssids;
Takashi Iwaiee979a142008-09-02 15:42:20 +02008075
Takashi Iwai7639a062015-03-03 10:07:24 +01008076 if (codec->core.vendor_id == 0x10ec0272 || codec->core.vendor_id == 0x10ec0663 ||
8077 codec->core.vendor_id == 0x10ec0665 || codec->core.vendor_id == 0x10ec0670 ||
8078 codec->core.vendor_id == 0x10ec0671)
Takashi Iwai3e6179b2011-07-08 16:55:13 +02008079 ssids = alc663_ssids;
Kailang Yang6227cdc2010-02-25 08:36:52 +01008080 else
Takashi Iwai3e6179b2011-07-08 16:55:13 +02008081 ssids = alc662_ssids;
8082 return alc_parse_auto_config(codec, alc662_ignore, ssids);
Kailang Yangbc9f98a2007-04-12 13:06:07 +02008083}
8084
Todd Broch6be79482010-12-07 16:51:05 -08008085static void alc272_fixup_mario(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01008086 const struct hda_fixup *fix, int action)
Takashi Iwai6fc398c2011-01-13 14:36:37 +01008087{
Takashi Iwai9bb1f062013-01-10 17:14:29 +01008088 if (action != HDA_FIXUP_ACT_PRE_PROBE)
Takashi Iwai6fc398c2011-01-13 14:36:37 +01008089 return;
Todd Broch6be79482010-12-07 16:51:05 -08008090 if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT,
8091 (0x3b << AC_AMPCAP_OFFSET_SHIFT) |
8092 (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) |
8093 (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) |
8094 (0 << AC_AMPCAP_MUTE_SHIFT)))
Takashi Iwai4e76a882014-02-25 12:21:03 +01008095 codec_warn(codec, "failed to override amp caps for NID 0x2\n");
Todd Broch6be79482010-12-07 16:51:05 -08008096}
8097
Takashi Iwai8e383952013-10-30 17:41:12 +01008098static const struct snd_pcm_chmap_elem asus_pcm_2_1_chmaps[] = {
8099 { .channels = 2,
8100 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } },
8101 { .channels = 4,
8102 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR,
8103 SNDRV_CHMAP_NA, SNDRV_CHMAP_LFE } }, /* LFE only on right */
8104 { }
8105};
8106
8107/* override the 2.1 chmap */
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01008108static void alc_fixup_bass_chmap(struct hda_codec *codec,
Takashi Iwai8e383952013-10-30 17:41:12 +01008109 const struct hda_fixup *fix, int action)
8110{
8111 if (action == HDA_FIXUP_ACT_BUILD) {
8112 struct alc_spec *spec = codec->spec;
Takashi Iwaibbbc7e82015-02-27 17:43:19 +01008113 spec->gen.pcm_rec[0]->stream[0].chmap = asus_pcm_2_1_chmaps;
Takashi Iwai8e383952013-10-30 17:41:12 +01008114 }
8115}
8116
Takashi Iwaibf686652014-01-13 16:18:25 +01008117/* avoid D3 for keeping GPIO up */
8118static unsigned int gpio_led_power_filter(struct hda_codec *codec,
8119 hda_nid_t nid,
8120 unsigned int power_state)
8121{
8122 struct alc_spec *spec = codec->spec;
Takashi Iwaid261eec2018-06-19 22:32:29 +02008123 if (nid == codec->core.afg && power_state == AC_PWRST_D3 && spec->gpio_data)
Takashi Iwaibf686652014-01-13 16:18:25 +01008124 return AC_PWRST_D0;
8125 return power_state;
8126}
8127
Takashi Iwai3e887f32014-01-10 17:50:58 +01008128static void alc662_fixup_led_gpio1(struct hda_codec *codec,
8129 const struct hda_fixup *fix, int action)
8130{
8131 struct alc_spec *spec = codec->spec;
Takashi Iwai3e887f32014-01-10 17:50:58 +01008132
Takashi Iwai01e4a272018-06-19 22:47:30 +02008133 alc_fixup_hp_gpio_led(codec, action, 0x01, 0);
Takashi Iwai3e887f32014-01-10 17:50:58 +01008134 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai0f32fd192014-11-19 12:16:14 +01008135 spec->mute_led_polarity = 1;
Takashi Iwaibf686652014-01-13 16:18:25 +01008136 codec->power_filter = gpio_led_power_filter;
Takashi Iwai3e887f32014-01-10 17:50:58 +01008137 }
8138}
8139
Kailang Yangc6790c82016-11-25 16:15:17 +08008140static void alc662_usi_automute_hook(struct hda_codec *codec,
8141 struct hda_jack_callback *jack)
8142{
8143 struct alc_spec *spec = codec->spec;
8144 int vref;
8145 msleep(200);
8146 snd_hda_gen_hp_automute(codec, jack);
8147
8148 vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0;
8149 msleep(100);
8150 snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8151 vref);
8152}
8153
8154static void alc662_fixup_usi_headset_mic(struct hda_codec *codec,
8155 const struct hda_fixup *fix, int action)
8156{
8157 struct alc_spec *spec = codec->spec;
8158 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
8159 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
8160 spec->gen.hp_automute_hook = alc662_usi_automute_hook;
8161 }
8162}
8163
Kailang Yangf3f91852014-10-24 15:43:46 +08008164static struct coef_fw alc668_coefs[] = {
8165 WRITE_COEF(0x01, 0xbebe), WRITE_COEF(0x02, 0xaaaa), WRITE_COEF(0x03, 0x0),
8166 WRITE_COEF(0x04, 0x0180), WRITE_COEF(0x06, 0x0), WRITE_COEF(0x07, 0x0f80),
8167 WRITE_COEF(0x08, 0x0031), WRITE_COEF(0x0a, 0x0060), WRITE_COEF(0x0b, 0x0),
8168 WRITE_COEF(0x0c, 0x7cf7), WRITE_COEF(0x0d, 0x1080), WRITE_COEF(0x0e, 0x7f7f),
8169 WRITE_COEF(0x0f, 0xcccc), WRITE_COEF(0x10, 0xddcc), WRITE_COEF(0x11, 0x0001),
8170 WRITE_COEF(0x13, 0x0), WRITE_COEF(0x14, 0x2aa0), WRITE_COEF(0x17, 0xa940),
8171 WRITE_COEF(0x19, 0x0), WRITE_COEF(0x1a, 0x0), WRITE_COEF(0x1b, 0x0),
8172 WRITE_COEF(0x1c, 0x0), WRITE_COEF(0x1d, 0x0), WRITE_COEF(0x1e, 0x7418),
8173 WRITE_COEF(0x1f, 0x0804), WRITE_COEF(0x20, 0x4200), WRITE_COEF(0x21, 0x0468),
8174 WRITE_COEF(0x22, 0x8ccc), WRITE_COEF(0x23, 0x0250), WRITE_COEF(0x24, 0x7418),
8175 WRITE_COEF(0x27, 0x0), WRITE_COEF(0x28, 0x8ccc), WRITE_COEF(0x2a, 0xff00),
8176 WRITE_COEF(0x2b, 0x8000), WRITE_COEF(0xa7, 0xff00), WRITE_COEF(0xa8, 0x8000),
8177 WRITE_COEF(0xaa, 0x2e17), WRITE_COEF(0xab, 0xa0c0), WRITE_COEF(0xac, 0x0),
8178 WRITE_COEF(0xad, 0x0), WRITE_COEF(0xae, 0x2ac6), WRITE_COEF(0xaf, 0xa480),
8179 WRITE_COEF(0xb0, 0x0), WRITE_COEF(0xb1, 0x0), WRITE_COEF(0xb2, 0x0),
8180 WRITE_COEF(0xb3, 0x0), WRITE_COEF(0xb4, 0x0), WRITE_COEF(0xb5, 0x1040),
8181 WRITE_COEF(0xb6, 0xd697), WRITE_COEF(0xb7, 0x902b), WRITE_COEF(0xb8, 0xd697),
8182 WRITE_COEF(0xb9, 0x902b), WRITE_COEF(0xba, 0xb8ba), WRITE_COEF(0xbb, 0xaaab),
8183 WRITE_COEF(0xbc, 0xaaaf), WRITE_COEF(0xbd, 0x6aaa), WRITE_COEF(0xbe, 0x1c02),
8184 WRITE_COEF(0xc0, 0x00ff), WRITE_COEF(0xc1, 0x0fa6),
8185 {}
8186};
8187
8188static void alc668_restore_default_value(struct hda_codec *codec)
8189{
8190 alc_process_coef_fw(codec, alc668_coefs);
8191}
8192
David Henningsson6cb3b702010-09-09 08:51:44 +02008193enum {
Daniel T Chen2df03512010-10-10 22:39:28 -04008194 ALC662_FIXUP_ASPIRE,
Takashi Iwai3e887f32014-01-10 17:50:58 +01008195 ALC662_FIXUP_LED_GPIO1,
David Henningsson6cb3b702010-09-09 08:51:44 +02008196 ALC662_FIXUP_IDEAPAD,
Todd Broch6be79482010-12-07 16:51:05 -08008197 ALC272_FIXUP_MARIO,
Anisse Astierd2ebd472011-01-20 12:36:21 +01008198 ALC662_FIXUP_CZC_P10T,
David Henningsson94024cd2011-04-29 14:10:55 +02008199 ALC662_FIXUP_SKU_IGNORE,
Takashi Iwaie59ea3e2011-06-29 17:21:00 +02008200 ALC662_FIXUP_HP_RP5800,
Takashi Iwai53c334a2011-08-23 18:27:14 +02008201 ALC662_FIXUP_ASUS_MODE1,
8202 ALC662_FIXUP_ASUS_MODE2,
8203 ALC662_FIXUP_ASUS_MODE3,
8204 ALC662_FIXUP_ASUS_MODE4,
8205 ALC662_FIXUP_ASUS_MODE5,
8206 ALC662_FIXUP_ASUS_MODE6,
8207 ALC662_FIXUP_ASUS_MODE7,
8208 ALC662_FIXUP_ASUS_MODE8,
Takashi Iwai1565cc32012-02-13 12:03:25 +01008209 ALC662_FIXUP_NO_JACK_DETECT,
David Henningssonedfe3bf2012-06-12 13:15:12 +02008210 ALC662_FIXUP_ZOTAC_Z68,
Takashi Iwai125821a2012-06-22 14:30:29 +02008211 ALC662_FIXUP_INV_DMIC,
David Henningsson1f8b46c2015-05-12 14:38:15 +02008212 ALC662_FIXUP_DELL_MIC_NO_PRESENCE,
David Henningsson73bdd592013-04-15 15:44:14 +02008213 ALC668_FIXUP_DELL_MIC_NO_PRESENCE,
David Henningsson1f8b46c2015-05-12 14:38:15 +02008214 ALC662_FIXUP_HEADSET_MODE,
David Henningsson73bdd592013-04-15 15:44:14 +02008215 ALC668_FIXUP_HEADSET_MODE,
David Henningsson8e54b4a2014-02-07 09:31:07 +01008216 ALC662_FIXUP_BASS_MODE4_CHMAP,
David Henningsson61a75f12014-02-07 09:31:08 +01008217 ALC662_FIXUP_BASS_16,
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01008218 ALC662_FIXUP_BASS_1A,
David Henningsson8e54b4a2014-02-07 09:31:07 +01008219 ALC662_FIXUP_BASS_CHMAP,
Hui Wang493a52a2014-01-14 14:07:36 +08008220 ALC668_FIXUP_AUTO_MUTE,
Gabriele Mazzotta5e6db662014-05-20 18:58:26 +02008221 ALC668_FIXUP_DELL_DISABLE_AAMIX,
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02008222 ALC668_FIXUP_DELL_XPS13,
Bobi Mihalca9d4dc582016-03-23 13:26:11 +02008223 ALC662_FIXUP_ASUS_Nx50,
Mikhail Paulyshkafc7438b2017-04-21 08:52:42 +02008224 ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE,
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07008225 ALC668_FIXUP_ASUS_Nx51,
Takashi Iwai5b7c5e12018-10-09 14:20:17 +02008226 ALC668_FIXUP_MIC_COEF,
Takashi Iwai11ba6112018-10-07 09:44:17 +02008227 ALC668_FIXUP_ASUS_G751,
Kailang Yang78f4f7c2016-06-07 11:31:34 +08008228 ALC891_FIXUP_HEADSET_MODE,
8229 ALC891_FIXUP_DELL_MIC_NO_PRESENCE,
Shrirang Bagul9b51fe32016-08-01 13:16:17 +08008230 ALC662_FIXUP_ACER_VERITON,
Takashi Iwai1a3f0992016-10-20 12:14:51 +02008231 ALC892_FIXUP_ASROCK_MOBO,
Kailang Yangc6790c82016-11-25 16:15:17 +08008232 ALC662_FIXUP_USI_FUNC,
8233 ALC662_FIXUP_USI_HEADSET_MODE,
Kailang Yangca169cc2017-04-25 16:17:40 +08008234 ALC662_FIXUP_LENOVO_MULTI_CODECS,
David Henningsson6cb3b702010-09-09 08:51:44 +02008235};
8236
Takashi Iwai1727a772013-01-10 09:52:52 +01008237static const struct hda_fixup alc662_fixups[] = {
Daniel T Chen2df03512010-10-10 22:39:28 -04008238 [ALC662_FIXUP_ASPIRE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008239 .type = HDA_FIXUP_PINS,
8240 .v.pins = (const struct hda_pintbl[]) {
Daniel T Chen2df03512010-10-10 22:39:28 -04008241 { 0x15, 0x99130112 }, /* subwoofer */
8242 { }
8243 }
8244 },
Takashi Iwai3e887f32014-01-10 17:50:58 +01008245 [ALC662_FIXUP_LED_GPIO1] = {
8246 .type = HDA_FIXUP_FUNC,
8247 .v.func = alc662_fixup_led_gpio1,
8248 },
David Henningsson6cb3b702010-09-09 08:51:44 +02008249 [ALC662_FIXUP_IDEAPAD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008250 .type = HDA_FIXUP_PINS,
8251 .v.pins = (const struct hda_pintbl[]) {
David Henningsson6cb3b702010-09-09 08:51:44 +02008252 { 0x17, 0x99130112 }, /* subwoofer */
8253 { }
Takashi Iwai3e887f32014-01-10 17:50:58 +01008254 },
8255 .chained = true,
8256 .chain_id = ALC662_FIXUP_LED_GPIO1,
David Henningsson6cb3b702010-09-09 08:51:44 +02008257 },
Todd Broch6be79482010-12-07 16:51:05 -08008258 [ALC272_FIXUP_MARIO] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008259 .type = HDA_FIXUP_FUNC,
Takashi Iwaib5bfbc62011-01-13 14:22:32 +01008260 .v.func = alc272_fixup_mario,
Anisse Astierd2ebd472011-01-20 12:36:21 +01008261 },
8262 [ALC662_FIXUP_CZC_P10T] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008263 .type = HDA_FIXUP_VERBS,
Anisse Astierd2ebd472011-01-20 12:36:21 +01008264 .v.verbs = (const struct hda_verb[]) {
8265 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
8266 {}
8267 }
8268 },
David Henningsson94024cd2011-04-29 14:10:55 +02008269 [ALC662_FIXUP_SKU_IGNORE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008270 .type = HDA_FIXUP_FUNC,
Takashi Iwai23d30f22012-05-07 17:17:32 +02008271 .v.func = alc_fixup_sku_ignore,
Takashi Iwaic6b35872011-03-28 12:05:31 +02008272 },
Takashi Iwaie59ea3e2011-06-29 17:21:00 +02008273 [ALC662_FIXUP_HP_RP5800] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008274 .type = HDA_FIXUP_PINS,
8275 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaie59ea3e2011-06-29 17:21:00 +02008276 { 0x14, 0x0221201f }, /* HP out */
8277 { }
8278 },
8279 .chained = true,
8280 .chain_id = ALC662_FIXUP_SKU_IGNORE
8281 },
Takashi Iwai53c334a2011-08-23 18:27:14 +02008282 [ALC662_FIXUP_ASUS_MODE1] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008283 .type = HDA_FIXUP_PINS,
8284 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008285 { 0x14, 0x99130110 }, /* speaker */
8286 { 0x18, 0x01a19c20 }, /* mic */
8287 { 0x19, 0x99a3092f }, /* int-mic */
8288 { 0x21, 0x0121401f }, /* HP out */
8289 { }
8290 },
8291 .chained = true,
8292 .chain_id = ALC662_FIXUP_SKU_IGNORE
8293 },
8294 [ALC662_FIXUP_ASUS_MODE2] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008295 .type = HDA_FIXUP_PINS,
8296 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai2996bdb2011-08-18 16:02:24 +02008297 { 0x14, 0x99130110 }, /* speaker */
8298 { 0x18, 0x01a19820 }, /* mic */
8299 { 0x19, 0x99a3092f }, /* int-mic */
8300 { 0x1b, 0x0121401f }, /* HP out */
8301 { }
8302 },
Takashi Iwai53c334a2011-08-23 18:27:14 +02008303 .chained = true,
8304 .chain_id = ALC662_FIXUP_SKU_IGNORE
8305 },
8306 [ALC662_FIXUP_ASUS_MODE3] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008307 .type = HDA_FIXUP_PINS,
8308 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008309 { 0x14, 0x99130110 }, /* speaker */
8310 { 0x15, 0x0121441f }, /* HP */
8311 { 0x18, 0x01a19840 }, /* mic */
8312 { 0x19, 0x99a3094f }, /* int-mic */
8313 { 0x21, 0x01211420 }, /* HP2 */
8314 { }
8315 },
8316 .chained = true,
8317 .chain_id = ALC662_FIXUP_SKU_IGNORE
8318 },
8319 [ALC662_FIXUP_ASUS_MODE4] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008320 .type = HDA_FIXUP_PINS,
8321 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008322 { 0x14, 0x99130110 }, /* speaker */
8323 { 0x16, 0x99130111 }, /* speaker */
8324 { 0x18, 0x01a19840 }, /* mic */
8325 { 0x19, 0x99a3094f }, /* int-mic */
8326 { 0x21, 0x0121441f }, /* HP */
8327 { }
8328 },
8329 .chained = true,
8330 .chain_id = ALC662_FIXUP_SKU_IGNORE
8331 },
8332 [ALC662_FIXUP_ASUS_MODE5] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008333 .type = HDA_FIXUP_PINS,
8334 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008335 { 0x14, 0x99130110 }, /* speaker */
8336 { 0x15, 0x0121441f }, /* HP */
8337 { 0x16, 0x99130111 }, /* speaker */
8338 { 0x18, 0x01a19840 }, /* mic */
8339 { 0x19, 0x99a3094f }, /* int-mic */
8340 { }
8341 },
8342 .chained = true,
8343 .chain_id = ALC662_FIXUP_SKU_IGNORE
8344 },
8345 [ALC662_FIXUP_ASUS_MODE6] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008346 .type = HDA_FIXUP_PINS,
8347 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008348 { 0x14, 0x99130110 }, /* speaker */
8349 { 0x15, 0x01211420 }, /* HP2 */
8350 { 0x18, 0x01a19840 }, /* mic */
8351 { 0x19, 0x99a3094f }, /* int-mic */
8352 { 0x1b, 0x0121441f }, /* HP */
8353 { }
8354 },
8355 .chained = true,
8356 .chain_id = ALC662_FIXUP_SKU_IGNORE
8357 },
8358 [ALC662_FIXUP_ASUS_MODE7] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008359 .type = HDA_FIXUP_PINS,
8360 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008361 { 0x14, 0x99130110 }, /* speaker */
8362 { 0x17, 0x99130111 }, /* speaker */
8363 { 0x18, 0x01a19840 }, /* mic */
8364 { 0x19, 0x99a3094f }, /* int-mic */
8365 { 0x1b, 0x01214020 }, /* HP */
8366 { 0x21, 0x0121401f }, /* HP */
8367 { }
8368 },
8369 .chained = true,
8370 .chain_id = ALC662_FIXUP_SKU_IGNORE
8371 },
8372 [ALC662_FIXUP_ASUS_MODE8] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008373 .type = HDA_FIXUP_PINS,
8374 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008375 { 0x14, 0x99130110 }, /* speaker */
8376 { 0x12, 0x99a30970 }, /* int-mic */
8377 { 0x15, 0x01214020 }, /* HP */
8378 { 0x17, 0x99130111 }, /* speaker */
8379 { 0x18, 0x01a19840 }, /* mic */
8380 { 0x21, 0x0121401f }, /* HP */
8381 { }
8382 },
8383 .chained = true,
8384 .chain_id = ALC662_FIXUP_SKU_IGNORE
Takashi Iwai2996bdb2011-08-18 16:02:24 +02008385 },
Takashi Iwai1565cc32012-02-13 12:03:25 +01008386 [ALC662_FIXUP_NO_JACK_DETECT] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008387 .type = HDA_FIXUP_FUNC,
Takashi Iwai1565cc32012-02-13 12:03:25 +01008388 .v.func = alc_fixup_no_jack_detect,
8389 },
David Henningssonedfe3bf2012-06-12 13:15:12 +02008390 [ALC662_FIXUP_ZOTAC_Z68] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008391 .type = HDA_FIXUP_PINS,
8392 .v.pins = (const struct hda_pintbl[]) {
David Henningssonedfe3bf2012-06-12 13:15:12 +02008393 { 0x1b, 0x02214020 }, /* Front HP */
8394 { }
8395 }
8396 },
Takashi Iwai125821a2012-06-22 14:30:29 +02008397 [ALC662_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01008398 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02008399 .v.func = alc_fixup_inv_dmic,
Takashi Iwai125821a2012-06-22 14:30:29 +02008400 },
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02008401 [ALC668_FIXUP_DELL_XPS13] = {
8402 .type = HDA_FIXUP_FUNC,
8403 .v.func = alc_fixup_dell_xps13,
8404 .chained = true,
8405 .chain_id = ALC668_FIXUP_DELL_DISABLE_AAMIX
8406 },
Gabriele Mazzotta5e6db662014-05-20 18:58:26 +02008407 [ALC668_FIXUP_DELL_DISABLE_AAMIX] = {
8408 .type = HDA_FIXUP_FUNC,
8409 .v.func = alc_fixup_disable_aamix,
8410 .chained = true,
8411 .chain_id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE
8412 },
Hui Wang493a52a2014-01-14 14:07:36 +08008413 [ALC668_FIXUP_AUTO_MUTE] = {
8414 .type = HDA_FIXUP_FUNC,
8415 .v.func = alc_fixup_auto_mute_via_amp,
8416 .chained = true,
8417 .chain_id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE
8418 },
David Henningsson1f8b46c2015-05-12 14:38:15 +02008419 [ALC662_FIXUP_DELL_MIC_NO_PRESENCE] = {
8420 .type = HDA_FIXUP_PINS,
8421 .v.pins = (const struct hda_pintbl[]) {
8422 { 0x19, 0x03a1113c }, /* use as headset mic, without its own jack detect */
8423 /* headphone mic by setting pin control of 0x1b (headphone out) to in + vref_50 */
8424 { }
8425 },
8426 .chained = true,
8427 .chain_id = ALC662_FIXUP_HEADSET_MODE
8428 },
8429 [ALC662_FIXUP_HEADSET_MODE] = {
8430 .type = HDA_FIXUP_FUNC,
8431 .v.func = alc_fixup_headset_mode_alc662,
8432 },
David Henningsson73bdd592013-04-15 15:44:14 +02008433 [ALC668_FIXUP_DELL_MIC_NO_PRESENCE] = {
8434 .type = HDA_FIXUP_PINS,
8435 .v.pins = (const struct hda_pintbl[]) {
8436 { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
8437 { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */
8438 { }
8439 },
8440 .chained = true,
8441 .chain_id = ALC668_FIXUP_HEADSET_MODE
8442 },
8443 [ALC668_FIXUP_HEADSET_MODE] = {
8444 .type = HDA_FIXUP_FUNC,
8445 .v.func = alc_fixup_headset_mode_alc668,
8446 },
David Henningsson8e54b4a2014-02-07 09:31:07 +01008447 [ALC662_FIXUP_BASS_MODE4_CHMAP] = {
Takashi Iwai8e383952013-10-30 17:41:12 +01008448 .type = HDA_FIXUP_FUNC,
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01008449 .v.func = alc_fixup_bass_chmap,
Takashi Iwai8e383952013-10-30 17:41:12 +01008450 .chained = true,
8451 .chain_id = ALC662_FIXUP_ASUS_MODE4
8452 },
David Henningsson61a75f12014-02-07 09:31:08 +01008453 [ALC662_FIXUP_BASS_16] = {
8454 .type = HDA_FIXUP_PINS,
8455 .v.pins = (const struct hda_pintbl[]) {
8456 {0x16, 0x80106111}, /* bass speaker */
8457 {}
8458 },
8459 .chained = true,
8460 .chain_id = ALC662_FIXUP_BASS_CHMAP,
8461 },
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01008462 [ALC662_FIXUP_BASS_1A] = {
8463 .type = HDA_FIXUP_PINS,
8464 .v.pins = (const struct hda_pintbl[]) {
8465 {0x1a, 0x80106111}, /* bass speaker */
8466 {}
8467 },
David Henningsson8e54b4a2014-02-07 09:31:07 +01008468 .chained = true,
8469 .chain_id = ALC662_FIXUP_BASS_CHMAP,
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01008470 },
David Henningsson8e54b4a2014-02-07 09:31:07 +01008471 [ALC662_FIXUP_BASS_CHMAP] = {
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01008472 .type = HDA_FIXUP_FUNC,
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01008473 .v.func = alc_fixup_bass_chmap,
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01008474 },
Bobi Mihalca9d4dc582016-03-23 13:26:11 +02008475 [ALC662_FIXUP_ASUS_Nx50] = {
8476 .type = HDA_FIXUP_FUNC,
8477 .v.func = alc_fixup_auto_mute_via_amp,
8478 .chained = true,
8479 .chain_id = ALC662_FIXUP_BASS_1A
8480 },
Mikhail Paulyshkafc7438b2017-04-21 08:52:42 +02008481 [ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE] = {
8482 .type = HDA_FIXUP_FUNC,
8483 .v.func = alc_fixup_headset_mode_alc668,
8484 .chain_id = ALC662_FIXUP_BASS_CHMAP
8485 },
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07008486 [ALC668_FIXUP_ASUS_Nx51] = {
8487 .type = HDA_FIXUP_PINS,
8488 .v.pins = (const struct hda_pintbl[]) {
Mikhail Paulyshkafc7438b2017-04-21 08:52:42 +02008489 { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
8490 { 0x1a, 0x90170151 }, /* bass speaker */
8491 { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07008492 {}
8493 },
8494 .chained = true,
Mikhail Paulyshkafc7438b2017-04-21 08:52:42 +02008495 .chain_id = ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE,
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07008496 },
Takashi Iwai5b7c5e12018-10-09 14:20:17 +02008497 [ALC668_FIXUP_MIC_COEF] = {
Takashi Iwai11ba6112018-10-07 09:44:17 +02008498 .type = HDA_FIXUP_VERBS,
8499 .v.verbs = (const struct hda_verb[]) {
8500 { 0x20, AC_VERB_SET_COEF_INDEX, 0xc3 },
8501 { 0x20, AC_VERB_SET_PROC_COEF, 0x4000 },
8502 {}
8503 },
8504 },
Takashi Iwai5b7c5e12018-10-09 14:20:17 +02008505 [ALC668_FIXUP_ASUS_G751] = {
8506 .type = HDA_FIXUP_PINS,
8507 .v.pins = (const struct hda_pintbl[]) {
8508 { 0x16, 0x0421101f }, /* HP */
8509 {}
8510 },
8511 .chained = true,
8512 .chain_id = ALC668_FIXUP_MIC_COEF
8513 },
Kailang Yang78f4f7c2016-06-07 11:31:34 +08008514 [ALC891_FIXUP_HEADSET_MODE] = {
8515 .type = HDA_FIXUP_FUNC,
8516 .v.func = alc_fixup_headset_mode,
8517 },
8518 [ALC891_FIXUP_DELL_MIC_NO_PRESENCE] = {
8519 .type = HDA_FIXUP_PINS,
8520 .v.pins = (const struct hda_pintbl[]) {
8521 { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
8522 { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */
8523 { }
8524 },
8525 .chained = true,
8526 .chain_id = ALC891_FIXUP_HEADSET_MODE
8527 },
Shrirang Bagul9b51fe32016-08-01 13:16:17 +08008528 [ALC662_FIXUP_ACER_VERITON] = {
8529 .type = HDA_FIXUP_PINS,
8530 .v.pins = (const struct hda_pintbl[]) {
8531 { 0x15, 0x50170120 }, /* no internal speaker */
8532 { }
8533 }
8534 },
Takashi Iwai1a3f0992016-10-20 12:14:51 +02008535 [ALC892_FIXUP_ASROCK_MOBO] = {
8536 .type = HDA_FIXUP_PINS,
8537 .v.pins = (const struct hda_pintbl[]) {
8538 { 0x15, 0x40f000f0 }, /* disabled */
8539 { 0x16, 0x40f000f0 }, /* disabled */
Takashi Iwai1a3f0992016-10-20 12:14:51 +02008540 { }
8541 }
8542 },
Kailang Yangc6790c82016-11-25 16:15:17 +08008543 [ALC662_FIXUP_USI_FUNC] = {
8544 .type = HDA_FIXUP_FUNC,
8545 .v.func = alc662_fixup_usi_headset_mic,
8546 },
8547 [ALC662_FIXUP_USI_HEADSET_MODE] = {
8548 .type = HDA_FIXUP_PINS,
8549 .v.pins = (const struct hda_pintbl[]) {
8550 { 0x19, 0x02a1913c }, /* use as headset mic, without its own jack detect */
8551 { 0x18, 0x01a1903d },
8552 { }
8553 },
8554 .chained = true,
8555 .chain_id = ALC662_FIXUP_USI_FUNC
8556 },
Kailang Yangca169cc2017-04-25 16:17:40 +08008557 [ALC662_FIXUP_LENOVO_MULTI_CODECS] = {
8558 .type = HDA_FIXUP_FUNC,
8559 .v.func = alc233_alc662_fixup_lenovo_dual_codecs,
8560 },
David Henningsson6cb3b702010-09-09 08:51:44 +02008561};
8562
Takashi Iwaia9111322011-05-02 11:30:18 +02008563static const struct snd_pci_quirk alc662_fixup_tbl[] = {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008564 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_FIXUP_ASUS_MODE2),
Takashi Iwaid3d38352013-08-19 20:05:50 +02008565 SND_PCI_QUIRK(0x1025, 0x022f, "Acer Aspire One", ALC662_FIXUP_INV_DMIC),
David Henningsson02f6ff92015-12-07 11:29:31 +01008566 SND_PCI_QUIRK(0x1025, 0x0241, "Packard Bell DOTS", ALC662_FIXUP_INV_DMIC),
David Henningssona6c47a82011-02-10 15:39:19 +01008567 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
David Henningsson94024cd2011-04-29 14:10:55 +02008568 SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
Takashi Iwai125821a2012-06-22 14:30:29 +02008569 SND_PCI_QUIRK(0x1025, 0x0349, "eMachines eM250", ALC662_FIXUP_INV_DMIC),
Takashi Iwai18019282013-08-16 08:17:05 +02008570 SND_PCI_QUIRK(0x1025, 0x034a, "Gateway LT27", ALC662_FIXUP_INV_DMIC),
Daniel T Chen2df03512010-10-10 22:39:28 -04008571 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
David Henningsson73bdd592013-04-15 15:44:14 +02008572 SND_PCI_QUIRK(0x1028, 0x05d8, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
8573 SND_PCI_QUIRK(0x1028, 0x05db, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
Takashi Iwaic5d019c2014-07-22 17:33:32 +02008574 SND_PCI_QUIRK(0x1028, 0x05fe, "Dell XPS 15", ALC668_FIXUP_DELL_XPS13),
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02008575 SND_PCI_QUIRK(0x1028, 0x060a, "Dell XPS 13", ALC668_FIXUP_DELL_XPS13),
Niranjan Sivakumar467e1432015-09-05 18:20:35 +02008576 SND_PCI_QUIRK(0x1028, 0x060d, "Dell M3800", ALC668_FIXUP_DELL_XPS13),
David Henningsson09d20142013-11-20 11:43:30 +01008577 SND_PCI_QUIRK(0x1028, 0x0625, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
David Henningssonad8ff992013-11-07 09:28:59 +01008578 SND_PCI_QUIRK(0x1028, 0x0626, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
Kailang Yang8dc9abb2014-04-16 15:53:12 +08008579 SND_PCI_QUIRK(0x1028, 0x0696, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
8580 SND_PCI_QUIRK(0x1028, 0x0698, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
Kailang Yang6a98e342014-10-27 16:20:30 +08008581 SND_PCI_QUIRK(0x1028, 0x069f, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
Takashi Iwaie59ea3e2011-06-29 17:21:00 +02008582 SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800),
Kaho Ng2da2dc92016-05-09 00:27:49 +08008583 SND_PCI_QUIRK(0x1043, 0x1080, "Asus UX501VW", ALC668_FIXUP_HEADSET_MODE),
Bobi Mihalca83a9efb2016-03-23 13:32:33 +02008584 SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_ASUS_Nx50),
Takashi Iwaidb8948e2016-01-18 09:17:30 +01008585 SND_PCI_QUIRK(0x1043, 0x13df, "Asus N550JX", ALC662_FIXUP_BASS_1A),
Bobi Mihalca9d4dc582016-03-23 13:26:11 +02008586 SND_PCI_QUIRK(0x1043, 0x129d, "Asus N750", ALC662_FIXUP_ASUS_Nx50),
Takashi Iwai11ba6112018-10-07 09:44:17 +02008587 SND_PCI_QUIRK(0x1043, 0x12ff, "ASUS G751", ALC668_FIXUP_ASUS_G751),
David Henningsson8e54b4a2014-02-07 09:31:07 +01008588 SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
David Henningsson61a75f12014-02-07 09:31:08 +01008589 SND_PCI_QUIRK(0x1043, 0x15a7, "ASUS UX51VZH", ALC662_FIXUP_BASS_16),
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07008590 SND_PCI_QUIRK(0x1043, 0x177d, "ASUS N551", ALC668_FIXUP_ASUS_Nx51),
8591 SND_PCI_QUIRK(0x1043, 0x17bd, "ASUS N751", ALC668_FIXUP_ASUS_Nx51),
Takashi Iwaic7efff92017-01-04 21:38:16 +01008592 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71SL", ALC662_FIXUP_ASUS_MODE8),
David Henningsson61a75f12014-02-07 09:31:08 +01008593 SND_PCI_QUIRK(0x1043, 0x1b73, "ASUS N55SF", ALC662_FIXUP_BASS_16),
David Henningsson8e54b4a2014-02-07 09:31:07 +01008594 SND_PCI_QUIRK(0x1043, 0x1bf3, "ASUS N76VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
Takashi Iwai1565cc32012-02-13 12:03:25 +01008595 SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT),
Takashi Iwai53c334a2011-08-23 18:27:14 +02008596 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2),
Daniel T Chena0e90ac2010-11-20 10:20:35 -05008597 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
Kailang Yangc6790c82016-11-25 16:15:17 +08008598 SND_PCI_QUIRK(0x14cd, 0x5003, "USI", ALC662_FIXUP_USI_HEADSET_MODE),
Kailang Yangca169cc2017-04-25 16:17:40 +08008599 SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC662_FIXUP_LENOVO_MULTI_CODECS),
Valentine Sinitsynd4118582010-10-01 22:24:08 +06008600 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
David Henningsson6cb3b702010-09-09 08:51:44 +02008601 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
Takashi Iwai1a3f0992016-10-20 12:14:51 +02008602 SND_PCI_QUIRK(0x1849, 0x5892, "ASRock B150M", ALC892_FIXUP_ASROCK_MOBO),
David Henningssonedfe3bf2012-06-12 13:15:12 +02008603 SND_PCI_QUIRK(0x19da, 0xa130, "Zotac Z68", ALC662_FIXUP_ZOTAC_Z68),
Shrirang Bagul9b51fe32016-08-01 13:16:17 +08008604 SND_PCI_QUIRK(0x1b0a, 0x01b8, "ACER Veriton", ALC662_FIXUP_ACER_VERITON),
Anisse Astierd2ebd472011-01-20 12:36:21 +01008605 SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
Takashi Iwai53c334a2011-08-23 18:27:14 +02008606
8607#if 0
8608 /* Below is a quirk table taken from the old code.
8609 * Basically the device should work as is without the fixup table.
8610 * If BIOS doesn't give a proper info, enable the corresponding
8611 * fixup entry.
Jesper Juhl7d7eb9e2012-04-12 22:11:25 +02008612 */
Takashi Iwai53c334a2011-08-23 18:27:14 +02008613 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC662_FIXUP_ASUS_MODE1),
8614 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC662_FIXUP_ASUS_MODE3),
8615 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC662_FIXUP_ASUS_MODE1),
8616 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC662_FIXUP_ASUS_MODE3),
8617 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
8618 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8619 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
8620 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC662_FIXUP_ASUS_MODE1),
8621 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC662_FIXUP_ASUS_MODE1),
8622 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8623 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC662_FIXUP_ASUS_MODE7),
8624 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC662_FIXUP_ASUS_MODE7),
8625 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC662_FIXUP_ASUS_MODE8),
8626 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC662_FIXUP_ASUS_MODE3),
8627 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC662_FIXUP_ASUS_MODE1),
8628 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8629 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_FIXUP_ASUS_MODE2),
8630 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC662_FIXUP_ASUS_MODE1),
8631 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8632 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
8633 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
8634 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8635 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC662_FIXUP_ASUS_MODE1),
8636 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC662_FIXUP_ASUS_MODE3),
8637 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_FIXUP_ASUS_MODE2),
8638 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8639 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC662_FIXUP_ASUS_MODE5),
8640 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
8641 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8642 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC662_FIXUP_ASUS_MODE1),
8643 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8644 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8645 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC662_FIXUP_ASUS_MODE3),
8646 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC662_FIXUP_ASUS_MODE3),
8647 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC662_FIXUP_ASUS_MODE1),
8648 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC662_FIXUP_ASUS_MODE1),
8649 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC662_FIXUP_ASUS_MODE1),
8650 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC662_FIXUP_ASUS_MODE1),
8651 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC662_FIXUP_ASUS_MODE1),
8652 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8653 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_FIXUP_ASUS_MODE2),
8654 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC662_FIXUP_ASUS_MODE1),
8655 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
8656 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC662_FIXUP_ASUS_MODE3),
8657 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC662_FIXUP_ASUS_MODE1),
8658 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC662_FIXUP_ASUS_MODE1),
8659 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC662_FIXUP_ASUS_MODE1),
8660 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_FIXUP_ASUS_MODE2),
8661 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
8662 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE4),
8663#endif
David Henningsson6cb3b702010-09-09 08:51:44 +02008664 {}
8665};
8666
Takashi Iwai1727a772013-01-10 09:52:52 +01008667static const struct hda_model_fixup alc662_fixup_models[] = {
Takashi Iwaiaa3841b2018-06-26 07:42:40 +02008668 {.id = ALC662_FIXUP_ASPIRE, .name = "aspire"},
8669 {.id = ALC662_FIXUP_IDEAPAD, .name = "ideapad"},
Todd Broch6be79482010-12-07 16:51:05 -08008670 {.id = ALC272_FIXUP_MARIO, .name = "mario"},
Takashi Iwaiaa3841b2018-06-26 07:42:40 +02008671 {.id = ALC662_FIXUP_HP_RP5800, .name = "hp-rp5800"},
Takashi Iwai53c334a2011-08-23 18:27:14 +02008672 {.id = ALC662_FIXUP_ASUS_MODE1, .name = "asus-mode1"},
8673 {.id = ALC662_FIXUP_ASUS_MODE2, .name = "asus-mode2"},
8674 {.id = ALC662_FIXUP_ASUS_MODE3, .name = "asus-mode3"},
8675 {.id = ALC662_FIXUP_ASUS_MODE4, .name = "asus-mode4"},
8676 {.id = ALC662_FIXUP_ASUS_MODE5, .name = "asus-mode5"},
8677 {.id = ALC662_FIXUP_ASUS_MODE6, .name = "asus-mode6"},
8678 {.id = ALC662_FIXUP_ASUS_MODE7, .name = "asus-mode7"},
8679 {.id = ALC662_FIXUP_ASUS_MODE8, .name = "asus-mode8"},
Takashi Iwaiaa3841b2018-06-26 07:42:40 +02008680 {.id = ALC662_FIXUP_ZOTAC_Z68, .name = "zotac-z68"},
Takashi Iwai6e72aa52012-06-25 10:52:25 +02008681 {.id = ALC662_FIXUP_INV_DMIC, .name = "inv-dmic"},
Takashi Iwaiaa3841b2018-06-26 07:42:40 +02008682 {.id = ALC662_FIXUP_DELL_MIC_NO_PRESENCE, .name = "alc662-headset-multi"},
David Henningssone32aa852013-06-17 11:04:02 +02008683 {.id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE, .name = "dell-headset-multi"},
Takashi Iwaiaa3841b2018-06-26 07:42:40 +02008684 {.id = ALC662_FIXUP_HEADSET_MODE, .name = "alc662-headset"},
8685 {.id = ALC668_FIXUP_HEADSET_MODE, .name = "alc668-headset"},
8686 {.id = ALC662_FIXUP_BASS_16, .name = "bass16"},
8687 {.id = ALC662_FIXUP_BASS_1A, .name = "bass1a"},
8688 {.id = ALC668_FIXUP_AUTO_MUTE, .name = "automute"},
8689 {.id = ALC668_FIXUP_DELL_XPS13, .name = "dell-xps13"},
8690 {.id = ALC662_FIXUP_ASUS_Nx50, .name = "asus-nx50"},
8691 {.id = ALC668_FIXUP_ASUS_Nx51, .name = "asus-nx51"},
Takashi Iwai40c51672018-10-07 09:47:39 +02008692 {.id = ALC668_FIXUP_ASUS_G751, .name = "asus-g751"},
Takashi Iwaiaa3841b2018-06-26 07:42:40 +02008693 {.id = ALC891_FIXUP_HEADSET_MODE, .name = "alc891-headset"},
8694 {.id = ALC891_FIXUP_DELL_MIC_NO_PRESENCE, .name = "alc891-headset-multi"},
8695 {.id = ALC662_FIXUP_ACER_VERITON, .name = "acer-veriton"},
8696 {.id = ALC892_FIXUP_ASROCK_MOBO, .name = "asrock-mobo"},
8697 {.id = ALC662_FIXUP_USI_HEADSET_MODE, .name = "usi-headset"},
Takashi Iwaiba90d6a2017-05-22 16:38:47 +02008698 {.id = ALC662_FIXUP_LENOVO_MULTI_CODECS, .name = "dual-codecs"},
Todd Broch6be79482010-12-07 16:51:05 -08008699 {}
8700};
David Henningsson6cb3b702010-09-09 08:51:44 +02008701
Hui Wang532895c2014-05-29 15:59:19 +08008702static const struct snd_hda_pin_quirk alc662_pin_fixup_tbl[] = {
Kailang Yang78f4f7c2016-06-07 11:31:34 +08008703 SND_HDA_PIN_QUIRK(0x10ec0867, 0x1028, "Dell", ALC891_FIXUP_DELL_MIC_NO_PRESENCE,
8704 {0x17, 0x02211010},
8705 {0x18, 0x01a19030},
8706 {0x1a, 0x01813040},
8707 {0x21, 0x01014020}),
David Henningsson1f8b46c2015-05-12 14:38:15 +02008708 SND_HDA_PIN_QUIRK(0x10ec0662, 0x1028, "Dell", ALC662_FIXUP_DELL_MIC_NO_PRESENCE,
David Henningsson1f8b46c2015-05-12 14:38:15 +02008709 {0x14, 0x01014010},
David Henningsson1f8b46c2015-05-12 14:38:15 +02008710 {0x18, 0x01a19020},
David Henningsson1f8b46c2015-05-12 14:38:15 +02008711 {0x1a, 0x0181302f},
Hui Wang11580292015-08-03 11:03:49 +08008712 {0x1b, 0x0221401f}),
David Henningsson76c21322014-06-24 14:46:54 +02008713 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
8714 {0x12, 0x99a30130},
8715 {0x14, 0x90170110},
8716 {0x15, 0x0321101f},
Hui Wang11580292015-08-03 11:03:49 +08008717 {0x16, 0x03011020}),
David Henningsson76c21322014-06-24 14:46:54 +02008718 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
8719 {0x12, 0x99a30140},
8720 {0x14, 0x90170110},
8721 {0x15, 0x0321101f},
Hui Wang11580292015-08-03 11:03:49 +08008722 {0x16, 0x03011020}),
David Henningsson76c21322014-06-24 14:46:54 +02008723 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
8724 {0x12, 0x99a30150},
8725 {0x14, 0x90170110},
8726 {0x15, 0x0321101f},
Hui Wang11580292015-08-03 11:03:49 +08008727 {0x16, 0x03011020}),
David Henningsson76c21322014-06-24 14:46:54 +02008728 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
David Henningsson76c21322014-06-24 14:46:54 +02008729 {0x14, 0x90170110},
8730 {0x15, 0x0321101f},
Hui Wang11580292015-08-03 11:03:49 +08008731 {0x16, 0x03011020}),
David Henningsson76c21322014-06-24 14:46:54 +02008732 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell XPS 15", ALC668_FIXUP_AUTO_MUTE,
8733 {0x12, 0x90a60130},
8734 {0x14, 0x90170110},
Hui Wang11580292015-08-03 11:03:49 +08008735 {0x15, 0x0321101f}),
Hui Wang532895c2014-05-29 15:59:19 +08008736 {}
8737};
8738
Takashi Iwai1d045db2011-07-07 18:23:21 +02008739/*
8740 */
Kailang Yangbc9f98a2007-04-12 13:06:07 +02008741static int patch_alc662(struct hda_codec *codec)
8742{
8743 struct alc_spec *spec;
Takashi Iwai3de95172012-05-07 18:03:15 +02008744 int err;
Kailang Yangbc9f98a2007-04-12 13:06:07 +02008745
Takashi Iwai3de95172012-05-07 18:03:15 +02008746 err = alc_alloc_spec(codec, 0x0b);
8747 if (err < 0)
8748 return err;
Kailang Yangbc9f98a2007-04-12 13:06:07 +02008749
Takashi Iwai3de95172012-05-07 18:03:15 +02008750 spec = codec->spec;
Takashi Iwai1f0f4b82011-06-27 10:52:59 +02008751
Takashi Iwai225068a2015-05-29 10:42:14 +02008752 spec->shutup = alc_eapd_shutup;
8753
Takashi Iwai53c334a2011-08-23 18:27:14 +02008754 /* handle multiple HPs as is */
8755 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
8756
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +02008757 alc_fix_pll_init(codec, 0x20, 0x04, 15);
8758
Takashi Iwai7639a062015-03-03 10:07:24 +01008759 switch (codec->core.vendor_id) {
Kailang Yangf3f91852014-10-24 15:43:46 +08008760 case 0x10ec0668:
8761 spec->init_hook = alc668_restore_default_value;
8762 break;
Kailang Yangf3f91852014-10-24 15:43:46 +08008763 }
Kailang Yang8663ff72012-06-29 09:35:52 +02008764
Takashi Iwai1727a772013-01-10 09:52:52 +01008765 snd_hda_pick_fixup(codec, alc662_fixup_models,
Takashi Iwai8e5a0502012-06-21 15:49:33 +02008766 alc662_fixup_tbl, alc662_fixups);
Hui Wang532895c2014-05-29 15:59:19 +08008767 snd_hda_pick_pin_fixup(codec, alc662_pin_fixup_tbl, alc662_fixups);
Takashi Iwai1727a772013-01-10 09:52:52 +01008768 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai8e5a0502012-06-21 15:49:33 +02008769
8770 alc_auto_parse_customize_define(codec);
8771
Takashi Iwai7504b6c2013-03-18 11:25:51 +01008772 if (has_cdefine_beep(codec))
8773 spec->gen.beep_nid = 0x01;
8774
Takashi Iwai1bb7e432011-10-17 16:50:59 +02008775 if ((alc_get_coef0(codec) & (1 << 14)) &&
Takashi Iwai5100cd02014-02-15 10:03:19 +01008776 codec->bus->pci && codec->bus->pci->subsystem_vendor == 0x1025 &&
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008777 spec->cdefine.platform_type == 1) {
Wei Yongjun6134b1a2013-04-18 11:12:59 +08008778 err = alc_codec_rename(codec, "ALC272X");
8779 if (err < 0)
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008780 goto error;
Takashi Iwai20ca0c32011-10-17 16:00:35 +02008781 }
Kailang Yang274693f2009-12-03 10:07:50 +01008782
Takashi Iwaib9c51062011-08-24 18:08:07 +02008783 /* automatic parse from the BIOS config */
8784 err = alc662_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008785 if (err < 0)
8786 goto error;
Kailang Yangbc9f98a2007-04-12 13:06:07 +02008787
Takashi Iwai7504b6c2013-03-18 11:25:51 +01008788 if (!spec->gen.no_analog && spec->gen.beep_nid) {
Takashi Iwai7639a062015-03-03 10:07:24 +01008789 switch (codec->core.vendor_id) {
Kailang Yangda00c242010-03-19 11:23:45 +01008790 case 0x10ec0662:
Takashi Iwaifea80fa2018-06-20 12:52:46 +02008791 err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
Kailang Yangda00c242010-03-19 11:23:45 +01008792 break;
8793 case 0x10ec0272:
8794 case 0x10ec0663:
8795 case 0x10ec0665:
Kailang Yang9ad54542013-11-26 15:41:40 +08008796 case 0x10ec0668:
Takashi Iwaifea80fa2018-06-20 12:52:46 +02008797 err = set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
Kailang Yangda00c242010-03-19 11:23:45 +01008798 break;
8799 case 0x10ec0273:
Takashi Iwaifea80fa2018-06-20 12:52:46 +02008800 err = set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
Kailang Yangda00c242010-03-19 11:23:45 +01008801 break;
8802 }
Takashi Iwaifea80fa2018-06-20 12:52:46 +02008803 if (err < 0)
8804 goto error;
Kailang Yangcec27c82010-02-04 14:18:18 +01008805 }
Takashi Iwai2134ea42008-01-10 16:53:55 +01008806
Takashi Iwai1727a772013-01-10 09:52:52 +01008807 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01008808
Kailang Yangbc9f98a2007-04-12 13:06:07 +02008809 return 0;
Kailang Yangbc9f98a2007-04-12 13:06:07 +02008810
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008811 error:
8812 alc_free(codec);
8813 return err;
Kailang Yangb478b992011-05-18 11:51:15 +02008814}
8815
Kailang Yangbc9f98a2007-04-12 13:06:07 +02008816/*
Kailang Yangd1eb57f2010-06-23 16:25:26 +02008817 * ALC680 support
8818 */
Kailang Yangd1eb57f2010-06-23 16:25:26 +02008819
Kailang Yangd1eb57f2010-06-23 16:25:26 +02008820static int alc680_parse_auto_config(struct hda_codec *codec)
8821{
Takashi Iwai3e6179b2011-07-08 16:55:13 +02008822 return alc_parse_auto_config(codec, NULL, NULL);
Kailang Yangd1eb57f2010-06-23 16:25:26 +02008823}
8824
Kailang Yangd1eb57f2010-06-23 16:25:26 +02008825/*
Kailang Yangd1eb57f2010-06-23 16:25:26 +02008826 */
Kailang Yangd1eb57f2010-06-23 16:25:26 +02008827static int patch_alc680(struct hda_codec *codec)
8828{
Kailang Yangd1eb57f2010-06-23 16:25:26 +02008829 int err;
8830
Takashi Iwai1f0f4b82011-06-27 10:52:59 +02008831 /* ALC680 has no aa-loopback mixer */
Takashi Iwai3de95172012-05-07 18:03:15 +02008832 err = alc_alloc_spec(codec, 0);
8833 if (err < 0)
8834 return err;
Takashi Iwai1f0f4b82011-06-27 10:52:59 +02008835
Takashi Iwai1ebec5f2011-08-15 13:21:48 +02008836 /* automatic parse from the BIOS config */
8837 err = alc680_parse_auto_config(codec);
8838 if (err < 0) {
8839 alc_free(codec);
8840 return err;
Kailang Yangd1eb57f2010-06-23 16:25:26 +02008841 }
8842
Kailang Yangd1eb57f2010-06-23 16:25:26 +02008843 return 0;
8844}
8845
8846/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07008847 * patch entries
8848 */
Takashi Iwaib9a94a92015-10-01 16:20:04 +02008849static const struct hda_device_id snd_hda_id_realtek[] = {
Kailang Yang0a6f0602017-06-30 16:00:48 +08008850 HDA_CODEC_ENTRY(0x10ec0215, "ALC215", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02008851 HDA_CODEC_ENTRY(0x10ec0221, "ALC221", patch_alc269),
Kailang Yang42314302016-02-03 15:03:50 +08008852 HDA_CODEC_ENTRY(0x10ec0225, "ALC225", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02008853 HDA_CODEC_ENTRY(0x10ec0231, "ALC231", patch_alc269),
8854 HDA_CODEC_ENTRY(0x10ec0233, "ALC233", patch_alc269),
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08008855 HDA_CODEC_ENTRY(0x10ec0234, "ALC234", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02008856 HDA_CODEC_ENTRY(0x10ec0235, "ALC233", patch_alc269),
Kailang Yang736f20a2017-10-20 15:06:34 +08008857 HDA_CODEC_ENTRY(0x10ec0236, "ALC236", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02008858 HDA_CODEC_ENTRY(0x10ec0255, "ALC255", patch_alc269),
8859 HDA_CODEC_ENTRY(0x10ec0256, "ALC256", patch_alc269),
Kailang Yangf429e7e2017-12-05 15:38:24 +08008860 HDA_CODEC_ENTRY(0x10ec0257, "ALC257", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02008861 HDA_CODEC_ENTRY(0x10ec0260, "ALC260", patch_alc260),
8862 HDA_CODEC_ENTRY(0x10ec0262, "ALC262", patch_alc262),
8863 HDA_CODEC_ENTRY(0x10ec0267, "ALC267", patch_alc268),
8864 HDA_CODEC_ENTRY(0x10ec0268, "ALC268", patch_alc268),
8865 HDA_CODEC_ENTRY(0x10ec0269, "ALC269", patch_alc269),
8866 HDA_CODEC_ENTRY(0x10ec0270, "ALC270", patch_alc269),
8867 HDA_CODEC_ENTRY(0x10ec0272, "ALC272", patch_alc662),
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08008868 HDA_CODEC_ENTRY(0x10ec0274, "ALC274", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02008869 HDA_CODEC_ENTRY(0x10ec0275, "ALC275", patch_alc269),
8870 HDA_CODEC_ENTRY(0x10ec0276, "ALC276", patch_alc269),
8871 HDA_CODEC_ENTRY(0x10ec0280, "ALC280", patch_alc269),
8872 HDA_CODEC_ENTRY(0x10ec0282, "ALC282", patch_alc269),
8873 HDA_CODEC_ENTRY(0x10ec0283, "ALC283", patch_alc269),
8874 HDA_CODEC_ENTRY(0x10ec0284, "ALC284", patch_alc269),
Kailang Yang0a6f0602017-06-30 16:00:48 +08008875 HDA_CODEC_ENTRY(0x10ec0285, "ALC285", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02008876 HDA_CODEC_ENTRY(0x10ec0286, "ALC286", patch_alc269),
8877 HDA_CODEC_ENTRY(0x10ec0288, "ALC288", patch_alc269),
Kailang Yang0a6f0602017-06-30 16:00:48 +08008878 HDA_CODEC_ENTRY(0x10ec0289, "ALC289", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02008879 HDA_CODEC_ENTRY(0x10ec0290, "ALC290", patch_alc269),
8880 HDA_CODEC_ENTRY(0x10ec0292, "ALC292", patch_alc269),
8881 HDA_CODEC_ENTRY(0x10ec0293, "ALC293", patch_alc269),
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08008882 HDA_CODEC_ENTRY(0x10ec0294, "ALC294", patch_alc269),
Kailang Yang7d727862016-05-24 16:46:07 +08008883 HDA_CODEC_ENTRY(0x10ec0295, "ALC295", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02008884 HDA_CODEC_ENTRY(0x10ec0298, "ALC298", patch_alc269),
Kailang Yang28f1f9b2017-01-04 14:49:07 +08008885 HDA_CODEC_ENTRY(0x10ec0299, "ALC299", patch_alc269),
Kailang Yang1078bef2018-11-08 16:36:15 +08008886 HDA_CODEC_ENTRY(0x10ec0300, "ALC300", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02008887 HDA_CODEC_REV_ENTRY(0x10ec0861, 0x100340, "ALC660", patch_alc861),
8888 HDA_CODEC_ENTRY(0x10ec0660, "ALC660-VD", patch_alc861vd),
8889 HDA_CODEC_ENTRY(0x10ec0861, "ALC861", patch_alc861),
8890 HDA_CODEC_ENTRY(0x10ec0862, "ALC861-VD", patch_alc861vd),
8891 HDA_CODEC_REV_ENTRY(0x10ec0662, 0x100002, "ALC662 rev2", patch_alc882),
8892 HDA_CODEC_REV_ENTRY(0x10ec0662, 0x100101, "ALC662 rev1", patch_alc662),
8893 HDA_CODEC_REV_ENTRY(0x10ec0662, 0x100300, "ALC662 rev3", patch_alc662),
8894 HDA_CODEC_ENTRY(0x10ec0663, "ALC663", patch_alc662),
8895 HDA_CODEC_ENTRY(0x10ec0665, "ALC665", patch_alc662),
8896 HDA_CODEC_ENTRY(0x10ec0667, "ALC667", patch_alc662),
8897 HDA_CODEC_ENTRY(0x10ec0668, "ALC668", patch_alc662),
8898 HDA_CODEC_ENTRY(0x10ec0670, "ALC670", patch_alc662),
8899 HDA_CODEC_ENTRY(0x10ec0671, "ALC671", patch_alc662),
8900 HDA_CODEC_ENTRY(0x10ec0680, "ALC680", patch_alc680),
Kailang Yang6fbae352016-05-30 16:44:20 +08008901 HDA_CODEC_ENTRY(0x10ec0700, "ALC700", patch_alc269),
8902 HDA_CODEC_ENTRY(0x10ec0701, "ALC701", patch_alc269),
8903 HDA_CODEC_ENTRY(0x10ec0703, "ALC703", patch_alc269),
Kailang Yang78f4f7c2016-06-07 11:31:34 +08008904 HDA_CODEC_ENTRY(0x10ec0867, "ALC891", patch_alc662),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02008905 HDA_CODEC_ENTRY(0x10ec0880, "ALC880", patch_alc880),
8906 HDA_CODEC_ENTRY(0x10ec0882, "ALC882", patch_alc882),
8907 HDA_CODEC_ENTRY(0x10ec0883, "ALC883", patch_alc882),
8908 HDA_CODEC_REV_ENTRY(0x10ec0885, 0x100101, "ALC889A", patch_alc882),
8909 HDA_CODEC_REV_ENTRY(0x10ec0885, 0x100103, "ALC889A", patch_alc882),
8910 HDA_CODEC_ENTRY(0x10ec0885, "ALC885", patch_alc882),
8911 HDA_CODEC_ENTRY(0x10ec0887, "ALC887", patch_alc882),
8912 HDA_CODEC_REV_ENTRY(0x10ec0888, 0x100101, "ALC1200", patch_alc882),
8913 HDA_CODEC_ENTRY(0x10ec0888, "ALC888", patch_alc882),
8914 HDA_CODEC_ENTRY(0x10ec0889, "ALC889", patch_alc882),
8915 HDA_CODEC_ENTRY(0x10ec0892, "ALC892", patch_alc662),
8916 HDA_CODEC_ENTRY(0x10ec0899, "ALC898", patch_alc882),
8917 HDA_CODEC_ENTRY(0x10ec0900, "ALC1150", patch_alc882),
Kailang Yang65553b12017-07-11 15:15:47 +08008918 HDA_CODEC_ENTRY(0x10ec1168, "ALC1220", patch_alc882),
Kailang Yanga535ad52017-01-16 16:59:26 +08008919 HDA_CODEC_ENTRY(0x10ec1220, "ALC1220", patch_alc882),
Linus Torvalds1da177e2005-04-16 15:20:36 -07008920 {} /* terminator */
8921};
Takashi Iwaib9a94a92015-10-01 16:20:04 +02008922MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_realtek);
Takashi Iwai1289e9e2008-11-27 15:47:11 +01008923
8924MODULE_LICENSE("GPL");
8925MODULE_DESCRIPTION("Realtek HD-audio codec");
8926
Takashi Iwaid8a766a2015-02-17 15:25:37 +01008927static struct hda_codec_driver realtek_driver = {
Takashi Iwaib9a94a92015-10-01 16:20:04 +02008928 .id = snd_hda_id_realtek,
Takashi Iwai1289e9e2008-11-27 15:47:11 +01008929};
8930
Takashi Iwaid8a766a2015-02-17 15:25:37 +01008931module_hda_codec_driver(realtek_driver);