blob: 489075b236527a91ce334caa6da94344e9190b22 [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>
Linus Torvalds1da177e2005-04-16 15:20:36 -070035#include "hda_codec.h"
36#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 */
Takashi Iwaia9111322011-05-02 11:30:18 +020086 const struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
Linus Torvalds1da177e2005-04-16 15:20:36 -070087 unsigned int num_mixers;
Takashi Iwai45bdd1c2009-02-06 16:11:25 +010088 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
Linus Torvalds1da177e2005-04-16 15:20:36 -070089
Kailang Yangda00c242010-03-19 11:23:45 +010090 struct alc_customize_define cdefine;
Takashi Iwai08c189f2012-12-19 15:22:24 +010091 unsigned int parse_flags; /* flag for snd_hda_parse_pin_defcfg() */
92
Takashi Iwai5579cd62018-06-19 22:22:41 +020093 /* GPIO bits */
94 unsigned int gpio_mask;
95 unsigned int gpio_dir;
96 unsigned int gpio_data;
97
Takashi Iwai08fb0d02013-01-10 17:33:58 +010098 /* mute LED for HP laptops, see alc269_fixup_mic_mute_hook() */
99 int mute_led_polarity;
100 hda_nid_t mute_led_nid;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +0800101 hda_nid_t cap_mute_led_nid;
Takashi Iwai08fb0d02013-01-10 17:33:58 +0100102
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +0100103 unsigned int gpio_led; /* used for alc269_fixup_hp_gpio_led() */
Takashi Iwai0f32fd192014-11-19 12:16:14 +0100104 unsigned int gpio_mute_led_mask;
105 unsigned int gpio_mic_led_mask;
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +0100106
David Henningsson73bdd592013-04-15 15:44:14 +0200107 hda_nid_t headset_mic_pin;
108 hda_nid_t headphone_mic_pin;
109 int current_headset_mode;
110 int current_headset_type;
111
Takashi Iwaiae6b8132006-03-03 16:47:17 +0100112 /* hooks */
113 void (*init_hook)(struct hda_codec *codec);
Takashi Iwai83012a72012-08-24 18:38:08 +0200114#ifdef CONFIG_PM
Daniel T Chenc97259d2009-12-27 18:52:08 -0500115 void (*power_hook)(struct hda_codec *codec);
Hector Martinf5de24b2009-12-20 22:51:31 +0100116#endif
Takashi Iwai1c7161532011-04-07 10:37:16 +0200117 void (*shutup)(struct hda_codec *codec);
Takashi Iwai70a09762015-12-15 14:59:58 +0100118 void (*reboot_notify)(struct hda_codec *codec);
Takashi Iwaid922b512011-04-28 12:18:53 +0200119
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200120 int init_amp;
Takashi Iwaid433a672010-09-20 15:11:54 +0200121 int codec_variant; /* flag for other variants */
Kailang Yang97a26572013-11-29 00:35:26 -0500122 unsigned int has_alc5505_dsp:1;
123 unsigned int no_depop_delay:1;
Takashi Iwaie64f14f2009-01-20 18:32:55 +0100124
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200125 /* for PLL fix */
126 hda_nid_t pll_nid;
127 unsigned int pll_coef_idx, pll_coef_bit;
Takashi Iwai1bb7e432011-10-17 16:50:59 +0200128 unsigned int coef0;
David Henningsson33f4acd2015-01-07 15:50:13 +0100129 struct input_dev *kb_dev;
Hui Wangc7b60a82015-12-28 11:35:25 +0800130 u8 alc_mute_keycode_map[1];
Kailang Yangdf694da2005-12-05 19:42:22 +0100131};
132
Takashi Iwai23f0c042009-02-26 13:03:58 +0100133/*
Takashi Iwaif2a227c2014-08-18 13:35:22 +0200134 * COEF access helper functions
135 */
136
137static int alc_read_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
138 unsigned int coef_idx)
139{
140 unsigned int val;
141
142 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, coef_idx);
143 val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PROC_COEF, 0);
144 return val;
145}
146
147#define alc_read_coef_idx(codec, coef_idx) \
148 alc_read_coefex_idx(codec, 0x20, coef_idx)
149
150static void alc_write_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
151 unsigned int coef_idx, unsigned int coef_val)
152{
153 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, coef_idx);
154 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PROC_COEF, coef_val);
155}
156
157#define alc_write_coef_idx(codec, coef_idx, coef_val) \
158 alc_write_coefex_idx(codec, 0x20, coef_idx, coef_val)
159
Takashi Iwai98b24882014-08-18 13:47:50 +0200160static void alc_update_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
161 unsigned int coef_idx, unsigned int mask,
162 unsigned int bits_set)
163{
164 unsigned int val = alc_read_coefex_idx(codec, nid, coef_idx);
165
166 if (val != -1)
167 alc_write_coefex_idx(codec, nid, coef_idx,
168 (val & ~mask) | bits_set);
169}
170
171#define alc_update_coef_idx(codec, coef_idx, mask, bits_set) \
172 alc_update_coefex_idx(codec, 0x20, coef_idx, mask, bits_set)
173
Takashi Iwaif2a227c2014-08-18 13:35:22 +0200174/* a special bypass for COEF 0; read the cached value at the second time */
175static unsigned int alc_get_coef0(struct hda_codec *codec)
176{
177 struct alc_spec *spec = codec->spec;
178
179 if (!spec->coef0)
180 spec->coef0 = alc_read_coef_idx(codec, 0);
181 return spec->coef0;
182}
183
Takashi Iwai54db6c32014-08-18 15:11:19 +0200184/* coef writes/updates batch */
185struct coef_fw {
186 unsigned char nid;
187 unsigned char idx;
188 unsigned short mask;
189 unsigned short val;
190};
191
192#define UPDATE_COEFEX(_nid, _idx, _mask, _val) \
193 { .nid = (_nid), .idx = (_idx), .mask = (_mask), .val = (_val) }
194#define WRITE_COEFEX(_nid, _idx, _val) UPDATE_COEFEX(_nid, _idx, -1, _val)
195#define WRITE_COEF(_idx, _val) WRITE_COEFEX(0x20, _idx, _val)
196#define UPDATE_COEF(_idx, _mask, _val) UPDATE_COEFEX(0x20, _idx, _mask, _val)
197
198static void alc_process_coef_fw(struct hda_codec *codec,
199 const struct coef_fw *fw)
200{
201 for (; fw->nid; fw++) {
202 if (fw->mask == (unsigned short)-1)
203 alc_write_coefex_idx(codec, fw->nid, fw->idx, fw->val);
204 else
205 alc_update_coefex_idx(codec, fw->nid, fw->idx,
206 fw->mask, fw->val);
207 }
208}
209
Takashi Iwaif2a227c2014-08-18 13:35:22 +0200210/*
Takashi Iwai1d045db2011-07-07 18:23:21 +0200211 * Append the given mixer and verb elements for the later use
212 * The mixer array is referred in build_controls(), and init_verbs are
213 * called in init().
Takashi Iwaid88897e2008-10-31 15:01:37 +0100214 */
Takashi Iwaia9111322011-05-02 11:30:18 +0200215static void add_mixer(struct alc_spec *spec, const struct snd_kcontrol_new *mix)
Takashi Iwaid88897e2008-10-31 15:01:37 +0100216{
217 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
218 return;
219 spec->mixers[spec->num_mixers++] = mix;
220}
221
Takashi Iwaid88897e2008-10-31 15:01:37 +0100222/*
Takashi Iwai1d045db2011-07-07 18:23:21 +0200223 * GPIO setup tables, used in initialization
Kailang Yangdf694da2005-12-05 19:42:22 +0100224 */
Takashi Iwai5579cd62018-06-19 22:22:41 +0200225
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200226/* Enable GPIO mask and set output */
Takashi Iwai5579cd62018-06-19 22:22:41 +0200227static void alc_setup_gpio(struct hda_codec *codec, unsigned int mask)
228{
229 struct alc_spec *spec = codec->spec;
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200230
Takashi Iwai5579cd62018-06-19 22:22:41 +0200231 spec->gpio_mask |= mask;
232 spec->gpio_dir |= mask;
233 spec->gpio_data |= mask;
234}
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200235
Takashi Iwai5579cd62018-06-19 22:22:41 +0200236static void alc_write_gpio_data(struct hda_codec *codec)
237{
238 struct alc_spec *spec = codec->spec;
239
240 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
241 spec->gpio_data);
242}
243
244static void alc_write_gpio(struct hda_codec *codec)
245{
246 struct alc_spec *spec = codec->spec;
247
248 if (!spec->gpio_mask)
249 return;
250
251 snd_hda_codec_write(codec, codec->core.afg, 0,
252 AC_VERB_SET_GPIO_MASK, spec->gpio_mask);
253 snd_hda_codec_write(codec, codec->core.afg, 0,
254 AC_VERB_SET_GPIO_DIRECTION, spec->gpio_dir);
255 alc_write_gpio_data(codec);
256}
257
258static void alc_fixup_gpio(struct hda_codec *codec, int action,
259 unsigned int mask)
260{
261 if (action == HDA_FIXUP_ACT_PRE_PROBE)
262 alc_setup_gpio(codec, mask);
263}
264
265static void alc_fixup_gpio1(struct hda_codec *codec,
266 const struct hda_fixup *fix, int action)
267{
268 alc_fixup_gpio(codec, action, 0x01);
269}
270
271static void alc_fixup_gpio2(struct hda_codec *codec,
272 const struct hda_fixup *fix, int action)
273{
274 alc_fixup_gpio(codec, action, 0x02);
275}
276
277static void alc_fixup_gpio3(struct hda_codec *codec,
278 const struct hda_fixup *fix, int action)
279{
280 alc_fixup_gpio(codec, action, 0x03);
281}
Kailang Yangbdd148a2007-05-08 15:19:08 +0200282
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200283/*
284 * Fix hardware PLL issue
285 * On some codecs, the analog PLL gating control must be off while
286 * the default value is 1.
287 */
288static void alc_fix_pll(struct hda_codec *codec)
289{
290 struct alc_spec *spec = codec->spec;
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200291
Takashi Iwai98b24882014-08-18 13:47:50 +0200292 if (spec->pll_nid)
293 alc_update_coefex_idx(codec, spec->pll_nid, spec->pll_coef_idx,
294 1 << spec->pll_coef_bit, 0);
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200295}
296
297static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
298 unsigned int coef_idx, unsigned int coef_bit)
299{
300 struct alc_spec *spec = codec->spec;
301 spec->pll_nid = nid;
302 spec->pll_coef_idx = coef_idx;
303 spec->pll_coef_bit = coef_bit;
304 alc_fix_pll(codec);
305}
306
Takashi Iwaicf5a2272012-02-20 16:31:07 +0100307/* update the master volume per volume-knob's unsol event */
Takashi Iwai1a4f69d2014-09-11 15:22:46 +0200308static void alc_update_knob_master(struct hda_codec *codec,
309 struct hda_jack_callback *jack)
Takashi Iwaicf5a2272012-02-20 16:31:07 +0100310{
311 unsigned int val;
312 struct snd_kcontrol *kctl;
313 struct snd_ctl_elem_value *uctl;
314
315 kctl = snd_hda_find_mixer_ctl(codec, "Master Playback Volume");
316 if (!kctl)
317 return;
318 uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
319 if (!uctl)
320 return;
Takashi Iwai2ebab402016-02-09 10:23:52 +0100321 val = snd_hda_codec_read(codec, jack->nid, 0,
Takashi Iwaicf5a2272012-02-20 16:31:07 +0100322 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
323 val &= HDA_AMP_VOLMASK;
324 uctl->value.integer.value[0] = val;
325 uctl->value.integer.value[1] = val;
326 kctl->put(kctl, uctl);
327 kfree(uctl);
328}
329
David Henningsson29adc4b2012-09-25 11:31:00 +0200330static void alc880_unsol_event(struct hda_codec *codec, unsigned int res)
Takashi Iwaif21d78e2012-01-19 12:10:29 +0100331{
David Henningsson29adc4b2012-09-25 11:31:00 +0200332 /* For some reason, the res given from ALC880 is broken.
333 Here we adjust it properly. */
334 snd_hda_jack_unsol_event(codec, res >> 2);
Takashi Iwaif21d78e2012-01-19 12:10:29 +0100335}
336
Kailang Yang394c97f2014-11-12 17:38:08 +0800337/* Change EAPD to verb control */
338static void alc_fill_eapd_coef(struct hda_codec *codec)
339{
340 int coef;
341
342 coef = alc_get_coef0(codec);
343
Takashi Iwai7639a062015-03-03 10:07:24 +0100344 switch (codec->core.vendor_id) {
Kailang Yang394c97f2014-11-12 17:38:08 +0800345 case 0x10ec0262:
346 alc_update_coef_idx(codec, 0x7, 0, 1<<5);
347 break;
348 case 0x10ec0267:
349 case 0x10ec0268:
350 alc_update_coef_idx(codec, 0x7, 0, 1<<13);
351 break;
352 case 0x10ec0269:
353 if ((coef & 0x00f0) == 0x0010)
354 alc_update_coef_idx(codec, 0xd, 0, 1<<14);
355 if ((coef & 0x00f0) == 0x0020)
356 alc_update_coef_idx(codec, 0x4, 1<<15, 0);
357 if ((coef & 0x00f0) == 0x0030)
358 alc_update_coef_idx(codec, 0x10, 1<<9, 0);
359 break;
360 case 0x10ec0280:
361 case 0x10ec0284:
362 case 0x10ec0290:
363 case 0x10ec0292:
364 alc_update_coef_idx(codec, 0x4, 1<<15, 0);
365 break;
Kailang Yang42314302016-02-03 15:03:50 +0800366 case 0x10ec0225:
Takashi Iwai44be77c2017-12-27 08:53:59 +0100367 case 0x10ec0295:
368 case 0x10ec0299:
369 alc_update_coef_idx(codec, 0x67, 0xf000, 0x3000);
370 /* fallthrough */
371 case 0x10ec0215:
Kailang Yang394c97f2014-11-12 17:38:08 +0800372 case 0x10ec0233:
Kailang Yangea04a1d2018-04-25 15:31:52 +0800373 case 0x10ec0235:
Kailang Yang736f20a2017-10-20 15:06:34 +0800374 case 0x10ec0236:
Kailang Yang394c97f2014-11-12 17:38:08 +0800375 case 0x10ec0255:
Kailang Yang4344aec2014-12-17 17:39:05 +0800376 case 0x10ec0256:
Kailang Yangf429e7e2017-12-05 15:38:24 +0800377 case 0x10ec0257:
Kailang Yang394c97f2014-11-12 17:38:08 +0800378 case 0x10ec0282:
379 case 0x10ec0283:
380 case 0x10ec0286:
381 case 0x10ec0288:
Kailang Yang0a6f0602017-06-30 16:00:48 +0800382 case 0x10ec0285:
Kailang Yang506b62c2014-12-18 17:07:44 +0800383 case 0x10ec0298:
Kailang Yang0a6f0602017-06-30 16:00:48 +0800384 case 0x10ec0289:
Kailang Yang394c97f2014-11-12 17:38:08 +0800385 alc_update_coef_idx(codec, 0x10, 1<<9, 0);
386 break;
Kailang Yang3aabf942017-11-08 15:28:33 +0800387 case 0x10ec0275:
388 alc_update_coef_idx(codec, 0xe, 0, 1<<0);
389 break;
Kailang Yang394c97f2014-11-12 17:38:08 +0800390 case 0x10ec0293:
391 alc_update_coef_idx(codec, 0xa, 1<<13, 0);
392 break;
Kailang Yangdcd4f0d2016-05-04 15:50:18 +0800393 case 0x10ec0234:
394 case 0x10ec0274:
395 case 0x10ec0294:
Kailang Yang6fbae352016-05-30 16:44:20 +0800396 case 0x10ec0700:
397 case 0x10ec0701:
398 case 0x10ec0703:
Kailang Yangdcd4f0d2016-05-04 15:50:18 +0800399 alc_update_coef_idx(codec, 0x10, 1<<15, 0);
400 break;
Kailang Yang394c97f2014-11-12 17:38:08 +0800401 case 0x10ec0662:
402 if ((coef & 0x00f0) == 0x0030)
403 alc_update_coef_idx(codec, 0x4, 1<<10, 0); /* EAPD Ctrl */
404 break;
405 case 0x10ec0272:
406 case 0x10ec0273:
407 case 0x10ec0663:
408 case 0x10ec0665:
409 case 0x10ec0670:
410 case 0x10ec0671:
411 case 0x10ec0672:
412 alc_update_coef_idx(codec, 0xd, 0, 1<<14); /* EAPD Ctrl */
413 break;
414 case 0x10ec0668:
415 alc_update_coef_idx(codec, 0x7, 3<<13, 0);
416 break;
417 case 0x10ec0867:
418 alc_update_coef_idx(codec, 0x4, 1<<10, 0);
419 break;
420 case 0x10ec0888:
421 if ((coef & 0x00f0) == 0x0020 || (coef & 0x00f0) == 0x0030)
422 alc_update_coef_idx(codec, 0x7, 1<<5, 0);
423 break;
424 case 0x10ec0892:
425 alc_update_coef_idx(codec, 0x7, 1<<5, 0);
426 break;
427 case 0x10ec0899:
428 case 0x10ec0900:
Kailang Yang65553b12017-07-11 15:15:47 +0800429 case 0x10ec1168:
Kailang Yanga535ad52017-01-16 16:59:26 +0800430 case 0x10ec1220:
Kailang Yang394c97f2014-11-12 17:38:08 +0800431 alc_update_coef_idx(codec, 0x7, 1<<1, 0);
432 break;
433 }
434}
435
Kailang Yangf9423e72008-05-27 12:32:25 +0200436/* additional initialization for ALC888 variants */
437static void alc888_coef_init(struct hda_codec *codec)
438{
Kailang Yang1df88742014-10-29 16:10:13 +0800439 switch (alc_get_coef0(codec) & 0x00f0) {
440 /* alc888-VA */
441 case 0x00:
442 /* alc888-VB */
443 case 0x10:
444 alc_update_coef_idx(codec, 7, 0, 0x2030); /* Turn EAPD to High */
445 break;
446 }
Jaroslav Kysela87a8c372009-07-23 10:58:29 +0200447}
448
Takashi Iwai3fb4a502010-01-19 15:46:37 +0100449/* turn on/off EAPD control (only if available) */
450static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
451{
452 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
453 return;
454 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
455 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
456 on ? 2 : 0);
457}
458
Takashi Iwai691f1fc2011-04-07 10:31:43 +0200459/* turn on/off EAPD controls of the codec */
460static void alc_auto_setup_eapd(struct hda_codec *codec, bool on)
461{
462 /* We currently only handle front, HP */
Takashi Iwai39fa84e2011-06-27 15:28:57 +0200463 static hda_nid_t pins[] = {
Hui Wangaf95b412015-03-26 17:14:55 +0800464 0x0f, 0x10, 0x14, 0x15, 0x17, 0
Takashi Iwai39fa84e2011-06-27 15:28:57 +0200465 };
466 hda_nid_t *p;
467 for (p = pins; *p; p++)
468 set_eapd(codec, *p, on);
Takashi Iwai691f1fc2011-04-07 10:31:43 +0200469}
470
Takashi Iwai1c7161532011-04-07 10:37:16 +0200471/* generic shutup callback;
Lars-Peter Clausen4ce8e6a2016-11-08 15:48:06 +0100472 * just turning off EAPD and a little pause for avoiding pop-noise
Takashi Iwai1c7161532011-04-07 10:37:16 +0200473 */
474static void alc_eapd_shutup(struct hda_codec *codec)
475{
Kailang Yang97a26572013-11-29 00:35:26 -0500476 struct alc_spec *spec = codec->spec;
477
Takashi Iwai1c7161532011-04-07 10:37:16 +0200478 alc_auto_setup_eapd(codec, false);
Kailang Yang97a26572013-11-29 00:35:26 -0500479 if (!spec->no_depop_delay)
480 msleep(200);
Takashi Iwai9bfb2842013-07-24 14:31:50 +0200481 snd_hda_shutup_pins(codec);
Takashi Iwai1c7161532011-04-07 10:37:16 +0200482}
483
Takashi Iwai1d045db2011-07-07 18:23:21 +0200484/* generic EAPD initialization */
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200485static void alc_auto_init_amp(struct hda_codec *codec, int type)
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200486{
Kailang Yang394c97f2014-11-12 17:38:08 +0800487 alc_fill_eapd_coef(codec);
Takashi Iwai39fa84e2011-06-27 15:28:57 +0200488 alc_auto_setup_eapd(codec, true);
Takashi Iwai5579cd62018-06-19 22:22:41 +0200489 alc_write_gpio(codec);
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200490 switch (type) {
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200491 case ALC_INIT_DEFAULT:
Takashi Iwai7639a062015-03-03 10:07:24 +0100492 switch (codec->core.vendor_id) {
Kailang Yangc9b58002007-10-16 14:30:01 +0200493 case 0x10ec0260:
Takashi Iwai98b24882014-08-18 13:47:50 +0200494 alc_update_coefex_idx(codec, 0x1a, 7, 0, 0x2010);
Kailang Yangc9b58002007-10-16 14:30:01 +0200495 break;
Kailang Yangc9b58002007-10-16 14:30:01 +0200496 case 0x10ec0880:
497 case 0x10ec0882:
498 case 0x10ec0883:
499 case 0x10ec0885:
Kailang Yang1df88742014-10-29 16:10:13 +0800500 alc_update_coef_idx(codec, 7, 0, 0x2030);
Kailang Yangc9b58002007-10-16 14:30:01 +0200501 break;
Kailang Yangf9423e72008-05-27 12:32:25 +0200502 case 0x10ec0888:
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200503 alc888_coef_init(codec);
Kailang Yangf9423e72008-05-27 12:32:25 +0200504 break;
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200505 }
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200506 break;
507 }
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200508}
Kailang Yangea1fb292008-08-26 12:58:38 +0200509
Takashi Iwai1d045db2011-07-07 18:23:21 +0200510
511/*
512 * Realtek SSID verification
513 */
514
David Henningsson90622912010-10-14 14:50:18 +0200515/* Could be any non-zero and even value. When used as fixup, tells
516 * the driver to ignore any present sku defines.
517 */
518#define ALC_FIXUP_SKU_IGNORE (2)
519
Takashi Iwai23d30f22012-05-07 17:17:32 +0200520static void alc_fixup_sku_ignore(struct hda_codec *codec,
521 const struct hda_fixup *fix, int action)
522{
523 struct alc_spec *spec = codec->spec;
524 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
525 spec->cdefine.fixup = 1;
526 spec->cdefine.sku_cfg = ALC_FIXUP_SKU_IGNORE;
527 }
528}
529
Mengdong Linb5c66112013-11-29 00:35:35 -0500530static void alc_fixup_no_depop_delay(struct hda_codec *codec,
531 const struct hda_fixup *fix, int action)
532{
533 struct alc_spec *spec = codec->spec;
534
Mengdong Lin84d2dc32013-12-02 22:26:03 -0500535 if (action == HDA_FIXUP_ACT_PROBE) {
Mengdong Linb5c66112013-11-29 00:35:35 -0500536 spec->no_depop_delay = 1;
Mengdong Lin84d2dc32013-12-02 22:26:03 -0500537 codec->depop_delay = 0;
538 }
Mengdong Linb5c66112013-11-29 00:35:35 -0500539}
540
Kailang Yangda00c242010-03-19 11:23:45 +0100541static int alc_auto_parse_customize_define(struct hda_codec *codec)
542{
543 unsigned int ass, tmp, i;
Takashi Iwai7fb56222010-03-22 17:09:47 +0100544 unsigned nid = 0;
Kailang Yangda00c242010-03-19 11:23:45 +0100545 struct alc_spec *spec = codec->spec;
546
Takashi Iwaib6cbe512010-07-28 17:43:36 +0200547 spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
548
David Henningsson90622912010-10-14 14:50:18 +0200549 if (spec->cdefine.fixup) {
550 ass = spec->cdefine.sku_cfg;
551 if (ass == ALC_FIXUP_SKU_IGNORE)
552 return -1;
553 goto do_sku;
554 }
555
Takashi Iwai5100cd02014-02-15 10:03:19 +0100556 if (!codec->bus->pci)
557 return -1;
Takashi Iwai7639a062015-03-03 10:07:24 +0100558 ass = codec->core.subsystem_id & 0xffff;
Takashi Iwaib6cbe512010-07-28 17:43:36 +0200559 if (ass != codec->bus->pci->subsystem_device && (ass & 1))
Kailang Yangda00c242010-03-19 11:23:45 +0100560 goto do_sku;
561
562 nid = 0x1d;
Takashi Iwai7639a062015-03-03 10:07:24 +0100563 if (codec->core.vendor_id == 0x10ec0260)
Kailang Yangda00c242010-03-19 11:23:45 +0100564 nid = 0x17;
565 ass = snd_hda_codec_get_pincfg(codec, nid);
566
567 if (!(ass & 1)) {
Takashi Iwai4e76a882014-02-25 12:21:03 +0100568 codec_info(codec, "%s: SKU not ready 0x%08x\n",
Takashi Iwai7639a062015-03-03 10:07:24 +0100569 codec->core.chip_name, ass);
Kailang Yangda00c242010-03-19 11:23:45 +0100570 return -1;
571 }
572
573 /* check sum */
574 tmp = 0;
575 for (i = 1; i < 16; i++) {
576 if ((ass >> i) & 1)
577 tmp++;
578 }
579 if (((ass >> 16) & 0xf) != tmp)
580 return -1;
581
582 spec->cdefine.port_connectivity = ass >> 30;
583 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
584 spec->cdefine.check_sum = (ass >> 16) & 0xf;
585 spec->cdefine.customization = ass >> 8;
586do_sku:
587 spec->cdefine.sku_cfg = ass;
588 spec->cdefine.external_amp = (ass & 0x38) >> 3;
589 spec->cdefine.platform_type = (ass & 0x4) >> 2;
590 spec->cdefine.swap = (ass & 0x2) >> 1;
591 spec->cdefine.override = ass & 0x1;
592
Takashi Iwai4e76a882014-02-25 12:21:03 +0100593 codec_dbg(codec, "SKU: Nid=0x%x sku_cfg=0x%08x\n",
Kailang Yangda00c242010-03-19 11:23:45 +0100594 nid, spec->cdefine.sku_cfg);
Takashi Iwai4e76a882014-02-25 12:21:03 +0100595 codec_dbg(codec, "SKU: port_connectivity=0x%x\n",
Kailang Yangda00c242010-03-19 11:23:45 +0100596 spec->cdefine.port_connectivity);
Takashi Iwai4e76a882014-02-25 12:21:03 +0100597 codec_dbg(codec, "SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
598 codec_dbg(codec, "SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
599 codec_dbg(codec, "SKU: customization=0x%08x\n", spec->cdefine.customization);
600 codec_dbg(codec, "SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
601 codec_dbg(codec, "SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
602 codec_dbg(codec, "SKU: swap=0x%x\n", spec->cdefine.swap);
603 codec_dbg(codec, "SKU: override=0x%x\n", spec->cdefine.override);
Kailang Yangda00c242010-03-19 11:23:45 +0100604
605 return 0;
606}
607
Takashi Iwai08c189f2012-12-19 15:22:24 +0100608/* return the position of NID in the list, or -1 if not found */
609static int find_idx_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
610{
611 int i;
612 for (i = 0; i < nums; i++)
613 if (list[i] == nid)
614 return i;
615 return -1;
616}
Takashi Iwai1d045db2011-07-07 18:23:21 +0200617/* return true if the given NID is found in the list */
Takashi Iwai3af9ee62011-06-27 12:34:01 +0200618static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
619{
Takashi Iwai21268962011-07-07 15:01:13 +0200620 return find_idx_in_nid_list(nid, list, nums) >= 0;
Takashi Iwai3af9ee62011-06-27 12:34:01 +0200621}
622
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200623/* check subsystem ID and set up device-specific initialization;
624 * return 1 if initialized, 0 if invalid SSID
625 */
626/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
627 * 31 ~ 16 : Manufacture ID
628 * 15 ~ 8 : SKU ID
629 * 7 ~ 0 : Assembly ID
630 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
631 */
Takashi Iwai58c57cf2014-01-07 18:22:49 +0100632static int alc_subsystem_id(struct hda_codec *codec, const hda_nid_t *ports)
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200633{
634 unsigned int ass, tmp, i;
635 unsigned nid;
636 struct alc_spec *spec = codec->spec;
637
David Henningsson90622912010-10-14 14:50:18 +0200638 if (spec->cdefine.fixup) {
639 ass = spec->cdefine.sku_cfg;
640 if (ass == ALC_FIXUP_SKU_IGNORE)
641 return 0;
642 goto do_sku;
643 }
644
Takashi Iwai7639a062015-03-03 10:07:24 +0100645 ass = codec->core.subsystem_id & 0xffff;
Takashi Iwai5100cd02014-02-15 10:03:19 +0100646 if (codec->bus->pci &&
647 ass != codec->bus->pci->subsystem_device && (ass & 1))
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200648 goto do_sku;
649
650 /* invalid SSID, check the special NID pin defcfg instead */
651 /*
Sasha Alexandrdef319f2009-06-16 16:00:15 -0400652 * 31~30 : port connectivity
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200653 * 29~21 : reserve
654 * 20 : PCBEEP input
655 * 19~16 : Check sum (15:1)
656 * 15~1 : Custom
657 * 0 : override
658 */
659 nid = 0x1d;
Takashi Iwai7639a062015-03-03 10:07:24 +0100660 if (codec->core.vendor_id == 0x10ec0260)
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200661 nid = 0x17;
662 ass = snd_hda_codec_get_pincfg(codec, nid);
Takashi Iwai4e76a882014-02-25 12:21:03 +0100663 codec_dbg(codec,
664 "realtek: No valid SSID, checking pincfg 0x%08x for NID 0x%x\n",
Takashi Iwaicb6605c2009-04-28 13:03:19 +0200665 ass, nid);
Kailang Yang6227cdc2010-02-25 08:36:52 +0100666 if (!(ass & 1))
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200667 return 0;
668 if ((ass >> 30) != 1) /* no physical connection */
669 return 0;
670
671 /* check sum */
672 tmp = 0;
673 for (i = 1; i < 16; i++) {
674 if ((ass >> i) & 1)
675 tmp++;
676 }
677 if (((ass >> 16) & 0xf) != tmp)
678 return 0;
679do_sku:
Takashi Iwai4e76a882014-02-25 12:21:03 +0100680 codec_dbg(codec, "realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
Takashi Iwai7639a062015-03-03 10:07:24 +0100681 ass & 0xffff, codec->core.vendor_id);
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200682 /*
683 * 0 : override
684 * 1 : Swap Jack
685 * 2 : 0 --> Desktop, 1 --> Laptop
686 * 3~5 : External Amplifier control
687 * 7~6 : Reserved
688 */
689 tmp = (ass & 0x38) >> 3; /* external Amp control */
Takashi Iwai1c76aa52018-06-21 16:37:54 +0200690 if (spec->init_amp == ALC_INIT_UNDEFINED) {
691 switch (tmp) {
692 case 1:
Takashi Iwai5579cd62018-06-19 22:22:41 +0200693 alc_setup_gpio(codec, 0x01);
Takashi Iwai1c76aa52018-06-21 16:37:54 +0200694 break;
695 case 3:
Takashi Iwai5579cd62018-06-19 22:22:41 +0200696 alc_setup_gpio(codec, 0x02);
Takashi Iwai1c76aa52018-06-21 16:37:54 +0200697 break;
698 case 7:
Takashi Iwai5579cd62018-06-19 22:22:41 +0200699 alc_setup_gpio(codec, 0x03);
Takashi Iwai1c76aa52018-06-21 16:37:54 +0200700 break;
701 case 5:
702 default:
703 spec->init_amp = ALC_INIT_DEFAULT;
704 break;
705 }
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200706 }
707
708 /* is laptop or Desktop and enable the function "Mute internal speaker
709 * when the external headphone out jack is plugged"
710 */
711 if (!(ass & 0x8000))
712 return 1;
713 /*
714 * 10~8 : Jack location
715 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
716 * 14~13: Resvered
717 * 15 : 1 --> enable the function "Mute internal speaker
718 * when the external headphone out jack is plugged"
719 */
Takashi Iwai08c189f2012-12-19 15:22:24 +0100720 if (!spec->gen.autocfg.hp_pins[0] &&
721 !(spec->gen.autocfg.line_out_pins[0] &&
722 spec->gen.autocfg.line_out_type == AUTO_PIN_HP_OUT)) {
Takashi Iwai01d48252009-10-06 13:21:54 +0200723 hda_nid_t nid;
Kailang Yangc9b58002007-10-16 14:30:01 +0200724 tmp = (ass >> 11) & 0x3; /* HP to chassis */
Takashi Iwai58c57cf2014-01-07 18:22:49 +0100725 nid = ports[tmp];
Takashi Iwai08c189f2012-12-19 15:22:24 +0100726 if (found_in_nid_list(nid, spec->gen.autocfg.line_out_pins,
727 spec->gen.autocfg.line_outs))
Takashi Iwai3af9ee62011-06-27 12:34:01 +0200728 return 1;
Takashi Iwai08c189f2012-12-19 15:22:24 +0100729 spec->gen.autocfg.hp_pins[0] = nid;
Kailang Yangc9b58002007-10-16 14:30:01 +0200730 }
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200731 return 1;
732}
Kailang Yangea1fb292008-08-26 12:58:38 +0200733
Takashi Iwai3e6179b2011-07-08 16:55:13 +0200734/* Check the validity of ALC subsystem-id
735 * ports contains an array of 4 pin NIDs for port-A, E, D and I */
736static void alc_ssid_check(struct hda_codec *codec, const hda_nid_t *ports)
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200737{
Takashi Iwai58c57cf2014-01-07 18:22:49 +0100738 if (!alc_subsystem_id(codec, ports)) {
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200739 struct alc_spec *spec = codec->spec;
Takashi Iwai4e76a882014-02-25 12:21:03 +0100740 codec_dbg(codec,
741 "realtek: Enable default setup for auto mode as fallback\n");
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200742 spec->init_amp = ALC_INIT_DEFAULT;
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200743 }
Takashi Iwai21268962011-07-07 15:01:13 +0200744}
Takashi Iwai1a1455d2011-04-28 17:36:18 +0200745
Takashi Iwai41e41f12005-06-08 14:48:49 +0200746/*
Takashi Iwai1d045db2011-07-07 18:23:21 +0200747 */
748
David Henningsson9d36a7d2014-10-07 10:18:42 +0200749static void alc_fixup_inv_dmic(struct hda_codec *codec,
750 const struct hda_fixup *fix, int action)
Takashi Iwai125821a2012-06-22 14:30:29 +0200751{
752 struct alc_spec *spec = codec->spec;
Takashi Iwai668d1e92012-11-29 14:10:17 +0100753
David Henningsson9d36a7d2014-10-07 10:18:42 +0200754 spec->gen.inv_dmic_split = 1;
Takashi Iwai6e72aa52012-06-25 10:52:25 +0200755}
756
Takashi Iwai603c4012008-07-30 15:01:44 +0200757
Takashi Iwai67d634c2009-11-16 15:35:59 +0100758#ifdef CONFIG_SND_HDA_INPUT_BEEP
Takashi Iwai45bdd1c2009-02-06 16:11:25 +0100759/* additional beep mixers; the actual parameters are overwritten at build */
Takashi Iwaia9111322011-05-02 11:30:18 +0200760static const struct snd_kcontrol_new alc_beep_mixer[] = {
Takashi Iwai45bdd1c2009-02-06 16:11:25 +0100761 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
Jaroslav Kysela123c07a2009-10-21 14:48:23 +0200762 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
Takashi Iwai45bdd1c2009-02-06 16:11:25 +0100763 { } /* end */
764};
Takashi Iwai67d634c2009-11-16 15:35:59 +0100765#endif
Takashi Iwai45bdd1c2009-02-06 16:11:25 +0100766
Takashi Iwai2eab6942012-12-18 15:30:41 +0100767static int alc_build_controls(struct hda_codec *codec)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700768{
769 struct alc_spec *spec = codec->spec;
Takashi Iwai666a70d2012-12-17 20:29:29 +0100770 int i, err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700771
Takashi Iwai08c189f2012-12-19 15:22:24 +0100772 err = snd_hda_gen_build_controls(codec);
773 if (err < 0)
774 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700775
776 for (i = 0; i < spec->num_mixers; i++) {
777 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
778 if (err < 0)
779 return err;
780 }
Takashi Iwai2134ea42008-01-10 16:53:55 +0100781
Takashi Iwai67d634c2009-11-16 15:35:59 +0100782#ifdef CONFIG_SND_HDA_INPUT_BEEP
Takashi Iwai45bdd1c2009-02-06 16:11:25 +0100783 /* create beep controls if needed */
784 if (spec->beep_amp) {
Takashi Iwaia9111322011-05-02 11:30:18 +0200785 const struct snd_kcontrol_new *knew;
Takashi Iwai45bdd1c2009-02-06 16:11:25 +0100786 for (knew = alc_beep_mixer; knew->name; knew++) {
787 struct snd_kcontrol *kctl;
788 kctl = snd_ctl_new1(knew, codec);
789 if (!kctl)
790 return -ENOMEM;
791 kctl->private_value = spec->beep_amp;
Jaroslav Kysela5e26dfd2009-12-10 13:57:01 +0100792 err = snd_hda_ctl_add(codec, 0, kctl);
Takashi Iwai45bdd1c2009-02-06 16:11:25 +0100793 if (err < 0)
794 return err;
795 }
796 }
Takashi Iwai67d634c2009-11-16 15:35:59 +0100797#endif
Takashi Iwai45bdd1c2009-02-06 16:11:25 +0100798
Takashi Iwai1727a772013-01-10 09:52:52 +0100799 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_BUILD);
Takashi Iwai420b0fe2012-03-12 12:35:27 +0100800 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700801}
802
Takashi Iwaie9edcee2005-06-13 14:16:38 +0200803
Linus Torvalds1da177e2005-04-16 15:20:36 -0700804/*
Takashi Iwaiae6b8132006-03-03 16:47:17 +0100805 * Common callbacks
Takashi Iwaie9edcee2005-06-13 14:16:38 +0200806 */
Takashi Iwai16ded522005-06-10 19:58:24 +0200807
Linus Torvalds1da177e2005-04-16 15:20:36 -0700808static int alc_init(struct hda_codec *codec)
809{
810 struct alc_spec *spec = codec->spec;
Takashi Iwaie9edcee2005-06-13 14:16:38 +0200811
Takashi Iwai546bb672012-03-07 08:37:19 +0100812 if (spec->init_hook)
813 spec->init_hook(codec);
Kailang Yang526af6e2012-03-07 08:25:20 +0100814
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200815 alc_fix_pll(codec);
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200816 alc_auto_init_amp(codec, spec->init_amp);
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200817
Takashi Iwai08c189f2012-12-19 15:22:24 +0100818 snd_hda_gen_init(codec);
Takashi Iwaiae6b8132006-03-03 16:47:17 +0100819
Takashi Iwai1727a772013-01-10 09:52:52 +0100820 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_INIT);
Takashi Iwaie08a0072006-09-07 17:52:14 +0200821
Linus Torvalds1da177e2005-04-16 15:20:36 -0700822 return 0;
823}
824
Takashi Iwaia4e09aa2009-12-27 11:22:24 +0100825static inline void alc_shutup(struct hda_codec *codec)
826{
Takashi Iwai1c7161532011-04-07 10:37:16 +0200827 struct alc_spec *spec = codec->spec;
828
Takashi Iwaic7273bd2018-06-12 16:09:57 +0200829 if (!snd_hda_get_bool_hint(codec, "shutup"))
830 return; /* disabled explicitly by hints */
831
Takashi Iwai1c7161532011-04-07 10:37:16 +0200832 if (spec && spec->shutup)
833 spec->shutup(codec);
Takashi Iwai9bfb2842013-07-24 14:31:50 +0200834 else
835 snd_hda_shutup_pins(codec);
Takashi Iwaia4e09aa2009-12-27 11:22:24 +0100836}
837
Takashi Iwai70a09762015-12-15 14:59:58 +0100838static void alc_reboot_notify(struct hda_codec *codec)
839{
840 struct alc_spec *spec = codec->spec;
841
842 if (spec && spec->reboot_notify)
843 spec->reboot_notify(codec);
844 else
845 alc_shutup(codec);
846}
847
848/* power down codec to D3 at reboot/shutdown; set as reboot_notify ops */
849static void alc_d3_at_reboot(struct hda_codec *codec)
850{
851 snd_hda_codec_set_power_to_all(codec, codec->core.afg, AC_PWRST_D3);
852 snd_hda_codec_write(codec, codec->core.afg, 0,
853 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
854 msleep(10);
855}
856
Takashi Iwai8a02c0c2014-02-10 18:09:45 +0100857#define alc_free snd_hda_gen_free
Linus Torvalds1da177e2005-04-16 15:20:36 -0700858
Takashi Iwai83012a72012-08-24 18:38:08 +0200859#ifdef CONFIG_PM
Daniel T Chenc97259d2009-12-27 18:52:08 -0500860static void alc_power_eapd(struct hda_codec *codec)
861{
Takashi Iwai691f1fc2011-04-07 10:31:43 +0200862 alc_auto_setup_eapd(codec, false);
Daniel T Chenc97259d2009-12-27 18:52:08 -0500863}
864
Takashi Iwai68cb2b52012-07-02 15:20:37 +0200865static int alc_suspend(struct hda_codec *codec)
Hector Martinf5de24b2009-12-20 22:51:31 +0100866{
867 struct alc_spec *spec = codec->spec;
Takashi Iwaia4e09aa2009-12-27 11:22:24 +0100868 alc_shutup(codec);
Hector Martinf5de24b2009-12-20 22:51:31 +0100869 if (spec && spec->power_hook)
Daniel T Chenc97259d2009-12-27 18:52:08 -0500870 spec->power_hook(codec);
Hector Martinf5de24b2009-12-20 22:51:31 +0100871 return 0;
872}
873#endif
874
Takashi Iwai2a439522011-07-26 09:52:50 +0200875#ifdef CONFIG_PM
Takashi Iwaie044c392008-10-27 16:56:24 +0100876static int alc_resume(struct hda_codec *codec)
877{
Kailang Yang97a26572013-11-29 00:35:26 -0500878 struct alc_spec *spec = codec->spec;
879
880 if (!spec->no_depop_delay)
881 msleep(150); /* to avoid pop noise */
Takashi Iwaie044c392008-10-27 16:56:24 +0100882 codec->patch_ops.init(codec);
Takashi Iwaieeecd9d2015-02-25 15:18:50 +0100883 regcache_sync(codec->core.regmap);
Takashi Iwai9e5341b2010-09-21 09:57:06 +0200884 hda_call_check_power_status(codec, 0x01);
Takashi Iwaie044c392008-10-27 16:56:24 +0100885 return 0;
886}
Takashi Iwaie044c392008-10-27 16:56:24 +0100887#endif
888
Linus Torvalds1da177e2005-04-16 15:20:36 -0700889/*
890 */
Takashi Iwaia9111322011-05-02 11:30:18 +0200891static const struct hda_codec_ops alc_patch_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700892 .build_controls = alc_build_controls,
Takashi Iwai08c189f2012-12-19 15:22:24 +0100893 .build_pcms = snd_hda_gen_build_pcms,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700894 .init = alc_init,
895 .free = alc_free,
David Henningsson29adc4b2012-09-25 11:31:00 +0200896 .unsol_event = snd_hda_jack_unsol_event,
Takashi Iwai2a439522011-07-26 09:52:50 +0200897#ifdef CONFIG_PM
Takashi Iwaie044c392008-10-27 16:56:24 +0100898 .resume = alc_resume,
Hector Martinf5de24b2009-12-20 22:51:31 +0100899 .suspend = alc_suspend,
Takashi Iwaifce52a32013-01-07 12:42:48 +0100900 .check_power_status = snd_hda_gen_check_power_status,
Takashi Iwaicb53c622007-08-10 17:21:45 +0200901#endif
Takashi Iwai70a09762015-12-15 14:59:58 +0100902 .reboot_notify = alc_reboot_notify,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700903};
904
David Henningsson29adc4b2012-09-25 11:31:00 +0200905
Takashi Iwaided255b2015-10-01 17:59:43 +0200906#define alc_codec_rename(codec, name) snd_hda_codec_set_name(codec, name)
Kailang Yangc027ddc2010-03-19 11:33:06 +0100907
Takashi Iwai2fa522b2005-05-12 14:51:12 +0200908/*
Kailang Yang4b016932013-11-28 11:55:09 +0100909 * Rename codecs appropriately from COEF value or subvendor id
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200910 */
911struct alc_codec_rename_table {
912 unsigned int vendor_id;
913 unsigned short coef_mask;
914 unsigned short coef_bits;
915 const char *name;
916};
917
Kailang Yang4b016932013-11-28 11:55:09 +0100918struct alc_codec_rename_pci_table {
919 unsigned int codec_vendor_id;
920 unsigned short pci_subvendor;
921 unsigned short pci_subdevice;
922 const char *name;
923};
924
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200925static struct alc_codec_rename_table rename_tbl[] = {
Kailang Yange6e5f7a2014-06-06 16:46:43 +0800926 { 0x10ec0221, 0xf00f, 0x1003, "ALC231" },
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200927 { 0x10ec0269, 0xfff0, 0x3010, "ALC277" },
928 { 0x10ec0269, 0xf0f0, 0x2010, "ALC259" },
929 { 0x10ec0269, 0xf0f0, 0x3010, "ALC258" },
930 { 0x10ec0269, 0x00f0, 0x0010, "ALC269VB" },
931 { 0x10ec0269, 0xffff, 0xa023, "ALC259" },
932 { 0x10ec0269, 0xffff, 0x6023, "ALC281X" },
933 { 0x10ec0269, 0x00f0, 0x0020, "ALC269VC" },
Kailang Yangadcc70b2012-05-25 08:08:38 +0200934 { 0x10ec0269, 0x00f0, 0x0030, "ALC269VD" },
Kailang Yange6e5f7a2014-06-06 16:46:43 +0800935 { 0x10ec0662, 0xffff, 0x4020, "ALC656" },
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200936 { 0x10ec0887, 0x00f0, 0x0030, "ALC887-VD" },
937 { 0x10ec0888, 0x00f0, 0x0030, "ALC888-VD" },
938 { 0x10ec0888, 0xf0f0, 0x3020, "ALC886" },
939 { 0x10ec0899, 0x2000, 0x2000, "ALC899" },
940 { 0x10ec0892, 0xffff, 0x8020, "ALC661" },
941 { 0x10ec0892, 0xffff, 0x8011, "ALC661" },
942 { 0x10ec0892, 0xffff, 0x4011, "ALC656" },
943 { } /* terminator */
944};
945
Kailang Yang4b016932013-11-28 11:55:09 +0100946static struct alc_codec_rename_pci_table rename_pci_tbl[] = {
947 { 0x10ec0280, 0x1028, 0, "ALC3220" },
948 { 0x10ec0282, 0x1028, 0, "ALC3221" },
949 { 0x10ec0283, 0x1028, 0, "ALC3223" },
Kailang Yang193177d2014-04-23 16:06:13 +0800950 { 0x10ec0288, 0x1028, 0, "ALC3263" },
Kailang Yang4b016932013-11-28 11:55:09 +0100951 { 0x10ec0292, 0x1028, 0, "ALC3226" },
Kailang Yang193177d2014-04-23 16:06:13 +0800952 { 0x10ec0293, 0x1028, 0, "ALC3235" },
Kailang Yang4b016932013-11-28 11:55:09 +0100953 { 0x10ec0255, 0x1028, 0, "ALC3234" },
954 { 0x10ec0668, 0x1028, 0, "ALC3661" },
Kailang Yange6e5f7a2014-06-06 16:46:43 +0800955 { 0x10ec0275, 0x1028, 0, "ALC3260" },
956 { 0x10ec0899, 0x1028, 0, "ALC3861" },
Kailang Yang2c674fa2015-05-05 15:02:42 +0800957 { 0x10ec0298, 0x1028, 0, "ALC3266" },
Kailang Yang736f20a2017-10-20 15:06:34 +0800958 { 0x10ec0236, 0x1028, 0, "ALC3204" },
Kailang Yang82324502015-05-25 17:16:49 +0800959 { 0x10ec0256, 0x1028, 0, "ALC3246" },
Kailang Yang42314302016-02-03 15:03:50 +0800960 { 0x10ec0225, 0x1028, 0, "ALC3253" },
Kailang Yang7d727862016-05-24 16:46:07 +0800961 { 0x10ec0295, 0x1028, 0, "ALC3254" },
Kailang Yang28f1f9b2017-01-04 14:49:07 +0800962 { 0x10ec0299, 0x1028, 0, "ALC3271" },
Kailang Yange6e5f7a2014-06-06 16:46:43 +0800963 { 0x10ec0670, 0x1025, 0, "ALC669X" },
964 { 0x10ec0676, 0x1025, 0, "ALC679X" },
965 { 0x10ec0282, 0x1043, 0, "ALC3229" },
966 { 0x10ec0233, 0x1043, 0, "ALC3236" },
967 { 0x10ec0280, 0x103c, 0, "ALC3228" },
968 { 0x10ec0282, 0x103c, 0, "ALC3227" },
969 { 0x10ec0286, 0x103c, 0, "ALC3242" },
970 { 0x10ec0290, 0x103c, 0, "ALC3241" },
971 { 0x10ec0668, 0x103c, 0, "ALC3662" },
972 { 0x10ec0283, 0x17aa, 0, "ALC3239" },
973 { 0x10ec0292, 0x17aa, 0, "ALC3232" },
Kailang Yang4b016932013-11-28 11:55:09 +0100974 { } /* terminator */
975};
976
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200977static int alc_codec_rename_from_preset(struct hda_codec *codec)
978{
979 const struct alc_codec_rename_table *p;
Kailang Yang4b016932013-11-28 11:55:09 +0100980 const struct alc_codec_rename_pci_table *q;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200981
982 for (p = rename_tbl; p->vendor_id; p++) {
Takashi Iwai7639a062015-03-03 10:07:24 +0100983 if (p->vendor_id != codec->core.vendor_id)
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200984 continue;
Takashi Iwai1bb7e432011-10-17 16:50:59 +0200985 if ((alc_get_coef0(codec) & p->coef_mask) == p->coef_bits)
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200986 return alc_codec_rename(codec, p->name);
987 }
Kailang Yang4b016932013-11-28 11:55:09 +0100988
Takashi Iwai5100cd02014-02-15 10:03:19 +0100989 if (!codec->bus->pci)
990 return 0;
Kailang Yang4b016932013-11-28 11:55:09 +0100991 for (q = rename_pci_tbl; q->codec_vendor_id; q++) {
Takashi Iwai7639a062015-03-03 10:07:24 +0100992 if (q->codec_vendor_id != codec->core.vendor_id)
Kailang Yang4b016932013-11-28 11:55:09 +0100993 continue;
994 if (q->pci_subvendor != codec->bus->pci->subsystem_vendor)
995 continue;
996 if (!q->pci_subdevice ||
997 q->pci_subdevice == codec->bus->pci->subsystem_device)
998 return alc_codec_rename(codec, q->name);
999 }
1000
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02001001 return 0;
1002}
1003
Takashi Iwaie4770622011-07-08 11:11:35 +02001004
1005/*
Takashi Iwai1d045db2011-07-07 18:23:21 +02001006 * Digital-beep handlers
1007 */
1008#ifdef CONFIG_SND_HDA_INPUT_BEEP
1009#define set_beep_amp(spec, nid, idx, dir) \
1010 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
1011
1012static const struct snd_pci_quirk beep_white_list[] = {
Duncan Roe71100052012-10-10 14:19:50 +02001013 SND_PCI_QUIRK(0x1043, 0x103c, "ASUS", 1),
W. Trevor Kinga4b7f21d2014-03-29 17:47:24 -07001014 SND_PCI_QUIRK(0x1043, 0x115d, "ASUS", 1),
Takashi Iwai1d045db2011-07-07 18:23:21 +02001015 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
Takashi Iwai8554ee42013-02-25 09:54:43 +01001016 SND_PCI_QUIRK(0x1043, 0x8376, "EeePC", 1),
Takashi Iwai1d045db2011-07-07 18:23:21 +02001017 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
1018 SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1),
1019 SND_PCI_QUIRK(0x1043, 0x834a, "EeePC", 1),
Takashi Iwai78f8baf2012-03-06 14:02:32 +01001020 SND_PCI_QUIRK(0x1458, 0xa002, "GA-MA790X", 1),
Takashi Iwai1d045db2011-07-07 18:23:21 +02001021 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
1022 {}
1023};
1024
1025static inline int has_cdefine_beep(struct hda_codec *codec)
1026{
1027 struct alc_spec *spec = codec->spec;
1028 const struct snd_pci_quirk *q;
1029 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
1030 if (q)
1031 return q->value;
1032 return spec->cdefine.enable_pcbeep;
1033}
1034#else
1035#define set_beep_amp(spec, nid, idx, dir) /* NOP */
1036#define has_cdefine_beep(codec) 0
1037#endif
1038
1039/* parse the BIOS configuration and set up the alc_spec */
1040/* return 1 if successful, 0 if the proper config is not found,
1041 * or a negative error code
1042 */
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001043static int alc_parse_auto_config(struct hda_codec *codec,
1044 const hda_nid_t *ignore_nids,
1045 const hda_nid_t *ssid_nids)
Takashi Iwai1d045db2011-07-07 18:23:21 +02001046{
1047 struct alc_spec *spec = codec->spec;
Takashi Iwai08c189f2012-12-19 15:22:24 +01001048 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001049 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001050
Takashi Iwai53c334a2011-08-23 18:27:14 +02001051 err = snd_hda_parse_pin_defcfg(codec, cfg, ignore_nids,
1052 spec->parse_flags);
Takashi Iwai1d045db2011-07-07 18:23:21 +02001053 if (err < 0)
1054 return err;
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001055
1056 if (ssid_nids)
1057 alc_ssid_check(codec, ssid_nids);
1058
Takashi Iwai08c189f2012-12-19 15:22:24 +01001059 err = snd_hda_gen_parse_auto_config(codec, cfg);
1060 if (err < 0)
1061 return err;
Takashi Iwai070cff42012-02-21 12:54:17 +01001062
Takashi Iwai1d045db2011-07-07 18:23:21 +02001063 return 1;
1064}
1065
Takashi Iwai3de95172012-05-07 18:03:15 +02001066/* common preparation job for alc_spec */
1067static int alc_alloc_spec(struct hda_codec *codec, hda_nid_t mixer_nid)
1068{
1069 struct alc_spec *spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1070 int err;
1071
1072 if (!spec)
1073 return -ENOMEM;
1074 codec->spec = spec;
Takashi Iwai08c189f2012-12-19 15:22:24 +01001075 snd_hda_gen_spec_init(&spec->gen);
1076 spec->gen.mixer_nid = mixer_nid;
1077 spec->gen.own_eapd_ctl = 1;
Takashi Iwai1098b7c2012-12-17 20:03:15 +01001078 codec->single_adc_amp = 1;
Takashi Iwai08c189f2012-12-19 15:22:24 +01001079 /* FIXME: do we need this for all Realtek codec models? */
1080 codec->spdif_status_reset = 1;
Takashi Iwai225068a2015-05-29 10:42:14 +02001081 codec->patch_ops = alc_patch_ops;
Takashi Iwai3de95172012-05-07 18:03:15 +02001082
1083 err = alc_codec_rename_from_preset(codec);
1084 if (err < 0) {
1085 kfree(spec);
1086 return err;
1087 }
1088 return 0;
1089}
1090
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001091static int alc880_parse_auto_config(struct hda_codec *codec)
1092{
1093 static const hda_nid_t alc880_ignore[] = { 0x1d, 0 };
Jesper Juhl7d7eb9e2012-04-12 22:11:25 +02001094 static const hda_nid_t alc880_ssids[] = { 0x15, 0x1b, 0x14, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001095 return alc_parse_auto_config(codec, alc880_ignore, alc880_ssids);
1096}
1097
Takashi Iwai1d045db2011-07-07 18:23:21 +02001098/*
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001099 * ALC880 fix-ups
1100 */
1101enum {
Takashi Iwai411225a2012-02-20 17:48:19 +01001102 ALC880_FIXUP_GPIO1,
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001103 ALC880_FIXUP_GPIO2,
1104 ALC880_FIXUP_MEDION_RIM,
Takashi Iwaidc6af522012-02-17 16:18:59 +01001105 ALC880_FIXUP_LG,
Takashi Iwaidb8a38e2013-08-09 12:34:42 +02001106 ALC880_FIXUP_LG_LW25,
Takashi Iwaif02aab52012-02-17 16:33:56 +01001107 ALC880_FIXUP_W810,
Takashi Iwai27e917f2012-02-17 17:49:54 +01001108 ALC880_FIXUP_EAPD_COEF,
Takashi Iwaib9368f52012-02-17 17:54:44 +01001109 ALC880_FIXUP_TCL_S700,
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001110 ALC880_FIXUP_VOL_KNOB,
1111 ALC880_FIXUP_FUJITSU,
Takashi Iwaiba533812012-02-20 16:36:52 +01001112 ALC880_FIXUP_F1734,
Takashi Iwai817de922012-02-20 17:20:48 +01001113 ALC880_FIXUP_UNIWILL,
Takashi Iwai967b88c2012-02-20 17:31:02 +01001114 ALC880_FIXUP_UNIWILL_DIG,
Takashi Iwai96e225f2012-02-20 17:41:51 +01001115 ALC880_FIXUP_Z71V,
Takashi Iwai487a5882013-11-07 07:29:30 +01001116 ALC880_FIXUP_ASUS_W5A,
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001117 ALC880_FIXUP_3ST_BASE,
1118 ALC880_FIXUP_3ST,
1119 ALC880_FIXUP_3ST_DIG,
1120 ALC880_FIXUP_5ST_BASE,
1121 ALC880_FIXUP_5ST,
1122 ALC880_FIXUP_5ST_DIG,
1123 ALC880_FIXUP_6ST_BASE,
1124 ALC880_FIXUP_6ST,
1125 ALC880_FIXUP_6ST_DIG,
Takashi Iwai53971452013-01-23 18:21:37 +01001126 ALC880_FIXUP_6ST_AUTOMUTE,
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001127};
1128
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001129/* enable the volume-knob widget support on NID 0x21 */
1130static void alc880_fixup_vol_knob(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001131 const struct hda_fixup *fix, int action)
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001132{
Takashi Iwai1727a772013-01-10 09:52:52 +01001133 if (action == HDA_FIXUP_ACT_PROBE)
Takashi Iwai62f949b2014-09-11 14:06:53 +02001134 snd_hda_jack_detect_enable_callback(codec, 0x21,
1135 alc_update_knob_master);
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001136}
1137
Takashi Iwai1727a772013-01-10 09:52:52 +01001138static const struct hda_fixup alc880_fixups[] = {
Takashi Iwai411225a2012-02-20 17:48:19 +01001139 [ALC880_FIXUP_GPIO1] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02001140 .type = HDA_FIXUP_FUNC,
1141 .v.func = alc_fixup_gpio1,
Takashi Iwai411225a2012-02-20 17:48:19 +01001142 },
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001143 [ALC880_FIXUP_GPIO2] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02001144 .type = HDA_FIXUP_FUNC,
1145 .v.func = alc_fixup_gpio2,
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001146 },
1147 [ALC880_FIXUP_MEDION_RIM] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001148 .type = HDA_FIXUP_VERBS,
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001149 .v.verbs = (const struct hda_verb[]) {
1150 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
1151 { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
1152 { }
1153 },
1154 .chained = true,
1155 .chain_id = ALC880_FIXUP_GPIO2,
1156 },
Takashi Iwaidc6af522012-02-17 16:18:59 +01001157 [ALC880_FIXUP_LG] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001158 .type = HDA_FIXUP_PINS,
1159 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaidc6af522012-02-17 16:18:59 +01001160 /* disable bogus unused pins */
1161 { 0x16, 0x411111f0 },
1162 { 0x18, 0x411111f0 },
1163 { 0x1a, 0x411111f0 },
1164 { }
1165 }
1166 },
Takashi Iwaidb8a38e2013-08-09 12:34:42 +02001167 [ALC880_FIXUP_LG_LW25] = {
1168 .type = HDA_FIXUP_PINS,
1169 .v.pins = (const struct hda_pintbl[]) {
1170 { 0x1a, 0x0181344f }, /* line-in */
1171 { 0x1b, 0x0321403f }, /* headphone */
1172 { }
1173 }
1174 },
Takashi Iwaif02aab52012-02-17 16:33:56 +01001175 [ALC880_FIXUP_W810] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001176 .type = HDA_FIXUP_PINS,
1177 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaif02aab52012-02-17 16:33:56 +01001178 /* disable bogus unused pins */
1179 { 0x17, 0x411111f0 },
1180 { }
1181 },
1182 .chained = true,
1183 .chain_id = ALC880_FIXUP_GPIO2,
1184 },
Takashi Iwai27e917f2012-02-17 17:49:54 +01001185 [ALC880_FIXUP_EAPD_COEF] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001186 .type = HDA_FIXUP_VERBS,
Takashi Iwai27e917f2012-02-17 17:49:54 +01001187 .v.verbs = (const struct hda_verb[]) {
1188 /* change to EAPD mode */
1189 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
1190 { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
1191 {}
1192 },
1193 },
Takashi Iwaib9368f52012-02-17 17:54:44 +01001194 [ALC880_FIXUP_TCL_S700] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001195 .type = HDA_FIXUP_VERBS,
Takashi Iwaib9368f52012-02-17 17:54:44 +01001196 .v.verbs = (const struct hda_verb[]) {
1197 /* change to EAPD mode */
1198 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
1199 { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
1200 {}
1201 },
1202 .chained = true,
1203 .chain_id = ALC880_FIXUP_GPIO2,
1204 },
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001205 [ALC880_FIXUP_VOL_KNOB] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001206 .type = HDA_FIXUP_FUNC,
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001207 .v.func = alc880_fixup_vol_knob,
1208 },
1209 [ALC880_FIXUP_FUJITSU] = {
1210 /* override all pins as BIOS on old Amilo is broken */
Takashi Iwai1727a772013-01-10 09:52:52 +01001211 .type = HDA_FIXUP_PINS,
1212 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaibb148bd2015-08-13 18:02:39 +02001213 { 0x14, 0x0121401f }, /* HP */
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001214 { 0x15, 0x99030120 }, /* speaker */
1215 { 0x16, 0x99030130 }, /* bass speaker */
1216 { 0x17, 0x411111f0 }, /* N/A */
1217 { 0x18, 0x411111f0 }, /* N/A */
1218 { 0x19, 0x01a19950 }, /* mic-in */
1219 { 0x1a, 0x411111f0 }, /* N/A */
1220 { 0x1b, 0x411111f0 }, /* N/A */
1221 { 0x1c, 0x411111f0 }, /* N/A */
1222 { 0x1d, 0x411111f0 }, /* N/A */
1223 { 0x1e, 0x01454140 }, /* SPDIF out */
1224 { }
1225 },
1226 .chained = true,
1227 .chain_id = ALC880_FIXUP_VOL_KNOB,
1228 },
Takashi Iwaiba533812012-02-20 16:36:52 +01001229 [ALC880_FIXUP_F1734] = {
1230 /* almost compatible with FUJITSU, but no bass and SPDIF */
Takashi Iwai1727a772013-01-10 09:52:52 +01001231 .type = HDA_FIXUP_PINS,
1232 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaibb148bd2015-08-13 18:02:39 +02001233 { 0x14, 0x0121401f }, /* HP */
Takashi Iwaiba533812012-02-20 16:36:52 +01001234 { 0x15, 0x99030120 }, /* speaker */
1235 { 0x16, 0x411111f0 }, /* N/A */
1236 { 0x17, 0x411111f0 }, /* N/A */
1237 { 0x18, 0x411111f0 }, /* N/A */
1238 { 0x19, 0x01a19950 }, /* mic-in */
1239 { 0x1a, 0x411111f0 }, /* N/A */
1240 { 0x1b, 0x411111f0 }, /* N/A */
1241 { 0x1c, 0x411111f0 }, /* N/A */
1242 { 0x1d, 0x411111f0 }, /* N/A */
1243 { 0x1e, 0x411111f0 }, /* N/A */
1244 { }
1245 },
1246 .chained = true,
1247 .chain_id = ALC880_FIXUP_VOL_KNOB,
1248 },
Takashi Iwai817de922012-02-20 17:20:48 +01001249 [ALC880_FIXUP_UNIWILL] = {
1250 /* need to fix HP and speaker pins to be parsed correctly */
Takashi Iwai1727a772013-01-10 09:52:52 +01001251 .type = HDA_FIXUP_PINS,
1252 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai817de922012-02-20 17:20:48 +01001253 { 0x14, 0x0121411f }, /* HP */
1254 { 0x15, 0x99030120 }, /* speaker */
1255 { 0x16, 0x99030130 }, /* bass speaker */
1256 { }
1257 },
1258 },
Takashi Iwai967b88c2012-02-20 17:31:02 +01001259 [ALC880_FIXUP_UNIWILL_DIG] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001260 .type = HDA_FIXUP_PINS,
1261 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai967b88c2012-02-20 17:31:02 +01001262 /* disable bogus unused pins */
1263 { 0x17, 0x411111f0 },
1264 { 0x19, 0x411111f0 },
1265 { 0x1b, 0x411111f0 },
1266 { 0x1f, 0x411111f0 },
1267 { }
1268 }
1269 },
Takashi Iwai96e225f2012-02-20 17:41:51 +01001270 [ALC880_FIXUP_Z71V] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001271 .type = HDA_FIXUP_PINS,
1272 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai96e225f2012-02-20 17:41:51 +01001273 /* set up the whole pins as BIOS is utterly broken */
1274 { 0x14, 0x99030120 }, /* speaker */
1275 { 0x15, 0x0121411f }, /* HP */
1276 { 0x16, 0x411111f0 }, /* N/A */
1277 { 0x17, 0x411111f0 }, /* N/A */
1278 { 0x18, 0x01a19950 }, /* mic-in */
1279 { 0x19, 0x411111f0 }, /* N/A */
1280 { 0x1a, 0x01813031 }, /* line-in */
1281 { 0x1b, 0x411111f0 }, /* N/A */
1282 { 0x1c, 0x411111f0 }, /* N/A */
1283 { 0x1d, 0x411111f0 }, /* N/A */
1284 { 0x1e, 0x0144111e }, /* SPDIF */
1285 { }
1286 }
1287 },
Takashi Iwai487a5882013-11-07 07:29:30 +01001288 [ALC880_FIXUP_ASUS_W5A] = {
1289 .type = HDA_FIXUP_PINS,
1290 .v.pins = (const struct hda_pintbl[]) {
1291 /* set up the whole pins as BIOS is utterly broken */
1292 { 0x14, 0x0121411f }, /* HP */
1293 { 0x15, 0x411111f0 }, /* N/A */
1294 { 0x16, 0x411111f0 }, /* N/A */
1295 { 0x17, 0x411111f0 }, /* N/A */
1296 { 0x18, 0x90a60160 }, /* mic */
1297 { 0x19, 0x411111f0 }, /* N/A */
1298 { 0x1a, 0x411111f0 }, /* N/A */
1299 { 0x1b, 0x411111f0 }, /* N/A */
1300 { 0x1c, 0x411111f0 }, /* N/A */
1301 { 0x1d, 0x411111f0 }, /* N/A */
1302 { 0x1e, 0xb743111e }, /* SPDIF out */
1303 { }
1304 },
1305 .chained = true,
1306 .chain_id = ALC880_FIXUP_GPIO1,
1307 },
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001308 [ALC880_FIXUP_3ST_BASE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001309 .type = HDA_FIXUP_PINS,
1310 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001311 { 0x14, 0x01014010 }, /* line-out */
1312 { 0x15, 0x411111f0 }, /* N/A */
1313 { 0x16, 0x411111f0 }, /* N/A */
1314 { 0x17, 0x411111f0 }, /* N/A */
1315 { 0x18, 0x01a19c30 }, /* mic-in */
1316 { 0x19, 0x0121411f }, /* HP */
1317 { 0x1a, 0x01813031 }, /* line-in */
1318 { 0x1b, 0x02a19c40 }, /* front-mic */
1319 { 0x1c, 0x411111f0 }, /* N/A */
1320 { 0x1d, 0x411111f0 }, /* N/A */
1321 /* 0x1e is filled in below */
1322 { 0x1f, 0x411111f0 }, /* N/A */
1323 { }
1324 }
1325 },
1326 [ALC880_FIXUP_3ST] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001327 .type = HDA_FIXUP_PINS,
1328 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001329 { 0x1e, 0x411111f0 }, /* N/A */
1330 { }
1331 },
1332 .chained = true,
1333 .chain_id = ALC880_FIXUP_3ST_BASE,
1334 },
1335 [ALC880_FIXUP_3ST_DIG] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001336 .type = HDA_FIXUP_PINS,
1337 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001338 { 0x1e, 0x0144111e }, /* SPDIF */
1339 { }
1340 },
1341 .chained = true,
1342 .chain_id = ALC880_FIXUP_3ST_BASE,
1343 },
1344 [ALC880_FIXUP_5ST_BASE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001345 .type = HDA_FIXUP_PINS,
1346 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001347 { 0x14, 0x01014010 }, /* front */
1348 { 0x15, 0x411111f0 }, /* N/A */
1349 { 0x16, 0x01011411 }, /* CLFE */
1350 { 0x17, 0x01016412 }, /* surr */
1351 { 0x18, 0x01a19c30 }, /* mic-in */
1352 { 0x19, 0x0121411f }, /* HP */
1353 { 0x1a, 0x01813031 }, /* line-in */
1354 { 0x1b, 0x02a19c40 }, /* front-mic */
1355 { 0x1c, 0x411111f0 }, /* N/A */
1356 { 0x1d, 0x411111f0 }, /* N/A */
1357 /* 0x1e is filled in below */
1358 { 0x1f, 0x411111f0 }, /* N/A */
1359 { }
1360 }
1361 },
1362 [ALC880_FIXUP_5ST] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001363 .type = HDA_FIXUP_PINS,
1364 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001365 { 0x1e, 0x411111f0 }, /* N/A */
1366 { }
1367 },
1368 .chained = true,
1369 .chain_id = ALC880_FIXUP_5ST_BASE,
1370 },
1371 [ALC880_FIXUP_5ST_DIG] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001372 .type = HDA_FIXUP_PINS,
1373 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001374 { 0x1e, 0x0144111e }, /* SPDIF */
1375 { }
1376 },
1377 .chained = true,
1378 .chain_id = ALC880_FIXUP_5ST_BASE,
1379 },
1380 [ALC880_FIXUP_6ST_BASE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001381 .type = HDA_FIXUP_PINS,
1382 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001383 { 0x14, 0x01014010 }, /* front */
1384 { 0x15, 0x01016412 }, /* surr */
1385 { 0x16, 0x01011411 }, /* CLFE */
1386 { 0x17, 0x01012414 }, /* side */
1387 { 0x18, 0x01a19c30 }, /* mic-in */
1388 { 0x19, 0x02a19c40 }, /* front-mic */
1389 { 0x1a, 0x01813031 }, /* line-in */
1390 { 0x1b, 0x0121411f }, /* HP */
1391 { 0x1c, 0x411111f0 }, /* N/A */
1392 { 0x1d, 0x411111f0 }, /* N/A */
1393 /* 0x1e is filled in below */
1394 { 0x1f, 0x411111f0 }, /* N/A */
1395 { }
1396 }
1397 },
1398 [ALC880_FIXUP_6ST] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001399 .type = HDA_FIXUP_PINS,
1400 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001401 { 0x1e, 0x411111f0 }, /* N/A */
1402 { }
1403 },
1404 .chained = true,
1405 .chain_id = ALC880_FIXUP_6ST_BASE,
1406 },
1407 [ALC880_FIXUP_6ST_DIG] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001408 .type = HDA_FIXUP_PINS,
1409 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001410 { 0x1e, 0x0144111e }, /* SPDIF */
1411 { }
1412 },
1413 .chained = true,
1414 .chain_id = ALC880_FIXUP_6ST_BASE,
1415 },
Takashi Iwai53971452013-01-23 18:21:37 +01001416 [ALC880_FIXUP_6ST_AUTOMUTE] = {
1417 .type = HDA_FIXUP_PINS,
1418 .v.pins = (const struct hda_pintbl[]) {
1419 { 0x1b, 0x0121401f }, /* HP with jack detect */
1420 { }
1421 },
1422 .chained_before = true,
1423 .chain_id = ALC880_FIXUP_6ST_BASE,
1424 },
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001425};
1426
1427static const struct snd_pci_quirk alc880_fixup_tbl[] = {
Takashi Iwaif02aab52012-02-17 16:33:56 +01001428 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_FIXUP_W810),
Takashi Iwai487a5882013-11-07 07:29:30 +01001429 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS W5A", ALC880_FIXUP_ASUS_W5A),
Takashi Iwai96e225f2012-02-20 17:41:51 +01001430 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_FIXUP_Z71V),
Takashi Iwai29e3fdc2012-02-20 17:56:57 +01001431 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_FIXUP_GPIO1),
David Henningsson6538de02014-06-10 10:52:50 +02001432 SND_PCI_QUIRK(0x147b, 0x1045, "ABit AA8XE", ALC880_FIXUP_6ST_AUTOMUTE),
Takashi Iwai29e3fdc2012-02-20 17:56:57 +01001433 SND_PCI_QUIRK(0x1558, 0x5401, "Clevo GPIO2", ALC880_FIXUP_GPIO2),
Takashi Iwai27e917f2012-02-17 17:49:54 +01001434 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo", ALC880_FIXUP_EAPD_COEF),
Takashi Iwai967b88c2012-02-20 17:31:02 +01001435 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_FIXUP_UNIWILL_DIG),
Takashi Iwaiba533812012-02-20 16:36:52 +01001436 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_FIXUP_F1734),
Takashi Iwai817de922012-02-20 17:20:48 +01001437 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_FIXUP_UNIWILL),
Takashi Iwai7833c7e2012-02-20 17:11:38 +01001438 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_FIXUP_VOL_KNOB),
Takashi Iwaif02aab52012-02-17 16:33:56 +01001439 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_FIXUP_W810),
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001440 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_FIXUP_MEDION_RIM),
Takashi Iwai53971452013-01-23 18:21:37 +01001441 SND_PCI_QUIRK(0x1631, 0xe011, "PB 13201056", ALC880_FIXUP_6ST_AUTOMUTE),
Takashi Iwaia1615742015-08-13 18:05:06 +02001442 SND_PCI_QUIRK(0x1734, 0x107c, "FSC Amilo M1437", ALC880_FIXUP_FUJITSU),
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001443 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FIXUP_FUJITSU),
Takashi Iwaiba533812012-02-20 16:36:52 +01001444 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_FIXUP_F1734),
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001445 SND_PCI_QUIRK(0x1734, 0x10b0, "FSC Amilo Pi1556", ALC880_FIXUP_FUJITSU),
Takashi Iwaidc6af522012-02-17 16:18:59 +01001446 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_FIXUP_LG),
1447 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_FIXUP_LG),
1448 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_FIXUP_LG),
Takashi Iwaidb8a38e2013-08-09 12:34:42 +02001449 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_FIXUP_LG_LW25),
Takashi Iwaib9368f52012-02-17 17:54:44 +01001450 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_FIXUP_TCL_S700),
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001451
1452 /* Below is the copied entries from alc880_quirks.c.
1453 * It's not quite sure whether BIOS sets the correct pin-config table
1454 * on these machines, thus they are kept to be compatible with
1455 * the old static quirks. Once when it's confirmed to work without
1456 * these overrides, it'd be better to remove.
1457 */
1458 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_FIXUP_5ST_DIG),
1459 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_FIXUP_6ST),
1460 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_FIXUP_3ST_DIG),
1461 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_FIXUP_6ST_DIG),
1462 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_FIXUP_6ST_DIG),
1463 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_FIXUP_6ST_DIG),
1464 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_FIXUP_3ST_DIG),
1465 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_FIXUP_3ST),
1466 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_FIXUP_6ST_DIG),
1467 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_FIXUP_3ST),
1468 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_FIXUP_3ST),
1469 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_FIXUP_5ST),
1470 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_FIXUP_5ST),
1471 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_FIXUP_5ST),
1472 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_FIXUP_6ST_DIG),
1473 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_FIXUP_6ST_DIG),
1474 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_FIXUP_6ST_DIG),
1475 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_FIXUP_6ST_DIG),
1476 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_FIXUP_5ST_DIG),
1477 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_FIXUP_5ST_DIG),
1478 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_FIXUP_5ST_DIG),
1479 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_FIXUP_6ST_DIG), /* broken BIOS */
1480 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_FIXUP_6ST_DIG),
1481 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1482 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1483 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1484 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_FIXUP_3ST_DIG),
1485 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1486 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_FIXUP_3ST_DIG),
1487 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_FIXUP_3ST_DIG),
1488 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1489 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1490 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1491 /* default Intel */
1492 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_FIXUP_3ST),
1493 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_FIXUP_5ST_DIG),
1494 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_FIXUP_6ST_DIG),
1495 {}
1496};
1497
Takashi Iwai1727a772013-01-10 09:52:52 +01001498static const struct hda_model_fixup alc880_fixup_models[] = {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001499 {.id = ALC880_FIXUP_3ST, .name = "3stack"},
1500 {.id = ALC880_FIXUP_3ST_DIG, .name = "3stack-digout"},
1501 {.id = ALC880_FIXUP_5ST, .name = "5stack"},
1502 {.id = ALC880_FIXUP_5ST_DIG, .name = "5stack-digout"},
1503 {.id = ALC880_FIXUP_6ST, .name = "6stack"},
1504 {.id = ALC880_FIXUP_6ST_DIG, .name = "6stack-digout"},
Takashi Iwai53971452013-01-23 18:21:37 +01001505 {.id = ALC880_FIXUP_6ST_AUTOMUTE, .name = "6stack-automute"},
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001506 {}
1507};
1508
1509
1510/*
Takashi Iwai1d045db2011-07-07 18:23:21 +02001511 * OK, here we have finally the patch for ALC880
1512 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02001513static int patch_alc880(struct hda_codec *codec)
1514{
1515 struct alc_spec *spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001516 int err;
1517
Takashi Iwai3de95172012-05-07 18:03:15 +02001518 err = alc_alloc_spec(codec, 0x0b);
1519 if (err < 0)
1520 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001521
Takashi Iwai3de95172012-05-07 18:03:15 +02001522 spec = codec->spec;
Takashi Iwai08c189f2012-12-19 15:22:24 +01001523 spec->gen.need_dac_fix = 1;
Takashi Iwai7504b6c2013-03-18 11:25:51 +01001524 spec->gen.beep_nid = 0x01;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001525
Takashi Iwai225068a2015-05-29 10:42:14 +02001526 codec->patch_ops.unsol_event = alc880_unsol_event;
1527
Takashi Iwai1727a772013-01-10 09:52:52 +01001528 snd_hda_pick_fixup(codec, alc880_fixup_models, alc880_fixup_tbl,
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001529 alc880_fixups);
Takashi Iwai1727a772013-01-10 09:52:52 +01001530 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02001531
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001532 /* automatic parse from the BIOS config */
1533 err = alc880_parse_auto_config(codec);
1534 if (err < 0)
1535 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001536
Takashi Iwai7504b6c2013-03-18 11:25:51 +01001537 if (!spec->gen.no_analog)
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001538 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
Takashi Iwai1d045db2011-07-07 18:23:21 +02001539
Takashi Iwai1727a772013-01-10 09:52:52 +01001540 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01001541
Takashi Iwai1d045db2011-07-07 18:23:21 +02001542 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02001543
1544 error:
1545 alc_free(codec);
1546 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001547}
1548
1549
1550/*
1551 * ALC260 support
1552 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02001553static int alc260_parse_auto_config(struct hda_codec *codec)
1554{
Takashi Iwai1d045db2011-07-07 18:23:21 +02001555 static const hda_nid_t alc260_ignore[] = { 0x17, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001556 static const hda_nid_t alc260_ssids[] = { 0x10, 0x15, 0x0f, 0 };
1557 return alc_parse_auto_config(codec, alc260_ignore, alc260_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02001558}
1559
Takashi Iwai1d045db2011-07-07 18:23:21 +02001560/*
1561 * Pin config fixes
1562 */
1563enum {
Takashi Iwaica8f0422012-02-16 11:51:19 +01001564 ALC260_FIXUP_HP_DC5750,
1565 ALC260_FIXUP_HP_PIN_0F,
1566 ALC260_FIXUP_COEF,
Takashi Iwai15317ab2012-02-16 12:02:53 +01001567 ALC260_FIXUP_GPIO1,
Takashi Iwai20f7d922012-02-16 12:35:16 +01001568 ALC260_FIXUP_GPIO1_TOGGLE,
1569 ALC260_FIXUP_REPLACER,
Takashi Iwai0a1c4fa2012-02-16 12:42:30 +01001570 ALC260_FIXUP_HP_B1900,
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001571 ALC260_FIXUP_KN1,
Takashi Iwai39aedee2013-01-10 17:10:40 +01001572 ALC260_FIXUP_FSC_S7020,
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001573 ALC260_FIXUP_FSC_S7020_JWSE,
Takashi Iwaid08c5ef2013-11-22 08:06:36 +01001574 ALC260_FIXUP_VAIO_PINS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02001575};
1576
Takashi Iwai20f7d922012-02-16 12:35:16 +01001577static void alc260_gpio1_automute(struct hda_codec *codec)
1578{
1579 struct alc_spec *spec = codec->spec;
1580 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
Takashi Iwai08c189f2012-12-19 15:22:24 +01001581 spec->gen.hp_jack_present);
Takashi Iwai20f7d922012-02-16 12:35:16 +01001582}
1583
1584static void alc260_fixup_gpio1_toggle(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001585 const struct hda_fixup *fix, int action)
Takashi Iwai20f7d922012-02-16 12:35:16 +01001586{
1587 struct alc_spec *spec = codec->spec;
Takashi Iwai1727a772013-01-10 09:52:52 +01001588 if (action == HDA_FIXUP_ACT_PROBE) {
Takashi Iwai20f7d922012-02-16 12:35:16 +01001589 /* although the machine has only one output pin, we need to
1590 * toggle GPIO1 according to the jack state
1591 */
Takashi Iwai08c189f2012-12-19 15:22:24 +01001592 spec->gen.automute_hook = alc260_gpio1_automute;
1593 spec->gen.detect_hp = 1;
1594 spec->gen.automute_speaker = 1;
1595 spec->gen.autocfg.hp_pins[0] = 0x0f; /* copy it for automute */
Takashi Iwai62f949b2014-09-11 14:06:53 +02001596 snd_hda_jack_detect_enable_callback(codec, 0x0f,
Takashi Iwai08c189f2012-12-19 15:22:24 +01001597 snd_hda_gen_hp_automute);
Takashi Iwai5579cd62018-06-19 22:22:41 +02001598 alc_setup_gpio(codec, 0x01);
Takashi Iwai20f7d922012-02-16 12:35:16 +01001599 }
1600}
1601
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001602static void alc260_fixup_kn1(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001603 const struct hda_fixup *fix, int action)
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001604{
1605 struct alc_spec *spec = codec->spec;
Takashi Iwai1727a772013-01-10 09:52:52 +01001606 static const struct hda_pintbl pincfgs[] = {
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001607 { 0x0f, 0x02214000 }, /* HP/speaker */
1608 { 0x12, 0x90a60160 }, /* int mic */
1609 { 0x13, 0x02a19000 }, /* ext mic */
1610 { 0x18, 0x01446000 }, /* SPDIF out */
1611 /* disable bogus I/O pins */
1612 { 0x10, 0x411111f0 },
1613 { 0x11, 0x411111f0 },
1614 { 0x14, 0x411111f0 },
1615 { 0x15, 0x411111f0 },
1616 { 0x16, 0x411111f0 },
1617 { 0x17, 0x411111f0 },
1618 { 0x19, 0x411111f0 },
1619 { }
1620 };
1621
1622 switch (action) {
Takashi Iwai1727a772013-01-10 09:52:52 +01001623 case HDA_FIXUP_ACT_PRE_PROBE:
1624 snd_hda_apply_pincfgs(codec, pincfgs);
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001625 spec->init_amp = ALC_INIT_NONE;
1626 break;
1627 }
1628}
1629
Takashi Iwai39aedee2013-01-10 17:10:40 +01001630static void alc260_fixup_fsc_s7020(struct hda_codec *codec,
1631 const struct hda_fixup *fix, int action)
1632{
1633 struct alc_spec *spec = codec->spec;
Takashi Iwai1c76aa52018-06-21 16:37:54 +02001634 if (action == HDA_FIXUP_ACT_PRE_PROBE)
Takashi Iwaie6e0ee52013-02-18 17:04:20 +01001635 spec->init_amp = ALC_INIT_NONE;
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001636}
1637
1638static void alc260_fixup_fsc_s7020_jwse(struct hda_codec *codec,
1639 const struct hda_fixup *fix, int action)
1640{
1641 struct alc_spec *spec = codec->spec;
1642 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwaif811c3c2013-03-07 18:32:59 +01001643 spec->gen.add_jack_modes = 1;
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001644 spec->gen.hp_mic = 1;
Takashi Iwaie6e0ee52013-02-18 17:04:20 +01001645 }
Takashi Iwai39aedee2013-01-10 17:10:40 +01001646}
1647
Takashi Iwai1727a772013-01-10 09:52:52 +01001648static const struct hda_fixup alc260_fixups[] = {
Takashi Iwaica8f0422012-02-16 11:51:19 +01001649 [ALC260_FIXUP_HP_DC5750] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001650 .type = HDA_FIXUP_PINS,
1651 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02001652 { 0x11, 0x90130110 }, /* speaker */
1653 { }
1654 }
1655 },
Takashi Iwaica8f0422012-02-16 11:51:19 +01001656 [ALC260_FIXUP_HP_PIN_0F] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001657 .type = HDA_FIXUP_PINS,
1658 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaica8f0422012-02-16 11:51:19 +01001659 { 0x0f, 0x01214000 }, /* HP */
1660 { }
1661 }
1662 },
1663 [ALC260_FIXUP_COEF] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001664 .type = HDA_FIXUP_VERBS,
Takashi Iwaica8f0422012-02-16 11:51:19 +01001665 .v.verbs = (const struct hda_verb[]) {
Ronan Marquete30cf2d2014-06-01 18:38:53 +02001666 { 0x1a, AC_VERB_SET_COEF_INDEX, 0x07 },
1667 { 0x1a, AC_VERB_SET_PROC_COEF, 0x3040 },
Takashi Iwaica8f0422012-02-16 11:51:19 +01001668 { }
1669 },
Takashi Iwaica8f0422012-02-16 11:51:19 +01001670 },
Takashi Iwai15317ab2012-02-16 12:02:53 +01001671 [ALC260_FIXUP_GPIO1] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02001672 .type = HDA_FIXUP_FUNC,
1673 .v.func = alc_fixup_gpio1,
Takashi Iwai15317ab2012-02-16 12:02:53 +01001674 },
Takashi Iwai20f7d922012-02-16 12:35:16 +01001675 [ALC260_FIXUP_GPIO1_TOGGLE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001676 .type = HDA_FIXUP_FUNC,
Takashi Iwai20f7d922012-02-16 12:35:16 +01001677 .v.func = alc260_fixup_gpio1_toggle,
1678 .chained = true,
1679 .chain_id = ALC260_FIXUP_HP_PIN_0F,
1680 },
1681 [ALC260_FIXUP_REPLACER] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001682 .type = HDA_FIXUP_VERBS,
Takashi Iwai20f7d922012-02-16 12:35:16 +01001683 .v.verbs = (const struct hda_verb[]) {
Takashi Iwai192a98e2014-06-02 15:16:07 +02001684 { 0x1a, AC_VERB_SET_COEF_INDEX, 0x07 },
1685 { 0x1a, AC_VERB_SET_PROC_COEF, 0x3050 },
Takashi Iwai20f7d922012-02-16 12:35:16 +01001686 { }
1687 },
1688 .chained = true,
1689 .chain_id = ALC260_FIXUP_GPIO1_TOGGLE,
1690 },
Takashi Iwai0a1c4fa2012-02-16 12:42:30 +01001691 [ALC260_FIXUP_HP_B1900] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001692 .type = HDA_FIXUP_FUNC,
Takashi Iwai0a1c4fa2012-02-16 12:42:30 +01001693 .v.func = alc260_fixup_gpio1_toggle,
1694 .chained = true,
1695 .chain_id = ALC260_FIXUP_COEF,
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001696 },
1697 [ALC260_FIXUP_KN1] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001698 .type = HDA_FIXUP_FUNC,
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001699 .v.func = alc260_fixup_kn1,
1700 },
Takashi Iwai39aedee2013-01-10 17:10:40 +01001701 [ALC260_FIXUP_FSC_S7020] = {
1702 .type = HDA_FIXUP_FUNC,
1703 .v.func = alc260_fixup_fsc_s7020,
1704 },
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001705 [ALC260_FIXUP_FSC_S7020_JWSE] = {
1706 .type = HDA_FIXUP_FUNC,
1707 .v.func = alc260_fixup_fsc_s7020_jwse,
1708 .chained = true,
1709 .chain_id = ALC260_FIXUP_FSC_S7020,
1710 },
Takashi Iwaid08c5ef2013-11-22 08:06:36 +01001711 [ALC260_FIXUP_VAIO_PINS] = {
1712 .type = HDA_FIXUP_PINS,
1713 .v.pins = (const struct hda_pintbl[]) {
1714 /* Pin configs are missing completely on some VAIOs */
1715 { 0x0f, 0x01211020 },
1716 { 0x10, 0x0001003f },
1717 { 0x11, 0x411111f0 },
1718 { 0x12, 0x01a15930 },
1719 { 0x13, 0x411111f0 },
1720 { 0x14, 0x411111f0 },
1721 { 0x15, 0x411111f0 },
1722 { 0x16, 0x411111f0 },
1723 { 0x17, 0x411111f0 },
1724 { 0x18, 0x411111f0 },
1725 { 0x19, 0x411111f0 },
1726 { }
1727 }
1728 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02001729};
1730
1731static const struct snd_pci_quirk alc260_fixup_tbl[] = {
Takashi Iwai15317ab2012-02-16 12:02:53 +01001732 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_FIXUP_GPIO1),
Takashi Iwaica8f0422012-02-16 11:51:19 +01001733 SND_PCI_QUIRK(0x1025, 0x007f, "Acer Aspire 9500", ALC260_FIXUP_COEF),
Takashi Iwai15317ab2012-02-16 12:02:53 +01001734 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_FIXUP_GPIO1),
Takashi Iwaica8f0422012-02-16 11:51:19 +01001735 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", ALC260_FIXUP_HP_DC5750),
Takashi Iwai0a1c4fa2012-02-16 12:42:30 +01001736 SND_PCI_QUIRK(0x103c, 0x30ba, "HP Presario B1900", ALC260_FIXUP_HP_B1900),
Takashi Iwaid08c5ef2013-11-22 08:06:36 +01001737 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_FIXUP_VAIO_PINS),
Takashi Iwai0f5a5b82013-11-21 09:12:52 +01001738 SND_PCI_QUIRK(0x104d, 0x81e2, "Sony VAIO TX", ALC260_FIXUP_HP_PIN_0F),
Takashi Iwai39aedee2013-01-10 17:10:40 +01001739 SND_PCI_QUIRK(0x10cf, 0x1326, "FSC LifeBook S7020", ALC260_FIXUP_FSC_S7020),
Takashi Iwaib1f58082012-02-16 12:45:03 +01001740 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FIXUP_GPIO1),
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001741 SND_PCI_QUIRK(0x152d, 0x0729, "Quanta KN1", ALC260_FIXUP_KN1),
Takashi Iwai20f7d922012-02-16 12:35:16 +01001742 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_FIXUP_REPLACER),
Takashi Iwaica8f0422012-02-16 11:51:19 +01001743 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_FIXUP_COEF),
Takashi Iwai1d045db2011-07-07 18:23:21 +02001744 {}
1745};
1746
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001747static const struct hda_model_fixup alc260_fixup_models[] = {
1748 {.id = ALC260_FIXUP_GPIO1, .name = "gpio1"},
1749 {.id = ALC260_FIXUP_COEF, .name = "coef"},
1750 {.id = ALC260_FIXUP_FSC_S7020, .name = "fujitsu"},
1751 {.id = ALC260_FIXUP_FSC_S7020_JWSE, .name = "fujitsu-jwse"},
1752 {}
1753};
1754
Takashi Iwai1d045db2011-07-07 18:23:21 +02001755/*
1756 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02001757static int patch_alc260(struct hda_codec *codec)
1758{
1759 struct alc_spec *spec;
Takashi Iwaic3c2c9e2012-02-16 12:59:55 +01001760 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001761
Takashi Iwai3de95172012-05-07 18:03:15 +02001762 err = alc_alloc_spec(codec, 0x07);
1763 if (err < 0)
1764 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001765
Takashi Iwai3de95172012-05-07 18:03:15 +02001766 spec = codec->spec;
Takashi Iwaiea46c3c2013-01-15 18:45:53 +01001767 /* as quite a few machines require HP amp for speaker outputs,
1768 * it's easier to enable it unconditionally; even if it's unneeded,
1769 * it's almost harmless.
1770 */
1771 spec->gen.prefer_hp_amp = 1;
Takashi Iwai7504b6c2013-03-18 11:25:51 +01001772 spec->gen.beep_nid = 0x01;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001773
Takashi Iwai225068a2015-05-29 10:42:14 +02001774 spec->shutup = alc_eapd_shutup;
1775
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001776 snd_hda_pick_fixup(codec, alc260_fixup_models, alc260_fixup_tbl,
1777 alc260_fixups);
Takashi Iwai1727a772013-01-10 09:52:52 +01001778 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02001779
Takashi Iwaic3c2c9e2012-02-16 12:59:55 +01001780 /* automatic parse from the BIOS config */
1781 err = alc260_parse_auto_config(codec);
1782 if (err < 0)
1783 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001784
Takashi Iwai7504b6c2013-03-18 11:25:51 +01001785 if (!spec->gen.no_analog)
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001786 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
Takashi Iwai1d045db2011-07-07 18:23:21 +02001787
Takashi Iwai1727a772013-01-10 09:52:52 +01001788 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01001789
Takashi Iwai1d045db2011-07-07 18:23:21 +02001790 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02001791
1792 error:
1793 alc_free(codec);
1794 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001795}
1796
1797
1798/*
1799 * ALC882/883/885/888/889 support
1800 *
1801 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
1802 * configuration. Each pin widget can choose any input DACs and a mixer.
1803 * Each ADC is connected from a mixer of all inputs. This makes possible
1804 * 6-channel independent captures.
1805 *
1806 * In addition, an independent DAC for the multi-playback (not used in this
1807 * driver yet).
1808 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02001809
1810/*
1811 * Pin config fixes
1812 */
1813enum {
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01001814 ALC882_FIXUP_ABIT_AW9D_MAX,
1815 ALC882_FIXUP_LENOVO_Y530,
1816 ALC882_FIXUP_PB_M5210,
1817 ALC882_FIXUP_ACER_ASPIRE_7736,
1818 ALC882_FIXUP_ASUS_W90V,
Marton Balint8f239212012-03-05 21:33:23 +01001819 ALC889_FIXUP_CD,
David Henningssonb2c53e22014-01-01 14:01:34 +01001820 ALC889_FIXUP_FRONT_HP_NO_PRESENCE,
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01001821 ALC889_FIXUP_VAIO_TT,
Takashi Iwai0e7cc2e2011-11-09 12:42:48 +01001822 ALC888_FIXUP_EEE1601,
Takashi Iwai177943a32011-11-09 12:55:18 +01001823 ALC882_FIXUP_EAPD,
Takashi Iwai7a6069b2011-11-09 15:22:01 +01001824 ALC883_FIXUP_EAPD,
Takashi Iwai8812c4f2011-11-09 17:39:15 +01001825 ALC883_FIXUP_ACER_EAPD,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001826 ALC882_FIXUP_GPIO1,
1827 ALC882_FIXUP_GPIO2,
Takashi Iwaieb844d52011-11-09 18:03:07 +01001828 ALC882_FIXUP_GPIO3,
Takashi Iwai68ef0562011-11-09 18:24:44 +01001829 ALC889_FIXUP_COEF,
1830 ALC882_FIXUP_ASUS_W2JC,
Takashi Iwaic3e837b2011-11-10 16:01:47 +01001831 ALC882_FIXUP_ACER_ASPIRE_4930G,
1832 ALC882_FIXUP_ACER_ASPIRE_8930G,
1833 ALC882_FIXUP_ASPIRE_8930G_VERBS,
Takashi Iwai56710872011-11-14 17:42:11 +01001834 ALC885_FIXUP_MACPRO_GPIO,
Takashi Iwai02a237b2012-02-13 15:25:07 +01001835 ALC889_FIXUP_DAC_ROUTE,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001836 ALC889_FIXUP_MBP_VREF,
1837 ALC889_FIXUP_IMAC91_VREF,
Adrien Vergée7729a42014-01-24 14:56:14 -05001838 ALC889_FIXUP_MBA11_VREF,
Takashi Iwai0756f092013-12-04 13:59:45 +01001839 ALC889_FIXUP_MBA21_VREF,
Takashi Iwaic20f31e2014-02-03 11:02:10 +01001840 ALC889_FIXUP_MP11_VREF,
Mario Kleiner9f660a12015-12-22 00:45:43 +01001841 ALC889_FIXUP_MP41_VREF,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02001842 ALC882_FIXUP_INV_DMIC,
Takashi Iwaie427c232012-07-29 10:04:08 +02001843 ALC882_FIXUP_NO_PRIMARY_HP,
Takashi Iwai1f0bbf02013-11-28 15:21:21 +01001844 ALC887_FIXUP_ASUS_BASS,
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01001845 ALC887_FIXUP_BASS_CHMAP,
Takashi Iwai7beb3a62017-04-10 18:05:52 +02001846 ALC1220_FIXUP_GB_DUAL_CODECS,
Peisen0202f5c2017-10-26 10:35:36 +08001847 ALC1220_FIXUP_CLEVO_P950,
Takashi Iwai1d045db2011-07-07 18:23:21 +02001848};
1849
Takashi Iwai68ef0562011-11-09 18:24:44 +01001850static void alc889_fixup_coef(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001851 const struct hda_fixup *fix, int action)
Takashi Iwai68ef0562011-11-09 18:24:44 +01001852{
Takashi Iwai1727a772013-01-10 09:52:52 +01001853 if (action != HDA_FIXUP_ACT_INIT)
Takashi Iwai68ef0562011-11-09 18:24:44 +01001854 return;
Kailang Yang1df88742014-10-29 16:10:13 +08001855 alc_update_coef_idx(codec, 7, 0, 0x2030);
Takashi Iwai68ef0562011-11-09 18:24:44 +01001856}
1857
Takashi Iwai56710872011-11-14 17:42:11 +01001858/* toggle speaker-output according to the hp-jack state */
1859static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
1860{
1861 unsigned int gpiostate, gpiomask, gpiodir;
1862
Takashi Iwai7639a062015-03-03 10:07:24 +01001863 gpiostate = snd_hda_codec_read(codec, codec->core.afg, 0,
Takashi Iwai56710872011-11-14 17:42:11 +01001864 AC_VERB_GET_GPIO_DATA, 0);
1865
1866 if (!muted)
1867 gpiostate |= (1 << pin);
1868 else
1869 gpiostate &= ~(1 << pin);
1870
Takashi Iwai7639a062015-03-03 10:07:24 +01001871 gpiomask = snd_hda_codec_read(codec, codec->core.afg, 0,
Takashi Iwai56710872011-11-14 17:42:11 +01001872 AC_VERB_GET_GPIO_MASK, 0);
1873 gpiomask |= (1 << pin);
1874
Takashi Iwai7639a062015-03-03 10:07:24 +01001875 gpiodir = snd_hda_codec_read(codec, codec->core.afg, 0,
Takashi Iwai56710872011-11-14 17:42:11 +01001876 AC_VERB_GET_GPIO_DIRECTION, 0);
1877 gpiodir |= (1 << pin);
1878
1879
Takashi Iwai7639a062015-03-03 10:07:24 +01001880 snd_hda_codec_write(codec, codec->core.afg, 0,
Takashi Iwai56710872011-11-14 17:42:11 +01001881 AC_VERB_SET_GPIO_MASK, gpiomask);
Takashi Iwai7639a062015-03-03 10:07:24 +01001882 snd_hda_codec_write(codec, codec->core.afg, 0,
Takashi Iwai56710872011-11-14 17:42:11 +01001883 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
1884
1885 msleep(1);
1886
Takashi Iwai7639a062015-03-03 10:07:24 +01001887 snd_hda_codec_write(codec, codec->core.afg, 0,
Takashi Iwai56710872011-11-14 17:42:11 +01001888 AC_VERB_SET_GPIO_DATA, gpiostate);
1889}
1890
1891/* set up GPIO at initialization */
1892static void alc885_fixup_macpro_gpio(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001893 const struct hda_fixup *fix, int action)
Takashi Iwai56710872011-11-14 17:42:11 +01001894{
Takashi Iwai1727a772013-01-10 09:52:52 +01001895 if (action != HDA_FIXUP_ACT_INIT)
Takashi Iwai56710872011-11-14 17:42:11 +01001896 return;
1897 alc882_gpio_mute(codec, 0, 0);
1898 alc882_gpio_mute(codec, 1, 0);
1899}
1900
Takashi Iwai02a237b2012-02-13 15:25:07 +01001901/* Fix the connection of some pins for ALC889:
1902 * At least, Acer Aspire 5935 shows the connections to DAC3/4 don't
1903 * work correctly (bko#42740)
1904 */
1905static void alc889_fixup_dac_route(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001906 const struct hda_fixup *fix, int action)
Takashi Iwai02a237b2012-02-13 15:25:07 +01001907{
Takashi Iwai1727a772013-01-10 09:52:52 +01001908 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwaief8d60f2012-02-17 10:12:38 +01001909 /* fake the connections during parsing the tree */
Takashi Iwai02a237b2012-02-13 15:25:07 +01001910 hda_nid_t conn1[2] = { 0x0c, 0x0d };
1911 hda_nid_t conn2[2] = { 0x0e, 0x0f };
1912 snd_hda_override_conn_list(codec, 0x14, 2, conn1);
1913 snd_hda_override_conn_list(codec, 0x15, 2, conn1);
1914 snd_hda_override_conn_list(codec, 0x18, 2, conn2);
1915 snd_hda_override_conn_list(codec, 0x1a, 2, conn2);
Takashi Iwai1727a772013-01-10 09:52:52 +01001916 } else if (action == HDA_FIXUP_ACT_PROBE) {
Takashi Iwaief8d60f2012-02-17 10:12:38 +01001917 /* restore the connections */
1918 hda_nid_t conn[5] = { 0x0c, 0x0d, 0x0e, 0x0f, 0x26 };
1919 snd_hda_override_conn_list(codec, 0x14, 5, conn);
1920 snd_hda_override_conn_list(codec, 0x15, 5, conn);
1921 snd_hda_override_conn_list(codec, 0x18, 5, conn);
1922 snd_hda_override_conn_list(codec, 0x1a, 5, conn);
Takashi Iwai02a237b2012-02-13 15:25:07 +01001923 }
1924}
1925
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001926/* Set VREF on HP pin */
1927static void alc889_fixup_mbp_vref(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001928 const struct hda_fixup *fix, int action)
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001929{
1930 struct alc_spec *spec = codec->spec;
Mario Kleiner9f660a12015-12-22 00:45:43 +01001931 static hda_nid_t nids[3] = { 0x14, 0x15, 0x19 };
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001932 int i;
1933
Takashi Iwai1727a772013-01-10 09:52:52 +01001934 if (action != HDA_FIXUP_ACT_INIT)
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001935 return;
1936 for (i = 0; i < ARRAY_SIZE(nids); i++) {
1937 unsigned int val = snd_hda_codec_get_pincfg(codec, nids[i]);
1938 if (get_defcfg_device(val) != AC_JACK_HP_OUT)
1939 continue;
Takashi Iwaid3f02d62013-01-10 10:12:22 +01001940 val = snd_hda_codec_get_pin_target(codec, nids[i]);
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001941 val |= AC_PINCTL_VREF_80;
Takashi Iwaicdd03ce2012-04-20 12:34:50 +02001942 snd_hda_set_pin_ctl(codec, nids[i], val);
Takashi Iwai08c189f2012-12-19 15:22:24 +01001943 spec->gen.keep_vref_in_automute = 1;
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001944 break;
1945 }
1946}
1947
Takashi Iwai0756f092013-12-04 13:59:45 +01001948static void alc889_fixup_mac_pins(struct hda_codec *codec,
1949 const hda_nid_t *nids, int num_nids)
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001950{
1951 struct alc_spec *spec = codec->spec;
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001952 int i;
1953
Takashi Iwai0756f092013-12-04 13:59:45 +01001954 for (i = 0; i < num_nids; i++) {
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001955 unsigned int val;
Takashi Iwaid3f02d62013-01-10 10:12:22 +01001956 val = snd_hda_codec_get_pin_target(codec, nids[i]);
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001957 val |= AC_PINCTL_VREF_50;
Takashi Iwaicdd03ce2012-04-20 12:34:50 +02001958 snd_hda_set_pin_ctl(codec, nids[i], val);
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001959 }
Takashi Iwai08c189f2012-12-19 15:22:24 +01001960 spec->gen.keep_vref_in_automute = 1;
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001961}
1962
Takashi Iwai0756f092013-12-04 13:59:45 +01001963/* Set VREF on speaker pins on imac91 */
1964static void alc889_fixup_imac91_vref(struct hda_codec *codec,
1965 const struct hda_fixup *fix, int action)
1966{
1967 static hda_nid_t nids[2] = { 0x18, 0x1a };
1968
1969 if (action == HDA_FIXUP_ACT_INIT)
1970 alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
1971}
1972
Adrien Vergée7729a42014-01-24 14:56:14 -05001973/* Set VREF on speaker pins on mba11 */
1974static void alc889_fixup_mba11_vref(struct hda_codec *codec,
1975 const struct hda_fixup *fix, int action)
1976{
1977 static hda_nid_t nids[1] = { 0x18 };
1978
1979 if (action == HDA_FIXUP_ACT_INIT)
1980 alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
1981}
1982
Takashi Iwai0756f092013-12-04 13:59:45 +01001983/* Set VREF on speaker pins on mba21 */
1984static void alc889_fixup_mba21_vref(struct hda_codec *codec,
1985 const struct hda_fixup *fix, int action)
1986{
1987 static hda_nid_t nids[2] = { 0x18, 0x19 };
1988
1989 if (action == HDA_FIXUP_ACT_INIT)
1990 alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
1991}
1992
Takashi Iwaie427c232012-07-29 10:04:08 +02001993/* Don't take HP output as primary
Fernando Luis Vázquez Caod9111492013-02-12 16:49:46 +09001994 * Strangely, the speaker output doesn't work on Vaio Z and some Vaio
1995 * all-in-one desktop PCs (for example VGC-LN51JGB) through DAC 0x05
Takashi Iwaie427c232012-07-29 10:04:08 +02001996 */
1997static void alc882_fixup_no_primary_hp(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001998 const struct hda_fixup *fix, int action)
Takashi Iwaie427c232012-07-29 10:04:08 +02001999{
2000 struct alc_spec *spec = codec->spec;
Takashi Iwaida96fb52013-07-29 16:54:36 +02002001 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai08c189f2012-12-19 15:22:24 +01002002 spec->gen.no_primary_hp = 1;
Takashi Iwaida96fb52013-07-29 16:54:36 +02002003 spec->gen.no_multi_io = 1;
2004 }
Takashi Iwaie427c232012-07-29 10:04:08 +02002005}
2006
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01002007static void alc_fixup_bass_chmap(struct hda_codec *codec,
2008 const struct hda_fixup *fix, int action);
2009
Takashi Iwai7beb3a62017-04-10 18:05:52 +02002010/* For dual-codec configuration, we need to disable some features to avoid
2011 * conflicts of kctls and PCM streams
2012 */
2013static void alc_fixup_dual_codecs(struct hda_codec *codec,
2014 const struct hda_fixup *fix, int action)
2015{
2016 struct alc_spec *spec = codec->spec;
2017
2018 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2019 return;
2020 /* disable vmaster */
2021 spec->gen.suppress_vmaster = 1;
2022 /* auto-mute and auto-mic switch don't work with multiple codecs */
2023 spec->gen.suppress_auto_mute = 1;
2024 spec->gen.suppress_auto_mic = 1;
2025 /* disable aamix as well */
2026 spec->gen.mixer_nid = 0;
2027 /* add location prefix to avoid conflicts */
2028 codec->force_pin_prefix = 1;
2029}
2030
2031static void rename_ctl(struct hda_codec *codec, const char *oldname,
2032 const char *newname)
2033{
2034 struct snd_kcontrol *kctl;
2035
2036 kctl = snd_hda_find_mixer_ctl(codec, oldname);
2037 if (kctl)
2038 strcpy(kctl->id.name, newname);
2039}
2040
2041static void alc1220_fixup_gb_dual_codecs(struct hda_codec *codec,
2042 const struct hda_fixup *fix,
2043 int action)
2044{
2045 alc_fixup_dual_codecs(codec, fix, action);
2046 switch (action) {
2047 case HDA_FIXUP_ACT_PRE_PROBE:
2048 /* override card longname to provide a unique UCM profile */
2049 strcpy(codec->card->longname, "HDAudio-Gigabyte-ALC1220DualCodecs");
2050 break;
2051 case HDA_FIXUP_ACT_BUILD:
2052 /* rename Capture controls depending on the codec */
2053 rename_ctl(codec, "Capture Volume",
2054 codec->addr == 0 ?
2055 "Rear-Panel Capture Volume" :
2056 "Front-Panel Capture Volume");
2057 rename_ctl(codec, "Capture Switch",
2058 codec->addr == 0 ?
2059 "Rear-Panel Capture Switch" :
2060 "Front-Panel Capture Switch");
2061 break;
2062 }
2063}
2064
Peisen0202f5c2017-10-26 10:35:36 +08002065static void alc1220_fixup_clevo_p950(struct hda_codec *codec,
2066 const struct hda_fixup *fix,
2067 int action)
2068{
2069 hda_nid_t conn1[1] = { 0x0c };
2070
2071 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2072 return;
2073
2074 alc_update_coef_idx(codec, 0x7, 0, 0x3c3);
2075 /* We therefore want to make sure 0x14 (front headphone) and
2076 * 0x1b (speakers) use the stereo DAC 0x02
2077 */
2078 snd_hda_override_conn_list(codec, 0x14, 1, conn1);
2079 snd_hda_override_conn_list(codec, 0x1b, 1, conn1);
2080}
2081
Takashi Iwai1727a772013-01-10 09:52:52 +01002082static const struct hda_fixup alc882_fixups[] = {
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002083 [ALC882_FIXUP_ABIT_AW9D_MAX] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002084 .type = HDA_FIXUP_PINS,
2085 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002086 { 0x15, 0x01080104 }, /* side */
2087 { 0x16, 0x01011012 }, /* rear */
2088 { 0x17, 0x01016011 }, /* clfe */
2089 { }
2090 }
2091 },
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002092 [ALC882_FIXUP_LENOVO_Y530] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002093 .type = HDA_FIXUP_PINS,
2094 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002095 { 0x15, 0x99130112 }, /* rear int speakers */
2096 { 0x16, 0x99130111 }, /* subwoofer */
2097 { }
2098 }
2099 },
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002100 [ALC882_FIXUP_PB_M5210] = {
Takashi Iwaifd108212013-01-10 10:18:14 +01002101 .type = HDA_FIXUP_PINCTLS,
2102 .v.pins = (const struct hda_pintbl[]) {
2103 { 0x19, PIN_VREF50 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02002104 {}
2105 }
2106 },
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002107 [ALC882_FIXUP_ACER_ASPIRE_7736] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002108 .type = HDA_FIXUP_FUNC,
Takashi Iwai23d30f22012-05-07 17:17:32 +02002109 .v.func = alc_fixup_sku_ignore,
Takashi Iwai1d045db2011-07-07 18:23:21 +02002110 },
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002111 [ALC882_FIXUP_ASUS_W90V] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002112 .type = HDA_FIXUP_PINS,
2113 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai5cdf7452011-10-26 23:04:08 +02002114 { 0x16, 0x99130110 }, /* fix sequence for CLFE */
2115 { }
2116 }
2117 },
Marton Balint8f239212012-03-05 21:33:23 +01002118 [ALC889_FIXUP_CD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002119 .type = HDA_FIXUP_PINS,
2120 .v.pins = (const struct hda_pintbl[]) {
Marton Balint8f239212012-03-05 21:33:23 +01002121 { 0x1c, 0x993301f0 }, /* CD */
2122 { }
2123 }
2124 },
David Henningssonb2c53e22014-01-01 14:01:34 +01002125 [ALC889_FIXUP_FRONT_HP_NO_PRESENCE] = {
2126 .type = HDA_FIXUP_PINS,
2127 .v.pins = (const struct hda_pintbl[]) {
2128 { 0x1b, 0x02214120 }, /* Front HP jack is flaky, disable jack detect */
2129 { }
2130 },
2131 .chained = true,
2132 .chain_id = ALC889_FIXUP_CD,
2133 },
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002134 [ALC889_FIXUP_VAIO_TT] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002135 .type = HDA_FIXUP_PINS,
2136 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002137 { 0x17, 0x90170111 }, /* hidden surround speaker */
2138 { }
2139 }
2140 },
Takashi Iwai0e7cc2e2011-11-09 12:42:48 +01002141 [ALC888_FIXUP_EEE1601] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002142 .type = HDA_FIXUP_VERBS,
Takashi Iwai0e7cc2e2011-11-09 12:42:48 +01002143 .v.verbs = (const struct hda_verb[]) {
2144 { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b },
2145 { 0x20, AC_VERB_SET_PROC_COEF, 0x0838 },
2146 { }
2147 }
Takashi Iwai177943a32011-11-09 12:55:18 +01002148 },
2149 [ALC882_FIXUP_EAPD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002150 .type = HDA_FIXUP_VERBS,
Takashi Iwai177943a32011-11-09 12:55:18 +01002151 .v.verbs = (const struct hda_verb[]) {
2152 /* change to EAPD mode */
2153 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2154 { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
2155 { }
2156 }
2157 },
Takashi Iwai7a6069b2011-11-09 15:22:01 +01002158 [ALC883_FIXUP_EAPD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002159 .type = HDA_FIXUP_VERBS,
Takashi Iwai7a6069b2011-11-09 15:22:01 +01002160 .v.verbs = (const struct hda_verb[]) {
2161 /* change to EAPD mode */
2162 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2163 { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
2164 { }
2165 }
2166 },
Takashi Iwai8812c4f2011-11-09 17:39:15 +01002167 [ALC883_FIXUP_ACER_EAPD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002168 .type = HDA_FIXUP_VERBS,
Takashi Iwai8812c4f2011-11-09 17:39:15 +01002169 .v.verbs = (const struct hda_verb[]) {
2170 /* eanable EAPD on Acer laptops */
2171 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2172 { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
2173 { }
2174 }
2175 },
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002176 [ALC882_FIXUP_GPIO1] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02002177 .type = HDA_FIXUP_FUNC,
2178 .v.func = alc_fixup_gpio1,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002179 },
2180 [ALC882_FIXUP_GPIO2] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02002181 .type = HDA_FIXUP_FUNC,
2182 .v.func = alc_fixup_gpio2,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002183 },
Takashi Iwaieb844d52011-11-09 18:03:07 +01002184 [ALC882_FIXUP_GPIO3] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02002185 .type = HDA_FIXUP_FUNC,
2186 .v.func = alc_fixup_gpio3,
Takashi Iwaieb844d52011-11-09 18:03:07 +01002187 },
Takashi Iwai68ef0562011-11-09 18:24:44 +01002188 [ALC882_FIXUP_ASUS_W2JC] = {
Takashi Iwai5579cd62018-06-19 22:22:41 +02002189 .type = HDA_FIXUP_FUNC,
2190 .v.func = alc_fixup_gpio1,
Takashi Iwai68ef0562011-11-09 18:24:44 +01002191 .chained = true,
2192 .chain_id = ALC882_FIXUP_EAPD,
2193 },
2194 [ALC889_FIXUP_COEF] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002195 .type = HDA_FIXUP_FUNC,
Takashi Iwai68ef0562011-11-09 18:24:44 +01002196 .v.func = alc889_fixup_coef,
2197 },
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002198 [ALC882_FIXUP_ACER_ASPIRE_4930G] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002199 .type = HDA_FIXUP_PINS,
2200 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002201 { 0x16, 0x99130111 }, /* CLFE speaker */
2202 { 0x17, 0x99130112 }, /* surround speaker */
2203 { }
Takashi Iwai038d4fe2012-04-11 17:18:12 +02002204 },
2205 .chained = true,
2206 .chain_id = ALC882_FIXUP_GPIO1,
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002207 },
2208 [ALC882_FIXUP_ACER_ASPIRE_8930G] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002209 .type = HDA_FIXUP_PINS,
2210 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002211 { 0x16, 0x99130111 }, /* CLFE speaker */
2212 { 0x1b, 0x99130112 }, /* surround speaker */
2213 { }
2214 },
2215 .chained = true,
2216 .chain_id = ALC882_FIXUP_ASPIRE_8930G_VERBS,
2217 },
2218 [ALC882_FIXUP_ASPIRE_8930G_VERBS] = {
2219 /* additional init verbs for Acer Aspire 8930G */
Takashi Iwai1727a772013-01-10 09:52:52 +01002220 .type = HDA_FIXUP_VERBS,
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002221 .v.verbs = (const struct hda_verb[]) {
2222 /* Enable all DACs */
2223 /* DAC DISABLE/MUTE 1? */
2224 /* setting bits 1-5 disables DAC nids 0x02-0x06
2225 * apparently. Init=0x38 */
2226 { 0x20, AC_VERB_SET_COEF_INDEX, 0x03 },
2227 { 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
2228 /* DAC DISABLE/MUTE 2? */
2229 /* some bit here disables the other DACs.
2230 * Init=0x4900 */
2231 { 0x20, AC_VERB_SET_COEF_INDEX, 0x08 },
2232 { 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
2233 /* DMIC fix
2234 * This laptop has a stereo digital microphone.
2235 * The mics are only 1cm apart which makes the stereo
2236 * useless. However, either the mic or the ALC889
2237 * makes the signal become a difference/sum signal
2238 * instead of standard stereo, which is annoying.
2239 * So instead we flip this bit which makes the
2240 * codec replicate the sum signal to both channels,
2241 * turning it into a normal mono mic.
2242 */
2243 /* DMIC_CONTROL? Init value = 0x0001 */
2244 { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b },
2245 { 0x20, AC_VERB_SET_PROC_COEF, 0x0003 },
2246 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2247 { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
2248 { }
Takashi Iwai038d4fe2012-04-11 17:18:12 +02002249 },
2250 .chained = true,
2251 .chain_id = ALC882_FIXUP_GPIO1,
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002252 },
Takashi Iwai56710872011-11-14 17:42:11 +01002253 [ALC885_FIXUP_MACPRO_GPIO] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002254 .type = HDA_FIXUP_FUNC,
Takashi Iwai56710872011-11-14 17:42:11 +01002255 .v.func = alc885_fixup_macpro_gpio,
2256 },
Takashi Iwai02a237b2012-02-13 15:25:07 +01002257 [ALC889_FIXUP_DAC_ROUTE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002258 .type = HDA_FIXUP_FUNC,
Takashi Iwai02a237b2012-02-13 15:25:07 +01002259 .v.func = alc889_fixup_dac_route,
2260 },
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002261 [ALC889_FIXUP_MBP_VREF] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002262 .type = HDA_FIXUP_FUNC,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002263 .v.func = alc889_fixup_mbp_vref,
2264 .chained = true,
2265 .chain_id = ALC882_FIXUP_GPIO1,
2266 },
2267 [ALC889_FIXUP_IMAC91_VREF] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002268 .type = HDA_FIXUP_FUNC,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002269 .v.func = alc889_fixup_imac91_vref,
2270 .chained = true,
2271 .chain_id = ALC882_FIXUP_GPIO1,
2272 },
Adrien Vergée7729a42014-01-24 14:56:14 -05002273 [ALC889_FIXUP_MBA11_VREF] = {
2274 .type = HDA_FIXUP_FUNC,
2275 .v.func = alc889_fixup_mba11_vref,
2276 .chained = true,
2277 .chain_id = ALC889_FIXUP_MBP_VREF,
2278 },
Takashi Iwai0756f092013-12-04 13:59:45 +01002279 [ALC889_FIXUP_MBA21_VREF] = {
2280 .type = HDA_FIXUP_FUNC,
2281 .v.func = alc889_fixup_mba21_vref,
2282 .chained = true,
2283 .chain_id = ALC889_FIXUP_MBP_VREF,
2284 },
Takashi Iwaic20f31e2014-02-03 11:02:10 +01002285 [ALC889_FIXUP_MP11_VREF] = {
2286 .type = HDA_FIXUP_FUNC,
2287 .v.func = alc889_fixup_mba11_vref,
2288 .chained = true,
2289 .chain_id = ALC885_FIXUP_MACPRO_GPIO,
2290 },
Mario Kleiner9f660a12015-12-22 00:45:43 +01002291 [ALC889_FIXUP_MP41_VREF] = {
2292 .type = HDA_FIXUP_FUNC,
2293 .v.func = alc889_fixup_mbp_vref,
2294 .chained = true,
2295 .chain_id = ALC885_FIXUP_MACPRO_GPIO,
2296 },
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002297 [ALC882_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002298 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02002299 .v.func = alc_fixup_inv_dmic,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002300 },
Takashi Iwaie427c232012-07-29 10:04:08 +02002301 [ALC882_FIXUP_NO_PRIMARY_HP] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002302 .type = HDA_FIXUP_FUNC,
Takashi Iwaie427c232012-07-29 10:04:08 +02002303 .v.func = alc882_fixup_no_primary_hp,
2304 },
Takashi Iwai1f0bbf02013-11-28 15:21:21 +01002305 [ALC887_FIXUP_ASUS_BASS] = {
2306 .type = HDA_FIXUP_PINS,
2307 .v.pins = (const struct hda_pintbl[]) {
2308 {0x16, 0x99130130}, /* bass speaker */
2309 {}
2310 },
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01002311 .chained = true,
2312 .chain_id = ALC887_FIXUP_BASS_CHMAP,
2313 },
2314 [ALC887_FIXUP_BASS_CHMAP] = {
2315 .type = HDA_FIXUP_FUNC,
2316 .v.func = alc_fixup_bass_chmap,
Takashi Iwai1f0bbf02013-11-28 15:21:21 +01002317 },
Takashi Iwai7beb3a62017-04-10 18:05:52 +02002318 [ALC1220_FIXUP_GB_DUAL_CODECS] = {
2319 .type = HDA_FIXUP_FUNC,
2320 .v.func = alc1220_fixup_gb_dual_codecs,
2321 },
Peisen0202f5c2017-10-26 10:35:36 +08002322 [ALC1220_FIXUP_CLEVO_P950] = {
2323 .type = HDA_FIXUP_FUNC,
2324 .v.func = alc1220_fixup_clevo_p950,
2325 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02002326};
2327
2328static const struct snd_pci_quirk alc882_fixup_tbl[] = {
Takashi Iwai8812c4f2011-11-09 17:39:15 +01002329 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_FIXUP_ACER_EAPD),
2330 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
Takashi Iwaib5d724b2015-06-02 19:57:08 +02002331 SND_PCI_QUIRK(0x1025, 0x0107, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
Takashi Iwai8812c4f2011-11-09 17:39:15 +01002332 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_FIXUP_ACER_EAPD),
2333 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
2334 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_FIXUP_ACER_EAPD),
2335 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_FIXUP_ACER_EAPD),
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002336 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
2337 ALC882_FIXUP_ACER_ASPIRE_4930G),
2338 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
2339 ALC882_FIXUP_ACER_ASPIRE_4930G),
2340 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
2341 ALC882_FIXUP_ACER_ASPIRE_8930G),
2342 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
2343 ALC882_FIXUP_ACER_ASPIRE_8930G),
2344 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
2345 ALC882_FIXUP_ACER_ASPIRE_4930G),
2346 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
2347 ALC882_FIXUP_ACER_ASPIRE_4930G),
2348 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
2349 ALC882_FIXUP_ACER_ASPIRE_4930G),
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002350 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", ALC882_FIXUP_PB_M5210),
Takashi Iwaif5c53d82012-05-07 10:07:33 +02002351 SND_PCI_QUIRK(0x1025, 0x021e, "Acer Aspire 5739G",
2352 ALC882_FIXUP_ACER_ASPIRE_4930G),
Takashi Iwai02a237b2012-02-13 15:25:07 +01002353 SND_PCI_QUIRK(0x1025, 0x0259, "Acer Aspire 5935", ALC889_FIXUP_DAC_ROUTE),
Takashi Iwaife97da12012-04-12 08:00:19 +02002354 SND_PCI_QUIRK(0x1025, 0x026b, "Acer Aspire 8940G", ALC882_FIXUP_ACER_ASPIRE_8930G),
Takashi Iwaiac9b1cd2011-11-09 17:45:55 +01002355 SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", ALC882_FIXUP_ACER_ASPIRE_7736),
Takashi Iwai177943a32011-11-09 12:55:18 +01002356 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_FIXUP_EAPD),
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002357 SND_PCI_QUIRK(0x1043, 0x1873, "ASUS W90V", ALC882_FIXUP_ASUS_W90V),
Takashi Iwai68ef0562011-11-09 18:24:44 +01002358 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_FIXUP_ASUS_W2JC),
Takashi Iwai0e7cc2e2011-11-09 12:42:48 +01002359 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_FIXUP_EEE1601),
Takashi Iwai1f0bbf02013-11-28 15:21:21 +01002360 SND_PCI_QUIRK(0x1043, 0x84bc, "ASUS ET2700", ALC887_FIXUP_ASUS_BASS),
Takashi Iwai85bcf962016-12-06 16:20:36 +01002361 SND_PCI_QUIRK(0x1043, 0x8691, "ASUS ROG Ranger VIII", ALC882_FIXUP_GPIO3),
Takashi Iwaiac9b1cd2011-11-09 17:45:55 +01002362 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT),
Takashi Iwaie427c232012-07-29 10:04:08 +02002363 SND_PCI_QUIRK(0x104d, 0x905a, "Sony Vaio Z", ALC882_FIXUP_NO_PRIMARY_HP),
Sergei A. Trusov3f3c3712017-08-02 20:23:48 +10002364 SND_PCI_QUIRK(0x104d, 0x9060, "Sony Vaio VPCL14M1R", ALC882_FIXUP_NO_PRIMARY_HP),
Fernando Luis Vázquez Cao12e31a72013-02-12 16:47:44 +09002365 SND_PCI_QUIRK(0x104d, 0x9043, "Sony Vaio VGC-LN51JGB", ALC882_FIXUP_NO_PRIMARY_HP),
Takashi Iwaic44d9b12016-02-07 09:38:26 +01002366 SND_PCI_QUIRK(0x104d, 0x9044, "Sony VAIO AiO", ALC882_FIXUP_NO_PRIMARY_HP),
Takashi Iwai56710872011-11-14 17:42:11 +01002367
2368 /* All Apple entries are in codec SSIDs */
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002369 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC889_FIXUP_MBP_VREF),
2370 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC889_FIXUP_MBP_VREF),
2371 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF),
Takashi Iwaic20f31e2014-02-03 11:02:10 +01002372 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC889_FIXUP_MP11_VREF),
Takashi Iwai56710872011-11-14 17:42:11 +01002373 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_FIXUP_MACPRO_GPIO),
2374 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_FIXUP_MACPRO_GPIO),
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002375 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC889_FIXUP_MBP_VREF),
2376 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889_FIXUP_MBP_VREF),
Takashi Iwai56710872011-11-14 17:42:11 +01002377 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_FIXUP_EAPD),
Adrien Vergée7729a42014-01-24 14:56:14 -05002378 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC889_FIXUP_MBA11_VREF),
Takashi Iwai0756f092013-12-04 13:59:45 +01002379 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC889_FIXUP_MBA21_VREF),
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002380 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889_FIXUP_MBP_VREF),
2381 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF),
Takashi Iwai56710872011-11-14 17:42:11 +01002382 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_FIXUP_MACPRO_GPIO),
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002383 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC889_FIXUP_IMAC91_VREF),
2384 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC889_FIXUP_IMAC91_VREF),
2385 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC889_FIXUP_IMAC91_VREF),
Mario Kleiner9f660a12015-12-22 00:45:43 +01002386 SND_PCI_QUIRK(0x106b, 0x4200, "Mac Pro 4,1/5,1", ALC889_FIXUP_MP41_VREF),
Takashi Iwai05193632012-11-12 10:07:36 +01002387 SND_PCI_QUIRK(0x106b, 0x4300, "iMac 9,1", ALC889_FIXUP_IMAC91_VREF),
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002388 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC889_FIXUP_IMAC91_VREF),
2389 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC889_FIXUP_IMAC91_VREF),
Takashi Iwai649ccd02015-07-30 22:30:29 +02002390 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC889_FIXUP_MBA11_VREF),
Takashi Iwai56710872011-11-14 17:42:11 +01002391
Takashi Iwai7a6069b2011-11-09 15:22:01 +01002392 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC882_FIXUP_EAPD),
David Henningssonb2c53e22014-01-01 14:01:34 +01002393 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3/Z87X-UD3H", ALC889_FIXUP_FRONT_HP_NO_PRESENCE),
Takashi Iwai7beb3a62017-04-10 18:05:52 +02002394 SND_PCI_QUIRK(0x1458, 0xa0b8, "Gigabyte AZ370-Gaming", ALC1220_FIXUP_GB_DUAL_CODECS),
Takashi Iwaid2c3b142017-06-01 09:35:30 +02002395 SND_PCI_QUIRK(0x1462, 0x7350, "MSI-7350", ALC889_FIXUP_CD),
Takashi Iwai63691582017-05-22 16:32:46 +02002396 SND_PCI_QUIRK(0x1462, 0xda57, "MSI Z270-Gaming", ALC1220_FIXUP_GB_DUAL_CODECS),
Takashi Iwaid2c3b142017-06-01 09:35:30 +02002397 SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3),
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002398 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX),
Peisen0202f5c2017-10-26 10:35:36 +08002399 SND_PCI_QUIRK(0x1558, 0x9501, "Clevo P950HR", ALC1220_FIXUP_CLEVO_P950),
Jeremy Soller2f0d5202018-05-07 09:28:45 -06002400 SND_PCI_QUIRK(0x1558, 0x95e2, "Clevo P950ER", ALC1220_FIXUP_CLEVO_P950),
Takashi Iwai7a6069b2011-11-09 15:22:01 +01002401 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD),
2402 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD),
Takashi Iwaiac9b1cd2011-11-09 17:45:55 +01002403 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", ALC882_FIXUP_LENOVO_Y530),
Takashi Iwai68ef0562011-11-09 18:24:44 +01002404 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_FIXUP_COEF),
Takashi Iwai1d045db2011-07-07 18:23:21 +02002405 {}
2406};
2407
Takashi Iwai1727a772013-01-10 09:52:52 +01002408static const struct hda_model_fixup alc882_fixup_models[] = {
Takashi Iwai912093b2012-04-11 14:03:41 +02002409 {.id = ALC882_FIXUP_ACER_ASPIRE_4930G, .name = "acer-aspire-4930g"},
2410 {.id = ALC882_FIXUP_ACER_ASPIRE_8930G, .name = "acer-aspire-8930g"},
2411 {.id = ALC883_FIXUP_ACER_EAPD, .name = "acer-aspire"},
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002412 {.id = ALC882_FIXUP_INV_DMIC, .name = "inv-dmic"},
Takashi Iwaie427c232012-07-29 10:04:08 +02002413 {.id = ALC882_FIXUP_NO_PRIMARY_HP, .name = "no-primary-hp"},
Takashi Iwaiba90d6a2017-05-22 16:38:47 +02002414 {.id = ALC1220_FIXUP_GB_DUAL_CODECS, .name = "dual-codecs"},
Takashi Iwai912093b2012-04-11 14:03:41 +02002415 {}
2416};
2417
Takashi Iwai1d045db2011-07-07 18:23:21 +02002418/*
2419 * BIOS auto configuration
2420 */
2421/* almost identical with ALC880 parser... */
2422static int alc882_parse_auto_config(struct hda_codec *codec)
2423{
Takashi Iwai1d045db2011-07-07 18:23:21 +02002424 static const hda_nid_t alc882_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002425 static const hda_nid_t alc882_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2426 return alc_parse_auto_config(codec, alc882_ignore, alc882_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002427}
2428
Takashi Iwai1d045db2011-07-07 18:23:21 +02002429/*
2430 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002431static int patch_alc882(struct hda_codec *codec)
2432{
2433 struct alc_spec *spec;
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002434 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002435
Takashi Iwai3de95172012-05-07 18:03:15 +02002436 err = alc_alloc_spec(codec, 0x0b);
2437 if (err < 0)
2438 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002439
Takashi Iwai3de95172012-05-07 18:03:15 +02002440 spec = codec->spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002441
Takashi Iwai7639a062015-03-03 10:07:24 +01002442 switch (codec->core.vendor_id) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002443 case 0x10ec0882:
2444 case 0x10ec0885:
Takashi Iwaiacf08082014-09-02 07:21:56 +02002445 case 0x10ec0900:
Kailang Yanga535ad52017-01-16 16:59:26 +08002446 case 0x10ec1220:
Takashi Iwai1d045db2011-07-07 18:23:21 +02002447 break;
2448 default:
2449 /* ALC883 and variants */
2450 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
2451 break;
2452 }
2453
Takashi Iwai1727a772013-01-10 09:52:52 +01002454 snd_hda_pick_fixup(codec, alc882_fixup_models, alc882_fixup_tbl,
Takashi Iwai912093b2012-04-11 14:03:41 +02002455 alc882_fixups);
Takashi Iwai1727a772013-01-10 09:52:52 +01002456 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002457
2458 alc_auto_parse_customize_define(codec);
2459
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002460 if (has_cdefine_beep(codec))
2461 spec->gen.beep_nid = 0x01;
2462
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002463 /* automatic parse from the BIOS config */
2464 err = alc882_parse_auto_config(codec);
2465 if (err < 0)
2466 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002467
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002468 if (!spec->gen.no_analog && spec->gen.beep_nid)
Takashi Iwai1d045db2011-07-07 18:23:21 +02002469 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
2470
Takashi Iwai1727a772013-01-10 09:52:52 +01002471 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01002472
Takashi Iwai1d045db2011-07-07 18:23:21 +02002473 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02002474
2475 error:
2476 alc_free(codec);
2477 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002478}
2479
2480
2481/*
2482 * ALC262 support
2483 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002484static int alc262_parse_auto_config(struct hda_codec *codec)
2485{
Takashi Iwai1d045db2011-07-07 18:23:21 +02002486 static const hda_nid_t alc262_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002487 static const hda_nid_t alc262_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2488 return alc_parse_auto_config(codec, alc262_ignore, alc262_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002489}
2490
2491/*
2492 * Pin config fixes
2493 */
2494enum {
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002495 ALC262_FIXUP_FSC_H270,
Takashi Iwai7513e6d2013-01-18 15:41:34 +01002496 ALC262_FIXUP_FSC_S7110,
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002497 ALC262_FIXUP_HP_Z200,
2498 ALC262_FIXUP_TYAN,
Takashi Iwaic4701502011-11-07 14:20:07 +01002499 ALC262_FIXUP_LENOVO_3000,
Takashi Iwaib42590b2011-11-07 14:41:01 +01002500 ALC262_FIXUP_BENQ,
2501 ALC262_FIXUP_BENQ_T31,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002502 ALC262_FIXUP_INV_DMIC,
Mengdong Linb5c66112013-11-29 00:35:35 -05002503 ALC262_FIXUP_INTEL_BAYLEYBAY,
Takashi Iwai1d045db2011-07-07 18:23:21 +02002504};
2505
Takashi Iwai1727a772013-01-10 09:52:52 +01002506static const struct hda_fixup alc262_fixups[] = {
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002507 [ALC262_FIXUP_FSC_H270] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002508 .type = HDA_FIXUP_PINS,
2509 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002510 { 0x14, 0x99130110 }, /* speaker */
2511 { 0x15, 0x0221142f }, /* front HP */
2512 { 0x1b, 0x0121141f }, /* rear HP */
2513 { }
2514 }
2515 },
Takashi Iwai7513e6d2013-01-18 15:41:34 +01002516 [ALC262_FIXUP_FSC_S7110] = {
2517 .type = HDA_FIXUP_PINS,
2518 .v.pins = (const struct hda_pintbl[]) {
2519 { 0x15, 0x90170110 }, /* speaker */
2520 { }
2521 },
2522 .chained = true,
2523 .chain_id = ALC262_FIXUP_BENQ,
2524 },
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002525 [ALC262_FIXUP_HP_Z200] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002526 .type = HDA_FIXUP_PINS,
2527 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002528 { 0x16, 0x99130120 }, /* internal speaker */
2529 { }
2530 }
2531 },
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002532 [ALC262_FIXUP_TYAN] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002533 .type = HDA_FIXUP_PINS,
2534 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002535 { 0x14, 0x1993e1f0 }, /* int AUX */
2536 { }
2537 }
2538 },
Takashi Iwaic4701502011-11-07 14:20:07 +01002539 [ALC262_FIXUP_LENOVO_3000] = {
Takashi Iwaifd108212013-01-10 10:18:14 +01002540 .type = HDA_FIXUP_PINCTLS,
2541 .v.pins = (const struct hda_pintbl[]) {
2542 { 0x19, PIN_VREF50 },
Takashi Iwaib42590b2011-11-07 14:41:01 +01002543 {}
2544 },
2545 .chained = true,
2546 .chain_id = ALC262_FIXUP_BENQ,
2547 },
2548 [ALC262_FIXUP_BENQ] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002549 .type = HDA_FIXUP_VERBS,
Takashi Iwaib42590b2011-11-07 14:41:01 +01002550 .v.verbs = (const struct hda_verb[]) {
Takashi Iwaic4701502011-11-07 14:20:07 +01002551 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2552 { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
2553 {}
2554 }
2555 },
Takashi Iwaib42590b2011-11-07 14:41:01 +01002556 [ALC262_FIXUP_BENQ_T31] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002557 .type = HDA_FIXUP_VERBS,
Takashi Iwaib42590b2011-11-07 14:41:01 +01002558 .v.verbs = (const struct hda_verb[]) {
2559 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2560 { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
2561 {}
2562 }
2563 },
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002564 [ALC262_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002565 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02002566 .v.func = alc_fixup_inv_dmic,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002567 },
Mengdong Linb5c66112013-11-29 00:35:35 -05002568 [ALC262_FIXUP_INTEL_BAYLEYBAY] = {
2569 .type = HDA_FIXUP_FUNC,
2570 .v.func = alc_fixup_no_depop_delay,
2571 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02002572};
2573
2574static const struct snd_pci_quirk alc262_fixup_tbl[] = {
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002575 SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", ALC262_FIXUP_HP_Z200),
Takashi Iwai7513e6d2013-01-18 15:41:34 +01002576 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu Lifebook S7110", ALC262_FIXUP_FSC_S7110),
Takashi Iwai3dcd3be2011-11-07 14:59:40 +01002577 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FIXUP_BENQ),
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002578 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_FIXUP_TYAN),
2579 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", ALC262_FIXUP_FSC_H270),
Takashi Iwaic4701502011-11-07 14:20:07 +01002580 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000", ALC262_FIXUP_LENOVO_3000),
Takashi Iwaib42590b2011-11-07 14:41:01 +01002581 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_FIXUP_BENQ),
2582 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_FIXUP_BENQ_T31),
Mengdong Linb5c66112013-11-29 00:35:35 -05002583 SND_PCI_QUIRK(0x8086, 0x7270, "BayleyBay", ALC262_FIXUP_INTEL_BAYLEYBAY),
Takashi Iwai1d045db2011-07-07 18:23:21 +02002584 {}
2585};
2586
Takashi Iwai1727a772013-01-10 09:52:52 +01002587static const struct hda_model_fixup alc262_fixup_models[] = {
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002588 {.id = ALC262_FIXUP_INV_DMIC, .name = "inv-dmic"},
2589 {}
2590};
Takashi Iwai1d045db2011-07-07 18:23:21 +02002591
Takashi Iwai1d045db2011-07-07 18:23:21 +02002592/*
2593 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002594static int patch_alc262(struct hda_codec *codec)
2595{
2596 struct alc_spec *spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002597 int err;
2598
Takashi Iwai3de95172012-05-07 18:03:15 +02002599 err = alc_alloc_spec(codec, 0x0b);
2600 if (err < 0)
2601 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002602
Takashi Iwai3de95172012-05-07 18:03:15 +02002603 spec = codec->spec;
Takashi Iwai08c189f2012-12-19 15:22:24 +01002604 spec->gen.shared_mic_vref_pin = 0x18;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002605
Takashi Iwai225068a2015-05-29 10:42:14 +02002606 spec->shutup = alc_eapd_shutup;
2607
Takashi Iwai1d045db2011-07-07 18:23:21 +02002608#if 0
2609 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
2610 * under-run
2611 */
Takashi Iwai98b24882014-08-18 13:47:50 +02002612 alc_update_coefex_idx(codec, 0x1a, 7, 0, 0x80);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002613#endif
Takashi Iwai1d045db2011-07-07 18:23:21 +02002614 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
2615
Takashi Iwai1727a772013-01-10 09:52:52 +01002616 snd_hda_pick_fixup(codec, alc262_fixup_models, alc262_fixup_tbl,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002617 alc262_fixups);
Takashi Iwai1727a772013-01-10 09:52:52 +01002618 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002619
Takashi Iwaiaf741c12012-05-07 18:09:48 +02002620 alc_auto_parse_customize_define(codec);
2621
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002622 if (has_cdefine_beep(codec))
2623 spec->gen.beep_nid = 0x01;
2624
Takashi Iwai42399f72011-11-07 17:18:44 +01002625 /* automatic parse from the BIOS config */
2626 err = alc262_parse_auto_config(codec);
2627 if (err < 0)
2628 goto error;
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002629
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002630 if (!spec->gen.no_analog && spec->gen.beep_nid)
Takashi Iwai1d045db2011-07-07 18:23:21 +02002631 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
2632
Takashi Iwai1727a772013-01-10 09:52:52 +01002633 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01002634
Takashi Iwai1d045db2011-07-07 18:23:21 +02002635 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02002636
2637 error:
2638 alc_free(codec);
2639 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002640}
2641
2642/*
2643 * ALC268
2644 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002645/* bind Beep switches of both NID 0x0f and 0x10 */
Takashi Iwaia7177772017-05-10 12:04:08 +02002646static int alc268_beep_switch_put(struct snd_kcontrol *kcontrol,
2647 struct snd_ctl_elem_value *ucontrol)
2648{
2649 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2650 unsigned long pval;
2651 int err;
2652
2653 mutex_lock(&codec->control_mutex);
2654 pval = kcontrol->private_value;
2655 kcontrol->private_value = (pval & ~0xff) | 0x0f;
2656 err = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
2657 if (err >= 0) {
2658 kcontrol->private_value = (pval & ~0xff) | 0x10;
2659 err = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
2660 }
2661 kcontrol->private_value = pval;
2662 mutex_unlock(&codec->control_mutex);
2663 return err;
2664}
Takashi Iwai1d045db2011-07-07 18:23:21 +02002665
2666static const struct snd_kcontrol_new alc268_beep_mixer[] = {
2667 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
Takashi Iwaia7177772017-05-10 12:04:08 +02002668 {
2669 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2670 .name = "Beep Playback Switch",
2671 .subdevice = HDA_SUBDEV_AMP_FLAG,
2672 .info = snd_hda_mixer_amp_switch_info,
2673 .get = snd_hda_mixer_amp_switch_get,
2674 .put = alc268_beep_switch_put,
2675 .private_value = HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT)
2676 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02002677 { }
2678};
2679
2680/* set PCBEEP vol = 0, mute connections */
2681static const struct hda_verb alc268_beep_init_verbs[] = {
2682 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2683 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2684 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2685 { }
2686};
2687
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002688enum {
2689 ALC268_FIXUP_INV_DMIC,
Takashi Iwaicb766402012-10-20 10:55:21 +02002690 ALC268_FIXUP_HP_EAPD,
Takashi Iwai24eff322013-11-04 18:21:08 +01002691 ALC268_FIXUP_SPDIF,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002692};
2693
Takashi Iwai1727a772013-01-10 09:52:52 +01002694static const struct hda_fixup alc268_fixups[] = {
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002695 [ALC268_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002696 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02002697 .v.func = alc_fixup_inv_dmic,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002698 },
Takashi Iwaicb766402012-10-20 10:55:21 +02002699 [ALC268_FIXUP_HP_EAPD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002700 .type = HDA_FIXUP_VERBS,
Takashi Iwaicb766402012-10-20 10:55:21 +02002701 .v.verbs = (const struct hda_verb[]) {
2702 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 0},
2703 {}
2704 }
2705 },
Takashi Iwai24eff322013-11-04 18:21:08 +01002706 [ALC268_FIXUP_SPDIF] = {
2707 .type = HDA_FIXUP_PINS,
2708 .v.pins = (const struct hda_pintbl[]) {
2709 { 0x1e, 0x014b1180 }, /* enable SPDIF out */
2710 {}
2711 }
2712 },
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002713};
2714
Takashi Iwai1727a772013-01-10 09:52:52 +01002715static const struct hda_model_fixup alc268_fixup_models[] = {
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002716 {.id = ALC268_FIXUP_INV_DMIC, .name = "inv-dmic"},
Takashi Iwaicb766402012-10-20 10:55:21 +02002717 {.id = ALC268_FIXUP_HP_EAPD, .name = "hp-eapd"},
2718 {}
2719};
2720
2721static const struct snd_pci_quirk alc268_fixup_tbl[] = {
Takashi Iwai24eff322013-11-04 18:21:08 +01002722 SND_PCI_QUIRK(0x1025, 0x0139, "Acer TravelMate 6293", ALC268_FIXUP_SPDIF),
David Henningssonfcd8f3b2013-01-28 05:45:47 +01002723 SND_PCI_QUIRK(0x1025, 0x015b, "Acer AOA 150 (ZG5)", ALC268_FIXUP_INV_DMIC),
Takashi Iwaicb766402012-10-20 10:55:21 +02002724 /* below is codec SSID since multiple Toshiba laptops have the
2725 * same PCI SSID 1179:ff00
2726 */
2727 SND_PCI_QUIRK(0x1179, 0xff06, "Toshiba P200", ALC268_FIXUP_HP_EAPD),
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002728 {}
2729};
2730
Takashi Iwai1d045db2011-07-07 18:23:21 +02002731/*
2732 * BIOS auto configuration
2733 */
2734static int alc268_parse_auto_config(struct hda_codec *codec)
2735{
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002736 static const hda_nid_t alc268_ssids[] = { 0x15, 0x1b, 0x14, 0 };
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002737 return alc_parse_auto_config(codec, NULL, alc268_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002738}
2739
Takashi Iwai1d045db2011-07-07 18:23:21 +02002740/*
2741 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002742static int patch_alc268(struct hda_codec *codec)
2743{
2744 struct alc_spec *spec;
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002745 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002746
Takashi Iwai1d045db2011-07-07 18:23:21 +02002747 /* ALC268 has no aa-loopback mixer */
Takashi Iwai3de95172012-05-07 18:03:15 +02002748 err = alc_alloc_spec(codec, 0);
2749 if (err < 0)
2750 return err;
2751
2752 spec = codec->spec;
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002753 spec->gen.beep_nid = 0x01;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002754
Takashi Iwai225068a2015-05-29 10:42:14 +02002755 spec->shutup = alc_eapd_shutup;
2756
Takashi Iwai1727a772013-01-10 09:52:52 +01002757 snd_hda_pick_fixup(codec, alc268_fixup_models, alc268_fixup_tbl, alc268_fixups);
2758 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002759
Takashi Iwai6ebb8052011-08-16 15:15:40 +02002760 /* automatic parse from the BIOS config */
2761 err = alc268_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02002762 if (err < 0)
2763 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002764
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002765 if (err > 0 && !spec->gen.no_analog &&
2766 spec->gen.autocfg.speaker_pins[0] != 0x1d) {
2767 add_mixer(spec, alc268_beep_mixer);
2768 snd_hda_add_verbs(codec, alc268_beep_init_verbs);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002769 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
2770 /* override the amp caps for beep generator */
2771 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
2772 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
2773 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
2774 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
2775 (0 << AC_AMPCAP_MUTE_SHIFT));
2776 }
2777
Takashi Iwai1727a772013-01-10 09:52:52 +01002778 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002779
Takashi Iwai1d045db2011-07-07 18:23:21 +02002780 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02002781
2782 error:
2783 alc_free(codec);
2784 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002785}
2786
2787/*
2788 * ALC269
2789 */
Takashi Iwai08c189f2012-12-19 15:22:24 +01002790
Takashi Iwai1d045db2011-07-07 18:23:21 +02002791static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002792 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002793};
2794
2795static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002796 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002797};
2798
Takashi Iwai1d045db2011-07-07 18:23:21 +02002799/* different alc269-variants */
2800enum {
2801 ALC269_TYPE_ALC269VA,
2802 ALC269_TYPE_ALC269VB,
2803 ALC269_TYPE_ALC269VC,
Kailang Yangadcc70b2012-05-25 08:08:38 +02002804 ALC269_TYPE_ALC269VD,
Kailang Yang065380f2013-01-10 10:25:48 +01002805 ALC269_TYPE_ALC280,
2806 ALC269_TYPE_ALC282,
Kailang Yang2af02be2013-08-22 10:03:50 +02002807 ALC269_TYPE_ALC283,
Kailang Yang065380f2013-01-10 10:25:48 +01002808 ALC269_TYPE_ALC284,
Kailang Yang4731d5d2017-06-30 15:22:57 +08002809 ALC269_TYPE_ALC293,
Kailang Yang7fc7d042013-04-25 11:04:43 +02002810 ALC269_TYPE_ALC286,
Kailang Yang506b62c2014-12-18 17:07:44 +08002811 ALC269_TYPE_ALC298,
Kailang Yang1d04c9d2013-10-24 11:35:18 +02002812 ALC269_TYPE_ALC255,
Kailang Yang4344aec2014-12-17 17:39:05 +08002813 ALC269_TYPE_ALC256,
Kailang Yangf429e7e2017-12-05 15:38:24 +08002814 ALC269_TYPE_ALC257,
Kailang Yang0a6f0602017-06-30 16:00:48 +08002815 ALC269_TYPE_ALC215,
Kailang Yang42314302016-02-03 15:03:50 +08002816 ALC269_TYPE_ALC225,
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08002817 ALC269_TYPE_ALC294,
Kailang Yang6fbae352016-05-30 16:44:20 +08002818 ALC269_TYPE_ALC700,
Takashi Iwai1d045db2011-07-07 18:23:21 +02002819};
2820
2821/*
2822 * BIOS auto configuration
2823 */
2824static int alc269_parse_auto_config(struct hda_codec *codec)
2825{
Takashi Iwai1d045db2011-07-07 18:23:21 +02002826 static const hda_nid_t alc269_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002827 static const hda_nid_t alc269_ssids[] = { 0, 0x1b, 0x14, 0x21 };
2828 static const hda_nid_t alc269va_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2829 struct alc_spec *spec = codec->spec;
Kailang Yangadcc70b2012-05-25 08:08:38 +02002830 const hda_nid_t *ssids;
2831
2832 switch (spec->codec_variant) {
2833 case ALC269_TYPE_ALC269VA:
2834 case ALC269_TYPE_ALC269VC:
Kailang Yang065380f2013-01-10 10:25:48 +01002835 case ALC269_TYPE_ALC280:
2836 case ALC269_TYPE_ALC284:
Kailang Yang4731d5d2017-06-30 15:22:57 +08002837 case ALC269_TYPE_ALC293:
Kailang Yangadcc70b2012-05-25 08:08:38 +02002838 ssids = alc269va_ssids;
2839 break;
2840 case ALC269_TYPE_ALC269VB:
2841 case ALC269_TYPE_ALC269VD:
Kailang Yang065380f2013-01-10 10:25:48 +01002842 case ALC269_TYPE_ALC282:
Kailang Yang2af02be2013-08-22 10:03:50 +02002843 case ALC269_TYPE_ALC283:
Kailang Yang7fc7d042013-04-25 11:04:43 +02002844 case ALC269_TYPE_ALC286:
Kailang Yang506b62c2014-12-18 17:07:44 +08002845 case ALC269_TYPE_ALC298:
Kailang Yang1d04c9d2013-10-24 11:35:18 +02002846 case ALC269_TYPE_ALC255:
Kailang Yang4344aec2014-12-17 17:39:05 +08002847 case ALC269_TYPE_ALC256:
Kailang Yangf429e7e2017-12-05 15:38:24 +08002848 case ALC269_TYPE_ALC257:
Kailang Yang0a6f0602017-06-30 16:00:48 +08002849 case ALC269_TYPE_ALC215:
Kailang Yang42314302016-02-03 15:03:50 +08002850 case ALC269_TYPE_ALC225:
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08002851 case ALC269_TYPE_ALC294:
Kailang Yang6fbae352016-05-30 16:44:20 +08002852 case ALC269_TYPE_ALC700:
Kailang Yangadcc70b2012-05-25 08:08:38 +02002853 ssids = alc269_ssids;
2854 break;
2855 default:
2856 ssids = alc269_ssids;
2857 break;
2858 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02002859
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002860 return alc_parse_auto_config(codec, alc269_ignore, ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002861}
2862
Kailang Yangf7ae9ba2014-06-30 16:10:37 +08002863static int find_ext_mic_pin(struct hda_codec *codec);
2864
2865static void alc286_shutup(struct hda_codec *codec)
2866{
Takashi Iwaia9c2dfc2018-04-23 17:24:56 +02002867 const struct hda_pincfg *pin;
Kailang Yangf7ae9ba2014-06-30 16:10:37 +08002868 int i;
2869 int mic_pin = find_ext_mic_pin(codec);
2870 /* don't shut up pins when unloading the driver; otherwise it breaks
2871 * the default pin setup at the next load of the driver
2872 */
2873 if (codec->bus->shutdown)
2874 return;
Takashi Iwaia9c2dfc2018-04-23 17:24:56 +02002875 snd_array_for_each(&codec->init_pins, i, pin) {
Kailang Yangf7ae9ba2014-06-30 16:10:37 +08002876 /* use read here for syncing after issuing each verb */
2877 if (pin->nid != mic_pin)
2878 snd_hda_codec_read(codec, pin->nid, 0,
2879 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
2880 }
2881 codec->pins_shutup = 1;
2882}
2883
Kailang Yang1387e2d2012-11-08 10:23:18 +01002884static void alc269vb_toggle_power_output(struct hda_codec *codec, int power_up)
Takashi Iwai1d045db2011-07-07 18:23:21 +02002885{
Takashi Iwai98b24882014-08-18 13:47:50 +02002886 alc_update_coef_idx(codec, 0x04, 1 << 11, power_up ? (1 << 11) : 0);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002887}
2888
2889static void alc269_shutup(struct hda_codec *codec)
2890{
Kailang Yangadcc70b2012-05-25 08:08:38 +02002891 struct alc_spec *spec = codec->spec;
2892
Kailang Yang1387e2d2012-11-08 10:23:18 +01002893 if (spec->codec_variant == ALC269_TYPE_ALC269VB)
2894 alc269vb_toggle_power_output(codec, 0);
2895 if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
2896 (alc_get_coef0(codec) & 0x00ff) == 0x018) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002897 msleep(150);
2898 }
Takashi Iwai9bfb2842013-07-24 14:31:50 +02002899 snd_hda_shutup_pins(codec);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002900}
2901
Takashi Iwai54db6c32014-08-18 15:11:19 +02002902static struct coef_fw alc282_coefs[] = {
2903 WRITE_COEF(0x03, 0x0002), /* Power Down Control */
Kailang Yang32fa7e42014-10-24 16:26:01 +08002904 UPDATE_COEF(0x05, 0xff3f, 0x0700), /* FIFO and filter clock */
Takashi Iwai54db6c32014-08-18 15:11:19 +02002905 WRITE_COEF(0x07, 0x0200), /* DMIC control */
2906 UPDATE_COEF(0x06, 0x00f0, 0), /* Analog clock */
2907 UPDATE_COEF(0x08, 0xfffc, 0x0c2c), /* JD */
2908 WRITE_COEF(0x0a, 0xcccc), /* JD offset1 */
2909 WRITE_COEF(0x0b, 0xcccc), /* JD offset2 */
2910 WRITE_COEF(0x0e, 0x6e00), /* LDO1/2/3, DAC/ADC */
2911 UPDATE_COEF(0x0f, 0xf800, 0x1000), /* JD */
2912 UPDATE_COEF(0x10, 0xfc00, 0x0c00), /* Capless */
2913 WRITE_COEF(0x6f, 0x0), /* Class D test 4 */
2914 UPDATE_COEF(0x0c, 0xfe00, 0), /* IO power down directly */
2915 WRITE_COEF(0x34, 0xa0c0), /* ANC */
2916 UPDATE_COEF(0x16, 0x0008, 0), /* AGC MUX */
2917 UPDATE_COEF(0x1d, 0x00e0, 0), /* DAC simple content protection */
2918 UPDATE_COEF(0x1f, 0x00e0, 0), /* ADC simple content protection */
2919 WRITE_COEF(0x21, 0x8804), /* DAC ADC Zero Detection */
2920 WRITE_COEF(0x63, 0x2902), /* PLL */
2921 WRITE_COEF(0x68, 0xa080), /* capless control 2 */
2922 WRITE_COEF(0x69, 0x3400), /* capless control 3 */
2923 WRITE_COEF(0x6a, 0x2f3e), /* capless control 4 */
2924 WRITE_COEF(0x6b, 0x0), /* capless control 5 */
2925 UPDATE_COEF(0x6d, 0x0fff, 0x0900), /* class D test 2 */
2926 WRITE_COEF(0x6e, 0x110a), /* class D test 3 */
2927 UPDATE_COEF(0x70, 0x00f8, 0x00d8), /* class D test 5 */
2928 WRITE_COEF(0x71, 0x0014), /* class D test 6 */
2929 WRITE_COEF(0x72, 0xc2ba), /* classD OCP */
2930 UPDATE_COEF(0x77, 0x0f80, 0), /* classD pure DC test */
2931 WRITE_COEF(0x6c, 0xfc06), /* Class D amp control */
2932 {}
2933};
2934
Kailang Yangcb149cb2014-03-18 16:45:32 +08002935static void alc282_restore_default_value(struct hda_codec *codec)
2936{
Takashi Iwai54db6c32014-08-18 15:11:19 +02002937 alc_process_coef_fw(codec, alc282_coefs);
Kailang Yangcb149cb2014-03-18 16:45:32 +08002938}
2939
Kailang Yang7b5c7a02014-03-18 16:15:54 +08002940static void alc282_init(struct hda_codec *codec)
2941{
2942 struct alc_spec *spec = codec->spec;
2943 hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
2944 bool hp_pin_sense;
2945 int coef78;
2946
Kailang Yangcb149cb2014-03-18 16:45:32 +08002947 alc282_restore_default_value(codec);
2948
Kailang Yang7b5c7a02014-03-18 16:15:54 +08002949 if (!hp_pin)
2950 return;
2951 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
2952 coef78 = alc_read_coef_idx(codec, 0x78);
2953
2954 /* Index 0x78 Direct Drive HP AMP LPM Control 1 */
2955 /* Headphone capless set to high power mode */
2956 alc_write_coef_idx(codec, 0x78, 0x9004);
2957
2958 if (hp_pin_sense)
2959 msleep(2);
2960
2961 snd_hda_codec_write(codec, hp_pin, 0,
2962 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
2963
2964 if (hp_pin_sense)
2965 msleep(85);
2966
2967 snd_hda_codec_write(codec, hp_pin, 0,
2968 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
2969
2970 if (hp_pin_sense)
2971 msleep(100);
2972
2973 /* Headphone capless set to normal mode */
2974 alc_write_coef_idx(codec, 0x78, coef78);
2975}
2976
2977static void alc282_shutup(struct hda_codec *codec)
2978{
2979 struct alc_spec *spec = codec->spec;
2980 hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
2981 bool hp_pin_sense;
2982 int coef78;
2983
2984 if (!hp_pin) {
2985 alc269_shutup(codec);
2986 return;
2987 }
2988
2989 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
2990 coef78 = alc_read_coef_idx(codec, 0x78);
2991 alc_write_coef_idx(codec, 0x78, 0x9004);
2992
2993 if (hp_pin_sense)
2994 msleep(2);
2995
2996 snd_hda_codec_write(codec, hp_pin, 0,
2997 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
2998
2999 if (hp_pin_sense)
3000 msleep(85);
3001
3002 snd_hda_codec_write(codec, hp_pin, 0,
3003 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
3004
3005 if (hp_pin_sense)
3006 msleep(100);
3007
3008 alc_auto_setup_eapd(codec, false);
3009 snd_hda_shutup_pins(codec);
3010 alc_write_coef_idx(codec, 0x78, coef78);
3011}
3012
Takashi Iwai54db6c32014-08-18 15:11:19 +02003013static struct coef_fw alc283_coefs[] = {
3014 WRITE_COEF(0x03, 0x0002), /* Power Down Control */
Kailang Yang56779862014-10-24 16:17:51 +08003015 UPDATE_COEF(0x05, 0xff3f, 0x0700), /* FIFO and filter clock */
Takashi Iwai54db6c32014-08-18 15:11:19 +02003016 WRITE_COEF(0x07, 0x0200), /* DMIC control */
3017 UPDATE_COEF(0x06, 0x00f0, 0), /* Analog clock */
3018 UPDATE_COEF(0x08, 0xfffc, 0x0c2c), /* JD */
3019 WRITE_COEF(0x0a, 0xcccc), /* JD offset1 */
3020 WRITE_COEF(0x0b, 0xcccc), /* JD offset2 */
3021 WRITE_COEF(0x0e, 0x6fc0), /* LDO1/2/3, DAC/ADC */
3022 UPDATE_COEF(0x0f, 0xf800, 0x1000), /* JD */
3023 UPDATE_COEF(0x10, 0xfc00, 0x0c00), /* Capless */
3024 WRITE_COEF(0x3a, 0x0), /* Class D test 4 */
3025 UPDATE_COEF(0x0c, 0xfe00, 0x0), /* IO power down directly */
3026 WRITE_COEF(0x22, 0xa0c0), /* ANC */
3027 UPDATE_COEFEX(0x53, 0x01, 0x000f, 0x0008), /* AGC MUX */
3028 UPDATE_COEF(0x1d, 0x00e0, 0), /* DAC simple content protection */
3029 UPDATE_COEF(0x1f, 0x00e0, 0), /* ADC simple content protection */
3030 WRITE_COEF(0x21, 0x8804), /* DAC ADC Zero Detection */
3031 WRITE_COEF(0x2e, 0x2902), /* PLL */
3032 WRITE_COEF(0x33, 0xa080), /* capless control 2 */
3033 WRITE_COEF(0x34, 0x3400), /* capless control 3 */
3034 WRITE_COEF(0x35, 0x2f3e), /* capless control 4 */
3035 WRITE_COEF(0x36, 0x0), /* capless control 5 */
3036 UPDATE_COEF(0x38, 0x0fff, 0x0900), /* class D test 2 */
3037 WRITE_COEF(0x39, 0x110a), /* class D test 3 */
3038 UPDATE_COEF(0x3b, 0x00f8, 0x00d8), /* class D test 5 */
3039 WRITE_COEF(0x3c, 0x0014), /* class D test 6 */
3040 WRITE_COEF(0x3d, 0xc2ba), /* classD OCP */
3041 UPDATE_COEF(0x42, 0x0f80, 0x0), /* classD pure DC test */
3042 WRITE_COEF(0x49, 0x0), /* test mode */
3043 UPDATE_COEF(0x40, 0xf800, 0x9800), /* Class D DC enable */
3044 UPDATE_COEF(0x42, 0xf000, 0x2000), /* DC offset */
3045 WRITE_COEF(0x37, 0xfc06), /* Class D amp control */
Kailang Yang56779862014-10-24 16:17:51 +08003046 UPDATE_COEF(0x1b, 0x8000, 0), /* HP JD control */
Takashi Iwai54db6c32014-08-18 15:11:19 +02003047 {}
3048};
3049
Kailang Yang6bd55b02014-03-17 13:51:27 +08003050static void alc283_restore_default_value(struct hda_codec *codec)
3051{
Takashi Iwai54db6c32014-08-18 15:11:19 +02003052 alc_process_coef_fw(codec, alc283_coefs);
Kailang Yang6bd55b02014-03-17 13:51:27 +08003053}
3054
Kailang Yang2af02be2013-08-22 10:03:50 +02003055static void alc283_init(struct hda_codec *codec)
3056{
3057 struct alc_spec *spec = codec->spec;
3058 hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
3059 bool hp_pin_sense;
Kailang Yang2af02be2013-08-22 10:03:50 +02003060
Kailang Yang8314f222014-04-03 17:28:39 +08003061 if (!spec->gen.autocfg.hp_outs) {
3062 if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
3063 hp_pin = spec->gen.autocfg.line_out_pins[0];
3064 }
3065
Kailang Yang6bd55b02014-03-17 13:51:27 +08003066 alc283_restore_default_value(codec);
3067
Kailang Yang2af02be2013-08-22 10:03:50 +02003068 if (!hp_pin)
3069 return;
Kailang Yanga59d7192015-04-08 16:34:00 +08003070
3071 msleep(30);
Kailang Yang2af02be2013-08-22 10:03:50 +02003072 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3073
3074 /* Index 0x43 Direct Drive HP AMP LPM Control 1 */
3075 /* Headphone capless set to high power mode */
3076 alc_write_coef_idx(codec, 0x43, 0x9004);
3077
3078 snd_hda_codec_write(codec, hp_pin, 0,
3079 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3080
3081 if (hp_pin_sense)
3082 msleep(85);
3083
3084 snd_hda_codec_write(codec, hp_pin, 0,
3085 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3086
3087 if (hp_pin_sense)
3088 msleep(85);
3089 /* Index 0x46 Combo jack auto switch control 2 */
3090 /* 3k pull low control for Headset jack. */
Takashi Iwai98b24882014-08-18 13:47:50 +02003091 alc_update_coef_idx(codec, 0x46, 3 << 12, 0);
Kailang Yang2af02be2013-08-22 10:03:50 +02003092 /* Headphone capless set to normal mode */
3093 alc_write_coef_idx(codec, 0x43, 0x9614);
3094}
3095
3096static void alc283_shutup(struct hda_codec *codec)
3097{
3098 struct alc_spec *spec = codec->spec;
3099 hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
3100 bool hp_pin_sense;
Kailang Yang2af02be2013-08-22 10:03:50 +02003101
Kailang Yang8314f222014-04-03 17:28:39 +08003102 if (!spec->gen.autocfg.hp_outs) {
3103 if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
3104 hp_pin = spec->gen.autocfg.line_out_pins[0];
3105 }
3106
Kailang Yang2af02be2013-08-22 10:03:50 +02003107 if (!hp_pin) {
3108 alc269_shutup(codec);
3109 return;
3110 }
3111
3112 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3113
3114 alc_write_coef_idx(codec, 0x43, 0x9004);
3115
Harsha Priyab450b172014-10-09 11:04:56 +00003116 /*depop hp during suspend*/
3117 alc_write_coef_idx(codec, 0x06, 0x2100);
3118
Kailang Yang2af02be2013-08-22 10:03:50 +02003119 snd_hda_codec_write(codec, hp_pin, 0,
3120 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3121
3122 if (hp_pin_sense)
Kailang Yang88011c092013-10-24 15:45:24 +02003123 msleep(100);
Kailang Yang2af02be2013-08-22 10:03:50 +02003124
3125 snd_hda_codec_write(codec, hp_pin, 0,
3126 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
3127
Takashi Iwai98b24882014-08-18 13:47:50 +02003128 alc_update_coef_idx(codec, 0x46, 0, 3 << 12);
Kailang Yang2af02be2013-08-22 10:03:50 +02003129
3130 if (hp_pin_sense)
Kailang Yang88011c092013-10-24 15:45:24 +02003131 msleep(100);
Kailang Yang0435b3f2014-04-08 17:14:14 +08003132 alc_auto_setup_eapd(codec, false);
Kailang Yang2af02be2013-08-22 10:03:50 +02003133 snd_hda_shutup_pins(codec);
3134 alc_write_coef_idx(codec, 0x43, 0x9614);
3135}
3136
Kailang Yang4a219ef2017-06-16 16:54:35 +08003137static void alc256_init(struct hda_codec *codec)
3138{
3139 struct alc_spec *spec = codec->spec;
3140 hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
3141 bool hp_pin_sense;
3142
3143 if (!hp_pin)
3144 return;
3145
3146 msleep(30);
3147
3148 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3149
3150 if (hp_pin_sense)
3151 msleep(2);
3152
3153 alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */
3154
3155 snd_hda_codec_write(codec, hp_pin, 0,
3156 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3157
3158 if (hp_pin_sense)
3159 msleep(85);
3160
3161 snd_hda_codec_write(codec, hp_pin, 0,
3162 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3163
3164 if (hp_pin_sense)
3165 msleep(100);
3166
3167 alc_update_coef_idx(codec, 0x46, 3 << 12, 0);
3168 alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x4); /* Hight power */
Kailang Yang88d42b22018-03-14 16:08:57 +08003169 alc_update_coefex_idx(codec, 0x53, 0x02, 0x8000, 1 << 15); /* Clear bit */
3170 alc_update_coefex_idx(codec, 0x53, 0x02, 0x8000, 0 << 15);
Kailang Yang4a219ef2017-06-16 16:54:35 +08003171}
3172
3173static void alc256_shutup(struct hda_codec *codec)
3174{
3175 struct alc_spec *spec = codec->spec;
3176 hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
3177 bool hp_pin_sense;
3178
3179 if (!hp_pin) {
3180 alc269_shutup(codec);
3181 return;
3182 }
3183
3184 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3185
3186 if (hp_pin_sense)
3187 msleep(2);
3188
3189 snd_hda_codec_write(codec, hp_pin, 0,
3190 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3191
3192 if (hp_pin_sense)
3193 msleep(85);
3194
Takashi Iwai1c9609e2018-01-19 14:18:34 +01003195 /* 3k pull low control for Headset jack. */
3196 /* NOTE: call this before clearing the pin, otherwise codec stalls */
3197 alc_update_coef_idx(codec, 0x46, 0, 3 << 12);
3198
Kailang Yang4a219ef2017-06-16 16:54:35 +08003199 snd_hda_codec_write(codec, hp_pin, 0,
3200 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
3201
Kailang Yang4a219ef2017-06-16 16:54:35 +08003202 if (hp_pin_sense)
3203 msleep(100);
3204
3205 alc_auto_setup_eapd(codec, false);
3206 snd_hda_shutup_pins(codec);
3207}
3208
Kailang Yangda911b12018-01-05 16:50:08 +08003209static void alc225_init(struct hda_codec *codec)
3210{
3211 struct alc_spec *spec = codec->spec;
3212 hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
3213 bool hp1_pin_sense, hp2_pin_sense;
3214
3215 if (!hp_pin)
3216 return;
3217
3218 msleep(30);
3219
3220 hp1_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3221 hp2_pin_sense = snd_hda_jack_detect(codec, 0x16);
3222
3223 if (hp1_pin_sense || hp2_pin_sense)
3224 msleep(2);
3225
3226 alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */
3227
3228 if (hp1_pin_sense)
3229 snd_hda_codec_write(codec, hp_pin, 0,
3230 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3231 if (hp2_pin_sense)
3232 snd_hda_codec_write(codec, 0x16, 0,
3233 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3234
3235 if (hp1_pin_sense || hp2_pin_sense)
3236 msleep(85);
3237
3238 if (hp1_pin_sense)
3239 snd_hda_codec_write(codec, hp_pin, 0,
3240 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3241 if (hp2_pin_sense)
3242 snd_hda_codec_write(codec, 0x16, 0,
3243 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3244
3245 if (hp1_pin_sense || hp2_pin_sense)
3246 msleep(100);
3247
3248 alc_update_coef_idx(codec, 0x4a, 3 << 10, 0);
3249 alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x4); /* Hight power */
3250}
3251
3252static void alc225_shutup(struct hda_codec *codec)
3253{
3254 struct alc_spec *spec = codec->spec;
3255 hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
3256 bool hp1_pin_sense, hp2_pin_sense;
3257
3258 if (!hp_pin) {
3259 alc269_shutup(codec);
3260 return;
3261 }
3262
3263 /* 3k pull low control for Headset jack. */
3264 alc_update_coef_idx(codec, 0x4a, 0, 3 << 10);
3265
3266 hp1_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3267 hp2_pin_sense = snd_hda_jack_detect(codec, 0x16);
3268
3269 if (hp1_pin_sense || hp2_pin_sense)
3270 msleep(2);
3271
3272 if (hp1_pin_sense)
3273 snd_hda_codec_write(codec, hp_pin, 0,
3274 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3275 if (hp2_pin_sense)
3276 snd_hda_codec_write(codec, 0x16, 0,
3277 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3278
3279 if (hp1_pin_sense || hp2_pin_sense)
3280 msleep(85);
3281
3282 if (hp1_pin_sense)
3283 snd_hda_codec_write(codec, hp_pin, 0,
3284 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
3285 if (hp2_pin_sense)
3286 snd_hda_codec_write(codec, 0x16, 0,
3287 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
3288
3289 if (hp1_pin_sense || hp2_pin_sense)
3290 msleep(100);
3291
3292 alc_auto_setup_eapd(codec, false);
3293 snd_hda_shutup_pins(codec);
3294}
3295
Kailang Yangc2d6af52017-06-21 14:50:54 +08003296static void alc_default_init(struct hda_codec *codec)
3297{
3298 struct alc_spec *spec = codec->spec;
3299 hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
3300 bool hp_pin_sense;
3301
3302 if (!hp_pin)
3303 return;
3304
3305 msleep(30);
3306
3307 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3308
3309 if (hp_pin_sense)
3310 msleep(2);
3311
3312 snd_hda_codec_write(codec, hp_pin, 0,
3313 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3314
3315 if (hp_pin_sense)
3316 msleep(85);
3317
3318 snd_hda_codec_write(codec, hp_pin, 0,
3319 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3320
3321 if (hp_pin_sense)
3322 msleep(100);
3323}
3324
3325static void alc_default_shutup(struct hda_codec *codec)
3326{
3327 struct alc_spec *spec = codec->spec;
3328 hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
3329 bool hp_pin_sense;
3330
3331 if (!hp_pin) {
3332 alc269_shutup(codec);
3333 return;
3334 }
3335
3336 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3337
3338 if (hp_pin_sense)
3339 msleep(2);
3340
3341 snd_hda_codec_write(codec, hp_pin, 0,
3342 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3343
3344 if (hp_pin_sense)
3345 msleep(85);
3346
3347 snd_hda_codec_write(codec, hp_pin, 0,
3348 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
3349
3350 if (hp_pin_sense)
3351 msleep(100);
3352
3353 alc_auto_setup_eapd(codec, false);
3354 snd_hda_shutup_pins(codec);
3355}
3356
Kailang Yangad60d502013-06-28 12:03:01 +02003357static void alc5505_coef_set(struct hda_codec *codec, unsigned int index_reg,
3358 unsigned int val)
3359{
3360 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_COEF_INDEX, index_reg >> 1);
3361 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_PROC_COEF, val & 0xffff); /* LSB */
3362 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_PROC_COEF, val >> 16); /* MSB */
3363}
3364
3365static int alc5505_coef_get(struct hda_codec *codec, unsigned int index_reg)
3366{
3367 unsigned int val;
3368
3369 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_COEF_INDEX, index_reg >> 1);
3370 val = snd_hda_codec_read(codec, 0x51, 0, AC_VERB_GET_PROC_COEF, 0)
3371 & 0xffff;
3372 val |= snd_hda_codec_read(codec, 0x51, 0, AC_VERB_GET_PROC_COEF, 0)
3373 << 16;
3374 return val;
3375}
3376
3377static void alc5505_dsp_halt(struct hda_codec *codec)
3378{
3379 unsigned int val;
3380
3381 alc5505_coef_set(codec, 0x3000, 0x000c); /* DSP CPU stop */
3382 alc5505_coef_set(codec, 0x880c, 0x0008); /* DDR enter self refresh */
3383 alc5505_coef_set(codec, 0x61c0, 0x11110080); /* Clock control for PLL and CPU */
3384 alc5505_coef_set(codec, 0x6230, 0xfc0d4011); /* Disable Input OP */
3385 alc5505_coef_set(codec, 0x61b4, 0x040a2b03); /* Stop PLL2 */
3386 alc5505_coef_set(codec, 0x61b0, 0x00005b17); /* Stop PLL1 */
3387 alc5505_coef_set(codec, 0x61b8, 0x04133303); /* Stop PLL3 */
3388 val = alc5505_coef_get(codec, 0x6220);
3389 alc5505_coef_set(codec, 0x6220, (val | 0x3000)); /* switch Ringbuffer clock to DBUS clock */
3390}
3391
3392static void alc5505_dsp_back_from_halt(struct hda_codec *codec)
3393{
3394 alc5505_coef_set(codec, 0x61b8, 0x04133302);
3395 alc5505_coef_set(codec, 0x61b0, 0x00005b16);
3396 alc5505_coef_set(codec, 0x61b4, 0x040a2b02);
3397 alc5505_coef_set(codec, 0x6230, 0xf80d4011);
3398 alc5505_coef_set(codec, 0x6220, 0x2002010f);
3399 alc5505_coef_set(codec, 0x880c, 0x00000004);
3400}
3401
3402static void alc5505_dsp_init(struct hda_codec *codec)
3403{
3404 unsigned int val;
3405
3406 alc5505_dsp_halt(codec);
3407 alc5505_dsp_back_from_halt(codec);
3408 alc5505_coef_set(codec, 0x61b0, 0x5b14); /* PLL1 control */
3409 alc5505_coef_set(codec, 0x61b0, 0x5b16);
3410 alc5505_coef_set(codec, 0x61b4, 0x04132b00); /* PLL2 control */
3411 alc5505_coef_set(codec, 0x61b4, 0x04132b02);
3412 alc5505_coef_set(codec, 0x61b8, 0x041f3300); /* PLL3 control*/
3413 alc5505_coef_set(codec, 0x61b8, 0x041f3302);
3414 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_CODEC_RESET, 0); /* Function reset */
3415 alc5505_coef_set(codec, 0x61b8, 0x041b3302);
3416 alc5505_coef_set(codec, 0x61b8, 0x04173302);
3417 alc5505_coef_set(codec, 0x61b8, 0x04163302);
3418 alc5505_coef_set(codec, 0x8800, 0x348b328b); /* DRAM control */
3419 alc5505_coef_set(codec, 0x8808, 0x00020022); /* DRAM control */
3420 alc5505_coef_set(codec, 0x8818, 0x00000400); /* DRAM control */
3421
3422 val = alc5505_coef_get(codec, 0x6200) >> 16; /* Read revision ID */
3423 if (val <= 3)
3424 alc5505_coef_set(codec, 0x6220, 0x2002010f); /* I/O PAD Configuration */
3425 else
3426 alc5505_coef_set(codec, 0x6220, 0x6002018f);
3427
3428 alc5505_coef_set(codec, 0x61ac, 0x055525f0); /**/
3429 alc5505_coef_set(codec, 0x61c0, 0x12230080); /* Clock control */
3430 alc5505_coef_set(codec, 0x61b4, 0x040e2b02); /* PLL2 control */
3431 alc5505_coef_set(codec, 0x61bc, 0x010234f8); /* OSC Control */
3432 alc5505_coef_set(codec, 0x880c, 0x00000004); /* DRAM Function control */
3433 alc5505_coef_set(codec, 0x880c, 0x00000003);
3434 alc5505_coef_set(codec, 0x880c, 0x00000010);
Takashi Iwaicd63a5f2013-07-05 12:13:59 +02003435
3436#ifdef HALT_REALTEK_ALC5505
3437 alc5505_dsp_halt(codec);
3438#endif
Kailang Yangad60d502013-06-28 12:03:01 +02003439}
3440
Takashi Iwaicd63a5f2013-07-05 12:13:59 +02003441#ifdef HALT_REALTEK_ALC5505
3442#define alc5505_dsp_suspend(codec) /* NOP */
3443#define alc5505_dsp_resume(codec) /* NOP */
3444#else
3445#define alc5505_dsp_suspend(codec) alc5505_dsp_halt(codec)
3446#define alc5505_dsp_resume(codec) alc5505_dsp_back_from_halt(codec)
3447#endif
3448
Takashi Iwai2a439522011-07-26 09:52:50 +02003449#ifdef CONFIG_PM
Kailang Yangad60d502013-06-28 12:03:01 +02003450static int alc269_suspend(struct hda_codec *codec)
3451{
3452 struct alc_spec *spec = codec->spec;
3453
3454 if (spec->has_alc5505_dsp)
Takashi Iwaicd63a5f2013-07-05 12:13:59 +02003455 alc5505_dsp_suspend(codec);
Kailang Yangad60d502013-06-28 12:03:01 +02003456 return alc_suspend(codec);
3457}
3458
Takashi Iwai1d045db2011-07-07 18:23:21 +02003459static int alc269_resume(struct hda_codec *codec)
3460{
Kailang Yangadcc70b2012-05-25 08:08:38 +02003461 struct alc_spec *spec = codec->spec;
3462
Kailang Yang1387e2d2012-11-08 10:23:18 +01003463 if (spec->codec_variant == ALC269_TYPE_ALC269VB)
3464 alc269vb_toggle_power_output(codec, 0);
3465 if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
Kailang Yangadcc70b2012-05-25 08:08:38 +02003466 (alc_get_coef0(codec) & 0x00ff) == 0x018) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02003467 msleep(150);
3468 }
3469
3470 codec->patch_ops.init(codec);
3471
Kailang Yang1387e2d2012-11-08 10:23:18 +01003472 if (spec->codec_variant == ALC269_TYPE_ALC269VB)
3473 alc269vb_toggle_power_output(codec, 1);
3474 if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
Kailang Yangadcc70b2012-05-25 08:08:38 +02003475 (alc_get_coef0(codec) & 0x00ff) == 0x017) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02003476 msleep(200);
3477 }
3478
Takashi Iwaieeecd9d2015-02-25 15:18:50 +01003479 regcache_sync(codec->core.regmap);
Takashi Iwai1d045db2011-07-07 18:23:21 +02003480 hda_call_check_power_status(codec, 0x01);
Hui Wangf4753712014-08-19 12:07:03 +08003481
3482 /* on some machine, the BIOS will clear the codec gpio data when enter
3483 * suspend, and won't restore the data after resume, so we restore it
3484 * in the driver.
3485 */
3486 if (spec->gpio_led)
Takashi Iwai7639a062015-03-03 10:07:24 +01003487 snd_hda_codec_write(codec, codec->core.afg, 0, AC_VERB_SET_GPIO_DATA,
Hui Wangf4753712014-08-19 12:07:03 +08003488 spec->gpio_led);
3489
Kailang Yangad60d502013-06-28 12:03:01 +02003490 if (spec->has_alc5505_dsp)
Takashi Iwaicd63a5f2013-07-05 12:13:59 +02003491 alc5505_dsp_resume(codec);
Kailang Yangc5177c82013-07-24 14:39:49 +02003492
Takashi Iwai1d045db2011-07-07 18:23:21 +02003493 return 0;
3494}
Takashi Iwai2a439522011-07-26 09:52:50 +02003495#endif /* CONFIG_PM */
Takashi Iwai1d045db2011-07-07 18:23:21 +02003496
David Henningsson108cc102012-07-20 10:37:25 +02003497static void alc269_fixup_pincfg_no_hp_to_lineout(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003498 const struct hda_fixup *fix, int action)
David Henningsson108cc102012-07-20 10:37:25 +02003499{
3500 struct alc_spec *spec = codec->spec;
3501
Takashi Iwai1727a772013-01-10 09:52:52 +01003502 if (action == HDA_FIXUP_ACT_PRE_PROBE)
David Henningsson108cc102012-07-20 10:37:25 +02003503 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
3504}
3505
Jan-Marek Glogowskifdcc9682018-02-14 11:29:15 +01003506static void alc269_fixup_pincfg_U7x7_headset_mic(struct hda_codec *codec,
3507 const struct hda_fixup *fix,
3508 int action)
3509{
3510 unsigned int cfg_headphone = snd_hda_codec_get_pincfg(codec, 0x21);
3511 unsigned int cfg_headset_mic = snd_hda_codec_get_pincfg(codec, 0x19);
3512
3513 if (cfg_headphone && cfg_headset_mic == 0x411111f0)
3514 snd_hda_codec_set_pincfg(codec, 0x19,
3515 (cfg_headphone & ~AC_DEFCFG_DEVICE) |
3516 (AC_JACK_MIC_IN << AC_DEFCFG_DEVICE_SHIFT));
3517}
3518
Takashi Iwai1d045db2011-07-07 18:23:21 +02003519static void alc269_fixup_hweq(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003520 const struct hda_fixup *fix, int action)
Takashi Iwai1d045db2011-07-07 18:23:21 +02003521{
Takashi Iwai98b24882014-08-18 13:47:50 +02003522 if (action == HDA_FIXUP_ACT_INIT)
3523 alc_update_coef_idx(codec, 0x1e, 0, 0x80);
Takashi Iwai1d045db2011-07-07 18:23:21 +02003524}
3525
David Henningsson7c478f02013-10-11 10:18:46 +02003526static void alc269_fixup_headset_mic(struct hda_codec *codec,
3527 const struct hda_fixup *fix, int action)
3528{
3529 struct alc_spec *spec = codec->spec;
3530
3531 if (action == HDA_FIXUP_ACT_PRE_PROBE)
3532 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
3533}
3534
Takashi Iwai1d045db2011-07-07 18:23:21 +02003535static void alc271_fixup_dmic(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003536 const struct hda_fixup *fix, int action)
Takashi Iwai1d045db2011-07-07 18:23:21 +02003537{
3538 static const struct hda_verb verbs[] = {
3539 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
3540 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
3541 {}
3542 };
3543 unsigned int cfg;
3544
Takashi Iwai7639a062015-03-03 10:07:24 +01003545 if (strcmp(codec->core.chip_name, "ALC271X") &&
3546 strcmp(codec->core.chip_name, "ALC269VB"))
Takashi Iwai1d045db2011-07-07 18:23:21 +02003547 return;
3548 cfg = snd_hda_codec_get_pincfg(codec, 0x12);
3549 if (get_defcfg_connect(cfg) == AC_JACK_PORT_FIXED)
3550 snd_hda_sequence_write(codec, verbs);
3551}
3552
Takashi Iwai017f2a12011-07-09 14:42:25 +02003553static void alc269_fixup_pcm_44k(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003554 const struct hda_fixup *fix, int action)
Takashi Iwai017f2a12011-07-09 14:42:25 +02003555{
3556 struct alc_spec *spec = codec->spec;
3557
Takashi Iwai1727a772013-01-10 09:52:52 +01003558 if (action != HDA_FIXUP_ACT_PROBE)
Takashi Iwai017f2a12011-07-09 14:42:25 +02003559 return;
3560
3561 /* Due to a hardware problem on Lenovo Ideadpad, we need to
3562 * fix the sample rate of analog I/O to 44.1kHz
3563 */
Takashi Iwai08c189f2012-12-19 15:22:24 +01003564 spec->gen.stream_analog_playback = &alc269_44k_pcm_analog_playback;
3565 spec->gen.stream_analog_capture = &alc269_44k_pcm_analog_capture;
Takashi Iwai017f2a12011-07-09 14:42:25 +02003566}
3567
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02003568static void alc269_fixup_stereo_dmic(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003569 const struct hda_fixup *fix, int action)
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02003570{
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02003571 /* The digital-mic unit sends PDM (differential signal) instead of
3572 * the standard PCM, thus you can't record a valid mono stream as is.
3573 * Below is a workaround specific to ALC269 to control the dmic
3574 * signal source as mono.
3575 */
Takashi Iwai98b24882014-08-18 13:47:50 +02003576 if (action == HDA_FIXUP_ACT_INIT)
3577 alc_update_coef_idx(codec, 0x07, 0, 0x80);
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02003578}
3579
Takashi Iwai24519912011-08-16 15:08:49 +02003580static void alc269_quanta_automute(struct hda_codec *codec)
3581{
Takashi Iwai08c189f2012-12-19 15:22:24 +01003582 snd_hda_gen_update_outputs(codec);
Takashi Iwai24519912011-08-16 15:08:49 +02003583
Takashi Iwai1687ccc2014-08-18 13:49:35 +02003584 alc_write_coef_idx(codec, 0x0c, 0x680);
3585 alc_write_coef_idx(codec, 0x0c, 0x480);
Takashi Iwai24519912011-08-16 15:08:49 +02003586}
3587
3588static void alc269_fixup_quanta_mute(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003589 const struct hda_fixup *fix, int action)
Takashi Iwai24519912011-08-16 15:08:49 +02003590{
3591 struct alc_spec *spec = codec->spec;
Takashi Iwai1727a772013-01-10 09:52:52 +01003592 if (action != HDA_FIXUP_ACT_PROBE)
Takashi Iwai24519912011-08-16 15:08:49 +02003593 return;
Takashi Iwai08c189f2012-12-19 15:22:24 +01003594 spec->gen.automute_hook = alc269_quanta_automute;
Takashi Iwai24519912011-08-16 15:08:49 +02003595}
3596
David Henningssond240d1d2013-04-15 12:50:02 +02003597static void alc269_x101_hp_automute_hook(struct hda_codec *codec,
Takashi Iwai1a4f69d2014-09-11 15:22:46 +02003598 struct hda_jack_callback *jack)
David Henningssond240d1d2013-04-15 12:50:02 +02003599{
3600 struct alc_spec *spec = codec->spec;
3601 int vref;
3602 msleep(200);
3603 snd_hda_gen_hp_automute(codec, jack);
3604
3605 vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0;
3606 msleep(100);
3607 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3608 vref);
3609 msleep(500);
3610 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3611 vref);
3612}
3613
3614static void alc269_fixup_x101_headset_mic(struct hda_codec *codec,
3615 const struct hda_fixup *fix, int action)
3616{
3617 struct alc_spec *spec = codec->spec;
3618 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3619 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
3620 spec->gen.hp_automute_hook = alc269_x101_hp_automute_hook;
3621 }
3622}
3623
3624
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003625/* update mute-LED according to the speaker mute state via mic VREF pin */
3626static void alc269_fixup_mic_mute_hook(void *private_data, int enabled)
David Henningsson6d3cd5d2013-01-07 12:03:47 +01003627{
3628 struct hda_codec *codec = private_data;
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003629 struct alc_spec *spec = codec->spec;
3630 unsigned int pinval;
3631
3632 if (spec->mute_led_polarity)
3633 enabled = !enabled;
Takashi Iwai415d5552014-04-03 11:51:21 +02003634 pinval = snd_hda_codec_get_pin_target(codec, spec->mute_led_nid);
3635 pinval &= ~AC_PINCTL_VREFEN;
3636 pinval |= enabled ? AC_PINCTL_VREF_HIZ : AC_PINCTL_VREF_80;
Takashi Iwaie40bdb02018-03-17 22:40:18 +01003637 if (spec->mute_led_nid) {
3638 /* temporarily power up/down for setting VREF */
3639 snd_hda_power_up_pm(codec);
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003640 snd_hda_set_pin_ctl_cache(codec, spec->mute_led_nid, pinval);
Takashi Iwaie40bdb02018-03-17 22:40:18 +01003641 snd_hda_power_down_pm(codec);
3642 }
David Henningsson6d3cd5d2013-01-07 12:03:47 +01003643}
3644
David Henningssond5b6b652013-11-06 10:50:44 +01003645/* Make sure the led works even in runtime suspend */
3646static unsigned int led_power_filter(struct hda_codec *codec,
3647 hda_nid_t nid,
3648 unsigned int power_state)
3649{
3650 struct alc_spec *spec = codec->spec;
3651
Hui Wang50dd9052014-07-08 17:56:15 +08003652 if (power_state != AC_PWRST_D3 || nid == 0 ||
3653 (nid != spec->mute_led_nid && nid != spec->cap_mute_led_nid))
David Henningssond5b6b652013-11-06 10:50:44 +01003654 return power_state;
3655
3656 /* Set pin ctl again, it might have just been set to 0 */
3657 snd_hda_set_pin_ctl(codec, nid,
3658 snd_hda_codec_get_pin_target(codec, nid));
3659
Takashi Iwaicffd3962015-04-09 10:30:25 +02003660 return snd_hda_gen_path_power_filter(codec, nid, power_state);
David Henningssond5b6b652013-11-06 10:50:44 +01003661}
3662
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003663static void alc269_fixup_hp_mute_led(struct hda_codec *codec,
3664 const struct hda_fixup *fix, int action)
David Henningsson6d3cd5d2013-01-07 12:03:47 +01003665{
3666 struct alc_spec *spec = codec->spec;
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003667 const struct dmi_device *dev = NULL;
3668
3669 if (action != HDA_FIXUP_ACT_PRE_PROBE)
3670 return;
3671
3672 while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) {
3673 int pol, pin;
3674 if (sscanf(dev->name, "HP_Mute_LED_%d_%x", &pol, &pin) != 2)
3675 continue;
3676 if (pin < 0x0a || pin >= 0x10)
3677 break;
3678 spec->mute_led_polarity = pol;
3679 spec->mute_led_nid = pin - 0x0a + 0x18;
3680 spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook;
Takashi Iwaifd25a972012-12-20 14:57:18 +01003681 spec->gen.vmaster_mute_enum = 1;
David Henningssond5b6b652013-11-06 10:50:44 +01003682 codec->power_filter = led_power_filter;
Takashi Iwai4e76a882014-02-25 12:21:03 +01003683 codec_dbg(codec,
3684 "Detected mute LED for %x:%d\n", spec->mute_led_nid,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003685 spec->mute_led_polarity);
David Henningsson6d3cd5d2013-01-07 12:03:47 +01003686 break;
3687 }
3688}
3689
Takashi Iwai85c467d2018-05-29 11:38:38 +02003690static void alc269_fixup_hp_mute_led_micx(struct hda_codec *codec,
3691 const struct hda_fixup *fix,
3692 int action, hda_nid_t pin)
David Henningssond06ac142013-02-18 11:41:55 +01003693{
3694 struct alc_spec *spec = codec->spec;
Takashi Iwai85c467d2018-05-29 11:38:38 +02003695
David Henningssond06ac142013-02-18 11:41:55 +01003696 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3697 spec->mute_led_polarity = 0;
Takashi Iwai85c467d2018-05-29 11:38:38 +02003698 spec->mute_led_nid = pin;
David Henningssond06ac142013-02-18 11:41:55 +01003699 spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook;
3700 spec->gen.vmaster_mute_enum = 1;
David Henningssond5b6b652013-11-06 10:50:44 +01003701 codec->power_filter = led_power_filter;
David Henningssond06ac142013-02-18 11:41:55 +01003702 }
3703}
3704
Takashi Iwai85c467d2018-05-29 11:38:38 +02003705static void alc269_fixup_hp_mute_led_mic1(struct hda_codec *codec,
3706 const struct hda_fixup *fix, int action)
3707{
3708 alc269_fixup_hp_mute_led_micx(codec, fix, action, 0x18);
3709}
3710
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003711static void alc269_fixup_hp_mute_led_mic2(struct hda_codec *codec,
3712 const struct hda_fixup *fix, int action)
Takashi Iwai420b0fe2012-03-12 12:35:27 +01003713{
Takashi Iwai85c467d2018-05-29 11:38:38 +02003714 alc269_fixup_hp_mute_led_micx(codec, fix, action, 0x19);
Takashi Iwai420b0fe2012-03-12 12:35:27 +01003715}
3716
Tom Briden7f783bd2017-03-25 10:12:01 +00003717static void alc269_fixup_hp_mute_led_mic3(struct hda_codec *codec,
3718 const struct hda_fixup *fix, int action)
3719{
Takashi Iwai85c467d2018-05-29 11:38:38 +02003720 alc269_fixup_hp_mute_led_micx(codec, fix, action, 0x1b);
Tom Briden7f783bd2017-03-25 10:12:01 +00003721}
3722
Takashi Iwai0f32fd192014-11-19 12:16:14 +01003723/* update LED status via GPIO */
3724static void alc_update_gpio_led(struct hda_codec *codec, unsigned int mask,
3725 bool enabled)
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003726{
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003727 struct alc_spec *spec = codec->spec;
3728 unsigned int oldval = spec->gpio_led;
3729
Takashi Iwai0f32fd192014-11-19 12:16:14 +01003730 if (spec->mute_led_polarity)
3731 enabled = !enabled;
3732
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003733 if (enabled)
Takashi Iwai0f32fd192014-11-19 12:16:14 +01003734 spec->gpio_led &= ~mask;
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003735 else
Takashi Iwai0f32fd192014-11-19 12:16:14 +01003736 spec->gpio_led |= mask;
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003737 if (spec->gpio_led != oldval)
3738 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
3739 spec->gpio_led);
3740}
3741
Takashi Iwai0f32fd192014-11-19 12:16:14 +01003742/* turn on/off mute LED via GPIO per vmaster hook */
3743static void alc_fixup_gpio_mute_hook(void *private_data, int enabled)
3744{
3745 struct hda_codec *codec = private_data;
3746 struct alc_spec *spec = codec->spec;
3747
3748 alc_update_gpio_led(codec, spec->gpio_mute_led_mask, enabled);
3749}
3750
3751/* turn on/off mic-mute LED via GPIO per capture hook */
Takashi Iwaid03abec2018-06-19 12:29:13 +02003752static void alc_gpio_micmute_update(struct hda_codec *codec)
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003753{
3754 struct alc_spec *spec = codec->spec;
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003755
Takashi Iwaid03abec2018-06-19 12:29:13 +02003756 alc_update_gpio_led(codec, spec->gpio_mic_led_mask,
3757 spec->gen.micmute_led.led_value);
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003758}
3759
3760static void alc269_fixup_hp_gpio_led(struct hda_codec *codec,
3761 const struct hda_fixup *fix, int action)
3762{
3763 struct alc_spec *spec = codec->spec;
3764 static const struct hda_verb gpio_init[] = {
3765 { 0x01, AC_VERB_SET_GPIO_MASK, 0x18 },
3766 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x18 },
3767 {}
3768 };
3769
3770 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai0f32fd192014-11-19 12:16:14 +01003771 spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook;
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003772 spec->gpio_led = 0;
Takashi Iwai0f32fd192014-11-19 12:16:14 +01003773 spec->mute_led_polarity = 0;
3774 spec->gpio_mute_led_mask = 0x08;
3775 spec->gpio_mic_led_mask = 0x10;
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003776 snd_hda_add_verbs(codec, gpio_init);
Takashi Iwaid03abec2018-06-19 12:29:13 +02003777 snd_hda_gen_add_micmute_led(codec, alc_gpio_micmute_update);
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003778 }
3779}
3780
Kailang Yangeaa8e5e2014-11-21 15:49:11 +08003781static void alc286_fixup_hp_gpio_led(struct hda_codec *codec,
3782 const struct hda_fixup *fix, int action)
3783{
3784 struct alc_spec *spec = codec->spec;
3785 static const struct hda_verb gpio_init[] = {
3786 { 0x01, AC_VERB_SET_GPIO_MASK, 0x22 },
3787 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x22 },
3788 {}
3789 };
3790
3791 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3792 spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook;
Kailang Yangeaa8e5e2014-11-21 15:49:11 +08003793 spec->gpio_led = 0;
3794 spec->mute_led_polarity = 0;
3795 spec->gpio_mute_led_mask = 0x02;
3796 spec->gpio_mic_led_mask = 0x20;
Takashi Iwai1d045db2011-07-07 18:23:21 +02003797 snd_hda_add_verbs(codec, gpio_init);
Takashi Iwaid03abec2018-06-19 12:29:13 +02003798 snd_hda_gen_add_micmute_led(codec, alc_gpio_micmute_update);
Takashi Iwai1d045db2011-07-07 18:23:21 +02003799 }
3800}
3801
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08003802/* turn on/off mic-mute LED per capture hook */
Takashi Iwaid03abec2018-06-19 12:29:13 +02003803static void alc_cap_micmute_update(struct hda_codec *codec)
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08003804{
3805 struct alc_spec *spec = codec->spec;
Takashi Iwaid03abec2018-06-19 12:29:13 +02003806 unsigned int pinval;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08003807
Takashi Iwaid03abec2018-06-19 12:29:13 +02003808 if (!spec->cap_mute_led_nid)
3809 return;
Hui Wangfc1fad92014-07-08 17:56:14 +08003810 pinval = snd_hda_codec_get_pin_target(codec, spec->cap_mute_led_nid);
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08003811 pinval &= ~AC_PINCTL_VREFEN;
Takashi Iwaid03abec2018-06-19 12:29:13 +02003812 if (spec->gen.micmute_led.led_value)
3813 pinval |= AC_PINCTL_VREF_80;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08003814 else
Takashi Iwaid03abec2018-06-19 12:29:13 +02003815 pinval |= AC_PINCTL_VREF_HIZ;
3816 snd_hda_set_pin_ctl_cache(codec, spec->cap_mute_led_nid, pinval);
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08003817}
3818
3819static void alc269_fixup_hp_gpio_mic1_led(struct hda_codec *codec,
3820 const struct hda_fixup *fix, int action)
3821{
3822 struct alc_spec *spec = codec->spec;
3823 static const struct hda_verb gpio_init[] = {
3824 { 0x01, AC_VERB_SET_GPIO_MASK, 0x08 },
3825 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x08 },
3826 {}
3827 };
3828
3829 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai0f32fd192014-11-19 12:16:14 +01003830 spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08003831 spec->gpio_led = 0;
Takashi Iwai0f32fd192014-11-19 12:16:14 +01003832 spec->mute_led_polarity = 0;
3833 spec->gpio_mute_led_mask = 0x08;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08003834 spec->cap_mute_led_nid = 0x18;
3835 snd_hda_add_verbs(codec, gpio_init);
Takashi Iwaid03abec2018-06-19 12:29:13 +02003836 snd_hda_gen_add_micmute_led(codec, alc_cap_micmute_update);
Hui Wang50dd9052014-07-08 17:56:15 +08003837 codec->power_filter = led_power_filter;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08003838 }
3839}
3840
David Henningsson7a5255f2014-10-30 08:26:01 +01003841static void alc280_fixup_hp_gpio4(struct hda_codec *codec,
3842 const struct hda_fixup *fix, int action)
3843{
3844 /* Like hp_gpio_mic1_led, but also needs GPIO4 low to enable headphone amp */
3845 struct alc_spec *spec = codec->spec;
3846 static const struct hda_verb gpio_init[] = {
3847 { 0x01, AC_VERB_SET_GPIO_MASK, 0x18 },
3848 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x18 },
3849 {}
3850 };
3851
3852 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai0f32fd192014-11-19 12:16:14 +01003853 spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook;
David Henningsson7a5255f2014-10-30 08:26:01 +01003854 spec->gpio_led = 0;
Takashi Iwai0f32fd192014-11-19 12:16:14 +01003855 spec->mute_led_polarity = 0;
3856 spec->gpio_mute_led_mask = 0x08;
David Henningsson7a5255f2014-10-30 08:26:01 +01003857 spec->cap_mute_led_nid = 0x18;
3858 snd_hda_add_verbs(codec, gpio_init);
Takashi Iwaid03abec2018-06-19 12:29:13 +02003859 snd_hda_gen_add_micmute_led(codec, alc_cap_micmute_update);
David Henningsson7a5255f2014-10-30 08:26:01 +01003860 codec->power_filter = led_power_filter;
3861 }
3862}
3863
Takashi Iwai6a30aba2018-04-27 17:17:35 +02003864#if IS_REACHABLE(CONFIG_INPUT)
David Henningsson33f4acd2015-01-07 15:50:13 +01003865static void gpio2_mic_hotkey_event(struct hda_codec *codec,
3866 struct hda_jack_callback *event)
3867{
3868 struct alc_spec *spec = codec->spec;
3869
3870 /* GPIO2 just toggles on a keypress/keyrelease cycle. Therefore
3871 send both key on and key off event for every interrupt. */
Hui Wangc7b60a82015-12-28 11:35:25 +08003872 input_report_key(spec->kb_dev, spec->alc_mute_keycode_map[ALC_KEY_MICMUTE_INDEX], 1);
David Henningsson33f4acd2015-01-07 15:50:13 +01003873 input_sync(spec->kb_dev);
Hui Wangc7b60a82015-12-28 11:35:25 +08003874 input_report_key(spec->kb_dev, spec->alc_mute_keycode_map[ALC_KEY_MICMUTE_INDEX], 0);
David Henningsson33f4acd2015-01-07 15:50:13 +01003875 input_sync(spec->kb_dev);
3876}
David Henningsson33f4acd2015-01-07 15:50:13 +01003877
Kailang3694cb22015-12-28 11:35:24 +08003878static int alc_register_micmute_input_device(struct hda_codec *codec)
3879{
3880 struct alc_spec *spec = codec->spec;
Hui Wangc7b60a82015-12-28 11:35:25 +08003881 int i;
Kailang3694cb22015-12-28 11:35:24 +08003882
3883 spec->kb_dev = input_allocate_device();
3884 if (!spec->kb_dev) {
3885 codec_err(codec, "Out of memory (input_allocate_device)\n");
3886 return -ENOMEM;
3887 }
Hui Wangc7b60a82015-12-28 11:35:25 +08003888
3889 spec->alc_mute_keycode_map[ALC_KEY_MICMUTE_INDEX] = KEY_MICMUTE;
3890
Kailang3694cb22015-12-28 11:35:24 +08003891 spec->kb_dev->name = "Microphone Mute Button";
3892 spec->kb_dev->evbit[0] = BIT_MASK(EV_KEY);
Hui Wangc7b60a82015-12-28 11:35:25 +08003893 spec->kb_dev->keycodesize = sizeof(spec->alc_mute_keycode_map[0]);
3894 spec->kb_dev->keycodemax = ARRAY_SIZE(spec->alc_mute_keycode_map);
3895 spec->kb_dev->keycode = spec->alc_mute_keycode_map;
3896 for (i = 0; i < ARRAY_SIZE(spec->alc_mute_keycode_map); i++)
3897 set_bit(spec->alc_mute_keycode_map[i], spec->kb_dev->keybit);
Kailang3694cb22015-12-28 11:35:24 +08003898
3899 if (input_register_device(spec->kb_dev)) {
3900 codec_err(codec, "input_register_device failed\n");
3901 input_free_device(spec->kb_dev);
3902 spec->kb_dev = NULL;
3903 return -ENOMEM;
3904 }
3905
3906 return 0;
3907}
3908
David Henningsson33f4acd2015-01-07 15:50:13 +01003909static void alc280_fixup_hp_gpio2_mic_hotkey(struct hda_codec *codec,
3910 const struct hda_fixup *fix, int action)
3911{
David Henningsson33f4acd2015-01-07 15:50:13 +01003912 /* GPIO1 = set according to SKU external amp
3913 GPIO2 = mic mute hotkey
3914 GPIO3 = mute LED
3915 GPIO4 = mic mute LED */
3916 static const struct hda_verb gpio_init[] = {
3917 { 0x01, AC_VERB_SET_GPIO_MASK, 0x1e },
3918 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x1a },
3919 { 0x01, AC_VERB_SET_GPIO_DATA, 0x02 },
3920 {}
3921 };
3922
3923 struct alc_spec *spec = codec->spec;
3924
3925 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai1c76aa52018-06-21 16:37:54 +02003926 spec->init_amp = ALC_INIT_DEFAULT;
Kailang3694cb22015-12-28 11:35:24 +08003927 if (alc_register_micmute_input_device(codec) != 0)
David Henningsson33f4acd2015-01-07 15:50:13 +01003928 return;
David Henningsson33f4acd2015-01-07 15:50:13 +01003929
3930 snd_hda_add_verbs(codec, gpio_init);
Takashi Iwai7639a062015-03-03 10:07:24 +01003931 snd_hda_codec_write_cache(codec, codec->core.afg, 0,
David Henningsson33f4acd2015-01-07 15:50:13 +01003932 AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x04);
Takashi Iwai7639a062015-03-03 10:07:24 +01003933 snd_hda_jack_detect_enable_callback(codec, codec->core.afg,
David Henningsson33f4acd2015-01-07 15:50:13 +01003934 gpio2_mic_hotkey_event);
3935
3936 spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook;
David Henningsson33f4acd2015-01-07 15:50:13 +01003937 spec->gpio_led = 0;
3938 spec->mute_led_polarity = 0;
3939 spec->gpio_mute_led_mask = 0x08;
3940 spec->gpio_mic_led_mask = 0x10;
Takashi Iwaid03abec2018-06-19 12:29:13 +02003941 snd_hda_gen_add_micmute_led(codec, alc_gpio_micmute_update);
David Henningsson33f4acd2015-01-07 15:50:13 +01003942 return;
3943 }
3944
3945 if (!spec->kb_dev)
3946 return;
3947
3948 switch (action) {
David Henningsson33f4acd2015-01-07 15:50:13 +01003949 case HDA_FIXUP_ACT_FREE:
3950 input_unregister_device(spec->kb_dev);
David Henningsson33f4acd2015-01-07 15:50:13 +01003951 spec->kb_dev = NULL;
3952 }
David Henningsson33f4acd2015-01-07 15:50:13 +01003953}
3954
Kailang3694cb22015-12-28 11:35:24 +08003955static void alc233_fixup_lenovo_line2_mic_hotkey(struct hda_codec *codec,
3956 const struct hda_fixup *fix, int action)
3957{
3958 /* Line2 = mic mute hotkey
3959 GPIO2 = mic mute LED */
3960 static const struct hda_verb gpio_init[] = {
3961 { 0x01, AC_VERB_SET_GPIO_MASK, 0x04 },
3962 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04 },
3963 {}
3964 };
3965
3966 struct alc_spec *spec = codec->spec;
3967
3968 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai1c76aa52018-06-21 16:37:54 +02003969 spec->init_amp = ALC_INIT_DEFAULT;
Kailang3694cb22015-12-28 11:35:24 +08003970 if (alc_register_micmute_input_device(codec) != 0)
3971 return;
3972
3973 snd_hda_add_verbs(codec, gpio_init);
3974 snd_hda_jack_detect_enable_callback(codec, 0x1b,
3975 gpio2_mic_hotkey_event);
3976
Kailang3694cb22015-12-28 11:35:24 +08003977 spec->gpio_led = 0;
3978 spec->mute_led_polarity = 0;
3979 spec->gpio_mic_led_mask = 0x04;
Takashi Iwaid03abec2018-06-19 12:29:13 +02003980 snd_hda_gen_add_micmute_led(codec, alc_gpio_micmute_update);
Kailang3694cb22015-12-28 11:35:24 +08003981 return;
3982 }
3983
3984 if (!spec->kb_dev)
3985 return;
3986
3987 switch (action) {
Kailang3694cb22015-12-28 11:35:24 +08003988 case HDA_FIXUP_ACT_FREE:
3989 input_unregister_device(spec->kb_dev);
3990 spec->kb_dev = NULL;
3991 }
3992}
Takashi Iwaic4696522018-01-15 10:44:35 +01003993#else /* INPUT */
3994#define alc280_fixup_hp_gpio2_mic_hotkey NULL
3995#define alc233_fixup_lenovo_line2_mic_hotkey NULL
3996#endif /* INPUT */
Kailang3694cb22015-12-28 11:35:24 +08003997
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08003998static void alc269_fixup_hp_line1_mic1_led(struct hda_codec *codec,
3999 const struct hda_fixup *fix, int action)
4000{
4001 struct alc_spec *spec = codec->spec;
4002
Takashi Iwai1bce62a2018-06-19 23:15:59 +02004003 alc269_fixup_hp_mute_led_micx(codec, fix, action, 0x1a);
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004004 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004005 spec->cap_mute_led_nid = 0x18;
Takashi Iwaid03abec2018-06-19 12:29:13 +02004006 snd_hda_gen_add_micmute_led(codec, alc_cap_micmute_update);
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004007 }
4008}
4009
Kailang Yang5a367672017-07-21 15:23:53 +08004010static struct coef_fw alc225_pre_hsmode[] = {
4011 UPDATE_COEF(0x4a, 1<<8, 0),
4012 UPDATE_COEFEX(0x57, 0x05, 1<<14, 0),
4013 UPDATE_COEF(0x63, 3<<14, 3<<14),
4014 UPDATE_COEF(0x4a, 3<<4, 2<<4),
4015 UPDATE_COEF(0x4a, 3<<10, 3<<10),
4016 UPDATE_COEF(0x45, 0x3f<<10, 0x34<<10),
4017 UPDATE_COEF(0x4a, 3<<10, 0),
4018 {}
4019};
4020
David Henningsson73bdd592013-04-15 15:44:14 +02004021static void alc_headset_mode_unplugged(struct hda_codec *codec)
4022{
Takashi Iwai54db6c32014-08-18 15:11:19 +02004023 static struct coef_fw coef0255[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004024 WRITE_COEF(0x45, 0xd089), /* UAJ function set to menual mode */
4025 UPDATE_COEFEX(0x57, 0x05, 1<<14, 0), /* Direct Drive HP Amp control(Set to verb control)*/
4026 WRITE_COEF(0x06, 0x6104), /* Set MIC2 Vref gate with HP */
4027 WRITE_COEFEX(0x57, 0x03, 0x8aa6), /* Direct Drive HP Amp control */
4028 {}
4029 };
Kailang Yange69e7e02016-05-30 15:58:28 +08004030 static struct coef_fw coef0255_1[] = {
4031 WRITE_COEF(0x1b, 0x0c0b), /* LDO and MISC control */
4032 {}
4033 };
4034 static struct coef_fw coef0256[] = {
4035 WRITE_COEF(0x1b, 0x0c4b), /* LDO and MISC control */
4036 {}
4037 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004038 static struct coef_fw coef0233[] = {
4039 WRITE_COEF(0x1b, 0x0c0b),
4040 WRITE_COEF(0x45, 0xc429),
4041 UPDATE_COEF(0x35, 0x4000, 0),
4042 WRITE_COEF(0x06, 0x2104),
4043 WRITE_COEF(0x1a, 0x0001),
4044 WRITE_COEF(0x26, 0x0004),
4045 WRITE_COEF(0x32, 0x42a3),
4046 {}
4047 };
Kailang Yangf3b70332015-04-08 15:01:17 +08004048 static struct coef_fw coef0288[] = {
4049 UPDATE_COEF(0x4f, 0xfcc0, 0xc400),
4050 UPDATE_COEF(0x50, 0x2000, 0x2000),
4051 UPDATE_COEF(0x56, 0x0006, 0x0006),
4052 UPDATE_COEF(0x66, 0x0008, 0),
4053 UPDATE_COEF(0x67, 0x2000, 0),
4054 {}
4055 };
Kailang Yang89542932017-07-17 15:03:43 +08004056 static struct coef_fw coef0298[] = {
4057 UPDATE_COEF(0x19, 0x1300, 0x0300),
4058 {}
4059 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004060 static struct coef_fw coef0292[] = {
4061 WRITE_COEF(0x76, 0x000e),
4062 WRITE_COEF(0x6c, 0x2400),
4063 WRITE_COEF(0x18, 0x7308),
4064 WRITE_COEF(0x6b, 0xc429),
4065 {}
4066 };
4067 static struct coef_fw coef0293[] = {
4068 UPDATE_COEF(0x10, 7<<8, 6<<8), /* SET Line1 JD to 0 */
4069 UPDATE_COEFEX(0x57, 0x05, 1<<15|1<<13, 0x0), /* SET charge pump by verb */
4070 UPDATE_COEFEX(0x57, 0x03, 1<<10, 1<<10), /* SET EN_OSW to 1 */
4071 UPDATE_COEF(0x1a, 1<<3, 1<<3), /* Combo JD gating with LINE1-VREFO */
4072 WRITE_COEF(0x45, 0xc429), /* Set to TRS type */
4073 UPDATE_COEF(0x4a, 0x000f, 0x000e), /* Combo Jack auto detect */
4074 {}
4075 };
4076 static struct coef_fw coef0668[] = {
4077 WRITE_COEF(0x15, 0x0d40),
4078 WRITE_COEF(0xb7, 0x802b),
4079 {}
4080 };
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004081 static struct coef_fw coef0225[] = {
Kailang Yang5a367672017-07-21 15:23:53 +08004082 UPDATE_COEF(0x63, 3<<14, 0),
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004083 {}
4084 };
Kailang Yang71683c32017-06-20 16:33:50 +08004085 static struct coef_fw coef0274[] = {
4086 UPDATE_COEF(0x4a, 0x0100, 0),
4087 UPDATE_COEFEX(0x57, 0x05, 0x4000, 0),
4088 UPDATE_COEF(0x6b, 0xf000, 0x5000),
4089 UPDATE_COEF(0x4a, 0x0010, 0),
4090 UPDATE_COEF(0x4a, 0x0c00, 0x0c00),
4091 WRITE_COEF(0x45, 0x5289),
4092 UPDATE_COEF(0x4a, 0x0c00, 0),
4093 {}
4094 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004095
Takashi Iwai7639a062015-03-03 10:07:24 +01004096 switch (codec->core.vendor_id) {
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004097 case 0x10ec0255:
Kailang Yange69e7e02016-05-30 15:58:28 +08004098 alc_process_coef_fw(codec, coef0255_1);
4099 alc_process_coef_fw(codec, coef0255);
4100 break;
Kailang Yang736f20a2017-10-20 15:06:34 +08004101 case 0x10ec0236:
Kailang Yang7081adf2015-03-30 17:05:37 +08004102 case 0x10ec0256:
Kailang Yange69e7e02016-05-30 15:58:28 +08004103 alc_process_coef_fw(codec, coef0256);
Takashi Iwai54db6c32014-08-18 15:11:19 +02004104 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004105 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004106 case 0x10ec0234:
4107 case 0x10ec0274:
4108 case 0x10ec0294:
4109 alc_process_coef_fw(codec, coef0274);
4110 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004111 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004112 case 0x10ec0283:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004113 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02004114 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004115 case 0x10ec0286:
4116 case 0x10ec0288:
Kailang Yang89542932017-07-17 15:03:43 +08004117 alc_process_coef_fw(codec, coef0288);
4118 break;
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004119 case 0x10ec0298:
Kailang Yang89542932017-07-17 15:03:43 +08004120 alc_process_coef_fw(codec, coef0298);
Kailang Yangf3b70332015-04-08 15:01:17 +08004121 alc_process_coef_fw(codec, coef0288);
4122 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004123 case 0x10ec0292:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004124 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02004125 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004126 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004127 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004128 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004129 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004130 alc_process_coef_fw(codec, coef0668);
David Henningsson73bdd592013-04-15 15:44:14 +02004131 break;
Kailang Yangc2b691e2018-01-17 15:22:55 +08004132 case 0x10ec0215:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004133 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004134 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08004135 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004136 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08004137 case 0x10ec0299:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004138 alc_process_coef_fw(codec, coef0225);
4139 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08004140 case 0x10ec0867:
4141 alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
4142 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004143 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01004144 codec_dbg(codec, "Headset jack set to unplugged mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02004145}
4146
4147
4148static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin,
4149 hda_nid_t mic_pin)
4150{
Takashi Iwai54db6c32014-08-18 15:11:19 +02004151 static struct coef_fw coef0255[] = {
4152 WRITE_COEFEX(0x57, 0x03, 0x8aa6),
4153 WRITE_COEF(0x06, 0x6100), /* Set MIC2 Vref gate to normal */
4154 {}
4155 };
4156 static struct coef_fw coef0233[] = {
4157 UPDATE_COEF(0x35, 0, 1<<14),
4158 WRITE_COEF(0x06, 0x2100),
4159 WRITE_COEF(0x1a, 0x0021),
4160 WRITE_COEF(0x26, 0x008c),
4161 {}
4162 };
Kailang Yangf3b70332015-04-08 15:01:17 +08004163 static struct coef_fw coef0288[] = {
Kailang Yang89542932017-07-17 15:03:43 +08004164 UPDATE_COEF(0x4f, 0x00c0, 0),
Kailang Yangf3b70332015-04-08 15:01:17 +08004165 UPDATE_COEF(0x50, 0x2000, 0),
4166 UPDATE_COEF(0x56, 0x0006, 0),
4167 UPDATE_COEF(0x4f, 0xfcc0, 0xc400),
4168 UPDATE_COEF(0x66, 0x0008, 0x0008),
4169 UPDATE_COEF(0x67, 0x2000, 0x2000),
4170 {}
4171 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004172 static struct coef_fw coef0292[] = {
4173 WRITE_COEF(0x19, 0xa208),
4174 WRITE_COEF(0x2e, 0xacf0),
4175 {}
4176 };
4177 static struct coef_fw coef0293[] = {
4178 UPDATE_COEFEX(0x57, 0x05, 0, 1<<15|1<<13), /* SET charge pump by verb */
4179 UPDATE_COEFEX(0x57, 0x03, 1<<10, 0), /* SET EN_OSW to 0 */
4180 UPDATE_COEF(0x1a, 1<<3, 0), /* Combo JD gating without LINE1-VREFO */
4181 {}
4182 };
4183 static struct coef_fw coef0688[] = {
4184 WRITE_COEF(0xb7, 0x802b),
4185 WRITE_COEF(0xb5, 0x1040),
4186 UPDATE_COEF(0xc3, 0, 1<<12),
4187 {}
4188 };
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004189 static struct coef_fw coef0225[] = {
4190 UPDATE_COEFEX(0x57, 0x05, 1<<14, 1<<14),
4191 UPDATE_COEF(0x4a, 3<<4, 2<<4),
4192 UPDATE_COEF(0x63, 3<<14, 0),
4193 {}
4194 };
Kailang Yang71683c32017-06-20 16:33:50 +08004195 static struct coef_fw coef0274[] = {
4196 UPDATE_COEFEX(0x57, 0x05, 0x4000, 0x4000),
4197 UPDATE_COEF(0x4a, 0x0010, 0),
4198 UPDATE_COEF(0x6b, 0xf000, 0),
4199 {}
4200 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004201
Takashi Iwai7639a062015-03-03 10:07:24 +01004202 switch (codec->core.vendor_id) {
Kailang Yang736f20a2017-10-20 15:06:34 +08004203 case 0x10ec0236:
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004204 case 0x10ec0255:
Kailang Yang7081adf2015-03-30 17:05:37 +08004205 case 0x10ec0256:
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004206 alc_write_coef_idx(codec, 0x45, 0xc489);
4207 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02004208 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004209 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4210 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004211 case 0x10ec0234:
4212 case 0x10ec0274:
4213 case 0x10ec0294:
4214 alc_write_coef_idx(codec, 0x45, 0x4689);
4215 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4216 alc_process_coef_fw(codec, coef0274);
4217 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4218 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004219 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004220 case 0x10ec0283:
4221 alc_write_coef_idx(codec, 0x45, 0xc429);
4222 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02004223 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02004224 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4225 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004226 case 0x10ec0286:
4227 case 0x10ec0288:
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004228 case 0x10ec0298:
Kailang Yangf3b70332015-04-08 15:01:17 +08004229 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4230 alc_process_coef_fw(codec, coef0288);
4231 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4232 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004233 case 0x10ec0292:
4234 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02004235 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02004236 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004237 case 0x10ec0293:
4238 /* Set to TRS mode */
4239 alc_write_coef_idx(codec, 0x45, 0xc429);
4240 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02004241 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004242 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4243 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08004244 case 0x10ec0867:
4245 alc_update_coefex_idx(codec, 0x57, 0x5, 0, 1<<14);
4246 /* fallthru */
Kailang Yang9eb5d0e2017-01-17 15:40:25 +08004247 case 0x10ec0221:
David Henningsson1f8b46c2015-05-12 14:38:15 +02004248 case 0x10ec0662:
4249 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4250 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4251 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004252 case 0x10ec0668:
4253 alc_write_coef_idx(codec, 0x11, 0x0001);
4254 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02004255 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02004256 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4257 break;
Kailang Yangc2b691e2018-01-17 15:22:55 +08004258 case 0x10ec0215:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004259 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004260 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08004261 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004262 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08004263 case 0x10ec0299:
Kailang Yang5a367672017-07-21 15:23:53 +08004264 alc_process_coef_fw(codec, alc225_pre_hsmode);
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004265 alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x31<<10);
4266 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4267 alc_process_coef_fw(codec, coef0225);
4268 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4269 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004270 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01004271 codec_dbg(codec, "Headset jack set to mic-in mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02004272}
4273
4274static void alc_headset_mode_default(struct hda_codec *codec)
4275{
David Henningsson2ae95572016-02-25 09:37:05 +01004276 static struct coef_fw coef0225[] = {
Kailang Yang5a367672017-07-21 15:23:53 +08004277 UPDATE_COEF(0x45, 0x3f<<10, 0x30<<10),
4278 UPDATE_COEF(0x45, 0x3f<<10, 0x31<<10),
4279 UPDATE_COEF(0x49, 3<<8, 0<<8),
4280 UPDATE_COEF(0x4a, 3<<4, 3<<4),
4281 UPDATE_COEF(0x63, 3<<14, 0),
4282 UPDATE_COEF(0x67, 0xf000, 0x3000),
David Henningsson2ae95572016-02-25 09:37:05 +01004283 {}
4284 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004285 static struct coef_fw coef0255[] = {
4286 WRITE_COEF(0x45, 0xc089),
4287 WRITE_COEF(0x45, 0xc489),
4288 WRITE_COEFEX(0x57, 0x03, 0x8ea6),
4289 WRITE_COEF(0x49, 0x0049),
4290 {}
4291 };
4292 static struct coef_fw coef0233[] = {
4293 WRITE_COEF(0x06, 0x2100),
4294 WRITE_COEF(0x32, 0x4ea3),
4295 {}
4296 };
Kailang Yangf3b70332015-04-08 15:01:17 +08004297 static struct coef_fw coef0288[] = {
4298 UPDATE_COEF(0x4f, 0xfcc0, 0xc400), /* Set to TRS type */
4299 UPDATE_COEF(0x50, 0x2000, 0x2000),
4300 UPDATE_COEF(0x56, 0x0006, 0x0006),
4301 UPDATE_COEF(0x66, 0x0008, 0),
4302 UPDATE_COEF(0x67, 0x2000, 0),
4303 {}
4304 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004305 static struct coef_fw coef0292[] = {
4306 WRITE_COEF(0x76, 0x000e),
4307 WRITE_COEF(0x6c, 0x2400),
4308 WRITE_COEF(0x6b, 0xc429),
4309 WRITE_COEF(0x18, 0x7308),
4310 {}
4311 };
4312 static struct coef_fw coef0293[] = {
4313 UPDATE_COEF(0x4a, 0x000f, 0x000e), /* Combo Jack auto detect */
4314 WRITE_COEF(0x45, 0xC429), /* Set to TRS type */
4315 UPDATE_COEF(0x1a, 1<<3, 0), /* Combo JD gating without LINE1-VREFO */
4316 {}
4317 };
4318 static struct coef_fw coef0688[] = {
4319 WRITE_COEF(0x11, 0x0041),
4320 WRITE_COEF(0x15, 0x0d40),
4321 WRITE_COEF(0xb7, 0x802b),
4322 {}
4323 };
Kailang Yang71683c32017-06-20 16:33:50 +08004324 static struct coef_fw coef0274[] = {
4325 WRITE_COEF(0x45, 0x4289),
4326 UPDATE_COEF(0x4a, 0x0010, 0x0010),
4327 UPDATE_COEF(0x6b, 0x0f00, 0),
4328 UPDATE_COEF(0x49, 0x0300, 0x0300),
4329 {}
4330 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004331
Takashi Iwai7639a062015-03-03 10:07:24 +01004332 switch (codec->core.vendor_id) {
Kailang Yangc2b691e2018-01-17 15:22:55 +08004333 case 0x10ec0215:
David Henningsson2ae95572016-02-25 09:37:05 +01004334 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004335 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08004336 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004337 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08004338 case 0x10ec0299:
Kailang Yang5a367672017-07-21 15:23:53 +08004339 alc_process_coef_fw(codec, alc225_pre_hsmode);
David Henningsson2ae95572016-02-25 09:37:05 +01004340 alc_process_coef_fw(codec, coef0225);
4341 break;
Kailang Yang736f20a2017-10-20 15:06:34 +08004342 case 0x10ec0236:
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004343 case 0x10ec0255:
Kailang Yang7081adf2015-03-30 17:05:37 +08004344 case 0x10ec0256:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004345 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004346 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004347 case 0x10ec0234:
4348 case 0x10ec0274:
4349 case 0x10ec0294:
4350 alc_process_coef_fw(codec, coef0274);
4351 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004352 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004353 case 0x10ec0283:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004354 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02004355 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004356 case 0x10ec0286:
4357 case 0x10ec0288:
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004358 case 0x10ec0298:
Kailang Yangf3b70332015-04-08 15:01:17 +08004359 alc_process_coef_fw(codec, coef0288);
4360 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004361 case 0x10ec0292:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004362 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02004363 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004364 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004365 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004366 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004367 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004368 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02004369 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08004370 case 0x10ec0867:
4371 alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
4372 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004373 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01004374 codec_dbg(codec, "Headset jack set to headphone (default) mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02004375}
4376
4377/* Iphone type */
4378static void alc_headset_mode_ctia(struct hda_codec *codec)
4379{
Kailang Yang89542932017-07-17 15:03:43 +08004380 int val;
4381
Takashi Iwai54db6c32014-08-18 15:11:19 +02004382 static struct coef_fw coef0255[] = {
4383 WRITE_COEF(0x45, 0xd489), /* Set to CTIA type */
4384 WRITE_COEF(0x1b, 0x0c2b),
4385 WRITE_COEFEX(0x57, 0x03, 0x8ea6),
4386 {}
4387 };
Kailang Yange69e7e02016-05-30 15:58:28 +08004388 static struct coef_fw coef0256[] = {
4389 WRITE_COEF(0x45, 0xd489), /* Set to CTIA type */
4390 WRITE_COEF(0x1b, 0x0c6b),
4391 WRITE_COEFEX(0x57, 0x03, 0x8ea6),
4392 {}
4393 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004394 static struct coef_fw coef0233[] = {
4395 WRITE_COEF(0x45, 0xd429),
4396 WRITE_COEF(0x1b, 0x0c2b),
4397 WRITE_COEF(0x32, 0x4ea3),
4398 {}
4399 };
Kailang Yangf3b70332015-04-08 15:01:17 +08004400 static struct coef_fw coef0288[] = {
4401 UPDATE_COEF(0x50, 0x2000, 0x2000),
4402 UPDATE_COEF(0x56, 0x0006, 0x0006),
4403 UPDATE_COEF(0x66, 0x0008, 0),
4404 UPDATE_COEF(0x67, 0x2000, 0),
4405 {}
4406 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004407 static struct coef_fw coef0292[] = {
4408 WRITE_COEF(0x6b, 0xd429),
4409 WRITE_COEF(0x76, 0x0008),
4410 WRITE_COEF(0x18, 0x7388),
4411 {}
4412 };
4413 static struct coef_fw coef0293[] = {
4414 WRITE_COEF(0x45, 0xd429), /* Set to ctia type */
4415 UPDATE_COEF(0x10, 7<<8, 7<<8), /* SET Line1 JD to 1 */
4416 {}
4417 };
4418 static struct coef_fw coef0688[] = {
4419 WRITE_COEF(0x11, 0x0001),
4420 WRITE_COEF(0x15, 0x0d60),
4421 WRITE_COEF(0xc3, 0x0000),
4422 {}
4423 };
Kailang Yang5a367672017-07-21 15:23:53 +08004424 static struct coef_fw coef0225_1[] = {
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004425 UPDATE_COEF(0x45, 0x3f<<10, 0x35<<10),
Kailang Yang5a367672017-07-21 15:23:53 +08004426 UPDATE_COEF(0x63, 3<<14, 2<<14),
4427 {}
4428 };
4429 static struct coef_fw coef0225_2[] = {
4430 UPDATE_COEF(0x45, 0x3f<<10, 0x35<<10),
4431 UPDATE_COEF(0x63, 3<<14, 1<<14),
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004432 {}
4433 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004434
Takashi Iwai7639a062015-03-03 10:07:24 +01004435 switch (codec->core.vendor_id) {
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004436 case 0x10ec0255:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004437 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004438 break;
Kailang Yang736f20a2017-10-20 15:06:34 +08004439 case 0x10ec0236:
Kailang Yange69e7e02016-05-30 15:58:28 +08004440 case 0x10ec0256:
4441 alc_process_coef_fw(codec, coef0256);
4442 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004443 case 0x10ec0234:
4444 case 0x10ec0274:
4445 case 0x10ec0294:
4446 alc_write_coef_idx(codec, 0x45, 0xd689);
4447 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004448 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004449 case 0x10ec0283:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004450 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02004451 break;
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004452 case 0x10ec0298:
Kailang Yang89542932017-07-17 15:03:43 +08004453 val = alc_read_coef_idx(codec, 0x50);
4454 if (val & (1 << 12)) {
4455 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0020);
4456 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400);
4457 msleep(300);
4458 } else {
4459 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0010);
4460 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400);
4461 msleep(300);
4462 }
4463 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004464 case 0x10ec0286:
4465 case 0x10ec0288:
4466 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400);
4467 msleep(300);
4468 alc_process_coef_fw(codec, coef0288);
4469 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004470 case 0x10ec0292:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004471 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02004472 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004473 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004474 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004475 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004476 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004477 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02004478 break;
Kailang Yangc2b691e2018-01-17 15:22:55 +08004479 case 0x10ec0215:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004480 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004481 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08004482 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004483 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08004484 case 0x10ec0299:
Kailang Yang5a367672017-07-21 15:23:53 +08004485 val = alc_read_coef_idx(codec, 0x45);
4486 if (val & (1 << 9))
4487 alc_process_coef_fw(codec, coef0225_2);
4488 else
4489 alc_process_coef_fw(codec, coef0225_1);
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004490 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08004491 case 0x10ec0867:
4492 alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
4493 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004494 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01004495 codec_dbg(codec, "Headset jack set to iPhone-style headset mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02004496}
4497
4498/* Nokia type */
4499static void alc_headset_mode_omtp(struct hda_codec *codec)
4500{
Takashi Iwai54db6c32014-08-18 15:11:19 +02004501 static struct coef_fw coef0255[] = {
4502 WRITE_COEF(0x45, 0xe489), /* Set to OMTP Type */
4503 WRITE_COEF(0x1b, 0x0c2b),
4504 WRITE_COEFEX(0x57, 0x03, 0x8ea6),
4505 {}
4506 };
Kailang Yange69e7e02016-05-30 15:58:28 +08004507 static struct coef_fw coef0256[] = {
4508 WRITE_COEF(0x45, 0xe489), /* Set to OMTP Type */
4509 WRITE_COEF(0x1b, 0x0c6b),
4510 WRITE_COEFEX(0x57, 0x03, 0x8ea6),
4511 {}
4512 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004513 static struct coef_fw coef0233[] = {
4514 WRITE_COEF(0x45, 0xe429),
4515 WRITE_COEF(0x1b, 0x0c2b),
4516 WRITE_COEF(0x32, 0x4ea3),
4517 {}
4518 };
Kailang Yangf3b70332015-04-08 15:01:17 +08004519 static struct coef_fw coef0288[] = {
4520 UPDATE_COEF(0x50, 0x2000, 0x2000),
4521 UPDATE_COEF(0x56, 0x0006, 0x0006),
4522 UPDATE_COEF(0x66, 0x0008, 0),
4523 UPDATE_COEF(0x67, 0x2000, 0),
4524 {}
4525 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004526 static struct coef_fw coef0292[] = {
4527 WRITE_COEF(0x6b, 0xe429),
4528 WRITE_COEF(0x76, 0x0008),
4529 WRITE_COEF(0x18, 0x7388),
4530 {}
4531 };
4532 static struct coef_fw coef0293[] = {
4533 WRITE_COEF(0x45, 0xe429), /* Set to omtp type */
4534 UPDATE_COEF(0x10, 7<<8, 7<<8), /* SET Line1 JD to 1 */
4535 {}
4536 };
4537 static struct coef_fw coef0688[] = {
4538 WRITE_COEF(0x11, 0x0001),
4539 WRITE_COEF(0x15, 0x0d50),
4540 WRITE_COEF(0xc3, 0x0000),
4541 {}
4542 };
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004543 static struct coef_fw coef0225[] = {
4544 UPDATE_COEF(0x45, 0x3f<<10, 0x39<<10),
Kailang Yang5a367672017-07-21 15:23:53 +08004545 UPDATE_COEF(0x63, 3<<14, 2<<14),
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004546 {}
4547 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004548
Takashi Iwai7639a062015-03-03 10:07:24 +01004549 switch (codec->core.vendor_id) {
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004550 case 0x10ec0255:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004551 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004552 break;
Kailang Yang736f20a2017-10-20 15:06:34 +08004553 case 0x10ec0236:
Kailang Yange69e7e02016-05-30 15:58:28 +08004554 case 0x10ec0256:
4555 alc_process_coef_fw(codec, coef0256);
4556 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004557 case 0x10ec0234:
4558 case 0x10ec0274:
4559 case 0x10ec0294:
4560 alc_write_coef_idx(codec, 0x45, 0xe689);
4561 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004562 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004563 case 0x10ec0283:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004564 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02004565 break;
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004566 case 0x10ec0298:
4567 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0010);/* Headset output enable */
Kailang Yang89542932017-07-17 15:03:43 +08004568 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xe400);
4569 msleep(300);
4570 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004571 case 0x10ec0286:
4572 case 0x10ec0288:
4573 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xe400);
4574 msleep(300);
4575 alc_process_coef_fw(codec, coef0288);
4576 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004577 case 0x10ec0292:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004578 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02004579 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004580 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004581 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004582 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004583 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004584 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02004585 break;
Kailang Yangc2b691e2018-01-17 15:22:55 +08004586 case 0x10ec0215:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004587 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004588 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08004589 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004590 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08004591 case 0x10ec0299:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004592 alc_process_coef_fw(codec, coef0225);
4593 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004594 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01004595 codec_dbg(codec, "Headset jack set to Nokia-style headset mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02004596}
4597
4598static void alc_determine_headset_type(struct hda_codec *codec)
4599{
4600 int val;
4601 bool is_ctia = false;
4602 struct alc_spec *spec = codec->spec;
Takashi Iwai54db6c32014-08-18 15:11:19 +02004603 static struct coef_fw coef0255[] = {
4604 WRITE_COEF(0x45, 0xd089), /* combo jack auto switch control(Check type)*/
4605 WRITE_COEF(0x49, 0x0149), /* combo jack auto switch control(Vref
4606 conteol) */
4607 {}
4608 };
Kailang Yangf3b70332015-04-08 15:01:17 +08004609 static struct coef_fw coef0288[] = {
4610 UPDATE_COEF(0x4f, 0xfcc0, 0xd400), /* Check Type */
4611 {}
4612 };
Kailang Yang89542932017-07-17 15:03:43 +08004613 static struct coef_fw coef0298[] = {
4614 UPDATE_COEF(0x50, 0x2000, 0x2000),
4615 UPDATE_COEF(0x56, 0x0006, 0x0006),
4616 UPDATE_COEF(0x66, 0x0008, 0),
4617 UPDATE_COEF(0x67, 0x2000, 0),
4618 UPDATE_COEF(0x19, 0x1300, 0x1300),
4619 {}
4620 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004621 static struct coef_fw coef0293[] = {
4622 UPDATE_COEF(0x4a, 0x000f, 0x0008), /* Combo Jack auto detect */
4623 WRITE_COEF(0x45, 0xD429), /* Set to ctia type */
4624 {}
4625 };
4626 static struct coef_fw coef0688[] = {
4627 WRITE_COEF(0x11, 0x0001),
4628 WRITE_COEF(0xb7, 0x802b),
4629 WRITE_COEF(0x15, 0x0d60),
4630 WRITE_COEF(0xc3, 0x0c00),
4631 {}
4632 };
Kailang Yang71683c32017-06-20 16:33:50 +08004633 static struct coef_fw coef0274[] = {
4634 UPDATE_COEF(0x4a, 0x0010, 0),
4635 UPDATE_COEF(0x4a, 0x8000, 0),
4636 WRITE_COEF(0x45, 0xd289),
4637 UPDATE_COEF(0x49, 0x0300, 0x0300),
4638 {}
4639 };
David Henningsson73bdd592013-04-15 15:44:14 +02004640
Takashi Iwai7639a062015-03-03 10:07:24 +01004641 switch (codec->core.vendor_id) {
Kailang Yang736f20a2017-10-20 15:06:34 +08004642 case 0x10ec0236:
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004643 case 0x10ec0255:
Kailang Yang7081adf2015-03-30 17:05:37 +08004644 case 0x10ec0256:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004645 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004646 msleep(300);
4647 val = alc_read_coef_idx(codec, 0x46);
4648 is_ctia = (val & 0x0070) == 0x0070;
4649 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004650 case 0x10ec0234:
4651 case 0x10ec0274:
4652 case 0x10ec0294:
4653 alc_process_coef_fw(codec, coef0274);
4654 msleep(80);
4655 val = alc_read_coef_idx(codec, 0x46);
4656 is_ctia = (val & 0x00f0) == 0x00f0;
4657 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004658 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004659 case 0x10ec0283:
4660 alc_write_coef_idx(codec, 0x45, 0xd029);
4661 msleep(300);
4662 val = alc_read_coef_idx(codec, 0x46);
4663 is_ctia = (val & 0x0070) == 0x0070;
4664 break;
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004665 case 0x10ec0298:
Kailang Yang89542932017-07-17 15:03:43 +08004666 snd_hda_codec_write(codec, 0x21, 0,
4667 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
4668 msleep(100);
4669 snd_hda_codec_write(codec, 0x21, 0,
4670 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
4671 msleep(200);
4672
4673 val = alc_read_coef_idx(codec, 0x50);
4674 if (val & (1 << 12)) {
4675 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0020);
4676 alc_process_coef_fw(codec, coef0288);
4677 msleep(350);
4678 val = alc_read_coef_idx(codec, 0x50);
4679 is_ctia = (val & 0x0070) == 0x0070;
4680 } else {
4681 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0010);
4682 alc_process_coef_fw(codec, coef0288);
4683 msleep(350);
4684 val = alc_read_coef_idx(codec, 0x50);
4685 is_ctia = (val & 0x0070) == 0x0070;
4686 }
4687 alc_process_coef_fw(codec, coef0298);
4688 snd_hda_codec_write(codec, 0x21, 0,
4689 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP);
4690 msleep(75);
4691 snd_hda_codec_write(codec, 0x21, 0,
4692 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
4693 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004694 case 0x10ec0286:
4695 case 0x10ec0288:
4696 alc_process_coef_fw(codec, coef0288);
4697 msleep(350);
4698 val = alc_read_coef_idx(codec, 0x50);
4699 is_ctia = (val & 0x0070) == 0x0070;
4700 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004701 case 0x10ec0292:
4702 alc_write_coef_idx(codec, 0x6b, 0xd429);
4703 msleep(300);
4704 val = alc_read_coef_idx(codec, 0x6c);
4705 is_ctia = (val & 0x001c) == 0x001c;
4706 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004707 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004708 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004709 msleep(300);
4710 val = alc_read_coef_idx(codec, 0x46);
4711 is_ctia = (val & 0x0070) == 0x0070;
4712 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004713 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004714 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02004715 msleep(300);
4716 val = alc_read_coef_idx(codec, 0xbe);
4717 is_ctia = (val & 0x1c02) == 0x1c02;
4718 break;
Kailang Yangc2b691e2018-01-17 15:22:55 +08004719 case 0x10ec0215:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004720 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004721 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08004722 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004723 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08004724 case 0x10ec0299:
Kailang Yangda911b12018-01-05 16:50:08 +08004725 snd_hda_codec_write(codec, 0x21, 0,
4726 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
4727 msleep(80);
4728 snd_hda_codec_write(codec, 0x21, 0,
4729 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
4730
Kailang Yang5a367672017-07-21 15:23:53 +08004731 alc_process_coef_fw(codec, alc225_pre_hsmode);
4732 alc_update_coef_idx(codec, 0x67, 0xf000, 0x1000);
4733 val = alc_read_coef_idx(codec, 0x45);
4734 if (val & (1 << 9)) {
4735 alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x34<<10);
4736 alc_update_coef_idx(codec, 0x49, 3<<8, 2<<8);
4737 msleep(800);
4738 val = alc_read_coef_idx(codec, 0x46);
4739 is_ctia = (val & 0x00f0) == 0x00f0;
4740 } else {
4741 alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x34<<10);
4742 alc_update_coef_idx(codec, 0x49, 3<<8, 1<<8);
4743 msleep(800);
4744 val = alc_read_coef_idx(codec, 0x46);
4745 is_ctia = (val & 0x00f0) == 0x00f0;
4746 }
4747 alc_update_coef_idx(codec, 0x4a, 7<<6, 7<<6);
4748 alc_update_coef_idx(codec, 0x4a, 3<<4, 3<<4);
4749 alc_update_coef_idx(codec, 0x67, 0xf000, 0x3000);
Kailang Yangda911b12018-01-05 16:50:08 +08004750
4751 snd_hda_codec_write(codec, 0x21, 0,
4752 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
4753 msleep(80);
4754 snd_hda_codec_write(codec, 0x21, 0,
4755 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004756 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08004757 case 0x10ec0867:
4758 is_ctia = true;
4759 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004760 }
4761
Takashi Iwai4e76a882014-02-25 12:21:03 +01004762 codec_dbg(codec, "Headset jack detected iPhone-style headset: %s\n",
David Henningsson73bdd592013-04-15 15:44:14 +02004763 is_ctia ? "yes" : "no");
4764 spec->current_headset_type = is_ctia ? ALC_HEADSET_TYPE_CTIA : ALC_HEADSET_TYPE_OMTP;
4765}
4766
4767static void alc_update_headset_mode(struct hda_codec *codec)
4768{
4769 struct alc_spec *spec = codec->spec;
4770
4771 hda_nid_t mux_pin = spec->gen.imux_pins[spec->gen.cur_mux[0]];
4772 hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
4773
4774 int new_headset_mode;
4775
4776 if (!snd_hda_jack_detect(codec, hp_pin))
4777 new_headset_mode = ALC_HEADSET_MODE_UNPLUGGED;
4778 else if (mux_pin == spec->headset_mic_pin)
4779 new_headset_mode = ALC_HEADSET_MODE_HEADSET;
4780 else if (mux_pin == spec->headphone_mic_pin)
4781 new_headset_mode = ALC_HEADSET_MODE_MIC;
4782 else
4783 new_headset_mode = ALC_HEADSET_MODE_HEADPHONE;
4784
David Henningsson5959a6b2013-11-12 11:10:57 +01004785 if (new_headset_mode == spec->current_headset_mode) {
4786 snd_hda_gen_update_outputs(codec);
David Henningsson73bdd592013-04-15 15:44:14 +02004787 return;
David Henningsson5959a6b2013-11-12 11:10:57 +01004788 }
David Henningsson73bdd592013-04-15 15:44:14 +02004789
4790 switch (new_headset_mode) {
4791 case ALC_HEADSET_MODE_UNPLUGGED:
4792 alc_headset_mode_unplugged(codec);
4793 spec->gen.hp_jack_present = false;
4794 break;
4795 case ALC_HEADSET_MODE_HEADSET:
4796 if (spec->current_headset_type == ALC_HEADSET_TYPE_UNKNOWN)
4797 alc_determine_headset_type(codec);
4798 if (spec->current_headset_type == ALC_HEADSET_TYPE_CTIA)
4799 alc_headset_mode_ctia(codec);
4800 else if (spec->current_headset_type == ALC_HEADSET_TYPE_OMTP)
4801 alc_headset_mode_omtp(codec);
4802 spec->gen.hp_jack_present = true;
4803 break;
4804 case ALC_HEADSET_MODE_MIC:
4805 alc_headset_mode_mic_in(codec, hp_pin, spec->headphone_mic_pin);
4806 spec->gen.hp_jack_present = false;
4807 break;
4808 case ALC_HEADSET_MODE_HEADPHONE:
4809 alc_headset_mode_default(codec);
4810 spec->gen.hp_jack_present = true;
4811 break;
4812 }
4813 if (new_headset_mode != ALC_HEADSET_MODE_MIC) {
4814 snd_hda_set_pin_ctl_cache(codec, hp_pin,
4815 AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN);
David Henningsson1f8b46c2015-05-12 14:38:15 +02004816 if (spec->headphone_mic_pin && spec->headphone_mic_pin != hp_pin)
David Henningsson73bdd592013-04-15 15:44:14 +02004817 snd_hda_set_pin_ctl_cache(codec, spec->headphone_mic_pin,
4818 PIN_VREFHIZ);
4819 }
4820 spec->current_headset_mode = new_headset_mode;
4821
4822 snd_hda_gen_update_outputs(codec);
4823}
4824
4825static void alc_update_headset_mode_hook(struct hda_codec *codec,
Takashi Iwai7fe30712014-01-30 17:59:02 +01004826 struct snd_kcontrol *kcontrol,
4827 struct snd_ctl_elem_value *ucontrol)
David Henningsson73bdd592013-04-15 15:44:14 +02004828{
4829 alc_update_headset_mode(codec);
4830}
4831
Takashi Iwai1a4f69d2014-09-11 15:22:46 +02004832static void alc_update_headset_jack_cb(struct hda_codec *codec,
4833 struct hda_jack_callback *jack)
David Henningsson73bdd592013-04-15 15:44:14 +02004834{
4835 struct alc_spec *spec = codec->spec;
David Henningsson5db4d342013-11-22 12:17:06 +01004836 spec->current_headset_type = ALC_HEADSET_TYPE_UNKNOWN;
David Henningsson73bdd592013-04-15 15:44:14 +02004837 snd_hda_gen_hp_automute(codec, jack);
4838}
4839
4840static void alc_probe_headset_mode(struct hda_codec *codec)
4841{
4842 int i;
4843 struct alc_spec *spec = codec->spec;
4844 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
4845
4846 /* Find mic pins */
4847 for (i = 0; i < cfg->num_inputs; i++) {
4848 if (cfg->inputs[i].is_headset_mic && !spec->headset_mic_pin)
4849 spec->headset_mic_pin = cfg->inputs[i].pin;
4850 if (cfg->inputs[i].is_headphone_mic && !spec->headphone_mic_pin)
4851 spec->headphone_mic_pin = cfg->inputs[i].pin;
4852 }
4853
Takashi Iwai0bed2aa2018-06-19 12:45:53 +02004854 WARN_ON(spec->gen.cap_sync_hook);
David Henningsson73bdd592013-04-15 15:44:14 +02004855 spec->gen.cap_sync_hook = alc_update_headset_mode_hook;
4856 spec->gen.automute_hook = alc_update_headset_mode;
4857 spec->gen.hp_automute_hook = alc_update_headset_jack_cb;
4858}
4859
4860static void alc_fixup_headset_mode(struct hda_codec *codec,
4861 const struct hda_fixup *fix, int action)
4862{
4863 struct alc_spec *spec = codec->spec;
4864
4865 switch (action) {
4866 case HDA_FIXUP_ACT_PRE_PROBE:
4867 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC | HDA_PINCFG_HEADPHONE_MIC;
4868 break;
4869 case HDA_FIXUP_ACT_PROBE:
4870 alc_probe_headset_mode(codec);
4871 break;
4872 case HDA_FIXUP_ACT_INIT:
4873 spec->current_headset_mode = 0;
4874 alc_update_headset_mode(codec);
4875 break;
4876 }
4877}
4878
4879static void alc_fixup_headset_mode_no_hp_mic(struct hda_codec *codec,
4880 const struct hda_fixup *fix, int action)
4881{
4882 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4883 struct alc_spec *spec = codec->spec;
4884 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
4885 }
4886 else
4887 alc_fixup_headset_mode(codec, fix, action);
4888}
4889
Kailang Yang31278992014-03-03 15:27:22 +08004890static void alc255_set_default_jack_type(struct hda_codec *codec)
4891{
4892 /* Set to iphone type */
Kailang Yange69e7e02016-05-30 15:58:28 +08004893 static struct coef_fw alc255fw[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004894 WRITE_COEF(0x1b, 0x880b),
4895 WRITE_COEF(0x45, 0xd089),
4896 WRITE_COEF(0x1b, 0x080b),
4897 WRITE_COEF(0x46, 0x0004),
4898 WRITE_COEF(0x1b, 0x0c0b),
4899 {}
4900 };
Kailang Yange69e7e02016-05-30 15:58:28 +08004901 static struct coef_fw alc256fw[] = {
4902 WRITE_COEF(0x1b, 0x884b),
4903 WRITE_COEF(0x45, 0xd089),
4904 WRITE_COEF(0x1b, 0x084b),
4905 WRITE_COEF(0x46, 0x0004),
4906 WRITE_COEF(0x1b, 0x0c4b),
4907 {}
4908 };
4909 switch (codec->core.vendor_id) {
4910 case 0x10ec0255:
4911 alc_process_coef_fw(codec, alc255fw);
4912 break;
Kailang Yang736f20a2017-10-20 15:06:34 +08004913 case 0x10ec0236:
Kailang Yange69e7e02016-05-30 15:58:28 +08004914 case 0x10ec0256:
4915 alc_process_coef_fw(codec, alc256fw);
4916 break;
4917 }
Kailang Yang31278992014-03-03 15:27:22 +08004918 msleep(30);
4919}
4920
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004921static void alc_fixup_headset_mode_alc255(struct hda_codec *codec,
4922 const struct hda_fixup *fix, int action)
4923{
4924 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Kailang Yang31278992014-03-03 15:27:22 +08004925 alc255_set_default_jack_type(codec);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004926 }
4927 alc_fixup_headset_mode(codec, fix, action);
4928}
4929
Kailang Yang31278992014-03-03 15:27:22 +08004930static void alc_fixup_headset_mode_alc255_no_hp_mic(struct hda_codec *codec,
4931 const struct hda_fixup *fix, int action)
4932{
4933 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4934 struct alc_spec *spec = codec->spec;
4935 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
4936 alc255_set_default_jack_type(codec);
4937 }
4938 else
4939 alc_fixup_headset_mode(codec, fix, action);
4940}
4941
Kailang Yange1e62b92015-04-08 16:01:22 +08004942static void alc288_update_headset_jack_cb(struct hda_codec *codec,
4943 struct hda_jack_callback *jack)
4944{
4945 struct alc_spec *spec = codec->spec;
4946 int present;
4947
4948 alc_update_headset_jack_cb(codec, jack);
4949 /* Headset Mic enable or disable, only for Dell Dino */
4950 present = spec->gen.hp_jack_present ? 0x40 : 0;
4951 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
4952 present);
4953}
4954
4955static void alc_fixup_headset_mode_dell_alc288(struct hda_codec *codec,
4956 const struct hda_fixup *fix, int action)
4957{
4958 alc_fixup_headset_mode(codec, fix, action);
4959 if (action == HDA_FIXUP_ACT_PROBE) {
4960 struct alc_spec *spec = codec->spec;
4961 spec->gen.hp_automute_hook = alc288_update_headset_jack_cb;
4962 }
4963}
4964
Hui Wang493a52a2014-01-14 14:07:36 +08004965static void alc_fixup_auto_mute_via_amp(struct hda_codec *codec,
4966 const struct hda_fixup *fix, int action)
4967{
4968 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4969 struct alc_spec *spec = codec->spec;
4970 spec->gen.auto_mute_via_amp = 1;
4971 }
4972}
4973
Takashi Iwai9b745ab2014-03-07 08:37:19 +01004974static void alc_no_shutup(struct hda_codec *codec)
4975{
4976}
4977
4978static void alc_fixup_no_shutup(struct hda_codec *codec,
4979 const struct hda_fixup *fix, int action)
4980{
Gabriele Mazzotta972aa2c2016-12-24 19:50:00 +01004981 if (action == HDA_FIXUP_ACT_PROBE) {
Takashi Iwai9b745ab2014-03-07 08:37:19 +01004982 struct alc_spec *spec = codec->spec;
4983 spec->shutup = alc_no_shutup;
4984 }
4985}
4986
Gabriele Mazzotta5e6db662014-05-20 18:58:26 +02004987static void alc_fixup_disable_aamix(struct hda_codec *codec,
4988 const struct hda_fixup *fix, int action)
4989{
4990 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4991 struct alc_spec *spec = codec->spec;
4992 /* Disable AA-loopback as it causes white noise */
4993 spec->gen.mixer_nid = 0;
4994 }
4995}
4996
Takashi Iwai7f57d802015-09-24 17:36:51 +02004997/* fixup for Thinkpad docks: add dock pins, avoid HP parser fixup */
4998static void alc_fixup_tpt440_dock(struct hda_codec *codec,
4999 const struct hda_fixup *fix, int action)
5000{
5001 static const struct hda_pintbl pincfgs[] = {
5002 { 0x16, 0x21211010 }, /* dock headphone */
5003 { 0x19, 0x21a11010 }, /* dock mic */
5004 { }
5005 };
5006 struct alc_spec *spec = codec->spec;
5007
5008 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai70a09762015-12-15 14:59:58 +01005009 spec->reboot_notify = alc_d3_at_reboot; /* reduce noise */
Takashi Iwai7f57d802015-09-24 17:36:51 +02005010 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
5011 codec->power_save_node = 0; /* avoid click noises */
5012 snd_hda_apply_pincfgs(codec, pincfgs);
5013 }
5014}
5015
Kailang Yang61fcf8e2018-02-02 15:26:46 +08005016static void alc_fixup_tpt470_dock(struct hda_codec *codec,
5017 const struct hda_fixup *fix, int action)
5018{
5019 static const struct hda_pintbl pincfgs[] = {
5020 { 0x17, 0x21211010 }, /* dock headphone */
5021 { 0x19, 0x21a11010 }, /* dock mic */
5022 { }
5023 };
5024 struct alc_spec *spec = codec->spec;
5025
5026 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5027 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
Takashi Iwai71db96d2018-02-26 15:36:38 +01005028 snd_hda_apply_pincfgs(codec, pincfgs);
5029 } else if (action == HDA_FIXUP_ACT_INIT) {
Kailang Yang61fcf8e2018-02-02 15:26:46 +08005030 /* Enable DOCK device */
5031 snd_hda_codec_write(codec, 0x17, 0,
5032 AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0);
5033 /* Enable DOCK device */
5034 snd_hda_codec_write(codec, 0x19, 0,
5035 AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0);
Kailang Yang61fcf8e2018-02-02 15:26:46 +08005036 }
5037}
5038
Gabriele Mazzotta9476d3692015-04-19 19:00:40 +02005039static void alc_shutup_dell_xps13(struct hda_codec *codec)
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02005040{
5041 struct alc_spec *spec = codec->spec;
Gabriele Mazzotta9476d3692015-04-19 19:00:40 +02005042 int hp_pin = spec->gen.autocfg.hp_pins[0];
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02005043
Gabriele Mazzotta9476d3692015-04-19 19:00:40 +02005044 /* Prevent pop noises when headphones are plugged in */
5045 snd_hda_codec_write(codec, hp_pin, 0,
5046 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
5047 msleep(20);
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02005048}
5049
5050static void alc_fixup_dell_xps13(struct hda_codec *codec,
5051 const struct hda_fixup *fix, int action)
5052{
Takashi Iwai3e1b0c42015-04-27 10:43:22 +02005053 struct alc_spec *spec = codec->spec;
5054 struct hda_input_mux *imux = &spec->gen.input_mux;
5055 int i;
Gabriele Mazzottaf38663a2014-08-08 19:34:40 +02005056
Takashi Iwai3e1b0c42015-04-27 10:43:22 +02005057 switch (action) {
5058 case HDA_FIXUP_ACT_PRE_PROBE:
5059 /* mic pin 0x19 must be initialized with Vref Hi-Z, otherwise
5060 * it causes a click noise at start up
5061 */
5062 snd_hda_codec_set_pin_target(codec, 0x19, PIN_VREFHIZ);
5063 break;
5064 case HDA_FIXUP_ACT_PROBE:
Gabriele Mazzotta9476d3692015-04-19 19:00:40 +02005065 spec->shutup = alc_shutup_dell_xps13;
Gabriele Mazzottaf38663a2014-08-08 19:34:40 +02005066
5067 /* Make the internal mic the default input source. */
5068 for (i = 0; i < imux->num_items; i++) {
5069 if (spec->gen.imux_pins[i] == 0x12) {
5070 spec->gen.cur_mux[0] = i;
5071 break;
5072 }
5073 }
Takashi Iwai3e1b0c42015-04-27 10:43:22 +02005074 break;
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02005075 }
5076}
5077
David Henningsson1f8b46c2015-05-12 14:38:15 +02005078static void alc_fixup_headset_mode_alc662(struct hda_codec *codec,
5079 const struct hda_fixup *fix, int action)
5080{
5081 struct alc_spec *spec = codec->spec;
5082
5083 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5084 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
5085 spec->gen.hp_mic = 1; /* Mic-in is same pin as headphone */
David Henningssonb40eda62015-05-28 09:40:23 +02005086
5087 /* Disable boost for mic-in permanently. (This code is only called
5088 from quirks that guarantee that the headphone is at NID 0x1b.) */
5089 snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000);
5090 snd_hda_override_wcaps(codec, 0x1b, get_wcaps(codec, 0x1b) & ~AC_WCAP_IN_AMP);
David Henningsson1f8b46c2015-05-12 14:38:15 +02005091 } else
5092 alc_fixup_headset_mode(codec, fix, action);
5093}
5094
David Henningsson73bdd592013-04-15 15:44:14 +02005095static void alc_fixup_headset_mode_alc668(struct hda_codec *codec,
5096 const struct hda_fixup *fix, int action)
5097{
5098 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
David Henningsson73bdd592013-04-15 15:44:14 +02005099 alc_write_coef_idx(codec, 0xc4, 0x8000);
Takashi Iwai98b24882014-08-18 13:47:50 +02005100 alc_update_coef_idx(codec, 0xc2, ~0xfe, 0);
David Henningsson73bdd592013-04-15 15:44:14 +02005101 snd_hda_set_pin_ctl_cache(codec, 0x18, 0);
5102 }
5103 alc_fixup_headset_mode(codec, fix, action);
5104}
5105
Chih-Chung Changbde7bc62013-08-05 16:38:42 +08005106/* Returns the nid of the external mic input pin, or 0 if it cannot be found. */
5107static int find_ext_mic_pin(struct hda_codec *codec)
5108{
5109 struct alc_spec *spec = codec->spec;
5110 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
5111 hda_nid_t nid;
5112 unsigned int defcfg;
5113 int i;
5114
5115 for (i = 0; i < cfg->num_inputs; i++) {
5116 if (cfg->inputs[i].type != AUTO_PIN_MIC)
5117 continue;
5118 nid = cfg->inputs[i].pin;
5119 defcfg = snd_hda_codec_get_pincfg(codec, nid);
5120 if (snd_hda_get_input_pin_attr(defcfg) == INPUT_PIN_ATTR_INT)
5121 continue;
5122 return nid;
5123 }
5124
5125 return 0;
5126}
5127
Dylan Reid08a978d2012-11-18 22:56:40 -08005128static void alc271_hp_gate_mic_jack(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01005129 const struct hda_fixup *fix,
Dylan Reid08a978d2012-11-18 22:56:40 -08005130 int action)
5131{
5132 struct alc_spec *spec = codec->spec;
5133
Takashi Iwai0db75792013-01-23 13:57:20 +01005134 if (action == HDA_FIXUP_ACT_PROBE) {
Chih-Chung Changbde7bc62013-08-05 16:38:42 +08005135 int mic_pin = find_ext_mic_pin(codec);
5136 int hp_pin = spec->gen.autocfg.hp_pins[0];
5137
5138 if (snd_BUG_ON(!mic_pin || !hp_pin))
Takashi Iwai0db75792013-01-23 13:57:20 +01005139 return;
Chih-Chung Changbde7bc62013-08-05 16:38:42 +08005140 snd_hda_jack_set_gating_jack(codec, mic_pin, hp_pin);
Takashi Iwai0db75792013-01-23 13:57:20 +01005141 }
Dylan Reid08a978d2012-11-18 22:56:40 -08005142}
David Henningsson693b6132012-06-22 19:12:10 +02005143
David Henningsson3e0d6112013-04-22 14:30:14 +02005144static void alc269_fixup_limit_int_mic_boost(struct hda_codec *codec,
5145 const struct hda_fixup *fix,
5146 int action)
5147{
5148 struct alc_spec *spec = codec->spec;
5149 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
5150 int i;
5151
5152 /* The mic boosts on level 2 and 3 are too noisy
5153 on the internal mic input.
5154 Therefore limit the boost to 0 or 1. */
5155
5156 if (action != HDA_FIXUP_ACT_PROBE)
5157 return;
5158
5159 for (i = 0; i < cfg->num_inputs; i++) {
5160 hda_nid_t nid = cfg->inputs[i].pin;
5161 unsigned int defcfg;
5162 if (cfg->inputs[i].type != AUTO_PIN_MIC)
5163 continue;
5164 defcfg = snd_hda_codec_get_pincfg(codec, nid);
5165 if (snd_hda_get_input_pin_attr(defcfg) != INPUT_PIN_ATTR_INT)
5166 continue;
5167
5168 snd_hda_override_amp_caps(codec, nid, HDA_INPUT,
5169 (0x00 << AC_AMPCAP_OFFSET_SHIFT) |
5170 (0x01 << AC_AMPCAP_NUM_STEPS_SHIFT) |
5171 (0x2f << AC_AMPCAP_STEP_SIZE_SHIFT) |
5172 (0 << AC_AMPCAP_MUTE_SHIFT));
5173 }
5174}
5175
Kailang Yangcd217a62013-08-22 10:15:24 +02005176static void alc283_hp_automute_hook(struct hda_codec *codec,
Takashi Iwai1a4f69d2014-09-11 15:22:46 +02005177 struct hda_jack_callback *jack)
Kailang Yangcd217a62013-08-22 10:15:24 +02005178{
5179 struct alc_spec *spec = codec->spec;
5180 int vref;
5181
5182 msleep(200);
5183 snd_hda_gen_hp_automute(codec, jack);
5184
5185 vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0;
5186
5187 msleep(600);
5188 snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5189 vref);
5190}
5191
Kailang Yangcd217a62013-08-22 10:15:24 +02005192static void alc283_fixup_chromebook(struct hda_codec *codec,
5193 const struct hda_fixup *fix, int action)
5194{
5195 struct alc_spec *spec = codec->spec;
Kailang Yangcd217a62013-08-22 10:15:24 +02005196
5197 switch (action) {
5198 case HDA_FIXUP_ACT_PRE_PROBE:
Kailang Yang0202e992013-12-02 15:20:15 +08005199 snd_hda_override_wcaps(codec, 0x03, 0);
Takashi Iwaid2e92702013-10-30 07:50:53 +01005200 /* Disable AA-loopback as it causes white noise */
5201 spec->gen.mixer_nid = 0;
Kailang Yang38070212013-11-01 15:57:35 +08005202 break;
5203 case HDA_FIXUP_ACT_INIT:
Kailang Yangde9481c2014-04-07 16:41:52 +08005204 /* MIC2-VREF control */
5205 /* Set to manual mode */
Takashi Iwai98b24882014-08-18 13:47:50 +02005206 alc_update_coef_idx(codec, 0x06, 0x000c, 0);
Kailang Yang0202e992013-12-02 15:20:15 +08005207 /* Enable Line1 input control by verb */
Takashi Iwai98b24882014-08-18 13:47:50 +02005208 alc_update_coef_idx(codec, 0x1a, 0, 1 << 4);
Kailang Yang0202e992013-12-02 15:20:15 +08005209 break;
5210 }
5211}
5212
5213static void alc283_fixup_sense_combo_jack(struct hda_codec *codec,
5214 const struct hda_fixup *fix, int action)
5215{
5216 struct alc_spec *spec = codec->spec;
Kailang Yang0202e992013-12-02 15:20:15 +08005217
5218 switch (action) {
5219 case HDA_FIXUP_ACT_PRE_PROBE:
Kailang Yangcd217a62013-08-22 10:15:24 +02005220 spec->gen.hp_automute_hook = alc283_hp_automute_hook;
5221 break;
5222 case HDA_FIXUP_ACT_INIT:
5223 /* MIC2-VREF control */
5224 /* Set to manual mode */
Takashi Iwai98b24882014-08-18 13:47:50 +02005225 alc_update_coef_idx(codec, 0x06, 0x000c, 0);
Kailang Yangcd217a62013-08-22 10:15:24 +02005226 break;
5227 }
5228}
5229
Takashi Iwai7bba2152013-09-06 15:45:38 +02005230/* mute tablet speaker pin (0x14) via dock plugging in addition */
5231static void asus_tx300_automute(struct hda_codec *codec)
5232{
5233 struct alc_spec *spec = codec->spec;
5234 snd_hda_gen_update_outputs(codec);
5235 if (snd_hda_jack_detect(codec, 0x1b))
5236 spec->gen.mute_bits |= (1ULL << 0x14);
5237}
5238
5239static void alc282_fixup_asus_tx300(struct hda_codec *codec,
5240 const struct hda_fixup *fix, int action)
5241{
5242 struct alc_spec *spec = codec->spec;
5243 /* TX300 needs to set up GPIO2 for the speaker amp */
5244 static const struct hda_verb gpio2_verbs[] = {
5245 { 0x01, AC_VERB_SET_GPIO_MASK, 0x04 },
5246 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04 },
5247 { 0x01, AC_VERB_SET_GPIO_DATA, 0x04 },
5248 {}
5249 };
5250 static const struct hda_pintbl dock_pins[] = {
5251 { 0x1b, 0x21114000 }, /* dock speaker pin */
5252 {}
5253 };
Takashi Iwai7bba2152013-09-06 15:45:38 +02005254
5255 switch (action) {
5256 case HDA_FIXUP_ACT_PRE_PROBE:
Takashi Iwai1c76aa52018-06-21 16:37:54 +02005257 spec->init_amp = ALC_INIT_DEFAULT;
Takashi Iwai7bba2152013-09-06 15:45:38 +02005258 snd_hda_add_verbs(codec, gpio2_verbs);
5259 snd_hda_apply_pincfgs(codec, dock_pins);
5260 spec->gen.auto_mute_via_amp = 1;
5261 spec->gen.automute_hook = asus_tx300_automute;
5262 snd_hda_jack_detect_enable_callback(codec, 0x1b,
Takashi Iwai7bba2152013-09-06 15:45:38 +02005263 snd_hda_gen_hp_automute);
5264 break;
Takashi Iwai5579cd62018-06-19 22:22:41 +02005265 case HDA_FIXUP_ACT_PROBE:
5266 spec->init_amp = ALC_INIT_DEFAULT;
5267 break;
Takashi Iwai7bba2152013-09-06 15:45:38 +02005268 case HDA_FIXUP_ACT_BUILD:
5269 /* this is a bit tricky; give more sane names for the main
5270 * (tablet) speaker and the dock speaker, respectively
5271 */
Takashi Iwai56798e62017-04-11 08:10:52 +02005272 rename_ctl(codec, "Speaker Playback Switch",
5273 "Dock Speaker Playback Switch");
5274 rename_ctl(codec, "Bass Speaker Playback Switch",
5275 "Speaker Playback Switch");
Takashi Iwai7bba2152013-09-06 15:45:38 +02005276 break;
5277 }
5278}
5279
David Henningsson338cae52013-10-07 10:39:59 +02005280static void alc290_fixup_mono_speakers(struct hda_codec *codec,
5281 const struct hda_fixup *fix, int action)
5282{
David Henningsson0f4881d2013-12-20 16:08:13 +01005283 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5284 /* DAC node 0x03 is giving mono output. We therefore want to
5285 make sure 0x14 (front speaker) and 0x15 (headphones) use the
5286 stereo DAC, while leaving 0x17 (bass speaker) for node 0x03. */
5287 hda_nid_t conn1[2] = { 0x0c };
5288 snd_hda_override_conn_list(codec, 0x14, 1, conn1);
5289 snd_hda_override_conn_list(codec, 0x15, 1, conn1);
5290 }
David Henningsson338cae52013-10-07 10:39:59 +02005291}
5292
Hui Wangdd9aa332016-08-01 10:20:32 +08005293static void alc298_fixup_speaker_volume(struct hda_codec *codec,
5294 const struct hda_fixup *fix, int action)
5295{
5296 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5297 /* The speaker is routed to the Node 0x06 by a mistake, as a result
5298 we can't adjust the speaker's volume since this node does not has
5299 Amp-out capability. we change the speaker's route to:
5300 Node 0x02 (Audio Output) -> Node 0x0c (Audio Mixer) -> Node 0x17 (
5301 Pin Complex), since Node 0x02 has Amp-out caps, we can adjust
5302 speaker's volume now. */
5303
5304 hda_nid_t conn1[1] = { 0x0c };
5305 snd_hda_override_conn_list(codec, 0x17, 1, conn1);
5306 }
5307}
5308
Takashi Iwaie312a862018-03-06 12:14:17 +01005309/* disable DAC3 (0x06) selection on NID 0x17 as it has no volume amp control */
5310static void alc295_fixup_disable_dac3(struct hda_codec *codec,
5311 const struct hda_fixup *fix, int action)
5312{
5313 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5314 hda_nid_t conn[2] = { 0x02, 0x03 };
5315 snd_hda_override_conn_list(codec, 0x17, 2, conn);
5316 }
5317}
5318
Keith Packard98973f22015-07-15 12:14:39 -07005319/* Hook to update amp GPIO4 for automute */
5320static void alc280_hp_gpio4_automute_hook(struct hda_codec *codec,
5321 struct hda_jack_callback *jack)
5322{
5323 struct alc_spec *spec = codec->spec;
5324
5325 snd_hda_gen_hp_automute(codec, jack);
5326 /* mute_led_polarity is set to 0, so we pass inverted value here */
5327 alc_update_gpio_led(codec, 0x10, !spec->gen.hp_jack_present);
5328}
5329
5330/* Manage GPIOs for HP EliteBook Folio 9480m.
5331 *
5332 * GPIO4 is the headphone amplifier power control
5333 * GPIO3 is the audio output mute indicator LED
5334 */
5335
5336static void alc280_fixup_hp_9480m(struct hda_codec *codec,
5337 const struct hda_fixup *fix,
5338 int action)
5339{
5340 struct alc_spec *spec = codec->spec;
5341 static const struct hda_verb gpio_init[] = {
5342 { 0x01, AC_VERB_SET_GPIO_MASK, 0x18 },
5343 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x18 },
5344 {}
5345 };
5346
5347 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5348 /* Set the hooks to turn the headphone amp on/off
5349 * as needed
5350 */
5351 spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook;
5352 spec->gen.hp_automute_hook = alc280_hp_gpio4_automute_hook;
5353
5354 /* The GPIOs are currently off */
5355 spec->gpio_led = 0;
5356
5357 /* GPIO3 is connected to the output mute LED,
5358 * high is on, low is off
5359 */
5360 spec->mute_led_polarity = 0;
5361 spec->gpio_mute_led_mask = 0x08;
5362
5363 /* Initialize GPIO configuration */
5364 snd_hda_add_verbs(codec, gpio_init);
5365 }
5366}
5367
Kailang Yangca169cc2017-04-25 16:17:40 +08005368static void alc233_alc662_fixup_lenovo_dual_codecs(struct hda_codec *codec,
5369 const struct hda_fixup *fix,
5370 int action)
5371{
5372 alc_fixup_dual_codecs(codec, fix, action);
5373 switch (action) {
5374 case HDA_FIXUP_ACT_PRE_PROBE:
5375 /* override card longname to provide a unique UCM profile */
5376 strcpy(codec->card->longname, "HDAudio-Lenovo-DualCodecs");
5377 break;
5378 case HDA_FIXUP_ACT_BUILD:
5379 /* rename Capture controls depending on the codec */
5380 rename_ctl(codec, "Capture Volume",
5381 codec->addr == 0 ?
5382 "Rear-Panel Capture Volume" :
5383 "Front-Panel Capture Volume");
5384 rename_ctl(codec, "Capture Switch",
5385 codec->addr == 0 ?
5386 "Rear-Panel Capture Switch" :
5387 "Front-Panel Capture Switch");
5388 break;
5389 }
5390}
5391
Kailang Yang92266652017-12-14 15:28:58 +08005392/* Forcibly assign NID 0x03 to HP/LO while NID 0x02 to SPK for EQ */
5393static void alc274_fixup_bind_dacs(struct hda_codec *codec,
5394 const struct hda_fixup *fix, int action)
5395{
5396 struct alc_spec *spec = codec->spec;
5397 static hda_nid_t preferred_pairs[] = {
5398 0x21, 0x03, 0x1b, 0x03, 0x16, 0x02,
5399 0
5400 };
5401
5402 if (action != HDA_FIXUP_ACT_PRE_PROBE)
5403 return;
5404
5405 spec->gen.preferred_dacs = preferred_pairs;
5406}
5407
Takashi Iwaib317b032014-01-08 11:44:21 +01005408/* for hda_fixup_thinkpad_acpi() */
5409#include "thinkpad_helper.c"
David Henningssonb67ae3f2013-11-05 13:11:37 +01005410
Takashi Iwaid5a6cab2018-06-13 12:43:10 +02005411static void alc_fixup_thinkpad_acpi(struct hda_codec *codec,
5412 const struct hda_fixup *fix, int action)
5413{
5414 alc_fixup_no_shutup(codec, fix, action); /* reduce click noise */
5415 hda_fixup_thinkpad_acpi(codec, fix, action);
5416}
5417
Hui Wang00ef9942014-07-31 11:52:38 +08005418/* for dell wmi mic mute led */
5419#include "dell_wmi_helper.c"
5420
Tom Bridenbbf8ff62018-05-29 17:34:20 +01005421/* for alc295_fixup_hp_top_speakers */
5422#include "hp_x360_helper.c"
5423
Takashi Iwai1d045db2011-07-07 18:23:21 +02005424enum {
5425 ALC269_FIXUP_SONY_VAIO,
5426 ALC275_FIXUP_SONY_VAIO_GPIO2,
5427 ALC269_FIXUP_DELL_M101Z,
5428 ALC269_FIXUP_SKU_IGNORE,
5429 ALC269_FIXUP_ASUS_G73JW,
5430 ALC269_FIXUP_LENOVO_EAPD,
5431 ALC275_FIXUP_SONY_HWEQ,
Takashi Iwaie9bd7d52014-05-21 11:06:49 +02005432 ALC275_FIXUP_SONY_DISABLE_AAMIX,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005433 ALC271_FIXUP_DMIC,
Takashi Iwai017f2a12011-07-09 14:42:25 +02005434 ALC269_FIXUP_PCM_44K,
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02005435 ALC269_FIXUP_STEREO_DMIC,
David Henningsson7c478f02013-10-11 10:18:46 +02005436 ALC269_FIXUP_HEADSET_MIC,
Takashi Iwai24519912011-08-16 15:08:49 +02005437 ALC269_FIXUP_QUANTA_MUTE,
5438 ALC269_FIXUP_LIFEBOOK,
David Henningsson2041d562014-06-13 11:15:44 +02005439 ALC269_FIXUP_LIFEBOOK_EXTMIC,
Takashi Iwaicc7016a2015-04-08 20:47:55 +02005440 ALC269_FIXUP_LIFEBOOK_HP_PIN,
Takashi Iwai4df3fd12015-06-29 08:38:02 +02005441 ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT,
Jan-Marek Glogowskifdcc9682018-02-14 11:29:15 +01005442 ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC,
Takashi Iwaia4297b52011-08-23 18:40:12 +02005443 ALC269_FIXUP_AMIC,
5444 ALC269_FIXUP_DMIC,
5445 ALC269VB_FIXUP_AMIC,
5446 ALC269VB_FIXUP_DMIC,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01005447 ALC269_FIXUP_HP_MUTE_LED,
David Henningssond06ac142013-02-18 11:41:55 +01005448 ALC269_FIXUP_HP_MUTE_LED_MIC1,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01005449 ALC269_FIXUP_HP_MUTE_LED_MIC2,
Tom Briden7f783bd2017-03-25 10:12:01 +00005450 ALC269_FIXUP_HP_MUTE_LED_MIC3,
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01005451 ALC269_FIXUP_HP_GPIO_LED,
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08005452 ALC269_FIXUP_HP_GPIO_MIC1_LED,
5453 ALC269_FIXUP_HP_LINE1_MIC1_LED,
David Henningsson693b6132012-06-22 19:12:10 +02005454 ALC269_FIXUP_INV_DMIC,
David Henningsson108cc102012-07-20 10:37:25 +02005455 ALC269_FIXUP_LENOVO_DOCK,
Takashi Iwai9b745ab2014-03-07 08:37:19 +01005456 ALC269_FIXUP_NO_SHUTUP,
David Henningsson88cfcf82013-10-11 10:18:45 +02005457 ALC286_FIXUP_SONY_MIC_NO_PRESENCE,
David Henningsson108cc102012-07-20 10:37:25 +02005458 ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT,
David Henningsson73bdd592013-04-15 15:44:14 +02005459 ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
5460 ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
David Henningsson338cae52013-10-07 10:39:59 +02005461 ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
Kailang Yangfcc6c872017-06-29 15:21:27 +08005462 ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
David Henningsson73bdd592013-04-15 15:44:14 +02005463 ALC269_FIXUP_HEADSET_MODE,
5464 ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC,
Takashi Iwai78197172015-06-27 10:21:13 +02005465 ALC269_FIXUP_ASPIRE_HEADSET_MIC,
David Henningssond240d1d2013-04-15 12:50:02 +02005466 ALC269_FIXUP_ASUS_X101_FUNC,
5467 ALC269_FIXUP_ASUS_X101_VERB,
5468 ALC269_FIXUP_ASUS_X101,
Dylan Reid08a978d2012-11-18 22:56:40 -08005469 ALC271_FIXUP_AMIC_MIC2,
5470 ALC271_FIXUP_HP_GATE_MIC_JACK,
Oleksij Rempelb1e89722013-12-04 20:50:53 +01005471 ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572,
Dylan Reid42397002013-04-05 14:58:22 -07005472 ALC269_FIXUP_ACER_AC700,
David Henningsson3e0d6112013-04-22 14:30:14 +02005473 ALC269_FIXUP_LIMIT_INT_MIC_BOOST,
Oleksij Rempel2cede302013-11-27 17:12:03 +01005474 ALC269VB_FIXUP_ASUS_ZENBOOK,
Takashi Iwai23870832013-11-29 14:13:12 +01005475 ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A,
David Henningsson8e35cd42013-11-06 11:20:01 +01005476 ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED,
Anisse Astier02b504d2013-06-03 11:53:10 +02005477 ALC269VB_FIXUP_ORDISSIMO_EVE2,
Kailang Yangcd217a62013-08-22 10:15:24 +02005478 ALC283_FIXUP_CHROME_BOOK,
Kailang Yang0202e992013-12-02 15:20:15 +08005479 ALC283_FIXUP_SENSE_COMBO_JACK,
Takashi Iwai7bba2152013-09-06 15:45:38 +02005480 ALC282_FIXUP_ASUS_TX300,
Kailang Yang1bb3e062013-09-27 13:10:25 +02005481 ALC283_FIXUP_INT_MIC,
David Henningsson338cae52013-10-07 10:39:59 +02005482 ALC290_FIXUP_MONO_SPEAKERS,
David Henningsson0f4881d2013-12-20 16:08:13 +01005483 ALC290_FIXUP_MONO_SPEAKERS_HSJACK,
5484 ALC290_FIXUP_SUBWOOFER,
5485 ALC290_FIXUP_SUBWOOFER_HSJACK,
David Henningssonb67ae3f2013-11-05 13:11:37 +01005486 ALC269_FIXUP_THINKPAD_ACPI,
David Henningsson56f27012016-01-11 09:33:14 +01005487 ALC269_FIXUP_DMIC_THINKPAD_ACPI,
Chris Chiu5824ce82017-02-28 14:17:11 -06005488 ALC255_FIXUP_ACER_MIC_NO_PRESENCE,
Chris Chiu615966a2017-02-28 14:17:12 -06005489 ALC255_FIXUP_ASUS_MIC_NO_PRESENCE,
Kailang Yang9a22a8f52013-11-08 15:54:49 +08005490 ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Kailang Yang31278992014-03-03 15:27:22 +08005491 ALC255_FIXUP_DELL2_MIC_NO_PRESENCE,
Kailang Yang9a22a8f52013-11-08 15:54:49 +08005492 ALC255_FIXUP_HEADSET_MODE,
Kailang Yang31278992014-03-03 15:27:22 +08005493 ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC,
Kailang Yanga22aa262014-04-23 17:34:28 +08005494 ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
Takashi Iwai1c37c222014-05-06 17:34:42 +02005495 ALC292_FIXUP_TPT440_DOCK,
Takashi Iwai9a811232015-12-09 15:17:43 +01005496 ALC292_FIXUP_TPT440,
Anisse Astierabaa22742016-08-24 09:14:13 +02005497 ALC283_FIXUP_HEADSET_MIC,
Hui Wang00ef9942014-07-31 11:52:38 +08005498 ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED,
Takashi Iwai1a22e772014-08-27 08:19:05 +02005499 ALC282_FIXUP_ASPIRE_V5_PINS,
David Henningsson7a5255f2014-10-30 08:26:01 +01005500 ALC280_FIXUP_HP_GPIO4,
Kailang Yangeaa8e5e2014-11-21 15:49:11 +08005501 ALC286_FIXUP_HP_GPIO_LED,
David Henningsson33f4acd2015-01-07 15:50:13 +01005502 ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY,
TienFu Chenb4b33f92015-01-20 15:06:21 +01005503 ALC280_FIXUP_HP_DOCK_PINS,
Jaroslav Kysela04d54662017-03-09 13:29:13 +01005504 ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED,
Keith Packard98973f22015-07-15 12:14:39 -07005505 ALC280_FIXUP_HP_9480M,
Kailang Yange1e62b92015-04-08 16:01:22 +08005506 ALC288_FIXUP_DELL_HEADSET_MODE,
5507 ALC288_FIXUP_DELL1_MIC_NO_PRESENCE,
5508 ALC288_FIXUP_DELL_XPS_13_GPIO6,
Hui Wang831bfdf92015-06-26 12:35:17 +08005509 ALC288_FIXUP_DELL_XPS_13,
5510 ALC288_FIXUP_DISABLE_AAMIX,
Takashi Iwai8b99aba2015-06-15 11:59:32 +02005511 ALC292_FIXUP_DELL_E7X,
5512 ALC292_FIXUP_DISABLE_AAMIX,
David Henningssonc04017e2015-12-15 14:44:03 +01005513 ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK,
Kailang Yang977e6272015-05-18 15:31:20 +08005514 ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang2f726ae2017-03-31 10:31:40 +08005515 ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE,
Kailang Yang6ed11312015-10-26 15:37:39 +08005516 ALC275_FIXUP_DELL_XPS,
Hui Wang8c697292015-11-24 11:08:18 +08005517 ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE,
Hui Wang23adc192015-12-08 12:27:18 +08005518 ALC293_FIXUP_LENOVO_SPK_NOISE,
Kailang3694cb22015-12-28 11:35:24 +08005519 ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY,
Kai-Heng Feng3b43b712016-02-25 15:19:38 +08005520 ALC255_FIXUP_DELL_SPK_NOISE,
David Henningsson2ae95572016-02-25 09:37:05 +01005521 ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
Takashi Iwaie312a862018-03-06 12:14:17 +01005522 ALC295_FIXUP_DISABLE_DAC3,
Takashi Iwaif8839822016-02-25 14:31:59 +01005523 ALC280_FIXUP_HP_HEADSET_MIC,
Hui Wange549d192016-04-01 11:00:15 +08005524 ALC221_FIXUP_HP_FRONT_MIC,
Sven Eckelmannc636b952016-04-11 16:55:26 +02005525 ALC292_FIXUP_TPT460,
Hui Wangdd9aa332016-08-01 10:20:32 +08005526 ALC298_FIXUP_SPK_VOLUME,
Kai-Heng Fengfd06c772016-08-30 15:36:34 +08005527 ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER,
Gabriele Mazzotta823ff162016-12-24 19:50:01 +01005528 ALC269_FIXUP_ATIV_BOOK_8,
Kailang Yang9eb5d0e2017-01-17 15:40:25 +08005529 ALC221_FIXUP_HP_MIC_NO_PRESENCE,
Chris Chiuc1732ed2017-02-28 14:17:13 -06005530 ALC256_FIXUP_ASUS_HEADSET_MODE,
5531 ALC256_FIXUP_ASUS_MIC,
Chris Chiueeed4cd2017-02-28 14:17:15 -06005532 ALC256_FIXUP_ASUS_AIO_GPIO2,
Chris Chiu216d7ae2017-02-28 14:17:14 -06005533 ALC233_FIXUP_ASUS_MIC_NO_PRESENCE,
5534 ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE,
Kailang Yangca169cc2017-04-25 16:17:40 +08005535 ALC233_FIXUP_LENOVO_MULTI_CODECS,
Hui Wangf33f79f2017-07-07 12:08:29 +08005536 ALC294_FIXUP_LENOVO_MIC_LOCATION,
Kailang Yang5f364132017-07-25 16:28:16 +08005537 ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE,
PeiSen Houb84e8432017-09-01 15:11:56 +08005538 ALC700_FIXUP_INTEL_REFERENCE,
Kailang Yang92266652017-12-14 15:28:58 +08005539 ALC274_FIXUP_DELL_BIND_DACS,
5540 ALC274_FIXUP_DELL_AIO_LINEOUT_VERB,
Kailang Yang61fcf8e2018-02-02 15:26:46 +08005541 ALC298_FIXUP_TPT470_DOCK,
Kailang Yangae104a22018-02-05 16:07:20 +08005542 ALC255_FIXUP_DUMMY_LINEOUT_VERB,
Kailang Yangf0ba9d62018-03-16 11:46:08 +08005543 ALC255_FIXUP_DELL_HEADSET_MIC,
Tom Bridenbbf8ff62018-05-29 17:34:20 +01005544 ALC295_FIXUP_HP_X360,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005545};
5546
Takashi Iwai1727a772013-01-10 09:52:52 +01005547static const struct hda_fixup alc269_fixups[] = {
Takashi Iwai1d045db2011-07-07 18:23:21 +02005548 [ALC269_FIXUP_SONY_VAIO] = {
Takashi Iwaifd108212013-01-10 10:18:14 +01005549 .type = HDA_FIXUP_PINCTLS,
5550 .v.pins = (const struct hda_pintbl[]) {
5551 {0x19, PIN_VREFGRD},
Takashi Iwai1d045db2011-07-07 18:23:21 +02005552 {}
5553 }
5554 },
5555 [ALC275_FIXUP_SONY_VAIO_GPIO2] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005556 .type = HDA_FIXUP_VERBS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005557 .v.verbs = (const struct hda_verb[]) {
5558 {0x01, AC_VERB_SET_GPIO_MASK, 0x04},
5559 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04},
5560 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5561 { }
5562 },
5563 .chained = true,
5564 .chain_id = ALC269_FIXUP_SONY_VAIO
5565 },
5566 [ALC269_FIXUP_DELL_M101Z] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005567 .type = HDA_FIXUP_VERBS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005568 .v.verbs = (const struct hda_verb[]) {
5569 /* Enables internal speaker */
5570 {0x20, AC_VERB_SET_COEF_INDEX, 13},
5571 {0x20, AC_VERB_SET_PROC_COEF, 0x4040},
5572 {}
5573 }
5574 },
5575 [ALC269_FIXUP_SKU_IGNORE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005576 .type = HDA_FIXUP_FUNC,
Takashi Iwai23d30f22012-05-07 17:17:32 +02005577 .v.func = alc_fixup_sku_ignore,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005578 },
5579 [ALC269_FIXUP_ASUS_G73JW] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005580 .type = HDA_FIXUP_PINS,
5581 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02005582 { 0x17, 0x99130111 }, /* subwoofer */
5583 { }
5584 }
5585 },
5586 [ALC269_FIXUP_LENOVO_EAPD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005587 .type = HDA_FIXUP_VERBS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005588 .v.verbs = (const struct hda_verb[]) {
5589 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
5590 {}
5591 }
5592 },
5593 [ALC275_FIXUP_SONY_HWEQ] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005594 .type = HDA_FIXUP_FUNC,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005595 .v.func = alc269_fixup_hweq,
5596 .chained = true,
5597 .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2
5598 },
Takashi Iwaie9bd7d52014-05-21 11:06:49 +02005599 [ALC275_FIXUP_SONY_DISABLE_AAMIX] = {
5600 .type = HDA_FIXUP_FUNC,
5601 .v.func = alc_fixup_disable_aamix,
5602 .chained = true,
5603 .chain_id = ALC269_FIXUP_SONY_VAIO
5604 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02005605 [ALC271_FIXUP_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005606 .type = HDA_FIXUP_FUNC,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005607 .v.func = alc271_fixup_dmic,
5608 },
Takashi Iwai017f2a12011-07-09 14:42:25 +02005609 [ALC269_FIXUP_PCM_44K] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005610 .type = HDA_FIXUP_FUNC,
Takashi Iwai017f2a12011-07-09 14:42:25 +02005611 .v.func = alc269_fixup_pcm_44k,
David Henningsson012e7eb2012-08-08 08:43:37 +02005612 .chained = true,
5613 .chain_id = ALC269_FIXUP_QUANTA_MUTE
Takashi Iwai017f2a12011-07-09 14:42:25 +02005614 },
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02005615 [ALC269_FIXUP_STEREO_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005616 .type = HDA_FIXUP_FUNC,
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02005617 .v.func = alc269_fixup_stereo_dmic,
5618 },
David Henningsson7c478f02013-10-11 10:18:46 +02005619 [ALC269_FIXUP_HEADSET_MIC] = {
5620 .type = HDA_FIXUP_FUNC,
5621 .v.func = alc269_fixup_headset_mic,
5622 },
Takashi Iwai24519912011-08-16 15:08:49 +02005623 [ALC269_FIXUP_QUANTA_MUTE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005624 .type = HDA_FIXUP_FUNC,
Takashi Iwai24519912011-08-16 15:08:49 +02005625 .v.func = alc269_fixup_quanta_mute,
5626 },
5627 [ALC269_FIXUP_LIFEBOOK] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005628 .type = HDA_FIXUP_PINS,
5629 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai24519912011-08-16 15:08:49 +02005630 { 0x1a, 0x2101103f }, /* dock line-out */
5631 { 0x1b, 0x23a11040 }, /* dock mic-in */
5632 { }
5633 },
5634 .chained = true,
5635 .chain_id = ALC269_FIXUP_QUANTA_MUTE
5636 },
David Henningsson2041d562014-06-13 11:15:44 +02005637 [ALC269_FIXUP_LIFEBOOK_EXTMIC] = {
5638 .type = HDA_FIXUP_PINS,
5639 .v.pins = (const struct hda_pintbl[]) {
5640 { 0x19, 0x01a1903c }, /* headset mic, with jack detect */
5641 { }
5642 },
5643 },
Takashi Iwaicc7016a2015-04-08 20:47:55 +02005644 [ALC269_FIXUP_LIFEBOOK_HP_PIN] = {
5645 .type = HDA_FIXUP_PINS,
5646 .v.pins = (const struct hda_pintbl[]) {
5647 { 0x21, 0x0221102f }, /* HP out */
5648 { }
5649 },
5650 },
Takashi Iwai4df3fd12015-06-29 08:38:02 +02005651 [ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT] = {
5652 .type = HDA_FIXUP_FUNC,
5653 .v.func = alc269_fixup_pincfg_no_hp_to_lineout,
5654 },
Jan-Marek Glogowskifdcc9682018-02-14 11:29:15 +01005655 [ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC] = {
5656 .type = HDA_FIXUP_FUNC,
5657 .v.func = alc269_fixup_pincfg_U7x7_headset_mic,
5658 },
Takashi Iwaia4297b52011-08-23 18:40:12 +02005659 [ALC269_FIXUP_AMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005660 .type = HDA_FIXUP_PINS,
5661 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaia4297b52011-08-23 18:40:12 +02005662 { 0x14, 0x99130110 }, /* speaker */
5663 { 0x15, 0x0121401f }, /* HP out */
5664 { 0x18, 0x01a19c20 }, /* mic */
5665 { 0x19, 0x99a3092f }, /* int-mic */
5666 { }
5667 },
5668 },
5669 [ALC269_FIXUP_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005670 .type = HDA_FIXUP_PINS,
5671 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaia4297b52011-08-23 18:40:12 +02005672 { 0x12, 0x99a3092f }, /* int-mic */
5673 { 0x14, 0x99130110 }, /* speaker */
5674 { 0x15, 0x0121401f }, /* HP out */
5675 { 0x18, 0x01a19c20 }, /* mic */
5676 { }
5677 },
5678 },
5679 [ALC269VB_FIXUP_AMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005680 .type = HDA_FIXUP_PINS,
5681 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaia4297b52011-08-23 18:40:12 +02005682 { 0x14, 0x99130110 }, /* speaker */
5683 { 0x18, 0x01a19c20 }, /* mic */
5684 { 0x19, 0x99a3092f }, /* int-mic */
5685 { 0x21, 0x0121401f }, /* HP out */
5686 { }
5687 },
5688 },
David Henningsson2267ea92012-01-03 08:45:56 +01005689 [ALC269VB_FIXUP_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005690 .type = HDA_FIXUP_PINS,
5691 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaia4297b52011-08-23 18:40:12 +02005692 { 0x12, 0x99a3092f }, /* int-mic */
5693 { 0x14, 0x99130110 }, /* speaker */
5694 { 0x18, 0x01a19c20 }, /* mic */
5695 { 0x21, 0x0121401f }, /* HP out */
5696 { }
5697 },
5698 },
Takashi Iwai08fb0d02013-01-10 17:33:58 +01005699 [ALC269_FIXUP_HP_MUTE_LED] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005700 .type = HDA_FIXUP_FUNC,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01005701 .v.func = alc269_fixup_hp_mute_led,
David Henningsson6d3cd5d2013-01-07 12:03:47 +01005702 },
David Henningssond06ac142013-02-18 11:41:55 +01005703 [ALC269_FIXUP_HP_MUTE_LED_MIC1] = {
5704 .type = HDA_FIXUP_FUNC,
5705 .v.func = alc269_fixup_hp_mute_led_mic1,
5706 },
Takashi Iwai08fb0d02013-01-10 17:33:58 +01005707 [ALC269_FIXUP_HP_MUTE_LED_MIC2] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005708 .type = HDA_FIXUP_FUNC,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01005709 .v.func = alc269_fixup_hp_mute_led_mic2,
Takashi Iwai420b0fe2012-03-12 12:35:27 +01005710 },
Tom Briden7f783bd2017-03-25 10:12:01 +00005711 [ALC269_FIXUP_HP_MUTE_LED_MIC3] = {
5712 .type = HDA_FIXUP_FUNC,
5713 .v.func = alc269_fixup_hp_mute_led_mic3,
5714 },
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01005715 [ALC269_FIXUP_HP_GPIO_LED] = {
5716 .type = HDA_FIXUP_FUNC,
5717 .v.func = alc269_fixup_hp_gpio_led,
5718 },
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08005719 [ALC269_FIXUP_HP_GPIO_MIC1_LED] = {
5720 .type = HDA_FIXUP_FUNC,
5721 .v.func = alc269_fixup_hp_gpio_mic1_led,
5722 },
5723 [ALC269_FIXUP_HP_LINE1_MIC1_LED] = {
5724 .type = HDA_FIXUP_FUNC,
5725 .v.func = alc269_fixup_hp_line1_mic1_led,
5726 },
David Henningsson693b6132012-06-22 19:12:10 +02005727 [ALC269_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005728 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02005729 .v.func = alc_fixup_inv_dmic,
David Henningsson693b6132012-06-22 19:12:10 +02005730 },
Takashi Iwai9b745ab2014-03-07 08:37:19 +01005731 [ALC269_FIXUP_NO_SHUTUP] = {
5732 .type = HDA_FIXUP_FUNC,
5733 .v.func = alc_fixup_no_shutup,
5734 },
David Henningsson108cc102012-07-20 10:37:25 +02005735 [ALC269_FIXUP_LENOVO_DOCK] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005736 .type = HDA_FIXUP_PINS,
5737 .v.pins = (const struct hda_pintbl[]) {
David Henningsson108cc102012-07-20 10:37:25 +02005738 { 0x19, 0x23a11040 }, /* dock mic */
5739 { 0x1b, 0x2121103f }, /* dock headphone */
5740 { }
5741 },
5742 .chained = true,
5743 .chain_id = ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT
5744 },
5745 [ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005746 .type = HDA_FIXUP_FUNC,
David Henningsson108cc102012-07-20 10:37:25 +02005747 .v.func = alc269_fixup_pincfg_no_hp_to_lineout,
David Henningsson52129002013-11-19 10:25:53 +01005748 .chained = true,
5749 .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
David Henningsson108cc102012-07-20 10:37:25 +02005750 },
David Henningsson73bdd592013-04-15 15:44:14 +02005751 [ALC269_FIXUP_DELL1_MIC_NO_PRESENCE] = {
5752 .type = HDA_FIXUP_PINS,
5753 .v.pins = (const struct hda_pintbl[]) {
5754 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5755 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
5756 { }
5757 },
5758 .chained = true,
5759 .chain_id = ALC269_FIXUP_HEADSET_MODE
5760 },
5761 [ALC269_FIXUP_DELL2_MIC_NO_PRESENCE] = {
5762 .type = HDA_FIXUP_PINS,
5763 .v.pins = (const struct hda_pintbl[]) {
5764 { 0x16, 0x21014020 }, /* dock line out */
5765 { 0x19, 0x21a19030 }, /* dock mic */
5766 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5767 { }
5768 },
5769 .chained = true,
5770 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
5771 },
David Henningsson338cae52013-10-07 10:39:59 +02005772 [ALC269_FIXUP_DELL3_MIC_NO_PRESENCE] = {
5773 .type = HDA_FIXUP_PINS,
5774 .v.pins = (const struct hda_pintbl[]) {
5775 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5776 { }
5777 },
5778 .chained = true,
5779 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
5780 },
Kailang Yangfcc6c872017-06-29 15:21:27 +08005781 [ALC269_FIXUP_DELL4_MIC_NO_PRESENCE] = {
5782 .type = HDA_FIXUP_PINS,
5783 .v.pins = (const struct hda_pintbl[]) {
5784 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5785 { 0x1b, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
5786 { }
5787 },
5788 .chained = true,
5789 .chain_id = ALC269_FIXUP_HEADSET_MODE
5790 },
David Henningsson73bdd592013-04-15 15:44:14 +02005791 [ALC269_FIXUP_HEADSET_MODE] = {
5792 .type = HDA_FIXUP_FUNC,
5793 .v.func = alc_fixup_headset_mode,
Hui Wang6676f302014-11-18 17:57:41 +08005794 .chained = true,
5795 .chain_id = ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED
David Henningsson73bdd592013-04-15 15:44:14 +02005796 },
5797 [ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC] = {
5798 .type = HDA_FIXUP_FUNC,
5799 .v.func = alc_fixup_headset_mode_no_hp_mic,
5800 },
Takashi Iwai78197172015-06-27 10:21:13 +02005801 [ALC269_FIXUP_ASPIRE_HEADSET_MIC] = {
5802 .type = HDA_FIXUP_PINS,
5803 .v.pins = (const struct hda_pintbl[]) {
5804 { 0x19, 0x01a1913c }, /* headset mic w/o jack detect */
5805 { }
5806 },
5807 .chained = true,
5808 .chain_id = ALC269_FIXUP_HEADSET_MODE,
5809 },
David Henningsson88cfcf82013-10-11 10:18:45 +02005810 [ALC286_FIXUP_SONY_MIC_NO_PRESENCE] = {
5811 .type = HDA_FIXUP_PINS,
5812 .v.pins = (const struct hda_pintbl[]) {
5813 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5814 { }
5815 },
David Henningssonfbc78ad2013-10-11 13:46:04 +02005816 .chained = true,
5817 .chain_id = ALC269_FIXUP_HEADSET_MIC
David Henningsson88cfcf82013-10-11 10:18:45 +02005818 },
David Henningssond240d1d2013-04-15 12:50:02 +02005819 [ALC269_FIXUP_ASUS_X101_FUNC] = {
5820 .type = HDA_FIXUP_FUNC,
5821 .v.func = alc269_fixup_x101_headset_mic,
5822 },
5823 [ALC269_FIXUP_ASUS_X101_VERB] = {
5824 .type = HDA_FIXUP_VERBS,
5825 .v.verbs = (const struct hda_verb[]) {
5826 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5827 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
5828 {0x20, AC_VERB_SET_PROC_COEF, 0x0310},
5829 { }
5830 },
5831 .chained = true,
5832 .chain_id = ALC269_FIXUP_ASUS_X101_FUNC
5833 },
5834 [ALC269_FIXUP_ASUS_X101] = {
5835 .type = HDA_FIXUP_PINS,
5836 .v.pins = (const struct hda_pintbl[]) {
5837 { 0x18, 0x04a1182c }, /* Headset mic */
5838 { }
5839 },
5840 .chained = true,
5841 .chain_id = ALC269_FIXUP_ASUS_X101_VERB
5842 },
Dylan Reid08a978d2012-11-18 22:56:40 -08005843 [ALC271_FIXUP_AMIC_MIC2] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005844 .type = HDA_FIXUP_PINS,
5845 .v.pins = (const struct hda_pintbl[]) {
Dylan Reid08a978d2012-11-18 22:56:40 -08005846 { 0x14, 0x99130110 }, /* speaker */
5847 { 0x19, 0x01a19c20 }, /* mic */
5848 { 0x1b, 0x99a7012f }, /* int-mic */
5849 { 0x21, 0x0121401f }, /* HP out */
5850 { }
5851 },
5852 },
5853 [ALC271_FIXUP_HP_GATE_MIC_JACK] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005854 .type = HDA_FIXUP_FUNC,
Dylan Reid08a978d2012-11-18 22:56:40 -08005855 .v.func = alc271_hp_gate_mic_jack,
5856 .chained = true,
5857 .chain_id = ALC271_FIXUP_AMIC_MIC2,
5858 },
Oleksij Rempelb1e89722013-12-04 20:50:53 +01005859 [ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572] = {
5860 .type = HDA_FIXUP_FUNC,
5861 .v.func = alc269_fixup_limit_int_mic_boost,
5862 .chained = true,
5863 .chain_id = ALC271_FIXUP_HP_GATE_MIC_JACK,
5864 },
Dylan Reid42397002013-04-05 14:58:22 -07005865 [ALC269_FIXUP_ACER_AC700] = {
5866 .type = HDA_FIXUP_PINS,
5867 .v.pins = (const struct hda_pintbl[]) {
5868 { 0x12, 0x99a3092f }, /* int-mic */
5869 { 0x14, 0x99130110 }, /* speaker */
5870 { 0x18, 0x03a11c20 }, /* mic */
5871 { 0x1e, 0x0346101e }, /* SPDIF1 */
5872 { 0x21, 0x0321101f }, /* HP out */
5873 { }
5874 },
5875 .chained = true,
5876 .chain_id = ALC271_FIXUP_DMIC,
5877 },
David Henningsson3e0d6112013-04-22 14:30:14 +02005878 [ALC269_FIXUP_LIMIT_INT_MIC_BOOST] = {
5879 .type = HDA_FIXUP_FUNC,
5880 .v.func = alc269_fixup_limit_int_mic_boost,
David Henningsson27937692013-11-18 11:51:47 +01005881 .chained = true,
5882 .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
David Henningsson3e0d6112013-04-22 14:30:14 +02005883 },
Oleksij Rempel2cede302013-11-27 17:12:03 +01005884 [ALC269VB_FIXUP_ASUS_ZENBOOK] = {
5885 .type = HDA_FIXUP_FUNC,
5886 .v.func = alc269_fixup_limit_int_mic_boost,
5887 .chained = true,
5888 .chain_id = ALC269VB_FIXUP_DMIC,
5889 },
Takashi Iwai23870832013-11-29 14:13:12 +01005890 [ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A] = {
5891 .type = HDA_FIXUP_VERBS,
5892 .v.verbs = (const struct hda_verb[]) {
5893 /* class-D output amp +5dB */
5894 { 0x20, AC_VERB_SET_COEF_INDEX, 0x12 },
5895 { 0x20, AC_VERB_SET_PROC_COEF, 0x2800 },
5896 {}
5897 },
5898 .chained = true,
5899 .chain_id = ALC269VB_FIXUP_ASUS_ZENBOOK,
5900 },
David Henningsson8e35cd42013-11-06 11:20:01 +01005901 [ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED] = {
5902 .type = HDA_FIXUP_FUNC,
5903 .v.func = alc269_fixup_limit_int_mic_boost,
5904 .chained = true,
5905 .chain_id = ALC269_FIXUP_HP_MUTE_LED_MIC1,
5906 },
Anisse Astier02b504d2013-06-03 11:53:10 +02005907 [ALC269VB_FIXUP_ORDISSIMO_EVE2] = {
5908 .type = HDA_FIXUP_PINS,
5909 .v.pins = (const struct hda_pintbl[]) {
5910 { 0x12, 0x99a3092f }, /* int-mic */
5911 { 0x18, 0x03a11d20 }, /* mic */
5912 { 0x19, 0x411111f0 }, /* Unused bogus pin */
5913 { }
5914 },
5915 },
Kailang Yangcd217a62013-08-22 10:15:24 +02005916 [ALC283_FIXUP_CHROME_BOOK] = {
5917 .type = HDA_FIXUP_FUNC,
5918 .v.func = alc283_fixup_chromebook,
5919 },
Kailang Yang0202e992013-12-02 15:20:15 +08005920 [ALC283_FIXUP_SENSE_COMBO_JACK] = {
5921 .type = HDA_FIXUP_FUNC,
5922 .v.func = alc283_fixup_sense_combo_jack,
5923 .chained = true,
5924 .chain_id = ALC283_FIXUP_CHROME_BOOK,
5925 },
Takashi Iwai7bba2152013-09-06 15:45:38 +02005926 [ALC282_FIXUP_ASUS_TX300] = {
5927 .type = HDA_FIXUP_FUNC,
5928 .v.func = alc282_fixup_asus_tx300,
5929 },
Kailang Yang1bb3e062013-09-27 13:10:25 +02005930 [ALC283_FIXUP_INT_MIC] = {
5931 .type = HDA_FIXUP_VERBS,
5932 .v.verbs = (const struct hda_verb[]) {
5933 {0x20, AC_VERB_SET_COEF_INDEX, 0x1a},
5934 {0x20, AC_VERB_SET_PROC_COEF, 0x0011},
5935 { }
5936 },
5937 .chained = true,
5938 .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST
5939 },
David Henningsson0f4881d2013-12-20 16:08:13 +01005940 [ALC290_FIXUP_SUBWOOFER_HSJACK] = {
5941 .type = HDA_FIXUP_PINS,
5942 .v.pins = (const struct hda_pintbl[]) {
5943 { 0x17, 0x90170112 }, /* subwoofer */
5944 { }
5945 },
5946 .chained = true,
5947 .chain_id = ALC290_FIXUP_MONO_SPEAKERS_HSJACK,
5948 },
5949 [ALC290_FIXUP_SUBWOOFER] = {
5950 .type = HDA_FIXUP_PINS,
5951 .v.pins = (const struct hda_pintbl[]) {
5952 { 0x17, 0x90170112 }, /* subwoofer */
5953 { }
5954 },
5955 .chained = true,
5956 .chain_id = ALC290_FIXUP_MONO_SPEAKERS,
5957 },
David Henningsson338cae52013-10-07 10:39:59 +02005958 [ALC290_FIXUP_MONO_SPEAKERS] = {
5959 .type = HDA_FIXUP_FUNC,
5960 .v.func = alc290_fixup_mono_speakers,
David Henningsson0f4881d2013-12-20 16:08:13 +01005961 },
5962 [ALC290_FIXUP_MONO_SPEAKERS_HSJACK] = {
5963 .type = HDA_FIXUP_FUNC,
5964 .v.func = alc290_fixup_mono_speakers,
David Henningsson338cae52013-10-07 10:39:59 +02005965 .chained = true,
5966 .chain_id = ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
5967 },
David Henningssonb67ae3f2013-11-05 13:11:37 +01005968 [ALC269_FIXUP_THINKPAD_ACPI] = {
5969 .type = HDA_FIXUP_FUNC,
Takashi Iwaid5a6cab2018-06-13 12:43:10 +02005970 .v.func = alc_fixup_thinkpad_acpi,
Takashi Iwai09da1112016-09-08 12:15:02 +02005971 .chained = true,
5972 .chain_id = ALC269_FIXUP_SKU_IGNORE,
David Henningssonb67ae3f2013-11-05 13:11:37 +01005973 },
David Henningsson56f27012016-01-11 09:33:14 +01005974 [ALC269_FIXUP_DMIC_THINKPAD_ACPI] = {
5975 .type = HDA_FIXUP_FUNC,
5976 .v.func = alc_fixup_inv_dmic,
5977 .chained = true,
5978 .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
5979 },
Chris Chiu5824ce82017-02-28 14:17:11 -06005980 [ALC255_FIXUP_ACER_MIC_NO_PRESENCE] = {
5981 .type = HDA_FIXUP_PINS,
5982 .v.pins = (const struct hda_pintbl[]) {
5983 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5984 { }
5985 },
5986 .chained = true,
5987 .chain_id = ALC255_FIXUP_HEADSET_MODE
5988 },
Chris Chiu615966a2017-02-28 14:17:12 -06005989 [ALC255_FIXUP_ASUS_MIC_NO_PRESENCE] = {
5990 .type = HDA_FIXUP_PINS,
5991 .v.pins = (const struct hda_pintbl[]) {
5992 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5993 { }
5994 },
5995 .chained = true,
5996 .chain_id = ALC255_FIXUP_HEADSET_MODE
5997 },
Kailang Yang9a22a8f52013-11-08 15:54:49 +08005998 [ALC255_FIXUP_DELL1_MIC_NO_PRESENCE] = {
5999 .type = HDA_FIXUP_PINS,
6000 .v.pins = (const struct hda_pintbl[]) {
6001 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6002 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6003 { }
6004 },
6005 .chained = true,
6006 .chain_id = ALC255_FIXUP_HEADSET_MODE
6007 },
Kailang Yang31278992014-03-03 15:27:22 +08006008 [ALC255_FIXUP_DELL2_MIC_NO_PRESENCE] = {
6009 .type = HDA_FIXUP_PINS,
6010 .v.pins = (const struct hda_pintbl[]) {
6011 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6012 { }
6013 },
6014 .chained = true,
6015 .chain_id = ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC
6016 },
Kailang Yang9a22a8f52013-11-08 15:54:49 +08006017 [ALC255_FIXUP_HEADSET_MODE] = {
6018 .type = HDA_FIXUP_FUNC,
6019 .v.func = alc_fixup_headset_mode_alc255,
Hui Wang4a83d422014-11-18 17:57:40 +08006020 .chained = true,
6021 .chain_id = ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED
Kailang Yang9a22a8f52013-11-08 15:54:49 +08006022 },
Kailang Yang31278992014-03-03 15:27:22 +08006023 [ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC] = {
6024 .type = HDA_FIXUP_FUNC,
6025 .v.func = alc_fixup_headset_mode_alc255_no_hp_mic,
6026 },
Kailang Yanga22aa262014-04-23 17:34:28 +08006027 [ALC293_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6028 .type = HDA_FIXUP_PINS,
6029 .v.pins = (const struct hda_pintbl[]) {
6030 { 0x18, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6031 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6032 { }
6033 },
6034 .chained = true,
6035 .chain_id = ALC269_FIXUP_HEADSET_MODE
6036 },
Takashi Iwai1c37c222014-05-06 17:34:42 +02006037 [ALC292_FIXUP_TPT440_DOCK] = {
David Henningssonec56af62015-06-24 10:46:33 +02006038 .type = HDA_FIXUP_FUNC,
Takashi Iwai7f57d802015-09-24 17:36:51 +02006039 .v.func = alc_fixup_tpt440_dock,
Takashi Iwai1c37c222014-05-06 17:34:42 +02006040 .chained = true,
6041 .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST
6042 },
Takashi Iwai9a811232015-12-09 15:17:43 +01006043 [ALC292_FIXUP_TPT440] = {
6044 .type = HDA_FIXUP_FUNC,
Takashi Iwai157f0b72015-12-10 23:30:43 +01006045 .v.func = alc_fixup_disable_aamix,
Takashi Iwai9a811232015-12-09 15:17:43 +01006046 .chained = true,
6047 .chain_id = ALC292_FIXUP_TPT440_DOCK,
6048 },
Anisse Astierabaa22742016-08-24 09:14:13 +02006049 [ALC283_FIXUP_HEADSET_MIC] = {
Daniel Drake9dc12862014-07-22 10:58:29 +01006050 .type = HDA_FIXUP_PINS,
6051 .v.pins = (const struct hda_pintbl[]) {
6052 { 0x19, 0x04a110f0 },
6053 { },
6054 },
6055 },
Hui Wang00ef9942014-07-31 11:52:38 +08006056 [ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED] = {
6057 .type = HDA_FIXUP_FUNC,
6058 .v.func = alc_fixup_dell_wmi,
Hui Wang00ef9942014-07-31 11:52:38 +08006059 },
Takashi Iwai1a22e772014-08-27 08:19:05 +02006060 [ALC282_FIXUP_ASPIRE_V5_PINS] = {
6061 .type = HDA_FIXUP_PINS,
6062 .v.pins = (const struct hda_pintbl[]) {
6063 { 0x12, 0x90a60130 },
6064 { 0x14, 0x90170110 },
6065 { 0x17, 0x40000008 },
6066 { 0x18, 0x411111f0 },
Mateusz Sylwestrzak04206942015-07-19 17:38:56 +02006067 { 0x19, 0x01a1913c },
Takashi Iwai1a22e772014-08-27 08:19:05 +02006068 { 0x1a, 0x411111f0 },
6069 { 0x1b, 0x411111f0 },
6070 { 0x1d, 0x40f89b2d },
6071 { 0x1e, 0x411111f0 },
6072 { 0x21, 0x0321101f },
6073 { },
6074 },
6075 },
David Henningsson7a5255f2014-10-30 08:26:01 +01006076 [ALC280_FIXUP_HP_GPIO4] = {
6077 .type = HDA_FIXUP_FUNC,
6078 .v.func = alc280_fixup_hp_gpio4,
6079 },
Kailang Yangeaa8e5e2014-11-21 15:49:11 +08006080 [ALC286_FIXUP_HP_GPIO_LED] = {
6081 .type = HDA_FIXUP_FUNC,
6082 .v.func = alc286_fixup_hp_gpio_led,
6083 },
David Henningsson33f4acd2015-01-07 15:50:13 +01006084 [ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY] = {
6085 .type = HDA_FIXUP_FUNC,
6086 .v.func = alc280_fixup_hp_gpio2_mic_hotkey,
6087 },
TienFu Chenb4b33f92015-01-20 15:06:21 +01006088 [ALC280_FIXUP_HP_DOCK_PINS] = {
6089 .type = HDA_FIXUP_PINS,
6090 .v.pins = (const struct hda_pintbl[]) {
6091 { 0x1b, 0x21011020 }, /* line-out */
6092 { 0x1a, 0x01a1903c }, /* headset mic */
6093 { 0x18, 0x2181103f }, /* line-in */
6094 { },
6095 },
6096 .chained = true,
6097 .chain_id = ALC280_FIXUP_HP_GPIO4
6098 },
Jaroslav Kysela04d54662017-03-09 13:29:13 +01006099 [ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED] = {
6100 .type = HDA_FIXUP_PINS,
6101 .v.pins = (const struct hda_pintbl[]) {
6102 { 0x1b, 0x21011020 }, /* line-out */
6103 { 0x18, 0x2181103f }, /* line-in */
6104 { },
6105 },
6106 .chained = true,
6107 .chain_id = ALC269_FIXUP_HP_GPIO_MIC1_LED
6108 },
Keith Packard98973f22015-07-15 12:14:39 -07006109 [ALC280_FIXUP_HP_9480M] = {
6110 .type = HDA_FIXUP_FUNC,
6111 .v.func = alc280_fixup_hp_9480m,
6112 },
Kailang Yange1e62b92015-04-08 16:01:22 +08006113 [ALC288_FIXUP_DELL_HEADSET_MODE] = {
6114 .type = HDA_FIXUP_FUNC,
6115 .v.func = alc_fixup_headset_mode_dell_alc288,
6116 .chained = true,
6117 .chain_id = ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED
6118 },
6119 [ALC288_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6120 .type = HDA_FIXUP_PINS,
6121 .v.pins = (const struct hda_pintbl[]) {
6122 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6123 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6124 { }
6125 },
6126 .chained = true,
6127 .chain_id = ALC288_FIXUP_DELL_HEADSET_MODE
6128 },
6129 [ALC288_FIXUP_DELL_XPS_13_GPIO6] = {
6130 .type = HDA_FIXUP_VERBS,
6131 .v.verbs = (const struct hda_verb[]) {
6132 {0x01, AC_VERB_SET_GPIO_MASK, 0x40},
6133 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x40},
6134 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6135 { }
6136 },
6137 .chained = true,
6138 .chain_id = ALC288_FIXUP_DELL1_MIC_NO_PRESENCE
6139 },
Hui Wang831bfdf92015-06-26 12:35:17 +08006140 [ALC288_FIXUP_DISABLE_AAMIX] = {
6141 .type = HDA_FIXUP_FUNC,
6142 .v.func = alc_fixup_disable_aamix,
6143 .chained = true,
6144 .chain_id = ALC288_FIXUP_DELL_XPS_13_GPIO6
6145 },
6146 [ALC288_FIXUP_DELL_XPS_13] = {
6147 .type = HDA_FIXUP_FUNC,
6148 .v.func = alc_fixup_dell_xps13,
6149 .chained = true,
6150 .chain_id = ALC288_FIXUP_DISABLE_AAMIX
6151 },
Takashi Iwai8b99aba2015-06-15 11:59:32 +02006152 [ALC292_FIXUP_DISABLE_AAMIX] = {
6153 .type = HDA_FIXUP_FUNC,
6154 .v.func = alc_fixup_disable_aamix,
Hui Wang831bfdf92015-06-26 12:35:17 +08006155 .chained = true,
6156 .chain_id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE
Takashi Iwai8b99aba2015-06-15 11:59:32 +02006157 },
David Henningssonc04017e2015-12-15 14:44:03 +01006158 [ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK] = {
6159 .type = HDA_FIXUP_FUNC,
6160 .v.func = alc_fixup_disable_aamix,
6161 .chained = true,
6162 .chain_id = ALC293_FIXUP_DELL1_MIC_NO_PRESENCE
6163 },
Takashi Iwai8b99aba2015-06-15 11:59:32 +02006164 [ALC292_FIXUP_DELL_E7X] = {
6165 .type = HDA_FIXUP_FUNC,
6166 .v.func = alc_fixup_dell_xps13,
6167 .chained = true,
6168 .chain_id = ALC292_FIXUP_DISABLE_AAMIX
6169 },
Kailang Yang977e6272015-05-18 15:31:20 +08006170 [ALC298_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6171 .type = HDA_FIXUP_PINS,
6172 .v.pins = (const struct hda_pintbl[]) {
6173 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6174 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6175 { }
6176 },
6177 .chained = true,
6178 .chain_id = ALC269_FIXUP_HEADSET_MODE
6179 },
Hui Wang2f726ae2017-03-31 10:31:40 +08006180 [ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE] = {
6181 .type = HDA_FIXUP_PINS,
6182 .v.pins = (const struct hda_pintbl[]) {
6183 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6184 { }
6185 },
6186 .chained = true,
6187 .chain_id = ALC269_FIXUP_HEADSET_MODE
6188 },
Kailang Yang6ed11312015-10-26 15:37:39 +08006189 [ALC275_FIXUP_DELL_XPS] = {
6190 .type = HDA_FIXUP_VERBS,
6191 .v.verbs = (const struct hda_verb[]) {
6192 /* Enables internal speaker */
6193 {0x20, AC_VERB_SET_COEF_INDEX, 0x1f},
6194 {0x20, AC_VERB_SET_PROC_COEF, 0x00c0},
6195 {0x20, AC_VERB_SET_COEF_INDEX, 0x30},
6196 {0x20, AC_VERB_SET_PROC_COEF, 0x00b1},
6197 {}
6198 }
6199 },
Hui Wang8c697292015-11-24 11:08:18 +08006200 [ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE] = {
6201 .type = HDA_FIXUP_VERBS,
6202 .v.verbs = (const struct hda_verb[]) {
6203 /* Disable pass-through path for FRONT 14h */
6204 {0x20, AC_VERB_SET_COEF_INDEX, 0x36},
6205 {0x20, AC_VERB_SET_PROC_COEF, 0x1737},
6206 {}
6207 },
6208 .chained = true,
6209 .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
6210 },
Hui Wang23adc192015-12-08 12:27:18 +08006211 [ALC293_FIXUP_LENOVO_SPK_NOISE] = {
6212 .type = HDA_FIXUP_FUNC,
6213 .v.func = alc_fixup_disable_aamix,
6214 .chained = true,
6215 .chain_id = ALC269_FIXUP_THINKPAD_ACPI
6216 },
Kailang3694cb22015-12-28 11:35:24 +08006217 [ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY] = {
6218 .type = HDA_FIXUP_FUNC,
6219 .v.func = alc233_fixup_lenovo_line2_mic_hotkey,
6220 },
Kai-Heng Feng3b43b712016-02-25 15:19:38 +08006221 [ALC255_FIXUP_DELL_SPK_NOISE] = {
6222 .type = HDA_FIXUP_FUNC,
6223 .v.func = alc_fixup_disable_aamix,
6224 .chained = true,
6225 .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
6226 },
David Henningsson2ae95572016-02-25 09:37:05 +01006227 [ALC225_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6228 .type = HDA_FIXUP_VERBS,
6229 .v.verbs = (const struct hda_verb[]) {
6230 /* Disable pass-through path for FRONT 14h */
6231 { 0x20, AC_VERB_SET_COEF_INDEX, 0x36 },
6232 { 0x20, AC_VERB_SET_PROC_COEF, 0x57d7 },
6233 {}
6234 },
6235 .chained = true,
6236 .chain_id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE
6237 },
Takashi Iwaif8839822016-02-25 14:31:59 +01006238 [ALC280_FIXUP_HP_HEADSET_MIC] = {
6239 .type = HDA_FIXUP_FUNC,
6240 .v.func = alc_fixup_disable_aamix,
6241 .chained = true,
6242 .chain_id = ALC269_FIXUP_HEADSET_MIC,
6243 },
Hui Wange549d192016-04-01 11:00:15 +08006244 [ALC221_FIXUP_HP_FRONT_MIC] = {
6245 .type = HDA_FIXUP_PINS,
6246 .v.pins = (const struct hda_pintbl[]) {
6247 { 0x19, 0x02a19020 }, /* Front Mic */
6248 { }
6249 },
6250 },
Sven Eckelmannc636b952016-04-11 16:55:26 +02006251 [ALC292_FIXUP_TPT460] = {
6252 .type = HDA_FIXUP_FUNC,
6253 .v.func = alc_fixup_tpt440_dock,
6254 .chained = true,
6255 .chain_id = ALC293_FIXUP_LENOVO_SPK_NOISE,
6256 },
Hui Wangdd9aa332016-08-01 10:20:32 +08006257 [ALC298_FIXUP_SPK_VOLUME] = {
6258 .type = HDA_FIXUP_FUNC,
6259 .v.func = alc298_fixup_speaker_volume,
Hui Wang59ec4b52016-08-04 15:28:04 +08006260 .chained = true,
Hui Wang2f726ae2017-03-31 10:31:40 +08006261 .chain_id = ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE,
Hui Wangdd9aa332016-08-01 10:20:32 +08006262 },
Takashi Iwaie312a862018-03-06 12:14:17 +01006263 [ALC295_FIXUP_DISABLE_DAC3] = {
6264 .type = HDA_FIXUP_FUNC,
6265 .v.func = alc295_fixup_disable_dac3,
6266 },
Kai-Heng Fengfd06c772016-08-30 15:36:34 +08006267 [ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER] = {
6268 .type = HDA_FIXUP_PINS,
6269 .v.pins = (const struct hda_pintbl[]) {
6270 { 0x1b, 0x90170151 },
6271 { }
6272 },
6273 .chained = true,
6274 .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
6275 },
Gabriele Mazzotta823ff162016-12-24 19:50:01 +01006276 [ALC269_FIXUP_ATIV_BOOK_8] = {
6277 .type = HDA_FIXUP_FUNC,
6278 .v.func = alc_fixup_auto_mute_via_amp,
6279 .chained = true,
6280 .chain_id = ALC269_FIXUP_NO_SHUTUP
6281 },
Kailang Yang9eb5d0e2017-01-17 15:40:25 +08006282 [ALC221_FIXUP_HP_MIC_NO_PRESENCE] = {
6283 .type = HDA_FIXUP_PINS,
6284 .v.pins = (const struct hda_pintbl[]) {
6285 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6286 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6287 { }
6288 },
6289 .chained = true,
6290 .chain_id = ALC269_FIXUP_HEADSET_MODE
6291 },
Chris Chiuc1732ed2017-02-28 14:17:13 -06006292 [ALC256_FIXUP_ASUS_HEADSET_MODE] = {
6293 .type = HDA_FIXUP_FUNC,
6294 .v.func = alc_fixup_headset_mode,
6295 },
6296 [ALC256_FIXUP_ASUS_MIC] = {
6297 .type = HDA_FIXUP_PINS,
6298 .v.pins = (const struct hda_pintbl[]) {
6299 { 0x13, 0x90a60160 }, /* use as internal mic */
6300 { 0x19, 0x04a11120 }, /* use as headset mic, without its own jack detect */
6301 { }
6302 },
6303 .chained = true,
6304 .chain_id = ALC256_FIXUP_ASUS_HEADSET_MODE
6305 },
Chris Chiueeed4cd2017-02-28 14:17:15 -06006306 [ALC256_FIXUP_ASUS_AIO_GPIO2] = {
6307 .type = HDA_FIXUP_VERBS,
6308 .v.verbs = (const struct hda_verb[]) {
6309 /* Set up GPIO2 for the speaker amp */
6310 { 0x01, AC_VERB_SET_GPIO_MASK, 0x04 },
6311 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04 },
6312 { 0x01, AC_VERB_SET_GPIO_DATA, 0x04 },
6313 {}
6314 },
6315 },
Chris Chiu216d7ae2017-02-28 14:17:14 -06006316 [ALC233_FIXUP_ASUS_MIC_NO_PRESENCE] = {
6317 .type = HDA_FIXUP_PINS,
6318 .v.pins = (const struct hda_pintbl[]) {
6319 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6320 { }
6321 },
6322 .chained = true,
6323 .chain_id = ALC269_FIXUP_HEADSET_MIC
6324 },
6325 [ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE] = {
6326 .type = HDA_FIXUP_VERBS,
6327 .v.verbs = (const struct hda_verb[]) {
6328 /* Enables internal speaker */
6329 {0x20, AC_VERB_SET_COEF_INDEX, 0x40},
6330 {0x20, AC_VERB_SET_PROC_COEF, 0x8800},
6331 {}
6332 },
6333 .chained = true,
6334 .chain_id = ALC233_FIXUP_ASUS_MIC_NO_PRESENCE
6335 },
Kailang Yangca169cc2017-04-25 16:17:40 +08006336 [ALC233_FIXUP_LENOVO_MULTI_CODECS] = {
6337 .type = HDA_FIXUP_FUNC,
6338 .v.func = alc233_alc662_fixup_lenovo_dual_codecs,
6339 },
Hui Wangf33f79f2017-07-07 12:08:29 +08006340 [ALC294_FIXUP_LENOVO_MIC_LOCATION] = {
6341 .type = HDA_FIXUP_PINS,
6342 .v.pins = (const struct hda_pintbl[]) {
6343 /* Change the mic location from front to right, otherwise there are
6344 two front mics with the same name, pulseaudio can't handle them.
6345 This is just a temporary workaround, after applying this fixup,
6346 there will be one "Front Mic" and one "Mic" in this machine.
6347 */
6348 { 0x1a, 0x04a19040 },
6349 { }
6350 },
6351 },
Kailang Yang5f364132017-07-25 16:28:16 +08006352 [ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE] = {
6353 .type = HDA_FIXUP_PINS,
6354 .v.pins = (const struct hda_pintbl[]) {
6355 { 0x16, 0x0101102f }, /* Rear Headset HP */
6356 { 0x19, 0x02a1913c }, /* use as Front headset mic, without its own jack detect */
6357 { 0x1a, 0x01a19030 }, /* Rear Headset MIC */
6358 { 0x1b, 0x02011020 },
6359 { }
6360 },
6361 .chained = true,
6362 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
6363 },
PeiSen Houb84e8432017-09-01 15:11:56 +08006364 [ALC700_FIXUP_INTEL_REFERENCE] = {
6365 .type = HDA_FIXUP_VERBS,
6366 .v.verbs = (const struct hda_verb[]) {
6367 /* Enables internal speaker */
6368 {0x20, AC_VERB_SET_COEF_INDEX, 0x45},
6369 {0x20, AC_VERB_SET_PROC_COEF, 0x5289},
6370 {0x20, AC_VERB_SET_COEF_INDEX, 0x4A},
6371 {0x20, AC_VERB_SET_PROC_COEF, 0x001b},
6372 {0x58, AC_VERB_SET_COEF_INDEX, 0x00},
6373 {0x58, AC_VERB_SET_PROC_COEF, 0x3888},
6374 {0x20, AC_VERB_SET_COEF_INDEX, 0x6f},
6375 {0x20, AC_VERB_SET_PROC_COEF, 0x2c0b},
6376 {}
6377 }
6378 },
Kailang Yang92266652017-12-14 15:28:58 +08006379 [ALC274_FIXUP_DELL_BIND_DACS] = {
6380 .type = HDA_FIXUP_FUNC,
6381 .v.func = alc274_fixup_bind_dacs,
6382 .chained = true,
6383 .chain_id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE
6384 },
6385 [ALC274_FIXUP_DELL_AIO_LINEOUT_VERB] = {
6386 .type = HDA_FIXUP_PINS,
6387 .v.pins = (const struct hda_pintbl[]) {
6388 { 0x1b, 0x0401102f },
6389 { }
6390 },
6391 .chained = true,
6392 .chain_id = ALC274_FIXUP_DELL_BIND_DACS
6393 },
Kailang Yang61fcf8e2018-02-02 15:26:46 +08006394 [ALC298_FIXUP_TPT470_DOCK] = {
6395 .type = HDA_FIXUP_FUNC,
6396 .v.func = alc_fixup_tpt470_dock,
6397 .chained = true,
6398 .chain_id = ALC293_FIXUP_LENOVO_SPK_NOISE
6399 },
Kailang Yangae104a22018-02-05 16:07:20 +08006400 [ALC255_FIXUP_DUMMY_LINEOUT_VERB] = {
6401 .type = HDA_FIXUP_PINS,
6402 .v.pins = (const struct hda_pintbl[]) {
6403 { 0x14, 0x0201101f },
6404 { }
6405 },
6406 .chained = true,
6407 .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
6408 },
Kailang Yangf0ba9d62018-03-16 11:46:08 +08006409 [ALC255_FIXUP_DELL_HEADSET_MIC] = {
6410 .type = HDA_FIXUP_PINS,
6411 .v.pins = (const struct hda_pintbl[]) {
6412 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6413 { }
6414 },
Hui Wang3ce0d5a2018-04-19 13:29:04 +08006415 .chained = true,
6416 .chain_id = ALC269_FIXUP_HEADSET_MIC
Kailang Yangf0ba9d62018-03-16 11:46:08 +08006417 },
Tom Bridenbbf8ff62018-05-29 17:34:20 +01006418 [ALC295_FIXUP_HP_X360] = {
6419 .type = HDA_FIXUP_FUNC,
6420 .v.func = alc295_fixup_hp_top_speakers,
6421 .chained = true,
6422 .chain_id = ALC269_FIXUP_HP_MUTE_LED_MIC3
6423 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02006424};
6425
6426static const struct snd_pci_quirk alc269_fixup_tbl[] = {
Marius Knausta6b92b62014-03-03 01:48:58 +01006427 SND_PCI_QUIRK(0x1025, 0x0283, "Acer TravelMate 8371", ALC269_FIXUP_INV_DMIC),
David Henningsson693b6132012-06-22 19:12:10 +02006428 SND_PCI_QUIRK(0x1025, 0x029b, "Acer 1810TZ", ALC269_FIXUP_INV_DMIC),
6429 SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC),
David Henningssonaaedfb42013-08-16 14:09:02 +02006430 SND_PCI_QUIRK(0x1025, 0x047c, "Acer AC700", ALC269_FIXUP_ACER_AC700),
Takashi Iwai78197172015-06-27 10:21:13 +02006431 SND_PCI_QUIRK(0x1025, 0x072d, "Acer Aspire V5-571G", ALC269_FIXUP_ASPIRE_HEADSET_MIC),
6432 SND_PCI_QUIRK(0x1025, 0x080d, "Acer Aspire V5-122P", ALC269_FIXUP_ASPIRE_HEADSET_MIC),
David Henningssonaaedfb42013-08-16 14:09:02 +02006433 SND_PCI_QUIRK(0x1025, 0x0740, "Acer AO725", ALC271_FIXUP_HP_GATE_MIC_JACK),
6434 SND_PCI_QUIRK(0x1025, 0x0742, "Acer AO756", ALC271_FIXUP_HP_GATE_MIC_JACK),
Simon South02322ac2016-03-02 23:10:44 -05006435 SND_PCI_QUIRK(0x1025, 0x0762, "Acer Aspire E1-472", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572),
Oleksij Rempelb1e89722013-12-04 20:50:53 +01006436 SND_PCI_QUIRK(0x1025, 0x0775, "Acer Aspire E1-572", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572),
Takashi Iwai1a22e772014-08-27 08:19:05 +02006437 SND_PCI_QUIRK(0x1025, 0x079b, "Acer Aspire V5-573G", ALC282_FIXUP_ASPIRE_V5_PINS),
Takashi Iwaib9c2fa52015-11-19 16:39:50 +01006438 SND_PCI_QUIRK(0x1025, 0x106d, "Acer Cloudbook 14", ALC283_FIXUP_CHROME_BOOK),
David Henningssonaaedfb42013-08-16 14:09:02 +02006439 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
Kailang Yang6ed11312015-10-26 15:37:39 +08006440 SND_PCI_QUIRK(0x1028, 0x054b, "Dell XPS one 2710", ALC275_FIXUP_DELL_XPS),
Takashi Iwai86f799b2015-11-14 17:46:31 +01006441 SND_PCI_QUIRK(0x1028, 0x05bd, "Dell Latitude E6440", ALC292_FIXUP_DELL_E7X),
Takashi Iwaicf521032016-01-15 12:59:25 +01006442 SND_PCI_QUIRK(0x1028, 0x05be, "Dell Latitude E6540", ALC292_FIXUP_DELL_E7X),
Takashi Iwai8b99aba2015-06-15 11:59:32 +02006443 SND_PCI_QUIRK(0x1028, 0x05ca, "Dell Latitude E7240", ALC292_FIXUP_DELL_E7X),
6444 SND_PCI_QUIRK(0x1028, 0x05cb, "Dell Latitude E7440", ALC292_FIXUP_DELL_E7X),
David Henningsson0f4881d2013-12-20 16:08:13 +01006445 SND_PCI_QUIRK(0x1028, 0x05da, "Dell Vostro 5460", ALC290_FIXUP_SUBWOOFER),
David Henningsson73bdd592013-04-15 15:44:14 +02006446 SND_PCI_QUIRK(0x1028, 0x05f4, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
6447 SND_PCI_QUIRK(0x1028, 0x05f5, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
6448 SND_PCI_QUIRK(0x1028, 0x05f6, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
David Henningsson0f4881d2013-12-20 16:08:13 +01006449 SND_PCI_QUIRK(0x1028, 0x0615, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK),
6450 SND_PCI_QUIRK(0x1028, 0x0616, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK),
Takashi Iwai98070572016-01-12 21:06:39 +01006451 SND_PCI_QUIRK(0x1028, 0x062c, "Dell Latitude E5550", ALC292_FIXUP_DELL_E7X),
Takashi Iwai42755542015-06-29 10:56:53 +02006452 SND_PCI_QUIRK(0x1028, 0x062e, "Dell Latitude E7450", ALC292_FIXUP_DELL_E7X),
David Henningsson0f4881d2013-12-20 16:08:13 +01006453 SND_PCI_QUIRK(0x1028, 0x0638, "Dell Inspiron 5439", ALC290_FIXUP_MONO_SPEAKERS_HSJACK),
Kailang Yanga22aa262014-04-23 17:34:28 +08006454 SND_PCI_QUIRK(0x1028, 0x064a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
6455 SND_PCI_QUIRK(0x1028, 0x064b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
Hui Wang831bfdf92015-06-26 12:35:17 +08006456 SND_PCI_QUIRK(0x1028, 0x0665, "Dell XPS 13", ALC288_FIXUP_DELL_XPS_13),
Bastien Noceraafecb142016-04-18 11:10:42 +02006457 SND_PCI_QUIRK(0x1028, 0x0669, "Dell Optiplex 9020m", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
Takashi Iwai3a05d122015-07-29 09:04:52 +02006458 SND_PCI_QUIRK(0x1028, 0x069a, "Dell Vostro 5480", ALC290_FIXUP_SUBWOOFER_HSJACK),
Kailang Yang8b724152014-12-17 17:08:59 +08006459 SND_PCI_QUIRK(0x1028, 0x06c7, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
Kailang Yangb7343042014-12-02 14:50:45 +08006460 SND_PCI_QUIRK(0x1028, 0x06d9, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
6461 SND_PCI_QUIRK(0x1028, 0x06da, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
David Henningssonc04017e2015-12-15 14:44:03 +01006462 SND_PCI_QUIRK(0x1028, 0x06db, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
6463 SND_PCI_QUIRK(0x1028, 0x06dd, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
6464 SND_PCI_QUIRK(0x1028, 0x06de, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
6465 SND_PCI_QUIRK(0x1028, 0x06df, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
6466 SND_PCI_QUIRK(0x1028, 0x06e0, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
Kai-Heng Feng423cd782016-05-20 15:47:23 +08006467 SND_PCI_QUIRK(0x1028, 0x0704, "Dell XPS 13 9350", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE),
Kai-Heng Fengfd06c772016-08-30 15:36:34 +08006468 SND_PCI_QUIRK(0x1028, 0x0706, "Dell Inspiron 7559", ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER),
Kai-Heng Feng3b43b712016-02-25 15:19:38 +08006469 SND_PCI_QUIRK(0x1028, 0x0725, "Dell Inspiron 3162", ALC255_FIXUP_DELL_SPK_NOISE),
Kai-Heng Feng423cd782016-05-20 15:47:23 +08006470 SND_PCI_QUIRK(0x1028, 0x075b, "Dell XPS 13 9360", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE),
Hui Wangdd9aa332016-08-01 10:20:32 +08006471 SND_PCI_QUIRK(0x1028, 0x075d, "Dell AIO", ALC298_FIXUP_SPK_VOLUME),
Takashi Iwaie312a862018-03-06 12:14:17 +01006472 SND_PCI_QUIRK(0x1028, 0x07b0, "Dell Precision 7520", ALC295_FIXUP_DISABLE_DAC3),
Takashi Iwai493de342017-02-28 17:27:57 +01006473 SND_PCI_QUIRK(0x1028, 0x0798, "Dell Inspiron 17 7000 Gaming", ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER),
Kailang Yang5f364132017-07-25 16:28:16 +08006474 SND_PCI_QUIRK(0x1028, 0x080c, "Dell WYSE", ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE),
Takashi Iwaie4c9fd12018-01-10 08:34:28 +01006475 SND_PCI_QUIRK(0x1028, 0x082a, "Dell XPS 13 9360", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE),
Kailang Yang40e2c4e2018-02-02 15:13:09 +08006476 SND_PCI_QUIRK(0x1028, 0x084b, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB),
6477 SND_PCI_QUIRK(0x1028, 0x084e, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB),
Kailang Yangf0ba9d62018-03-16 11:46:08 +08006478 SND_PCI_QUIRK(0x1028, 0x0871, "Dell Precision 3630", ALC255_FIXUP_DELL_HEADSET_MIC),
6479 SND_PCI_QUIRK(0x1028, 0x0872, "Dell Precision 3630", ALC255_FIXUP_DELL_HEADSET_MIC),
Kailang Yangae104a22018-02-05 16:07:20 +08006480 SND_PCI_QUIRK(0x1028, 0x0873, "Dell Precision 3930", ALC255_FIXUP_DUMMY_LINEOUT_VERB),
Kailang Yanga22aa262014-04-23 17:34:28 +08006481 SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
6482 SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
Takashi Iwai08fb0d02013-01-10 17:33:58 +01006483 SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01006484 SND_PCI_QUIRK(0x103c, 0x18e6, "HP", ALC269_FIXUP_HP_GPIO_LED),
David Henningsson8e35cd42013-11-06 11:20:01 +01006485 SND_PCI_QUIRK(0x103c, 0x218b, "HP", ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED),
David Henningsson33f4acd2015-01-07 15:50:13 +01006486 SND_PCI_QUIRK(0x103c, 0x225f, "HP", ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY),
Kailang Yangc60666b2014-02-21 16:23:35 +08006487 /* ALC282 */
Hui Wang7976eb42015-02-13 11:14:41 +08006488 SND_PCI_QUIRK(0x103c, 0x21f9, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang8a02b162014-06-13 17:16:31 +08006489 SND_PCI_QUIRK(0x103c, 0x2210, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang8a02b162014-06-13 17:16:31 +08006490 SND_PCI_QUIRK(0x103c, 0x2214, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08006491 SND_PCI_QUIRK(0x103c, 0x2236, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
6492 SND_PCI_QUIRK(0x103c, 0x2237, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
6493 SND_PCI_QUIRK(0x103c, 0x2238, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
6494 SND_PCI_QUIRK(0x103c, 0x2239, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08006495 SND_PCI_QUIRK(0x103c, 0x224b, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
Kailang Yangc60666b2014-02-21 16:23:35 +08006496 SND_PCI_QUIRK(0x103c, 0x2268, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08006497 SND_PCI_QUIRK(0x103c, 0x226a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
6498 SND_PCI_QUIRK(0x103c, 0x226b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang8a02b162014-06-13 17:16:31 +08006499 SND_PCI_QUIRK(0x103c, 0x226e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangeaa8e5e2014-11-21 15:49:11 +08006500 SND_PCI_QUIRK(0x103c, 0x2271, "HP", ALC286_FIXUP_HP_GPIO_LED),
TienFu Chenb4b33f92015-01-20 15:06:21 +01006501 SND_PCI_QUIRK(0x103c, 0x2272, "HP", ALC280_FIXUP_HP_DOCK_PINS),
TienFu Chen3271cb22015-02-10 09:09:41 +01006502 SND_PCI_QUIRK(0x103c, 0x2273, "HP", ALC280_FIXUP_HP_DOCK_PINS),
Kailang Yangc60666b2014-02-21 16:23:35 +08006503 SND_PCI_QUIRK(0x103c, 0x229e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08006504 SND_PCI_QUIRK(0x103c, 0x22b2, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
6505 SND_PCI_QUIRK(0x103c, 0x22b7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
6506 SND_PCI_QUIRK(0x103c, 0x22bf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08006507 SND_PCI_QUIRK(0x103c, 0x22cf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Keith Packard98973f22015-07-15 12:14:39 -07006508 SND_PCI_QUIRK(0x103c, 0x22db, "HP", ALC280_FIXUP_HP_9480M),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08006509 SND_PCI_QUIRK(0x103c, 0x22dc, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
6510 SND_PCI_QUIRK(0x103c, 0x22fb, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yangc60666b2014-02-21 16:23:35 +08006511 /* ALC290 */
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08006512 SND_PCI_QUIRK(0x103c, 0x221b, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08006513 SND_PCI_QUIRK(0x103c, 0x2221, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08006514 SND_PCI_QUIRK(0x103c, 0x2225, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08006515 SND_PCI_QUIRK(0x103c, 0x2253, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
6516 SND_PCI_QUIRK(0x103c, 0x2254, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
6517 SND_PCI_QUIRK(0x103c, 0x2255, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
6518 SND_PCI_QUIRK(0x103c, 0x2256, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
6519 SND_PCI_QUIRK(0x103c, 0x2257, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08006520 SND_PCI_QUIRK(0x103c, 0x2259, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Jaroslav Kysela04d54662017-03-09 13:29:13 +01006521 SND_PCI_QUIRK(0x103c, 0x225a, "HP", ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED),
Kailang Yangc60666b2014-02-21 16:23:35 +08006522 SND_PCI_QUIRK(0x103c, 0x2260, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08006523 SND_PCI_QUIRK(0x103c, 0x2263, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
6524 SND_PCI_QUIRK(0x103c, 0x2264, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
6525 SND_PCI_QUIRK(0x103c, 0x2265, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08006526 SND_PCI_QUIRK(0x103c, 0x2272, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
6527 SND_PCI_QUIRK(0x103c, 0x2273, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08006528 SND_PCI_QUIRK(0x103c, 0x2278, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yangc60666b2014-02-21 16:23:35 +08006529 SND_PCI_QUIRK(0x103c, 0x227f, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08006530 SND_PCI_QUIRK(0x103c, 0x2282, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08006531 SND_PCI_QUIRK(0x103c, 0x228b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08006532 SND_PCI_QUIRK(0x103c, 0x228e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
6533 SND_PCI_QUIRK(0x103c, 0x22c5, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08006534 SND_PCI_QUIRK(0x103c, 0x22c7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
6535 SND_PCI_QUIRK(0x103c, 0x22c8, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08006536 SND_PCI_QUIRK(0x103c, 0x22c4, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang8a02b162014-06-13 17:16:31 +08006537 SND_PCI_QUIRK(0x103c, 0x2334, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
6538 SND_PCI_QUIRK(0x103c, 0x2335, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
6539 SND_PCI_QUIRK(0x103c, 0x2336, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
6540 SND_PCI_QUIRK(0x103c, 0x2337, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Takashi Iwaif8839822016-02-25 14:31:59 +01006541 SND_PCI_QUIRK(0x103c, 0x221c, "HP EliteBook 755 G2", ALC280_FIXUP_HP_HEADSET_MIC),
Hui Wange549d192016-04-01 11:00:15 +08006542 SND_PCI_QUIRK(0x103c, 0x8256, "HP", ALC221_FIXUP_HP_FRONT_MIC),
Tom Bridenbbf8ff62018-05-29 17:34:20 +01006543 SND_PCI_QUIRK(0x103c, 0x827e, "HP x360", ALC295_FIXUP_HP_X360),
Kailang Yang9eb5d0e2017-01-17 15:40:25 +08006544 SND_PCI_QUIRK(0x103c, 0x82bf, "HP", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
6545 SND_PCI_QUIRK(0x103c, 0x82c0, "HP", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
Chris Chiuc1732ed2017-02-28 14:17:13 -06006546 SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC),
Takashi Iwai7bba2152013-09-06 15:45:38 +02006547 SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300),
David Henningsson3e0d6112013-04-22 14:30:14 +02006548 SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Chris Chiuc1732ed2017-02-28 14:17:13 -06006549 SND_PCI_QUIRK(0x1043, 0x10c0, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC),
Takashi Iwai4eab0ea2017-06-06 12:33:17 +02006550 SND_PCI_QUIRK(0x1043, 0x10d0, "ASUS X540LA/X540LJ", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
David Henningsson3e0d6112013-04-22 14:30:14 +02006551 SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Takashi Iwai4eab0ea2017-06-06 12:33:17 +02006552 SND_PCI_QUIRK(0x1043, 0x11c0, "ASUS X556UR", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
6553 SND_PCI_QUIRK(0x1043, 0x1290, "ASUS X441SA", ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE),
6554 SND_PCI_QUIRK(0x1043, 0x12a0, "ASUS X441UV", ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE),
Chris Chiuc1732ed2017-02-28 14:17:13 -06006555 SND_PCI_QUIRK(0x1043, 0x12f0, "ASUS X541UV", ALC256_FIXUP_ASUS_MIC),
6556 SND_PCI_QUIRK(0x1043, 0x12e0, "ASUS X541SA", ALC256_FIXUP_ASUS_MIC),
6557 SND_PCI_QUIRK(0x1043, 0x13b0, "ASUS Z550SA", ALC256_FIXUP_ASUS_MIC),
Oleksij Rempel2cede302013-11-27 17:12:03 +01006558 SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK),
Takashi Iwai23870832013-11-29 14:13:12 +01006559 SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A),
David Henningsson3e0d6112013-04-22 14:30:14 +02006560 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC),
Takashi Iwai017f2a12011-07-09 14:42:25 +02006561 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
Chris Chiu28e8af82017-06-05 15:05:30 -06006562 SND_PCI_QUIRK(0x1043, 0x1a30, "ASUS X705UD", ALC256_FIXUP_ASUS_MIC),
David Henningsson693b6132012-06-22 19:12:10 +02006563 SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC),
Chris Chiu615966a2017-02-28 14:17:12 -06006564 SND_PCI_QUIRK(0x1043, 0x1bbd, "ASUS Z550MA", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
Takashi Iwai4eab0ea2017-06-06 12:33:17 +02006565 SND_PCI_QUIRK(0x1043, 0x1c23, "Asus X55U", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Chris Chiuc1732ed2017-02-28 14:17:13 -06006566 SND_PCI_QUIRK(0x1043, 0x1ccd, "ASUS X555UB", ALC256_FIXUP_ASUS_MIC),
Chris Chiueeed4cd2017-02-28 14:17:15 -06006567 SND_PCI_QUIRK(0x1043, 0x3030, "ASUS ZN270IE", ALC256_FIXUP_ASUS_AIO_GPIO2),
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02006568 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC),
6569 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC),
6570 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
6571 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
David Henningssond240d1d2013-04-15 12:50:02 +02006572 SND_PCI_QUIRK(0x1043, 0x8516, "ASUS X101CH", ALC269_FIXUP_ASUS_X101),
Takashi Iwaif88abaa2014-02-07 12:07:59 +01006573 SND_PCI_QUIRK(0x104d, 0x90b5, "Sony VAIO Pro 11", ALC286_FIXUP_SONY_MIC_NO_PRESENCE),
David Henningsson88cfcf82013-10-11 10:18:45 +02006574 SND_PCI_QUIRK(0x104d, 0x90b6, "Sony VAIO Pro 13", ALC286_FIXUP_SONY_MIC_NO_PRESENCE),
Takashi Iwai1d045db2011-07-07 18:23:21 +02006575 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
6576 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
6577 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
Takashi Iwaie9bd7d52014-05-21 11:06:49 +02006578 SND_PCI_QUIRK(0x104d, 0x9099, "Sony VAIO S13", ALC275_FIXUP_SONY_DISABLE_AAMIX),
Takashi Iwai24519912011-08-16 15:08:49 +02006579 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook", ALC269_FIXUP_LIFEBOOK),
Takashi Iwai4df3fd12015-06-29 08:38:02 +02006580 SND_PCI_QUIRK(0x10cf, 0x159f, "Lifebook E780", ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT),
Takashi Iwaicc7016a2015-04-08 20:47:55 +02006581 SND_PCI_QUIRK(0x10cf, 0x15dc, "Lifebook T731", ALC269_FIXUP_LIFEBOOK_HP_PIN),
Takashi Iwai88776f32015-05-01 09:20:34 +02006582 SND_PCI_QUIRK(0x10cf, 0x1757, "Lifebook E752", ALC269_FIXUP_LIFEBOOK_HP_PIN),
Jan-Marek Glogowskifdcc9682018-02-14 11:29:15 +01006583 SND_PCI_QUIRK(0x10cf, 0x1629, "Lifebook U7x7", ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC),
David Henningsson2041d562014-06-13 11:15:44 +02006584 SND_PCI_QUIRK(0x10cf, 0x1845, "Lifebook U904", ALC269_FIXUP_LIFEBOOK_EXTMIC),
PeiSen Houb84e8432017-09-01 15:11:56 +08006585 SND_PCI_QUIRK(0x10ec, 0x10f2, "Intel Reference board", ALC700_FIXUP_INTEL_REFERENCE),
David Henningssona33cc482014-10-07 10:18:41 +02006586 SND_PCI_QUIRK(0x144d, 0xc109, "Samsung Ativ book 9 (NP900X3G)", ALC269_FIXUP_INV_DMIC),
Gabriele Mazzotta823ff162016-12-24 19:50:01 +01006587 SND_PCI_QUIRK(0x144d, 0xc740, "Samsung Ativ book 8 (NP870Z5G)", ALC269_FIXUP_ATIV_BOOK_8),
Anisse Astierabaa22742016-08-24 09:14:13 +02006588 SND_PCI_QUIRK(0x1458, 0xfa53, "Gigabyte BXBT-2807", ALC283_FIXUP_HEADSET_MIC),
6589 SND_PCI_QUIRK(0x1462, 0xb120, "MSI Cubi MS-B120", ALC283_FIXUP_HEADSET_MIC),
Kailang Yangca169cc2017-04-25 16:17:40 +08006590 SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC233_FIXUP_LENOVO_MULTI_CODECS),
Takashi Iwai1d045db2011-07-07 18:23:21 +02006591 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
6592 SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
6593 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
6594 SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
6595 SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
Takashi Iwai707fba32012-08-02 09:04:39 +02006596 SND_PCI_QUIRK(0x17aa, 0x21f6, "Thinkpad T530", ALC269_FIXUP_LENOVO_DOCK),
Felix Kaechelec8415a42012-08-06 23:02:01 +02006597 SND_PCI_QUIRK(0x17aa, 0x21fa, "Thinkpad X230", ALC269_FIXUP_LENOVO_DOCK),
Stefán Freyr84f98fd2012-10-19 22:46:00 +02006598 SND_PCI_QUIRK(0x17aa, 0x21f3, "Thinkpad T430", ALC269_FIXUP_LENOVO_DOCK),
Philipp A. Mohrenweiser4407be62012-08-06 13:14:18 +02006599 SND_PCI_QUIRK(0x17aa, 0x21fb, "Thinkpad T430s", ALC269_FIXUP_LENOVO_DOCK),
David Henningsson108cc102012-07-20 10:37:25 +02006600 SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK),
David Henningssonaaedfb42013-08-16 14:09:02 +02006601 SND_PCI_QUIRK(0x17aa, 0x2208, "Thinkpad T431s", ALC269_FIXUP_LENOVO_DOCK),
Takashi Iwai9a811232015-12-09 15:17:43 +01006602 SND_PCI_QUIRK(0x17aa, 0x220c, "Thinkpad T440s", ALC292_FIXUP_TPT440),
Takashi Iwai1c37c222014-05-06 17:34:42 +02006603 SND_PCI_QUIRK(0x17aa, 0x220e, "Thinkpad T440p", ALC292_FIXUP_TPT440_DOCK),
Takashi Iwaia12137e2014-06-27 12:14:35 +02006604 SND_PCI_QUIRK(0x17aa, 0x2210, "Thinkpad T540p", ALC292_FIXUP_TPT440_DOCK),
Rick Sherman59a51a62015-08-18 21:04:30 -05006605 SND_PCI_QUIRK(0x17aa, 0x2211, "Thinkpad W541", ALC292_FIXUP_TPT440_DOCK),
Takashi Iwai6d169412014-10-07 17:27:02 +02006606 SND_PCI_QUIRK(0x17aa, 0x2212, "Thinkpad T440", ALC292_FIXUP_TPT440_DOCK),
Lukas Bossard7c215392014-10-29 18:31:07 +01006607 SND_PCI_QUIRK(0x17aa, 0x2214, "Thinkpad X240", ALC292_FIXUP_TPT440_DOCK),
David Henningssona4a9e082013-08-16 14:09:01 +02006608 SND_PCI_QUIRK(0x17aa, 0x2215, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Takashi Iwaib6903c02015-12-10 12:20:20 +01006609 SND_PCI_QUIRK(0x17aa, 0x2218, "Thinkpad X1 Carbon 2nd", ALC292_FIXUP_TPT440_DOCK),
Laura Abbottd05ea7d2015-10-02 11:09:54 -07006610 SND_PCI_QUIRK(0x17aa, 0x2223, "ThinkPad T550", ALC292_FIXUP_TPT440_DOCK),
Yves-Alexis Perezc0278662015-04-11 09:31:35 +02006611 SND_PCI_QUIRK(0x17aa, 0x2226, "ThinkPad X250", ALC292_FIXUP_TPT440_DOCK),
Kailang Yang61fcf8e2018-02-02 15:26:46 +08006612 SND_PCI_QUIRK(0x17aa, 0x222d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
6613 SND_PCI_QUIRK(0x17aa, 0x222e, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
Torsten Hilbrichdab38e42016-06-07 13:14:21 +02006614 SND_PCI_QUIRK(0x17aa, 0x2231, "Thinkpad T560", ALC292_FIXUP_TPT460),
Sven Eckelmannc636b952016-04-11 16:55:26 +02006615 SND_PCI_QUIRK(0x17aa, 0x2233, "Thinkpad", ALC292_FIXUP_TPT460),
Kailang Yang61fcf8e2018-02-02 15:26:46 +08006616 SND_PCI_QUIRK(0x17aa, 0x2245, "Thinkpad T470", ALC298_FIXUP_TPT470_DOCK),
6617 SND_PCI_QUIRK(0x17aa, 0x2246, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
6618 SND_PCI_QUIRK(0x17aa, 0x2247, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
Dennis Wassenberge4c07b32018-03-08 13:17:54 +01006619 SND_PCI_QUIRK(0x17aa, 0x2249, "Thinkpad", ALC292_FIXUP_TPT460),
Kailang Yang61fcf8e2018-02-02 15:26:46 +08006620 SND_PCI_QUIRK(0x17aa, 0x224b, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
6621 SND_PCI_QUIRK(0x17aa, 0x224c, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
6622 SND_PCI_QUIRK(0x17aa, 0x224d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
Benjamin Berg85981df2018-02-14 13:29:39 +01006623 SND_PCI_QUIRK(0x17aa, 0x225d, "Thinkpad T480", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Kailang3694cb22015-12-28 11:35:24 +08006624 SND_PCI_QUIRK(0x17aa, 0x30bb, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
Hui Wang6ef2f682016-03-11 12:04:02 +08006625 SND_PCI_QUIRK(0x17aa, 0x30e2, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
Hui Wangf33f79f2017-07-07 12:08:29 +08006626 SND_PCI_QUIRK(0x17aa, 0x310c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
Kailang Yang65811832018-04-25 17:07:27 +08006627 SND_PCI_QUIRK(0x17aa, 0x312f, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
Hui Wanga3dafb22018-04-19 13:29:05 +08006628 SND_PCI_QUIRK(0x17aa, 0x3138, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
Hui Wang8da5bbf2017-12-22 11:17:46 +08006629 SND_PCI_QUIRK(0x17aa, 0x313c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
David Henningsson56f27012016-01-11 09:33:14 +01006630 SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
Takashi Iwaifedb2242014-11-13 07:11:38 +01006631 SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC),
Takashi Iwai9b745ab2014-03-07 08:37:19 +01006632 SND_PCI_QUIRK(0x17aa, 0x3978, "IdeaPad Y410P", ALC269_FIXUP_NO_SHUTUP),
David Henningssona4a9e082013-08-16 14:09:01 +02006633 SND_PCI_QUIRK(0x17aa, 0x5013, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Kailang Yang1bb3e062013-09-27 13:10:25 +02006634 SND_PCI_QUIRK(0x17aa, 0x501a, "Thinkpad", ALC283_FIXUP_INT_MIC),
Takashi Iwaic497d9f2014-10-08 12:14:40 +02006635 SND_PCI_QUIRK(0x17aa, 0x501e, "Thinkpad L440", ALC292_FIXUP_TPT440_DOCK),
David Henningssoncd5302c2013-08-19 12:22:33 +02006636 SND_PCI_QUIRK(0x17aa, 0x5026, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Jo-Philipp Wichf2aa1112015-04-13 12:47:26 +02006637 SND_PCI_QUIRK(0x17aa, 0x5034, "Thinkpad T450", ALC292_FIXUP_TPT440_DOCK),
Sebastian Wicki80b311d2015-03-23 17:23:11 +01006638 SND_PCI_QUIRK(0x17aa, 0x5036, "Thinkpad T450s", ALC292_FIXUP_TPT440_DOCK),
Ansgar Hegerfeld09ea9972015-05-14 12:31:32 +02006639 SND_PCI_QUIRK(0x17aa, 0x503c, "Thinkpad L450", ALC292_FIXUP_TPT440_DOCK),
Conrad Kostecki037e1192016-04-26 10:08:10 +02006640 SND_PCI_QUIRK(0x17aa, 0x504a, "ThinkPad X260", ALC292_FIXUP_TPT440_DOCK),
Hui Wang23adc192015-12-08 12:27:18 +08006641 SND_PCI_QUIRK(0x17aa, 0x504b, "Thinkpad", ALC293_FIXUP_LENOVO_SPK_NOISE),
Jaroslav Kysela0f087ee2016-06-24 15:13:16 +02006642 SND_PCI_QUIRK(0x17aa, 0x5050, "Thinkpad T560p", ALC292_FIXUP_TPT460),
Torsten Hilbrich9cd25742016-07-05 10:40:22 +02006643 SND_PCI_QUIRK(0x17aa, 0x5051, "Thinkpad L460", ALC292_FIXUP_TPT460),
Jaroslav Kysela0f087ee2016-06-24 15:13:16 +02006644 SND_PCI_QUIRK(0x17aa, 0x5053, "Thinkpad T460", ALC292_FIXUP_TPT460),
Kailang Yang61fcf8e2018-02-02 15:26:46 +08006645 SND_PCI_QUIRK(0x17aa, 0x505d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
6646 SND_PCI_QUIRK(0x17aa, 0x505f, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
6647 SND_PCI_QUIRK(0x17aa, 0x5062, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
David Henningssoncd5302c2013-08-19 12:22:33 +02006648 SND_PCI_QUIRK(0x17aa, 0x5109, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Kailang Yang61fcf8e2018-02-02 15:26:46 +08006649 SND_PCI_QUIRK(0x17aa, 0x511e, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
6650 SND_PCI_QUIRK(0x17aa, 0x511f, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
David Henningsson012e7eb2012-08-08 08:43:37 +02006651 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K),
Takashi Iwai1d045db2011-07-07 18:23:21 +02006652 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
Anisse Astier02b504d2013-06-03 11:53:10 +02006653 SND_PCI_QUIRK(0x1b7d, 0xa831, "Ordissimo EVE2 ", ALC269VB_FIXUP_ORDISSIMO_EVE2), /* Also known as Malata PC-B1303 */
Takashi Iwaia4297b52011-08-23 18:40:12 +02006654
Takashi Iwaia7f3eed2012-02-16 13:03:18 +01006655#if 0
Takashi Iwaia4297b52011-08-23 18:40:12 +02006656 /* Below is a quirk table taken from the old code.
6657 * Basically the device should work as is without the fixup table.
6658 * If BIOS doesn't give a proper info, enable the corresponding
6659 * fixup entry.
Jesper Juhl7d7eb9e2012-04-12 22:11:25 +02006660 */
Takashi Iwaia4297b52011-08-23 18:40:12 +02006661 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
6662 ALC269_FIXUP_AMIC),
6663 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269_FIXUP_AMIC),
Takashi Iwaia4297b52011-08-23 18:40:12 +02006664 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269_FIXUP_AMIC),
6665 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_FIXUP_AMIC),
6666 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269_FIXUP_AMIC),
6667 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269_FIXUP_AMIC),
6668 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269_FIXUP_AMIC),
6669 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269_FIXUP_AMIC),
6670 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_FIXUP_AMIC),
6671 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269_FIXUP_AMIC),
6672 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_FIXUP_AMIC),
6673 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_FIXUP_AMIC),
6674 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_FIXUP_AMIC),
6675 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_FIXUP_AMIC),
6676 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_FIXUP_AMIC),
6677 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_FIXUP_AMIC),
6678 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_FIXUP_AMIC),
6679 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_FIXUP_AMIC),
6680 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_FIXUP_AMIC),
6681 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_FIXUP_AMIC),
6682 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_FIXUP_AMIC),
6683 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_FIXUP_AMIC),
6684 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_FIXUP_AMIC),
6685 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_FIXUP_AMIC),
6686 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_FIXUP_AMIC),
6687 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_FIXUP_AMIC),
6688 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_FIXUP_AMIC),
6689 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_FIXUP_AMIC),
6690 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_FIXUP_AMIC),
6691 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_FIXUP_AMIC),
6692 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_FIXUP_AMIC),
6693 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_FIXUP_AMIC),
6694 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_FIXUP_AMIC),
6695 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_FIXUP_AMIC),
6696 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_FIXUP_AMIC),
6697 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_FIXUP_DMIC),
6698 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_FIXUP_AMIC),
6699 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_AMIC),
6700 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_FIXUP_DMIC),
6701 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_FIXUP_DMIC),
6702#endif
6703 {}
6704};
6705
David Henningsson214eef72014-07-22 14:09:35 +02006706static const struct snd_pci_quirk alc269_fixup_vendor_tbl[] = {
6707 SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC),
6708 SND_PCI_QUIRK_VENDOR(0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED),
6709 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
6710 SND_PCI_QUIRK_VENDOR(0x17aa, "Thinkpad", ALC269_FIXUP_THINKPAD_ACPI),
6711 {}
6712};
6713
Takashi Iwai1727a772013-01-10 09:52:52 +01006714static const struct hda_model_fixup alc269_fixup_models[] = {
Takashi Iwaia4297b52011-08-23 18:40:12 +02006715 {.id = ALC269_FIXUP_AMIC, .name = "laptop-amic"},
6716 {.id = ALC269_FIXUP_DMIC, .name = "laptop-dmic"},
Takashi Iwai6e72aa52012-06-25 10:52:25 +02006717 {.id = ALC269_FIXUP_STEREO_DMIC, .name = "alc269-dmic"},
6718 {.id = ALC271_FIXUP_DMIC, .name = "alc271-dmic"},
6719 {.id = ALC269_FIXUP_INV_DMIC, .name = "inv-dmic"},
David Henningsson7c478f02013-10-11 10:18:46 +02006720 {.id = ALC269_FIXUP_HEADSET_MIC, .name = "headset-mic"},
Takashi Iwaib0169512015-05-19 10:20:13 +02006721 {.id = ALC269_FIXUP_HEADSET_MODE, .name = "headset-mode"},
6722 {.id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC, .name = "headset-mode-no-hp-mic"},
David Henningsson108cc102012-07-20 10:37:25 +02006723 {.id = ALC269_FIXUP_LENOVO_DOCK, .name = "lenovo-dock"},
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01006724 {.id = ALC269_FIXUP_HP_GPIO_LED, .name = "hp-gpio-led"},
Jaroslav Kysela04d54662017-03-09 13:29:13 +01006725 {.id = ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED, .name = "hp-dock-gpio-mic1-led"},
David Henningssone32aa852013-06-17 11:04:02 +02006726 {.id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "dell-headset-multi"},
6727 {.id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE, .name = "dell-headset-dock"},
Kailang Yangbe8ef162014-04-08 15:19:49 +08006728 {.id = ALC283_FIXUP_CHROME_BOOK, .name = "alc283-dac-wcaps"},
Kailang Yang0202e992013-12-02 15:20:15 +08006729 {.id = ALC283_FIXUP_SENSE_COMBO_JACK, .name = "alc283-sense-combo"},
Takashi Iwai1c37c222014-05-06 17:34:42 +02006730 {.id = ALC292_FIXUP_TPT440_DOCK, .name = "tpt440-dock"},
Takashi Iwai9a811232015-12-09 15:17:43 +01006731 {.id = ALC292_FIXUP_TPT440, .name = "tpt440"},
Sven Eckelmannc636b952016-04-11 16:55:26 +02006732 {.id = ALC292_FIXUP_TPT460, .name = "tpt460"},
Takashi Iwaiba90d6a2017-05-22 16:38:47 +02006733 {.id = ALC233_FIXUP_LENOVO_MULTI_CODECS, .name = "dual-codecs"},
Takashi Iwai28d1d6d2017-10-18 14:01:58 +02006734 {.id = ALC700_FIXUP_INTEL_REFERENCE, .name = "alc700-ref"},
Takashi Iwai1d045db2011-07-07 18:23:21 +02006735 {}
6736};
Kailang Yangcfc5a842016-02-03 15:20:39 +08006737#define ALC225_STANDARD_PINS \
Kailang Yangcfc5a842016-02-03 15:20:39 +08006738 {0x21, 0x04211020}
Takashi Iwai1d045db2011-07-07 18:23:21 +02006739
Hui Wange8191a82015-04-24 13:39:59 +08006740#define ALC256_STANDARD_PINS \
6741 {0x12, 0x90a60140}, \
6742 {0x14, 0x90170110}, \
Hui Wange8191a82015-04-24 13:39:59 +08006743 {0x21, 0x02211020}
6744
David Henningssonfea185e2014-09-03 10:23:04 +02006745#define ALC282_STANDARD_PINS \
Hui Wang11580292015-08-03 11:03:49 +08006746 {0x14, 0x90170110}
Kailang Yange1e62b92015-04-08 16:01:22 +08006747
David Henningssonfea185e2014-09-03 10:23:04 +02006748#define ALC290_STANDARD_PINS \
Hui Wang11580292015-08-03 11:03:49 +08006749 {0x12, 0x99a30130}
David Henningssonfea185e2014-09-03 10:23:04 +02006750
6751#define ALC292_STANDARD_PINS \
6752 {0x14, 0x90170110}, \
Hui Wang11580292015-08-03 11:03:49 +08006753 {0x15, 0x0221401f}
Kailang Yang977e6272015-05-18 15:31:20 +08006754
Hui Wang3f6409702016-09-11 11:26:16 +08006755#define ALC295_STANDARD_PINS \
6756 {0x12, 0xb7a60130}, \
6757 {0x14, 0x90170110}, \
Hui Wang3f6409702016-09-11 11:26:16 +08006758 {0x21, 0x04211020}
6759
Woodrow Shen703867e2015-08-05 12:34:12 +08006760#define ALC298_STANDARD_PINS \
6761 {0x12, 0x90a60130}, \
6762 {0x21, 0x03211020}
6763
Hui Wange1918932014-05-26 16:22:44 +08006764static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
Chris Chiu5824ce82017-02-28 14:17:11 -06006765 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1025, "Acer", ALC255_FIXUP_ACER_MIC_NO_PRESENCE,
6766 {0x12, 0x90a601c0},
6767 {0x14, 0x90171120},
6768 {0x21, 0x02211030}),
Chris Chiu615966a2017-02-28 14:17:12 -06006769 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1043, "ASUS", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE,
6770 {0x14, 0x90170110},
6771 {0x1b, 0x90a70130},
6772 {0x21, 0x03211020}),
6773 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1043, "ASUS", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE,
6774 {0x1a, 0x90a70130},
6775 {0x1b, 0x90170110},
6776 {0x21, 0x03211020}),
David Henningsson2ae95572016-02-25 09:37:05 +01006777 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
Kailang Yangcfc5a842016-02-03 15:20:39 +08006778 ALC225_STANDARD_PINS,
Hui Wang8a132092016-07-08 14:26:57 +08006779 {0x12, 0xb7a60130},
Kailang Yangcfc5a842016-02-03 15:20:39 +08006780 {0x14, 0x901701a0}),
David Henningsson2ae95572016-02-25 09:37:05 +01006781 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
Kailang Yangcfc5a842016-02-03 15:20:39 +08006782 ALC225_STANDARD_PINS,
Hui Wang8a132092016-07-08 14:26:57 +08006783 {0x12, 0xb7a60130},
Kailang Yangcfc5a842016-02-03 15:20:39 +08006784 {0x14, 0x901701b0}),
Hui Wang8a132092016-07-08 14:26:57 +08006785 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
6786 ALC225_STANDARD_PINS,
6787 {0x12, 0xb7a60150},
6788 {0x14, 0x901701a0}),
6789 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
6790 ALC225_STANDARD_PINS,
6791 {0x12, 0xb7a60150},
6792 {0x14, 0x901701b0}),
6793 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
6794 ALC225_STANDARD_PINS,
6795 {0x12, 0xb7a60130},
6796 {0x1b, 0x90170110}),
Kai-Heng Feng0ce48e12017-11-20 02:29:13 -05006797 SND_HDA_PIN_QUIRK(0x10ec0233, 0x8086, "Intel NUC Skull Canyon", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
6798 {0x1b, 0x01111010},
6799 {0x1e, 0x01451130},
6800 {0x21, 0x02211020}),
Hui Wang986376b2018-05-30 12:33:07 +08006801 SND_HDA_PIN_QUIRK(0x10ec0235, 0x17aa, "Lenovo", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY,
6802 {0x12, 0x90a60140},
6803 {0x14, 0x90170110},
6804 {0x19, 0x02a11030},
6805 {0x21, 0x02211020}),
Hui Wangf2657882017-10-24 16:53:34 +08006806 SND_HDA_PIN_QUIRK(0x10ec0236, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6807 {0x12, 0x90a60140},
6808 {0x14, 0x90170110},
6809 {0x21, 0x02211020}),
6810 SND_HDA_PIN_QUIRK(0x10ec0236, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6811 {0x12, 0x90a60140},
6812 {0x14, 0x90170150},
6813 {0x21, 0x02211020}),
Hui Wangc77900e2014-09-03 11:31:07 +08006814 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE,
Hui Wangc77900e2014-09-03 11:31:07 +08006815 {0x14, 0x90170110},
Hui Wangc77900e2014-09-03 11:31:07 +08006816 {0x21, 0x02211020}),
David Henningsson76c21322014-06-24 14:46:54 +02006817 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang86c72d12016-05-25 12:12:32 +08006818 {0x14, 0x90170130},
6819 {0x21, 0x02211040}),
6820 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningsson76c21322014-06-24 14:46:54 +02006821 {0x12, 0x90a60140},
6822 {0x14, 0x90170110},
David Henningsson76c21322014-06-24 14:46:54 +02006823 {0x21, 0x02211020}),
6824 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6825 {0x12, 0x90a60160},
6826 {0x14, 0x90170120},
David Henningsson76c21322014-06-24 14:46:54 +02006827 {0x21, 0x02211030}),
6828 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang392c9da2016-09-26 10:59:38 +08006829 {0x14, 0x90170110},
6830 {0x1b, 0x02011020},
6831 {0x21, 0x0221101f}),
6832 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang6aecd872016-10-20 14:03:33 +08006833 {0x14, 0x90170110},
6834 {0x1b, 0x01011020},
6835 {0x21, 0x0221101f}),
6836 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssoncba59972015-07-22 10:00:25 +02006837 {0x14, 0x90170130},
David Henningssoncba59972015-07-22 10:00:25 +02006838 {0x1b, 0x01014020},
David Henningssoncba59972015-07-22 10:00:25 +02006839 {0x21, 0x0221103f}),
6840 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang59ec4b52016-08-04 15:28:04 +08006841 {0x14, 0x90170130},
Hui Wang6aecd872016-10-20 14:03:33 +08006842 {0x1b, 0x01011020},
6843 {0x21, 0x0221103f}),
6844 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6845 {0x14, 0x90170130},
Hui Wang59ec4b52016-08-04 15:28:04 +08006846 {0x1b, 0x02011020},
6847 {0x21, 0x0221103f}),
6848 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Woodrow Shene9c28e12015-07-25 10:36:16 +08006849 {0x14, 0x90170150},
Woodrow Shene9c28e12015-07-25 10:36:16 +08006850 {0x1b, 0x02011020},
Woodrow Shene9c28e12015-07-25 10:36:16 +08006851 {0x21, 0x0221105f}),
6852 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Woodrow Shene9c28e12015-07-25 10:36:16 +08006853 {0x14, 0x90170110},
Woodrow Shene9c28e12015-07-25 10:36:16 +08006854 {0x1b, 0x01014020},
Woodrow Shene9c28e12015-07-25 10:36:16 +08006855 {0x21, 0x0221101f}),
6856 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningsson76c21322014-06-24 14:46:54 +02006857 {0x12, 0x90a60160},
6858 {0x14, 0x90170120},
6859 {0x17, 0x90170140},
David Henningsson76c21322014-06-24 14:46:54 +02006860 {0x21, 0x0321102f}),
6861 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6862 {0x12, 0x90a60160},
6863 {0x14, 0x90170130},
David Henningsson76c21322014-06-24 14:46:54 +02006864 {0x21, 0x02211040}),
6865 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6866 {0x12, 0x90a60160},
6867 {0x14, 0x90170140},
David Henningsson76c21322014-06-24 14:46:54 +02006868 {0x21, 0x02211050}),
6869 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6870 {0x12, 0x90a60170},
6871 {0x14, 0x90170120},
David Henningsson76c21322014-06-24 14:46:54 +02006872 {0x21, 0x02211030}),
6873 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6874 {0x12, 0x90a60170},
6875 {0x14, 0x90170130},
David Henningsson76c21322014-06-24 14:46:54 +02006876 {0x21, 0x02211040}),
Hui Wang70658b92015-03-06 14:03:57 +08006877 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang70658b92015-03-06 14:03:57 +08006878 {0x12, 0x90a60170},
Hui Wang0a1f90a2016-01-13 11:51:38 +08006879 {0x14, 0x90171130},
6880 {0x21, 0x02211040}),
6881 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6882 {0x12, 0x90a60170},
Hui Wang70658b92015-03-06 14:03:57 +08006883 {0x14, 0x90170140},
Hui Wang70658b92015-03-06 14:03:57 +08006884 {0x21, 0x02211050}),
David Henningsson9b5a4e32015-05-11 14:04:14 +02006885 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell Inspiron 5548", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningsson9b5a4e32015-05-11 14:04:14 +02006886 {0x12, 0x90a60180},
6887 {0x14, 0x90170130},
David Henningsson9b5a4e32015-05-11 14:04:14 +02006888 {0x21, 0x02211040}),
AceLan Kaof90d83b2016-06-03 14:45:25 +08006889 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell Inspiron 5565", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6890 {0x12, 0x90a60180},
6891 {0x14, 0x90170120},
6892 {0x21, 0x02211030}),
Hui Wang989dbe42016-11-23 16:05:38 +08006893 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6894 {0x1b, 0x01011020},
6895 {0x21, 0x02211010}),
Kailang Yang7081adf2015-03-30 17:05:37 +08006896 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang285d5dd2017-12-22 11:17:45 +08006897 {0x12, 0x90a60130},
6898 {0x14, 0x90170110},
6899 {0x1b, 0x01011020},
6900 {0x21, 0x0221101f}),
6901 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Kailang Yang81a12312015-05-28 16:48:22 +08006902 {0x12, 0x90a60160},
6903 {0x14, 0x90170120},
Kailang Yang81a12312015-05-28 16:48:22 +08006904 {0x21, 0x02211030}),
6905 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Woodrow Shenf83c3292016-06-24 15:58:34 +08006906 {0x12, 0x90a60170},
6907 {0x14, 0x90170120},
6908 {0x21, 0x02211030}),
Shrirang Bagul311042d2016-08-29 15:19:27 +08006909 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell Inspiron 5468", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6910 {0x12, 0x90a60180},
6911 {0x14, 0x90170120},
6912 {0x21, 0x02211030}),
Woodrow Shenf83c3292016-06-24 15:58:34 +08006913 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang3f6409702016-09-11 11:26:16 +08006914 {0x12, 0xb7a60130},
6915 {0x14, 0x90170110},
6916 {0x21, 0x02211020}),
David Henningssoncf51eb92014-10-30 08:26:02 +01006917 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang3f2f7c52018-01-29 14:23:15 +08006918 {0x12, 0x90a60130},
6919 {0x14, 0x90170110},
6920 {0x14, 0x01011020},
6921 {0x21, 0x0221101f}),
6922 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssoncf51eb92014-10-30 08:26:02 +01006923 ALC256_STANDARD_PINS),
Chris Chiuc1732ed2017-02-28 14:17:13 -06006924 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC,
6925 {0x14, 0x90170110},
6926 {0x1b, 0x90a70130},
6927 {0x21, 0x04211020}),
6928 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC,
6929 {0x14, 0x90170110},
6930 {0x1b, 0x90a70130},
6931 {0x21, 0x03211020}),
Kailang Yang92266652017-12-14 15:28:58 +08006932 SND_HDA_PIN_QUIRK(0x10ec0274, 0x1028, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB,
Hui Wang75ee94b2017-11-09 08:48:08 +08006933 {0x12, 0xb7a60130},
6934 {0x13, 0xb8a61140},
6935 {0x16, 0x90170110},
6936 {0x21, 0x04211020}),
David Henningssoncf51eb92014-10-30 08:26:02 +01006937 SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC280_FIXUP_HP_GPIO4,
6938 {0x12, 0x90a60130},
6939 {0x14, 0x90170110},
6940 {0x15, 0x0421101f},
Hui Wang11580292015-08-03 11:03:49 +08006941 {0x1a, 0x04a11020}),
Hui Wang02796612014-09-03 11:31:11 +08006942 SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED,
6943 {0x12, 0x90a60140},
Hui Wang02796612014-09-03 11:31:11 +08006944 {0x14, 0x90170110},
6945 {0x15, 0x0421101f},
Hui Wang02796612014-09-03 11:31:11 +08006946 {0x18, 0x02811030},
Hui Wang02796612014-09-03 11:31:11 +08006947 {0x1a, 0x04a1103f},
Hui Wang11580292015-08-03 11:03:49 +08006948 {0x1b, 0x02011020}),
David Henningsson42304472014-07-22 11:42:17 +02006949 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP 15 Touchsmart", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02006950 ALC282_STANDARD_PINS,
David Henningsson42304472014-07-22 11:42:17 +02006951 {0x12, 0x99a30130},
David Henningsson42304472014-07-22 11:42:17 +02006952 {0x19, 0x03a11020},
David Henningsson42304472014-07-22 11:42:17 +02006953 {0x21, 0x0321101f}),
Hui Wang2c609992014-09-03 11:31:08 +08006954 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02006955 ALC282_STANDARD_PINS,
Hui Wang2c609992014-09-03 11:31:08 +08006956 {0x12, 0x99a30130},
Hui Wang2c609992014-09-03 11:31:08 +08006957 {0x19, 0x03a11020},
Hui Wang2c609992014-09-03 11:31:08 +08006958 {0x21, 0x03211040}),
6959 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02006960 ALC282_STANDARD_PINS,
Hui Wang2c609992014-09-03 11:31:08 +08006961 {0x12, 0x99a30130},
Hui Wang2c609992014-09-03 11:31:08 +08006962 {0x19, 0x03a11030},
Hui Wang2c609992014-09-03 11:31:08 +08006963 {0x21, 0x03211020}),
6964 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02006965 ALC282_STANDARD_PINS,
Hui Wang2c609992014-09-03 11:31:08 +08006966 {0x12, 0x99a30130},
Hui Wang2c609992014-09-03 11:31:08 +08006967 {0x19, 0x04a11020},
Hui Wang2c609992014-09-03 11:31:08 +08006968 {0x21, 0x0421101f}),
Hui Wang200afc02014-09-03 11:31:10 +08006969 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED,
David Henningssonaec856d2014-09-03 10:23:05 +02006970 ALC282_STANDARD_PINS,
Hui Wang200afc02014-09-03 11:31:10 +08006971 {0x12, 0x90a60140},
Hui Wang200afc02014-09-03 11:31:10 +08006972 {0x19, 0x04a11030},
Hui Wang200afc02014-09-03 11:31:10 +08006973 {0x21, 0x04211020}),
David Henningsson76c21322014-06-24 14:46:54 +02006974 SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02006975 ALC282_STANDARD_PINS,
David Henningsson76c21322014-06-24 14:46:54 +02006976 {0x12, 0x90a60130},
David Henningsson76c21322014-06-24 14:46:54 +02006977 {0x21, 0x0321101f}),
6978 SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
6979 {0x12, 0x90a60160},
6980 {0x14, 0x90170120},
David Henningsson76c21322014-06-24 14:46:54 +02006981 {0x21, 0x02211030}),
Hui Wangbc262172014-09-03 11:31:05 +08006982 SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02006983 ALC282_STANDARD_PINS,
Hui Wangbc262172014-09-03 11:31:05 +08006984 {0x12, 0x90a60130},
Hui Wangbc262172014-09-03 11:31:05 +08006985 {0x19, 0x03a11020},
Hui Wangbc262172014-09-03 11:31:05 +08006986 {0x21, 0x0321101f}),
Kailang Yange1e62b92015-04-08 16:01:22 +08006987 SND_HDA_PIN_QUIRK(0x10ec0288, 0x1028, "Dell", ALC288_FIXUP_DELL_XPS_13_GPIO6,
Kailang Yange1e62b92015-04-08 16:01:22 +08006988 {0x12, 0x90a60120},
Kailang Yange1e62b92015-04-08 16:01:22 +08006989 {0x14, 0x90170110},
Kailang Yange1e62b92015-04-08 16:01:22 +08006990 {0x21, 0x0321101f}),
Hui Wangd5078192018-03-02 13:05:36 +08006991 SND_HDA_PIN_QUIRK(0x10ec0289, 0x1028, "Dell", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
Hui Wang3f2f7c52018-01-29 14:23:15 +08006992 {0x12, 0xb7a60130},
6993 {0x14, 0x90170110},
6994 {0x21, 0x04211020}),
Hui Wange4442bc2014-09-03 11:31:09 +08006995 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02006996 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08006997 {0x15, 0x04211040},
Hui Wange4442bc2014-09-03 11:31:09 +08006998 {0x18, 0x90170112},
Hui Wang11580292015-08-03 11:03:49 +08006999 {0x1a, 0x04a11020}),
Hui Wange4442bc2014-09-03 11:31:09 +08007000 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007001 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08007002 {0x15, 0x04211040},
Hui Wange4442bc2014-09-03 11:31:09 +08007003 {0x18, 0x90170110},
Hui Wang11580292015-08-03 11:03:49 +08007004 {0x1a, 0x04a11020}),
Hui Wange4442bc2014-09-03 11:31:09 +08007005 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007006 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08007007 {0x15, 0x0421101f},
Hui Wang11580292015-08-03 11:03:49 +08007008 {0x1a, 0x04a11020}),
Hui Wange4442bc2014-09-03 11:31:09 +08007009 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007010 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08007011 {0x15, 0x04211020},
Hui Wang11580292015-08-03 11:03:49 +08007012 {0x1a, 0x04a11040}),
Hui Wange4442bc2014-09-03 11:31:09 +08007013 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007014 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08007015 {0x14, 0x90170110},
7016 {0x15, 0x04211020},
Hui Wang11580292015-08-03 11:03:49 +08007017 {0x1a, 0x04a11040}),
Hui Wange4442bc2014-09-03 11:31:09 +08007018 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007019 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08007020 {0x14, 0x90170110},
7021 {0x15, 0x04211020},
Hui Wang11580292015-08-03 11:03:49 +08007022 {0x1a, 0x04a11020}),
Hui Wange4442bc2014-09-03 11:31:09 +08007023 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007024 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08007025 {0x14, 0x90170110},
7026 {0x15, 0x0421101f},
Hui Wang11580292015-08-03 11:03:49 +08007027 {0x1a, 0x04a11020}),
Hui Wange8818fa2014-09-03 11:31:04 +08007028 SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007029 ALC292_STANDARD_PINS,
Hui Wange8818fa2014-09-03 11:31:04 +08007030 {0x12, 0x90a60140},
Hui Wange8818fa2014-09-03 11:31:04 +08007031 {0x16, 0x01014020},
Hui Wang11580292015-08-03 11:03:49 +08007032 {0x19, 0x01a19030}),
Hui Wange8818fa2014-09-03 11:31:04 +08007033 SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007034 ALC292_STANDARD_PINS,
Hui Wange8818fa2014-09-03 11:31:04 +08007035 {0x12, 0x90a60140},
Hui Wange8818fa2014-09-03 11:31:04 +08007036 {0x16, 0x01014020},
7037 {0x18, 0x02a19031},
Hui Wang11580292015-08-03 11:03:49 +08007038 {0x19, 0x01a1903e}),
David Henningsson76c21322014-06-24 14:46:54 +02007039 SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007040 ALC292_STANDARD_PINS,
Hui Wang11580292015-08-03 11:03:49 +08007041 {0x12, 0x90a60140}),
David Henningsson76c21322014-06-24 14:46:54 +02007042 SND_HDA_PIN_QUIRK(0x10ec0293, 0x1028, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007043 ALC292_STANDARD_PINS,
David Henningsson76c21322014-06-24 14:46:54 +02007044 {0x13, 0x90a60140},
David Henningsson76c21322014-06-24 14:46:54 +02007045 {0x16, 0x21014020},
Hui Wang11580292015-08-03 11:03:49 +08007046 {0x19, 0x21a19030}),
David Henningssone03fdbd2014-06-27 08:41:59 +02007047 SND_HDA_PIN_QUIRK(0x10ec0293, 0x1028, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007048 ALC292_STANDARD_PINS,
Hui Wang11580292015-08-03 11:03:49 +08007049 {0x13, 0x90a60140}),
Hui Wang3f6409702016-09-11 11:26:16 +08007050 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wangf771d5b2016-10-18 10:59:09 +08007051 ALC295_STANDARD_PINS,
7052 {0x17, 0x21014020},
7053 {0x18, 0x21a19030}),
7054 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
7055 ALC295_STANDARD_PINS,
7056 {0x17, 0x21014040},
7057 {0x18, 0x21a19050}),
Hui Wang3f307832017-03-23 10:00:25 +08007058 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
7059 ALC295_STANDARD_PINS),
Kailang Yang977e6272015-05-18 15:31:20 +08007060 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
Woodrow Shen703867e2015-08-05 12:34:12 +08007061 ALC298_STANDARD_PINS,
Takashi Iwai9f502ff2015-08-05 12:09:45 +02007062 {0x17, 0x90170110}),
7063 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
7064 ALC298_STANDARD_PINS,
Woodrow Shen703867e2015-08-05 12:34:12 +08007065 {0x17, 0x90170140}),
7066 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
7067 ALC298_STANDARD_PINS,
Takashi Iwai9f502ff2015-08-05 12:09:45 +02007068 {0x17, 0x90170150}),
Kai-Heng Feng9f1bc2c42017-02-16 15:26:54 +08007069 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_SPK_VOLUME,
7070 {0x12, 0xb7a60140},
7071 {0x13, 0xb7a60150},
7072 {0x17, 0x90170110},
7073 {0x1a, 0x03011020},
7074 {0x21, 0x03211030}),
Kailang Yangfcc6c872017-06-29 15:21:27 +08007075 SND_HDA_PIN_QUIRK(0x10ec0299, 0x1028, "Dell", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
7076 ALC225_STANDARD_PINS,
7077 {0x12, 0xb7a60130},
Kailang Yangfcc6c872017-06-29 15:21:27 +08007078 {0x17, 0x90170110}),
Hui Wange1918932014-05-26 16:22:44 +08007079 {}
7080};
Takashi Iwai1d045db2011-07-07 18:23:21 +02007081
Takashi Iwai546bb672012-03-07 08:37:19 +01007082static void alc269_fill_coef(struct hda_codec *codec)
Takashi Iwai1d045db2011-07-07 18:23:21 +02007083{
Kailang Yang526af6e2012-03-07 08:25:20 +01007084 struct alc_spec *spec = codec->spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02007085 int val;
7086
Kailang Yang526af6e2012-03-07 08:25:20 +01007087 if (spec->codec_variant != ALC269_TYPE_ALC269VB)
Takashi Iwai546bb672012-03-07 08:37:19 +01007088 return;
Kailang Yang526af6e2012-03-07 08:25:20 +01007089
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007090 if ((alc_get_coef0(codec) & 0x00ff) < 0x015) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02007091 alc_write_coef_idx(codec, 0xf, 0x960b);
7092 alc_write_coef_idx(codec, 0xe, 0x8817);
7093 }
7094
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007095 if ((alc_get_coef0(codec) & 0x00ff) == 0x016) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02007096 alc_write_coef_idx(codec, 0xf, 0x960b);
7097 alc_write_coef_idx(codec, 0xe, 0x8814);
7098 }
7099
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007100 if ((alc_get_coef0(codec) & 0x00ff) == 0x017) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02007101 /* Power up output pin */
Takashi Iwai98b24882014-08-18 13:47:50 +02007102 alc_update_coef_idx(codec, 0x04, 0, 1<<11);
Takashi Iwai1d045db2011-07-07 18:23:21 +02007103 }
7104
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007105 if ((alc_get_coef0(codec) & 0x00ff) == 0x018) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02007106 val = alc_read_coef_idx(codec, 0xd);
Takashi Iwaif3ee07d2014-08-15 17:35:00 +02007107 if (val != -1 && (val & 0x0c00) >> 10 != 0x1) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02007108 /* Capless ramp up clock control */
7109 alc_write_coef_idx(codec, 0xd, val | (1<<10));
7110 }
7111 val = alc_read_coef_idx(codec, 0x17);
Takashi Iwaif3ee07d2014-08-15 17:35:00 +02007112 if (val != -1 && (val & 0x01c0) >> 6 != 0x4) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02007113 /* Class D power on reset */
7114 alc_write_coef_idx(codec, 0x17, val | (1<<7));
7115 }
7116 }
7117
Takashi Iwai98b24882014-08-18 13:47:50 +02007118 /* HP */
7119 alc_update_coef_idx(codec, 0x4, 0, 1<<11);
Takashi Iwai1d045db2011-07-07 18:23:21 +02007120}
7121
7122/*
7123 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02007124static int patch_alc269(struct hda_codec *codec)
7125{
7126 struct alc_spec *spec;
Takashi Iwai3de95172012-05-07 18:03:15 +02007127 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02007128
Takashi Iwai3de95172012-05-07 18:03:15 +02007129 err = alc_alloc_spec(codec, 0x0b);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007130 if (err < 0)
Takashi Iwai3de95172012-05-07 18:03:15 +02007131 return err;
7132
7133 spec = codec->spec;
Takashi Iwai08c189f2012-12-19 15:22:24 +01007134 spec->gen.shared_mic_vref_pin = 0x18;
Takashi Iwai8b99aba2015-06-15 11:59:32 +02007135 codec->power_save_node = 1;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007136
Takashi Iwai225068a2015-05-29 10:42:14 +02007137#ifdef CONFIG_PM
7138 codec->patch_ops.suspend = alc269_suspend;
7139 codec->patch_ops.resume = alc269_resume;
7140#endif
Kailang Yangc2d6af52017-06-21 14:50:54 +08007141 spec->shutup = alc_default_shutup;
7142 spec->init_hook = alc_default_init;
Takashi Iwai225068a2015-05-29 10:42:14 +02007143
Takashi Iwai1727a772013-01-10 09:52:52 +01007144 snd_hda_pick_fixup(codec, alc269_fixup_models,
Herton Ronaldo Krzesinski9f720bb92012-09-27 10:38:14 -03007145 alc269_fixup_tbl, alc269_fixups);
Hui Wange1918932014-05-26 16:22:44 +08007146 snd_hda_pick_pin_fixup(codec, alc269_pin_fixup_tbl, alc269_fixups);
David Henningsson214eef72014-07-22 14:09:35 +02007147 snd_hda_pick_fixup(codec, NULL, alc269_fixup_vendor_tbl,
7148 alc269_fixups);
Takashi Iwai1727a772013-01-10 09:52:52 +01007149 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Herton Ronaldo Krzesinski9f720bb92012-09-27 10:38:14 -03007150
7151 alc_auto_parse_customize_define(codec);
7152
Takashi Iwai7504b6c2013-03-18 11:25:51 +01007153 if (has_cdefine_beep(codec))
7154 spec->gen.beep_nid = 0x01;
7155
Takashi Iwai7639a062015-03-03 10:07:24 +01007156 switch (codec->core.vendor_id) {
Kailang Yang065380f2013-01-10 10:25:48 +01007157 case 0x10ec0269:
Takashi Iwai1d045db2011-07-07 18:23:21 +02007158 spec->codec_variant = ALC269_TYPE_ALC269VA;
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007159 switch (alc_get_coef0(codec) & 0x00f0) {
7160 case 0x0010:
Takashi Iwai5100cd02014-02-15 10:03:19 +01007161 if (codec->bus->pci &&
7162 codec->bus->pci->subsystem_vendor == 0x1025 &&
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007163 spec->cdefine.platform_type == 1)
Takashi Iwai20ca0c32011-10-17 16:00:35 +02007164 err = alc_codec_rename(codec, "ALC271X");
Takashi Iwai1d045db2011-07-07 18:23:21 +02007165 spec->codec_variant = ALC269_TYPE_ALC269VB;
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007166 break;
7167 case 0x0020:
Takashi Iwai5100cd02014-02-15 10:03:19 +01007168 if (codec->bus->pci &&
7169 codec->bus->pci->subsystem_vendor == 0x17aa &&
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007170 codec->bus->pci->subsystem_device == 0x21f3)
Takashi Iwai20ca0c32011-10-17 16:00:35 +02007171 err = alc_codec_rename(codec, "ALC3202");
Takashi Iwai1d045db2011-07-07 18:23:21 +02007172 spec->codec_variant = ALC269_TYPE_ALC269VC;
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007173 break;
Kailang Yangadcc70b2012-05-25 08:08:38 +02007174 case 0x0030:
7175 spec->codec_variant = ALC269_TYPE_ALC269VD;
7176 break;
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007177 default:
Takashi Iwai1d045db2011-07-07 18:23:21 +02007178 alc_fix_pll_init(codec, 0x20, 0x04, 15);
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007179 }
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007180 if (err < 0)
7181 goto error;
Kailang Yangc2d6af52017-06-21 14:50:54 +08007182 spec->shutup = alc269_shutup;
Takashi Iwai546bb672012-03-07 08:37:19 +01007183 spec->init_hook = alc269_fill_coef;
Takashi Iwai1d045db2011-07-07 18:23:21 +02007184 alc269_fill_coef(codec);
Kailang Yang065380f2013-01-10 10:25:48 +01007185 break;
7186
7187 case 0x10ec0280:
7188 case 0x10ec0290:
7189 spec->codec_variant = ALC269_TYPE_ALC280;
7190 break;
7191 case 0x10ec0282:
Kailang Yang065380f2013-01-10 10:25:48 +01007192 spec->codec_variant = ALC269_TYPE_ALC282;
Kailang Yang7b5c7a02014-03-18 16:15:54 +08007193 spec->shutup = alc282_shutup;
7194 spec->init_hook = alc282_init;
Kailang Yang065380f2013-01-10 10:25:48 +01007195 break;
Kailang Yang2af02be2013-08-22 10:03:50 +02007196 case 0x10ec0233:
7197 case 0x10ec0283:
7198 spec->codec_variant = ALC269_TYPE_ALC283;
7199 spec->shutup = alc283_shutup;
7200 spec->init_hook = alc283_init;
7201 break;
Kailang Yang065380f2013-01-10 10:25:48 +01007202 case 0x10ec0284:
7203 case 0x10ec0292:
7204 spec->codec_variant = ALC269_TYPE_ALC284;
7205 break;
Kailang Yang161ebf22013-10-24 11:36:33 +02007206 case 0x10ec0293:
Kailang Yang4731d5d2017-06-30 15:22:57 +08007207 spec->codec_variant = ALC269_TYPE_ALC293;
Kailang Yang161ebf22013-10-24 11:36:33 +02007208 break;
Kailang Yang7fc7d042013-04-25 11:04:43 +02007209 case 0x10ec0286:
Kailang Yang7c665932014-04-14 15:09:44 +08007210 case 0x10ec0288:
Kailang Yang7fc7d042013-04-25 11:04:43 +02007211 spec->codec_variant = ALC269_TYPE_ALC286;
Kailang Yangf7ae9ba2014-06-30 16:10:37 +08007212 spec->shutup = alc286_shutup;
Kailang Yang7fc7d042013-04-25 11:04:43 +02007213 break;
Kailang Yang506b62c2014-12-18 17:07:44 +08007214 case 0x10ec0298:
7215 spec->codec_variant = ALC269_TYPE_ALC298;
7216 break;
Kailang Yangea04a1d2018-04-25 15:31:52 +08007217 case 0x10ec0235:
Kailang Yang1d04c9d2013-10-24 11:35:18 +02007218 case 0x10ec0255:
7219 spec->codec_variant = ALC269_TYPE_ALC255;
Kailang Yangab3b8e52018-04-25 16:05:27 +08007220 spec->shutup = alc256_shutup;
7221 spec->init_hook = alc256_init;
Kailang Yang1d04c9d2013-10-24 11:35:18 +02007222 break;
Kailang Yang736f20a2017-10-20 15:06:34 +08007223 case 0x10ec0236:
Kailang Yang4344aec2014-12-17 17:39:05 +08007224 case 0x10ec0256:
7225 spec->codec_variant = ALC269_TYPE_ALC256;
Kailang Yang4a219ef2017-06-16 16:54:35 +08007226 spec->shutup = alc256_shutup;
7227 spec->init_hook = alc256_init;
David Henningsson7d1b6e22015-04-21 10:48:46 +02007228 spec->gen.mixer_nid = 0; /* ALC256 does not have any loopback mixer path */
Kailang Yangd32b6662015-04-23 15:10:53 +08007229 alc_update_coef_idx(codec, 0x36, 1 << 13, 1 << 5); /* Switch pcbeep path to Line in path*/
Kailang Yang4344aec2014-12-17 17:39:05 +08007230 break;
Kailang Yangf429e7e2017-12-05 15:38:24 +08007231 case 0x10ec0257:
7232 spec->codec_variant = ALC269_TYPE_ALC257;
Kailang Yang88d42b22018-03-14 16:08:57 +08007233 spec->shutup = alc256_shutup;
7234 spec->init_hook = alc256_init;
Kailang Yangf429e7e2017-12-05 15:38:24 +08007235 spec->gen.mixer_nid = 0;
7236 break;
Kailang Yang0a6f0602017-06-30 16:00:48 +08007237 case 0x10ec0215:
7238 case 0x10ec0285:
7239 case 0x10ec0289:
7240 spec->codec_variant = ALC269_TYPE_ALC215;
Kailang Yang1b6832be2018-01-17 15:32:03 +08007241 spec->shutup = alc225_shutup;
7242 spec->init_hook = alc225_init;
Kailang Yang0a6f0602017-06-30 16:00:48 +08007243 spec->gen.mixer_nid = 0;
7244 break;
Kailang Yang42314302016-02-03 15:03:50 +08007245 case 0x10ec0225:
Kailang Yang7d727862016-05-24 16:46:07 +08007246 case 0x10ec0295:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08007247 case 0x10ec0299:
Kailang Yang42314302016-02-03 15:03:50 +08007248 spec->codec_variant = ALC269_TYPE_ALC225;
Kailang Yangda911b12018-01-05 16:50:08 +08007249 spec->shutup = alc225_shutup;
7250 spec->init_hook = alc225_init;
Takashi Iwaic1350bf2017-12-27 09:03:45 +01007251 spec->gen.mixer_nid = 0; /* no loopback on ALC225, ALC295 and ALC299 */
Kailang Yang42314302016-02-03 15:03:50 +08007252 break;
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08007253 case 0x10ec0234:
7254 case 0x10ec0274:
7255 case 0x10ec0294:
7256 spec->codec_variant = ALC269_TYPE_ALC294;
Hui Wang532a7782017-06-26 12:30:32 +08007257 spec->gen.mixer_nid = 0; /* ALC2x4 does not have any loopback mixer path */
Kailang Yang71683c32017-06-20 16:33:50 +08007258 alc_update_coef_idx(codec, 0x6b, 0x0018, (1<<4) | (1<<3)); /* UAJ MIC Vref control by verb */
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08007259 break;
Kailang Yang6fbae352016-05-30 16:44:20 +08007260 case 0x10ec0700:
7261 case 0x10ec0701:
7262 case 0x10ec0703:
7263 spec->codec_variant = ALC269_TYPE_ALC700;
7264 spec->gen.mixer_nid = 0; /* ALC700 does not have any loopback mixer path */
Kailang Yang2d7fe612017-11-22 15:21:32 +08007265 alc_update_coef_idx(codec, 0x4a, 1 << 15, 0); /* Combo jack auto trigger control */
Kailang Yang6fbae352016-05-30 16:44:20 +08007266 break;
7267
Takashi Iwai1d045db2011-07-07 18:23:21 +02007268 }
7269
Kailang Yangad60d502013-06-28 12:03:01 +02007270 if (snd_hda_codec_read(codec, 0x51, 0, AC_VERB_PARAMETERS, 0) == 0x10ec5505) {
Kailang Yang97a26572013-11-29 00:35:26 -05007271 spec->has_alc5505_dsp = 1;
Kailang Yangad60d502013-06-28 12:03:01 +02007272 spec->init_hook = alc5505_dsp_init;
7273 }
7274
Takashi Iwaia4297b52011-08-23 18:40:12 +02007275 /* automatic parse from the BIOS config */
7276 err = alc269_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007277 if (err < 0)
7278 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02007279
David Henningsson7d1b6e22015-04-21 10:48:46 +02007280 if (!spec->gen.no_analog && spec->gen.beep_nid && spec->gen.mixer_nid)
7281 set_beep_amp(spec, spec->gen.mixer_nid, 0x04, HDA_INPUT);
Takashi Iwai1d045db2011-07-07 18:23:21 +02007282
Takashi Iwai1727a772013-01-10 09:52:52 +01007283 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01007284
Takashi Iwai1d045db2011-07-07 18:23:21 +02007285 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007286
7287 error:
7288 alc_free(codec);
7289 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02007290}
7291
7292/*
7293 * ALC861
7294 */
7295
Takashi Iwai1d045db2011-07-07 18:23:21 +02007296static int alc861_parse_auto_config(struct hda_codec *codec)
7297{
Takashi Iwai1d045db2011-07-07 18:23:21 +02007298 static const hda_nid_t alc861_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02007299 static const hda_nid_t alc861_ssids[] = { 0x0e, 0x0f, 0x0b, 0 };
7300 return alc_parse_auto_config(codec, alc861_ignore, alc861_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02007301}
7302
Takashi Iwai1d045db2011-07-07 18:23:21 +02007303/* Pin config fixes */
7304enum {
Takashi Iwaie652f4c2012-02-13 11:56:25 +01007305 ALC861_FIXUP_FSC_AMILO_PI1505,
7306 ALC861_FIXUP_AMP_VREF_0F,
7307 ALC861_FIXUP_NO_JACK_DETECT,
7308 ALC861_FIXUP_ASUS_A6RP,
Takashi Iwai6ddf0fd2013-11-29 12:47:34 +01007309 ALC660_FIXUP_ASUS_W7J,
Takashi Iwai1d045db2011-07-07 18:23:21 +02007310};
7311
Takashi Iwai31150f22012-01-30 10:54:08 +01007312/* On some laptops, VREF of pin 0x0f is abused for controlling the main amp */
7313static void alc861_fixup_asus_amp_vref_0f(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01007314 const struct hda_fixup *fix, int action)
Takashi Iwai31150f22012-01-30 10:54:08 +01007315{
7316 struct alc_spec *spec = codec->spec;
7317 unsigned int val;
7318
Takashi Iwai1727a772013-01-10 09:52:52 +01007319 if (action != HDA_FIXUP_ACT_INIT)
Takashi Iwai31150f22012-01-30 10:54:08 +01007320 return;
Takashi Iwaid3f02d62013-01-10 10:12:22 +01007321 val = snd_hda_codec_get_pin_target(codec, 0x0f);
Takashi Iwai31150f22012-01-30 10:54:08 +01007322 if (!(val & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN)))
7323 val |= AC_PINCTL_IN_EN;
7324 val |= AC_PINCTL_VREF_50;
Takashi Iwaicdd03ce2012-04-20 12:34:50 +02007325 snd_hda_set_pin_ctl(codec, 0x0f, val);
Takashi Iwai08c189f2012-12-19 15:22:24 +01007326 spec->gen.keep_vref_in_automute = 1;
Takashi Iwai31150f22012-01-30 10:54:08 +01007327}
7328
Takashi Iwaie652f4c2012-02-13 11:56:25 +01007329/* suppress the jack-detection */
7330static void alc_fixup_no_jack_detect(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01007331 const struct hda_fixup *fix, int action)
Takashi Iwaie652f4c2012-02-13 11:56:25 +01007332{
Takashi Iwai1727a772013-01-10 09:52:52 +01007333 if (action == HDA_FIXUP_ACT_PRE_PROBE)
Takashi Iwaie652f4c2012-02-13 11:56:25 +01007334 codec->no_jack_detect = 1;
Jesper Juhl7d7eb9e2012-04-12 22:11:25 +02007335}
Takashi Iwaie652f4c2012-02-13 11:56:25 +01007336
Takashi Iwai1727a772013-01-10 09:52:52 +01007337static const struct hda_fixup alc861_fixups[] = {
Takashi Iwaie652f4c2012-02-13 11:56:25 +01007338 [ALC861_FIXUP_FSC_AMILO_PI1505] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01007339 .type = HDA_FIXUP_PINS,
7340 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02007341 { 0x0b, 0x0221101f }, /* HP */
7342 { 0x0f, 0x90170310 }, /* speaker */
7343 { }
7344 }
7345 },
Takashi Iwaie652f4c2012-02-13 11:56:25 +01007346 [ALC861_FIXUP_AMP_VREF_0F] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01007347 .type = HDA_FIXUP_FUNC,
Takashi Iwai31150f22012-01-30 10:54:08 +01007348 .v.func = alc861_fixup_asus_amp_vref_0f,
Takashi Iwai3b25eb62012-01-25 09:55:46 +01007349 },
Takashi Iwaie652f4c2012-02-13 11:56:25 +01007350 [ALC861_FIXUP_NO_JACK_DETECT] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01007351 .type = HDA_FIXUP_FUNC,
Takashi Iwaie652f4c2012-02-13 11:56:25 +01007352 .v.func = alc_fixup_no_jack_detect,
7353 },
7354 [ALC861_FIXUP_ASUS_A6RP] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01007355 .type = HDA_FIXUP_FUNC,
Takashi Iwaie652f4c2012-02-13 11:56:25 +01007356 .v.func = alc861_fixup_asus_amp_vref_0f,
7357 .chained = true,
7358 .chain_id = ALC861_FIXUP_NO_JACK_DETECT,
Takashi Iwai6ddf0fd2013-11-29 12:47:34 +01007359 },
7360 [ALC660_FIXUP_ASUS_W7J] = {
7361 .type = HDA_FIXUP_VERBS,
7362 .v.verbs = (const struct hda_verb[]) {
7363 /* ASUS W7J needs a magic pin setup on unused NID 0x10
7364 * for enabling outputs
7365 */
7366 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
7367 { }
7368 },
Takashi Iwaie652f4c2012-02-13 11:56:25 +01007369 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02007370};
7371
7372static const struct snd_pci_quirk alc861_fixup_tbl[] = {
Takashi Iwai6ddf0fd2013-11-29 12:47:34 +01007373 SND_PCI_QUIRK(0x1043, 0x1253, "ASUS W7J", ALC660_FIXUP_ASUS_W7J),
Takashi Iwaie7ca2372013-12-02 15:27:19 +01007374 SND_PCI_QUIRK(0x1043, 0x1263, "ASUS Z35HL", ALC660_FIXUP_ASUS_W7J),
Takashi Iwaie652f4c2012-02-13 11:56:25 +01007375 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS A6Rp", ALC861_FIXUP_ASUS_A6RP),
7376 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", ALC861_FIXUP_AMP_VREF_0F),
7377 SND_PCI_QUIRK(0x1462, 0x7254, "HP DX2200", ALC861_FIXUP_NO_JACK_DETECT),
7378 SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", ALC861_FIXUP_AMP_VREF_0F),
7379 SND_PCI_QUIRK(0x1584, 0x0000, "Uniwill ECS M31EI", ALC861_FIXUP_AMP_VREF_0F),
7380 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", ALC861_FIXUP_FSC_AMILO_PI1505),
Takashi Iwai1d045db2011-07-07 18:23:21 +02007381 {}
7382};
7383
7384/*
7385 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02007386static int patch_alc861(struct hda_codec *codec)
7387{
7388 struct alc_spec *spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02007389 int err;
7390
Takashi Iwai3de95172012-05-07 18:03:15 +02007391 err = alc_alloc_spec(codec, 0x15);
7392 if (err < 0)
7393 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02007394
Takashi Iwai3de95172012-05-07 18:03:15 +02007395 spec = codec->spec;
Takashi Iwai7504b6c2013-03-18 11:25:51 +01007396 spec->gen.beep_nid = 0x23;
Takashi Iwai1d045db2011-07-07 18:23:21 +02007397
Takashi Iwai225068a2015-05-29 10:42:14 +02007398#ifdef CONFIG_PM
7399 spec->power_hook = alc_power_eapd;
7400#endif
7401
Takashi Iwai1727a772013-01-10 09:52:52 +01007402 snd_hda_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
7403 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02007404
Takashi Iwaicb4e4822011-08-23 17:34:25 +02007405 /* automatic parse from the BIOS config */
7406 err = alc861_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007407 if (err < 0)
7408 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02007409
Takashi Iwai7504b6c2013-03-18 11:25:51 +01007410 if (!spec->gen.no_analog)
Takashi Iwai3e6179b2011-07-08 16:55:13 +02007411 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
Takashi Iwai1d045db2011-07-07 18:23:21 +02007412
Takashi Iwai1727a772013-01-10 09:52:52 +01007413 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01007414
Takashi Iwai1d045db2011-07-07 18:23:21 +02007415 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007416
7417 error:
7418 alc_free(codec);
7419 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02007420}
7421
7422/*
7423 * ALC861-VD support
7424 *
7425 * Based on ALC882
7426 *
7427 * In addition, an independent DAC
7428 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02007429static int alc861vd_parse_auto_config(struct hda_codec *codec)
7430{
Takashi Iwai1d045db2011-07-07 18:23:21 +02007431 static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02007432 static const hda_nid_t alc861vd_ssids[] = { 0x15, 0x1b, 0x14, 0 };
7433 return alc_parse_auto_config(codec, alc861vd_ignore, alc861vd_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02007434}
7435
Takashi Iwai1d045db2011-07-07 18:23:21 +02007436enum {
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02007437 ALC660VD_FIX_ASUS_GPIO1,
7438 ALC861VD_FIX_DALLAS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02007439};
7440
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02007441/* exclude VREF80 */
7442static void alc861vd_fixup_dallas(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01007443 const struct hda_fixup *fix, int action)
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02007444{
Takashi Iwai1727a772013-01-10 09:52:52 +01007445 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwaib78562b2012-12-17 20:06:49 +01007446 snd_hda_override_pin_caps(codec, 0x18, 0x00000734);
7447 snd_hda_override_pin_caps(codec, 0x19, 0x0000073c);
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02007448 }
7449}
7450
Takashi Iwai1727a772013-01-10 09:52:52 +01007451static const struct hda_fixup alc861vd_fixups[] = {
Takashi Iwai1d045db2011-07-07 18:23:21 +02007452 [ALC660VD_FIX_ASUS_GPIO1] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01007453 .type = HDA_FIXUP_VERBS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02007454 .v.verbs = (const struct hda_verb[]) {
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02007455 /* reset GPIO1 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02007456 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
7457 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
7458 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
7459 { }
7460 }
7461 },
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02007462 [ALC861VD_FIX_DALLAS] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01007463 .type = HDA_FIXUP_FUNC,
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02007464 .v.func = alc861vd_fixup_dallas,
7465 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02007466};
7467
7468static const struct snd_pci_quirk alc861vd_fixup_tbl[] = {
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02007469 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_FIX_DALLAS),
Takashi Iwai1d045db2011-07-07 18:23:21 +02007470 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02007471 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_FIX_DALLAS),
Takashi Iwai1d045db2011-07-07 18:23:21 +02007472 {}
7473};
7474
Takashi Iwai1d045db2011-07-07 18:23:21 +02007475/*
7476 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02007477static int patch_alc861vd(struct hda_codec *codec)
7478{
7479 struct alc_spec *spec;
Takashi Iwaicb4e4822011-08-23 17:34:25 +02007480 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02007481
Takashi Iwai3de95172012-05-07 18:03:15 +02007482 err = alc_alloc_spec(codec, 0x0b);
7483 if (err < 0)
7484 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02007485
Takashi Iwai3de95172012-05-07 18:03:15 +02007486 spec = codec->spec;
Takashi Iwai7504b6c2013-03-18 11:25:51 +01007487 spec->gen.beep_nid = 0x23;
Takashi Iwai1d045db2011-07-07 18:23:21 +02007488
Takashi Iwai225068a2015-05-29 10:42:14 +02007489 spec->shutup = alc_eapd_shutup;
7490
Takashi Iwai1727a772013-01-10 09:52:52 +01007491 snd_hda_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
7492 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02007493
Takashi Iwaicb4e4822011-08-23 17:34:25 +02007494 /* automatic parse from the BIOS config */
7495 err = alc861vd_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007496 if (err < 0)
7497 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02007498
Takashi Iwai7504b6c2013-03-18 11:25:51 +01007499 if (!spec->gen.no_analog)
Takashi Iwai3e6179b2011-07-08 16:55:13 +02007500 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
Takashi Iwai1d045db2011-07-07 18:23:21 +02007501
Takashi Iwai1727a772013-01-10 09:52:52 +01007502 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01007503
Takashi Iwai1d045db2011-07-07 18:23:21 +02007504 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007505
7506 error:
7507 alc_free(codec);
7508 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02007509}
7510
7511/*
7512 * ALC662 support
7513 *
7514 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
7515 * configuration. Each pin widget can choose any input DACs and a mixer.
7516 * Each ADC is connected from a mixer of all inputs. This makes possible
7517 * 6-channel independent captures.
7518 *
7519 * In addition, an independent DAC for the multi-playback (not used in this
7520 * driver yet).
7521 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02007522
7523/*
7524 * BIOS auto configuration
7525 */
7526
Kailang Yangbc9f98a2007-04-12 13:06:07 +02007527static int alc662_parse_auto_config(struct hda_codec *codec)
7528{
Takashi Iwai4c6d72d2011-05-02 11:30:18 +02007529 static const hda_nid_t alc662_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02007530 static const hda_nid_t alc663_ssids[] = { 0x15, 0x1b, 0x14, 0x21 };
7531 static const hda_nid_t alc662_ssids[] = { 0x15, 0x1b, 0x14, 0 };
7532 const hda_nid_t *ssids;
Takashi Iwaiee979a142008-09-02 15:42:20 +02007533
Takashi Iwai7639a062015-03-03 10:07:24 +01007534 if (codec->core.vendor_id == 0x10ec0272 || codec->core.vendor_id == 0x10ec0663 ||
7535 codec->core.vendor_id == 0x10ec0665 || codec->core.vendor_id == 0x10ec0670 ||
7536 codec->core.vendor_id == 0x10ec0671)
Takashi Iwai3e6179b2011-07-08 16:55:13 +02007537 ssids = alc663_ssids;
Kailang Yang6227cdc2010-02-25 08:36:52 +01007538 else
Takashi Iwai3e6179b2011-07-08 16:55:13 +02007539 ssids = alc662_ssids;
7540 return alc_parse_auto_config(codec, alc662_ignore, ssids);
Kailang Yangbc9f98a2007-04-12 13:06:07 +02007541}
7542
Todd Broch6be79482010-12-07 16:51:05 -08007543static void alc272_fixup_mario(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01007544 const struct hda_fixup *fix, int action)
Takashi Iwai6fc398c2011-01-13 14:36:37 +01007545{
Takashi Iwai9bb1f062013-01-10 17:14:29 +01007546 if (action != HDA_FIXUP_ACT_PRE_PROBE)
Takashi Iwai6fc398c2011-01-13 14:36:37 +01007547 return;
Todd Broch6be79482010-12-07 16:51:05 -08007548 if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT,
7549 (0x3b << AC_AMPCAP_OFFSET_SHIFT) |
7550 (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) |
7551 (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) |
7552 (0 << AC_AMPCAP_MUTE_SHIFT)))
Takashi Iwai4e76a882014-02-25 12:21:03 +01007553 codec_warn(codec, "failed to override amp caps for NID 0x2\n");
Todd Broch6be79482010-12-07 16:51:05 -08007554}
7555
Takashi Iwai8e383952013-10-30 17:41:12 +01007556static const struct snd_pcm_chmap_elem asus_pcm_2_1_chmaps[] = {
7557 { .channels = 2,
7558 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } },
7559 { .channels = 4,
7560 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR,
7561 SNDRV_CHMAP_NA, SNDRV_CHMAP_LFE } }, /* LFE only on right */
7562 { }
7563};
7564
7565/* override the 2.1 chmap */
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01007566static void alc_fixup_bass_chmap(struct hda_codec *codec,
Takashi Iwai8e383952013-10-30 17:41:12 +01007567 const struct hda_fixup *fix, int action)
7568{
7569 if (action == HDA_FIXUP_ACT_BUILD) {
7570 struct alc_spec *spec = codec->spec;
Takashi Iwaibbbc7e82015-02-27 17:43:19 +01007571 spec->gen.pcm_rec[0]->stream[0].chmap = asus_pcm_2_1_chmaps;
Takashi Iwai8e383952013-10-30 17:41:12 +01007572 }
7573}
7574
Takashi Iwaibf686652014-01-13 16:18:25 +01007575/* avoid D3 for keeping GPIO up */
7576static unsigned int gpio_led_power_filter(struct hda_codec *codec,
7577 hda_nid_t nid,
7578 unsigned int power_state)
7579{
7580 struct alc_spec *spec = codec->spec;
Takashi Iwai7639a062015-03-03 10:07:24 +01007581 if (nid == codec->core.afg && power_state == AC_PWRST_D3 && spec->gpio_led)
Takashi Iwaibf686652014-01-13 16:18:25 +01007582 return AC_PWRST_D0;
7583 return power_state;
7584}
7585
Takashi Iwai3e887f32014-01-10 17:50:58 +01007586static void alc662_fixup_led_gpio1(struct hda_codec *codec,
7587 const struct hda_fixup *fix, int action)
7588{
7589 struct alc_spec *spec = codec->spec;
7590 static const struct hda_verb gpio_init[] = {
7591 { 0x01, AC_VERB_SET_GPIO_MASK, 0x01 },
7592 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01 },
7593 {}
7594 };
7595
7596 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai0f32fd192014-11-19 12:16:14 +01007597 spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook;
Takashi Iwai3e887f32014-01-10 17:50:58 +01007598 spec->gpio_led = 0;
Takashi Iwai0f32fd192014-11-19 12:16:14 +01007599 spec->mute_led_polarity = 1;
7600 spec->gpio_mute_led_mask = 0x01;
Takashi Iwai3e887f32014-01-10 17:50:58 +01007601 snd_hda_add_verbs(codec, gpio_init);
Takashi Iwaibf686652014-01-13 16:18:25 +01007602 codec->power_filter = gpio_led_power_filter;
Takashi Iwai3e887f32014-01-10 17:50:58 +01007603 }
7604}
7605
Kailang Yangc6790c82016-11-25 16:15:17 +08007606static void alc662_usi_automute_hook(struct hda_codec *codec,
7607 struct hda_jack_callback *jack)
7608{
7609 struct alc_spec *spec = codec->spec;
7610 int vref;
7611 msleep(200);
7612 snd_hda_gen_hp_automute(codec, jack);
7613
7614 vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0;
7615 msleep(100);
7616 snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
7617 vref);
7618}
7619
7620static void alc662_fixup_usi_headset_mic(struct hda_codec *codec,
7621 const struct hda_fixup *fix, int action)
7622{
7623 struct alc_spec *spec = codec->spec;
7624 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
7625 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
7626 spec->gen.hp_automute_hook = alc662_usi_automute_hook;
7627 }
7628}
7629
Kailang Yangf3f91852014-10-24 15:43:46 +08007630static struct coef_fw alc668_coefs[] = {
7631 WRITE_COEF(0x01, 0xbebe), WRITE_COEF(0x02, 0xaaaa), WRITE_COEF(0x03, 0x0),
7632 WRITE_COEF(0x04, 0x0180), WRITE_COEF(0x06, 0x0), WRITE_COEF(0x07, 0x0f80),
7633 WRITE_COEF(0x08, 0x0031), WRITE_COEF(0x0a, 0x0060), WRITE_COEF(0x0b, 0x0),
7634 WRITE_COEF(0x0c, 0x7cf7), WRITE_COEF(0x0d, 0x1080), WRITE_COEF(0x0e, 0x7f7f),
7635 WRITE_COEF(0x0f, 0xcccc), WRITE_COEF(0x10, 0xddcc), WRITE_COEF(0x11, 0x0001),
7636 WRITE_COEF(0x13, 0x0), WRITE_COEF(0x14, 0x2aa0), WRITE_COEF(0x17, 0xa940),
7637 WRITE_COEF(0x19, 0x0), WRITE_COEF(0x1a, 0x0), WRITE_COEF(0x1b, 0x0),
7638 WRITE_COEF(0x1c, 0x0), WRITE_COEF(0x1d, 0x0), WRITE_COEF(0x1e, 0x7418),
7639 WRITE_COEF(0x1f, 0x0804), WRITE_COEF(0x20, 0x4200), WRITE_COEF(0x21, 0x0468),
7640 WRITE_COEF(0x22, 0x8ccc), WRITE_COEF(0x23, 0x0250), WRITE_COEF(0x24, 0x7418),
7641 WRITE_COEF(0x27, 0x0), WRITE_COEF(0x28, 0x8ccc), WRITE_COEF(0x2a, 0xff00),
7642 WRITE_COEF(0x2b, 0x8000), WRITE_COEF(0xa7, 0xff00), WRITE_COEF(0xa8, 0x8000),
7643 WRITE_COEF(0xaa, 0x2e17), WRITE_COEF(0xab, 0xa0c0), WRITE_COEF(0xac, 0x0),
7644 WRITE_COEF(0xad, 0x0), WRITE_COEF(0xae, 0x2ac6), WRITE_COEF(0xaf, 0xa480),
7645 WRITE_COEF(0xb0, 0x0), WRITE_COEF(0xb1, 0x0), WRITE_COEF(0xb2, 0x0),
7646 WRITE_COEF(0xb3, 0x0), WRITE_COEF(0xb4, 0x0), WRITE_COEF(0xb5, 0x1040),
7647 WRITE_COEF(0xb6, 0xd697), WRITE_COEF(0xb7, 0x902b), WRITE_COEF(0xb8, 0xd697),
7648 WRITE_COEF(0xb9, 0x902b), WRITE_COEF(0xba, 0xb8ba), WRITE_COEF(0xbb, 0xaaab),
7649 WRITE_COEF(0xbc, 0xaaaf), WRITE_COEF(0xbd, 0x6aaa), WRITE_COEF(0xbe, 0x1c02),
7650 WRITE_COEF(0xc0, 0x00ff), WRITE_COEF(0xc1, 0x0fa6),
7651 {}
7652};
7653
7654static void alc668_restore_default_value(struct hda_codec *codec)
7655{
7656 alc_process_coef_fw(codec, alc668_coefs);
7657}
7658
David Henningsson6cb3b702010-09-09 08:51:44 +02007659enum {
Daniel T Chen2df03512010-10-10 22:39:28 -04007660 ALC662_FIXUP_ASPIRE,
Takashi Iwai3e887f32014-01-10 17:50:58 +01007661 ALC662_FIXUP_LED_GPIO1,
David Henningsson6cb3b702010-09-09 08:51:44 +02007662 ALC662_FIXUP_IDEAPAD,
Todd Broch6be79482010-12-07 16:51:05 -08007663 ALC272_FIXUP_MARIO,
Anisse Astierd2ebd472011-01-20 12:36:21 +01007664 ALC662_FIXUP_CZC_P10T,
David Henningsson94024cd2011-04-29 14:10:55 +02007665 ALC662_FIXUP_SKU_IGNORE,
Takashi Iwaie59ea3e2011-06-29 17:21:00 +02007666 ALC662_FIXUP_HP_RP5800,
Takashi Iwai53c334a2011-08-23 18:27:14 +02007667 ALC662_FIXUP_ASUS_MODE1,
7668 ALC662_FIXUP_ASUS_MODE2,
7669 ALC662_FIXUP_ASUS_MODE3,
7670 ALC662_FIXUP_ASUS_MODE4,
7671 ALC662_FIXUP_ASUS_MODE5,
7672 ALC662_FIXUP_ASUS_MODE6,
7673 ALC662_FIXUP_ASUS_MODE7,
7674 ALC662_FIXUP_ASUS_MODE8,
Takashi Iwai1565cc32012-02-13 12:03:25 +01007675 ALC662_FIXUP_NO_JACK_DETECT,
David Henningssonedfe3bf2012-06-12 13:15:12 +02007676 ALC662_FIXUP_ZOTAC_Z68,
Takashi Iwai125821a2012-06-22 14:30:29 +02007677 ALC662_FIXUP_INV_DMIC,
David Henningsson1f8b46c2015-05-12 14:38:15 +02007678 ALC662_FIXUP_DELL_MIC_NO_PRESENCE,
David Henningsson73bdd592013-04-15 15:44:14 +02007679 ALC668_FIXUP_DELL_MIC_NO_PRESENCE,
David Henningsson1f8b46c2015-05-12 14:38:15 +02007680 ALC662_FIXUP_HEADSET_MODE,
David Henningsson73bdd592013-04-15 15:44:14 +02007681 ALC668_FIXUP_HEADSET_MODE,
David Henningsson8e54b4a2014-02-07 09:31:07 +01007682 ALC662_FIXUP_BASS_MODE4_CHMAP,
David Henningsson61a75f12014-02-07 09:31:08 +01007683 ALC662_FIXUP_BASS_16,
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01007684 ALC662_FIXUP_BASS_1A,
David Henningsson8e54b4a2014-02-07 09:31:07 +01007685 ALC662_FIXUP_BASS_CHMAP,
Hui Wang493a52a2014-01-14 14:07:36 +08007686 ALC668_FIXUP_AUTO_MUTE,
Gabriele Mazzotta5e6db662014-05-20 18:58:26 +02007687 ALC668_FIXUP_DELL_DISABLE_AAMIX,
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02007688 ALC668_FIXUP_DELL_XPS13,
Bobi Mihalca9d4dc582016-03-23 13:26:11 +02007689 ALC662_FIXUP_ASUS_Nx50,
Mikhail Paulyshkafc7438b2017-04-21 08:52:42 +02007690 ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE,
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07007691 ALC668_FIXUP_ASUS_Nx51,
Kailang Yang78f4f7c2016-06-07 11:31:34 +08007692 ALC891_FIXUP_HEADSET_MODE,
7693 ALC891_FIXUP_DELL_MIC_NO_PRESENCE,
Shrirang Bagul9b51fe32016-08-01 13:16:17 +08007694 ALC662_FIXUP_ACER_VERITON,
Takashi Iwai1a3f0992016-10-20 12:14:51 +02007695 ALC892_FIXUP_ASROCK_MOBO,
Kailang Yangc6790c82016-11-25 16:15:17 +08007696 ALC662_FIXUP_USI_FUNC,
7697 ALC662_FIXUP_USI_HEADSET_MODE,
Kailang Yangca169cc2017-04-25 16:17:40 +08007698 ALC662_FIXUP_LENOVO_MULTI_CODECS,
David Henningsson6cb3b702010-09-09 08:51:44 +02007699};
7700
Takashi Iwai1727a772013-01-10 09:52:52 +01007701static const struct hda_fixup alc662_fixups[] = {
Daniel T Chen2df03512010-10-10 22:39:28 -04007702 [ALC662_FIXUP_ASPIRE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01007703 .type = HDA_FIXUP_PINS,
7704 .v.pins = (const struct hda_pintbl[]) {
Daniel T Chen2df03512010-10-10 22:39:28 -04007705 { 0x15, 0x99130112 }, /* subwoofer */
7706 { }
7707 }
7708 },
Takashi Iwai3e887f32014-01-10 17:50:58 +01007709 [ALC662_FIXUP_LED_GPIO1] = {
7710 .type = HDA_FIXUP_FUNC,
7711 .v.func = alc662_fixup_led_gpio1,
7712 },
David Henningsson6cb3b702010-09-09 08:51:44 +02007713 [ALC662_FIXUP_IDEAPAD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01007714 .type = HDA_FIXUP_PINS,
7715 .v.pins = (const struct hda_pintbl[]) {
David Henningsson6cb3b702010-09-09 08:51:44 +02007716 { 0x17, 0x99130112 }, /* subwoofer */
7717 { }
Takashi Iwai3e887f32014-01-10 17:50:58 +01007718 },
7719 .chained = true,
7720 .chain_id = ALC662_FIXUP_LED_GPIO1,
David Henningsson6cb3b702010-09-09 08:51:44 +02007721 },
Todd Broch6be79482010-12-07 16:51:05 -08007722 [ALC272_FIXUP_MARIO] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01007723 .type = HDA_FIXUP_FUNC,
Takashi Iwaib5bfbc62011-01-13 14:22:32 +01007724 .v.func = alc272_fixup_mario,
Anisse Astierd2ebd472011-01-20 12:36:21 +01007725 },
7726 [ALC662_FIXUP_CZC_P10T] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01007727 .type = HDA_FIXUP_VERBS,
Anisse Astierd2ebd472011-01-20 12:36:21 +01007728 .v.verbs = (const struct hda_verb[]) {
7729 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
7730 {}
7731 }
7732 },
David Henningsson94024cd2011-04-29 14:10:55 +02007733 [ALC662_FIXUP_SKU_IGNORE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01007734 .type = HDA_FIXUP_FUNC,
Takashi Iwai23d30f22012-05-07 17:17:32 +02007735 .v.func = alc_fixup_sku_ignore,
Takashi Iwaic6b35872011-03-28 12:05:31 +02007736 },
Takashi Iwaie59ea3e2011-06-29 17:21:00 +02007737 [ALC662_FIXUP_HP_RP5800] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01007738 .type = HDA_FIXUP_PINS,
7739 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaie59ea3e2011-06-29 17:21:00 +02007740 { 0x14, 0x0221201f }, /* HP out */
7741 { }
7742 },
7743 .chained = true,
7744 .chain_id = ALC662_FIXUP_SKU_IGNORE
7745 },
Takashi Iwai53c334a2011-08-23 18:27:14 +02007746 [ALC662_FIXUP_ASUS_MODE1] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01007747 .type = HDA_FIXUP_PINS,
7748 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02007749 { 0x14, 0x99130110 }, /* speaker */
7750 { 0x18, 0x01a19c20 }, /* mic */
7751 { 0x19, 0x99a3092f }, /* int-mic */
7752 { 0x21, 0x0121401f }, /* HP out */
7753 { }
7754 },
7755 .chained = true,
7756 .chain_id = ALC662_FIXUP_SKU_IGNORE
7757 },
7758 [ALC662_FIXUP_ASUS_MODE2] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01007759 .type = HDA_FIXUP_PINS,
7760 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai2996bdb2011-08-18 16:02:24 +02007761 { 0x14, 0x99130110 }, /* speaker */
7762 { 0x18, 0x01a19820 }, /* mic */
7763 { 0x19, 0x99a3092f }, /* int-mic */
7764 { 0x1b, 0x0121401f }, /* HP out */
7765 { }
7766 },
Takashi Iwai53c334a2011-08-23 18:27:14 +02007767 .chained = true,
7768 .chain_id = ALC662_FIXUP_SKU_IGNORE
7769 },
7770 [ALC662_FIXUP_ASUS_MODE3] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01007771 .type = HDA_FIXUP_PINS,
7772 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02007773 { 0x14, 0x99130110 }, /* speaker */
7774 { 0x15, 0x0121441f }, /* HP */
7775 { 0x18, 0x01a19840 }, /* mic */
7776 { 0x19, 0x99a3094f }, /* int-mic */
7777 { 0x21, 0x01211420 }, /* HP2 */
7778 { }
7779 },
7780 .chained = true,
7781 .chain_id = ALC662_FIXUP_SKU_IGNORE
7782 },
7783 [ALC662_FIXUP_ASUS_MODE4] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01007784 .type = HDA_FIXUP_PINS,
7785 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02007786 { 0x14, 0x99130110 }, /* speaker */
7787 { 0x16, 0x99130111 }, /* speaker */
7788 { 0x18, 0x01a19840 }, /* mic */
7789 { 0x19, 0x99a3094f }, /* int-mic */
7790 { 0x21, 0x0121441f }, /* HP */
7791 { }
7792 },
7793 .chained = true,
7794 .chain_id = ALC662_FIXUP_SKU_IGNORE
7795 },
7796 [ALC662_FIXUP_ASUS_MODE5] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01007797 .type = HDA_FIXUP_PINS,
7798 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02007799 { 0x14, 0x99130110 }, /* speaker */
7800 { 0x15, 0x0121441f }, /* HP */
7801 { 0x16, 0x99130111 }, /* speaker */
7802 { 0x18, 0x01a19840 }, /* mic */
7803 { 0x19, 0x99a3094f }, /* int-mic */
7804 { }
7805 },
7806 .chained = true,
7807 .chain_id = ALC662_FIXUP_SKU_IGNORE
7808 },
7809 [ALC662_FIXUP_ASUS_MODE6] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01007810 .type = HDA_FIXUP_PINS,
7811 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02007812 { 0x14, 0x99130110 }, /* speaker */
7813 { 0x15, 0x01211420 }, /* HP2 */
7814 { 0x18, 0x01a19840 }, /* mic */
7815 { 0x19, 0x99a3094f }, /* int-mic */
7816 { 0x1b, 0x0121441f }, /* HP */
7817 { }
7818 },
7819 .chained = true,
7820 .chain_id = ALC662_FIXUP_SKU_IGNORE
7821 },
7822 [ALC662_FIXUP_ASUS_MODE7] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01007823 .type = HDA_FIXUP_PINS,
7824 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02007825 { 0x14, 0x99130110 }, /* speaker */
7826 { 0x17, 0x99130111 }, /* speaker */
7827 { 0x18, 0x01a19840 }, /* mic */
7828 { 0x19, 0x99a3094f }, /* int-mic */
7829 { 0x1b, 0x01214020 }, /* HP */
7830 { 0x21, 0x0121401f }, /* HP */
7831 { }
7832 },
7833 .chained = true,
7834 .chain_id = ALC662_FIXUP_SKU_IGNORE
7835 },
7836 [ALC662_FIXUP_ASUS_MODE8] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01007837 .type = HDA_FIXUP_PINS,
7838 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02007839 { 0x14, 0x99130110 }, /* speaker */
7840 { 0x12, 0x99a30970 }, /* int-mic */
7841 { 0x15, 0x01214020 }, /* HP */
7842 { 0x17, 0x99130111 }, /* speaker */
7843 { 0x18, 0x01a19840 }, /* mic */
7844 { 0x21, 0x0121401f }, /* HP */
7845 { }
7846 },
7847 .chained = true,
7848 .chain_id = ALC662_FIXUP_SKU_IGNORE
Takashi Iwai2996bdb2011-08-18 16:02:24 +02007849 },
Takashi Iwai1565cc32012-02-13 12:03:25 +01007850 [ALC662_FIXUP_NO_JACK_DETECT] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01007851 .type = HDA_FIXUP_FUNC,
Takashi Iwai1565cc32012-02-13 12:03:25 +01007852 .v.func = alc_fixup_no_jack_detect,
7853 },
David Henningssonedfe3bf2012-06-12 13:15:12 +02007854 [ALC662_FIXUP_ZOTAC_Z68] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01007855 .type = HDA_FIXUP_PINS,
7856 .v.pins = (const struct hda_pintbl[]) {
David Henningssonedfe3bf2012-06-12 13:15:12 +02007857 { 0x1b, 0x02214020 }, /* Front HP */
7858 { }
7859 }
7860 },
Takashi Iwai125821a2012-06-22 14:30:29 +02007861 [ALC662_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01007862 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02007863 .v.func = alc_fixup_inv_dmic,
Takashi Iwai125821a2012-06-22 14:30:29 +02007864 },
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02007865 [ALC668_FIXUP_DELL_XPS13] = {
7866 .type = HDA_FIXUP_FUNC,
7867 .v.func = alc_fixup_dell_xps13,
7868 .chained = true,
7869 .chain_id = ALC668_FIXUP_DELL_DISABLE_AAMIX
7870 },
Gabriele Mazzotta5e6db662014-05-20 18:58:26 +02007871 [ALC668_FIXUP_DELL_DISABLE_AAMIX] = {
7872 .type = HDA_FIXUP_FUNC,
7873 .v.func = alc_fixup_disable_aamix,
7874 .chained = true,
7875 .chain_id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE
7876 },
Hui Wang493a52a2014-01-14 14:07:36 +08007877 [ALC668_FIXUP_AUTO_MUTE] = {
7878 .type = HDA_FIXUP_FUNC,
7879 .v.func = alc_fixup_auto_mute_via_amp,
7880 .chained = true,
7881 .chain_id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE
7882 },
David Henningsson1f8b46c2015-05-12 14:38:15 +02007883 [ALC662_FIXUP_DELL_MIC_NO_PRESENCE] = {
7884 .type = HDA_FIXUP_PINS,
7885 .v.pins = (const struct hda_pintbl[]) {
7886 { 0x19, 0x03a1113c }, /* use as headset mic, without its own jack detect */
7887 /* headphone mic by setting pin control of 0x1b (headphone out) to in + vref_50 */
7888 { }
7889 },
7890 .chained = true,
7891 .chain_id = ALC662_FIXUP_HEADSET_MODE
7892 },
7893 [ALC662_FIXUP_HEADSET_MODE] = {
7894 .type = HDA_FIXUP_FUNC,
7895 .v.func = alc_fixup_headset_mode_alc662,
7896 },
David Henningsson73bdd592013-04-15 15:44:14 +02007897 [ALC668_FIXUP_DELL_MIC_NO_PRESENCE] = {
7898 .type = HDA_FIXUP_PINS,
7899 .v.pins = (const struct hda_pintbl[]) {
7900 { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
7901 { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */
7902 { }
7903 },
7904 .chained = true,
7905 .chain_id = ALC668_FIXUP_HEADSET_MODE
7906 },
7907 [ALC668_FIXUP_HEADSET_MODE] = {
7908 .type = HDA_FIXUP_FUNC,
7909 .v.func = alc_fixup_headset_mode_alc668,
7910 },
David Henningsson8e54b4a2014-02-07 09:31:07 +01007911 [ALC662_FIXUP_BASS_MODE4_CHMAP] = {
Takashi Iwai8e383952013-10-30 17:41:12 +01007912 .type = HDA_FIXUP_FUNC,
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01007913 .v.func = alc_fixup_bass_chmap,
Takashi Iwai8e383952013-10-30 17:41:12 +01007914 .chained = true,
7915 .chain_id = ALC662_FIXUP_ASUS_MODE4
7916 },
David Henningsson61a75f12014-02-07 09:31:08 +01007917 [ALC662_FIXUP_BASS_16] = {
7918 .type = HDA_FIXUP_PINS,
7919 .v.pins = (const struct hda_pintbl[]) {
7920 {0x16, 0x80106111}, /* bass speaker */
7921 {}
7922 },
7923 .chained = true,
7924 .chain_id = ALC662_FIXUP_BASS_CHMAP,
7925 },
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01007926 [ALC662_FIXUP_BASS_1A] = {
7927 .type = HDA_FIXUP_PINS,
7928 .v.pins = (const struct hda_pintbl[]) {
7929 {0x1a, 0x80106111}, /* bass speaker */
7930 {}
7931 },
David Henningsson8e54b4a2014-02-07 09:31:07 +01007932 .chained = true,
7933 .chain_id = ALC662_FIXUP_BASS_CHMAP,
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01007934 },
David Henningsson8e54b4a2014-02-07 09:31:07 +01007935 [ALC662_FIXUP_BASS_CHMAP] = {
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01007936 .type = HDA_FIXUP_FUNC,
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01007937 .v.func = alc_fixup_bass_chmap,
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01007938 },
Bobi Mihalca9d4dc582016-03-23 13:26:11 +02007939 [ALC662_FIXUP_ASUS_Nx50] = {
7940 .type = HDA_FIXUP_FUNC,
7941 .v.func = alc_fixup_auto_mute_via_amp,
7942 .chained = true,
7943 .chain_id = ALC662_FIXUP_BASS_1A
7944 },
Mikhail Paulyshkafc7438b2017-04-21 08:52:42 +02007945 [ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE] = {
7946 .type = HDA_FIXUP_FUNC,
7947 .v.func = alc_fixup_headset_mode_alc668,
7948 .chain_id = ALC662_FIXUP_BASS_CHMAP
7949 },
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07007950 [ALC668_FIXUP_ASUS_Nx51] = {
7951 .type = HDA_FIXUP_PINS,
7952 .v.pins = (const struct hda_pintbl[]) {
Mikhail Paulyshkafc7438b2017-04-21 08:52:42 +02007953 { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
7954 { 0x1a, 0x90170151 }, /* bass speaker */
7955 { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07007956 {}
7957 },
7958 .chained = true,
Mikhail Paulyshkafc7438b2017-04-21 08:52:42 +02007959 .chain_id = ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE,
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07007960 },
Kailang Yang78f4f7c2016-06-07 11:31:34 +08007961 [ALC891_FIXUP_HEADSET_MODE] = {
7962 .type = HDA_FIXUP_FUNC,
7963 .v.func = alc_fixup_headset_mode,
7964 },
7965 [ALC891_FIXUP_DELL_MIC_NO_PRESENCE] = {
7966 .type = HDA_FIXUP_PINS,
7967 .v.pins = (const struct hda_pintbl[]) {
7968 { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
7969 { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */
7970 { }
7971 },
7972 .chained = true,
7973 .chain_id = ALC891_FIXUP_HEADSET_MODE
7974 },
Shrirang Bagul9b51fe32016-08-01 13:16:17 +08007975 [ALC662_FIXUP_ACER_VERITON] = {
7976 .type = HDA_FIXUP_PINS,
7977 .v.pins = (const struct hda_pintbl[]) {
7978 { 0x15, 0x50170120 }, /* no internal speaker */
7979 { }
7980 }
7981 },
Takashi Iwai1a3f0992016-10-20 12:14:51 +02007982 [ALC892_FIXUP_ASROCK_MOBO] = {
7983 .type = HDA_FIXUP_PINS,
7984 .v.pins = (const struct hda_pintbl[]) {
7985 { 0x15, 0x40f000f0 }, /* disabled */
7986 { 0x16, 0x40f000f0 }, /* disabled */
Takashi Iwai1a3f0992016-10-20 12:14:51 +02007987 { }
7988 }
7989 },
Kailang Yangc6790c82016-11-25 16:15:17 +08007990 [ALC662_FIXUP_USI_FUNC] = {
7991 .type = HDA_FIXUP_FUNC,
7992 .v.func = alc662_fixup_usi_headset_mic,
7993 },
7994 [ALC662_FIXUP_USI_HEADSET_MODE] = {
7995 .type = HDA_FIXUP_PINS,
7996 .v.pins = (const struct hda_pintbl[]) {
7997 { 0x19, 0x02a1913c }, /* use as headset mic, without its own jack detect */
7998 { 0x18, 0x01a1903d },
7999 { }
8000 },
8001 .chained = true,
8002 .chain_id = ALC662_FIXUP_USI_FUNC
8003 },
Kailang Yangca169cc2017-04-25 16:17:40 +08008004 [ALC662_FIXUP_LENOVO_MULTI_CODECS] = {
8005 .type = HDA_FIXUP_FUNC,
8006 .v.func = alc233_alc662_fixup_lenovo_dual_codecs,
8007 },
David Henningsson6cb3b702010-09-09 08:51:44 +02008008};
8009
Takashi Iwaia9111322011-05-02 11:30:18 +02008010static const struct snd_pci_quirk alc662_fixup_tbl[] = {
Takashi Iwai53c334a2011-08-23 18:27:14 +02008011 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_FIXUP_ASUS_MODE2),
Takashi Iwaid3d38352013-08-19 20:05:50 +02008012 SND_PCI_QUIRK(0x1025, 0x022f, "Acer Aspire One", ALC662_FIXUP_INV_DMIC),
David Henningsson02f6ff92015-12-07 11:29:31 +01008013 SND_PCI_QUIRK(0x1025, 0x0241, "Packard Bell DOTS", ALC662_FIXUP_INV_DMIC),
David Henningssona6c47a82011-02-10 15:39:19 +01008014 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
David Henningsson94024cd2011-04-29 14:10:55 +02008015 SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
Takashi Iwai125821a2012-06-22 14:30:29 +02008016 SND_PCI_QUIRK(0x1025, 0x0349, "eMachines eM250", ALC662_FIXUP_INV_DMIC),
Takashi Iwai18019282013-08-16 08:17:05 +02008017 SND_PCI_QUIRK(0x1025, 0x034a, "Gateway LT27", ALC662_FIXUP_INV_DMIC),
Daniel T Chen2df03512010-10-10 22:39:28 -04008018 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
David Henningsson73bdd592013-04-15 15:44:14 +02008019 SND_PCI_QUIRK(0x1028, 0x05d8, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
8020 SND_PCI_QUIRK(0x1028, 0x05db, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
Takashi Iwaic5d019c2014-07-22 17:33:32 +02008021 SND_PCI_QUIRK(0x1028, 0x05fe, "Dell XPS 15", ALC668_FIXUP_DELL_XPS13),
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02008022 SND_PCI_QUIRK(0x1028, 0x060a, "Dell XPS 13", ALC668_FIXUP_DELL_XPS13),
Niranjan Sivakumar467e1432015-09-05 18:20:35 +02008023 SND_PCI_QUIRK(0x1028, 0x060d, "Dell M3800", ALC668_FIXUP_DELL_XPS13),
David Henningsson09d20142013-11-20 11:43:30 +01008024 SND_PCI_QUIRK(0x1028, 0x0625, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
David Henningssonad8ff99e2013-11-07 09:28:59 +01008025 SND_PCI_QUIRK(0x1028, 0x0626, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
Kailang Yang8dc9abb2014-04-16 15:53:12 +08008026 SND_PCI_QUIRK(0x1028, 0x0696, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
8027 SND_PCI_QUIRK(0x1028, 0x0698, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
Kailang Yang6a98e342014-10-27 16:20:30 +08008028 SND_PCI_QUIRK(0x1028, 0x069f, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
Takashi Iwaie59ea3e2011-06-29 17:21:00 +02008029 SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800),
Kaho Ng2da2dc92016-05-09 00:27:49 +08008030 SND_PCI_QUIRK(0x1043, 0x1080, "Asus UX501VW", ALC668_FIXUP_HEADSET_MODE),
Bobi Mihalca83a9efb2016-03-23 13:32:33 +02008031 SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_ASUS_Nx50),
Takashi Iwaidb8948e2016-01-18 09:17:30 +01008032 SND_PCI_QUIRK(0x1043, 0x13df, "Asus N550JX", ALC662_FIXUP_BASS_1A),
Bobi Mihalca9d4dc582016-03-23 13:26:11 +02008033 SND_PCI_QUIRK(0x1043, 0x129d, "Asus N750", ALC662_FIXUP_ASUS_Nx50),
David Henningsson8e54b4a2014-02-07 09:31:07 +01008034 SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
David Henningsson61a75f12014-02-07 09:31:08 +01008035 SND_PCI_QUIRK(0x1043, 0x15a7, "ASUS UX51VZH", ALC662_FIXUP_BASS_16),
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07008036 SND_PCI_QUIRK(0x1043, 0x177d, "ASUS N551", ALC668_FIXUP_ASUS_Nx51),
8037 SND_PCI_QUIRK(0x1043, 0x17bd, "ASUS N751", ALC668_FIXUP_ASUS_Nx51),
Takashi Iwaic7efff92017-01-04 21:38:16 +01008038 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71SL", ALC662_FIXUP_ASUS_MODE8),
David Henningsson61a75f12014-02-07 09:31:08 +01008039 SND_PCI_QUIRK(0x1043, 0x1b73, "ASUS N55SF", ALC662_FIXUP_BASS_16),
David Henningsson8e54b4a2014-02-07 09:31:07 +01008040 SND_PCI_QUIRK(0x1043, 0x1bf3, "ASUS N76VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
Takashi Iwai1565cc32012-02-13 12:03:25 +01008041 SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT),
Takashi Iwai53c334a2011-08-23 18:27:14 +02008042 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2),
Daniel T Chena0e90ac2010-11-20 10:20:35 -05008043 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
Kailang Yangc6790c82016-11-25 16:15:17 +08008044 SND_PCI_QUIRK(0x14cd, 0x5003, "USI", ALC662_FIXUP_USI_HEADSET_MODE),
Kailang Yangca169cc2017-04-25 16:17:40 +08008045 SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC662_FIXUP_LENOVO_MULTI_CODECS),
Valentine Sinitsynd4118582010-10-01 22:24:08 +06008046 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
David Henningsson6cb3b702010-09-09 08:51:44 +02008047 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
Takashi Iwai1a3f0992016-10-20 12:14:51 +02008048 SND_PCI_QUIRK(0x1849, 0x5892, "ASRock B150M", ALC892_FIXUP_ASROCK_MOBO),
David Henningssonedfe3bf2012-06-12 13:15:12 +02008049 SND_PCI_QUIRK(0x19da, 0xa130, "Zotac Z68", ALC662_FIXUP_ZOTAC_Z68),
Shrirang Bagul9b51fe32016-08-01 13:16:17 +08008050 SND_PCI_QUIRK(0x1b0a, 0x01b8, "ACER Veriton", ALC662_FIXUP_ACER_VERITON),
Anisse Astierd2ebd472011-01-20 12:36:21 +01008051 SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
Takashi Iwai53c334a2011-08-23 18:27:14 +02008052
8053#if 0
8054 /* Below is a quirk table taken from the old code.
8055 * Basically the device should work as is without the fixup table.
8056 * If BIOS doesn't give a proper info, enable the corresponding
8057 * fixup entry.
Jesper Juhl7d7eb9e2012-04-12 22:11:25 +02008058 */
Takashi Iwai53c334a2011-08-23 18:27:14 +02008059 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC662_FIXUP_ASUS_MODE1),
8060 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC662_FIXUP_ASUS_MODE3),
8061 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC662_FIXUP_ASUS_MODE1),
8062 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC662_FIXUP_ASUS_MODE3),
8063 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
8064 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8065 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
8066 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC662_FIXUP_ASUS_MODE1),
8067 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC662_FIXUP_ASUS_MODE1),
8068 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8069 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC662_FIXUP_ASUS_MODE7),
8070 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC662_FIXUP_ASUS_MODE7),
8071 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC662_FIXUP_ASUS_MODE8),
8072 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC662_FIXUP_ASUS_MODE3),
8073 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC662_FIXUP_ASUS_MODE1),
8074 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8075 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_FIXUP_ASUS_MODE2),
8076 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC662_FIXUP_ASUS_MODE1),
8077 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8078 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
8079 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
8080 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8081 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC662_FIXUP_ASUS_MODE1),
8082 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC662_FIXUP_ASUS_MODE3),
8083 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_FIXUP_ASUS_MODE2),
8084 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8085 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC662_FIXUP_ASUS_MODE5),
8086 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
8087 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8088 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC662_FIXUP_ASUS_MODE1),
8089 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8090 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8091 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC662_FIXUP_ASUS_MODE3),
8092 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC662_FIXUP_ASUS_MODE3),
8093 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC662_FIXUP_ASUS_MODE1),
8094 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC662_FIXUP_ASUS_MODE1),
8095 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC662_FIXUP_ASUS_MODE1),
8096 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC662_FIXUP_ASUS_MODE1),
8097 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC662_FIXUP_ASUS_MODE1),
8098 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8099 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_FIXUP_ASUS_MODE2),
8100 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC662_FIXUP_ASUS_MODE1),
8101 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
8102 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC662_FIXUP_ASUS_MODE3),
8103 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC662_FIXUP_ASUS_MODE1),
8104 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC662_FIXUP_ASUS_MODE1),
8105 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC662_FIXUP_ASUS_MODE1),
8106 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_FIXUP_ASUS_MODE2),
8107 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
8108 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE4),
8109#endif
David Henningsson6cb3b702010-09-09 08:51:44 +02008110 {}
8111};
8112
Takashi Iwai1727a772013-01-10 09:52:52 +01008113static const struct hda_model_fixup alc662_fixup_models[] = {
Todd Broch6be79482010-12-07 16:51:05 -08008114 {.id = ALC272_FIXUP_MARIO, .name = "mario"},
Takashi Iwai53c334a2011-08-23 18:27:14 +02008115 {.id = ALC662_FIXUP_ASUS_MODE1, .name = "asus-mode1"},
8116 {.id = ALC662_FIXUP_ASUS_MODE2, .name = "asus-mode2"},
8117 {.id = ALC662_FIXUP_ASUS_MODE3, .name = "asus-mode3"},
8118 {.id = ALC662_FIXUP_ASUS_MODE4, .name = "asus-mode4"},
8119 {.id = ALC662_FIXUP_ASUS_MODE5, .name = "asus-mode5"},
8120 {.id = ALC662_FIXUP_ASUS_MODE6, .name = "asus-mode6"},
8121 {.id = ALC662_FIXUP_ASUS_MODE7, .name = "asus-mode7"},
8122 {.id = ALC662_FIXUP_ASUS_MODE8, .name = "asus-mode8"},
Takashi Iwai6e72aa52012-06-25 10:52:25 +02008123 {.id = ALC662_FIXUP_INV_DMIC, .name = "inv-dmic"},
David Henningssone32aa852013-06-17 11:04:02 +02008124 {.id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE, .name = "dell-headset-multi"},
Takashi Iwaiba90d6a2017-05-22 16:38:47 +02008125 {.id = ALC662_FIXUP_LENOVO_MULTI_CODECS, .name = "dual-codecs"},
Todd Broch6be79482010-12-07 16:51:05 -08008126 {}
8127};
David Henningsson6cb3b702010-09-09 08:51:44 +02008128
Hui Wang532895c2014-05-29 15:59:19 +08008129static const struct snd_hda_pin_quirk alc662_pin_fixup_tbl[] = {
Kailang Yang78f4f7c2016-06-07 11:31:34 +08008130 SND_HDA_PIN_QUIRK(0x10ec0867, 0x1028, "Dell", ALC891_FIXUP_DELL_MIC_NO_PRESENCE,
8131 {0x17, 0x02211010},
8132 {0x18, 0x01a19030},
8133 {0x1a, 0x01813040},
8134 {0x21, 0x01014020}),
David Henningsson1f8b46c2015-05-12 14:38:15 +02008135 SND_HDA_PIN_QUIRK(0x10ec0662, 0x1028, "Dell", ALC662_FIXUP_DELL_MIC_NO_PRESENCE,
David Henningsson1f8b46c2015-05-12 14:38:15 +02008136 {0x14, 0x01014010},
David Henningsson1f8b46c2015-05-12 14:38:15 +02008137 {0x18, 0x01a19020},
David Henningsson1f8b46c2015-05-12 14:38:15 +02008138 {0x1a, 0x0181302f},
Hui Wang11580292015-08-03 11:03:49 +08008139 {0x1b, 0x0221401f}),
David Henningsson76c21322014-06-24 14:46:54 +02008140 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
8141 {0x12, 0x99a30130},
8142 {0x14, 0x90170110},
8143 {0x15, 0x0321101f},
Hui Wang11580292015-08-03 11:03:49 +08008144 {0x16, 0x03011020}),
David Henningsson76c21322014-06-24 14:46:54 +02008145 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
8146 {0x12, 0x99a30140},
8147 {0x14, 0x90170110},
8148 {0x15, 0x0321101f},
Hui Wang11580292015-08-03 11:03:49 +08008149 {0x16, 0x03011020}),
David Henningsson76c21322014-06-24 14:46:54 +02008150 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
8151 {0x12, 0x99a30150},
8152 {0x14, 0x90170110},
8153 {0x15, 0x0321101f},
Hui Wang11580292015-08-03 11:03:49 +08008154 {0x16, 0x03011020}),
David Henningsson76c21322014-06-24 14:46:54 +02008155 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
David Henningsson76c21322014-06-24 14:46:54 +02008156 {0x14, 0x90170110},
8157 {0x15, 0x0321101f},
Hui Wang11580292015-08-03 11:03:49 +08008158 {0x16, 0x03011020}),
David Henningsson76c21322014-06-24 14:46:54 +02008159 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell XPS 15", ALC668_FIXUP_AUTO_MUTE,
8160 {0x12, 0x90a60130},
8161 {0x14, 0x90170110},
Hui Wang11580292015-08-03 11:03:49 +08008162 {0x15, 0x0321101f}),
Hui Wang532895c2014-05-29 15:59:19 +08008163 {}
8164};
8165
Takashi Iwai1d045db2011-07-07 18:23:21 +02008166/*
8167 */
Kailang Yangbc9f98a2007-04-12 13:06:07 +02008168static int patch_alc662(struct hda_codec *codec)
8169{
8170 struct alc_spec *spec;
Takashi Iwai3de95172012-05-07 18:03:15 +02008171 int err;
Kailang Yangbc9f98a2007-04-12 13:06:07 +02008172
Takashi Iwai3de95172012-05-07 18:03:15 +02008173 err = alc_alloc_spec(codec, 0x0b);
8174 if (err < 0)
8175 return err;
Kailang Yangbc9f98a2007-04-12 13:06:07 +02008176
Takashi Iwai3de95172012-05-07 18:03:15 +02008177 spec = codec->spec;
Takashi Iwai1f0f4b82011-06-27 10:52:59 +02008178
Takashi Iwai225068a2015-05-29 10:42:14 +02008179 spec->shutup = alc_eapd_shutup;
8180
Takashi Iwai53c334a2011-08-23 18:27:14 +02008181 /* handle multiple HPs as is */
8182 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
8183
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +02008184 alc_fix_pll_init(codec, 0x20, 0x04, 15);
8185
Takashi Iwai7639a062015-03-03 10:07:24 +01008186 switch (codec->core.vendor_id) {
Kailang Yangf3f91852014-10-24 15:43:46 +08008187 case 0x10ec0668:
8188 spec->init_hook = alc668_restore_default_value;
8189 break;
Kailang Yangf3f91852014-10-24 15:43:46 +08008190 }
Kailang Yang8663ff72012-06-29 09:35:52 +02008191
Takashi Iwai1727a772013-01-10 09:52:52 +01008192 snd_hda_pick_fixup(codec, alc662_fixup_models,
Takashi Iwai8e5a0502012-06-21 15:49:33 +02008193 alc662_fixup_tbl, alc662_fixups);
Hui Wang532895c2014-05-29 15:59:19 +08008194 snd_hda_pick_pin_fixup(codec, alc662_pin_fixup_tbl, alc662_fixups);
Takashi Iwai1727a772013-01-10 09:52:52 +01008195 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai8e5a0502012-06-21 15:49:33 +02008196
8197 alc_auto_parse_customize_define(codec);
8198
Takashi Iwai7504b6c2013-03-18 11:25:51 +01008199 if (has_cdefine_beep(codec))
8200 spec->gen.beep_nid = 0x01;
8201
Takashi Iwai1bb7e432011-10-17 16:50:59 +02008202 if ((alc_get_coef0(codec) & (1 << 14)) &&
Takashi Iwai5100cd02014-02-15 10:03:19 +01008203 codec->bus->pci && codec->bus->pci->subsystem_vendor == 0x1025 &&
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008204 spec->cdefine.platform_type == 1) {
Wei Yongjun6134b1a2013-04-18 11:12:59 +08008205 err = alc_codec_rename(codec, "ALC272X");
8206 if (err < 0)
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008207 goto error;
Takashi Iwai20ca0c32011-10-17 16:00:35 +02008208 }
Kailang Yang274693f2009-12-03 10:07:50 +01008209
Takashi Iwaib9c51062011-08-24 18:08:07 +02008210 /* automatic parse from the BIOS config */
8211 err = alc662_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008212 if (err < 0)
8213 goto error;
Kailang Yangbc9f98a2007-04-12 13:06:07 +02008214
Takashi Iwai7504b6c2013-03-18 11:25:51 +01008215 if (!spec->gen.no_analog && spec->gen.beep_nid) {
Takashi Iwai7639a062015-03-03 10:07:24 +01008216 switch (codec->core.vendor_id) {
Kailang Yangda00c242010-03-19 11:23:45 +01008217 case 0x10ec0662:
8218 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
8219 break;
8220 case 0x10ec0272:
8221 case 0x10ec0663:
8222 case 0x10ec0665:
Kailang Yang9ad54542013-11-26 15:41:40 +08008223 case 0x10ec0668:
Kailang Yangda00c242010-03-19 11:23:45 +01008224 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
8225 break;
8226 case 0x10ec0273:
8227 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
8228 break;
8229 }
Kailang Yangcec27c82010-02-04 14:18:18 +01008230 }
Takashi Iwai2134ea42008-01-10 16:53:55 +01008231
Takashi Iwai1727a772013-01-10 09:52:52 +01008232 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01008233
Kailang Yangbc9f98a2007-04-12 13:06:07 +02008234 return 0;
Kailang Yangbc9f98a2007-04-12 13:06:07 +02008235
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008236 error:
8237 alc_free(codec);
8238 return err;
Kailang Yangb478b992011-05-18 11:51:15 +02008239}
8240
Kailang Yangbc9f98a2007-04-12 13:06:07 +02008241/*
Kailang Yangd1eb57f2010-06-23 16:25:26 +02008242 * ALC680 support
8243 */
Kailang Yangd1eb57f2010-06-23 16:25:26 +02008244
Kailang Yangd1eb57f2010-06-23 16:25:26 +02008245static int alc680_parse_auto_config(struct hda_codec *codec)
8246{
Takashi Iwai3e6179b2011-07-08 16:55:13 +02008247 return alc_parse_auto_config(codec, NULL, NULL);
Kailang Yangd1eb57f2010-06-23 16:25:26 +02008248}
8249
Kailang Yangd1eb57f2010-06-23 16:25:26 +02008250/*
Kailang Yangd1eb57f2010-06-23 16:25:26 +02008251 */
Kailang Yangd1eb57f2010-06-23 16:25:26 +02008252static int patch_alc680(struct hda_codec *codec)
8253{
Kailang Yangd1eb57f2010-06-23 16:25:26 +02008254 int err;
8255
Takashi Iwai1f0f4b82011-06-27 10:52:59 +02008256 /* ALC680 has no aa-loopback mixer */
Takashi Iwai3de95172012-05-07 18:03:15 +02008257 err = alc_alloc_spec(codec, 0);
8258 if (err < 0)
8259 return err;
Takashi Iwai1f0f4b82011-06-27 10:52:59 +02008260
Takashi Iwai1ebec5f2011-08-15 13:21:48 +02008261 /* automatic parse from the BIOS config */
8262 err = alc680_parse_auto_config(codec);
8263 if (err < 0) {
8264 alc_free(codec);
8265 return err;
Kailang Yangd1eb57f2010-06-23 16:25:26 +02008266 }
8267
Kailang Yangd1eb57f2010-06-23 16:25:26 +02008268 return 0;
8269}
8270
8271/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07008272 * patch entries
8273 */
Takashi Iwaib9a94a92015-10-01 16:20:04 +02008274static const struct hda_device_id snd_hda_id_realtek[] = {
Kailang Yang0a6f0602017-06-30 16:00:48 +08008275 HDA_CODEC_ENTRY(0x10ec0215, "ALC215", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02008276 HDA_CODEC_ENTRY(0x10ec0221, "ALC221", patch_alc269),
Kailang Yang42314302016-02-03 15:03:50 +08008277 HDA_CODEC_ENTRY(0x10ec0225, "ALC225", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02008278 HDA_CODEC_ENTRY(0x10ec0231, "ALC231", patch_alc269),
8279 HDA_CODEC_ENTRY(0x10ec0233, "ALC233", patch_alc269),
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08008280 HDA_CODEC_ENTRY(0x10ec0234, "ALC234", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02008281 HDA_CODEC_ENTRY(0x10ec0235, "ALC233", patch_alc269),
Kailang Yang736f20a2017-10-20 15:06:34 +08008282 HDA_CODEC_ENTRY(0x10ec0236, "ALC236", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02008283 HDA_CODEC_ENTRY(0x10ec0255, "ALC255", patch_alc269),
8284 HDA_CODEC_ENTRY(0x10ec0256, "ALC256", patch_alc269),
Kailang Yangf429e7e2017-12-05 15:38:24 +08008285 HDA_CODEC_ENTRY(0x10ec0257, "ALC257", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02008286 HDA_CODEC_ENTRY(0x10ec0260, "ALC260", patch_alc260),
8287 HDA_CODEC_ENTRY(0x10ec0262, "ALC262", patch_alc262),
8288 HDA_CODEC_ENTRY(0x10ec0267, "ALC267", patch_alc268),
8289 HDA_CODEC_ENTRY(0x10ec0268, "ALC268", patch_alc268),
8290 HDA_CODEC_ENTRY(0x10ec0269, "ALC269", patch_alc269),
8291 HDA_CODEC_ENTRY(0x10ec0270, "ALC270", patch_alc269),
8292 HDA_CODEC_ENTRY(0x10ec0272, "ALC272", patch_alc662),
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08008293 HDA_CODEC_ENTRY(0x10ec0274, "ALC274", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02008294 HDA_CODEC_ENTRY(0x10ec0275, "ALC275", patch_alc269),
8295 HDA_CODEC_ENTRY(0x10ec0276, "ALC276", patch_alc269),
8296 HDA_CODEC_ENTRY(0x10ec0280, "ALC280", patch_alc269),
8297 HDA_CODEC_ENTRY(0x10ec0282, "ALC282", patch_alc269),
8298 HDA_CODEC_ENTRY(0x10ec0283, "ALC283", patch_alc269),
8299 HDA_CODEC_ENTRY(0x10ec0284, "ALC284", patch_alc269),
Kailang Yang0a6f0602017-06-30 16:00:48 +08008300 HDA_CODEC_ENTRY(0x10ec0285, "ALC285", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02008301 HDA_CODEC_ENTRY(0x10ec0286, "ALC286", patch_alc269),
8302 HDA_CODEC_ENTRY(0x10ec0288, "ALC288", patch_alc269),
Kailang Yang0a6f0602017-06-30 16:00:48 +08008303 HDA_CODEC_ENTRY(0x10ec0289, "ALC289", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02008304 HDA_CODEC_ENTRY(0x10ec0290, "ALC290", patch_alc269),
8305 HDA_CODEC_ENTRY(0x10ec0292, "ALC292", patch_alc269),
8306 HDA_CODEC_ENTRY(0x10ec0293, "ALC293", patch_alc269),
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08008307 HDA_CODEC_ENTRY(0x10ec0294, "ALC294", patch_alc269),
Kailang Yang7d727862016-05-24 16:46:07 +08008308 HDA_CODEC_ENTRY(0x10ec0295, "ALC295", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02008309 HDA_CODEC_ENTRY(0x10ec0298, "ALC298", patch_alc269),
Kailang Yang28f1f9b2017-01-04 14:49:07 +08008310 HDA_CODEC_ENTRY(0x10ec0299, "ALC299", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02008311 HDA_CODEC_REV_ENTRY(0x10ec0861, 0x100340, "ALC660", patch_alc861),
8312 HDA_CODEC_ENTRY(0x10ec0660, "ALC660-VD", patch_alc861vd),
8313 HDA_CODEC_ENTRY(0x10ec0861, "ALC861", patch_alc861),
8314 HDA_CODEC_ENTRY(0x10ec0862, "ALC861-VD", patch_alc861vd),
8315 HDA_CODEC_REV_ENTRY(0x10ec0662, 0x100002, "ALC662 rev2", patch_alc882),
8316 HDA_CODEC_REV_ENTRY(0x10ec0662, 0x100101, "ALC662 rev1", patch_alc662),
8317 HDA_CODEC_REV_ENTRY(0x10ec0662, 0x100300, "ALC662 rev3", patch_alc662),
8318 HDA_CODEC_ENTRY(0x10ec0663, "ALC663", patch_alc662),
8319 HDA_CODEC_ENTRY(0x10ec0665, "ALC665", patch_alc662),
8320 HDA_CODEC_ENTRY(0x10ec0667, "ALC667", patch_alc662),
8321 HDA_CODEC_ENTRY(0x10ec0668, "ALC668", patch_alc662),
8322 HDA_CODEC_ENTRY(0x10ec0670, "ALC670", patch_alc662),
8323 HDA_CODEC_ENTRY(0x10ec0671, "ALC671", patch_alc662),
8324 HDA_CODEC_ENTRY(0x10ec0680, "ALC680", patch_alc680),
Kailang Yang6fbae352016-05-30 16:44:20 +08008325 HDA_CODEC_ENTRY(0x10ec0700, "ALC700", patch_alc269),
8326 HDA_CODEC_ENTRY(0x10ec0701, "ALC701", patch_alc269),
8327 HDA_CODEC_ENTRY(0x10ec0703, "ALC703", patch_alc269),
Kailang Yang78f4f7c2016-06-07 11:31:34 +08008328 HDA_CODEC_ENTRY(0x10ec0867, "ALC891", patch_alc662),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02008329 HDA_CODEC_ENTRY(0x10ec0880, "ALC880", patch_alc880),
8330 HDA_CODEC_ENTRY(0x10ec0882, "ALC882", patch_alc882),
8331 HDA_CODEC_ENTRY(0x10ec0883, "ALC883", patch_alc882),
8332 HDA_CODEC_REV_ENTRY(0x10ec0885, 0x100101, "ALC889A", patch_alc882),
8333 HDA_CODEC_REV_ENTRY(0x10ec0885, 0x100103, "ALC889A", patch_alc882),
8334 HDA_CODEC_ENTRY(0x10ec0885, "ALC885", patch_alc882),
8335 HDA_CODEC_ENTRY(0x10ec0887, "ALC887", patch_alc882),
8336 HDA_CODEC_REV_ENTRY(0x10ec0888, 0x100101, "ALC1200", patch_alc882),
8337 HDA_CODEC_ENTRY(0x10ec0888, "ALC888", patch_alc882),
8338 HDA_CODEC_ENTRY(0x10ec0889, "ALC889", patch_alc882),
8339 HDA_CODEC_ENTRY(0x10ec0892, "ALC892", patch_alc662),
8340 HDA_CODEC_ENTRY(0x10ec0899, "ALC898", patch_alc882),
8341 HDA_CODEC_ENTRY(0x10ec0900, "ALC1150", patch_alc882),
Kailang Yang65553b12017-07-11 15:15:47 +08008342 HDA_CODEC_ENTRY(0x10ec1168, "ALC1220", patch_alc882),
Kailang Yanga535ad52017-01-16 16:59:26 +08008343 HDA_CODEC_ENTRY(0x10ec1220, "ALC1220", patch_alc882),
Linus Torvalds1da177e2005-04-16 15:20:36 -07008344 {} /* terminator */
8345};
Takashi Iwaib9a94a92015-10-01 16:20:04 +02008346MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_realtek);
Takashi Iwai1289e9e2008-11-27 15:47:11 +01008347
8348MODULE_LICENSE("GPL");
8349MODULE_DESCRIPTION("Realtek HD-audio codec");
8350
Takashi Iwaid8a766a2015-02-17 15:25:37 +01008351static struct hda_codec_driver realtek_driver = {
Takashi Iwaib9a94a92015-10-01 16:20:04 +02008352 .id = snd_hda_id_realtek,
Takashi Iwai1289e9e2008-11-27 15:47:11 +01008353};
8354
Takashi Iwaid8a766a2015-02-17 15:25:37 +01008355module_hda_codec_driver(realtek_driver);