blob: d64dcb9a4c9957ed8d473eb1cb92e9af93a5e4f4 [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 {
46 ALC_INIT_NONE,
47 ALC_INIT_DEFAULT,
48 ALC_INIT_GPIO1,
49 ALC_INIT_GPIO2,
50 ALC_INIT_GPIO3,
51};
52
David Henningsson73bdd592013-04-15 15:44:14 +020053enum {
54 ALC_HEADSET_MODE_UNKNOWN,
55 ALC_HEADSET_MODE_UNPLUGGED,
56 ALC_HEADSET_MODE_HEADSET,
57 ALC_HEADSET_MODE_MIC,
58 ALC_HEADSET_MODE_HEADPHONE,
59};
60
61enum {
62 ALC_HEADSET_TYPE_UNKNOWN,
63 ALC_HEADSET_TYPE_CTIA,
64 ALC_HEADSET_TYPE_OMTP,
65};
66
Hui Wangc7b60a82015-12-28 11:35:25 +080067enum {
68 ALC_KEY_MICMUTE_INDEX,
69};
70
Kailang Yangda00c242010-03-19 11:23:45 +010071struct alc_customize_define {
72 unsigned int sku_cfg;
73 unsigned char port_connectivity;
74 unsigned char check_sum;
75 unsigned char customization;
76 unsigned char external_amp;
77 unsigned int enable_pcbeep:1;
78 unsigned int platform_type:1;
79 unsigned int swap:1;
80 unsigned int override:1;
David Henningsson90622912010-10-14 14:50:18 +020081 unsigned int fixup:1; /* Means that this sku is set by driver, not read from hw */
Kailang Yangda00c242010-03-19 11:23:45 +010082};
83
Linus Torvalds1da177e2005-04-16 15:20:36 -070084struct alc_spec {
Takashi Iwai08c189f2012-12-19 15:22:24 +010085 struct hda_gen_spec gen; /* must be at head */
Takashi Iwai23d30f22012-05-07 17:17:32 +020086
Linus Torvalds1da177e2005-04-16 15:20:36 -070087 /* codec parameterization */
Takashi Iwaia9111322011-05-02 11:30:18 +020088 const struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
Linus Torvalds1da177e2005-04-16 15:20:36 -070089 unsigned int num_mixers;
Takashi Iwai45bdd1c2009-02-06 16:11:25 +010090 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
Linus Torvalds1da177e2005-04-16 15:20:36 -070091
Kailang Yangda00c242010-03-19 11:23:45 +010092 struct alc_customize_define cdefine;
Takashi Iwai08c189f2012-12-19 15:22:24 +010093 unsigned int parse_flags; /* flag for snd_hda_parse_pin_defcfg() */
94
Takashi Iwai08fb0d02013-01-10 17:33:58 +010095 /* mute LED for HP laptops, see alc269_fixup_mic_mute_hook() */
96 int mute_led_polarity;
97 hda_nid_t mute_led_nid;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +080098 hda_nid_t cap_mute_led_nid;
Takashi Iwai08fb0d02013-01-10 17:33:58 +010099
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +0100100 unsigned int gpio_led; /* used for alc269_fixup_hp_gpio_led() */
Takashi Iwai0f32fd192014-11-19 12:16:14 +0100101 unsigned int gpio_mute_led_mask;
102 unsigned int gpio_mic_led_mask;
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +0100103
David Henningsson73bdd592013-04-15 15:44:14 +0200104 hda_nid_t headset_mic_pin;
105 hda_nid_t headphone_mic_pin;
106 int current_headset_mode;
107 int current_headset_type;
108
Takashi Iwaiae6b8132006-03-03 16:47:17 +0100109 /* hooks */
110 void (*init_hook)(struct hda_codec *codec);
Takashi Iwai83012a72012-08-24 18:38:08 +0200111#ifdef CONFIG_PM
Daniel T Chenc97259d2009-12-27 18:52:08 -0500112 void (*power_hook)(struct hda_codec *codec);
Hector Martinf5de24b2009-12-20 22:51:31 +0100113#endif
Takashi Iwai1c7161532011-04-07 10:37:16 +0200114 void (*shutup)(struct hda_codec *codec);
Takashi Iwai70a09762015-12-15 14:59:58 +0100115 void (*reboot_notify)(struct hda_codec *codec);
Takashi Iwaid922b512011-04-28 12:18:53 +0200116
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200117 int init_amp;
Takashi Iwaid433a672010-09-20 15:11:54 +0200118 int codec_variant; /* flag for other variants */
Kailang Yang97a26572013-11-29 00:35:26 -0500119 unsigned int has_alc5505_dsp:1;
120 unsigned int no_depop_delay:1;
Takashi Iwaie64f14f2009-01-20 18:32:55 +0100121
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200122 /* for PLL fix */
123 hda_nid_t pll_nid;
124 unsigned int pll_coef_idx, pll_coef_bit;
Takashi Iwai1bb7e432011-10-17 16:50:59 +0200125 unsigned int coef0;
David Henningsson33f4acd2015-01-07 15:50:13 +0100126 struct input_dev *kb_dev;
Hui Wangc7b60a82015-12-28 11:35:25 +0800127 u8 alc_mute_keycode_map[1];
Kailang Yangdf694da2005-12-05 19:42:22 +0100128};
129
Takashi Iwai23f0c042009-02-26 13:03:58 +0100130/*
Takashi Iwaif2a227c2014-08-18 13:35:22 +0200131 * COEF access helper functions
132 */
133
134static int alc_read_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
135 unsigned int coef_idx)
136{
137 unsigned int val;
138
139 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, coef_idx);
140 val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PROC_COEF, 0);
141 return val;
142}
143
144#define alc_read_coef_idx(codec, coef_idx) \
145 alc_read_coefex_idx(codec, 0x20, coef_idx)
146
147static void alc_write_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
148 unsigned int coef_idx, unsigned int coef_val)
149{
150 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, coef_idx);
151 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PROC_COEF, coef_val);
152}
153
154#define alc_write_coef_idx(codec, coef_idx, coef_val) \
155 alc_write_coefex_idx(codec, 0x20, coef_idx, coef_val)
156
Takashi Iwai98b24882014-08-18 13:47:50 +0200157static void alc_update_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
158 unsigned int coef_idx, unsigned int mask,
159 unsigned int bits_set)
160{
161 unsigned int val = alc_read_coefex_idx(codec, nid, coef_idx);
162
163 if (val != -1)
164 alc_write_coefex_idx(codec, nid, coef_idx,
165 (val & ~mask) | bits_set);
166}
167
168#define alc_update_coef_idx(codec, coef_idx, mask, bits_set) \
169 alc_update_coefex_idx(codec, 0x20, coef_idx, mask, bits_set)
170
Takashi Iwaif2a227c2014-08-18 13:35:22 +0200171/* a special bypass for COEF 0; read the cached value at the second time */
172static unsigned int alc_get_coef0(struct hda_codec *codec)
173{
174 struct alc_spec *spec = codec->spec;
175
176 if (!spec->coef0)
177 spec->coef0 = alc_read_coef_idx(codec, 0);
178 return spec->coef0;
179}
180
Takashi Iwai54db6c32014-08-18 15:11:19 +0200181/* coef writes/updates batch */
182struct coef_fw {
183 unsigned char nid;
184 unsigned char idx;
185 unsigned short mask;
186 unsigned short val;
187};
188
189#define UPDATE_COEFEX(_nid, _idx, _mask, _val) \
190 { .nid = (_nid), .idx = (_idx), .mask = (_mask), .val = (_val) }
191#define WRITE_COEFEX(_nid, _idx, _val) UPDATE_COEFEX(_nid, _idx, -1, _val)
192#define WRITE_COEF(_idx, _val) WRITE_COEFEX(0x20, _idx, _val)
193#define UPDATE_COEF(_idx, _mask, _val) UPDATE_COEFEX(0x20, _idx, _mask, _val)
194
195static void alc_process_coef_fw(struct hda_codec *codec,
196 const struct coef_fw *fw)
197{
198 for (; fw->nid; fw++) {
199 if (fw->mask == (unsigned short)-1)
200 alc_write_coefex_idx(codec, fw->nid, fw->idx, fw->val);
201 else
202 alc_update_coefex_idx(codec, fw->nid, fw->idx,
203 fw->mask, fw->val);
204 }
205}
206
Takashi Iwaif2a227c2014-08-18 13:35:22 +0200207/*
Takashi Iwai1d045db2011-07-07 18:23:21 +0200208 * Append the given mixer and verb elements for the later use
209 * The mixer array is referred in build_controls(), and init_verbs are
210 * called in init().
Takashi Iwaid88897e2008-10-31 15:01:37 +0100211 */
Takashi Iwaia9111322011-05-02 11:30:18 +0200212static void add_mixer(struct alc_spec *spec, const struct snd_kcontrol_new *mix)
Takashi Iwaid88897e2008-10-31 15:01:37 +0100213{
214 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
215 return;
216 spec->mixers[spec->num_mixers++] = mix;
217}
218
Takashi Iwaid88897e2008-10-31 15:01:37 +0100219/*
Takashi Iwai1d045db2011-07-07 18:23:21 +0200220 * GPIO setup tables, used in initialization
Kailang Yangdf694da2005-12-05 19:42:22 +0100221 */
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200222/* Enable GPIO mask and set output */
Takashi Iwaia9111322011-05-02 11:30:18 +0200223static const struct hda_verb alc_gpio1_init_verbs[] = {
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200224 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
225 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
226 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
227 { }
228};
229
Takashi Iwaia9111322011-05-02 11:30:18 +0200230static const struct hda_verb alc_gpio2_init_verbs[] = {
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200231 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
232 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
233 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
234 { }
235};
236
Takashi Iwaia9111322011-05-02 11:30:18 +0200237static const struct hda_verb alc_gpio3_init_verbs[] = {
Kailang Yangbdd148a2007-05-08 15:19:08 +0200238 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
239 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
240 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
241 { }
242};
243
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200244/*
245 * Fix hardware PLL issue
246 * On some codecs, the analog PLL gating control must be off while
247 * the default value is 1.
248 */
249static void alc_fix_pll(struct hda_codec *codec)
250{
251 struct alc_spec *spec = codec->spec;
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200252
Takashi Iwai98b24882014-08-18 13:47:50 +0200253 if (spec->pll_nid)
254 alc_update_coefex_idx(codec, spec->pll_nid, spec->pll_coef_idx,
255 1 << spec->pll_coef_bit, 0);
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200256}
257
258static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
259 unsigned int coef_idx, unsigned int coef_bit)
260{
261 struct alc_spec *spec = codec->spec;
262 spec->pll_nid = nid;
263 spec->pll_coef_idx = coef_idx;
264 spec->pll_coef_bit = coef_bit;
265 alc_fix_pll(codec);
266}
267
Takashi Iwaicf5a2272012-02-20 16:31:07 +0100268/* update the master volume per volume-knob's unsol event */
Takashi Iwai1a4f69d2014-09-11 15:22:46 +0200269static void alc_update_knob_master(struct hda_codec *codec,
270 struct hda_jack_callback *jack)
Takashi Iwaicf5a2272012-02-20 16:31:07 +0100271{
272 unsigned int val;
273 struct snd_kcontrol *kctl;
274 struct snd_ctl_elem_value *uctl;
275
276 kctl = snd_hda_find_mixer_ctl(codec, "Master Playback Volume");
277 if (!kctl)
278 return;
279 uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
280 if (!uctl)
281 return;
Takashi Iwai2ebab402016-02-09 10:23:52 +0100282 val = snd_hda_codec_read(codec, jack->nid, 0,
Takashi Iwaicf5a2272012-02-20 16:31:07 +0100283 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
284 val &= HDA_AMP_VOLMASK;
285 uctl->value.integer.value[0] = val;
286 uctl->value.integer.value[1] = val;
287 kctl->put(kctl, uctl);
288 kfree(uctl);
289}
290
David Henningsson29adc4b2012-09-25 11:31:00 +0200291static void alc880_unsol_event(struct hda_codec *codec, unsigned int res)
Takashi Iwaif21d78e2012-01-19 12:10:29 +0100292{
David Henningsson29adc4b2012-09-25 11:31:00 +0200293 /* For some reason, the res given from ALC880 is broken.
294 Here we adjust it properly. */
295 snd_hda_jack_unsol_event(codec, res >> 2);
Takashi Iwaif21d78e2012-01-19 12:10:29 +0100296}
297
Kailang Yang394c97f2014-11-12 17:38:08 +0800298/* Change EAPD to verb control */
299static void alc_fill_eapd_coef(struct hda_codec *codec)
300{
301 int coef;
302
303 coef = alc_get_coef0(codec);
304
Takashi Iwai7639a062015-03-03 10:07:24 +0100305 switch (codec->core.vendor_id) {
Kailang Yang394c97f2014-11-12 17:38:08 +0800306 case 0x10ec0262:
307 alc_update_coef_idx(codec, 0x7, 0, 1<<5);
308 break;
309 case 0x10ec0267:
310 case 0x10ec0268:
311 alc_update_coef_idx(codec, 0x7, 0, 1<<13);
312 break;
313 case 0x10ec0269:
314 if ((coef & 0x00f0) == 0x0010)
315 alc_update_coef_idx(codec, 0xd, 0, 1<<14);
316 if ((coef & 0x00f0) == 0x0020)
317 alc_update_coef_idx(codec, 0x4, 1<<15, 0);
318 if ((coef & 0x00f0) == 0x0030)
319 alc_update_coef_idx(codec, 0x10, 1<<9, 0);
320 break;
321 case 0x10ec0280:
322 case 0x10ec0284:
323 case 0x10ec0290:
324 case 0x10ec0292:
325 alc_update_coef_idx(codec, 0x4, 1<<15, 0);
326 break;
Kailang Yang42314302016-02-03 15:03:50 +0800327 case 0x10ec0225:
Takashi Iwai44be77c2017-12-27 08:53:59 +0100328 case 0x10ec0295:
329 case 0x10ec0299:
330 alc_update_coef_idx(codec, 0x67, 0xf000, 0x3000);
331 /* fallthrough */
332 case 0x10ec0215:
Kailang Yang394c97f2014-11-12 17:38:08 +0800333 case 0x10ec0233:
Kailang Yangea04a1d2018-04-25 15:31:52 +0800334 case 0x10ec0235:
Kailang Yang736f20a2017-10-20 15:06:34 +0800335 case 0x10ec0236:
Kailang Yang394c97f2014-11-12 17:38:08 +0800336 case 0x10ec0255:
Kailang Yang4344aec2014-12-17 17:39:05 +0800337 case 0x10ec0256:
Kailang Yangf429e7e2017-12-05 15:38:24 +0800338 case 0x10ec0257:
Kailang Yang394c97f2014-11-12 17:38:08 +0800339 case 0x10ec0282:
340 case 0x10ec0283:
341 case 0x10ec0286:
342 case 0x10ec0288:
Kailang Yang0a6f0602017-06-30 16:00:48 +0800343 case 0x10ec0285:
Kailang Yang506b62c2014-12-18 17:07:44 +0800344 case 0x10ec0298:
Kailang Yang0a6f0602017-06-30 16:00:48 +0800345 case 0x10ec0289:
Kailang Yang394c97f2014-11-12 17:38:08 +0800346 alc_update_coef_idx(codec, 0x10, 1<<9, 0);
347 break;
Kailang Yang3aabf942017-11-08 15:28:33 +0800348 case 0x10ec0275:
349 alc_update_coef_idx(codec, 0xe, 0, 1<<0);
350 break;
Kailang Yang394c97f2014-11-12 17:38:08 +0800351 case 0x10ec0293:
352 alc_update_coef_idx(codec, 0xa, 1<<13, 0);
353 break;
Kailang Yangdcd4f0d2016-05-04 15:50:18 +0800354 case 0x10ec0234:
355 case 0x10ec0274:
356 case 0x10ec0294:
Kailang Yang6fbae352016-05-30 16:44:20 +0800357 case 0x10ec0700:
358 case 0x10ec0701:
359 case 0x10ec0703:
Kailang Yangdcd4f0d2016-05-04 15:50:18 +0800360 alc_update_coef_idx(codec, 0x10, 1<<15, 0);
361 break;
Kailang Yang394c97f2014-11-12 17:38:08 +0800362 case 0x10ec0662:
363 if ((coef & 0x00f0) == 0x0030)
364 alc_update_coef_idx(codec, 0x4, 1<<10, 0); /* EAPD Ctrl */
365 break;
366 case 0x10ec0272:
367 case 0x10ec0273:
368 case 0x10ec0663:
369 case 0x10ec0665:
370 case 0x10ec0670:
371 case 0x10ec0671:
372 case 0x10ec0672:
373 alc_update_coef_idx(codec, 0xd, 0, 1<<14); /* EAPD Ctrl */
374 break;
375 case 0x10ec0668:
376 alc_update_coef_idx(codec, 0x7, 3<<13, 0);
377 break;
378 case 0x10ec0867:
379 alc_update_coef_idx(codec, 0x4, 1<<10, 0);
380 break;
381 case 0x10ec0888:
382 if ((coef & 0x00f0) == 0x0020 || (coef & 0x00f0) == 0x0030)
383 alc_update_coef_idx(codec, 0x7, 1<<5, 0);
384 break;
385 case 0x10ec0892:
386 alc_update_coef_idx(codec, 0x7, 1<<5, 0);
387 break;
388 case 0x10ec0899:
389 case 0x10ec0900:
Kailang Yang65553b12017-07-11 15:15:47 +0800390 case 0x10ec1168:
Kailang Yanga535ad52017-01-16 16:59:26 +0800391 case 0x10ec1220:
Kailang Yang394c97f2014-11-12 17:38:08 +0800392 alc_update_coef_idx(codec, 0x7, 1<<1, 0);
393 break;
394 }
395}
396
Kailang Yangf9423e72008-05-27 12:32:25 +0200397/* additional initialization for ALC888 variants */
398static void alc888_coef_init(struct hda_codec *codec)
399{
Kailang Yang1df88742014-10-29 16:10:13 +0800400 switch (alc_get_coef0(codec) & 0x00f0) {
401 /* alc888-VA */
402 case 0x00:
403 /* alc888-VB */
404 case 0x10:
405 alc_update_coef_idx(codec, 7, 0, 0x2030); /* Turn EAPD to High */
406 break;
407 }
Jaroslav Kysela87a8c372009-07-23 10:58:29 +0200408}
409
Takashi Iwai3fb4a502010-01-19 15:46:37 +0100410/* turn on/off EAPD control (only if available) */
411static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
412{
413 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
414 return;
415 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
416 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
417 on ? 2 : 0);
418}
419
Takashi Iwai691f1fc2011-04-07 10:31:43 +0200420/* turn on/off EAPD controls of the codec */
421static void alc_auto_setup_eapd(struct hda_codec *codec, bool on)
422{
423 /* We currently only handle front, HP */
Takashi Iwai39fa84e2011-06-27 15:28:57 +0200424 static hda_nid_t pins[] = {
Hui Wangaf95b412015-03-26 17:14:55 +0800425 0x0f, 0x10, 0x14, 0x15, 0x17, 0
Takashi Iwai39fa84e2011-06-27 15:28:57 +0200426 };
427 hda_nid_t *p;
428 for (p = pins; *p; p++)
429 set_eapd(codec, *p, on);
Takashi Iwai691f1fc2011-04-07 10:31:43 +0200430}
431
Takashi Iwai1c7161532011-04-07 10:37:16 +0200432/* generic shutup callback;
Lars-Peter Clausen4ce8e6a2016-11-08 15:48:06 +0100433 * just turning off EAPD and a little pause for avoiding pop-noise
Takashi Iwai1c7161532011-04-07 10:37:16 +0200434 */
435static void alc_eapd_shutup(struct hda_codec *codec)
436{
Kailang Yang97a26572013-11-29 00:35:26 -0500437 struct alc_spec *spec = codec->spec;
438
Takashi Iwai1c7161532011-04-07 10:37:16 +0200439 alc_auto_setup_eapd(codec, false);
Kailang Yang97a26572013-11-29 00:35:26 -0500440 if (!spec->no_depop_delay)
441 msleep(200);
Takashi Iwai9bfb2842013-07-24 14:31:50 +0200442 snd_hda_shutup_pins(codec);
Takashi Iwai1c7161532011-04-07 10:37:16 +0200443}
444
Takashi Iwai1d045db2011-07-07 18:23:21 +0200445/* generic EAPD initialization */
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200446static void alc_auto_init_amp(struct hda_codec *codec, int type)
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200447{
Kailang Yang394c97f2014-11-12 17:38:08 +0800448 alc_fill_eapd_coef(codec);
Takashi Iwai39fa84e2011-06-27 15:28:57 +0200449 alc_auto_setup_eapd(codec, true);
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200450 switch (type) {
451 case ALC_INIT_GPIO1:
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200452 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
453 break;
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200454 case ALC_INIT_GPIO2:
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200455 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
456 break;
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200457 case ALC_INIT_GPIO3:
Kailang Yangbdd148a2007-05-08 15:19:08 +0200458 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
459 break;
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200460 case ALC_INIT_DEFAULT:
Takashi Iwai7639a062015-03-03 10:07:24 +0100461 switch (codec->core.vendor_id) {
Kailang Yangc9b58002007-10-16 14:30:01 +0200462 case 0x10ec0260:
Takashi Iwai98b24882014-08-18 13:47:50 +0200463 alc_update_coefex_idx(codec, 0x1a, 7, 0, 0x2010);
Kailang Yangc9b58002007-10-16 14:30:01 +0200464 break;
Kailang Yangc9b58002007-10-16 14:30:01 +0200465 case 0x10ec0880:
466 case 0x10ec0882:
467 case 0x10ec0883:
468 case 0x10ec0885:
Kailang Yang1df88742014-10-29 16:10:13 +0800469 alc_update_coef_idx(codec, 7, 0, 0x2030);
Kailang Yangc9b58002007-10-16 14:30:01 +0200470 break;
Kailang Yangf9423e72008-05-27 12:32:25 +0200471 case 0x10ec0888:
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200472 alc888_coef_init(codec);
Kailang Yangf9423e72008-05-27 12:32:25 +0200473 break;
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200474 }
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200475 break;
476 }
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200477}
Kailang Yangea1fb292008-08-26 12:58:38 +0200478
Takashi Iwai1d045db2011-07-07 18:23:21 +0200479
480/*
481 * Realtek SSID verification
482 */
483
David Henningsson90622912010-10-14 14:50:18 +0200484/* Could be any non-zero and even value. When used as fixup, tells
485 * the driver to ignore any present sku defines.
486 */
487#define ALC_FIXUP_SKU_IGNORE (2)
488
Takashi Iwai23d30f22012-05-07 17:17:32 +0200489static void alc_fixup_sku_ignore(struct hda_codec *codec,
490 const struct hda_fixup *fix, int action)
491{
492 struct alc_spec *spec = codec->spec;
493 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
494 spec->cdefine.fixup = 1;
495 spec->cdefine.sku_cfg = ALC_FIXUP_SKU_IGNORE;
496 }
497}
498
Mengdong Linb5c66112013-11-29 00:35:35 -0500499static void alc_fixup_no_depop_delay(struct hda_codec *codec,
500 const struct hda_fixup *fix, int action)
501{
502 struct alc_spec *spec = codec->spec;
503
Mengdong Lin84d2dc32013-12-02 22:26:03 -0500504 if (action == HDA_FIXUP_ACT_PROBE) {
Mengdong Linb5c66112013-11-29 00:35:35 -0500505 spec->no_depop_delay = 1;
Mengdong Lin84d2dc32013-12-02 22:26:03 -0500506 codec->depop_delay = 0;
507 }
Mengdong Linb5c66112013-11-29 00:35:35 -0500508}
509
Kailang Yangda00c242010-03-19 11:23:45 +0100510static int alc_auto_parse_customize_define(struct hda_codec *codec)
511{
512 unsigned int ass, tmp, i;
Takashi Iwai7fb56222010-03-22 17:09:47 +0100513 unsigned nid = 0;
Kailang Yangda00c242010-03-19 11:23:45 +0100514 struct alc_spec *spec = codec->spec;
515
Takashi Iwaib6cbe512010-07-28 17:43:36 +0200516 spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
517
David Henningsson90622912010-10-14 14:50:18 +0200518 if (spec->cdefine.fixup) {
519 ass = spec->cdefine.sku_cfg;
520 if (ass == ALC_FIXUP_SKU_IGNORE)
521 return -1;
522 goto do_sku;
523 }
524
Takashi Iwai5100cd02014-02-15 10:03:19 +0100525 if (!codec->bus->pci)
526 return -1;
Takashi Iwai7639a062015-03-03 10:07:24 +0100527 ass = codec->core.subsystem_id & 0xffff;
Takashi Iwaib6cbe512010-07-28 17:43:36 +0200528 if (ass != codec->bus->pci->subsystem_device && (ass & 1))
Kailang Yangda00c242010-03-19 11:23:45 +0100529 goto do_sku;
530
531 nid = 0x1d;
Takashi Iwai7639a062015-03-03 10:07:24 +0100532 if (codec->core.vendor_id == 0x10ec0260)
Kailang Yangda00c242010-03-19 11:23:45 +0100533 nid = 0x17;
534 ass = snd_hda_codec_get_pincfg(codec, nid);
535
536 if (!(ass & 1)) {
Takashi Iwai4e76a882014-02-25 12:21:03 +0100537 codec_info(codec, "%s: SKU not ready 0x%08x\n",
Takashi Iwai7639a062015-03-03 10:07:24 +0100538 codec->core.chip_name, ass);
Kailang Yangda00c242010-03-19 11:23:45 +0100539 return -1;
540 }
541
542 /* check sum */
543 tmp = 0;
544 for (i = 1; i < 16; i++) {
545 if ((ass >> i) & 1)
546 tmp++;
547 }
548 if (((ass >> 16) & 0xf) != tmp)
549 return -1;
550
551 spec->cdefine.port_connectivity = ass >> 30;
552 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
553 spec->cdefine.check_sum = (ass >> 16) & 0xf;
554 spec->cdefine.customization = ass >> 8;
555do_sku:
556 spec->cdefine.sku_cfg = ass;
557 spec->cdefine.external_amp = (ass & 0x38) >> 3;
558 spec->cdefine.platform_type = (ass & 0x4) >> 2;
559 spec->cdefine.swap = (ass & 0x2) >> 1;
560 spec->cdefine.override = ass & 0x1;
561
Takashi Iwai4e76a882014-02-25 12:21:03 +0100562 codec_dbg(codec, "SKU: Nid=0x%x sku_cfg=0x%08x\n",
Kailang Yangda00c242010-03-19 11:23:45 +0100563 nid, spec->cdefine.sku_cfg);
Takashi Iwai4e76a882014-02-25 12:21:03 +0100564 codec_dbg(codec, "SKU: port_connectivity=0x%x\n",
Kailang Yangda00c242010-03-19 11:23:45 +0100565 spec->cdefine.port_connectivity);
Takashi Iwai4e76a882014-02-25 12:21:03 +0100566 codec_dbg(codec, "SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
567 codec_dbg(codec, "SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
568 codec_dbg(codec, "SKU: customization=0x%08x\n", spec->cdefine.customization);
569 codec_dbg(codec, "SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
570 codec_dbg(codec, "SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
571 codec_dbg(codec, "SKU: swap=0x%x\n", spec->cdefine.swap);
572 codec_dbg(codec, "SKU: override=0x%x\n", spec->cdefine.override);
Kailang Yangda00c242010-03-19 11:23:45 +0100573
574 return 0;
575}
576
Takashi Iwai08c189f2012-12-19 15:22:24 +0100577/* return the position of NID in the list, or -1 if not found */
578static int find_idx_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
579{
580 int i;
581 for (i = 0; i < nums; i++)
582 if (list[i] == nid)
583 return i;
584 return -1;
585}
Takashi Iwai1d045db2011-07-07 18:23:21 +0200586/* return true if the given NID is found in the list */
Takashi Iwai3af9ee62011-06-27 12:34:01 +0200587static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
588{
Takashi Iwai21268962011-07-07 15:01:13 +0200589 return find_idx_in_nid_list(nid, list, nums) >= 0;
Takashi Iwai3af9ee62011-06-27 12:34:01 +0200590}
591
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200592/* check subsystem ID and set up device-specific initialization;
593 * return 1 if initialized, 0 if invalid SSID
594 */
595/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
596 * 31 ~ 16 : Manufacture ID
597 * 15 ~ 8 : SKU ID
598 * 7 ~ 0 : Assembly ID
599 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
600 */
Takashi Iwai58c57cf2014-01-07 18:22:49 +0100601static int alc_subsystem_id(struct hda_codec *codec, const hda_nid_t *ports)
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200602{
603 unsigned int ass, tmp, i;
604 unsigned nid;
605 struct alc_spec *spec = codec->spec;
606
David Henningsson90622912010-10-14 14:50:18 +0200607 if (spec->cdefine.fixup) {
608 ass = spec->cdefine.sku_cfg;
609 if (ass == ALC_FIXUP_SKU_IGNORE)
610 return 0;
611 goto do_sku;
612 }
613
Takashi Iwai7639a062015-03-03 10:07:24 +0100614 ass = codec->core.subsystem_id & 0xffff;
Takashi Iwai5100cd02014-02-15 10:03:19 +0100615 if (codec->bus->pci &&
616 ass != codec->bus->pci->subsystem_device && (ass & 1))
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200617 goto do_sku;
618
619 /* invalid SSID, check the special NID pin defcfg instead */
620 /*
Sasha Alexandrdef319f2009-06-16 16:00:15 -0400621 * 31~30 : port connectivity
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200622 * 29~21 : reserve
623 * 20 : PCBEEP input
624 * 19~16 : Check sum (15:1)
625 * 15~1 : Custom
626 * 0 : override
627 */
628 nid = 0x1d;
Takashi Iwai7639a062015-03-03 10:07:24 +0100629 if (codec->core.vendor_id == 0x10ec0260)
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200630 nid = 0x17;
631 ass = snd_hda_codec_get_pincfg(codec, nid);
Takashi Iwai4e76a882014-02-25 12:21:03 +0100632 codec_dbg(codec,
633 "realtek: No valid SSID, checking pincfg 0x%08x for NID 0x%x\n",
Takashi Iwaicb6605c2009-04-28 13:03:19 +0200634 ass, nid);
Kailang Yang6227cdc2010-02-25 08:36:52 +0100635 if (!(ass & 1))
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200636 return 0;
637 if ((ass >> 30) != 1) /* no physical connection */
638 return 0;
639
640 /* check sum */
641 tmp = 0;
642 for (i = 1; i < 16; i++) {
643 if ((ass >> i) & 1)
644 tmp++;
645 }
646 if (((ass >> 16) & 0xf) != tmp)
647 return 0;
648do_sku:
Takashi Iwai4e76a882014-02-25 12:21:03 +0100649 codec_dbg(codec, "realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
Takashi Iwai7639a062015-03-03 10:07:24 +0100650 ass & 0xffff, codec->core.vendor_id);
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200651 /*
652 * 0 : override
653 * 1 : Swap Jack
654 * 2 : 0 --> Desktop, 1 --> Laptop
655 * 3~5 : External Amplifier control
656 * 7~6 : Reserved
657 */
658 tmp = (ass & 0x38) >> 3; /* external Amp control */
659 switch (tmp) {
660 case 1:
661 spec->init_amp = ALC_INIT_GPIO1;
662 break;
663 case 3:
664 spec->init_amp = ALC_INIT_GPIO2;
665 break;
666 case 7:
667 spec->init_amp = ALC_INIT_GPIO3;
668 break;
669 case 5:
Takashi Iwai5a8cfb42010-11-26 17:11:18 +0100670 default:
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200671 spec->init_amp = ALC_INIT_DEFAULT;
672 break;
673 }
674
675 /* is laptop or Desktop and enable the function "Mute internal speaker
676 * when the external headphone out jack is plugged"
677 */
678 if (!(ass & 0x8000))
679 return 1;
680 /*
681 * 10~8 : Jack location
682 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
683 * 14~13: Resvered
684 * 15 : 1 --> enable the function "Mute internal speaker
685 * when the external headphone out jack is plugged"
686 */
Takashi Iwai08c189f2012-12-19 15:22:24 +0100687 if (!spec->gen.autocfg.hp_pins[0] &&
688 !(spec->gen.autocfg.line_out_pins[0] &&
689 spec->gen.autocfg.line_out_type == AUTO_PIN_HP_OUT)) {
Takashi Iwai01d48252009-10-06 13:21:54 +0200690 hda_nid_t nid;
Kailang Yangc9b58002007-10-16 14:30:01 +0200691 tmp = (ass >> 11) & 0x3; /* HP to chassis */
Takashi Iwai58c57cf2014-01-07 18:22:49 +0100692 nid = ports[tmp];
Takashi Iwai08c189f2012-12-19 15:22:24 +0100693 if (found_in_nid_list(nid, spec->gen.autocfg.line_out_pins,
694 spec->gen.autocfg.line_outs))
Takashi Iwai3af9ee62011-06-27 12:34:01 +0200695 return 1;
Takashi Iwai08c189f2012-12-19 15:22:24 +0100696 spec->gen.autocfg.hp_pins[0] = nid;
Kailang Yangc9b58002007-10-16 14:30:01 +0200697 }
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200698 return 1;
699}
Kailang Yangea1fb292008-08-26 12:58:38 +0200700
Takashi Iwai3e6179b2011-07-08 16:55:13 +0200701/* Check the validity of ALC subsystem-id
702 * ports contains an array of 4 pin NIDs for port-A, E, D and I */
703static void alc_ssid_check(struct hda_codec *codec, const hda_nid_t *ports)
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200704{
Takashi Iwai58c57cf2014-01-07 18:22:49 +0100705 if (!alc_subsystem_id(codec, ports)) {
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200706 struct alc_spec *spec = codec->spec;
Takashi Iwai4e76a882014-02-25 12:21:03 +0100707 codec_dbg(codec,
708 "realtek: Enable default setup for auto mode as fallback\n");
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200709 spec->init_amp = ALC_INIT_DEFAULT;
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200710 }
Takashi Iwai21268962011-07-07 15:01:13 +0200711}
Takashi Iwai1a1455d2011-04-28 17:36:18 +0200712
Takashi Iwai41e41f12005-06-08 14:48:49 +0200713/*
Takashi Iwai1d045db2011-07-07 18:23:21 +0200714 */
715
David Henningsson9d36a7d2014-10-07 10:18:42 +0200716static void alc_fixup_inv_dmic(struct hda_codec *codec,
717 const struct hda_fixup *fix, int action)
Takashi Iwai125821a2012-06-22 14:30:29 +0200718{
719 struct alc_spec *spec = codec->spec;
Takashi Iwai668d1e92012-11-29 14:10:17 +0100720
David Henningsson9d36a7d2014-10-07 10:18:42 +0200721 spec->gen.inv_dmic_split = 1;
Takashi Iwai6e72aa52012-06-25 10:52:25 +0200722}
723
Takashi Iwai603c4012008-07-30 15:01:44 +0200724
Takashi Iwai67d634c2009-11-16 15:35:59 +0100725#ifdef CONFIG_SND_HDA_INPUT_BEEP
Takashi Iwai45bdd1c2009-02-06 16:11:25 +0100726/* additional beep mixers; the actual parameters are overwritten at build */
Takashi Iwaia9111322011-05-02 11:30:18 +0200727static const struct snd_kcontrol_new alc_beep_mixer[] = {
Takashi Iwai45bdd1c2009-02-06 16:11:25 +0100728 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
Jaroslav Kysela123c07a2009-10-21 14:48:23 +0200729 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
Takashi Iwai45bdd1c2009-02-06 16:11:25 +0100730 { } /* end */
731};
Takashi Iwai67d634c2009-11-16 15:35:59 +0100732#endif
Takashi Iwai45bdd1c2009-02-06 16:11:25 +0100733
Takashi Iwai2eab6942012-12-18 15:30:41 +0100734static int alc_build_controls(struct hda_codec *codec)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700735{
736 struct alc_spec *spec = codec->spec;
Takashi Iwai666a70d2012-12-17 20:29:29 +0100737 int i, err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700738
Takashi Iwai08c189f2012-12-19 15:22:24 +0100739 err = snd_hda_gen_build_controls(codec);
740 if (err < 0)
741 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700742
743 for (i = 0; i < spec->num_mixers; i++) {
744 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
745 if (err < 0)
746 return err;
747 }
Takashi Iwai2134ea42008-01-10 16:53:55 +0100748
Takashi Iwai67d634c2009-11-16 15:35:59 +0100749#ifdef CONFIG_SND_HDA_INPUT_BEEP
Takashi Iwai45bdd1c2009-02-06 16:11:25 +0100750 /* create beep controls if needed */
751 if (spec->beep_amp) {
Takashi Iwaia9111322011-05-02 11:30:18 +0200752 const struct snd_kcontrol_new *knew;
Takashi Iwai45bdd1c2009-02-06 16:11:25 +0100753 for (knew = alc_beep_mixer; knew->name; knew++) {
754 struct snd_kcontrol *kctl;
755 kctl = snd_ctl_new1(knew, codec);
756 if (!kctl)
757 return -ENOMEM;
758 kctl->private_value = spec->beep_amp;
Jaroslav Kysela5e26dfd2009-12-10 13:57:01 +0100759 err = snd_hda_ctl_add(codec, 0, kctl);
Takashi Iwai45bdd1c2009-02-06 16:11:25 +0100760 if (err < 0)
761 return err;
762 }
763 }
Takashi Iwai67d634c2009-11-16 15:35:59 +0100764#endif
Takashi Iwai45bdd1c2009-02-06 16:11:25 +0100765
Takashi Iwai1727a772013-01-10 09:52:52 +0100766 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_BUILD);
Takashi Iwai420b0fe2012-03-12 12:35:27 +0100767 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700768}
769
Takashi Iwaie9edcee2005-06-13 14:16:38 +0200770
Linus Torvalds1da177e2005-04-16 15:20:36 -0700771/*
Takashi Iwaiae6b8132006-03-03 16:47:17 +0100772 * Common callbacks
Takashi Iwaie9edcee2005-06-13 14:16:38 +0200773 */
Takashi Iwai16ded522005-06-10 19:58:24 +0200774
Linus Torvalds1da177e2005-04-16 15:20:36 -0700775static int alc_init(struct hda_codec *codec)
776{
777 struct alc_spec *spec = codec->spec;
Takashi Iwaie9edcee2005-06-13 14:16:38 +0200778
Takashi Iwai546bb672012-03-07 08:37:19 +0100779 if (spec->init_hook)
780 spec->init_hook(codec);
Kailang Yang526af6e2012-03-07 08:25:20 +0100781
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200782 alc_fix_pll(codec);
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200783 alc_auto_init_amp(codec, spec->init_amp);
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200784
Takashi Iwai08c189f2012-12-19 15:22:24 +0100785 snd_hda_gen_init(codec);
Takashi Iwaiae6b8132006-03-03 16:47:17 +0100786
Takashi Iwai1727a772013-01-10 09:52:52 +0100787 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_INIT);
Takashi Iwaie08a0072006-09-07 17:52:14 +0200788
Linus Torvalds1da177e2005-04-16 15:20:36 -0700789 return 0;
790}
791
Takashi Iwaia4e09aa2009-12-27 11:22:24 +0100792static inline void alc_shutup(struct hda_codec *codec)
793{
Takashi Iwai1c7161532011-04-07 10:37:16 +0200794 struct alc_spec *spec = codec->spec;
795
796 if (spec && spec->shutup)
797 spec->shutup(codec);
Takashi Iwai9bfb2842013-07-24 14:31:50 +0200798 else
799 snd_hda_shutup_pins(codec);
Takashi Iwaia4e09aa2009-12-27 11:22:24 +0100800}
801
Takashi Iwai70a09762015-12-15 14:59:58 +0100802static void alc_reboot_notify(struct hda_codec *codec)
803{
804 struct alc_spec *spec = codec->spec;
805
806 if (spec && spec->reboot_notify)
807 spec->reboot_notify(codec);
808 else
809 alc_shutup(codec);
810}
811
812/* power down codec to D3 at reboot/shutdown; set as reboot_notify ops */
813static void alc_d3_at_reboot(struct hda_codec *codec)
814{
815 snd_hda_codec_set_power_to_all(codec, codec->core.afg, AC_PWRST_D3);
816 snd_hda_codec_write(codec, codec->core.afg, 0,
817 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
818 msleep(10);
819}
820
Takashi Iwai8a02c0c2014-02-10 18:09:45 +0100821#define alc_free snd_hda_gen_free
Linus Torvalds1da177e2005-04-16 15:20:36 -0700822
Takashi Iwai83012a72012-08-24 18:38:08 +0200823#ifdef CONFIG_PM
Daniel T Chenc97259d2009-12-27 18:52:08 -0500824static void alc_power_eapd(struct hda_codec *codec)
825{
Takashi Iwai691f1fc2011-04-07 10:31:43 +0200826 alc_auto_setup_eapd(codec, false);
Daniel T Chenc97259d2009-12-27 18:52:08 -0500827}
828
Takashi Iwai68cb2b52012-07-02 15:20:37 +0200829static int alc_suspend(struct hda_codec *codec)
Hector Martinf5de24b2009-12-20 22:51:31 +0100830{
831 struct alc_spec *spec = codec->spec;
Takashi Iwaia4e09aa2009-12-27 11:22:24 +0100832 alc_shutup(codec);
Hector Martinf5de24b2009-12-20 22:51:31 +0100833 if (spec && spec->power_hook)
Daniel T Chenc97259d2009-12-27 18:52:08 -0500834 spec->power_hook(codec);
Hector Martinf5de24b2009-12-20 22:51:31 +0100835 return 0;
836}
837#endif
838
Takashi Iwai2a439522011-07-26 09:52:50 +0200839#ifdef CONFIG_PM
Takashi Iwaie044c392008-10-27 16:56:24 +0100840static int alc_resume(struct hda_codec *codec)
841{
Kailang Yang97a26572013-11-29 00:35:26 -0500842 struct alc_spec *spec = codec->spec;
843
844 if (!spec->no_depop_delay)
845 msleep(150); /* to avoid pop noise */
Takashi Iwaie044c392008-10-27 16:56:24 +0100846 codec->patch_ops.init(codec);
Takashi Iwaieeecd9d2015-02-25 15:18:50 +0100847 regcache_sync(codec->core.regmap);
Takashi Iwai9e5341b2010-09-21 09:57:06 +0200848 hda_call_check_power_status(codec, 0x01);
Takashi Iwaie044c392008-10-27 16:56:24 +0100849 return 0;
850}
Takashi Iwaie044c392008-10-27 16:56:24 +0100851#endif
852
Linus Torvalds1da177e2005-04-16 15:20:36 -0700853/*
854 */
Takashi Iwaia9111322011-05-02 11:30:18 +0200855static const struct hda_codec_ops alc_patch_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700856 .build_controls = alc_build_controls,
Takashi Iwai08c189f2012-12-19 15:22:24 +0100857 .build_pcms = snd_hda_gen_build_pcms,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700858 .init = alc_init,
859 .free = alc_free,
David Henningsson29adc4b2012-09-25 11:31:00 +0200860 .unsol_event = snd_hda_jack_unsol_event,
Takashi Iwai2a439522011-07-26 09:52:50 +0200861#ifdef CONFIG_PM
Takashi Iwaie044c392008-10-27 16:56:24 +0100862 .resume = alc_resume,
Hector Martinf5de24b2009-12-20 22:51:31 +0100863 .suspend = alc_suspend,
Takashi Iwaifce52a32013-01-07 12:42:48 +0100864 .check_power_status = snd_hda_gen_check_power_status,
Takashi Iwaicb53c622007-08-10 17:21:45 +0200865#endif
Takashi Iwai70a09762015-12-15 14:59:58 +0100866 .reboot_notify = alc_reboot_notify,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700867};
868
David Henningsson29adc4b2012-09-25 11:31:00 +0200869
Takashi Iwaided255b2015-10-01 17:59:43 +0200870#define alc_codec_rename(codec, name) snd_hda_codec_set_name(codec, name)
Kailang Yangc027ddc2010-03-19 11:33:06 +0100871
Takashi Iwai2fa522b2005-05-12 14:51:12 +0200872/*
Kailang Yang4b016932013-11-28 11:55:09 +0100873 * Rename codecs appropriately from COEF value or subvendor id
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200874 */
875struct alc_codec_rename_table {
876 unsigned int vendor_id;
877 unsigned short coef_mask;
878 unsigned short coef_bits;
879 const char *name;
880};
881
Kailang Yang4b016932013-11-28 11:55:09 +0100882struct alc_codec_rename_pci_table {
883 unsigned int codec_vendor_id;
884 unsigned short pci_subvendor;
885 unsigned short pci_subdevice;
886 const char *name;
887};
888
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200889static struct alc_codec_rename_table rename_tbl[] = {
Kailang Yange6e5f7a2014-06-06 16:46:43 +0800890 { 0x10ec0221, 0xf00f, 0x1003, "ALC231" },
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200891 { 0x10ec0269, 0xfff0, 0x3010, "ALC277" },
892 { 0x10ec0269, 0xf0f0, 0x2010, "ALC259" },
893 { 0x10ec0269, 0xf0f0, 0x3010, "ALC258" },
894 { 0x10ec0269, 0x00f0, 0x0010, "ALC269VB" },
895 { 0x10ec0269, 0xffff, 0xa023, "ALC259" },
896 { 0x10ec0269, 0xffff, 0x6023, "ALC281X" },
897 { 0x10ec0269, 0x00f0, 0x0020, "ALC269VC" },
Kailang Yangadcc70b2012-05-25 08:08:38 +0200898 { 0x10ec0269, 0x00f0, 0x0030, "ALC269VD" },
Kailang Yange6e5f7a2014-06-06 16:46:43 +0800899 { 0x10ec0662, 0xffff, 0x4020, "ALC656" },
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200900 { 0x10ec0887, 0x00f0, 0x0030, "ALC887-VD" },
901 { 0x10ec0888, 0x00f0, 0x0030, "ALC888-VD" },
902 { 0x10ec0888, 0xf0f0, 0x3020, "ALC886" },
903 { 0x10ec0899, 0x2000, 0x2000, "ALC899" },
904 { 0x10ec0892, 0xffff, 0x8020, "ALC661" },
905 { 0x10ec0892, 0xffff, 0x8011, "ALC661" },
906 { 0x10ec0892, 0xffff, 0x4011, "ALC656" },
907 { } /* terminator */
908};
909
Kailang Yang4b016932013-11-28 11:55:09 +0100910static struct alc_codec_rename_pci_table rename_pci_tbl[] = {
911 { 0x10ec0280, 0x1028, 0, "ALC3220" },
912 { 0x10ec0282, 0x1028, 0, "ALC3221" },
913 { 0x10ec0283, 0x1028, 0, "ALC3223" },
Kailang Yang193177d2014-04-23 16:06:13 +0800914 { 0x10ec0288, 0x1028, 0, "ALC3263" },
Kailang Yang4b016932013-11-28 11:55:09 +0100915 { 0x10ec0292, 0x1028, 0, "ALC3226" },
Kailang Yang193177d2014-04-23 16:06:13 +0800916 { 0x10ec0293, 0x1028, 0, "ALC3235" },
Kailang Yang4b016932013-11-28 11:55:09 +0100917 { 0x10ec0255, 0x1028, 0, "ALC3234" },
918 { 0x10ec0668, 0x1028, 0, "ALC3661" },
Kailang Yange6e5f7a2014-06-06 16:46:43 +0800919 { 0x10ec0275, 0x1028, 0, "ALC3260" },
920 { 0x10ec0899, 0x1028, 0, "ALC3861" },
Kailang Yang2c674fa2015-05-05 15:02:42 +0800921 { 0x10ec0298, 0x1028, 0, "ALC3266" },
Kailang Yang736f20a2017-10-20 15:06:34 +0800922 { 0x10ec0236, 0x1028, 0, "ALC3204" },
Kailang Yang82324502015-05-25 17:16:49 +0800923 { 0x10ec0256, 0x1028, 0, "ALC3246" },
Kailang Yang42314302016-02-03 15:03:50 +0800924 { 0x10ec0225, 0x1028, 0, "ALC3253" },
Kailang Yang7d727862016-05-24 16:46:07 +0800925 { 0x10ec0295, 0x1028, 0, "ALC3254" },
Kailang Yang28f1f9b2017-01-04 14:49:07 +0800926 { 0x10ec0299, 0x1028, 0, "ALC3271" },
Kailang Yange6e5f7a2014-06-06 16:46:43 +0800927 { 0x10ec0670, 0x1025, 0, "ALC669X" },
928 { 0x10ec0676, 0x1025, 0, "ALC679X" },
929 { 0x10ec0282, 0x1043, 0, "ALC3229" },
930 { 0x10ec0233, 0x1043, 0, "ALC3236" },
931 { 0x10ec0280, 0x103c, 0, "ALC3228" },
932 { 0x10ec0282, 0x103c, 0, "ALC3227" },
933 { 0x10ec0286, 0x103c, 0, "ALC3242" },
934 { 0x10ec0290, 0x103c, 0, "ALC3241" },
935 { 0x10ec0668, 0x103c, 0, "ALC3662" },
936 { 0x10ec0283, 0x17aa, 0, "ALC3239" },
937 { 0x10ec0292, 0x17aa, 0, "ALC3232" },
Kailang Yang4b016932013-11-28 11:55:09 +0100938 { } /* terminator */
939};
940
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200941static int alc_codec_rename_from_preset(struct hda_codec *codec)
942{
943 const struct alc_codec_rename_table *p;
Kailang Yang4b016932013-11-28 11:55:09 +0100944 const struct alc_codec_rename_pci_table *q;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200945
946 for (p = rename_tbl; p->vendor_id; p++) {
Takashi Iwai7639a062015-03-03 10:07:24 +0100947 if (p->vendor_id != codec->core.vendor_id)
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200948 continue;
Takashi Iwai1bb7e432011-10-17 16:50:59 +0200949 if ((alc_get_coef0(codec) & p->coef_mask) == p->coef_bits)
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200950 return alc_codec_rename(codec, p->name);
951 }
Kailang Yang4b016932013-11-28 11:55:09 +0100952
Takashi Iwai5100cd02014-02-15 10:03:19 +0100953 if (!codec->bus->pci)
954 return 0;
Kailang Yang4b016932013-11-28 11:55:09 +0100955 for (q = rename_pci_tbl; q->codec_vendor_id; q++) {
Takashi Iwai7639a062015-03-03 10:07:24 +0100956 if (q->codec_vendor_id != codec->core.vendor_id)
Kailang Yang4b016932013-11-28 11:55:09 +0100957 continue;
958 if (q->pci_subvendor != codec->bus->pci->subsystem_vendor)
959 continue;
960 if (!q->pci_subdevice ||
961 q->pci_subdevice == codec->bus->pci->subsystem_device)
962 return alc_codec_rename(codec, q->name);
963 }
964
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200965 return 0;
966}
967
Takashi Iwaie4770622011-07-08 11:11:35 +0200968
969/*
Takashi Iwai1d045db2011-07-07 18:23:21 +0200970 * Digital-beep handlers
971 */
972#ifdef CONFIG_SND_HDA_INPUT_BEEP
973#define set_beep_amp(spec, nid, idx, dir) \
974 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
975
976static const struct snd_pci_quirk beep_white_list[] = {
Duncan Roe71100052012-10-10 14:19:50 +0200977 SND_PCI_QUIRK(0x1043, 0x103c, "ASUS", 1),
W. Trevor Kinga4b7f21d2014-03-29 17:47:24 -0700978 SND_PCI_QUIRK(0x1043, 0x115d, "ASUS", 1),
Takashi Iwai1d045db2011-07-07 18:23:21 +0200979 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
Takashi Iwai8554ee42013-02-25 09:54:43 +0100980 SND_PCI_QUIRK(0x1043, 0x8376, "EeePC", 1),
Takashi Iwai1d045db2011-07-07 18:23:21 +0200981 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
982 SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1),
983 SND_PCI_QUIRK(0x1043, 0x834a, "EeePC", 1),
Takashi Iwai78f8baf2012-03-06 14:02:32 +0100984 SND_PCI_QUIRK(0x1458, 0xa002, "GA-MA790X", 1),
Takashi Iwai1d045db2011-07-07 18:23:21 +0200985 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
986 {}
987};
988
989static inline int has_cdefine_beep(struct hda_codec *codec)
990{
991 struct alc_spec *spec = codec->spec;
992 const struct snd_pci_quirk *q;
993 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
994 if (q)
995 return q->value;
996 return spec->cdefine.enable_pcbeep;
997}
998#else
999#define set_beep_amp(spec, nid, idx, dir) /* NOP */
1000#define has_cdefine_beep(codec) 0
1001#endif
1002
1003/* parse the BIOS configuration and set up the alc_spec */
1004/* return 1 if successful, 0 if the proper config is not found,
1005 * or a negative error code
1006 */
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001007static int alc_parse_auto_config(struct hda_codec *codec,
1008 const hda_nid_t *ignore_nids,
1009 const hda_nid_t *ssid_nids)
Takashi Iwai1d045db2011-07-07 18:23:21 +02001010{
1011 struct alc_spec *spec = codec->spec;
Takashi Iwai08c189f2012-12-19 15:22:24 +01001012 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001013 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001014
Takashi Iwai53c334a2011-08-23 18:27:14 +02001015 err = snd_hda_parse_pin_defcfg(codec, cfg, ignore_nids,
1016 spec->parse_flags);
Takashi Iwai1d045db2011-07-07 18:23:21 +02001017 if (err < 0)
1018 return err;
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001019
1020 if (ssid_nids)
1021 alc_ssid_check(codec, ssid_nids);
1022
Takashi Iwai08c189f2012-12-19 15:22:24 +01001023 err = snd_hda_gen_parse_auto_config(codec, cfg);
1024 if (err < 0)
1025 return err;
Takashi Iwai070cff42012-02-21 12:54:17 +01001026
Takashi Iwai1d045db2011-07-07 18:23:21 +02001027 return 1;
1028}
1029
Takashi Iwai3de95172012-05-07 18:03:15 +02001030/* common preparation job for alc_spec */
1031static int alc_alloc_spec(struct hda_codec *codec, hda_nid_t mixer_nid)
1032{
1033 struct alc_spec *spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1034 int err;
1035
1036 if (!spec)
1037 return -ENOMEM;
1038 codec->spec = spec;
Takashi Iwai08c189f2012-12-19 15:22:24 +01001039 snd_hda_gen_spec_init(&spec->gen);
1040 spec->gen.mixer_nid = mixer_nid;
1041 spec->gen.own_eapd_ctl = 1;
Takashi Iwai1098b7c2012-12-17 20:03:15 +01001042 codec->single_adc_amp = 1;
Takashi Iwai08c189f2012-12-19 15:22:24 +01001043 /* FIXME: do we need this for all Realtek codec models? */
1044 codec->spdif_status_reset = 1;
Takashi Iwai225068a2015-05-29 10:42:14 +02001045 codec->patch_ops = alc_patch_ops;
Takashi Iwai3de95172012-05-07 18:03:15 +02001046
1047 err = alc_codec_rename_from_preset(codec);
1048 if (err < 0) {
1049 kfree(spec);
1050 return err;
1051 }
1052 return 0;
1053}
1054
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001055static int alc880_parse_auto_config(struct hda_codec *codec)
1056{
1057 static const hda_nid_t alc880_ignore[] = { 0x1d, 0 };
Jesper Juhl7d7eb9e2012-04-12 22:11:25 +02001058 static const hda_nid_t alc880_ssids[] = { 0x15, 0x1b, 0x14, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001059 return alc_parse_auto_config(codec, alc880_ignore, alc880_ssids);
1060}
1061
Takashi Iwai1d045db2011-07-07 18:23:21 +02001062/*
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001063 * ALC880 fix-ups
1064 */
1065enum {
Takashi Iwai411225a2012-02-20 17:48:19 +01001066 ALC880_FIXUP_GPIO1,
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001067 ALC880_FIXUP_GPIO2,
1068 ALC880_FIXUP_MEDION_RIM,
Takashi Iwaidc6af522012-02-17 16:18:59 +01001069 ALC880_FIXUP_LG,
Takashi Iwaidb8a38e2013-08-09 12:34:42 +02001070 ALC880_FIXUP_LG_LW25,
Takashi Iwaif02aab52012-02-17 16:33:56 +01001071 ALC880_FIXUP_W810,
Takashi Iwai27e917f2012-02-17 17:49:54 +01001072 ALC880_FIXUP_EAPD_COEF,
Takashi Iwaib9368f52012-02-17 17:54:44 +01001073 ALC880_FIXUP_TCL_S700,
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001074 ALC880_FIXUP_VOL_KNOB,
1075 ALC880_FIXUP_FUJITSU,
Takashi Iwaiba533812012-02-20 16:36:52 +01001076 ALC880_FIXUP_F1734,
Takashi Iwai817de922012-02-20 17:20:48 +01001077 ALC880_FIXUP_UNIWILL,
Takashi Iwai967b88c2012-02-20 17:31:02 +01001078 ALC880_FIXUP_UNIWILL_DIG,
Takashi Iwai96e225f2012-02-20 17:41:51 +01001079 ALC880_FIXUP_Z71V,
Takashi Iwai487a5882013-11-07 07:29:30 +01001080 ALC880_FIXUP_ASUS_W5A,
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001081 ALC880_FIXUP_3ST_BASE,
1082 ALC880_FIXUP_3ST,
1083 ALC880_FIXUP_3ST_DIG,
1084 ALC880_FIXUP_5ST_BASE,
1085 ALC880_FIXUP_5ST,
1086 ALC880_FIXUP_5ST_DIG,
1087 ALC880_FIXUP_6ST_BASE,
1088 ALC880_FIXUP_6ST,
1089 ALC880_FIXUP_6ST_DIG,
Takashi Iwai53971452013-01-23 18:21:37 +01001090 ALC880_FIXUP_6ST_AUTOMUTE,
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001091};
1092
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001093/* enable the volume-knob widget support on NID 0x21 */
1094static void alc880_fixup_vol_knob(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001095 const struct hda_fixup *fix, int action)
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001096{
Takashi Iwai1727a772013-01-10 09:52:52 +01001097 if (action == HDA_FIXUP_ACT_PROBE)
Takashi Iwai62f949b2014-09-11 14:06:53 +02001098 snd_hda_jack_detect_enable_callback(codec, 0x21,
1099 alc_update_knob_master);
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001100}
1101
Takashi Iwai1727a772013-01-10 09:52:52 +01001102static const struct hda_fixup alc880_fixups[] = {
Takashi Iwai411225a2012-02-20 17:48:19 +01001103 [ALC880_FIXUP_GPIO1] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001104 .type = HDA_FIXUP_VERBS,
Takashi Iwai411225a2012-02-20 17:48:19 +01001105 .v.verbs = alc_gpio1_init_verbs,
1106 },
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001107 [ALC880_FIXUP_GPIO2] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001108 .type = HDA_FIXUP_VERBS,
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001109 .v.verbs = alc_gpio2_init_verbs,
1110 },
1111 [ALC880_FIXUP_MEDION_RIM] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001112 .type = HDA_FIXUP_VERBS,
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001113 .v.verbs = (const struct hda_verb[]) {
1114 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
1115 { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
1116 { }
1117 },
1118 .chained = true,
1119 .chain_id = ALC880_FIXUP_GPIO2,
1120 },
Takashi Iwaidc6af522012-02-17 16:18:59 +01001121 [ALC880_FIXUP_LG] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001122 .type = HDA_FIXUP_PINS,
1123 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaidc6af522012-02-17 16:18:59 +01001124 /* disable bogus unused pins */
1125 { 0x16, 0x411111f0 },
1126 { 0x18, 0x411111f0 },
1127 { 0x1a, 0x411111f0 },
1128 { }
1129 }
1130 },
Takashi Iwaidb8a38e2013-08-09 12:34:42 +02001131 [ALC880_FIXUP_LG_LW25] = {
1132 .type = HDA_FIXUP_PINS,
1133 .v.pins = (const struct hda_pintbl[]) {
1134 { 0x1a, 0x0181344f }, /* line-in */
1135 { 0x1b, 0x0321403f }, /* headphone */
1136 { }
1137 }
1138 },
Takashi Iwaif02aab52012-02-17 16:33:56 +01001139 [ALC880_FIXUP_W810] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001140 .type = HDA_FIXUP_PINS,
1141 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaif02aab52012-02-17 16:33:56 +01001142 /* disable bogus unused pins */
1143 { 0x17, 0x411111f0 },
1144 { }
1145 },
1146 .chained = true,
1147 .chain_id = ALC880_FIXUP_GPIO2,
1148 },
Takashi Iwai27e917f2012-02-17 17:49:54 +01001149 [ALC880_FIXUP_EAPD_COEF] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001150 .type = HDA_FIXUP_VERBS,
Takashi Iwai27e917f2012-02-17 17:49:54 +01001151 .v.verbs = (const struct hda_verb[]) {
1152 /* change to EAPD mode */
1153 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
1154 { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
1155 {}
1156 },
1157 },
Takashi Iwaib9368f52012-02-17 17:54:44 +01001158 [ALC880_FIXUP_TCL_S700] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001159 .type = HDA_FIXUP_VERBS,
Takashi Iwaib9368f52012-02-17 17:54:44 +01001160 .v.verbs = (const struct hda_verb[]) {
1161 /* change to EAPD mode */
1162 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
1163 { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
1164 {}
1165 },
1166 .chained = true,
1167 .chain_id = ALC880_FIXUP_GPIO2,
1168 },
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001169 [ALC880_FIXUP_VOL_KNOB] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001170 .type = HDA_FIXUP_FUNC,
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001171 .v.func = alc880_fixup_vol_knob,
1172 },
1173 [ALC880_FIXUP_FUJITSU] = {
1174 /* override all pins as BIOS on old Amilo is broken */
Takashi Iwai1727a772013-01-10 09:52:52 +01001175 .type = HDA_FIXUP_PINS,
1176 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaibb148bd2015-08-13 18:02:39 +02001177 { 0x14, 0x0121401f }, /* HP */
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001178 { 0x15, 0x99030120 }, /* speaker */
1179 { 0x16, 0x99030130 }, /* bass speaker */
1180 { 0x17, 0x411111f0 }, /* N/A */
1181 { 0x18, 0x411111f0 }, /* N/A */
1182 { 0x19, 0x01a19950 }, /* mic-in */
1183 { 0x1a, 0x411111f0 }, /* N/A */
1184 { 0x1b, 0x411111f0 }, /* N/A */
1185 { 0x1c, 0x411111f0 }, /* N/A */
1186 { 0x1d, 0x411111f0 }, /* N/A */
1187 { 0x1e, 0x01454140 }, /* SPDIF out */
1188 { }
1189 },
1190 .chained = true,
1191 .chain_id = ALC880_FIXUP_VOL_KNOB,
1192 },
Takashi Iwaiba533812012-02-20 16:36:52 +01001193 [ALC880_FIXUP_F1734] = {
1194 /* almost compatible with FUJITSU, but no bass and SPDIF */
Takashi Iwai1727a772013-01-10 09:52:52 +01001195 .type = HDA_FIXUP_PINS,
1196 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaibb148bd2015-08-13 18:02:39 +02001197 { 0x14, 0x0121401f }, /* HP */
Takashi Iwaiba533812012-02-20 16:36:52 +01001198 { 0x15, 0x99030120 }, /* speaker */
1199 { 0x16, 0x411111f0 }, /* N/A */
1200 { 0x17, 0x411111f0 }, /* N/A */
1201 { 0x18, 0x411111f0 }, /* N/A */
1202 { 0x19, 0x01a19950 }, /* mic-in */
1203 { 0x1a, 0x411111f0 }, /* N/A */
1204 { 0x1b, 0x411111f0 }, /* N/A */
1205 { 0x1c, 0x411111f0 }, /* N/A */
1206 { 0x1d, 0x411111f0 }, /* N/A */
1207 { 0x1e, 0x411111f0 }, /* N/A */
1208 { }
1209 },
1210 .chained = true,
1211 .chain_id = ALC880_FIXUP_VOL_KNOB,
1212 },
Takashi Iwai817de922012-02-20 17:20:48 +01001213 [ALC880_FIXUP_UNIWILL] = {
1214 /* need to fix HP and speaker pins to be parsed correctly */
Takashi Iwai1727a772013-01-10 09:52:52 +01001215 .type = HDA_FIXUP_PINS,
1216 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai817de922012-02-20 17:20:48 +01001217 { 0x14, 0x0121411f }, /* HP */
1218 { 0x15, 0x99030120 }, /* speaker */
1219 { 0x16, 0x99030130 }, /* bass speaker */
1220 { }
1221 },
1222 },
Takashi Iwai967b88c2012-02-20 17:31:02 +01001223 [ALC880_FIXUP_UNIWILL_DIG] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001224 .type = HDA_FIXUP_PINS,
1225 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai967b88c2012-02-20 17:31:02 +01001226 /* disable bogus unused pins */
1227 { 0x17, 0x411111f0 },
1228 { 0x19, 0x411111f0 },
1229 { 0x1b, 0x411111f0 },
1230 { 0x1f, 0x411111f0 },
1231 { }
1232 }
1233 },
Takashi Iwai96e225f2012-02-20 17:41:51 +01001234 [ALC880_FIXUP_Z71V] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001235 .type = HDA_FIXUP_PINS,
1236 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai96e225f2012-02-20 17:41:51 +01001237 /* set up the whole pins as BIOS is utterly broken */
1238 { 0x14, 0x99030120 }, /* speaker */
1239 { 0x15, 0x0121411f }, /* HP */
1240 { 0x16, 0x411111f0 }, /* N/A */
1241 { 0x17, 0x411111f0 }, /* N/A */
1242 { 0x18, 0x01a19950 }, /* mic-in */
1243 { 0x19, 0x411111f0 }, /* N/A */
1244 { 0x1a, 0x01813031 }, /* line-in */
1245 { 0x1b, 0x411111f0 }, /* N/A */
1246 { 0x1c, 0x411111f0 }, /* N/A */
1247 { 0x1d, 0x411111f0 }, /* N/A */
1248 { 0x1e, 0x0144111e }, /* SPDIF */
1249 { }
1250 }
1251 },
Takashi Iwai487a5882013-11-07 07:29:30 +01001252 [ALC880_FIXUP_ASUS_W5A] = {
1253 .type = HDA_FIXUP_PINS,
1254 .v.pins = (const struct hda_pintbl[]) {
1255 /* set up the whole pins as BIOS is utterly broken */
1256 { 0x14, 0x0121411f }, /* HP */
1257 { 0x15, 0x411111f0 }, /* N/A */
1258 { 0x16, 0x411111f0 }, /* N/A */
1259 { 0x17, 0x411111f0 }, /* N/A */
1260 { 0x18, 0x90a60160 }, /* mic */
1261 { 0x19, 0x411111f0 }, /* N/A */
1262 { 0x1a, 0x411111f0 }, /* N/A */
1263 { 0x1b, 0x411111f0 }, /* N/A */
1264 { 0x1c, 0x411111f0 }, /* N/A */
1265 { 0x1d, 0x411111f0 }, /* N/A */
1266 { 0x1e, 0xb743111e }, /* SPDIF out */
1267 { }
1268 },
1269 .chained = true,
1270 .chain_id = ALC880_FIXUP_GPIO1,
1271 },
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001272 [ALC880_FIXUP_3ST_BASE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001273 .type = HDA_FIXUP_PINS,
1274 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001275 { 0x14, 0x01014010 }, /* line-out */
1276 { 0x15, 0x411111f0 }, /* N/A */
1277 { 0x16, 0x411111f0 }, /* N/A */
1278 { 0x17, 0x411111f0 }, /* N/A */
1279 { 0x18, 0x01a19c30 }, /* mic-in */
1280 { 0x19, 0x0121411f }, /* HP */
1281 { 0x1a, 0x01813031 }, /* line-in */
1282 { 0x1b, 0x02a19c40 }, /* front-mic */
1283 { 0x1c, 0x411111f0 }, /* N/A */
1284 { 0x1d, 0x411111f0 }, /* N/A */
1285 /* 0x1e is filled in below */
1286 { 0x1f, 0x411111f0 }, /* N/A */
1287 { }
1288 }
1289 },
1290 [ALC880_FIXUP_3ST] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001291 .type = HDA_FIXUP_PINS,
1292 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001293 { 0x1e, 0x411111f0 }, /* N/A */
1294 { }
1295 },
1296 .chained = true,
1297 .chain_id = ALC880_FIXUP_3ST_BASE,
1298 },
1299 [ALC880_FIXUP_3ST_DIG] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001300 .type = HDA_FIXUP_PINS,
1301 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001302 { 0x1e, 0x0144111e }, /* SPDIF */
1303 { }
1304 },
1305 .chained = true,
1306 .chain_id = ALC880_FIXUP_3ST_BASE,
1307 },
1308 [ALC880_FIXUP_5ST_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 }, /* front */
1312 { 0x15, 0x411111f0 }, /* N/A */
1313 { 0x16, 0x01011411 }, /* CLFE */
1314 { 0x17, 0x01016412 }, /* surr */
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_5ST] = {
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_5ST_BASE,
1334 },
1335 [ALC880_FIXUP_5ST_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_5ST_BASE,
1343 },
1344 [ALC880_FIXUP_6ST_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, 0x01016412 }, /* surr */
1349 { 0x16, 0x01011411 }, /* CLFE */
1350 { 0x17, 0x01012414 }, /* side */
1351 { 0x18, 0x01a19c30 }, /* mic-in */
1352 { 0x19, 0x02a19c40 }, /* front-mic */
1353 { 0x1a, 0x01813031 }, /* line-in */
1354 { 0x1b, 0x0121411f }, /* HP */
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_6ST] = {
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_6ST_BASE,
1370 },
1371 [ALC880_FIXUP_6ST_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_6ST_BASE,
1379 },
Takashi Iwai53971452013-01-23 18:21:37 +01001380 [ALC880_FIXUP_6ST_AUTOMUTE] = {
1381 .type = HDA_FIXUP_PINS,
1382 .v.pins = (const struct hda_pintbl[]) {
1383 { 0x1b, 0x0121401f }, /* HP with jack detect */
1384 { }
1385 },
1386 .chained_before = true,
1387 .chain_id = ALC880_FIXUP_6ST_BASE,
1388 },
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001389};
1390
1391static const struct snd_pci_quirk alc880_fixup_tbl[] = {
Takashi Iwaif02aab52012-02-17 16:33:56 +01001392 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_FIXUP_W810),
Takashi Iwai487a5882013-11-07 07:29:30 +01001393 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS W5A", ALC880_FIXUP_ASUS_W5A),
Takashi Iwai96e225f2012-02-20 17:41:51 +01001394 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_FIXUP_Z71V),
Takashi Iwai29e3fdc2012-02-20 17:56:57 +01001395 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_FIXUP_GPIO1),
David Henningsson6538de02014-06-10 10:52:50 +02001396 SND_PCI_QUIRK(0x147b, 0x1045, "ABit AA8XE", ALC880_FIXUP_6ST_AUTOMUTE),
Takashi Iwai29e3fdc2012-02-20 17:56:57 +01001397 SND_PCI_QUIRK(0x1558, 0x5401, "Clevo GPIO2", ALC880_FIXUP_GPIO2),
Takashi Iwai27e917f2012-02-17 17:49:54 +01001398 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo", ALC880_FIXUP_EAPD_COEF),
Takashi Iwai967b88c2012-02-20 17:31:02 +01001399 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_FIXUP_UNIWILL_DIG),
Takashi Iwaiba533812012-02-20 16:36:52 +01001400 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_FIXUP_F1734),
Takashi Iwai817de922012-02-20 17:20:48 +01001401 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_FIXUP_UNIWILL),
Takashi Iwai7833c7e2012-02-20 17:11:38 +01001402 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_FIXUP_VOL_KNOB),
Takashi Iwaif02aab52012-02-17 16:33:56 +01001403 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_FIXUP_W810),
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001404 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_FIXUP_MEDION_RIM),
Takashi Iwai53971452013-01-23 18:21:37 +01001405 SND_PCI_QUIRK(0x1631, 0xe011, "PB 13201056", ALC880_FIXUP_6ST_AUTOMUTE),
Takashi Iwaia1615742015-08-13 18:05:06 +02001406 SND_PCI_QUIRK(0x1734, 0x107c, "FSC Amilo M1437", ALC880_FIXUP_FUJITSU),
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001407 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FIXUP_FUJITSU),
Takashi Iwaiba533812012-02-20 16:36:52 +01001408 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_FIXUP_F1734),
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001409 SND_PCI_QUIRK(0x1734, 0x10b0, "FSC Amilo Pi1556", ALC880_FIXUP_FUJITSU),
Takashi Iwaidc6af522012-02-17 16:18:59 +01001410 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_FIXUP_LG),
1411 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_FIXUP_LG),
1412 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_FIXUP_LG),
Takashi Iwaidb8a38e2013-08-09 12:34:42 +02001413 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_FIXUP_LG_LW25),
Takashi Iwaib9368f52012-02-17 17:54:44 +01001414 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_FIXUP_TCL_S700),
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001415
1416 /* Below is the copied entries from alc880_quirks.c.
1417 * It's not quite sure whether BIOS sets the correct pin-config table
1418 * on these machines, thus they are kept to be compatible with
1419 * the old static quirks. Once when it's confirmed to work without
1420 * these overrides, it'd be better to remove.
1421 */
1422 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_FIXUP_5ST_DIG),
1423 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_FIXUP_6ST),
1424 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_FIXUP_3ST_DIG),
1425 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_FIXUP_6ST_DIG),
1426 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_FIXUP_6ST_DIG),
1427 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_FIXUP_6ST_DIG),
1428 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_FIXUP_3ST_DIG),
1429 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_FIXUP_3ST),
1430 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_FIXUP_6ST_DIG),
1431 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_FIXUP_3ST),
1432 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_FIXUP_3ST),
1433 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_FIXUP_5ST),
1434 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_FIXUP_5ST),
1435 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_FIXUP_5ST),
1436 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_FIXUP_6ST_DIG),
1437 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_FIXUP_6ST_DIG),
1438 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_FIXUP_6ST_DIG),
1439 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_FIXUP_6ST_DIG),
1440 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_FIXUP_5ST_DIG),
1441 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_FIXUP_5ST_DIG),
1442 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_FIXUP_5ST_DIG),
1443 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_FIXUP_6ST_DIG), /* broken BIOS */
1444 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_FIXUP_6ST_DIG),
1445 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1446 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1447 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1448 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_FIXUP_3ST_DIG),
1449 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1450 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_FIXUP_3ST_DIG),
1451 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_FIXUP_3ST_DIG),
1452 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1453 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1454 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1455 /* default Intel */
1456 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_FIXUP_3ST),
1457 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_FIXUP_5ST_DIG),
1458 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_FIXUP_6ST_DIG),
1459 {}
1460};
1461
Takashi Iwai1727a772013-01-10 09:52:52 +01001462static const struct hda_model_fixup alc880_fixup_models[] = {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001463 {.id = ALC880_FIXUP_3ST, .name = "3stack"},
1464 {.id = ALC880_FIXUP_3ST_DIG, .name = "3stack-digout"},
1465 {.id = ALC880_FIXUP_5ST, .name = "5stack"},
1466 {.id = ALC880_FIXUP_5ST_DIG, .name = "5stack-digout"},
1467 {.id = ALC880_FIXUP_6ST, .name = "6stack"},
1468 {.id = ALC880_FIXUP_6ST_DIG, .name = "6stack-digout"},
Takashi Iwai53971452013-01-23 18:21:37 +01001469 {.id = ALC880_FIXUP_6ST_AUTOMUTE, .name = "6stack-automute"},
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001470 {}
1471};
1472
1473
1474/*
Takashi Iwai1d045db2011-07-07 18:23:21 +02001475 * OK, here we have finally the patch for ALC880
1476 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02001477static int patch_alc880(struct hda_codec *codec)
1478{
1479 struct alc_spec *spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001480 int err;
1481
Takashi Iwai3de95172012-05-07 18:03:15 +02001482 err = alc_alloc_spec(codec, 0x0b);
1483 if (err < 0)
1484 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001485
Takashi Iwai3de95172012-05-07 18:03:15 +02001486 spec = codec->spec;
Takashi Iwai08c189f2012-12-19 15:22:24 +01001487 spec->gen.need_dac_fix = 1;
Takashi Iwai7504b6c2013-03-18 11:25:51 +01001488 spec->gen.beep_nid = 0x01;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001489
Takashi Iwai225068a2015-05-29 10:42:14 +02001490 codec->patch_ops.unsol_event = alc880_unsol_event;
1491
Takashi Iwai1727a772013-01-10 09:52:52 +01001492 snd_hda_pick_fixup(codec, alc880_fixup_models, alc880_fixup_tbl,
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001493 alc880_fixups);
Takashi Iwai1727a772013-01-10 09:52:52 +01001494 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02001495
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001496 /* automatic parse from the BIOS config */
1497 err = alc880_parse_auto_config(codec);
1498 if (err < 0)
1499 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001500
Takashi Iwai7504b6c2013-03-18 11:25:51 +01001501 if (!spec->gen.no_analog)
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001502 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
Takashi Iwai1d045db2011-07-07 18:23:21 +02001503
Takashi Iwai1727a772013-01-10 09:52:52 +01001504 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01001505
Takashi Iwai1d045db2011-07-07 18:23:21 +02001506 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02001507
1508 error:
1509 alc_free(codec);
1510 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001511}
1512
1513
1514/*
1515 * ALC260 support
1516 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02001517static int alc260_parse_auto_config(struct hda_codec *codec)
1518{
Takashi Iwai1d045db2011-07-07 18:23:21 +02001519 static const hda_nid_t alc260_ignore[] = { 0x17, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001520 static const hda_nid_t alc260_ssids[] = { 0x10, 0x15, 0x0f, 0 };
1521 return alc_parse_auto_config(codec, alc260_ignore, alc260_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02001522}
1523
Takashi Iwai1d045db2011-07-07 18:23:21 +02001524/*
1525 * Pin config fixes
1526 */
1527enum {
Takashi Iwaica8f0422012-02-16 11:51:19 +01001528 ALC260_FIXUP_HP_DC5750,
1529 ALC260_FIXUP_HP_PIN_0F,
1530 ALC260_FIXUP_COEF,
Takashi Iwai15317ab2012-02-16 12:02:53 +01001531 ALC260_FIXUP_GPIO1,
Takashi Iwai20f7d922012-02-16 12:35:16 +01001532 ALC260_FIXUP_GPIO1_TOGGLE,
1533 ALC260_FIXUP_REPLACER,
Takashi Iwai0a1c4fa2012-02-16 12:42:30 +01001534 ALC260_FIXUP_HP_B1900,
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001535 ALC260_FIXUP_KN1,
Takashi Iwai39aedee2013-01-10 17:10:40 +01001536 ALC260_FIXUP_FSC_S7020,
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001537 ALC260_FIXUP_FSC_S7020_JWSE,
Takashi Iwaid08c5ef2013-11-22 08:06:36 +01001538 ALC260_FIXUP_VAIO_PINS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02001539};
1540
Takashi Iwai20f7d922012-02-16 12:35:16 +01001541static void alc260_gpio1_automute(struct hda_codec *codec)
1542{
1543 struct alc_spec *spec = codec->spec;
1544 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
Takashi Iwai08c189f2012-12-19 15:22:24 +01001545 spec->gen.hp_jack_present);
Takashi Iwai20f7d922012-02-16 12:35:16 +01001546}
1547
1548static void alc260_fixup_gpio1_toggle(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001549 const struct hda_fixup *fix, int action)
Takashi Iwai20f7d922012-02-16 12:35:16 +01001550{
1551 struct alc_spec *spec = codec->spec;
Takashi Iwai1727a772013-01-10 09:52:52 +01001552 if (action == HDA_FIXUP_ACT_PROBE) {
Takashi Iwai20f7d922012-02-16 12:35:16 +01001553 /* although the machine has only one output pin, we need to
1554 * toggle GPIO1 according to the jack state
1555 */
Takashi Iwai08c189f2012-12-19 15:22:24 +01001556 spec->gen.automute_hook = alc260_gpio1_automute;
1557 spec->gen.detect_hp = 1;
1558 spec->gen.automute_speaker = 1;
1559 spec->gen.autocfg.hp_pins[0] = 0x0f; /* copy it for automute */
Takashi Iwai62f949b2014-09-11 14:06:53 +02001560 snd_hda_jack_detect_enable_callback(codec, 0x0f,
Takashi Iwai08c189f2012-12-19 15:22:24 +01001561 snd_hda_gen_hp_automute);
Takashi Iwaic9ce6b22012-12-18 18:12:44 +01001562 snd_hda_add_verbs(codec, alc_gpio1_init_verbs);
Takashi Iwai20f7d922012-02-16 12:35:16 +01001563 }
1564}
1565
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001566static void alc260_fixup_kn1(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001567 const struct hda_fixup *fix, int action)
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001568{
1569 struct alc_spec *spec = codec->spec;
Takashi Iwai1727a772013-01-10 09:52:52 +01001570 static const struct hda_pintbl pincfgs[] = {
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001571 { 0x0f, 0x02214000 }, /* HP/speaker */
1572 { 0x12, 0x90a60160 }, /* int mic */
1573 { 0x13, 0x02a19000 }, /* ext mic */
1574 { 0x18, 0x01446000 }, /* SPDIF out */
1575 /* disable bogus I/O pins */
1576 { 0x10, 0x411111f0 },
1577 { 0x11, 0x411111f0 },
1578 { 0x14, 0x411111f0 },
1579 { 0x15, 0x411111f0 },
1580 { 0x16, 0x411111f0 },
1581 { 0x17, 0x411111f0 },
1582 { 0x19, 0x411111f0 },
1583 { }
1584 };
1585
1586 switch (action) {
Takashi Iwai1727a772013-01-10 09:52:52 +01001587 case HDA_FIXUP_ACT_PRE_PROBE:
1588 snd_hda_apply_pincfgs(codec, pincfgs);
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001589 break;
Takashi Iwai1727a772013-01-10 09:52:52 +01001590 case HDA_FIXUP_ACT_PROBE:
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001591 spec->init_amp = ALC_INIT_NONE;
1592 break;
1593 }
1594}
1595
Takashi Iwai39aedee2013-01-10 17:10:40 +01001596static void alc260_fixup_fsc_s7020(struct hda_codec *codec,
1597 const struct hda_fixup *fix, int action)
1598{
1599 struct alc_spec *spec = codec->spec;
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001600 if (action == HDA_FIXUP_ACT_PROBE)
Takashi Iwaie6e0ee52013-02-18 17:04:20 +01001601 spec->init_amp = ALC_INIT_NONE;
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001602}
1603
1604static void alc260_fixup_fsc_s7020_jwse(struct hda_codec *codec,
1605 const struct hda_fixup *fix, int action)
1606{
1607 struct alc_spec *spec = codec->spec;
1608 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwaif811c3c2013-03-07 18:32:59 +01001609 spec->gen.add_jack_modes = 1;
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001610 spec->gen.hp_mic = 1;
Takashi Iwaie6e0ee52013-02-18 17:04:20 +01001611 }
Takashi Iwai39aedee2013-01-10 17:10:40 +01001612}
1613
Takashi Iwai1727a772013-01-10 09:52:52 +01001614static const struct hda_fixup alc260_fixups[] = {
Takashi Iwaica8f0422012-02-16 11:51:19 +01001615 [ALC260_FIXUP_HP_DC5750] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001616 .type = HDA_FIXUP_PINS,
1617 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02001618 { 0x11, 0x90130110 }, /* speaker */
1619 { }
1620 }
1621 },
Takashi Iwaica8f0422012-02-16 11:51:19 +01001622 [ALC260_FIXUP_HP_PIN_0F] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001623 .type = HDA_FIXUP_PINS,
1624 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaica8f0422012-02-16 11:51:19 +01001625 { 0x0f, 0x01214000 }, /* HP */
1626 { }
1627 }
1628 },
1629 [ALC260_FIXUP_COEF] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001630 .type = HDA_FIXUP_VERBS,
Takashi Iwaica8f0422012-02-16 11:51:19 +01001631 .v.verbs = (const struct hda_verb[]) {
Ronan Marquete30cf2d2014-06-01 18:38:53 +02001632 { 0x1a, AC_VERB_SET_COEF_INDEX, 0x07 },
1633 { 0x1a, AC_VERB_SET_PROC_COEF, 0x3040 },
Takashi Iwaica8f0422012-02-16 11:51:19 +01001634 { }
1635 },
Takashi Iwaica8f0422012-02-16 11:51:19 +01001636 },
Takashi Iwai15317ab2012-02-16 12:02:53 +01001637 [ALC260_FIXUP_GPIO1] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001638 .type = HDA_FIXUP_VERBS,
Takashi Iwai15317ab2012-02-16 12:02:53 +01001639 .v.verbs = alc_gpio1_init_verbs,
1640 },
Takashi Iwai20f7d922012-02-16 12:35:16 +01001641 [ALC260_FIXUP_GPIO1_TOGGLE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001642 .type = HDA_FIXUP_FUNC,
Takashi Iwai20f7d922012-02-16 12:35:16 +01001643 .v.func = alc260_fixup_gpio1_toggle,
1644 .chained = true,
1645 .chain_id = ALC260_FIXUP_HP_PIN_0F,
1646 },
1647 [ALC260_FIXUP_REPLACER] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001648 .type = HDA_FIXUP_VERBS,
Takashi Iwai20f7d922012-02-16 12:35:16 +01001649 .v.verbs = (const struct hda_verb[]) {
Takashi Iwai192a98e2014-06-02 15:16:07 +02001650 { 0x1a, AC_VERB_SET_COEF_INDEX, 0x07 },
1651 { 0x1a, AC_VERB_SET_PROC_COEF, 0x3050 },
Takashi Iwai20f7d922012-02-16 12:35:16 +01001652 { }
1653 },
1654 .chained = true,
1655 .chain_id = ALC260_FIXUP_GPIO1_TOGGLE,
1656 },
Takashi Iwai0a1c4fa2012-02-16 12:42:30 +01001657 [ALC260_FIXUP_HP_B1900] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001658 .type = HDA_FIXUP_FUNC,
Takashi Iwai0a1c4fa2012-02-16 12:42:30 +01001659 .v.func = alc260_fixup_gpio1_toggle,
1660 .chained = true,
1661 .chain_id = ALC260_FIXUP_COEF,
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001662 },
1663 [ALC260_FIXUP_KN1] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001664 .type = HDA_FIXUP_FUNC,
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001665 .v.func = alc260_fixup_kn1,
1666 },
Takashi Iwai39aedee2013-01-10 17:10:40 +01001667 [ALC260_FIXUP_FSC_S7020] = {
1668 .type = HDA_FIXUP_FUNC,
1669 .v.func = alc260_fixup_fsc_s7020,
1670 },
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001671 [ALC260_FIXUP_FSC_S7020_JWSE] = {
1672 .type = HDA_FIXUP_FUNC,
1673 .v.func = alc260_fixup_fsc_s7020_jwse,
1674 .chained = true,
1675 .chain_id = ALC260_FIXUP_FSC_S7020,
1676 },
Takashi Iwaid08c5ef2013-11-22 08:06:36 +01001677 [ALC260_FIXUP_VAIO_PINS] = {
1678 .type = HDA_FIXUP_PINS,
1679 .v.pins = (const struct hda_pintbl[]) {
1680 /* Pin configs are missing completely on some VAIOs */
1681 { 0x0f, 0x01211020 },
1682 { 0x10, 0x0001003f },
1683 { 0x11, 0x411111f0 },
1684 { 0x12, 0x01a15930 },
1685 { 0x13, 0x411111f0 },
1686 { 0x14, 0x411111f0 },
1687 { 0x15, 0x411111f0 },
1688 { 0x16, 0x411111f0 },
1689 { 0x17, 0x411111f0 },
1690 { 0x18, 0x411111f0 },
1691 { 0x19, 0x411111f0 },
1692 { }
1693 }
1694 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02001695};
1696
1697static const struct snd_pci_quirk alc260_fixup_tbl[] = {
Takashi Iwai15317ab2012-02-16 12:02:53 +01001698 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_FIXUP_GPIO1),
Takashi Iwaica8f0422012-02-16 11:51:19 +01001699 SND_PCI_QUIRK(0x1025, 0x007f, "Acer Aspire 9500", ALC260_FIXUP_COEF),
Takashi Iwai15317ab2012-02-16 12:02:53 +01001700 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_FIXUP_GPIO1),
Takashi Iwaica8f0422012-02-16 11:51:19 +01001701 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", ALC260_FIXUP_HP_DC5750),
Takashi Iwai0a1c4fa2012-02-16 12:42:30 +01001702 SND_PCI_QUIRK(0x103c, 0x30ba, "HP Presario B1900", ALC260_FIXUP_HP_B1900),
Takashi Iwaid08c5ef2013-11-22 08:06:36 +01001703 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_FIXUP_VAIO_PINS),
Takashi Iwai0f5a5b82013-11-21 09:12:52 +01001704 SND_PCI_QUIRK(0x104d, 0x81e2, "Sony VAIO TX", ALC260_FIXUP_HP_PIN_0F),
Takashi Iwai39aedee2013-01-10 17:10:40 +01001705 SND_PCI_QUIRK(0x10cf, 0x1326, "FSC LifeBook S7020", ALC260_FIXUP_FSC_S7020),
Takashi Iwaib1f58082012-02-16 12:45:03 +01001706 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FIXUP_GPIO1),
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001707 SND_PCI_QUIRK(0x152d, 0x0729, "Quanta KN1", ALC260_FIXUP_KN1),
Takashi Iwai20f7d922012-02-16 12:35:16 +01001708 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_FIXUP_REPLACER),
Takashi Iwaica8f0422012-02-16 11:51:19 +01001709 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_FIXUP_COEF),
Takashi Iwai1d045db2011-07-07 18:23:21 +02001710 {}
1711};
1712
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001713static const struct hda_model_fixup alc260_fixup_models[] = {
1714 {.id = ALC260_FIXUP_GPIO1, .name = "gpio1"},
1715 {.id = ALC260_FIXUP_COEF, .name = "coef"},
1716 {.id = ALC260_FIXUP_FSC_S7020, .name = "fujitsu"},
1717 {.id = ALC260_FIXUP_FSC_S7020_JWSE, .name = "fujitsu-jwse"},
1718 {}
1719};
1720
Takashi Iwai1d045db2011-07-07 18:23:21 +02001721/*
1722 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02001723static int patch_alc260(struct hda_codec *codec)
1724{
1725 struct alc_spec *spec;
Takashi Iwaic3c2c9e2012-02-16 12:59:55 +01001726 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001727
Takashi Iwai3de95172012-05-07 18:03:15 +02001728 err = alc_alloc_spec(codec, 0x07);
1729 if (err < 0)
1730 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001731
Takashi Iwai3de95172012-05-07 18:03:15 +02001732 spec = codec->spec;
Takashi Iwaiea46c3c2013-01-15 18:45:53 +01001733 /* as quite a few machines require HP amp for speaker outputs,
1734 * it's easier to enable it unconditionally; even if it's unneeded,
1735 * it's almost harmless.
1736 */
1737 spec->gen.prefer_hp_amp = 1;
Takashi Iwai7504b6c2013-03-18 11:25:51 +01001738 spec->gen.beep_nid = 0x01;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001739
Takashi Iwai225068a2015-05-29 10:42:14 +02001740 spec->shutup = alc_eapd_shutup;
1741
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001742 snd_hda_pick_fixup(codec, alc260_fixup_models, alc260_fixup_tbl,
1743 alc260_fixups);
Takashi Iwai1727a772013-01-10 09:52:52 +01001744 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02001745
Takashi Iwaic3c2c9e2012-02-16 12:59:55 +01001746 /* automatic parse from the BIOS config */
1747 err = alc260_parse_auto_config(codec);
1748 if (err < 0)
1749 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001750
Takashi Iwai7504b6c2013-03-18 11:25:51 +01001751 if (!spec->gen.no_analog)
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001752 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
Takashi Iwai1d045db2011-07-07 18:23:21 +02001753
Takashi Iwai1727a772013-01-10 09:52:52 +01001754 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01001755
Takashi Iwai1d045db2011-07-07 18:23:21 +02001756 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02001757
1758 error:
1759 alc_free(codec);
1760 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001761}
1762
1763
1764/*
1765 * ALC882/883/885/888/889 support
1766 *
1767 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
1768 * configuration. Each pin widget can choose any input DACs and a mixer.
1769 * Each ADC is connected from a mixer of all inputs. This makes possible
1770 * 6-channel independent captures.
1771 *
1772 * In addition, an independent DAC for the multi-playback (not used in this
1773 * driver yet).
1774 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02001775
1776/*
1777 * Pin config fixes
1778 */
1779enum {
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01001780 ALC882_FIXUP_ABIT_AW9D_MAX,
1781 ALC882_FIXUP_LENOVO_Y530,
1782 ALC882_FIXUP_PB_M5210,
1783 ALC882_FIXUP_ACER_ASPIRE_7736,
1784 ALC882_FIXUP_ASUS_W90V,
Marton Balint8f239212012-03-05 21:33:23 +01001785 ALC889_FIXUP_CD,
David Henningssonb2c53e22014-01-01 14:01:34 +01001786 ALC889_FIXUP_FRONT_HP_NO_PRESENCE,
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01001787 ALC889_FIXUP_VAIO_TT,
Takashi Iwai0e7cc2e2011-11-09 12:42:48 +01001788 ALC888_FIXUP_EEE1601,
Takashi Iwai177943a2011-11-09 12:55:18 +01001789 ALC882_FIXUP_EAPD,
Takashi Iwai7a6069b2011-11-09 15:22:01 +01001790 ALC883_FIXUP_EAPD,
Takashi Iwai8812c4f2011-11-09 17:39:15 +01001791 ALC883_FIXUP_ACER_EAPD,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001792 ALC882_FIXUP_GPIO1,
1793 ALC882_FIXUP_GPIO2,
Takashi Iwaieb844d52011-11-09 18:03:07 +01001794 ALC882_FIXUP_GPIO3,
Takashi Iwai68ef0562011-11-09 18:24:44 +01001795 ALC889_FIXUP_COEF,
1796 ALC882_FIXUP_ASUS_W2JC,
Takashi Iwaic3e837b2011-11-10 16:01:47 +01001797 ALC882_FIXUP_ACER_ASPIRE_4930G,
1798 ALC882_FIXUP_ACER_ASPIRE_8930G,
1799 ALC882_FIXUP_ASPIRE_8930G_VERBS,
Takashi Iwai56710872011-11-14 17:42:11 +01001800 ALC885_FIXUP_MACPRO_GPIO,
Takashi Iwai02a237b2012-02-13 15:25:07 +01001801 ALC889_FIXUP_DAC_ROUTE,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001802 ALC889_FIXUP_MBP_VREF,
1803 ALC889_FIXUP_IMAC91_VREF,
Adrien Vergée7729a42014-01-24 14:56:14 -05001804 ALC889_FIXUP_MBA11_VREF,
Takashi Iwai0756f092013-12-04 13:59:45 +01001805 ALC889_FIXUP_MBA21_VREF,
Takashi Iwaic20f31e2014-02-03 11:02:10 +01001806 ALC889_FIXUP_MP11_VREF,
Mario Kleiner9f660a12015-12-22 00:45:43 +01001807 ALC889_FIXUP_MP41_VREF,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02001808 ALC882_FIXUP_INV_DMIC,
Takashi Iwaie427c232012-07-29 10:04:08 +02001809 ALC882_FIXUP_NO_PRIMARY_HP,
Takashi Iwai1f0bbf02013-11-28 15:21:21 +01001810 ALC887_FIXUP_ASUS_BASS,
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01001811 ALC887_FIXUP_BASS_CHMAP,
Takashi Iwai7beb3a62017-04-10 18:05:52 +02001812 ALC1220_FIXUP_GB_DUAL_CODECS,
Peisen0202f5c2017-10-26 10:35:36 +08001813 ALC1220_FIXUP_CLEVO_P950,
Takashi Iwai1d045db2011-07-07 18:23:21 +02001814};
1815
Takashi Iwai68ef0562011-11-09 18:24:44 +01001816static void alc889_fixup_coef(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001817 const struct hda_fixup *fix, int action)
Takashi Iwai68ef0562011-11-09 18:24:44 +01001818{
Takashi Iwai1727a772013-01-10 09:52:52 +01001819 if (action != HDA_FIXUP_ACT_INIT)
Takashi Iwai68ef0562011-11-09 18:24:44 +01001820 return;
Kailang Yang1df88742014-10-29 16:10:13 +08001821 alc_update_coef_idx(codec, 7, 0, 0x2030);
Takashi Iwai68ef0562011-11-09 18:24:44 +01001822}
1823
Takashi Iwai56710872011-11-14 17:42:11 +01001824/* toggle speaker-output according to the hp-jack state */
1825static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
1826{
1827 unsigned int gpiostate, gpiomask, gpiodir;
1828
Takashi Iwai7639a062015-03-03 10:07:24 +01001829 gpiostate = snd_hda_codec_read(codec, codec->core.afg, 0,
Takashi Iwai56710872011-11-14 17:42:11 +01001830 AC_VERB_GET_GPIO_DATA, 0);
1831
1832 if (!muted)
1833 gpiostate |= (1 << pin);
1834 else
1835 gpiostate &= ~(1 << pin);
1836
Takashi Iwai7639a062015-03-03 10:07:24 +01001837 gpiomask = snd_hda_codec_read(codec, codec->core.afg, 0,
Takashi Iwai56710872011-11-14 17:42:11 +01001838 AC_VERB_GET_GPIO_MASK, 0);
1839 gpiomask |= (1 << pin);
1840
Takashi Iwai7639a062015-03-03 10:07:24 +01001841 gpiodir = snd_hda_codec_read(codec, codec->core.afg, 0,
Takashi Iwai56710872011-11-14 17:42:11 +01001842 AC_VERB_GET_GPIO_DIRECTION, 0);
1843 gpiodir |= (1 << pin);
1844
1845
Takashi Iwai7639a062015-03-03 10:07:24 +01001846 snd_hda_codec_write(codec, codec->core.afg, 0,
Takashi Iwai56710872011-11-14 17:42:11 +01001847 AC_VERB_SET_GPIO_MASK, gpiomask);
Takashi Iwai7639a062015-03-03 10:07:24 +01001848 snd_hda_codec_write(codec, codec->core.afg, 0,
Takashi Iwai56710872011-11-14 17:42:11 +01001849 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
1850
1851 msleep(1);
1852
Takashi Iwai7639a062015-03-03 10:07:24 +01001853 snd_hda_codec_write(codec, codec->core.afg, 0,
Takashi Iwai56710872011-11-14 17:42:11 +01001854 AC_VERB_SET_GPIO_DATA, gpiostate);
1855}
1856
1857/* set up GPIO at initialization */
1858static void alc885_fixup_macpro_gpio(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001859 const struct hda_fixup *fix, int action)
Takashi Iwai56710872011-11-14 17:42:11 +01001860{
Takashi Iwai1727a772013-01-10 09:52:52 +01001861 if (action != HDA_FIXUP_ACT_INIT)
Takashi Iwai56710872011-11-14 17:42:11 +01001862 return;
1863 alc882_gpio_mute(codec, 0, 0);
1864 alc882_gpio_mute(codec, 1, 0);
1865}
1866
Takashi Iwai02a237b2012-02-13 15:25:07 +01001867/* Fix the connection of some pins for ALC889:
1868 * At least, Acer Aspire 5935 shows the connections to DAC3/4 don't
1869 * work correctly (bko#42740)
1870 */
1871static void alc889_fixup_dac_route(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001872 const struct hda_fixup *fix, int action)
Takashi Iwai02a237b2012-02-13 15:25:07 +01001873{
Takashi Iwai1727a772013-01-10 09:52:52 +01001874 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwaief8d60f2012-02-17 10:12:38 +01001875 /* fake the connections during parsing the tree */
Takashi Iwai02a237b2012-02-13 15:25:07 +01001876 hda_nid_t conn1[2] = { 0x0c, 0x0d };
1877 hda_nid_t conn2[2] = { 0x0e, 0x0f };
1878 snd_hda_override_conn_list(codec, 0x14, 2, conn1);
1879 snd_hda_override_conn_list(codec, 0x15, 2, conn1);
1880 snd_hda_override_conn_list(codec, 0x18, 2, conn2);
1881 snd_hda_override_conn_list(codec, 0x1a, 2, conn2);
Takashi Iwai1727a772013-01-10 09:52:52 +01001882 } else if (action == HDA_FIXUP_ACT_PROBE) {
Takashi Iwaief8d60f2012-02-17 10:12:38 +01001883 /* restore the connections */
1884 hda_nid_t conn[5] = { 0x0c, 0x0d, 0x0e, 0x0f, 0x26 };
1885 snd_hda_override_conn_list(codec, 0x14, 5, conn);
1886 snd_hda_override_conn_list(codec, 0x15, 5, conn);
1887 snd_hda_override_conn_list(codec, 0x18, 5, conn);
1888 snd_hda_override_conn_list(codec, 0x1a, 5, conn);
Takashi Iwai02a237b2012-02-13 15:25:07 +01001889 }
1890}
1891
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001892/* Set VREF on HP pin */
1893static void alc889_fixup_mbp_vref(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001894 const struct hda_fixup *fix, int action)
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001895{
1896 struct alc_spec *spec = codec->spec;
Mario Kleiner9f660a12015-12-22 00:45:43 +01001897 static hda_nid_t nids[3] = { 0x14, 0x15, 0x19 };
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001898 int i;
1899
Takashi Iwai1727a772013-01-10 09:52:52 +01001900 if (action != HDA_FIXUP_ACT_INIT)
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001901 return;
1902 for (i = 0; i < ARRAY_SIZE(nids); i++) {
1903 unsigned int val = snd_hda_codec_get_pincfg(codec, nids[i]);
1904 if (get_defcfg_device(val) != AC_JACK_HP_OUT)
1905 continue;
Takashi Iwaid3f02d62013-01-10 10:12:22 +01001906 val = snd_hda_codec_get_pin_target(codec, nids[i]);
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001907 val |= AC_PINCTL_VREF_80;
Takashi Iwaicdd03ce2012-04-20 12:34:50 +02001908 snd_hda_set_pin_ctl(codec, nids[i], val);
Takashi Iwai08c189f2012-12-19 15:22:24 +01001909 spec->gen.keep_vref_in_automute = 1;
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001910 break;
1911 }
1912}
1913
Takashi Iwai0756f092013-12-04 13:59:45 +01001914static void alc889_fixup_mac_pins(struct hda_codec *codec,
1915 const hda_nid_t *nids, int num_nids)
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001916{
1917 struct alc_spec *spec = codec->spec;
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001918 int i;
1919
Takashi Iwai0756f092013-12-04 13:59:45 +01001920 for (i = 0; i < num_nids; i++) {
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001921 unsigned int val;
Takashi Iwaid3f02d62013-01-10 10:12:22 +01001922 val = snd_hda_codec_get_pin_target(codec, nids[i]);
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001923 val |= AC_PINCTL_VREF_50;
Takashi Iwaicdd03ce2012-04-20 12:34:50 +02001924 snd_hda_set_pin_ctl(codec, nids[i], val);
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001925 }
Takashi Iwai08c189f2012-12-19 15:22:24 +01001926 spec->gen.keep_vref_in_automute = 1;
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001927}
1928
Takashi Iwai0756f092013-12-04 13:59:45 +01001929/* Set VREF on speaker pins on imac91 */
1930static void alc889_fixup_imac91_vref(struct hda_codec *codec,
1931 const struct hda_fixup *fix, int action)
1932{
1933 static hda_nid_t nids[2] = { 0x18, 0x1a };
1934
1935 if (action == HDA_FIXUP_ACT_INIT)
1936 alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
1937}
1938
Adrien Vergée7729a42014-01-24 14:56:14 -05001939/* Set VREF on speaker pins on mba11 */
1940static void alc889_fixup_mba11_vref(struct hda_codec *codec,
1941 const struct hda_fixup *fix, int action)
1942{
1943 static hda_nid_t nids[1] = { 0x18 };
1944
1945 if (action == HDA_FIXUP_ACT_INIT)
1946 alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
1947}
1948
Takashi Iwai0756f092013-12-04 13:59:45 +01001949/* Set VREF on speaker pins on mba21 */
1950static void alc889_fixup_mba21_vref(struct hda_codec *codec,
1951 const struct hda_fixup *fix, int action)
1952{
1953 static hda_nid_t nids[2] = { 0x18, 0x19 };
1954
1955 if (action == HDA_FIXUP_ACT_INIT)
1956 alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
1957}
1958
Takashi Iwaie427c232012-07-29 10:04:08 +02001959/* Don't take HP output as primary
Fernando Luis Vázquez Caod9111492013-02-12 16:49:46 +09001960 * Strangely, the speaker output doesn't work on Vaio Z and some Vaio
1961 * all-in-one desktop PCs (for example VGC-LN51JGB) through DAC 0x05
Takashi Iwaie427c232012-07-29 10:04:08 +02001962 */
1963static void alc882_fixup_no_primary_hp(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001964 const struct hda_fixup *fix, int action)
Takashi Iwaie427c232012-07-29 10:04:08 +02001965{
1966 struct alc_spec *spec = codec->spec;
Takashi Iwaida96fb52013-07-29 16:54:36 +02001967 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai08c189f2012-12-19 15:22:24 +01001968 spec->gen.no_primary_hp = 1;
Takashi Iwaida96fb52013-07-29 16:54:36 +02001969 spec->gen.no_multi_io = 1;
1970 }
Takashi Iwaie427c232012-07-29 10:04:08 +02001971}
1972
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01001973static void alc_fixup_bass_chmap(struct hda_codec *codec,
1974 const struct hda_fixup *fix, int action);
1975
Takashi Iwai7beb3a62017-04-10 18:05:52 +02001976/* For dual-codec configuration, we need to disable some features to avoid
1977 * conflicts of kctls and PCM streams
1978 */
1979static void alc_fixup_dual_codecs(struct hda_codec *codec,
1980 const struct hda_fixup *fix, int action)
1981{
1982 struct alc_spec *spec = codec->spec;
1983
1984 if (action != HDA_FIXUP_ACT_PRE_PROBE)
1985 return;
1986 /* disable vmaster */
1987 spec->gen.suppress_vmaster = 1;
1988 /* auto-mute and auto-mic switch don't work with multiple codecs */
1989 spec->gen.suppress_auto_mute = 1;
1990 spec->gen.suppress_auto_mic = 1;
1991 /* disable aamix as well */
1992 spec->gen.mixer_nid = 0;
1993 /* add location prefix to avoid conflicts */
1994 codec->force_pin_prefix = 1;
1995}
1996
1997static void rename_ctl(struct hda_codec *codec, const char *oldname,
1998 const char *newname)
1999{
2000 struct snd_kcontrol *kctl;
2001
2002 kctl = snd_hda_find_mixer_ctl(codec, oldname);
2003 if (kctl)
2004 strcpy(kctl->id.name, newname);
2005}
2006
2007static void alc1220_fixup_gb_dual_codecs(struct hda_codec *codec,
2008 const struct hda_fixup *fix,
2009 int action)
2010{
2011 alc_fixup_dual_codecs(codec, fix, action);
2012 switch (action) {
2013 case HDA_FIXUP_ACT_PRE_PROBE:
2014 /* override card longname to provide a unique UCM profile */
2015 strcpy(codec->card->longname, "HDAudio-Gigabyte-ALC1220DualCodecs");
2016 break;
2017 case HDA_FIXUP_ACT_BUILD:
2018 /* rename Capture controls depending on the codec */
2019 rename_ctl(codec, "Capture Volume",
2020 codec->addr == 0 ?
2021 "Rear-Panel Capture Volume" :
2022 "Front-Panel Capture Volume");
2023 rename_ctl(codec, "Capture Switch",
2024 codec->addr == 0 ?
2025 "Rear-Panel Capture Switch" :
2026 "Front-Panel Capture Switch");
2027 break;
2028 }
2029}
2030
Peisen0202f5c2017-10-26 10:35:36 +08002031static void alc1220_fixup_clevo_p950(struct hda_codec *codec,
2032 const struct hda_fixup *fix,
2033 int action)
2034{
2035 hda_nid_t conn1[1] = { 0x0c };
2036
2037 if (action != HDA_FIXUP_ACT_PRE_PROBE)
2038 return;
2039
2040 alc_update_coef_idx(codec, 0x7, 0, 0x3c3);
2041 /* We therefore want to make sure 0x14 (front headphone) and
2042 * 0x1b (speakers) use the stereo DAC 0x02
2043 */
2044 snd_hda_override_conn_list(codec, 0x14, 1, conn1);
2045 snd_hda_override_conn_list(codec, 0x1b, 1, conn1);
2046}
2047
Takashi Iwai1727a772013-01-10 09:52:52 +01002048static const struct hda_fixup alc882_fixups[] = {
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002049 [ALC882_FIXUP_ABIT_AW9D_MAX] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002050 .type = HDA_FIXUP_PINS,
2051 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002052 { 0x15, 0x01080104 }, /* side */
2053 { 0x16, 0x01011012 }, /* rear */
2054 { 0x17, 0x01016011 }, /* clfe */
2055 { }
2056 }
2057 },
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002058 [ALC882_FIXUP_LENOVO_Y530] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002059 .type = HDA_FIXUP_PINS,
2060 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002061 { 0x15, 0x99130112 }, /* rear int speakers */
2062 { 0x16, 0x99130111 }, /* subwoofer */
2063 { }
2064 }
2065 },
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002066 [ALC882_FIXUP_PB_M5210] = {
Takashi Iwaifd108212013-01-10 10:18:14 +01002067 .type = HDA_FIXUP_PINCTLS,
2068 .v.pins = (const struct hda_pintbl[]) {
2069 { 0x19, PIN_VREF50 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02002070 {}
2071 }
2072 },
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002073 [ALC882_FIXUP_ACER_ASPIRE_7736] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002074 .type = HDA_FIXUP_FUNC,
Takashi Iwai23d30f22012-05-07 17:17:32 +02002075 .v.func = alc_fixup_sku_ignore,
Takashi Iwai1d045db2011-07-07 18:23:21 +02002076 },
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002077 [ALC882_FIXUP_ASUS_W90V] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002078 .type = HDA_FIXUP_PINS,
2079 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai5cdf7452011-10-26 23:04:08 +02002080 { 0x16, 0x99130110 }, /* fix sequence for CLFE */
2081 { }
2082 }
2083 },
Marton Balint8f239212012-03-05 21:33:23 +01002084 [ALC889_FIXUP_CD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002085 .type = HDA_FIXUP_PINS,
2086 .v.pins = (const struct hda_pintbl[]) {
Marton Balint8f239212012-03-05 21:33:23 +01002087 { 0x1c, 0x993301f0 }, /* CD */
2088 { }
2089 }
2090 },
David Henningssonb2c53e22014-01-01 14:01:34 +01002091 [ALC889_FIXUP_FRONT_HP_NO_PRESENCE] = {
2092 .type = HDA_FIXUP_PINS,
2093 .v.pins = (const struct hda_pintbl[]) {
2094 { 0x1b, 0x02214120 }, /* Front HP jack is flaky, disable jack detect */
2095 { }
2096 },
2097 .chained = true,
2098 .chain_id = ALC889_FIXUP_CD,
2099 },
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002100 [ALC889_FIXUP_VAIO_TT] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002101 .type = HDA_FIXUP_PINS,
2102 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002103 { 0x17, 0x90170111 }, /* hidden surround speaker */
2104 { }
2105 }
2106 },
Takashi Iwai0e7cc2e2011-11-09 12:42:48 +01002107 [ALC888_FIXUP_EEE1601] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002108 .type = HDA_FIXUP_VERBS,
Takashi Iwai0e7cc2e2011-11-09 12:42:48 +01002109 .v.verbs = (const struct hda_verb[]) {
2110 { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b },
2111 { 0x20, AC_VERB_SET_PROC_COEF, 0x0838 },
2112 { }
2113 }
Takashi Iwai177943a2011-11-09 12:55:18 +01002114 },
2115 [ALC882_FIXUP_EAPD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002116 .type = HDA_FIXUP_VERBS,
Takashi Iwai177943a2011-11-09 12:55:18 +01002117 .v.verbs = (const struct hda_verb[]) {
2118 /* change to EAPD mode */
2119 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2120 { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
2121 { }
2122 }
2123 },
Takashi Iwai7a6069b2011-11-09 15:22:01 +01002124 [ALC883_FIXUP_EAPD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002125 .type = HDA_FIXUP_VERBS,
Takashi Iwai7a6069b2011-11-09 15:22:01 +01002126 .v.verbs = (const struct hda_verb[]) {
2127 /* change to EAPD mode */
2128 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2129 { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
2130 { }
2131 }
2132 },
Takashi Iwai8812c4f2011-11-09 17:39:15 +01002133 [ALC883_FIXUP_ACER_EAPD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002134 .type = HDA_FIXUP_VERBS,
Takashi Iwai8812c4f2011-11-09 17:39:15 +01002135 .v.verbs = (const struct hda_verb[]) {
2136 /* eanable EAPD on Acer laptops */
2137 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2138 { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
2139 { }
2140 }
2141 },
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002142 [ALC882_FIXUP_GPIO1] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002143 .type = HDA_FIXUP_VERBS,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002144 .v.verbs = alc_gpio1_init_verbs,
2145 },
2146 [ALC882_FIXUP_GPIO2] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002147 .type = HDA_FIXUP_VERBS,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002148 .v.verbs = alc_gpio2_init_verbs,
2149 },
Takashi Iwaieb844d52011-11-09 18:03:07 +01002150 [ALC882_FIXUP_GPIO3] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002151 .type = HDA_FIXUP_VERBS,
Takashi Iwaieb844d52011-11-09 18:03:07 +01002152 .v.verbs = alc_gpio3_init_verbs,
2153 },
Takashi Iwai68ef0562011-11-09 18:24:44 +01002154 [ALC882_FIXUP_ASUS_W2JC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002155 .type = HDA_FIXUP_VERBS,
Takashi Iwai68ef0562011-11-09 18:24:44 +01002156 .v.verbs = alc_gpio1_init_verbs,
2157 .chained = true,
2158 .chain_id = ALC882_FIXUP_EAPD,
2159 },
2160 [ALC889_FIXUP_COEF] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002161 .type = HDA_FIXUP_FUNC,
Takashi Iwai68ef0562011-11-09 18:24:44 +01002162 .v.func = alc889_fixup_coef,
2163 },
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002164 [ALC882_FIXUP_ACER_ASPIRE_4930G] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002165 .type = HDA_FIXUP_PINS,
2166 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002167 { 0x16, 0x99130111 }, /* CLFE speaker */
2168 { 0x17, 0x99130112 }, /* surround speaker */
2169 { }
Takashi Iwai038d4fe2012-04-11 17:18:12 +02002170 },
2171 .chained = true,
2172 .chain_id = ALC882_FIXUP_GPIO1,
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002173 },
2174 [ALC882_FIXUP_ACER_ASPIRE_8930G] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002175 .type = HDA_FIXUP_PINS,
2176 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002177 { 0x16, 0x99130111 }, /* CLFE speaker */
2178 { 0x1b, 0x99130112 }, /* surround speaker */
2179 { }
2180 },
2181 .chained = true,
2182 .chain_id = ALC882_FIXUP_ASPIRE_8930G_VERBS,
2183 },
2184 [ALC882_FIXUP_ASPIRE_8930G_VERBS] = {
2185 /* additional init verbs for Acer Aspire 8930G */
Takashi Iwai1727a772013-01-10 09:52:52 +01002186 .type = HDA_FIXUP_VERBS,
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002187 .v.verbs = (const struct hda_verb[]) {
2188 /* Enable all DACs */
2189 /* DAC DISABLE/MUTE 1? */
2190 /* setting bits 1-5 disables DAC nids 0x02-0x06
2191 * apparently. Init=0x38 */
2192 { 0x20, AC_VERB_SET_COEF_INDEX, 0x03 },
2193 { 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
2194 /* DAC DISABLE/MUTE 2? */
2195 /* some bit here disables the other DACs.
2196 * Init=0x4900 */
2197 { 0x20, AC_VERB_SET_COEF_INDEX, 0x08 },
2198 { 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
2199 /* DMIC fix
2200 * This laptop has a stereo digital microphone.
2201 * The mics are only 1cm apart which makes the stereo
2202 * useless. However, either the mic or the ALC889
2203 * makes the signal become a difference/sum signal
2204 * instead of standard stereo, which is annoying.
2205 * So instead we flip this bit which makes the
2206 * codec replicate the sum signal to both channels,
2207 * turning it into a normal mono mic.
2208 */
2209 /* DMIC_CONTROL? Init value = 0x0001 */
2210 { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b },
2211 { 0x20, AC_VERB_SET_PROC_COEF, 0x0003 },
2212 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2213 { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
2214 { }
Takashi Iwai038d4fe2012-04-11 17:18:12 +02002215 },
2216 .chained = true,
2217 .chain_id = ALC882_FIXUP_GPIO1,
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002218 },
Takashi Iwai56710872011-11-14 17:42:11 +01002219 [ALC885_FIXUP_MACPRO_GPIO] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002220 .type = HDA_FIXUP_FUNC,
Takashi Iwai56710872011-11-14 17:42:11 +01002221 .v.func = alc885_fixup_macpro_gpio,
2222 },
Takashi Iwai02a237b2012-02-13 15:25:07 +01002223 [ALC889_FIXUP_DAC_ROUTE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002224 .type = HDA_FIXUP_FUNC,
Takashi Iwai02a237b2012-02-13 15:25:07 +01002225 .v.func = alc889_fixup_dac_route,
2226 },
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002227 [ALC889_FIXUP_MBP_VREF] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002228 .type = HDA_FIXUP_FUNC,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002229 .v.func = alc889_fixup_mbp_vref,
2230 .chained = true,
2231 .chain_id = ALC882_FIXUP_GPIO1,
2232 },
2233 [ALC889_FIXUP_IMAC91_VREF] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002234 .type = HDA_FIXUP_FUNC,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002235 .v.func = alc889_fixup_imac91_vref,
2236 .chained = true,
2237 .chain_id = ALC882_FIXUP_GPIO1,
2238 },
Adrien Vergée7729a42014-01-24 14:56:14 -05002239 [ALC889_FIXUP_MBA11_VREF] = {
2240 .type = HDA_FIXUP_FUNC,
2241 .v.func = alc889_fixup_mba11_vref,
2242 .chained = true,
2243 .chain_id = ALC889_FIXUP_MBP_VREF,
2244 },
Takashi Iwai0756f092013-12-04 13:59:45 +01002245 [ALC889_FIXUP_MBA21_VREF] = {
2246 .type = HDA_FIXUP_FUNC,
2247 .v.func = alc889_fixup_mba21_vref,
2248 .chained = true,
2249 .chain_id = ALC889_FIXUP_MBP_VREF,
2250 },
Takashi Iwaic20f31e2014-02-03 11:02:10 +01002251 [ALC889_FIXUP_MP11_VREF] = {
2252 .type = HDA_FIXUP_FUNC,
2253 .v.func = alc889_fixup_mba11_vref,
2254 .chained = true,
2255 .chain_id = ALC885_FIXUP_MACPRO_GPIO,
2256 },
Mario Kleiner9f660a12015-12-22 00:45:43 +01002257 [ALC889_FIXUP_MP41_VREF] = {
2258 .type = HDA_FIXUP_FUNC,
2259 .v.func = alc889_fixup_mbp_vref,
2260 .chained = true,
2261 .chain_id = ALC885_FIXUP_MACPRO_GPIO,
2262 },
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002263 [ALC882_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002264 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02002265 .v.func = alc_fixup_inv_dmic,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002266 },
Takashi Iwaie427c232012-07-29 10:04:08 +02002267 [ALC882_FIXUP_NO_PRIMARY_HP] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002268 .type = HDA_FIXUP_FUNC,
Takashi Iwaie427c232012-07-29 10:04:08 +02002269 .v.func = alc882_fixup_no_primary_hp,
2270 },
Takashi Iwai1f0bbf02013-11-28 15:21:21 +01002271 [ALC887_FIXUP_ASUS_BASS] = {
2272 .type = HDA_FIXUP_PINS,
2273 .v.pins = (const struct hda_pintbl[]) {
2274 {0x16, 0x99130130}, /* bass speaker */
2275 {}
2276 },
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01002277 .chained = true,
2278 .chain_id = ALC887_FIXUP_BASS_CHMAP,
2279 },
2280 [ALC887_FIXUP_BASS_CHMAP] = {
2281 .type = HDA_FIXUP_FUNC,
2282 .v.func = alc_fixup_bass_chmap,
Takashi Iwai1f0bbf02013-11-28 15:21:21 +01002283 },
Takashi Iwai7beb3a62017-04-10 18:05:52 +02002284 [ALC1220_FIXUP_GB_DUAL_CODECS] = {
2285 .type = HDA_FIXUP_FUNC,
2286 .v.func = alc1220_fixup_gb_dual_codecs,
2287 },
Peisen0202f5c2017-10-26 10:35:36 +08002288 [ALC1220_FIXUP_CLEVO_P950] = {
2289 .type = HDA_FIXUP_FUNC,
2290 .v.func = alc1220_fixup_clevo_p950,
2291 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02002292};
2293
2294static const struct snd_pci_quirk alc882_fixup_tbl[] = {
Takashi Iwai8812c4f2011-11-09 17:39:15 +01002295 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_FIXUP_ACER_EAPD),
2296 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
Takashi Iwaib5d724b2015-06-02 19:57:08 +02002297 SND_PCI_QUIRK(0x1025, 0x0107, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
Takashi Iwai8812c4f2011-11-09 17:39:15 +01002298 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_FIXUP_ACER_EAPD),
2299 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
2300 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_FIXUP_ACER_EAPD),
2301 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_FIXUP_ACER_EAPD),
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002302 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
2303 ALC882_FIXUP_ACER_ASPIRE_4930G),
2304 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
2305 ALC882_FIXUP_ACER_ASPIRE_4930G),
2306 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
2307 ALC882_FIXUP_ACER_ASPIRE_8930G),
2308 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
2309 ALC882_FIXUP_ACER_ASPIRE_8930G),
2310 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
2311 ALC882_FIXUP_ACER_ASPIRE_4930G),
2312 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
2313 ALC882_FIXUP_ACER_ASPIRE_4930G),
2314 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
2315 ALC882_FIXUP_ACER_ASPIRE_4930G),
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002316 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", ALC882_FIXUP_PB_M5210),
Takashi Iwaif5c53d82012-05-07 10:07:33 +02002317 SND_PCI_QUIRK(0x1025, 0x021e, "Acer Aspire 5739G",
2318 ALC882_FIXUP_ACER_ASPIRE_4930G),
Takashi Iwai02a237b2012-02-13 15:25:07 +01002319 SND_PCI_QUIRK(0x1025, 0x0259, "Acer Aspire 5935", ALC889_FIXUP_DAC_ROUTE),
Takashi Iwaife97da12012-04-12 08:00:19 +02002320 SND_PCI_QUIRK(0x1025, 0x026b, "Acer Aspire 8940G", ALC882_FIXUP_ACER_ASPIRE_8930G),
Takashi Iwaiac9b1cd2011-11-09 17:45:55 +01002321 SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", ALC882_FIXUP_ACER_ASPIRE_7736),
Takashi Iwai177943a2011-11-09 12:55:18 +01002322 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_FIXUP_EAPD),
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002323 SND_PCI_QUIRK(0x1043, 0x1873, "ASUS W90V", ALC882_FIXUP_ASUS_W90V),
Takashi Iwai68ef0562011-11-09 18:24:44 +01002324 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_FIXUP_ASUS_W2JC),
Takashi Iwai0e7cc2e2011-11-09 12:42:48 +01002325 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_FIXUP_EEE1601),
Takashi Iwai1f0bbf02013-11-28 15:21:21 +01002326 SND_PCI_QUIRK(0x1043, 0x84bc, "ASUS ET2700", ALC887_FIXUP_ASUS_BASS),
Takashi Iwai85bcf962016-12-06 16:20:36 +01002327 SND_PCI_QUIRK(0x1043, 0x8691, "ASUS ROG Ranger VIII", ALC882_FIXUP_GPIO3),
Takashi Iwaiac9b1cd2011-11-09 17:45:55 +01002328 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT),
Takashi Iwaie427c232012-07-29 10:04:08 +02002329 SND_PCI_QUIRK(0x104d, 0x905a, "Sony Vaio Z", ALC882_FIXUP_NO_PRIMARY_HP),
Sergei A. Trusov3f3c3712017-08-02 20:23:48 +10002330 SND_PCI_QUIRK(0x104d, 0x9060, "Sony Vaio VPCL14M1R", ALC882_FIXUP_NO_PRIMARY_HP),
Fernando Luis Vázquez Cao12e31a72013-02-12 16:47:44 +09002331 SND_PCI_QUIRK(0x104d, 0x9043, "Sony Vaio VGC-LN51JGB", ALC882_FIXUP_NO_PRIMARY_HP),
Takashi Iwaic44d9b12016-02-07 09:38:26 +01002332 SND_PCI_QUIRK(0x104d, 0x9044, "Sony VAIO AiO", ALC882_FIXUP_NO_PRIMARY_HP),
Takashi Iwai56710872011-11-14 17:42:11 +01002333
2334 /* All Apple entries are in codec SSIDs */
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002335 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC889_FIXUP_MBP_VREF),
2336 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC889_FIXUP_MBP_VREF),
2337 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF),
Takashi Iwaic20f31e2014-02-03 11:02:10 +01002338 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC889_FIXUP_MP11_VREF),
Takashi Iwai56710872011-11-14 17:42:11 +01002339 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_FIXUP_MACPRO_GPIO),
2340 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_FIXUP_MACPRO_GPIO),
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002341 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC889_FIXUP_MBP_VREF),
2342 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889_FIXUP_MBP_VREF),
Takashi Iwai56710872011-11-14 17:42:11 +01002343 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_FIXUP_EAPD),
Adrien Vergée7729a42014-01-24 14:56:14 -05002344 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC889_FIXUP_MBA11_VREF),
Takashi Iwai0756f092013-12-04 13:59:45 +01002345 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC889_FIXUP_MBA21_VREF),
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002346 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889_FIXUP_MBP_VREF),
2347 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF),
Takashi Iwai56710872011-11-14 17:42:11 +01002348 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_FIXUP_MACPRO_GPIO),
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002349 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC889_FIXUP_IMAC91_VREF),
2350 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC889_FIXUP_IMAC91_VREF),
2351 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC889_FIXUP_IMAC91_VREF),
Mario Kleiner9f660a12015-12-22 00:45:43 +01002352 SND_PCI_QUIRK(0x106b, 0x4200, "Mac Pro 4,1/5,1", ALC889_FIXUP_MP41_VREF),
Takashi Iwai05193632012-11-12 10:07:36 +01002353 SND_PCI_QUIRK(0x106b, 0x4300, "iMac 9,1", ALC889_FIXUP_IMAC91_VREF),
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002354 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC889_FIXUP_IMAC91_VREF),
2355 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC889_FIXUP_IMAC91_VREF),
Takashi Iwai649ccd02015-07-30 22:30:29 +02002356 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC889_FIXUP_MBA11_VREF),
Takashi Iwai56710872011-11-14 17:42:11 +01002357
Takashi Iwai7a6069b2011-11-09 15:22:01 +01002358 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC882_FIXUP_EAPD),
David Henningssonb2c53e22014-01-01 14:01:34 +01002359 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3/Z87X-UD3H", ALC889_FIXUP_FRONT_HP_NO_PRESENCE),
Takashi Iwai7beb3a62017-04-10 18:05:52 +02002360 SND_PCI_QUIRK(0x1458, 0xa0b8, "Gigabyte AZ370-Gaming", ALC1220_FIXUP_GB_DUAL_CODECS),
Takashi Iwaid2c3b142017-06-01 09:35:30 +02002361 SND_PCI_QUIRK(0x1462, 0x7350, "MSI-7350", ALC889_FIXUP_CD),
Takashi Iwai63691582017-05-22 16:32:46 +02002362 SND_PCI_QUIRK(0x1462, 0xda57, "MSI Z270-Gaming", ALC1220_FIXUP_GB_DUAL_CODECS),
Takashi Iwaid2c3b142017-06-01 09:35:30 +02002363 SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3),
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002364 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX),
Peisen0202f5c2017-10-26 10:35:36 +08002365 SND_PCI_QUIRK(0x1558, 0x9501, "Clevo P950HR", ALC1220_FIXUP_CLEVO_P950),
Jeremy Soller2f0d5202018-05-07 09:28:45 -06002366 SND_PCI_QUIRK(0x1558, 0x95e2, "Clevo P950ER", ALC1220_FIXUP_CLEVO_P950),
Takashi Iwai7a6069b2011-11-09 15:22:01 +01002367 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD),
2368 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD),
Takashi Iwaiac9b1cd2011-11-09 17:45:55 +01002369 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", ALC882_FIXUP_LENOVO_Y530),
Takashi Iwai68ef0562011-11-09 18:24:44 +01002370 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_FIXUP_COEF),
Takashi Iwai1d045db2011-07-07 18:23:21 +02002371 {}
2372};
2373
Takashi Iwai1727a772013-01-10 09:52:52 +01002374static const struct hda_model_fixup alc882_fixup_models[] = {
Takashi Iwai912093b2012-04-11 14:03:41 +02002375 {.id = ALC882_FIXUP_ACER_ASPIRE_4930G, .name = "acer-aspire-4930g"},
2376 {.id = ALC882_FIXUP_ACER_ASPIRE_8930G, .name = "acer-aspire-8930g"},
2377 {.id = ALC883_FIXUP_ACER_EAPD, .name = "acer-aspire"},
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002378 {.id = ALC882_FIXUP_INV_DMIC, .name = "inv-dmic"},
Takashi Iwaie427c232012-07-29 10:04:08 +02002379 {.id = ALC882_FIXUP_NO_PRIMARY_HP, .name = "no-primary-hp"},
Takashi Iwaiba90d6a2017-05-22 16:38:47 +02002380 {.id = ALC1220_FIXUP_GB_DUAL_CODECS, .name = "dual-codecs"},
Takashi Iwai912093b2012-04-11 14:03:41 +02002381 {}
2382};
2383
Takashi Iwai1d045db2011-07-07 18:23:21 +02002384/*
2385 * BIOS auto configuration
2386 */
2387/* almost identical with ALC880 parser... */
2388static int alc882_parse_auto_config(struct hda_codec *codec)
2389{
Takashi Iwai1d045db2011-07-07 18:23:21 +02002390 static const hda_nid_t alc882_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002391 static const hda_nid_t alc882_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2392 return alc_parse_auto_config(codec, alc882_ignore, alc882_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002393}
2394
Takashi Iwai1d045db2011-07-07 18:23:21 +02002395/*
2396 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002397static int patch_alc882(struct hda_codec *codec)
2398{
2399 struct alc_spec *spec;
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002400 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002401
Takashi Iwai3de95172012-05-07 18:03:15 +02002402 err = alc_alloc_spec(codec, 0x0b);
2403 if (err < 0)
2404 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002405
Takashi Iwai3de95172012-05-07 18:03:15 +02002406 spec = codec->spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002407
Takashi Iwai7639a062015-03-03 10:07:24 +01002408 switch (codec->core.vendor_id) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002409 case 0x10ec0882:
2410 case 0x10ec0885:
Takashi Iwaiacf08082014-09-02 07:21:56 +02002411 case 0x10ec0900:
Kailang Yanga535ad52017-01-16 16:59:26 +08002412 case 0x10ec1220:
Takashi Iwai1d045db2011-07-07 18:23:21 +02002413 break;
2414 default:
2415 /* ALC883 and variants */
2416 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
2417 break;
2418 }
2419
Takashi Iwai1727a772013-01-10 09:52:52 +01002420 snd_hda_pick_fixup(codec, alc882_fixup_models, alc882_fixup_tbl,
Takashi Iwai912093b2012-04-11 14:03:41 +02002421 alc882_fixups);
Takashi Iwai1727a772013-01-10 09:52:52 +01002422 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002423
2424 alc_auto_parse_customize_define(codec);
2425
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002426 if (has_cdefine_beep(codec))
2427 spec->gen.beep_nid = 0x01;
2428
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002429 /* automatic parse from the BIOS config */
2430 err = alc882_parse_auto_config(codec);
2431 if (err < 0)
2432 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002433
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002434 if (!spec->gen.no_analog && spec->gen.beep_nid)
Takashi Iwai1d045db2011-07-07 18:23:21 +02002435 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
2436
Takashi Iwai1727a772013-01-10 09:52:52 +01002437 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01002438
Takashi Iwai1d045db2011-07-07 18:23:21 +02002439 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02002440
2441 error:
2442 alc_free(codec);
2443 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002444}
2445
2446
2447/*
2448 * ALC262 support
2449 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002450static int alc262_parse_auto_config(struct hda_codec *codec)
2451{
Takashi Iwai1d045db2011-07-07 18:23:21 +02002452 static const hda_nid_t alc262_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002453 static const hda_nid_t alc262_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2454 return alc_parse_auto_config(codec, alc262_ignore, alc262_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002455}
2456
2457/*
2458 * Pin config fixes
2459 */
2460enum {
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002461 ALC262_FIXUP_FSC_H270,
Takashi Iwai7513e6d2013-01-18 15:41:34 +01002462 ALC262_FIXUP_FSC_S7110,
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002463 ALC262_FIXUP_HP_Z200,
2464 ALC262_FIXUP_TYAN,
Takashi Iwaic4701502011-11-07 14:20:07 +01002465 ALC262_FIXUP_LENOVO_3000,
Takashi Iwaib42590b2011-11-07 14:41:01 +01002466 ALC262_FIXUP_BENQ,
2467 ALC262_FIXUP_BENQ_T31,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002468 ALC262_FIXUP_INV_DMIC,
Mengdong Linb5c66112013-11-29 00:35:35 -05002469 ALC262_FIXUP_INTEL_BAYLEYBAY,
Takashi Iwai1d045db2011-07-07 18:23:21 +02002470};
2471
Takashi Iwai1727a772013-01-10 09:52:52 +01002472static const struct hda_fixup alc262_fixups[] = {
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002473 [ALC262_FIXUP_FSC_H270] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002474 .type = HDA_FIXUP_PINS,
2475 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002476 { 0x14, 0x99130110 }, /* speaker */
2477 { 0x15, 0x0221142f }, /* front HP */
2478 { 0x1b, 0x0121141f }, /* rear HP */
2479 { }
2480 }
2481 },
Takashi Iwai7513e6d2013-01-18 15:41:34 +01002482 [ALC262_FIXUP_FSC_S7110] = {
2483 .type = HDA_FIXUP_PINS,
2484 .v.pins = (const struct hda_pintbl[]) {
2485 { 0x15, 0x90170110 }, /* speaker */
2486 { }
2487 },
2488 .chained = true,
2489 .chain_id = ALC262_FIXUP_BENQ,
2490 },
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002491 [ALC262_FIXUP_HP_Z200] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002492 .type = HDA_FIXUP_PINS,
2493 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002494 { 0x16, 0x99130120 }, /* internal speaker */
2495 { }
2496 }
2497 },
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002498 [ALC262_FIXUP_TYAN] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002499 .type = HDA_FIXUP_PINS,
2500 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002501 { 0x14, 0x1993e1f0 }, /* int AUX */
2502 { }
2503 }
2504 },
Takashi Iwaic4701502011-11-07 14:20:07 +01002505 [ALC262_FIXUP_LENOVO_3000] = {
Takashi Iwaifd108212013-01-10 10:18:14 +01002506 .type = HDA_FIXUP_PINCTLS,
2507 .v.pins = (const struct hda_pintbl[]) {
2508 { 0x19, PIN_VREF50 },
Takashi Iwaib42590b2011-11-07 14:41:01 +01002509 {}
2510 },
2511 .chained = true,
2512 .chain_id = ALC262_FIXUP_BENQ,
2513 },
2514 [ALC262_FIXUP_BENQ] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002515 .type = HDA_FIXUP_VERBS,
Takashi Iwaib42590b2011-11-07 14:41:01 +01002516 .v.verbs = (const struct hda_verb[]) {
Takashi Iwaic4701502011-11-07 14:20:07 +01002517 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2518 { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
2519 {}
2520 }
2521 },
Takashi Iwaib42590b2011-11-07 14:41:01 +01002522 [ALC262_FIXUP_BENQ_T31] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002523 .type = HDA_FIXUP_VERBS,
Takashi Iwaib42590b2011-11-07 14:41:01 +01002524 .v.verbs = (const struct hda_verb[]) {
2525 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2526 { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
2527 {}
2528 }
2529 },
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002530 [ALC262_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002531 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02002532 .v.func = alc_fixup_inv_dmic,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002533 },
Mengdong Linb5c66112013-11-29 00:35:35 -05002534 [ALC262_FIXUP_INTEL_BAYLEYBAY] = {
2535 .type = HDA_FIXUP_FUNC,
2536 .v.func = alc_fixup_no_depop_delay,
2537 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02002538};
2539
2540static const struct snd_pci_quirk alc262_fixup_tbl[] = {
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002541 SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", ALC262_FIXUP_HP_Z200),
Takashi Iwai7513e6d2013-01-18 15:41:34 +01002542 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu Lifebook S7110", ALC262_FIXUP_FSC_S7110),
Takashi Iwai3dcd3be2011-11-07 14:59:40 +01002543 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FIXUP_BENQ),
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002544 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_FIXUP_TYAN),
2545 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", ALC262_FIXUP_FSC_H270),
Takashi Iwaic4701502011-11-07 14:20:07 +01002546 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000", ALC262_FIXUP_LENOVO_3000),
Takashi Iwaib42590b2011-11-07 14:41:01 +01002547 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_FIXUP_BENQ),
2548 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_FIXUP_BENQ_T31),
Mengdong Linb5c66112013-11-29 00:35:35 -05002549 SND_PCI_QUIRK(0x8086, 0x7270, "BayleyBay", ALC262_FIXUP_INTEL_BAYLEYBAY),
Takashi Iwai1d045db2011-07-07 18:23:21 +02002550 {}
2551};
2552
Takashi Iwai1727a772013-01-10 09:52:52 +01002553static const struct hda_model_fixup alc262_fixup_models[] = {
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002554 {.id = ALC262_FIXUP_INV_DMIC, .name = "inv-dmic"},
2555 {}
2556};
Takashi Iwai1d045db2011-07-07 18:23:21 +02002557
Takashi Iwai1d045db2011-07-07 18:23:21 +02002558/*
2559 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002560static int patch_alc262(struct hda_codec *codec)
2561{
2562 struct alc_spec *spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002563 int err;
2564
Takashi Iwai3de95172012-05-07 18:03:15 +02002565 err = alc_alloc_spec(codec, 0x0b);
2566 if (err < 0)
2567 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002568
Takashi Iwai3de95172012-05-07 18:03:15 +02002569 spec = codec->spec;
Takashi Iwai08c189f2012-12-19 15:22:24 +01002570 spec->gen.shared_mic_vref_pin = 0x18;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002571
Takashi Iwai225068a2015-05-29 10:42:14 +02002572 spec->shutup = alc_eapd_shutup;
2573
Takashi Iwai1d045db2011-07-07 18:23:21 +02002574#if 0
2575 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
2576 * under-run
2577 */
Takashi Iwai98b24882014-08-18 13:47:50 +02002578 alc_update_coefex_idx(codec, 0x1a, 7, 0, 0x80);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002579#endif
Takashi Iwai1d045db2011-07-07 18:23:21 +02002580 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
2581
Takashi Iwai1727a772013-01-10 09:52:52 +01002582 snd_hda_pick_fixup(codec, alc262_fixup_models, alc262_fixup_tbl,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002583 alc262_fixups);
Takashi Iwai1727a772013-01-10 09:52:52 +01002584 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002585
Takashi Iwaiaf741c12012-05-07 18:09:48 +02002586 alc_auto_parse_customize_define(codec);
2587
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002588 if (has_cdefine_beep(codec))
2589 spec->gen.beep_nid = 0x01;
2590
Takashi Iwai42399f72011-11-07 17:18:44 +01002591 /* automatic parse from the BIOS config */
2592 err = alc262_parse_auto_config(codec);
2593 if (err < 0)
2594 goto error;
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002595
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002596 if (!spec->gen.no_analog && spec->gen.beep_nid)
Takashi Iwai1d045db2011-07-07 18:23:21 +02002597 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
2598
Takashi Iwai1727a772013-01-10 09:52:52 +01002599 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01002600
Takashi Iwai1d045db2011-07-07 18:23:21 +02002601 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02002602
2603 error:
2604 alc_free(codec);
2605 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002606}
2607
2608/*
2609 * ALC268
2610 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002611/* bind Beep switches of both NID 0x0f and 0x10 */
Takashi Iwaia7177772017-05-10 12:04:08 +02002612static int alc268_beep_switch_put(struct snd_kcontrol *kcontrol,
2613 struct snd_ctl_elem_value *ucontrol)
2614{
2615 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2616 unsigned long pval;
2617 int err;
2618
2619 mutex_lock(&codec->control_mutex);
2620 pval = kcontrol->private_value;
2621 kcontrol->private_value = (pval & ~0xff) | 0x0f;
2622 err = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
2623 if (err >= 0) {
2624 kcontrol->private_value = (pval & ~0xff) | 0x10;
2625 err = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
2626 }
2627 kcontrol->private_value = pval;
2628 mutex_unlock(&codec->control_mutex);
2629 return err;
2630}
Takashi Iwai1d045db2011-07-07 18:23:21 +02002631
2632static const struct snd_kcontrol_new alc268_beep_mixer[] = {
2633 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
Takashi Iwaia7177772017-05-10 12:04:08 +02002634 {
2635 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2636 .name = "Beep Playback Switch",
2637 .subdevice = HDA_SUBDEV_AMP_FLAG,
2638 .info = snd_hda_mixer_amp_switch_info,
2639 .get = snd_hda_mixer_amp_switch_get,
2640 .put = alc268_beep_switch_put,
2641 .private_value = HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT)
2642 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02002643 { }
2644};
2645
2646/* set PCBEEP vol = 0, mute connections */
2647static const struct hda_verb alc268_beep_init_verbs[] = {
2648 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2649 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2650 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2651 { }
2652};
2653
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002654enum {
2655 ALC268_FIXUP_INV_DMIC,
Takashi Iwaicb766402012-10-20 10:55:21 +02002656 ALC268_FIXUP_HP_EAPD,
Takashi Iwai24eff322013-11-04 18:21:08 +01002657 ALC268_FIXUP_SPDIF,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002658};
2659
Takashi Iwai1727a772013-01-10 09:52:52 +01002660static const struct hda_fixup alc268_fixups[] = {
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002661 [ALC268_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002662 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02002663 .v.func = alc_fixup_inv_dmic,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002664 },
Takashi Iwaicb766402012-10-20 10:55:21 +02002665 [ALC268_FIXUP_HP_EAPD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002666 .type = HDA_FIXUP_VERBS,
Takashi Iwaicb766402012-10-20 10:55:21 +02002667 .v.verbs = (const struct hda_verb[]) {
2668 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 0},
2669 {}
2670 }
2671 },
Takashi Iwai24eff322013-11-04 18:21:08 +01002672 [ALC268_FIXUP_SPDIF] = {
2673 .type = HDA_FIXUP_PINS,
2674 .v.pins = (const struct hda_pintbl[]) {
2675 { 0x1e, 0x014b1180 }, /* enable SPDIF out */
2676 {}
2677 }
2678 },
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002679};
2680
Takashi Iwai1727a772013-01-10 09:52:52 +01002681static const struct hda_model_fixup alc268_fixup_models[] = {
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002682 {.id = ALC268_FIXUP_INV_DMIC, .name = "inv-dmic"},
Takashi Iwaicb766402012-10-20 10:55:21 +02002683 {.id = ALC268_FIXUP_HP_EAPD, .name = "hp-eapd"},
2684 {}
2685};
2686
2687static const struct snd_pci_quirk alc268_fixup_tbl[] = {
Takashi Iwai24eff322013-11-04 18:21:08 +01002688 SND_PCI_QUIRK(0x1025, 0x0139, "Acer TravelMate 6293", ALC268_FIXUP_SPDIF),
David Henningssonfcd8f3b2013-01-28 05:45:47 +01002689 SND_PCI_QUIRK(0x1025, 0x015b, "Acer AOA 150 (ZG5)", ALC268_FIXUP_INV_DMIC),
Takashi Iwaicb766402012-10-20 10:55:21 +02002690 /* below is codec SSID since multiple Toshiba laptops have the
2691 * same PCI SSID 1179:ff00
2692 */
2693 SND_PCI_QUIRK(0x1179, 0xff06, "Toshiba P200", ALC268_FIXUP_HP_EAPD),
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002694 {}
2695};
2696
Takashi Iwai1d045db2011-07-07 18:23:21 +02002697/*
2698 * BIOS auto configuration
2699 */
2700static int alc268_parse_auto_config(struct hda_codec *codec)
2701{
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002702 static const hda_nid_t alc268_ssids[] = { 0x15, 0x1b, 0x14, 0 };
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002703 return alc_parse_auto_config(codec, NULL, alc268_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002704}
2705
Takashi Iwai1d045db2011-07-07 18:23:21 +02002706/*
2707 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002708static int patch_alc268(struct hda_codec *codec)
2709{
2710 struct alc_spec *spec;
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002711 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002712
Takashi Iwai1d045db2011-07-07 18:23:21 +02002713 /* ALC268 has no aa-loopback mixer */
Takashi Iwai3de95172012-05-07 18:03:15 +02002714 err = alc_alloc_spec(codec, 0);
2715 if (err < 0)
2716 return err;
2717
2718 spec = codec->spec;
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002719 spec->gen.beep_nid = 0x01;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002720
Takashi Iwai225068a2015-05-29 10:42:14 +02002721 spec->shutup = alc_eapd_shutup;
2722
Takashi Iwai1727a772013-01-10 09:52:52 +01002723 snd_hda_pick_fixup(codec, alc268_fixup_models, alc268_fixup_tbl, alc268_fixups);
2724 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002725
Takashi Iwai6ebb8052011-08-16 15:15:40 +02002726 /* automatic parse from the BIOS config */
2727 err = alc268_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02002728 if (err < 0)
2729 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002730
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002731 if (err > 0 && !spec->gen.no_analog &&
2732 spec->gen.autocfg.speaker_pins[0] != 0x1d) {
2733 add_mixer(spec, alc268_beep_mixer);
2734 snd_hda_add_verbs(codec, alc268_beep_init_verbs);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002735 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
2736 /* override the amp caps for beep generator */
2737 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
2738 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
2739 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
2740 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
2741 (0 << AC_AMPCAP_MUTE_SHIFT));
2742 }
2743
Takashi Iwai1727a772013-01-10 09:52:52 +01002744 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002745
Takashi Iwai1d045db2011-07-07 18:23:21 +02002746 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02002747
2748 error:
2749 alc_free(codec);
2750 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002751}
2752
2753/*
2754 * ALC269
2755 */
Takashi Iwai08c189f2012-12-19 15:22:24 +01002756
Takashi Iwai1d045db2011-07-07 18:23:21 +02002757static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002758 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002759};
2760
2761static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002762 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002763};
2764
Takashi Iwai1d045db2011-07-07 18:23:21 +02002765/* different alc269-variants */
2766enum {
2767 ALC269_TYPE_ALC269VA,
2768 ALC269_TYPE_ALC269VB,
2769 ALC269_TYPE_ALC269VC,
Kailang Yangadcc70b2012-05-25 08:08:38 +02002770 ALC269_TYPE_ALC269VD,
Kailang Yang065380f2013-01-10 10:25:48 +01002771 ALC269_TYPE_ALC280,
2772 ALC269_TYPE_ALC282,
Kailang Yang2af02be2013-08-22 10:03:50 +02002773 ALC269_TYPE_ALC283,
Kailang Yang065380f2013-01-10 10:25:48 +01002774 ALC269_TYPE_ALC284,
Kailang Yang4731d5d2017-06-30 15:22:57 +08002775 ALC269_TYPE_ALC293,
Kailang Yang7fc7d042013-04-25 11:04:43 +02002776 ALC269_TYPE_ALC286,
Kailang Yang506b62c2014-12-18 17:07:44 +08002777 ALC269_TYPE_ALC298,
Kailang Yang1d04c9d2013-10-24 11:35:18 +02002778 ALC269_TYPE_ALC255,
Kailang Yang4344aec2014-12-17 17:39:05 +08002779 ALC269_TYPE_ALC256,
Kailang Yangf429e7e2017-12-05 15:38:24 +08002780 ALC269_TYPE_ALC257,
Kailang Yang0a6f0602017-06-30 16:00:48 +08002781 ALC269_TYPE_ALC215,
Kailang Yang42314302016-02-03 15:03:50 +08002782 ALC269_TYPE_ALC225,
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08002783 ALC269_TYPE_ALC294,
Kailang Yang6fbae352016-05-30 16:44:20 +08002784 ALC269_TYPE_ALC700,
Takashi Iwai1d045db2011-07-07 18:23:21 +02002785};
2786
2787/*
2788 * BIOS auto configuration
2789 */
2790static int alc269_parse_auto_config(struct hda_codec *codec)
2791{
Takashi Iwai1d045db2011-07-07 18:23:21 +02002792 static const hda_nid_t alc269_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002793 static const hda_nid_t alc269_ssids[] = { 0, 0x1b, 0x14, 0x21 };
2794 static const hda_nid_t alc269va_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2795 struct alc_spec *spec = codec->spec;
Kailang Yangadcc70b2012-05-25 08:08:38 +02002796 const hda_nid_t *ssids;
2797
2798 switch (spec->codec_variant) {
2799 case ALC269_TYPE_ALC269VA:
2800 case ALC269_TYPE_ALC269VC:
Kailang Yang065380f2013-01-10 10:25:48 +01002801 case ALC269_TYPE_ALC280:
2802 case ALC269_TYPE_ALC284:
Kailang Yang4731d5d2017-06-30 15:22:57 +08002803 case ALC269_TYPE_ALC293:
Kailang Yangadcc70b2012-05-25 08:08:38 +02002804 ssids = alc269va_ssids;
2805 break;
2806 case ALC269_TYPE_ALC269VB:
2807 case ALC269_TYPE_ALC269VD:
Kailang Yang065380f2013-01-10 10:25:48 +01002808 case ALC269_TYPE_ALC282:
Kailang Yang2af02be2013-08-22 10:03:50 +02002809 case ALC269_TYPE_ALC283:
Kailang Yang7fc7d042013-04-25 11:04:43 +02002810 case ALC269_TYPE_ALC286:
Kailang Yang506b62c2014-12-18 17:07:44 +08002811 case ALC269_TYPE_ALC298:
Kailang Yang1d04c9d2013-10-24 11:35:18 +02002812 case ALC269_TYPE_ALC255:
Kailang Yang4344aec2014-12-17 17:39:05 +08002813 case ALC269_TYPE_ALC256:
Kailang Yangf429e7e2017-12-05 15:38:24 +08002814 case ALC269_TYPE_ALC257:
Kailang Yang0a6f0602017-06-30 16:00:48 +08002815 case ALC269_TYPE_ALC215:
Kailang Yang42314302016-02-03 15:03:50 +08002816 case ALC269_TYPE_ALC225:
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08002817 case ALC269_TYPE_ALC294:
Kailang Yang6fbae352016-05-30 16:44:20 +08002818 case ALC269_TYPE_ALC700:
Kailang Yangadcc70b2012-05-25 08:08:38 +02002819 ssids = alc269_ssids;
2820 break;
2821 default:
2822 ssids = alc269_ssids;
2823 break;
2824 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02002825
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002826 return alc_parse_auto_config(codec, alc269_ignore, ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002827}
2828
Kailang Yangf7ae9ba2014-06-30 16:10:37 +08002829static int find_ext_mic_pin(struct hda_codec *codec);
2830
2831static void alc286_shutup(struct hda_codec *codec)
2832{
Takashi Iwaia9c2dfc2018-04-23 17:24:56 +02002833 const struct hda_pincfg *pin;
Kailang Yangf7ae9ba2014-06-30 16:10:37 +08002834 int i;
2835 int mic_pin = find_ext_mic_pin(codec);
2836 /* don't shut up pins when unloading the driver; otherwise it breaks
2837 * the default pin setup at the next load of the driver
2838 */
2839 if (codec->bus->shutdown)
2840 return;
Takashi Iwaia9c2dfc2018-04-23 17:24:56 +02002841 snd_array_for_each(&codec->init_pins, i, pin) {
Kailang Yangf7ae9ba2014-06-30 16:10:37 +08002842 /* use read here for syncing after issuing each verb */
2843 if (pin->nid != mic_pin)
2844 snd_hda_codec_read(codec, pin->nid, 0,
2845 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
2846 }
2847 codec->pins_shutup = 1;
2848}
2849
Kailang Yang1387e2d2012-11-08 10:23:18 +01002850static void alc269vb_toggle_power_output(struct hda_codec *codec, int power_up)
Takashi Iwai1d045db2011-07-07 18:23:21 +02002851{
Takashi Iwai98b24882014-08-18 13:47:50 +02002852 alc_update_coef_idx(codec, 0x04, 1 << 11, power_up ? (1 << 11) : 0);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002853}
2854
2855static void alc269_shutup(struct hda_codec *codec)
2856{
Kailang Yangadcc70b2012-05-25 08:08:38 +02002857 struct alc_spec *spec = codec->spec;
2858
Kailang Yang1387e2d2012-11-08 10:23:18 +01002859 if (spec->codec_variant == ALC269_TYPE_ALC269VB)
2860 alc269vb_toggle_power_output(codec, 0);
2861 if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
2862 (alc_get_coef0(codec) & 0x00ff) == 0x018) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002863 msleep(150);
2864 }
Takashi Iwai9bfb2842013-07-24 14:31:50 +02002865 snd_hda_shutup_pins(codec);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002866}
2867
Takashi Iwai54db6c32014-08-18 15:11:19 +02002868static struct coef_fw alc282_coefs[] = {
2869 WRITE_COEF(0x03, 0x0002), /* Power Down Control */
Kailang Yang32fa7e42014-10-24 16:26:01 +08002870 UPDATE_COEF(0x05, 0xff3f, 0x0700), /* FIFO and filter clock */
Takashi Iwai54db6c32014-08-18 15:11:19 +02002871 WRITE_COEF(0x07, 0x0200), /* DMIC control */
2872 UPDATE_COEF(0x06, 0x00f0, 0), /* Analog clock */
2873 UPDATE_COEF(0x08, 0xfffc, 0x0c2c), /* JD */
2874 WRITE_COEF(0x0a, 0xcccc), /* JD offset1 */
2875 WRITE_COEF(0x0b, 0xcccc), /* JD offset2 */
2876 WRITE_COEF(0x0e, 0x6e00), /* LDO1/2/3, DAC/ADC */
2877 UPDATE_COEF(0x0f, 0xf800, 0x1000), /* JD */
2878 UPDATE_COEF(0x10, 0xfc00, 0x0c00), /* Capless */
2879 WRITE_COEF(0x6f, 0x0), /* Class D test 4 */
2880 UPDATE_COEF(0x0c, 0xfe00, 0), /* IO power down directly */
2881 WRITE_COEF(0x34, 0xa0c0), /* ANC */
2882 UPDATE_COEF(0x16, 0x0008, 0), /* AGC MUX */
2883 UPDATE_COEF(0x1d, 0x00e0, 0), /* DAC simple content protection */
2884 UPDATE_COEF(0x1f, 0x00e0, 0), /* ADC simple content protection */
2885 WRITE_COEF(0x21, 0x8804), /* DAC ADC Zero Detection */
2886 WRITE_COEF(0x63, 0x2902), /* PLL */
2887 WRITE_COEF(0x68, 0xa080), /* capless control 2 */
2888 WRITE_COEF(0x69, 0x3400), /* capless control 3 */
2889 WRITE_COEF(0x6a, 0x2f3e), /* capless control 4 */
2890 WRITE_COEF(0x6b, 0x0), /* capless control 5 */
2891 UPDATE_COEF(0x6d, 0x0fff, 0x0900), /* class D test 2 */
2892 WRITE_COEF(0x6e, 0x110a), /* class D test 3 */
2893 UPDATE_COEF(0x70, 0x00f8, 0x00d8), /* class D test 5 */
2894 WRITE_COEF(0x71, 0x0014), /* class D test 6 */
2895 WRITE_COEF(0x72, 0xc2ba), /* classD OCP */
2896 UPDATE_COEF(0x77, 0x0f80, 0), /* classD pure DC test */
2897 WRITE_COEF(0x6c, 0xfc06), /* Class D amp control */
2898 {}
2899};
2900
Kailang Yangcb149cb2014-03-18 16:45:32 +08002901static void alc282_restore_default_value(struct hda_codec *codec)
2902{
Takashi Iwai54db6c32014-08-18 15:11:19 +02002903 alc_process_coef_fw(codec, alc282_coefs);
Kailang Yangcb149cb2014-03-18 16:45:32 +08002904}
2905
Kailang Yang7b5c7a02014-03-18 16:15:54 +08002906static void alc282_init(struct hda_codec *codec)
2907{
2908 struct alc_spec *spec = codec->spec;
2909 hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
2910 bool hp_pin_sense;
2911 int coef78;
2912
Kailang Yangcb149cb2014-03-18 16:45:32 +08002913 alc282_restore_default_value(codec);
2914
Kailang Yang7b5c7a02014-03-18 16:15:54 +08002915 if (!hp_pin)
2916 return;
2917 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
2918 coef78 = alc_read_coef_idx(codec, 0x78);
2919
2920 /* Index 0x78 Direct Drive HP AMP LPM Control 1 */
2921 /* Headphone capless set to high power mode */
2922 alc_write_coef_idx(codec, 0x78, 0x9004);
2923
2924 if (hp_pin_sense)
2925 msleep(2);
2926
2927 snd_hda_codec_write(codec, hp_pin, 0,
2928 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
2929
2930 if (hp_pin_sense)
2931 msleep(85);
2932
2933 snd_hda_codec_write(codec, hp_pin, 0,
2934 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
2935
2936 if (hp_pin_sense)
2937 msleep(100);
2938
2939 /* Headphone capless set to normal mode */
2940 alc_write_coef_idx(codec, 0x78, coef78);
2941}
2942
2943static void alc282_shutup(struct hda_codec *codec)
2944{
2945 struct alc_spec *spec = codec->spec;
2946 hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
2947 bool hp_pin_sense;
2948 int coef78;
2949
2950 if (!hp_pin) {
2951 alc269_shutup(codec);
2952 return;
2953 }
2954
2955 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
2956 coef78 = alc_read_coef_idx(codec, 0x78);
2957 alc_write_coef_idx(codec, 0x78, 0x9004);
2958
2959 if (hp_pin_sense)
2960 msleep(2);
2961
2962 snd_hda_codec_write(codec, hp_pin, 0,
2963 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
2964
2965 if (hp_pin_sense)
2966 msleep(85);
2967
2968 snd_hda_codec_write(codec, hp_pin, 0,
2969 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
2970
2971 if (hp_pin_sense)
2972 msleep(100);
2973
2974 alc_auto_setup_eapd(codec, false);
2975 snd_hda_shutup_pins(codec);
2976 alc_write_coef_idx(codec, 0x78, coef78);
2977}
2978
Takashi Iwai54db6c32014-08-18 15:11:19 +02002979static struct coef_fw alc283_coefs[] = {
2980 WRITE_COEF(0x03, 0x0002), /* Power Down Control */
Kailang Yang56779862014-10-24 16:17:51 +08002981 UPDATE_COEF(0x05, 0xff3f, 0x0700), /* FIFO and filter clock */
Takashi Iwai54db6c32014-08-18 15:11:19 +02002982 WRITE_COEF(0x07, 0x0200), /* DMIC control */
2983 UPDATE_COEF(0x06, 0x00f0, 0), /* Analog clock */
2984 UPDATE_COEF(0x08, 0xfffc, 0x0c2c), /* JD */
2985 WRITE_COEF(0x0a, 0xcccc), /* JD offset1 */
2986 WRITE_COEF(0x0b, 0xcccc), /* JD offset2 */
2987 WRITE_COEF(0x0e, 0x6fc0), /* LDO1/2/3, DAC/ADC */
2988 UPDATE_COEF(0x0f, 0xf800, 0x1000), /* JD */
2989 UPDATE_COEF(0x10, 0xfc00, 0x0c00), /* Capless */
2990 WRITE_COEF(0x3a, 0x0), /* Class D test 4 */
2991 UPDATE_COEF(0x0c, 0xfe00, 0x0), /* IO power down directly */
2992 WRITE_COEF(0x22, 0xa0c0), /* ANC */
2993 UPDATE_COEFEX(0x53, 0x01, 0x000f, 0x0008), /* AGC MUX */
2994 UPDATE_COEF(0x1d, 0x00e0, 0), /* DAC simple content protection */
2995 UPDATE_COEF(0x1f, 0x00e0, 0), /* ADC simple content protection */
2996 WRITE_COEF(0x21, 0x8804), /* DAC ADC Zero Detection */
2997 WRITE_COEF(0x2e, 0x2902), /* PLL */
2998 WRITE_COEF(0x33, 0xa080), /* capless control 2 */
2999 WRITE_COEF(0x34, 0x3400), /* capless control 3 */
3000 WRITE_COEF(0x35, 0x2f3e), /* capless control 4 */
3001 WRITE_COEF(0x36, 0x0), /* capless control 5 */
3002 UPDATE_COEF(0x38, 0x0fff, 0x0900), /* class D test 2 */
3003 WRITE_COEF(0x39, 0x110a), /* class D test 3 */
3004 UPDATE_COEF(0x3b, 0x00f8, 0x00d8), /* class D test 5 */
3005 WRITE_COEF(0x3c, 0x0014), /* class D test 6 */
3006 WRITE_COEF(0x3d, 0xc2ba), /* classD OCP */
3007 UPDATE_COEF(0x42, 0x0f80, 0x0), /* classD pure DC test */
3008 WRITE_COEF(0x49, 0x0), /* test mode */
3009 UPDATE_COEF(0x40, 0xf800, 0x9800), /* Class D DC enable */
3010 UPDATE_COEF(0x42, 0xf000, 0x2000), /* DC offset */
3011 WRITE_COEF(0x37, 0xfc06), /* Class D amp control */
Kailang Yang56779862014-10-24 16:17:51 +08003012 UPDATE_COEF(0x1b, 0x8000, 0), /* HP JD control */
Takashi Iwai54db6c32014-08-18 15:11:19 +02003013 {}
3014};
3015
Kailang Yang6bd55b02014-03-17 13:51:27 +08003016static void alc283_restore_default_value(struct hda_codec *codec)
3017{
Takashi Iwai54db6c32014-08-18 15:11:19 +02003018 alc_process_coef_fw(codec, alc283_coefs);
Kailang Yang6bd55b02014-03-17 13:51:27 +08003019}
3020
Kailang Yang2af02be2013-08-22 10:03:50 +02003021static void alc283_init(struct hda_codec *codec)
3022{
3023 struct alc_spec *spec = codec->spec;
3024 hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
3025 bool hp_pin_sense;
Kailang Yang2af02be2013-08-22 10:03:50 +02003026
Kailang Yang8314f222014-04-03 17:28:39 +08003027 if (!spec->gen.autocfg.hp_outs) {
3028 if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
3029 hp_pin = spec->gen.autocfg.line_out_pins[0];
3030 }
3031
Kailang Yang6bd55b02014-03-17 13:51:27 +08003032 alc283_restore_default_value(codec);
3033
Kailang Yang2af02be2013-08-22 10:03:50 +02003034 if (!hp_pin)
3035 return;
Kailang Yanga59d7192015-04-08 16:34:00 +08003036
3037 msleep(30);
Kailang Yang2af02be2013-08-22 10:03:50 +02003038 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3039
3040 /* Index 0x43 Direct Drive HP AMP LPM Control 1 */
3041 /* Headphone capless set to high power mode */
3042 alc_write_coef_idx(codec, 0x43, 0x9004);
3043
3044 snd_hda_codec_write(codec, hp_pin, 0,
3045 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3046
3047 if (hp_pin_sense)
3048 msleep(85);
3049
3050 snd_hda_codec_write(codec, hp_pin, 0,
3051 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3052
3053 if (hp_pin_sense)
3054 msleep(85);
3055 /* Index 0x46 Combo jack auto switch control 2 */
3056 /* 3k pull low control for Headset jack. */
Takashi Iwai98b24882014-08-18 13:47:50 +02003057 alc_update_coef_idx(codec, 0x46, 3 << 12, 0);
Kailang Yang2af02be2013-08-22 10:03:50 +02003058 /* Headphone capless set to normal mode */
3059 alc_write_coef_idx(codec, 0x43, 0x9614);
3060}
3061
3062static void alc283_shutup(struct hda_codec *codec)
3063{
3064 struct alc_spec *spec = codec->spec;
3065 hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
3066 bool hp_pin_sense;
Kailang Yang2af02be2013-08-22 10:03:50 +02003067
Kailang Yang8314f222014-04-03 17:28:39 +08003068 if (!spec->gen.autocfg.hp_outs) {
3069 if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
3070 hp_pin = spec->gen.autocfg.line_out_pins[0];
3071 }
3072
Kailang Yang2af02be2013-08-22 10:03:50 +02003073 if (!hp_pin) {
3074 alc269_shutup(codec);
3075 return;
3076 }
3077
3078 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3079
3080 alc_write_coef_idx(codec, 0x43, 0x9004);
3081
Harsha Priyab450b172014-10-09 11:04:56 +00003082 /*depop hp during suspend*/
3083 alc_write_coef_idx(codec, 0x06, 0x2100);
3084
Kailang Yang2af02be2013-08-22 10:03:50 +02003085 snd_hda_codec_write(codec, hp_pin, 0,
3086 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3087
3088 if (hp_pin_sense)
Kailang Yang88011c092013-10-24 15:45:24 +02003089 msleep(100);
Kailang Yang2af02be2013-08-22 10:03:50 +02003090
3091 snd_hda_codec_write(codec, hp_pin, 0,
3092 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
3093
Takashi Iwai98b24882014-08-18 13:47:50 +02003094 alc_update_coef_idx(codec, 0x46, 0, 3 << 12);
Kailang Yang2af02be2013-08-22 10:03:50 +02003095
3096 if (hp_pin_sense)
Kailang Yang88011c092013-10-24 15:45:24 +02003097 msleep(100);
Kailang Yang0435b3f2014-04-08 17:14:14 +08003098 alc_auto_setup_eapd(codec, false);
Kailang Yang2af02be2013-08-22 10:03:50 +02003099 snd_hda_shutup_pins(codec);
3100 alc_write_coef_idx(codec, 0x43, 0x9614);
3101}
3102
Kailang Yang4a219ef2017-06-16 16:54:35 +08003103static void alc256_init(struct hda_codec *codec)
3104{
3105 struct alc_spec *spec = codec->spec;
3106 hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
3107 bool hp_pin_sense;
3108
3109 if (!hp_pin)
3110 return;
3111
3112 msleep(30);
3113
3114 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3115
3116 if (hp_pin_sense)
3117 msleep(2);
3118
3119 alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */
3120
3121 snd_hda_codec_write(codec, hp_pin, 0,
3122 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3123
3124 if (hp_pin_sense)
3125 msleep(85);
3126
3127 snd_hda_codec_write(codec, hp_pin, 0,
3128 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3129
3130 if (hp_pin_sense)
3131 msleep(100);
3132
3133 alc_update_coef_idx(codec, 0x46, 3 << 12, 0);
3134 alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x4); /* Hight power */
Kailang Yang88d42b22018-03-14 16:08:57 +08003135 alc_update_coefex_idx(codec, 0x53, 0x02, 0x8000, 1 << 15); /* Clear bit */
3136 alc_update_coefex_idx(codec, 0x53, 0x02, 0x8000, 0 << 15);
Kailang Yang4a219ef2017-06-16 16:54:35 +08003137}
3138
3139static void alc256_shutup(struct hda_codec *codec)
3140{
3141 struct alc_spec *spec = codec->spec;
3142 hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
3143 bool hp_pin_sense;
3144
3145 if (!hp_pin) {
3146 alc269_shutup(codec);
3147 return;
3148 }
3149
3150 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3151
3152 if (hp_pin_sense)
3153 msleep(2);
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
Takashi Iwai1c9609e2018-01-19 14:18:34 +01003161 /* 3k pull low control for Headset jack. */
3162 /* NOTE: call this before clearing the pin, otherwise codec stalls */
3163 alc_update_coef_idx(codec, 0x46, 0, 3 << 12);
3164
Kailang Yang4a219ef2017-06-16 16:54:35 +08003165 snd_hda_codec_write(codec, hp_pin, 0,
3166 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
3167
Kailang Yang4a219ef2017-06-16 16:54:35 +08003168 if (hp_pin_sense)
3169 msleep(100);
3170
3171 alc_auto_setup_eapd(codec, false);
3172 snd_hda_shutup_pins(codec);
3173}
3174
Kailang Yangda911b12018-01-05 16:50:08 +08003175static void alc225_init(struct hda_codec *codec)
3176{
3177 struct alc_spec *spec = codec->spec;
3178 hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
3179 bool hp1_pin_sense, hp2_pin_sense;
3180
3181 if (!hp_pin)
3182 return;
3183
3184 msleep(30);
3185
3186 hp1_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3187 hp2_pin_sense = snd_hda_jack_detect(codec, 0x16);
3188
3189 if (hp1_pin_sense || hp2_pin_sense)
3190 msleep(2);
3191
3192 alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */
3193
3194 if (hp1_pin_sense)
3195 snd_hda_codec_write(codec, hp_pin, 0,
3196 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3197 if (hp2_pin_sense)
3198 snd_hda_codec_write(codec, 0x16, 0,
3199 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3200
3201 if (hp1_pin_sense || hp2_pin_sense)
3202 msleep(85);
3203
3204 if (hp1_pin_sense)
3205 snd_hda_codec_write(codec, hp_pin, 0,
3206 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3207 if (hp2_pin_sense)
3208 snd_hda_codec_write(codec, 0x16, 0,
3209 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3210
3211 if (hp1_pin_sense || hp2_pin_sense)
3212 msleep(100);
3213
3214 alc_update_coef_idx(codec, 0x4a, 3 << 10, 0);
3215 alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x4); /* Hight power */
3216}
3217
3218static void alc225_shutup(struct hda_codec *codec)
3219{
3220 struct alc_spec *spec = codec->spec;
3221 hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
3222 bool hp1_pin_sense, hp2_pin_sense;
3223
3224 if (!hp_pin) {
3225 alc269_shutup(codec);
3226 return;
3227 }
3228
3229 /* 3k pull low control for Headset jack. */
3230 alc_update_coef_idx(codec, 0x4a, 0, 3 << 10);
3231
3232 hp1_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3233 hp2_pin_sense = snd_hda_jack_detect(codec, 0x16);
3234
3235 if (hp1_pin_sense || hp2_pin_sense)
3236 msleep(2);
3237
3238 if (hp1_pin_sense)
3239 snd_hda_codec_write(codec, hp_pin, 0,
3240 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3241 if (hp2_pin_sense)
3242 snd_hda_codec_write(codec, 0x16, 0,
3243 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3244
3245 if (hp1_pin_sense || hp2_pin_sense)
3246 msleep(85);
3247
3248 if (hp1_pin_sense)
3249 snd_hda_codec_write(codec, hp_pin, 0,
3250 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
3251 if (hp2_pin_sense)
3252 snd_hda_codec_write(codec, 0x16, 0,
3253 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
3254
3255 if (hp1_pin_sense || hp2_pin_sense)
3256 msleep(100);
3257
3258 alc_auto_setup_eapd(codec, false);
3259 snd_hda_shutup_pins(codec);
3260}
3261
Kailang Yangc2d6af52017-06-21 14:50:54 +08003262static void alc_default_init(struct hda_codec *codec)
3263{
3264 struct alc_spec *spec = codec->spec;
3265 hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
3266 bool hp_pin_sense;
3267
3268 if (!hp_pin)
3269 return;
3270
3271 msleep(30);
3272
3273 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3274
3275 if (hp_pin_sense)
3276 msleep(2);
3277
3278 snd_hda_codec_write(codec, hp_pin, 0,
3279 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3280
3281 if (hp_pin_sense)
3282 msleep(85);
3283
3284 snd_hda_codec_write(codec, hp_pin, 0,
3285 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3286
3287 if (hp_pin_sense)
3288 msleep(100);
3289}
3290
3291static void alc_default_shutup(struct hda_codec *codec)
3292{
3293 struct alc_spec *spec = codec->spec;
3294 hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
3295 bool hp_pin_sense;
3296
3297 if (!hp_pin) {
3298 alc269_shutup(codec);
3299 return;
3300 }
3301
3302 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3303
3304 if (hp_pin_sense)
3305 msleep(2);
3306
3307 snd_hda_codec_write(codec, hp_pin, 0,
3308 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3309
3310 if (hp_pin_sense)
3311 msleep(85);
3312
3313 snd_hda_codec_write(codec, hp_pin, 0,
3314 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
3315
3316 if (hp_pin_sense)
3317 msleep(100);
3318
3319 alc_auto_setup_eapd(codec, false);
3320 snd_hda_shutup_pins(codec);
3321}
3322
Kailang Yangad60d502013-06-28 12:03:01 +02003323static void alc5505_coef_set(struct hda_codec *codec, unsigned int index_reg,
3324 unsigned int val)
3325{
3326 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_COEF_INDEX, index_reg >> 1);
3327 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_PROC_COEF, val & 0xffff); /* LSB */
3328 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_PROC_COEF, val >> 16); /* MSB */
3329}
3330
3331static int alc5505_coef_get(struct hda_codec *codec, unsigned int index_reg)
3332{
3333 unsigned int val;
3334
3335 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_COEF_INDEX, index_reg >> 1);
3336 val = snd_hda_codec_read(codec, 0x51, 0, AC_VERB_GET_PROC_COEF, 0)
3337 & 0xffff;
3338 val |= snd_hda_codec_read(codec, 0x51, 0, AC_VERB_GET_PROC_COEF, 0)
3339 << 16;
3340 return val;
3341}
3342
3343static void alc5505_dsp_halt(struct hda_codec *codec)
3344{
3345 unsigned int val;
3346
3347 alc5505_coef_set(codec, 0x3000, 0x000c); /* DSP CPU stop */
3348 alc5505_coef_set(codec, 0x880c, 0x0008); /* DDR enter self refresh */
3349 alc5505_coef_set(codec, 0x61c0, 0x11110080); /* Clock control for PLL and CPU */
3350 alc5505_coef_set(codec, 0x6230, 0xfc0d4011); /* Disable Input OP */
3351 alc5505_coef_set(codec, 0x61b4, 0x040a2b03); /* Stop PLL2 */
3352 alc5505_coef_set(codec, 0x61b0, 0x00005b17); /* Stop PLL1 */
3353 alc5505_coef_set(codec, 0x61b8, 0x04133303); /* Stop PLL3 */
3354 val = alc5505_coef_get(codec, 0x6220);
3355 alc5505_coef_set(codec, 0x6220, (val | 0x3000)); /* switch Ringbuffer clock to DBUS clock */
3356}
3357
3358static void alc5505_dsp_back_from_halt(struct hda_codec *codec)
3359{
3360 alc5505_coef_set(codec, 0x61b8, 0x04133302);
3361 alc5505_coef_set(codec, 0x61b0, 0x00005b16);
3362 alc5505_coef_set(codec, 0x61b4, 0x040a2b02);
3363 alc5505_coef_set(codec, 0x6230, 0xf80d4011);
3364 alc5505_coef_set(codec, 0x6220, 0x2002010f);
3365 alc5505_coef_set(codec, 0x880c, 0x00000004);
3366}
3367
3368static void alc5505_dsp_init(struct hda_codec *codec)
3369{
3370 unsigned int val;
3371
3372 alc5505_dsp_halt(codec);
3373 alc5505_dsp_back_from_halt(codec);
3374 alc5505_coef_set(codec, 0x61b0, 0x5b14); /* PLL1 control */
3375 alc5505_coef_set(codec, 0x61b0, 0x5b16);
3376 alc5505_coef_set(codec, 0x61b4, 0x04132b00); /* PLL2 control */
3377 alc5505_coef_set(codec, 0x61b4, 0x04132b02);
3378 alc5505_coef_set(codec, 0x61b8, 0x041f3300); /* PLL3 control*/
3379 alc5505_coef_set(codec, 0x61b8, 0x041f3302);
3380 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_CODEC_RESET, 0); /* Function reset */
3381 alc5505_coef_set(codec, 0x61b8, 0x041b3302);
3382 alc5505_coef_set(codec, 0x61b8, 0x04173302);
3383 alc5505_coef_set(codec, 0x61b8, 0x04163302);
3384 alc5505_coef_set(codec, 0x8800, 0x348b328b); /* DRAM control */
3385 alc5505_coef_set(codec, 0x8808, 0x00020022); /* DRAM control */
3386 alc5505_coef_set(codec, 0x8818, 0x00000400); /* DRAM control */
3387
3388 val = alc5505_coef_get(codec, 0x6200) >> 16; /* Read revision ID */
3389 if (val <= 3)
3390 alc5505_coef_set(codec, 0x6220, 0x2002010f); /* I/O PAD Configuration */
3391 else
3392 alc5505_coef_set(codec, 0x6220, 0x6002018f);
3393
3394 alc5505_coef_set(codec, 0x61ac, 0x055525f0); /**/
3395 alc5505_coef_set(codec, 0x61c0, 0x12230080); /* Clock control */
3396 alc5505_coef_set(codec, 0x61b4, 0x040e2b02); /* PLL2 control */
3397 alc5505_coef_set(codec, 0x61bc, 0x010234f8); /* OSC Control */
3398 alc5505_coef_set(codec, 0x880c, 0x00000004); /* DRAM Function control */
3399 alc5505_coef_set(codec, 0x880c, 0x00000003);
3400 alc5505_coef_set(codec, 0x880c, 0x00000010);
Takashi Iwaicd63a5f2013-07-05 12:13:59 +02003401
3402#ifdef HALT_REALTEK_ALC5505
3403 alc5505_dsp_halt(codec);
3404#endif
Kailang Yangad60d502013-06-28 12:03:01 +02003405}
3406
Takashi Iwaicd63a5f2013-07-05 12:13:59 +02003407#ifdef HALT_REALTEK_ALC5505
3408#define alc5505_dsp_suspend(codec) /* NOP */
3409#define alc5505_dsp_resume(codec) /* NOP */
3410#else
3411#define alc5505_dsp_suspend(codec) alc5505_dsp_halt(codec)
3412#define alc5505_dsp_resume(codec) alc5505_dsp_back_from_halt(codec)
3413#endif
3414
Takashi Iwai2a439522011-07-26 09:52:50 +02003415#ifdef CONFIG_PM
Kailang Yangad60d502013-06-28 12:03:01 +02003416static int alc269_suspend(struct hda_codec *codec)
3417{
3418 struct alc_spec *spec = codec->spec;
3419
3420 if (spec->has_alc5505_dsp)
Takashi Iwaicd63a5f2013-07-05 12:13:59 +02003421 alc5505_dsp_suspend(codec);
Kailang Yangad60d502013-06-28 12:03:01 +02003422 return alc_suspend(codec);
3423}
3424
Takashi Iwai1d045db2011-07-07 18:23:21 +02003425static int alc269_resume(struct hda_codec *codec)
3426{
Kailang Yangadcc70b2012-05-25 08:08:38 +02003427 struct alc_spec *spec = codec->spec;
3428
Kailang Yang1387e2d2012-11-08 10:23:18 +01003429 if (spec->codec_variant == ALC269_TYPE_ALC269VB)
3430 alc269vb_toggle_power_output(codec, 0);
3431 if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
Kailang Yangadcc70b2012-05-25 08:08:38 +02003432 (alc_get_coef0(codec) & 0x00ff) == 0x018) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02003433 msleep(150);
3434 }
3435
3436 codec->patch_ops.init(codec);
3437
Kailang Yang1387e2d2012-11-08 10:23:18 +01003438 if (spec->codec_variant == ALC269_TYPE_ALC269VB)
3439 alc269vb_toggle_power_output(codec, 1);
3440 if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
Kailang Yangadcc70b2012-05-25 08:08:38 +02003441 (alc_get_coef0(codec) & 0x00ff) == 0x017) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02003442 msleep(200);
3443 }
3444
Takashi Iwaieeecd9d2015-02-25 15:18:50 +01003445 regcache_sync(codec->core.regmap);
Takashi Iwai1d045db2011-07-07 18:23:21 +02003446 hda_call_check_power_status(codec, 0x01);
Hui Wangf4753712014-08-19 12:07:03 +08003447
3448 /* on some machine, the BIOS will clear the codec gpio data when enter
3449 * suspend, and won't restore the data after resume, so we restore it
3450 * in the driver.
3451 */
3452 if (spec->gpio_led)
Takashi Iwai7639a062015-03-03 10:07:24 +01003453 snd_hda_codec_write(codec, codec->core.afg, 0, AC_VERB_SET_GPIO_DATA,
Hui Wangf4753712014-08-19 12:07:03 +08003454 spec->gpio_led);
3455
Kailang Yangad60d502013-06-28 12:03:01 +02003456 if (spec->has_alc5505_dsp)
Takashi Iwaicd63a5f2013-07-05 12:13:59 +02003457 alc5505_dsp_resume(codec);
Kailang Yangc5177c82013-07-24 14:39:49 +02003458
Takashi Iwai1d045db2011-07-07 18:23:21 +02003459 return 0;
3460}
Takashi Iwai2a439522011-07-26 09:52:50 +02003461#endif /* CONFIG_PM */
Takashi Iwai1d045db2011-07-07 18:23:21 +02003462
David Henningsson108cc102012-07-20 10:37:25 +02003463static void alc269_fixup_pincfg_no_hp_to_lineout(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003464 const struct hda_fixup *fix, int action)
David Henningsson108cc102012-07-20 10:37:25 +02003465{
3466 struct alc_spec *spec = codec->spec;
3467
Takashi Iwai1727a772013-01-10 09:52:52 +01003468 if (action == HDA_FIXUP_ACT_PRE_PROBE)
David Henningsson108cc102012-07-20 10:37:25 +02003469 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
3470}
3471
Jan-Marek Glogowskifdcc9682018-02-14 11:29:15 +01003472static void alc269_fixup_pincfg_U7x7_headset_mic(struct hda_codec *codec,
3473 const struct hda_fixup *fix,
3474 int action)
3475{
3476 unsigned int cfg_headphone = snd_hda_codec_get_pincfg(codec, 0x21);
3477 unsigned int cfg_headset_mic = snd_hda_codec_get_pincfg(codec, 0x19);
3478
3479 if (cfg_headphone && cfg_headset_mic == 0x411111f0)
3480 snd_hda_codec_set_pincfg(codec, 0x19,
3481 (cfg_headphone & ~AC_DEFCFG_DEVICE) |
3482 (AC_JACK_MIC_IN << AC_DEFCFG_DEVICE_SHIFT));
3483}
3484
Takashi Iwai1d045db2011-07-07 18:23:21 +02003485static void alc269_fixup_hweq(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003486 const struct hda_fixup *fix, int action)
Takashi Iwai1d045db2011-07-07 18:23:21 +02003487{
Takashi Iwai98b24882014-08-18 13:47:50 +02003488 if (action == HDA_FIXUP_ACT_INIT)
3489 alc_update_coef_idx(codec, 0x1e, 0, 0x80);
Takashi Iwai1d045db2011-07-07 18:23:21 +02003490}
3491
David Henningsson7c478f02013-10-11 10:18:46 +02003492static void alc269_fixup_headset_mic(struct hda_codec *codec,
3493 const struct hda_fixup *fix, int action)
3494{
3495 struct alc_spec *spec = codec->spec;
3496
3497 if (action == HDA_FIXUP_ACT_PRE_PROBE)
3498 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
3499}
3500
Takashi Iwai1d045db2011-07-07 18:23:21 +02003501static void alc271_fixup_dmic(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003502 const struct hda_fixup *fix, int action)
Takashi Iwai1d045db2011-07-07 18:23:21 +02003503{
3504 static const struct hda_verb verbs[] = {
3505 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
3506 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
3507 {}
3508 };
3509 unsigned int cfg;
3510
Takashi Iwai7639a062015-03-03 10:07:24 +01003511 if (strcmp(codec->core.chip_name, "ALC271X") &&
3512 strcmp(codec->core.chip_name, "ALC269VB"))
Takashi Iwai1d045db2011-07-07 18:23:21 +02003513 return;
3514 cfg = snd_hda_codec_get_pincfg(codec, 0x12);
3515 if (get_defcfg_connect(cfg) == AC_JACK_PORT_FIXED)
3516 snd_hda_sequence_write(codec, verbs);
3517}
3518
Takashi Iwai017f2a12011-07-09 14:42:25 +02003519static void alc269_fixup_pcm_44k(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003520 const struct hda_fixup *fix, int action)
Takashi Iwai017f2a12011-07-09 14:42:25 +02003521{
3522 struct alc_spec *spec = codec->spec;
3523
Takashi Iwai1727a772013-01-10 09:52:52 +01003524 if (action != HDA_FIXUP_ACT_PROBE)
Takashi Iwai017f2a12011-07-09 14:42:25 +02003525 return;
3526
3527 /* Due to a hardware problem on Lenovo Ideadpad, we need to
3528 * fix the sample rate of analog I/O to 44.1kHz
3529 */
Takashi Iwai08c189f2012-12-19 15:22:24 +01003530 spec->gen.stream_analog_playback = &alc269_44k_pcm_analog_playback;
3531 spec->gen.stream_analog_capture = &alc269_44k_pcm_analog_capture;
Takashi Iwai017f2a12011-07-09 14:42:25 +02003532}
3533
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02003534static void alc269_fixup_stereo_dmic(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003535 const struct hda_fixup *fix, int action)
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02003536{
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02003537 /* The digital-mic unit sends PDM (differential signal) instead of
3538 * the standard PCM, thus you can't record a valid mono stream as is.
3539 * Below is a workaround specific to ALC269 to control the dmic
3540 * signal source as mono.
3541 */
Takashi Iwai98b24882014-08-18 13:47:50 +02003542 if (action == HDA_FIXUP_ACT_INIT)
3543 alc_update_coef_idx(codec, 0x07, 0, 0x80);
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02003544}
3545
Takashi Iwai24519912011-08-16 15:08:49 +02003546static void alc269_quanta_automute(struct hda_codec *codec)
3547{
Takashi Iwai08c189f2012-12-19 15:22:24 +01003548 snd_hda_gen_update_outputs(codec);
Takashi Iwai24519912011-08-16 15:08:49 +02003549
Takashi Iwai1687ccc2014-08-18 13:49:35 +02003550 alc_write_coef_idx(codec, 0x0c, 0x680);
3551 alc_write_coef_idx(codec, 0x0c, 0x480);
Takashi Iwai24519912011-08-16 15:08:49 +02003552}
3553
3554static void alc269_fixup_quanta_mute(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003555 const struct hda_fixup *fix, int action)
Takashi Iwai24519912011-08-16 15:08:49 +02003556{
3557 struct alc_spec *spec = codec->spec;
Takashi Iwai1727a772013-01-10 09:52:52 +01003558 if (action != HDA_FIXUP_ACT_PROBE)
Takashi Iwai24519912011-08-16 15:08:49 +02003559 return;
Takashi Iwai08c189f2012-12-19 15:22:24 +01003560 spec->gen.automute_hook = alc269_quanta_automute;
Takashi Iwai24519912011-08-16 15:08:49 +02003561}
3562
David Henningssond240d1d2013-04-15 12:50:02 +02003563static void alc269_x101_hp_automute_hook(struct hda_codec *codec,
Takashi Iwai1a4f69d2014-09-11 15:22:46 +02003564 struct hda_jack_callback *jack)
David Henningssond240d1d2013-04-15 12:50:02 +02003565{
3566 struct alc_spec *spec = codec->spec;
3567 int vref;
3568 msleep(200);
3569 snd_hda_gen_hp_automute(codec, jack);
3570
3571 vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0;
3572 msleep(100);
3573 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3574 vref);
3575 msleep(500);
3576 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3577 vref);
3578}
3579
3580static void alc269_fixup_x101_headset_mic(struct hda_codec *codec,
3581 const struct hda_fixup *fix, int action)
3582{
3583 struct alc_spec *spec = codec->spec;
3584 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3585 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
3586 spec->gen.hp_automute_hook = alc269_x101_hp_automute_hook;
3587 }
3588}
3589
3590
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003591/* update mute-LED according to the speaker mute state via mic VREF pin */
3592static void alc269_fixup_mic_mute_hook(void *private_data, int enabled)
David Henningsson6d3cd5d2013-01-07 12:03:47 +01003593{
3594 struct hda_codec *codec = private_data;
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003595 struct alc_spec *spec = codec->spec;
3596 unsigned int pinval;
3597
3598 if (spec->mute_led_polarity)
3599 enabled = !enabled;
Takashi Iwai415d5552014-04-03 11:51:21 +02003600 pinval = snd_hda_codec_get_pin_target(codec, spec->mute_led_nid);
3601 pinval &= ~AC_PINCTL_VREFEN;
3602 pinval |= enabled ? AC_PINCTL_VREF_HIZ : AC_PINCTL_VREF_80;
Takashi Iwaie40bdb02018-03-17 22:40:18 +01003603 if (spec->mute_led_nid) {
3604 /* temporarily power up/down for setting VREF */
3605 snd_hda_power_up_pm(codec);
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003606 snd_hda_set_pin_ctl_cache(codec, spec->mute_led_nid, pinval);
Takashi Iwaie40bdb02018-03-17 22:40:18 +01003607 snd_hda_power_down_pm(codec);
3608 }
David Henningsson6d3cd5d2013-01-07 12:03:47 +01003609}
3610
David Henningssond5b6b652013-11-06 10:50:44 +01003611/* Make sure the led works even in runtime suspend */
3612static unsigned int led_power_filter(struct hda_codec *codec,
3613 hda_nid_t nid,
3614 unsigned int power_state)
3615{
3616 struct alc_spec *spec = codec->spec;
3617
Hui Wang50dd9052014-07-08 17:56:15 +08003618 if (power_state != AC_PWRST_D3 || nid == 0 ||
3619 (nid != spec->mute_led_nid && nid != spec->cap_mute_led_nid))
David Henningssond5b6b652013-11-06 10:50:44 +01003620 return power_state;
3621
3622 /* Set pin ctl again, it might have just been set to 0 */
3623 snd_hda_set_pin_ctl(codec, nid,
3624 snd_hda_codec_get_pin_target(codec, nid));
3625
Takashi Iwaicffd3962015-04-09 10:30:25 +02003626 return snd_hda_gen_path_power_filter(codec, nid, power_state);
David Henningssond5b6b652013-11-06 10:50:44 +01003627}
3628
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003629static void alc269_fixup_hp_mute_led(struct hda_codec *codec,
3630 const struct hda_fixup *fix, int action)
David Henningsson6d3cd5d2013-01-07 12:03:47 +01003631{
3632 struct alc_spec *spec = codec->spec;
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003633 const struct dmi_device *dev = NULL;
3634
3635 if (action != HDA_FIXUP_ACT_PRE_PROBE)
3636 return;
3637
3638 while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) {
3639 int pol, pin;
3640 if (sscanf(dev->name, "HP_Mute_LED_%d_%x", &pol, &pin) != 2)
3641 continue;
3642 if (pin < 0x0a || pin >= 0x10)
3643 break;
3644 spec->mute_led_polarity = pol;
3645 spec->mute_led_nid = pin - 0x0a + 0x18;
3646 spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook;
Takashi Iwaifd25a972012-12-20 14:57:18 +01003647 spec->gen.vmaster_mute_enum = 1;
David Henningssond5b6b652013-11-06 10:50:44 +01003648 codec->power_filter = led_power_filter;
Takashi Iwai4e76a882014-02-25 12:21:03 +01003649 codec_dbg(codec,
3650 "Detected mute LED for %x:%d\n", spec->mute_led_nid,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003651 spec->mute_led_polarity);
David Henningsson6d3cd5d2013-01-07 12:03:47 +01003652 break;
3653 }
3654}
3655
Takashi Iwai85c467d2018-05-29 11:38:38 +02003656static void alc269_fixup_hp_mute_led_micx(struct hda_codec *codec,
3657 const struct hda_fixup *fix,
3658 int action, hda_nid_t pin)
David Henningssond06ac142013-02-18 11:41:55 +01003659{
3660 struct alc_spec *spec = codec->spec;
Takashi Iwai85c467d2018-05-29 11:38:38 +02003661
David Henningssond06ac142013-02-18 11:41:55 +01003662 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3663 spec->mute_led_polarity = 0;
Takashi Iwai85c467d2018-05-29 11:38:38 +02003664 spec->mute_led_nid = pin;
David Henningssond06ac142013-02-18 11:41:55 +01003665 spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook;
3666 spec->gen.vmaster_mute_enum = 1;
David Henningssond5b6b652013-11-06 10:50:44 +01003667 codec->power_filter = led_power_filter;
David Henningssond06ac142013-02-18 11:41:55 +01003668 }
3669}
3670
Takashi Iwai85c467d2018-05-29 11:38:38 +02003671static void alc269_fixup_hp_mute_led_mic1(struct hda_codec *codec,
3672 const struct hda_fixup *fix, int action)
3673{
3674 alc269_fixup_hp_mute_led_micx(codec, fix, action, 0x18);
3675}
3676
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003677static void alc269_fixup_hp_mute_led_mic2(struct hda_codec *codec,
3678 const struct hda_fixup *fix, int action)
Takashi Iwai420b0fe2012-03-12 12:35:27 +01003679{
Takashi Iwai85c467d2018-05-29 11:38:38 +02003680 alc269_fixup_hp_mute_led_micx(codec, fix, action, 0x19);
Takashi Iwai420b0fe2012-03-12 12:35:27 +01003681}
3682
Tom Briden7f783bd2017-03-25 10:12:01 +00003683static void alc269_fixup_hp_mute_led_mic3(struct hda_codec *codec,
3684 const struct hda_fixup *fix, int action)
3685{
Takashi Iwai85c467d2018-05-29 11:38:38 +02003686 alc269_fixup_hp_mute_led_micx(codec, fix, action, 0x1b);
Tom Briden7f783bd2017-03-25 10:12:01 +00003687}
3688
Takashi Iwai0f32fd192014-11-19 12:16:14 +01003689/* update LED status via GPIO */
3690static void alc_update_gpio_led(struct hda_codec *codec, unsigned int mask,
3691 bool enabled)
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003692{
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003693 struct alc_spec *spec = codec->spec;
3694 unsigned int oldval = spec->gpio_led;
3695
Takashi Iwai0f32fd192014-11-19 12:16:14 +01003696 if (spec->mute_led_polarity)
3697 enabled = !enabled;
3698
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003699 if (enabled)
Takashi Iwai0f32fd192014-11-19 12:16:14 +01003700 spec->gpio_led &= ~mask;
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003701 else
Takashi Iwai0f32fd192014-11-19 12:16:14 +01003702 spec->gpio_led |= mask;
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003703 if (spec->gpio_led != oldval)
3704 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
3705 spec->gpio_led);
3706}
3707
Takashi Iwai0f32fd192014-11-19 12:16:14 +01003708/* turn on/off mute LED via GPIO per vmaster hook */
3709static void alc_fixup_gpio_mute_hook(void *private_data, int enabled)
3710{
3711 struct hda_codec *codec = private_data;
3712 struct alc_spec *spec = codec->spec;
3713
3714 alc_update_gpio_led(codec, spec->gpio_mute_led_mask, enabled);
3715}
3716
3717/* turn on/off mic-mute LED via GPIO per capture hook */
3718static void alc_fixup_gpio_mic_mute_hook(struct hda_codec *codec,
3719 struct snd_kcontrol *kcontrol,
3720 struct snd_ctl_elem_value *ucontrol)
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003721{
3722 struct alc_spec *spec = codec->spec;
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003723
Takashi Iwai0f32fd192014-11-19 12:16:14 +01003724 if (ucontrol)
3725 alc_update_gpio_led(codec, spec->gpio_mic_led_mask,
3726 ucontrol->value.integer.value[0] ||
3727 ucontrol->value.integer.value[1]);
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003728}
3729
3730static void alc269_fixup_hp_gpio_led(struct hda_codec *codec,
3731 const struct hda_fixup *fix, int action)
3732{
3733 struct alc_spec *spec = codec->spec;
3734 static const struct hda_verb gpio_init[] = {
3735 { 0x01, AC_VERB_SET_GPIO_MASK, 0x18 },
3736 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x18 },
3737 {}
3738 };
3739
3740 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai0f32fd192014-11-19 12:16:14 +01003741 spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook;
3742 spec->gen.cap_sync_hook = alc_fixup_gpio_mic_mute_hook;
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003743 spec->gpio_led = 0;
Takashi Iwai0f32fd192014-11-19 12:16:14 +01003744 spec->mute_led_polarity = 0;
3745 spec->gpio_mute_led_mask = 0x08;
3746 spec->gpio_mic_led_mask = 0x10;
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003747 snd_hda_add_verbs(codec, gpio_init);
3748 }
3749}
3750
Kailang Yangeaa8e5e2014-11-21 15:49:11 +08003751static void alc286_fixup_hp_gpio_led(struct hda_codec *codec,
3752 const struct hda_fixup *fix, int action)
3753{
3754 struct alc_spec *spec = codec->spec;
3755 static const struct hda_verb gpio_init[] = {
3756 { 0x01, AC_VERB_SET_GPIO_MASK, 0x22 },
3757 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x22 },
3758 {}
3759 };
3760
3761 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3762 spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook;
3763 spec->gen.cap_sync_hook = alc_fixup_gpio_mic_mute_hook;
3764 spec->gpio_led = 0;
3765 spec->mute_led_polarity = 0;
3766 spec->gpio_mute_led_mask = 0x02;
3767 spec->gpio_mic_led_mask = 0x20;
Takashi Iwai1d045db2011-07-07 18:23:21 +02003768 snd_hda_add_verbs(codec, gpio_init);
3769 }
3770}
3771
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08003772/* turn on/off mic-mute LED per capture hook */
3773static void alc269_fixup_hp_cap_mic_mute_hook(struct hda_codec *codec,
3774 struct snd_kcontrol *kcontrol,
3775 struct snd_ctl_elem_value *ucontrol)
3776{
3777 struct alc_spec *spec = codec->spec;
3778 unsigned int pinval, enable, disable;
3779
Hui Wangfc1fad92014-07-08 17:56:14 +08003780 pinval = snd_hda_codec_get_pin_target(codec, spec->cap_mute_led_nid);
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08003781 pinval &= ~AC_PINCTL_VREFEN;
3782 enable = pinval | AC_PINCTL_VREF_80;
3783 disable = pinval | AC_PINCTL_VREF_HIZ;
3784
3785 if (!ucontrol)
3786 return;
3787
3788 if (ucontrol->value.integer.value[0] ||
3789 ucontrol->value.integer.value[1])
3790 pinval = disable;
3791 else
3792 pinval = enable;
3793
3794 if (spec->cap_mute_led_nid)
3795 snd_hda_set_pin_ctl_cache(codec, spec->cap_mute_led_nid, pinval);
3796}
3797
3798static void alc269_fixup_hp_gpio_mic1_led(struct hda_codec *codec,
3799 const struct hda_fixup *fix, int action)
3800{
3801 struct alc_spec *spec = codec->spec;
3802 static const struct hda_verb gpio_init[] = {
3803 { 0x01, AC_VERB_SET_GPIO_MASK, 0x08 },
3804 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x08 },
3805 {}
3806 };
3807
3808 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai0f32fd192014-11-19 12:16:14 +01003809 spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08003810 spec->gen.cap_sync_hook = alc269_fixup_hp_cap_mic_mute_hook;
3811 spec->gpio_led = 0;
Takashi Iwai0f32fd192014-11-19 12:16:14 +01003812 spec->mute_led_polarity = 0;
3813 spec->gpio_mute_led_mask = 0x08;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08003814 spec->cap_mute_led_nid = 0x18;
3815 snd_hda_add_verbs(codec, gpio_init);
Hui Wang50dd9052014-07-08 17:56:15 +08003816 codec->power_filter = led_power_filter;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08003817 }
3818}
3819
David Henningsson7a5255f2014-10-30 08:26:01 +01003820static void alc280_fixup_hp_gpio4(struct hda_codec *codec,
3821 const struct hda_fixup *fix, int action)
3822{
3823 /* Like hp_gpio_mic1_led, but also needs GPIO4 low to enable headphone amp */
3824 struct alc_spec *spec = codec->spec;
3825 static const struct hda_verb gpio_init[] = {
3826 { 0x01, AC_VERB_SET_GPIO_MASK, 0x18 },
3827 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x18 },
3828 {}
3829 };
3830
3831 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai0f32fd192014-11-19 12:16:14 +01003832 spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook;
David Henningsson7a5255f2014-10-30 08:26:01 +01003833 spec->gen.cap_sync_hook = alc269_fixup_hp_cap_mic_mute_hook;
3834 spec->gpio_led = 0;
Takashi Iwai0f32fd192014-11-19 12:16:14 +01003835 spec->mute_led_polarity = 0;
3836 spec->gpio_mute_led_mask = 0x08;
David Henningsson7a5255f2014-10-30 08:26:01 +01003837 spec->cap_mute_led_nid = 0x18;
3838 snd_hda_add_verbs(codec, gpio_init);
3839 codec->power_filter = led_power_filter;
3840 }
3841}
3842
Takashi Iwai6a30aba2018-04-27 17:17:35 +02003843#if IS_REACHABLE(CONFIG_INPUT)
David Henningsson33f4acd2015-01-07 15:50:13 +01003844static void gpio2_mic_hotkey_event(struct hda_codec *codec,
3845 struct hda_jack_callback *event)
3846{
3847 struct alc_spec *spec = codec->spec;
3848
3849 /* GPIO2 just toggles on a keypress/keyrelease cycle. Therefore
3850 send both key on and key off event for every interrupt. */
Hui Wangc7b60a82015-12-28 11:35:25 +08003851 input_report_key(spec->kb_dev, spec->alc_mute_keycode_map[ALC_KEY_MICMUTE_INDEX], 1);
David Henningsson33f4acd2015-01-07 15:50:13 +01003852 input_sync(spec->kb_dev);
Hui Wangc7b60a82015-12-28 11:35:25 +08003853 input_report_key(spec->kb_dev, spec->alc_mute_keycode_map[ALC_KEY_MICMUTE_INDEX], 0);
David Henningsson33f4acd2015-01-07 15:50:13 +01003854 input_sync(spec->kb_dev);
3855}
David Henningsson33f4acd2015-01-07 15:50:13 +01003856
Kailang3694cb22015-12-28 11:35:24 +08003857static int alc_register_micmute_input_device(struct hda_codec *codec)
3858{
3859 struct alc_spec *spec = codec->spec;
Hui Wangc7b60a82015-12-28 11:35:25 +08003860 int i;
Kailang3694cb22015-12-28 11:35:24 +08003861
3862 spec->kb_dev = input_allocate_device();
3863 if (!spec->kb_dev) {
3864 codec_err(codec, "Out of memory (input_allocate_device)\n");
3865 return -ENOMEM;
3866 }
Hui Wangc7b60a82015-12-28 11:35:25 +08003867
3868 spec->alc_mute_keycode_map[ALC_KEY_MICMUTE_INDEX] = KEY_MICMUTE;
3869
Kailang3694cb22015-12-28 11:35:24 +08003870 spec->kb_dev->name = "Microphone Mute Button";
3871 spec->kb_dev->evbit[0] = BIT_MASK(EV_KEY);
Hui Wangc7b60a82015-12-28 11:35:25 +08003872 spec->kb_dev->keycodesize = sizeof(spec->alc_mute_keycode_map[0]);
3873 spec->kb_dev->keycodemax = ARRAY_SIZE(spec->alc_mute_keycode_map);
3874 spec->kb_dev->keycode = spec->alc_mute_keycode_map;
3875 for (i = 0; i < ARRAY_SIZE(spec->alc_mute_keycode_map); i++)
3876 set_bit(spec->alc_mute_keycode_map[i], spec->kb_dev->keybit);
Kailang3694cb22015-12-28 11:35:24 +08003877
3878 if (input_register_device(spec->kb_dev)) {
3879 codec_err(codec, "input_register_device failed\n");
3880 input_free_device(spec->kb_dev);
3881 spec->kb_dev = NULL;
3882 return -ENOMEM;
3883 }
3884
3885 return 0;
3886}
3887
David Henningsson33f4acd2015-01-07 15:50:13 +01003888static void alc280_fixup_hp_gpio2_mic_hotkey(struct hda_codec *codec,
3889 const struct hda_fixup *fix, int action)
3890{
David Henningsson33f4acd2015-01-07 15:50:13 +01003891 /* GPIO1 = set according to SKU external amp
3892 GPIO2 = mic mute hotkey
3893 GPIO3 = mute LED
3894 GPIO4 = mic mute LED */
3895 static const struct hda_verb gpio_init[] = {
3896 { 0x01, AC_VERB_SET_GPIO_MASK, 0x1e },
3897 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x1a },
3898 { 0x01, AC_VERB_SET_GPIO_DATA, 0x02 },
3899 {}
3900 };
3901
3902 struct alc_spec *spec = codec->spec;
3903
3904 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Kailang3694cb22015-12-28 11:35:24 +08003905 if (alc_register_micmute_input_device(codec) != 0)
David Henningsson33f4acd2015-01-07 15:50:13 +01003906 return;
David Henningsson33f4acd2015-01-07 15:50:13 +01003907
3908 snd_hda_add_verbs(codec, gpio_init);
Takashi Iwai7639a062015-03-03 10:07:24 +01003909 snd_hda_codec_write_cache(codec, codec->core.afg, 0,
David Henningsson33f4acd2015-01-07 15:50:13 +01003910 AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x04);
Takashi Iwai7639a062015-03-03 10:07:24 +01003911 snd_hda_jack_detect_enable_callback(codec, codec->core.afg,
David Henningsson33f4acd2015-01-07 15:50:13 +01003912 gpio2_mic_hotkey_event);
3913
3914 spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook;
3915 spec->gen.cap_sync_hook = alc_fixup_gpio_mic_mute_hook;
3916 spec->gpio_led = 0;
3917 spec->mute_led_polarity = 0;
3918 spec->gpio_mute_led_mask = 0x08;
3919 spec->gpio_mic_led_mask = 0x10;
3920 return;
3921 }
3922
3923 if (!spec->kb_dev)
3924 return;
3925
3926 switch (action) {
3927 case HDA_FIXUP_ACT_PROBE:
3928 spec->init_amp = ALC_INIT_DEFAULT;
3929 break;
3930 case HDA_FIXUP_ACT_FREE:
3931 input_unregister_device(spec->kb_dev);
David Henningsson33f4acd2015-01-07 15:50:13 +01003932 spec->kb_dev = NULL;
3933 }
David Henningsson33f4acd2015-01-07 15:50:13 +01003934}
3935
Kailang3694cb22015-12-28 11:35:24 +08003936static void alc233_fixup_lenovo_line2_mic_hotkey(struct hda_codec *codec,
3937 const struct hda_fixup *fix, int action)
3938{
3939 /* Line2 = mic mute hotkey
3940 GPIO2 = mic mute LED */
3941 static const struct hda_verb gpio_init[] = {
3942 { 0x01, AC_VERB_SET_GPIO_MASK, 0x04 },
3943 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04 },
3944 {}
3945 };
3946
3947 struct alc_spec *spec = codec->spec;
3948
3949 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3950 if (alc_register_micmute_input_device(codec) != 0)
3951 return;
3952
3953 snd_hda_add_verbs(codec, gpio_init);
3954 snd_hda_jack_detect_enable_callback(codec, 0x1b,
3955 gpio2_mic_hotkey_event);
3956
3957 spec->gen.cap_sync_hook = alc_fixup_gpio_mic_mute_hook;
3958 spec->gpio_led = 0;
3959 spec->mute_led_polarity = 0;
3960 spec->gpio_mic_led_mask = 0x04;
3961 return;
3962 }
3963
3964 if (!spec->kb_dev)
3965 return;
3966
3967 switch (action) {
3968 case HDA_FIXUP_ACT_PROBE:
3969 spec->init_amp = ALC_INIT_DEFAULT;
3970 break;
3971 case HDA_FIXUP_ACT_FREE:
3972 input_unregister_device(spec->kb_dev);
3973 spec->kb_dev = NULL;
3974 }
3975}
Takashi Iwaic4696522018-01-15 10:44:35 +01003976#else /* INPUT */
3977#define alc280_fixup_hp_gpio2_mic_hotkey NULL
3978#define alc233_fixup_lenovo_line2_mic_hotkey NULL
3979#endif /* INPUT */
Kailang3694cb22015-12-28 11:35:24 +08003980
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08003981static void alc269_fixup_hp_line1_mic1_led(struct hda_codec *codec,
3982 const struct hda_fixup *fix, int action)
3983{
3984 struct alc_spec *spec = codec->spec;
3985
3986 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3987 spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook;
3988 spec->gen.cap_sync_hook = alc269_fixup_hp_cap_mic_mute_hook;
3989 spec->mute_led_polarity = 0;
3990 spec->mute_led_nid = 0x1a;
3991 spec->cap_mute_led_nid = 0x18;
3992 spec->gen.vmaster_mute_enum = 1;
3993 codec->power_filter = led_power_filter;
3994 }
3995}
3996
Kailang Yang5a367672017-07-21 15:23:53 +08003997static struct coef_fw alc225_pre_hsmode[] = {
3998 UPDATE_COEF(0x4a, 1<<8, 0),
3999 UPDATE_COEFEX(0x57, 0x05, 1<<14, 0),
4000 UPDATE_COEF(0x63, 3<<14, 3<<14),
4001 UPDATE_COEF(0x4a, 3<<4, 2<<4),
4002 UPDATE_COEF(0x4a, 3<<10, 3<<10),
4003 UPDATE_COEF(0x45, 0x3f<<10, 0x34<<10),
4004 UPDATE_COEF(0x4a, 3<<10, 0),
4005 {}
4006};
4007
David Henningsson73bdd592013-04-15 15:44:14 +02004008static void alc_headset_mode_unplugged(struct hda_codec *codec)
4009{
Takashi Iwai54db6c32014-08-18 15:11:19 +02004010 static struct coef_fw coef0255[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004011 WRITE_COEF(0x45, 0xd089), /* UAJ function set to menual mode */
4012 UPDATE_COEFEX(0x57, 0x05, 1<<14, 0), /* Direct Drive HP Amp control(Set to verb control)*/
4013 WRITE_COEF(0x06, 0x6104), /* Set MIC2 Vref gate with HP */
4014 WRITE_COEFEX(0x57, 0x03, 0x8aa6), /* Direct Drive HP Amp control */
4015 {}
4016 };
Kailang Yange69e7e02016-05-30 15:58:28 +08004017 static struct coef_fw coef0255_1[] = {
4018 WRITE_COEF(0x1b, 0x0c0b), /* LDO and MISC control */
4019 {}
4020 };
4021 static struct coef_fw coef0256[] = {
4022 WRITE_COEF(0x1b, 0x0c4b), /* LDO and MISC control */
4023 {}
4024 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004025 static struct coef_fw coef0233[] = {
4026 WRITE_COEF(0x1b, 0x0c0b),
4027 WRITE_COEF(0x45, 0xc429),
4028 UPDATE_COEF(0x35, 0x4000, 0),
4029 WRITE_COEF(0x06, 0x2104),
4030 WRITE_COEF(0x1a, 0x0001),
4031 WRITE_COEF(0x26, 0x0004),
4032 WRITE_COEF(0x32, 0x42a3),
4033 {}
4034 };
Kailang Yangf3b70332015-04-08 15:01:17 +08004035 static struct coef_fw coef0288[] = {
4036 UPDATE_COEF(0x4f, 0xfcc0, 0xc400),
4037 UPDATE_COEF(0x50, 0x2000, 0x2000),
4038 UPDATE_COEF(0x56, 0x0006, 0x0006),
4039 UPDATE_COEF(0x66, 0x0008, 0),
4040 UPDATE_COEF(0x67, 0x2000, 0),
4041 {}
4042 };
Kailang Yang89542932017-07-17 15:03:43 +08004043 static struct coef_fw coef0298[] = {
4044 UPDATE_COEF(0x19, 0x1300, 0x0300),
4045 {}
4046 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004047 static struct coef_fw coef0292[] = {
4048 WRITE_COEF(0x76, 0x000e),
4049 WRITE_COEF(0x6c, 0x2400),
4050 WRITE_COEF(0x18, 0x7308),
4051 WRITE_COEF(0x6b, 0xc429),
4052 {}
4053 };
4054 static struct coef_fw coef0293[] = {
4055 UPDATE_COEF(0x10, 7<<8, 6<<8), /* SET Line1 JD to 0 */
4056 UPDATE_COEFEX(0x57, 0x05, 1<<15|1<<13, 0x0), /* SET charge pump by verb */
4057 UPDATE_COEFEX(0x57, 0x03, 1<<10, 1<<10), /* SET EN_OSW to 1 */
4058 UPDATE_COEF(0x1a, 1<<3, 1<<3), /* Combo JD gating with LINE1-VREFO */
4059 WRITE_COEF(0x45, 0xc429), /* Set to TRS type */
4060 UPDATE_COEF(0x4a, 0x000f, 0x000e), /* Combo Jack auto detect */
4061 {}
4062 };
4063 static struct coef_fw coef0668[] = {
4064 WRITE_COEF(0x15, 0x0d40),
4065 WRITE_COEF(0xb7, 0x802b),
4066 {}
4067 };
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004068 static struct coef_fw coef0225[] = {
Kailang Yang5a367672017-07-21 15:23:53 +08004069 UPDATE_COEF(0x63, 3<<14, 0),
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004070 {}
4071 };
Kailang Yang71683c32017-06-20 16:33:50 +08004072 static struct coef_fw coef0274[] = {
4073 UPDATE_COEF(0x4a, 0x0100, 0),
4074 UPDATE_COEFEX(0x57, 0x05, 0x4000, 0),
4075 UPDATE_COEF(0x6b, 0xf000, 0x5000),
4076 UPDATE_COEF(0x4a, 0x0010, 0),
4077 UPDATE_COEF(0x4a, 0x0c00, 0x0c00),
4078 WRITE_COEF(0x45, 0x5289),
4079 UPDATE_COEF(0x4a, 0x0c00, 0),
4080 {}
4081 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004082
Takashi Iwai7639a062015-03-03 10:07:24 +01004083 switch (codec->core.vendor_id) {
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004084 case 0x10ec0255:
Kailang Yange69e7e02016-05-30 15:58:28 +08004085 alc_process_coef_fw(codec, coef0255_1);
4086 alc_process_coef_fw(codec, coef0255);
4087 break;
Kailang Yang736f20a2017-10-20 15:06:34 +08004088 case 0x10ec0236:
Kailang Yang7081adf2015-03-30 17:05:37 +08004089 case 0x10ec0256:
Kailang Yange69e7e02016-05-30 15:58:28 +08004090 alc_process_coef_fw(codec, coef0256);
Takashi Iwai54db6c32014-08-18 15:11:19 +02004091 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004092 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004093 case 0x10ec0234:
4094 case 0x10ec0274:
4095 case 0x10ec0294:
4096 alc_process_coef_fw(codec, coef0274);
4097 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004098 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004099 case 0x10ec0283:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004100 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02004101 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004102 case 0x10ec0286:
4103 case 0x10ec0288:
Kailang Yang89542932017-07-17 15:03:43 +08004104 alc_process_coef_fw(codec, coef0288);
4105 break;
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004106 case 0x10ec0298:
Kailang Yang89542932017-07-17 15:03:43 +08004107 alc_process_coef_fw(codec, coef0298);
Kailang Yangf3b70332015-04-08 15:01:17 +08004108 alc_process_coef_fw(codec, coef0288);
4109 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004110 case 0x10ec0292:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004111 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02004112 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004113 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004114 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004115 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004116 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004117 alc_process_coef_fw(codec, coef0668);
David Henningsson73bdd592013-04-15 15:44:14 +02004118 break;
Kailang Yangc2b691e2018-01-17 15:22:55 +08004119 case 0x10ec0215:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004120 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004121 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08004122 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004123 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08004124 case 0x10ec0299:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004125 alc_process_coef_fw(codec, coef0225);
4126 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08004127 case 0x10ec0867:
4128 alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
4129 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004130 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01004131 codec_dbg(codec, "Headset jack set to unplugged mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02004132}
4133
4134
4135static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin,
4136 hda_nid_t mic_pin)
4137{
Takashi Iwai54db6c32014-08-18 15:11:19 +02004138 static struct coef_fw coef0255[] = {
4139 WRITE_COEFEX(0x57, 0x03, 0x8aa6),
4140 WRITE_COEF(0x06, 0x6100), /* Set MIC2 Vref gate to normal */
4141 {}
4142 };
4143 static struct coef_fw coef0233[] = {
4144 UPDATE_COEF(0x35, 0, 1<<14),
4145 WRITE_COEF(0x06, 0x2100),
4146 WRITE_COEF(0x1a, 0x0021),
4147 WRITE_COEF(0x26, 0x008c),
4148 {}
4149 };
Kailang Yangf3b70332015-04-08 15:01:17 +08004150 static struct coef_fw coef0288[] = {
Kailang Yang89542932017-07-17 15:03:43 +08004151 UPDATE_COEF(0x4f, 0x00c0, 0),
Kailang Yangf3b70332015-04-08 15:01:17 +08004152 UPDATE_COEF(0x50, 0x2000, 0),
4153 UPDATE_COEF(0x56, 0x0006, 0),
4154 UPDATE_COEF(0x4f, 0xfcc0, 0xc400),
4155 UPDATE_COEF(0x66, 0x0008, 0x0008),
4156 UPDATE_COEF(0x67, 0x2000, 0x2000),
4157 {}
4158 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004159 static struct coef_fw coef0292[] = {
4160 WRITE_COEF(0x19, 0xa208),
4161 WRITE_COEF(0x2e, 0xacf0),
4162 {}
4163 };
4164 static struct coef_fw coef0293[] = {
4165 UPDATE_COEFEX(0x57, 0x05, 0, 1<<15|1<<13), /* SET charge pump by verb */
4166 UPDATE_COEFEX(0x57, 0x03, 1<<10, 0), /* SET EN_OSW to 0 */
4167 UPDATE_COEF(0x1a, 1<<3, 0), /* Combo JD gating without LINE1-VREFO */
4168 {}
4169 };
4170 static struct coef_fw coef0688[] = {
4171 WRITE_COEF(0xb7, 0x802b),
4172 WRITE_COEF(0xb5, 0x1040),
4173 UPDATE_COEF(0xc3, 0, 1<<12),
4174 {}
4175 };
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004176 static struct coef_fw coef0225[] = {
4177 UPDATE_COEFEX(0x57, 0x05, 1<<14, 1<<14),
4178 UPDATE_COEF(0x4a, 3<<4, 2<<4),
4179 UPDATE_COEF(0x63, 3<<14, 0),
4180 {}
4181 };
Kailang Yang71683c32017-06-20 16:33:50 +08004182 static struct coef_fw coef0274[] = {
4183 UPDATE_COEFEX(0x57, 0x05, 0x4000, 0x4000),
4184 UPDATE_COEF(0x4a, 0x0010, 0),
4185 UPDATE_COEF(0x6b, 0xf000, 0),
4186 {}
4187 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004188
Takashi Iwai7639a062015-03-03 10:07:24 +01004189 switch (codec->core.vendor_id) {
Kailang Yang736f20a2017-10-20 15:06:34 +08004190 case 0x10ec0236:
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004191 case 0x10ec0255:
Kailang Yang7081adf2015-03-30 17:05:37 +08004192 case 0x10ec0256:
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004193 alc_write_coef_idx(codec, 0x45, 0xc489);
4194 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02004195 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004196 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4197 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004198 case 0x10ec0234:
4199 case 0x10ec0274:
4200 case 0x10ec0294:
4201 alc_write_coef_idx(codec, 0x45, 0x4689);
4202 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4203 alc_process_coef_fw(codec, coef0274);
4204 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4205 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004206 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004207 case 0x10ec0283:
4208 alc_write_coef_idx(codec, 0x45, 0xc429);
4209 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02004210 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02004211 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4212 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004213 case 0x10ec0286:
4214 case 0x10ec0288:
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004215 case 0x10ec0298:
Kailang Yangf3b70332015-04-08 15:01:17 +08004216 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4217 alc_process_coef_fw(codec, coef0288);
4218 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4219 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004220 case 0x10ec0292:
4221 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02004222 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02004223 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004224 case 0x10ec0293:
4225 /* Set to TRS mode */
4226 alc_write_coef_idx(codec, 0x45, 0xc429);
4227 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02004228 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004229 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4230 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08004231 case 0x10ec0867:
4232 alc_update_coefex_idx(codec, 0x57, 0x5, 0, 1<<14);
4233 /* fallthru */
Kailang Yang9eb5d0e2017-01-17 15:40:25 +08004234 case 0x10ec0221:
David Henningsson1f8b46c2015-05-12 14:38:15 +02004235 case 0x10ec0662:
4236 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4237 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4238 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004239 case 0x10ec0668:
4240 alc_write_coef_idx(codec, 0x11, 0x0001);
4241 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02004242 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02004243 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4244 break;
Kailang Yangc2b691e2018-01-17 15:22:55 +08004245 case 0x10ec0215:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004246 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004247 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08004248 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004249 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08004250 case 0x10ec0299:
Kailang Yang5a367672017-07-21 15:23:53 +08004251 alc_process_coef_fw(codec, alc225_pre_hsmode);
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004252 alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x31<<10);
4253 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
4254 alc_process_coef_fw(codec, coef0225);
4255 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
4256 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004257 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01004258 codec_dbg(codec, "Headset jack set to mic-in mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02004259}
4260
4261static void alc_headset_mode_default(struct hda_codec *codec)
4262{
David Henningsson2ae95572016-02-25 09:37:05 +01004263 static struct coef_fw coef0225[] = {
Kailang Yang5a367672017-07-21 15:23:53 +08004264 UPDATE_COEF(0x45, 0x3f<<10, 0x30<<10),
4265 UPDATE_COEF(0x45, 0x3f<<10, 0x31<<10),
4266 UPDATE_COEF(0x49, 3<<8, 0<<8),
4267 UPDATE_COEF(0x4a, 3<<4, 3<<4),
4268 UPDATE_COEF(0x63, 3<<14, 0),
4269 UPDATE_COEF(0x67, 0xf000, 0x3000),
David Henningsson2ae95572016-02-25 09:37:05 +01004270 {}
4271 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004272 static struct coef_fw coef0255[] = {
4273 WRITE_COEF(0x45, 0xc089),
4274 WRITE_COEF(0x45, 0xc489),
4275 WRITE_COEFEX(0x57, 0x03, 0x8ea6),
4276 WRITE_COEF(0x49, 0x0049),
4277 {}
4278 };
4279 static struct coef_fw coef0233[] = {
4280 WRITE_COEF(0x06, 0x2100),
4281 WRITE_COEF(0x32, 0x4ea3),
4282 {}
4283 };
Kailang Yangf3b70332015-04-08 15:01:17 +08004284 static struct coef_fw coef0288[] = {
4285 UPDATE_COEF(0x4f, 0xfcc0, 0xc400), /* Set to TRS type */
4286 UPDATE_COEF(0x50, 0x2000, 0x2000),
4287 UPDATE_COEF(0x56, 0x0006, 0x0006),
4288 UPDATE_COEF(0x66, 0x0008, 0),
4289 UPDATE_COEF(0x67, 0x2000, 0),
4290 {}
4291 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004292 static struct coef_fw coef0292[] = {
4293 WRITE_COEF(0x76, 0x000e),
4294 WRITE_COEF(0x6c, 0x2400),
4295 WRITE_COEF(0x6b, 0xc429),
4296 WRITE_COEF(0x18, 0x7308),
4297 {}
4298 };
4299 static struct coef_fw coef0293[] = {
4300 UPDATE_COEF(0x4a, 0x000f, 0x000e), /* Combo Jack auto detect */
4301 WRITE_COEF(0x45, 0xC429), /* Set to TRS type */
4302 UPDATE_COEF(0x1a, 1<<3, 0), /* Combo JD gating without LINE1-VREFO */
4303 {}
4304 };
4305 static struct coef_fw coef0688[] = {
4306 WRITE_COEF(0x11, 0x0041),
4307 WRITE_COEF(0x15, 0x0d40),
4308 WRITE_COEF(0xb7, 0x802b),
4309 {}
4310 };
Kailang Yang71683c32017-06-20 16:33:50 +08004311 static struct coef_fw coef0274[] = {
4312 WRITE_COEF(0x45, 0x4289),
4313 UPDATE_COEF(0x4a, 0x0010, 0x0010),
4314 UPDATE_COEF(0x6b, 0x0f00, 0),
4315 UPDATE_COEF(0x49, 0x0300, 0x0300),
4316 {}
4317 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004318
Takashi Iwai7639a062015-03-03 10:07:24 +01004319 switch (codec->core.vendor_id) {
Kailang Yangc2b691e2018-01-17 15:22:55 +08004320 case 0x10ec0215:
David Henningsson2ae95572016-02-25 09:37:05 +01004321 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004322 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08004323 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004324 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08004325 case 0x10ec0299:
Kailang Yang5a367672017-07-21 15:23:53 +08004326 alc_process_coef_fw(codec, alc225_pre_hsmode);
David Henningsson2ae95572016-02-25 09:37:05 +01004327 alc_process_coef_fw(codec, coef0225);
4328 break;
Kailang Yang736f20a2017-10-20 15:06:34 +08004329 case 0x10ec0236:
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004330 case 0x10ec0255:
Kailang Yang7081adf2015-03-30 17:05:37 +08004331 case 0x10ec0256:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004332 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004333 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004334 case 0x10ec0234:
4335 case 0x10ec0274:
4336 case 0x10ec0294:
4337 alc_process_coef_fw(codec, coef0274);
4338 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004339 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004340 case 0x10ec0283:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004341 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02004342 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004343 case 0x10ec0286:
4344 case 0x10ec0288:
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004345 case 0x10ec0298:
Kailang Yangf3b70332015-04-08 15:01:17 +08004346 alc_process_coef_fw(codec, coef0288);
4347 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004348 case 0x10ec0292:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004349 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02004350 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004351 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004352 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004353 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004354 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004355 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02004356 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08004357 case 0x10ec0867:
4358 alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
4359 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004360 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01004361 codec_dbg(codec, "Headset jack set to headphone (default) mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02004362}
4363
4364/* Iphone type */
4365static void alc_headset_mode_ctia(struct hda_codec *codec)
4366{
Kailang Yang89542932017-07-17 15:03:43 +08004367 int val;
4368
Takashi Iwai54db6c32014-08-18 15:11:19 +02004369 static struct coef_fw coef0255[] = {
4370 WRITE_COEF(0x45, 0xd489), /* Set to CTIA type */
4371 WRITE_COEF(0x1b, 0x0c2b),
4372 WRITE_COEFEX(0x57, 0x03, 0x8ea6),
4373 {}
4374 };
Kailang Yange69e7e02016-05-30 15:58:28 +08004375 static struct coef_fw coef0256[] = {
4376 WRITE_COEF(0x45, 0xd489), /* Set to CTIA type */
4377 WRITE_COEF(0x1b, 0x0c6b),
4378 WRITE_COEFEX(0x57, 0x03, 0x8ea6),
4379 {}
4380 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004381 static struct coef_fw coef0233[] = {
4382 WRITE_COEF(0x45, 0xd429),
4383 WRITE_COEF(0x1b, 0x0c2b),
4384 WRITE_COEF(0x32, 0x4ea3),
4385 {}
4386 };
Kailang Yangf3b70332015-04-08 15:01:17 +08004387 static struct coef_fw coef0288[] = {
4388 UPDATE_COEF(0x50, 0x2000, 0x2000),
4389 UPDATE_COEF(0x56, 0x0006, 0x0006),
4390 UPDATE_COEF(0x66, 0x0008, 0),
4391 UPDATE_COEF(0x67, 0x2000, 0),
4392 {}
4393 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004394 static struct coef_fw coef0292[] = {
4395 WRITE_COEF(0x6b, 0xd429),
4396 WRITE_COEF(0x76, 0x0008),
4397 WRITE_COEF(0x18, 0x7388),
4398 {}
4399 };
4400 static struct coef_fw coef0293[] = {
4401 WRITE_COEF(0x45, 0xd429), /* Set to ctia type */
4402 UPDATE_COEF(0x10, 7<<8, 7<<8), /* SET Line1 JD to 1 */
4403 {}
4404 };
4405 static struct coef_fw coef0688[] = {
4406 WRITE_COEF(0x11, 0x0001),
4407 WRITE_COEF(0x15, 0x0d60),
4408 WRITE_COEF(0xc3, 0x0000),
4409 {}
4410 };
Kailang Yang5a367672017-07-21 15:23:53 +08004411 static struct coef_fw coef0225_1[] = {
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004412 UPDATE_COEF(0x45, 0x3f<<10, 0x35<<10),
Kailang Yang5a367672017-07-21 15:23:53 +08004413 UPDATE_COEF(0x63, 3<<14, 2<<14),
4414 {}
4415 };
4416 static struct coef_fw coef0225_2[] = {
4417 UPDATE_COEF(0x45, 0x3f<<10, 0x35<<10),
4418 UPDATE_COEF(0x63, 3<<14, 1<<14),
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004419 {}
4420 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004421
Takashi Iwai7639a062015-03-03 10:07:24 +01004422 switch (codec->core.vendor_id) {
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004423 case 0x10ec0255:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004424 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004425 break;
Kailang Yang736f20a2017-10-20 15:06:34 +08004426 case 0x10ec0236:
Kailang Yange69e7e02016-05-30 15:58:28 +08004427 case 0x10ec0256:
4428 alc_process_coef_fw(codec, coef0256);
4429 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004430 case 0x10ec0234:
4431 case 0x10ec0274:
4432 case 0x10ec0294:
4433 alc_write_coef_idx(codec, 0x45, 0xd689);
4434 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004435 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004436 case 0x10ec0283:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004437 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02004438 break;
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004439 case 0x10ec0298:
Kailang Yang89542932017-07-17 15:03:43 +08004440 val = alc_read_coef_idx(codec, 0x50);
4441 if (val & (1 << 12)) {
4442 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0020);
4443 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400);
4444 msleep(300);
4445 } else {
4446 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0010);
4447 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400);
4448 msleep(300);
4449 }
4450 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004451 case 0x10ec0286:
4452 case 0x10ec0288:
4453 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400);
4454 msleep(300);
4455 alc_process_coef_fw(codec, coef0288);
4456 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004457 case 0x10ec0292:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004458 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02004459 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004460 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004461 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004462 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004463 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004464 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02004465 break;
Kailang Yangc2b691e2018-01-17 15:22:55 +08004466 case 0x10ec0215:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004467 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004468 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08004469 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004470 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08004471 case 0x10ec0299:
Kailang Yang5a367672017-07-21 15:23:53 +08004472 val = alc_read_coef_idx(codec, 0x45);
4473 if (val & (1 << 9))
4474 alc_process_coef_fw(codec, coef0225_2);
4475 else
4476 alc_process_coef_fw(codec, coef0225_1);
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004477 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08004478 case 0x10ec0867:
4479 alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
4480 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004481 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01004482 codec_dbg(codec, "Headset jack set to iPhone-style headset mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02004483}
4484
4485/* Nokia type */
4486static void alc_headset_mode_omtp(struct hda_codec *codec)
4487{
Takashi Iwai54db6c32014-08-18 15:11:19 +02004488 static struct coef_fw coef0255[] = {
4489 WRITE_COEF(0x45, 0xe489), /* Set to OMTP Type */
4490 WRITE_COEF(0x1b, 0x0c2b),
4491 WRITE_COEFEX(0x57, 0x03, 0x8ea6),
4492 {}
4493 };
Kailang Yange69e7e02016-05-30 15:58:28 +08004494 static struct coef_fw coef0256[] = {
4495 WRITE_COEF(0x45, 0xe489), /* Set to OMTP Type */
4496 WRITE_COEF(0x1b, 0x0c6b),
4497 WRITE_COEFEX(0x57, 0x03, 0x8ea6),
4498 {}
4499 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004500 static struct coef_fw coef0233[] = {
4501 WRITE_COEF(0x45, 0xe429),
4502 WRITE_COEF(0x1b, 0x0c2b),
4503 WRITE_COEF(0x32, 0x4ea3),
4504 {}
4505 };
Kailang Yangf3b70332015-04-08 15:01:17 +08004506 static struct coef_fw coef0288[] = {
4507 UPDATE_COEF(0x50, 0x2000, 0x2000),
4508 UPDATE_COEF(0x56, 0x0006, 0x0006),
4509 UPDATE_COEF(0x66, 0x0008, 0),
4510 UPDATE_COEF(0x67, 0x2000, 0),
4511 {}
4512 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004513 static struct coef_fw coef0292[] = {
4514 WRITE_COEF(0x6b, 0xe429),
4515 WRITE_COEF(0x76, 0x0008),
4516 WRITE_COEF(0x18, 0x7388),
4517 {}
4518 };
4519 static struct coef_fw coef0293[] = {
4520 WRITE_COEF(0x45, 0xe429), /* Set to omtp type */
4521 UPDATE_COEF(0x10, 7<<8, 7<<8), /* SET Line1 JD to 1 */
4522 {}
4523 };
4524 static struct coef_fw coef0688[] = {
4525 WRITE_COEF(0x11, 0x0001),
4526 WRITE_COEF(0x15, 0x0d50),
4527 WRITE_COEF(0xc3, 0x0000),
4528 {}
4529 };
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004530 static struct coef_fw coef0225[] = {
4531 UPDATE_COEF(0x45, 0x3f<<10, 0x39<<10),
Kailang Yang5a367672017-07-21 15:23:53 +08004532 UPDATE_COEF(0x63, 3<<14, 2<<14),
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004533 {}
4534 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004535
Takashi Iwai7639a062015-03-03 10:07:24 +01004536 switch (codec->core.vendor_id) {
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004537 case 0x10ec0255:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004538 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004539 break;
Kailang Yang736f20a2017-10-20 15:06:34 +08004540 case 0x10ec0236:
Kailang Yange69e7e02016-05-30 15:58:28 +08004541 case 0x10ec0256:
4542 alc_process_coef_fw(codec, coef0256);
4543 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004544 case 0x10ec0234:
4545 case 0x10ec0274:
4546 case 0x10ec0294:
4547 alc_write_coef_idx(codec, 0x45, 0xe689);
4548 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004549 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004550 case 0x10ec0283:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004551 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02004552 break;
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004553 case 0x10ec0298:
4554 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0010);/* Headset output enable */
Kailang Yang89542932017-07-17 15:03:43 +08004555 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xe400);
4556 msleep(300);
4557 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004558 case 0x10ec0286:
4559 case 0x10ec0288:
4560 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xe400);
4561 msleep(300);
4562 alc_process_coef_fw(codec, coef0288);
4563 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004564 case 0x10ec0292:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004565 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02004566 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004567 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004568 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004569 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004570 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004571 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02004572 break;
Kailang Yangc2b691e2018-01-17 15:22:55 +08004573 case 0x10ec0215:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004574 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004575 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08004576 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004577 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08004578 case 0x10ec0299:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004579 alc_process_coef_fw(codec, coef0225);
4580 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004581 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01004582 codec_dbg(codec, "Headset jack set to Nokia-style headset mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02004583}
4584
4585static void alc_determine_headset_type(struct hda_codec *codec)
4586{
4587 int val;
4588 bool is_ctia = false;
4589 struct alc_spec *spec = codec->spec;
Takashi Iwai54db6c32014-08-18 15:11:19 +02004590 static struct coef_fw coef0255[] = {
4591 WRITE_COEF(0x45, 0xd089), /* combo jack auto switch control(Check type)*/
4592 WRITE_COEF(0x49, 0x0149), /* combo jack auto switch control(Vref
4593 conteol) */
4594 {}
4595 };
Kailang Yangf3b70332015-04-08 15:01:17 +08004596 static struct coef_fw coef0288[] = {
4597 UPDATE_COEF(0x4f, 0xfcc0, 0xd400), /* Check Type */
4598 {}
4599 };
Kailang Yang89542932017-07-17 15:03:43 +08004600 static struct coef_fw coef0298[] = {
4601 UPDATE_COEF(0x50, 0x2000, 0x2000),
4602 UPDATE_COEF(0x56, 0x0006, 0x0006),
4603 UPDATE_COEF(0x66, 0x0008, 0),
4604 UPDATE_COEF(0x67, 0x2000, 0),
4605 UPDATE_COEF(0x19, 0x1300, 0x1300),
4606 {}
4607 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004608 static struct coef_fw coef0293[] = {
4609 UPDATE_COEF(0x4a, 0x000f, 0x0008), /* Combo Jack auto detect */
4610 WRITE_COEF(0x45, 0xD429), /* Set to ctia type */
4611 {}
4612 };
4613 static struct coef_fw coef0688[] = {
4614 WRITE_COEF(0x11, 0x0001),
4615 WRITE_COEF(0xb7, 0x802b),
4616 WRITE_COEF(0x15, 0x0d60),
4617 WRITE_COEF(0xc3, 0x0c00),
4618 {}
4619 };
Kailang Yang71683c32017-06-20 16:33:50 +08004620 static struct coef_fw coef0274[] = {
4621 UPDATE_COEF(0x4a, 0x0010, 0),
4622 UPDATE_COEF(0x4a, 0x8000, 0),
4623 WRITE_COEF(0x45, 0xd289),
4624 UPDATE_COEF(0x49, 0x0300, 0x0300),
4625 {}
4626 };
David Henningsson73bdd592013-04-15 15:44:14 +02004627
Takashi Iwai7639a062015-03-03 10:07:24 +01004628 switch (codec->core.vendor_id) {
Kailang Yang736f20a2017-10-20 15:06:34 +08004629 case 0x10ec0236:
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004630 case 0x10ec0255:
Kailang Yang7081adf2015-03-30 17:05:37 +08004631 case 0x10ec0256:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004632 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004633 msleep(300);
4634 val = alc_read_coef_idx(codec, 0x46);
4635 is_ctia = (val & 0x0070) == 0x0070;
4636 break;
Kailang Yang71683c32017-06-20 16:33:50 +08004637 case 0x10ec0234:
4638 case 0x10ec0274:
4639 case 0x10ec0294:
4640 alc_process_coef_fw(codec, coef0274);
4641 msleep(80);
4642 val = alc_read_coef_idx(codec, 0x46);
4643 is_ctia = (val & 0x00f0) == 0x00f0;
4644 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004645 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004646 case 0x10ec0283:
4647 alc_write_coef_idx(codec, 0x45, 0xd029);
4648 msleep(300);
4649 val = alc_read_coef_idx(codec, 0x46);
4650 is_ctia = (val & 0x0070) == 0x0070;
4651 break;
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004652 case 0x10ec0298:
Kailang Yang89542932017-07-17 15:03:43 +08004653 snd_hda_codec_write(codec, 0x21, 0,
4654 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
4655 msleep(100);
4656 snd_hda_codec_write(codec, 0x21, 0,
4657 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
4658 msleep(200);
4659
4660 val = alc_read_coef_idx(codec, 0x50);
4661 if (val & (1 << 12)) {
4662 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0020);
4663 alc_process_coef_fw(codec, coef0288);
4664 msleep(350);
4665 val = alc_read_coef_idx(codec, 0x50);
4666 is_ctia = (val & 0x0070) == 0x0070;
4667 } else {
4668 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0010);
4669 alc_process_coef_fw(codec, coef0288);
4670 msleep(350);
4671 val = alc_read_coef_idx(codec, 0x50);
4672 is_ctia = (val & 0x0070) == 0x0070;
4673 }
4674 alc_process_coef_fw(codec, coef0298);
4675 snd_hda_codec_write(codec, 0x21, 0,
4676 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP);
4677 msleep(75);
4678 snd_hda_codec_write(codec, 0x21, 0,
4679 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
4680 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08004681 case 0x10ec0286:
4682 case 0x10ec0288:
4683 alc_process_coef_fw(codec, coef0288);
4684 msleep(350);
4685 val = alc_read_coef_idx(codec, 0x50);
4686 is_ctia = (val & 0x0070) == 0x0070;
4687 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004688 case 0x10ec0292:
4689 alc_write_coef_idx(codec, 0x6b, 0xd429);
4690 msleep(300);
4691 val = alc_read_coef_idx(codec, 0x6c);
4692 is_ctia = (val & 0x001c) == 0x001c;
4693 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004694 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004695 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004696 msleep(300);
4697 val = alc_read_coef_idx(codec, 0x46);
4698 is_ctia = (val & 0x0070) == 0x0070;
4699 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004700 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004701 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02004702 msleep(300);
4703 val = alc_read_coef_idx(codec, 0xbe);
4704 is_ctia = (val & 0x1c02) == 0x1c02;
4705 break;
Kailang Yangc2b691e2018-01-17 15:22:55 +08004706 case 0x10ec0215:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004707 case 0x10ec0225:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004708 case 0x10ec0285:
Kailang Yang7d727862016-05-24 16:46:07 +08004709 case 0x10ec0295:
Kailang Yangc2b691e2018-01-17 15:22:55 +08004710 case 0x10ec0289:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08004711 case 0x10ec0299:
Kailang Yangda911b12018-01-05 16:50:08 +08004712 snd_hda_codec_write(codec, 0x21, 0,
4713 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
4714 msleep(80);
4715 snd_hda_codec_write(codec, 0x21, 0,
4716 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
4717
Kailang Yang5a367672017-07-21 15:23:53 +08004718 alc_process_coef_fw(codec, alc225_pre_hsmode);
4719 alc_update_coef_idx(codec, 0x67, 0xf000, 0x1000);
4720 val = alc_read_coef_idx(codec, 0x45);
4721 if (val & (1 << 9)) {
4722 alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x34<<10);
4723 alc_update_coef_idx(codec, 0x49, 3<<8, 2<<8);
4724 msleep(800);
4725 val = alc_read_coef_idx(codec, 0x46);
4726 is_ctia = (val & 0x00f0) == 0x00f0;
4727 } else {
4728 alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x34<<10);
4729 alc_update_coef_idx(codec, 0x49, 3<<8, 1<<8);
4730 msleep(800);
4731 val = alc_read_coef_idx(codec, 0x46);
4732 is_ctia = (val & 0x00f0) == 0x00f0;
4733 }
4734 alc_update_coef_idx(codec, 0x4a, 7<<6, 7<<6);
4735 alc_update_coef_idx(codec, 0x4a, 3<<4, 3<<4);
4736 alc_update_coef_idx(codec, 0x67, 0xf000, 0x3000);
Kailang Yangda911b12018-01-05 16:50:08 +08004737
4738 snd_hda_codec_write(codec, 0x21, 0,
4739 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
4740 msleep(80);
4741 snd_hda_codec_write(codec, 0x21, 0,
4742 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004743 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08004744 case 0x10ec0867:
4745 is_ctia = true;
4746 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004747 }
4748
Takashi Iwai4e76a882014-02-25 12:21:03 +01004749 codec_dbg(codec, "Headset jack detected iPhone-style headset: %s\n",
David Henningsson73bdd592013-04-15 15:44:14 +02004750 is_ctia ? "yes" : "no");
4751 spec->current_headset_type = is_ctia ? ALC_HEADSET_TYPE_CTIA : ALC_HEADSET_TYPE_OMTP;
4752}
4753
4754static void alc_update_headset_mode(struct hda_codec *codec)
4755{
4756 struct alc_spec *spec = codec->spec;
4757
4758 hda_nid_t mux_pin = spec->gen.imux_pins[spec->gen.cur_mux[0]];
4759 hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
4760
4761 int new_headset_mode;
4762
4763 if (!snd_hda_jack_detect(codec, hp_pin))
4764 new_headset_mode = ALC_HEADSET_MODE_UNPLUGGED;
4765 else if (mux_pin == spec->headset_mic_pin)
4766 new_headset_mode = ALC_HEADSET_MODE_HEADSET;
4767 else if (mux_pin == spec->headphone_mic_pin)
4768 new_headset_mode = ALC_HEADSET_MODE_MIC;
4769 else
4770 new_headset_mode = ALC_HEADSET_MODE_HEADPHONE;
4771
David Henningsson5959a6b2013-11-12 11:10:57 +01004772 if (new_headset_mode == spec->current_headset_mode) {
4773 snd_hda_gen_update_outputs(codec);
David Henningsson73bdd592013-04-15 15:44:14 +02004774 return;
David Henningsson5959a6b2013-11-12 11:10:57 +01004775 }
David Henningsson73bdd592013-04-15 15:44:14 +02004776
4777 switch (new_headset_mode) {
4778 case ALC_HEADSET_MODE_UNPLUGGED:
4779 alc_headset_mode_unplugged(codec);
4780 spec->gen.hp_jack_present = false;
4781 break;
4782 case ALC_HEADSET_MODE_HEADSET:
4783 if (spec->current_headset_type == ALC_HEADSET_TYPE_UNKNOWN)
4784 alc_determine_headset_type(codec);
4785 if (spec->current_headset_type == ALC_HEADSET_TYPE_CTIA)
4786 alc_headset_mode_ctia(codec);
4787 else if (spec->current_headset_type == ALC_HEADSET_TYPE_OMTP)
4788 alc_headset_mode_omtp(codec);
4789 spec->gen.hp_jack_present = true;
4790 break;
4791 case ALC_HEADSET_MODE_MIC:
4792 alc_headset_mode_mic_in(codec, hp_pin, spec->headphone_mic_pin);
4793 spec->gen.hp_jack_present = false;
4794 break;
4795 case ALC_HEADSET_MODE_HEADPHONE:
4796 alc_headset_mode_default(codec);
4797 spec->gen.hp_jack_present = true;
4798 break;
4799 }
4800 if (new_headset_mode != ALC_HEADSET_MODE_MIC) {
4801 snd_hda_set_pin_ctl_cache(codec, hp_pin,
4802 AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN);
David Henningsson1f8b46c2015-05-12 14:38:15 +02004803 if (spec->headphone_mic_pin && spec->headphone_mic_pin != hp_pin)
David Henningsson73bdd592013-04-15 15:44:14 +02004804 snd_hda_set_pin_ctl_cache(codec, spec->headphone_mic_pin,
4805 PIN_VREFHIZ);
4806 }
4807 spec->current_headset_mode = new_headset_mode;
4808
4809 snd_hda_gen_update_outputs(codec);
4810}
4811
4812static void alc_update_headset_mode_hook(struct hda_codec *codec,
Takashi Iwai7fe30712014-01-30 17:59:02 +01004813 struct snd_kcontrol *kcontrol,
4814 struct snd_ctl_elem_value *ucontrol)
David Henningsson73bdd592013-04-15 15:44:14 +02004815{
4816 alc_update_headset_mode(codec);
4817}
4818
Takashi Iwai1a4f69d2014-09-11 15:22:46 +02004819static void alc_update_headset_jack_cb(struct hda_codec *codec,
4820 struct hda_jack_callback *jack)
David Henningsson73bdd592013-04-15 15:44:14 +02004821{
4822 struct alc_spec *spec = codec->spec;
David Henningsson5db4d342013-11-22 12:17:06 +01004823 spec->current_headset_type = ALC_HEADSET_TYPE_UNKNOWN;
David Henningsson73bdd592013-04-15 15:44:14 +02004824 snd_hda_gen_hp_automute(codec, jack);
4825}
4826
4827static void alc_probe_headset_mode(struct hda_codec *codec)
4828{
4829 int i;
4830 struct alc_spec *spec = codec->spec;
4831 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
4832
4833 /* Find mic pins */
4834 for (i = 0; i < cfg->num_inputs; i++) {
4835 if (cfg->inputs[i].is_headset_mic && !spec->headset_mic_pin)
4836 spec->headset_mic_pin = cfg->inputs[i].pin;
4837 if (cfg->inputs[i].is_headphone_mic && !spec->headphone_mic_pin)
4838 spec->headphone_mic_pin = cfg->inputs[i].pin;
4839 }
4840
4841 spec->gen.cap_sync_hook = alc_update_headset_mode_hook;
4842 spec->gen.automute_hook = alc_update_headset_mode;
4843 spec->gen.hp_automute_hook = alc_update_headset_jack_cb;
4844}
4845
4846static void alc_fixup_headset_mode(struct hda_codec *codec,
4847 const struct hda_fixup *fix, int action)
4848{
4849 struct alc_spec *spec = codec->spec;
4850
4851 switch (action) {
4852 case HDA_FIXUP_ACT_PRE_PROBE:
4853 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC | HDA_PINCFG_HEADPHONE_MIC;
4854 break;
4855 case HDA_FIXUP_ACT_PROBE:
4856 alc_probe_headset_mode(codec);
4857 break;
4858 case HDA_FIXUP_ACT_INIT:
4859 spec->current_headset_mode = 0;
4860 alc_update_headset_mode(codec);
4861 break;
4862 }
4863}
4864
4865static void alc_fixup_headset_mode_no_hp_mic(struct hda_codec *codec,
4866 const struct hda_fixup *fix, int action)
4867{
4868 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4869 struct alc_spec *spec = codec->spec;
4870 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
4871 }
4872 else
4873 alc_fixup_headset_mode(codec, fix, action);
4874}
4875
Kailang Yang31278992014-03-03 15:27:22 +08004876static void alc255_set_default_jack_type(struct hda_codec *codec)
4877{
4878 /* Set to iphone type */
Kailang Yange69e7e02016-05-30 15:58:28 +08004879 static struct coef_fw alc255fw[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004880 WRITE_COEF(0x1b, 0x880b),
4881 WRITE_COEF(0x45, 0xd089),
4882 WRITE_COEF(0x1b, 0x080b),
4883 WRITE_COEF(0x46, 0x0004),
4884 WRITE_COEF(0x1b, 0x0c0b),
4885 {}
4886 };
Kailang Yange69e7e02016-05-30 15:58:28 +08004887 static struct coef_fw alc256fw[] = {
4888 WRITE_COEF(0x1b, 0x884b),
4889 WRITE_COEF(0x45, 0xd089),
4890 WRITE_COEF(0x1b, 0x084b),
4891 WRITE_COEF(0x46, 0x0004),
4892 WRITE_COEF(0x1b, 0x0c4b),
4893 {}
4894 };
4895 switch (codec->core.vendor_id) {
4896 case 0x10ec0255:
4897 alc_process_coef_fw(codec, alc255fw);
4898 break;
Kailang Yang736f20a2017-10-20 15:06:34 +08004899 case 0x10ec0236:
Kailang Yange69e7e02016-05-30 15:58:28 +08004900 case 0x10ec0256:
4901 alc_process_coef_fw(codec, alc256fw);
4902 break;
4903 }
Kailang Yang31278992014-03-03 15:27:22 +08004904 msleep(30);
4905}
4906
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004907static void alc_fixup_headset_mode_alc255(struct hda_codec *codec,
4908 const struct hda_fixup *fix, int action)
4909{
4910 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Kailang Yang31278992014-03-03 15:27:22 +08004911 alc255_set_default_jack_type(codec);
Kailang Yang9a22a8f52013-11-08 15:54:49 +08004912 }
4913 alc_fixup_headset_mode(codec, fix, action);
4914}
4915
Kailang Yang31278992014-03-03 15:27:22 +08004916static void alc_fixup_headset_mode_alc255_no_hp_mic(struct hda_codec *codec,
4917 const struct hda_fixup *fix, int action)
4918{
4919 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4920 struct alc_spec *spec = codec->spec;
4921 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
4922 alc255_set_default_jack_type(codec);
4923 }
4924 else
4925 alc_fixup_headset_mode(codec, fix, action);
4926}
4927
Kailang Yange1e62b92015-04-08 16:01:22 +08004928static void alc288_update_headset_jack_cb(struct hda_codec *codec,
4929 struct hda_jack_callback *jack)
4930{
4931 struct alc_spec *spec = codec->spec;
4932 int present;
4933
4934 alc_update_headset_jack_cb(codec, jack);
4935 /* Headset Mic enable or disable, only for Dell Dino */
4936 present = spec->gen.hp_jack_present ? 0x40 : 0;
4937 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
4938 present);
4939}
4940
4941static void alc_fixup_headset_mode_dell_alc288(struct hda_codec *codec,
4942 const struct hda_fixup *fix, int action)
4943{
4944 alc_fixup_headset_mode(codec, fix, action);
4945 if (action == HDA_FIXUP_ACT_PROBE) {
4946 struct alc_spec *spec = codec->spec;
4947 spec->gen.hp_automute_hook = alc288_update_headset_jack_cb;
4948 }
4949}
4950
Hui Wang493a52a2014-01-14 14:07:36 +08004951static void alc_fixup_auto_mute_via_amp(struct hda_codec *codec,
4952 const struct hda_fixup *fix, int action)
4953{
4954 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4955 struct alc_spec *spec = codec->spec;
4956 spec->gen.auto_mute_via_amp = 1;
4957 }
4958}
4959
Takashi Iwai9b745ab2014-03-07 08:37:19 +01004960static void alc_no_shutup(struct hda_codec *codec)
4961{
4962}
4963
4964static void alc_fixup_no_shutup(struct hda_codec *codec,
4965 const struct hda_fixup *fix, int action)
4966{
Gabriele Mazzotta972aa2c2016-12-24 19:50:00 +01004967 if (action == HDA_FIXUP_ACT_PROBE) {
Takashi Iwai9b745ab2014-03-07 08:37:19 +01004968 struct alc_spec *spec = codec->spec;
4969 spec->shutup = alc_no_shutup;
4970 }
4971}
4972
Gabriele Mazzotta5e6db662014-05-20 18:58:26 +02004973static void alc_fixup_disable_aamix(struct hda_codec *codec,
4974 const struct hda_fixup *fix, int action)
4975{
4976 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4977 struct alc_spec *spec = codec->spec;
4978 /* Disable AA-loopback as it causes white noise */
4979 spec->gen.mixer_nid = 0;
4980 }
4981}
4982
Takashi Iwai7f57d802015-09-24 17:36:51 +02004983/* fixup for Thinkpad docks: add dock pins, avoid HP parser fixup */
4984static void alc_fixup_tpt440_dock(struct hda_codec *codec,
4985 const struct hda_fixup *fix, int action)
4986{
4987 static const struct hda_pintbl pincfgs[] = {
4988 { 0x16, 0x21211010 }, /* dock headphone */
4989 { 0x19, 0x21a11010 }, /* dock mic */
4990 { }
4991 };
4992 struct alc_spec *spec = codec->spec;
4993
4994 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai157f0b72015-12-10 23:30:43 +01004995 spec->shutup = alc_no_shutup; /* reduce click noise */
Takashi Iwai70a09762015-12-15 14:59:58 +01004996 spec->reboot_notify = alc_d3_at_reboot; /* reduce noise */
Takashi Iwai7f57d802015-09-24 17:36:51 +02004997 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
4998 codec->power_save_node = 0; /* avoid click noises */
4999 snd_hda_apply_pincfgs(codec, pincfgs);
5000 }
5001}
5002
Kailang Yang61fcf8e2018-02-02 15:26:46 +08005003static void alc_fixup_tpt470_dock(struct hda_codec *codec,
5004 const struct hda_fixup *fix, int action)
5005{
5006 static const struct hda_pintbl pincfgs[] = {
5007 { 0x17, 0x21211010 }, /* dock headphone */
5008 { 0x19, 0x21a11010 }, /* dock mic */
5009 { }
5010 };
5011 struct alc_spec *spec = codec->spec;
5012
5013 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5014 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
Takashi Iwai71db96d2018-02-26 15:36:38 +01005015 snd_hda_apply_pincfgs(codec, pincfgs);
5016 } else if (action == HDA_FIXUP_ACT_INIT) {
Kailang Yang61fcf8e2018-02-02 15:26:46 +08005017 /* Enable DOCK device */
5018 snd_hda_codec_write(codec, 0x17, 0,
5019 AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0);
5020 /* Enable DOCK device */
5021 snd_hda_codec_write(codec, 0x19, 0,
5022 AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0);
Kailang Yang61fcf8e2018-02-02 15:26:46 +08005023 }
5024}
5025
Gabriele Mazzotta9476d3692015-04-19 19:00:40 +02005026static void alc_shutup_dell_xps13(struct hda_codec *codec)
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02005027{
5028 struct alc_spec *spec = codec->spec;
Gabriele Mazzotta9476d3692015-04-19 19:00:40 +02005029 int hp_pin = spec->gen.autocfg.hp_pins[0];
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02005030
Gabriele Mazzotta9476d3692015-04-19 19:00:40 +02005031 /* Prevent pop noises when headphones are plugged in */
5032 snd_hda_codec_write(codec, hp_pin, 0,
5033 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
5034 msleep(20);
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02005035}
5036
5037static void alc_fixup_dell_xps13(struct hda_codec *codec,
5038 const struct hda_fixup *fix, int action)
5039{
Takashi Iwai3e1b0c42015-04-27 10:43:22 +02005040 struct alc_spec *spec = codec->spec;
5041 struct hda_input_mux *imux = &spec->gen.input_mux;
5042 int i;
Gabriele Mazzottaf38663a2014-08-08 19:34:40 +02005043
Takashi Iwai3e1b0c42015-04-27 10:43:22 +02005044 switch (action) {
5045 case HDA_FIXUP_ACT_PRE_PROBE:
5046 /* mic pin 0x19 must be initialized with Vref Hi-Z, otherwise
5047 * it causes a click noise at start up
5048 */
5049 snd_hda_codec_set_pin_target(codec, 0x19, PIN_VREFHIZ);
5050 break;
5051 case HDA_FIXUP_ACT_PROBE:
Gabriele Mazzotta9476d3692015-04-19 19:00:40 +02005052 spec->shutup = alc_shutup_dell_xps13;
Gabriele Mazzottaf38663a2014-08-08 19:34:40 +02005053
5054 /* Make the internal mic the default input source. */
5055 for (i = 0; i < imux->num_items; i++) {
5056 if (spec->gen.imux_pins[i] == 0x12) {
5057 spec->gen.cur_mux[0] = i;
5058 break;
5059 }
5060 }
Takashi Iwai3e1b0c42015-04-27 10:43:22 +02005061 break;
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02005062 }
5063}
5064
David Henningsson1f8b46c2015-05-12 14:38:15 +02005065static void alc_fixup_headset_mode_alc662(struct hda_codec *codec,
5066 const struct hda_fixup *fix, int action)
5067{
5068 struct alc_spec *spec = codec->spec;
5069
5070 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5071 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
5072 spec->gen.hp_mic = 1; /* Mic-in is same pin as headphone */
David Henningssonb40eda62015-05-28 09:40:23 +02005073
5074 /* Disable boost for mic-in permanently. (This code is only called
5075 from quirks that guarantee that the headphone is at NID 0x1b.) */
5076 snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000);
5077 snd_hda_override_wcaps(codec, 0x1b, get_wcaps(codec, 0x1b) & ~AC_WCAP_IN_AMP);
David Henningsson1f8b46c2015-05-12 14:38:15 +02005078 } else
5079 alc_fixup_headset_mode(codec, fix, action);
5080}
5081
David Henningsson73bdd592013-04-15 15:44:14 +02005082static void alc_fixup_headset_mode_alc668(struct hda_codec *codec,
5083 const struct hda_fixup *fix, int action)
5084{
5085 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
David Henningsson73bdd592013-04-15 15:44:14 +02005086 alc_write_coef_idx(codec, 0xc4, 0x8000);
Takashi Iwai98b24882014-08-18 13:47:50 +02005087 alc_update_coef_idx(codec, 0xc2, ~0xfe, 0);
David Henningsson73bdd592013-04-15 15:44:14 +02005088 snd_hda_set_pin_ctl_cache(codec, 0x18, 0);
5089 }
5090 alc_fixup_headset_mode(codec, fix, action);
5091}
5092
Chih-Chung Changbde7bc62013-08-05 16:38:42 +08005093/* Returns the nid of the external mic input pin, or 0 if it cannot be found. */
5094static int find_ext_mic_pin(struct hda_codec *codec)
5095{
5096 struct alc_spec *spec = codec->spec;
5097 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
5098 hda_nid_t nid;
5099 unsigned int defcfg;
5100 int i;
5101
5102 for (i = 0; i < cfg->num_inputs; i++) {
5103 if (cfg->inputs[i].type != AUTO_PIN_MIC)
5104 continue;
5105 nid = cfg->inputs[i].pin;
5106 defcfg = snd_hda_codec_get_pincfg(codec, nid);
5107 if (snd_hda_get_input_pin_attr(defcfg) == INPUT_PIN_ATTR_INT)
5108 continue;
5109 return nid;
5110 }
5111
5112 return 0;
5113}
5114
Dylan Reid08a978d2012-11-18 22:56:40 -08005115static void alc271_hp_gate_mic_jack(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01005116 const struct hda_fixup *fix,
Dylan Reid08a978d2012-11-18 22:56:40 -08005117 int action)
5118{
5119 struct alc_spec *spec = codec->spec;
5120
Takashi Iwai0db75792013-01-23 13:57:20 +01005121 if (action == HDA_FIXUP_ACT_PROBE) {
Chih-Chung Changbde7bc62013-08-05 16:38:42 +08005122 int mic_pin = find_ext_mic_pin(codec);
5123 int hp_pin = spec->gen.autocfg.hp_pins[0];
5124
5125 if (snd_BUG_ON(!mic_pin || !hp_pin))
Takashi Iwai0db75792013-01-23 13:57:20 +01005126 return;
Chih-Chung Changbde7bc62013-08-05 16:38:42 +08005127 snd_hda_jack_set_gating_jack(codec, mic_pin, hp_pin);
Takashi Iwai0db75792013-01-23 13:57:20 +01005128 }
Dylan Reid08a978d2012-11-18 22:56:40 -08005129}
David Henningsson693b6132012-06-22 19:12:10 +02005130
David Henningsson3e0d6112013-04-22 14:30:14 +02005131static void alc269_fixup_limit_int_mic_boost(struct hda_codec *codec,
5132 const struct hda_fixup *fix,
5133 int action)
5134{
5135 struct alc_spec *spec = codec->spec;
5136 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
5137 int i;
5138
5139 /* The mic boosts on level 2 and 3 are too noisy
5140 on the internal mic input.
5141 Therefore limit the boost to 0 or 1. */
5142
5143 if (action != HDA_FIXUP_ACT_PROBE)
5144 return;
5145
5146 for (i = 0; i < cfg->num_inputs; i++) {
5147 hda_nid_t nid = cfg->inputs[i].pin;
5148 unsigned int defcfg;
5149 if (cfg->inputs[i].type != AUTO_PIN_MIC)
5150 continue;
5151 defcfg = snd_hda_codec_get_pincfg(codec, nid);
5152 if (snd_hda_get_input_pin_attr(defcfg) != INPUT_PIN_ATTR_INT)
5153 continue;
5154
5155 snd_hda_override_amp_caps(codec, nid, HDA_INPUT,
5156 (0x00 << AC_AMPCAP_OFFSET_SHIFT) |
5157 (0x01 << AC_AMPCAP_NUM_STEPS_SHIFT) |
5158 (0x2f << AC_AMPCAP_STEP_SIZE_SHIFT) |
5159 (0 << AC_AMPCAP_MUTE_SHIFT));
5160 }
5161}
5162
Kailang Yangcd217a62013-08-22 10:15:24 +02005163static void alc283_hp_automute_hook(struct hda_codec *codec,
Takashi Iwai1a4f69d2014-09-11 15:22:46 +02005164 struct hda_jack_callback *jack)
Kailang Yangcd217a62013-08-22 10:15:24 +02005165{
5166 struct alc_spec *spec = codec->spec;
5167 int vref;
5168
5169 msleep(200);
5170 snd_hda_gen_hp_automute(codec, jack);
5171
5172 vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0;
5173
5174 msleep(600);
5175 snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5176 vref);
5177}
5178
Kailang Yangcd217a62013-08-22 10:15:24 +02005179static void alc283_fixup_chromebook(struct hda_codec *codec,
5180 const struct hda_fixup *fix, int action)
5181{
5182 struct alc_spec *spec = codec->spec;
Kailang Yangcd217a62013-08-22 10:15:24 +02005183
5184 switch (action) {
5185 case HDA_FIXUP_ACT_PRE_PROBE:
Kailang Yang0202e992013-12-02 15:20:15 +08005186 snd_hda_override_wcaps(codec, 0x03, 0);
Takashi Iwaid2e92702013-10-30 07:50:53 +01005187 /* Disable AA-loopback as it causes white noise */
5188 spec->gen.mixer_nid = 0;
Kailang Yang38070212013-11-01 15:57:35 +08005189 break;
5190 case HDA_FIXUP_ACT_INIT:
Kailang Yangde9481c2014-04-07 16:41:52 +08005191 /* MIC2-VREF control */
5192 /* Set to manual mode */
Takashi Iwai98b24882014-08-18 13:47:50 +02005193 alc_update_coef_idx(codec, 0x06, 0x000c, 0);
Kailang Yang0202e992013-12-02 15:20:15 +08005194 /* Enable Line1 input control by verb */
Takashi Iwai98b24882014-08-18 13:47:50 +02005195 alc_update_coef_idx(codec, 0x1a, 0, 1 << 4);
Kailang Yang0202e992013-12-02 15:20:15 +08005196 break;
5197 }
5198}
5199
5200static void alc283_fixup_sense_combo_jack(struct hda_codec *codec,
5201 const struct hda_fixup *fix, int action)
5202{
5203 struct alc_spec *spec = codec->spec;
Kailang Yang0202e992013-12-02 15:20:15 +08005204
5205 switch (action) {
5206 case HDA_FIXUP_ACT_PRE_PROBE:
Kailang Yangcd217a62013-08-22 10:15:24 +02005207 spec->gen.hp_automute_hook = alc283_hp_automute_hook;
5208 break;
5209 case HDA_FIXUP_ACT_INIT:
5210 /* MIC2-VREF control */
5211 /* Set to manual mode */
Takashi Iwai98b24882014-08-18 13:47:50 +02005212 alc_update_coef_idx(codec, 0x06, 0x000c, 0);
Kailang Yangcd217a62013-08-22 10:15:24 +02005213 break;
5214 }
5215}
5216
Takashi Iwai7bba2152013-09-06 15:45:38 +02005217/* mute tablet speaker pin (0x14) via dock plugging in addition */
5218static void asus_tx300_automute(struct hda_codec *codec)
5219{
5220 struct alc_spec *spec = codec->spec;
5221 snd_hda_gen_update_outputs(codec);
5222 if (snd_hda_jack_detect(codec, 0x1b))
5223 spec->gen.mute_bits |= (1ULL << 0x14);
5224}
5225
5226static void alc282_fixup_asus_tx300(struct hda_codec *codec,
5227 const struct hda_fixup *fix, int action)
5228{
5229 struct alc_spec *spec = codec->spec;
5230 /* TX300 needs to set up GPIO2 for the speaker amp */
5231 static const struct hda_verb gpio2_verbs[] = {
5232 { 0x01, AC_VERB_SET_GPIO_MASK, 0x04 },
5233 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04 },
5234 { 0x01, AC_VERB_SET_GPIO_DATA, 0x04 },
5235 {}
5236 };
5237 static const struct hda_pintbl dock_pins[] = {
5238 { 0x1b, 0x21114000 }, /* dock speaker pin */
5239 {}
5240 };
Takashi Iwai7bba2152013-09-06 15:45:38 +02005241
5242 switch (action) {
5243 case HDA_FIXUP_ACT_PRE_PROBE:
5244 snd_hda_add_verbs(codec, gpio2_verbs);
5245 snd_hda_apply_pincfgs(codec, dock_pins);
5246 spec->gen.auto_mute_via_amp = 1;
5247 spec->gen.automute_hook = asus_tx300_automute;
5248 snd_hda_jack_detect_enable_callback(codec, 0x1b,
Takashi Iwai7bba2152013-09-06 15:45:38 +02005249 snd_hda_gen_hp_automute);
5250 break;
5251 case HDA_FIXUP_ACT_BUILD:
5252 /* this is a bit tricky; give more sane names for the main
5253 * (tablet) speaker and the dock speaker, respectively
5254 */
Takashi Iwai56798e62017-04-11 08:10:52 +02005255 rename_ctl(codec, "Speaker Playback Switch",
5256 "Dock Speaker Playback Switch");
5257 rename_ctl(codec, "Bass Speaker Playback Switch",
5258 "Speaker Playback Switch");
Takashi Iwai7bba2152013-09-06 15:45:38 +02005259 break;
5260 }
5261}
5262
David Henningsson338cae52013-10-07 10:39:59 +02005263static void alc290_fixup_mono_speakers(struct hda_codec *codec,
5264 const struct hda_fixup *fix, int action)
5265{
David Henningsson0f4881d2013-12-20 16:08:13 +01005266 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5267 /* DAC node 0x03 is giving mono output. We therefore want to
5268 make sure 0x14 (front speaker) and 0x15 (headphones) use the
5269 stereo DAC, while leaving 0x17 (bass speaker) for node 0x03. */
5270 hda_nid_t conn1[2] = { 0x0c };
5271 snd_hda_override_conn_list(codec, 0x14, 1, conn1);
5272 snd_hda_override_conn_list(codec, 0x15, 1, conn1);
5273 }
David Henningsson338cae52013-10-07 10:39:59 +02005274}
5275
Hui Wangdd9aa332016-08-01 10:20:32 +08005276static void alc298_fixup_speaker_volume(struct hda_codec *codec,
5277 const struct hda_fixup *fix, int action)
5278{
5279 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5280 /* The speaker is routed to the Node 0x06 by a mistake, as a result
5281 we can't adjust the speaker's volume since this node does not has
5282 Amp-out capability. we change the speaker's route to:
5283 Node 0x02 (Audio Output) -> Node 0x0c (Audio Mixer) -> Node 0x17 (
5284 Pin Complex), since Node 0x02 has Amp-out caps, we can adjust
5285 speaker's volume now. */
5286
5287 hda_nid_t conn1[1] = { 0x0c };
5288 snd_hda_override_conn_list(codec, 0x17, 1, conn1);
5289 }
5290}
5291
Takashi Iwaie312a862018-03-06 12:14:17 +01005292/* disable DAC3 (0x06) selection on NID 0x17 as it has no volume amp control */
5293static void alc295_fixup_disable_dac3(struct hda_codec *codec,
5294 const struct hda_fixup *fix, int action)
5295{
5296 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5297 hda_nid_t conn[2] = { 0x02, 0x03 };
5298 snd_hda_override_conn_list(codec, 0x17, 2, conn);
5299 }
5300}
5301
Keith Packard98973f22015-07-15 12:14:39 -07005302/* Hook to update amp GPIO4 for automute */
5303static void alc280_hp_gpio4_automute_hook(struct hda_codec *codec,
5304 struct hda_jack_callback *jack)
5305{
5306 struct alc_spec *spec = codec->spec;
5307
5308 snd_hda_gen_hp_automute(codec, jack);
5309 /* mute_led_polarity is set to 0, so we pass inverted value here */
5310 alc_update_gpio_led(codec, 0x10, !spec->gen.hp_jack_present);
5311}
5312
5313/* Manage GPIOs for HP EliteBook Folio 9480m.
5314 *
5315 * GPIO4 is the headphone amplifier power control
5316 * GPIO3 is the audio output mute indicator LED
5317 */
5318
5319static void alc280_fixup_hp_9480m(struct hda_codec *codec,
5320 const struct hda_fixup *fix,
5321 int action)
5322{
5323 struct alc_spec *spec = codec->spec;
5324 static const struct hda_verb gpio_init[] = {
5325 { 0x01, AC_VERB_SET_GPIO_MASK, 0x18 },
5326 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x18 },
5327 {}
5328 };
5329
5330 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5331 /* Set the hooks to turn the headphone amp on/off
5332 * as needed
5333 */
5334 spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook;
5335 spec->gen.hp_automute_hook = alc280_hp_gpio4_automute_hook;
5336
5337 /* The GPIOs are currently off */
5338 spec->gpio_led = 0;
5339
5340 /* GPIO3 is connected to the output mute LED,
5341 * high is on, low is off
5342 */
5343 spec->mute_led_polarity = 0;
5344 spec->gpio_mute_led_mask = 0x08;
5345
5346 /* Initialize GPIO configuration */
5347 snd_hda_add_verbs(codec, gpio_init);
5348 }
5349}
5350
Kailang Yangca169cc2017-04-25 16:17:40 +08005351static void alc233_alc662_fixup_lenovo_dual_codecs(struct hda_codec *codec,
5352 const struct hda_fixup *fix,
5353 int action)
5354{
5355 alc_fixup_dual_codecs(codec, fix, action);
5356 switch (action) {
5357 case HDA_FIXUP_ACT_PRE_PROBE:
5358 /* override card longname to provide a unique UCM profile */
5359 strcpy(codec->card->longname, "HDAudio-Lenovo-DualCodecs");
5360 break;
5361 case HDA_FIXUP_ACT_BUILD:
5362 /* rename Capture controls depending on the codec */
5363 rename_ctl(codec, "Capture Volume",
5364 codec->addr == 0 ?
5365 "Rear-Panel Capture Volume" :
5366 "Front-Panel Capture Volume");
5367 rename_ctl(codec, "Capture Switch",
5368 codec->addr == 0 ?
5369 "Rear-Panel Capture Switch" :
5370 "Front-Panel Capture Switch");
5371 break;
5372 }
5373}
5374
Kailang Yang92266652017-12-14 15:28:58 +08005375/* Forcibly assign NID 0x03 to HP/LO while NID 0x02 to SPK for EQ */
5376static void alc274_fixup_bind_dacs(struct hda_codec *codec,
5377 const struct hda_fixup *fix, int action)
5378{
5379 struct alc_spec *spec = codec->spec;
5380 static hda_nid_t preferred_pairs[] = {
5381 0x21, 0x03, 0x1b, 0x03, 0x16, 0x02,
5382 0
5383 };
5384
5385 if (action != HDA_FIXUP_ACT_PRE_PROBE)
5386 return;
5387
5388 spec->gen.preferred_dacs = preferred_pairs;
5389}
5390
Takashi Iwaib317b032014-01-08 11:44:21 +01005391/* for hda_fixup_thinkpad_acpi() */
5392#include "thinkpad_helper.c"
David Henningssonb67ae3f2013-11-05 13:11:37 +01005393
Hui Wang00ef9942014-07-31 11:52:38 +08005394/* for dell wmi mic mute led */
5395#include "dell_wmi_helper.c"
5396
Tom Bridenbbf8ff62018-05-29 17:34:20 +01005397/* for alc295_fixup_hp_top_speakers */
5398#include "hp_x360_helper.c"
5399
Takashi Iwai1d045db2011-07-07 18:23:21 +02005400enum {
5401 ALC269_FIXUP_SONY_VAIO,
5402 ALC275_FIXUP_SONY_VAIO_GPIO2,
5403 ALC269_FIXUP_DELL_M101Z,
5404 ALC269_FIXUP_SKU_IGNORE,
5405 ALC269_FIXUP_ASUS_G73JW,
5406 ALC269_FIXUP_LENOVO_EAPD,
5407 ALC275_FIXUP_SONY_HWEQ,
Takashi Iwaie9bd7d52014-05-21 11:06:49 +02005408 ALC275_FIXUP_SONY_DISABLE_AAMIX,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005409 ALC271_FIXUP_DMIC,
Takashi Iwai017f2a12011-07-09 14:42:25 +02005410 ALC269_FIXUP_PCM_44K,
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02005411 ALC269_FIXUP_STEREO_DMIC,
David Henningsson7c478f02013-10-11 10:18:46 +02005412 ALC269_FIXUP_HEADSET_MIC,
Takashi Iwai24519912011-08-16 15:08:49 +02005413 ALC269_FIXUP_QUANTA_MUTE,
5414 ALC269_FIXUP_LIFEBOOK,
David Henningsson2041d562014-06-13 11:15:44 +02005415 ALC269_FIXUP_LIFEBOOK_EXTMIC,
Takashi Iwaicc7016a2015-04-08 20:47:55 +02005416 ALC269_FIXUP_LIFEBOOK_HP_PIN,
Takashi Iwai4df3fd12015-06-29 08:38:02 +02005417 ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT,
Jan-Marek Glogowskifdcc9682018-02-14 11:29:15 +01005418 ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC,
Takashi Iwaia4297b52011-08-23 18:40:12 +02005419 ALC269_FIXUP_AMIC,
5420 ALC269_FIXUP_DMIC,
5421 ALC269VB_FIXUP_AMIC,
5422 ALC269VB_FIXUP_DMIC,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01005423 ALC269_FIXUP_HP_MUTE_LED,
David Henningssond06ac142013-02-18 11:41:55 +01005424 ALC269_FIXUP_HP_MUTE_LED_MIC1,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01005425 ALC269_FIXUP_HP_MUTE_LED_MIC2,
Tom Briden7f783bd2017-03-25 10:12:01 +00005426 ALC269_FIXUP_HP_MUTE_LED_MIC3,
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01005427 ALC269_FIXUP_HP_GPIO_LED,
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08005428 ALC269_FIXUP_HP_GPIO_MIC1_LED,
5429 ALC269_FIXUP_HP_LINE1_MIC1_LED,
David Henningsson693b6132012-06-22 19:12:10 +02005430 ALC269_FIXUP_INV_DMIC,
David Henningsson108cc102012-07-20 10:37:25 +02005431 ALC269_FIXUP_LENOVO_DOCK,
Takashi Iwai9b745ab2014-03-07 08:37:19 +01005432 ALC269_FIXUP_NO_SHUTUP,
David Henningsson88cfcf82013-10-11 10:18:45 +02005433 ALC286_FIXUP_SONY_MIC_NO_PRESENCE,
David Henningsson108cc102012-07-20 10:37:25 +02005434 ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT,
David Henningsson73bdd592013-04-15 15:44:14 +02005435 ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
5436 ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
David Henningsson338cae52013-10-07 10:39:59 +02005437 ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
Kailang Yangfcc6c872017-06-29 15:21:27 +08005438 ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
David Henningsson73bdd592013-04-15 15:44:14 +02005439 ALC269_FIXUP_HEADSET_MODE,
5440 ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC,
Takashi Iwai78197172015-06-27 10:21:13 +02005441 ALC269_FIXUP_ASPIRE_HEADSET_MIC,
David Henningssond240d1d2013-04-15 12:50:02 +02005442 ALC269_FIXUP_ASUS_X101_FUNC,
5443 ALC269_FIXUP_ASUS_X101_VERB,
5444 ALC269_FIXUP_ASUS_X101,
Dylan Reid08a978d2012-11-18 22:56:40 -08005445 ALC271_FIXUP_AMIC_MIC2,
5446 ALC271_FIXUP_HP_GATE_MIC_JACK,
Oleksij Rempelb1e89722013-12-04 20:50:53 +01005447 ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572,
Dylan Reid42397002013-04-05 14:58:22 -07005448 ALC269_FIXUP_ACER_AC700,
David Henningsson3e0d6112013-04-22 14:30:14 +02005449 ALC269_FIXUP_LIMIT_INT_MIC_BOOST,
Oleksij Rempel2cede302013-11-27 17:12:03 +01005450 ALC269VB_FIXUP_ASUS_ZENBOOK,
Takashi Iwai23870832013-11-29 14:13:12 +01005451 ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A,
David Henningsson8e35cd42013-11-06 11:20:01 +01005452 ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED,
Anisse Astier02b504d2013-06-03 11:53:10 +02005453 ALC269VB_FIXUP_ORDISSIMO_EVE2,
Kailang Yangcd217a62013-08-22 10:15:24 +02005454 ALC283_FIXUP_CHROME_BOOK,
Kailang Yang0202e992013-12-02 15:20:15 +08005455 ALC283_FIXUP_SENSE_COMBO_JACK,
Takashi Iwai7bba2152013-09-06 15:45:38 +02005456 ALC282_FIXUP_ASUS_TX300,
Kailang Yang1bb3e062013-09-27 13:10:25 +02005457 ALC283_FIXUP_INT_MIC,
David Henningsson338cae52013-10-07 10:39:59 +02005458 ALC290_FIXUP_MONO_SPEAKERS,
David Henningsson0f4881d2013-12-20 16:08:13 +01005459 ALC290_FIXUP_MONO_SPEAKERS_HSJACK,
5460 ALC290_FIXUP_SUBWOOFER,
5461 ALC290_FIXUP_SUBWOOFER_HSJACK,
David Henningssonb67ae3f2013-11-05 13:11:37 +01005462 ALC269_FIXUP_THINKPAD_ACPI,
David Henningsson56f27012016-01-11 09:33:14 +01005463 ALC269_FIXUP_DMIC_THINKPAD_ACPI,
Chris Chiu5824ce82017-02-28 14:17:11 -06005464 ALC255_FIXUP_ACER_MIC_NO_PRESENCE,
Chris Chiu615966a2017-02-28 14:17:12 -06005465 ALC255_FIXUP_ASUS_MIC_NO_PRESENCE,
Kailang Yang9a22a8f52013-11-08 15:54:49 +08005466 ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Kailang Yang31278992014-03-03 15:27:22 +08005467 ALC255_FIXUP_DELL2_MIC_NO_PRESENCE,
Kailang Yang9a22a8f52013-11-08 15:54:49 +08005468 ALC255_FIXUP_HEADSET_MODE,
Kailang Yang31278992014-03-03 15:27:22 +08005469 ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC,
Kailang Yanga22aa262014-04-23 17:34:28 +08005470 ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
Takashi Iwai1c37c222014-05-06 17:34:42 +02005471 ALC292_FIXUP_TPT440_DOCK,
Takashi Iwai9a811232015-12-09 15:17:43 +01005472 ALC292_FIXUP_TPT440,
Anisse Astierabaa22742016-08-24 09:14:13 +02005473 ALC283_FIXUP_HEADSET_MIC,
Hui Wang00ef9942014-07-31 11:52:38 +08005474 ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED,
Takashi Iwai1a22e772014-08-27 08:19:05 +02005475 ALC282_FIXUP_ASPIRE_V5_PINS,
David Henningsson7a5255f2014-10-30 08:26:01 +01005476 ALC280_FIXUP_HP_GPIO4,
Kailang Yangeaa8e5e2014-11-21 15:49:11 +08005477 ALC286_FIXUP_HP_GPIO_LED,
David Henningsson33f4acd2015-01-07 15:50:13 +01005478 ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY,
TienFu Chenb4b33f92015-01-20 15:06:21 +01005479 ALC280_FIXUP_HP_DOCK_PINS,
Jaroslav Kysela04d54662017-03-09 13:29:13 +01005480 ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED,
Keith Packard98973f22015-07-15 12:14:39 -07005481 ALC280_FIXUP_HP_9480M,
Kailang Yange1e62b92015-04-08 16:01:22 +08005482 ALC288_FIXUP_DELL_HEADSET_MODE,
5483 ALC288_FIXUP_DELL1_MIC_NO_PRESENCE,
5484 ALC288_FIXUP_DELL_XPS_13_GPIO6,
Hui Wang831bfdf92015-06-26 12:35:17 +08005485 ALC288_FIXUP_DELL_XPS_13,
5486 ALC288_FIXUP_DISABLE_AAMIX,
Takashi Iwai8b99aba2015-06-15 11:59:32 +02005487 ALC292_FIXUP_DELL_E7X,
5488 ALC292_FIXUP_DISABLE_AAMIX,
David Henningssonc04017e2015-12-15 14:44:03 +01005489 ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK,
Kailang Yang977e6272015-05-18 15:31:20 +08005490 ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang2f726ae2017-03-31 10:31:40 +08005491 ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE,
Kailang Yang6ed11312015-10-26 15:37:39 +08005492 ALC275_FIXUP_DELL_XPS,
Hui Wang8c697292015-11-24 11:08:18 +08005493 ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE,
Hui Wang23adc192015-12-08 12:27:18 +08005494 ALC293_FIXUP_LENOVO_SPK_NOISE,
Kailang3694cb22015-12-28 11:35:24 +08005495 ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY,
Kai-Heng Feng3b43b712016-02-25 15:19:38 +08005496 ALC255_FIXUP_DELL_SPK_NOISE,
David Henningsson2ae95572016-02-25 09:37:05 +01005497 ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
Takashi Iwaie312a862018-03-06 12:14:17 +01005498 ALC295_FIXUP_DISABLE_DAC3,
Takashi Iwaif8839822016-02-25 14:31:59 +01005499 ALC280_FIXUP_HP_HEADSET_MIC,
Hui Wange549d192016-04-01 11:00:15 +08005500 ALC221_FIXUP_HP_FRONT_MIC,
Sven Eckelmannc636b952016-04-11 16:55:26 +02005501 ALC292_FIXUP_TPT460,
Hui Wangdd9aa332016-08-01 10:20:32 +08005502 ALC298_FIXUP_SPK_VOLUME,
Kai-Heng Fengfd06c772016-08-30 15:36:34 +08005503 ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER,
Gabriele Mazzotta823ff162016-12-24 19:50:01 +01005504 ALC269_FIXUP_ATIV_BOOK_8,
Kailang Yang9eb5d0e2017-01-17 15:40:25 +08005505 ALC221_FIXUP_HP_MIC_NO_PRESENCE,
Chris Chiuc1732ed2017-02-28 14:17:13 -06005506 ALC256_FIXUP_ASUS_HEADSET_MODE,
5507 ALC256_FIXUP_ASUS_MIC,
Chris Chiueeed4cd2017-02-28 14:17:15 -06005508 ALC256_FIXUP_ASUS_AIO_GPIO2,
Chris Chiu216d7ae2017-02-28 14:17:14 -06005509 ALC233_FIXUP_ASUS_MIC_NO_PRESENCE,
5510 ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE,
Kailang Yangca169cc2017-04-25 16:17:40 +08005511 ALC233_FIXUP_LENOVO_MULTI_CODECS,
Hui Wangf33f79f2017-07-07 12:08:29 +08005512 ALC294_FIXUP_LENOVO_MIC_LOCATION,
Kailang Yang5f364132017-07-25 16:28:16 +08005513 ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE,
PeiSen Houb84e8432017-09-01 15:11:56 +08005514 ALC700_FIXUP_INTEL_REFERENCE,
Kailang Yang92266652017-12-14 15:28:58 +08005515 ALC274_FIXUP_DELL_BIND_DACS,
5516 ALC274_FIXUP_DELL_AIO_LINEOUT_VERB,
Kailang Yang61fcf8e2018-02-02 15:26:46 +08005517 ALC298_FIXUP_TPT470_DOCK,
Kailang Yangae104a22018-02-05 16:07:20 +08005518 ALC255_FIXUP_DUMMY_LINEOUT_VERB,
Kailang Yangf0ba9d62018-03-16 11:46:08 +08005519 ALC255_FIXUP_DELL_HEADSET_MIC,
Tom Bridenbbf8ff62018-05-29 17:34:20 +01005520 ALC295_FIXUP_HP_X360,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005521};
5522
Takashi Iwai1727a772013-01-10 09:52:52 +01005523static const struct hda_fixup alc269_fixups[] = {
Takashi Iwai1d045db2011-07-07 18:23:21 +02005524 [ALC269_FIXUP_SONY_VAIO] = {
Takashi Iwaifd108212013-01-10 10:18:14 +01005525 .type = HDA_FIXUP_PINCTLS,
5526 .v.pins = (const struct hda_pintbl[]) {
5527 {0x19, PIN_VREFGRD},
Takashi Iwai1d045db2011-07-07 18:23:21 +02005528 {}
5529 }
5530 },
5531 [ALC275_FIXUP_SONY_VAIO_GPIO2] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005532 .type = HDA_FIXUP_VERBS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005533 .v.verbs = (const struct hda_verb[]) {
5534 {0x01, AC_VERB_SET_GPIO_MASK, 0x04},
5535 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04},
5536 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5537 { }
5538 },
5539 .chained = true,
5540 .chain_id = ALC269_FIXUP_SONY_VAIO
5541 },
5542 [ALC269_FIXUP_DELL_M101Z] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005543 .type = HDA_FIXUP_VERBS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005544 .v.verbs = (const struct hda_verb[]) {
5545 /* Enables internal speaker */
5546 {0x20, AC_VERB_SET_COEF_INDEX, 13},
5547 {0x20, AC_VERB_SET_PROC_COEF, 0x4040},
5548 {}
5549 }
5550 },
5551 [ALC269_FIXUP_SKU_IGNORE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005552 .type = HDA_FIXUP_FUNC,
Takashi Iwai23d30f22012-05-07 17:17:32 +02005553 .v.func = alc_fixup_sku_ignore,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005554 },
5555 [ALC269_FIXUP_ASUS_G73JW] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005556 .type = HDA_FIXUP_PINS,
5557 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02005558 { 0x17, 0x99130111 }, /* subwoofer */
5559 { }
5560 }
5561 },
5562 [ALC269_FIXUP_LENOVO_EAPD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005563 .type = HDA_FIXUP_VERBS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005564 .v.verbs = (const struct hda_verb[]) {
5565 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
5566 {}
5567 }
5568 },
5569 [ALC275_FIXUP_SONY_HWEQ] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005570 .type = HDA_FIXUP_FUNC,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005571 .v.func = alc269_fixup_hweq,
5572 .chained = true,
5573 .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2
5574 },
Takashi Iwaie9bd7d52014-05-21 11:06:49 +02005575 [ALC275_FIXUP_SONY_DISABLE_AAMIX] = {
5576 .type = HDA_FIXUP_FUNC,
5577 .v.func = alc_fixup_disable_aamix,
5578 .chained = true,
5579 .chain_id = ALC269_FIXUP_SONY_VAIO
5580 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02005581 [ALC271_FIXUP_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005582 .type = HDA_FIXUP_FUNC,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005583 .v.func = alc271_fixup_dmic,
5584 },
Takashi Iwai017f2a12011-07-09 14:42:25 +02005585 [ALC269_FIXUP_PCM_44K] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005586 .type = HDA_FIXUP_FUNC,
Takashi Iwai017f2a12011-07-09 14:42:25 +02005587 .v.func = alc269_fixup_pcm_44k,
David Henningsson012e7eb2012-08-08 08:43:37 +02005588 .chained = true,
5589 .chain_id = ALC269_FIXUP_QUANTA_MUTE
Takashi Iwai017f2a12011-07-09 14:42:25 +02005590 },
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02005591 [ALC269_FIXUP_STEREO_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005592 .type = HDA_FIXUP_FUNC,
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02005593 .v.func = alc269_fixup_stereo_dmic,
5594 },
David Henningsson7c478f02013-10-11 10:18:46 +02005595 [ALC269_FIXUP_HEADSET_MIC] = {
5596 .type = HDA_FIXUP_FUNC,
5597 .v.func = alc269_fixup_headset_mic,
5598 },
Takashi Iwai24519912011-08-16 15:08:49 +02005599 [ALC269_FIXUP_QUANTA_MUTE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005600 .type = HDA_FIXUP_FUNC,
Takashi Iwai24519912011-08-16 15:08:49 +02005601 .v.func = alc269_fixup_quanta_mute,
5602 },
5603 [ALC269_FIXUP_LIFEBOOK] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005604 .type = HDA_FIXUP_PINS,
5605 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai24519912011-08-16 15:08:49 +02005606 { 0x1a, 0x2101103f }, /* dock line-out */
5607 { 0x1b, 0x23a11040 }, /* dock mic-in */
5608 { }
5609 },
5610 .chained = true,
5611 .chain_id = ALC269_FIXUP_QUANTA_MUTE
5612 },
David Henningsson2041d562014-06-13 11:15:44 +02005613 [ALC269_FIXUP_LIFEBOOK_EXTMIC] = {
5614 .type = HDA_FIXUP_PINS,
5615 .v.pins = (const struct hda_pintbl[]) {
5616 { 0x19, 0x01a1903c }, /* headset mic, with jack detect */
5617 { }
5618 },
5619 },
Takashi Iwaicc7016a2015-04-08 20:47:55 +02005620 [ALC269_FIXUP_LIFEBOOK_HP_PIN] = {
5621 .type = HDA_FIXUP_PINS,
5622 .v.pins = (const struct hda_pintbl[]) {
5623 { 0x21, 0x0221102f }, /* HP out */
5624 { }
5625 },
5626 },
Takashi Iwai4df3fd12015-06-29 08:38:02 +02005627 [ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT] = {
5628 .type = HDA_FIXUP_FUNC,
5629 .v.func = alc269_fixup_pincfg_no_hp_to_lineout,
5630 },
Jan-Marek Glogowskifdcc9682018-02-14 11:29:15 +01005631 [ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC] = {
5632 .type = HDA_FIXUP_FUNC,
5633 .v.func = alc269_fixup_pincfg_U7x7_headset_mic,
5634 },
Takashi Iwaia4297b52011-08-23 18:40:12 +02005635 [ALC269_FIXUP_AMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005636 .type = HDA_FIXUP_PINS,
5637 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaia4297b52011-08-23 18:40:12 +02005638 { 0x14, 0x99130110 }, /* speaker */
5639 { 0x15, 0x0121401f }, /* HP out */
5640 { 0x18, 0x01a19c20 }, /* mic */
5641 { 0x19, 0x99a3092f }, /* int-mic */
5642 { }
5643 },
5644 },
5645 [ALC269_FIXUP_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005646 .type = HDA_FIXUP_PINS,
5647 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaia4297b52011-08-23 18:40:12 +02005648 { 0x12, 0x99a3092f }, /* int-mic */
5649 { 0x14, 0x99130110 }, /* speaker */
5650 { 0x15, 0x0121401f }, /* HP out */
5651 { 0x18, 0x01a19c20 }, /* mic */
5652 { }
5653 },
5654 },
5655 [ALC269VB_FIXUP_AMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005656 .type = HDA_FIXUP_PINS,
5657 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaia4297b52011-08-23 18:40:12 +02005658 { 0x14, 0x99130110 }, /* speaker */
5659 { 0x18, 0x01a19c20 }, /* mic */
5660 { 0x19, 0x99a3092f }, /* int-mic */
5661 { 0x21, 0x0121401f }, /* HP out */
5662 { }
5663 },
5664 },
David Henningsson2267ea92012-01-03 08:45:56 +01005665 [ALC269VB_FIXUP_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005666 .type = HDA_FIXUP_PINS,
5667 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaia4297b52011-08-23 18:40:12 +02005668 { 0x12, 0x99a3092f }, /* int-mic */
5669 { 0x14, 0x99130110 }, /* speaker */
5670 { 0x18, 0x01a19c20 }, /* mic */
5671 { 0x21, 0x0121401f }, /* HP out */
5672 { }
5673 },
5674 },
Takashi Iwai08fb0d02013-01-10 17:33:58 +01005675 [ALC269_FIXUP_HP_MUTE_LED] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005676 .type = HDA_FIXUP_FUNC,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01005677 .v.func = alc269_fixup_hp_mute_led,
David Henningsson6d3cd5d2013-01-07 12:03:47 +01005678 },
David Henningssond06ac142013-02-18 11:41:55 +01005679 [ALC269_FIXUP_HP_MUTE_LED_MIC1] = {
5680 .type = HDA_FIXUP_FUNC,
5681 .v.func = alc269_fixup_hp_mute_led_mic1,
5682 },
Takashi Iwai08fb0d02013-01-10 17:33:58 +01005683 [ALC269_FIXUP_HP_MUTE_LED_MIC2] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005684 .type = HDA_FIXUP_FUNC,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01005685 .v.func = alc269_fixup_hp_mute_led_mic2,
Takashi Iwai420b0fe2012-03-12 12:35:27 +01005686 },
Tom Briden7f783bd2017-03-25 10:12:01 +00005687 [ALC269_FIXUP_HP_MUTE_LED_MIC3] = {
5688 .type = HDA_FIXUP_FUNC,
5689 .v.func = alc269_fixup_hp_mute_led_mic3,
5690 },
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01005691 [ALC269_FIXUP_HP_GPIO_LED] = {
5692 .type = HDA_FIXUP_FUNC,
5693 .v.func = alc269_fixup_hp_gpio_led,
5694 },
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08005695 [ALC269_FIXUP_HP_GPIO_MIC1_LED] = {
5696 .type = HDA_FIXUP_FUNC,
5697 .v.func = alc269_fixup_hp_gpio_mic1_led,
5698 },
5699 [ALC269_FIXUP_HP_LINE1_MIC1_LED] = {
5700 .type = HDA_FIXUP_FUNC,
5701 .v.func = alc269_fixup_hp_line1_mic1_led,
5702 },
David Henningsson693b6132012-06-22 19:12:10 +02005703 [ALC269_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005704 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02005705 .v.func = alc_fixup_inv_dmic,
David Henningsson693b6132012-06-22 19:12:10 +02005706 },
Takashi Iwai9b745ab2014-03-07 08:37:19 +01005707 [ALC269_FIXUP_NO_SHUTUP] = {
5708 .type = HDA_FIXUP_FUNC,
5709 .v.func = alc_fixup_no_shutup,
5710 },
David Henningsson108cc102012-07-20 10:37:25 +02005711 [ALC269_FIXUP_LENOVO_DOCK] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005712 .type = HDA_FIXUP_PINS,
5713 .v.pins = (const struct hda_pintbl[]) {
David Henningsson108cc102012-07-20 10:37:25 +02005714 { 0x19, 0x23a11040 }, /* dock mic */
5715 { 0x1b, 0x2121103f }, /* dock headphone */
5716 { }
5717 },
5718 .chained = true,
5719 .chain_id = ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT
5720 },
5721 [ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005722 .type = HDA_FIXUP_FUNC,
David Henningsson108cc102012-07-20 10:37:25 +02005723 .v.func = alc269_fixup_pincfg_no_hp_to_lineout,
David Henningsson52129002013-11-19 10:25:53 +01005724 .chained = true,
5725 .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
David Henningsson108cc102012-07-20 10:37:25 +02005726 },
David Henningsson73bdd592013-04-15 15:44:14 +02005727 [ALC269_FIXUP_DELL1_MIC_NO_PRESENCE] = {
5728 .type = HDA_FIXUP_PINS,
5729 .v.pins = (const struct hda_pintbl[]) {
5730 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5731 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
5732 { }
5733 },
5734 .chained = true,
5735 .chain_id = ALC269_FIXUP_HEADSET_MODE
5736 },
5737 [ALC269_FIXUP_DELL2_MIC_NO_PRESENCE] = {
5738 .type = HDA_FIXUP_PINS,
5739 .v.pins = (const struct hda_pintbl[]) {
5740 { 0x16, 0x21014020 }, /* dock line out */
5741 { 0x19, 0x21a19030 }, /* dock mic */
5742 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5743 { }
5744 },
5745 .chained = true,
5746 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
5747 },
David Henningsson338cae52013-10-07 10:39:59 +02005748 [ALC269_FIXUP_DELL3_MIC_NO_PRESENCE] = {
5749 .type = HDA_FIXUP_PINS,
5750 .v.pins = (const struct hda_pintbl[]) {
5751 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5752 { }
5753 },
5754 .chained = true,
5755 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
5756 },
Kailang Yangfcc6c872017-06-29 15:21:27 +08005757 [ALC269_FIXUP_DELL4_MIC_NO_PRESENCE] = {
5758 .type = HDA_FIXUP_PINS,
5759 .v.pins = (const struct hda_pintbl[]) {
5760 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5761 { 0x1b, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
5762 { }
5763 },
5764 .chained = true,
5765 .chain_id = ALC269_FIXUP_HEADSET_MODE
5766 },
David Henningsson73bdd592013-04-15 15:44:14 +02005767 [ALC269_FIXUP_HEADSET_MODE] = {
5768 .type = HDA_FIXUP_FUNC,
5769 .v.func = alc_fixup_headset_mode,
Hui Wang6676f302014-11-18 17:57:41 +08005770 .chained = true,
5771 .chain_id = ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED
David Henningsson73bdd592013-04-15 15:44:14 +02005772 },
5773 [ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC] = {
5774 .type = HDA_FIXUP_FUNC,
5775 .v.func = alc_fixup_headset_mode_no_hp_mic,
5776 },
Takashi Iwai78197172015-06-27 10:21:13 +02005777 [ALC269_FIXUP_ASPIRE_HEADSET_MIC] = {
5778 .type = HDA_FIXUP_PINS,
5779 .v.pins = (const struct hda_pintbl[]) {
5780 { 0x19, 0x01a1913c }, /* headset mic w/o jack detect */
5781 { }
5782 },
5783 .chained = true,
5784 .chain_id = ALC269_FIXUP_HEADSET_MODE,
5785 },
David Henningsson88cfcf82013-10-11 10:18:45 +02005786 [ALC286_FIXUP_SONY_MIC_NO_PRESENCE] = {
5787 .type = HDA_FIXUP_PINS,
5788 .v.pins = (const struct hda_pintbl[]) {
5789 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5790 { }
5791 },
David Henningssonfbc78ad2013-10-11 13:46:04 +02005792 .chained = true,
5793 .chain_id = ALC269_FIXUP_HEADSET_MIC
David Henningsson88cfcf82013-10-11 10:18:45 +02005794 },
David Henningssond240d1d2013-04-15 12:50:02 +02005795 [ALC269_FIXUP_ASUS_X101_FUNC] = {
5796 .type = HDA_FIXUP_FUNC,
5797 .v.func = alc269_fixup_x101_headset_mic,
5798 },
5799 [ALC269_FIXUP_ASUS_X101_VERB] = {
5800 .type = HDA_FIXUP_VERBS,
5801 .v.verbs = (const struct hda_verb[]) {
5802 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5803 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
5804 {0x20, AC_VERB_SET_PROC_COEF, 0x0310},
5805 { }
5806 },
5807 .chained = true,
5808 .chain_id = ALC269_FIXUP_ASUS_X101_FUNC
5809 },
5810 [ALC269_FIXUP_ASUS_X101] = {
5811 .type = HDA_FIXUP_PINS,
5812 .v.pins = (const struct hda_pintbl[]) {
5813 { 0x18, 0x04a1182c }, /* Headset mic */
5814 { }
5815 },
5816 .chained = true,
5817 .chain_id = ALC269_FIXUP_ASUS_X101_VERB
5818 },
Dylan Reid08a978d2012-11-18 22:56:40 -08005819 [ALC271_FIXUP_AMIC_MIC2] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005820 .type = HDA_FIXUP_PINS,
5821 .v.pins = (const struct hda_pintbl[]) {
Dylan Reid08a978d2012-11-18 22:56:40 -08005822 { 0x14, 0x99130110 }, /* speaker */
5823 { 0x19, 0x01a19c20 }, /* mic */
5824 { 0x1b, 0x99a7012f }, /* int-mic */
5825 { 0x21, 0x0121401f }, /* HP out */
5826 { }
5827 },
5828 },
5829 [ALC271_FIXUP_HP_GATE_MIC_JACK] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005830 .type = HDA_FIXUP_FUNC,
Dylan Reid08a978d2012-11-18 22:56:40 -08005831 .v.func = alc271_hp_gate_mic_jack,
5832 .chained = true,
5833 .chain_id = ALC271_FIXUP_AMIC_MIC2,
5834 },
Oleksij Rempelb1e89722013-12-04 20:50:53 +01005835 [ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572] = {
5836 .type = HDA_FIXUP_FUNC,
5837 .v.func = alc269_fixup_limit_int_mic_boost,
5838 .chained = true,
5839 .chain_id = ALC271_FIXUP_HP_GATE_MIC_JACK,
5840 },
Dylan Reid42397002013-04-05 14:58:22 -07005841 [ALC269_FIXUP_ACER_AC700] = {
5842 .type = HDA_FIXUP_PINS,
5843 .v.pins = (const struct hda_pintbl[]) {
5844 { 0x12, 0x99a3092f }, /* int-mic */
5845 { 0x14, 0x99130110 }, /* speaker */
5846 { 0x18, 0x03a11c20 }, /* mic */
5847 { 0x1e, 0x0346101e }, /* SPDIF1 */
5848 { 0x21, 0x0321101f }, /* HP out */
5849 { }
5850 },
5851 .chained = true,
5852 .chain_id = ALC271_FIXUP_DMIC,
5853 },
David Henningsson3e0d6112013-04-22 14:30:14 +02005854 [ALC269_FIXUP_LIMIT_INT_MIC_BOOST] = {
5855 .type = HDA_FIXUP_FUNC,
5856 .v.func = alc269_fixup_limit_int_mic_boost,
David Henningsson27937692013-11-18 11:51:47 +01005857 .chained = true,
5858 .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
David Henningsson3e0d6112013-04-22 14:30:14 +02005859 },
Oleksij Rempel2cede302013-11-27 17:12:03 +01005860 [ALC269VB_FIXUP_ASUS_ZENBOOK] = {
5861 .type = HDA_FIXUP_FUNC,
5862 .v.func = alc269_fixup_limit_int_mic_boost,
5863 .chained = true,
5864 .chain_id = ALC269VB_FIXUP_DMIC,
5865 },
Takashi Iwai23870832013-11-29 14:13:12 +01005866 [ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A] = {
5867 .type = HDA_FIXUP_VERBS,
5868 .v.verbs = (const struct hda_verb[]) {
5869 /* class-D output amp +5dB */
5870 { 0x20, AC_VERB_SET_COEF_INDEX, 0x12 },
5871 { 0x20, AC_VERB_SET_PROC_COEF, 0x2800 },
5872 {}
5873 },
5874 .chained = true,
5875 .chain_id = ALC269VB_FIXUP_ASUS_ZENBOOK,
5876 },
David Henningsson8e35cd42013-11-06 11:20:01 +01005877 [ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED] = {
5878 .type = HDA_FIXUP_FUNC,
5879 .v.func = alc269_fixup_limit_int_mic_boost,
5880 .chained = true,
5881 .chain_id = ALC269_FIXUP_HP_MUTE_LED_MIC1,
5882 },
Anisse Astier02b504d2013-06-03 11:53:10 +02005883 [ALC269VB_FIXUP_ORDISSIMO_EVE2] = {
5884 .type = HDA_FIXUP_PINS,
5885 .v.pins = (const struct hda_pintbl[]) {
5886 { 0x12, 0x99a3092f }, /* int-mic */
5887 { 0x18, 0x03a11d20 }, /* mic */
5888 { 0x19, 0x411111f0 }, /* Unused bogus pin */
5889 { }
5890 },
5891 },
Kailang Yangcd217a62013-08-22 10:15:24 +02005892 [ALC283_FIXUP_CHROME_BOOK] = {
5893 .type = HDA_FIXUP_FUNC,
5894 .v.func = alc283_fixup_chromebook,
5895 },
Kailang Yang0202e992013-12-02 15:20:15 +08005896 [ALC283_FIXUP_SENSE_COMBO_JACK] = {
5897 .type = HDA_FIXUP_FUNC,
5898 .v.func = alc283_fixup_sense_combo_jack,
5899 .chained = true,
5900 .chain_id = ALC283_FIXUP_CHROME_BOOK,
5901 },
Takashi Iwai7bba2152013-09-06 15:45:38 +02005902 [ALC282_FIXUP_ASUS_TX300] = {
5903 .type = HDA_FIXUP_FUNC,
5904 .v.func = alc282_fixup_asus_tx300,
5905 },
Kailang Yang1bb3e062013-09-27 13:10:25 +02005906 [ALC283_FIXUP_INT_MIC] = {
5907 .type = HDA_FIXUP_VERBS,
5908 .v.verbs = (const struct hda_verb[]) {
5909 {0x20, AC_VERB_SET_COEF_INDEX, 0x1a},
5910 {0x20, AC_VERB_SET_PROC_COEF, 0x0011},
5911 { }
5912 },
5913 .chained = true,
5914 .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST
5915 },
David Henningsson0f4881d2013-12-20 16:08:13 +01005916 [ALC290_FIXUP_SUBWOOFER_HSJACK] = {
5917 .type = HDA_FIXUP_PINS,
5918 .v.pins = (const struct hda_pintbl[]) {
5919 { 0x17, 0x90170112 }, /* subwoofer */
5920 { }
5921 },
5922 .chained = true,
5923 .chain_id = ALC290_FIXUP_MONO_SPEAKERS_HSJACK,
5924 },
5925 [ALC290_FIXUP_SUBWOOFER] = {
5926 .type = HDA_FIXUP_PINS,
5927 .v.pins = (const struct hda_pintbl[]) {
5928 { 0x17, 0x90170112 }, /* subwoofer */
5929 { }
5930 },
5931 .chained = true,
5932 .chain_id = ALC290_FIXUP_MONO_SPEAKERS,
5933 },
David Henningsson338cae52013-10-07 10:39:59 +02005934 [ALC290_FIXUP_MONO_SPEAKERS] = {
5935 .type = HDA_FIXUP_FUNC,
5936 .v.func = alc290_fixup_mono_speakers,
David Henningsson0f4881d2013-12-20 16:08:13 +01005937 },
5938 [ALC290_FIXUP_MONO_SPEAKERS_HSJACK] = {
5939 .type = HDA_FIXUP_FUNC,
5940 .v.func = alc290_fixup_mono_speakers,
David Henningsson338cae52013-10-07 10:39:59 +02005941 .chained = true,
5942 .chain_id = ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
5943 },
David Henningssonb67ae3f2013-11-05 13:11:37 +01005944 [ALC269_FIXUP_THINKPAD_ACPI] = {
5945 .type = HDA_FIXUP_FUNC,
Takashi Iwaib317b032014-01-08 11:44:21 +01005946 .v.func = hda_fixup_thinkpad_acpi,
Takashi Iwai09da1112016-09-08 12:15:02 +02005947 .chained = true,
5948 .chain_id = ALC269_FIXUP_SKU_IGNORE,
David Henningssonb67ae3f2013-11-05 13:11:37 +01005949 },
David Henningsson56f27012016-01-11 09:33:14 +01005950 [ALC269_FIXUP_DMIC_THINKPAD_ACPI] = {
5951 .type = HDA_FIXUP_FUNC,
5952 .v.func = alc_fixup_inv_dmic,
5953 .chained = true,
5954 .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
5955 },
Chris Chiu5824ce82017-02-28 14:17:11 -06005956 [ALC255_FIXUP_ACER_MIC_NO_PRESENCE] = {
5957 .type = HDA_FIXUP_PINS,
5958 .v.pins = (const struct hda_pintbl[]) {
5959 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5960 { }
5961 },
5962 .chained = true,
5963 .chain_id = ALC255_FIXUP_HEADSET_MODE
5964 },
Chris Chiu615966a2017-02-28 14:17:12 -06005965 [ALC255_FIXUP_ASUS_MIC_NO_PRESENCE] = {
5966 .type = HDA_FIXUP_PINS,
5967 .v.pins = (const struct hda_pintbl[]) {
5968 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5969 { }
5970 },
5971 .chained = true,
5972 .chain_id = ALC255_FIXUP_HEADSET_MODE
5973 },
Kailang Yang9a22a8f52013-11-08 15:54:49 +08005974 [ALC255_FIXUP_DELL1_MIC_NO_PRESENCE] = {
5975 .type = HDA_FIXUP_PINS,
5976 .v.pins = (const struct hda_pintbl[]) {
5977 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5978 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
5979 { }
5980 },
5981 .chained = true,
5982 .chain_id = ALC255_FIXUP_HEADSET_MODE
5983 },
Kailang Yang31278992014-03-03 15:27:22 +08005984 [ALC255_FIXUP_DELL2_MIC_NO_PRESENCE] = {
5985 .type = HDA_FIXUP_PINS,
5986 .v.pins = (const struct hda_pintbl[]) {
5987 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5988 { }
5989 },
5990 .chained = true,
5991 .chain_id = ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC
5992 },
Kailang Yang9a22a8f52013-11-08 15:54:49 +08005993 [ALC255_FIXUP_HEADSET_MODE] = {
5994 .type = HDA_FIXUP_FUNC,
5995 .v.func = alc_fixup_headset_mode_alc255,
Hui Wang4a83d422014-11-18 17:57:40 +08005996 .chained = true,
5997 .chain_id = ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED
Kailang Yang9a22a8f52013-11-08 15:54:49 +08005998 },
Kailang Yang31278992014-03-03 15:27:22 +08005999 [ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC] = {
6000 .type = HDA_FIXUP_FUNC,
6001 .v.func = alc_fixup_headset_mode_alc255_no_hp_mic,
6002 },
Kailang Yanga22aa262014-04-23 17:34:28 +08006003 [ALC293_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6004 .type = HDA_FIXUP_PINS,
6005 .v.pins = (const struct hda_pintbl[]) {
6006 { 0x18, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6007 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6008 { }
6009 },
6010 .chained = true,
6011 .chain_id = ALC269_FIXUP_HEADSET_MODE
6012 },
Takashi Iwai1c37c222014-05-06 17:34:42 +02006013 [ALC292_FIXUP_TPT440_DOCK] = {
David Henningssonec56af62015-06-24 10:46:33 +02006014 .type = HDA_FIXUP_FUNC,
Takashi Iwai7f57d802015-09-24 17:36:51 +02006015 .v.func = alc_fixup_tpt440_dock,
Takashi Iwai1c37c222014-05-06 17:34:42 +02006016 .chained = true,
6017 .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST
6018 },
Takashi Iwai9a811232015-12-09 15:17:43 +01006019 [ALC292_FIXUP_TPT440] = {
6020 .type = HDA_FIXUP_FUNC,
Takashi Iwai157f0b72015-12-10 23:30:43 +01006021 .v.func = alc_fixup_disable_aamix,
Takashi Iwai9a811232015-12-09 15:17:43 +01006022 .chained = true,
6023 .chain_id = ALC292_FIXUP_TPT440_DOCK,
6024 },
Anisse Astierabaa22742016-08-24 09:14:13 +02006025 [ALC283_FIXUP_HEADSET_MIC] = {
Daniel Drake9dc12862014-07-22 10:58:29 +01006026 .type = HDA_FIXUP_PINS,
6027 .v.pins = (const struct hda_pintbl[]) {
6028 { 0x19, 0x04a110f0 },
6029 { },
6030 },
6031 },
Hui Wang00ef9942014-07-31 11:52:38 +08006032 [ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED] = {
6033 .type = HDA_FIXUP_FUNC,
6034 .v.func = alc_fixup_dell_wmi,
Hui Wang00ef9942014-07-31 11:52:38 +08006035 },
Takashi Iwai1a22e772014-08-27 08:19:05 +02006036 [ALC282_FIXUP_ASPIRE_V5_PINS] = {
6037 .type = HDA_FIXUP_PINS,
6038 .v.pins = (const struct hda_pintbl[]) {
6039 { 0x12, 0x90a60130 },
6040 { 0x14, 0x90170110 },
6041 { 0x17, 0x40000008 },
6042 { 0x18, 0x411111f0 },
Mateusz Sylwestrzak04206942015-07-19 17:38:56 +02006043 { 0x19, 0x01a1913c },
Takashi Iwai1a22e772014-08-27 08:19:05 +02006044 { 0x1a, 0x411111f0 },
6045 { 0x1b, 0x411111f0 },
6046 { 0x1d, 0x40f89b2d },
6047 { 0x1e, 0x411111f0 },
6048 { 0x21, 0x0321101f },
6049 { },
6050 },
6051 },
David Henningsson7a5255f2014-10-30 08:26:01 +01006052 [ALC280_FIXUP_HP_GPIO4] = {
6053 .type = HDA_FIXUP_FUNC,
6054 .v.func = alc280_fixup_hp_gpio4,
6055 },
Kailang Yangeaa8e5e2014-11-21 15:49:11 +08006056 [ALC286_FIXUP_HP_GPIO_LED] = {
6057 .type = HDA_FIXUP_FUNC,
6058 .v.func = alc286_fixup_hp_gpio_led,
6059 },
David Henningsson33f4acd2015-01-07 15:50:13 +01006060 [ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY] = {
6061 .type = HDA_FIXUP_FUNC,
6062 .v.func = alc280_fixup_hp_gpio2_mic_hotkey,
6063 },
TienFu Chenb4b33f92015-01-20 15:06:21 +01006064 [ALC280_FIXUP_HP_DOCK_PINS] = {
6065 .type = HDA_FIXUP_PINS,
6066 .v.pins = (const struct hda_pintbl[]) {
6067 { 0x1b, 0x21011020 }, /* line-out */
6068 { 0x1a, 0x01a1903c }, /* headset mic */
6069 { 0x18, 0x2181103f }, /* line-in */
6070 { },
6071 },
6072 .chained = true,
6073 .chain_id = ALC280_FIXUP_HP_GPIO4
6074 },
Jaroslav Kysela04d54662017-03-09 13:29:13 +01006075 [ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED] = {
6076 .type = HDA_FIXUP_PINS,
6077 .v.pins = (const struct hda_pintbl[]) {
6078 { 0x1b, 0x21011020 }, /* line-out */
6079 { 0x18, 0x2181103f }, /* line-in */
6080 { },
6081 },
6082 .chained = true,
6083 .chain_id = ALC269_FIXUP_HP_GPIO_MIC1_LED
6084 },
Keith Packard98973f22015-07-15 12:14:39 -07006085 [ALC280_FIXUP_HP_9480M] = {
6086 .type = HDA_FIXUP_FUNC,
6087 .v.func = alc280_fixup_hp_9480m,
6088 },
Kailang Yange1e62b92015-04-08 16:01:22 +08006089 [ALC288_FIXUP_DELL_HEADSET_MODE] = {
6090 .type = HDA_FIXUP_FUNC,
6091 .v.func = alc_fixup_headset_mode_dell_alc288,
6092 .chained = true,
6093 .chain_id = ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED
6094 },
6095 [ALC288_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6096 .type = HDA_FIXUP_PINS,
6097 .v.pins = (const struct hda_pintbl[]) {
6098 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6099 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6100 { }
6101 },
6102 .chained = true,
6103 .chain_id = ALC288_FIXUP_DELL_HEADSET_MODE
6104 },
6105 [ALC288_FIXUP_DELL_XPS_13_GPIO6] = {
6106 .type = HDA_FIXUP_VERBS,
6107 .v.verbs = (const struct hda_verb[]) {
6108 {0x01, AC_VERB_SET_GPIO_MASK, 0x40},
6109 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x40},
6110 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6111 { }
6112 },
6113 .chained = true,
6114 .chain_id = ALC288_FIXUP_DELL1_MIC_NO_PRESENCE
6115 },
Hui Wang831bfdf92015-06-26 12:35:17 +08006116 [ALC288_FIXUP_DISABLE_AAMIX] = {
6117 .type = HDA_FIXUP_FUNC,
6118 .v.func = alc_fixup_disable_aamix,
6119 .chained = true,
6120 .chain_id = ALC288_FIXUP_DELL_XPS_13_GPIO6
6121 },
6122 [ALC288_FIXUP_DELL_XPS_13] = {
6123 .type = HDA_FIXUP_FUNC,
6124 .v.func = alc_fixup_dell_xps13,
6125 .chained = true,
6126 .chain_id = ALC288_FIXUP_DISABLE_AAMIX
6127 },
Takashi Iwai8b99aba2015-06-15 11:59:32 +02006128 [ALC292_FIXUP_DISABLE_AAMIX] = {
6129 .type = HDA_FIXUP_FUNC,
6130 .v.func = alc_fixup_disable_aamix,
Hui Wang831bfdf92015-06-26 12:35:17 +08006131 .chained = true,
6132 .chain_id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE
Takashi Iwai8b99aba2015-06-15 11:59:32 +02006133 },
David Henningssonc04017e2015-12-15 14:44:03 +01006134 [ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK] = {
6135 .type = HDA_FIXUP_FUNC,
6136 .v.func = alc_fixup_disable_aamix,
6137 .chained = true,
6138 .chain_id = ALC293_FIXUP_DELL1_MIC_NO_PRESENCE
6139 },
Takashi Iwai8b99aba2015-06-15 11:59:32 +02006140 [ALC292_FIXUP_DELL_E7X] = {
6141 .type = HDA_FIXUP_FUNC,
6142 .v.func = alc_fixup_dell_xps13,
6143 .chained = true,
6144 .chain_id = ALC292_FIXUP_DISABLE_AAMIX
6145 },
Kailang Yang977e6272015-05-18 15:31:20 +08006146 [ALC298_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6147 .type = HDA_FIXUP_PINS,
6148 .v.pins = (const struct hda_pintbl[]) {
6149 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6150 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6151 { }
6152 },
6153 .chained = true,
6154 .chain_id = ALC269_FIXUP_HEADSET_MODE
6155 },
Hui Wang2f726ae2017-03-31 10:31:40 +08006156 [ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE] = {
6157 .type = HDA_FIXUP_PINS,
6158 .v.pins = (const struct hda_pintbl[]) {
6159 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6160 { }
6161 },
6162 .chained = true,
6163 .chain_id = ALC269_FIXUP_HEADSET_MODE
6164 },
Kailang Yang6ed11312015-10-26 15:37:39 +08006165 [ALC275_FIXUP_DELL_XPS] = {
6166 .type = HDA_FIXUP_VERBS,
6167 .v.verbs = (const struct hda_verb[]) {
6168 /* Enables internal speaker */
6169 {0x20, AC_VERB_SET_COEF_INDEX, 0x1f},
6170 {0x20, AC_VERB_SET_PROC_COEF, 0x00c0},
6171 {0x20, AC_VERB_SET_COEF_INDEX, 0x30},
6172 {0x20, AC_VERB_SET_PROC_COEF, 0x00b1},
6173 {}
6174 }
6175 },
Hui Wang8c697292015-11-24 11:08:18 +08006176 [ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE] = {
6177 .type = HDA_FIXUP_VERBS,
6178 .v.verbs = (const struct hda_verb[]) {
6179 /* Disable pass-through path for FRONT 14h */
6180 {0x20, AC_VERB_SET_COEF_INDEX, 0x36},
6181 {0x20, AC_VERB_SET_PROC_COEF, 0x1737},
6182 {}
6183 },
6184 .chained = true,
6185 .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
6186 },
Hui Wang23adc192015-12-08 12:27:18 +08006187 [ALC293_FIXUP_LENOVO_SPK_NOISE] = {
6188 .type = HDA_FIXUP_FUNC,
6189 .v.func = alc_fixup_disable_aamix,
6190 .chained = true,
6191 .chain_id = ALC269_FIXUP_THINKPAD_ACPI
6192 },
Kailang3694cb22015-12-28 11:35:24 +08006193 [ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY] = {
6194 .type = HDA_FIXUP_FUNC,
6195 .v.func = alc233_fixup_lenovo_line2_mic_hotkey,
6196 },
Kai-Heng Feng3b43b712016-02-25 15:19:38 +08006197 [ALC255_FIXUP_DELL_SPK_NOISE] = {
6198 .type = HDA_FIXUP_FUNC,
6199 .v.func = alc_fixup_disable_aamix,
6200 .chained = true,
6201 .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
6202 },
David Henningsson2ae95572016-02-25 09:37:05 +01006203 [ALC225_FIXUP_DELL1_MIC_NO_PRESENCE] = {
6204 .type = HDA_FIXUP_VERBS,
6205 .v.verbs = (const struct hda_verb[]) {
6206 /* Disable pass-through path for FRONT 14h */
6207 { 0x20, AC_VERB_SET_COEF_INDEX, 0x36 },
6208 { 0x20, AC_VERB_SET_PROC_COEF, 0x57d7 },
6209 {}
6210 },
6211 .chained = true,
6212 .chain_id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE
6213 },
Takashi Iwaif8839822016-02-25 14:31:59 +01006214 [ALC280_FIXUP_HP_HEADSET_MIC] = {
6215 .type = HDA_FIXUP_FUNC,
6216 .v.func = alc_fixup_disable_aamix,
6217 .chained = true,
6218 .chain_id = ALC269_FIXUP_HEADSET_MIC,
6219 },
Hui Wange549d192016-04-01 11:00:15 +08006220 [ALC221_FIXUP_HP_FRONT_MIC] = {
6221 .type = HDA_FIXUP_PINS,
6222 .v.pins = (const struct hda_pintbl[]) {
6223 { 0x19, 0x02a19020 }, /* Front Mic */
6224 { }
6225 },
6226 },
Sven Eckelmannc636b952016-04-11 16:55:26 +02006227 [ALC292_FIXUP_TPT460] = {
6228 .type = HDA_FIXUP_FUNC,
6229 .v.func = alc_fixup_tpt440_dock,
6230 .chained = true,
6231 .chain_id = ALC293_FIXUP_LENOVO_SPK_NOISE,
6232 },
Hui Wangdd9aa332016-08-01 10:20:32 +08006233 [ALC298_FIXUP_SPK_VOLUME] = {
6234 .type = HDA_FIXUP_FUNC,
6235 .v.func = alc298_fixup_speaker_volume,
Hui Wang59ec4b52016-08-04 15:28:04 +08006236 .chained = true,
Hui Wang2f726ae2017-03-31 10:31:40 +08006237 .chain_id = ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE,
Hui Wangdd9aa332016-08-01 10:20:32 +08006238 },
Takashi Iwaie312a862018-03-06 12:14:17 +01006239 [ALC295_FIXUP_DISABLE_DAC3] = {
6240 .type = HDA_FIXUP_FUNC,
6241 .v.func = alc295_fixup_disable_dac3,
6242 },
Kai-Heng Fengfd06c772016-08-30 15:36:34 +08006243 [ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER] = {
6244 .type = HDA_FIXUP_PINS,
6245 .v.pins = (const struct hda_pintbl[]) {
6246 { 0x1b, 0x90170151 },
6247 { }
6248 },
6249 .chained = true,
6250 .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
6251 },
Gabriele Mazzotta823ff162016-12-24 19:50:01 +01006252 [ALC269_FIXUP_ATIV_BOOK_8] = {
6253 .type = HDA_FIXUP_FUNC,
6254 .v.func = alc_fixup_auto_mute_via_amp,
6255 .chained = true,
6256 .chain_id = ALC269_FIXUP_NO_SHUTUP
6257 },
Kailang Yang9eb5d0e2017-01-17 15:40:25 +08006258 [ALC221_FIXUP_HP_MIC_NO_PRESENCE] = {
6259 .type = HDA_FIXUP_PINS,
6260 .v.pins = (const struct hda_pintbl[]) {
6261 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6262 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
6263 { }
6264 },
6265 .chained = true,
6266 .chain_id = ALC269_FIXUP_HEADSET_MODE
6267 },
Chris Chiuc1732ed2017-02-28 14:17:13 -06006268 [ALC256_FIXUP_ASUS_HEADSET_MODE] = {
6269 .type = HDA_FIXUP_FUNC,
6270 .v.func = alc_fixup_headset_mode,
6271 },
6272 [ALC256_FIXUP_ASUS_MIC] = {
6273 .type = HDA_FIXUP_PINS,
6274 .v.pins = (const struct hda_pintbl[]) {
6275 { 0x13, 0x90a60160 }, /* use as internal mic */
6276 { 0x19, 0x04a11120 }, /* use as headset mic, without its own jack detect */
6277 { }
6278 },
6279 .chained = true,
6280 .chain_id = ALC256_FIXUP_ASUS_HEADSET_MODE
6281 },
Chris Chiueeed4cd2017-02-28 14:17:15 -06006282 [ALC256_FIXUP_ASUS_AIO_GPIO2] = {
6283 .type = HDA_FIXUP_VERBS,
6284 .v.verbs = (const struct hda_verb[]) {
6285 /* Set up GPIO2 for the speaker amp */
6286 { 0x01, AC_VERB_SET_GPIO_MASK, 0x04 },
6287 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04 },
6288 { 0x01, AC_VERB_SET_GPIO_DATA, 0x04 },
6289 {}
6290 },
6291 },
Chris Chiu216d7ae2017-02-28 14:17:14 -06006292 [ALC233_FIXUP_ASUS_MIC_NO_PRESENCE] = {
6293 .type = HDA_FIXUP_PINS,
6294 .v.pins = (const struct hda_pintbl[]) {
6295 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6296 { }
6297 },
6298 .chained = true,
6299 .chain_id = ALC269_FIXUP_HEADSET_MIC
6300 },
6301 [ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE] = {
6302 .type = HDA_FIXUP_VERBS,
6303 .v.verbs = (const struct hda_verb[]) {
6304 /* Enables internal speaker */
6305 {0x20, AC_VERB_SET_COEF_INDEX, 0x40},
6306 {0x20, AC_VERB_SET_PROC_COEF, 0x8800},
6307 {}
6308 },
6309 .chained = true,
6310 .chain_id = ALC233_FIXUP_ASUS_MIC_NO_PRESENCE
6311 },
Kailang Yangca169cc2017-04-25 16:17:40 +08006312 [ALC233_FIXUP_LENOVO_MULTI_CODECS] = {
6313 .type = HDA_FIXUP_FUNC,
6314 .v.func = alc233_alc662_fixup_lenovo_dual_codecs,
6315 },
Hui Wangf33f79f2017-07-07 12:08:29 +08006316 [ALC294_FIXUP_LENOVO_MIC_LOCATION] = {
6317 .type = HDA_FIXUP_PINS,
6318 .v.pins = (const struct hda_pintbl[]) {
6319 /* Change the mic location from front to right, otherwise there are
6320 two front mics with the same name, pulseaudio can't handle them.
6321 This is just a temporary workaround, after applying this fixup,
6322 there will be one "Front Mic" and one "Mic" in this machine.
6323 */
6324 { 0x1a, 0x04a19040 },
6325 { }
6326 },
6327 },
Kailang Yang5f364132017-07-25 16:28:16 +08006328 [ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE] = {
6329 .type = HDA_FIXUP_PINS,
6330 .v.pins = (const struct hda_pintbl[]) {
6331 { 0x16, 0x0101102f }, /* Rear Headset HP */
6332 { 0x19, 0x02a1913c }, /* use as Front headset mic, without its own jack detect */
6333 { 0x1a, 0x01a19030 }, /* Rear Headset MIC */
6334 { 0x1b, 0x02011020 },
6335 { }
6336 },
6337 .chained = true,
6338 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
6339 },
PeiSen Houb84e8432017-09-01 15:11:56 +08006340 [ALC700_FIXUP_INTEL_REFERENCE] = {
6341 .type = HDA_FIXUP_VERBS,
6342 .v.verbs = (const struct hda_verb[]) {
6343 /* Enables internal speaker */
6344 {0x20, AC_VERB_SET_COEF_INDEX, 0x45},
6345 {0x20, AC_VERB_SET_PROC_COEF, 0x5289},
6346 {0x20, AC_VERB_SET_COEF_INDEX, 0x4A},
6347 {0x20, AC_VERB_SET_PROC_COEF, 0x001b},
6348 {0x58, AC_VERB_SET_COEF_INDEX, 0x00},
6349 {0x58, AC_VERB_SET_PROC_COEF, 0x3888},
6350 {0x20, AC_VERB_SET_COEF_INDEX, 0x6f},
6351 {0x20, AC_VERB_SET_PROC_COEF, 0x2c0b},
6352 {}
6353 }
6354 },
Kailang Yang92266652017-12-14 15:28:58 +08006355 [ALC274_FIXUP_DELL_BIND_DACS] = {
6356 .type = HDA_FIXUP_FUNC,
6357 .v.func = alc274_fixup_bind_dacs,
6358 .chained = true,
6359 .chain_id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE
6360 },
6361 [ALC274_FIXUP_DELL_AIO_LINEOUT_VERB] = {
6362 .type = HDA_FIXUP_PINS,
6363 .v.pins = (const struct hda_pintbl[]) {
6364 { 0x1b, 0x0401102f },
6365 { }
6366 },
6367 .chained = true,
6368 .chain_id = ALC274_FIXUP_DELL_BIND_DACS
6369 },
Kailang Yang61fcf8e2018-02-02 15:26:46 +08006370 [ALC298_FIXUP_TPT470_DOCK] = {
6371 .type = HDA_FIXUP_FUNC,
6372 .v.func = alc_fixup_tpt470_dock,
6373 .chained = true,
6374 .chain_id = ALC293_FIXUP_LENOVO_SPK_NOISE
6375 },
Kailang Yangae104a22018-02-05 16:07:20 +08006376 [ALC255_FIXUP_DUMMY_LINEOUT_VERB] = {
6377 .type = HDA_FIXUP_PINS,
6378 .v.pins = (const struct hda_pintbl[]) {
6379 { 0x14, 0x0201101f },
6380 { }
6381 },
6382 .chained = true,
6383 .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
6384 },
Kailang Yangf0ba9d62018-03-16 11:46:08 +08006385 [ALC255_FIXUP_DELL_HEADSET_MIC] = {
6386 .type = HDA_FIXUP_PINS,
6387 .v.pins = (const struct hda_pintbl[]) {
6388 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
6389 { }
6390 },
Hui Wang3ce0d5a2018-04-19 13:29:04 +08006391 .chained = true,
6392 .chain_id = ALC269_FIXUP_HEADSET_MIC
Kailang Yangf0ba9d62018-03-16 11:46:08 +08006393 },
Tom Bridenbbf8ff62018-05-29 17:34:20 +01006394 [ALC295_FIXUP_HP_X360] = {
6395 .type = HDA_FIXUP_FUNC,
6396 .v.func = alc295_fixup_hp_top_speakers,
6397 .chained = true,
6398 .chain_id = ALC269_FIXUP_HP_MUTE_LED_MIC3
6399 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02006400};
6401
6402static const struct snd_pci_quirk alc269_fixup_tbl[] = {
Marius Knausta6b92b62014-03-03 01:48:58 +01006403 SND_PCI_QUIRK(0x1025, 0x0283, "Acer TravelMate 8371", ALC269_FIXUP_INV_DMIC),
David Henningsson693b6132012-06-22 19:12:10 +02006404 SND_PCI_QUIRK(0x1025, 0x029b, "Acer 1810TZ", ALC269_FIXUP_INV_DMIC),
6405 SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC),
David Henningssonaaedfb42013-08-16 14:09:02 +02006406 SND_PCI_QUIRK(0x1025, 0x047c, "Acer AC700", ALC269_FIXUP_ACER_AC700),
Takashi Iwai78197172015-06-27 10:21:13 +02006407 SND_PCI_QUIRK(0x1025, 0x072d, "Acer Aspire V5-571G", ALC269_FIXUP_ASPIRE_HEADSET_MIC),
6408 SND_PCI_QUIRK(0x1025, 0x080d, "Acer Aspire V5-122P", ALC269_FIXUP_ASPIRE_HEADSET_MIC),
David Henningssonaaedfb42013-08-16 14:09:02 +02006409 SND_PCI_QUIRK(0x1025, 0x0740, "Acer AO725", ALC271_FIXUP_HP_GATE_MIC_JACK),
6410 SND_PCI_QUIRK(0x1025, 0x0742, "Acer AO756", ALC271_FIXUP_HP_GATE_MIC_JACK),
Simon South02322ac2016-03-02 23:10:44 -05006411 SND_PCI_QUIRK(0x1025, 0x0762, "Acer Aspire E1-472", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572),
Oleksij Rempelb1e89722013-12-04 20:50:53 +01006412 SND_PCI_QUIRK(0x1025, 0x0775, "Acer Aspire E1-572", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572),
Takashi Iwai1a22e772014-08-27 08:19:05 +02006413 SND_PCI_QUIRK(0x1025, 0x079b, "Acer Aspire V5-573G", ALC282_FIXUP_ASPIRE_V5_PINS),
Takashi Iwaib9c2fa52015-11-19 16:39:50 +01006414 SND_PCI_QUIRK(0x1025, 0x106d, "Acer Cloudbook 14", ALC283_FIXUP_CHROME_BOOK),
David Henningssonaaedfb42013-08-16 14:09:02 +02006415 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
Kailang Yang6ed11312015-10-26 15:37:39 +08006416 SND_PCI_QUIRK(0x1028, 0x054b, "Dell XPS one 2710", ALC275_FIXUP_DELL_XPS),
Takashi Iwai86f799b2015-11-14 17:46:31 +01006417 SND_PCI_QUIRK(0x1028, 0x05bd, "Dell Latitude E6440", ALC292_FIXUP_DELL_E7X),
Takashi Iwaicf521032016-01-15 12:59:25 +01006418 SND_PCI_QUIRK(0x1028, 0x05be, "Dell Latitude E6540", ALC292_FIXUP_DELL_E7X),
Takashi Iwai8b99aba2015-06-15 11:59:32 +02006419 SND_PCI_QUIRK(0x1028, 0x05ca, "Dell Latitude E7240", ALC292_FIXUP_DELL_E7X),
6420 SND_PCI_QUIRK(0x1028, 0x05cb, "Dell Latitude E7440", ALC292_FIXUP_DELL_E7X),
David Henningsson0f4881d2013-12-20 16:08:13 +01006421 SND_PCI_QUIRK(0x1028, 0x05da, "Dell Vostro 5460", ALC290_FIXUP_SUBWOOFER),
David Henningsson73bdd592013-04-15 15:44:14 +02006422 SND_PCI_QUIRK(0x1028, 0x05f4, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
6423 SND_PCI_QUIRK(0x1028, 0x05f5, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
6424 SND_PCI_QUIRK(0x1028, 0x05f6, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
David Henningsson0f4881d2013-12-20 16:08:13 +01006425 SND_PCI_QUIRK(0x1028, 0x0615, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK),
6426 SND_PCI_QUIRK(0x1028, 0x0616, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK),
Takashi Iwai98070572016-01-12 21:06:39 +01006427 SND_PCI_QUIRK(0x1028, 0x062c, "Dell Latitude E5550", ALC292_FIXUP_DELL_E7X),
Takashi Iwai42755542015-06-29 10:56:53 +02006428 SND_PCI_QUIRK(0x1028, 0x062e, "Dell Latitude E7450", ALC292_FIXUP_DELL_E7X),
David Henningsson0f4881d2013-12-20 16:08:13 +01006429 SND_PCI_QUIRK(0x1028, 0x0638, "Dell Inspiron 5439", ALC290_FIXUP_MONO_SPEAKERS_HSJACK),
Kailang Yanga22aa262014-04-23 17:34:28 +08006430 SND_PCI_QUIRK(0x1028, 0x064a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
6431 SND_PCI_QUIRK(0x1028, 0x064b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
Hui Wang831bfdf92015-06-26 12:35:17 +08006432 SND_PCI_QUIRK(0x1028, 0x0665, "Dell XPS 13", ALC288_FIXUP_DELL_XPS_13),
Bastien Noceraafecb142016-04-18 11:10:42 +02006433 SND_PCI_QUIRK(0x1028, 0x0669, "Dell Optiplex 9020m", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
Takashi Iwai3a05d122015-07-29 09:04:52 +02006434 SND_PCI_QUIRK(0x1028, 0x069a, "Dell Vostro 5480", ALC290_FIXUP_SUBWOOFER_HSJACK),
Kailang Yang8b724152014-12-17 17:08:59 +08006435 SND_PCI_QUIRK(0x1028, 0x06c7, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
Kailang Yangb7343042014-12-02 14:50:45 +08006436 SND_PCI_QUIRK(0x1028, 0x06d9, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
6437 SND_PCI_QUIRK(0x1028, 0x06da, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
David Henningssonc04017e2015-12-15 14:44:03 +01006438 SND_PCI_QUIRK(0x1028, 0x06db, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
6439 SND_PCI_QUIRK(0x1028, 0x06dd, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
6440 SND_PCI_QUIRK(0x1028, 0x06de, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
6441 SND_PCI_QUIRK(0x1028, 0x06df, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
6442 SND_PCI_QUIRK(0x1028, 0x06e0, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
Kai-Heng Feng423cd782016-05-20 15:47:23 +08006443 SND_PCI_QUIRK(0x1028, 0x0704, "Dell XPS 13 9350", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE),
Kai-Heng Fengfd06c772016-08-30 15:36:34 +08006444 SND_PCI_QUIRK(0x1028, 0x0706, "Dell Inspiron 7559", ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER),
Kai-Heng Feng3b43b712016-02-25 15:19:38 +08006445 SND_PCI_QUIRK(0x1028, 0x0725, "Dell Inspiron 3162", ALC255_FIXUP_DELL_SPK_NOISE),
Kai-Heng Feng423cd782016-05-20 15:47:23 +08006446 SND_PCI_QUIRK(0x1028, 0x075b, "Dell XPS 13 9360", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE),
Hui Wangdd9aa332016-08-01 10:20:32 +08006447 SND_PCI_QUIRK(0x1028, 0x075d, "Dell AIO", ALC298_FIXUP_SPK_VOLUME),
Takashi Iwaie312a862018-03-06 12:14:17 +01006448 SND_PCI_QUIRK(0x1028, 0x07b0, "Dell Precision 7520", ALC295_FIXUP_DISABLE_DAC3),
Takashi Iwai493de342017-02-28 17:27:57 +01006449 SND_PCI_QUIRK(0x1028, 0x0798, "Dell Inspiron 17 7000 Gaming", ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER),
Kailang Yang5f364132017-07-25 16:28:16 +08006450 SND_PCI_QUIRK(0x1028, 0x080c, "Dell WYSE", ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE),
Takashi Iwaie4c9fd12018-01-10 08:34:28 +01006451 SND_PCI_QUIRK(0x1028, 0x082a, "Dell XPS 13 9360", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE),
Kailang Yang40e2c4e2018-02-02 15:13:09 +08006452 SND_PCI_QUIRK(0x1028, 0x084b, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB),
6453 SND_PCI_QUIRK(0x1028, 0x084e, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB),
Kailang Yangf0ba9d62018-03-16 11:46:08 +08006454 SND_PCI_QUIRK(0x1028, 0x0871, "Dell Precision 3630", ALC255_FIXUP_DELL_HEADSET_MIC),
6455 SND_PCI_QUIRK(0x1028, 0x0872, "Dell Precision 3630", ALC255_FIXUP_DELL_HEADSET_MIC),
Kailang Yangae104a22018-02-05 16:07:20 +08006456 SND_PCI_QUIRK(0x1028, 0x0873, "Dell Precision 3930", ALC255_FIXUP_DUMMY_LINEOUT_VERB),
Kailang Yanga22aa262014-04-23 17:34:28 +08006457 SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
6458 SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
Takashi Iwai08fb0d02013-01-10 17:33:58 +01006459 SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01006460 SND_PCI_QUIRK(0x103c, 0x18e6, "HP", ALC269_FIXUP_HP_GPIO_LED),
David Henningsson8e35cd42013-11-06 11:20:01 +01006461 SND_PCI_QUIRK(0x103c, 0x218b, "HP", ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED),
David Henningsson33f4acd2015-01-07 15:50:13 +01006462 SND_PCI_QUIRK(0x103c, 0x225f, "HP", ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY),
Kailang Yangc60666b2014-02-21 16:23:35 +08006463 /* ALC282 */
Hui Wang7976eb42015-02-13 11:14:41 +08006464 SND_PCI_QUIRK(0x103c, 0x21f9, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang8a02b162014-06-13 17:16:31 +08006465 SND_PCI_QUIRK(0x103c, 0x2210, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang8a02b162014-06-13 17:16:31 +08006466 SND_PCI_QUIRK(0x103c, 0x2214, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08006467 SND_PCI_QUIRK(0x103c, 0x2236, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
6468 SND_PCI_QUIRK(0x103c, 0x2237, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
6469 SND_PCI_QUIRK(0x103c, 0x2238, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
6470 SND_PCI_QUIRK(0x103c, 0x2239, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08006471 SND_PCI_QUIRK(0x103c, 0x224b, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
Kailang Yangc60666b2014-02-21 16:23:35 +08006472 SND_PCI_QUIRK(0x103c, 0x2268, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08006473 SND_PCI_QUIRK(0x103c, 0x226a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
6474 SND_PCI_QUIRK(0x103c, 0x226b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang8a02b162014-06-13 17:16:31 +08006475 SND_PCI_QUIRK(0x103c, 0x226e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangeaa8e5e2014-11-21 15:49:11 +08006476 SND_PCI_QUIRK(0x103c, 0x2271, "HP", ALC286_FIXUP_HP_GPIO_LED),
TienFu Chenb4b33f92015-01-20 15:06:21 +01006477 SND_PCI_QUIRK(0x103c, 0x2272, "HP", ALC280_FIXUP_HP_DOCK_PINS),
TienFu Chen3271cb22015-02-10 09:09:41 +01006478 SND_PCI_QUIRK(0x103c, 0x2273, "HP", ALC280_FIXUP_HP_DOCK_PINS),
Kailang Yangc60666b2014-02-21 16:23:35 +08006479 SND_PCI_QUIRK(0x103c, 0x229e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08006480 SND_PCI_QUIRK(0x103c, 0x22b2, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
6481 SND_PCI_QUIRK(0x103c, 0x22b7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
6482 SND_PCI_QUIRK(0x103c, 0x22bf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08006483 SND_PCI_QUIRK(0x103c, 0x22cf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Keith Packard98973f22015-07-15 12:14:39 -07006484 SND_PCI_QUIRK(0x103c, 0x22db, "HP", ALC280_FIXUP_HP_9480M),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08006485 SND_PCI_QUIRK(0x103c, 0x22dc, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
6486 SND_PCI_QUIRK(0x103c, 0x22fb, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yangc60666b2014-02-21 16:23:35 +08006487 /* ALC290 */
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08006488 SND_PCI_QUIRK(0x103c, 0x221b, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08006489 SND_PCI_QUIRK(0x103c, 0x2221, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08006490 SND_PCI_QUIRK(0x103c, 0x2225, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08006491 SND_PCI_QUIRK(0x103c, 0x2253, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
6492 SND_PCI_QUIRK(0x103c, 0x2254, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
6493 SND_PCI_QUIRK(0x103c, 0x2255, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
6494 SND_PCI_QUIRK(0x103c, 0x2256, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
6495 SND_PCI_QUIRK(0x103c, 0x2257, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08006496 SND_PCI_QUIRK(0x103c, 0x2259, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Jaroslav Kysela04d54662017-03-09 13:29:13 +01006497 SND_PCI_QUIRK(0x103c, 0x225a, "HP", ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED),
Kailang Yangc60666b2014-02-21 16:23:35 +08006498 SND_PCI_QUIRK(0x103c, 0x2260, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08006499 SND_PCI_QUIRK(0x103c, 0x2263, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
6500 SND_PCI_QUIRK(0x103c, 0x2264, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
6501 SND_PCI_QUIRK(0x103c, 0x2265, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08006502 SND_PCI_QUIRK(0x103c, 0x2272, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
6503 SND_PCI_QUIRK(0x103c, 0x2273, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08006504 SND_PCI_QUIRK(0x103c, 0x2278, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yangc60666b2014-02-21 16:23:35 +08006505 SND_PCI_QUIRK(0x103c, 0x227f, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08006506 SND_PCI_QUIRK(0x103c, 0x2282, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08006507 SND_PCI_QUIRK(0x103c, 0x228b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08006508 SND_PCI_QUIRK(0x103c, 0x228e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
6509 SND_PCI_QUIRK(0x103c, 0x22c5, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08006510 SND_PCI_QUIRK(0x103c, 0x22c7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
6511 SND_PCI_QUIRK(0x103c, 0x22c8, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08006512 SND_PCI_QUIRK(0x103c, 0x22c4, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang8a02b162014-06-13 17:16:31 +08006513 SND_PCI_QUIRK(0x103c, 0x2334, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
6514 SND_PCI_QUIRK(0x103c, 0x2335, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
6515 SND_PCI_QUIRK(0x103c, 0x2336, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
6516 SND_PCI_QUIRK(0x103c, 0x2337, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Takashi Iwaif8839822016-02-25 14:31:59 +01006517 SND_PCI_QUIRK(0x103c, 0x221c, "HP EliteBook 755 G2", ALC280_FIXUP_HP_HEADSET_MIC),
Hui Wange549d192016-04-01 11:00:15 +08006518 SND_PCI_QUIRK(0x103c, 0x8256, "HP", ALC221_FIXUP_HP_FRONT_MIC),
Tom Bridenbbf8ff62018-05-29 17:34:20 +01006519 SND_PCI_QUIRK(0x103c, 0x827e, "HP x360", ALC295_FIXUP_HP_X360),
Kailang Yang9eb5d0e2017-01-17 15:40:25 +08006520 SND_PCI_QUIRK(0x103c, 0x82bf, "HP", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
6521 SND_PCI_QUIRK(0x103c, 0x82c0, "HP", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
Chris Chiuc1732ed2017-02-28 14:17:13 -06006522 SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC),
Takashi Iwai7bba2152013-09-06 15:45:38 +02006523 SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300),
David Henningsson3e0d6112013-04-22 14:30:14 +02006524 SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Chris Chiuc1732ed2017-02-28 14:17:13 -06006525 SND_PCI_QUIRK(0x1043, 0x10c0, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC),
Takashi Iwai4eab0ea2017-06-06 12:33:17 +02006526 SND_PCI_QUIRK(0x1043, 0x10d0, "ASUS X540LA/X540LJ", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
David Henningsson3e0d6112013-04-22 14:30:14 +02006527 SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Takashi Iwai4eab0ea2017-06-06 12:33:17 +02006528 SND_PCI_QUIRK(0x1043, 0x11c0, "ASUS X556UR", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
6529 SND_PCI_QUIRK(0x1043, 0x1290, "ASUS X441SA", ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE),
6530 SND_PCI_QUIRK(0x1043, 0x12a0, "ASUS X441UV", ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE),
Chris Chiuc1732ed2017-02-28 14:17:13 -06006531 SND_PCI_QUIRK(0x1043, 0x12f0, "ASUS X541UV", ALC256_FIXUP_ASUS_MIC),
6532 SND_PCI_QUIRK(0x1043, 0x12e0, "ASUS X541SA", ALC256_FIXUP_ASUS_MIC),
6533 SND_PCI_QUIRK(0x1043, 0x13b0, "ASUS Z550SA", ALC256_FIXUP_ASUS_MIC),
Oleksij Rempel2cede302013-11-27 17:12:03 +01006534 SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK),
Takashi Iwai23870832013-11-29 14:13:12 +01006535 SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A),
David Henningsson3e0d6112013-04-22 14:30:14 +02006536 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC),
Takashi Iwai017f2a12011-07-09 14:42:25 +02006537 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
Chris Chiu28e8af82017-06-05 15:05:30 -06006538 SND_PCI_QUIRK(0x1043, 0x1a30, "ASUS X705UD", ALC256_FIXUP_ASUS_MIC),
David Henningsson693b6132012-06-22 19:12:10 +02006539 SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC),
Chris Chiu615966a2017-02-28 14:17:12 -06006540 SND_PCI_QUIRK(0x1043, 0x1bbd, "ASUS Z550MA", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
Takashi Iwai4eab0ea2017-06-06 12:33:17 +02006541 SND_PCI_QUIRK(0x1043, 0x1c23, "Asus X55U", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Chris Chiuc1732ed2017-02-28 14:17:13 -06006542 SND_PCI_QUIRK(0x1043, 0x1ccd, "ASUS X555UB", ALC256_FIXUP_ASUS_MIC),
Chris Chiueeed4cd2017-02-28 14:17:15 -06006543 SND_PCI_QUIRK(0x1043, 0x3030, "ASUS ZN270IE", ALC256_FIXUP_ASUS_AIO_GPIO2),
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02006544 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC),
6545 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC),
6546 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
6547 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
David Henningssond240d1d2013-04-15 12:50:02 +02006548 SND_PCI_QUIRK(0x1043, 0x8516, "ASUS X101CH", ALC269_FIXUP_ASUS_X101),
Takashi Iwaif88abaa2014-02-07 12:07:59 +01006549 SND_PCI_QUIRK(0x104d, 0x90b5, "Sony VAIO Pro 11", ALC286_FIXUP_SONY_MIC_NO_PRESENCE),
David Henningsson88cfcf82013-10-11 10:18:45 +02006550 SND_PCI_QUIRK(0x104d, 0x90b6, "Sony VAIO Pro 13", ALC286_FIXUP_SONY_MIC_NO_PRESENCE),
Takashi Iwai1d045db2011-07-07 18:23:21 +02006551 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
6552 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
6553 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
Takashi Iwaie9bd7d52014-05-21 11:06:49 +02006554 SND_PCI_QUIRK(0x104d, 0x9099, "Sony VAIO S13", ALC275_FIXUP_SONY_DISABLE_AAMIX),
Takashi Iwai24519912011-08-16 15:08:49 +02006555 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook", ALC269_FIXUP_LIFEBOOK),
Takashi Iwai4df3fd12015-06-29 08:38:02 +02006556 SND_PCI_QUIRK(0x10cf, 0x159f, "Lifebook E780", ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT),
Takashi Iwaicc7016a2015-04-08 20:47:55 +02006557 SND_PCI_QUIRK(0x10cf, 0x15dc, "Lifebook T731", ALC269_FIXUP_LIFEBOOK_HP_PIN),
Takashi Iwai88776f32015-05-01 09:20:34 +02006558 SND_PCI_QUIRK(0x10cf, 0x1757, "Lifebook E752", ALC269_FIXUP_LIFEBOOK_HP_PIN),
Jan-Marek Glogowskifdcc9682018-02-14 11:29:15 +01006559 SND_PCI_QUIRK(0x10cf, 0x1629, "Lifebook U7x7", ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC),
David Henningsson2041d562014-06-13 11:15:44 +02006560 SND_PCI_QUIRK(0x10cf, 0x1845, "Lifebook U904", ALC269_FIXUP_LIFEBOOK_EXTMIC),
PeiSen Houb84e8432017-09-01 15:11:56 +08006561 SND_PCI_QUIRK(0x10ec, 0x10f2, "Intel Reference board", ALC700_FIXUP_INTEL_REFERENCE),
David Henningssona33cc482014-10-07 10:18:41 +02006562 SND_PCI_QUIRK(0x144d, 0xc109, "Samsung Ativ book 9 (NP900X3G)", ALC269_FIXUP_INV_DMIC),
Gabriele Mazzotta823ff162016-12-24 19:50:01 +01006563 SND_PCI_QUIRK(0x144d, 0xc740, "Samsung Ativ book 8 (NP870Z5G)", ALC269_FIXUP_ATIV_BOOK_8),
Anisse Astierabaa22742016-08-24 09:14:13 +02006564 SND_PCI_QUIRK(0x1458, 0xfa53, "Gigabyte BXBT-2807", ALC283_FIXUP_HEADSET_MIC),
6565 SND_PCI_QUIRK(0x1462, 0xb120, "MSI Cubi MS-B120", ALC283_FIXUP_HEADSET_MIC),
Kailang Yangca169cc2017-04-25 16:17:40 +08006566 SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC233_FIXUP_LENOVO_MULTI_CODECS),
Takashi Iwai1d045db2011-07-07 18:23:21 +02006567 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
6568 SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
6569 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
6570 SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
6571 SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
Takashi Iwai707fba32012-08-02 09:04:39 +02006572 SND_PCI_QUIRK(0x17aa, 0x21f6, "Thinkpad T530", ALC269_FIXUP_LENOVO_DOCK),
Felix Kaechelec8415a42012-08-06 23:02:01 +02006573 SND_PCI_QUIRK(0x17aa, 0x21fa, "Thinkpad X230", ALC269_FIXUP_LENOVO_DOCK),
Stefán Freyr84f98fd2012-10-19 22:46:00 +02006574 SND_PCI_QUIRK(0x17aa, 0x21f3, "Thinkpad T430", ALC269_FIXUP_LENOVO_DOCK),
Philipp A. Mohrenweiser4407be62012-08-06 13:14:18 +02006575 SND_PCI_QUIRK(0x17aa, 0x21fb, "Thinkpad T430s", ALC269_FIXUP_LENOVO_DOCK),
David Henningsson108cc102012-07-20 10:37:25 +02006576 SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK),
David Henningssonaaedfb42013-08-16 14:09:02 +02006577 SND_PCI_QUIRK(0x17aa, 0x2208, "Thinkpad T431s", ALC269_FIXUP_LENOVO_DOCK),
Takashi Iwai9a811232015-12-09 15:17:43 +01006578 SND_PCI_QUIRK(0x17aa, 0x220c, "Thinkpad T440s", ALC292_FIXUP_TPT440),
Takashi Iwai1c37c222014-05-06 17:34:42 +02006579 SND_PCI_QUIRK(0x17aa, 0x220e, "Thinkpad T440p", ALC292_FIXUP_TPT440_DOCK),
Takashi Iwaia12137e2014-06-27 12:14:35 +02006580 SND_PCI_QUIRK(0x17aa, 0x2210, "Thinkpad T540p", ALC292_FIXUP_TPT440_DOCK),
Rick Sherman59a51a62015-08-18 21:04:30 -05006581 SND_PCI_QUIRK(0x17aa, 0x2211, "Thinkpad W541", ALC292_FIXUP_TPT440_DOCK),
Takashi Iwai6d169412014-10-07 17:27:02 +02006582 SND_PCI_QUIRK(0x17aa, 0x2212, "Thinkpad T440", ALC292_FIXUP_TPT440_DOCK),
Lukas Bossard7c215392014-10-29 18:31:07 +01006583 SND_PCI_QUIRK(0x17aa, 0x2214, "Thinkpad X240", ALC292_FIXUP_TPT440_DOCK),
David Henningssona4a9e082013-08-16 14:09:01 +02006584 SND_PCI_QUIRK(0x17aa, 0x2215, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Takashi Iwaib6903c02015-12-10 12:20:20 +01006585 SND_PCI_QUIRK(0x17aa, 0x2218, "Thinkpad X1 Carbon 2nd", ALC292_FIXUP_TPT440_DOCK),
Laura Abbottd05ea7d2015-10-02 11:09:54 -07006586 SND_PCI_QUIRK(0x17aa, 0x2223, "ThinkPad T550", ALC292_FIXUP_TPT440_DOCK),
Yves-Alexis Perezc0278662015-04-11 09:31:35 +02006587 SND_PCI_QUIRK(0x17aa, 0x2226, "ThinkPad X250", ALC292_FIXUP_TPT440_DOCK),
Kailang Yang61fcf8e2018-02-02 15:26:46 +08006588 SND_PCI_QUIRK(0x17aa, 0x222d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
6589 SND_PCI_QUIRK(0x17aa, 0x222e, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
Torsten Hilbrichdab38e42016-06-07 13:14:21 +02006590 SND_PCI_QUIRK(0x17aa, 0x2231, "Thinkpad T560", ALC292_FIXUP_TPT460),
Sven Eckelmannc636b952016-04-11 16:55:26 +02006591 SND_PCI_QUIRK(0x17aa, 0x2233, "Thinkpad", ALC292_FIXUP_TPT460),
Kailang Yang61fcf8e2018-02-02 15:26:46 +08006592 SND_PCI_QUIRK(0x17aa, 0x2245, "Thinkpad T470", ALC298_FIXUP_TPT470_DOCK),
6593 SND_PCI_QUIRK(0x17aa, 0x2246, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
6594 SND_PCI_QUIRK(0x17aa, 0x2247, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
Dennis Wassenberge4c07b32018-03-08 13:17:54 +01006595 SND_PCI_QUIRK(0x17aa, 0x2249, "Thinkpad", ALC292_FIXUP_TPT460),
Kailang Yang61fcf8e2018-02-02 15:26:46 +08006596 SND_PCI_QUIRK(0x17aa, 0x224b, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
6597 SND_PCI_QUIRK(0x17aa, 0x224c, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
6598 SND_PCI_QUIRK(0x17aa, 0x224d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
Benjamin Berg85981df2018-02-14 13:29:39 +01006599 SND_PCI_QUIRK(0x17aa, 0x225d, "Thinkpad T480", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Kailang3694cb22015-12-28 11:35:24 +08006600 SND_PCI_QUIRK(0x17aa, 0x30bb, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
Hui Wang6ef2f682016-03-11 12:04:02 +08006601 SND_PCI_QUIRK(0x17aa, 0x30e2, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
Hui Wangf33f79f2017-07-07 12:08:29 +08006602 SND_PCI_QUIRK(0x17aa, 0x310c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
Kailang Yang65811832018-04-25 17:07:27 +08006603 SND_PCI_QUIRK(0x17aa, 0x312f, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
Hui Wanga3dafb22018-04-19 13:29:05 +08006604 SND_PCI_QUIRK(0x17aa, 0x3138, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
Hui Wang8da5bbf2017-12-22 11:17:46 +08006605 SND_PCI_QUIRK(0x17aa, 0x313c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
David Henningsson56f27012016-01-11 09:33:14 +01006606 SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
Takashi Iwaifedb2242014-11-13 07:11:38 +01006607 SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC),
Takashi Iwai9b745ab2014-03-07 08:37:19 +01006608 SND_PCI_QUIRK(0x17aa, 0x3978, "IdeaPad Y410P", ALC269_FIXUP_NO_SHUTUP),
David Henningssona4a9e082013-08-16 14:09:01 +02006609 SND_PCI_QUIRK(0x17aa, 0x5013, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Kailang Yang1bb3e062013-09-27 13:10:25 +02006610 SND_PCI_QUIRK(0x17aa, 0x501a, "Thinkpad", ALC283_FIXUP_INT_MIC),
Takashi Iwaic497d9f2014-10-08 12:14:40 +02006611 SND_PCI_QUIRK(0x17aa, 0x501e, "Thinkpad L440", ALC292_FIXUP_TPT440_DOCK),
David Henningssoncd5302c2013-08-19 12:22:33 +02006612 SND_PCI_QUIRK(0x17aa, 0x5026, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Jo-Philipp Wichf2aa1112015-04-13 12:47:26 +02006613 SND_PCI_QUIRK(0x17aa, 0x5034, "Thinkpad T450", ALC292_FIXUP_TPT440_DOCK),
Sebastian Wicki80b311d2015-03-23 17:23:11 +01006614 SND_PCI_QUIRK(0x17aa, 0x5036, "Thinkpad T450s", ALC292_FIXUP_TPT440_DOCK),
Ansgar Hegerfeld09ea9972015-05-14 12:31:32 +02006615 SND_PCI_QUIRK(0x17aa, 0x503c, "Thinkpad L450", ALC292_FIXUP_TPT440_DOCK),
Conrad Kostecki037e1192016-04-26 10:08:10 +02006616 SND_PCI_QUIRK(0x17aa, 0x504a, "ThinkPad X260", ALC292_FIXUP_TPT440_DOCK),
Hui Wang23adc192015-12-08 12:27:18 +08006617 SND_PCI_QUIRK(0x17aa, 0x504b, "Thinkpad", ALC293_FIXUP_LENOVO_SPK_NOISE),
Jaroslav Kysela0f087ee2016-06-24 15:13:16 +02006618 SND_PCI_QUIRK(0x17aa, 0x5050, "Thinkpad T560p", ALC292_FIXUP_TPT460),
Torsten Hilbrich9cd25742016-07-05 10:40:22 +02006619 SND_PCI_QUIRK(0x17aa, 0x5051, "Thinkpad L460", ALC292_FIXUP_TPT460),
Jaroslav Kysela0f087ee2016-06-24 15:13:16 +02006620 SND_PCI_QUIRK(0x17aa, 0x5053, "Thinkpad T460", ALC292_FIXUP_TPT460),
Kailang Yang61fcf8e2018-02-02 15:26:46 +08006621 SND_PCI_QUIRK(0x17aa, 0x505d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
6622 SND_PCI_QUIRK(0x17aa, 0x505f, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
6623 SND_PCI_QUIRK(0x17aa, 0x5062, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
David Henningssoncd5302c2013-08-19 12:22:33 +02006624 SND_PCI_QUIRK(0x17aa, 0x5109, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Kailang Yang61fcf8e2018-02-02 15:26:46 +08006625 SND_PCI_QUIRK(0x17aa, 0x511e, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
6626 SND_PCI_QUIRK(0x17aa, 0x511f, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
David Henningsson012e7eb2012-08-08 08:43:37 +02006627 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K),
Takashi Iwai1d045db2011-07-07 18:23:21 +02006628 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
Anisse Astier02b504d2013-06-03 11:53:10 +02006629 SND_PCI_QUIRK(0x1b7d, 0xa831, "Ordissimo EVE2 ", ALC269VB_FIXUP_ORDISSIMO_EVE2), /* Also known as Malata PC-B1303 */
Takashi Iwaia4297b52011-08-23 18:40:12 +02006630
Takashi Iwaia7f3eed2012-02-16 13:03:18 +01006631#if 0
Takashi Iwaia4297b52011-08-23 18:40:12 +02006632 /* Below is a quirk table taken from the old code.
6633 * Basically the device should work as is without the fixup table.
6634 * If BIOS doesn't give a proper info, enable the corresponding
6635 * fixup entry.
Jesper Juhl7d7eb9e2012-04-12 22:11:25 +02006636 */
Takashi Iwaia4297b52011-08-23 18:40:12 +02006637 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
6638 ALC269_FIXUP_AMIC),
6639 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269_FIXUP_AMIC),
Takashi Iwaia4297b52011-08-23 18:40:12 +02006640 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269_FIXUP_AMIC),
6641 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_FIXUP_AMIC),
6642 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269_FIXUP_AMIC),
6643 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269_FIXUP_AMIC),
6644 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269_FIXUP_AMIC),
6645 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269_FIXUP_AMIC),
6646 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_FIXUP_AMIC),
6647 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269_FIXUP_AMIC),
6648 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_FIXUP_AMIC),
6649 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_FIXUP_AMIC),
6650 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_FIXUP_AMIC),
6651 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_FIXUP_AMIC),
6652 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_FIXUP_AMIC),
6653 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_FIXUP_AMIC),
6654 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_FIXUP_AMIC),
6655 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_FIXUP_AMIC),
6656 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_FIXUP_AMIC),
6657 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_FIXUP_AMIC),
6658 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_FIXUP_AMIC),
6659 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_FIXUP_AMIC),
6660 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_FIXUP_AMIC),
6661 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_FIXUP_AMIC),
6662 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_FIXUP_AMIC),
6663 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_FIXUP_AMIC),
6664 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_FIXUP_AMIC),
6665 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_FIXUP_AMIC),
6666 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_FIXUP_AMIC),
6667 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_FIXUP_AMIC),
6668 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_FIXUP_AMIC),
6669 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_FIXUP_AMIC),
6670 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_FIXUP_AMIC),
6671 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_FIXUP_AMIC),
6672 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_FIXUP_AMIC),
6673 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_FIXUP_DMIC),
6674 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_FIXUP_AMIC),
6675 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_AMIC),
6676 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_FIXUP_DMIC),
6677 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_FIXUP_DMIC),
6678#endif
6679 {}
6680};
6681
David Henningsson214eef72014-07-22 14:09:35 +02006682static const struct snd_pci_quirk alc269_fixup_vendor_tbl[] = {
6683 SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC),
6684 SND_PCI_QUIRK_VENDOR(0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED),
6685 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
6686 SND_PCI_QUIRK_VENDOR(0x17aa, "Thinkpad", ALC269_FIXUP_THINKPAD_ACPI),
6687 {}
6688};
6689
Takashi Iwai1727a772013-01-10 09:52:52 +01006690static const struct hda_model_fixup alc269_fixup_models[] = {
Takashi Iwaia4297b52011-08-23 18:40:12 +02006691 {.id = ALC269_FIXUP_AMIC, .name = "laptop-amic"},
6692 {.id = ALC269_FIXUP_DMIC, .name = "laptop-dmic"},
Takashi Iwai6e72aa52012-06-25 10:52:25 +02006693 {.id = ALC269_FIXUP_STEREO_DMIC, .name = "alc269-dmic"},
6694 {.id = ALC271_FIXUP_DMIC, .name = "alc271-dmic"},
6695 {.id = ALC269_FIXUP_INV_DMIC, .name = "inv-dmic"},
David Henningsson7c478f02013-10-11 10:18:46 +02006696 {.id = ALC269_FIXUP_HEADSET_MIC, .name = "headset-mic"},
Takashi Iwaib0169512015-05-19 10:20:13 +02006697 {.id = ALC269_FIXUP_HEADSET_MODE, .name = "headset-mode"},
6698 {.id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC, .name = "headset-mode-no-hp-mic"},
David Henningsson108cc102012-07-20 10:37:25 +02006699 {.id = ALC269_FIXUP_LENOVO_DOCK, .name = "lenovo-dock"},
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01006700 {.id = ALC269_FIXUP_HP_GPIO_LED, .name = "hp-gpio-led"},
Jaroslav Kysela04d54662017-03-09 13:29:13 +01006701 {.id = ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED, .name = "hp-dock-gpio-mic1-led"},
David Henningssone32aa852013-06-17 11:04:02 +02006702 {.id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "dell-headset-multi"},
6703 {.id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE, .name = "dell-headset-dock"},
Kailang Yangbe8ef162014-04-08 15:19:49 +08006704 {.id = ALC283_FIXUP_CHROME_BOOK, .name = "alc283-dac-wcaps"},
Kailang Yang0202e992013-12-02 15:20:15 +08006705 {.id = ALC283_FIXUP_SENSE_COMBO_JACK, .name = "alc283-sense-combo"},
Takashi Iwai1c37c222014-05-06 17:34:42 +02006706 {.id = ALC292_FIXUP_TPT440_DOCK, .name = "tpt440-dock"},
Takashi Iwai9a811232015-12-09 15:17:43 +01006707 {.id = ALC292_FIXUP_TPT440, .name = "tpt440"},
Sven Eckelmannc636b952016-04-11 16:55:26 +02006708 {.id = ALC292_FIXUP_TPT460, .name = "tpt460"},
Takashi Iwaiba90d6a2017-05-22 16:38:47 +02006709 {.id = ALC233_FIXUP_LENOVO_MULTI_CODECS, .name = "dual-codecs"},
Takashi Iwai28d1d6d2017-10-18 14:01:58 +02006710 {.id = ALC700_FIXUP_INTEL_REFERENCE, .name = "alc700-ref"},
Takashi Iwai1d045db2011-07-07 18:23:21 +02006711 {}
6712};
Kailang Yangcfc5a842016-02-03 15:20:39 +08006713#define ALC225_STANDARD_PINS \
Kailang Yangcfc5a842016-02-03 15:20:39 +08006714 {0x21, 0x04211020}
Takashi Iwai1d045db2011-07-07 18:23:21 +02006715
Hui Wange8191a82015-04-24 13:39:59 +08006716#define ALC256_STANDARD_PINS \
6717 {0x12, 0x90a60140}, \
6718 {0x14, 0x90170110}, \
Hui Wange8191a82015-04-24 13:39:59 +08006719 {0x21, 0x02211020}
6720
David Henningssonfea185e2014-09-03 10:23:04 +02006721#define ALC282_STANDARD_PINS \
Hui Wang11580292015-08-03 11:03:49 +08006722 {0x14, 0x90170110}
Kailang Yange1e62b92015-04-08 16:01:22 +08006723
David Henningssonfea185e2014-09-03 10:23:04 +02006724#define ALC290_STANDARD_PINS \
Hui Wang11580292015-08-03 11:03:49 +08006725 {0x12, 0x99a30130}
David Henningssonfea185e2014-09-03 10:23:04 +02006726
6727#define ALC292_STANDARD_PINS \
6728 {0x14, 0x90170110}, \
Hui Wang11580292015-08-03 11:03:49 +08006729 {0x15, 0x0221401f}
Kailang Yang977e6272015-05-18 15:31:20 +08006730
Hui Wang3f6409702016-09-11 11:26:16 +08006731#define ALC295_STANDARD_PINS \
6732 {0x12, 0xb7a60130}, \
6733 {0x14, 0x90170110}, \
Hui Wang3f6409702016-09-11 11:26:16 +08006734 {0x21, 0x04211020}
6735
Woodrow Shen703867e2015-08-05 12:34:12 +08006736#define ALC298_STANDARD_PINS \
6737 {0x12, 0x90a60130}, \
6738 {0x21, 0x03211020}
6739
Hui Wange1918932014-05-26 16:22:44 +08006740static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
Chris Chiu5824ce82017-02-28 14:17:11 -06006741 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1025, "Acer", ALC255_FIXUP_ACER_MIC_NO_PRESENCE,
6742 {0x12, 0x90a601c0},
6743 {0x14, 0x90171120},
6744 {0x21, 0x02211030}),
Chris Chiu615966a2017-02-28 14:17:12 -06006745 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1043, "ASUS", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE,
6746 {0x14, 0x90170110},
6747 {0x1b, 0x90a70130},
6748 {0x21, 0x03211020}),
6749 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1043, "ASUS", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE,
6750 {0x1a, 0x90a70130},
6751 {0x1b, 0x90170110},
6752 {0x21, 0x03211020}),
David Henningsson2ae95572016-02-25 09:37:05 +01006753 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
Kailang Yangcfc5a842016-02-03 15:20:39 +08006754 ALC225_STANDARD_PINS,
Hui Wang8a132092016-07-08 14:26:57 +08006755 {0x12, 0xb7a60130},
Kailang Yangcfc5a842016-02-03 15:20:39 +08006756 {0x14, 0x901701a0}),
David Henningsson2ae95572016-02-25 09:37:05 +01006757 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
Kailang Yangcfc5a842016-02-03 15:20:39 +08006758 ALC225_STANDARD_PINS,
Hui Wang8a132092016-07-08 14:26:57 +08006759 {0x12, 0xb7a60130},
Kailang Yangcfc5a842016-02-03 15:20:39 +08006760 {0x14, 0x901701b0}),
Hui Wang8a132092016-07-08 14:26:57 +08006761 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
6762 ALC225_STANDARD_PINS,
6763 {0x12, 0xb7a60150},
6764 {0x14, 0x901701a0}),
6765 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
6766 ALC225_STANDARD_PINS,
6767 {0x12, 0xb7a60150},
6768 {0x14, 0x901701b0}),
6769 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
6770 ALC225_STANDARD_PINS,
6771 {0x12, 0xb7a60130},
6772 {0x1b, 0x90170110}),
Kai-Heng Feng0ce48e12017-11-20 02:29:13 -05006773 SND_HDA_PIN_QUIRK(0x10ec0233, 0x8086, "Intel NUC Skull Canyon", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
6774 {0x1b, 0x01111010},
6775 {0x1e, 0x01451130},
6776 {0x21, 0x02211020}),
Hui Wang986376b2018-05-30 12:33:07 +08006777 SND_HDA_PIN_QUIRK(0x10ec0235, 0x17aa, "Lenovo", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY,
6778 {0x12, 0x90a60140},
6779 {0x14, 0x90170110},
6780 {0x19, 0x02a11030},
6781 {0x21, 0x02211020}),
Hui Wangf2657882017-10-24 16:53:34 +08006782 SND_HDA_PIN_QUIRK(0x10ec0236, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6783 {0x12, 0x90a60140},
6784 {0x14, 0x90170110},
6785 {0x21, 0x02211020}),
6786 SND_HDA_PIN_QUIRK(0x10ec0236, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6787 {0x12, 0x90a60140},
6788 {0x14, 0x90170150},
6789 {0x21, 0x02211020}),
Hui Wangc77900e2014-09-03 11:31:07 +08006790 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE,
Hui Wangc77900e2014-09-03 11:31:07 +08006791 {0x14, 0x90170110},
Hui Wangc77900e2014-09-03 11:31:07 +08006792 {0x21, 0x02211020}),
David Henningsson76c21322014-06-24 14:46:54 +02006793 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang86c72d12016-05-25 12:12:32 +08006794 {0x14, 0x90170130},
6795 {0x21, 0x02211040}),
6796 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningsson76c21322014-06-24 14:46:54 +02006797 {0x12, 0x90a60140},
6798 {0x14, 0x90170110},
David Henningsson76c21322014-06-24 14:46:54 +02006799 {0x21, 0x02211020}),
6800 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6801 {0x12, 0x90a60160},
6802 {0x14, 0x90170120},
David Henningsson76c21322014-06-24 14:46:54 +02006803 {0x21, 0x02211030}),
6804 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang392c9da2016-09-26 10:59:38 +08006805 {0x14, 0x90170110},
6806 {0x1b, 0x02011020},
6807 {0x21, 0x0221101f}),
6808 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang6aecd872016-10-20 14:03:33 +08006809 {0x14, 0x90170110},
6810 {0x1b, 0x01011020},
6811 {0x21, 0x0221101f}),
6812 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssoncba59972015-07-22 10:00:25 +02006813 {0x14, 0x90170130},
David Henningssoncba59972015-07-22 10:00:25 +02006814 {0x1b, 0x01014020},
David Henningssoncba59972015-07-22 10:00:25 +02006815 {0x21, 0x0221103f}),
6816 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang59ec4b52016-08-04 15:28:04 +08006817 {0x14, 0x90170130},
Hui Wang6aecd872016-10-20 14:03:33 +08006818 {0x1b, 0x01011020},
6819 {0x21, 0x0221103f}),
6820 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6821 {0x14, 0x90170130},
Hui Wang59ec4b52016-08-04 15:28:04 +08006822 {0x1b, 0x02011020},
6823 {0x21, 0x0221103f}),
6824 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Woodrow Shene9c28e12015-07-25 10:36:16 +08006825 {0x14, 0x90170150},
Woodrow Shene9c28e12015-07-25 10:36:16 +08006826 {0x1b, 0x02011020},
Woodrow Shene9c28e12015-07-25 10:36:16 +08006827 {0x21, 0x0221105f}),
6828 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Woodrow Shene9c28e12015-07-25 10:36:16 +08006829 {0x14, 0x90170110},
Woodrow Shene9c28e12015-07-25 10:36:16 +08006830 {0x1b, 0x01014020},
Woodrow Shene9c28e12015-07-25 10:36:16 +08006831 {0x21, 0x0221101f}),
6832 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningsson76c21322014-06-24 14:46:54 +02006833 {0x12, 0x90a60160},
6834 {0x14, 0x90170120},
6835 {0x17, 0x90170140},
David Henningsson76c21322014-06-24 14:46:54 +02006836 {0x21, 0x0321102f}),
6837 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6838 {0x12, 0x90a60160},
6839 {0x14, 0x90170130},
David Henningsson76c21322014-06-24 14:46:54 +02006840 {0x21, 0x02211040}),
6841 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6842 {0x12, 0x90a60160},
6843 {0x14, 0x90170140},
David Henningsson76c21322014-06-24 14:46:54 +02006844 {0x21, 0x02211050}),
6845 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6846 {0x12, 0x90a60170},
6847 {0x14, 0x90170120},
David Henningsson76c21322014-06-24 14:46:54 +02006848 {0x21, 0x02211030}),
6849 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6850 {0x12, 0x90a60170},
6851 {0x14, 0x90170130},
David Henningsson76c21322014-06-24 14:46:54 +02006852 {0x21, 0x02211040}),
Hui Wang70658b92015-03-06 14:03:57 +08006853 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang70658b92015-03-06 14:03:57 +08006854 {0x12, 0x90a60170},
Hui Wang0a1f90a2016-01-13 11:51:38 +08006855 {0x14, 0x90171130},
6856 {0x21, 0x02211040}),
6857 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6858 {0x12, 0x90a60170},
Hui Wang70658b92015-03-06 14:03:57 +08006859 {0x14, 0x90170140},
Hui Wang70658b92015-03-06 14:03:57 +08006860 {0x21, 0x02211050}),
David Henningsson9b5a4e32015-05-11 14:04:14 +02006861 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell Inspiron 5548", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningsson9b5a4e32015-05-11 14:04:14 +02006862 {0x12, 0x90a60180},
6863 {0x14, 0x90170130},
David Henningsson9b5a4e32015-05-11 14:04:14 +02006864 {0x21, 0x02211040}),
AceLan Kaof90d83b2016-06-03 14:45:25 +08006865 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell Inspiron 5565", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6866 {0x12, 0x90a60180},
6867 {0x14, 0x90170120},
6868 {0x21, 0x02211030}),
Hui Wang989dbe42016-11-23 16:05:38 +08006869 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6870 {0x1b, 0x01011020},
6871 {0x21, 0x02211010}),
Kailang Yang7081adf2015-03-30 17:05:37 +08006872 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang285d5dd2017-12-22 11:17:45 +08006873 {0x12, 0x90a60130},
6874 {0x14, 0x90170110},
6875 {0x1b, 0x01011020},
6876 {0x21, 0x0221101f}),
6877 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Kailang Yang81a12312015-05-28 16:48:22 +08006878 {0x12, 0x90a60160},
6879 {0x14, 0x90170120},
Kailang Yang81a12312015-05-28 16:48:22 +08006880 {0x21, 0x02211030}),
6881 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Woodrow Shenf83c3292016-06-24 15:58:34 +08006882 {0x12, 0x90a60170},
6883 {0x14, 0x90170120},
6884 {0x21, 0x02211030}),
Shrirang Bagul311042d2016-08-29 15:19:27 +08006885 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell Inspiron 5468", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6886 {0x12, 0x90a60180},
6887 {0x14, 0x90170120},
6888 {0x21, 0x02211030}),
Woodrow Shenf83c3292016-06-24 15:58:34 +08006889 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang3f6409702016-09-11 11:26:16 +08006890 {0x12, 0xb7a60130},
6891 {0x14, 0x90170110},
6892 {0x21, 0x02211020}),
David Henningssoncf51eb92014-10-30 08:26:02 +01006893 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang3f2f7c52018-01-29 14:23:15 +08006894 {0x12, 0x90a60130},
6895 {0x14, 0x90170110},
6896 {0x14, 0x01011020},
6897 {0x21, 0x0221101f}),
6898 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssoncf51eb92014-10-30 08:26:02 +01006899 ALC256_STANDARD_PINS),
Chris Chiuc1732ed2017-02-28 14:17:13 -06006900 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC,
6901 {0x14, 0x90170110},
6902 {0x1b, 0x90a70130},
6903 {0x21, 0x04211020}),
6904 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC,
6905 {0x14, 0x90170110},
6906 {0x1b, 0x90a70130},
6907 {0x21, 0x03211020}),
Kailang Yang92266652017-12-14 15:28:58 +08006908 SND_HDA_PIN_QUIRK(0x10ec0274, 0x1028, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB,
Hui Wang75ee94b2017-11-09 08:48:08 +08006909 {0x12, 0xb7a60130},
6910 {0x13, 0xb8a61140},
6911 {0x16, 0x90170110},
6912 {0x21, 0x04211020}),
David Henningssoncf51eb92014-10-30 08:26:02 +01006913 SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC280_FIXUP_HP_GPIO4,
6914 {0x12, 0x90a60130},
6915 {0x14, 0x90170110},
6916 {0x15, 0x0421101f},
Hui Wang11580292015-08-03 11:03:49 +08006917 {0x1a, 0x04a11020}),
Hui Wang02796612014-09-03 11:31:11 +08006918 SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED,
6919 {0x12, 0x90a60140},
Hui Wang02796612014-09-03 11:31:11 +08006920 {0x14, 0x90170110},
6921 {0x15, 0x0421101f},
Hui Wang02796612014-09-03 11:31:11 +08006922 {0x18, 0x02811030},
Hui Wang02796612014-09-03 11:31:11 +08006923 {0x1a, 0x04a1103f},
Hui Wang11580292015-08-03 11:03:49 +08006924 {0x1b, 0x02011020}),
David Henningsson42304472014-07-22 11:42:17 +02006925 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP 15 Touchsmart", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02006926 ALC282_STANDARD_PINS,
David Henningsson42304472014-07-22 11:42:17 +02006927 {0x12, 0x99a30130},
David Henningsson42304472014-07-22 11:42:17 +02006928 {0x19, 0x03a11020},
David Henningsson42304472014-07-22 11:42:17 +02006929 {0x21, 0x0321101f}),
Hui Wang2c609992014-09-03 11:31:08 +08006930 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02006931 ALC282_STANDARD_PINS,
Hui Wang2c609992014-09-03 11:31:08 +08006932 {0x12, 0x99a30130},
Hui Wang2c609992014-09-03 11:31:08 +08006933 {0x19, 0x03a11020},
Hui Wang2c609992014-09-03 11:31:08 +08006934 {0x21, 0x03211040}),
6935 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02006936 ALC282_STANDARD_PINS,
Hui Wang2c609992014-09-03 11:31:08 +08006937 {0x12, 0x99a30130},
Hui Wang2c609992014-09-03 11:31:08 +08006938 {0x19, 0x03a11030},
Hui Wang2c609992014-09-03 11:31:08 +08006939 {0x21, 0x03211020}),
6940 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02006941 ALC282_STANDARD_PINS,
Hui Wang2c609992014-09-03 11:31:08 +08006942 {0x12, 0x99a30130},
Hui Wang2c609992014-09-03 11:31:08 +08006943 {0x19, 0x04a11020},
Hui Wang2c609992014-09-03 11:31:08 +08006944 {0x21, 0x0421101f}),
Hui Wang200afc02014-09-03 11:31:10 +08006945 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED,
David Henningssonaec856d2014-09-03 10:23:05 +02006946 ALC282_STANDARD_PINS,
Hui Wang200afc02014-09-03 11:31:10 +08006947 {0x12, 0x90a60140},
Hui Wang200afc02014-09-03 11:31:10 +08006948 {0x19, 0x04a11030},
Hui Wang200afc02014-09-03 11:31:10 +08006949 {0x21, 0x04211020}),
David Henningsson76c21322014-06-24 14:46:54 +02006950 SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02006951 ALC282_STANDARD_PINS,
David Henningsson76c21322014-06-24 14:46:54 +02006952 {0x12, 0x90a60130},
David Henningsson76c21322014-06-24 14:46:54 +02006953 {0x21, 0x0321101f}),
6954 SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
6955 {0x12, 0x90a60160},
6956 {0x14, 0x90170120},
David Henningsson76c21322014-06-24 14:46:54 +02006957 {0x21, 0x02211030}),
Hui Wangbc262172014-09-03 11:31:05 +08006958 SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02006959 ALC282_STANDARD_PINS,
Hui Wangbc262172014-09-03 11:31:05 +08006960 {0x12, 0x90a60130},
Hui Wangbc262172014-09-03 11:31:05 +08006961 {0x19, 0x03a11020},
Hui Wangbc262172014-09-03 11:31:05 +08006962 {0x21, 0x0321101f}),
Kailang Yange1e62b92015-04-08 16:01:22 +08006963 SND_HDA_PIN_QUIRK(0x10ec0288, 0x1028, "Dell", ALC288_FIXUP_DELL_XPS_13_GPIO6,
Kailang Yange1e62b92015-04-08 16:01:22 +08006964 {0x12, 0x90a60120},
Kailang Yange1e62b92015-04-08 16:01:22 +08006965 {0x14, 0x90170110},
Kailang Yange1e62b92015-04-08 16:01:22 +08006966 {0x21, 0x0321101f}),
Hui Wangd5078192018-03-02 13:05:36 +08006967 SND_HDA_PIN_QUIRK(0x10ec0289, 0x1028, "Dell", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
Hui Wang3f2f7c52018-01-29 14:23:15 +08006968 {0x12, 0xb7a60130},
6969 {0x14, 0x90170110},
6970 {0x21, 0x04211020}),
Hui Wange4442bc2014-09-03 11:31:09 +08006971 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02006972 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08006973 {0x15, 0x04211040},
Hui Wange4442bc2014-09-03 11:31:09 +08006974 {0x18, 0x90170112},
Hui Wang11580292015-08-03 11:03:49 +08006975 {0x1a, 0x04a11020}),
Hui Wange4442bc2014-09-03 11:31:09 +08006976 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02006977 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08006978 {0x15, 0x04211040},
Hui Wange4442bc2014-09-03 11:31:09 +08006979 {0x18, 0x90170110},
Hui Wang11580292015-08-03 11:03:49 +08006980 {0x1a, 0x04a11020}),
Hui Wange4442bc2014-09-03 11:31:09 +08006981 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02006982 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08006983 {0x15, 0x0421101f},
Hui Wang11580292015-08-03 11:03:49 +08006984 {0x1a, 0x04a11020}),
Hui Wange4442bc2014-09-03 11:31:09 +08006985 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02006986 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08006987 {0x15, 0x04211020},
Hui Wang11580292015-08-03 11:03:49 +08006988 {0x1a, 0x04a11040}),
Hui Wange4442bc2014-09-03 11:31:09 +08006989 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02006990 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08006991 {0x14, 0x90170110},
6992 {0x15, 0x04211020},
Hui Wang11580292015-08-03 11:03:49 +08006993 {0x1a, 0x04a11040}),
Hui Wange4442bc2014-09-03 11:31:09 +08006994 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02006995 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08006996 {0x14, 0x90170110},
6997 {0x15, 0x04211020},
Hui Wang11580292015-08-03 11:03:49 +08006998 {0x1a, 0x04a11020}),
Hui Wange4442bc2014-09-03 11:31:09 +08006999 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02007000 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08007001 {0x14, 0x90170110},
7002 {0x15, 0x0421101f},
Hui Wang11580292015-08-03 11:03:49 +08007003 {0x1a, 0x04a11020}),
Hui Wange8818fa2014-09-03 11:31:04 +08007004 SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007005 ALC292_STANDARD_PINS,
Hui Wange8818fa2014-09-03 11:31:04 +08007006 {0x12, 0x90a60140},
Hui Wange8818fa2014-09-03 11:31:04 +08007007 {0x16, 0x01014020},
Hui Wang11580292015-08-03 11:03:49 +08007008 {0x19, 0x01a19030}),
Hui Wange8818fa2014-09-03 11:31:04 +08007009 SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007010 ALC292_STANDARD_PINS,
Hui Wange8818fa2014-09-03 11:31:04 +08007011 {0x12, 0x90a60140},
Hui Wange8818fa2014-09-03 11:31:04 +08007012 {0x16, 0x01014020},
7013 {0x18, 0x02a19031},
Hui Wang11580292015-08-03 11:03:49 +08007014 {0x19, 0x01a1903e}),
David Henningsson76c21322014-06-24 14:46:54 +02007015 SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007016 ALC292_STANDARD_PINS,
Hui Wang11580292015-08-03 11:03:49 +08007017 {0x12, 0x90a60140}),
David Henningsson76c21322014-06-24 14:46:54 +02007018 SND_HDA_PIN_QUIRK(0x10ec0293, 0x1028, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007019 ALC292_STANDARD_PINS,
David Henningsson76c21322014-06-24 14:46:54 +02007020 {0x13, 0x90a60140},
David Henningsson76c21322014-06-24 14:46:54 +02007021 {0x16, 0x21014020},
Hui Wang11580292015-08-03 11:03:49 +08007022 {0x19, 0x21a19030}),
David Henningssone03fdbd2014-06-27 08:41:59 +02007023 SND_HDA_PIN_QUIRK(0x10ec0293, 0x1028, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02007024 ALC292_STANDARD_PINS,
Hui Wang11580292015-08-03 11:03:49 +08007025 {0x13, 0x90a60140}),
Hui Wang3f6409702016-09-11 11:26:16 +08007026 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wangf771d5b2016-10-18 10:59:09 +08007027 ALC295_STANDARD_PINS,
7028 {0x17, 0x21014020},
7029 {0x18, 0x21a19030}),
7030 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
7031 ALC295_STANDARD_PINS,
7032 {0x17, 0x21014040},
7033 {0x18, 0x21a19050}),
Hui Wang3f307832017-03-23 10:00:25 +08007034 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
7035 ALC295_STANDARD_PINS),
Kailang Yang977e6272015-05-18 15:31:20 +08007036 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
Woodrow Shen703867e2015-08-05 12:34:12 +08007037 ALC298_STANDARD_PINS,
Takashi Iwai9f502ff2015-08-05 12:09:45 +02007038 {0x17, 0x90170110}),
7039 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
7040 ALC298_STANDARD_PINS,
Woodrow Shen703867e2015-08-05 12:34:12 +08007041 {0x17, 0x90170140}),
7042 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
7043 ALC298_STANDARD_PINS,
Takashi Iwai9f502ff2015-08-05 12:09:45 +02007044 {0x17, 0x90170150}),
Kai-Heng Feng9f1bc2c42017-02-16 15:26:54 +08007045 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_SPK_VOLUME,
7046 {0x12, 0xb7a60140},
7047 {0x13, 0xb7a60150},
7048 {0x17, 0x90170110},
7049 {0x1a, 0x03011020},
7050 {0x21, 0x03211030}),
Kailang Yangfcc6c872017-06-29 15:21:27 +08007051 SND_HDA_PIN_QUIRK(0x10ec0299, 0x1028, "Dell", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
7052 ALC225_STANDARD_PINS,
7053 {0x12, 0xb7a60130},
Kailang Yangfcc6c872017-06-29 15:21:27 +08007054 {0x17, 0x90170110}),
Hui Wange1918932014-05-26 16:22:44 +08007055 {}
7056};
Takashi Iwai1d045db2011-07-07 18:23:21 +02007057
Takashi Iwai546bb672012-03-07 08:37:19 +01007058static void alc269_fill_coef(struct hda_codec *codec)
Takashi Iwai1d045db2011-07-07 18:23:21 +02007059{
Kailang Yang526af6e2012-03-07 08:25:20 +01007060 struct alc_spec *spec = codec->spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02007061 int val;
7062
Kailang Yang526af6e2012-03-07 08:25:20 +01007063 if (spec->codec_variant != ALC269_TYPE_ALC269VB)
Takashi Iwai546bb672012-03-07 08:37:19 +01007064 return;
Kailang Yang526af6e2012-03-07 08:25:20 +01007065
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007066 if ((alc_get_coef0(codec) & 0x00ff) < 0x015) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02007067 alc_write_coef_idx(codec, 0xf, 0x960b);
7068 alc_write_coef_idx(codec, 0xe, 0x8817);
7069 }
7070
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007071 if ((alc_get_coef0(codec) & 0x00ff) == 0x016) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02007072 alc_write_coef_idx(codec, 0xf, 0x960b);
7073 alc_write_coef_idx(codec, 0xe, 0x8814);
7074 }
7075
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007076 if ((alc_get_coef0(codec) & 0x00ff) == 0x017) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02007077 /* Power up output pin */
Takashi Iwai98b24882014-08-18 13:47:50 +02007078 alc_update_coef_idx(codec, 0x04, 0, 1<<11);
Takashi Iwai1d045db2011-07-07 18:23:21 +02007079 }
7080
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007081 if ((alc_get_coef0(codec) & 0x00ff) == 0x018) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02007082 val = alc_read_coef_idx(codec, 0xd);
Takashi Iwaif3ee07d2014-08-15 17:35:00 +02007083 if (val != -1 && (val & 0x0c00) >> 10 != 0x1) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02007084 /* Capless ramp up clock control */
7085 alc_write_coef_idx(codec, 0xd, val | (1<<10));
7086 }
7087 val = alc_read_coef_idx(codec, 0x17);
Takashi Iwaif3ee07d2014-08-15 17:35:00 +02007088 if (val != -1 && (val & 0x01c0) >> 6 != 0x4) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02007089 /* Class D power on reset */
7090 alc_write_coef_idx(codec, 0x17, val | (1<<7));
7091 }
7092 }
7093
Takashi Iwai98b24882014-08-18 13:47:50 +02007094 /* HP */
7095 alc_update_coef_idx(codec, 0x4, 0, 1<<11);
Takashi Iwai1d045db2011-07-07 18:23:21 +02007096}
7097
7098/*
7099 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02007100static int patch_alc269(struct hda_codec *codec)
7101{
7102 struct alc_spec *spec;
Takashi Iwai3de95172012-05-07 18:03:15 +02007103 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02007104
Takashi Iwai3de95172012-05-07 18:03:15 +02007105 err = alc_alloc_spec(codec, 0x0b);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007106 if (err < 0)
Takashi Iwai3de95172012-05-07 18:03:15 +02007107 return err;
7108
7109 spec = codec->spec;
Takashi Iwai08c189f2012-12-19 15:22:24 +01007110 spec->gen.shared_mic_vref_pin = 0x18;
Takashi Iwai8b99aba2015-06-15 11:59:32 +02007111 codec->power_save_node = 1;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007112
Takashi Iwai225068a2015-05-29 10:42:14 +02007113#ifdef CONFIG_PM
7114 codec->patch_ops.suspend = alc269_suspend;
7115 codec->patch_ops.resume = alc269_resume;
7116#endif
Kailang Yangc2d6af52017-06-21 14:50:54 +08007117 spec->shutup = alc_default_shutup;
7118 spec->init_hook = alc_default_init;
Takashi Iwai225068a2015-05-29 10:42:14 +02007119
Takashi Iwai1727a772013-01-10 09:52:52 +01007120 snd_hda_pick_fixup(codec, alc269_fixup_models,
Herton Ronaldo Krzesinski9f720bb92012-09-27 10:38:14 -03007121 alc269_fixup_tbl, alc269_fixups);
Hui Wange1918932014-05-26 16:22:44 +08007122 snd_hda_pick_pin_fixup(codec, alc269_pin_fixup_tbl, alc269_fixups);
David Henningsson214eef72014-07-22 14:09:35 +02007123 snd_hda_pick_fixup(codec, NULL, alc269_fixup_vendor_tbl,
7124 alc269_fixups);
Takashi Iwai1727a772013-01-10 09:52:52 +01007125 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Herton Ronaldo Krzesinski9f720bb92012-09-27 10:38:14 -03007126
7127 alc_auto_parse_customize_define(codec);
7128
Takashi Iwai7504b6c2013-03-18 11:25:51 +01007129 if (has_cdefine_beep(codec))
7130 spec->gen.beep_nid = 0x01;
7131
Takashi Iwai7639a062015-03-03 10:07:24 +01007132 switch (codec->core.vendor_id) {
Kailang Yang065380f2013-01-10 10:25:48 +01007133 case 0x10ec0269:
Takashi Iwai1d045db2011-07-07 18:23:21 +02007134 spec->codec_variant = ALC269_TYPE_ALC269VA;
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007135 switch (alc_get_coef0(codec) & 0x00f0) {
7136 case 0x0010:
Takashi Iwai5100cd02014-02-15 10:03:19 +01007137 if (codec->bus->pci &&
7138 codec->bus->pci->subsystem_vendor == 0x1025 &&
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007139 spec->cdefine.platform_type == 1)
Takashi Iwai20ca0c32011-10-17 16:00:35 +02007140 err = alc_codec_rename(codec, "ALC271X");
Takashi Iwai1d045db2011-07-07 18:23:21 +02007141 spec->codec_variant = ALC269_TYPE_ALC269VB;
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007142 break;
7143 case 0x0020:
Takashi Iwai5100cd02014-02-15 10:03:19 +01007144 if (codec->bus->pci &&
7145 codec->bus->pci->subsystem_vendor == 0x17aa &&
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007146 codec->bus->pci->subsystem_device == 0x21f3)
Takashi Iwai20ca0c32011-10-17 16:00:35 +02007147 err = alc_codec_rename(codec, "ALC3202");
Takashi Iwai1d045db2011-07-07 18:23:21 +02007148 spec->codec_variant = ALC269_TYPE_ALC269VC;
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007149 break;
Kailang Yangadcc70b2012-05-25 08:08:38 +02007150 case 0x0030:
7151 spec->codec_variant = ALC269_TYPE_ALC269VD;
7152 break;
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007153 default:
Takashi Iwai1d045db2011-07-07 18:23:21 +02007154 alc_fix_pll_init(codec, 0x20, 0x04, 15);
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007155 }
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007156 if (err < 0)
7157 goto error;
Kailang Yangc2d6af52017-06-21 14:50:54 +08007158 spec->shutup = alc269_shutup;
Takashi Iwai546bb672012-03-07 08:37:19 +01007159 spec->init_hook = alc269_fill_coef;
Takashi Iwai1d045db2011-07-07 18:23:21 +02007160 alc269_fill_coef(codec);
Kailang Yang065380f2013-01-10 10:25:48 +01007161 break;
7162
7163 case 0x10ec0280:
7164 case 0x10ec0290:
7165 spec->codec_variant = ALC269_TYPE_ALC280;
7166 break;
7167 case 0x10ec0282:
Kailang Yang065380f2013-01-10 10:25:48 +01007168 spec->codec_variant = ALC269_TYPE_ALC282;
Kailang Yang7b5c7a02014-03-18 16:15:54 +08007169 spec->shutup = alc282_shutup;
7170 spec->init_hook = alc282_init;
Kailang Yang065380f2013-01-10 10:25:48 +01007171 break;
Kailang Yang2af02be2013-08-22 10:03:50 +02007172 case 0x10ec0233:
7173 case 0x10ec0283:
7174 spec->codec_variant = ALC269_TYPE_ALC283;
7175 spec->shutup = alc283_shutup;
7176 spec->init_hook = alc283_init;
7177 break;
Kailang Yang065380f2013-01-10 10:25:48 +01007178 case 0x10ec0284:
7179 case 0x10ec0292:
7180 spec->codec_variant = ALC269_TYPE_ALC284;
7181 break;
Kailang Yang161ebf22013-10-24 11:36:33 +02007182 case 0x10ec0293:
Kailang Yang4731d5d2017-06-30 15:22:57 +08007183 spec->codec_variant = ALC269_TYPE_ALC293;
Kailang Yang161ebf22013-10-24 11:36:33 +02007184 break;
Kailang Yang7fc7d042013-04-25 11:04:43 +02007185 case 0x10ec0286:
Kailang Yang7c665932014-04-14 15:09:44 +08007186 case 0x10ec0288:
Kailang Yang7fc7d042013-04-25 11:04:43 +02007187 spec->codec_variant = ALC269_TYPE_ALC286;
Kailang Yangf7ae9ba2014-06-30 16:10:37 +08007188 spec->shutup = alc286_shutup;
Kailang Yang7fc7d042013-04-25 11:04:43 +02007189 break;
Kailang Yang506b62c2014-12-18 17:07:44 +08007190 case 0x10ec0298:
7191 spec->codec_variant = ALC269_TYPE_ALC298;
7192 break;
Kailang Yangea04a1d2018-04-25 15:31:52 +08007193 case 0x10ec0235:
Kailang Yang1d04c9d2013-10-24 11:35:18 +02007194 case 0x10ec0255:
7195 spec->codec_variant = ALC269_TYPE_ALC255;
Kailang Yangab3b8e52018-04-25 16:05:27 +08007196 spec->shutup = alc256_shutup;
7197 spec->init_hook = alc256_init;
Kailang Yang1d04c9d2013-10-24 11:35:18 +02007198 break;
Kailang Yang736f20a2017-10-20 15:06:34 +08007199 case 0x10ec0236:
Kailang Yang4344aec2014-12-17 17:39:05 +08007200 case 0x10ec0256:
7201 spec->codec_variant = ALC269_TYPE_ALC256;
Kailang Yang4a219ef2017-06-16 16:54:35 +08007202 spec->shutup = alc256_shutup;
7203 spec->init_hook = alc256_init;
David Henningsson7d1b6e22015-04-21 10:48:46 +02007204 spec->gen.mixer_nid = 0; /* ALC256 does not have any loopback mixer path */
Kailang Yangd32b6662015-04-23 15:10:53 +08007205 alc_update_coef_idx(codec, 0x36, 1 << 13, 1 << 5); /* Switch pcbeep path to Line in path*/
Kailang Yang4344aec2014-12-17 17:39:05 +08007206 break;
Kailang Yangf429e7e2017-12-05 15:38:24 +08007207 case 0x10ec0257:
7208 spec->codec_variant = ALC269_TYPE_ALC257;
Kailang Yang88d42b22018-03-14 16:08:57 +08007209 spec->shutup = alc256_shutup;
7210 spec->init_hook = alc256_init;
Kailang Yangf429e7e2017-12-05 15:38:24 +08007211 spec->gen.mixer_nid = 0;
7212 break;
Kailang Yang0a6f0602017-06-30 16:00:48 +08007213 case 0x10ec0215:
7214 case 0x10ec0285:
7215 case 0x10ec0289:
7216 spec->codec_variant = ALC269_TYPE_ALC215;
Kailang Yang1b6832be2018-01-17 15:32:03 +08007217 spec->shutup = alc225_shutup;
7218 spec->init_hook = alc225_init;
Kailang Yang0a6f0602017-06-30 16:00:48 +08007219 spec->gen.mixer_nid = 0;
7220 break;
Kailang Yang42314302016-02-03 15:03:50 +08007221 case 0x10ec0225:
Kailang Yang7d727862016-05-24 16:46:07 +08007222 case 0x10ec0295:
Kailang Yang28f1f9b2017-01-04 14:49:07 +08007223 case 0x10ec0299:
Kailang Yang42314302016-02-03 15:03:50 +08007224 spec->codec_variant = ALC269_TYPE_ALC225;
Kailang Yangda911b12018-01-05 16:50:08 +08007225 spec->shutup = alc225_shutup;
7226 spec->init_hook = alc225_init;
Takashi Iwaic1350bf2017-12-27 09:03:45 +01007227 spec->gen.mixer_nid = 0; /* no loopback on ALC225, ALC295 and ALC299 */
Kailang Yang42314302016-02-03 15:03:50 +08007228 break;
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08007229 case 0x10ec0234:
7230 case 0x10ec0274:
7231 case 0x10ec0294:
7232 spec->codec_variant = ALC269_TYPE_ALC294;
Hui Wang532a7782017-06-26 12:30:32 +08007233 spec->gen.mixer_nid = 0; /* ALC2x4 does not have any loopback mixer path */
Kailang Yang71683c32017-06-20 16:33:50 +08007234 alc_update_coef_idx(codec, 0x6b, 0x0018, (1<<4) | (1<<3)); /* UAJ MIC Vref control by verb */
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08007235 break;
Kailang Yang6fbae352016-05-30 16:44:20 +08007236 case 0x10ec0700:
7237 case 0x10ec0701:
7238 case 0x10ec0703:
7239 spec->codec_variant = ALC269_TYPE_ALC700;
7240 spec->gen.mixer_nid = 0; /* ALC700 does not have any loopback mixer path */
Kailang Yang2d7fe612017-11-22 15:21:32 +08007241 alc_update_coef_idx(codec, 0x4a, 1 << 15, 0); /* Combo jack auto trigger control */
Kailang Yang6fbae352016-05-30 16:44:20 +08007242 break;
7243
Takashi Iwai1d045db2011-07-07 18:23:21 +02007244 }
7245
Kailang Yangad60d502013-06-28 12:03:01 +02007246 if (snd_hda_codec_read(codec, 0x51, 0, AC_VERB_PARAMETERS, 0) == 0x10ec5505) {
Kailang Yang97a26572013-11-29 00:35:26 -05007247 spec->has_alc5505_dsp = 1;
Kailang Yangad60d502013-06-28 12:03:01 +02007248 spec->init_hook = alc5505_dsp_init;
7249 }
7250
Takashi Iwaia4297b52011-08-23 18:40:12 +02007251 /* automatic parse from the BIOS config */
7252 err = alc269_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007253 if (err < 0)
7254 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02007255
David Henningsson7d1b6e22015-04-21 10:48:46 +02007256 if (!spec->gen.no_analog && spec->gen.beep_nid && spec->gen.mixer_nid)
7257 set_beep_amp(spec, spec->gen.mixer_nid, 0x04, HDA_INPUT);
Takashi Iwai1d045db2011-07-07 18:23:21 +02007258
Takashi Iwai1727a772013-01-10 09:52:52 +01007259 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01007260
Takashi Iwai1d045db2011-07-07 18:23:21 +02007261 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007262
7263 error:
7264 alc_free(codec);
7265 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02007266}
7267
7268/*
7269 * ALC861
7270 */
7271
Takashi Iwai1d045db2011-07-07 18:23:21 +02007272static int alc861_parse_auto_config(struct hda_codec *codec)
7273{
Takashi Iwai1d045db2011-07-07 18:23:21 +02007274 static const hda_nid_t alc861_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02007275 static const hda_nid_t alc861_ssids[] = { 0x0e, 0x0f, 0x0b, 0 };
7276 return alc_parse_auto_config(codec, alc861_ignore, alc861_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02007277}
7278
Takashi Iwai1d045db2011-07-07 18:23:21 +02007279/* Pin config fixes */
7280enum {
Takashi Iwaie652f4c2012-02-13 11:56:25 +01007281 ALC861_FIXUP_FSC_AMILO_PI1505,
7282 ALC861_FIXUP_AMP_VREF_0F,
7283 ALC861_FIXUP_NO_JACK_DETECT,
7284 ALC861_FIXUP_ASUS_A6RP,
Takashi Iwai6ddf0fd2013-11-29 12:47:34 +01007285 ALC660_FIXUP_ASUS_W7J,
Takashi Iwai1d045db2011-07-07 18:23:21 +02007286};
7287
Takashi Iwai31150f22012-01-30 10:54:08 +01007288/* On some laptops, VREF of pin 0x0f is abused for controlling the main amp */
7289static void alc861_fixup_asus_amp_vref_0f(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01007290 const struct hda_fixup *fix, int action)
Takashi Iwai31150f22012-01-30 10:54:08 +01007291{
7292 struct alc_spec *spec = codec->spec;
7293 unsigned int val;
7294
Takashi Iwai1727a772013-01-10 09:52:52 +01007295 if (action != HDA_FIXUP_ACT_INIT)
Takashi Iwai31150f22012-01-30 10:54:08 +01007296 return;
Takashi Iwaid3f02d62013-01-10 10:12:22 +01007297 val = snd_hda_codec_get_pin_target(codec, 0x0f);
Takashi Iwai31150f22012-01-30 10:54:08 +01007298 if (!(val & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN)))
7299 val |= AC_PINCTL_IN_EN;
7300 val |= AC_PINCTL_VREF_50;
Takashi Iwaicdd03ce2012-04-20 12:34:50 +02007301 snd_hda_set_pin_ctl(codec, 0x0f, val);
Takashi Iwai08c189f2012-12-19 15:22:24 +01007302 spec->gen.keep_vref_in_automute = 1;
Takashi Iwai31150f22012-01-30 10:54:08 +01007303}
7304
Takashi Iwaie652f4c2012-02-13 11:56:25 +01007305/* suppress the jack-detection */
7306static void alc_fixup_no_jack_detect(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01007307 const struct hda_fixup *fix, int action)
Takashi Iwaie652f4c2012-02-13 11:56:25 +01007308{
Takashi Iwai1727a772013-01-10 09:52:52 +01007309 if (action == HDA_FIXUP_ACT_PRE_PROBE)
Takashi Iwaie652f4c2012-02-13 11:56:25 +01007310 codec->no_jack_detect = 1;
Jesper Juhl7d7eb9e2012-04-12 22:11:25 +02007311}
Takashi Iwaie652f4c2012-02-13 11:56:25 +01007312
Takashi Iwai1727a772013-01-10 09:52:52 +01007313static const struct hda_fixup alc861_fixups[] = {
Takashi Iwaie652f4c2012-02-13 11:56:25 +01007314 [ALC861_FIXUP_FSC_AMILO_PI1505] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01007315 .type = HDA_FIXUP_PINS,
7316 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02007317 { 0x0b, 0x0221101f }, /* HP */
7318 { 0x0f, 0x90170310 }, /* speaker */
7319 { }
7320 }
7321 },
Takashi Iwaie652f4c2012-02-13 11:56:25 +01007322 [ALC861_FIXUP_AMP_VREF_0F] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01007323 .type = HDA_FIXUP_FUNC,
Takashi Iwai31150f22012-01-30 10:54:08 +01007324 .v.func = alc861_fixup_asus_amp_vref_0f,
Takashi Iwai3b25eb62012-01-25 09:55:46 +01007325 },
Takashi Iwaie652f4c2012-02-13 11:56:25 +01007326 [ALC861_FIXUP_NO_JACK_DETECT] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01007327 .type = HDA_FIXUP_FUNC,
Takashi Iwaie652f4c2012-02-13 11:56:25 +01007328 .v.func = alc_fixup_no_jack_detect,
7329 },
7330 [ALC861_FIXUP_ASUS_A6RP] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01007331 .type = HDA_FIXUP_FUNC,
Takashi Iwaie652f4c2012-02-13 11:56:25 +01007332 .v.func = alc861_fixup_asus_amp_vref_0f,
7333 .chained = true,
7334 .chain_id = ALC861_FIXUP_NO_JACK_DETECT,
Takashi Iwai6ddf0fd2013-11-29 12:47:34 +01007335 },
7336 [ALC660_FIXUP_ASUS_W7J] = {
7337 .type = HDA_FIXUP_VERBS,
7338 .v.verbs = (const struct hda_verb[]) {
7339 /* ASUS W7J needs a magic pin setup on unused NID 0x10
7340 * for enabling outputs
7341 */
7342 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
7343 { }
7344 },
Takashi Iwaie652f4c2012-02-13 11:56:25 +01007345 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02007346};
7347
7348static const struct snd_pci_quirk alc861_fixup_tbl[] = {
Takashi Iwai6ddf0fd2013-11-29 12:47:34 +01007349 SND_PCI_QUIRK(0x1043, 0x1253, "ASUS W7J", ALC660_FIXUP_ASUS_W7J),
Takashi Iwaie7ca2372013-12-02 15:27:19 +01007350 SND_PCI_QUIRK(0x1043, 0x1263, "ASUS Z35HL", ALC660_FIXUP_ASUS_W7J),
Takashi Iwaie652f4c2012-02-13 11:56:25 +01007351 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS A6Rp", ALC861_FIXUP_ASUS_A6RP),
7352 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", ALC861_FIXUP_AMP_VREF_0F),
7353 SND_PCI_QUIRK(0x1462, 0x7254, "HP DX2200", ALC861_FIXUP_NO_JACK_DETECT),
7354 SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", ALC861_FIXUP_AMP_VREF_0F),
7355 SND_PCI_QUIRK(0x1584, 0x0000, "Uniwill ECS M31EI", ALC861_FIXUP_AMP_VREF_0F),
7356 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", ALC861_FIXUP_FSC_AMILO_PI1505),
Takashi Iwai1d045db2011-07-07 18:23:21 +02007357 {}
7358};
7359
7360/*
7361 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02007362static int patch_alc861(struct hda_codec *codec)
7363{
7364 struct alc_spec *spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02007365 int err;
7366
Takashi Iwai3de95172012-05-07 18:03:15 +02007367 err = alc_alloc_spec(codec, 0x15);
7368 if (err < 0)
7369 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02007370
Takashi Iwai3de95172012-05-07 18:03:15 +02007371 spec = codec->spec;
Takashi Iwai7504b6c2013-03-18 11:25:51 +01007372 spec->gen.beep_nid = 0x23;
Takashi Iwai1d045db2011-07-07 18:23:21 +02007373
Takashi Iwai225068a2015-05-29 10:42:14 +02007374#ifdef CONFIG_PM
7375 spec->power_hook = alc_power_eapd;
7376#endif
7377
Takashi Iwai1727a772013-01-10 09:52:52 +01007378 snd_hda_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
7379 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02007380
Takashi Iwaicb4e4822011-08-23 17:34:25 +02007381 /* automatic parse from the BIOS config */
7382 err = alc861_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007383 if (err < 0)
7384 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02007385
Takashi Iwai7504b6c2013-03-18 11:25:51 +01007386 if (!spec->gen.no_analog)
Takashi Iwai3e6179b2011-07-08 16:55:13 +02007387 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
Takashi Iwai1d045db2011-07-07 18:23:21 +02007388
Takashi Iwai1727a772013-01-10 09:52:52 +01007389 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01007390
Takashi Iwai1d045db2011-07-07 18:23:21 +02007391 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007392
7393 error:
7394 alc_free(codec);
7395 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02007396}
7397
7398/*
7399 * ALC861-VD support
7400 *
7401 * Based on ALC882
7402 *
7403 * In addition, an independent DAC
7404 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02007405static int alc861vd_parse_auto_config(struct hda_codec *codec)
7406{
Takashi Iwai1d045db2011-07-07 18:23:21 +02007407 static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02007408 static const hda_nid_t alc861vd_ssids[] = { 0x15, 0x1b, 0x14, 0 };
7409 return alc_parse_auto_config(codec, alc861vd_ignore, alc861vd_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02007410}
7411
Takashi Iwai1d045db2011-07-07 18:23:21 +02007412enum {
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02007413 ALC660VD_FIX_ASUS_GPIO1,
7414 ALC861VD_FIX_DALLAS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02007415};
7416
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02007417/* exclude VREF80 */
7418static void alc861vd_fixup_dallas(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01007419 const struct hda_fixup *fix, int action)
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02007420{
Takashi Iwai1727a772013-01-10 09:52:52 +01007421 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwaib78562b2012-12-17 20:06:49 +01007422 snd_hda_override_pin_caps(codec, 0x18, 0x00000734);
7423 snd_hda_override_pin_caps(codec, 0x19, 0x0000073c);
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02007424 }
7425}
7426
Takashi Iwai1727a772013-01-10 09:52:52 +01007427static const struct hda_fixup alc861vd_fixups[] = {
Takashi Iwai1d045db2011-07-07 18:23:21 +02007428 [ALC660VD_FIX_ASUS_GPIO1] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01007429 .type = HDA_FIXUP_VERBS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02007430 .v.verbs = (const struct hda_verb[]) {
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02007431 /* reset GPIO1 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02007432 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
7433 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
7434 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
7435 { }
7436 }
7437 },
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02007438 [ALC861VD_FIX_DALLAS] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01007439 .type = HDA_FIXUP_FUNC,
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02007440 .v.func = alc861vd_fixup_dallas,
7441 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02007442};
7443
7444static const struct snd_pci_quirk alc861vd_fixup_tbl[] = {
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02007445 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_FIX_DALLAS),
Takashi Iwai1d045db2011-07-07 18:23:21 +02007446 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02007447 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_FIX_DALLAS),
Takashi Iwai1d045db2011-07-07 18:23:21 +02007448 {}
7449};
7450
Takashi Iwai1d045db2011-07-07 18:23:21 +02007451/*
7452 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02007453static int patch_alc861vd(struct hda_codec *codec)
7454{
7455 struct alc_spec *spec;
Takashi Iwaicb4e4822011-08-23 17:34:25 +02007456 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02007457
Takashi Iwai3de95172012-05-07 18:03:15 +02007458 err = alc_alloc_spec(codec, 0x0b);
7459 if (err < 0)
7460 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02007461
Takashi Iwai3de95172012-05-07 18:03:15 +02007462 spec = codec->spec;
Takashi Iwai7504b6c2013-03-18 11:25:51 +01007463 spec->gen.beep_nid = 0x23;
Takashi Iwai1d045db2011-07-07 18:23:21 +02007464
Takashi Iwai225068a2015-05-29 10:42:14 +02007465 spec->shutup = alc_eapd_shutup;
7466
Takashi Iwai1727a772013-01-10 09:52:52 +01007467 snd_hda_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
7468 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02007469
Takashi Iwaicb4e4822011-08-23 17:34:25 +02007470 /* automatic parse from the BIOS config */
7471 err = alc861vd_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007472 if (err < 0)
7473 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02007474
Takashi Iwai7504b6c2013-03-18 11:25:51 +01007475 if (!spec->gen.no_analog)
Takashi Iwai3e6179b2011-07-08 16:55:13 +02007476 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
Takashi Iwai1d045db2011-07-07 18:23:21 +02007477
Takashi Iwai1727a772013-01-10 09:52:52 +01007478 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01007479
Takashi Iwai1d045db2011-07-07 18:23:21 +02007480 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007481
7482 error:
7483 alc_free(codec);
7484 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02007485}
7486
7487/*
7488 * ALC662 support
7489 *
7490 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
7491 * configuration. Each pin widget can choose any input DACs and a mixer.
7492 * Each ADC is connected from a mixer of all inputs. This makes possible
7493 * 6-channel independent captures.
7494 *
7495 * In addition, an independent DAC for the multi-playback (not used in this
7496 * driver yet).
7497 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02007498
7499/*
7500 * BIOS auto configuration
7501 */
7502
Kailang Yangbc9f98a2007-04-12 13:06:07 +02007503static int alc662_parse_auto_config(struct hda_codec *codec)
7504{
Takashi Iwai4c6d72d2011-05-02 11:30:18 +02007505 static const hda_nid_t alc662_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02007506 static const hda_nid_t alc663_ssids[] = { 0x15, 0x1b, 0x14, 0x21 };
7507 static const hda_nid_t alc662_ssids[] = { 0x15, 0x1b, 0x14, 0 };
7508 const hda_nid_t *ssids;
Takashi Iwaiee979a142008-09-02 15:42:20 +02007509
Takashi Iwai7639a062015-03-03 10:07:24 +01007510 if (codec->core.vendor_id == 0x10ec0272 || codec->core.vendor_id == 0x10ec0663 ||
7511 codec->core.vendor_id == 0x10ec0665 || codec->core.vendor_id == 0x10ec0670 ||
7512 codec->core.vendor_id == 0x10ec0671)
Takashi Iwai3e6179b2011-07-08 16:55:13 +02007513 ssids = alc663_ssids;
Kailang Yang6227cdc2010-02-25 08:36:52 +01007514 else
Takashi Iwai3e6179b2011-07-08 16:55:13 +02007515 ssids = alc662_ssids;
7516 return alc_parse_auto_config(codec, alc662_ignore, ssids);
Kailang Yangbc9f98a2007-04-12 13:06:07 +02007517}
7518
Todd Broch6be79482010-12-07 16:51:05 -08007519static void alc272_fixup_mario(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01007520 const struct hda_fixup *fix, int action)
Takashi Iwai6fc398c2011-01-13 14:36:37 +01007521{
Takashi Iwai9bb1f062013-01-10 17:14:29 +01007522 if (action != HDA_FIXUP_ACT_PRE_PROBE)
Takashi Iwai6fc398c2011-01-13 14:36:37 +01007523 return;
Todd Broch6be79482010-12-07 16:51:05 -08007524 if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT,
7525 (0x3b << AC_AMPCAP_OFFSET_SHIFT) |
7526 (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) |
7527 (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) |
7528 (0 << AC_AMPCAP_MUTE_SHIFT)))
Takashi Iwai4e76a882014-02-25 12:21:03 +01007529 codec_warn(codec, "failed to override amp caps for NID 0x2\n");
Todd Broch6be79482010-12-07 16:51:05 -08007530}
7531
Takashi Iwai8e383952013-10-30 17:41:12 +01007532static const struct snd_pcm_chmap_elem asus_pcm_2_1_chmaps[] = {
7533 { .channels = 2,
7534 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } },
7535 { .channels = 4,
7536 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR,
7537 SNDRV_CHMAP_NA, SNDRV_CHMAP_LFE } }, /* LFE only on right */
7538 { }
7539};
7540
7541/* override the 2.1 chmap */
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01007542static void alc_fixup_bass_chmap(struct hda_codec *codec,
Takashi Iwai8e383952013-10-30 17:41:12 +01007543 const struct hda_fixup *fix, int action)
7544{
7545 if (action == HDA_FIXUP_ACT_BUILD) {
7546 struct alc_spec *spec = codec->spec;
Takashi Iwaibbbc7e82015-02-27 17:43:19 +01007547 spec->gen.pcm_rec[0]->stream[0].chmap = asus_pcm_2_1_chmaps;
Takashi Iwai8e383952013-10-30 17:41:12 +01007548 }
7549}
7550
Takashi Iwaibf686652014-01-13 16:18:25 +01007551/* avoid D3 for keeping GPIO up */
7552static unsigned int gpio_led_power_filter(struct hda_codec *codec,
7553 hda_nid_t nid,
7554 unsigned int power_state)
7555{
7556 struct alc_spec *spec = codec->spec;
Takashi Iwai7639a062015-03-03 10:07:24 +01007557 if (nid == codec->core.afg && power_state == AC_PWRST_D3 && spec->gpio_led)
Takashi Iwaibf686652014-01-13 16:18:25 +01007558 return AC_PWRST_D0;
7559 return power_state;
7560}
7561
Takashi Iwai3e887f32014-01-10 17:50:58 +01007562static void alc662_fixup_led_gpio1(struct hda_codec *codec,
7563 const struct hda_fixup *fix, int action)
7564{
7565 struct alc_spec *spec = codec->spec;
7566 static const struct hda_verb gpio_init[] = {
7567 { 0x01, AC_VERB_SET_GPIO_MASK, 0x01 },
7568 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01 },
7569 {}
7570 };
7571
7572 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai0f32fd192014-11-19 12:16:14 +01007573 spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook;
Takashi Iwai3e887f32014-01-10 17:50:58 +01007574 spec->gpio_led = 0;
Takashi Iwai0f32fd192014-11-19 12:16:14 +01007575 spec->mute_led_polarity = 1;
7576 spec->gpio_mute_led_mask = 0x01;
Takashi Iwai3e887f32014-01-10 17:50:58 +01007577 snd_hda_add_verbs(codec, gpio_init);
Takashi Iwaibf686652014-01-13 16:18:25 +01007578 codec->power_filter = gpio_led_power_filter;
Takashi Iwai3e887f32014-01-10 17:50:58 +01007579 }
7580}
7581
Kailang Yangc6790c82016-11-25 16:15:17 +08007582static void alc662_usi_automute_hook(struct hda_codec *codec,
7583 struct hda_jack_callback *jack)
7584{
7585 struct alc_spec *spec = codec->spec;
7586 int vref;
7587 msleep(200);
7588 snd_hda_gen_hp_automute(codec, jack);
7589
7590 vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0;
7591 msleep(100);
7592 snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
7593 vref);
7594}
7595
7596static void alc662_fixup_usi_headset_mic(struct hda_codec *codec,
7597 const struct hda_fixup *fix, int action)
7598{
7599 struct alc_spec *spec = codec->spec;
7600 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
7601 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
7602 spec->gen.hp_automute_hook = alc662_usi_automute_hook;
7603 }
7604}
7605
Kailang Yangf3f91852014-10-24 15:43:46 +08007606static struct coef_fw alc668_coefs[] = {
7607 WRITE_COEF(0x01, 0xbebe), WRITE_COEF(0x02, 0xaaaa), WRITE_COEF(0x03, 0x0),
7608 WRITE_COEF(0x04, 0x0180), WRITE_COEF(0x06, 0x0), WRITE_COEF(0x07, 0x0f80),
7609 WRITE_COEF(0x08, 0x0031), WRITE_COEF(0x0a, 0x0060), WRITE_COEF(0x0b, 0x0),
7610 WRITE_COEF(0x0c, 0x7cf7), WRITE_COEF(0x0d, 0x1080), WRITE_COEF(0x0e, 0x7f7f),
7611 WRITE_COEF(0x0f, 0xcccc), WRITE_COEF(0x10, 0xddcc), WRITE_COEF(0x11, 0x0001),
7612 WRITE_COEF(0x13, 0x0), WRITE_COEF(0x14, 0x2aa0), WRITE_COEF(0x17, 0xa940),
7613 WRITE_COEF(0x19, 0x0), WRITE_COEF(0x1a, 0x0), WRITE_COEF(0x1b, 0x0),
7614 WRITE_COEF(0x1c, 0x0), WRITE_COEF(0x1d, 0x0), WRITE_COEF(0x1e, 0x7418),
7615 WRITE_COEF(0x1f, 0x0804), WRITE_COEF(0x20, 0x4200), WRITE_COEF(0x21, 0x0468),
7616 WRITE_COEF(0x22, 0x8ccc), WRITE_COEF(0x23, 0x0250), WRITE_COEF(0x24, 0x7418),
7617 WRITE_COEF(0x27, 0x0), WRITE_COEF(0x28, 0x8ccc), WRITE_COEF(0x2a, 0xff00),
7618 WRITE_COEF(0x2b, 0x8000), WRITE_COEF(0xa7, 0xff00), WRITE_COEF(0xa8, 0x8000),
7619 WRITE_COEF(0xaa, 0x2e17), WRITE_COEF(0xab, 0xa0c0), WRITE_COEF(0xac, 0x0),
7620 WRITE_COEF(0xad, 0x0), WRITE_COEF(0xae, 0x2ac6), WRITE_COEF(0xaf, 0xa480),
7621 WRITE_COEF(0xb0, 0x0), WRITE_COEF(0xb1, 0x0), WRITE_COEF(0xb2, 0x0),
7622 WRITE_COEF(0xb3, 0x0), WRITE_COEF(0xb4, 0x0), WRITE_COEF(0xb5, 0x1040),
7623 WRITE_COEF(0xb6, 0xd697), WRITE_COEF(0xb7, 0x902b), WRITE_COEF(0xb8, 0xd697),
7624 WRITE_COEF(0xb9, 0x902b), WRITE_COEF(0xba, 0xb8ba), WRITE_COEF(0xbb, 0xaaab),
7625 WRITE_COEF(0xbc, 0xaaaf), WRITE_COEF(0xbd, 0x6aaa), WRITE_COEF(0xbe, 0x1c02),
7626 WRITE_COEF(0xc0, 0x00ff), WRITE_COEF(0xc1, 0x0fa6),
7627 {}
7628};
7629
7630static void alc668_restore_default_value(struct hda_codec *codec)
7631{
7632 alc_process_coef_fw(codec, alc668_coefs);
7633}
7634
David Henningsson6cb3b702010-09-09 08:51:44 +02007635enum {
Daniel T Chen2df03512010-10-10 22:39:28 -04007636 ALC662_FIXUP_ASPIRE,
Takashi Iwai3e887f32014-01-10 17:50:58 +01007637 ALC662_FIXUP_LED_GPIO1,
David Henningsson6cb3b702010-09-09 08:51:44 +02007638 ALC662_FIXUP_IDEAPAD,
Todd Broch6be79482010-12-07 16:51:05 -08007639 ALC272_FIXUP_MARIO,
Anisse Astierd2ebd472011-01-20 12:36:21 +01007640 ALC662_FIXUP_CZC_P10T,
David Henningsson94024cd2011-04-29 14:10:55 +02007641 ALC662_FIXUP_SKU_IGNORE,
Takashi Iwaie59ea3e2011-06-29 17:21:00 +02007642 ALC662_FIXUP_HP_RP5800,
Takashi Iwai53c334a2011-08-23 18:27:14 +02007643 ALC662_FIXUP_ASUS_MODE1,
7644 ALC662_FIXUP_ASUS_MODE2,
7645 ALC662_FIXUP_ASUS_MODE3,
7646 ALC662_FIXUP_ASUS_MODE4,
7647 ALC662_FIXUP_ASUS_MODE5,
7648 ALC662_FIXUP_ASUS_MODE6,
7649 ALC662_FIXUP_ASUS_MODE7,
7650 ALC662_FIXUP_ASUS_MODE8,
Takashi Iwai1565cc32012-02-13 12:03:25 +01007651 ALC662_FIXUP_NO_JACK_DETECT,
David Henningssonedfe3bf2012-06-12 13:15:12 +02007652 ALC662_FIXUP_ZOTAC_Z68,
Takashi Iwai125821a2012-06-22 14:30:29 +02007653 ALC662_FIXUP_INV_DMIC,
David Henningsson1f8b46c2015-05-12 14:38:15 +02007654 ALC662_FIXUP_DELL_MIC_NO_PRESENCE,
David Henningsson73bdd592013-04-15 15:44:14 +02007655 ALC668_FIXUP_DELL_MIC_NO_PRESENCE,
David Henningsson1f8b46c2015-05-12 14:38:15 +02007656 ALC662_FIXUP_HEADSET_MODE,
David Henningsson73bdd592013-04-15 15:44:14 +02007657 ALC668_FIXUP_HEADSET_MODE,
David Henningsson8e54b4a2014-02-07 09:31:07 +01007658 ALC662_FIXUP_BASS_MODE4_CHMAP,
David Henningsson61a75f12014-02-07 09:31:08 +01007659 ALC662_FIXUP_BASS_16,
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01007660 ALC662_FIXUP_BASS_1A,
David Henningsson8e54b4a2014-02-07 09:31:07 +01007661 ALC662_FIXUP_BASS_CHMAP,
Hui Wang493a52a2014-01-14 14:07:36 +08007662 ALC668_FIXUP_AUTO_MUTE,
Gabriele Mazzotta5e6db662014-05-20 18:58:26 +02007663 ALC668_FIXUP_DELL_DISABLE_AAMIX,
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02007664 ALC668_FIXUP_DELL_XPS13,
Bobi Mihalca9d4dc582016-03-23 13:26:11 +02007665 ALC662_FIXUP_ASUS_Nx50,
Mikhail Paulyshkafc7438b2017-04-21 08:52:42 +02007666 ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE,
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07007667 ALC668_FIXUP_ASUS_Nx51,
Kailang Yang78f4f7c2016-06-07 11:31:34 +08007668 ALC891_FIXUP_HEADSET_MODE,
7669 ALC891_FIXUP_DELL_MIC_NO_PRESENCE,
Shrirang Bagul9b51fe32016-08-01 13:16:17 +08007670 ALC662_FIXUP_ACER_VERITON,
Takashi Iwai1a3f0992016-10-20 12:14:51 +02007671 ALC892_FIXUP_ASROCK_MOBO,
Kailang Yangc6790c82016-11-25 16:15:17 +08007672 ALC662_FIXUP_USI_FUNC,
7673 ALC662_FIXUP_USI_HEADSET_MODE,
Kailang Yangca169cc2017-04-25 16:17:40 +08007674 ALC662_FIXUP_LENOVO_MULTI_CODECS,
David Henningsson6cb3b702010-09-09 08:51:44 +02007675};
7676
Takashi Iwai1727a772013-01-10 09:52:52 +01007677static const struct hda_fixup alc662_fixups[] = {
Daniel T Chen2df03512010-10-10 22:39:28 -04007678 [ALC662_FIXUP_ASPIRE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01007679 .type = HDA_FIXUP_PINS,
7680 .v.pins = (const struct hda_pintbl[]) {
Daniel T Chen2df03512010-10-10 22:39:28 -04007681 { 0x15, 0x99130112 }, /* subwoofer */
7682 { }
7683 }
7684 },
Takashi Iwai3e887f32014-01-10 17:50:58 +01007685 [ALC662_FIXUP_LED_GPIO1] = {
7686 .type = HDA_FIXUP_FUNC,
7687 .v.func = alc662_fixup_led_gpio1,
7688 },
David Henningsson6cb3b702010-09-09 08:51:44 +02007689 [ALC662_FIXUP_IDEAPAD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01007690 .type = HDA_FIXUP_PINS,
7691 .v.pins = (const struct hda_pintbl[]) {
David Henningsson6cb3b702010-09-09 08:51:44 +02007692 { 0x17, 0x99130112 }, /* subwoofer */
7693 { }
Takashi Iwai3e887f32014-01-10 17:50:58 +01007694 },
7695 .chained = true,
7696 .chain_id = ALC662_FIXUP_LED_GPIO1,
David Henningsson6cb3b702010-09-09 08:51:44 +02007697 },
Todd Broch6be79482010-12-07 16:51:05 -08007698 [ALC272_FIXUP_MARIO] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01007699 .type = HDA_FIXUP_FUNC,
Takashi Iwaib5bfbc62011-01-13 14:22:32 +01007700 .v.func = alc272_fixup_mario,
Anisse Astierd2ebd472011-01-20 12:36:21 +01007701 },
7702 [ALC662_FIXUP_CZC_P10T] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01007703 .type = HDA_FIXUP_VERBS,
Anisse Astierd2ebd472011-01-20 12:36:21 +01007704 .v.verbs = (const struct hda_verb[]) {
7705 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
7706 {}
7707 }
7708 },
David Henningsson94024cd2011-04-29 14:10:55 +02007709 [ALC662_FIXUP_SKU_IGNORE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01007710 .type = HDA_FIXUP_FUNC,
Takashi Iwai23d30f22012-05-07 17:17:32 +02007711 .v.func = alc_fixup_sku_ignore,
Takashi Iwaic6b35872011-03-28 12:05:31 +02007712 },
Takashi Iwaie59ea3e2011-06-29 17:21:00 +02007713 [ALC662_FIXUP_HP_RP5800] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01007714 .type = HDA_FIXUP_PINS,
7715 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaie59ea3e2011-06-29 17:21:00 +02007716 { 0x14, 0x0221201f }, /* HP out */
7717 { }
7718 },
7719 .chained = true,
7720 .chain_id = ALC662_FIXUP_SKU_IGNORE
7721 },
Takashi Iwai53c334a2011-08-23 18:27:14 +02007722 [ALC662_FIXUP_ASUS_MODE1] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01007723 .type = HDA_FIXUP_PINS,
7724 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02007725 { 0x14, 0x99130110 }, /* speaker */
7726 { 0x18, 0x01a19c20 }, /* mic */
7727 { 0x19, 0x99a3092f }, /* int-mic */
7728 { 0x21, 0x0121401f }, /* HP out */
7729 { }
7730 },
7731 .chained = true,
7732 .chain_id = ALC662_FIXUP_SKU_IGNORE
7733 },
7734 [ALC662_FIXUP_ASUS_MODE2] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01007735 .type = HDA_FIXUP_PINS,
7736 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai2996bdb2011-08-18 16:02:24 +02007737 { 0x14, 0x99130110 }, /* speaker */
7738 { 0x18, 0x01a19820 }, /* mic */
7739 { 0x19, 0x99a3092f }, /* int-mic */
7740 { 0x1b, 0x0121401f }, /* HP out */
7741 { }
7742 },
Takashi Iwai53c334a2011-08-23 18:27:14 +02007743 .chained = true,
7744 .chain_id = ALC662_FIXUP_SKU_IGNORE
7745 },
7746 [ALC662_FIXUP_ASUS_MODE3] = {
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 { 0x15, 0x0121441f }, /* HP */
7751 { 0x18, 0x01a19840 }, /* mic */
7752 { 0x19, 0x99a3094f }, /* int-mic */
7753 { 0x21, 0x01211420 }, /* HP2 */
7754 { }
7755 },
7756 .chained = true,
7757 .chain_id = ALC662_FIXUP_SKU_IGNORE
7758 },
7759 [ALC662_FIXUP_ASUS_MODE4] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01007760 .type = HDA_FIXUP_PINS,
7761 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02007762 { 0x14, 0x99130110 }, /* speaker */
7763 { 0x16, 0x99130111 }, /* speaker */
7764 { 0x18, 0x01a19840 }, /* mic */
7765 { 0x19, 0x99a3094f }, /* int-mic */
7766 { 0x21, 0x0121441f }, /* HP */
7767 { }
7768 },
7769 .chained = true,
7770 .chain_id = ALC662_FIXUP_SKU_IGNORE
7771 },
7772 [ALC662_FIXUP_ASUS_MODE5] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01007773 .type = HDA_FIXUP_PINS,
7774 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02007775 { 0x14, 0x99130110 }, /* speaker */
7776 { 0x15, 0x0121441f }, /* HP */
7777 { 0x16, 0x99130111 }, /* speaker */
7778 { 0x18, 0x01a19840 }, /* mic */
7779 { 0x19, 0x99a3094f }, /* int-mic */
7780 { }
7781 },
7782 .chained = true,
7783 .chain_id = ALC662_FIXUP_SKU_IGNORE
7784 },
7785 [ALC662_FIXUP_ASUS_MODE6] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01007786 .type = HDA_FIXUP_PINS,
7787 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02007788 { 0x14, 0x99130110 }, /* speaker */
7789 { 0x15, 0x01211420 }, /* HP2 */
7790 { 0x18, 0x01a19840 }, /* mic */
7791 { 0x19, 0x99a3094f }, /* int-mic */
7792 { 0x1b, 0x0121441f }, /* HP */
7793 { }
7794 },
7795 .chained = true,
7796 .chain_id = ALC662_FIXUP_SKU_IGNORE
7797 },
7798 [ALC662_FIXUP_ASUS_MODE7] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01007799 .type = HDA_FIXUP_PINS,
7800 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02007801 { 0x14, 0x99130110 }, /* speaker */
7802 { 0x17, 0x99130111 }, /* speaker */
7803 { 0x18, 0x01a19840 }, /* mic */
7804 { 0x19, 0x99a3094f }, /* int-mic */
7805 { 0x1b, 0x01214020 }, /* HP */
7806 { 0x21, 0x0121401f }, /* HP */
7807 { }
7808 },
7809 .chained = true,
7810 .chain_id = ALC662_FIXUP_SKU_IGNORE
7811 },
7812 [ALC662_FIXUP_ASUS_MODE8] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01007813 .type = HDA_FIXUP_PINS,
7814 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02007815 { 0x14, 0x99130110 }, /* speaker */
7816 { 0x12, 0x99a30970 }, /* int-mic */
7817 { 0x15, 0x01214020 }, /* HP */
7818 { 0x17, 0x99130111 }, /* speaker */
7819 { 0x18, 0x01a19840 }, /* mic */
7820 { 0x21, 0x0121401f }, /* HP */
7821 { }
7822 },
7823 .chained = true,
7824 .chain_id = ALC662_FIXUP_SKU_IGNORE
Takashi Iwai2996bdb2011-08-18 16:02:24 +02007825 },
Takashi Iwai1565cc32012-02-13 12:03:25 +01007826 [ALC662_FIXUP_NO_JACK_DETECT] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01007827 .type = HDA_FIXUP_FUNC,
Takashi Iwai1565cc32012-02-13 12:03:25 +01007828 .v.func = alc_fixup_no_jack_detect,
7829 },
David Henningssonedfe3bf2012-06-12 13:15:12 +02007830 [ALC662_FIXUP_ZOTAC_Z68] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01007831 .type = HDA_FIXUP_PINS,
7832 .v.pins = (const struct hda_pintbl[]) {
David Henningssonedfe3bf2012-06-12 13:15:12 +02007833 { 0x1b, 0x02214020 }, /* Front HP */
7834 { }
7835 }
7836 },
Takashi Iwai125821a2012-06-22 14:30:29 +02007837 [ALC662_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01007838 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02007839 .v.func = alc_fixup_inv_dmic,
Takashi Iwai125821a2012-06-22 14:30:29 +02007840 },
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02007841 [ALC668_FIXUP_DELL_XPS13] = {
7842 .type = HDA_FIXUP_FUNC,
7843 .v.func = alc_fixup_dell_xps13,
7844 .chained = true,
7845 .chain_id = ALC668_FIXUP_DELL_DISABLE_AAMIX
7846 },
Gabriele Mazzotta5e6db662014-05-20 18:58:26 +02007847 [ALC668_FIXUP_DELL_DISABLE_AAMIX] = {
7848 .type = HDA_FIXUP_FUNC,
7849 .v.func = alc_fixup_disable_aamix,
7850 .chained = true,
7851 .chain_id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE
7852 },
Hui Wang493a52a2014-01-14 14:07:36 +08007853 [ALC668_FIXUP_AUTO_MUTE] = {
7854 .type = HDA_FIXUP_FUNC,
7855 .v.func = alc_fixup_auto_mute_via_amp,
7856 .chained = true,
7857 .chain_id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE
7858 },
David Henningsson1f8b46c2015-05-12 14:38:15 +02007859 [ALC662_FIXUP_DELL_MIC_NO_PRESENCE] = {
7860 .type = HDA_FIXUP_PINS,
7861 .v.pins = (const struct hda_pintbl[]) {
7862 { 0x19, 0x03a1113c }, /* use as headset mic, without its own jack detect */
7863 /* headphone mic by setting pin control of 0x1b (headphone out) to in + vref_50 */
7864 { }
7865 },
7866 .chained = true,
7867 .chain_id = ALC662_FIXUP_HEADSET_MODE
7868 },
7869 [ALC662_FIXUP_HEADSET_MODE] = {
7870 .type = HDA_FIXUP_FUNC,
7871 .v.func = alc_fixup_headset_mode_alc662,
7872 },
David Henningsson73bdd592013-04-15 15:44:14 +02007873 [ALC668_FIXUP_DELL_MIC_NO_PRESENCE] = {
7874 .type = HDA_FIXUP_PINS,
7875 .v.pins = (const struct hda_pintbl[]) {
7876 { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
7877 { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */
7878 { }
7879 },
7880 .chained = true,
7881 .chain_id = ALC668_FIXUP_HEADSET_MODE
7882 },
7883 [ALC668_FIXUP_HEADSET_MODE] = {
7884 .type = HDA_FIXUP_FUNC,
7885 .v.func = alc_fixup_headset_mode_alc668,
7886 },
David Henningsson8e54b4a2014-02-07 09:31:07 +01007887 [ALC662_FIXUP_BASS_MODE4_CHMAP] = {
Takashi Iwai8e383952013-10-30 17:41:12 +01007888 .type = HDA_FIXUP_FUNC,
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01007889 .v.func = alc_fixup_bass_chmap,
Takashi Iwai8e383952013-10-30 17:41:12 +01007890 .chained = true,
7891 .chain_id = ALC662_FIXUP_ASUS_MODE4
7892 },
David Henningsson61a75f12014-02-07 09:31:08 +01007893 [ALC662_FIXUP_BASS_16] = {
7894 .type = HDA_FIXUP_PINS,
7895 .v.pins = (const struct hda_pintbl[]) {
7896 {0x16, 0x80106111}, /* bass speaker */
7897 {}
7898 },
7899 .chained = true,
7900 .chain_id = ALC662_FIXUP_BASS_CHMAP,
7901 },
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01007902 [ALC662_FIXUP_BASS_1A] = {
7903 .type = HDA_FIXUP_PINS,
7904 .v.pins = (const struct hda_pintbl[]) {
7905 {0x1a, 0x80106111}, /* bass speaker */
7906 {}
7907 },
David Henningsson8e54b4a2014-02-07 09:31:07 +01007908 .chained = true,
7909 .chain_id = ALC662_FIXUP_BASS_CHMAP,
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01007910 },
David Henningsson8e54b4a2014-02-07 09:31:07 +01007911 [ALC662_FIXUP_BASS_CHMAP] = {
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01007912 .type = HDA_FIXUP_FUNC,
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01007913 .v.func = alc_fixup_bass_chmap,
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01007914 },
Bobi Mihalca9d4dc582016-03-23 13:26:11 +02007915 [ALC662_FIXUP_ASUS_Nx50] = {
7916 .type = HDA_FIXUP_FUNC,
7917 .v.func = alc_fixup_auto_mute_via_amp,
7918 .chained = true,
7919 .chain_id = ALC662_FIXUP_BASS_1A
7920 },
Mikhail Paulyshkafc7438b2017-04-21 08:52:42 +02007921 [ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE] = {
7922 .type = HDA_FIXUP_FUNC,
7923 .v.func = alc_fixup_headset_mode_alc668,
7924 .chain_id = ALC662_FIXUP_BASS_CHMAP
7925 },
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07007926 [ALC668_FIXUP_ASUS_Nx51] = {
7927 .type = HDA_FIXUP_PINS,
7928 .v.pins = (const struct hda_pintbl[]) {
Mikhail Paulyshkafc7438b2017-04-21 08:52:42 +02007929 { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
7930 { 0x1a, 0x90170151 }, /* bass speaker */
7931 { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07007932 {}
7933 },
7934 .chained = true,
Mikhail Paulyshkafc7438b2017-04-21 08:52:42 +02007935 .chain_id = ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE,
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07007936 },
Kailang Yang78f4f7c2016-06-07 11:31:34 +08007937 [ALC891_FIXUP_HEADSET_MODE] = {
7938 .type = HDA_FIXUP_FUNC,
7939 .v.func = alc_fixup_headset_mode,
7940 },
7941 [ALC891_FIXUP_DELL_MIC_NO_PRESENCE] = {
7942 .type = HDA_FIXUP_PINS,
7943 .v.pins = (const struct hda_pintbl[]) {
7944 { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
7945 { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */
7946 { }
7947 },
7948 .chained = true,
7949 .chain_id = ALC891_FIXUP_HEADSET_MODE
7950 },
Shrirang Bagul9b51fe32016-08-01 13:16:17 +08007951 [ALC662_FIXUP_ACER_VERITON] = {
7952 .type = HDA_FIXUP_PINS,
7953 .v.pins = (const struct hda_pintbl[]) {
7954 { 0x15, 0x50170120 }, /* no internal speaker */
7955 { }
7956 }
7957 },
Takashi Iwai1a3f0992016-10-20 12:14:51 +02007958 [ALC892_FIXUP_ASROCK_MOBO] = {
7959 .type = HDA_FIXUP_PINS,
7960 .v.pins = (const struct hda_pintbl[]) {
7961 { 0x15, 0x40f000f0 }, /* disabled */
7962 { 0x16, 0x40f000f0 }, /* disabled */
Takashi Iwai1a3f0992016-10-20 12:14:51 +02007963 { }
7964 }
7965 },
Kailang Yangc6790c82016-11-25 16:15:17 +08007966 [ALC662_FIXUP_USI_FUNC] = {
7967 .type = HDA_FIXUP_FUNC,
7968 .v.func = alc662_fixup_usi_headset_mic,
7969 },
7970 [ALC662_FIXUP_USI_HEADSET_MODE] = {
7971 .type = HDA_FIXUP_PINS,
7972 .v.pins = (const struct hda_pintbl[]) {
7973 { 0x19, 0x02a1913c }, /* use as headset mic, without its own jack detect */
7974 { 0x18, 0x01a1903d },
7975 { }
7976 },
7977 .chained = true,
7978 .chain_id = ALC662_FIXUP_USI_FUNC
7979 },
Kailang Yangca169cc2017-04-25 16:17:40 +08007980 [ALC662_FIXUP_LENOVO_MULTI_CODECS] = {
7981 .type = HDA_FIXUP_FUNC,
7982 .v.func = alc233_alc662_fixup_lenovo_dual_codecs,
7983 },
David Henningsson6cb3b702010-09-09 08:51:44 +02007984};
7985
Takashi Iwaia9111322011-05-02 11:30:18 +02007986static const struct snd_pci_quirk alc662_fixup_tbl[] = {
Takashi Iwai53c334a2011-08-23 18:27:14 +02007987 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_FIXUP_ASUS_MODE2),
Takashi Iwaid3d38352013-08-19 20:05:50 +02007988 SND_PCI_QUIRK(0x1025, 0x022f, "Acer Aspire One", ALC662_FIXUP_INV_DMIC),
David Henningsson02f6ff92015-12-07 11:29:31 +01007989 SND_PCI_QUIRK(0x1025, 0x0241, "Packard Bell DOTS", ALC662_FIXUP_INV_DMIC),
David Henningssona6c47a82011-02-10 15:39:19 +01007990 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
David Henningsson94024cd2011-04-29 14:10:55 +02007991 SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
Takashi Iwai125821a2012-06-22 14:30:29 +02007992 SND_PCI_QUIRK(0x1025, 0x0349, "eMachines eM250", ALC662_FIXUP_INV_DMIC),
Takashi Iwai18019282013-08-16 08:17:05 +02007993 SND_PCI_QUIRK(0x1025, 0x034a, "Gateway LT27", ALC662_FIXUP_INV_DMIC),
Daniel T Chen2df03512010-10-10 22:39:28 -04007994 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
David Henningsson73bdd592013-04-15 15:44:14 +02007995 SND_PCI_QUIRK(0x1028, 0x05d8, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
7996 SND_PCI_QUIRK(0x1028, 0x05db, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
Takashi Iwaic5d019c2014-07-22 17:33:32 +02007997 SND_PCI_QUIRK(0x1028, 0x05fe, "Dell XPS 15", ALC668_FIXUP_DELL_XPS13),
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02007998 SND_PCI_QUIRK(0x1028, 0x060a, "Dell XPS 13", ALC668_FIXUP_DELL_XPS13),
Niranjan Sivakumar467e1432015-09-05 18:20:35 +02007999 SND_PCI_QUIRK(0x1028, 0x060d, "Dell M3800", ALC668_FIXUP_DELL_XPS13),
David Henningsson09d20142013-11-20 11:43:30 +01008000 SND_PCI_QUIRK(0x1028, 0x0625, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
David Henningssonad8ff992013-11-07 09:28:59 +01008001 SND_PCI_QUIRK(0x1028, 0x0626, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
Kailang Yang8dc9abb2014-04-16 15:53:12 +08008002 SND_PCI_QUIRK(0x1028, 0x0696, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
8003 SND_PCI_QUIRK(0x1028, 0x0698, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
Kailang Yang6a98e342014-10-27 16:20:30 +08008004 SND_PCI_QUIRK(0x1028, 0x069f, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
Takashi Iwaie59ea3e2011-06-29 17:21:00 +02008005 SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800),
Kaho Ng2da2dc92016-05-09 00:27:49 +08008006 SND_PCI_QUIRK(0x1043, 0x1080, "Asus UX501VW", ALC668_FIXUP_HEADSET_MODE),
Bobi Mihalca83a9efb2016-03-23 13:32:33 +02008007 SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_ASUS_Nx50),
Takashi Iwaidb8948e2016-01-18 09:17:30 +01008008 SND_PCI_QUIRK(0x1043, 0x13df, "Asus N550JX", ALC662_FIXUP_BASS_1A),
Bobi Mihalca9d4dc582016-03-23 13:26:11 +02008009 SND_PCI_QUIRK(0x1043, 0x129d, "Asus N750", ALC662_FIXUP_ASUS_Nx50),
David Henningsson8e54b4a2014-02-07 09:31:07 +01008010 SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
David Henningsson61a75f12014-02-07 09:31:08 +01008011 SND_PCI_QUIRK(0x1043, 0x15a7, "ASUS UX51VZH", ALC662_FIXUP_BASS_16),
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07008012 SND_PCI_QUIRK(0x1043, 0x177d, "ASUS N551", ALC668_FIXUP_ASUS_Nx51),
8013 SND_PCI_QUIRK(0x1043, 0x17bd, "ASUS N751", ALC668_FIXUP_ASUS_Nx51),
Takashi Iwaic7efff92017-01-04 21:38:16 +01008014 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71SL", ALC662_FIXUP_ASUS_MODE8),
David Henningsson61a75f12014-02-07 09:31:08 +01008015 SND_PCI_QUIRK(0x1043, 0x1b73, "ASUS N55SF", ALC662_FIXUP_BASS_16),
David Henningsson8e54b4a2014-02-07 09:31:07 +01008016 SND_PCI_QUIRK(0x1043, 0x1bf3, "ASUS N76VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
Takashi Iwai1565cc32012-02-13 12:03:25 +01008017 SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT),
Takashi Iwai53c334a2011-08-23 18:27:14 +02008018 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2),
Daniel T Chena0e90ac2010-11-20 10:20:35 -05008019 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
Kailang Yangc6790c82016-11-25 16:15:17 +08008020 SND_PCI_QUIRK(0x14cd, 0x5003, "USI", ALC662_FIXUP_USI_HEADSET_MODE),
Kailang Yangca169cc2017-04-25 16:17:40 +08008021 SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC662_FIXUP_LENOVO_MULTI_CODECS),
Valentine Sinitsynd4118582010-10-01 22:24:08 +06008022 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
David Henningsson6cb3b702010-09-09 08:51:44 +02008023 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
Takashi Iwai1a3f0992016-10-20 12:14:51 +02008024 SND_PCI_QUIRK(0x1849, 0x5892, "ASRock B150M", ALC892_FIXUP_ASROCK_MOBO),
David Henningssonedfe3bf2012-06-12 13:15:12 +02008025 SND_PCI_QUIRK(0x19da, 0xa130, "Zotac Z68", ALC662_FIXUP_ZOTAC_Z68),
Shrirang Bagul9b51fe32016-08-01 13:16:17 +08008026 SND_PCI_QUIRK(0x1b0a, 0x01b8, "ACER Veriton", ALC662_FIXUP_ACER_VERITON),
Anisse Astierd2ebd472011-01-20 12:36:21 +01008027 SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
Takashi Iwai53c334a2011-08-23 18:27:14 +02008028
8029#if 0
8030 /* Below is a quirk table taken from the old code.
8031 * Basically the device should work as is without the fixup table.
8032 * If BIOS doesn't give a proper info, enable the corresponding
8033 * fixup entry.
Jesper Juhl7d7eb9e2012-04-12 22:11:25 +02008034 */
Takashi Iwai53c334a2011-08-23 18:27:14 +02008035 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC662_FIXUP_ASUS_MODE1),
8036 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC662_FIXUP_ASUS_MODE3),
8037 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC662_FIXUP_ASUS_MODE1),
8038 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC662_FIXUP_ASUS_MODE3),
8039 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
8040 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8041 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
8042 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC662_FIXUP_ASUS_MODE1),
8043 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC662_FIXUP_ASUS_MODE1),
8044 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8045 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC662_FIXUP_ASUS_MODE7),
8046 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC662_FIXUP_ASUS_MODE7),
8047 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC662_FIXUP_ASUS_MODE8),
8048 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC662_FIXUP_ASUS_MODE3),
8049 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC662_FIXUP_ASUS_MODE1),
8050 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8051 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_FIXUP_ASUS_MODE2),
8052 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC662_FIXUP_ASUS_MODE1),
8053 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8054 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
8055 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
8056 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8057 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC662_FIXUP_ASUS_MODE1),
8058 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC662_FIXUP_ASUS_MODE3),
8059 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_FIXUP_ASUS_MODE2),
8060 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8061 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC662_FIXUP_ASUS_MODE5),
8062 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
8063 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8064 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC662_FIXUP_ASUS_MODE1),
8065 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8066 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8067 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC662_FIXUP_ASUS_MODE3),
8068 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC662_FIXUP_ASUS_MODE3),
8069 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC662_FIXUP_ASUS_MODE1),
8070 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC662_FIXUP_ASUS_MODE1),
8071 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC662_FIXUP_ASUS_MODE1),
8072 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC662_FIXUP_ASUS_MODE1),
8073 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC662_FIXUP_ASUS_MODE1),
8074 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
8075 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_FIXUP_ASUS_MODE2),
8076 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC662_FIXUP_ASUS_MODE1),
8077 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
8078 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC662_FIXUP_ASUS_MODE3),
8079 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC662_FIXUP_ASUS_MODE1),
8080 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC662_FIXUP_ASUS_MODE1),
8081 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC662_FIXUP_ASUS_MODE1),
8082 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_FIXUP_ASUS_MODE2),
8083 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
8084 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE4),
8085#endif
David Henningsson6cb3b702010-09-09 08:51:44 +02008086 {}
8087};
8088
Takashi Iwai1727a772013-01-10 09:52:52 +01008089static const struct hda_model_fixup alc662_fixup_models[] = {
Todd Broch6be79482010-12-07 16:51:05 -08008090 {.id = ALC272_FIXUP_MARIO, .name = "mario"},
Takashi Iwai53c334a2011-08-23 18:27:14 +02008091 {.id = ALC662_FIXUP_ASUS_MODE1, .name = "asus-mode1"},
8092 {.id = ALC662_FIXUP_ASUS_MODE2, .name = "asus-mode2"},
8093 {.id = ALC662_FIXUP_ASUS_MODE3, .name = "asus-mode3"},
8094 {.id = ALC662_FIXUP_ASUS_MODE4, .name = "asus-mode4"},
8095 {.id = ALC662_FIXUP_ASUS_MODE5, .name = "asus-mode5"},
8096 {.id = ALC662_FIXUP_ASUS_MODE6, .name = "asus-mode6"},
8097 {.id = ALC662_FIXUP_ASUS_MODE7, .name = "asus-mode7"},
8098 {.id = ALC662_FIXUP_ASUS_MODE8, .name = "asus-mode8"},
Takashi Iwai6e72aa52012-06-25 10:52:25 +02008099 {.id = ALC662_FIXUP_INV_DMIC, .name = "inv-dmic"},
David Henningssone32aa852013-06-17 11:04:02 +02008100 {.id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE, .name = "dell-headset-multi"},
Takashi Iwaiba90d6a2017-05-22 16:38:47 +02008101 {.id = ALC662_FIXUP_LENOVO_MULTI_CODECS, .name = "dual-codecs"},
Todd Broch6be79482010-12-07 16:51:05 -08008102 {}
8103};
David Henningsson6cb3b702010-09-09 08:51:44 +02008104
Hui Wang532895c2014-05-29 15:59:19 +08008105static const struct snd_hda_pin_quirk alc662_pin_fixup_tbl[] = {
Kailang Yang78f4f7c2016-06-07 11:31:34 +08008106 SND_HDA_PIN_QUIRK(0x10ec0867, 0x1028, "Dell", ALC891_FIXUP_DELL_MIC_NO_PRESENCE,
8107 {0x17, 0x02211010},
8108 {0x18, 0x01a19030},
8109 {0x1a, 0x01813040},
8110 {0x21, 0x01014020}),
David Henningsson1f8b46c2015-05-12 14:38:15 +02008111 SND_HDA_PIN_QUIRK(0x10ec0662, 0x1028, "Dell", ALC662_FIXUP_DELL_MIC_NO_PRESENCE,
David Henningsson1f8b46c2015-05-12 14:38:15 +02008112 {0x14, 0x01014010},
David Henningsson1f8b46c2015-05-12 14:38:15 +02008113 {0x18, 0x01a19020},
David Henningsson1f8b46c2015-05-12 14:38:15 +02008114 {0x1a, 0x0181302f},
Hui Wang11580292015-08-03 11:03:49 +08008115 {0x1b, 0x0221401f}),
David Henningsson76c21322014-06-24 14:46:54 +02008116 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
8117 {0x12, 0x99a30130},
8118 {0x14, 0x90170110},
8119 {0x15, 0x0321101f},
Hui Wang11580292015-08-03 11:03:49 +08008120 {0x16, 0x03011020}),
David Henningsson76c21322014-06-24 14:46:54 +02008121 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
8122 {0x12, 0x99a30140},
8123 {0x14, 0x90170110},
8124 {0x15, 0x0321101f},
Hui Wang11580292015-08-03 11:03:49 +08008125 {0x16, 0x03011020}),
David Henningsson76c21322014-06-24 14:46:54 +02008126 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
8127 {0x12, 0x99a30150},
8128 {0x14, 0x90170110},
8129 {0x15, 0x0321101f},
Hui Wang11580292015-08-03 11:03:49 +08008130 {0x16, 0x03011020}),
David Henningsson76c21322014-06-24 14:46:54 +02008131 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
David Henningsson76c21322014-06-24 14:46:54 +02008132 {0x14, 0x90170110},
8133 {0x15, 0x0321101f},
Hui Wang11580292015-08-03 11:03:49 +08008134 {0x16, 0x03011020}),
David Henningsson76c21322014-06-24 14:46:54 +02008135 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell XPS 15", ALC668_FIXUP_AUTO_MUTE,
8136 {0x12, 0x90a60130},
8137 {0x14, 0x90170110},
Hui Wang11580292015-08-03 11:03:49 +08008138 {0x15, 0x0321101f}),
Hui Wang532895c2014-05-29 15:59:19 +08008139 {}
8140};
8141
Takashi Iwai1d045db2011-07-07 18:23:21 +02008142/*
8143 */
Kailang Yangbc9f98a2007-04-12 13:06:07 +02008144static int patch_alc662(struct hda_codec *codec)
8145{
8146 struct alc_spec *spec;
Takashi Iwai3de95172012-05-07 18:03:15 +02008147 int err;
Kailang Yangbc9f98a2007-04-12 13:06:07 +02008148
Takashi Iwai3de95172012-05-07 18:03:15 +02008149 err = alc_alloc_spec(codec, 0x0b);
8150 if (err < 0)
8151 return err;
Kailang Yangbc9f98a2007-04-12 13:06:07 +02008152
Takashi Iwai3de95172012-05-07 18:03:15 +02008153 spec = codec->spec;
Takashi Iwai1f0f4b82011-06-27 10:52:59 +02008154
Takashi Iwai225068a2015-05-29 10:42:14 +02008155 spec->shutup = alc_eapd_shutup;
8156
Takashi Iwai53c334a2011-08-23 18:27:14 +02008157 /* handle multiple HPs as is */
8158 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
8159
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +02008160 alc_fix_pll_init(codec, 0x20, 0x04, 15);
8161
Takashi Iwai7639a062015-03-03 10:07:24 +01008162 switch (codec->core.vendor_id) {
Kailang Yangf3f91852014-10-24 15:43:46 +08008163 case 0x10ec0668:
8164 spec->init_hook = alc668_restore_default_value;
8165 break;
Kailang Yangf3f91852014-10-24 15:43:46 +08008166 }
Kailang Yang8663ff72012-06-29 09:35:52 +02008167
Takashi Iwai1727a772013-01-10 09:52:52 +01008168 snd_hda_pick_fixup(codec, alc662_fixup_models,
Takashi Iwai8e5a0502012-06-21 15:49:33 +02008169 alc662_fixup_tbl, alc662_fixups);
Hui Wang532895c2014-05-29 15:59:19 +08008170 snd_hda_pick_pin_fixup(codec, alc662_pin_fixup_tbl, alc662_fixups);
Takashi Iwai1727a772013-01-10 09:52:52 +01008171 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai8e5a0502012-06-21 15:49:33 +02008172
8173 alc_auto_parse_customize_define(codec);
8174
Takashi Iwai7504b6c2013-03-18 11:25:51 +01008175 if (has_cdefine_beep(codec))
8176 spec->gen.beep_nid = 0x01;
8177
Takashi Iwai1bb7e432011-10-17 16:50:59 +02008178 if ((alc_get_coef0(codec) & (1 << 14)) &&
Takashi Iwai5100cd02014-02-15 10:03:19 +01008179 codec->bus->pci && codec->bus->pci->subsystem_vendor == 0x1025 &&
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008180 spec->cdefine.platform_type == 1) {
Wei Yongjun6134b1a2013-04-18 11:12:59 +08008181 err = alc_codec_rename(codec, "ALC272X");
8182 if (err < 0)
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008183 goto error;
Takashi Iwai20ca0c32011-10-17 16:00:35 +02008184 }
Kailang Yang274693f2009-12-03 10:07:50 +01008185
Takashi Iwaib9c51062011-08-24 18:08:07 +02008186 /* automatic parse from the BIOS config */
8187 err = alc662_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008188 if (err < 0)
8189 goto error;
Kailang Yangbc9f98a2007-04-12 13:06:07 +02008190
Takashi Iwai7504b6c2013-03-18 11:25:51 +01008191 if (!spec->gen.no_analog && spec->gen.beep_nid) {
Takashi Iwai7639a062015-03-03 10:07:24 +01008192 switch (codec->core.vendor_id) {
Kailang Yangda00c242010-03-19 11:23:45 +01008193 case 0x10ec0662:
8194 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
8195 break;
8196 case 0x10ec0272:
8197 case 0x10ec0663:
8198 case 0x10ec0665:
Kailang Yang9ad54542013-11-26 15:41:40 +08008199 case 0x10ec0668:
Kailang Yangda00c242010-03-19 11:23:45 +01008200 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
8201 break;
8202 case 0x10ec0273:
8203 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
8204 break;
8205 }
Kailang Yangcec27c82010-02-04 14:18:18 +01008206 }
Takashi Iwai2134ea42008-01-10 16:53:55 +01008207
Takashi Iwai1727a772013-01-10 09:52:52 +01008208 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01008209
Kailang Yangbc9f98a2007-04-12 13:06:07 +02008210 return 0;
Kailang Yangbc9f98a2007-04-12 13:06:07 +02008211
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02008212 error:
8213 alc_free(codec);
8214 return err;
Kailang Yangb478b992011-05-18 11:51:15 +02008215}
8216
Kailang Yangbc9f98a2007-04-12 13:06:07 +02008217/*
Kailang Yangd1eb57f2010-06-23 16:25:26 +02008218 * ALC680 support
8219 */
Kailang Yangd1eb57f2010-06-23 16:25:26 +02008220
Kailang Yangd1eb57f2010-06-23 16:25:26 +02008221static int alc680_parse_auto_config(struct hda_codec *codec)
8222{
Takashi Iwai3e6179b2011-07-08 16:55:13 +02008223 return alc_parse_auto_config(codec, NULL, NULL);
Kailang Yangd1eb57f2010-06-23 16:25:26 +02008224}
8225
Kailang Yangd1eb57f2010-06-23 16:25:26 +02008226/*
Kailang Yangd1eb57f2010-06-23 16:25:26 +02008227 */
Kailang Yangd1eb57f2010-06-23 16:25:26 +02008228static int patch_alc680(struct hda_codec *codec)
8229{
Kailang Yangd1eb57f2010-06-23 16:25:26 +02008230 int err;
8231
Takashi Iwai1f0f4b82011-06-27 10:52:59 +02008232 /* ALC680 has no aa-loopback mixer */
Takashi Iwai3de95172012-05-07 18:03:15 +02008233 err = alc_alloc_spec(codec, 0);
8234 if (err < 0)
8235 return err;
Takashi Iwai1f0f4b82011-06-27 10:52:59 +02008236
Takashi Iwai1ebec5f2011-08-15 13:21:48 +02008237 /* automatic parse from the BIOS config */
8238 err = alc680_parse_auto_config(codec);
8239 if (err < 0) {
8240 alc_free(codec);
8241 return err;
Kailang Yangd1eb57f2010-06-23 16:25:26 +02008242 }
8243
Kailang Yangd1eb57f2010-06-23 16:25:26 +02008244 return 0;
8245}
8246
8247/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07008248 * patch entries
8249 */
Takashi Iwaib9a94a92015-10-01 16:20:04 +02008250static const struct hda_device_id snd_hda_id_realtek[] = {
Kailang Yang0a6f0602017-06-30 16:00:48 +08008251 HDA_CODEC_ENTRY(0x10ec0215, "ALC215", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02008252 HDA_CODEC_ENTRY(0x10ec0221, "ALC221", patch_alc269),
Kailang Yang42314302016-02-03 15:03:50 +08008253 HDA_CODEC_ENTRY(0x10ec0225, "ALC225", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02008254 HDA_CODEC_ENTRY(0x10ec0231, "ALC231", patch_alc269),
8255 HDA_CODEC_ENTRY(0x10ec0233, "ALC233", patch_alc269),
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08008256 HDA_CODEC_ENTRY(0x10ec0234, "ALC234", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02008257 HDA_CODEC_ENTRY(0x10ec0235, "ALC233", patch_alc269),
Kailang Yang736f20a2017-10-20 15:06:34 +08008258 HDA_CODEC_ENTRY(0x10ec0236, "ALC236", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02008259 HDA_CODEC_ENTRY(0x10ec0255, "ALC255", patch_alc269),
8260 HDA_CODEC_ENTRY(0x10ec0256, "ALC256", patch_alc269),
Kailang Yangf429e7e2017-12-05 15:38:24 +08008261 HDA_CODEC_ENTRY(0x10ec0257, "ALC257", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02008262 HDA_CODEC_ENTRY(0x10ec0260, "ALC260", patch_alc260),
8263 HDA_CODEC_ENTRY(0x10ec0262, "ALC262", patch_alc262),
8264 HDA_CODEC_ENTRY(0x10ec0267, "ALC267", patch_alc268),
8265 HDA_CODEC_ENTRY(0x10ec0268, "ALC268", patch_alc268),
8266 HDA_CODEC_ENTRY(0x10ec0269, "ALC269", patch_alc269),
8267 HDA_CODEC_ENTRY(0x10ec0270, "ALC270", patch_alc269),
8268 HDA_CODEC_ENTRY(0x10ec0272, "ALC272", patch_alc662),
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08008269 HDA_CODEC_ENTRY(0x10ec0274, "ALC274", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02008270 HDA_CODEC_ENTRY(0x10ec0275, "ALC275", patch_alc269),
8271 HDA_CODEC_ENTRY(0x10ec0276, "ALC276", patch_alc269),
8272 HDA_CODEC_ENTRY(0x10ec0280, "ALC280", patch_alc269),
8273 HDA_CODEC_ENTRY(0x10ec0282, "ALC282", patch_alc269),
8274 HDA_CODEC_ENTRY(0x10ec0283, "ALC283", patch_alc269),
8275 HDA_CODEC_ENTRY(0x10ec0284, "ALC284", patch_alc269),
Kailang Yang0a6f0602017-06-30 16:00:48 +08008276 HDA_CODEC_ENTRY(0x10ec0285, "ALC285", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02008277 HDA_CODEC_ENTRY(0x10ec0286, "ALC286", patch_alc269),
8278 HDA_CODEC_ENTRY(0x10ec0288, "ALC288", patch_alc269),
Kailang Yang0a6f0602017-06-30 16:00:48 +08008279 HDA_CODEC_ENTRY(0x10ec0289, "ALC289", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02008280 HDA_CODEC_ENTRY(0x10ec0290, "ALC290", patch_alc269),
8281 HDA_CODEC_ENTRY(0x10ec0292, "ALC292", patch_alc269),
8282 HDA_CODEC_ENTRY(0x10ec0293, "ALC293", patch_alc269),
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08008283 HDA_CODEC_ENTRY(0x10ec0294, "ALC294", patch_alc269),
Kailang Yang7d727862016-05-24 16:46:07 +08008284 HDA_CODEC_ENTRY(0x10ec0295, "ALC295", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02008285 HDA_CODEC_ENTRY(0x10ec0298, "ALC298", patch_alc269),
Kailang Yang28f1f9b2017-01-04 14:49:07 +08008286 HDA_CODEC_ENTRY(0x10ec0299, "ALC299", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02008287 HDA_CODEC_REV_ENTRY(0x10ec0861, 0x100340, "ALC660", patch_alc861),
8288 HDA_CODEC_ENTRY(0x10ec0660, "ALC660-VD", patch_alc861vd),
8289 HDA_CODEC_ENTRY(0x10ec0861, "ALC861", patch_alc861),
8290 HDA_CODEC_ENTRY(0x10ec0862, "ALC861-VD", patch_alc861vd),
8291 HDA_CODEC_REV_ENTRY(0x10ec0662, 0x100002, "ALC662 rev2", patch_alc882),
8292 HDA_CODEC_REV_ENTRY(0x10ec0662, 0x100101, "ALC662 rev1", patch_alc662),
8293 HDA_CODEC_REV_ENTRY(0x10ec0662, 0x100300, "ALC662 rev3", patch_alc662),
8294 HDA_CODEC_ENTRY(0x10ec0663, "ALC663", patch_alc662),
8295 HDA_CODEC_ENTRY(0x10ec0665, "ALC665", patch_alc662),
8296 HDA_CODEC_ENTRY(0x10ec0667, "ALC667", patch_alc662),
8297 HDA_CODEC_ENTRY(0x10ec0668, "ALC668", patch_alc662),
8298 HDA_CODEC_ENTRY(0x10ec0670, "ALC670", patch_alc662),
8299 HDA_CODEC_ENTRY(0x10ec0671, "ALC671", patch_alc662),
8300 HDA_CODEC_ENTRY(0x10ec0680, "ALC680", patch_alc680),
Kailang Yang6fbae352016-05-30 16:44:20 +08008301 HDA_CODEC_ENTRY(0x10ec0700, "ALC700", patch_alc269),
8302 HDA_CODEC_ENTRY(0x10ec0701, "ALC701", patch_alc269),
8303 HDA_CODEC_ENTRY(0x10ec0703, "ALC703", patch_alc269),
Kailang Yang78f4f7c2016-06-07 11:31:34 +08008304 HDA_CODEC_ENTRY(0x10ec0867, "ALC891", patch_alc662),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02008305 HDA_CODEC_ENTRY(0x10ec0880, "ALC880", patch_alc880),
8306 HDA_CODEC_ENTRY(0x10ec0882, "ALC882", patch_alc882),
8307 HDA_CODEC_ENTRY(0x10ec0883, "ALC883", patch_alc882),
8308 HDA_CODEC_REV_ENTRY(0x10ec0885, 0x100101, "ALC889A", patch_alc882),
8309 HDA_CODEC_REV_ENTRY(0x10ec0885, 0x100103, "ALC889A", patch_alc882),
8310 HDA_CODEC_ENTRY(0x10ec0885, "ALC885", patch_alc882),
8311 HDA_CODEC_ENTRY(0x10ec0887, "ALC887", patch_alc882),
8312 HDA_CODEC_REV_ENTRY(0x10ec0888, 0x100101, "ALC1200", patch_alc882),
8313 HDA_CODEC_ENTRY(0x10ec0888, "ALC888", patch_alc882),
8314 HDA_CODEC_ENTRY(0x10ec0889, "ALC889", patch_alc882),
8315 HDA_CODEC_ENTRY(0x10ec0892, "ALC892", patch_alc662),
8316 HDA_CODEC_ENTRY(0x10ec0899, "ALC898", patch_alc882),
8317 HDA_CODEC_ENTRY(0x10ec0900, "ALC1150", patch_alc882),
Kailang Yang65553b12017-07-11 15:15:47 +08008318 HDA_CODEC_ENTRY(0x10ec1168, "ALC1220", patch_alc882),
Kailang Yanga535ad52017-01-16 16:59:26 +08008319 HDA_CODEC_ENTRY(0x10ec1220, "ALC1220", patch_alc882),
Linus Torvalds1da177e2005-04-16 15:20:36 -07008320 {} /* terminator */
8321};
Takashi Iwaib9a94a92015-10-01 16:20:04 +02008322MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_realtek);
Takashi Iwai1289e9e2008-11-27 15:47:11 +01008323
8324MODULE_LICENSE("GPL");
8325MODULE_DESCRIPTION("Realtek HD-audio codec");
8326
Takashi Iwaid8a766a2015-02-17 15:25:37 +01008327static struct hda_codec_driver realtek_driver = {
Takashi Iwaib9a94a92015-10-01 16:20:04 +02008328 .id = snd_hda_id_realtek,
Takashi Iwai1289e9e2008-11-27 15:47:11 +01008329};
8330
Takashi Iwaid8a766a2015-02-17 15:25:37 +01008331module_hda_codec_driver(realtek_driver);